diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4419-drm-amdgpu-smu_v11-Unify-and-fix-power-limits.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4419-drm-amdgpu-smu_v11-Unify-and-fix-power-limits.patch | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4419-drm-amdgpu-smu_v11-Unify-and-fix-power-limits.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4419-drm-amdgpu-smu_v11-Unify-and-fix-power-limits.patch new file mode 100644 index 00000000..5ab66eeb --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4419-drm-amdgpu-smu_v11-Unify-and-fix-power-limits.patch @@ -0,0 +1,318 @@ +From bded65628b641bb8cb50be6190abf36500a91624 Mon Sep 17 00:00:00 2001 +From: Matt Coffin <mcoffin13@gmail.com> +Date: Mon, 11 Nov 2019 11:36:31 -0700 +Subject: [PATCH 4419/4736] drm/amdgpu/smu_v11: Unify and fix power limits + +[Why] +On Navi10, and presumably arcterus, updating pp_table via sysfs would +not re-scale the maximum possible power limit one can set. On navi10, +the SMU code ignored the power percentage overdrive setting entirely, +and would not allow you to exceed the default power limit at all. + +[How] +Adding a function to the SMU interface to get the pptable version of the +default power limit allows ASIC-specific code to provide the correct +maximum-settable power limit for the current pptable. + +v3: fix spelling (Alex) + +Change-Id: Idfa0d2ec64da34520e2928e5011ac3c54bf60a4d +Reviewed-by: Evan Quan <evan.quan@amd.com> +Signed-off-by: Matt Coffin <mcoffin13@gmail.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 12 +++++- + drivers/gpu/drm/amd/powerplay/arcturus_ppt.c | 23 ++++++----- + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 4 +- + drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 2 + + .../drm/amd/powerplay/inc/smu_v11_0_pptable.h | 2 + + drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 22 +++++----- + drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 40 +++++++++++++++++-- + drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 1 - + 8 files changed, 78 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +index 76a4154b3be2..df5487fae20a 100644 +--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +@@ -1109,7 +1109,7 @@ static int smu_smc_table_hw_init(struct smu_context *smu, + if (ret) + return ret; + +- ret = smu_get_power_limit(smu, &smu->default_power_limit, true, false); ++ ret = smu_get_power_limit(smu, &smu->default_power_limit, false, false); + if (ret) + return ret; + } +@@ -2511,3 +2511,13 @@ int smu_get_dpm_clock_table(struct smu_context *smu, + + return ret; + } ++ ++uint32_t smu_get_pptable_power_limit(struct smu_context *smu) ++{ ++ uint32_t ret = 0; ++ ++ if (smu->ppt_funcs->get_pptable_power_limit) ++ ret = smu->ppt_funcs->get_pptable_power_limit(smu); ++ ++ return ret; ++} +diff --git a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c +index 4315a887e918..6d1401b30aaf 100644 +--- a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c +@@ -1261,15 +1261,14 @@ arcturus_get_profiling_clk_mask(struct smu_context *smu, + + static int arcturus_get_power_limit(struct smu_context *smu, + uint32_t *limit, +- bool asic_default) ++ bool cap) + { + PPTable_t *pptable = smu->smu_table.driver_pptable; + uint32_t asic_default_power_limit = 0; + int ret = 0; + int power_src; + +- if (!smu->default_power_limit || +- !smu->power_limit) { ++ if (!smu->power_limit) { + if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) { + power_src = smu_power_get_index(smu, SMU_POWER_SOURCE_AC); + if (power_src < 0) +@@ -1292,17 +1291,11 @@ static int arcturus_get_power_limit(struct smu_context *smu, + pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; + } + +- if (smu->od_enabled) { +- asic_default_power_limit *= (100 + smu->smu_table.TDPODLimit); +- asic_default_power_limit /= 100; +- } +- +- smu->default_power_limit = asic_default_power_limit; + smu->power_limit = asic_default_power_limit; + } + +- if (asic_default) +- *limit = smu->default_power_limit; ++ if (cap) ++ *limit = smu_v11_0_get_max_power_limit(smu); + else + *limit = smu->power_limit; + +@@ -2070,6 +2063,13 @@ static void arcturus_i2c_eeprom_control_fini(struct i2c_adapter *control) + i2c_del_adapter(control); + } + ++static uint32_t arcturus_get_pptable_power_limit(struct smu_context *smu) ++{ ++ PPTable_t *pptable = smu->smu_table.driver_pptable; ++ ++ return pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; ++} ++ + static const struct pptable_funcs arcturus_ppt_funcs = { + /* translate smu index into arcturus specific index */ + .get_smu_msg_index = arcturus_get_smu_msg_index, +@@ -2160,6 +2160,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { + .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, + .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range, + .override_pcie_parameters = smu_v11_0_override_pcie_parameters, ++ .get_pptable_power_limit = arcturus_get_pptable_power_limit, + }; + + void arcturus_set_ppt_funcs(struct smu_context *smu) +diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +index 8120e7587585..999445c5c010 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +@@ -261,7 +261,6 @@ struct smu_table_context + struct smu_table *tables; + struct smu_table memory_pool; + uint8_t thermal_controller_type; +- uint16_t TDPODLimit; + + void *overdrive_table; + }; +@@ -548,6 +547,7 @@ struct pptable_funcs { + int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max); + int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max); + int (*override_pcie_parameters)(struct smu_context *smu); ++ uint32_t (*get_pptable_power_limit)(struct smu_context *smu); + }; + + int smu_load_microcode(struct smu_context *smu); +@@ -717,4 +717,6 @@ int smu_get_uclk_dpm_states(struct smu_context *smu, + int smu_get_dpm_clock_table(struct smu_context *smu, + struct dpm_clocks *clock_table); + ++uint32_t smu_get_pptable_power_limit(struct smu_context *smu); ++ + #endif +diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h +index 0ec6ed0456e0..0269fac1a77b 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h +@@ -253,4 +253,6 @@ int smu_v11_0_override_pcie_parameters(struct smu_context *smu); + + int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size); + ++uint32_t smu_v11_0_get_max_power_limit(struct smu_context *smu); ++ + #endif +diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0_pptable.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0_pptable.h +index 86cdc3393eac..b2f96a101124 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0_pptable.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0_pptable.h +@@ -141,7 +141,9 @@ struct smu_11_0_powerplay_table + struct smu_11_0_power_saving_clock_table power_saving_clock; + struct smu_11_0_overdrive_table overdrive_table; + ++#ifndef SMU_11_0_PARTIAL_PPTABLE + PPTable_t smc_pptable; //PPTable_t in smu11_driver_if.h ++#endif + } __attribute__((packed)); + + #endif +diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +index 5c6ffbd0d884..17ccdb74f4e2 100644 +--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +@@ -1632,17 +1632,22 @@ static int navi10_display_disable_memory_clock_switch(struct smu_context *smu, + return ret; + } + ++static uint32_t navi10_get_pptable_power_limit(struct smu_context *smu) ++{ ++ PPTable_t *pptable = smu->smu_table.driver_pptable; ++ return pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; ++} ++ + static int navi10_get_power_limit(struct smu_context *smu, + uint32_t *limit, +- bool asic_default) ++ bool cap) + { + PPTable_t *pptable = smu->smu_table.driver_pptable; + uint32_t asic_default_power_limit = 0; + int ret = 0; + int power_src; + +- if (!smu->default_power_limit || +- !smu->power_limit) { ++ if (!smu->power_limit) { + if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) { + power_src = smu_power_get_index(smu, SMU_POWER_SOURCE_AC); + if (power_src < 0) +@@ -1665,17 +1670,11 @@ static int navi10_get_power_limit(struct smu_context *smu, + pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; + } + +- if (smu->od_enabled) { +- asic_default_power_limit *= (100 + smu->smu_table.TDPODLimit); +- asic_default_power_limit /= 100; +- } +- +- smu->default_power_limit = asic_default_power_limit; + smu->power_limit = asic_default_power_limit; + } + +- if (asic_default) +- *limit = smu->default_power_limit; ++ if (cap) ++ *limit = smu_v11_0_get_max_power_limit(smu); + else + *limit = smu->power_limit; + +@@ -2023,6 +2022,7 @@ static const struct pptable_funcs navi10_ppt_funcs = { + .override_pcie_parameters = smu_v11_0_override_pcie_parameters, + .set_default_od_settings = navi10_set_default_od_settings, + .od_edit_dpm_table = navi10_od_edit_dpm_table, ++ .get_pptable_power_limit = navi10_get_pptable_power_limit, + }; + + void navi10_set_ppt_funcs(struct smu_context *smu) +diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +index 13ae44ca3504..928877f73dfd 100644 +--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +@@ -20,6 +20,8 @@ + * OTHER DEALINGS IN THE SOFTWARE. + */ + ++#define SMU_11_0_PARTIAL_PPTABLE ++ + #include "pp_debug.h" + #include <linux/firmware.h> + #include "amdgpu.h" +@@ -28,6 +30,7 @@ + #include "atomfirmware.h" + #include "amdgpu_atomfirmware.h" + #include "smu_v11_0.h" ++#include "smu_v11_0_pptable.h" + #include "soc15_common.h" + #include "atom.h" + #include "amd_pcie.h" +@@ -1045,13 +1048,44 @@ int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu) + return 0; + } + ++uint32_t smu_v11_0_get_max_power_limit(struct smu_context *smu) { ++ uint32_t od_limit, max_power_limit; ++ struct smu_11_0_powerplay_table *powerplay_table = NULL; ++ struct smu_table_context *table_context = &smu->smu_table; ++ powerplay_table = table_context->power_play_table; ++ ++ max_power_limit = smu_get_pptable_power_limit(smu); ++ ++ if (!max_power_limit) { ++ // If we couldn't get the table limit, fall back on first-read value ++ if (!smu->default_power_limit) ++ smu->default_power_limit = smu->power_limit; ++ max_power_limit = smu->default_power_limit; ++ } ++ ++ if (smu->od_enabled) { ++ od_limit = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); ++ ++ pr_debug("ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_limit, smu->default_power_limit); ++ ++ max_power_limit *= (100 + od_limit); ++ max_power_limit /= 100; ++ } ++ ++ return max_power_limit; ++} ++ + int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n) + { + int ret = 0; ++ uint32_t max_power_limit; ++ ++ max_power_limit = smu_v11_0_get_max_power_limit(smu); + +- if (n > smu->default_power_limit) { +- pr_err("New power limit is over the max allowed %d\n", +- smu->default_power_limit); ++ if (n > max_power_limit) { ++ pr_err("New power limit (%d) is over the max allowed %d\n", ++ n, ++ max_power_limit); + return -EINVAL; + } + +diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +index e00ffbbde791..399697a2ad7f 100644 +--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +@@ -466,7 +466,6 @@ static int vega20_store_powerplay_table(struct smu_context *smu) + sizeof(PPTable_t)); + + table_context->thermal_controller_type = powerplay_table->ucThermalControllerType; +- table_context->TDPODLimit = le32_to_cpu(powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE]); + + return 0; + } +-- +2.17.1 + |