<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:10pt;color:#0000FF;margin:5pt;" align="Left">
[AMD Official Use Only]<br>
</p>
<br>
<div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;font-size:14.6667px;background-color:rgb(255, 255, 255);display:inline !important">> The whole idea seems
fine to me. However, we are trying to do some cleanups to avoid spiking into power internals(as above via adev->powerplay.pp_funcs->emit_clock_levels).</span><br>
<span style="font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;font-size:14.6667px;background-color:rgb(255, 255, 255);display:inline !important">> Check the patch series
below:</span><br style="font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;font-size:14.6667px;background-color:rgb(255, 255, 255)">
> <a href="https://lists.freedesktop.org/archives/amd-gfx/2021-December/072096.html" style="margin:0px;font-size:14.6667px;font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;background-color:rgb(255, 255, 255)">https://lists.freedesktop.org/archives/amd-gfx/2021-December/072096.html</a><br style="font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;font-size:14.6667px;background-color:rgb(255, 255, 255)">
<span style="font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;font-size:14.6667px;background-color:rgb(255, 255, 255);display:inline !important">> So, it would be better
if you can rebase the patches here based on that. Or you can wait a while to let me land them first.</span><br style="font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;font-size:14.6667px;background-color:rgb(255, 255, 255)">
<br style="font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;font-size:14.6667px;background-color:rgb(255, 255, 255)">
<span style="font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;font-size:14.6667px;background-color:rgb(255, 255, 255);display:inline !important">> BR</span><br style="font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;font-size:14.6667px;background-color:rgb(255, 255, 255)">
<span style="font-family:"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;font-size:14.6667px;background-color:rgb(255, 255, 255);display:inline !important">> Evan</span><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>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
I can wait for it to land and rebase then, will send v2 of series once this happens</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Darren</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> Quan, Evan <Evan.Quan@amd.com><br>
<b>Sent:</b> Wednesday, December 8, 2021 8:48 PM<br>
<b>To:</b> Powell, Darren <Darren.Powell@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Cc:</b> Powell, Darren <Darren.Powell@amd.com><br>
<b>Subject:</b> RE: [PATCH 1/3] amdgpu/pm: Implement new API function "emit" that accepts buffer base and write offset</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText">[AMD Official Use Only]<br>
<br>
<br>
<br>
> -----Original Message-----<br>
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of<br>
> Darren Powell<br>
> Sent: Wednesday, December 8, 2021 2:36 PM<br>
> To: amd-gfx@lists.freedesktop.org<br>
> Cc: Powell, Darren <Darren.Powell@amd.com><br>
> Subject: [PATCH 1/3] amdgpu/pm: Implement new API function "emit" that<br>
> accepts buffer base and write offset<br>
> <br>
> - new power management function emit_clk_levels implemented by<br>
> navi10_emit_clk_levels()<br>
> This function currently duplicates the functionality of<br>
> navi10_print_clk_levels, where<br>
> snprintf is used write to the sysfs buffer. The first implementation to use<br>
> sysfs_emit<br>
> was unsuccessful due to requirement that buf must be aligned to a<br>
> specific memory<br>
> boundary. This solution passes the buffer base and write offset down the<br>
> stack.<br>
> - new power management function emit_clock_levels implemented by<br>
> smu_emit_ppclk_levels()<br>
> This function combines implementation of smu_print_ppclk_levels and<br>
> smu_print_smuclk_levels and calls emit_clk_levels<br>
> - new helper function smu_convert_to_smuclk called by<br>
> smu_print_ppclk_levels and<br>
> smu_emit_ppclk_levels<br>
> - emit_clock_levels currently returns the length of the string written to the<br>
> buffer,<br>
> maintaining the behaviour of print_clock_levels, but will be upgraded to<br>
> return<br>
> error values in a subsequent patch<br>
> - failure of the emit_clock_levels at the top level<br>
> (amdgpu_get_pp_dpm_clock) triggers a<br>
> fallback to the print_clock_levels, which can be removed after<br>
> emit_clock_levels is<br>
> implemented across all platforms.<br>
> <br>
> == Test ==<br>
> LOGFILE=pp_clk.test.log<br>
> AMDGPU_PCI_ADDR=`lspci -nn | grep "VGA\|Display" | cut -d " " -f 1`<br>
> AMDGPU_HWMON=`ls -la /sys/class/hwmon | grep $AMDGPU_PCI_ADDR |<br>
> awk '{print $9}'`<br>
> HWMON_DIR=/sys/class/hwmon/${AMDGPU_HWMON}<br>
> <br>
> lspci -nn | grep "VGA\|Display" > $LOGFILE<br>
> FILES="pp_od_clk_voltage<br>
> pp_dpm_sclk<br>
> pp_dpm_mclk<br>
> pp_dpm_pcie<br>
> pp_dpm_socclk<br>
> pp_dpm_fclk<br>
> pp_dpm_dcefclk<br>
> pp_dpm_vclk<br>
> pp_dpm_dclk "<br>
> <br>
> for f in $FILES<br>
> do<br>
> echo === $f === >> $LOGFILE<br>
> cat $HWMON_DIR/device/$f >> $LOGFILE<br>
> done<br>
> cat $LOGFILE<br>
> <br>
> Signed-off-by: Darren Powell <darren.powell@amd.com><br>
> ---<br>
> .../gpu/drm/amd/include/kgd_pp_interface.h | 1 +<br>
> drivers/gpu/drm/amd/pm/amdgpu_pm.c | 20 +-<br>
> drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 3 +<br>
> drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h | 10 +<br>
> drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 50 ++++-<br>
> .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 189<br>
> ++++++++++++++++++<br>
> 6 files changed, 262 insertions(+), 11 deletions(-)<br>
> <br>
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> b/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> index bac15c466733..43f43a4f321b 100644<br>
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> @@ -310,6 +310,7 @@ struct amd_pm_funcs {<br>
> int (*get_fan_speed_pwm)(void *handle, u32 *speed);<br>
> int (*force_clock_level)(void *handle, enum pp_clock_type type,<br>
> uint32_t mask);<br>
> int (*print_clock_levels)(void *handle, enum pp_clock_type type,<br>
> char *buf);<br>
> + int (*emit_clock_levels)(void *handle, enum pp_clock_type type,<br>
> char *buf, int *offset);<br>
> int (*force_performance_level)(void *handle, enum<br>
> amd_dpm_forced_level level);<br>
> int (*get_sclk_od)(void *handle);<br>
> int (*set_sclk_od)(void *handle, uint32_t value);<br>
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c<br>
> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c<br>
> index 49df4c20f09e..a1169a2397ca 100644<br>
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c<br>
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c<br>
> @@ -1056,8 +1056,8 @@ static ssize_t amdgpu_get_pp_dpm_clock(struct<br>
> device *dev,<br>
> {<br>
> struct drm_device *ddev = dev_get_drvdata(dev);<br>
> struct amdgpu_device *adev = drm_to_adev(ddev);<br>
> - ssize_t size;<br>
> - int ret;<br>
> + int size = 0;<br>
> + int ret = 0;<br>
> <br>
> if (amdgpu_in_reset(adev))<br>
> return -EPERM;<br>
> @@ -1070,10 +1070,18 @@ static ssize_t amdgpu_get_pp_dpm_clock(struct<br>
> device *dev,<br>
> return ret;<br>
> }<br>
> <br>
> - if (adev->powerplay.pp_funcs->print_clock_levels)<br>
> - size = amdgpu_dpm_print_clock_levels(adev, type, buf);<br>
> - else<br>
> - size = sysfs_emit(buf, "\n");<br>
> + ret = -EOPNOTSUPP;<br>
> + if (adev->powerplay.pp_funcs->emit_clock_levels) {<br>
> + ret = amdgpu_dpm_emit_clock_levels(adev, type, buf,<br>
> &size);<br>
> + }<br>
The whole idea seems fine to me. However, we are trying to do some cleanups to avoid spiking into power internals(as above via adev->powerplay.pp_funcs->emit_clock_levels).<br>
Check the patch series below:<br>
<a href="https://lists.freedesktop.org/archives/amd-gfx/2021-December/072096.html">https://lists.freedesktop.org/archives/amd-gfx/2021-December/072096.html</a><br>
So, it would be better if you can rebase the patches here based on that. Or you can wait a while to let me land them first.<br>
<br>
BR<br>
Evan<br>
> +<br>
> + if (ret < 0) {<br>
> + if (adev->powerplay.pp_funcs->print_clock_levels) {<br>
> + size = amdgpu_dpm_print_clock_levels(adev, type,<br>
> buf);<br>
> + }<br>
> + else<br>
> + size = sysfs_emit(buf, "\n");<br>
> + }<br>
> <br>
> pm_runtime_mark_last_busy(ddev->dev);<br>
> pm_runtime_put_autosuspend(ddev->dev);<br>
> diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h<br>
> b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h<br>
> index 16e3f72d31b9..95add7afcc86 100644<br>
> --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h<br>
> +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h<br>
> @@ -310,6 +310,9 @@ enum amdgpu_pcie_gen {<br>
> #define amdgpu_dpm_print_clock_levels(adev, type, buf) \<br>
> ((adev)->powerplay.pp_funcs->print_clock_levels((adev)-<br>
> >powerplay.pp_handle, type, buf))<br>
> <br>
> +#define amdgpu_dpm_emit_clock_levels(adev, type, buf, offset) \<br>
> + ((adev)->powerplay.pp_funcs->emit_clock_levels((adev)-<br>
> >powerplay.pp_handle, type, buf, offset))<br>
> +<br>
> #define amdgpu_dpm_force_clock_level(adev, type, level) \<br>
> ((adev)->powerplay.pp_funcs->force_clock_level((adev)-<br>
> >powerplay.pp_handle, type, level))<br>
> <br>
> diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h<br>
> b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h<br>
> index f738f7dc20c9..dc1325783c10 100644<br>
> --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h<br>
> +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h<br>
> @@ -620,6 +620,16 @@ struct pptable_funcs {<br>
> */<br>
> int (*print_clk_levels)(struct smu_context *smu, enum<br>
> smu_clk_type clk_type, char *buf);<br>
> <br>
> + /**<br>
> + * @emit_clk_levels: Print DPM clock levels for a clock domain<br>
> + * to buffer using sysfs_emit_at. Star current level.<br>
> + *<br>
> + * Used for sysfs interfaces.<br>
> + * &buf: sysfs buffer<br>
> + * &offset: offset within buffer to start printing<br>
> + */<br>
> + int (*emit_clk_levels)(struct smu_context *smu, enum<br>
> smu_clk_type clk_type, char *buf, int *offset);<br>
> +<br>
> /**<br>
> * @force_clk_levels: Set a range of allowed DPM levels for a clock<br>
> * domain.<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c<br>
> b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c<br>
> index e156add7b560..b0638d8308d2 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c<br>
> @@ -2397,11 +2397,8 @@ static int smu_print_smuclk_levels(struct<br>
> smu_context *smu, enum smu_clk_type cl<br>
> return ret;<br>
> }<br>
> <br>
> -static int smu_print_ppclk_levels(void *handle,<br>
> - enum pp_clock_type type,<br>
> - char *buf)<br>
> +static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type<br>
> type)<br>
> {<br>
> - struct smu_context *smu = handle;<br>
> enum smu_clk_type clk_type;<br>
> <br>
> switch (type) {<br>
> @@ -2434,12 +2431,54 @@ static int smu_print_ppclk_levels(void *handle,<br>
> case OD_CCLK:<br>
> clk_type = SMU_OD_CCLK; break;<br>
> default:<br>
> - return -EINVAL;<br>
> + clk_type = SMU_CLK_COUNT; break;<br>
> }<br>
> <br>
> + return clk_type;<br>
> +}<br>
> +<br>
> +static int smu_print_ppclk_levels(void *handle,<br>
> + enum pp_clock_type type,<br>
> + char *buf)<br>
> +{<br>
> + struct smu_context *smu = handle;<br>
> + enum smu_clk_type clk_type;<br>
> +<br>
> + clk_type = smu_convert_to_smuclk(type);<br>
> + if (clk_type == SMU_CLK_COUNT)<br>
> + return -EINVAL;<br>
> +<br>
> return smu_print_smuclk_levels(smu, clk_type, buf);<br>
> }<br>
> <br>
> +static int smu_emit_ppclk_levels(void *handle, enum pp_clock_type type,<br>
> char *buf, int *offset)<br>
> +{<br>
> + struct smu_context *smu = handle;<br>
> + enum smu_clk_type clk_type;<br>
> + int ret = 0;<br>
> +<br>
> + clk_type = smu_convert_to_smuclk(type);<br>
> + if (clk_type == SMU_CLK_COUNT)<br>
> + return -EINVAL;<br>
> +<br>
> + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)<br>
> + return -EOPNOTSUPP;<br>
> +<br>
> + mutex_lock(&smu->mutex);<br>
> +<br>
> + if (smu->ppt_funcs->emit_clk_levels) {<br>
> + ret = smu->ppt_funcs->emit_clk_levels(smu, clk_type, buf,<br>
> offset);<br>
> + }<br>
> + else {<br>
> + ret = -EOPNOTSUPP;<br>
> + }<br>
> +<br>
> + mutex_unlock(&smu->mutex);<br>
> +<br>
> + return ret;<br>
> +<br>
> +}<br>
> +<br>
> static int smu_od_edit_dpm_table(void *handle,<br>
> enum PP_OD_DPM_TABLE_COMMAND<br>
> type,<br>
> long *input, uint32_t size)<br>
> @@ -3117,6 +3156,7 @@ static const struct amd_pm_funcs<br>
> swsmu_pm_funcs = {<br>
> .get_fan_speed_pwm = smu_get_fan_speed_pwm,<br>
> .force_clock_level = smu_force_ppclk_levels,<br>
> .print_clock_levels = smu_print_ppclk_levels,<br>
> + .emit_clock_levels = smu_emit_ppclk_levels,<br>
> .force_performance_level = smu_force_performance_level,<br>
> .read_sensor = smu_read_sensor,<br>
> .get_performance_level = smu_get_performance_level,<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c<br>
> b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c<br>
> index 60a557068ea4..e43c7e950a55 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c<br>
> @@ -1261,6 +1261,194 @@ static void navi10_od_setting_get_range(struct<br>
> smu_11_0_overdrive_table *od_tabl<br>
> *max = od_table->max[setting];<br>
> }<br>
> <br>
> +static int navi10_emit_clk_levels(struct smu_context *smu,<br>
> + enum smu_clk_type clk_type, char *buf, int *offset)<br>
> +{<br>
> + uint16_t *curve_settings;<br>
> + int ret = 0;<br>
> + uint32_t cur_value = 0, value = 0;<br>
> + uint32_t freq_values[3] = {0};<br>
> + uint32_t i, levels, mark_index = 0, count = 0;<br>
> + struct smu_table_context *table_context = &smu->smu_table;<br>
> + uint32_t gen_speed, lane_width;<br>
> + struct smu_dpm_context *smu_dpm = &smu->smu_dpm;<br>
> + struct smu_11_0_dpm_context *dpm_context = smu_dpm-<br>
> >dpm_context;<br>
> + PPTable_t *pptable = (PPTable_t *)table_context->driver_pptable;<br>
> + OverDriveTable_t *od_table =<br>
> + (OverDriveTable_t *)table_context->overdrive_table;<br>
> + struct smu_11_0_overdrive_table *od_settings = smu->od_settings;<br>
> + uint32_t min_value, max_value;<br>
> + int save_offset = *offset;<br>
> +<br>
> + switch (clk_type) {<br>
> + case SMU_GFXCLK:<br>
> + case SMU_SCLK:<br>
> + case SMU_SOCCLK:<br>
> + case SMU_MCLK:<br>
> + case SMU_UCLK:<br>
> + case SMU_FCLK:<br>
> + case SMU_VCLK:<br>
> + case SMU_DCLK:<br>
> + case SMU_DCEFCLK:<br>
> + ret = navi10_get_current_clk_freq_by_table(smu, clk_type,<br>
> &cur_value);<br>
> + if (ret)<br>
> + return 0;<br>
> +<br>
> + ret = smu_v11_0_get_dpm_level_count(smu, clk_type,<br>
> &count);<br>
> + if (ret)<br>
> + return 0;<br>
> +<br>
> + if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) {<br>
> + for (i = 0; i < count; i++) {<br>
> + ret =<br>
> smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value);<br>
> + if (ret)<br>
> + return (*offset - save_offset);<br>
> +<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "%d: %uMhz %s\n", i, value,<br>
> + cur_value == value ? "*" : "");<br>
> +<br>
> + }<br>
> + } else {<br>
> + ret = smu_v11_0_get_dpm_freq_by_index(smu,<br>
> clk_type, 0, &freq_values[0]);<br>
> + if (ret)<br>
> + return 0;<br>
> + ret = smu_v11_0_get_dpm_freq_by_index(smu,<br>
> clk_type, count - 1, &freq_values[2]);<br>
> + if (ret)<br>
> + return 0;<br>
> +<br>
> + freq_values[1] = cur_value;<br>
> + mark_index = cur_value == freq_values[0] ? 0 :<br>
> + cur_value == freq_values[2] ? 2 : 1;<br>
> +<br>
> + levels = 3;<br>
> + if (mark_index != 1) {<br>
> + levels = 2;<br>
> + freq_values[1] = freq_values[2];<br>
> + }<br>
> +<br>
> + for (i = 0; i < levels; i++) {<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "%d: %uMhz %s\n", i, freq_values[i],<br>
> + i == mark_index ? "*" : "");<br>
> + }<br>
> + }<br>
> + break;<br>
> + case SMU_PCIE:<br>
> + gen_speed =<br>
> smu_v11_0_get_current_pcie_link_speed_level(smu);<br>
> + lane_width =<br>
> smu_v11_0_get_current_pcie_link_width_level(smu);<br>
> + for (i = 0; i < NUM_LINK_LEVELS; i++) {<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "%d: %s %s %dMhz %s\n", i,<br>
> + (dpm_context-<br>
> >dpm_tables.pcie_table.pcie_gen[i] == 0) ? "2.5GT/s," :<br>
> + (dpm_context-<br>
> >dpm_tables.pcie_table.pcie_gen[i] == 1) ? "5.0GT/s," :<br>
> + (dpm_context-<br>
> >dpm_tables.pcie_table.pcie_gen[i] == 2) ? "8.0GT/s," :<br>
> + (dpm_context-<br>
> >dpm_tables.pcie_table.pcie_gen[i] == 3) ? "16.0GT/s," : "",<br>
> + (dpm_context-<br>
> >dpm_tables.pcie_table.pcie_lane[i] == 1) ? "x1" :<br>
> + (dpm_context-<br>
> >dpm_tables.pcie_table.pcie_lane[i] == 2) ? "x2" :<br>
> + (dpm_context-<br>
> >dpm_tables.pcie_table.pcie_lane[i] == 3) ? "x4" :<br>
> + (dpm_context-<br>
> >dpm_tables.pcie_table.pcie_lane[i] == 4) ? "x8" :<br>
> + (dpm_context-<br>
> >dpm_tables.pcie_table.pcie_lane[i] == 5) ? "x12" :<br>
> + (dpm_context-<br>
> >dpm_tables.pcie_table.pcie_lane[i] == 6) ? "x16" : "",<br>
> + pptable->LclkFreq[i],<br>
> + (gen_speed == dpm_context-<br>
> >dpm_tables.pcie_table.pcie_gen[i]) &&<br>
> + (lane_width == dpm_context-<br>
> >dpm_tables.pcie_table.pcie_lane[i]) ?<br>
> + "*" : "");<br>
> + }<br>
> + break;<br>
> + case SMU_OD_SCLK:<br>
> + if (!smu->od_enabled || !od_table || !od_settings)<br>
> + break;<br>
> + if (!navi10_od_feature_is_supported(od_settings,<br>
> SMU_11_0_ODCAP_GFXCLK_LIMITS))<br>
> + break;<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "OD_SCLK:\n0: %uMhz\n1: %uMhz\n",<br>
> + od_table->GfxclkFmin, od_table-<br>
> >GfxclkFmax);<br>
> + break;<br>
> + case SMU_OD_MCLK:<br>
> + if (!smu->od_enabled || !od_table || !od_settings)<br>
> + break;<br>
> + if (!navi10_od_feature_is_supported(od_settings,<br>
> SMU_11_0_ODCAP_UCLK_MAX))<br>
> + break;<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "OD_MCLK:\n1: %uMHz\n", od_table->UclkFmax);<br>
> + break;<br>
> + case SMU_OD_VDDC_CURVE:<br>
> + if (!smu->od_enabled || !od_table || !od_settings)<br>
> + break;<br>
> + if (!navi10_od_feature_is_supported(od_settings,<br>
> SMU_11_0_ODCAP_GFXCLK_CURVE))<br>
> + break;<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "OD_VDDC_CURVE:\n");<br>
> + for (i = 0; i < 3; i++) {<br>
> + switch (i) {<br>
> + case 0:<br>
> + curve_settings = &od_table->GfxclkFreq1;<br>
> + break;<br>
> + case 1:<br>
> + curve_settings = &od_table->GfxclkFreq2;<br>
> + break;<br>
> + case 2:<br>
> + curve_settings = &od_table->GfxclkFreq3;<br>
> + break;<br>
> + default:<br>
> + break;<br>
> + }<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "%d: %uMHz %umV\n",<br>
> + i, curve_settings[0],<br>
> + curve_settings[1] /<br>
> NAVI10_VOLTAGE_SCALE);<br>
> + }<br>
> + break;<br>
> + case SMU_OD_RANGE:<br>
> + if (!smu->od_enabled || !od_table || !od_settings)<br>
> + break;<br>
> + *offset += sysfs_emit_at(buf, *offset, "%s:\n",<br>
> "OD_RANGE");<br>
> +<br>
> + if (navi10_od_feature_is_supported(od_settings,<br>
> SMU_11_0_ODCAP_GFXCLK_LIMITS)) {<br>
> + navi10_od_setting_get_range(od_settings,<br>
> SMU_11_0_ODSETTING_GFXCLKFMIN,<br>
> + &min_value, NULL);<br>
> + navi10_od_setting_get_range(od_settings,<br>
> SMU_11_0_ODSETTING_GFXCLKFMAX,<br>
> + NULL, &max_value);<br>
> + *offset+= sysfs_emit_at(buf, *offset,<br>
> "SCLK: %7uMhz %10uMhz\n",<br>
> + min_value, max_value);<br>
> + }<br>
> +<br>
> + if (navi10_od_feature_is_supported(od_settings,<br>
> SMU_11_0_ODCAP_UCLK_MAX)) {<br>
> + navi10_od_setting_get_range(od_settings,<br>
> SMU_11_0_ODSETTING_UCLKFMAX,<br>
> + &min_value, &max_value);<br>
> + *offset+= sysfs_emit_at(buf, *offset,<br>
> "MCLK: %7uMhz %10uMhz\n",<br>
> + min_value, max_value);<br>
> + }<br>
> +<br>
> + if (navi10_od_feature_is_supported(od_settings,<br>
> SMU_11_0_ODCAP_GFXCLK_CURVE)) {<br>
> + navi10_od_setting_get_range(od_settings,<br>
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1,<br>
> + &min_value, &max_value);<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n",<br>
> + min_value, max_value);<br>
> + navi10_od_setting_get_range(od_settings,<br>
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1,<br>
> + &min_value, &max_value);<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n",<br>
> + min_value, max_value);<br>
> + navi10_od_setting_get_range(od_settings,<br>
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2,<br>
> + &min_value, &max_value);<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n",<br>
> + min_value, max_value);<br>
> + navi10_od_setting_get_range(od_settings,<br>
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2,<br>
> + &min_value, &max_value);<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n",<br>
> + min_value, max_value);<br>
> + navi10_od_setting_get_range(od_settings,<br>
> SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3,<br>
> + &min_value, &max_value);<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n",<br>
> + min_value, max_value);<br>
> + navi10_od_setting_get_range(od_settings,<br>
> SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3,<br>
> + &min_value, &max_value);<br>
> + *offset += sysfs_emit_at(buf, *offset,<br>
> "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n",<br>
> + min_value, max_value);<br>
> + }<br>
> +<br>
> + break;<br>
> + default:<br>
> + break;<br>
> + }<br>
> +<br>
> + return (*offset - save_offset);<br>
> +}<br>
> +<br>
> static int navi10_print_clk_levels(struct smu_context *smu,<br>
> enum smu_clk_type clk_type, char *buf)<br>
> {<br>
> @@ -3245,6 +3433,7 @@ static const struct pptable_funcs navi10_ppt_funcs<br>
> = {<br>
> .i2c_init = navi10_i2c_control_init,<br>
> .i2c_fini = navi10_i2c_control_fini,<br>
> .print_clk_levels = navi10_print_clk_levels,<br>
> + .emit_clk_levels = navi10_emit_clk_levels,<br>
> .force_clk_levels = navi10_force_clk_levels,<br>
> .populate_umd_state_clk = navi10_populate_umd_state_clk,<br>
> .get_clock_by_type_with_latency =<br>
> navi10_get_clock_by_type_with_latency,<br>
> --<br>
> 2.34.1<br>
</div>
</span></font></div>
</div>
</body>
</html>