drm/amd/pm: Add ih for SMU v13.0.6 thermal throttling
Add interrupt handler for thermal throttler events from PMFW on SMUv13.0.6 Signed-off-by: Asad kamal <asad.kamal@amd.com> Acked-by: Evan Quan <evan.quan@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
6d5f5eaf6a
commit
676915e410
1 changed files with 104 additions and 3 deletions
|
@ -1297,6 +1297,109 @@ static int smu_v13_0_6_set_power_limit(struct smu_context *smu,
|
||||||
return smu_v13_0_set_power_limit(smu, limit_type, limit);
|
return smu_v13_0_set_power_limit(smu, limit_type, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int smu_v13_0_6_irq_process(struct amdgpu_device *adev,
|
||||||
|
struct amdgpu_irq_src *source,
|
||||||
|
struct amdgpu_iv_entry *entry)
|
||||||
|
{
|
||||||
|
struct smu_context *smu = adev->powerplay.pp_handle;
|
||||||
|
uint32_t client_id = entry->client_id;
|
||||||
|
uint32_t src_id = entry->src_id;
|
||||||
|
/*
|
||||||
|
* ctxid is used to distinguish different
|
||||||
|
* events for SMCToHost interrupt
|
||||||
|
*/
|
||||||
|
uint32_t ctxid = entry->src_data[0];
|
||||||
|
uint32_t data;
|
||||||
|
|
||||||
|
if (client_id == SOC15_IH_CLIENTID_MP1) {
|
||||||
|
if (src_id == IH_INTERRUPT_ID_TO_DRIVER) {
|
||||||
|
/* ACK SMUToHost interrupt */
|
||||||
|
data = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
|
||||||
|
data = REG_SET_FIELD(data, MP1_SMN_IH_SW_INT_CTRL, INT_ACK, 1);
|
||||||
|
WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, data);
|
||||||
|
|
||||||
|
switch (ctxid) {
|
||||||
|
case IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING:
|
||||||
|
/*
|
||||||
|
* Increment the throttle interrupt counter
|
||||||
|
*/
|
||||||
|
atomic64_inc(&smu->throttle_int_counter);
|
||||||
|
|
||||||
|
if (!atomic_read(&adev->throttling_logging_enabled))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (__ratelimit(&adev->throttling_logging_rs))
|
||||||
|
schedule_work(&smu->throttling_logging_work);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smu_v13_0_6_set_irq_state(struct amdgpu_device *adev,
|
||||||
|
struct amdgpu_irq_src *source,
|
||||||
|
unsigned tyep,
|
||||||
|
enum amdgpu_interrupt_state state)
|
||||||
|
{
|
||||||
|
uint32_t val = 0;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case AMDGPU_IRQ_STATE_DISABLE:
|
||||||
|
/* For MP1 SW irqs */
|
||||||
|
val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
|
||||||
|
val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 1);
|
||||||
|
WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case AMDGPU_IRQ_STATE_ENABLE:
|
||||||
|
/* For MP1 SW irqs */
|
||||||
|
val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT);
|
||||||
|
val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, ID, 0xFE);
|
||||||
|
val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, VALID, 0);
|
||||||
|
WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT, val);
|
||||||
|
|
||||||
|
val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
|
||||||
|
val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 0);
|
||||||
|
WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct amdgpu_irq_src_funcs smu_v13_0_6_irq_funcs =
|
||||||
|
{
|
||||||
|
.set = smu_v13_0_6_set_irq_state,
|
||||||
|
.process = smu_v13_0_6_irq_process,
|
||||||
|
};
|
||||||
|
|
||||||
|
int smu_v13_0_6_register_irq_handler(struct smu_context *smu)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = smu->adev;
|
||||||
|
struct amdgpu_irq_src *irq_src = &smu->irq_source;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (amdgpu_sriov_vf(adev))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
irq_src->num_types = 1;
|
||||||
|
irq_src->funcs = &smu_v13_0_6_irq_funcs;
|
||||||
|
|
||||||
|
ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_MP1,
|
||||||
|
IH_INTERRUPT_ID_TO_DRIVER,
|
||||||
|
irq_src);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int smu_v13_0_6_system_features_control(struct smu_context *smu,
|
static int smu_v13_0_6_system_features_control(struct smu_context *smu,
|
||||||
bool enable)
|
bool enable)
|
||||||
{
|
{
|
||||||
|
@ -2042,11 +2145,9 @@ static const struct pptable_funcs smu_v13_0_6_ppt_funcs = {
|
||||||
.feature_is_enabled = smu_cmn_feature_is_enabled,
|
.feature_is_enabled = smu_cmn_feature_is_enabled,
|
||||||
.set_power_limit = smu_v13_0_6_set_power_limit,
|
.set_power_limit = smu_v13_0_6_set_power_limit,
|
||||||
.set_xgmi_pstate = smu_v13_0_set_xgmi_pstate,
|
.set_xgmi_pstate = smu_v13_0_set_xgmi_pstate,
|
||||||
/* TODO: Thermal limits unknown, skip these for now
|
.register_irq_handler = smu_v13_0_6_register_irq_handler,
|
||||||
.register_irq_handler = smu_v13_0_register_irq_handler,
|
|
||||||
.enable_thermal_alert = smu_v13_0_enable_thermal_alert,
|
.enable_thermal_alert = smu_v13_0_enable_thermal_alert,
|
||||||
.disable_thermal_alert = smu_v13_0_disable_thermal_alert,
|
.disable_thermal_alert = smu_v13_0_disable_thermal_alert,
|
||||||
*/
|
|
||||||
.setup_pptable = smu_v13_0_6_setup_pptable,
|
.setup_pptable = smu_v13_0_6_setup_pptable,
|
||||||
.baco_is_support = smu_v13_0_6_is_baco_supported,
|
.baco_is_support = smu_v13_0_6_is_baco_supported,
|
||||||
.get_dpm_ultimate_freq = smu_v13_0_6_get_dpm_ultimate_freq,
|
.get_dpm_ultimate_freq = smu_v13_0_6_get_dpm_ultimate_freq,
|
||||||
|
|
Loading…
Add table
Reference in a new issue