drm/amd/amdgpu: S4 issue for amdgpu (v2)
authorjimqu <Jim.Qu@amd.com>
Wed, 7 Sep 2016 09:09:12 +0000 (17:09 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 12 Sep 2016 22:12:18 +0000 (18:12 -0400)
reset the asic if adapter is not powerdown when doing freeze()
thaw() and restore(), in order to get a valid state of adapter.

v2: squash in warning fix from Rex

Signed-off-by: JimQu <Jim.Qu@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Tested By: Shawn Starr <shawn.starr@rogers.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c

index 1aa0364d79617ac85c141a06d15eb8cb312e3791..d324a079fe9b5b983f602ddcd716ec2cb0ba6ae7 100644 (file)
@@ -1895,6 +1895,10 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
                /* Shut down the device */
                pci_disable_device(dev->pdev);
                pci_set_power_state(dev->pdev, PCI_D3hot);
+       } else {
+               r = amdgpu_asic_reset(adev);
+               if (r)
+                       DRM_ERROR("amdgpu asic reset failed\n");
        }
 
        if (fbcon) {
@@ -1925,22 +1929,26 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
            dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
                return 0;
 
-       if (fbcon) {
+       if (fbcon)
                console_lock();
-       }
+
        if (resume) {
                pci_set_power_state(dev->pdev, PCI_D0);
                pci_restore_state(dev->pdev);
-               if (pci_enable_device(dev->pdev)) {
+               r = pci_enable_device(dev->pdev);
+               if (r) {
                        if (fbcon)
                                console_unlock();
-                       return -1;
+                       return r;
                }
        }
 
        /* post card */
-       if (!amdgpu_card_posted(adev))
-               amdgpu_atom_asic_init(adev->mode_info.atom_context);
+       if (!amdgpu_card_posted(adev) || !resume) {
+               r = amdgpu_atom_asic_init(adev->mode_info.atom_context);
+               if (r)
+                       DRM_ERROR("amdgpu asic init failed\n");
+       }
 
        r = amdgpu_resume(adev);
        if (r)
index ea54e304478781d67f1cf8ddc753534044535ded..3bbc0faf48c8a464f021a565d7e63d795aa248d6 100644 (file)
@@ -487,6 +487,7 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
 static int amdgpu_pmops_suspend(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
+
        struct drm_device *drm_dev = pci_get_drvdata(pdev);
        return amdgpu_device_suspend(drm_dev, true, true);
 }
@@ -509,6 +510,7 @@ static int amdgpu_pmops_resume(struct device *dev)
 static int amdgpu_pmops_freeze(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
+
        struct drm_device *drm_dev = pci_get_drvdata(pdev);
        return amdgpu_device_suspend(drm_dev, false, true);
 }
@@ -516,6 +518,23 @@ static int amdgpu_pmops_freeze(struct device *dev)
 static int amdgpu_pmops_thaw(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
+
+       struct drm_device *drm_dev = pci_get_drvdata(pdev);
+       return amdgpu_device_resume(drm_dev, false, true);
+}
+
+static int amdgpu_pmops_poweroff(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+
+       struct drm_device *drm_dev = pci_get_drvdata(pdev);
+       return amdgpu_device_suspend(drm_dev, true, true);
+}
+
+static int amdgpu_pmops_restore(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+
        struct drm_device *drm_dev = pci_get_drvdata(pdev);
        return amdgpu_device_resume(drm_dev, false, true);
 }
@@ -622,8 +641,8 @@ static const struct dev_pm_ops amdgpu_pm_ops = {
        .resume = amdgpu_pmops_resume,
        .freeze = amdgpu_pmops_freeze,
        .thaw = amdgpu_pmops_thaw,
-       .poweroff = amdgpu_pmops_freeze,
-       .restore = amdgpu_pmops_resume,
+       .poweroff = amdgpu_pmops_poweroff,
+       .restore = amdgpu_pmops_restore,
        .runtime_suspend = amdgpu_pmops_runtime_suspend,
        .runtime_resume = amdgpu_pmops_runtime_resume,
        .runtime_idle = amdgpu_pmops_runtime_idle,