mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
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:
parent
292deb7a3b
commit
45c4e0aae9
3 changed files with 61 additions and 55 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue