diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-11-09 15:18:47 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-12-21 19:01:35 +1000 |
commit | f62b27db6b5479efe376b408802a081a834ef50e (patch) | |
tree | cb8a21800e7996f58e2e68027228bc3c071572f1 /drivers | |
parent | 1772fcc6f8af681a6e08f5cca15e86e710efe809 (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')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 6 |
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 803248d467fb..6ac6931624f4 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[] = { } while(0) int +nouveau_display_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_display_engine *disp = &dev_priv->engine.display; + int ret; + + ret = disp->init(dev); + if (ret == 0) { + drm_kms_helper_poll_enable(dev); + } + + return ret; +} + +void +nouveau_display_fini(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_display_engine *disp = &dev_priv->engine.display; + + drm_kms_helper_poll_disable(dev); + disp->fini(dev); +} + +int nouveau_display_create(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -258,13 +283,19 @@ nouveau_display_create(struct drm_device *dev) dev->mode_config.max_height = 8192; } + drm_kms_helper_poll_init(dev); + drm_kms_helper_poll_disable(dev); + ret = disp->create(dev); if (ret) return ret; - ret = disp->init(dev); - if (ret) - disp->destroy(dev); + if (dev->mode_config.num_crtc) { + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); + if (ret) + return ret; + } + return ret; } @@ -274,8 +305,11 @@ nouveau_display_destroy(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_display_engine *disp = &dev_priv->engine.display; - disp->fini(dev); + drm_vblank_cleanup(dev); + disp->destroy(dev); + + drm_kms_helper_poll_fini(dev); drm_mode_config_cleanup(dev); } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index cb357ab3670c..e4485404892e 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) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - drm_kms_helper_poll_disable(dev); + NV_INFO(dev, "Disabling display...\n"); + nouveau_display_fini(dev); NV_INFO(dev, "Disabling fbcon...\n"); nouveau_fbcon_set_suspend(dev, 1); @@ -357,8 +358,7 @@ nouveau_pci_resume(struct pci_dev *pdev) nouveau_fbcon_set_suspend(dev, 0); nouveau_fbcon_zfill_all(dev); - engine->display.init(dev); - drm_kms_helper_poll_enable(dev); + nouveau_display_init(dev); /* Force CLUT to get re-loaded during modeset */ 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 a22ca4735943..c13918588034 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 *, /* nouveau_display.c */ int nouveau_display_create(struct drm_device *dev); void nouveau_display_destroy(struct drm_device *dev); +int nouveau_display_init(struct drm_device *dev); +void nouveau_display_fini(struct drm_device *dev); int nouveau_vblank_enable(struct drm_device *dev, int crtc); void nouveau_vblank_disable(struct drm_device *dev, int crtc); int 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 0c3368b36e6c..013b33bac302 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) } if (dev->mode_config.num_crtc) { - ret = drm_vblank_init(dev, dev->mode_config.num_crtc); + ret = nouveau_display_init(dev); if (ret) goto out_chan; nouveau_fbcon_init(dev); - drm_kms_helper_poll_init(dev); } return 0; @@ -829,9 +828,8 @@ static void nouveau_card_takedown(struct drm_device *dev) int e; if (dev->mode_config.num_crtc) { - drm_kms_helper_poll_fini(dev); nouveau_fbcon_fini(dev); - drm_vblank_cleanup(dev); + nouveau_display_fini(dev); } if (dev_priv->channel) { |