blob: de22b3e85dfe338f24d8afb7b1aad9e8c9ea2650 [file] [log] [blame]
Yidi Lin2368a312021-02-02 21:00:36 +08001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <assert.h>
4#include <console/console.h>
5#include <delay.h>
6#include <soc/mt6359p.h>
7#include <soc/pmif.h>
8#include <timer.h>
9
10static const struct pmic_setting key_protect_setting[] = {
11 {0x3A8, 0x9CA6, 0xFFFF, 0},
12 {0x44A, 0xBADE, 0xFFFF, 0},
13 {0xA3A, 0x4729, 0xFFFF, 0},
14 {0xC58, 0x1605, 0xFFFF, 0},
15 {0xC5A, 0x1706, 0xFFFF, 0},
16 {0xC5C, 0x1807, 0xFFFF, 0},
17 {0xFB4, 0x6359, 0xFFFF, 0},
18 {0x1432, 0x5543, 0xFFFF, 0},
19};
20
21static const struct pmic_efuse efuse_setting[] = {
22 {79, 0xa0e, 0x1, 0xf},
23 {886, 0x198c, 0xf, 0x8},
24 {890, 0x198e, 0xf, 0x0},
25 {902, 0x1998, 0xf, 0x8},
26 {906, 0x1998, 0xf, 0xc},
27 {918, 0x19a2, 0xf, 0x8},
28 {922, 0x19a2, 0xf, 0xc},
29 {1014, 0x19ae, 0xf, 0x7},
30 {1018, 0x19ae, 0xf, 0xb},
31 {1158, 0x1a0a, 0xf, 0x7},
32 {1162, 0x1a0a, 0xf, 0xb},
33 {1206, 0x1a16, 0xf, 0x7},
34 {1210, 0x1a16, 0xf, 0xb},
35 {1254, 0x1a22, 0xf, 0x7},
36 {1258, 0x1a22, 0xf, 0xb},
37 {1304, 0x1a2c, 0x7, 0x4},
38 {1307, 0x1a32, 0x7, 0x8},
39 {1336, 0x1a34, 0x7, 0x4},
40 {1339, 0x1a3a, 0x7, 0x8},
41 {1683, 0x79c, 0xf, 0x4},
42 {1688, 0xc8a, 0x1, 0x3},
43 {1689, 0xc88, 0x1, 0x3},
44 {1690, 0xc88, 0x7, 0x0},
45};
46
47static struct pmif *pmif_arb = NULL;
48static void mt6359p_write(u32 reg, u32 data)
49{
50 pmif_arb->write(pmif_arb, 0, reg, data);
51}
52
53static u32 mt6359p_read_field(u32 reg, u32 mask, u32 shift)
54{
55 return pmif_arb->read_field(pmif_arb, 0, reg, mask, shift);
56}
57
58void mt6359p_write_field(u32 reg, u32 val, u32 mask, u32 shift)
59{
60 pmif_arb->write_field(pmif_arb, 0, reg, val, mask, shift);
61}
62
63static void pmic_set_power_hold(void)
64{
65 mt6359p_write_field(PMIC_PWRHOLD, 0x1, 0x1, 0);
66}
67
68static void pmic_wdt_set(void)
69{
70 /* [5]=1, RG_WDTRSTB_DEB */
71 mt6359p_write_field(PMIC_TOP_RST_MISC_SET, 0x20, 0xFFFF, 0);
72 /* [1]=0, RG_WDTRSTB_MODE */
73 mt6359p_write_field(PMIC_TOP_RST_MISC_CLR, 0x02, 0xFFFF, 0);
74 /* [0]=1, RG_WDTRSTB_EN */
75 mt6359p_write_field(PMIC_TOP_RST_MISC_SET, 0x01, 0xFFFF, 0);
76}
77
78static void pmic_protect_key_setting(bool lock)
79{
80 for (int i = 0; i < ARRAY_SIZE(key_protect_setting); i++)
81 mt6359p_write(key_protect_setting[i].addr,
82 lock ? 0 : key_protect_setting[i].val);
83}
84
85static int check_idle(u32 timeout, u32 addr, u32 mask)
86{
87 if (!wait_us(timeout, !mt6359p_read_field(addr, mask, 0)))
88 return -1;
89
90 return 0;
91}
92
93static u32 pmic_read_efuse(u32 efuse_bit, u32 mask)
94{
95 u32 efuse_data;
96 int index, shift;
97
98 index = efuse_bit / 16;
99 shift = efuse_bit % 16;
100 mt6359p_write_field(PMIC_TOP_CKHWEN_CON0, 0, 0x1, 2);
101 mt6359p_write_field(PMIC_TOP_CKPDN_CON0, 0, 0x1, 4);
102 mt6359p_write_field(PMIC_OTP_CON11, 1, 0x1, 0);
103 mt6359p_write_field(PMIC_OTP_CON0, index * 2, 0xFF, 0);
104 if (mt6359p_read_field(PMIC_OTP_CON8, 1, 0))
105 mt6359p_write_field(PMIC_OTP_CON8, 0, 1, 0);
106 else
107 mt6359p_write_field(PMIC_OTP_CON8, 1, 1, 0);
108
109 udelay(300);
110 if (check_idle(EFUSE_WAIT_US, PMIC_OTP_CON13, EFUSE_BUSY))
111 die("[%s] timeout after %d usecs\n", __func__, EFUSE_WAIT_US);
112
113 udelay(100);
114
115 efuse_data = mt6359p_read_field(PMIC_OTP_CON12, 0xFFFF, 0);
116 efuse_data = (efuse_data >> shift) & mask;
117
118 mt6359p_write_field(PMIC_TOP_CKHWEN_CON0, 1, 0x1, 2);
119 mt6359p_write_field(PMIC_TOP_CKPDN_CON0, 1, 0x1, 4);
120
121 return efuse_data;
122}
123
124static void pmic_efuse_setting(void)
125{
126 u32 efuse_data;
127 struct stopwatch sw;
128
129 stopwatch_init(&sw);
130
131 for (int i = 0; i < ARRAY_SIZE(efuse_setting); i++) {
132 efuse_data = pmic_read_efuse(efuse_setting[i].efuse_bit, efuse_setting[i].mask);
133 mt6359p_write_field(efuse_setting[i].addr, efuse_data,
134 efuse_setting[i].mask, efuse_setting[i].shift);
135 }
136
137 efuse_data = pmic_read_efuse(EFUSE_RG_VPA_OC_FT, 0x1);
138 if (efuse_data) {
139 /* restore VPA_DLC initial setting */
140 mt6359p_write(PMIC_BUCK_VPA_DLC_CON0, 0x2810);
141 mt6359p_write(PMIC_BUCK_VPA_DLC_CON1, 0x800);
142 }
143
Rob Barnesd522f382022-09-12 06:31:47 -0600144 printk(BIOS_DEBUG, "%s: Set efuses in %lld msecs\n",
Yidi Lin2368a312021-02-02 21:00:36 +0800145 __func__, stopwatch_duration_msecs(&sw));
146}
147
148static void pmic_wk_vs2_voter_setting(void)
149{
150 /*
151 * 1. Set VS2_VOTER_VOSEL = 1.35V
152 * 2. Clear VS2_VOTER
153 * 3. Set VS2_VOSEL = 1.4V
154 */
155 mt6359p_write_field(PMIC_VS2_VOTER_CFG, 0x2C, 0x7F, 0);
156 mt6359p_write_field(PMIC_VS2_VOTER, 0, 0xFFF, 0);
157 mt6359p_write_field(PMIC_VS2_ELR0, 0x30, 0x7F, 0);
158}
159
160void mt6359p_buck_set_voltage(u32 buck_id, u32 buck_uv)
161{
Hui Liu8ba3e342022-07-15 13:58:09 +0800162 u32 vol_offset, vol_reg, vol, vol_step;
Yidi Lin2368a312021-02-02 21:00:36 +0800163
164 if (!pmif_arb)
165 die("ERROR: pmif_arb not initialized");
166
167 switch (buck_id) {
168 case MT6359P_GPU11:
169 vol_offset = 400000;
170 vol_reg = PMIC_VGPU11_ELR0;
Hui Liu8ba3e342022-07-15 13:58:09 +0800171 vol_step = 6250;
Yidi Lin2368a312021-02-02 21:00:36 +0800172 break;
173 case MT6359P_SRAM_PROC1:
174 vol_offset = 500000;
175 vol_reg = PMIC_VSRAM_PROC1_ELR;
Hui Liu8ba3e342022-07-15 13:58:09 +0800176 vol_step = 6250;
Yidi Lin2368a312021-02-02 21:00:36 +0800177 break;
178 case MT6359P_SRAM_PROC2:
179 vol_offset = 500000;
180 vol_reg = PMIC_VSRAM_PROC2_ELR;
Hui Liu8ba3e342022-07-15 13:58:09 +0800181 vol_step = 6250;
Yidi Lin2368a312021-02-02 21:00:36 +0800182 break;
James Lo55c98c32021-08-04 14:17:16 +0800183 case MT6359P_CORE:
184 vol_offset = 506250;
185 vol_reg = PMIC_VCORE_ELR0;
Hui Liu8ba3e342022-07-15 13:58:09 +0800186 vol_step = 6250;
187 break;
188 case MT6359P_PA:
189 vol_offset = 500000;
190 vol_reg = PMIC_VPA_CON1;
191 vol_step = 50000;
James Lo55c98c32021-08-04 14:17:16 +0800192 break;
Yidi Lin2368a312021-02-02 21:00:36 +0800193 default:
194 die("ERROR: Unknown buck_id %u", buck_id);
195 return;
196 };
197
Hui Liu8ba3e342022-07-15 13:58:09 +0800198 vol = (buck_uv - vol_offset) / vol_step;
Yidi Lin2368a312021-02-02 21:00:36 +0800199 mt6359p_write_field(vol_reg, vol, 0x7F, 0);
200}
201
202u32 mt6359p_buck_get_voltage(u32 buck_id)
203{
Hui Liu8ba3e342022-07-15 13:58:09 +0800204 u32 vol_shift, vol_offset, vol_reg, vol, vol_step;
Yidi Lin2368a312021-02-02 21:00:36 +0800205
206 if (!pmif_arb)
207 die("ERROR: pmif_arb not initialized");
208
209 switch (buck_id) {
210 case MT6359P_GPU11:
211 vol_shift = 0;
212 vol_offset = 400000;
213 vol_reg = PMIC_VGPU11_DBG0;
Hui Liu8ba3e342022-07-15 13:58:09 +0800214 vol_step = 6250;
Yidi Lin2368a312021-02-02 21:00:36 +0800215 break;
216 case MT6359P_SRAM_PROC1:
217 vol_shift = 8;
218 vol_offset = 500000;
219 vol_reg = PMIC_VSRAM_PROC1_VOSEL1;
Hui Liu8ba3e342022-07-15 13:58:09 +0800220 vol_step = 6250;
Yidi Lin2368a312021-02-02 21:00:36 +0800221 break;
222 case MT6359P_SRAM_PROC2:
223 vol_shift = 8;
224 vol_offset = 500000;
225 vol_reg = PMIC_VSRAM_PROC2_VOSEL1;
Hui Liu8ba3e342022-07-15 13:58:09 +0800226 vol_step = 6250;
Yidi Lin2368a312021-02-02 21:00:36 +0800227 break;
James Lo55c98c32021-08-04 14:17:16 +0800228 case MT6359P_CORE:
229 vol_shift = 0;
230 vol_offset = 506250;
231 vol_reg = PMIC_VCORE_DBG0;
Hui Liu8ba3e342022-07-15 13:58:09 +0800232 vol_step = 6250;
233 break;
234 case MT6359P_PA:
235 vol_shift = 0;
236 vol_offset = 500000;
237 vol_reg = PMIC_VPA_DBG0;
238 vol_step = 50000;
James Lo55c98c32021-08-04 14:17:16 +0800239 break;
Yidi Lin2368a312021-02-02 21:00:36 +0800240 default:
241 die("ERROR: Unknown buck_id %u", buck_id);
242 return 0;
243 };
244
245 vol = mt6359p_read_field(vol_reg, 0x7F, vol_shift);
Hui Liu8ba3e342022-07-15 13:58:09 +0800246 return vol_offset + vol * vol_step;
Yidi Lin2368a312021-02-02 21:00:36 +0800247}
248
249void mt6359p_set_vm18_voltage(u32 vm18_uv)
250{
251 u32 reg_vol, reg_cali;
252
253 if (!pmif_arb)
254 die("ERROR: pmif_arb not initialized");
255
256 assert(vm18_uv >= 1700000);
257 assert(vm18_uv < 2000000);
258
259 reg_vol = (vm18_uv / 1000 - VM18_VOL_OFFSET) / 100;
260 reg_cali = ((vm18_uv / 1000) % 100) / 10;
261 mt6359p_write(PMIC_VM18_ANA_CON0, (reg_vol << VM18_VOL_REG_SHIFT) | reg_cali);
262}
263
264u32 mt6359p_get_vm18_voltage(void)
265{
266 u32 reg_vol, reg_cali;
267
268 if (!pmif_arb)
269 die("ERROR: pmif_arb not initialized");
270
271 reg_vol = 100 * mt6359p_read_field(PMIC_VM18_ANA_CON0, 0xF, VM18_VOL_REG_SHIFT);
272 reg_cali = 10 * mt6359p_read_field(PMIC_VM18_ANA_CON0, 0xF, 0);
273 return 1000 * (VM18_VOL_OFFSET + reg_vol + reg_cali);
274}
275
Hui Liu8ba3e342022-07-15 13:58:09 +0800276void mt6359p_set_vsim1_voltage(u32 vsim1_uv)
277{
278 u32 reg_vol, reg_cali;
279
280 if (!pmif_arb)
281 die("ERROR: pmif_arb not initialized");
282
283 if ((vsim1_uv >= 1700000) && (vsim1_uv <= 1900000))
284 reg_vol = (vsim1_uv / 1000 - VSIM1_VOL_OFFSET_1) / 100;
285 else if ((vsim1_uv >= 2700000) && (vsim1_uv <= 2800000))
286 reg_vol = (vsim1_uv / 1000 - VSIM1_VOL_OFFSET_2) / 100;
287 else if ((vsim1_uv >= 3000000) && (vsim1_uv <= 3200000))
288 reg_vol = (vsim1_uv / 1000 - VSIM1_VOL_OFFSET_2) / 100;
289 else
290 die("ERROR: Unknown vsim1 voltage %u", vsim1_uv);
291
292 reg_cali = ((vsim1_uv / 1000) % 100) / 10;
293 mt6359p_write(PMIC_VSIM1_ANA_CON0, (reg_vol << VSIM1_VOL_REG_SHIFT) | reg_cali);
294}
295
296u32 mt6359p_get_vsim1_voltage(void)
297{
298 u32 reg_vol, reg_cali, reg_offset;
299
300 if (!pmif_arb)
301 die("ERROR: pmif_arb not initialized");
302
303 reg_vol = 100 * mt6359p_read_field(PMIC_VSIM1_ANA_CON0, 0xF,
304 VSIM1_VOL_REG_SHIFT);
305 reg_cali = 10 * mt6359p_read_field(PMIC_VSIM1_ANA_CON0, 0xF, 0);
306
307 if ((reg_vol == 300) || (reg_vol == 400))
308 reg_offset = VSIM1_VOL_OFFSET_1;
309 else if ((reg_vol == 800) || (reg_vol == 1100) || (reg_vol == 1200))
310 reg_offset = VSIM1_VOL_OFFSET_2;
311 else
312 die("ERROR: Unknown vsim1 reg_vol %x", reg_vol);
313
314 return 1000 * (reg_offset + reg_vol + reg_cali);
315}
316
317void mt6359p_enable_vpa(bool enable)
318{
319 mt6359p_write_field(PMIC_VPA_CON0, !!enable, 0x1, 0);
320}
321
322void mt6359p_enable_vsim1(bool enable)
323{
324 mt6359p_write_field(PMIC_VSIM1_CON0, !!enable, 0x1, 0);
325}
326
Yidi Lin2368a312021-02-02 21:00:36 +0800327static void init_pmif_arb(void)
328{
329 if (!pmif_arb) {
330 pmif_arb = get_pmif_controller(PMIF_SPI, 0);
331 if (!pmif_arb)
332 die("ERROR: No spi device");
333 }
334
335 if (pmif_arb->is_pmif_init_done(pmif_arb))
336 die("ERROR - Failed to initialize pmif spi");
337}
338
339void mt6359p_init(void)
340{
341 init_pmif_arb();
342 pmic_set_power_hold();
343 pmic_wdt_set();
344 pmic_protect_key_setting(false);
345 pmic_init_setting();
346 pmic_lp_setting();
347 pmic_efuse_setting();
348 pmic_protect_key_setting(true);
349 pmic_wk_vs2_voter_setting();
350}