[AMD Official Use Only - Internal Distribution Only] -----Original Message----- From: Gao, Likun <Likun.Gao@xxxxxxx> Sent: Tuesday, June 2, 2020 5:09 PM To: amd-gfx@xxxxxxxxxxxxxxxxxxxxx Cc: Feng, Kenneth <Kenneth.Feng@xxxxxxx>; Quan, Evan <Evan.Quan@xxxxxxx>; Wang, Kevin(Yang) <Kevin1.Wang@xxxxxxx>; Gao, Likun <Likun.Gao@xxxxxxx> Subject: [PATCH] drm/amd/powerplay: move powerplay table operation out of smu_v11_0.c From: Likun Gao <Likun.Gao@xxxxxxx> move smu_v11_0_get_max_power_limit and smu_v11_0_set_thermal_range function from smu_v11_0.c to asic specific _ppt.c to avoid powerplay table conflict with different ASIC with smu11. Signed-off-by: Likun Gao <Likun.Gao@xxxxxxx> Change-Id: I194f44e9f59daf19fa4758ed746fa13ccece4308 --- drivers/gpu/drm/amd/powerplay/arcturus_ppt.c | 64 ++++++++++++++++++- .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 2 + drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 2 - drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 64 ++++++++++++++++++- drivers/gpu/drm/amd/powerplay/smu_internal.h | 5 ++ drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 63 +----------------- 6 files changed, 135 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c index 1c66b7d7139c..d5527e834a8e 100644 --- a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c @@ -37,6 +37,8 @@ #include "arcturus_ppsmc.h" #include "nbio/nbio_7_4_offset.h" #include "nbio/nbio_7_4_sh_mask.h" +#include "thm/thm_11_0_2_offset.h" +#include "thm/thm_11_0_2_sh_mask.h" #include "amdgpu_xgmi.h" #include <linux/i2c.h> #include <linux/pci.h> @@ -1324,7 +1326,7 @@ static int arcturus_get_power_limit(struct smu_context *smu, } if (cap) -*limit = smu_v11_0_get_max_power_limit(smu); +*limit = smu_get_max_power_limit(smu); [Quan, Evan] I think you can just call atcturus_get_max_power_limit directly here without need of another wrapper. else *limit = smu->power_limit; @@ -2286,6 +2288,64 @@ static int arcturus_set_df_cstate(struct smu_context *smu, return smu_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state, NULL); } +static int arcturus_set_thermal_range(struct smu_context *smu, + struct smu_temperature_range range) +{ +struct amdgpu_device *adev = smu->adev; +int low = SMU_THERMAL_MINIMUM_ALERT_TEMP; +int high = SMU_THERMAL_MAXIMUM_ALERT_TEMP; +uint32_t val; +struct smu_table_context *table_context = &smu->smu_table; +struct smu_11_0_powerplay_table *powerplay_table = table_context->power_play_table; + +low = max(SMU_THERMAL_MINIMUM_ALERT_TEMP, +range.min / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES); +high = min((uint16_t)SMU_THERMAL_MAXIMUM_ALERT_TEMP, powerplay_table->software_shutdown_temp); + +if (low > high) +return -EINVAL; + +val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 0); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 0); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high & 0xff)); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low & 0xff)); +val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); + +WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val); + +return 0; +} + +static uint32_t atcturus_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; +} + static const struct pptable_funcs arcturus_ppt_funcs = { /* translate smu index into arcturus specific index */ .get_smu_msg_index = arcturus_get_smu_msg_index, @@ -2379,6 +2439,8 @@ static const struct pptable_funcs arcturus_ppt_funcs = { .override_pcie_parameters = smu_v11_0_override_pcie_parameters, .get_pptable_power_limit = arcturus_get_pptable_power_limit, .set_df_cstate = arcturus_set_df_cstate, +.set_thermal_range = arcturus_set_thermal_range, +.get_max_power_limit = atcturus_get_max_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 928eed220f93..0453482fb748 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -574,6 +574,8 @@ struct pptable_funcs { uint32_t (*get_pptable_power_limit)(struct smu_context *smu); int (*disable_umc_cdr_12gbps_workaround)(struct smu_context *smu); int (*set_power_source)(struct smu_context *smu, enum smu_power_src_type power_src); +int (*set_thermal_range)(struct smu_context *smu, struct smu_temperature_range range); +uint32_t (*get_max_power_limit)(struct smu_context *smu); }; int smu_load_microcode(struct smu_context *smu); 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 1f5830bbcc3e..4ad3f07891fe 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h @@ -262,8 +262,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); - int smu_v11_0_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level); diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c index 0c9be864d072..3641f059186e 100644 --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c @@ -37,6 +37,8 @@ #include "smu_v11_0_ppsmc.h" #include "nbio/nbio_2_3_offset.h" #include "nbio/nbio_2_3_sh_mask.h" +#include "thm/thm_11_0_2_offset.h" +#include "thm/thm_11_0_2_sh_mask.h" #include "asic_reg/mp/mp_11_0_sh_mask.h" @@ -1841,7 +1843,7 @@ static int navi10_get_power_limit(struct smu_context *smu, } if (cap) -*limit = smu_v11_0_get_max_power_limit(smu); +*limit = smu_get_max_power_limit(smu); [Quan, Evan] Use navi10_get_max_power_limit() here. else *limit = smu->power_limit; @@ -2253,6 +2255,64 @@ static int navi10_disable_umc_cdr_12gbps_workaround(struct smu_context *smu) return navi10_dummy_pstate_control(smu, true); } +static int navi10_set_thermal_range(struct smu_context *smu, + struct smu_temperature_range range) +{ +struct amdgpu_device *adev = smu->adev; +int low = SMU_THERMAL_MINIMUM_ALERT_TEMP; +int high = SMU_THERMAL_MAXIMUM_ALERT_TEMP; +uint32_t val; +struct smu_table_context *table_context = &smu->smu_table; +struct smu_11_0_powerplay_table *powerplay_table = table_context->power_play_table; + +low = max(SMU_THERMAL_MINIMUM_ALERT_TEMP, +range.min / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES); +high = min((uint16_t)SMU_THERMAL_MAXIMUM_ALERT_TEMP, powerplay_table->software_shutdown_temp); + +if (low > high) +return -EINVAL; + +val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 0); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 0); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high & 0xff)); +val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low & 0xff)); +val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); + +WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val); + +return 0; +} + +static uint32_t navi10_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; +} + static const struct pptable_funcs navi10_ppt_funcs = { .tables_init = navi10_tables_init, .alloc_dpm_context = navi10_allocate_dpm_context, @@ -2348,6 +2408,8 @@ static const struct pptable_funcs navi10_ppt_funcs = { .run_btc = navi10_run_btc, .disable_umc_cdr_12gbps_workaround = navi10_disable_umc_cdr_12gbps_workaround, .set_power_source = smu_v11_0_set_power_source, +.set_thermal_range = navi10_set_thermal_range, +.get_max_power_limit = navi10_get_max_power_limit, }; void navi10_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/powerplay/smu_internal.h b/drivers/gpu/drm/amd/powerplay/smu_internal.h index c97444841abc..093b63d405e5 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_internal.h +++ b/drivers/gpu/drm/amd/powerplay/smu_internal.h @@ -208,6 +208,11 @@ static inline int smu_send_smc_msg(struct smu_context *smu, enum smu_message_typ #define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) \ ((smu)->ppt_funcs->update_pcie_parameters ? (smu)->ppt_funcs->update_pcie_parameters((smu), (pcie_gen_cap), (pcie_width_cap)) : 0) +#define smu_set_thermal_range(smu, range) \ +((smu)->ppt_funcs->set_thermal_range ? (smu)->ppt_funcs->set_thermal_range((smu), (range)) : 0) +#define smu_get_max_power_limit(smu) \ +((smu)->ppt_funcs->get_max_power_limit ? (smu)->ppt_funcs->get_max_power_limit((smu)) : 0) + #define smu_disable_umc_cdr_12gbps_workaround(smu) \ ((smu)->ppt_funcs->disable_umc_cdr_12gbps_workaround ? (smu)->ppt_funcs->disable_umc_cdr_12gbps_workaround((smu)) : 0) diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c index 4c2d98becc16..5133110dc5c8 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c @@ -32,7 +32,6 @@ #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" @@ -1093,33 +1092,6 @@ 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; @@ -1128,7 +1100,7 @@ int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n) if (amdgpu_sriov_vf(smu->adev)) return 0; -max_power_limit = smu_v11_0_get_max_power_limit(smu); +max_power_limit = smu_get_max_power_limit(smu); if (n > max_power_limit) { pr_err("New power limit (%d) is over the max allowed %d\n", @@ -1186,37 +1158,6 @@ int smu_v11_0_get_current_clk_freq(struct smu_context *smu, return ret; } -static int smu_v11_0_set_thermal_range(struct smu_context *smu, - struct smu_temperature_range range) -{ -struct amdgpu_device *adev = smu->adev; -int low = SMU_THERMAL_MINIMUM_ALERT_TEMP; -int high = SMU_THERMAL_MAXIMUM_ALERT_TEMP; -uint32_t val; -struct smu_table_context *table_context = &smu->smu_table; -struct smu_11_0_powerplay_table *powerplay_table = table_context->power_play_table; - -low = max(SMU_THERMAL_MINIMUM_ALERT_TEMP, -range.min / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES); -high = min((uint16_t)SMU_THERMAL_MAXIMUM_ALERT_TEMP, powerplay_table->software_shutdown_temp); - -if (low > high) -return -EINVAL; - -val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL); -val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); -val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); -val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 0); -val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 0); -val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high & 0xff)); -val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low & 0xff)); -val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); - -WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val); - -return 0; -} - static int smu_v11_0_enable_thermal_alert(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; @@ -1244,7 +1185,7 @@ int smu_v11_0_start_thermal_control(struct smu_context *smu) return ret; if (smu->smu_table.thermal_controller_type) { -ret = smu_v11_0_set_thermal_range(smu, range); +ret = smu_set_thermal_range(smu, range); [Quan, Evan] It seems you were not working on the latest code. And the sequence here can be revised a little to avoid cross calling. smu_enable_thermal_alert (from smu.c) | |-- navi10_enable_thermal_alert (from navi10_ppt.c) |-- naiv10_get_thermal_temperature_range() |-- navi10_set_thermal_temperature_range() |-- smu_v11_0_set_thermal_alert() if (ret) return ret; -- 2.25.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx