blob: ff79428a6afdf38eb86858fd103b901cc346406c [file] [log] [blame]
Yann Gautier3edc7c32019-05-20 19:17:08 +02001/*
Nicolas Le Bayon36898692019-11-18 17:18:06 +01002 * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
Yann Gautier3edc7c32019-05-20 19:17:08 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Yann Gautier07cf3f22021-01-12 15:52:19 +01007#include <assert.h>
8#include <errno.h>
9
Yann Gautier3edc7c32019-05-20 19:17:08 +020010#include <common/debug.h>
Etienne Carriere1de46d02020-02-07 13:38:30 +010011#include <drivers/clk.h>
Nicolas Le Bayon36898692019-11-18 17:18:06 +010012#include <drivers/delay_timer.h>
Yann Gautier3edc7c32019-05-20 19:17:08 +020013#include <drivers/st/stpmic1.h>
14#include <lib/mmio.h>
Yann Gautierf36a1d32020-04-21 15:03:59 +020015#include <lib/utils_def.h>
Yann Gautier07cf3f22021-01-12 15:52:19 +010016#include <libfdt.h>
Yann Gautier3edc7c32019-05-20 19:17:08 +020017
Nicolas Le Bayon36898692019-11-18 17:18:06 +010018#include <platform_def.h>
Lionel Debievebc2d88d2019-11-04 14:31:38 +010019#include <stm32mp_common.h>
Yann Gautier3edc7c32019-05-20 19:17:08 +020020#include <stm32mp_dt.h>
21#include <stm32mp1_private.h>
22
23/*
24 * SYSCFG REGISTER OFFSET (base relative)
25 */
26#define SYSCFG_BOOTR 0x00U
Nicolas Toromanoff1877b132021-02-03 16:52:03 +010027#define SYSCFG_BOOTCR 0x0CU
Yann Gautiercc5f89a2020-02-12 09:36:23 +010028#if STM32MP15
Yann Gautier3edc7c32019-05-20 19:17:08 +020029#define SYSCFG_IOCTRLSETR 0x18U
30#define SYSCFG_ICNR 0x1CU
Yann Gautiercc5f89a2020-02-12 09:36:23 +010031#endif
Yann Gautier3edc7c32019-05-20 19:17:08 +020032#define SYSCFG_CMPCR 0x20U
33#define SYSCFG_CMPENSETR 0x24U
Yann Gautier0315fa02020-10-26 15:21:25 +010034#define SYSCFG_CMPENCLRR 0x28U
Yann Gautier4a164842020-11-17 15:27:58 +010035#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
Yann Gautier07cf3f22021-01-12 15:52:19 +010042#define SYSCFG_HSLVEN0R 0x50U
Yann Gautier4a164842020-11-17 15:27:58 +010043#endif
Yann Gautierf36a1d32020-04-21 15:03:59 +020044#define SYSCFG_IDC 0x380U
Yann Gautier3edc7c32019-05-20 19:17:08 +020045
Yann Gautierb76c61a2020-12-16 10:17:35 +010046#define CMPCR_CMPENSETR_OFFSET 0x4U
47#define CMPCR_CMPENCLRR_OFFSET 0x8U
48
Yann Gautier3edc7c32019-05-20 19:17:08 +020049/*
50 * SYSCFG_BOOTR Register
51 */
52#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
Yann Gautiercc5f89a2020-02-12 09:36:23 +010053#if STM32MP15
Yann Gautier3edc7c32019-05-20 19:17:08 +020054#define SYSCFG_BOOTR_BOOTPD_MASK GENMASK(6, 4)
55#define SYSCFG_BOOTR_BOOTPD_SHIFT 4
Yann Gautiercc5f89a2020-02-12 09:36:23 +010056#endif
57
Yann Gautier3edc7c32019-05-20 19:17:08 +020058/*
Nicolas Toromanoff1877b132021-02-03 16:52:03 +010059 * SYSCFG_BOOTCR Register
60 */
61#define SYSCFG_BOOTCR_BMEN BIT(0)
62
63/*
Yann Gautier3edc7c32019-05-20 19:17:08 +020064 * 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
Nicolas Le Bayon36898692019-11-18 17:18:06 +010087#define SYSCFG_CMPCR_READY_TIMEOUT_US 10000U
88
Yann Gautier3edc7c32019-05-20 19:17:08 +020089/*
90 * SYSCFG_CMPENSETR Register
91 */
92#define SYSCFG_CMPENSETR_MPU_EN BIT(0)
93
Yann Gautierf36a1d32020-04-21 15:03:59 +020094/*
Yann Gautier07cf3f22021-01-12 15:52:19 +010095 * 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/*
Yann Gautierf36a1d32020-04-21 15:03:59 +0200114 * 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
Yann Gautierb76c61a2020-12-16 10:17:35 +0100120static 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
137static 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
Yann Gautier07cf3f22021-01-12 15:52:19 +0100159#if STM32MP13
160static 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
186static 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
219static 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
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100243static void enable_high_speed_mode_low_voltage(void)
Yann Gautier3edc7c32019-05-20 19:17:08 +0200244{
Yann Gautier07cf3f22021-01-12 15:52:19 +0100245#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
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100252#if STM32MP15
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100253 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);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100259#endif
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100260}
261
262static void stm32mp1_syscfg_set_hslv(void)
263{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100264 uint32_t otp_value;
Yann Gautier3edc7c32019-05-20 19:17:08 +0200265 uint32_t vdd_voltage;
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100266 bool product_below_2v5;
Yann Gautier3edc7c32019-05-20 19:17:08 +0200267
268 /*
Yann Gautier3edc7c32019-05-20 19:17:08 +0200269 * 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 */
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100283 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier3edc7c32019-05-20 19:17:08 +0200284 panic();
285 }
286
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100287 product_below_2v5 = (otp_value & HW2_OTP_PRODUCT_BELOW_2V5) != 0U;
Yann Gautier3edc7c32019-05-20 19:17:08 +0200288
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) {
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100294 WARN("VDD unknown\n");
Yann Gautier3edc7c32019-05-20 19:17:08 +0200295 } else if (vdd_voltage < 2700000U) {
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100296 enable_high_speed_mode_low_voltage();
Yann Gautier3edc7c32019-05-20 19:17:08 +0200297
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100298 if (!product_below_2v5) {
Yann Gautier3edc7c32019-05-20 19:17:08 +0200299 INFO("Product_below_2v5=0: HSLVEN protected by HW\n");
300 }
301 } else {
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100302 if (product_below_2v5) {
Yann Gautier3edc7c32019-05-20 19:17:08 +0200303 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 }
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100309}
310
311void stm32mp1_syscfg_init(void)
312{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100313#if STM32MP15
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100314 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);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100327#endif
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100328
329 stm32mp1_syscfg_set_hslv();
Yann Gautier3edc7c32019-05-20 19:17:08 +0200330
Yann Gautierb76c61a2020-12-16 10:17:35 +0100331 stm32mp1_syscfg_enable_io_compensation_start();
Yann Gautier3edc7c32019-05-20 19:17:08 +0200332}
333
Yann Gautierb76c61a2020-12-16 10:17:35 +0100334void stm32mp1_syscfg_enable_io_compensation_start(void)
Yann Gautier3edc7c32019-05-20 19:17:08 +0200335{
Yann Gautier3edc7c32019-05-20 19:17:08 +0200336 /*
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 */
Etienne Carriere1de46d02020-02-07 13:38:30 +0100341 clk_enable(SYSCFG);
Yann Gautier3edc7c32019-05-20 19:17:08 +0200342
Yann Gautierb76c61a2020-12-16 10:17:35 +0100343 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPCR,
Yann Gautier3edc7c32019-05-20 19:17:08 +0200344 SYSCFG_CMPENSETR_MPU_EN);
Yann Gautier4a164842020-11-17 15:27:58 +0100345#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
Yann Gautierb76c61a2020-12-16 10:17:35 +0100352}
Yann Gautier3edc7c32019-05-20 19:17:08 +0200353
Yann Gautierb76c61a2020-12-16 10:17:35 +0100354void stm32mp1_syscfg_enable_io_compensation_finish(void)
355{
356 enable_io_comp_cell_finish(SYSCFG_CMPCR);
Yann Gautier4a164842020-11-17 15:27:58 +0100357#if STM32MP13
358 enable_io_comp_cell_finish(SYSCFG_CMPSD1CR);
359 enable_io_comp_cell_finish(SYSCFG_CMPSD2CR);
360#endif
Yann Gautier3edc7c32019-05-20 19:17:08 +0200361}
362
363void stm32mp1_syscfg_disable_io_compensation(void)
364{
Yann Gautierb76c61a2020-12-16 10:17:35 +0100365 clk_enable(SYSCFG);
Yann Gautier3edc7c32019-05-20 19:17:08 +0200366
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 */
Yann Gautierb76c61a2020-12-16 10:17:35 +0100373 disable_io_comp_cell(SYSCFG_CMPCR);
Yann Gautier4a164842020-11-17 15:27:58 +0100374#if STM32MP13
375 disable_io_comp_cell(SYSCFG_CMPSD1CR);
376 disable_io_comp_cell(SYSCFG_CMPSD2CR);
377#endif
Yann Gautier3edc7c32019-05-20 19:17:08 +0200378
Etienne Carriere1de46d02020-02-07 13:38:30 +0100379 clk_disable(SYSCFG);
Yann Gautier3edc7c32019-05-20 19:17:08 +0200380}
Yann Gautierf36a1d32020-04-21 15:03:59 +0200381
382/*
383 * @brief Get silicon revision from SYSCFG registers.
384 * @retval chip version (REV_ID).
385 */
386uint32_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 */
396uint32_t stm32mp1_syscfg_get_chip_dev_id(void)
397{
398 return mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & SYSCFG_IDC_DEV_ID_MASK;
399}
Nicolas Toromanoff1877b132021-02-03 16:52:03 +0100400
401#if STM32MP13
402void stm32mp1_syscfg_boot_mode_enable(void)
403{
404 mmio_setbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
405}
406
407void stm32mp1_syscfg_boot_mode_disable(void)
408{
409 mmio_clrbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
410}
411#endif