xref: /rk3399_ARM-atf/plat/st/stm32mp1/stm32mp1_syscfg.c (revision fca10a8f1b47231ef92634a0adf1a26cbfc97c2a)
1 /*
2  * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 
10 #include <common/debug.h>
11 #include <drivers/clk.h>
12 #include <drivers/delay_timer.h>
13 #include <drivers/st/stpmic1.h>
14 #include <lib/mmio.h>
15 #include <lib/utils_def.h>
16 #include <libfdt.h>
17 
18 #include <platform_def.h>
19 #include <stm32mp_common.h>
20 #include <stm32mp_dt.h>
21 #include <stm32mp1_private.h>
22 
23 /*
24  * SYSCFG REGISTER OFFSET (base relative)
25  */
26 #define SYSCFG_BOOTR				0x00U
27 #if STM32MP15
28 #define SYSCFG_IOCTRLSETR			0x18U
29 #define SYSCFG_ICNR				0x1CU
30 #endif
31 #define SYSCFG_CMPCR				0x20U
32 #define SYSCFG_CMPENSETR			0x24U
33 #define SYSCFG_CMPENCLRR			0x28U
34 #if STM32MP13
35 #define SYSCFG_CMPSD1CR				0x30U
36 #define SYSCFG_CMPSD1ENSETR			0x34U
37 #define SYSCFG_CMPSD1ENCLRR			0x38U
38 #define SYSCFG_CMPSD2CR				0x40U
39 #define SYSCFG_CMPSD2ENSETR			0x44U
40 #define SYSCFG_CMPSD2ENCLRR			0x48U
41 #define SYSCFG_HSLVEN0R				0x50U
42 #endif
43 #define SYSCFG_IDC				0x380U
44 
45 #define CMPCR_CMPENSETR_OFFSET			0x4U
46 #define CMPCR_CMPENCLRR_OFFSET			0x8U
47 
48 /*
49  * SYSCFG_BOOTR Register
50  */
51 #define SYSCFG_BOOTR_BOOT_MASK			GENMASK(2, 0)
52 #if STM32MP15
53 #define SYSCFG_BOOTR_BOOTPD_MASK		GENMASK(6, 4)
54 #define SYSCFG_BOOTR_BOOTPD_SHIFT		4
55 #endif
56 
57 /*
58  * SYSCFG_IOCTRLSETR Register
59  */
60 #define SYSCFG_IOCTRLSETR_HSLVEN_TRACE		BIT(0)
61 #define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI	BIT(1)
62 #define SYSCFG_IOCTRLSETR_HSLVEN_ETH		BIT(2)
63 #define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC		BIT(3)
64 #define SYSCFG_IOCTRLSETR_HSLVEN_SPI		BIT(4)
65 
66 /*
67  * SYSCFG_ICNR Register
68  */
69 #define SYSCFG_ICNR_AXI_M9			BIT(9)
70 
71 /*
72  * SYSCFG_CMPCR Register
73  */
74 #define SYSCFG_CMPCR_SW_CTRL			BIT(1)
75 #define SYSCFG_CMPCR_READY			BIT(8)
76 #define SYSCFG_CMPCR_RANSRC			GENMASK(19, 16)
77 #define SYSCFG_CMPCR_RANSRC_SHIFT		16
78 #define SYSCFG_CMPCR_RAPSRC			GENMASK(23, 20)
79 #define SYSCFG_CMPCR_ANSRC_SHIFT		24
80 
81 #define SYSCFG_CMPCR_READY_TIMEOUT_US		10000U
82 
83 /*
84  * SYSCFG_CMPENSETR Register
85  */
86 #define SYSCFG_CMPENSETR_MPU_EN			BIT(0)
87 
88 /*
89  * HSLV definitions
90  */
91 #define HSLV_IDX_TPIU				0U
92 #define HSLV_IDX_QSPI				1U
93 #define HSLV_IDX_ETH1				2U
94 #define HSLV_IDX_ETH2				3U
95 #define HSLV_IDX_SDMMC1				4U
96 #define HSLV_IDX_SDMMC2				5U
97 #define HSLV_IDX_SPI1				6U
98 #define HSLV_IDX_SPI2				7U
99 #define HSLV_IDX_SPI3				8U
100 #define HSLV_IDX_SPI4				9U
101 #define HSLV_IDX_SPI5				10U
102 #define HSLV_IDX_LTDC				11U
103 #define HSLV_NB_IDX				12U
104 
105 #define HSLV_KEY				0x1018U
106 
107 /*
108  * SYSCFG_IDC Register
109  */
110 #define SYSCFG_IDC_DEV_ID_MASK			GENMASK(11, 0)
111 #define SYSCFG_IDC_REV_ID_MASK			GENMASK(31, 16)
112 #define SYSCFG_IDC_REV_ID_SHIFT			16
113 
114 static void enable_io_comp_cell_finish(uintptr_t cmpcr_off)
115 {
116 	uint64_t start;
117 
118 	start = timeout_init_us(SYSCFG_CMPCR_READY_TIMEOUT_US);
119 
120 	while ((mmio_read_32(SYSCFG_BASE + cmpcr_off) & SYSCFG_CMPCR_READY) == 0U) {
121 		if (timeout_elapsed(start)) {
122 			/* Failure on IO compensation enable is not a issue: warn only. */
123 			WARN("IO compensation cell not ready\n");
124 			break;
125 		}
126 	}
127 
128 	mmio_clrbits_32(SYSCFG_BASE + cmpcr_off, SYSCFG_CMPCR_SW_CTRL);
129 }
130 
131 static void disable_io_comp_cell(uintptr_t cmpcr_off)
132 {
133 	uint32_t value;
134 
135 	if (((mmio_read_32(SYSCFG_BASE + cmpcr_off) & SYSCFG_CMPCR_READY) == 0U) ||
136 	    ((mmio_read_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENSETR_OFFSET) &
137 	     SYSCFG_CMPENSETR_MPU_EN) == 0U)) {
138 		return;
139 	}
140 
141 	value = mmio_read_32(SYSCFG_BASE + cmpcr_off) >> SYSCFG_CMPCR_ANSRC_SHIFT;
142 
143 	mmio_clrbits_32(SYSCFG_BASE + cmpcr_off, SYSCFG_CMPCR_RANSRC | SYSCFG_CMPCR_RAPSRC);
144 
145 	value <<= SYSCFG_CMPCR_RANSRC_SHIFT;
146 	value |= mmio_read_32(SYSCFG_BASE + cmpcr_off);
147 
148 	mmio_write_32(SYSCFG_BASE + cmpcr_off, value | SYSCFG_CMPCR_SW_CTRL);
149 
150 	mmio_setbits_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENCLRR_OFFSET, SYSCFG_CMPENSETR_MPU_EN);
151 }
152 
153 #if STM32MP13
154 static int get_regu_max_voltage(void *fdt, int sdmmc_node,
155 				const char *regu_name, uint32_t *regu_val)
156 {
157 	int node;
158 	const fdt32_t *cuint;
159 
160 	cuint = fdt_getprop(fdt, sdmmc_node, regu_name, NULL);
161 	if (cuint == NULL) {
162 		return -ENODEV;
163 	}
164 
165 	node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
166 	if (node < 0) {
167 		return -ENODEV;
168 	}
169 
170 	cuint = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
171 	if (cuint == NULL) {
172 		return -ENODEV;
173 	}
174 
175 	*regu_val = fdt32_to_cpu(*cuint);
176 
177 	return 0;
178 }
179 
180 static bool sdmmc_is_low_voltage(uintptr_t sdmmc_base)
181 {
182 	int ret;
183 	int node;
184 	void *fdt = NULL;
185 	uint32_t regu_max_val;
186 
187 	if (fdt_get_address(&fdt) == 0) {
188 		return false;
189 	}
190 
191 	if (fdt == NULL) {
192 		return false;
193 	}
194 
195 	node = dt_match_instance_by_compatible(DT_SDMMC2_COMPAT, sdmmc_base);
196 	if (node < 0) {
197 		/* No SD or eMMC device on this instance, enable HSLV */
198 		return true;
199 	}
200 
201 	ret = get_regu_max_voltage(fdt, node, "vqmmc-supply", &regu_max_val);
202 	if ((ret < 0) || (regu_max_val > 1800000U)) {
203 		/*
204 		 * The vqmmc-supply property should always be present for eMMC.
205 		 * For SD-card, if it is not, then the card only supports 3.3V.
206 		 */
207 		return false;
208 	}
209 
210 	return true;
211 }
212 
213 static void enable_hslv_by_index(uint32_t index)
214 {
215 	bool apply_hslv;
216 
217 	assert(index < HSLV_NB_IDX);
218 
219 	switch (index) {
220 	case HSLV_IDX_SDMMC1:
221 		apply_hslv = sdmmc_is_low_voltage(STM32MP_SDMMC1_BASE);
222 		break;
223 	case HSLV_IDX_SDMMC2:
224 		apply_hslv = sdmmc_is_low_voltage(STM32MP_SDMMC2_BASE);
225 		break;
226 	default:
227 		apply_hslv = true;
228 		break;
229 	}
230 
231 	if (apply_hslv) {
232 		mmio_write_32(SYSCFG_BASE + SYSCFG_HSLVEN0R + index * sizeof(uint32_t), HSLV_KEY);
233 	}
234 }
235 #endif
236 
237 static void enable_high_speed_mode_low_voltage(void)
238 {
239 #if STM32MP13
240 	uint32_t idx;
241 
242 	for (idx = 0U; idx < HSLV_NB_IDX; idx++) {
243 		enable_hslv_by_index(idx);
244 	}
245 #endif
246 #if STM32MP15
247 	mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR,
248 		      SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
249 		      SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
250 		      SYSCFG_IOCTRLSETR_HSLVEN_ETH |
251 		      SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
252 		      SYSCFG_IOCTRLSETR_HSLVEN_SPI);
253 #endif
254 }
255 
256 static void stm32mp1_syscfg_set_hslv(void)
257 {
258 	uint32_t otp_value;
259 	uint32_t vdd_voltage;
260 	bool product_below_2v5;
261 
262 	/*
263 	 * High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
264 	 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
265 	 * It could be disabled for low frequencies or if AFMUX is selected
266 	 * but the function is not used, typically for TRACE.
267 	 * If high speed low voltage pad mode is node enable, platform will
268 	 * over consume.
269 	 *
270 	 * WARNING:
271 	 *   Enabling High Speed mode while VDD > 2.7V
272 	 *   with the OTP product_below_2v5 (OTP 18, BIT 13)
273 	 *   erroneously set to 1 can damage the SoC!
274 	 *   => TF-A enables the low power mode only if VDD < 2.7V (in DT)
275 	 *      but this value needs to be consistent with board design.
276 	 */
277 	if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
278 		panic();
279 	}
280 
281 	product_below_2v5 = (otp_value & HW2_OTP_PRODUCT_BELOW_2V5) != 0U;
282 
283 	/* Get VDD supply */
284 	vdd_voltage = dt_get_pwr_vdd_voltage();
285 
286 	/* Check if VDD is Low Voltage */
287 	if (vdd_voltage == 0U) {
288 		WARN("VDD unknown\n");
289 	} else if (vdd_voltage < 2700000U) {
290 		enable_high_speed_mode_low_voltage();
291 
292 		if (!product_below_2v5) {
293 			INFO("Product_below_2v5=0: HSLVEN protected by HW\n");
294 		}
295 	} else {
296 		if (product_below_2v5) {
297 			ERROR("Product_below_2v5=1:\n");
298 			ERROR("\tHSLVEN update is destructive,\n");
299 			ERROR("\tno update as VDD > 2.7V\n");
300 			panic();
301 		}
302 	}
303 }
304 
305 void stm32mp1_syscfg_init(void)
306 {
307 #if STM32MP15
308 	uint32_t bootr;
309 
310 	/*
311 	 * Interconnect update : select master using the port 1.
312 	 * LTDC = AXI_M9.
313 	 */
314 	mmio_write_32(SYSCFG_BASE + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9);
315 
316 	/* Disable Pull-Down for boot pin connected to VDD */
317 	bootr = mmio_read_32(SYSCFG_BASE + SYSCFG_BOOTR) &
318 		SYSCFG_BOOTR_BOOT_MASK;
319 	mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK,
320 			   bootr << SYSCFG_BOOTR_BOOTPD_SHIFT);
321 #endif
322 
323 	stm32mp1_syscfg_set_hslv();
324 
325 	stm32mp1_syscfg_enable_io_compensation_start();
326 }
327 
328 void stm32mp1_syscfg_enable_io_compensation_start(void)
329 {
330 	/*
331 	 * Activate automatic I/O compensation.
332 	 * Warning: need to ensure CSI enabled and ready in clock driver.
333 	 * Enable non-secure clock, we assume non-secure is suspended.
334 	 */
335 	clk_enable(SYSCFG);
336 
337 	mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPCR,
338 			SYSCFG_CMPENSETR_MPU_EN);
339 #if STM32MP13
340 	mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD1CR,
341 			SYSCFG_CMPENSETR_MPU_EN);
342 	mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD2CR,
343 			SYSCFG_CMPENSETR_MPU_EN);
344 
345 #endif
346 }
347 
348 void stm32mp1_syscfg_enable_io_compensation_finish(void)
349 {
350 	enable_io_comp_cell_finish(SYSCFG_CMPCR);
351 #if STM32MP13
352 	enable_io_comp_cell_finish(SYSCFG_CMPSD1CR);
353 	enable_io_comp_cell_finish(SYSCFG_CMPSD2CR);
354 #endif
355 }
356 
357 void stm32mp1_syscfg_disable_io_compensation(void)
358 {
359 	clk_enable(SYSCFG);
360 
361 	/*
362 	 * Deactivate automatic I/O compensation.
363 	 * Warning: CSI is disabled automatically in STOP if not
364 	 * requested for other usages and always OFF in STANDBY.
365 	 * Disable non-secure SYSCFG clock, we assume non-secure is suspended.
366 	 */
367 	disable_io_comp_cell(SYSCFG_CMPCR);
368 #if STM32MP13
369 	disable_io_comp_cell(SYSCFG_CMPSD1CR);
370 	disable_io_comp_cell(SYSCFG_CMPSD2CR);
371 #endif
372 
373 	clk_disable(SYSCFG);
374 }
375 
376 /*
377  * @brief  Get silicon revision from SYSCFG registers.
378  * @retval chip version (REV_ID).
379  */
380 uint32_t stm32mp1_syscfg_get_chip_version(void)
381 {
382 	return (mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) &
383 		SYSCFG_IDC_REV_ID_MASK) >> SYSCFG_IDC_REV_ID_SHIFT;
384 }
385 
386 /*
387  * @brief  Get device ID from SYSCFG registers.
388  * @retval device ID (DEV_ID).
389  */
390 uint32_t stm32mp1_syscfg_get_chip_dev_id(void)
391 {
392 	return mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & SYSCFG_IDC_DEV_ID_MASK;
393 }
394