Merge remote-tracking branch 'ftrace/for-next'
[deliverable/linux.git] / drivers / gpu / drm / amd / powerplay / hwmgr / iceland_thermal.c
CommitLineData
025f8bfb
HR
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 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25#include <asm/div64.h>
26#include "iceland_thermal.h"
27#include "iceland_hwmgr.h"
28#include "iceland_smumgr.h"
29#include "atombios.h"
30#include "ppsmc.h"
31
32#include "gmc/gmc_8_1_d.h"
33#include "gmc/gmc_8_1_sh_mask.h"
34
35#include "bif/bif_5_0_d.h"
36#include "bif/bif_5_0_sh_mask.h"
37
38#include "smu/smu_7_1_1_d.h"
39#include "smu/smu_7_1_1_sh_mask.h"
40
41
42/**
43* Get Fan Speed Control Parameters.
44* @param hwmgr the address of the powerplay hardware manager.
45* @param pSpeed is the address of the structure where the result is to be placed.
46* @exception Always succeeds except if we cannot zero out the output structure.
47*/
48int iceland_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
49 struct phm_fan_speed_info *fan_speed_info)
50{
51
52 if (hwmgr->thermal_controller.fanInfo.bNoFan)
53 return 0;
54
55 fan_speed_info->supports_percent_read = true;
56 fan_speed_info->supports_percent_write = true;
57 fan_speed_info->min_percent = 0;
58 fan_speed_info->max_percent = 100;
59
60 if (0 != hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution) {
61 fan_speed_info->supports_rpm_read = true;
62 fan_speed_info->supports_rpm_write = true;
63 fan_speed_info->min_rpm = hwmgr->thermal_controller.fanInfo.ulMinRPM;
64 fan_speed_info->max_rpm = hwmgr->thermal_controller.fanInfo.ulMaxRPM;
65 } else {
66 fan_speed_info->min_rpm = 0;
67 fan_speed_info->max_rpm = 0;
68 }
69
70 return 0;
71}
72
73/**
74* Get Fan Speed in percent.
75* @param hwmgr the address of the powerplay hardware manager.
76* @param pSpeed is the address of the structure where the result is to be placed.
77* @exception Fails is the 100% setting appears to be 0.
78*/
79int iceland_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t *speed)
80{
81 uint32_t duty100;
82 uint32_t duty;
83 uint64_t tmp64;
84
85 if (hwmgr->thermal_controller.fanInfo.bNoFan)
86 return 0;
87
88 duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100);
89 duty = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_STATUS, FDO_PWM_DUTY);
90
91 if (0 == duty100)
92 return -EINVAL;
93
94
95 tmp64 = (uint64_t)duty * 100;
96 do_div(tmp64, duty100);
97 *speed = (uint32_t)tmp64;
98
99 if (*speed > 100)
100 *speed = 100;
101
102 return 0;
103}
104
105/**
106* Get Fan Speed in RPM.
107* @param hwmgr the address of the powerplay hardware manager.
108* @param speed is the address of the structure where the result is to be placed.
109* @exception Returns not supported if no fan is found or if pulses per revolution are not set
110*/
111int iceland_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
112{
113 return 0;
114}
115
116/**
117* Set Fan Speed Control to static mode, so that the user can decide what speed to use.
118* @param hwmgr the address of the powerplay hardware manager.
119* mode the fan control mode, 0 default, 1 by percent, 5, by RPM
120* @exception Should always succeed.
121*/
122int iceland_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
123{
124
125 if (hwmgr->fan_ctrl_is_in_default_mode) {
126 hwmgr->fan_ctrl_default_mode = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, FDO_PWM_MODE);
127 hwmgr->tmin = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TMIN);
128 hwmgr->fan_ctrl_is_in_default_mode = false;
129 }
130
131 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TMIN, 0);
132 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, FDO_PWM_MODE, mode);
133
134 return 0;
135}
136
137/**
138* Reset Fan Speed Control to default mode.
139* @param hwmgr the address of the powerplay hardware manager.
140* @exception Should always succeed.
141*/
142static int iceland_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr)
143{
144 if (!hwmgr->fan_ctrl_is_in_default_mode) {
145 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, FDO_PWM_MODE, hwmgr->fan_ctrl_default_mode);
146 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TMIN, hwmgr->tmin);
147 hwmgr->fan_ctrl_is_in_default_mode = true;
148 }
149
150 return 0;
151}
152
153int iceland_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
154{
155 return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StartFanControl) == 0) ? 0 : -EINVAL;
156}
157
158
159int iceland_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
160{
161 return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StopFanControl) == 0) ? 0 : -EINVAL;
162}
163
164/**
165* Set Fan Speed in percent.
166* @param hwmgr the address of the powerplay hardware manager.
167* @param speed is the percentage value (0% - 100%) to be set.
168* @exception Fails is the 100% setting appears to be 0.
169*/
170int iceland_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t speed)
171{
172 uint32_t duty100;
173 uint32_t duty;
174 uint64_t tmp64;
175
176 if (hwmgr->thermal_controller.fanInfo.bNoFan)
177 return -EINVAL;
178
179 if (speed > 100) {
180 pr_warning("Cannot set more than 100%% duty cycle. Set it to 100.\n");
181 speed = 100;
182 }
183
184 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl))
185 iceland_fan_ctrl_stop_smc_fan_control(hwmgr);
186
187 duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100);
188
189 if (0 == duty100)
190 return -EINVAL;
191
192 tmp64 = (uint64_t)speed * duty100;
193 do_div(tmp64, 100);
194 duty = (uint32_t)tmp64;
195
196 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL0, FDO_STATIC_DUTY, duty);
197
198 return iceland_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
199}
200
201/**
202* Reset Fan Speed to default.
203* @param hwmgr the address of the powerplay hardware manager.
204* @exception Always succeeds.
205*/
206int iceland_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr)
207{
208 int result;
209
210 if (hwmgr->thermal_controller.fanInfo.bNoFan)
211 return 0;
212
213 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl)) {
214 result = iceland_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
215 if (0 == result)
216 result = iceland_fan_ctrl_start_smc_fan_control(hwmgr);
217 } else
218 result = iceland_fan_ctrl_set_default_mode(hwmgr);
219
220 return result;
221}
222
223/**
224* Set Fan Speed in RPM.
225* @param hwmgr the address of the powerplay hardware manager.
226* @param speed is the percentage value (min - max) to be set.
227* @exception Fails is the speed not lie between min and max.
228*/
229int iceland_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
230{
231 return 0;
232}
233
234/**
235* Reads the remote temperature from the SIslands thermal controller.
236*
237* @param hwmgr The address of the hardware manager.
238*/
239int iceland_thermal_get_temperature(struct pp_hwmgr *hwmgr)
240{
241 int temp;
242
243 temp = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_STATUS, CTF_TEMP);
244
245 /*
246 * Bit 9 means the reading is lower than the lowest usable
247 * value.
248 */
249 if (0 != (0x200 & temp))
250 temp = ICELAND_THERMAL_MAXIMUM_TEMP_READING;
251 else
252 temp = (temp & 0x1ff);
253
254 temp = temp * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
255
256 return temp;
257}
258
259/**
260* Set the requested temperature range for high and low alert signals
261*
262* @param hwmgr The address of the hardware manager.
263* @param range Temperature range to be programmed for high and low alert signals
264* @exception PP_Result_BadInput if the input data is not valid.
265*/
266static int iceland_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, uint32_t low_temp, uint32_t high_temp)
267{
268 uint32_t low = ICELAND_THERMAL_MINIMUM_ALERT_TEMP * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
269 uint32_t high = ICELAND_THERMAL_MAXIMUM_ALERT_TEMP * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
270
271 if (low < low_temp)
272 low = low_temp;
273 if (high > high_temp)
274 high = high_temp;
275
276 if (low > high)
277 return -EINVAL;
278
279 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
280 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
281 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_CTRL, DIG_THERM_DPM, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
282
283 return 0;
284}
285
286/**
287* Programs thermal controller one-time setting registers
288*
289* @param hwmgr The address of the hardware manager.
290*/
291static int iceland_thermal_initialize(struct pp_hwmgr *hwmgr)
292{
293 if (0 != hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution)
294 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
295 CG_TACH_CTRL, EDGE_PER_REV,
296 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution - 1);
297
298 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TACH_PWM_RESP_RATE, 0x28);
299
300 return 0;
301}
302
303/**
304* Enable thermal alerts on the RV770 thermal controller.
305*
306* @param hwmgr The address of the hardware manager.
307*/
308static int iceland_thermal_enable_alert(struct pp_hwmgr *hwmgr)
309{
310 uint32_t alert;
311
312 alert = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK);
313 alert &= ~(ICELAND_THERMAL_HIGH_ALERT_MASK | ICELAND_THERMAL_LOW_ALERT_MASK);
314 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK, alert);
315
316 /* send message to SMU to enable internal thermal interrupts */
317 return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Thermal_Cntl_Enable) == 0) ? 0 : -1;
318}
319
320/**
321* Disable thermal alerts on the RV770 thermal controller.
322* @param hwmgr The address of the hardware manager.
323*/
324static int iceland_thermal_disable_alert(struct pp_hwmgr *hwmgr)
325{
326 uint32_t alert;
327
328 alert = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK);
329 alert |= (ICELAND_THERMAL_HIGH_ALERT_MASK | ICELAND_THERMAL_LOW_ALERT_MASK);
330 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK, alert);
331
332 /* send message to SMU to disable internal thermal interrupts */
333 return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Thermal_Cntl_Disable) == 0) ? 0 : -1;
334}
335
336/**
337* Uninitialize the thermal controller.
338* Currently just disables alerts.
339* @param hwmgr The address of the hardware manager.
340*/
341int iceland_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr)
342{
343 int result = iceland_thermal_disable_alert(hwmgr);
344
345 if (result)
346 pr_warning("Failed to disable thermal alerts!\n");
347
348 if (hwmgr->thermal_controller.fanInfo.bNoFan)
349 iceland_fan_ctrl_set_default_mode(hwmgr);
350
351 return result;
352}
353
354/**
355* Set up the fan table to control the fan using the SMC.
356* @param hwmgr the address of the powerplay hardware manager.
357* @param pInput the pointer to input data
358* @param pOutput the pointer to output data
359* @param pStorage the pointer to temporary storage
360* @param Result the last failure code
361* @return result from set temperature range routine
362*/
363int tf_iceland_thermal_setup_fan_table(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
364{
365 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
366 SMU71_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE };
367 uint32_t duty100;
368 uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2;
369 uint16_t fdo_min, slope1, slope2;
370 uint32_t reference_clock;
371 int res;
372 uint64_t tmp64;
373
374 if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl))
375 return 0;
376
377 if (0 == data->fan_table_start) {
378 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
379 return 0;
380 }
381
382 duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100);
383
384 if (0 == duty100) {
385 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
386 return 0;
387 }
388
389 tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin * duty100;
390 do_div(tmp64, 10000);
391 fdo_min = (uint16_t)tmp64;
392
393 t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - hwmgr->thermal_controller.advanceFanControlParameters.usTMin;
394 t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - hwmgr->thermal_controller.advanceFanControlParameters.usTMed;
395
396 pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin;
397 pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed;
398
399 slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
400 slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);
401
402 fan_table.TempMin = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMin) / 100);
403 fan_table.TempMed = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMed) / 100);
404 fan_table.TempMax = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMax) / 100);
405
406 fan_table.Slope1 = cpu_to_be16(slope1);
407 fan_table.Slope2 = cpu_to_be16(slope2);
408
409 fan_table.FdoMin = cpu_to_be16(fdo_min);
410
411 fan_table.HystDown = cpu_to_be16(hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst);
412
413 fan_table.HystUp = cpu_to_be16(1);
414
415 fan_table.HystSlope = cpu_to_be16(1);
416
417 fan_table.TempRespLim = cpu_to_be16(5);
418
419 reference_clock = iceland_get_xclk(hwmgr);
420
421 fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600);
422
423 fan_table.FdoMax = cpu_to_be16((uint16_t)duty100);
424
425 fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_CTRL, TEMP_SEL);
426
427 //fan_table.FanControl_GL_Flag = 1;
428
429 res = iceland_copy_bytes_to_smc(hwmgr->smumgr, data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), data->sram_end);
430/* TO DO FOR SOME DEVICE ID 0X692b, send this msg return invalid command.
431 if (res == 0 && hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit != 0)
432 res = (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanMinPwm, \
433 hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit) ? 0 : -1);
434
435 if (res == 0 && hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit != 0)
436 res = (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanSclkTarget, \
437 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit) ? 0 : -1);
438
439 if (0 != res)
440 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
441*/
442 return 0;
443}
444
445/**
446* Start the fan control on the SMC.
447* @param hwmgr the address of the powerplay hardware manager.
448* @param pInput the pointer to input data
449* @param pOutput the pointer to output data
450* @param pStorage the pointer to temporary storage
451* @param Result the last failure code
452* @return result from set temperature range routine
453*/
454int tf_iceland_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
455{
456/* If the fantable setup has failed we could have disabled PHM_PlatformCaps_MicrocodeFanControl even after this function was included in the table.
457 * Make sure that we still think controlling the fan is OK.
458*/
459 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl)) {
460 iceland_fan_ctrl_start_smc_fan_control(hwmgr);
461 iceland_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
462 }
463
464 return 0;
465}
466
467/**
468* Set temperature range for high and low alerts
469* @param hwmgr the address of the powerplay hardware manager.
470* @param pInput the pointer to input data
471* @param pOutput the pointer to output data
472* @param pStorage the pointer to temporary storage
473* @param Result the last failure code
474* @return result from set temperature range routine
475*/
476static int tf_iceland_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
477 void *input, void *output, void *storage, int result)
478{
479 struct PP_TemperatureRange *range = (struct PP_TemperatureRange *)input;
480
481 if (range == NULL)
482 return -EINVAL;
483
484 return iceland_thermal_set_temperature_range(hwmgr, range->min, range->max);
485}
486
487/**
488* Programs one-time setting registers
489* @param hwmgr the address of the powerplay hardware manager.
490* @param pInput the pointer to input data
491* @param pOutput the pointer to output data
492* @param pStorage the pointer to temporary storage
493* @param Result the last failure code
494* @return result from initialize thermal controller routine
495*/
496static int tf_iceland_thermal_initialize(struct pp_hwmgr *hwmgr, void *input,
497 void *output, void *storage, int result)
498{
499 return iceland_thermal_initialize(hwmgr);
500}
501
502/**
503* Enable high and low alerts
504* @param hwmgr the address of the powerplay hardware manager.
505* @param pInput the pointer to input data
506* @param pOutput the pointer to output data
507* @param pStorage the pointer to temporary storage
508* @param Result the last failure code
509* @return result from enable alert routine
510*/
511static int tf_iceland_thermal_enable_alert(struct pp_hwmgr *hwmgr,
512 void *input, void *output, void *storage, int result)
513{
514 return iceland_thermal_enable_alert(hwmgr);
515}
516
517/**
518* Disable high and low alerts
519* @param hwmgr the address of the powerplay hardware manager.
520* @param pInput the pointer to input data
521* @param pOutput the pointer to output data
522* @param pStorage the pointer to temporary storage
523* @param Result the last failure code
524* @return result from disable alert routine
525*/
526static int tf_iceland_thermal_disable_alert(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
527{
528 return iceland_thermal_disable_alert(hwmgr);
529}
530
531static const struct phm_master_table_item iceland_thermal_start_thermal_controller_master_list[] = {
532 { NULL, tf_iceland_thermal_initialize },
533 { NULL, tf_iceland_thermal_set_temperature_range },
534 { NULL, tf_iceland_thermal_enable_alert },
535 /*
536 * We should restrict performance levels to low before we halt
537 * the SMC. On the other hand we are still in boot state when
538 * we do this so it would be pointless. If this assumption
539 * changes we have to revisit this table.
540 */
541 { NULL, tf_iceland_thermal_setup_fan_table},
542 { NULL, tf_iceland_thermal_start_smc_fan_control},
543 { NULL, NULL }
544};
545
546static const struct phm_master_table_header iceland_thermal_start_thermal_controller_master = {
547 0,
548 PHM_MasterTableFlag_None,
549 iceland_thermal_start_thermal_controller_master_list
550};
551
552static const struct phm_master_table_item iceland_thermal_set_temperature_range_master_list[] = {
553 { NULL, tf_iceland_thermal_disable_alert},
554 { NULL, tf_iceland_thermal_set_temperature_range},
555 { NULL, tf_iceland_thermal_enable_alert},
556 { NULL, NULL }
557};
558
559static const struct phm_master_table_header iceland_thermal_set_temperature_range_master = {
560 0,
561 PHM_MasterTableFlag_None,
562 iceland_thermal_set_temperature_range_master_list
563};
564
565int iceland_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr)
566{
567 if (!hwmgr->thermal_controller.fanInfo.bNoFan)
568 iceland_fan_ctrl_set_default_mode(hwmgr);
569 return 0;
570}
571
572/**
573* Initializes the thermal controller related functions in the Hardware Manager structure.
574* @param hwmgr The address of the hardware manager.
575* @exception Any error code from the low-level communication.
576*/
577int pp_iceland_thermal_initialize(struct pp_hwmgr *hwmgr)
578{
579 int result;
580
581 result = phm_construct_table(hwmgr, &iceland_thermal_set_temperature_range_master, &(hwmgr->set_temperature_range));
582
583 if (0 == result) {
584 result = phm_construct_table(hwmgr,
585 &iceland_thermal_start_thermal_controller_master,
586 &(hwmgr->start_thermal_controller));
587 if (0 != result)
588 phm_destroy_table(hwmgr, &(hwmgr->set_temperature_range));
589 }
590
591 if (0 == result)
592 hwmgr->fan_ctrl_is_in_default_mode = true;
593 return result;
594}
595
This page took 0.053523 seconds and 5 git commands to generate.