Please ignore this patch. I will re-submit patch with better solution.

-----Original Message-----
From: Yintian Tao [mailto:yt...@amd.com] 
Sent: Wednesday, August 22, 2018 2:50 PM
To: amd-gfx@lists.freedesktop.org
Cc: Tao, Yintian <yintian....@amd.com>
Subject: [PATCH] drm/amdgpu: move set pg&cg state to suspend phase2

Under virtualization, We have to require full-acess gpu at suspend phase2 due 
to some special register access. In order to guarantee it, we should move set 
pg and cg state to suspend
phase2 to make registers access at one full-acess lifecycle.

Signed-off-by: Yintian Tao <yt...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 42 ++++++++++++++++++++++--------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index c9557d9..2d95769 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1713,10 +1713,11 @@ static int amdgpu_device_set_cg_state(struct 
amdgpu_device *adev,
                i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 
1;
                if (!adev->ip_blocks[i].status.valid)
                        continue;
-               /* skip CG for VCE/UVD, it's handled specially */
+               /* skip CG for VCE/UVD and DCE, it's handled specially */
                if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
                    adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE &&
                    adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCN &&
+                   adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_DCE &&
                    adev->ip_blocks[i].version->funcs->set_clockgating_state) {
                        /* enable clockgating to save power */
                        r = 
adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, @@ 
-1743,10 +1744,11 @@ static int amdgpu_device_set_pg_state(struct amdgpu_device 
*adev, enum amd_power
                i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 
1;
                if (!adev->ip_blocks[i].status.valid)
                        continue;
-               /* skip CG for VCE/UVD, it's handled specially */
+               /* skip CG for VCE/UVD and DCE, it's handled specially */
                if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
                    adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE &&
                    adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCN &&
+                   adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_DCE &&
                    adev->ip_blocks[i].version->funcs->set_powergating_state) {
                        /* enable powergating to save power */
                        r = 
adev->ip_blocks[i].version->funcs->set_powergating_state((void *)adev, @@ 
-1932,17 +1934,29 @@ static int amdgpu_device_ip_suspend_phase1(struct 
amdgpu_device *adev)  {
        int i, r;
 
-       if (amdgpu_sriov_vf(adev))
-               amdgpu_virt_request_full_gpu(adev, false);
-
-       amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
-       amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
-
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
                if (!adev->ip_blocks[i].status.valid)
                        continue;
                /* displays are handled separately */
                if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) {
+                       if 
(adev->ip_blocks[i].version->funcs->set_powergating_state) {
+                               r = 
adev->ip_blocks[i].version->funcs->set_powergating_state((void *)adev,
+                                                                               
             AMD_PG_STATE_UNGATE);
+                               if (r) {
+                                       DRM_ERROR("set_powergating_state(gate) 
of IP block <%s> failed %d\n",
+                                                 
adev->ip_blocks[i].version->funcs->name, r);
+                                       return r;
+                               }
+                       }
+                       /* ungate blocks so that suspend can properly shut them 
down */
+                       if 
(adev->ip_blocks[i].version->funcs->set_clockgating_state) {
+                               r = 
adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
+                                                                               
             AMD_CG_STATE_UNGATE);
+                               if (r) {
+                                       
DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n",
+                                                 
adev->ip_blocks[i].version->funcs->name, r);
+                               }
+                       }
                        /* XXX handle errors */
                        r = adev->ip_blocks[i].version->funcs->suspend(adev);
                        /* XXX handle errors */
@@ -1953,9 +1967,6 @@ static int amdgpu_device_ip_suspend_phase1(struct 
amdgpu_device *adev)
                }
        }
 
-       if (amdgpu_sriov_vf(adev))
-               amdgpu_virt_release_full_gpu(adev, false);
-
        return 0;
 }
 
@@ -1974,6 +1985,12 @@ static int amdgpu_device_ip_suspend_phase2(struct 
amdgpu_device *adev)  {
        int i, r;
 
+       if (amdgpu_sriov_vf(adev))
+               amdgpu_virt_request_full_gpu(adev, false);
+
+       amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
+       amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
+
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
                if (!adev->ip_blocks[i].status.valid)
                        continue;
@@ -1989,6 +2006,9 @@ static int amdgpu_device_ip_suspend_phase2(struct 
amdgpu_device *adev)
                }
        }
 
+       if (amdgpu_sriov_vf(adev))
+               amdgpu_virt_release_full_gpu(adev, false);
+
        return 0;
 }
 
--
2.7.4

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to