<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0"><span style="color: rgb(255, 0, 0);">Please see in line.</span></p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">Regards</p>
<p style="margin-top:0;margin-bottom:0">Rex<br>
</p>
<br>
<br>
<div style="color: rgb(0, 0, 0);">
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" color="#000000" face="Calibri, sans-serif"><b>From:</b> amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of Evan Quan <evan.quan@amd.com><br>
<b>Sent:</b> Thursday, September 20, 2018 10:26 AM<br>
<b>To:</b> amd-gfx@lists.freedesktop.org<br>
<b>Cc:</b> Deucher, Alexander; Quan, Evan<br>
<b>Subject:</b> [PATCH] drm/amd/powerplay: enable fan RPM and pwm settings</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Manual fan RPM and pwm setting on vega20 are<br>
available now.<br>
<br>
Change-Id: Iad45a169d6984acc091c4efaf46973619fe43a29<br>
Signed-off-by: Evan Quan <evan.quan@amd.com><br>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com><br>
Reviewed-by: Rex Zhu <Rex.Zhu@amd.com><br>
---<br>
 .../include/asic_reg/thm/thm_11_0_2_offset.h  |  12 ++<br>
 .../include/asic_reg/thm/thm_11_0_2_sh_mask.h |  10 ++<br>
 .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c    |  27 ++++<br>
 .../drm/amd/powerplay/hwmgr/vega20_thermal.c  | 148 +++++++++++++++++-<br>
 .../drm/amd/powerplay/hwmgr/vega20_thermal.h  |  11 +-<br>
 5 files changed, 204 insertions(+), 4 deletions(-)<br>
<br>
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<br>
index 510ec3c70626..5ad10408660e 100644<br>
--- a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h<br>
+++ b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h<br>
@@ -26,6 +26,18 @@<br>
 #define mmCG_MULT_THERMAL_STATUS                                                                       0x005f<br>
 #define mmCG_MULT_THERMAL_STATUS_BASE_IDX                                                              0<br>
 <br>
+#define mmCG_FDO_CTRL0                                                                                 0x0067<br>
+#define mmCG_FDO_CTRL0_BASE_IDX                                                                        0<br>
+<br>
+#define mmCG_FDO_CTRL1                                                                                 0x0068<br>
+#define mmCG_FDO_CTRL1_BASE_IDX                                                                        0<br>
+<br>
+#define mmCG_FDO_CTRL2                                                                                 0x0069<br>
+#define mmCG_FDO_CTRL2_BASE_IDX                                                                        0<br>
+<br>
+#define mmCG_TACH_STATUS                                                                               0x006b<br>
+#define mmCG_TACH_STATUS_BASE_IDX                                                                      0<br>
+<br>
 #define mmTHM_THERMAL_INT_ENA                                                                          0x000a<br>
 #define mmTHM_THERMAL_INT_ENA_BASE_IDX                                                                 0<br>
 #define mmTHM_THERMAL_INT_CTRL                                                                         0x000b<br>
diff --git a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h<br>
index f69533fa6abf..ed1a2c869de5 100644<br>
--- a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h<br>
+++ b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h<br>
@@ -28,6 +28,16 @@<br>
 #define CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT                                                               0x9<br>
 #define CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP_MASK                                                            0x000001FFL<br>
 #define CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK                                                                 0x0003FE00L<br>
+#define CG_FDO_CTRL2__TMIN__SHIFT                                                                             0x0<br>
+#define CG_FDO_CTRL2__TMIN_MASK                                                                               0x000000FFL<br>
+#define CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT                                                                     0xb<br>
+#define CG_FDO_CTRL2__FDO_PWM_MODE_MASK                                                                       0x00003800L<br>
+#define CG_FDO_CTRL1__FMAX_DUTY100__SHIFT                                                                     0x0<br>
+#define CG_FDO_CTRL1__FMAX_DUTY100_MASK                                                                       0x000000FFL<br>
+#define CG_FDO_CTRL0__FDO_STATIC_DUTY__SHIFT                                                                  0x0<br>
+#define CG_FDO_CTRL0__FDO_STATIC_DUTY_MASK                                                                    0x000000FFL<br>
+#define CG_TACH_STATUS__TACH_PERIOD__SHIFT                                                                    0x0<br>
+#define CG_TACH_STATUS__TACH_PERIOD_MASK                                                                      0xFFFFFFFFL<br>
 <br>
 //THM_THERMAL_INT_ENA<br>
 #define THM_THERMAL_INT_ENA__THERM_INTH_SET__SHIFT                                                            0x0<br>
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c<br>
index 39069663ac3f..4a80b8101194 100644<br>
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c<br>
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c<br>
@@ -2284,6 +2284,25 @@ static uint32_t vega20_get_fan_control_mode(struct pp_hwmgr *hwmgr)<br>
                 return AMD_FAN_CTRL_AUTO;<br>
 }<br>
 <br>
+static void vega20_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)<br>
+{<br>
+       switch (mode) {<br>
+       case AMD_FAN_CTRL_NONE:<br>
+               vega20_fan_ctrl_set_fan_speed_percent(hwmgr, 100);<br>
+               break;<br>
+       case AMD_FAN_CTRL_MANUAL:<br>
+               if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))<br>
+                       vega20_fan_ctrl_stop_smc_fan_control(hwmgr);<br>
+               break;<br>
+       case AMD_FAN_CTRL_AUTO:<br>
+               if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))<br>
+                       vega20_fan_ctrl_start_smc_fan_control(hwmgr);<br>
+               break;<br>
+       default:<br>
+               break;<br>
+       }<br>
+}<br>
+<br>
 static int vega20_get_dal_power_level(struct pp_hwmgr *hwmgr,<br>
                 struct amd_pp_simple_clock_info *info)<br>
 {<br>
@@ -3447,12 +3466,20 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {<br>
         .disable_smc_firmware_ctf =<br>
                 vega20_thermal_disable_alert,<br>
         /* fan control related */<br>
+       .get_fan_speed_percent =<br>
+               vega20_fan_ctrl_get_fan_speed_percent,<br>
+       .set_fan_speed_percent =<br>
+               vega20_fan_ctrl_set_fan_speed_percent,<br>
         .get_fan_speed_info =<br>
                 vega20_fan_ctrl_get_fan_speed_info,<br>
         .get_fan_speed_rpm =<br>
                 vega20_fan_ctrl_get_fan_speed_rpm,<br>
+       .set_fan_speed_rpm =<br>
+               vega20_fan_ctrl_set_fan_speed_rpm,<br>
         .get_fan_control_mode =<br>
                 vega20_get_fan_control_mode,<br>
+       .set_fan_control_mode =<br>
+               vega20_set_fan_control_mode,<br>
         /* smu memory related */<br>
         .notify_cac_buffer_info =<br>
                 vega20_notify_cac_buffer_info,<br>
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c<br>
index 2984ddd5428c..33062497a2c0 100644<br>
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c<br>
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c<br>
@@ -29,6 +29,78 @@<br>
 #include "soc15_common.h"<br>
 #include "pp_debug.h"<br>
 <br>
+static int vega20_disable_fan_control_feature(struct pp_hwmgr *hwmgr)<br>
+{<br>
+       struct vega20_hwmgr *data = hwmgr->backend;<br>
+       int ret = 0;<br>
+<br>
+       if (data->smu_features[GNLD_FAN_CONTROL].supported) {<br>
+               ret = vega20_enable_smc_features(<br>
+                               hwmgr, false,<br>
+                               data->smu_features[GNLD_FAN_CONTROL].<br>
+                               smu_feature_bitmap);<br>
+               PP_ASSERT_WITH_CODE(!ret,<br>
+                               "Disable FAN CONTROL feature Failed!",<br>
+                               return ret);<br>
+               data->smu_features[GNLD_FAN_CONTROL].enabled = false;<br>
+       }<br>
+<br>
+       return ret;<br>
+}<br>
+<br>
+int vega20_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)<br>
+{<br>
+       struct vega20_hwmgr *data = hwmgr->backend;<br>
+<br>
+       if (data->smu_features[GNLD_FAN_CONTROL].supported)<br>
+               return vega20_disable_fan_control_feature(hwmgr);<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
+static int vega20_enable_fan_control_feature(struct pp_hwmgr *hwmgr)<br>
+{<br>
+       struct vega20_hwmgr *data = hwmgr->backend;<br>
+       int ret = 0;<br>
+<br>
+       if (data->smu_features[GNLD_FAN_CONTROL].supported) {<br>
+               ret = vega20_enable_smc_features(<br>
+                               hwmgr, true,<br>
+                               data->smu_features[GNLD_FAN_CONTROL].<br>
+                               smu_feature_bitmap);<br>
+               PP_ASSERT_WITH_CODE(!ret,<br>
+                               "Enable FAN CONTROL feature Failed!",<br>
+                               return ret);<br>
+               data->smu_features[GNLD_FAN_CONTROL].enabled = true;<br>
+       }<br>
+<br>
+       return ret;<br>
+}<br>
+<br>
+int vega20_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)<br>
+{<br>
+       struct vega20_hwmgr *data = hwmgr->backend;<br>
+<br>
+       if (data->smu_features[GNLD_FAN_CONTROL].supported)<br>
+               return vega20_enable_fan_control_feature(hwmgr);<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
+static int vega20_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)<br>
+{<br>
+       struct amdgpu_device *adev = hwmgr->adev;<br>
+<br>
+       WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,<br>
+                       REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),<br>
+                               CG_FDO_CTRL2, TMIN, 0));<br>
+       WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,<br>
+                       REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),<br>
+                               CG_FDO_CTRL2, FDO_PWM_MODE, mode));<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
 static int vega20_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)<br>
 {<br>
         int ret = 0;<br>
@@ -45,12 +117,62 @@ static int vega20_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)<br>
         return 0;<br>
 }<br>
 <br>
+int vega20_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr,<br>
+               uint32_t *speed)<br>
+{<br>
+       struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);<br>
+       PPTable_t *pp_table = &(data->smc_state_table.pp_table);<br>
+       uint32_t current_rpm, percent = 0;<br>
+       int ret = 0;<br>
+<br>
+       ret = vega20_get_current_rpm(hwmgr, &current_rpm);<br>
+       if (ret)<br>
+               return ret;<br>
+<br>
+       percent = current_rpm * 100 / pp_table->FanMaximumRpm;<br>
+<br>
+       *speed = percent > 100 ? 100 : percent;<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
+int vega20_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr,<br>
+               uint32_t speed)<br>
+{<br>
+       struct amdgpu_device *adev = hwmgr->adev;<br>
+       uint32_t duty100;<br>
+       uint32_t duty;<br>
+       uint64_t tmp64;<br>
+<br>
+       if (speed > 100)<br>
+               speed = 100;<br>
+<br>
+       if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))<br>
+               vega20_fan_ctrl_stop_smc_fan_control(hwmgr);<br>
+<br>
+       duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),<br>
+                                   CG_FDO_CTRL1, FMAX_DUTY100);<br>
+<br>
+       if (duty100 == 0)<br>
+               return -EINVAL;<br>
+<br>
+       tmp64 = (uint64_t)speed * duty100;<br>
+       do_div(tmp64, 100);<br>
+       duty = (uint32_t)tmp64;<br>
+<br>
+       WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0,<br>
+               REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0),<br>
+                       CG_FDO_CTRL0, FDO_STATIC_DUTY, duty));<br>
+<br>
+       return vega20_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);<br>
+}<br>
+<br>
 int vega20_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,<br>
                 struct phm_fan_speed_info *fan_speed_info)<br>
 {<br>
         memset(fan_speed_info, 0, sizeof(*fan_speed_info));<br>
-       fan_speed_info->supports_percent_read = false;<br>
-       fan_speed_info->supports_percent_write = false;<br>
+       fan_speed_info->supports_percent_read = true;<br>
+       fan_speed_info->supports_percent_write = true;<br>
         fan_speed_info->supports_rpm_read = true;<br>
         fan_speed_info->supports_rpm_write = true;<br>
 <br>
@@ -64,6 +186,28 @@ int vega20_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)<br>
         return vega20_get_current_rpm(hwmgr, speed);<br>
 }<br>
 <br>
+int vega20_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)<br>
+{<br>
+       struct amdgpu_device *adev = hwmgr->adev;<br>
+       uint32_t tach_period, crystal_clock_freq;<br>
+       int result = 0;<br>
+<br>
+       if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) {<br>
+               result = vega20_fan_ctrl_stop_smc_fan_control(hwmgr);<br>
+               if (result)<br>
+                       return result;<br>
+       }<br>
+<br>
+       crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);<br>
<br>
<span style="color: rgb(255, 0, 0);">Make sure the speed not equal to zero to avoid
</span><span><span style="color: rgb(255, 0, 0);">divide-by-zero</span><span style="color: rgb(255, 0, 0);"> crash</span><br>
<br>
</span>+       tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);<br>
<br>
+       WREG32_SOC15(THM, 0, <span style="background-color: rgb(0, 255, 0);">mmCG_TACH_STATUS,</span><br>
+                       REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_STATUS),<br>
+                               CG_TACH_STATUS, TACH_PERIOD,<br>
+                               tach_period));<br>
<br>
<span style="color: rgb(255, 0, 0);">should be set the register </span><font size="2"><span style="font-size:11pt;"><span style="background-color: rgb(0, 255, 0); color: rgb(255, 0, 0);">mmCG_TACH_CTRL<br>
<br>
<span style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);">Rex</span><br>
<br>
</span></span></font>+       return vega20_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC_RPM);<br>
+}<br>
+<br>
 /**<br>
 * Reads the remote temperature from the SIslands thermal controller.<br>
 *<br>
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.h<br>
index 2a6d49fec4e0..2d1769bbd24e 100644<br>
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.h<br>
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.h<br>
@@ -50,15 +50,22 @@ struct vega20_temperature {<br>
 #define FDO_PWM_MODE_STATIC_RPM 5<br>
 <br>
 extern int vega20_thermal_get_temperature(struct pp_hwmgr *hwmgr);<br>
-extern int vega20_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr);<br>
 extern int vega20_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,<br>
                 struct phm_fan_speed_info *fan_speed_info);<br>
-extern int vega20_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr);<br>
 extern int vega20_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr,<br>
                 uint32_t *speed);<br>
+extern int vega20_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr,<br>
+               uint32_t speed);<br>
+extern int vega20_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr,<br>
+               uint32_t *speed);<br>
+extern int vega20_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr,<br>
+               uint32_t speed);<br>
+extern int vega20_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr);<br>
+extern int vega20_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr);<br>
 extern int vega20_thermal_disable_alert(struct pp_hwmgr *hwmgr);<br>
 extern int vega20_start_thermal_controller(struct pp_hwmgr *hwmgr,<br>
                                 struct PP_TemperatureRange *range);<br>
+extern int vega20_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr);<br>
 <br>
 #endif<br>
 <br>
-- <br>
2.19.0<br>
<br>
_______________________________________________<br>
amd-gfx mailing list<br>
amd-gfx@lists.freedesktop.org<br>
<a href="https://lists.freedesktop.org/mailman/listinfo/amd-gfx" id="LPlnk501422" class="OWAAutoLink" previewremoved="true">https://lists.freedesktop.org/mailman/listinfo/amd-gfx</a>
<div id="LPBorder_GT_15374277370060.9438929616905177" style="margin-bottom: 20px; overflow: auto; width: 100%; text-indent: 0px;">
<table id="LPContainer_15374277370040.1896930136272339" style="width: 90%; background-color: rgb(255, 255, 255); position: relative; overflow: auto; padding-top: 20px; padding-bottom: 20px; margin-top: 20px; border-top: 1px dotted rgb(200, 200, 200); border-bottom: 1px dotted rgb(200, 200, 200);" role="presentation" cellspacing="0">
<tbody>
<tr style="border-spacing: 0px;" valign="top">
<td id="TextCell_15374277370040.585617775214696" style="vertical-align: top; position: relative; padding: 0px; display: table-cell;" colspan="2">
<div id="LPRemovePreviewContainer_15374277370040.5915342476635934"></div>
<div id="LPTitle_15374277370040.8118232702903718" style="top: 0px; color: rgb(0, 120, 215); font-weight: 400; font-size: 21px; font-family: "wf_segoe-ui_light", "Segoe UI Light", "Segoe WP Light", "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif; line-height: 21px;">
<a id="LPUrlAnchor_15374277370040.049581260627777124" style="text-decoration: none;" href="https://lists.freedesktop.org/mailman/listinfo/amd-gfx" target="_blank">amd-gfx Info Page - freedesktop.org</a></div>
<div id="LPMetadata_15374277370060.33834794254126455" style="margin: 10px 0px 16px; color: rgb(102, 102, 102); font-weight: 400; font-family: "wf_segoe-ui_normal", "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif; font-size: 14px; line-height: 14px;">
lists.freedesktop.org</div>
<div id="LPDescription_15374277370060.5403322754932623" style="display: block; color: rgb(102, 102, 102); font-weight: 400; font-family: "wf_segoe-ui_normal", "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif; font-size: 14px; line-height: 20px; max-height: 100px; overflow: hidden;">
To see the collection of prior postings to the list, visit the amd-gfx Archives.. Using amd-gfx: To post a message to all the list members, send email to amd-gfx@lists.freedesktop.org. You can subscribe to the list, or change your existing subscription, in
 the sections below.</div>
</td>
</tr>
</tbody>
</table>
</div>
<br>
</div>
</span></font></div>
</div>
</div>
</body>
</html>