aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-08-09 14:10:19 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-08-09 15:12:55 -0400
commitab0af559d34b6817768c1720859aef7d7009ee57 (patch)
tree5d2b27a3b78acd6e3869bd7f3762d53b885f03eb /drivers/gpu
parent7820e5eef0faa4a5e10834296680827f7ce78a89 (diff)
drm/nv50/kms: move framebuffer wrangling out of common code
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c59
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.h4
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c65
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
200nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) 200nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
201{ 201{
202 struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 202 struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
203 struct nouveau_display *disp = nouveau_display(drm_fb->dev);
204
205 if (disp->fb_dtor)
206 disp->fb_dtor(drm_fb);
203 207
204 if (fb->nvbo) 208 if (fb->nvbo)
205 drm_gem_object_unreference_unlocked(&fb->nvbo->gem); 209 drm_gem_object_unreference_unlocked(&fb->nvbo->gem);
@@ -229,63 +233,24 @@ nouveau_framebuffer_init(struct drm_device *dev,
229 struct drm_mode_fb_cmd2 *mode_cmd, 233 struct drm_mode_fb_cmd2 *mode_cmd,
230 struct nouveau_bo *nvbo) 234 struct nouveau_bo *nvbo)
231{ 235{
232 struct nouveau_drm *drm = nouveau_drm(dev); 236 struct nouveau_display *disp = nouveau_display(dev);
233 struct drm_framebuffer *fb = &nv_fb->base; 237 struct drm_framebuffer *fb = &nv_fb->base;
234 int ret; 238 int ret;
235 239
236 drm_helper_mode_fill_fb_struct(fb, mode_cmd); 240 drm_helper_mode_fill_fb_struct(fb, mode_cmd);
237 nv_fb->nvbo = nvbo; 241 nv_fb->nvbo = nvbo;
238 242
239 if (nv_device(drm->device)->card_type >= NV_50) {
240 u32 tile_flags = nouveau_bo_tile_layout(nvbo);
241 if (tile_flags == 0x7a00 ||
242 tile_flags == 0xfe00)
243 nv_fb->r_dma = NvEvoFB32;
244 else
245 if (tile_flags == 0x7000)
246 nv_fb->r_dma = NvEvoFB16;
247 else
248 nv_fb->r_dma = NvEvoVRAM_LP;
249
250 switch (fb->depth) {
251 case 8: nv_fb->r_format = 0x1e00; break;
252 case 15: nv_fb->r_format = 0xe900; break;
253 case 16: nv_fb->r_format = 0xe800; break;
254 case 24:
255 case 32: nv_fb->r_format = 0xcf00; break;
256 case 30: nv_fb->r_format = 0xd100; break;
257 default:
258 NV_ERROR(drm, "unknown depth %d\n", fb->depth);
259 return -EINVAL;
260 }
261
262 if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) {
263 NV_ERROR(drm, "framebuffer requires contiguous bo\n");
264 return -EINVAL;
265 }
266
267 if (nv_device(drm->device)->chipset == 0x50)
268 nv_fb->r_format |= (tile_flags << 8);
269
270 if (!tile_flags) {
271 if (nv_device(drm->device)->card_type < NV_D0)
272 nv_fb->r_pitch = 0x00100000 | fb->pitches[0];
273 else
274 nv_fb->r_pitch = 0x01000000 | fb->pitches[0];
275 } else {
276 u32 mode = nvbo->tile_mode;
277 if (nv_device(drm->device)->card_type >= NV_C0)
278 mode >>= 4;
279 nv_fb->r_pitch = ((fb->pitches[0] / 4) << 4) | mode;
280 }
281 }
282
283 ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); 243 ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
284 if (ret) { 244 if (ret)
285 return ret; 245 return ret;
246
247 if (disp->fb_ctor) {
248 ret = disp->fb_ctor(fb);
249 if (ret)
250 disp->fb_dtor(fb);
286 } 251 }
287 252
288 return 0; 253 return ret;
289} 254}
290 255
291static struct drm_framebuffer * 256static 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 {
36 int (*init)(struct drm_device *); 36 int (*init)(struct drm_device *);
37 void (*fini)(struct drm_device *); 37 void (*fini)(struct drm_device *);
38 38
39 int (*fb_ctor)(struct drm_framebuffer *);
40 void (*fb_dtor)(struct drm_framebuffer *);
41
39 struct nouveau_object *core; 42 struct nouveau_object *core;
40 struct nouveau_eventh **vblank; 43 struct nouveau_eventh **vblank;
41 44
45
42 struct drm_property *dithering_mode; 46 struct drm_property *dithering_mode;
43 struct drm_property *dithering_depth; 47 struct drm_property *dithering_depth;
44 struct drm_property *underscan_property; 48 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)
2169} 2169}
2170 2170
2171/****************************************************************************** 2171/******************************************************************************
2172 * Framebuffer
2173 *****************************************************************************/
2174
2175static void
2176nv50_fb_dtor(struct drm_framebuffer *fb)
2177{
2178}
2179
2180static int
2181nv50_fb_ctor(struct drm_framebuffer *fb)
2182{
2183 struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
2184 struct nouveau_drm *drm = nouveau_drm(fb->dev);
2185 struct nouveau_bo *nvbo = nv_fb->nvbo;
2186 u32 tile_flags;
2187
2188 tile_flags = nouveau_bo_tile_layout(nvbo);
2189 if (tile_flags == 0x7a00 ||
2190 tile_flags == 0xfe00)
2191 nv_fb->r_dma = NvEvoFB32;
2192 else
2193 if (tile_flags == 0x7000)
2194 nv_fb->r_dma = NvEvoFB16;
2195 else
2196 nv_fb->r_dma = NvEvoVRAM_LP;
2197
2198 if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) {
2199 NV_ERROR(drm, "framebuffer requires contiguous bo\n");
2200 return -EINVAL;
2201 }
2202
2203 switch (fb->depth) {
2204 case 8: nv_fb->r_format = 0x1e00; break;
2205 case 15: nv_fb->r_format = 0xe900; break;
2206 case 16: nv_fb->r_format = 0xe800; break;
2207 case 24:
2208 case 32: nv_fb->r_format = 0xcf00; break;
2209 case 30: nv_fb->r_format = 0xd100; break;
2210 default:
2211 NV_ERROR(drm, "unknown depth %d\n", fb->depth);
2212 return -EINVAL;
2213 }
2214
2215 if (nv_device(drm->device)->chipset == 0x50)
2216 nv_fb->r_format |= (tile_flags << 8);
2217
2218 if (!tile_flags) {
2219 if (nv_device(drm->device)->card_type < NV_D0)
2220 nv_fb->r_pitch = 0x00100000 | fb->pitches[0];
2221 else
2222 nv_fb->r_pitch = 0x01000000 | fb->pitches[0];
2223 } else {
2224 u32 mode = nvbo->tile_mode;
2225 if (nv_device(drm->device)->card_type >= NV_C0)
2226 mode >>= 4;
2227 nv_fb->r_pitch = ((fb->pitches[0] / 4) << 4) | mode;
2228 }
2229
2230 return 0;
2231}
2232
2233/******************************************************************************
2172 * Init 2234 * Init
2173 *****************************************************************************/ 2235 *****************************************************************************/
2236
2174void 2237void
2175nv50_display_fini(struct drm_device *dev) 2238nv50_display_fini(struct drm_device *dev)
2176{ 2239{
@@ -2233,6 +2296,8 @@ nv50_display_create(struct drm_device *dev)
2233 nouveau_display(dev)->dtor = nv50_display_destroy; 2296 nouveau_display(dev)->dtor = nv50_display_destroy;
2234 nouveau_display(dev)->init = nv50_display_init; 2297 nouveau_display(dev)->init = nv50_display_init;
2235 nouveau_display(dev)->fini = nv50_display_fini; 2298 nouveau_display(dev)->fini = nv50_display_fini;
2299 nouveau_display(dev)->fb_ctor = nv50_fb_ctor;
2300 nouveau_display(dev)->fb_dtor = nv50_fb_dtor;
2236 disp->core = nouveau_display(dev)->core; 2301 disp->core = nouveau_display(dev)->core;
2237 2302
2238 /* small shared memory area we use for notifiers and semaphores */ 2303 /* small shared memory area we use for notifiers and semaphores */