Merge branch 'drm-fixes-5.0' of git://people.freedesktop.org/~agd5f/linux into drm...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / powerplay / hwmgr / vega10_thermal.c
1 /*
2  * Copyright 2016 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23
24 #include "vega10_thermal.h"
25 #include "vega10_hwmgr.h"
26 #include "vega10_smumgr.h"
27 #include "vega10_ppsmc.h"
28 #include "vega10_inc.h"
29 #include "soc15_common.h"
30 #include "pp_debug.h"
31
32 static int vega10_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
33 {
34         smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentRpm);
35         *current_rpm = smum_get_argument(hwmgr);
36         return 0;
37 }
38
39 int vega10_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
40                 struct phm_fan_speed_info *fan_speed_info)
41 {
42
43         if (hwmgr->thermal_controller.fanInfo.bNoFan)
44                 return 0;
45
46         fan_speed_info->supports_percent_read = true;
47         fan_speed_info->supports_percent_write = true;
48         fan_speed_info->min_percent = 0;
49         fan_speed_info->max_percent = 100;
50
51         if (PP_CAP(PHM_PlatformCaps_FanSpeedInTableIsRPM) &&
52                 hwmgr->thermal_controller.fanInfo.
53                 ucTachometerPulsesPerRevolution) {
54                 fan_speed_info->supports_rpm_read = true;
55                 fan_speed_info->supports_rpm_write = true;
56                 fan_speed_info->min_rpm =
57                                 hwmgr->thermal_controller.fanInfo.ulMinRPM;
58                 fan_speed_info->max_rpm =
59                                 hwmgr->thermal_controller.fanInfo.ulMaxRPM;
60         } else {
61                 fan_speed_info->min_rpm = 0;
62                 fan_speed_info->max_rpm = 0;
63         }
64
65         return 0;
66 }
67
68 int vega10_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr,
69                 uint32_t *speed)
70 {
71         uint32_t current_rpm;
72         uint32_t percent = 0;
73
74         if (hwmgr->thermal_controller.fanInfo.bNoFan)
75                 return 0;
76
77         if (vega10_get_current_rpm(hwmgr, &current_rpm))
78                 return -1;
79
80         if (hwmgr->thermal_controller.
81                         advanceFanControlParameters.usMaxFanRPM != 0)
82                 percent = current_rpm * 100 /
83                         hwmgr->thermal_controller.
84                         advanceFanControlParameters.usMaxFanRPM;
85
86         *speed = percent > 100 ? 100 : percent;
87
88         return 0;
89 }
90
91 int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
92 {
93         struct amdgpu_device *adev = hwmgr->adev;
94         struct vega10_hwmgr *data = hwmgr->backend;
95         uint32_t tach_period;
96         uint32_t crystal_clock_freq;
97         int result = 0;
98
99         if (hwmgr->thermal_controller.fanInfo.bNoFan)
100                 return -1;
101
102         if (data->smu_features[GNLD_FAN_CONTROL].supported) {
103                 result = vega10_get_current_rpm(hwmgr, speed);
104         } else {
105                 tach_period =
106                         REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_STATUS),
107                                           CG_TACH_STATUS,
108                                           TACH_PERIOD);
109
110                 if (tach_period == 0)
111                         return -EINVAL;
112
113                 crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
114
115                 *speed = 60 * crystal_clock_freq * 10000 / tach_period;
116         }
117
118         return result;
119 }
120
121 /**
122 * Set Fan Speed Control to static mode,
123 * so that the user can decide what speed to use.
124 * @param    hwmgr  the address of the powerplay hardware manager.
125 *           mode the fan control mode, 0 default, 1 by percent, 5, by RPM
126 * @exception Should always succeed.
127 */
128 int vega10_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
129 {
130         struct amdgpu_device *adev = hwmgr->adev;
131
132         if (hwmgr->fan_ctrl_is_in_default_mode) {
133                 hwmgr->fan_ctrl_default_mode =
134                         REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
135                                 CG_FDO_CTRL2, FDO_PWM_MODE);
136                 hwmgr->tmin =
137                         REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
138                                 CG_FDO_CTRL2, TMIN);
139                 hwmgr->fan_ctrl_is_in_default_mode = false;
140         }
141
142         WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
143                         REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
144                                 CG_FDO_CTRL2, TMIN, 0));
145         WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
146                         REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
147                                 CG_FDO_CTRL2, FDO_PWM_MODE, mode));
148
149         return 0;
150 }
151
152 /**
153 * Reset Fan Speed Control to default mode.
154 * @param    hwmgr  the address of the powerplay hardware manager.
155 * @exception Should always succeed.
156 */
157 int vega10_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr)
158 {
159         struct amdgpu_device *adev = hwmgr->adev;
160
161         if (!hwmgr->fan_ctrl_is_in_default_mode) {
162                 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
163                         REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
164                                 CG_FDO_CTRL2, FDO_PWM_MODE,
165                                 hwmgr->fan_ctrl_default_mode));
166                 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
167                         REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
168                                 CG_FDO_CTRL2, TMIN,
169                                 hwmgr->tmin << CG_FDO_CTRL2__TMIN__SHIFT));
170                 hwmgr->fan_ctrl_is_in_default_mode = true;
171         }
172
173         return 0;
174 }
175
176 /**
177  * @fn vega10_enable_fan_control_feature
178  * @brief Enables the SMC Fan Control Feature.
179  *
180  * @param    hwmgr - the address of the powerplay hardware manager.
181  * @return   0 on success. -1 otherwise.
182  */
183 static int vega10_enable_fan_control_feature(struct pp_hwmgr *hwmgr)
184 {
185         struct vega10_hwmgr *data = hwmgr->backend;
186
187         if (data->smu_features[GNLD_FAN_CONTROL].supported) {
188                 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(
189                                 hwmgr, true,
190                                 data->smu_features[GNLD_FAN_CONTROL].
191                                 smu_feature_bitmap),
192                                 "Attempt to Enable FAN CONTROL feature Failed!",
193                                 return -1);
194                 data->smu_features[GNLD_FAN_CONTROL].enabled = true;
195         }
196
197         return 0;
198 }
199
200 static int vega10_disable_fan_control_feature(struct pp_hwmgr *hwmgr)
201 {
202         struct vega10_hwmgr *data = hwmgr->backend;
203
204         if (data->smu_features[GNLD_FAN_CONTROL].supported) {
205                 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(
206                                 hwmgr, false,
207                                 data->smu_features[GNLD_FAN_CONTROL].
208                                 smu_feature_bitmap),
209                                 "Attempt to Enable FAN CONTROL feature Failed!",
210                                 return -1);
211                 data->smu_features[GNLD_FAN_CONTROL].enabled = false;
212         }
213
214         return 0;
215 }
216
217 int vega10_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
218 {
219         if (hwmgr->thermal_controller.fanInfo.bNoFan)
220                 return -1;
221
222         PP_ASSERT_WITH_CODE(!vega10_enable_fan_control_feature(hwmgr),
223                         "Attempt to Enable SMC FAN CONTROL Feature Failed!",
224                         return -1);
225
226         return 0;
227 }
228
229
230 int vega10_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
231 {
232         struct vega10_hwmgr *data = hwmgr->backend;
233
234         if (hwmgr->thermal_controller.fanInfo.bNoFan)
235                 return -1;
236
237         if (data->smu_features[GNLD_FAN_CONTROL].supported) {
238                 PP_ASSERT_WITH_CODE(!vega10_disable_fan_control_feature(hwmgr),
239                                 "Attempt to Disable SMC FAN CONTROL Feature Failed!",
240                                 return -1);
241         }
242         return 0;
243 }
244
245 /**
246 * Set Fan Speed in percent.
247 * @param    hwmgr  the address of the powerplay hardware manager.
248 * @param    speed is the percentage value (0% - 100%) to be set.
249 * @exception Fails is the 100% setting appears to be 0.
250 */
251 int vega10_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr,
252                 uint32_t speed)
253 {
254         struct amdgpu_device *adev = hwmgr->adev;
255         uint32_t duty100;
256         uint32_t duty;
257         uint64_t tmp64;
258
259         if (hwmgr->thermal_controller.fanInfo.bNoFan)
260                 return 0;
261
262         if (speed > 100)
263                 speed = 100;
264
265         if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
266                 vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
267
268         duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
269                                     CG_FDO_CTRL1, FMAX_DUTY100);
270
271         if (duty100 == 0)
272                 return -EINVAL;
273
274         tmp64 = (uint64_t)speed * duty100;
275         do_div(tmp64, 100);
276         duty = (uint32_t)tmp64;
277
278         WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0,
279                 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0),
280                         CG_FDO_CTRL0, FDO_STATIC_DUTY, duty));
281
282         return vega10_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
283 }
284
285 /**
286 * Reset Fan Speed to default.
287 * @param    hwmgr  the address of the powerplay hardware manager.
288 * @exception Always succeeds.
289 */
290 int vega10_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr)
291 {
292         if (hwmgr->thermal_controller.fanInfo.bNoFan)
293                 return 0;
294
295         if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
296                 return vega10_fan_ctrl_start_smc_fan_control(hwmgr);
297         else
298                 return vega10_fan_ctrl_set_default_mode(hwmgr);
299 }
300
301 /**
302 * Set Fan Speed in RPM.
303 * @param    hwmgr  the address of the powerplay hardware manager.
304 * @param    speed is the percentage value (min - max) to be set.
305 * @exception Fails is the speed not lie between min and max.
306 */
307 int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
308 {
309         struct amdgpu_device *adev = hwmgr->adev;
310         uint32_t tach_period;
311         uint32_t crystal_clock_freq;
312         int result = 0;
313
314         if (hwmgr->thermal_controller.fanInfo.bNoFan ||
315             speed == 0 ||
316             (speed < hwmgr->thermal_controller.fanInfo.ulMinRPM) ||
317             (speed > hwmgr->thermal_controller.fanInfo.ulMaxRPM))
318                 return -1;
319
320         if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
321                 result = vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
322
323         if (!result) {
324                 crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
325                 tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
326                 WREG32_SOC15(THM, 0, mmCG_TACH_CTRL,
327                                 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL),
328                                         CG_TACH_CTRL, TARGET_PERIOD,
329                                         tach_period));
330         }
331         return vega10_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC_RPM);
332 }
333
334 /**
335 * Reads the remote temperature from the SIslands thermal controller.
336 *
337 * @param    hwmgr The address of the hardware manager.
338 */
339 int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr)
340 {
341         struct amdgpu_device *adev = hwmgr->adev;
342         int temp;
343
344         temp = RREG32_SOC15(THM, 0, mmCG_MULT_THERMAL_STATUS);
345
346         temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >>
347                         CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT;
348
349         temp = temp & 0x1ff;
350
351         temp *= PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
352
353         return temp;
354 }
355
356 /**
357 * Set the requested temperature range for high and low alert signals
358 *
359 * @param    hwmgr The address of the hardware manager.
360 * @param    range Temperature range to be programmed for
361 *           high and low alert signals
362 * @exception PP_Result_BadInput if the input data is not valid.
363 */
364 static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
365                 struct PP_TemperatureRange *range)
366 {
367         struct amdgpu_device *adev = hwmgr->adev;
368         int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP *
369                         PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
370         int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP *
371                         PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
372         uint32_t val;
373
374         if (low < range->min)
375                 low = range->min;
376         if (high > range->max)
377                 high = range->max;
378
379         if (low > high)
380                 return -EINVAL;
381
382         val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL);
383
384         val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
385         val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
386         val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
387         val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
388         val &= (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK) &
389                         (~THM_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK) &
390                         (~THM_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK);
391
392         WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);
393
394         return 0;
395 }
396
397 /**
398 * Programs thermal controller one-time setting registers
399 *
400 * @param    hwmgr The address of the hardware manager.
401 */
402 static int vega10_thermal_initialize(struct pp_hwmgr *hwmgr)
403 {
404         struct amdgpu_device *adev = hwmgr->adev;
405
406         if (hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution) {
407                 WREG32_SOC15(THM, 0, mmCG_TACH_CTRL,
408                         REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL),
409                                 CG_TACH_CTRL, EDGE_PER_REV,
410                                 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution - 1));
411         }
412
413         WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
414                 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
415                         CG_FDO_CTRL2, TACH_PWM_RESP_RATE, 0x28));
416
417         return 0;
418 }
419
420 /**
421 * Enable thermal alerts on the RV770 thermal controller.
422 *
423 * @param    hwmgr The address of the hardware manager.
424 */
425 static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
426 {
427         struct amdgpu_device *adev = hwmgr->adev;
428         struct vega10_hwmgr *data = hwmgr->backend;
429         uint32_t val = 0;
430
431         if (data->smu_features[GNLD_FW_CTF].supported) {
432                 if (data->smu_features[GNLD_FW_CTF].enabled)
433                         printk("[Thermal_EnableAlert] FW CTF Already Enabled!\n");
434
435                 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
436                                 true,
437                                 data->smu_features[GNLD_FW_CTF].smu_feature_bitmap),
438                                 "Attempt to Enable FW CTF feature Failed!",
439                                 return -1);
440                 data->smu_features[GNLD_FW_CTF].enabled = true;
441         }
442
443         val |= (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT);
444         val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT);
445         val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT);
446
447         WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, val);
448
449         return 0;
450 }
451
452 /**
453 * Disable thermal alerts on the RV770 thermal controller.
454 * @param    hwmgr The address of the hardware manager.
455 */
456 int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr)
457 {
458         struct amdgpu_device *adev = hwmgr->adev;
459         struct vega10_hwmgr *data = hwmgr->backend;
460
461         if (data->smu_features[GNLD_FW_CTF].supported) {
462                 if (!data->smu_features[GNLD_FW_CTF].enabled)
463                         printk("[Thermal_EnableAlert] FW CTF Already disabled!\n");
464
465
466                 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
467                         false,
468                         data->smu_features[GNLD_FW_CTF].smu_feature_bitmap),
469                         "Attempt to disable FW CTF feature Failed!",
470                         return -1);
471                 data->smu_features[GNLD_FW_CTF].enabled = false;
472         }
473
474         WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, 0);
475
476         return 0;
477 }
478
479 /**
480 * Uninitialize the thermal controller.
481 * Currently just disables alerts.
482 * @param    hwmgr The address of the hardware manager.
483 */
484 int vega10_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr)
485 {
486         int result = vega10_thermal_disable_alert(hwmgr);
487
488         if (!hwmgr->thermal_controller.fanInfo.bNoFan)
489                 vega10_fan_ctrl_set_default_mode(hwmgr);
490
491         return result;
492 }
493
494 /**
495 * Set up the fan table to control the fan using the SMC.
496 * @param    hwmgr  the address of the powerplay hardware manager.
497 * @param    pInput the pointer to input data
498 * @param    pOutput the pointer to output data
499 * @param    pStorage the pointer to temporary storage
500 * @param    Result the last failure code
501 * @return   result from set temperature range routine
502 */
503 int vega10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
504 {
505         int ret;
506         struct vega10_hwmgr *data = hwmgr->backend;
507         PPTable_t *table = &(data->smc_state_table.pp_table);
508
509         if (!data->smu_features[GNLD_FAN_CONTROL].supported)
510                 return 0;
511
512         table->FanMaximumRpm = (uint16_t)hwmgr->thermal_controller.
513                         advanceFanControlParameters.usMaxFanRPM;
514         table->FanThrottlingRpm = hwmgr->thermal_controller.
515                         advanceFanControlParameters.usFanRPMMaxLimit;
516         table->FanAcousticLimitRpm = (uint16_t)(hwmgr->thermal_controller.
517                         advanceFanControlParameters.ulMinFanSCLKAcousticLimit);
518         table->FanTargetTemperature = hwmgr->thermal_controller.
519                         advanceFanControlParameters.usTMax;
520
521         smum_send_msg_to_smc_with_parameter(hwmgr,
522                                 PPSMC_MSG_SetFanTemperatureTarget,
523                                 (uint32_t)table->FanTargetTemperature);
524
525         table->FanPwmMin = hwmgr->thermal_controller.
526                         advanceFanControlParameters.usPWMMin * 255 / 100;
527         table->FanTargetGfxclk = (uint16_t)(hwmgr->thermal_controller.
528                         advanceFanControlParameters.ulTargetGfxClk);
529         table->FanGainEdge = hwmgr->thermal_controller.
530                         advanceFanControlParameters.usFanGainEdge;
531         table->FanGainHotspot = hwmgr->thermal_controller.
532                         advanceFanControlParameters.usFanGainHotspot;
533         table->FanGainLiquid = hwmgr->thermal_controller.
534                         advanceFanControlParameters.usFanGainLiquid;
535         table->FanGainVrVddc = hwmgr->thermal_controller.
536                         advanceFanControlParameters.usFanGainVrVddc;
537         table->FanGainVrMvdd = hwmgr->thermal_controller.
538                         advanceFanControlParameters.usFanGainVrMvdd;
539         table->FanGainPlx = hwmgr->thermal_controller.
540                         advanceFanControlParameters.usFanGainPlx;
541         table->FanGainHbm = hwmgr->thermal_controller.
542                         advanceFanControlParameters.usFanGainHbm;
543         table->FanZeroRpmEnable = hwmgr->thermal_controller.
544                         advanceFanControlParameters.ucEnableZeroRPM;
545         table->FanStopTemp = hwmgr->thermal_controller.
546                         advanceFanControlParameters.usZeroRPMStopTemperature;
547         table->FanStartTemp = hwmgr->thermal_controller.
548                         advanceFanControlParameters.usZeroRPMStartTemperature;
549
550         ret = smum_smc_table_manager(hwmgr,
551                                 (uint8_t *)(&(data->smc_state_table.pp_table)),
552                                 PPTABLE, false);
553         if (ret)
554                 pr_info("Failed to update Fan Control Table in PPTable!");
555
556         return ret;
557 }
558
559 /**
560 * Start the fan control on the SMC.
561 * @param    hwmgr  the address of the powerplay hardware manager.
562 * @param    pInput the pointer to input data
563 * @param    pOutput the pointer to output data
564 * @param    pStorage the pointer to temporary storage
565 * @param    Result the last failure code
566 * @return   result from set temperature range routine
567 */
568 int vega10_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr)
569 {
570 /* If the fantable setup has failed we could have disabled
571  * PHM_PlatformCaps_MicrocodeFanControl even after
572  * this function was included in the table.
573  * Make sure that we still think controlling the fan is OK.
574 */
575         if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
576                 vega10_fan_ctrl_start_smc_fan_control(hwmgr);
577
578         return 0;
579 }
580
581
582 int vega10_start_thermal_controller(struct pp_hwmgr *hwmgr,
583                                 struct PP_TemperatureRange *range)
584 {
585         int ret = 0;
586
587         if (range == NULL)
588                 return -EINVAL;
589
590         vega10_thermal_initialize(hwmgr);
591         ret = vega10_thermal_set_temperature_range(hwmgr, range);
592         if (ret)
593                 return -EINVAL;
594
595         vega10_thermal_enable_alert(hwmgr);
596 /* We should restrict performance levels to low before we halt the SMC.
597  * On the other hand we are still in boot state when we do this
598  * so it would be pointless.
599  * If this assumption changes we have to revisit this table.
600  */
601         ret = vega10_thermal_setup_fan_table(hwmgr);
602         if (ret)
603                 return -EINVAL;
604
605         vega10_thermal_start_smc_fan_control(hwmgr);
606
607         return 0;
608 };
609
610
611
612
613 int vega10_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr)
614 {
615         if (!hwmgr->thermal_controller.fanInfo.bNoFan) {
616                 vega10_fan_ctrl_set_default_mode(hwmgr);
617                 vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
618         }
619         return 0;
620 }