RE: [PATCH v2 1/9] drm/amd/pm: Add support for DPM policies
[AMD Official Use Only - General] -Original Message- From: amd-gfx On Behalf Of Lijo Lazar Sent: Thursday, March 14, 2024 7:56 PM To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Deucher, Alexander ; Liu, Shuzhou (Bill) Subject: [PATCH v2 1/9] 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 Reviewed-by: Hawking Zhang --- v2: Add NULL checks before accessing smu_dpm_policy_ctxt .../gpu/drm/amd/include/kgd_pp_interface.h| 16 drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 29 ++ drivers/gpu/drm/amd/pm/amdgpu_pm.c| 92 ++ drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 4 + drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 95 +++ drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 29 ++ 6 files changed, 265 insertions(+) diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index afb930b70615..84dd819ccc06 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_MASK0xF000 #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 f84bfed50681..db3addd07120 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -411,6 +411,35 @@ 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, char +*buf) { + struct smu_context *smu = adev->powerplay.pp_handle; + int ret = -EOPNOTSUPP; + + if (is_support_sw_smu(adev)) { + mutex_lock(>pm.mutex); + ret = smu_get_pm_policy_info(smu, buf); + mutex_unlock(>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(>pm.mutex); + ret = smu_set_pm_policy(smu, policy_type, policy_level); + mutex_unlock(>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 efc631bddf4a..7ee11c2e3c61 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -2179,6 +2179,96 @@ static ssize_t amdgpu_set_xgmi_plpd_policy(struct device *dev, return count; } +static ssize_t amdgpu_get_pm_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); + + if (amdgpu_in_reset(adev)) + return -EPERM; + if (adev->in_suspend && !adev->in_runpm) + return -EPERM; + + return amdgpu_dpm_get_pm_policy_info(adev, buf); } + +static ssize_t amdgpu_set_pm_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 policy_type, 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); + if (strncmp(tmp, "soc_pstate", strlen("soc_pstate")) == 0) { [Kevin]: It is better to use 'sizeof() - 1' instead of strlen() function to calculate const string size. Best Regards, Kevin + policy_type = PP_PM_POLICY_SOC_PSTATE; + tmp +=
RE: [PATCH v2 1/9] drm/amd/pm: Add support for DPM policies
[Public] > -Original Message- > From: Lazar, Lijo > Sent: Thursday, March 14, 2024 7:56 AM > To: amd-gfx@lists.freedesktop.org > Cc: Zhang, Hawking ; Deucher, Alexander > ; Liu, Shuzhou (Bill) > > Subject: [PATCH v2 1/9] 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 > Reviewed-by: Hawking Zhang > --- > v2: Add NULL checks before accessing smu_dpm_policy_ctxt > > .../gpu/drm/amd/include/kgd_pp_interface.h| 16 > drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 29 ++ > drivers/gpu/drm/amd/pm/amdgpu_pm.c| 92 ++ > drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 4 + > drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 95 > +++ > drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 29 ++ > 6 files changed, 265 insertions(+) > > diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h > b/drivers/gpu/drm/amd/include/kgd_pp_interface.h > index afb930b70615..84dd819ccc06 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_MASK0xF000 > #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 f84bfed50681..db3addd07120 100644 > --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c > +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c > @@ -411,6 +411,35 @@ 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, char > +*buf) { > + struct smu_context *smu = adev->powerplay.pp_handle; > + int ret = -EOPNOTSUPP; > + > + if (is_support_sw_smu(adev)) { > + mutex_lock(>pm.mutex); > + ret = smu_get_pm_policy_info(smu, buf); > + mutex_unlock(>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(>pm.mutex); > + ret = smu_set_pm_policy(smu, policy_type, policy_level); > + mutex_unlock(>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 efc631bddf4a..7ee11c2e3c61 100644 > --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c > +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c > @@ -2179,6 +2179,96 @@ static ssize_t > amdgpu_set_xgmi_plpd_policy(struct device *dev, > return count; > } > > +static ssize_t amdgpu_get_pm_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); > + > + if (amdgpu_in_reset(adev)) > + return -EPERM; > + if (adev->in_suspend && !adev->in_runpm) > + return -EPERM; > + > + return amdgpu_dpm_get_pm_policy_info(adev, buf); } > + > +static ssize_t amdgpu_set_pm_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 policy_type, 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); > + if (strncmp(tmp, "soc_pstate", strlen("soc_pstate")) == 0) { > + policy_type = PP_PM_POLICY_SOC_PSTATE; > + tmp += strlen("soc_pstate");