Commit 48c19a95 authored by Perry Yuan's avatar Perry Yuan Committed by Alex Deucher

drm/amd/pm: add GFXCLK/SCLK clocks level print support for APUs

add support that allow the userspace tool like RGP to get the GFX clock
value at runtime, the fix follow the old way to show the min/current/max
clocks level for compatible consideration.

=== Test ===
$ cat /sys/class/drm/card0/device/pp_dpm_sclk
0: 200Mhz *
1: 1100Mhz
2: 1600Mhz

then run stress test on one APU system.
$ cat /sys/class/drm/card0/device/pp_dpm_sclk
0: 200Mhz
1: 1040Mhz *
2: 1600Mhz

The current GFXCLK value is updated at runtime.

BugLink: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5260Reviewed-by: default avatarHuang Ray <Ray.Huang@amd.com>
Signed-off-by: default avatarPerry Yuan <Perry.Yuan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 7eb0502a
...@@ -309,6 +309,7 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu, ...@@ -309,6 +309,7 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
{ {
int ret = 0, size = 0; int ret = 0, size = 0;
uint32_t cur_value = 0; uint32_t cur_value = 0;
int i;
smu_cmn_get_sysfs_buf(&buf, &size); smu_cmn_get_sysfs_buf(&buf, &size);
...@@ -334,8 +335,6 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu, ...@@ -334,8 +335,6 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
size += sysfs_emit_at(buf, size, "VDDC: %7umV %10umV\n", size += sysfs_emit_at(buf, size, "VDDC: %7umV %10umV\n",
CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX); CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX);
break; break;
case SMU_GFXCLK:
case SMU_SCLK:
case SMU_FCLK: case SMU_FCLK:
case SMU_MCLK: case SMU_MCLK:
case SMU_SOCCLK: case SMU_SOCCLK:
...@@ -346,6 +345,25 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu, ...@@ -346,6 +345,25 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
return ret; return ret;
size += sysfs_emit_at(buf, size, "0: %uMhz *\n", cur_value); size += sysfs_emit_at(buf, size, "0: %uMhz *\n", cur_value);
break; break;
case SMU_SCLK:
case SMU_GFXCLK:
ret = cyan_skillfish_get_current_clk_freq(smu, clk_type, &cur_value);
if (ret)
return ret;
if (cur_value == CYAN_SKILLFISH_SCLK_MAX)
i = 2;
else if (cur_value == CYAN_SKILLFISH_SCLK_MIN)
i = 0;
else
i = 1;
size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MIN,
i == 0 ? "*" : "");
size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
i == 1 ? cur_value : cyan_skillfish_sclk_default,
i == 1 ? "*" : "");
size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MAX,
i == 2 ? "*" : "");
break;
default: default:
dev_warn(smu->adev->dev, "Unsupported clock type\n"); dev_warn(smu->adev->dev, "Unsupported clock type\n");
return ret; return ret;
......
...@@ -683,6 +683,7 @@ static int vangogh_print_clk_levels(struct smu_context *smu, ...@@ -683,6 +683,7 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
int i, size = 0, ret = 0; int i, size = 0, ret = 0;
uint32_t cur_value = 0, value = 0, count = 0; uint32_t cur_value = 0, value = 0, count = 0;
bool cur_value_match_level = false; bool cur_value_match_level = false;
uint32_t min, max;
memset(&metrics, 0, sizeof(metrics)); memset(&metrics, 0, sizeof(metrics));
...@@ -743,6 +744,13 @@ static int vangogh_print_clk_levels(struct smu_context *smu, ...@@ -743,6 +744,13 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
if (ret) if (ret)
return ret; return ret;
break; break;
case SMU_GFXCLK:
case SMU_SCLK:
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetGfxclkFrequency, 0, &cur_value);
if (ret) {
return ret;
}
break;
default: default:
break; break;
} }
...@@ -768,6 +776,24 @@ static int vangogh_print_clk_levels(struct smu_context *smu, ...@@ -768,6 +776,24 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
if (!cur_value_match_level) if (!cur_value_match_level)
size += sysfs_emit_at(buf, size, " %uMhz *\n", cur_value); size += sysfs_emit_at(buf, size, " %uMhz *\n", cur_value);
break; break;
case SMU_GFXCLK:
case SMU_SCLK:
min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
if (cur_value == max)
i = 2;
else if (cur_value == min)
i = 0;
else
i = 1;
size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
i == 0 ? "*" : "");
size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
i == 1 ? cur_value : VANGOGH_UMD_PSTATE_STANDARD_GFXCLK,
i == 1 ? "*" : "");
size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
i == 2 ? "*" : "");
break;
default: default:
break; break;
} }
......
...@@ -697,6 +697,11 @@ static int yellow_carp_get_current_clk_freq(struct smu_context *smu, ...@@ -697,6 +697,11 @@ static int yellow_carp_get_current_clk_freq(struct smu_context *smu,
case SMU_FCLK: case SMU_FCLK:
return smu_cmn_send_smc_msg_with_param(smu, return smu_cmn_send_smc_msg_with_param(smu,
SMU_MSG_GetFclkFrequency, 0, value); SMU_MSG_GetFclkFrequency, 0, value);
case SMU_GFXCLK:
case SMU_SCLK:
return smu_cmn_send_smc_msg_with_param(smu,
SMU_MSG_GetGfxclkFrequency, 0, value);
break;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -967,6 +972,7 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu, ...@@ -967,6 +972,7 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu,
{ {
int i, size = 0, ret = 0; int i, size = 0, ret = 0;
uint32_t cur_value = 0, value = 0, count = 0; uint32_t cur_value = 0, value = 0, count = 0;
uint32_t min, max;
smu_cmn_get_sysfs_buf(&buf, &size); smu_cmn_get_sysfs_buf(&buf, &size);
...@@ -1005,6 +1011,27 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu, ...@@ -1005,6 +1011,27 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu,
cur_value == value ? "*" : ""); cur_value == value ? "*" : "");
} }
break; break;
case SMU_GFXCLK:
case SMU_SCLK:
ret = yellow_carp_get_current_clk_freq(smu, clk_type, &cur_value);
if (ret)
goto print_clk_out;
min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
if (cur_value == max)
i = 2;
else if (cur_value == min)
i = 0;
else
i = 1;
size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
i == 0 ? "*" : "");
size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
i == 1 ? cur_value : YELLOW_CARP_UMD_PSTATE_GFXCLK,
i == 1 ? "*" : "");
size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
i == 2 ? "*" : "");
break;
default: default:
break; break;
} }
......
...@@ -24,5 +24,6 @@ ...@@ -24,5 +24,6 @@
#define __YELLOW_CARP_PPT_H__ #define __YELLOW_CARP_PPT_H__
extern void yellow_carp_set_ppt_funcs(struct smu_context *smu); extern void yellow_carp_set_ppt_funcs(struct smu_context *smu);
#define YELLOW_CARP_UMD_PSTATE_GFXCLK 1100
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment