From a6bcffa596770b0c54b3ddccbc115bdab4df08e9 Mon Sep 17 00:00:00 2001 From: Hawking Zhang Date: Wed, 1 May 2024 00:12:34 +0800 Subject: drm/amdgpu: Add smu v13_0_14 ip block Add smu v13_0_14 ip block support Signed-off-by: Hawking Zhang Reviewed-by: Le Ma Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c') diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 7789b313285c..bdf9f8031187 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -705,6 +705,7 @@ static int smu_set_funcs(struct amdgpu_device *adev) smu_v13_0_0_set_ppt_funcs(smu); break; case IP_VERSION(13, 0, 6): + case IP_VERSION(13, 0, 14): smu_v13_0_6_set_ppt_funcs(smu); /* Enable pp_od_clk_voltage node */ smu->od_enabled = true; @@ -2716,6 +2717,7 @@ int smu_get_power_limit(void *handle, switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(13, 0, 2): case IP_VERSION(13, 0, 6): + case IP_VERSION(13, 0, 14): case IP_VERSION(11, 0, 7): case IP_VERSION(11, 0, 11): case IP_VERSION(11, 0, 12): -- cgit From 3474e02ed5b30c625c1739f10375ef940bb23382 Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Wed, 31 Jan 2024 15:36:12 +0800 Subject: drm/amd/pm: support mode1 reset on smu_v14_0_3 support mode1 reset on smu_v14_0_3 Signed-off-by: Kenneth Feng Reviewed-by: Likun Gao Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc24.c | 1 + drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c') diff --git a/drivers/gpu/drm/amd/amdgpu/soc24.c b/drivers/gpu/drm/amd/amdgpu/soc24.c index 1bbcd23e703b..12900488dd61 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc24.c +++ b/drivers/gpu/drm/amd/amdgpu/soc24.c @@ -204,6 +204,7 @@ soc24_asic_reset_method(struct amdgpu_device *adev) switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(14, 0, 2): + case IP_VERSION(14, 0, 3): return AMD_RESET_METHOD_MODE1; default: if (amdgpu_dpm_is_baco_supported(adev)) diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index bdf9f8031187..dc0d3a9f1d6d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -1845,6 +1845,8 @@ static int smu_disable_dpms(struct smu_context *smu) case IP_VERSION(13, 0, 0): case IP_VERSION(13, 0, 7): case IP_VERSION(13, 0, 10): + case IP_VERSION(14, 0, 2): + case IP_VERSION(14, 0, 3): return 0; default: break; -- cgit From f683f24093dd94a831085fe0ea8e9dc4c6c1a2d1 Mon Sep 17 00:00:00 2001 From: Ma Jun Date: Sun, 28 Apr 2024 15:58:10 +0800 Subject: drm/amdgpu/pm: Fix the param type of set_power_profile_mode Function .set_power_profile_mode need an array as input parameter. So define variable workload as an array to fix the below coverity warning. "Passing &workload to function hwmgr->hwmgr_func->set_power_profile_mode which uses it as an array. This might corrupt or misinterpret adjacent memory locations" Signed-off-by: Ma Jun Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c | 8 ++++---- drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c | 8 ++++---- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 16 ++++++++-------- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c') diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c index 1c40a362d5ab..a71c6117d7e5 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c @@ -929,7 +929,7 @@ static int pp_dpm_switch_power_profile(void *handle, enum PP_SMC_POWER_PROFILE type, bool en) { struct pp_hwmgr *hwmgr = handle; - long workload; + long workload[1]; uint32_t index; if (!hwmgr || !hwmgr->pm_en) @@ -947,12 +947,12 @@ static int pp_dpm_switch_power_profile(void *handle, hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]); index = fls(hwmgr->workload_mask); index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; - workload = hwmgr->workload_setting[index]; + workload[0] = hwmgr->workload_setting[index]; } else { hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]); index = fls(hwmgr->workload_mask); index = index <= Workload_Policy_Max ? index - 1 : 0; - workload = hwmgr->workload_setting[index]; + workload[0] = hwmgr->workload_setting[index]; } if (type == PP_SMC_POWER_PROFILE_COMPUTE && @@ -962,7 +962,7 @@ static int pp_dpm_switch_power_profile(void *handle, } if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) - hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); + hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0); return 0; } diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c index 1d829402cd2e..f4bd8e9357e2 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c @@ -269,7 +269,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set struct pp_power_state *new_ps) { uint32_t index; - long workload; + long workload[1]; if (hwmgr->not_vf) { if (!skip_display_settings) @@ -294,10 +294,10 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { index = fls(hwmgr->workload_mask); index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; - workload = hwmgr->workload_setting[index]; + workload[0] = hwmgr->workload_setting[index]; - if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode) - hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); + if (hwmgr->power_profile_mode != workload[0] && hwmgr->hwmgr_func->set_power_profile_mode) + hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0); } return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index dc0d3a9f1d6d..e61aa4418d44 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -2210,7 +2210,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, { int ret = 0; int index = 0; - long workload; + long workload[1]; struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); if (!skip_display_settings) { @@ -2250,10 +2250,10 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) { index = fls(smu->workload_mask); index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; - workload = smu->workload_setting[index]; + workload[0] = smu->workload_setting[index]; - if (smu->power_profile_mode != workload) - smu_bump_power_profile_mode(smu, &workload, 0); + if (smu->power_profile_mode != workload[0]) + smu_bump_power_profile_mode(smu, workload, 0); } return ret; @@ -2303,7 +2303,7 @@ static int smu_switch_power_profile(void *handle, { struct smu_context *smu = handle; struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); - long workload; + long workload[1]; uint32_t index; if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) @@ -2316,17 +2316,17 @@ static int smu_switch_power_profile(void *handle, smu->workload_mask &= ~(1 << smu->workload_prority[type]); index = fls(smu->workload_mask); index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; - workload = smu->workload_setting[index]; + workload[0] = smu->workload_setting[index]; } else { smu->workload_mask |= (1 << smu->workload_prority[type]); index = fls(smu->workload_mask); index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; - workload = smu->workload_setting[index]; + workload[0] = smu->workload_setting[index]; } if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) - smu_bump_power_profile_mode(smu, &workload, 0); + smu_bump_power_profile_mode(smu, workload, 0); return 0; } -- cgit From 4d154b1ca580fd724f384a7042a5f24611809476 Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Wed, 21 Feb 2024 14:54:49 +0530 Subject: drm/amd/pm: Add support for DPM policies Add support to set/get information about different DPM policies. The support is only available on SOCs which use swsmu architecture. A DPM policy type may be defined with different levels. For example, a policy may be defined to select Pstate preference and then later a pstate preference may be chosen. Signed-off-by: Lijo Lazar Acked-by: Alex Deucher Reviewed-by: Asad Kamal Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 16 +++ drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 30 ++++++ drivers/gpu/drm/amd/pm/amdgpu_pm.c | 133 +++++++++++++++++++++++++ drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 5 + drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 99 ++++++++++++++++++ drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 32 ++++++ 6 files changed, 315 insertions(+) (limited to 'drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c') diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index a0955cfe41ce..4adfe9f0fd92 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -273,6 +273,22 @@ enum pp_xgmi_plpd_mode { XGMI_PLPD_COUNT, }; +enum pp_pm_policy { + PP_PM_POLICY_NONE = -1, + PP_PM_POLICY_SOC_PSTATE = 0, + PP_PM_POLICY_NUM, +}; + +enum pp_policy_soc_pstate { + SOC_PSTATE_DEFAULT = 0, + SOC_PSTATE_0, + SOC_PSTATE_1, + SOC_PSTATE_2, + SOC_PSTAT_COUNT, +}; + +#define PP_POLICY_MAX_LEVELS 5 + #define PP_GROUP_MASK 0xF0000000 #define PP_GROUP_SHIFT 28 diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index eee919577b44..9c991362b398 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -411,6 +411,36 @@ int amdgpu_dpm_set_xgmi_plpd_mode(struct amdgpu_device *adev, int mode) return ret; } +ssize_t amdgpu_dpm_get_pm_policy_info(struct amdgpu_device *adev, + enum pp_pm_policy p_type, char *buf) +{ + struct smu_context *smu = adev->powerplay.pp_handle; + int ret = -EOPNOTSUPP; + + if (is_support_sw_smu(adev)) { + mutex_lock(&adev->pm.mutex); + ret = smu_get_pm_policy_info(smu, p_type, buf); + mutex_unlock(&adev->pm.mutex); + } + + return ret; +} + +int amdgpu_dpm_set_pm_policy(struct amdgpu_device *adev, int policy_type, + int policy_level) +{ + struct smu_context *smu = adev->powerplay.pp_handle; + int ret = -EOPNOTSUPP; + + if (is_support_sw_smu(adev)) { + mutex_lock(&adev->pm.mutex); + ret = smu_set_pm_policy(smu, policy_type, policy_level); + mutex_unlock(&adev->pm.mutex); + } + + return ret; +} + int amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device *adev) { void *pp_handle = adev->powerplay.pp_handle; diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 110f2fc31754..2aebe5a67b03 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -2278,6 +2278,131 @@ static ssize_t amdgpu_set_xgmi_plpd_policy(struct device *dev, return count; } +/* pm policy attributes */ +struct amdgpu_pm_policy_attr { + struct device_attribute dev_attr; + enum pp_pm_policy id; +}; + +static ssize_t amdgpu_get_pm_policy_attr(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = drm_to_adev(ddev); + struct amdgpu_pm_policy_attr *policy_attr; + + policy_attr = + container_of(attr, struct amdgpu_pm_policy_attr, dev_attr); + + if (amdgpu_in_reset(adev)) + return -EPERM; + if (adev->in_suspend && !adev->in_runpm) + return -EPERM; + + return amdgpu_dpm_get_pm_policy_info(adev, policy_attr->id, buf); +} + +static ssize_t amdgpu_set_pm_policy_attr(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = drm_to_adev(ddev); + struct amdgpu_pm_policy_attr *policy_attr; + int ret, num_params = 0; + char delimiter[] = " \n\t"; + char tmp_buf[128]; + char *tmp, *param; + long val; + + if (amdgpu_in_reset(adev)) + return -EPERM; + if (adev->in_suspend && !adev->in_runpm) + return -EPERM; + + count = min(count, sizeof(tmp_buf)); + memcpy(tmp_buf, buf, count); + tmp_buf[count - 1] = '\0'; + tmp = tmp_buf; + + tmp = skip_spaces(tmp); + while ((param = strsep(&tmp, delimiter))) { + if (!strlen(param)) { + tmp = skip_spaces(tmp); + continue; + } + ret = kstrtol(param, 0, &val); + if (ret) + return -EINVAL; + num_params++; + if (num_params > 1) + return -EINVAL; + } + + if (num_params != 1) + return -EINVAL; + + policy_attr = + container_of(attr, struct amdgpu_pm_policy_attr, dev_attr); + + ret = pm_runtime_get_sync(ddev->dev); + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); + return ret; + } + + ret = amdgpu_dpm_set_pm_policy(adev, policy_attr->id, val); + + pm_runtime_mark_last_busy(ddev->dev); + pm_runtime_put_autosuspend(ddev->dev); + + if (ret) + return ret; + + return count; +} + +#define AMDGPU_PM_POLICY_ATTR(_name, _id) \ + static struct amdgpu_pm_policy_attr pm_policy_attr_##_name = { \ + .dev_attr = __ATTR(_name, 0644, amdgpu_get_pm_policy_attr, \ + amdgpu_set_pm_policy_attr), \ + .id = PP_PM_POLICY_##_id, \ + }; + +#define AMDGPU_PM_POLICY_ATTR_VAR(_name) pm_policy_attr_##_name.dev_attr.attr + +AMDGPU_PM_POLICY_ATTR(soc_pstate, SOC_PSTATE) + +static struct attribute *pm_policy_attrs[] = { + &AMDGPU_PM_POLICY_ATTR_VAR(soc_pstate), + NULL +}; + +static umode_t amdgpu_pm_policy_attr_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = drm_to_adev(ddev); + struct amdgpu_pm_policy_attr *policy_attr; + + policy_attr = + container_of(attr, struct amdgpu_pm_policy_attr, dev_attr.attr); + + if (amdgpu_dpm_get_pm_policy_info(adev, policy_attr->id, NULL) == + -ENOENT) + return 0; + + return attr->mode; +} + +const struct attribute_group amdgpu_pm_policy_attr_group = { + .name = "pm_policy", + .attrs = pm_policy_attrs, + .is_visible = amdgpu_pm_policy_attr_visible, +}; + static struct amdgpu_device_attr amdgpu_device_attrs[] = { AMDGPU_DEVICE_ATTR_RW(power_dpm_state, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), AMDGPU_DEVICE_ATTR_RW(power_dpm_force_performance_level, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), @@ -4419,6 +4544,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) dev_info(adev->dev, "overdrive feature is not supported\n"); } + if (amdgpu_dpm_get_pm_policy_info(adev, PP_PM_POLICY_NONE, NULL) != + -EOPNOTSUPP) { + ret = devm_device_add_group(adev->dev, + &amdgpu_pm_policy_attr_group); + if (ret) + goto err_out0; + } + adev->pm.sysfs_initialized = true; return 0; diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index 501f8c726e8d..c0f4037d2041 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -598,4 +598,9 @@ enum pp_smu_status amdgpu_dpm_get_uclk_dpm_states(struct amdgpu_device *adev, unsigned int *num_states); int amdgpu_dpm_get_dpm_clock_table(struct amdgpu_device *adev, struct dpm_clocks *clock_table); +int amdgpu_dpm_set_pm_policy(struct amdgpu_device *adev, int policy_type, + int policy_level); +ssize_t amdgpu_dpm_get_pm_policy_info(struct amdgpu_device *adev, + enum pp_pm_policy p_type, char *buf); + #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index e61aa4418d44..5c4062630c3b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -3498,6 +3498,105 @@ static int smu_get_prv_buffer_details(void *handle, void **addr, size_t *size) return 0; } +static void smu_print_dpm_policy(struct smu_dpm_policy *policy, char *sysbuf, + size_t *size) +{ + size_t offset = *size; + int level; + + for_each_set_bit(level, &policy->level_mask, PP_POLICY_MAX_LEVELS) { + if (level == policy->current_level) + offset += sysfs_emit_at(sysbuf, offset, + "%d : %s*\n", level, + policy->desc->get_desc(policy, level)); + else + offset += sysfs_emit_at(sysbuf, offset, + "%d : %s\n", level, + policy->desc->get_desc(policy, level)); + } + + *size = offset; +} + +ssize_t smu_get_pm_policy_info(struct smu_context *smu, + enum pp_pm_policy p_type, char *sysbuf) +{ + struct smu_dpm_context *dpm_ctxt = &smu->smu_dpm; + struct smu_dpm_policy_ctxt *policy_ctxt; + struct smu_dpm_policy *dpm_policy; + size_t offset = 0; + + policy_ctxt = dpm_ctxt->dpm_policies; + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled || !policy_ctxt || + !policy_ctxt->policy_mask) + return -EOPNOTSUPP; + + if (p_type == PP_PM_POLICY_NONE) + return -EINVAL; + + dpm_policy = smu_get_pm_policy(smu, p_type); + if (!dpm_policy || !dpm_policy->level_mask || !dpm_policy->desc) + return -ENOENT; + + if (!sysbuf) + return -EINVAL; + + smu_print_dpm_policy(dpm_policy, sysbuf, &offset); + + return offset; +} + +struct smu_dpm_policy *smu_get_pm_policy(struct smu_context *smu, + enum pp_pm_policy p_type) +{ + struct smu_dpm_context *dpm_ctxt = &smu->smu_dpm; + struct smu_dpm_policy_ctxt *policy_ctxt; + int i; + + policy_ctxt = dpm_ctxt->dpm_policies; + if (!policy_ctxt) + return NULL; + + for (i = 0; i < hweight32(policy_ctxt->policy_mask); ++i) { + if (policy_ctxt->policies[i].policy_type == p_type) + return &policy_ctxt->policies[i]; + } + + return NULL; +} + +int smu_set_pm_policy(struct smu_context *smu, enum pp_pm_policy p_type, + int level) +{ + struct smu_dpm_context *dpm_ctxt = &smu->smu_dpm; + struct smu_dpm_policy *dpm_policy = NULL; + struct smu_dpm_policy_ctxt *policy_ctxt; + int ret = -EOPNOTSUPP; + + policy_ctxt = dpm_ctxt->dpm_policies; + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled || !policy_ctxt || + !policy_ctxt->policy_mask) + return ret; + + if (level < 0 || level >= PP_POLICY_MAX_LEVELS) + return -EINVAL; + + dpm_policy = smu_get_pm_policy(smu, p_type); + + if (!dpm_policy || !dpm_policy->level_mask || !dpm_policy->set_policy) + return ret; + + if (dpm_policy->current_level == level) + return 0; + + ret = dpm_policy->set_policy(smu, level); + + if (!ret) + dpm_policy->current_level = level; + + return ret; +} + int smu_set_xgmi_plpd_mode(struct smu_context *smu, enum pp_xgmi_plpd_mode mode) { diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 0917dec8efe3..a35ffe5d2021 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -362,6 +362,27 @@ struct smu_table_context { void *gpu_metrics_table; }; +struct smu_context; +struct smu_dpm_policy; + +struct smu_dpm_policy_desc { + const char *name; + char *(*get_desc)(struct smu_dpm_policy *dpm_policy, int level); +}; + +struct smu_dpm_policy { + struct smu_dpm_policy_desc *desc; + enum pp_pm_policy policy_type; + unsigned long level_mask; + int current_level; + int (*set_policy)(struct smu_context *ctxt, int level); +}; + +struct smu_dpm_policy_ctxt { + struct smu_dpm_policy policies[PP_PM_POLICY_NUM]; + unsigned long policy_mask; +}; + struct smu_dpm_context { uint32_t dpm_context_size; void *dpm_context; @@ -372,6 +393,7 @@ struct smu_dpm_context { struct smu_power_state *dpm_request_power_state; struct smu_power_state *dpm_current_power_state; struct mclock_latency_table *mclk_latency_table; + struct smu_dpm_policy_ctxt *dpm_policies; }; struct smu_power_gate { @@ -1551,6 +1573,11 @@ typedef struct { uint32_t MmHubPadding[8]; } WifiBandEntryTable_t; +#define STR_SOC_PSTATE_POLICY "soc_pstate" + +struct smu_dpm_policy *smu_get_pm_policy(struct smu_context *smu, + enum pp_pm_policy p_type); + #if !defined(SWSMU_CODE_LAYER_L2) && !defined(SWSMU_CODE_LAYER_L3) && !defined(SWSMU_CODE_LAYER_L4) int smu_get_power_limit(void *handle, uint32_t *limit, @@ -1598,5 +1625,10 @@ void amdgpu_smu_stb_debug_fs_init(struct amdgpu_device *adev); int smu_send_hbm_bad_pages_num(struct smu_context *smu, uint32_t size); int smu_send_hbm_bad_channel_flag(struct smu_context *smu, uint32_t size); int smu_send_rma_reason(struct smu_context *smu); +int smu_set_pm_policy(struct smu_context *smu, enum pp_pm_policy p_type, + int level); +ssize_t smu_get_pm_policy_info(struct smu_context *smu, + enum pp_pm_policy p_type, char *sysbuf); + #endif #endif -- cgit From 20897c6e711595b4bbd8da45fe9fec3905e19fea Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Mon, 4 Mar 2024 11:49:08 +0530 Subject: drm/amd/pm: Add xgmi plpd to SMU v13.0.6 pm_policy On SOCs with SMU v13.0.6, allow changing xgmi plpd policy through 'pm_policy/xgmi_plpd' sysfs interface. Signed-off-by: Lijo Lazar Reviewed-by: Hawking Zhang Reviewed-by: Asad Kamal Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 17 +++++++- .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 51 ++++++++++++++++++++-- drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 27 ++++++++++++ drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 1 + 4 files changed, 90 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c') diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 5c4062630c3b..15ad2d426c16 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -1197,6 +1197,9 @@ static void smu_swctf_delayed_work_handler(struct work_struct *work) static void smu_init_xgmi_plpd_mode(struct smu_context *smu) { + struct smu_dpm_context *dpm_ctxt = &(smu->smu_dpm); + struct smu_dpm_policy_ctxt *policy_ctxt; + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 2)) { smu->plpd_mode = XGMI_PLPD_DEFAULT; return; @@ -1204,10 +1207,20 @@ static void smu_init_xgmi_plpd_mode(struct smu_context *smu) /* PMFW put PLPD into default policy after enabling the feature */ if (smu_feature_is_enabled(smu, - SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT)) + SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT)) { + struct smu_dpm_policy *policy; + smu->plpd_mode = XGMI_PLPD_DEFAULT; - else + policy = smu_get_pm_policy(smu, PP_PM_POLICY_XGMI_PLPD); + if (policy) + policy->current_level = XGMI_PLPD_DEFAULT; + } else { smu->plpd_mode = XGMI_PLPD_NONE; + policy_ctxt = dpm_ctxt->dpm_policies; + if (policy_ctxt) + policy_ctxt->policy_mask &= + ~BIT(PP_PM_POLICY_XGMI_PLPD); + } } static int smu_sw_init(void *handle) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 9351e7896822..ceb2174baff6 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -403,9 +403,45 @@ static int smu_v13_0_6_select_policy_soc_pstate(struct smu_context *smu, return ret; } +static int smu_v13_0_6_select_plpd_policy(struct smu_context *smu, int level) +{ + struct amdgpu_device *adev = smu->adev; + int ret, param; + + switch (level) { + case XGMI_PLPD_DEFAULT: + param = PPSMC_PLPD_MODE_DEFAULT; + break; + case XGMI_PLPD_OPTIMIZED: + param = PPSMC_PLPD_MODE_OPTIMIZED; + break; + case XGMI_PLPD_DISALLOW: + param = 0; + break; + default: + return -EINVAL; + } + + if (level == XGMI_PLPD_DISALLOW) + ret = smu_cmn_send_smc_msg_with_param( + smu, SMU_MSG_GmiPwrDnControl, param, NULL); + else + /* change xgmi per-link power down policy */ + ret = smu_cmn_send_smc_msg_with_param( + smu, SMU_MSG_SelectPLPDMode, param, NULL); + + if (ret) + dev_err(adev->dev, + "select xgmi per-link power down policy %d failed\n", + level); + + return ret; +} + static int smu_v13_0_6_allocate_dpm_context(struct smu_context *smu) { struct smu_dpm_context *smu_dpm = &smu->smu_dpm; + struct smu_dpm_policy *policy; smu_dpm->dpm_context = kzalloc(sizeof(struct smu_13_0_dpm_context), GFP_KERNEL); @@ -413,11 +449,9 @@ static int smu_v13_0_6_allocate_dpm_context(struct smu_context *smu) return -ENOMEM; smu_dpm->dpm_context_size = sizeof(struct smu_13_0_dpm_context); + smu_dpm->dpm_policies = + kzalloc(sizeof(struct smu_dpm_policy_ctxt), GFP_KERNEL); if (!(smu->adev->flags & AMD_IS_APU)) { - struct smu_dpm_policy *policy; - - smu_dpm->dpm_policies = - kzalloc(sizeof(struct smu_dpm_policy_ctxt), GFP_KERNEL); policy = &(smu_dpm->dpm_policies->policies[0]); policy->policy_type = PP_PM_POLICY_SOC_PSTATE; @@ -430,6 +464,15 @@ static int smu_v13_0_6_allocate_dpm_context(struct smu_context *smu) smu_dpm->dpm_policies->policy_mask |= BIT(PP_PM_POLICY_SOC_PSTATE); } + policy = &(smu_dpm->dpm_policies->policies[1]); + + policy->policy_type = PP_PM_POLICY_XGMI_PLPD; + policy->level_mask = BIT(XGMI_PLPD_DISALLOW) | BIT(XGMI_PLPD_DEFAULT) | + BIT(XGMI_PLPD_OPTIMIZED); + policy->current_level = XGMI_PLPD_DEFAULT; + policy->set_policy = smu_v13_0_6_select_plpd_policy; + smu_cmn_generic_plpd_policy_desc(policy); + smu_dpm->dpm_policies->policy_mask |= BIT(PP_PM_POLICY_XGMI_PLPD); return 0; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index 50fe9feaf80d..f265a449c342 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -1165,3 +1165,30 @@ void smu_cmn_generic_soc_policy_desc(struct smu_dpm_policy *policy) policy->desc = &pstate_policy_desc; } +static char *smu_xgmi_plpd_policy_get_desc(struct smu_dpm_policy *policy, + int level) +{ + if (level < 0 || !(policy->level_mask & BIT(level))) + return "Invalid"; + + switch (level) { + case XGMI_PLPD_DISALLOW: + return "plpd_disallow"; + case XGMI_PLPD_DEFAULT: + return "plpd_default"; + case XGMI_PLPD_OPTIMIZED: + return "plpd_optimized"; + } + + return "Invalid"; +} + +static struct smu_dpm_policy_desc xgmi_plpd_policy_desc = { + .name = STR_XGMI_PLPD_POLICY, + .get_desc = smu_xgmi_plpd_policy_get_desc, +}; + +void smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy *policy) +{ + policy->desc = &xgmi_plpd_policy_desc; +} diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h index d135d984329e..1de685defe85 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h @@ -145,6 +145,7 @@ static inline void smu_cmn_get_sysfs_buf(char **buf, int *offset) bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev); void smu_cmn_generic_soc_policy_desc(struct smu_dpm_policy *policy); +void smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy *policy); #endif #endif -- cgit From 5d6f66b542a6a6f8b0c5b4698fefe0f7fd5e065a Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Mon, 4 Mar 2024 12:26:58 +0530 Subject: drm/amd/pm: Add xgmi plpd to arcturus pm_policy On arcturus, allow changing xgmi plpd policy through 'pm_policy/xgmi_plpd' sysfs interface. Signed-off-by: Lijo Lazar Reviewed-by: Hawking Zhang Reviewed-by: Asad Kamal Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 7 ++-- drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 42 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c') diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 15ad2d426c16..ab68bb8d17cf 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -1199,19 +1199,20 @@ static void smu_init_xgmi_plpd_mode(struct smu_context *smu) { struct smu_dpm_context *dpm_ctxt = &(smu->smu_dpm); struct smu_dpm_policy_ctxt *policy_ctxt; + struct smu_dpm_policy *policy; + policy = smu_get_pm_policy(smu, PP_PM_POLICY_XGMI_PLPD); if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 2)) { smu->plpd_mode = XGMI_PLPD_DEFAULT; + if (policy) + policy->current_level = XGMI_PLPD_DEFAULT; return; } /* PMFW put PLPD into default policy after enabling the feature */ if (smu_feature_is_enabled(smu, SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT)) { - struct smu_dpm_policy *policy; - smu->plpd_mode = XGMI_PLPD_DEFAULT; - policy = smu_get_pm_policy(smu, PP_PM_POLICY_XGMI_PLPD); if (policy) policy->current_level = XGMI_PLPD_DEFAULT; } else { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index 623f6052f97e..84f7d4139bda 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -283,9 +283,29 @@ static int arcturus_tables_init(struct smu_context *smu) return 0; } +static int arcturus_select_plpd_policy(struct smu_context *smu, int level) +{ + /* PPSMC_MSG_GmiPwrDnControl is supported by 54.23.0 and onwards */ + if (smu->smc_fw_version < 0x00361700) { + dev_err(smu->adev->dev, + "XGMI power down control is only supported by PMFW 54.23.0 and onwards\n"); + return -EINVAL; + } + + if (level == XGMI_PLPD_DEFAULT) + return smu_cmn_send_smc_msg_with_param( + smu, SMU_MSG_GmiPwrDnControl, 1, NULL); + else if (level == XGMI_PLPD_DISALLOW) + return smu_cmn_send_smc_msg_with_param( + smu, SMU_MSG_GmiPwrDnControl, 0, NULL); + else + return -EINVAL; +} + static int arcturus_allocate_dpm_context(struct smu_context *smu) { struct smu_dpm_context *smu_dpm = &smu->smu_dpm; + struct smu_dpm_policy *policy; smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context), GFP_KERNEL); @@ -293,6 +313,20 @@ static int arcturus_allocate_dpm_context(struct smu_context *smu) return -ENOMEM; smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context); + smu_dpm->dpm_policies = + kzalloc(sizeof(struct smu_dpm_policy_ctxt), GFP_KERNEL); + + if (!smu_dpm->dpm_policies) + return -ENOMEM; + + policy = &(smu_dpm->dpm_policies->policies[0]); + policy->policy_type = PP_PM_POLICY_XGMI_PLPD; + policy->level_mask = BIT(XGMI_PLPD_DISALLOW) | BIT(XGMI_PLPD_DEFAULT); + policy->current_level = XGMI_PLPD_DEFAULT; + policy->set_policy = arcturus_select_plpd_policy; + smu_cmn_generic_plpd_policy_desc(policy); + smu_dpm->dpm_policies->policy_mask |= BIT(PP_PM_POLICY_XGMI_PLPD); + return 0; } @@ -403,6 +437,14 @@ static int arcturus_set_default_dpm_table(struct smu_context *smu) dpm_table->max = dpm_table->dpm_levels[0].value; } + /* XGMI PLPD is supported by 54.23.0 and onwards */ + if (smu->smc_fw_version < 0x00361700) { + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; + + smu_dpm->dpm_policies->policy_mask &= + ~BIT(PP_PM_POLICY_XGMI_PLPD); + } + return 0; } -- cgit From 546e6309d14cfdc584b92eb6f2274618e629b3f5 Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Mon, 4 Mar 2024 18:55:27 +0530 Subject: drm/amd/pm: Remove legacy interface for xgmi plpd Replace the legacy interface with amdgpu_dpm_set_pm_policy to set XGMI PLPD mode. Also, xgmi_plpd_policy sysfs node is not used by any client. Remove that as well. Signed-off-by: Lijo Lazar Reviewed-by: Hawking Zhang Reviewed-by: Asad Kamal Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 4 +- drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 43 ----------------- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 68 --------------------------- drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 5 -- drivers/gpu/drm/amd/pm/inc/amdgpu_pm.h | 1 - drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 27 ----------- drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 2 - 7 files changed, 2 insertions(+), 148 deletions(-) (limited to 'drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index 4a14f9c1bfe8..821ba2309dec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -1446,7 +1446,7 @@ static int amdgpu_ras_error_inject_xgmi(struct amdgpu_device *adev, if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW)) dev_warn(adev->dev, "Failed to disallow df cstate"); - ret1 = amdgpu_dpm_set_xgmi_plpd_mode(adev, XGMI_PLPD_DISALLOW); + ret1 = amdgpu_dpm_set_pm_policy(adev, PP_PM_POLICY_XGMI_PLPD, XGMI_PLPD_DISALLOW); if (ret1 && ret1 != -EOPNOTSUPP) dev_warn(adev->dev, "Failed to disallow XGMI power down"); @@ -1455,7 +1455,7 @@ static int amdgpu_ras_error_inject_xgmi(struct amdgpu_device *adev, if (amdgpu_ras_intr_triggered()) return ret2; - ret1 = amdgpu_dpm_set_xgmi_plpd_mode(adev, XGMI_PLPD_DEFAULT); + ret1 = amdgpu_dpm_set_pm_policy(adev, PP_PM_POLICY_XGMI_PLPD, XGMI_PLPD_DEFAULT); if (ret1 && ret1 != -EOPNOTSUPP) dev_warn(adev->dev, "Failed to allow XGMI power down"); diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index 9c991362b398..b3b5e7b74c85 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -368,49 +368,6 @@ int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev, return ret; } -int amdgpu_dpm_get_xgmi_plpd_mode(struct amdgpu_device *adev, char **mode_desc) -{ - struct smu_context *smu = adev->powerplay.pp_handle; - int mode = XGMI_PLPD_NONE; - - if (is_support_sw_smu(adev)) { - mode = smu->plpd_mode; - if (mode_desc == NULL) - return mode; - switch (smu->plpd_mode) { - case XGMI_PLPD_DISALLOW: - *mode_desc = "disallow"; - break; - case XGMI_PLPD_DEFAULT: - *mode_desc = "default"; - break; - case XGMI_PLPD_OPTIMIZED: - *mode_desc = "optimized"; - break; - case XGMI_PLPD_NONE: - default: - *mode_desc = "none"; - break; - } - } - - return mode; -} - -int amdgpu_dpm_set_xgmi_plpd_mode(struct amdgpu_device *adev, int mode) -{ - struct smu_context *smu = adev->powerplay.pp_handle; - int ret = -EOPNOTSUPP; - - if (is_support_sw_smu(adev)) { - mutex_lock(&adev->pm.mutex); - ret = smu_set_xgmi_plpd_mode(smu, mode); - mutex_unlock(&adev->pm.mutex); - } - - return ret; -} - ssize_t amdgpu_dpm_get_pm_policy_info(struct amdgpu_device *adev, enum pp_pm_policy p_type, char *buf) { diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 4bce339c5dc0..125fd1a25351 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -2214,70 +2214,6 @@ static int pp_dpm_clk_default_attr_update(struct amdgpu_device *adev, struct amd return 0; } -/* Following items will be read out to indicate current plpd policy: - * - -1: none - * - 0: disallow - * - 1: default - * - 2: optimized - */ -static ssize_t amdgpu_get_xgmi_plpd_policy(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct amdgpu_device *adev = drm_to_adev(ddev); - char *mode_desc = "none"; - int mode; - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - mode = amdgpu_dpm_get_xgmi_plpd_mode(adev, &mode_desc); - - return sysfs_emit(buf, "%d: %s\n", mode, mode_desc); -} - -/* Following argument value is expected from user to change plpd policy - * - arg 0: disallow plpd - * - arg 1: default policy - * - arg 2: optimized policy - */ -static ssize_t amdgpu_set_xgmi_plpd_policy(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct amdgpu_device *adev = drm_to_adev(ddev); - int mode, ret; - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - ret = kstrtos32(buf, 0, &mode); - if (ret) - return -EINVAL; - - ret = pm_runtime_get_sync(ddev->dev); - if (ret < 0) { - pm_runtime_put_autosuspend(ddev->dev); - return ret; - } - - ret = amdgpu_dpm_set_xgmi_plpd_mode(adev, mode); - - pm_runtime_mark_last_busy(ddev->dev); - pm_runtime_put_autosuspend(ddev->dev); - - if (ret) - return ret; - - return count; -} - /* pm policy attributes */ struct amdgpu_pm_policy_attr { struct device_attribute dev_attr; @@ -2452,7 +2388,6 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = { .attr_update = ss_power_attr_update), AMDGPU_DEVICE_ATTR_RW(smartshift_bias, ATTR_FLAG_BASIC, .attr_update = ss_bias_attr_update), - AMDGPU_DEVICE_ATTR_RW(xgmi_plpd_policy, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RO(pm_metrics, ATTR_FLAG_BASIC, .attr_update = amdgpu_pm_metrics_attr_update), }; @@ -2520,9 +2455,6 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ else if ((gc_ver == IP_VERSION(10, 3, 0) || gc_ver == IP_VERSION(11, 0, 3)) && amdgpu_sriov_vf(adev)) *states = ATTR_STATE_UNSUPPORTED; - } else if (DEVICE_ATTR_IS(xgmi_plpd_policy)) { - if (amdgpu_dpm_get_xgmi_plpd_mode(adev, NULL) == XGMI_PLPD_NONE) - *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_mclk_od)) { if (amdgpu_dpm_get_mclk_od(adev) == -EOPNOTSUPP) *states = ATTR_STATE_UNSUPPORTED; diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index c0f4037d2041..f5bf41f21c41 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -430,11 +430,6 @@ int amdgpu_dpm_baco_enter(struct amdgpu_device *adev); int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev, uint32_t cstate); -int amdgpu_dpm_get_xgmi_plpd_mode(struct amdgpu_device *adev, - char **mode); - -int amdgpu_dpm_set_xgmi_plpd_mode(struct amdgpu_device *adev, int mode); - int amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device *adev); int amdgpu_dpm_set_clockgating_by_smu(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_pm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_pm.h index 448ba3a14584..c12ced32f780 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_pm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_pm.h @@ -77,7 +77,6 @@ enum amdgpu_device_attr_id { device_attr_id__smartshift_apu_power, device_attr_id__smartshift_dgpu_power, device_attr_id__smartshift_bias, - device_attr_id__xgmi_plpd_policy, device_attr_id__pm_metrics, device_attr_id__count, }; diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index ab68bb8d17cf..52b99fc04a66 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -1203,7 +1203,6 @@ static void smu_init_xgmi_plpd_mode(struct smu_context *smu) policy = smu_get_pm_policy(smu, PP_PM_POLICY_XGMI_PLPD); if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 2)) { - smu->plpd_mode = XGMI_PLPD_DEFAULT; if (policy) policy->current_level = XGMI_PLPD_DEFAULT; return; @@ -1212,11 +1211,9 @@ static void smu_init_xgmi_plpd_mode(struct smu_context *smu) /* PMFW put PLPD into default policy after enabling the feature */ if (smu_feature_is_enabled(smu, SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT)) { - smu->plpd_mode = XGMI_PLPD_DEFAULT; if (policy) policy->current_level = XGMI_PLPD_DEFAULT; } else { - smu->plpd_mode = XGMI_PLPD_NONE; policy_ctxt = dpm_ctxt->dpm_policies; if (policy_ctxt) policy_ctxt->policy_mask &= @@ -3611,30 +3608,6 @@ int smu_set_pm_policy(struct smu_context *smu, enum pp_pm_policy p_type, return ret; } -int smu_set_xgmi_plpd_mode(struct smu_context *smu, - enum pp_xgmi_plpd_mode mode) -{ - int ret = -EOPNOTSUPP; - - if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) - return ret; - - /* PLPD policy is not supported if it's NONE */ - if (smu->plpd_mode == XGMI_PLPD_NONE) - return ret; - - if (smu->plpd_mode == mode) - return 0; - - if (smu->ppt_funcs && smu->ppt_funcs->select_xgmi_plpd_policy) - ret = smu->ppt_funcs->select_xgmi_plpd_policy(smu, mode); - - if (!ret) - smu->plpd_mode = mode; - - return ret; -} - static const struct amd_pm_funcs swsmu_pm_funcs = { /* export for sysfs */ .set_fan_control_mode = smu_set_fan_control_mode, diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 84ec4ae3d6c5..7030bc008883 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -602,8 +602,6 @@ struct smu_context { struct delayed_work swctf_delayed_work; - enum pp_xgmi_plpd_mode plpd_mode; - /* data structures for wbrf feature support */ bool wbrf_supported; struct notifier_block wbrf_notifier; -- cgit From 6b18376ef37c3dd2bbf34ed4b42fefaa1f348a3d Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Fri, 26 Apr 2024 09:30:25 +0800 Subject: drm/amd/pm: workaround to pass jpeg unit test this is a workaround to pass jpeg unit test on vcn 5.0 now. will be removed later. Signed-off-by: Kenneth Feng Reviewed-by: Sonny Jiang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 3 ++- .../gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 30 +++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c') diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 52b99fc04a66..6f742d88867d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -237,6 +237,7 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu, { struct smu_power_context *smu_power = &smu->smu_power; struct smu_power_gate *power_gate = &smu_power->power_gate; + struct amdgpu_device *adev = smu->adev; int ret = 0; /* @@ -252,7 +253,7 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu, return 0; ret = smu->ppt_funcs->dpm_set_vcn_enable(smu, enable); - if (!ret) + if (!ret && !adev->enable_jpeg_test) atomic_set(&power_gate->vcn_gated, !enable); return ret; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c index 98ea58d792ca..7179cdacf156 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c @@ -1869,6 +1869,34 @@ static ssize_t smu_v14_0_2_get_ecc_info(struct smu_context *smu, return ret; } +static int smu_v14_0_2_set_vcn_enable(struct smu_context *smu, + bool enable) +{ + struct amdgpu_device *adev = smu->adev; + struct smu_power_gate *power_gate = &smu->smu_power.power_gate; + int i, ret = 0; + + if (!adev->enable_jpeg_test) + return smu_v14_0_set_vcn_enable(smu, enable); + + if (!atomic_read(&power_gate->vcn_gated) || !enable) + return 0; + + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + if (adev->vcn.harvest_config & (1 << i)) + continue; + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, + i << 16U, NULL); + if (ret) + return ret; + } + + atomic_set(&power_gate->vcn_gated, 0); + + return ret; +} + static const struct pptable_funcs smu_v14_0_2_ppt_funcs = { .get_allowed_feature_mask = smu_v14_0_2_get_allowed_feature_mask, .set_default_dpm_table = smu_v14_0_2_set_default_dpm_table, @@ -1891,7 +1919,7 @@ static const struct pptable_funcs smu_v14_0_2_ppt_funcs = { .system_features_control = smu_v14_0_system_features_control, .set_allowed_mask = smu_v14_0_set_allowed_mask, .get_enabled_mask = smu_cmn_get_enabled_mask, - .dpm_set_vcn_enable = smu_v14_0_set_vcn_enable, + .dpm_set_vcn_enable = smu_v14_0_2_set_vcn_enable, .dpm_set_jpeg_enable = smu_v14_0_set_jpeg_enable, .get_dpm_ultimate_freq = smu_v14_0_2_get_dpm_ultimate_freq, .get_vbios_bootup_values = smu_v14_0_get_vbios_bootup_values, -- cgit