aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-11-09 00:18:47 -0500
committerBen Skeggs <bskeggs@redhat.com>2011-12-21 04:01:35 -0500
commitf62b27db6b5479efe376b408802a081a834ef50e (patch)
treecb8a21800e7996f58e2e68027228bc3c071572f1 /drivers/gpu/drm/nouveau
parent1772fcc6f8af681a6e08f5cca15e86e710efe809 (diff)
drm/nouveau: shutdown display on suspend/hibernate
Known to fix some serious issues with hibernate on a couple of systems. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c42
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c6
4 files changed, 45 insertions, 11 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 803248d467f..6ac6931624f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -207,6 +207,31 @@ static struct drm_prop_enum_list dither_depth[] = {
207} while(0) 207} while(0)
208 208
209int 209int
210nouveau_display_init(struct drm_device *dev)
211{
212 struct drm_nouveau_private *dev_priv = dev->dev_private;
213 struct nouveau_display_engine *disp = &dev_priv->engine.display;
214 int ret;
215
216 ret = disp->init(dev);
217 if (ret == 0) {
218 drm_kms_helper_poll_enable(dev);
219 }
220
221 return ret;
222}
223
224void
225nouveau_display_fini(struct drm_device *dev)
226{
227 struct drm_nouveau_private *dev_priv = dev->dev_private;
228 struct nouveau_display_engine *disp = &dev_priv->engine.display;
229
230 drm_kms_helper_poll_disable(dev);
231 disp->fini(dev);
232}
233
234int
210nouveau_display_create(struct drm_device *dev) 235nouveau_display_create(struct drm_device *dev)
211{ 236{
212 struct drm_nouveau_private *dev_priv = dev->dev_private; 237 struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -258,13 +283,19 @@ nouveau_display_create(struct drm_device *dev)
258 dev->mode_config.max_height = 8192; 283 dev->mode_config.max_height = 8192;
259 } 284 }
260 285
286 drm_kms_helper_poll_init(dev);
287 drm_kms_helper_poll_disable(dev);
288
261 ret = disp->create(dev); 289 ret = disp->create(dev);
262 if (ret) 290 if (ret)
263 return ret; 291 return ret;
264 292
265 ret = disp->init(dev); 293 if (dev->mode_config.num_crtc) {
266 if (ret) 294 ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
267 disp->destroy(dev); 295 if (ret)
296 return ret;
297 }
298
268 return ret; 299 return ret;
269} 300}
270 301
@@ -274,8 +305,11 @@ nouveau_display_destroy(struct drm_device *dev)
274 struct drm_nouveau_private *dev_priv = dev->dev_private; 305 struct drm_nouveau_private *dev_priv = dev->dev_private;
275 struct nouveau_display_engine *disp = &dev_priv->engine.display; 306 struct nouveau_display_engine *disp = &dev_priv->engine.display;
276 307
277 disp->fini(dev); 308 drm_vblank_cleanup(dev);
309
278 disp->destroy(dev); 310 disp->destroy(dev);
311
312 drm_kms_helper_poll_fini(dev);
279 drm_mode_config_cleanup(dev); 313 drm_mode_config_cleanup(dev);
280} 314}
281 315
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index cb357ab3670..e4485404892 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -178,7 +178,8 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
178 if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 178 if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
179 return 0; 179 return 0;
180 180
181 drm_kms_helper_poll_disable(dev); 181 NV_INFO(dev, "Disabling display...\n");
182 nouveau_display_fini(dev);
182 183
183 NV_INFO(dev, "Disabling fbcon...\n"); 184 NV_INFO(dev, "Disabling fbcon...\n");
184 nouveau_fbcon_set_suspend(dev, 1); 185 nouveau_fbcon_set_suspend(dev, 1);
@@ -357,8 +358,7 @@ nouveau_pci_resume(struct pci_dev *pdev)
357 nouveau_fbcon_set_suspend(dev, 0); 358 nouveau_fbcon_set_suspend(dev, 0);
358 nouveau_fbcon_zfill_all(dev); 359 nouveau_fbcon_zfill_all(dev);
359 360
360 engine->display.init(dev); 361 nouveau_display_init(dev);
361 drm_kms_helper_poll_enable(dev);
362 362
363 /* Force CLUT to get re-loaded during modeset */ 363 /* Force CLUT to get re-loaded during modeset */
364 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 364 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index a22ca473594..c1391858803 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1449,6 +1449,8 @@ extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
1449/* nouveau_display.c */ 1449/* nouveau_display.c */
1450int nouveau_display_create(struct drm_device *dev); 1450int nouveau_display_create(struct drm_device *dev);
1451void nouveau_display_destroy(struct drm_device *dev); 1451void nouveau_display_destroy(struct drm_device *dev);
1452int nouveau_display_init(struct drm_device *dev);
1453void nouveau_display_fini(struct drm_device *dev);
1452int nouveau_vblank_enable(struct drm_device *dev, int crtc); 1454int nouveau_vblank_enable(struct drm_device *dev, int crtc);
1453void nouveau_vblank_disable(struct drm_device *dev, int crtc); 1455void nouveau_vblank_disable(struct drm_device *dev, int crtc);
1454int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 1456int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 0c3368b36e6..013b33bac30 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -763,12 +763,11 @@ nouveau_card_init(struct drm_device *dev)
763 } 763 }
764 764
765 if (dev->mode_config.num_crtc) { 765 if (dev->mode_config.num_crtc) {
766 ret = drm_vblank_init(dev, dev->mode_config.num_crtc); 766 ret = nouveau_display_init(dev);
767 if (ret) 767 if (ret)
768 goto out_chan; 768 goto out_chan;
769 769
770 nouveau_fbcon_init(dev); 770 nouveau_fbcon_init(dev);
771 drm_kms_helper_poll_init(dev);
772 } 771 }
773 772
774 return 0; 773 return 0;
@@ -829,9 +828,8 @@ static void nouveau_card_takedown(struct drm_device *dev)
829 int e; 828 int e;
830 829
831 if (dev->mode_config.num_crtc) { 830 if (dev->mode_config.num_crtc) {
832 drm_kms_helper_poll_fini(dev);
833 nouveau_fbcon_fini(dev); 831 nouveau_fbcon_fini(dev);
834 drm_vblank_cleanup(dev); 832 nouveau_display_fini(dev);
835 } 833 }
836 834
837 if (dev_priv->channel) { 835 if (dev_priv->channel) {