cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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, &current_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}