Commit | Line | Data |
---|---|---|
da28d1c0 AD |
1 | /* |
2 | * Copyright 2019 Advanced Micro Devices, Inc. | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | |
5 | * copy of this software and associated documentation files (the "Software"), | |
6 | * to deal in the Software without restriction, including without limitation | |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
8 | * and/or sell copies of the Software, and to permit persons to whom the | |
9 | * Software is furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice shall be included in | |
12 | * all copies or substantial portions of the Software. | |
13 | * | |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
20 | * OTHER DEALINGS IN THE SOFTWARE. | |
21 | * | |
22 | */ | |
23 | #include "amdgpu.h" | |
24 | #include "fiji_baco.h" | |
25 | ||
26 | #include "gmc/gmc_8_1_d.h" | |
27 | #include "gmc/gmc_8_1_sh_mask.h" | |
28 | ||
29 | #include "bif/bif_5_0_d.h" | |
30 | #include "bif/bif_5_0_sh_mask.h" | |
31 | ||
32 | #include "dce/dce_10_0_d.h" | |
33 | #include "dce/dce_10_0_sh_mask.h" | |
34 | ||
35 | #include "smu/smu_7_1_3_d.h" | |
36 | #include "smu/smu_7_1_3_sh_mask.h" | |
37 | ||
38 | ||
39 | static const struct baco_cmd_entry gpio_tbl[] = | |
40 | { | |
41 | { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, | |
42 | { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, | |
43 | { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, | |
44 | { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff }, | |
45 | { CMD_WRITE, mmDC_GPIO_DVODATA_EN, 0, 0, 0, 0x0 }, | |
46 | { CMD_WRITE, mmDC_GPIO_DVODATA_MASK, 0, 0, 0, 0xffffffff }, | |
47 | { CMD_WRITE, mmDC_GPIO_GENERIC_EN, 0, 0, 0, 0x0 }, | |
48 | { CMD_READMODIFYWRITE, mmDC_GPIO_GENERIC_MASK, 0, 0, 0, 0x03333333 }, | |
49 | { CMD_WRITE, mmDC_GPIO_SYNCA_EN, 0, 0, 0, 0x0 }, | |
50 | { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 } | |
51 | }; | |
52 | ||
53 | static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = | |
54 | { | |
55 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 }, | |
56 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, | |
57 | { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 } | |
58 | }; | |
59 | ||
60 | static const struct baco_cmd_entry use_bclk_tbl[] = | |
61 | { | |
62 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, | |
63 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, | |
64 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | |
65 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x1 }, | |
66 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS }, | |
67 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 }, | |
68 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | |
69 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x0 }, | |
70 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x1 }, | |
71 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS }, | |
72 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 }, | |
73 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | |
74 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x0 }, | |
75 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, | |
76 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 }, | |
77 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | |
78 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 } | |
79 | }; | |
80 | ||
81 | static const struct baco_cmd_entry turn_off_plls_tbl[] = | |
82 | { | |
83 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, | |
84 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_RESET_MASK, CG_SPLL_FUNC_CNTL__SPLL_RESET__SHIFT, 0, 0x1 }, | |
85 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_PWRON_MASK, CG_SPLL_FUNC_CNTL__SPLL_PWRON__SHIFT, 0, 0x0 }, | |
86 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, | |
87 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x2000000, 0x19, 0, 0x1 }, | |
88 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x8000000, 0x1b, 0, 0x0 } | |
89 | }; | |
90 | ||
91 | static const struct baco_cmd_entry clk_req_b_tbl[] = | |
92 | { | |
93 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_2 }, | |
94 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN_MASK, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN__SHIFT, 0, 0x0 }, | |
95 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | |
96 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x4 }, | |
97 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMISC_CLK_CTRL }, | |
98 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL_MASK, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL__SHIFT, 0, 0x1 }, | |
99 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__ZCLK_SEL_MASK, MISC_CLK_CTRL__ZCLK_SEL__SHIFT, 0, 0x1 }, | |
100 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL }, | |
101 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL__BCLK_AS_XCLK_MASK, CG_CLKPIN_CNTL__BCLK_AS_XCLK__SHIFT, 0, 0x0 }, | |
102 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixTHM_CLK_CNTL }, | |
103 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__CMON_CLK_SEL_MASK, THM_CLK_CNTL__CMON_CLK_SEL__SHIFT, 0, 0x1 }, | |
104 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x1 } | |
105 | }; | |
106 | ||
107 | static const struct baco_cmd_entry enter_baco_tbl[] = | |
108 | { | |
109 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 }, | |
110 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x01 }, | |
111 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, 0, 5, 0x40000 }, | |
112 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x01 }, | |
113 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, 0, 5, 0x02 }, | |
114 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x00 }, | |
115 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, 0, 5, 0x00 }, | |
116 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x00 }, | |
117 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, 0, 5, 0x00 }, | |
118 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x01 }, | |
119 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, 0, 5, 0x08 }, | |
120 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x40 } | |
121 | }; | |
122 | ||
123 | #define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK | |
124 | ||
125 | static const struct baco_cmd_entry exit_baco_tbl[] = | |
126 | { | |
127 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, | |
128 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, | |
129 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, | |
130 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x200 }, | |
131 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 }, | |
132 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c00 }, | |
133 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 }, | |
134 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x00 }, | |
135 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 }, | |
136 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x100 }, | |
137 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 }, | |
138 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } | |
139 | }; | |
140 | ||
141 | static const struct baco_cmd_entry clean_baco_tbl[] = | |
142 | { | |
143 | { CMD_WRITE, mmBIOS_SCRATCH_0, 0, 0, 0, 0 }, | |
144 | { CMD_WRITE, mmBIOS_SCRATCH_1, 0, 0, 0, 0 }, | |
145 | { CMD_WRITE, mmBIOS_SCRATCH_2, 0, 0, 0, 0 }, | |
146 | { CMD_WRITE, mmBIOS_SCRATCH_3, 0, 0, 0, 0 }, | |
147 | { CMD_WRITE, mmBIOS_SCRATCH_4, 0, 0, 0, 0 }, | |
148 | { CMD_WRITE, mmBIOS_SCRATCH_5, 0, 0, 0, 0 }, | |
149 | { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 }, | |
150 | { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 }, | |
151 | { CMD_WRITE, mmBIOS_SCRATCH_8, 0, 0, 0, 0 }, | |
152 | { CMD_WRITE, mmBIOS_SCRATCH_9, 0, 0, 0, 0 }, | |
153 | { CMD_WRITE, mmBIOS_SCRATCH_10, 0, 0, 0, 0 }, | |
154 | { CMD_WRITE, mmBIOS_SCRATCH_11, 0, 0, 0, 0 }, | |
155 | { CMD_WRITE, mmBIOS_SCRATCH_12, 0, 0, 0, 0 }, | |
156 | { CMD_WRITE, mmBIOS_SCRATCH_13, 0, 0, 0, 0 }, | |
157 | { CMD_WRITE, mmBIOS_SCRATCH_14, 0, 0, 0, 0 }, | |
158 | { CMD_WRITE, mmBIOS_SCRATCH_15, 0, 0, 0, 0 } | |
159 | }; | |
160 | ||
161 | int fiji_baco_get_capability(struct pp_hwmgr *hwmgr, bool *cap) | |
162 | { | |
163 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | |
164 | uint32_t reg; | |
165 | ||
166 | *cap = false; | |
167 | if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_BACO)) | |
168 | return 0; | |
169 | ||
170 | reg = RREG32(mmCC_BIF_BX_FUSESTRAP0); | |
171 | ||
172 | if (reg & CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE_MASK) | |
173 | *cap = true; | |
174 | ||
175 | return 0; | |
176 | } | |
177 | ||
178 | int fiji_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state) | |
179 | { | |
180 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | |
181 | uint32_t reg; | |
182 | ||
183 | reg = RREG32(mmBACO_CNTL); | |
184 | ||
185 | if (reg & BACO_CNTL__BACO_MODE_MASK) | |
186 | /* gfx has already entered BACO state */ | |
187 | *state = BACO_STATE_IN; | |
188 | else | |
189 | *state = BACO_STATE_OUT; | |
190 | return 0; | |
191 | } | |
192 | ||
193 | int fiji_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) | |
194 | { | |
195 | enum BACO_STATE cur_state; | |
196 | ||
197 | fiji_baco_get_state(hwmgr, &cur_state); | |
198 | ||
199 | if (cur_state == state) | |
200 | /* aisc already in the target state */ | |
201 | return 0; | |
202 | ||
203 | if (state == BACO_STATE_IN) { | |
204 | baco_program_registers(hwmgr, gpio_tbl, ARRAY_SIZE(gpio_tbl)); | |
205 | baco_program_registers(hwmgr, enable_fb_req_rej_tbl, | |
206 | ARRAY_SIZE(enable_fb_req_rej_tbl)); | |
207 | baco_program_registers(hwmgr, use_bclk_tbl, ARRAY_SIZE(use_bclk_tbl)); | |
208 | baco_program_registers(hwmgr, turn_off_plls_tbl, | |
209 | ARRAY_SIZE(turn_off_plls_tbl)); | |
210 | baco_program_registers(hwmgr, clk_req_b_tbl, ARRAY_SIZE(clk_req_b_tbl)); | |
211 | if (baco_program_registers(hwmgr, enter_baco_tbl, | |
212 | ARRAY_SIZE(enter_baco_tbl))) | |
213 | return 0; | |
214 | ||
215 | } else if (state == BACO_STATE_OUT) { | |
216 | /* HW requires at least 20ms between regulator off and on */ | |
217 | msleep(20); | |
218 | /* Execute Hardware BACO exit sequence */ | |
219 | if (baco_program_registers(hwmgr, exit_baco_tbl, | |
220 | ARRAY_SIZE(exit_baco_tbl))) { | |
221 | if (baco_program_registers(hwmgr, clean_baco_tbl, | |
222 | ARRAY_SIZE(clean_baco_tbl))) | |
223 | return 0; | |
224 | } | |
225 | } | |
226 | ||
227 | return -EINVAL; | |
228 | } |