[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