drm/amd/pm: perform SMC reset on suspend/hibernation
authorEvan Quan <evan.quan@amd.com>
Fri, 16 Oct 2020 02:45:26 +0000 (10:45 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 30 Oct 2020 05:00:43 +0000 (01:00 -0400)
So that the succeeding resume can be performed based on
a clean state.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Tested-by: Sandeep Raghuraman <sandy.8925@gmail.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/pm/inc/hwmgr.h
drivers/gpu/drm/amd/pm/inc/smumgr.h
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c
drivers/gpu/drm/amd/pm/powerplay/smumgr/smumgr.c

index 0e4707a76f6d30dee343c0a538bab4be05c26ea1..7e29ec2902dc4071b2b1608f177e70b861f874c0 100644 (file)
@@ -229,6 +229,7 @@ struct pp_smumgr_func {
        bool (*is_hw_avfs_present)(struct pp_hwmgr  *hwmgr);
        int (*update_dpm_settings)(struct pp_hwmgr *hwmgr, void *profile_setting);
        int (*smc_table_manager)(struct pp_hwmgr *hwmgr, uint8_t *table, uint16_t table_id, bool rw); /*rw: true for read, false for write */
+       int (*stop_smc)(struct pp_hwmgr *hwmgr);
 };
 
 struct pp_hwmgr_func {
index ad100b533d0496c8f4f4c5be28c3ced01692208b..5f46f1a4f38efa357e9afd450642dbc47c583e96 100644 (file)
@@ -113,4 +113,6 @@ extern int smum_update_dpm_settings(struct pp_hwmgr *hwmgr, void *profile_settin
 
 extern int smum_smc_table_manager(struct pp_hwmgr *hwmgr, uint8_t *table, uint16_t table_id, bool rw);
 
+extern int smum_stop_smc(struct pp_hwmgr *hwmgr);
+
 #endif
index 49db61a89505aa011f8f6163e882b8053c521cb9..6d2f13dc900e45c8edd27b9e399e37c29e14935a 100644 (file)
@@ -1667,6 +1667,10 @@ static int smu7_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
        PP_ASSERT_WITH_CODE((tmp_result == 0),
                        "Failed to reset to default!", result = tmp_result);
 
+       tmp_result = smum_stop_smc(hwmgr);
+       PP_ASSERT_WITH_CODE((tmp_result == 0),
+                       "Failed to stop smc!", result = tmp_result);
+
        tmp_result = smu7_force_switch_to_arbf0(hwmgr);
        PP_ASSERT_WITH_CODE((tmp_result == 0),
                        "Failed to force to switch arbf0!", result = tmp_result);
index e4d1f3d66ef4888fe4a9d2add1fe240db14731d0..09128122b493265001a20882c542462bfa56d9fd 100644 (file)
@@ -2939,6 +2939,29 @@ static int ci_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type)
        return 0;
 }
 
+static void ci_reset_smc(struct pp_hwmgr *hwmgr)
+{
+       PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+                                 SMC_SYSCON_RESET_CNTL,
+                                 rst_reg, 1);
+}
+
+
+static void ci_stop_smc_clock(struct pp_hwmgr *hwmgr)
+{
+       PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+                                 SMC_SYSCON_CLOCK_CNTL_0,
+                                 ck_disable, 1);
+}
+
+static int ci_stop_smc(struct pp_hwmgr *hwmgr)
+{
+       ci_reset_smc(hwmgr);
+       ci_stop_smc_clock(hwmgr);
+
+       return 0;
+}
+
 const struct pp_smumgr_func ci_smu_funcs = {
        .name = "ci_smu",
        .smu_init = ci_smu_init,
@@ -2964,4 +2987,5 @@ const struct pp_smumgr_func ci_smu_funcs = {
        .is_dpm_running = ci_is_dpm_running,
        .update_dpm_settings = ci_update_dpm_settings,
        .update_smc_table = ci_update_smc_table,
+       .stop_smc = ci_stop_smc,
 };
index b6fb480668416a92892f5e6d85122d0a5ac2eb8b..b6921db3c1305988ff974e34352e4d49264f8193 100644 (file)
@@ -245,3 +245,11 @@ int smum_smc_table_manager(struct pp_hwmgr *hwmgr, uint8_t *table, uint16_t tabl
 
        return -EINVAL;
 }
+
+int smum_stop_smc(struct pp_hwmgr *hwmgr)
+{
+       if (hwmgr->smumgr_funcs->stop_smc)
+               return hwmgr->smumgr_funcs->stop_smc(hwmgr);
+
+       return 0;
+}