1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include "amdgpu.h"
24#include "soc15.h"
25#include "soc15_hw_ip.h"
26#include "soc15_common.h"
27#include "vega20_inc.h"
28#include "vega20_ppsmc.h"
29#include "vega20_baco.h"
30#include "vega20_smumgr.h"
31
32
33
34static const struct soc15_baco_cmd_entry clean_baco_tbl[] =
35{
36 {CMD_WRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIOS_SCRATCH_6), 0, 0, 0, 0},
37 {CMD_WRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIOS_SCRATCH_7), 0, 0, 0, 0},
38};
39
40int vega20_baco_get_capability(struct pp_hwmgr *hwmgr, bool *cap)
41{
42 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
43 uint32_t reg;
44
45 *cap = false;
46 if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_BACO))
47 return 0;
48
49 if (((RREG32(0x17569) & 0x20000000) >> 29) == 0x1) {
50 reg = RREG32_SOC15(NBIF, 0, mmRCC_BIF_STRAP0);
51
52 if (reg & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK)
53 *cap = true;
54 }
55
56 return 0;
57}
58
59int vega20_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state)
60{
61 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
62 uint32_t reg;
63
64 reg = RREG32_SOC15(NBIF, 0, mmBACO_CNTL);
65
66 if (reg & BACO_CNTL__BACO_MODE_MASK)
67
68 *state = BACO_STATE_IN;
69 else
70 *state = BACO_STATE_OUT;
71 return 0;
72}
73
74int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
75{
76 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
77 enum BACO_STATE cur_state;
78 uint32_t data;
79
80 vega20_baco_get_state(hwmgr, &cur_state);
81
82 if (cur_state == state)
83
84 return 0;
85
86 if (state == BACO_STATE_IN) {
87 data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL);
88 data |= 0x80000000;
89 WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data);
90
91
92 if(smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0))
93 return -EINVAL;
94
95 } else if (state == BACO_STATE_OUT) {
96 if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ExitBaco))
97 return -EINVAL;
98 if (!soc15_baco_program_registers(hwmgr, clean_baco_tbl,
99 ARRAY_SIZE(clean_baco_tbl)))
100 return -EINVAL;
101 }
102
103 return 0;
104}
105
106int vega20_baco_apply_vdci_flush_workaround(struct pp_hwmgr *hwmgr)
107{
108 int ret = 0;
109
110 ret = vega20_set_pptable_driver_address(hwmgr);
111 if (ret)
112 return ret;
113
114 return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_BacoWorkAroundFlushVDCI);
115}
116