vega10_thermal.c (19781B)
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 32static int vega10_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm) 33{ 34 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentRpm, current_rpm); 35 return 0; 36} 37 38int vega10_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, 39 struct phm_fan_speed_info *fan_speed_info) 40{ 41 42 if (hwmgr->thermal_controller.fanInfo.bNoFan) 43 return 0; 44 45 fan_speed_info->supports_percent_read = true; 46 fan_speed_info->supports_percent_write = true; 47 fan_speed_info->min_percent = 0; 48 fan_speed_info->max_percent = 100; 49 50 if (PP_CAP(PHM_PlatformCaps_FanSpeedInTableIsRPM) && 51 hwmgr->thermal_controller.fanInfo. 52 ucTachometerPulsesPerRevolution) { 53 fan_speed_info->supports_rpm_read = true; 54 fan_speed_info->supports_rpm_write = true; 55 fan_speed_info->min_rpm = 56 hwmgr->thermal_controller.fanInfo.ulMinRPM; 57 fan_speed_info->max_rpm = 58 hwmgr->thermal_controller.fanInfo.ulMaxRPM; 59 } else { 60 fan_speed_info->min_rpm = 0; 61 fan_speed_info->max_rpm = 0; 62 } 63 64 return 0; 65} 66 67int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr, 68 uint32_t *speed) 69{ 70 uint32_t current_rpm; 71 uint32_t percent = 0; 72 73 if (hwmgr->thermal_controller.fanInfo.bNoFan) 74 return 0; 75 76 if (vega10_get_current_rpm(hwmgr, ¤t_rpm)) 77 return -1; 78 79 if (hwmgr->thermal_controller. 80 advanceFanControlParameters.usMaxFanRPM != 0) 81 percent = current_rpm * 255 / 82 hwmgr->thermal_controller. 83 advanceFanControlParameters.usMaxFanRPM; 84 85 *speed = MIN(percent, 255); 86 87 return 0; 88} 89 90int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed) 91{ 92 struct amdgpu_device *adev = hwmgr->adev; 93 struct vega10_hwmgr *data = hwmgr->backend; 94 uint32_t tach_period; 95 uint32_t crystal_clock_freq; 96 int result = 0; 97 98 if (hwmgr->thermal_controller.fanInfo.bNoFan) 99 return -1; 100 101 if (data->smu_features[GNLD_FAN_CONTROL].supported) { 102 result = vega10_get_current_rpm(hwmgr, speed); 103 } else { 104 tach_period = 105 REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_STATUS), 106 CG_TACH_STATUS, 107 TACH_PERIOD); 108 109 if (tach_period == 0) 110 return -EINVAL; 111 112 crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev); 113 114 *speed = 60 * crystal_clock_freq * 10000 / tach_period; 115 } 116 117 return result; 118} 119 120/** 121 * vega10_fan_ctrl_set_static_mode - Set Fan Speed Control to static mode, 122 * so that the user can decide what speed to use. 123 * @hwmgr: the address of the powerplay hardware manager. 124 * @mode: the fan control mode, 0 default, 1 by percent, 5, by RPM 125 * Exception: Should always succeed. 126 */ 127int vega10_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode) 128{ 129 struct amdgpu_device *adev = hwmgr->adev; 130 131 if (hwmgr->fan_ctrl_is_in_default_mode) { 132 hwmgr->fan_ctrl_default_mode = 133 REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2), 134 CG_FDO_CTRL2, FDO_PWM_MODE); 135 hwmgr->tmin = 136 REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2), 137 CG_FDO_CTRL2, TMIN); 138 hwmgr->fan_ctrl_is_in_default_mode = false; 139 } 140 141 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2, 142 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2), 143 CG_FDO_CTRL2, TMIN, 0)); 144 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2, 145 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2), 146 CG_FDO_CTRL2, FDO_PWM_MODE, mode)); 147 148 return 0; 149} 150 151/** 152 * vega10_fan_ctrl_set_default_mode - Reset Fan Speed Control to default mode. 153 * @hwmgr: the address of the powerplay hardware manager. 154 * Exception: Should always succeed. 155 */ 156int vega10_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr) 157{ 158 struct amdgpu_device *adev = hwmgr->adev; 159 160 if (!hwmgr->fan_ctrl_is_in_default_mode) { 161 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2, 162 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2), 163 CG_FDO_CTRL2, FDO_PWM_MODE, 164 hwmgr->fan_ctrl_default_mode)); 165 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2, 166 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2), 167 CG_FDO_CTRL2, TMIN, 168 hwmgr->tmin << CG_FDO_CTRL2__TMIN__SHIFT)); 169 hwmgr->fan_ctrl_is_in_default_mode = true; 170 } 171 172 return 0; 173} 174 175/** 176 * vega10_enable_fan_control_feature - Enables the SMC Fan Control Feature. 177 * 178 * @hwmgr: the address of the powerplay hardware manager. 179 * Return: 0 on success. -1 otherwise. 180 */ 181static int vega10_enable_fan_control_feature(struct pp_hwmgr *hwmgr) 182{ 183 struct vega10_hwmgr *data = hwmgr->backend; 184 185 if (data->smu_features[GNLD_FAN_CONTROL].supported) { 186 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features( 187 hwmgr, true, 188 data->smu_features[GNLD_FAN_CONTROL]. 189 smu_feature_bitmap), 190 "Attempt to Enable FAN CONTROL feature Failed!", 191 return -1); 192 data->smu_features[GNLD_FAN_CONTROL].enabled = true; 193 } 194 195 return 0; 196} 197 198static int vega10_disable_fan_control_feature(struct pp_hwmgr *hwmgr) 199{ 200 struct vega10_hwmgr *data = hwmgr->backend; 201 202 if (data->smu_features[GNLD_FAN_CONTROL].supported) { 203 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features( 204 hwmgr, false, 205 data->smu_features[GNLD_FAN_CONTROL]. 206 smu_feature_bitmap), 207 "Attempt to Enable FAN CONTROL feature Failed!", 208 return -1); 209 data->smu_features[GNLD_FAN_CONTROL].enabled = false; 210 } 211 212 return 0; 213} 214 215int vega10_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr) 216{ 217 if (hwmgr->thermal_controller.fanInfo.bNoFan) 218 return -1; 219 220 PP_ASSERT_WITH_CODE(!vega10_enable_fan_control_feature(hwmgr), 221 "Attempt to Enable SMC FAN CONTROL Feature Failed!", 222 return -1); 223 224 return 0; 225} 226 227 228int vega10_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr) 229{ 230 struct vega10_hwmgr *data = hwmgr->backend; 231 232 if (hwmgr->thermal_controller.fanInfo.bNoFan) 233 return -1; 234 235 if (data->smu_features[GNLD_FAN_CONTROL].supported) { 236 PP_ASSERT_WITH_CODE(!vega10_disable_fan_control_feature(hwmgr), 237 "Attempt to Disable SMC FAN CONTROL Feature Failed!", 238 return -1); 239 } 240 return 0; 241} 242 243/** 244 * vega10_fan_ctrl_set_fan_speed_pwm - Set Fan Speed in PWM. 245 * @hwmgr: the address of the powerplay hardware manager. 246 * @speed: is the percentage value (0 - 255) to be set. 247 */ 248int vega10_fan_ctrl_set_fan_speed_pwm(struct pp_hwmgr *hwmgr, 249 uint32_t speed) 250{ 251 struct amdgpu_device *adev = hwmgr->adev; 252 uint32_t duty100; 253 uint32_t duty; 254 uint64_t tmp64; 255 256 if (hwmgr->thermal_controller.fanInfo.bNoFan) 257 return 0; 258 259 speed = MIN(speed, 255); 260 261 if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) 262 vega10_fan_ctrl_stop_smc_fan_control(hwmgr); 263 264 duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1), 265 CG_FDO_CTRL1, FMAX_DUTY100); 266 267 if (duty100 == 0) 268 return -EINVAL; 269 270 tmp64 = (uint64_t)speed * duty100; 271 do_div(tmp64, 255); 272 duty = (uint32_t)tmp64; 273 274 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0, 275 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0), 276 CG_FDO_CTRL0, FDO_STATIC_DUTY, duty)); 277 278 return vega10_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC); 279} 280 281/** 282 * vega10_fan_ctrl_reset_fan_speed_to_default - Reset Fan Speed to default. 283 * @hwmgr: the address of the powerplay hardware manager. 284 * Exception: Always succeeds. 285 */ 286int vega10_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr) 287{ 288 if (hwmgr->thermal_controller.fanInfo.bNoFan) 289 return 0; 290 291 if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) 292 return vega10_fan_ctrl_start_smc_fan_control(hwmgr); 293 else 294 return vega10_fan_ctrl_set_default_mode(hwmgr); 295} 296 297/** 298 * vega10_fan_ctrl_set_fan_speed_rpm - Set Fan Speed in RPM. 299 * @hwmgr: the address of the powerplay hardware manager. 300 * @speed: is the percentage value (min - max) to be set. 301 * Exception: Fails is the speed not lie between min and max. 302 */ 303int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed) 304{ 305 struct amdgpu_device *adev = hwmgr->adev; 306 uint32_t tach_period; 307 uint32_t crystal_clock_freq; 308 int result = 0; 309 310 if (hwmgr->thermal_controller.fanInfo.bNoFan || 311 speed == 0 || 312 (speed < hwmgr->thermal_controller.fanInfo.ulMinRPM) || 313 (speed > hwmgr->thermal_controller.fanInfo.ulMaxRPM)) 314 return -1; 315 316 if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) 317 result = vega10_fan_ctrl_stop_smc_fan_control(hwmgr); 318 319 if (!result) { 320 crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev); 321 tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed); 322 WREG32_SOC15(THM, 0, mmCG_TACH_CTRL, 323 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL), 324 CG_TACH_CTRL, TARGET_PERIOD, 325 tach_period)); 326 } 327 return vega10_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC_RPM); 328} 329 330/** 331 * vega10_thermal_get_temperature - Reads the remote temperature from the SIslands thermal controller. 332 * 333 * @hwmgr: The address of the hardware manager. 334 */ 335int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr) 336{ 337 struct amdgpu_device *adev = hwmgr->adev; 338 int temp; 339 340 temp = RREG32_SOC15(THM, 0, mmCG_MULT_THERMAL_STATUS); 341 342 temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >> 343 CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT; 344 345 temp = temp & 0x1ff; 346 347 temp *= PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 348 349 return temp; 350} 351 352/** 353 * vega10_thermal_set_temperature_range - Set the requested temperature range for high and low alert signals 354 * 355 * @hwmgr: The address of the hardware manager. 356 * @range: Temperature range to be programmed for 357 * high and low alert signals 358 * Exception: PP_Result_BadInput if the input data is not valid. 359 */ 360static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, 361 struct PP_TemperatureRange *range) 362{ 363 struct phm_ppt_v2_information *pp_table_info = 364 (struct phm_ppt_v2_information *)(hwmgr->pptable); 365 struct phm_tdp_table *tdp_table = pp_table_info->tdp_table; 366 struct amdgpu_device *adev = hwmgr->adev; 367 int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP; 368 int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP; 369 uint32_t val; 370 371 /* compare them in unit celsius degree */ 372 if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) 373 low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 374 375 /* 376 * As a common sense, usSoftwareShutdownTemp should be bigger 377 * than ThotspotLimit. For any invalid usSoftwareShutdownTemp, 378 * we will just use the max possible setting VEGA10_THERMAL_MAXIMUM_ALERT_TEMP 379 * to avoid false alarms. 380 */ 381 if ((tdp_table->usSoftwareShutdownTemp > 382 range->hotspot_crit_max / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)) { 383 if (high > tdp_table->usSoftwareShutdownTemp) 384 high = tdp_table->usSoftwareShutdownTemp; 385 } 386 387 if (low > high) 388 return -EINVAL; 389 390 val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL); 391 392 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); 393 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); 394 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high); 395 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low); 396 val &= (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK) & 397 (~THM_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK) & 398 (~THM_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK); 399 400 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val); 401 402 return 0; 403} 404 405/** 406 * vega10_thermal_initialize - Programs thermal controller one-time setting registers 407 * 408 * @hwmgr: The address of the hardware manager. 409 */ 410static int vega10_thermal_initialize(struct pp_hwmgr *hwmgr) 411{ 412 struct amdgpu_device *adev = hwmgr->adev; 413 414 if (hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution) { 415 WREG32_SOC15(THM, 0, mmCG_TACH_CTRL, 416 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL), 417 CG_TACH_CTRL, EDGE_PER_REV, 418 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution - 1)); 419 } 420 421 WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2, 422 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2), 423 CG_FDO_CTRL2, TACH_PWM_RESP_RATE, 0x28)); 424 425 return 0; 426} 427 428/** 429 * vega10_thermal_enable_alert - Enable thermal alerts on the RV770 thermal controller. 430 * 431 * @hwmgr: The address of the hardware manager. 432 */ 433static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr) 434{ 435 struct amdgpu_device *adev = hwmgr->adev; 436 struct vega10_hwmgr *data = hwmgr->backend; 437 uint32_t val = 0; 438 439 if (data->smu_features[GNLD_FW_CTF].supported) { 440 if (data->smu_features[GNLD_FW_CTF].enabled) 441 printk("[Thermal_EnableAlert] FW CTF Already Enabled!\n"); 442 443 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr, 444 true, 445 data->smu_features[GNLD_FW_CTF].smu_feature_bitmap), 446 "Attempt to Enable FW CTF feature Failed!", 447 return -1); 448 data->smu_features[GNLD_FW_CTF].enabled = true; 449 } 450 451 val |= (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT); 452 val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT); 453 val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT); 454 455 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, val); 456 457 return 0; 458} 459 460/** 461 * vega10_thermal_disable_alert - Disable thermal alerts on the RV770 thermal controller. 462 * @hwmgr: The address of the hardware manager. 463 */ 464int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr) 465{ 466 struct amdgpu_device *adev = hwmgr->adev; 467 struct vega10_hwmgr *data = hwmgr->backend; 468 469 if (data->smu_features[GNLD_FW_CTF].supported) { 470 if (!data->smu_features[GNLD_FW_CTF].enabled) 471 printk("[Thermal_EnableAlert] FW CTF Already disabled!\n"); 472 473 474 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr, 475 false, 476 data->smu_features[GNLD_FW_CTF].smu_feature_bitmap), 477 "Attempt to disable FW CTF feature Failed!", 478 return -1); 479 data->smu_features[GNLD_FW_CTF].enabled = false; 480 } 481 482 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, 0); 483 484 return 0; 485} 486 487/** 488 * vega10_thermal_stop_thermal_controller - Uninitialize the thermal controller. 489 * Currently just disables alerts. 490 * @hwmgr: The address of the hardware manager. 491 */ 492int vega10_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) 493{ 494 int result = vega10_thermal_disable_alert(hwmgr); 495 496 if (!hwmgr->thermal_controller.fanInfo.bNoFan) 497 vega10_fan_ctrl_set_default_mode(hwmgr); 498 499 return result; 500} 501 502/** 503 * vega10_thermal_setup_fan_table - Set up the fan table to control the fan using the SMC. 504 * @hwmgr: the address of the powerplay hardware manager. 505 * Return: result from set temperature range routine 506 */ 507static int vega10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) 508{ 509 int ret; 510 struct vega10_hwmgr *data = hwmgr->backend; 511 PPTable_t *table = &(data->smc_state_table.pp_table); 512 513 if (!data->smu_features[GNLD_FAN_CONTROL].supported) 514 return 0; 515 516 table->FanMaximumRpm = (uint16_t)hwmgr->thermal_controller. 517 advanceFanControlParameters.usMaxFanRPM; 518 table->FanThrottlingRpm = hwmgr->thermal_controller. 519 advanceFanControlParameters.usFanRPMMaxLimit; 520 table->FanAcousticLimitRpm = (uint16_t)(hwmgr->thermal_controller. 521 advanceFanControlParameters.ulMinFanSCLKAcousticLimit); 522 table->FanTargetTemperature = hwmgr->thermal_controller. 523 advanceFanControlParameters.usTMax; 524 525 smum_send_msg_to_smc_with_parameter(hwmgr, 526 PPSMC_MSG_SetFanTemperatureTarget, 527 (uint32_t)table->FanTargetTemperature, 528 NULL); 529 530 table->FanPwmMin = hwmgr->thermal_controller. 531 advanceFanControlParameters.usPWMMin * 255 / 100; 532 table->FanTargetGfxclk = (uint16_t)(hwmgr->thermal_controller. 533 advanceFanControlParameters.ulTargetGfxClk); 534 table->FanGainEdge = hwmgr->thermal_controller. 535 advanceFanControlParameters.usFanGainEdge; 536 table->FanGainHotspot = hwmgr->thermal_controller. 537 advanceFanControlParameters.usFanGainHotspot; 538 table->FanGainLiquid = hwmgr->thermal_controller. 539 advanceFanControlParameters.usFanGainLiquid; 540 table->FanGainVrVddc = hwmgr->thermal_controller. 541 advanceFanControlParameters.usFanGainVrVddc; 542 table->FanGainVrMvdd = hwmgr->thermal_controller. 543 advanceFanControlParameters.usFanGainVrMvdd; 544 table->FanGainPlx = hwmgr->thermal_controller. 545 advanceFanControlParameters.usFanGainPlx; 546 table->FanGainHbm = hwmgr->thermal_controller. 547 advanceFanControlParameters.usFanGainHbm; 548 table->FanZeroRpmEnable = hwmgr->thermal_controller. 549 advanceFanControlParameters.ucEnableZeroRPM; 550 table->FanStopTemp = hwmgr->thermal_controller. 551 advanceFanControlParameters.usZeroRPMStopTemperature; 552 table->FanStartTemp = hwmgr->thermal_controller. 553 advanceFanControlParameters.usZeroRPMStartTemperature; 554 555 ret = smum_smc_table_manager(hwmgr, 556 (uint8_t *)(&(data->smc_state_table.pp_table)), 557 PPTABLE, false); 558 if (ret) 559 pr_info("Failed to update Fan Control Table in PPTable!"); 560 561 return ret; 562} 563 564int vega10_enable_mgpu_fan_boost(struct pp_hwmgr *hwmgr) 565{ 566 struct vega10_hwmgr *data = hwmgr->backend; 567 PPTable_t *table = &(data->smc_state_table.pp_table); 568 int ret; 569 570 if (!data->smu_features[GNLD_FAN_CONTROL].supported) 571 return 0; 572 573 if (!hwmgr->thermal_controller.advanceFanControlParameters. 574 usMGpuThrottlingRPMLimit) 575 return 0; 576 577 table->FanThrottlingRpm = hwmgr->thermal_controller. 578 advanceFanControlParameters.usMGpuThrottlingRPMLimit; 579 580 ret = smum_smc_table_manager(hwmgr, 581 (uint8_t *)(&(data->smc_state_table.pp_table)), 582 PPTABLE, false); 583 if (ret) { 584 pr_info("Failed to update fan control table in pptable!"); 585 return ret; 586 } 587 588 ret = vega10_disable_fan_control_feature(hwmgr); 589 if (ret) { 590 pr_info("Attempt to disable SMC fan control feature failed!"); 591 return ret; 592 } 593 594 ret = vega10_enable_fan_control_feature(hwmgr); 595 if (ret) 596 pr_info("Attempt to enable SMC fan control feature failed!"); 597 598 return ret; 599} 600 601/** 602 * vega10_thermal_start_smc_fan_control - Start the fan control on the SMC. 603 * @hwmgr: the address of the powerplay hardware manager. 604 * Return: result from set temperature range routine 605 */ 606static int vega10_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr) 607{ 608/* If the fantable setup has failed we could have disabled 609 * PHM_PlatformCaps_MicrocodeFanControl even after 610 * this function was included in the table. 611 * Make sure that we still think controlling the fan is OK. 612*/ 613 if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) 614 vega10_fan_ctrl_start_smc_fan_control(hwmgr); 615 616 return 0; 617} 618 619 620int vega10_start_thermal_controller(struct pp_hwmgr *hwmgr, 621 struct PP_TemperatureRange *range) 622{ 623 int ret = 0; 624 625 if (range == NULL) 626 return -EINVAL; 627 628 vega10_thermal_initialize(hwmgr); 629 ret = vega10_thermal_set_temperature_range(hwmgr, range); 630 if (ret) 631 return -EINVAL; 632 633 vega10_thermal_enable_alert(hwmgr); 634/* We should restrict performance levels to low before we halt the SMC. 635 * On the other hand we are still in boot state when we do this 636 * so it would be pointless. 637 * If this assumption changes we have to revisit this table. 638 */ 639 ret = vega10_thermal_setup_fan_table(hwmgr); 640 if (ret) 641 return -EINVAL; 642 643 vega10_thermal_start_smc_fan_control(hwmgr); 644 645 return 0; 646}; 647 648 649 650 651int vega10_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr) 652{ 653 if (!hwmgr->thermal_controller.fanInfo.bNoFan) { 654 vega10_fan_ctrl_set_default_mode(hwmgr); 655 vega10_fan_ctrl_stop_smc_fan_control(hwmgr); 656 } 657 return 0; 658}