diff options
Diffstat (limited to 'drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c')
-rw-r--r-- | drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 83 |
1 files changed, 77 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index ef9b56de143b..e8fe84f806d1 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -60,6 +60,15 @@ MODULE_FIRMWARE("amdgpu/aldebaran_smc.bin"); MODULE_FIRMWARE("amdgpu/smu_13_0_0.bin"); MODULE_FIRMWARE("amdgpu/smu_13_0_7.bin"); +#define mmMP1_SMN_C2PMSG_66 0x0282 +#define mmMP1_SMN_C2PMSG_66_BASE_IDX 0 + +#define mmMP1_SMN_C2PMSG_82 0x0292 +#define mmMP1_SMN_C2PMSG_82_BASE_IDX 0 + +#define mmMP1_SMN_C2PMSG_90 0x029a +#define mmMP1_SMN_C2PMSG_90_BASE_IDX 0 + #define SMU13_VOLTAGE_SCALE 4 #define LINK_WIDTH_MAX 6 @@ -264,8 +273,16 @@ int smu_v13_0_check_fw_status(struct smu_context *smu) struct amdgpu_device *adev = smu->adev; uint32_t mp1_fw_flags; - mp1_fw_flags = RREG32_PCIE(MP1_Public | - (smnMP1_FIRMWARE_FLAGS & 0xffffffff)); + switch (adev->ip_versions[MP1_HWIP][0]) { + case IP_VERSION(13, 0, 4): + mp1_fw_flags = RREG32_PCIE(MP1_Public | + (smnMP1_V13_0_4_FIRMWARE_FLAGS & 0xffffffff)); + break; + default: + mp1_fw_flags = RREG32_PCIE(MP1_Public | + (smnMP1_FIRMWARE_FLAGS & 0xffffffff)); + break; + } if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >> MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT) @@ -714,6 +731,8 @@ int smu_v13_0_get_vbios_bootup_values(struct smu_context *smu) smu->smu_table.boot_values.vclk = smu_info_v3_6->bootup_vclk_10khz; smu->smu_table.boot_values.dclk = smu_info_v3_6->bootup_dclk_10khz; smu->smu_table.boot_values.fclk = smu_info_v3_6->bootup_fclk_10khz; + } else if ((frev == 3) && (crev == 1)) { + return 0; } else if ((frev == 4) && (crev == 0)) { smu_info_v4_0 = (struct atom_smu_info_v4_0 *)header; @@ -1065,12 +1084,33 @@ int smu_v13_0_set_power_limit(struct smu_context *smu, return 0; } +static int smu_v13_0_allow_ih_interrupt(struct smu_context *smu) +{ + return smu_cmn_send_smc_msg(smu, + SMU_MSG_AllowIHHostInterrupt, + NULL); +} + +static int smu_v13_0_process_pending_interrupt(struct smu_context *smu) +{ + int ret = 0; + + if (smu->dc_controlled_by_gpio && + smu_cmn_feature_is_enabled(smu, SMU_FEATURE_ACDC_BIT)) + ret = smu_v13_0_allow_ih_interrupt(smu); + + return ret; +} + int smu_v13_0_enable_thermal_alert(struct smu_context *smu) { - if (smu->smu_table.thermal_controller_type) - return amdgpu_irq_get(smu->adev, &smu->irq_source, 0); + int ret = 0; - return 0; + ret = amdgpu_irq_get(smu->adev, &smu->irq_source, 0); + if (ret) + return ret; + + return smu_v13_0_process_pending_interrupt(smu); } int smu_v13_0_disable_thermal_alert(struct smu_context *smu) @@ -2257,7 +2297,8 @@ int smu_v13_0_baco_set_state(struct smu_context *smu, if (state == SMU_BACO_STATE_ENTER) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, - 0, + smu_baco->maco_support ? + BACO_SEQ_BAMACO : BACO_SEQ_BACO, NULL); } else { ret = smu_cmn_send_smc_msg(smu, @@ -2297,6 +2338,16 @@ int smu_v13_0_baco_exit(struct smu_context *smu) SMU_BACO_STATE_EXIT); } +int smu_v13_0_set_gfx_power_up_by_imu(struct smu_context *smu) +{ + uint16_t index; + + index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, + SMU_MSG_EnableGfxImu); + + return smu_cmn_send_msg_without_waiting(smu, index, 0); +} + int smu_v13_0_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) @@ -2386,3 +2437,23 @@ int smu_v13_0_set_default_dpm_tables(struct smu_context *smu) return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false); } + +void smu_v13_0_set_smu_mailbox_registers(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + + smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82); + smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66); + smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90); +} + +int smu_v13_0_mode1_reset(struct smu_context *smu) +{ + int ret = 0; + + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL); + if (!ret) + msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS); + + return ret; +} |