0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include "amdgpu.h"
0024 #include "soc15.h"
0025 #include "soc15_hw_ip.h"
0026 #include "soc15_common.h"
0027 #include "vega20_inc.h"
0028 #include "vega20_ppsmc.h"
0029 #include "vega20_baco.h"
0030 #include "vega20_smumgr.h"
0031
0032 #include "amdgpu_ras.h"
0033
0034 static const struct soc15_baco_cmd_entry clean_baco_tbl[] =
0035 {
0036 {CMD_WRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIOS_SCRATCH_6), 0, 0, 0, 0},
0037 {CMD_WRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIOS_SCRATCH_7), 0, 0, 0, 0},
0038 };
0039
0040 int vega20_baco_get_capability(struct pp_hwmgr *hwmgr, bool *cap)
0041 {
0042 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
0043 uint32_t reg;
0044
0045 *cap = false;
0046 if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_BACO))
0047 return 0;
0048
0049 if (((RREG32(0x17569) & 0x20000000) >> 29) == 0x1) {
0050 reg = RREG32_SOC15(NBIF, 0, mmRCC_BIF_STRAP0);
0051
0052 if (reg & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK)
0053 *cap = true;
0054 }
0055
0056 return 0;
0057 }
0058
0059 int vega20_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state)
0060 {
0061 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
0062 uint32_t reg;
0063
0064 reg = RREG32_SOC15(NBIF, 0, mmBACO_CNTL);
0065
0066 if (reg & BACO_CNTL__BACO_MODE_MASK)
0067
0068 *state = BACO_STATE_IN;
0069 else
0070 *state = BACO_STATE_OUT;
0071 return 0;
0072 }
0073
0074 int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
0075 {
0076 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
0077 struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
0078 enum BACO_STATE cur_state;
0079 uint32_t data;
0080
0081 vega20_baco_get_state(hwmgr, &cur_state);
0082
0083 if (cur_state == state)
0084
0085 return 0;
0086
0087 if (state == BACO_STATE_IN) {
0088 if (!ras || !adev->ras_enabled) {
0089 data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL);
0090 data |= 0x80000000;
0091 WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data);
0092
0093 if(smum_send_msg_to_smc_with_parameter(hwmgr,
0094 PPSMC_MSG_EnterBaco, 0, NULL))
0095 return -EINVAL;
0096 } else {
0097 if(smum_send_msg_to_smc_with_parameter(hwmgr,
0098 PPSMC_MSG_EnterBaco, 1, NULL))
0099 return -EINVAL;
0100 }
0101
0102 } else if (state == BACO_STATE_OUT) {
0103 if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ExitBaco, NULL))
0104 return -EINVAL;
0105 if (!soc15_baco_program_registers(hwmgr, clean_baco_tbl,
0106 ARRAY_SIZE(clean_baco_tbl)))
0107 return -EINVAL;
0108 }
0109
0110 return 0;
0111 }
0112
0113 int vega20_baco_apply_vdci_flush_workaround(struct pp_hwmgr *hwmgr)
0114 {
0115 int ret = 0;
0116
0117 ret = vega20_set_pptable_driver_address(hwmgr);
0118 if (ret)
0119 return ret;
0120
0121 return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_BacoWorkAroundFlushVDCI, NULL);
0122 }