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