A current value of a clock frequency of 0, means that the IP block is in some kind of low power state. Ignore it and don't report it here. Here we only report the possible operating (non-zero) frequencies of the block requested. So, if the current clock value is 0, then print the DPM frequencies, but don't report a current value. v2: Don't report the minimum one as the current one when reported one is 0, i.e. don't add an asterisk (Lijo). LT: It is conceivable that this may confuse user-mode tools if they scan and look for a current one, i.e. look for an asterisk, but they'll have to adapt and use other methods for finding power states of the chip--we can't report 0 as current. v3: Start the subject title with a verb. (PaulM) Cc: Alex Deucher <Alexander.Deucher@xxxxxxx> Cc: Lijo Lazar <Lijo.Lazar@xxxxxxx> Cc: Paul Menzel <pmenzel@xxxxxxxxxxxxx> Signed-off-by: Luben Tuikov <luben.tuikov@xxxxxxx> --- .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index 646e9bbf8af42a..2af6fd336352aa 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -1267,9 +1267,8 @@ static int navi10_print_clk_levels(struct smu_context *smu, { uint16_t *curve_settings; int i, size = 0, ret = 0; - uint32_t curr_value = 0, value = 0, count = 0; + uint32_t curr_value, value, count; uint32_t freq_value[3] = {0, 0, 0}; - uint32_t mark_index = 0; struct smu_table_context *table_context = &smu->smu_table; uint32_t gen_speed, lane_width; struct smu_dpm_context *smu_dpm = &smu->smu_dpm; @@ -1279,6 +1278,7 @@ static int navi10_print_clk_levels(struct smu_context *smu, (OverDriveTable_t *)table_context->overdrive_table; struct smu_11_0_overdrive_table *od_settings = smu->od_settings; uint32_t min_value, max_value; + bool fine_grained; smu_cmn_get_sysfs_buf(&buf, &size); @@ -1296,12 +1296,20 @@ static int navi10_print_clk_levels(struct smu_context *smu, if (ret) return size; + ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, 0, + &freq_value[0]); + if (ret) + return size; + ret = smu_v11_0_get_dpm_level_count(smu, clk_type, &count); if (ret) return size; - if (!navi10_supports_fine_grained_dpm(smu, clk_type)) { - for (i = 0; i < count; i++) { + fine_grained = navi10_supports_fine_grained_dpm(smu, clk_type); + if (!fine_grained) { + size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", 0, freq_value[0], + curr_value == freq_value[0] ? "*" : ""); + for (i = 1; i < count; i++) { ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value); if (ret) return size; @@ -1310,24 +1318,28 @@ static int navi10_print_clk_levels(struct smu_context *smu, curr_value == value ? "*" : ""); } } else { - ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, 0, &freq_value[0]); - if (ret) - return size; + freq_value[1] = curr_value ?: freq_value[0]; ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, count - 1, &freq_value[2]); if (ret) return size; - freq_value[1] = curr_value; - mark_index = curr_value == freq_value[0] ? 0 : - curr_value == freq_value[2] ? 2 : 1; - if (mark_index != 1) - freq_value[1] = (freq_value[0] + freq_value[2]) / 2; - - for (i = 0; i < 3; i++) { - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, freq_value[i], - i == mark_index ? "*" : ""); + if (freq_value[1] == freq_value[0]) { + i = 1; + count = 3; + } else if (freq_value[1] == freq_value[2]) { + i = 0; + count = 2; + } else { + i = 0; + count = 3; } + for ( ; i < count; i++) { + size += sysfs_emit_at(buf, size, + "%d: %uMhz %s\n", + i, freq_value[i], + curr_value == freq_value[i] ? "*" : ""); + } } break; case SMU_PCIE: -- 2.33.1.558.g2bd2f258f4