blob: 8edf3389ea5c66f3a42877e47be104eaf7b38f37 [file] [log] [blame]
Yann Gautierf33b2432019-05-20 19:17:08 +02001/*
Nicolas Le Bayonde02e9b2019-11-18 17:18:06 +01002 * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
Yann Gautierf33b2432019-05-20 19:17:08 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Yann Gautierf33b2432019-05-20 19:17:08 +02007#include <common/debug.h>
Etienne Carrierec7a66e72020-02-07 13:38:30 +01008#include <drivers/clk.h>
Nicolas Le Bayonde02e9b2019-11-18 17:18:06 +01009#include <drivers/delay_timer.h>
Yann Gautierf33b2432019-05-20 19:17:08 +020010#include <drivers/st/stpmic1.h>
11#include <lib/mmio.h>
Yann Gautier6512c3a2020-04-21 15:03:59 +020012#include <lib/utils_def.h>
Yann Gautierf33b2432019-05-20 19:17:08 +020013
Nicolas Le Bayonde02e9b2019-11-18 17:18:06 +010014#include <platform_def.h>
Lionel Debieveae3ce8b2019-11-04 14:31:38 +010015#include <stm32mp_common.h>
Yann Gautierf33b2432019-05-20 19:17:08 +020016#include <stm32mp_dt.h>
17#include <stm32mp1_private.h>
18
19/*
20 * SYSCFG REGISTER OFFSET (base relative)
21 */
22#define SYSCFG_BOOTR 0x00U
Yann Gautier111a3842020-02-12 09:36:23 +010023#if STM32MP15
Yann Gautierf33b2432019-05-20 19:17:08 +020024#define SYSCFG_IOCTRLSETR 0x18U
25#define SYSCFG_ICNR 0x1CU
Yann Gautier111a3842020-02-12 09:36:23 +010026#endif
Yann Gautierf33b2432019-05-20 19:17:08 +020027#define SYSCFG_CMPCR 0x20U
28#define SYSCFG_CMPENSETR 0x24U
Yann Gautierc2d18ca2020-10-26 15:21:25 +010029#define SYSCFG_CMPENCLRR 0x28U
Yann Gautier8e07ab52020-11-17 15:27:58 +010030#if STM32MP13
31#define SYSCFG_CMPSD1CR 0x30U
32#define SYSCFG_CMPSD1ENSETR 0x34U
33#define SYSCFG_CMPSD1ENCLRR 0x38U
34#define SYSCFG_CMPSD2CR 0x40U
35#define SYSCFG_CMPSD2ENSETR 0x44U
36#define SYSCFG_CMPSD2ENCLRR 0x48U
37#endif
Yann Gautier6512c3a2020-04-21 15:03:59 +020038#define SYSCFG_IDC 0x380U
Yann Gautierf33b2432019-05-20 19:17:08 +020039
Yann Gautier1f4513c2020-12-16 10:17:35 +010040#define CMPCR_CMPENSETR_OFFSET 0x4U
41#define CMPCR_CMPENCLRR_OFFSET 0x8U
42
Yann Gautierf33b2432019-05-20 19:17:08 +020043/*
44 * SYSCFG_BOOTR Register
45 */
46#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
Yann Gautier111a3842020-02-12 09:36:23 +010047#if STM32MP15
Yann Gautierf33b2432019-05-20 19:17:08 +020048#define SYSCFG_BOOTR_BOOTPD_MASK GENMASK(6, 4)
49#define SYSCFG_BOOTR_BOOTPD_SHIFT 4
Yann Gautier111a3842020-02-12 09:36:23 +010050#endif
51
Yann Gautierf33b2432019-05-20 19:17:08 +020052/*
53 * SYSCFG_IOCTRLSETR Register
54 */
55#define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0)
56#define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1)
57#define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2)
58#define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3)
59#define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4)
60
61/*
62 * SYSCFG_ICNR Register
63 */
64#define SYSCFG_ICNR_AXI_M9 BIT(9)
65
66/*
67 * SYSCFG_CMPCR Register
68 */
69#define SYSCFG_CMPCR_SW_CTRL BIT(1)
70#define SYSCFG_CMPCR_READY BIT(8)
71#define SYSCFG_CMPCR_RANSRC GENMASK(19, 16)
72#define SYSCFG_CMPCR_RANSRC_SHIFT 16
73#define SYSCFG_CMPCR_RAPSRC GENMASK(23, 20)
74#define SYSCFG_CMPCR_ANSRC_SHIFT 24
75
Nicolas Le Bayonde02e9b2019-11-18 17:18:06 +010076#define SYSCFG_CMPCR_READY_TIMEOUT_US 10000U
77
Yann Gautierf33b2432019-05-20 19:17:08 +020078/*
79 * SYSCFG_CMPENSETR Register
80 */
81#define SYSCFG_CMPENSETR_MPU_EN BIT(0)
82
Yann Gautier6512c3a2020-04-21 15:03:59 +020083/*
84 * SYSCFG_IDC Register
85 */
86#define SYSCFG_IDC_DEV_ID_MASK GENMASK(11, 0)
87#define SYSCFG_IDC_REV_ID_MASK GENMASK(31, 16)
88#define SYSCFG_IDC_REV_ID_SHIFT 16
89
Yann Gautier1f4513c2020-12-16 10:17:35 +010090static void enable_io_comp_cell_finish(uintptr_t cmpcr_off)
91{
92 uint64_t start;
93
94 start = timeout_init_us(SYSCFG_CMPCR_READY_TIMEOUT_US);
95
96 while ((mmio_read_32(SYSCFG_BASE + cmpcr_off) & SYSCFG_CMPCR_READY) == 0U) {
97 if (timeout_elapsed(start)) {
98 /* Failure on IO compensation enable is not a issue: warn only. */
99 WARN("IO compensation cell not ready\n");
100 break;
101 }
102 }
103
104 mmio_clrbits_32(SYSCFG_BASE + cmpcr_off, SYSCFG_CMPCR_SW_CTRL);
105}
106
107static void disable_io_comp_cell(uintptr_t cmpcr_off)
108{
109 uint32_t value;
110
111 if (((mmio_read_32(SYSCFG_BASE + cmpcr_off) & SYSCFG_CMPCR_READY) == 0U) ||
112 ((mmio_read_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENSETR_OFFSET) &
113 SYSCFG_CMPENSETR_MPU_EN) == 0U)) {
114 return;
115 }
116
117 value = mmio_read_32(SYSCFG_BASE + cmpcr_off) >> SYSCFG_CMPCR_ANSRC_SHIFT;
118
119 mmio_clrbits_32(SYSCFG_BASE + cmpcr_off, SYSCFG_CMPCR_RANSRC | SYSCFG_CMPCR_RAPSRC);
120
121 value <<= SYSCFG_CMPCR_RANSRC_SHIFT;
122 value |= mmio_read_32(SYSCFG_BASE + cmpcr_off);
123
124 mmio_write_32(SYSCFG_BASE + cmpcr_off, value | SYSCFG_CMPCR_SW_CTRL);
125
126 mmio_setbits_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENCLRR_OFFSET, SYSCFG_CMPENSETR_MPU_EN);
127}
128
Yann Gautierdea02f42021-01-12 14:45:02 +0100129static void enable_high_speed_mode_low_voltage(void)
Yann Gautierf33b2432019-05-20 19:17:08 +0200130{
Yann Gautier111a3842020-02-12 09:36:23 +0100131#if STM32MP15
Yann Gautierdea02f42021-01-12 14:45:02 +0100132 mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR,
133 SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
134 SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
135 SYSCFG_IOCTRLSETR_HSLVEN_ETH |
136 SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
137 SYSCFG_IOCTRLSETR_HSLVEN_SPI);
Yann Gautier111a3842020-02-12 09:36:23 +0100138#endif
Yann Gautierdea02f42021-01-12 14:45:02 +0100139}
140
141static void stm32mp1_syscfg_set_hslv(void)
142{
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100143 uint32_t otp_value;
Yann Gautierf33b2432019-05-20 19:17:08 +0200144 uint32_t vdd_voltage;
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100145 bool product_below_2v5;
Yann Gautierf33b2432019-05-20 19:17:08 +0200146
147 /*
Yann Gautierf33b2432019-05-20 19:17:08 +0200148 * High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
149 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
150 * It could be disabled for low frequencies or if AFMUX is selected
151 * but the function is not used, typically for TRACE.
152 * If high speed low voltage pad mode is node enable, platform will
153 * over consume.
154 *
155 * WARNING:
156 * Enabling High Speed mode while VDD > 2.7V
157 * with the OTP product_below_2v5 (OTP 18, BIT 13)
158 * erroneously set to 1 can damage the SoC!
159 * => TF-A enables the low power mode only if VDD < 2.7V (in DT)
160 * but this value needs to be consistent with board design.
161 */
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100162 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautierf33b2432019-05-20 19:17:08 +0200163 panic();
164 }
165
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100166 product_below_2v5 = (otp_value & HW2_OTP_PRODUCT_BELOW_2V5) != 0U;
Yann Gautierf33b2432019-05-20 19:17:08 +0200167
168 /* Get VDD supply */
169 vdd_voltage = dt_get_pwr_vdd_voltage();
170
171 /* Check if VDD is Low Voltage */
172 if (vdd_voltage == 0U) {
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100173 WARN("VDD unknown\n");
Yann Gautierf33b2432019-05-20 19:17:08 +0200174 } else if (vdd_voltage < 2700000U) {
Yann Gautierdea02f42021-01-12 14:45:02 +0100175 enable_high_speed_mode_low_voltage();
Yann Gautierf33b2432019-05-20 19:17:08 +0200176
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100177 if (!product_below_2v5) {
Yann Gautierf33b2432019-05-20 19:17:08 +0200178 INFO("Product_below_2v5=0: HSLVEN protected by HW\n");
179 }
180 } else {
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100181 if (product_below_2v5) {
Yann Gautierf33b2432019-05-20 19:17:08 +0200182 ERROR("Product_below_2v5=1:\n");
183 ERROR("\tHSLVEN update is destructive,\n");
184 ERROR("\tno update as VDD > 2.7V\n");
185 panic();
186 }
187 }
Yann Gautierdea02f42021-01-12 14:45:02 +0100188}
189
190void stm32mp1_syscfg_init(void)
191{
Yann Gautier111a3842020-02-12 09:36:23 +0100192#if STM32MP15
Yann Gautierdea02f42021-01-12 14:45:02 +0100193 uint32_t bootr;
194
195 /*
196 * Interconnect update : select master using the port 1.
197 * LTDC = AXI_M9.
198 */
199 mmio_write_32(SYSCFG_BASE + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9);
200
201 /* Disable Pull-Down for boot pin connected to VDD */
202 bootr = mmio_read_32(SYSCFG_BASE + SYSCFG_BOOTR) &
203 SYSCFG_BOOTR_BOOT_MASK;
204 mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK,
205 bootr << SYSCFG_BOOTR_BOOTPD_SHIFT);
Yann Gautier111a3842020-02-12 09:36:23 +0100206#endif
Yann Gautierdea02f42021-01-12 14:45:02 +0100207
208 stm32mp1_syscfg_set_hslv();
Yann Gautierf33b2432019-05-20 19:17:08 +0200209
Yann Gautier1f4513c2020-12-16 10:17:35 +0100210 stm32mp1_syscfg_enable_io_compensation_start();
Yann Gautierf33b2432019-05-20 19:17:08 +0200211}
212
Yann Gautier1f4513c2020-12-16 10:17:35 +0100213void stm32mp1_syscfg_enable_io_compensation_start(void)
Yann Gautierf33b2432019-05-20 19:17:08 +0200214{
Yann Gautierf33b2432019-05-20 19:17:08 +0200215 /*
216 * Activate automatic I/O compensation.
217 * Warning: need to ensure CSI enabled and ready in clock driver.
218 * Enable non-secure clock, we assume non-secure is suspended.
219 */
Etienne Carrierec7a66e72020-02-07 13:38:30 +0100220 clk_enable(SYSCFG);
Yann Gautierf33b2432019-05-20 19:17:08 +0200221
Yann Gautier1f4513c2020-12-16 10:17:35 +0100222 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPCR,
Yann Gautierf33b2432019-05-20 19:17:08 +0200223 SYSCFG_CMPENSETR_MPU_EN);
Yann Gautier8e07ab52020-11-17 15:27:58 +0100224#if STM32MP13
225 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD1CR,
226 SYSCFG_CMPENSETR_MPU_EN);
227 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD2CR,
228 SYSCFG_CMPENSETR_MPU_EN);
229
230#endif
Yann Gautier1f4513c2020-12-16 10:17:35 +0100231}
Yann Gautierf33b2432019-05-20 19:17:08 +0200232
Yann Gautier1f4513c2020-12-16 10:17:35 +0100233void stm32mp1_syscfg_enable_io_compensation_finish(void)
234{
235 enable_io_comp_cell_finish(SYSCFG_CMPCR);
Yann Gautier8e07ab52020-11-17 15:27:58 +0100236#if STM32MP13
237 enable_io_comp_cell_finish(SYSCFG_CMPSD1CR);
238 enable_io_comp_cell_finish(SYSCFG_CMPSD2CR);
239#endif
Yann Gautierf33b2432019-05-20 19:17:08 +0200240}
241
242void stm32mp1_syscfg_disable_io_compensation(void)
243{
Yann Gautier1f4513c2020-12-16 10:17:35 +0100244 clk_enable(SYSCFG);
Yann Gautierf33b2432019-05-20 19:17:08 +0200245
246 /*
247 * Deactivate automatic I/O compensation.
248 * Warning: CSI is disabled automatically in STOP if not
249 * requested for other usages and always OFF in STANDBY.
250 * Disable non-secure SYSCFG clock, we assume non-secure is suspended.
251 */
Yann Gautier1f4513c2020-12-16 10:17:35 +0100252 disable_io_comp_cell(SYSCFG_CMPCR);
Yann Gautier8e07ab52020-11-17 15:27:58 +0100253#if STM32MP13
254 disable_io_comp_cell(SYSCFG_CMPSD1CR);
255 disable_io_comp_cell(SYSCFG_CMPSD2CR);
256#endif
Yann Gautierf33b2432019-05-20 19:17:08 +0200257
Etienne Carrierec7a66e72020-02-07 13:38:30 +0100258 clk_disable(SYSCFG);
Yann Gautierf33b2432019-05-20 19:17:08 +0200259}
Yann Gautier6512c3a2020-04-21 15:03:59 +0200260
261/*
262 * @brief Get silicon revision from SYSCFG registers.
263 * @retval chip version (REV_ID).
264 */
265uint32_t stm32mp1_syscfg_get_chip_version(void)
266{
267 return (mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) &
268 SYSCFG_IDC_REV_ID_MASK) >> SYSCFG_IDC_REV_ID_SHIFT;
269}
270
271/*
272 * @brief Get device ID from SYSCFG registers.
273 * @retval device ID (DEV_ID).
274 */
275uint32_t stm32mp1_syscfg_get_chip_dev_id(void)
276{
277 return mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & SYSCFG_IDC_DEV_ID_MASK;
278}