drm/nv50-nvc0: precalculate some fb state when creating them

Just a cleanup, to avoid duplicating parts of nv50_crtc.c's code in
the page flipping routines.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs 2011-02-09 11:57:45 +10:00
parent 292deb7a3b
commit 45c4e0aae9
3 changed files with 61 additions and 55 deletions

View File

@ -32,6 +32,7 @@
#include "nouveau_hw.h"
#include "nouveau_crtc.h"
#include "nouveau_dma.h"
#include "nv50_display.h"
static void
nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
@ -61,18 +62,59 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
};
int
nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb,
struct drm_mode_fb_cmd *mode_cmd, struct nouveau_bo *nvbo)
nouveau_framebuffer_init(struct drm_device *dev,
struct nouveau_framebuffer *nv_fb,
struct drm_mode_fb_cmd *mode_cmd,
struct nouveau_bo *nvbo)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_framebuffer *fb = &nv_fb->base;
int ret;
ret = drm_framebuffer_init(dev, &nouveau_fb->base, &nouveau_framebuffer_funcs);
ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
if (ret) {
return ret;
}
drm_helper_mode_fill_fb_struct(&nouveau_fb->base, mode_cmd);
nouveau_fb->nvbo = nvbo;
drm_helper_mode_fill_fb_struct(fb, mode_cmd);
nv_fb->nvbo = nvbo;
if (dev_priv->card_type >= NV_50) {
u32 tile_flags = nouveau_bo_tile_layout(nvbo);
if (tile_flags == 0x7a00 ||
tile_flags == 0xfe00)
nv_fb->r_dma = NvEvoFB32;
else
if (tile_flags == 0x7000)
nv_fb->r_dma = NvEvoFB16;
else
nv_fb->r_dma = NvEvoVRAM_LP;
switch (fb->depth) {
case 8: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_8; break;
case 15: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_15; break;
case 16: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_16; break;
case 24:
case 32: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_24; break;
case 30: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_30; break;
default:
NV_ERROR(dev, "unknown depth %d\n", fb->depth);
return -EINVAL;
}
if (dev_priv->chipset == 0x50)
nv_fb->r_format |= (tile_flags << 8);
if (!tile_flags)
nv_fb->r_pitch = 0x00100000 | fb->pitch;
else {
u32 mode = nvbo->tile_mode;
if (dev_priv->card_type >= NV_C0)
mode >>= 4;
nv_fb->r_pitch = ((fb->pitch / 4) << 4) | mode;
}
}
return 0;
}

View File

@ -30,6 +30,9 @@
struct nouveau_framebuffer {
struct drm_framebuffer base;
struct nouveau_bo *nvbo;
u32 r_dma;
u32 r_format;
u32 r_pitch;
};
static inline struct nouveau_framebuffer *

View File

@ -522,7 +522,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
struct nouveau_channel *evo = nv50_display(dev)->master;
struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
int ret, format;
int ret;
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
@ -548,28 +548,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
}
}
switch (drm_fb->depth) {
case 8:
format = NV50_EVO_CRTC_FB_DEPTH_8;
break;
case 15:
format = NV50_EVO_CRTC_FB_DEPTH_15;
break;
case 16:
format = NV50_EVO_CRTC_FB_DEPTH_16;
break;
case 24:
case 32:
format = NV50_EVO_CRTC_FB_DEPTH_24;
break;
case 30:
format = NV50_EVO_CRTC_FB_DEPTH_30;
break;
default:
NV_ERROR(dev, "unknown depth %d\n", drm_fb->depth);
return -EINVAL;
}
nv_crtc->fb.offset = fb->nvbo->bo.mem.start << PAGE_SHIFT;
nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo);
nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
@ -579,14 +557,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
return ret;
BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1);
if (nv_crtc->fb.tile_flags == 0x7a00 ||
nv_crtc->fb.tile_flags == 0xfe00)
OUT_RING(evo, NvEvoFB32);
else
if (nv_crtc->fb.tile_flags == 0x7000)
OUT_RING(evo, NvEvoFB16);
else
OUT_RING(evo, NvEvoVRAM_LP);
OUT_RING (evo, fb->r_dma);
}
ret = RING_SPACE(evo, 12);
@ -594,30 +565,20 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
return ret;
BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5);
OUT_RING(evo, nv_crtc->fb.offset >> 8);
OUT_RING(evo, 0);
OUT_RING(evo, (drm_fb->height << 16) | drm_fb->width);
if (!nv_crtc->fb.tile_flags) {
OUT_RING(evo, drm_fb->pitch | (1 << 20));
} else {
u32 tile_mode = fb->nvbo->tile_mode;
if (dev_priv->card_type >= NV_C0)
tile_mode >>= 4;
OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | tile_mode);
}
if (dev_priv->chipset == 0x50)
OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format);
else
OUT_RING(evo, format);
OUT_RING (evo, nv_crtc->fb.offset >> 8);
OUT_RING (evo, 0);
OUT_RING (evo, (drm_fb->height << 16) | drm_fb->width);
OUT_RING (evo, fb->r_pitch);
OUT_RING (evo, fb->r_format);
BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1);
OUT_RING(evo, fb->base.depth == 8 ?
NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON);
OUT_RING (evo, fb->base.depth == 8 ?
NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON);
BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1);
OUT_RING(evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR);
OUT_RING (evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR);
BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1);
OUT_RING(evo, (y << 16) | x);
OUT_RING (evo, (y << 16) | x);
if (nv_crtc->lut.depth != fb->base.depth) {
nv_crtc->lut.depth = fb->base.depth;