drm/amd/powerplay: Setup sw CTF to allow graceful exit when temperature exceeds maximum.

cherry-pick from amd windows driver.

Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Rex Zhu 2017-05-04 14:51:31 +08:00 committed by Alex Deucher
parent 652bd0c344
commit 5784d5cca6

View File

@ -381,14 +381,10 @@ int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr)
temp = cgs_read_register(hwmgr->device, reg); temp = cgs_read_register(hwmgr->device, reg);
temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >> temp = (temp & CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP_MASK) >>
CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT; CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP__SHIFT;
/* Bit 9 means the reading is lower than the lowest usable value. */ temp = temp & 0x1ff;
if (temp & 0x200)
temp = VEGA10_THERMAL_MAXIMUM_TEMP_READING;
else
temp = temp & 0x1ff;
temp *= PP_TEMPERATURE_UNITS_PER_CENTIGRADES; temp *= PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
@ -424,23 +420,28 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
mmTHM_THERMAL_INT_CTRL_BASE_IDX, mmTHM_THERMAL_INT_CTRL); mmTHM_THERMAL_INT_CTRL_BASE_IDX, mmTHM_THERMAL_INT_CTRL);
val = cgs_read_register(hwmgr->device, reg); val = cgs_read_register(hwmgr->device, reg);
val &= ~(THM_THERMAL_INT_CTRL__DIG_THERM_INTH_MASK);
val |= (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) << val &= (~THM_THERMAL_INT_CTRL__MAX_IH_CREDIT_MASK);
THM_THERMAL_INT_CTRL__DIG_THERM_INTH__SHIFT; val |= (5 << THM_THERMAL_INT_CTRL__MAX_IH_CREDIT__SHIFT);
val &= ~(THM_THERMAL_INT_CTRL__DIG_THERM_INTL_MASK);
val |= (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) << val &= (~THM_THERMAL_INT_CTRL__THERM_IH_HW_ENA_MASK);
THM_THERMAL_INT_CTRL__DIG_THERM_INTL__SHIFT; val |= (1 << THM_THERMAL_INT_CTRL__THERM_IH_HW_ENA__SHIFT);
val &= (~THM_THERMAL_INT_CTRL__DIG_THERM_INTH_MASK);
val |= ((high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
<< THM_THERMAL_INT_CTRL__DIG_THERM_INTH__SHIFT);
val &= (~THM_THERMAL_INT_CTRL__DIG_THERM_INTL_MASK);
val |= ((low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
<< THM_THERMAL_INT_CTRL__DIG_THERM_INTL__SHIFT);
val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
cgs_write_register(hwmgr->device, reg, val); cgs_write_register(hwmgr->device, reg, val);
reg = soc15_get_register_offset(THM_HWID, 0, reg = soc15_get_register_offset(THM_HWID, 0,
mmTHM_TCON_HTC_BASE_IDX, mmTHM_TCON_HTC); mmTHM_TCON_HTC_BASE_IDX, mmTHM_TCON_HTC);
val = cgs_read_register(hwmgr->device, reg);
val &= ~(THM_TCON_HTC__HTC_TMP_LMT_MASK);
val |= (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) <<
THM_TCON_HTC__HTC_TMP_LMT__SHIFT;
cgs_write_register(hwmgr->device, reg, val);
return 0; return 0;
} }
@ -482,18 +483,28 @@ static int vega10_thermal_initialize(struct pp_hwmgr *hwmgr)
static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr) static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
{ {
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend); struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
uint32_t val = 0;
uint32_t reg;
if (data->smu_features[GNLD_FW_CTF].supported) { if (data->smu_features[GNLD_FW_CTF].supported) {
if (data->smu_features[GNLD_FW_CTF].enabled) if (data->smu_features[GNLD_FW_CTF].enabled)
printk("[Thermal_EnableAlert] FW CTF Already Enabled!\n"); printk("[Thermal_EnableAlert] FW CTF Already Enabled!\n");
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
true,
data->smu_features[GNLD_FW_CTF].smu_feature_bitmap),
"Attempt to Enable FW CTF feature Failed!",
return -1);
data->smu_features[GNLD_FW_CTF].enabled = true;
} }
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr, val |= (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT);
true, val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT);
data->smu_features[GNLD_FW_CTF].smu_feature_bitmap), val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT);
"Attempt to Enable FW CTF feature Failed!",
return -1); reg = soc15_get_register_offset(THM_HWID, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX, mmTHM_THERMAL_INT_ENA);
data->smu_features[GNLD_FW_CTF].enabled = true; cgs_write_register(hwmgr->device, reg, val);
return 0; return 0;
} }
@ -504,18 +515,24 @@ static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr) int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr)
{ {
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend); struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
uint32_t reg;
if (data->smu_features[GNLD_FW_CTF].supported) { if (data->smu_features[GNLD_FW_CTF].supported) {
if (!data->smu_features[GNLD_FW_CTF].enabled) if (!data->smu_features[GNLD_FW_CTF].enabled)
printk("[Thermal_EnableAlert] FW CTF Already disabled!\n"); printk("[Thermal_EnableAlert] FW CTF Already disabled!\n");
}
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
false, false,
data->smu_features[GNLD_FW_CTF].smu_feature_bitmap), data->smu_features[GNLD_FW_CTF].smu_feature_bitmap),
"Attempt to disable FW CTF feature Failed!", "Attempt to disable FW CTF feature Failed!",
return -1); return -1);
data->smu_features[GNLD_FW_CTF].enabled = false; data->smu_features[GNLD_FW_CTF].enabled = false;
}
reg = soc15_get_register_offset(THM_HWID, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX, mmTHM_THERMAL_INT_ENA);
cgs_write_register(hwmgr->device, reg, 0);
return 0; return 0;
} }