29
29
#include "soc15_common.h"
30
30
#include "pp_debug.h"
31
31
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
+
32
104
static int vega20_get_current_rpm (struct pp_hwmgr * hwmgr , uint32_t * current_rpm )
33
105
{
34
106
int ret = 0 ;
@@ -42,12 +114,62 @@ static int vega20_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
42
114
return 0 ;
43
115
}
44
116
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
+
45
167
int vega20_fan_ctrl_get_fan_speed_info (struct pp_hwmgr * hwmgr ,
46
168
struct phm_fan_speed_info * fan_speed_info )
47
169
{
48
170
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 ;
51
173
fan_speed_info -> supports_rpm_read = true;
52
174
fan_speed_info -> supports_rpm_write = true;
53
175
@@ -61,6 +183,31 @@ int vega20_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
61
183
return vega20_get_current_rpm (hwmgr , speed );
62
184
}
63
185
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
+
64
211
/**
65
212
* Reads the remote temperature from the SIslands thermal controller.
66
213
*
0 commit comments