[PATCH 4/7] drm/amd/pm: correct the fan speed RPM retrieving
Lazar, Lijo
lijo.lazar at amd.com
Wed Jul 7 09:05:43 UTC 2021
On 7/7/2021 7:26 AM, Evan Quan wrote:
> The relationship "PWM = RPM / smu->fan_max_rpm" between fan speed
> PWM and RPM is not true for SMU11 ASICs. So, we need a new way to
> retrieving the fan speed RPM.
>
> Change-Id: Ife4298c8b7ec93ef023a7da27d59654e0444e044
> Signed-off-by: Evan Quan <evan.quan at amd.com>
> ---
> .../include/asic_reg/thm/thm_11_0_2_offset.h | 3 ++
> drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h | 5 ++++
> drivers/gpu/drm/amd/pm/inc/smu_v11_0.h | 3 ++
> drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 7 ++---
> .../gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 24 ++++++++++++++++
> .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 24 ++++++++++++++++
> .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 21 ++++++++++++++
> .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 28 +++++++++++++++++++
> 8 files changed, 110 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h
> index eca96abef445..8474f419caa5 100644
> --- a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h
> +++ b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h
> @@ -38,6 +38,9 @@
> #define mmCG_TACH_CTRL 0x006a
> #define mmCG_TACH_CTRL_BASE_IDX 0
>
> +#define mmCG_TACH_STATUS 0x006b
> +#define mmCG_TACH_STATUS_BASE_IDX 0
> +
> #define mmTHM_THERMAL_INT_ENA 0x000a
> #define mmTHM_THERMAL_INT_ENA_BASE_IDX 0
> #define mmTHM_THERMAL_INT_CTRL 0x000b
> diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
> index fa585f0be530..db5123fc6042 100644
> --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
> +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
> @@ -726,6 +726,11 @@ struct pptable_funcs {
> */
> int (*get_fan_speed_percent)(struct smu_context *smu, uint32_t *speed);
>
> + /**
> + * @get_fan_speed_rpm: Get the current fan speed in rpm.
> + */
> + int (*get_fan_speed_rpm)(struct smu_context *smu, uint32_t *speed);
> +
> /**
> * @set_watermarks_table: Configure and upload the watermarks tables to
> * the SMU.
> diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h
> index 8e0f8e9a1665..05c8fc8fc3f9 100644
> --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h
> +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h
> @@ -229,6 +229,9 @@ int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
> int smu_v11_0_get_fan_speed_percent(struct smu_context *smu,
> uint32_t *speed);
>
> +int smu_v11_0_get_fan_speed_rpm(struct smu_context *smu,
> + uint32_t *speed);
> +
> int smu_v11_0_set_xgmi_pstate(struct smu_context *smu,
> uint32_t pstate);
>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> index 9a25443988e3..54fb3d7d23ee 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> @@ -2614,17 +2614,14 @@ static int smu_get_fan_speed_rpm(void *handle, uint32_t *speed)
> {
> struct smu_context *smu = handle;
> int ret = 0;
> - u32 percent;
>
> if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
> return -EOPNOTSUPP;
>
> mutex_lock(&smu->mutex);
>
> - if (smu->ppt_funcs->get_fan_speed_percent) {
> - ret = smu->ppt_funcs->get_fan_speed_percent(smu, &percent);
> - *speed = percent * smu->fan_max_rpm / 100;
> - }
> + if (smu->ppt_funcs->get_fan_speed_rpm)
> + ret = smu->ppt_funcs->get_fan_speed_rpm(smu, speed);
>
> mutex_unlock(&smu->mutex);
>
> 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 4a6544b8e05e..e3303c8dcaca 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
> @@ -1162,6 +1162,29 @@ static int arcturus_read_sensor(struct smu_context *smu,
> return ret;
> }
>
> +static int arcturus_get_fan_speed_rpm(struct smu_context *smu,
> + uint32_t *speed)
> +{
> + int ret = 0;
> +
> + if (!speed)
> + return -EINVAL;
> +
> + switch (smu_v11_0_get_fan_control_mode(smu)) {
> + case AMD_FAN_CTRL_AUTO:
> + ret = arcturus_get_smu_metrics_data(smu,
> + METRICS_CURR_FANSPEED,
> + speed);
> + break;
> + default:
> + ret = smu_v11_0_get_fan_speed_rpm(smu,
> + speed);
> + break;
> + }
> +
> + return ret;
> +}
> +
> static int arcturus_get_fan_parameters(struct smu_context *smu)
> {
> PPTable_t *pptable = smu->smu_table.driver_pptable;
> @@ -2246,6 +2269,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
> .force_clk_levels = arcturus_force_clk_levels,
> .read_sensor = arcturus_read_sensor,
> .get_fan_speed_percent = smu_v11_0_get_fan_speed_percent,
> + .get_fan_speed_rpm = arcturus_get_fan_speed_rpm,
> .get_power_profile_mode = arcturus_get_power_profile_mode,
> .set_power_profile_mode = arcturus_set_power_profile_mode,
> .set_performance_level = arcturus_set_performance_level,
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
> index 2ddf35788672..7dce5ea7c1a0 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
> @@ -1668,6 +1668,29 @@ static bool navi10_is_dpm_running(struct smu_context *smu)
> return !!(feature_enabled & SMC_DPM_FEATURE);
> }
>
> +static int navi10_get_fan_speed_rpm(struct smu_context *smu,
> + uint32_t *speed)
> +{
> + int ret = 0;
> +
> + if (!speed)
> + return -EINVAL;
> +
> + switch (smu_v11_0_get_fan_control_mode(smu)) {
> + case AMD_FAN_CTRL_AUTO:
> + ret = navi10_get_smu_metrics_data(smu,
> + METRICS_CURR_FANSPEED,
> + speed);
> + break;
> + default:
> + ret = smu_v11_0_get_fan_speed_rpm(smu,
> + speed);
> + break;
> + }
> +
> + return ret;
> +}
> +
> static int navi10_get_fan_parameters(struct smu_context *smu)
> {
> PPTable_t *pptable = smu->smu_table.driver_pptable;
> @@ -3182,6 +3205,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
> .notify_smc_display_config = navi10_notify_smc_display_config,
> .is_dpm_running = navi10_is_dpm_running,
> .get_fan_speed_percent = smu_v11_0_get_fan_speed_percent,
> + .get_fan_speed_rpm = navi10_get_fan_speed_rpm,
> .get_power_profile_mode = navi10_get_power_profile_mode,
> .set_power_profile_mode = navi10_set_power_profile_mode,
> .set_watermarks_table = navi10_set_watermarks_table,
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
> index e7686ce6744b..2f93dc4b5968 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
> @@ -1355,6 +1355,26 @@ static bool sienna_cichlid_is_dpm_running(struct smu_context *smu)
> return !!(feature_enabled & SMC_DPM_FEATURE);
> }
>
> +static int sienna_cichlid_get_fan_speed_rpm(struct smu_context *smu,
> + uint32_t *speed)
> +{
> + int ret = 0;
> +
> + if (!speed)
> + return -EINVAL;
> +
> + /*
> + * For Sienna_Cichlid and later, the fan speed(rpm) reported
> + * by pmfw is always trustable(even when the fan control feature
> + * disabled or 0 RPM kicked in).
> + */
> + ret = sienna_cichlid_get_smu_metrics_data(smu,
> + METRICS_CURR_FANSPEED,
> + speed);
> +
> + return ret;
> +}
> +
> static int sienna_cichlid_get_fan_parameters(struct smu_context *smu)
> {
> uint16_t *table_member;
> @@ -3820,6 +3840,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
> .notify_smc_display_config = sienna_cichlid_notify_smc_display_config,
> .is_dpm_running = sienna_cichlid_is_dpm_running,
> .get_fan_speed_percent = smu_v11_0_get_fan_speed_percent,
> + .get_fan_speed_rpm = sienna_cichlid_get_fan_speed_rpm,
> .get_power_profile_mode = sienna_cichlid_get_power_profile_mode,
> .set_power_profile_mode = sienna_cichlid_set_power_profile_mode,
> .set_watermarks_table = sienna_cichlid_set_watermarks_table,
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
> index c49683b07076..0cdf55a0dba2 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
> @@ -1284,6 +1284,34 @@ int smu_v11_0_get_fan_speed_percent(struct smu_context *smu,
> return 0;
> }
>
> +int smu_v11_0_get_fan_speed_rpm(struct smu_context *smu,
> + uint32_t *speed)
> +{
> + struct amdgpu_device *adev = smu->adev;
> + uint32_t tach_status, crystal_clock_freq;
> + uint64_t tmp64;
> +
> + /*
> + * For pre Sienna Cichlid ASICs, the 0 RPM may be not correctly
> + * detected via register retrieving. To workaround this, we will
> + * report the fan speed as 0 RPM if user just requested such.
> + */
> + if ((smu->user_dpm_profile.custom_fan_speed & SMU_CUSTOM_FAN_SPEED_RPM)
> + && !smu->user_dpm_profile.fan_speed_rpm) {
> + *speed = 0;
> + return 0;
> + }
> +
> + crystal_clock_freq = amdgpu_asic_get_xclk(adev) / 4;
Same frequency comment - no need to related to ASIC refclk, define and
use fan control crystal clock.
Thanks,
Lijo
> + tmp64 = (uint64_t)crystal_clock_freq * 60 * 10000;
> +
> + tach_status = RREG32_SOC15(THM, 0, mmCG_TACH_STATUS);
> + do_div(tmp64, tach_status);
> + *speed = (uint32_t)tmp64;
> +
> + return 0;
> +}
> +
> int
> smu_v11_0_set_fan_control_mode(struct smu_context *smu,
> uint32_t mode)
>
More information about the amd-gfx
mailing list