aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_fb.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-03-30 01:34:18 -0400
committerDave Airlie <airlied@redhat.com>2010-04-06 20:30:38 -0400
commit4abe35204af82a018ca3ce6db4102aa09719698e (patch)
treefcc91e2e109fe311a673d5b99dc758aba3bb4a79 /drivers/gpu/drm/radeon/radeon_fb.c
parent5c4426a782bc9509573fc7958a786ebd14fafdf3 (diff)
drm/kms/fb: use slow work mechanism for normal hotplug also.
a) slow work is always used now for any fbcon hotplug, as its not a fast task and is more suited to being ran under slow work. b) attempt to not do any fbdev changes when X is running as we'll just mess it up. This hooks set_par to hopefully do the changes once X hands control to fbdev. This also adds the nouveau/intel hotplug support. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_fb.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c74
1 files changed, 32 insertions, 42 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 7913e50fe501..93cc54fac330 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -86,11 +86,6 @@ static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bo
86 return aligned; 86 return aligned;
87} 87}
88 88
89static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
90 .gamma_set = radeon_crtc_fb_gamma_set,
91 .gamma_get = radeon_crtc_fb_gamma_get,
92};
93
94static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) 89static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
95{ 90{
96 struct radeon_bo *rbo = gobj->driver_private; 91 struct radeon_bo *rbo = gobj->driver_private;
@@ -222,7 +217,6 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
222 /* setup helper */ 217 /* setup helper */
223 rfbdev->helper.fb = fb; 218 rfbdev->helper.fb = fb;
224 rfbdev->helper.fbdev = info; 219 rfbdev->helper.fbdev = info;
225 rfbdev->helper.funcs = &radeon_fb_helper_funcs;
226 220
227 memset_io(rbo->kptr, 0x0, radeon_bo_size(rbo)); 221 memset_io(rbo->kptr, 0x0, radeon_bo_size(rbo));
228 222
@@ -252,10 +246,18 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
252 info->pixmap.access_align = 32; 246 info->pixmap.access_align = 32;
253 info->pixmap.flags = FB_PIXMAP_SYSTEM; 247 info->pixmap.flags = FB_PIXMAP_SYSTEM;
254 info->pixmap.scan_align = 1; 248 info->pixmap.scan_align = 1;
249
255 if (info->screen_base == NULL) { 250 if (info->screen_base == NULL) {
256 ret = -ENOSPC; 251 ret = -ENOSPC;
257 goto out_unref; 252 goto out_unref;
258 } 253 }
254
255 ret = fb_alloc_cmap(&info->cmap, 256, 0);
256 if (ret) {
257 ret = -ENOMEM;
258 goto out_unref;
259 }
260
259 DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); 261 DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start);
260 DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base); 262 DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base);
261 DRM_INFO("size %lu\n", (unsigned long)radeon_bo_size(rbo)); 263 DRM_INFO("size %lu\n", (unsigned long)radeon_bo_size(rbo));
@@ -309,33 +311,16 @@ int radeon_parse_options(char *options)
309 return 0; 311 return 0;
310} 312}
311 313
312static int radeonfb_probe(struct radeon_fbdev *rfbdev)
313{
314 struct radeon_device *rdev = rfbdev->rdev;
315 int bpp_sel = 32;
316
317 /* select 8 bpp console on RN50 or 16MB cards */
318 if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
319 bpp_sel = 8;
320
321 return drm_fb_helper_single_fb_probe(&rfbdev->helper, bpp_sel);
322}
323
324void radeonfb_hotplug(struct drm_device *dev, bool polled) 314void radeonfb_hotplug(struct drm_device *dev, bool polled)
325{ 315{
326 struct radeon_device *rdev = dev->dev_private; 316 struct radeon_device *rdev = dev->dev_private;
327 int max_width, max_height;
328
329 max_width = rdev->mode_info.rfbdev->rfb.base.width;
330 max_height = rdev->mode_info.rfbdev->rfb.base.height;
331 drm_helper_fb_hotplug_event(&rdev->mode_info.rfbdev->helper, max_width, max_height, polled);
332 317
333 radeonfb_probe(rdev->mode_info.rfbdev); 318 drm_helper_fb_hpd_irq_event(&rdev->mode_info.rfbdev->helper);
334} 319}
335 320
336static void radeon_fb_poll_changed(struct drm_fb_helper *fb_helper) 321static void radeon_fb_output_status_changed(struct drm_fb_helper *fb_helper)
337{ 322{
338 radeonfb_hotplug(fb_helper->dev, true); 323 drm_helper_fb_hotplug_event(fb_helper, true);
339} 324}
340 325
341static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev) 326static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev)
@@ -347,7 +332,10 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
347 332
348 if (rfbdev->helper.fbdev) { 333 if (rfbdev->helper.fbdev) {
349 info = rfbdev->helper.fbdev; 334 info = rfbdev->helper.fbdev;
335
350 unregister_framebuffer(info); 336 unregister_framebuffer(info);
337 if (info->cmap.len)
338 fb_dealloc_cmap(&info->cmap);
351 framebuffer_release(info); 339 framebuffer_release(info);
352 } 340 }
353 341
@@ -361,16 +349,27 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
361 } 349 }
362 drm_gem_object_unreference_unlocked(rfb->obj); 350 drm_gem_object_unreference_unlocked(rfb->obj);
363 } 351 }
364 drm_fb_helper_free(&rfbdev->helper); 352 drm_fb_helper_fini(&rfbdev->helper);
365 drm_framebuffer_cleanup(&rfb->base); 353 drm_framebuffer_cleanup(&rfb->base);
366 354
367 return 0; 355 return 0;
368} 356}
369MODULE_LICENSE("GPL"); 357
358static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
359 .gamma_set = radeon_crtc_fb_gamma_set,
360 .gamma_get = radeon_crtc_fb_gamma_get,
361 .fb_probe = radeon_fb_find_or_create_single,
362 .fb_output_status_changed = radeon_fb_output_status_changed,
363};
370 364
371int radeon_fbdev_init(struct radeon_device *rdev) 365int radeon_fbdev_init(struct radeon_device *rdev)
372{ 366{
373 struct radeon_fbdev *rfbdev; 367 struct radeon_fbdev *rfbdev;
368 int bpp_sel = 32;
369
370 /* select 8 bpp console on RN50 or 16MB cards */
371 if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
372 bpp_sel = 8;
374 373
375 rfbdev = kzalloc(sizeof(struct radeon_fbdev), GFP_KERNEL); 374 rfbdev = kzalloc(sizeof(struct radeon_fbdev), GFP_KERNEL);
376 if (!rfbdev) 375 if (!rfbdev)
@@ -378,20 +377,13 @@ int radeon_fbdev_init(struct radeon_device *rdev)
378 377
379 rfbdev->rdev = rdev; 378 rfbdev->rdev = rdev;
380 rdev->mode_info.rfbdev = rfbdev; 379 rdev->mode_info.rfbdev = rfbdev;
380 rfbdev->helper.funcs = &radeon_fb_helper_funcs;
381 381
382 drm_fb_helper_init_crtc_count(rdev->ddev, &rfbdev->helper, 382 drm_fb_helper_init(rdev->ddev, &rfbdev->helper,
383 rdev->num_crtc, 383 rdev->num_crtc,
384 RADEONFB_CONN_LIMIT); 384 RADEONFB_CONN_LIMIT, true);
385 rfbdev->helper.fb_probe = radeon_fb_find_or_create_single;
386
387 drm_fb_helper_single_add_all_connectors(&rfbdev->helper); 385 drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
388 386 drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
389 rfbdev->helper.fb_poll_changed = radeon_fb_poll_changed;
390 drm_fb_helper_poll_init(&rfbdev->helper);
391
392 drm_fb_helper_initial_config(&rfbdev->helper);
393 radeonfb_probe(rfbdev);
394
395 return 0; 387 return 0;
396 388
397} 389}
@@ -401,7 +393,6 @@ void radeon_fbdev_fini(struct radeon_device *rdev)
401 if (!rdev->mode_info.rfbdev) 393 if (!rdev->mode_info.rfbdev)
402 return; 394 return;
403 395
404 drm_fb_helper_poll_fini(&rdev->mode_info.rfbdev->helper);
405 radeon_fbdev_destroy(rdev->ddev, rdev->mode_info.rfbdev); 396 radeon_fbdev_destroy(rdev->ddev, rdev->mode_info.rfbdev);
406 kfree(rdev->mode_info.rfbdev); 397 kfree(rdev->mode_info.rfbdev);
407 rdev->mode_info.rfbdev = NULL; 398 rdev->mode_info.rfbdev = NULL;
@@ -428,4 +419,3 @@ bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
428 return true; 419 return true;
429 return false; 420 return false;
430} 421}
431