From 094e0fa8b96c9fab5df9597e728d82f3d87ee471 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 5 Oct 2010 12:43:00 +0200 Subject: drm/vmwgfx: Fix ACPI S3 & S4 functionality. Don't suspend or hibernate when there are 3D resources active since we can't restore the device's 3D state. Instead fail with an error message. In other cases, make sure we re-enable the fifo and unlock ttm on resume. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 38 +++++++++++++++++++++++++++++++++++-- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 + 2 files changed, 37 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/vmwgfx') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 5c845b6ec492..91eeade92124 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -751,15 +751,40 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, * Buffer contents is moved to swappable memory. */ ttm_bo_swapout_all(&dev_priv->bdev); + + /** + * Release 3d reference held by fbdev and potentially + * stop fifo. + */ + dev_priv->suspended = true; + if (dev_priv->enable_fb) + vmw_3d_resource_dec(dev_priv); + break; case PM_POST_HIBERNATION: case PM_POST_SUSPEND: + case PM_POST_RESTORE: + if (!dev_priv->suspended) { + printk(KERN_WARNING + "[%s] Driver is not suspended at resume" + " point.\n", VMWGFX_DRIVER_NAME); + + break; + } + + /** + * Reclaim 3d reference held by fbdev and potentially + * start fifo. + */ + if (dev_priv->enable_fb) + vmw_3d_resource_inc(dev_priv); + + dev_priv->suspended = false; ttm_suspend_unlock(&vmaster->lock); + break; case PM_RESTORE_PREPARE: break; - case PM_POST_RESTORE: - break; default: break; } @@ -772,6 +797,15 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state) { + struct drm_device *dev = pci_get_drvdata(pdev); + struct vmw_private *dev_priv = vmw_priv(dev); + + if (dev_priv->num_3d_resources != 0) { + DRM_INFO("Can't suspend or hibernate " + "while 3D resources are active.\n"); + return -EBUSY; + } + pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 58de6393f611..132cc248d229 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -286,6 +286,7 @@ struct vmw_private { struct vmw_master *active_master; struct vmw_master fbdev_master; struct notifier_block pm_nb; + bool suspended; struct mutex release_mutex; uint32_t num_3d_resources; -- cgit v1.2.1