[PATCH v1 4/4] amdgpu/pm: Optimize aldebaran_emit_clk_levels
Quan, Evan
Evan.Quan at amd.com
Fri May 13 07:48:18 UTC 2022
[AMD Official Use Only - General]
Series is acked-by: Evan Quan <evan.quan at amd.com>
> -----Original Message-----
> From: Powell, Darren <Darren.Powell at amd.com>
> Sent: Friday, May 13, 2022 11:15 AM
> To: amd-gfx at lists.freedesktop.org
> Cc: Quan, Evan <Evan.Quan at amd.com>; Wang, Yang(Kevin)
> <KevinYang.Wang at amd.com>; david.nieto at amd.com; Lazar, Lijo
> <Lijo.Lazar at amd.com>; Feng, Kenneth <Kenneth.Feng at amd.com>; Yu,
> Lang <Lang.Yu at amd.com>; Powell, Darren <Darren.Powell at amd.com>
> Subject: [PATCH v1 4/4] amdgpu/pm: Optimize aldebaran_emit_clk_levels
>
> aldebaran_get_clk_table cannot fail so convert to void function
> aldebaran_freqs_in_same_level now returns bool
> aldebaran_emit_clk_levels optimized:
> split into two switch statements to gather vars, then use common output
> removed impossible error messages for failure of get_clk_table
> reduce size of string literals by creating static string var
> changed unsafe loop iterator from single_dpm_table->count to
> clocks.num_levels
> in case MAX_DPM_LEVELS > PP_MAX_CLOCK_LEVELS in future code
> added clock_mhz to remove double divide by 1000
> collapse duplicate case statements in second switch statement
> simplified code to output detect frequency level match to current level
>
> == Test ==
> LOGFILE=aldebaran.test.log
> AMDGPU_PCI_ADDR=`lspci -nn | grep "VGA\|Display" | cut -d " " -f 1`
> AMDGPU_HWMON=`ls -la /sys/class/hwmon | grep $AMDGPU_PCI_ADDR |
> awk '{print $9}'`
> HWMON_DIR=/sys/class/hwmon/${AMDGPU_HWMON}
>
> lspci -nn | grep "VGA\|Display" > $LOGFILE
> FILES="pp_dpm_sclk
> pp_dpm_mclk
> pp_dpm_pcie
> pp_dpm_socclk
> pp_dpm_fclk
> pp_dpm_vclk
> pp_dpm_dclk "
>
> for f in $FILES
> do
> echo === $f === >> $LOGFILE
> cat $HWMON_DIR/device/$f >> $LOGFILE
> done
> cat $LOGFILE
>
> Signed-off-by: Darren Powell <darren.powell at amd.com>
> ---
> .../drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 173 +++++++-----------
> 1 file changed, 62 insertions(+), 111 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
> b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
> index e593878bc173..23a87bfb4429 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
> @@ -545,9 +545,9 @@ static int aldebaran_populate_umd_state_clk(struct
> smu_context *smu)
> return 0;
> }
>
> -static int aldebaran_get_clk_table(struct smu_context *smu,
> - struct pp_clock_levels_with_latency *clocks,
> - struct smu_13_0_dpm_table *dpm_table)
> +static void aldebaran_get_clk_table(struct smu_context *smu,
> + struct pp_clock_levels_with_latency
> *clocks,
> + struct smu_13_0_dpm_table *dpm_table)
> {
> int i, count;
>
> @@ -560,11 +560,11 @@ static int aldebaran_get_clk_table(struct
> smu_context *smu,
> clocks->data[i].latency_in_us = 0;
> }
>
> - return 0;
> + return;
> }
>
> -static int aldebaran_freqs_in_same_level(int32_t frequency1,
> - int32_t frequency2)
> +static bool aldebaran_freqs_in_same_level(int32_t frequency1,
> + int32_t frequency2)
> {
> return (abs(frequency1 - frequency2) <= EPSILON);
> }
> @@ -738,9 +738,12 @@ static int aldebaran_emit_clk_levels(struct
> smu_context *smu,
> struct smu_13_0_dpm_table *single_dpm_table;
> struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
> struct smu_13_0_dpm_context *dpm_context = NULL;
> - uint32_t i, display_levels;
> + uint32_t i, cur_value = 0;
> uint32_t freq_values[3] = {0};
> - uint32_t min_clk, max_clk, cur_value = 0;
> + uint32_t min_clk, max_clk, display_levels;
> + bool freq_match;
> + unsigned int clock_mhz;
> + static const char attempt_string[] = "Attempt to get current";
>
> if (amdgpu_ras_intr_triggered()) {
> *offset += sysfs_emit_at(buf, *offset, "unavailable\n");
> @@ -750,23 +753,18 @@ static int aldebaran_emit_clk_levels(struct
> smu_context *smu,
> dpm_context = smu_dpm->dpm_context;
>
> switch (type) {
> -
> case SMU_OD_SCLK:
> *offset += sysfs_emit_at(buf, *offset, "%s:\n", "GFXCLK");
> fallthrough;
> case SMU_SCLK:
> ret = aldebaran_get_current_clk_freq_by_table(smu,
> SMU_GFXCLK, &cur_value);
> if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get current
> gfx clk Failed!");
> + dev_err(smu->adev->dev, "%s gfx clk Failed!",
> attempt_string);
> return ret;
> }
>
> single_dpm_table = &(dpm_context-
> >dpm_tables.gfx_table);
> - ret = aldebaran_get_clk_table(smu, &clocks,
> single_dpm_table);
> - if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get gfx clk
> levels Failed!");
> - return ret;
> - }
> + aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
>
> display_levels = clocks.num_levels;
>
> @@ -782,152 +780,105 @@ static int aldebaran_emit_clk_levels(struct
> smu_context *smu,
> freq_values[2] = max_clk;
> freq_values[1] = cur_value;
> }
> -
> - /*
> - * For DPM disabled case, there will be only one clock level.
> - * And it's safe to assume that is always the current clock.
> - */
> - if (display_levels == clocks.num_levels) {
> - for (i = 0; i < clocks.num_levels; i++)
> - *offset += sysfs_emit_at(buf, *offset,
> "%d: %uMhz %s\n", i,
> - freq_values[i],
> - (clocks.num_levels == 1) ?
> - "*" :
> -
> (aldebaran_freqs_in_same_level(
> - freq_values[i],
> cur_value) ?
> - "*" :
> - ""));
> - } else {
> - for (i = 0; i < display_levels; i++)
> - *offset += sysfs_emit_at(buf, *offset,
> "%d: %uMhz %s\n", i,
> - freq_values[i], i == 1 ? "*" :
> "");
> - }
> -
> break;
> -
> case SMU_OD_MCLK:
> *offset += sysfs_emit_at(buf, *offset, "%s:\n", "MCLK");
> fallthrough;
> case SMU_MCLK:
> ret = aldebaran_get_current_clk_freq_by_table(smu,
> SMU_UCLK, &cur_value);
> if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get current
> mclk Failed!");
> + dev_err(smu->adev->dev, "%s mclk Failed!",
> attempt_string);
> return ret;
> }
>
> single_dpm_table = &(dpm_context-
> >dpm_tables.uclk_table);
> - ret = aldebaran_get_clk_table(smu, &clocks,
> single_dpm_table);
> - if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get memory
> clk levels Failed!");
> - return ret;
> - }
> -
> - for (i = 0; i < clocks.num_levels; i++)
> - *offset += sysfs_emit_at(buf, *offset,
> "%d: %uMhz %s\n",
> - i, clocks.data[i].clocks_in_khz / 1000,
> - (clocks.num_levels == 1) ? "*" :
> - (aldebaran_freqs_in_same_level(
> -
> clocks.data[i].clocks_in_khz / 1000,
> -
> cur_value) ? "*" : ""));
> + aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
> break;
> -
> case SMU_SOCCLK:
> ret = aldebaran_get_current_clk_freq_by_table(smu,
> SMU_SOCCLK, &cur_value);
> if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get current
> socclk Failed!");
> + dev_err(smu->adev->dev, "%s socclk Failed!",
> attempt_string);
> return ret;
> }
>
> single_dpm_table = &(dpm_context-
> >dpm_tables.soc_table);
> - ret = aldebaran_get_clk_table(smu, &clocks,
> single_dpm_table);
> - if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get socclk
> levels Failed!");
> - return ret;
> - }
> -
> - for (i = 0; i < clocks.num_levels; i++)
> - *offset += sysfs_emit_at(buf, *offset,
> "%d: %uMhz %s\n",
> - i, clocks.data[i].clocks_in_khz / 1000,
> - (clocks.num_levels == 1) ? "*" :
> - (aldebaran_freqs_in_same_level(
> -
> clocks.data[i].clocks_in_khz / 1000,
> -
> cur_value) ? "*" : ""));
> + aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
> break;
> -
> case SMU_FCLK:
> ret = aldebaran_get_current_clk_freq_by_table(smu,
> SMU_FCLK, &cur_value);
> if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get current
> fclk Failed!");
> + dev_err(smu->adev->dev, "%s fclk Failed!",
> attempt_string);
> return ret;
> }
>
> single_dpm_table = &(dpm_context-
> >dpm_tables.fclk_table);
> - ret = aldebaran_get_clk_table(smu, &clocks,
> single_dpm_table);
> - if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get fclk levels
> Failed!");
> - return ret;
> - }
> -
> - for (i = 0; i < single_dpm_table->count; i++)
> - *offset += sysfs_emit_at(buf, *offset,
> "%d: %uMhz %s\n",
> - i, single_dpm_table-
> >dpm_levels[i].value,
> - (clocks.num_levels == 1) ? "*" :
> - (aldebaran_freqs_in_same_level(
> -
> clocks.data[i].clocks_in_khz / 1000,
> -
> cur_value) ? "*" : ""));
> + aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
> break;
> -
> case SMU_VCLK:
> ret = aldebaran_get_current_clk_freq_by_table(smu,
> SMU_VCLK, &cur_value);
> if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get current
> vclk Failed!");
> + dev_err(smu->adev->dev, "%s vclk Failed!",
> attempt_string);
> return ret;
> }
>
> single_dpm_table = &(dpm_context-
> >dpm_tables.vclk_table);
> - ret = aldebaran_get_clk_table(smu, &clocks,
> single_dpm_table);
> - if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get vclk
> levels Failed!");
> - return ret;
> - }
> -
> - for (i = 0; i < single_dpm_table->count; i++)
> - *offset += sysfs_emit_at(buf, *offset,
> "%d: %uMhz %s\n",
> - i, single_dpm_table-
> >dpm_levels[i].value,
> - (clocks.num_levels == 1) ? "*" :
> - (aldebaran_freqs_in_same_level(
> -
> clocks.data[i].clocks_in_khz / 1000,
> -
> cur_value) ? "*" : ""));
> + aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
> break;
> -
> case SMU_DCLK:
> ret = aldebaran_get_current_clk_freq_by_table(smu,
> SMU_DCLK, &cur_value);
> if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get current
> dclk Failed!");
> + dev_err(smu->adev->dev, "%s dclk Failed!",
> attempt_string);
> return ret;
> }
>
> single_dpm_table = &(dpm_context-
> >dpm_tables.dclk_table);
> - ret = aldebaran_get_clk_table(smu, &clocks,
> single_dpm_table);
> - if (ret) {
> - dev_err(smu->adev->dev, "Attempt to get dclk
> levels Failed!");
> - return ret;
> + aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + switch (type) {
> + case SMU_OD_SCLK:
> + case SMU_SCLK:
> + /*
> + * For DPM disabled case, there will be only one clock level.
> + * And it's safe to assume that is always the current clock.
> + */
> + if (display_levels == clocks.num_levels) {
> + for (i = 0; i < clocks.num_levels; i++) {
> + clock_mhz = freq_values[i];
> + freq_match =
> aldebaran_freqs_in_same_level(clock_mhz, cur_value);
> + freq_match |= (clocks.num_levels == 1);
> + *offset += sysfs_emit_at(buf, *offset,
> "%d: %uMhz %s\n", i,
> + clock_mhz,
> + freq_match ? "*" :
> "");
> + }
> + } else {
> + for (i = 0; i < display_levels; i++)
> + *offset += sysfs_emit_at(buf, *offset,
> "%d: %uMhz %s\n", i,
> + freq_values[i], i == 1 ?
> "*" : "");
> }
>
> - for (i = 0; i < single_dpm_table->count; i++)
> + break;
> + case SMU_OD_MCLK:
> + case SMU_MCLK:
> + case SMU_SOCCLK:
> + case SMU_FCLK:
> + case SMU_VCLK:
> + case SMU_DCLK:
> + for (i = 0; i < clocks.num_levels; i++) {
> + clock_mhz = clocks.data[i].clocks_in_khz / 1000;
> + freq_match =
> aldebaran_freqs_in_same_level(clock_mhz, cur_value);
> + freq_match |= (clocks.num_levels == 1);
> *offset += sysfs_emit_at(buf, *offset,
> "%d: %uMhz %s\n",
> - i, single_dpm_table-
> >dpm_levels[i].value,
> - (clocks.num_levels == 1) ? "*" :
> - (aldebaran_freqs_in_same_level(
> -
> clocks.data[i].clocks_in_khz / 1000,
> -
> cur_value) ? "*" : ""));
> + i, clock_mhz,
> + freq_match ? "*" : "");
> + }
> break;
> -
> default:
> return -EINVAL;
> - break;
> }
> -
> return 0;
> }
>
> --
> 2.35.1
More information about the amd-gfx
mailing list