[PATCH] drm/amd/pp: handle negative values when reading OD
Alex Deucher
alexdeucher at gmail.com
Mon Nov 19 19:20:42 UTC 2018
On Mon, Nov 19, 2018 at 11:59 AM Greathouse, Joseph
<Joseph.Greathouse at amd.com> wrote:
>
> Reading the sysfs files pp_sclk_od and pp_mclk_od return the
> percentage difference between the VBIOS-provided default
> frequency and the current (possibly user-set) frequency in
> the highest SCLK and MCLK DPM states, respectively.
>
> Writing to these files provides an easy mechanism for
> setting a higher-than-default maximum frequency. We
> normally only allow values >= 0 to be written here.
>
> However, with the addition of pp_od_clk_voltage, we now
> allow users to set custom DPM tables. If they then set
> the maximum DPM state to something less than the default,
> later reads of pp_*_od should return a negative value.
> The highest DPM state is now less than the VBIOS-provided
> default, so the percentage is negative.
>
> The math to calculate this was originally performed with
> unsigned values, meaning reads that should return negative
> values returned meaningless data. This patch corrects that
> issue and normalizes how all of the calculations are done
> across the various hwmgr types.
>
> Signed-off-by: Joseph Greathouse <Joseph.Greathouse at amd.com>
Acked-by: Alex Deucher <alexander.deucher at amd.com>
> ---
> .../gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 20 +++++++--------
> .../drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 25 ++++++++-----------
> .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 23 ++++++++---------
> .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 18 +++++++------
> 4 files changed, 40 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
> index ed35ec0341e6..88f6b35ea6fe 100644
> --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
> @@ -4525,12 +4525,12 @@ static int smu7_get_sclk_od(struct pp_hwmgr *hwmgr)
> struct smu7_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table);
> struct smu7_single_dpm_table *golden_sclk_table =
> &(data->golden_dpm_table.sclk_table);
> - int value;
> + int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
> + int golden_value = golden_sclk_table->dpm_levels
> + [golden_sclk_table->count - 1].value;
>
> - value = (sclk_table->dpm_levels[sclk_table->count - 1].value -
> - golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) *
> - 100 /
> - golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
> + value -= golden_value;
> + value = DIV_ROUND_UP(value * 100, golden_value);
>
> return value;
> }
> @@ -4567,12 +4567,12 @@ static int smu7_get_mclk_od(struct pp_hwmgr *hwmgr)
> struct smu7_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table);
> struct smu7_single_dpm_table *golden_mclk_table =
> &(data->golden_dpm_table.mclk_table);
> - int value;
> + int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
> + int golden_value = golden_mclk_table->dpm_levels
> + [golden_mclk_table->count - 1].value;
>
> - value = (mclk_table->dpm_levels[mclk_table->count - 1].value -
> - golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) *
> - 100 /
> - golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value;
> + value -= golden_value;
> + value = DIV_ROUND_UP(value * 100, golden_value);
>
> return value;
> }
> diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
> index 8c4db86bb4b7..e2bc6e0c229f 100644
> --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
> @@ -4522,15 +4522,13 @@ static int vega10_get_sclk_od(struct pp_hwmgr *hwmgr)
> struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
> struct vega10_single_dpm_table *golden_sclk_table =
> &(data->golden_dpm_table.gfx_table);
> - int value;
> -
> - value = (sclk_table->dpm_levels[sclk_table->count - 1].value -
> - golden_sclk_table->dpm_levels
> - [golden_sclk_table->count - 1].value) *
> - 100 /
> - golden_sclk_table->dpm_levels
> + int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
> + int golden_value = golden_sclk_table->dpm_levels
> [golden_sclk_table->count - 1].value;
>
> + value -= golden_value;
> + value = DIV_ROUND_UP(value * 100, golden_value);
> +
> return value;
> }
>
> @@ -4575,16 +4573,13 @@ static int vega10_get_mclk_od(struct pp_hwmgr *hwmgr)
> struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
> struct vega10_single_dpm_table *golden_mclk_table =
> &(data->golden_dpm_table.mem_table);
> - int value;
> -
> - value = (mclk_table->dpm_levels
> - [mclk_table->count - 1].value -
> - golden_mclk_table->dpm_levels
> - [golden_mclk_table->count - 1].value) *
> - 100 /
> - golden_mclk_table->dpm_levels
> + int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
> + int golden_value = golden_mclk_table->dpm_levels
> [golden_mclk_table->count - 1].value;
>
> + value -= golden_value;
> + value = DIV_ROUND_UP(value * 100, golden_value);
> +
> return value;
> }
>
> diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
> index 74bc37308dc0..54364444ecd1 100644
> --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
> @@ -2243,12 +2243,12 @@ static int vega12_get_sclk_od(struct pp_hwmgr *hwmgr)
> struct vega12_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
> struct vega12_single_dpm_table *golden_sclk_table =
> &(data->golden_dpm_table.gfx_table);
> - int value;
> + int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
> + int golden_value = golden_sclk_table->dpm_levels
> + [golden_sclk_table->count - 1].value;
>
> - value = (sclk_table->dpm_levels[sclk_table->count - 1].value -
> - golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) *
> - 100 /
> - golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
> + value -= golden_value;
> + value = DIV_ROUND_UP(value * 100, golden_value);
>
> return value;
> }
> @@ -2264,16 +2264,13 @@ static int vega12_get_mclk_od(struct pp_hwmgr *hwmgr)
> struct vega12_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
> struct vega12_single_dpm_table *golden_mclk_table =
> &(data->golden_dpm_table.mem_table);
> - int value;
> -
> - value = (mclk_table->dpm_levels
> - [mclk_table->count - 1].value -
> - golden_mclk_table->dpm_levels
> - [golden_mclk_table->count - 1].value) *
> - 100 /
> - golden_mclk_table->dpm_levels
> + int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
> + int golden_value = golden_mclk_table->dpm_levels
> [golden_mclk_table->count - 1].value;
>
> + value -= golden_value;
> + value = DIV_ROUND_UP(value * 100, golden_value);
> +
> return value;
> }
>
> diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
> index f2daf00cc911..ec2029bae606 100644
> --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
> @@ -1313,12 +1313,13 @@ static int vega20_get_sclk_od(
> &(data->dpm_table.gfx_table);
> struct vega20_single_dpm_table *golden_sclk_table =
> &(data->golden_dpm_table.gfx_table);
> - int value;
> + int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
> + int golden_value = golden_sclk_table->dpm_levels
> + [golden_sclk_table->count - 1].value;
>
> /* od percentage */
> - value = DIV_ROUND_UP((sclk_table->dpm_levels[sclk_table->count - 1].value -
> - golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * 100,
> - golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value);
> + value -= golden_value;
> + value = DIV_ROUND_UP(value * 100, golden_value);
>
> return value;
> }
> @@ -1358,12 +1359,13 @@ static int vega20_get_mclk_od(
> &(data->dpm_table.mem_table);
> struct vega20_single_dpm_table *golden_mclk_table =
> &(data->golden_dpm_table.mem_table);
> - int value;
> + int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
> + int golden_value = golden_mclk_table->dpm_levels
> + [golden_mclk_table->count - 1].value;
>
> /* od percentage */
> - value = DIV_ROUND_UP((mclk_table->dpm_levels[mclk_table->count - 1].value -
> - golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * 100,
> - golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value);
> + value -= golden_value;
> + value = DIV_ROUND_UP(value * 100, golden_value);
>
> return value;
> }
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
More information about the amd-gfx
mailing list