diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-10 04:10:19 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-10 05:12:55 +1000 |
commit | ab0af559d34b6817768c1720859aef7d7009ee57 (patch) | |
tree | 5d2b27a3b78acd6e3869bd7f3762d53b885f03eb | |
parent | 7820e5eef0faa4a5e10834296680827f7ce78a89 (diff) |
drm/nv50/kms: move framebuffer wrangling out of common code
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 59 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 65 |
3 files changed, 81 insertions, 47 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index dd469dbeaae1..b6e258faa4f7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -200,6 +200,10 @@ static void nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) { struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); + struct nouveau_display *disp = nouveau_display(drm_fb->dev); + + if (disp->fb_dtor) + disp->fb_dtor(drm_fb); if (fb->nvbo) drm_gem_object_unreference_unlocked(&fb->nvbo->gem); @@ -229,63 +233,24 @@ nouveau_framebuffer_init(struct drm_device *dev, struct drm_mode_fb_cmd2 *mode_cmd, struct nouveau_bo *nvbo) { - struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_display *disp = nouveau_display(dev); struct drm_framebuffer *fb = &nv_fb->base; int ret; drm_helper_mode_fill_fb_struct(fb, mode_cmd); nv_fb->nvbo = nvbo; - if (nv_device(drm->device)->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 = 0x1e00; break; - case 15: nv_fb->r_format = 0xe900; break; - case 16: nv_fb->r_format = 0xe800; break; - case 24: - case 32: nv_fb->r_format = 0xcf00; break; - case 30: nv_fb->r_format = 0xd100; break; - default: - NV_ERROR(drm, "unknown depth %d\n", fb->depth); - return -EINVAL; - } - - if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) { - NV_ERROR(drm, "framebuffer requires contiguous bo\n"); - return -EINVAL; - } - - if (nv_device(drm->device)->chipset == 0x50) - nv_fb->r_format |= (tile_flags << 8); - - if (!tile_flags) { - if (nv_device(drm->device)->card_type < NV_D0) - nv_fb->r_pitch = 0x00100000 | fb->pitches[0]; - else - nv_fb->r_pitch = 0x01000000 | fb->pitches[0]; - } else { - u32 mode = nvbo->tile_mode; - if (nv_device(drm->device)->card_type >= NV_C0) - mode >>= 4; - nv_fb->r_pitch = ((fb->pitches[0] / 4) << 4) | mode; - } - } - ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); - if (ret) { + if (ret) return ret; + + if (disp->fb_ctor) { + ret = disp->fb_ctor(fb); + if (ret) + disp->fb_dtor(fb); } - return 0; + return ret; } static struct drm_framebuffer * diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index a71cf77e55b2..90426cb07c5e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -36,9 +36,13 @@ struct nouveau_display { int (*init)(struct drm_device *); void (*fini)(struct drm_device *); + int (*fb_ctor)(struct drm_framebuffer *); + void (*fb_dtor)(struct drm_framebuffer *); + struct nouveau_object *core; struct nouveau_eventh **vblank; + struct drm_property *dithering_mode; struct drm_property *dithering_depth; struct drm_property *underscan_property; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 4c534b7b04da..9e3a3dec6b47 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -2169,8 +2169,71 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) } /****************************************************************************** + * Framebuffer + *****************************************************************************/ + +static void +nv50_fb_dtor(struct drm_framebuffer *fb) +{ +} + +static int +nv50_fb_ctor(struct drm_framebuffer *fb) +{ + struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); + struct nouveau_drm *drm = nouveau_drm(fb->dev); + struct nouveau_bo *nvbo = nv_fb->nvbo; + u32 tile_flags; + + 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; + + if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) { + NV_ERROR(drm, "framebuffer requires contiguous bo\n"); + return -EINVAL; + } + + switch (fb->depth) { + case 8: nv_fb->r_format = 0x1e00; break; + case 15: nv_fb->r_format = 0xe900; break; + case 16: nv_fb->r_format = 0xe800; break; + case 24: + case 32: nv_fb->r_format = 0xcf00; break; + case 30: nv_fb->r_format = 0xd100; break; + default: + NV_ERROR(drm, "unknown depth %d\n", fb->depth); + return -EINVAL; + } + + if (nv_device(drm->device)->chipset == 0x50) + nv_fb->r_format |= (tile_flags << 8); + + if (!tile_flags) { + if (nv_device(drm->device)->card_type < NV_D0) + nv_fb->r_pitch = 0x00100000 | fb->pitches[0]; + else + nv_fb->r_pitch = 0x01000000 | fb->pitches[0]; + } else { + u32 mode = nvbo->tile_mode; + if (nv_device(drm->device)->card_type >= NV_C0) + mode >>= 4; + nv_fb->r_pitch = ((fb->pitches[0] / 4) << 4) | mode; + } + + return 0; +} + +/****************************************************************************** * Init *****************************************************************************/ + void nv50_display_fini(struct drm_device *dev) { @@ -2233,6 +2296,8 @@ nv50_display_create(struct drm_device *dev) nouveau_display(dev)->dtor = nv50_display_destroy; nouveau_display(dev)->init = nv50_display_init; nouveau_display(dev)->fini = nv50_display_fini; + nouveau_display(dev)->fb_ctor = nv50_fb_ctor; + nouveau_display(dev)->fb_dtor = nv50_fb_dtor; disp->core = nouveau_display(dev)->core; /* small shared memory area we use for notifiers and semaphores */ |