Skip to content

Commit 031db09

Browse files
Evan Quanalexdeucher
authored andcommitted
drm/amd/powerplay/vega20: enable fan RPM and pwm settings V2
Manual fan RPM and pwm setting on vega20 are available now. V2: correct the register for fan speed setting and avoid divide-by-zero Signed-off-by: Evan Quan <[email protected]> Reviewed-by: Alex Deucher <[email protected]> Reviewed-by: Rex Zhu <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 42fae99 commit 031db09

File tree

5 files changed

+207
-4
lines changed

5 files changed

+207
-4
lines changed

drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@
2626
#define mmCG_MULT_THERMAL_STATUS 0x005f
2727
#define mmCG_MULT_THERMAL_STATUS_BASE_IDX 0
2828

29+
#define mmCG_FDO_CTRL0 0x0067
30+
#define mmCG_FDO_CTRL0_BASE_IDX 0
31+
32+
#define mmCG_FDO_CTRL1 0x0068
33+
#define mmCG_FDO_CTRL1_BASE_IDX 0
34+
35+
#define mmCG_FDO_CTRL2 0x0069
36+
#define mmCG_FDO_CTRL2_BASE_IDX 0
37+
38+
#define mmCG_TACH_CTRL 0x006a
39+
#define mmCG_TACH_CTRL_BASE_IDX 0
40+
2941
#define mmTHM_THERMAL_INT_ENA 0x000a
3042
#define mmTHM_THERMAL_INT_ENA_BASE_IDX 0
3143
#define mmTHM_THERMAL_INT_CTRL 0x000b

drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@
2828
#define CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT 0x9
2929
#define CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP_MASK 0x000001FFL
3030
#define CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK 0x0003FE00L
31+
#define CG_FDO_CTRL2__TMIN__SHIFT 0x0
32+
#define CG_FDO_CTRL2__TMIN_MASK 0x000000FFL
33+
#define CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT 0xb
34+
#define CG_FDO_CTRL2__FDO_PWM_MODE_MASK 0x00003800L
35+
#define CG_FDO_CTRL1__FMAX_DUTY100__SHIFT 0x0
36+
#define CG_FDO_CTRL1__FMAX_DUTY100_MASK 0x000000FFL
37+
#define CG_FDO_CTRL0__FDO_STATIC_DUTY__SHIFT 0x0
38+
#define CG_FDO_CTRL0__FDO_STATIC_DUTY_MASK 0x000000FFL
39+
#define CG_TACH_CTRL__TARGET_PERIOD__SHIFT 0x3
40+
#define CG_TACH_CTRL__TARGET_PERIOD_MASK 0xFFFFFFF8L
3141

3242
//THM_THERMAL_INT_ENA
3343
#define THM_THERMAL_INT_ENA__THERM_INTH_SET__SHIFT 0x0

drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,6 +2289,25 @@ static uint32_t vega20_get_fan_control_mode(struct pp_hwmgr *hwmgr)
22892289
return AMD_FAN_CTRL_AUTO;
22902290
}
22912291

2292+
static void vega20_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
2293+
{
2294+
switch (mode) {
2295+
case AMD_FAN_CTRL_NONE:
2296+
vega20_fan_ctrl_set_fan_speed_percent(hwmgr, 100);
2297+
break;
2298+
case AMD_FAN_CTRL_MANUAL:
2299+
if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
2300+
vega20_fan_ctrl_stop_smc_fan_control(hwmgr);
2301+
break;
2302+
case AMD_FAN_CTRL_AUTO:
2303+
if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
2304+
vega20_fan_ctrl_start_smc_fan_control(hwmgr);
2305+
break;
2306+
default:
2307+
break;
2308+
}
2309+
}
2310+
22922311
static int vega20_get_dal_power_level(struct pp_hwmgr *hwmgr,
22932312
struct amd_pp_simple_clock_info *info)
22942313
{
@@ -3452,12 +3471,20 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
34523471
.disable_smc_firmware_ctf =
34533472
vega20_thermal_disable_alert,
34543473
/* fan control related */
3474+
.get_fan_speed_percent =
3475+
vega20_fan_ctrl_get_fan_speed_percent,
3476+
.set_fan_speed_percent =
3477+
vega20_fan_ctrl_set_fan_speed_percent,
34553478
.get_fan_speed_info =
34563479
vega20_fan_ctrl_get_fan_speed_info,
34573480
.get_fan_speed_rpm =
34583481
vega20_fan_ctrl_get_fan_speed_rpm,
3482+
.set_fan_speed_rpm =
3483+
vega20_fan_ctrl_set_fan_speed_rpm,
34593484
.get_fan_control_mode =
34603485
vega20_get_fan_control_mode,
3486+
.set_fan_control_mode =
3487+
vega20_set_fan_control_mode,
34613488
/* smu memory related */
34623489
.notify_cac_buffer_info =
34633490
vega20_notify_cac_buffer_info,

drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c

Lines changed: 149 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,78 @@
2929
#include "soc15_common.h"
3030
#include "pp_debug.h"
3131

32+
static int vega20_disable_fan_control_feature(struct pp_hwmgr *hwmgr)
33+
{
34+
struct vega20_hwmgr *data = hwmgr->backend;
35+
int ret = 0;
36+
37+
if (data->smu_features[GNLD_FAN_CONTROL].supported) {
38+
ret = vega20_enable_smc_features(
39+
hwmgr, false,
40+
data->smu_features[GNLD_FAN_CONTROL].
41+
smu_feature_bitmap);
42+
PP_ASSERT_WITH_CODE(!ret,
43+
"Disable FAN CONTROL feature Failed!",
44+
return ret);
45+
data->smu_features[GNLD_FAN_CONTROL].enabled = false;
46+
}
47+
48+
return ret;
49+
}
50+
51+
int vega20_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
52+
{
53+
struct vega20_hwmgr *data = hwmgr->backend;
54+
55+
if (data->smu_features[GNLD_FAN_CONTROL].supported)
56+
return vega20_disable_fan_control_feature(hwmgr);
57+
58+
return 0;
59+
}
60+
61+
static int vega20_enable_fan_control_feature(struct pp_hwmgr *hwmgr)
62+
{
63+
struct vega20_hwmgr *data = hwmgr->backend;
64+
int ret = 0;
65+
66+
if (data->smu_features[GNLD_FAN_CONTROL].supported) {
67+
ret = vega20_enable_smc_features(
68+
hwmgr, true,
69+
data->smu_features[GNLD_FAN_CONTROL].
70+
smu_feature_bitmap);
71+
PP_ASSERT_WITH_CODE(!ret,
72+
"Enable FAN CONTROL feature Failed!",
73+
return ret);
74+
data->smu_features[GNLD_FAN_CONTROL].enabled = true;
75+
}
76+
77+
return ret;
78+
}
79+
80+
int vega20_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
81+
{
82+
struct vega20_hwmgr *data = hwmgr->backend;
83+
84+
if (data->smu_features[GNLD_FAN_CONTROL].supported)
85+
return vega20_enable_fan_control_feature(hwmgr);
86+
87+
return 0;
88+
}
89+
90+
static int vega20_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
91+
{
92+
struct amdgpu_device *adev = hwmgr->adev;
93+
94+
WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
95+
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
96+
CG_FDO_CTRL2, TMIN, 0));
97+
WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
98+
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
99+
CG_FDO_CTRL2, FDO_PWM_MODE, mode));
100+
101+
return 0;
102+
}
103+
32104
static int vega20_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
33105
{
34106
int ret = 0;
@@ -42,12 +114,62 @@ static int vega20_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
42114
return 0;
43115
}
44116

117+
int vega20_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr,
118+
uint32_t *speed)
119+
{
120+
struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
121+
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
122+
uint32_t current_rpm, percent = 0;
123+
int ret = 0;
124+
125+
ret = vega20_get_current_rpm(hwmgr, &current_rpm);
126+
if (ret)
127+
return ret;
128+
129+
percent = current_rpm * 100 / pp_table->FanMaximumRpm;
130+
131+
*speed = percent > 100 ? 100 : percent;
132+
133+
return 0;
134+
}
135+
136+
int vega20_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr,
137+
uint32_t speed)
138+
{
139+
struct amdgpu_device *adev = hwmgr->adev;
140+
uint32_t duty100;
141+
uint32_t duty;
142+
uint64_t tmp64;
143+
144+
if (speed > 100)
145+
speed = 100;
146+
147+
if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
148+
vega20_fan_ctrl_stop_smc_fan_control(hwmgr);
149+
150+
duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
151+
CG_FDO_CTRL1, FMAX_DUTY100);
152+
153+
if (duty100 == 0)
154+
return -EINVAL;
155+
156+
tmp64 = (uint64_t)speed * duty100;
157+
do_div(tmp64, 100);
158+
duty = (uint32_t)tmp64;
159+
160+
WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0,
161+
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0),
162+
CG_FDO_CTRL0, FDO_STATIC_DUTY, duty));
163+
164+
return vega20_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
165+
}
166+
45167
int vega20_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
46168
struct phm_fan_speed_info *fan_speed_info)
47169
{
48170
memset(fan_speed_info, 0, sizeof(*fan_speed_info));
49-
fan_speed_info->supports_percent_read = false;
50-
fan_speed_info->supports_percent_write = false;
171+
fan_speed_info->supports_percent_read = true;
172+
fan_speed_info->supports_percent_write = true;
51173
fan_speed_info->supports_rpm_read = true;
52174
fan_speed_info->supports_rpm_write = true;
53175

@@ -61,6 +183,31 @@ int vega20_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
61183
return vega20_get_current_rpm(hwmgr, speed);
62184
}
63185

186+
int vega20_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
187+
{
188+
struct amdgpu_device *adev = hwmgr->adev;
189+
uint32_t tach_period, crystal_clock_freq;
190+
int result = 0;
191+
192+
if (!speed)
193+
return -EINVAL;
194+
195+
if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) {
196+
result = vega20_fan_ctrl_stop_smc_fan_control(hwmgr);
197+
if (result)
198+
return result;
199+
}
200+
201+
crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
202+
tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
203+
WREG32_SOC15(THM, 0, mmCG_TACH_CTRL,
204+
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL),
205+
CG_TACH_CTRL, TARGET_PERIOD,
206+
tach_period));
207+
208+
return vega20_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC_RPM);
209+
}
210+
64211
/**
65212
* Reads the remote temperature from the SIslands thermal controller.
66213
*

drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,22 @@ struct vega20_temperature {
5050
#define FDO_PWM_MODE_STATIC_RPM 5
5151

5252
extern int vega20_thermal_get_temperature(struct pp_hwmgr *hwmgr);
53-
extern int vega20_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr);
5453
extern int vega20_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
5554
struct phm_fan_speed_info *fan_speed_info);
56-
extern int vega20_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr);
5755
extern int vega20_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr,
5856
uint32_t *speed);
57+
extern int vega20_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr,
58+
uint32_t speed);
59+
extern int vega20_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr,
60+
uint32_t *speed);
61+
extern int vega20_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr,
62+
uint32_t speed);
63+
extern int vega20_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr);
64+
extern int vega20_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr);
5965
extern int vega20_thermal_disable_alert(struct pp_hwmgr *hwmgr);
6066
extern int vega20_start_thermal_controller(struct pp_hwmgr *hwmgr,
6167
struct PP_TemperatureRange *range);
68+
extern int vega20_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr);
6269

6370
#endif
6471

0 commit comments

Comments
 (0)