diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 14:10:19 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 15:12:55 -0400 |
commit | ab0af559d34b6817768c1720859aef7d7009ee57 (patch) | |
tree | 5d2b27a3b78acd6e3869bd7f3762d53b885f03eb /drivers/gpu | |
parent | 7820e5eef0faa4a5e10834296680827f7ce78a89 (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.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 | |||
200 | nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) | 200 | nouveau_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 | ||
291 | static struct drm_framebuffer * | 256 | 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 { | |||
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 | |||
2175 | static void | ||
2176 | nv50_fb_dtor(struct drm_framebuffer *fb) | ||
2177 | { | ||
2178 | } | ||
2179 | |||
2180 | static int | ||
2181 | nv50_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 | |||
2174 | void | 2237 | void |
2175 | nv50_display_fini(struct drm_device *dev) | 2238 | nv50_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 */ |