aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-04-21 17:18:32 -0400
committerDave Airlie <airlied@redhat.com>2011-04-27 03:51:59 -0400
commite8e7a2b8ccfdae0d4cb6bd25824bbedcd42da316 (patch)
tree1b2140075e01d32af330370307004b9b73a9d796
parent6565945b60922211c299968ba66a66617af32c9f (diff)
drm/i915: restore only the mode of this driver on lastclose (v2)
i915 calls the panic handler function on last close to reset the modes, however this is a really bad idea for multi-gpu machines, esp shareable gpus machines. So add a new entry point for the driver to just restore its own fbcon mode. v2: move code into fb helper, fix panic code to block mode change on powered off GPUs. [airlied: this hits drm core and I wrote it and it was reviewed on intel-gfx so really I signed it off twice ;-).] Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c27
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c2
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c10
-rw-r--r--include/drm/drm_fb_helper.h1
5 files changed, 33 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 950720473967..11d7a72c22d9 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -342,9 +342,22 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
342} 342}
343EXPORT_SYMBOL(drm_fb_helper_debug_leave); 343EXPORT_SYMBOL(drm_fb_helper_debug_leave);
344 344
345bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper)
346{
347 bool error = false;
348 int i, ret;
349 for (i = 0; i < fb_helper->crtc_count; i++) {
350 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
351 ret = drm_crtc_helper_set_config(mode_set);
352 if (ret)
353 error = true;
354 }
355 return error;
356}
357EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode);
358
345bool drm_fb_helper_force_kernel_mode(void) 359bool drm_fb_helper_force_kernel_mode(void)
346{ 360{
347 int i = 0;
348 bool ret, error = false; 361 bool ret, error = false;
349 struct drm_fb_helper *helper; 362 struct drm_fb_helper *helper;
350 363
@@ -352,12 +365,12 @@ bool drm_fb_helper_force_kernel_mode(void)
352 return false; 365 return false;
353 366
354 list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { 367 list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
355 for (i = 0; i < helper->crtc_count; i++) { 368 if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF)
356 struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; 369 continue;
357 ret = drm_crtc_helper_set_config(mode_set); 370
358 if (ret) 371 ret = drm_fb_helper_restore_fbdev_mode(helper);
359 error = true; 372 if (ret)
360 } 373 error = true;
361 } 374 }
362 return error; 375 return error;
363} 376}
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 72730377a01b..12876f2795d2 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -2207,7 +2207,7 @@ void i915_driver_lastclose(struct drm_device * dev)
2207 drm_i915_private_t *dev_priv = dev->dev_private; 2207 drm_i915_private_t *dev_priv = dev->dev_private;
2208 2208
2209 if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { 2209 if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) {
2210 drm_fb_helper_restore(); 2210 intel_fb_restore_mode(dev);
2211 vga_switcheroo_process_delayed_switch(); 2211 vga_switcheroo_process_delayed_switch();
2212 return; 2212 return;
2213 } 2213 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f5b0d8306d83..1d20712d527f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -338,4 +338,5 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data,
338 struct drm_file *file_priv); 338 struct drm_file *file_priv);
339 339
340extern void intel_fb_output_poll_changed(struct drm_device *dev); 340extern void intel_fb_output_poll_changed(struct drm_device *dev);
341extern void intel_fb_restore_mode(struct drm_device *dev);
341#endif /* __INTEL_DRV_H__ */ 342#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 512782728e51..ec49bae73382 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -264,3 +264,13 @@ void intel_fb_output_poll_changed(struct drm_device *dev)
264 drm_i915_private_t *dev_priv = dev->dev_private; 264 drm_i915_private_t *dev_priv = dev->dev_private;
265 drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); 265 drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
266} 266}
267
268void intel_fb_restore_mode(struct drm_device *dev)
269{
270 int ret;
271 drm_i915_private_t *dev_priv = dev->dev_private;
272
273 ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
274 if (ret)
275 DRM_DEBUG("failed to restore crtc mode\n");
276}
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index f22e7fe4b6db..ade09d7b4271 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -118,6 +118,7 @@ int drm_fb_helper_setcolreg(unsigned regno,
118 unsigned transp, 118 unsigned transp,
119 struct fb_info *info); 119 struct fb_info *info);
120 120
121bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper);
121void drm_fb_helper_restore(void); 122void drm_fb_helper_restore(void);
122void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, 123void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper,
123 uint32_t fb_width, uint32_t fb_height); 124 uint32_t fb_width, uint32_t fb_height);