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", ®u_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 mmio_write_32(SYSCFG_BASE + SYSCFG_HSLVEN0R + index * sizeof(uint32_t), HSLV_KEY);
239 }
240 }
241 #endif
242
enable_high_speed_mode_low_voltage(void)243 static void enable_high_speed_mode_low_voltage(void)
244 {
245 #if STM32MP13
246 uint32_t idx;
247
248 for (idx = 0U; idx < HSLV_NB_IDX; idx++) {
249 enable_hslv_by_index(idx);
250 }
251 #endif
252 #if STM32MP15
253 mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR,
254 SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
255 SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
256 SYSCFG_IOCTRLSETR_HSLVEN_ETH |
257 SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
258 SYSCFG_IOCTRLSETR_HSLVEN_SPI);
259 #endif
260 }
261
stm32mp1_syscfg_set_hslv(void)262 static void stm32mp1_syscfg_set_hslv(void)
263 {
264 uint32_t otp_value;
265 uint32_t vdd_voltage;
266 bool product_below_2v5;
267
268 /*
269 * High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
270 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
271 * It could be disabled for low frequencies or if AFMUX is selected
272 * but the function is not used, typically for TRACE.
273 * If high speed low voltage pad mode is node enable, platform will
274 * over consume.
275 *
276 * WARNING:
277 * Enabling High Speed mode while VDD > 2.7V
278 * with the OTP product_below_2v5 (OTP 18, BIT 13)
279 * erroneously set to 1 can damage the SoC!
280 * => TF-A enables the low power mode only if VDD < 2.7V (in DT)
281 * but this value needs to be consistent with board design.
282 */
283 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
284 panic();
285 }
286
287 product_below_2v5 = (otp_value & HW2_OTP_PRODUCT_BELOW_2V5) != 0U;
288
289 /* Get VDD supply */
290 vdd_voltage = dt_get_pwr_vdd_voltage();
291
292 /* Check if VDD is Low Voltage */
293 if (vdd_voltage == 0U) {
294 WARN("VDD unknown\n");
295 } else if (vdd_voltage < 2700000U) {
296 enable_high_speed_mode_low_voltage();
297
298 if (!product_below_2v5) {
299 INFO("Product_below_2v5=0: HSLVEN protected by HW\n");
300 }
301 } else {
302 if (product_below_2v5) {
303 ERROR("Product_below_2v5=1:\n");
304 ERROR("\tHSLVEN update is destructive,\n");
305 ERROR("\tno update as VDD > 2.7V\n");
306 panic();
307 }
308 }
309 }
310
stm32mp1_syscfg_init(void)311 void stm32mp1_syscfg_init(void)
312 {
313 #if STM32MP15
314 uint32_t bootr;
315
316 /*
317 * Interconnect update : select master using the port 1.
318 * LTDC = AXI_M9.
319 */
320 mmio_write_32(SYSCFG_BASE + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9);
321
322 /* Disable Pull-Down for boot pin connected to VDD */
323 bootr = mmio_read_32(SYSCFG_BASE + SYSCFG_BOOTR) &
324 SYSCFG_BOOTR_BOOT_MASK;
325 mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK,
326 bootr << SYSCFG_BOOTR_BOOTPD_SHIFT);
327 #endif
328
329 stm32mp1_syscfg_set_hslv();
330
331 stm32mp1_syscfg_enable_io_compensation_start();
332 }
333
stm32mp1_syscfg_enable_io_compensation_start(void)334 void stm32mp1_syscfg_enable_io_compensation_start(void)
335 {
336 /*
337 * Activate automatic I/O compensation.
338 * Warning: need to ensure CSI enabled and ready in clock driver.
339 * Enable non-secure clock, we assume non-secure is suspended.
340 */
341 clk_enable(SYSCFG);
342
343 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPCR,
344 SYSCFG_CMPENSETR_MPU_EN);
345 #if STM32MP13
346 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD1CR,
347 SYSCFG_CMPENSETR_MPU_EN);
348 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD2CR,
349 SYSCFG_CMPENSETR_MPU_EN);
350
351 #endif
352 }
353
stm32mp1_syscfg_enable_io_compensation_finish(void)354 void stm32mp1_syscfg_enable_io_compensation_finish(void)
355 {
356 enable_io_comp_cell_finish(SYSCFG_CMPCR);
357 #if STM32MP13
358 enable_io_comp_cell_finish(SYSCFG_CMPSD1CR);
359 enable_io_comp_cell_finish(SYSCFG_CMPSD2CR);
360 #endif
361 }
362
stm32mp1_syscfg_disable_io_compensation(void)363 void stm32mp1_syscfg_disable_io_compensation(void)
364 {
365 clk_enable(SYSCFG);
366
367 /*
368 * Deactivate automatic I/O compensation.
369 * Warning: CSI is disabled automatically in STOP if not
370 * requested for other usages and always OFF in STANDBY.
371 * Disable non-secure SYSCFG clock, we assume non-secure is suspended.
372 */
373 disable_io_comp_cell(SYSCFG_CMPCR);
374 #if STM32MP13
375 disable_io_comp_cell(SYSCFG_CMPSD1CR);
376 disable_io_comp_cell(SYSCFG_CMPSD2CR);
377 #endif
378
379 clk_disable(SYSCFG);
380 }
381
382 /*
383 * @brief Get silicon revision from SYSCFG registers.
384 * @retval chip version (REV_ID).
385 */
stm32mp1_syscfg_get_chip_version(void)386 uint32_t stm32mp1_syscfg_get_chip_version(void)
387 {
388 return (mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) &
389 SYSCFG_IDC_REV_ID_MASK) >> SYSCFG_IDC_REV_ID_SHIFT;
390 }
391
392 /*
393 * @brief Get device ID from SYSCFG registers.
394 * @retval device ID (DEV_ID).
395 */
stm32mp1_syscfg_get_chip_dev_id(void)396 uint32_t stm32mp1_syscfg_get_chip_dev_id(void)
397 {
398 return mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & SYSCFG_IDC_DEV_ID_MASK;
399 }
400
401 #if STM32MP13
stm32mp1_syscfg_boot_mode_enable(void)402 void stm32mp1_syscfg_boot_mode_enable(void)
403 {
404 mmio_setbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
405 }
406
stm32mp1_syscfg_boot_mode_disable(void)407 void stm32mp1_syscfg_boot_mode_disable(void)
408 {
409 mmio_clrbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
410 }
411 #endif
412