diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0822-drm-amd-pp-handle-negative-values-when-reading-OD.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/0822-drm-amd-pp-handle-negative-values-when-reading-OD.patch | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0822-drm-amd-pp-handle-negative-values-when-reading-OD.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0822-drm-amd-pp-handle-negative-values-when-reading-OD.patch new file mode 100644 index 00000000..5636af70 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0822-drm-amd-pp-handle-negative-values-when-reading-OD.patch @@ -0,0 +1,211 @@ +From 49cdc9ce20237ed66727d19f1d9bc64848301edc Mon Sep 17 00:00:00 2001 +From: "Greathouse, Joseph" <Joseph.Greathouse@amd.com> +Date: Mon, 19 Nov 2018 16:59:28 +0000 +Subject: [PATCH 0822/2940] drm/amd/pp: handle negative values when reading OD + +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. + +Acked-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Joseph Greathouse <Joseph.Greathouse@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@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 198ca40567a7..21aa332ed47c 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +@@ -4528,12 +4528,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; + } +@@ -4570,12 +4570,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 9a773d8e880d..2679d1240fa1 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +@@ -1323,12 +1323,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; + } +@@ -1368,12 +1369,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 + |