[Public]

A comment inline.

Regards,
Guchun

-----Original Message-----
From: amd-gfx <amd-gfx-boun...@lists.freedesktop.org> On Behalf Of Evan Quan
Sent: Wednesday, July 7, 2021 9:57 AM
To: amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander <alexander.deuc...@amd.com>; Quan, Evan 
<evan.q...@amd.com>
Subject: [PATCH 4/7] drm/amd/pm: correct the fan speed RPM retrieving

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.q...@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;
[Guchun] More simple if directly return function 
sienna_cichlid_get_smu_metrics_data, then variable 'ret' can be dropped.

+}
+
 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;
+       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)
--
2.29.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&amp;data=04%7C01%7Cguchun.chen%40amd.com%7C24bf2298a1554dbd9b8508d940eadc6d%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637612199748658238%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=nB08a637vYeUyLJIcsw6fuDdjZaDUCnPIfDSQrDIIVI%3D&amp;reserved=0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to