aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/0822-drm-amd-pp-handle-negative-values-when-reading-OD.patch
diff options
context:
space:
mode:
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.patch211
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
+