xref: /aosp_15_r20/external/coreboot/src/soc/mediatek/common/mt6359p.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* 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 
10 static 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 
21 static 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 
47 static struct pmif *pmif_arb = NULL;
mt6359p_write(u32 reg,u32 data)48 static void mt6359p_write(u32 reg, u32 data)
49 {
50 	pmif_arb->write(pmif_arb, 0, reg, data);
51 }
52 
mt6359p_read_field(u32 reg,u32 mask,u32 shift)53 static 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 
mt6359p_write_field(u32 reg,u32 val,u32 mask,u32 shift)58 void 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 
pmic_set_power_hold(void)63 static void pmic_set_power_hold(void)
64 {
65 	mt6359p_write_field(PMIC_PWRHOLD, 0x1, 0x1, 0);
66 }
67 
pmic_wdt_set(void)68 static 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 
pmic_protect_key_setting(bool lock)78 static 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 
check_idle(u32 timeout,u32 addr,u32 mask)85 static 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 
pmic_read_efuse(u32 efuse_bit,u32 mask)93 static 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 
pmic_efuse_setting(void)124 static 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 
144 	printk(BIOS_DEBUG, "%s: Set efuses in %lld msecs\n",
145 	       __func__, stopwatch_duration_msecs(&sw));
146 }
147 
pmic_wk_vs2_voter_setting(void)148 static 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 
mt6359p_buck_set_voltage(u32 buck_id,u32 buck_uv)160 void mt6359p_buck_set_voltage(u32 buck_id, u32 buck_uv)
161 {
162 	u32 vol_offset, vol_reg, vol, vol_step;
163 
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;
171 		vol_step = 6250;
172 		break;
173 	case MT6359P_SRAM_PROC1:
174 		vol_offset = 500000;
175 		vol_reg = PMIC_VSRAM_PROC1_ELR;
176 		vol_step = 6250;
177 		break;
178 	case MT6359P_SRAM_PROC2:
179 		vol_offset = 500000;
180 		vol_reg = PMIC_VSRAM_PROC2_ELR;
181 		vol_step = 6250;
182 		break;
183 	case MT6359P_CORE:
184 		vol_offset = 506250;
185 		vol_reg = PMIC_VCORE_ELR0;
186 		vol_step = 6250;
187 		break;
188 	case MT6359P_PA:
189 		vol_offset = 500000;
190 		vol_reg = PMIC_VPA_CON1;
191 		vol_step = 50000;
192 		break;
193 	default:
194 		die("ERROR: Unknown buck_id %u", buck_id);
195 		return;
196 	};
197 
198 	vol = (buck_uv - vol_offset) / vol_step;
199 	mt6359p_write_field(vol_reg, vol, 0x7F, 0);
200 }
201 
mt6359p_buck_get_voltage(u32 buck_id)202 u32 mt6359p_buck_get_voltage(u32 buck_id)
203 {
204 	u32 vol_shift, vol_offset, vol_reg, vol, vol_step;
205 
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;
214 		vol_step = 6250;
215 		break;
216 	case MT6359P_SRAM_PROC1:
217 		vol_shift = 8;
218 		vol_offset = 500000;
219 		vol_reg = PMIC_VSRAM_PROC1_VOSEL1;
220 		vol_step = 6250;
221 		break;
222 	case MT6359P_SRAM_PROC2:
223 		vol_shift = 8;
224 		vol_offset = 500000;
225 		vol_reg = PMIC_VSRAM_PROC2_VOSEL1;
226 		vol_step = 6250;
227 		break;
228 	case MT6359P_CORE:
229 		vol_shift = 0;
230 		vol_offset = 506250;
231 		vol_reg = PMIC_VCORE_DBG0;
232 		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;
239 		break;
240 	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);
246 	return vol_offset + vol * vol_step;
247 }
248 
mt6359p_set_vm18_voltage(u32 vm18_uv)249 void 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 
mt6359p_get_vm18_voltage(void)264 u32 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 
mt6359p_set_vsim1_voltage(u32 vsim1_uv)276 void 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 
mt6359p_get_vsim1_voltage(void)296 u32 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 
mt6359p_enable_vpa(bool enable)317 void mt6359p_enable_vpa(bool enable)
318 {
319 	mt6359p_write_field(PMIC_VPA_CON0, enable, 0x1, 0);
320 }
321 
mt6359p_enable_vsim1(bool enable)322 void mt6359p_enable_vsim1(bool enable)
323 {
324 	mt6359p_write_field(PMIC_VSIM1_CON0, enable, 0x1, 0);
325 }
326 
mt6359p_enable_vm18(bool enable)327 void mt6359p_enable_vm18(bool enable)
328 {
329 	mt6359p_write_field(PMIC_VM18_CON0, enable, 0x1, 0);
330 }
331 
mt6359p_init_pmif_arb(void)332 void mt6359p_init_pmif_arb(void)
333 {
334 	if (!pmif_arb) {
335 		pmif_arb = get_pmif_controller(PMIF_SPI, 0);
336 		if (!pmif_arb)
337 			die("ERROR: No spi device");
338 	}
339 
340 	if (pmif_arb->is_pmif_init_done(pmif_arb))
341 		die("ERROR - Failed to initialize pmif spi");
342 }
343 
mt6359p_init(void)344 void mt6359p_init(void)
345 {
346 	mt6359p_init_pmif_arb();
347 	pmic_set_power_hold();
348 	pmic_wdt_set();
349 	pmic_protect_key_setting(false);
350 	pmic_init_setting();
351 	pmic_lp_setting();
352 	pmic_efuse_setting();
353 	pmic_protect_key_setting(true);
354 	pmic_wk_vs2_voter_setting();
355 }
356