OSDN Git Service

drm/amd/powerplay: fix checking gfxoff status for rn
authorAaron Liu <aaron.liu@amd.com>
Fri, 26 Jul 2019 02:51:32 +0000 (10:51 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 22 Aug 2019 22:37:42 +0000 (17:37 -0500)
For renoir, it should use mmSMUIO_GFX_MISC_CNTL to check
gfxoff status. For the first time to enter gfxoff status,
it maybe takes about one second more. So just set the max
timeout to 5s.

GFXOFF_STATUS(bits 2:1)'s description is below:
0=GFXOFF(default).
1=Transition out of GFX State.
2=Not in GFXOFF.
3=Transition into GFXOFF.

Reviewed-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Evan Quan <evan.quan@amd.com>
Signed-off-by: Aaron Liu <aaron.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/powerplay/smu_v12_0.c

index 7d4e966..363a5a7 100644 (file)
 
 #define smnMP1_FIRMWARE_FLAGS                                0x3010024
 
-#define mmPWR_MISC_CNTL_STATUS                                 0x0183
-#define mmPWR_MISC_CNTL_STATUS_BASE_IDX                                0
-#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT       0x0
-#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT         0x1
-#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK         0x00000001L
-#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK           0x00000006L
+#define mmSMUIO_GFX_MISC_CNTL                                0x00c8
+#define mmSMUIO_GFX_MISC_CNTL_BASE_IDX                       0
+#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS_MASK          0x00000006L
+#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS__SHIFT        0x1
 
 static int smu_v12_0_send_msg_without_waiting(struct smu_context *smu,
                                              uint16_t msg)
@@ -214,30 +212,52 @@ static int smu_v12_0_set_gfx_cgpg(struct smu_context *smu, bool enable)
                SMU_MSG_SetGfxCGPG, enable ? 1 : 0);
 }
 
-static bool smu_v12_0_is_gfx_on(struct smu_context *smu)
+/**
+ * smu_v12_0_get_gfxoff_status - get gfxoff status
+ *
+ * @smu: amdgpu_device pointer
+ *
+ * This function will be used to get gfxoff status
+ *
+ * Returns 0=GFXOFF(default).
+ * Returns 1=Transition out of GFX State.
+ * Returns 2=Not in GFXOFF.
+ * Returns 3=Transition into GFXOFF.
+ */
+static uint32_t smu_v12_0_get_gfxoff_status(struct smu_context *smu)
 {
        uint32_t reg;
+       uint32_t gfxOff_Status = 0;
        struct amdgpu_device *adev = smu->adev;
 
-       reg = RREG32_SOC15(PWR, 0, mmPWR_MISC_CNTL_STATUS);
-       if ((reg & PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK) ==
-           (0x2 << PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT))
-               return true;
+       reg = RREG32_SOC15(SMUIO, 0, mmSMUIO_GFX_MISC_CNTL);
+       gfxOff_Status = (reg & SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS_MASK)
+               >> SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS__SHIFT;
 
-       return false;
+       return gfxOff_Status;
 }
 
 static int smu_v12_0_gfx_off_control(struct smu_context *smu, bool enable)
 {
-       int ret = 0, timeout = 10;
+       int ret = 0, timeout = 500;
 
        if (enable) {
                ret = smu_send_smc_msg(smu, SMU_MSG_AllowGfxOff);
+
+               /* confirm gfx is back to "off" state, timeout is 5 seconds */
+               while (!(smu_v12_0_get_gfxoff_status(smu) == 0)) {
+                       msleep(10);
+                       timeout--;
+                       if (timeout == 0) {
+                               DRM_ERROR("enable gfxoff timeout and failed!\n");
+                               break;
+                       }
+               }
        } else {
                ret = smu_send_smc_msg(smu, SMU_MSG_DisallowGfxOff);
 
-               /* confirm gfx is back to "on" state */
-               while (!smu_v12_0_is_gfx_on(smu)) {
+               /* confirm gfx is back to "on" state, timeout is 0.5 second */
+               while (!(smu_v12_0_get_gfxoff_status(smu) == 2)) {
                        msleep(1);
                        timeout--;
                        if (timeout == 0) {