<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<p style="font-family:Arial;font-size:11pt;color:#0078D7;margin:5pt;" align="Left">
[AMD Official Use Only - Internal Distribution Only]<br>
</p>
<br>
<div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="appendonsend"></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> Lazar, Lijo <Lijo.Lazar@amd.com><br>
<b>Sent:</b> Thursday, May 13, 2021 7:53 PM<br>
<b>To:</b> Wang, Kevin(Yang) <Kevin1.Wang@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Cc:</b> Zhang, Hawking <Hawking.Zhang@amd.com>; Feng, Kenneth <Kenneth.Feng@amd.com><br>
<b>Subject:</b> Re: [PATCH 2/3] drm/amd/pm: Fix showing incorrect frequencies on aldebaran</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText"><br>
<br>
On 5/13/2021 5:06 PM, Wang, Kevin(Yang) wrote:<br>
> [AMD Official Use Only - Internal Distribution Only]<br>
> <br>
> <br>
> <br>
> <br>
> ------------------------------------------------------------------------<br>
> *From:* Lazar, Lijo <Lijo.Lazar@amd.com><br>
> *Sent:* Thursday, May 13, 2021 5:47 PM<br>
> *To:* amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
> *Cc:* Zhang, Hawking <Hawking.Zhang@amd.com>; Feng, Kenneth <br>
> <Kenneth.Feng@amd.com>; Wang, Kevin(Yang) <Kevin1.Wang@amd.com><br>
> *Subject:* [PATCH 2/3] drm/amd/pm: Fix showing incorrect frequencies on <br>
> aldebaran<br>
> <br>
> Use the current and custom pstate frequencies to track the current and<br>
> user-set min/max values in manual and determinism mode. Previously, only<br>
> actual_* value was used to track the currrent and user requested value.<br>
> The value will get reassigned whenever user requests a new value with<br>
> pp_od_clk_voltage node. Hence it will show incorrect values when user<br>
> requests an invalid value or tries a partial request without committing<br>
> the values. Separating out to custom and current variable fixes such<br>
> issues.<br>
> <br>
> Signed-off-by: Lijo Lazar <lijo.lazar@amd.com><br>
> ---<br>
> .../drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 65 ++++++++++++-------<br>
> .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 18 ++++-<br>
> 2 files changed, 55 insertions(+), 28 deletions(-)<br>
> <br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c<br>
> b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c<br>
> index 5d04a1dfdfd8..d27ed2954705 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c<br>
> @@ -78,8 +78,6 @@<br>
> <br>
> #define smnPCIE_ESM_CTRL 0x111003D0<br>
> <br>
> -#define CLOCK_VALID (1 << 31)<br>
> -<br>
> static const struct cmn2asic_msg_mapping<br>
> aldebaran_message_map[SMU_MSG_MAX_COUNT] = {<br>
> MSG_MAP(TestMessage, <br>
> PPSMC_MSG_TestMessage, 0),<br>
> MSG_MAP(GetSmuVersion, <br>
> PPSMC_MSG_GetSmuVersion, 1),<br>
> @@ -455,12 +453,18 @@ static int aldebaran_populate_umd_state_clk(struct<br>
> smu_context *smu)<br>
> <br>
> pstate_table->gfxclk_pstate.min = gfx_table->min;<br>
> pstate_table->gfxclk_pstate.peak = gfx_table->max;<br>
> + pstate_table->gfxclk_pstate.curr.min = gfx_table->min;<br>
> + pstate_table->gfxclk_pstate.curr.max = gfx_table->max;<br>
> <br>
> pstate_table->uclk_pstate.min = mem_table->min;<br>
> pstate_table->uclk_pstate.peak = mem_table->max;<br>
> + pstate_table->uclk_pstate.curr.min = mem_table->min;<br>
> + pstate_table->uclk_pstate.curr.max = mem_table->max;<br>
> <br>
> pstate_table->socclk_pstate.min = soc_table->min;<br>
> pstate_table->socclk_pstate.peak = soc_table->max;<br>
> + pstate_table->socclk_pstate.curr.min = soc_table->min;<br>
> + pstate_table->socclk_pstate.curr.max = soc_table->max;<br>
> <br>
> if (gfx_table->count > ALDEBARAN_UMD_PSTATE_GFXCLK_LEVEL &&<br>
> mem_table->count > ALDEBARAN_UMD_PSTATE_MCLK_LEVEL &&<br>
> @@ -669,6 +673,7 @@ static int aldebaran_print_clk_levels(struct<br>
> smu_context *smu,<br>
> {<br>
> int i, now, size = 0;<br>
> int ret = 0;<br>
> + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;<br>
> struct pp_clock_levels_with_latency clocks;<br>
> struct smu_13_0_dpm_table *single_dpm_table;<br>
> struct smu_dpm_context *smu_dpm = &smu->smu_dpm;<br>
> @@ -703,12 +708,8 @@ static int aldebaran_print_clk_levels(struct<br>
> smu_context *smu,<br>
> <br>
> display_levels = clocks.num_levels;<br>
> <br>
> - min_clk = smu->gfx_actual_hard_min_freq & CLOCK_VALID ?<br>
> - smu->gfx_actual_hard_min_freq & <br>
> ~CLOCK_VALID :<br>
> - single_dpm_table->dpm_levels[0].value;<br>
> - max_clk = smu->gfx_actual_soft_max_freq & CLOCK_VALID ?<br>
> - smu->gfx_actual_soft_max_freq & <br>
> ~CLOCK_VALID :<br>
> - single_dpm_table->dpm_levels[1].value;<br>
> + min_clk = pstate_table->gfxclk_pstate.curr.min;<br>
> + max_clk = pstate_table->gfxclk_pstate.curr.max;<br>
> <br>
> freq_values[0] = min_clk;<br>
> freq_values[1] = max_clk;<br>
> @@ -1134,9 +1135,6 @@ static int aldebaran_set_performance_level(struct<br>
> smu_context *smu,<br>
> && (level != <br>
> AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM))<br>
> smu_cmn_send_smc_msg(smu, SMU_MSG_DisableDeterminism, <br>
> NULL);<br>
> <br>
> - /* Reset user min/max gfx clock */<br>
> - smu->gfx_actual_hard_min_freq = 0;<br>
> - smu->gfx_actual_soft_max_freq = 0;<br>
> <br>
> switch (level) {<br>
> <br>
> @@ -1163,6 +1161,7 @@ static int<br>
> aldebaran_set_soft_freq_limited_range(struct smu_context *smu,<br>
> {<br>
> struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);<br>
> struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;<br>
> + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;<br>
> struct amdgpu_device *adev = smu->adev;<br>
> uint32_t min_clk;<br>
> uint32_t max_clk;<br>
> @@ -1176,14 +1175,20 @@ static int<br>
> aldebaran_set_soft_freq_limited_range(struct smu_context *smu,<br>
> return -EINVAL;<br>
> <br>
> if (smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {<br>
> - min_clk = max(min, dpm_context->dpm_tables.gfx_table.min);<br>
> - max_clk = min(max, dpm_context->dpm_tables.gfx_table.max);<br>
> - ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK,<br>
> - min_clk, <br>
> max_clk);<br>
> + if (min >= max) {<br>
> + dev_err(smu->adev->dev,<br>
> + "Minimum GFX clk should be less than the <br>
> maximum allowed clock\n");<br>
> + return -EINVAL;<br>
> + }<br>
> <br>
> [kevin]:<br>
> why can these value not be equal in manual mode?<br>
<br>
We are intentionally avoiding user expectation to run at fixed clocks. <br>
The message is to make it clear that it is not a reasonable expectation <br>
on aldebaran.<br>
<br>
Thanks,<br>
Lijo</div>
<div class="PlainText"><br>
</div>
<div class="PlainText">[kevin]:</div>
<div class="PlainText">In fact, the SMU firmware allows driver to set the same clock,</div>
<div class="PlainText">in other asic, we have the same code logic.</div>
<div class="PlainText"><br>
</div>
<div class="PlainText">Regards,</div>
<div class="PlainText">Kevin<br>
> + if ((min == pstate_table->gfxclk_pstate.curr.min) &&<br>
> + (max == pstate_table->gfxclk_pstate.curr.max))<br>
> + return 0;<br>
> + ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK,<br>
> + min, max);<br>
> if (!ret) {<br>
> - smu->gfx_actual_hard_min_freq = min_clk | <br>
> CLOCK_VALID;<br>
> - smu->gfx_actual_soft_max_freq = max_clk | <br>
> CLOCK_VALID;<br>
> + pstate_table->gfxclk_pstate.curr.min = min;<br>
> + pstate_table->gfxclk_pstate.curr.max = max;<br>
> }<br>
> return ret;<br>
> }<br>
> @@ -1209,10 +1214,8 @@ static int<br>
> aldebaran_set_soft_freq_limited_range(struct smu_context *smu,<br>
> dev_err(adev->dev,<br>
> "Failed to enable <br>
> determinism at GFX clock %d MHz\n", max);<br>
> } else {<br>
> - smu->gfx_actual_hard_min_freq =<br>
> - min_clk | CLOCK_VALID;<br>
> - smu->gfx_actual_soft_max_freq =<br>
> - max | CLOCK_VALID;<br>
> + pstate_table->gfxclk_pstate.curr.min = <br>
> min_clk;<br>
> + pstate_table->gfxclk_pstate.curr.max = max;<br>
> }<br>
> }<br>
> }<br>
> @@ -1225,6 +1228,7 @@ static int aldebaran_usr_edit_dpm_table(struct<br>
> smu_context *smu, enum PP_OD_DPM_<br>
> {<br>
> struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);<br>
> struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;<br>
> + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;<br>
> uint32_t min_clk;<br>
> uint32_t max_clk;<br>
> int ret = 0;<br>
> @@ -1245,16 +1249,20 @@ static int aldebaran_usr_edit_dpm_table(struct<br>
> smu_context *smu, enum PP_OD_DPM_<br>
> if (input[1] < <br>
> dpm_context->dpm_tables.gfx_table.min) {<br>
> dev_warn(smu->adev->dev, "Minimum GFX <br>
> clk (%ld) MHz specified is<br>
> less than the minimum allowed (%d) MHz\n",<br>
> input[1], <br>
> dpm_context->dpm_tables.gfx_table.min);<br>
> + pstate_table->gfxclk_pstate.custom.min =<br>
> + <br>
> pstate_table->gfxclk_pstate.curr.min;<br>
> return -EINVAL;<br>
> }<br>
> - smu->gfx_actual_hard_min_freq = input[1];<br>
> + pstate_table->gfxclk_pstate.custom.min = input[1];<br>
> } else if (input[0] == 1) {<br>
> if (input[1] > <br>
> dpm_context->dpm_tables.gfx_table.max) {<br>
> dev_warn(smu->adev->dev, "Maximum GFX <br>
> clk (%ld) MHz specified is<br>
> greater than the maximum allowed (%d) MHz\n",<br>
> input[1], <br>
> dpm_context->dpm_tables.gfx_table.max);<br>
> + pstate_table->gfxclk_pstate.custom.max =<br>
> + <br>
> pstate_table->gfxclk_pstate.curr.max;<br>
> return -EINVAL;<br>
> }<br>
> - smu->gfx_actual_soft_max_freq = input[1];<br>
> + pstate_table->gfxclk_pstate.custom.max = input[1];<br>
> } else {<br>
> return -EINVAL;<br>
> }<br>
> @@ -1276,8 +1284,15 @@ static int aldebaran_usr_edit_dpm_table(struct<br>
> smu_context *smu, enum PP_OD_DPM_<br>
> dev_err(smu->adev->dev, "Input parameter <br>
> number not correct\n");<br>
> return -EINVAL;<br>
> } else {<br>
> - min_clk = smu->gfx_actual_hard_min_freq;<br>
> - max_clk = smu->gfx_actual_soft_max_freq;<br>
> + if (!pstate_table->gfxclk_pstate.custom.min)<br>
> + pstate_table->gfxclk_pstate.custom.min =<br>
> + <br>
> pstate_table->gfxclk_pstate.curr.min;<br>
> + if (!pstate_table->gfxclk_pstate.custom.max)<br>
> + pstate_table->gfxclk_pstate.custom.max =<br>
> + <br>
> pstate_table->gfxclk_pstate.curr.max;<br>
> + min_clk = pstate_table->gfxclk_pstate.custom.min;<br>
> + max_clk = pstate_table->gfxclk_pstate.custom.max;<br>
> +<br>
> return <br>
> aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK,<br>
> min_clk, max_clk);<br>
> }<br>
> break;<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c<br>
> b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c<br>
> index 0864083e7435..755bddaf6c4b 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c<br>
> @@ -1624,8 +1624,12 @@ int smu_v13_0_set_performance_level(struct<br>
> smu_context *smu,<br>
> SMU_GFXCLK,<br>
> sclk_min,<br>
> sclk_max);<br>
> - if (ret)<br>
> + if (ret) {<br>
> return ret;<br>
> + } else {<br>
> + pstate_table->gfxclk_pstate.curr.min = sclk_min;<br>
> + pstate_table->gfxclk_pstate.curr.max = sclk_max;<br>
> + }<br>
> }<br>
> <br>
> if (mclk_min && mclk_max) {<br>
> @@ -1633,8 +1637,12 @@ int smu_v13_0_set_performance_level(struct<br>
> smu_context *smu,<br>
> SMU_MCLK,<br>
> mclk_min,<br>
> mclk_max);<br>
> - if (ret)<br>
> + if (ret) {<br>
> return ret;<br>
> + } else {<br>
> + pstate_table->uclk_pstate.curr.min = mclk_min;<br>
> + pstate_table->uclk_pstate.curr.max = mclk_max;<br>
> + }<br>
> }<br>
> <br>
> if (socclk_min && socclk_max) {<br>
> @@ -1642,8 +1650,12 @@ int smu_v13_0_set_performance_level(struct<br>
> smu_context *smu,<br>
> SMU_SOCCLK,<br>
> socclk_min,<br>
> socclk_max);<br>
> - if (ret)<br>
> + if (ret) {<br>
> return ret;<br>
> + } else {<br>
> + pstate_table->socclk_pstate.curr.min = socclk_min;<br>
> + pstate_table->socclk_pstate.curr.max = socclk_max;<br>
> + }<br>
> }<br>
> <br>
> return ret;<br>
> -- <br>
> 2.17.1<br>
> <br>
<br>
</div>
</span></font></div>
</div>
</body>
</html>