xref: /rk3399_ARM-atf/plat/mediatek/drivers/apusys/mt8196/apusys_power.c (revision 6d415de83fe084c08558895837d0eb90210420a9)
1 /*
2  * Copyright (c) 2024, MediaTek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <inttypes.h>
8 
9 #define SPMI_ENABLE	(0)
10 
11 #if SPMI_ENABLE
12 #include <include/drivers/spmi_api.h>
13 #endif
14 
15 #include <common/debug.h>
16 #include <drivers/delay_timer.h>
17 #include <lib/mmio.h>
18 #include <lib/spinlock.h>
19 #include <lib/utils_def.h>
20 #include <lib/xlat_tables/xlat_tables_v2.h>
21 
22 #include "apusys_power.h"
23 
24 static void apu_w_are(int entry, uint32_t reg, uint32_t data)
25 {
26 	uint32_t are_entry_addr;
27 
28 	are_entry_addr = APUSYS_BASE + APU_ARE + ARE_REG_SIZE * ARE_ENTRY(entry);
29 	mmio_write_32(are_entry_addr, reg);
30 	mmio_write_32((are_entry_addr + ARE_REG_SIZE), data);
31 }
32 
33 static void get_pll_pcw(uint32_t clk_rate, uint32_t *r1, uint32_t *r2)
34 {
35 	unsigned int fvco = clk_rate;
36 	unsigned int pcw_val;
37 	unsigned int postdiv_val = 1;
38 	unsigned int postdiv_reg = 0;
39 
40 	while (fvco <= OUT_CLK_FREQ_MIN) {
41 		postdiv_val = postdiv_val << 1;
42 		postdiv_reg = postdiv_reg + 1;
43 		fvco = fvco << 1;
44 	}
45 
46 	pcw_val = (fvco * (1 << DDS_SHIFT)) / BASIC_CLK_FREQ;
47 
48 	if (postdiv_reg == 0) {
49 		pcw_val = pcw_val * 2;
50 		postdiv_val = postdiv_val << 1;
51 		postdiv_reg = postdiv_reg + 1;
52 	}
53 
54 	*r1 = postdiv_reg;
55 	*r2 = pcw_val;
56 }
57 
58 static void buck_off_by_pcu(uint32_t ofs, uint32_t shift, uint32_t slv_id)
59 {
60 	uint32_t pmif_id = 0x0;
61 	int retry = 10;
62 
63 	mmio_setbits_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, PMIC_IRQ_EN);
64 	mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_TAR_BUF1,
65 		      (ofs << PMIC_OFF_ADDR_OFF) | BIT(shift));
66 	mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_TAR_BUF2,
67 		      (slv_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_BUCK_OFF_CMD);
68 	mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_CMD, PMIC_CMD_EN);
69 
70 	while ((mmio_read_32(APUSYS_PCU + APU_PCU_PMIC_IRQ) & PMIC_CMD_IRQ) == 0) {
71 		udelay(10);
72 		if (--retry < 0)
73 			ERROR("%s wait APU_PCU_PMIC_IRQ timeout !\n", __func__);
74 	}
75 
76 	mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_IRQ, PMIC_CMD_IRQ);
77 }
78 
79 static void apu_buck_off_cfg(void)
80 {
81 	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(10));
82 	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(9));
83 	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(12));
84 	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(14));
85 
86 	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(10));
87 	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(9));
88 	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(12));
89 	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(14));
90 	udelay(1);
91 
92 	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_PROT_REQ_SET);
93 	udelay(1);
94 
95 	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, SRAM_AOC_LHENB_SET);
96 	udelay(1);
97 
98 	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, SRAM_AOC_ISO_SET);
99 	udelay(1);
100 
101 	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, PLL_AOC_ISO_EN_SET);
102 	udelay(1);
103 
104 	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_ELS_EN_SET);
105 	udelay(1);
106 
107 	mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_AO_RST_B_CLR);
108 	udelay(1);
109 
110 	buck_off_by_pcu(BUCK_VAPU_PMIC_REG_EN_CLR_ADDR, BUCK_VAPU_PMIC_REG_EN_SHIFT,
111 			BUCK_VAPU_PMIC_ID);
112 
113 	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(6));
114 	udelay(1);
115 	mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(7));
116 	udelay(1);
117 	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(6));
118 	udelay(1);
119 	mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(7));
120 	udelay(1);
121 }
122 
123 static void apu_acc_init(void)
124 {
125 	uint32_t top_acc_base_arr[] = {MNOC_ACC_BASE, UP_ACC_BASE};
126 	uint32_t eng_acc_base_arr[] = {MVPU_ACC_BASE, MDLA_ACC_BASE};
127 	int acc_idx;
128 	int are_idx = ACC_ENTRY_BEGIN;
129 	uint32_t base_reg;
130 
131 	for (acc_idx = 0 ; acc_idx < ARRAY_SIZE(top_acc_base_arr) ; acc_idx++) {
132 		base_reg = APUSYS_ACC + top_acc_base_arr[acc_idx];
133 #if CFG_APU_ARDCM_ENABLE
134 		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_0);
135 		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_0);
136 		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_1);
137 		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_1);
138 #endif
139 		apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_CLR0, CGEN_SOC);
140 		apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_SET0, HW_CTRL_EN);
141 	}
142 
143 	for (acc_idx = 0 ; acc_idx < ARRAY_SIZE(eng_acc_base_arr) ; acc_idx++) {
144 		base_reg = APUSYS_ACC + eng_acc_base_arr[acc_idx];
145 #if CFG_APU_ARDCM_ENABLE
146 		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_0);
147 		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_0);
148 		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_1);
149 		apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_1);
150 #endif
151 		apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_CLR0, CGEN_SOC);
152 		apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_SET0, HW_CTRL_EN);
153 		apu_w_are(are_idx++, base_reg + APU_ACC_AUTO_CTRL_SET0, CLK_REQ_SW_EN);
154 	}
155 }
156 
157 static void apu_pll_init(void)
158 {
159 	uint32_t pll_base_arr[] = {MNOC_PLL_BASE, UP_PLL_BASE, MVPU_PLL_BASE, MDLA_PLL_BASE};
160 	int32_t pll_freq_out[] = {
161 		APUPLL0_DEFAULT_FREQ,
162 		APUPLL1_DEFAULT_FREQ,
163 		APUPLL2_DEFAULT_FREQ,
164 		APUPLL3_DEFAULT_FREQ
165 	};
166 	uint32_t pcw_val, posdiv_val;
167 	int pll_idx, are_idx;
168 	uint32_t base_reg;
169 
170 	mmio_setbits_32(APUSYS_BASE + APU_ARE, ARE_RCX_AO_EN);
171 	mmio_setbits_32(APUSYS_BASE + APU_ARE_REG, ARE_RCX_AO_EN);
172 
173 	mmio_write_32(APUSYS_BASE + APU_ARE + ARE_RCX_AO_CONFIG, ARE_ENTRY(RCX_AO_BEGIN) |
174 		      (ARE_ENTRIES(RCX_AO_BEGIN, RCX_AO_END) << ARE_RCX_AO_CONFIG_HIGH_OFF));
175 
176 	are_idx = PLL_ENTRY_BEGIN;
177 	for (pll_idx = 0 ; pll_idx < ARRAY_SIZE(pll_base_arr) ; pll_idx++) {
178 		base_reg = APUSYS_PLL + pll_base_arr[pll_idx];
179 
180 		apu_w_are(are_idx++, base_reg + RG_PLLGP_LVR_REFSEL, RG_PLLGP_LVR_REFSEL_VAL);
181 		apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_HP_EN, FHCTL_CTRL);
182 		apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_RST_CON, FHCTL_NO_RESET);
183 		apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_CLK_CON, FHCTL_CLKEN);
184 		apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL0_CFG,
185 			  FHCTL_HOPPING_EN | FHCTL_SFSTR0_EN);
186 
187 		posdiv_val = 0;
188 		pcw_val = 0;
189 		get_pll_pcw(pll_freq_out[pll_idx], &posdiv_val, &pcw_val);
190 
191 		apu_w_are(are_idx++, base_reg + PLL1C_PLL1_CON1,
192 			  ((0x1U << RG_PLL_SDM_PCW_CHG_OFF) |
193 			   (posdiv_val << RG_PLL_POSDIV_OFF) | pcw_val));
194 
195 		apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL0_DDS,
196 			  ((0x1U << FHCTL0_PLL_TGL_ORG) | pcw_val));
197 	}
198 }
199 
200 static void apu_are_init(void)
201 {
202 	int entry = 0;
203 
204 	mmio_clrbits_32(APUSYS_BASE + APU_ARE, 0xFFFU << ARE_VCORE_OFF);
205 
206 	mmio_setbits_32(APUSYS_BASE + APU_ARE, ARE_VCORE_EN);
207 	mmio_setbits_32(APUSYS_BASE + APU_ARE_REG, ARE_VCORE_EN);
208 
209 	for (entry = ARE_CONF_START; entry < ARE_CONF_END; entry += 4)
210 		mmio_write_32(APUSYS_BASE + APU_ARE + entry, 0);
211 }
212 
213 static void apu_rpclite_init(void)
214 {
215 	uint32_t sleep_type_offset[] = {
216 		APU_RPC_SW_TYPE1_OFF,
217 		APU_RPC_SW_TYPE2_OFF,
218 		APU_RPC_SW_TYPE3_OFF,
219 		APU_RPC_SW_TYPE4_OFF
220 	};
221 	uint32_t rpc_lite_base[] = {
222 		APU_ACX0_RPC_LITE,
223 		APU_ACX1_RPC_LITE,
224 		APU_ACX2_RPC_LITE,
225 	};
226 	int ofs_idx, rpc_lite_idx;
227 	uint32_t base;
228 
229 	for (rpc_lite_idx = 0; rpc_lite_idx < ARRAY_SIZE(rpc_lite_base); rpc_lite_idx++) {
230 		base = APUSYS_BASE + rpc_lite_base[rpc_lite_idx];
231 		for (ofs_idx = 0; ofs_idx < ARRAY_SIZE(sleep_type_offset); ofs_idx++)
232 			mmio_clrbits_32(base + sleep_type_offset[ofs_idx],
233 					SW_TYPE_MVPU_MDLA_RV);
234 		mmio_setbits_32(base + APU_RPC_TOP_SEL, TOP_SEL_VAL);
235 	}
236 }
237 
238 static void apu_rpc_mdla_init(void)
239 {
240 	mmio_clrbits_32(APUSYS_BASE + APU_RPCTOP_MDLA + APU_RPC_SW_TYPE0_OFF, SW_TYPE_MVPU_MDLA_RV);
241 }
242 
243 static void apu_rpc_init(void)
244 {
245 	mmio_write_32(APUSYS_RPC + APU_RPC_SW_TYPE0_OFF, RPC_TYPE_INIT_VAL);
246 	mmio_setbits_32(APUSYS_RPC + APU_RPC_TOP_SEL, RPC_TOP_SEL_VAL);
247 
248 #if !CFG_CTL_RPC_BY_CE
249 	mmio_clrbits_32(APUSYS_RPC + APU_RPC_TOP_SEL, CE_ENABLE);
250 #endif
251 
252 	mmio_setbits_32(APUSYS_RPC + APU_RPC_TOP_SEL_1, BUCK_PROT_SEL);
253 }
254 
255 static int apu_pcu_init(void)
256 {
257 	uint32_t pmif_id = 0x0;
258 	uint32_t slave_id = BUCK_VAPU_PMIC_ID;
259 	uint32_t en_set_offset = BUCK_VAPU_PMIC_REG_EN_SET_ADDR;
260 	uint32_t en_clr_offset = BUCK_VAPU_PMIC_REG_EN_CLR_ADDR;
261 	uint32_t en_shift = BUCK_VAPU_PMIC_REG_EN_SHIFT;
262 #if SPMI_ENABLE
263 	struct spmi_device *vsram_sdev;
264 #endif
265 	unsigned char vsram = 0;
266 
267 	mmio_write_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, AUTO_BUCK_EN);
268 
269 	mmio_write_32((APUSYS_PCU + APU_PCU_BUCK_STEP_SEL), BUCK_STEP_SEL_VAL);
270 
271 #if SPMI_ENABLE
272 	vsram_sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
273 	if (!vsram_sdev) {
274 		ERROR("[APUPW] VSRAM BUCK4 get device fail\n");
275 		return -1;
276 	}
277 
278 	if (spmi_ext_register_readl(vsram_sdev, MT6363_RG_BUCK_VBUCK4_VOSEL_ADDR, &vsram, 1)) {
279 		ERROR("[APUPW] VSRAM BUCK4 read fail\n");
280 		return -1;
281 	}
282 #endif
283 
284 	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_L,
285 		      (BUCK_VAPU_PMIC_REG_VOSEL_ADDR << PMIC_OFF_ADDR_OFF) | vsram);
286 
287 	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_H,
288 		      (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
289 
290 	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT1_L,
291 		      (en_set_offset << PMIC_OFF_ADDR_OFF) | (0x1U << en_shift));
292 	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT1_H,
293 		      (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
294 
295 	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_OFF_DAT0_L,
296 		      (en_clr_offset << PMIC_OFF_ADDR_OFF) | (0x1U << en_shift));
297 	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_OFF_DAT0_H,
298 		      (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
299 
300 	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_SLE0, 0);
301 	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_SLE1, VAPU_BUCK_ON_SETTLE_TIME);
302 
303 	return 0;
304 }
305 
306 static void apu_aoc_init(void)
307 {
308 	uint32_t reg;
309 
310 	mmio_setbits_32(SPM_BASE + 0xF6C, BIT(4));
311 	mmio_clrbits_32(SPM_BASE + 0x414, BIT(1));
312 
313 	mmio_write_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CONFIG, APUSYS_AO_SRAM_EN);
314 	udelay(1);
315 
316 	reg = APUSYS_AO_CTL + APUSYS_AO_SRAM_SET;
317 
318 #if !CFG_CTL_RPC_BY_CE
319 	mmio_setbits_32(reg, BIT(8));
320 	udelay(1);
321 	mmio_setbits_32(reg, BIT(11));
322 	udelay(1);
323 	mmio_setbits_32(reg, BIT(13));
324 	udelay(1);
325 
326 	mmio_clrbits_32(reg, BIT(8));
327 	udelay(1);
328 	mmio_clrbits_32(reg, BIT(11));
329 	udelay(1);
330 	mmio_clrbits_32(reg, BIT(13));
331 #else
332 	mmio_setbits_32(reg, BIT(9));
333 	mmio_setbits_32(reg, BIT(12));
334 	mmio_setbits_32(reg, BIT(14));
335 
336 	mmio_clrbits_32(reg, BIT(9));
337 	mmio_clrbits_32(reg, BIT(12));
338 	mmio_clrbits_32(reg, BIT(14));
339 	udelay(1);
340 #endif
341 
342 	reg = APUSYS_RPC + APU_RPC_HW_CON;
343 
344 	mmio_write_32(reg, BUCK_ELS_EN_CLR);
345 	udelay(1);
346 
347 	mmio_write_32(reg, BUCK_AO_RST_B_SET);
348 	udelay(1);
349 
350 	mmio_write_32(reg, BUCK_PROT_REQ_CLR);
351 	udelay(1);
352 
353 	mmio_write_32(reg, SRAM_AOC_ISO_CLR);
354 	udelay(1);
355 
356 	mmio_write_32(reg, PLL_AOC_ISO_EN_CLR);
357 	udelay(1);
358 }
359 
360 static int init_hw_setting(void)
361 {
362 	int ret;
363 
364 	apu_aoc_init();
365 	ret = apu_pcu_init();
366 	apu_rpc_init();
367 	apu_rpc_mdla_init();
368 	apu_rpclite_init();
369 	apu_are_init();
370 	apu_pll_init();
371 	apu_acc_init();
372 	apu_buck_off_cfg();
373 
374 	return ret;
375 }
376 
377 int apusys_power_init(void)
378 {
379 	int ret;
380 
381 	ret = init_hw_setting();
382 	if (ret != 0)
383 		ERROR("%s init HW failed\n", __func__);
384 	else
385 		INFO("%s init HW done\n", __func__);
386 
387 	mmio_write_32(APU_ACE_HW_FLAG_DIS, APU_ACE_DIS_FLAG_VAL);
388 
389 	return ret;
390 }
391