提交 45c4e0aa 编写于 作者: B Ben Skeggs

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: NBen Skeggs <bskeggs@redhat.com>
上级 292deb7a
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "nouveau_hw.h" #include "nouveau_hw.h"
#include "nouveau_crtc.h" #include "nouveau_crtc.h"
#include "nouveau_dma.h" #include "nouveau_dma.h"
#include "nv50_display.h"
static void static void
nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
...@@ -61,18 +62,59 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { ...@@ -61,18 +62,59 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
}; };
int int
nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb, nouveau_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd *mode_cmd, struct nouveau_bo *nvbo) 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; int ret;
ret = drm_framebuffer_init(dev, &nouveau_fb->base, &nouveau_framebuffer_funcs); ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
if (ret) { if (ret) {
return ret; return ret;
} }
drm_helper_mode_fill_fb_struct(&nouveau_fb->base, mode_cmd); drm_helper_mode_fill_fb_struct(fb, mode_cmd);
nouveau_fb->nvbo = nvbo; 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; return 0;
} }
......
...@@ -30,6 +30,9 @@ ...@@ -30,6 +30,9 @@
struct nouveau_framebuffer { struct nouveau_framebuffer {
struct drm_framebuffer base; struct drm_framebuffer base;
struct nouveau_bo *nvbo; struct nouveau_bo *nvbo;
u32 r_dma;
u32 r_format;
u32 r_pitch;
}; };
static inline struct nouveau_framebuffer * static inline struct nouveau_framebuffer *
......
...@@ -522,7 +522,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, ...@@ -522,7 +522,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
struct nouveau_channel *evo = nv50_display(dev)->master; struct nouveau_channel *evo = nv50_display(dev)->master;
struct drm_framebuffer *drm_fb = nv_crtc->base.fb; struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
int ret, format; int ret;
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
...@@ -548,28 +548,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, ...@@ -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.offset = fb->nvbo->bo.mem.start << PAGE_SHIFT;
nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo); nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo);
nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
...@@ -579,14 +557,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, ...@@ -579,14 +557,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
return ret; return ret;
BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1); BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1);
if (nv_crtc->fb.tile_flags == 0x7a00 || OUT_RING (evo, fb->r_dma);
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);
} }
ret = RING_SPACE(evo, 12); ret = RING_SPACE(evo, 12);
...@@ -594,30 +565,20 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, ...@@ -594,30 +565,20 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
return ret; return ret;
BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5); BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5);
OUT_RING(evo, nv_crtc->fb.offset >> 8); OUT_RING (evo, nv_crtc->fb.offset >> 8);
OUT_RING(evo, 0); OUT_RING (evo, 0);
OUT_RING(evo, (drm_fb->height << 16) | drm_fb->width); OUT_RING (evo, (drm_fb->height << 16) | drm_fb->width);
if (!nv_crtc->fb.tile_flags) { OUT_RING (evo, fb->r_pitch);
OUT_RING(evo, drm_fb->pitch | (1 << 20)); OUT_RING (evo, fb->r_format);
} 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);
BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1); BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1);
OUT_RING(evo, fb->base.depth == 8 ? OUT_RING (evo, fb->base.depth == 8 ?
NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON); 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); 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); 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) { if (nv_crtc->lut.depth != fb->base.depth) {
nv_crtc->lut.depth = fb->base.depth; nv_crtc->lut.depth = fb->base.depth;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册