| From a5c204b1e398d925745791dac2b8fea47f38f6c4 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 16 Oct 2020 10:45:26 +0800 |
| Subject: drm/amd/pm: perform SMC reset on suspend/hibernation |
| |
| From: Evan Quan <evan.quan@amd.com> |
| |
| [ Upstream commit 277b080f98803cb73a83fb234f0be83a10e63958 ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| .../gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 4 ++++ |
| drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 1 + |
| drivers/gpu/drm/amd/powerplay/inc/smumgr.h | 2 ++ |
| .../gpu/drm/amd/powerplay/smumgr/ci_smumgr.c | 24 +++++++++++++++++++ |
| drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | 8 +++++++ |
| 5 files changed, 39 insertions(+) |
| |
| diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c |
| index fc63d9e32e1f8..c8ee931075e52 100644 |
| --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c |
| +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c |
| @@ -1541,6 +1541,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); |
| diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h |
| index 15ed6cbdf3660..91cdc53472f01 100644 |
| --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h |
| +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h |
| @@ -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 { |
| diff --git a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h |
| index ad100b533d049..5f46f1a4f38ef 100644 |
| --- a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h |
| +++ b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h |
| @@ -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 |
| diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c |
| index e4d1f3d66ef48..09128122b4932 100644 |
| --- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c |
| +++ b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c |
| @@ -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, |
| }; |
| diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c |
| index b6fb480668416..b6921db3c1305 100644 |
| --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c |
| +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c |
| @@ -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; |
| +} |
| -- |
| 2.27.0 |
| |