Merge remote-tracking branch 'xen-tip/linux-next'
[deliverable/linux.git] / drivers / gpu / drm / amd / powerplay / hwmgr / iceland_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 * 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 */
48 int 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 */
79 int 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 */
111 int 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 */
122 int 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 */
142 static 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
153 int 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
159 int 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 */
170 int 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 */
206 int 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 */
229 int 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 */
239 int 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 */
266 static 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 */
291 static 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 */
308 static 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 */
324 static 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 */
341 int 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 */
363 int 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 */
454 int 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 */
476 static 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 */
496 static 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 */
511 static 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 */
526 static 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
531 static 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
546 static 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
552 static 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
559 static 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
565 int 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 */
577 int 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.059007 seconds and 5 git commands to generate.