linux/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
<<
>>
Prefs
   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);
  35        *current_rpm = smum_get_argument(hwmgr);
  36        return 0;
  37}
  38
  39int 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
  68int 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
  91int 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*/
 128int 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*/
 157int 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 */
 183static 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
 200static 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
 217int 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
 230int 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*/
 251int 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*/
 290int 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*/
 307int 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*/
 339int 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*/
 364static 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*/
 402static 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*/
 425static 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*/
 456int 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*/
 484int 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*/
 503int 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
 559int vega10_enable_mgpu_fan_boost(struct pp_hwmgr *hwmgr)
 560{
 561        struct vega10_hwmgr *data = hwmgr->backend;
 562        PPTable_t *table = &(data->smc_state_table.pp_table);
 563        int ret;
 564
 565        if (!data->smu_features[GNLD_FAN_CONTROL].supported)
 566                return 0;
 567
 568        if (!hwmgr->thermal_controller.advanceFanControlParameters.
 569                        usMGpuThrottlingRPMLimit)
 570                return 0;
 571
 572        table->FanThrottlingRpm = hwmgr->thermal_controller.
 573                        advanceFanControlParameters.usMGpuThrottlingRPMLimit;
 574
 575        ret = smum_smc_table_manager(hwmgr,
 576                                (uint8_t *)(&(data->smc_state_table.pp_table)),
 577                                PPTABLE, false);
 578        if (ret) {
 579                pr_info("Failed to update fan control table in pptable!");
 580                return ret;
 581        }
 582
 583        ret = vega10_disable_fan_control_feature(hwmgr);
 584        if (ret) {
 585                pr_info("Attempt to disable SMC fan control feature failed!");
 586                return ret;
 587        }
 588
 589        ret = vega10_enable_fan_control_feature(hwmgr);
 590        if (ret)
 591                pr_info("Attempt to enable SMC fan control feature failed!");
 592
 593        return ret;
 594}
 595
 596/**
 597* Start the fan control on the SMC.
 598* @param    hwmgr  the address of the powerplay hardware manager.
 599* @param    pInput the pointer to input data
 600* @param    pOutput the pointer to output data
 601* @param    pStorage the pointer to temporary storage
 602* @param    Result the last failure code
 603* @return   result from set temperature range routine
 604*/
 605int vega10_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr)
 606{
 607/* If the fantable setup has failed we could have disabled
 608 * PHM_PlatformCaps_MicrocodeFanControl even after
 609 * this function was included in the table.
 610 * Make sure that we still think controlling the fan is OK.
 611*/
 612        if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
 613                vega10_fan_ctrl_start_smc_fan_control(hwmgr);
 614
 615        return 0;
 616}
 617
 618
 619int vega10_start_thermal_controller(struct pp_hwmgr *hwmgr,
 620                                struct PP_TemperatureRange *range)
 621{
 622        int ret = 0;
 623
 624        if (range == NULL)
 625                return -EINVAL;
 626
 627        vega10_thermal_initialize(hwmgr);
 628        ret = vega10_thermal_set_temperature_range(hwmgr, range);
 629        if (ret)
 630                return -EINVAL;
 631
 632        vega10_thermal_enable_alert(hwmgr);
 633/* We should restrict performance levels to low before we halt the SMC.
 634 * On the other hand we are still in boot state when we do this
 635 * so it would be pointless.
 636 * If this assumption changes we have to revisit this table.
 637 */
 638        ret = vega10_thermal_setup_fan_table(hwmgr);
 639        if (ret)
 640                return -EINVAL;
 641
 642        vega10_thermal_start_smc_fan_control(hwmgr);
 643
 644        return 0;
 645};
 646
 647
 648
 649
 650int vega10_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr)
 651{
 652        if (!hwmgr->thermal_controller.fanInfo.bNoFan) {
 653                vega10_fan_ctrl_set_default_mode(hwmgr);
 654                vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
 655        }
 656        return 0;
 657}
 658