All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/amd/pm: Fix that RPM cannot be obtained for specific GPU
@ 2021-09-28  0:49 huangyizhi
  2021-09-28  6:29 ` Christian König
  0 siblings, 1 reply; 4+ messages in thread
From: huangyizhi @ 2021-09-28  0:49 UTC (permalink / raw)
  To: evan.quan, alexander.deucher, christian.koenig, Xinhui.Pan,
	airlied, daniel, lee.jones, lijo.lazar
  Cc: amd-gfx, huangyizhi

The current mechanism for obtaining RPM is to read tach_period from
the register, and then calculate the RPM together with the frequency.
But we found that on specific GPUs, such as RX 550 and RX 560D,
tach_period always reads as 0 and smu7_fan_ctrl_get_fan_speed_rpm
will returns -EINVAL.

To solve this problem, when reading tach_period as 0, we try
to estimate the current RPM using the percentage of current pwm, the
maximum and minimum RPM.

Signed-off-by: huangyizhi <huangyizhi@hnu.edu.cn>
---
 .../drm/amd/pm/powerplay/hwmgr/smu7_thermal.c | 28 ++++++++++++++++---
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c
index a6c3610db23e..307dd87d6882 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c
@@ -81,6 +81,11 @@ int smu7_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
 {
 	uint32_t tach_period;
 	uint32_t crystal_clock_freq;
+	uint32_t duty100;
+	uint32_t duty;
+	uint32_t speed_percent;
+	uint64_t tmp64;
+
 
 	if (hwmgr->thermal_controller.fanInfo.bNoFan ||
 	    !hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution)
@@ -89,13 +94,28 @@ int smu7_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
 	tach_period = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
 			CG_TACH_STATUS, TACH_PERIOD);
 
-	if (tach_period == 0)
-		return -EINVAL;
+	if (tach_period == 0) {
 
-	crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
+		duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+				CG_FDO_CTRL1, FMAX_DUTY100);
+		duty = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+				CG_THERMAL_STATUS, FDO_PWM_DUTY);
 
-	*speed = 60 * crystal_clock_freq * 10000 / tach_period;
+		if (duty100 == 0)
+			return -EINVAL;
 
+		tmp64 = (uint64_t)duty * 100;
+		do_div(tmp64, duty100);
+		speed_percent = MIN((uint32_t)tmp64, 100);
+
+		*speed = speed_percent * (hwmgr->thermal_controller.fanInfo.ulMaxRPM
+			- hwmgr->thermal_controller.fanInfo.ulMinRPM) / 100;
+	} else {
+
+		crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
+
+		*speed = 60 * crystal_clock_freq * 10000 / tach_period;
+	}
 	return 0;
 }
 
-- 
2.30.0




^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-09-29  9:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-28  0:49 [PATCH] drm/amd/pm: Fix that RPM cannot be obtained for specific GPU huangyizhi
2021-09-28  6:29 ` Christian König
2021-09-28 21:50   ` Alex Deucher
2021-09-29  9:51     ` Christian König

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.