aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fb_helper.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 16:08:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 16:08:22 -0400
commitbe53bfdb8088e9d1924199cc1a96e113756b1075 (patch)
tree8c65eb9d82ca4c0f11c17cfdc44d5263820b415b /drivers/gpu/drm/drm_fb_helper.c
parentb2094ef840697bc8ca5d17a83b7e30fad5f1e9fa (diff)
parent5466c7b1683a23dbbcfb7ee4a71c4f23886001c7 (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm main changes from Dave Airlie: "This is the main drm pull request, I'm probably going to send two more smaller ones, will explain below. This contains a patch that is also in the fbdev tree, but it should be the same patch, it added an API for hot unplugging framebuffer devices, and I need that API for a new driver. It also contains some changes to the i2c tree which Jean has acked, and one change to moorestown platform stuff in x86. Highlights: - new drivers: UDL driver for USB displaylink devices, kms only, should support correct hotplug operations. - core: i2c speedups + better hotplug support, EDID overriding via firmware interface - allows user to load a firmware for a broken monitor/kvm from userspace, it even has documentation for it. - exynos: new HDMI audio + hdmi 1.4 + virtual output driver - gma500: code cleanup - radeon: cleanups, CS optimisations, streamout support and pageflip fix - nouveau: NVD9 displayport support + more reclocking work - i915: re-enabling GMBUS, finish gpu patch (might help hibernation who knows), missed irq fixes, stencil tiling fixes, interlaced support, aliasesd PPGTT support for SNB/IVB, swizzling for SNB/IVB, semaphore fixes As well as the usual bunch of cleanups and fixes all over the place. I've got two things I'd like to merge a bit later: a) AMD support for all their new radeonhd 7000 series GPU and APUs. AMD dropped this a bit late due to insane internal review processes, (please AMD just follow Intel and let open source guys ship stuff early) however I don't want to penalise people who own this hardware (since its been on sale for 3-4 months and GPU hw doesn't exactly have a lifetime in years) and consign them to using closed drivers for longer than necessary. The changes are well contained and just plug into the driver new gpu functionality so they should be fairly regression proof. I just want to give them a bit of a run on the hw AMD kindly sent me. b) drm prime/dma-buf interface code. This is just infrastructure code to expose the dma-buf stuff to drm drivers and to userspace. I'm not planning on pushing any driver support in this cycle (except maybe exynos), but I'd like to get the infrastructure code in so for the next cycle I can start getting the driver support into the individual drivers. We have started driver support for i915, nouveau and udl along with I think exynos and omap in staging. However this code relies on the dma-buf tree being pulled into your tree first since it needs the latest interfaces from that tree. I'll push to get that tree sent asap. (oh and any warnings you see in i915 are gcc's fault from what anyone can see)." Fix up trivial conflicts in arch/x86/platform/mrst/mrst.c due to the new msic_thermal_platform_data() thermal function being added next to the tc35876x_platform_data() i2c device function.. * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (326 commits) drm/i915: use DDC_ADDR instead of hard-coding it drm/radeon: use DDC_ADDR instead of hard-coding it drm: remove unneeded redefinition of DDC_ADDR drm/exynos: added virtual display driver. drm: allow loading an EDID as firmware to override broken monitor drm/exynos: enable hdmi audio feature drm/exynos: add default pixel format for plane drm/exynos: cleanup exynos_hdmi.h drm/exynos: add is_local member in exynos_drm_subdrv struct drm/exynos: add subdrv open/close functions drm/exynos: remove module of exynos drm subdrv drm/exynos: release pending pageflip events when closed drm/exynos: added new funtion to get/put dma address. drm/exynos: update gem and buffer framework. drm/exynos: added mode_fixup feature and code clean. drm/exynos: add HDMI version 1.4 support drm/exynos: remove exynos_mixer.h gma500: Fix mmap frambuffer drm/radeon: Drop radeon_gem_object_(un)pin. drm/radeon: Restrict offset for legacy display engine. ...
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c88
1 files changed, 15 insertions, 73 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index aada26f63dec..7740dd26f007 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -306,91 +306,31 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
306static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; 306static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
307#endif 307#endif
308 308
309static void drm_fb_helper_on(struct fb_info *info) 309static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
310{ 310{
311 struct drm_fb_helper *fb_helper = info->par; 311 struct drm_fb_helper *fb_helper = info->par;
312 struct drm_device *dev = fb_helper->dev; 312 struct drm_device *dev = fb_helper->dev;
313 struct drm_crtc *crtc; 313 struct drm_crtc *crtc;
314 struct drm_crtc_helper_funcs *crtc_funcs;
315 struct drm_connector *connector;
316 struct drm_encoder *encoder;
317 int i, j;
318
319 /*
320 * For each CRTC in this fb, turn the crtc on then,
321 * find all associated encoders and turn them on.
322 */
323 mutex_lock(&dev->mode_config.mutex);
324 for (i = 0; i < fb_helper->crtc_count; i++) {
325 crtc = fb_helper->crtc_info[i].mode_set.crtc;
326 crtc_funcs = crtc->helper_private;
327
328 if (!crtc->enabled)
329 continue;
330
331 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
332
333 /* Walk the connectors & encoders on this fb turning them on */
334 for (j = 0; j < fb_helper->connector_count; j++) {
335 connector = fb_helper->connector_info[j]->connector;
336 connector->dpms = DRM_MODE_DPMS_ON;
337 drm_connector_property_set_value(connector,
338 dev->mode_config.dpms_property,
339 DRM_MODE_DPMS_ON);
340 }
341 /* Found a CRTC on this fb, now find encoders */
342 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
343 if (encoder->crtc == crtc) {
344 struct drm_encoder_helper_funcs *encoder_funcs;
345
346 encoder_funcs = encoder->helper_private;
347 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
348 }
349 }
350 }
351 mutex_unlock(&dev->mode_config.mutex);
352}
353
354static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
355{
356 struct drm_fb_helper *fb_helper = info->par;
357 struct drm_device *dev = fb_helper->dev;
358 struct drm_crtc *crtc;
359 struct drm_crtc_helper_funcs *crtc_funcs;
360 struct drm_connector *connector; 314 struct drm_connector *connector;
361 struct drm_encoder *encoder;
362 int i, j; 315 int i, j;
363 316
364 /* 317 /*
365 * For each CRTC in this fb, find all associated encoders 318 * For each CRTC in this fb, turn the connectors on/off.
366 * and turn them off, then turn off the CRTC.
367 */ 319 */
368 mutex_lock(&dev->mode_config.mutex); 320 mutex_lock(&dev->mode_config.mutex);
369 for (i = 0; i < fb_helper->crtc_count; i++) { 321 for (i = 0; i < fb_helper->crtc_count; i++) {
370 crtc = fb_helper->crtc_info[i].mode_set.crtc; 322 crtc = fb_helper->crtc_info[i].mode_set.crtc;
371 crtc_funcs = crtc->helper_private;
372 323
373 if (!crtc->enabled) 324 if (!crtc->enabled)
374 continue; 325 continue;
375 326
376 /* Walk the connectors on this fb and mark them off */ 327 /* Walk the connectors & encoders on this fb turning them on/off */
377 for (j = 0; j < fb_helper->connector_count; j++) { 328 for (j = 0; j < fb_helper->connector_count; j++) {
378 connector = fb_helper->connector_info[j]->connector; 329 connector = fb_helper->connector_info[j]->connector;
379 connector->dpms = dpms_mode; 330 drm_helper_connector_dpms(connector, dpms_mode);
380 drm_connector_property_set_value(connector, 331 drm_connector_property_set_value(connector,
381 dev->mode_config.dpms_property, 332 dev->mode_config.dpms_property, dpms_mode);
382 dpms_mode);
383 }
384 /* Found a CRTC on this fb, now find encoders */
385 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
386 if (encoder->crtc == crtc) {
387 struct drm_encoder_helper_funcs *encoder_funcs;
388
389 encoder_funcs = encoder->helper_private;
390 encoder_funcs->dpms(encoder, dpms_mode);
391 }
392 } 333 }
393 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
394 } 334 }
395 mutex_unlock(&dev->mode_config.mutex); 335 mutex_unlock(&dev->mode_config.mutex);
396} 336}
@@ -400,23 +340,23 @@ int drm_fb_helper_blank(int blank, struct fb_info *info)
400 switch (blank) { 340 switch (blank) {
401 /* Display: On; HSync: On, VSync: On */ 341 /* Display: On; HSync: On, VSync: On */
402 case FB_BLANK_UNBLANK: 342 case FB_BLANK_UNBLANK:
403 drm_fb_helper_on(info); 343 drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON);
404 break; 344 break;
405 /* Display: Off; HSync: On, VSync: On */ 345 /* Display: Off; HSync: On, VSync: On */
406 case FB_BLANK_NORMAL: 346 case FB_BLANK_NORMAL:
407 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); 347 drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
408 break; 348 break;
409 /* Display: Off; HSync: Off, VSync: On */ 349 /* Display: Off; HSync: Off, VSync: On */
410 case FB_BLANK_HSYNC_SUSPEND: 350 case FB_BLANK_HSYNC_SUSPEND:
411 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); 351 drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
412 break; 352 break;
413 /* Display: Off; HSync: On, VSync: Off */ 353 /* Display: Off; HSync: On, VSync: Off */
414 case FB_BLANK_VSYNC_SUSPEND: 354 case FB_BLANK_VSYNC_SUSPEND:
415 drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND); 355 drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND);
416 break; 356 break;
417 /* Display: Off; HSync: Off, VSync: Off */ 357 /* Display: Off; HSync: Off, VSync: Off */
418 case FB_BLANK_POWERDOWN: 358 case FB_BLANK_POWERDOWN:
419 drm_fb_helper_off(info, DRM_MODE_DPMS_OFF); 359 drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF);
420 break; 360 break;
421 } 361 }
422 return 0; 362 return 0;
@@ -430,8 +370,11 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
430 for (i = 0; i < helper->connector_count; i++) 370 for (i = 0; i < helper->connector_count; i++)
431 kfree(helper->connector_info[i]); 371 kfree(helper->connector_info[i]);
432 kfree(helper->connector_info); 372 kfree(helper->connector_info);
433 for (i = 0; i < helper->crtc_count; i++) 373 for (i = 0; i < helper->crtc_count; i++) {
434 kfree(helper->crtc_info[i].mode_set.connectors); 374 kfree(helper->crtc_info[i].mode_set.connectors);
375 if (helper->crtc_info[i].mode_set.mode)
376 drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
377 }
435 kfree(helper->crtc_info); 378 kfree(helper->crtc_info);
436} 379}
437 380
@@ -474,11 +417,10 @@ int drm_fb_helper_init(struct drm_device *dev,
474 417
475 i = 0; 418 i = 0;
476 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 419 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
477 fb_helper->crtc_info[i].crtc_id = crtc->base.id;
478 fb_helper->crtc_info[i].mode_set.crtc = crtc; 420 fb_helper->crtc_info[i].mode_set.crtc = crtc;
479 i++; 421 i++;
480 } 422 }
481 fb_helper->conn_limit = max_conn_count; 423
482 return 0; 424 return 0;
483out_free: 425out_free:
484 drm_fb_helper_crtc_free(fb_helper); 426 drm_fb_helper_crtc_free(fb_helper);