RE: [PATCH 2/2] drm/amd/powerplay: enable df cstate control on swSMU routine
Reviewed-by: Kenneth Feng -Original Message- From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf Of Quan, Evan Sent: Thursday, October 10, 2019 11:45 AM To: amd-gfx@lists.freedesktop.org Cc: Quan, Evan Subject: [PATCH 2/2] drm/amd/powerplay: enable df cstate control on swSMU routine [CAUTION: External Email] Currently this is only supported on Vega20 with 40.50 and later SMC firmware. Change-Id: I8397f9ccc5dec32dc86ef7635c5ed227c77e61a3 Signed-off-by: Evan Quan --- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c| 23 + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h| 3 +++ drivers/gpu/drm/amd/powerplay/inc/smu_types.h | 1 + drivers/gpu/drm/amd/powerplay/vega20_ppt.c| 25 ++- 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 054376342454..a37a1b1d8abd 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -1834,6 +1834,29 @@ int smu_set_mp1_state(struct smu_context *smu, return ret; } +int smu_set_df_cstate(struct smu_context *smu, + enum pp_df_cstate state) { + int ret = 0; + + /* +* The SMC is not fully ready. That may be +* expected as the IP may be masked. +* So, just return without error. +*/ + if (!smu->pm_enabled) + return 0; + + if (!smu->ppt_funcs || !smu->ppt_funcs->set_df_cstate) + return 0; + + ret = smu->ppt_funcs->set_df_cstate(smu, state); + if (ret) + pr_err("[SetDfCstate] failed!\n"); + + return ret; +} + const struct amd_ip_funcs smu_ip_funcs = { .name = "smu", .early_init = smu_early_init, diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index ccf711c327c8..401affdee49d 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -468,6 +468,7 @@ struct pptable_funcs { int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default); int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t dpm_level, uint32_t *freq); + int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate + state); }; struct smu_funcs @@ -852,5 +853,7 @@ int smu_force_clk_levels(struct smu_context *smu, uint32_t mask); int smu_set_mp1_state(struct smu_context *smu, enum pp_mp1_state mp1_state); +int smu_set_df_cstate(struct smu_context *smu, + enum pp_df_cstate state); #endif diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_types.h b/drivers/gpu/drm/amd/powerplay/inc/smu_types.h index 12a1de55ce3c..d8c9b7f91fcc 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu_types.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu_types.h @@ -169,6 +169,7 @@ __SMU_DUMMY_MAP(PowerGateAtHub), \ __SMU_DUMMY_MAP(SetSoftMinJpeg), \ __SMU_DUMMY_MAP(SetHardMinFclkByFreq),\ + __SMU_DUMMY_MAP(DFCstateControl), \ #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(type) SMU_MSG_##type diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c index 99effde33ac1..1050566cb69a 100644 --- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c @@ -143,6 +143,7 @@ static struct smu_11_0_cmn2aisc_mapping vega20_message_map[SMU_MSG_MAX_COUNT] = MSG_MAP(PrepareMp1ForShutdown), MSG_MAP(SetMGpuFanBoostLimitRpm), MSG_MAP(GetAVFSVoltageByDpm), + MSG_MAP(DFCstateControl), }; static struct smu_11_0_cmn2aisc_mapping vega20_clk_map[SMU_CLK_COUNT] = { @@ -3135,6 +3136,27 @@ static int vega20_get_thermal_temperature_range(struct smu_context *smu, return 0; } +static int vega20_set_df_cstate(struct smu_context *smu, + enum pp_df_cstate state) { + uint32_t smu_version; + int ret; + + ret = smu_get_smc_version(smu, NULL, _version); + if (ret) { + pr_err("Failed to get smu version!\n"); + return ret; + } + + /* PPSMC_MSG_DFCstateControl is supported with 40.50 and later fws */ + if (smu_version < 0x283200) { + pr_err("Df cstate control is supported with 40.50 and later SMC fw!\n"); + return -EINVAL; + } + + return smu_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, +state); } + static const struct pptable_funcs vega20_ppt_funcs = { .tables_init = vega20_tables_init, .alloc_dpm_context = vega20_allocate_dpm_context, @@ -3177,7 +3199,8 @@ static const struct pptable_funcs vega20_ppt_funcs = {
RE: [PATCH 2/2] drm/amd/powerplay: enable df cstate control on swSMU routine
Yes, we have to toggle DF-C state before/after programming DF Perf counter registers. The series is to provide interface for such case. Regards, Hawking -Original Message- From: amd-gfx On Behalf Of Feng, Kenneth Sent: 2019年10月10日 12:50 To: Quan, Evan ; amd-gfx@lists.freedesktop.org Cc: Quan, Evan Subject: RE: [PATCH 2/2] drm/amd/powerplay: enable df cstate control on swSMU routine Hi Evan, Is there any use case for this interface? Thanks. -Original Message- From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf Of Quan, Evan Sent: Thursday, October 10, 2019 11:45 AM To: amd-gfx@lists.freedesktop.org Cc: Quan, Evan Subject: [PATCH 2/2] drm/amd/powerplay: enable df cstate control on swSMU routine [CAUTION: External Email] Currently this is only supported on Vega20 with 40.50 and later SMC firmware. Change-Id: I8397f9ccc5dec32dc86ef7635c5ed227c77e61a3 Signed-off-by: Evan Quan --- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c| 23 + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h| 3 +++ drivers/gpu/drm/amd/powerplay/inc/smu_types.h | 1 + drivers/gpu/drm/amd/powerplay/vega20_ppt.c| 25 ++- 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 054376342454..a37a1b1d8abd 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -1834,6 +1834,29 @@ int smu_set_mp1_state(struct smu_context *smu, return ret; } +int smu_set_df_cstate(struct smu_context *smu, + enum pp_df_cstate state) { + int ret = 0; + + /* +* The SMC is not fully ready. That may be +* expected as the IP may be masked. +* So, just return without error. +*/ + if (!smu->pm_enabled) + return 0; + + if (!smu->ppt_funcs || !smu->ppt_funcs->set_df_cstate) + return 0; + + ret = smu->ppt_funcs->set_df_cstate(smu, state); + if (ret) + pr_err("[SetDfCstate] failed!\n"); + + return ret; +} + const struct amd_ip_funcs smu_ip_funcs = { .name = "smu", .early_init = smu_early_init, diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index ccf711c327c8..401affdee49d 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -468,6 +468,7 @@ struct pptable_funcs { int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default); int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t dpm_level, uint32_t *freq); + int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate + state); }; struct smu_funcs @@ -852,5 +853,7 @@ int smu_force_clk_levels(struct smu_context *smu, uint32_t mask); int smu_set_mp1_state(struct smu_context *smu, enum pp_mp1_state mp1_state); +int smu_set_df_cstate(struct smu_context *smu, + enum pp_df_cstate state); #endif diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_types.h b/drivers/gpu/drm/amd/powerplay/inc/smu_types.h index 12a1de55ce3c..d8c9b7f91fcc 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu_types.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu_types.h @@ -169,6 +169,7 @@ __SMU_DUMMY_MAP(PowerGateAtHub), \ __SMU_DUMMY_MAP(SetSoftMinJpeg), \ __SMU_DUMMY_MAP(SetHardMinFclkByFreq),\ + __SMU_DUMMY_MAP(DFCstateControl), \ #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(type) SMU_MSG_##type diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c index 99effde33ac1..1050566cb69a 100644 --- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c @@ -143,6 +143,7 @@ static struct smu_11_0_cmn2aisc_mapping vega20_message_map[SMU_MSG_MAX_COUNT] = MSG_MAP(PrepareMp1ForShutdown), MSG_MAP(SetMGpuFanBoostLimitRpm), MSG_MAP(GetAVFSVoltageByDpm), + MSG_MAP(DFCstateControl), }; static struct smu_11_0_cmn2aisc_mapping vega20_clk_map[SMU_CLK_COUNT] = { @@ -3135,6 +3136,27 @@ static int vega20_get_thermal_temperature_range(struct smu_context *smu, return 0; } +static int vega20_set_df_cstate(struct smu_context *smu, + enum pp_df_cstate state) { + uint32_t smu_version; + int ret; + + ret = smu_get_smc_version(smu, NULL, _version); + if (ret) { + pr_err("Failed to get smu version!\n"); + return ret; + } + + /* PPSMC_MSG_DFCstateControl is supported with 40.50 and later fws */ + if (smu_version < 0x283200) { +
RE: [PATCH 2/2] drm/amd/powerplay: enable df cstate control on swSMU routine
Hi Evan, Is there any use case for this interface? Thanks. -Original Message- From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf Of Quan, Evan Sent: Thursday, October 10, 2019 11:45 AM To: amd-gfx@lists.freedesktop.org Cc: Quan, Evan Subject: [PATCH 2/2] drm/amd/powerplay: enable df cstate control on swSMU routine [CAUTION: External Email] Currently this is only supported on Vega20 with 40.50 and later SMC firmware. Change-Id: I8397f9ccc5dec32dc86ef7635c5ed227c77e61a3 Signed-off-by: Evan Quan --- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c| 23 + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h| 3 +++ drivers/gpu/drm/amd/powerplay/inc/smu_types.h | 1 + drivers/gpu/drm/amd/powerplay/vega20_ppt.c| 25 ++- 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 054376342454..a37a1b1d8abd 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -1834,6 +1834,29 @@ int smu_set_mp1_state(struct smu_context *smu, return ret; } +int smu_set_df_cstate(struct smu_context *smu, + enum pp_df_cstate state) { + int ret = 0; + + /* +* The SMC is not fully ready. That may be +* expected as the IP may be masked. +* So, just return without error. +*/ + if (!smu->pm_enabled) + return 0; + + if (!smu->ppt_funcs || !smu->ppt_funcs->set_df_cstate) + return 0; + + ret = smu->ppt_funcs->set_df_cstate(smu, state); + if (ret) + pr_err("[SetDfCstate] failed!\n"); + + return ret; +} + const struct amd_ip_funcs smu_ip_funcs = { .name = "smu", .early_init = smu_early_init, diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index ccf711c327c8..401affdee49d 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -468,6 +468,7 @@ struct pptable_funcs { int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default); int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t dpm_level, uint32_t *freq); + int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate + state); }; struct smu_funcs @@ -852,5 +853,7 @@ int smu_force_clk_levels(struct smu_context *smu, uint32_t mask); int smu_set_mp1_state(struct smu_context *smu, enum pp_mp1_state mp1_state); +int smu_set_df_cstate(struct smu_context *smu, + enum pp_df_cstate state); #endif diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_types.h b/drivers/gpu/drm/amd/powerplay/inc/smu_types.h index 12a1de55ce3c..d8c9b7f91fcc 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu_types.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu_types.h @@ -169,6 +169,7 @@ __SMU_DUMMY_MAP(PowerGateAtHub), \ __SMU_DUMMY_MAP(SetSoftMinJpeg), \ __SMU_DUMMY_MAP(SetHardMinFclkByFreq),\ + __SMU_DUMMY_MAP(DFCstateControl), \ #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(type) SMU_MSG_##type diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c index 99effde33ac1..1050566cb69a 100644 --- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c @@ -143,6 +143,7 @@ static struct smu_11_0_cmn2aisc_mapping vega20_message_map[SMU_MSG_MAX_COUNT] = MSG_MAP(PrepareMp1ForShutdown), MSG_MAP(SetMGpuFanBoostLimitRpm), MSG_MAP(GetAVFSVoltageByDpm), + MSG_MAP(DFCstateControl), }; static struct smu_11_0_cmn2aisc_mapping vega20_clk_map[SMU_CLK_COUNT] = { @@ -3135,6 +3136,27 @@ static int vega20_get_thermal_temperature_range(struct smu_context *smu, return 0; } +static int vega20_set_df_cstate(struct smu_context *smu, + enum pp_df_cstate state) { + uint32_t smu_version; + int ret; + + ret = smu_get_smc_version(smu, NULL, _version); + if (ret) { + pr_err("Failed to get smu version!\n"); + return ret; + } + + /* PPSMC_MSG_DFCstateControl is supported with 40.50 and later fws */ + if (smu_version < 0x283200) { + pr_err("Df cstate control is supported with 40.50 and later SMC fw!\n"); + return -EINVAL; + } + + return smu_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, +state); } + static const struct pptable_funcs vega20_ppt_funcs = { .tables_init = vega20_tables_init, .alloc_dpm_context = vega20_allocate_dpm_context, @@ -3177,7 +3199,8 @@ static const struct pptable_funcs vega20_ppt_funcs =