1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2019-2023, STMicroelectronics
4 */
5
6 #include <config.h>
7 #include <drivers/clk.h>
8 #include <drivers/stm32mp_dt_bindings.h>
9 #include <drivers/stm32mp1_syscfg.h>
10 #include <initcall.h>
11 #include <kernel/delay.h>
12 #include <mm/core_memprot.h>
13 #include <stm32_util.h>
14 #include <io.h>
15 #include <trace.h>
16 #include <types_ext.h>
17
18 /*
19 * SYSCFG register offsets (base relative)
20 */
21 #define SYSCFG_SRAM3ERASER U(0x10)
22 #define SYSCFG_SRAM3KR U(0x14)
23 #define SYSCFG_IOCTRLSETR U(0x18)
24 #define SYSCFG_CMPCR U(0x20)
25 #define SYSCFG_CMPENSETR U(0x24)
26 #define SYSCFG_CMPSD1CR U(0x30)
27 #define SYSCFG_CMPSD2CR U(0x40)
28 #define SYSCFG_HSLVEN0R U(0x50)
29 #define SYSCFG_IDC U(0x380)
30 #define SYSCFG_IOSIZE U(0x400)
31
32 /*
33 * SYSCFG_IOCTRLSETR Register for STM32MP15 variants
34 */
35 #define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0)
36 #define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1)
37 #define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2)
38 #define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3)
39 #define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4)
40
41 /*
42 * SYSCFG_SRAM3ERASE Register
43 */
44 #define SYSCFG_SRAM3KR_KEY1 U(0xCA)
45 #define SYSCFG_SRAM3KR_KEY2 U(0x53)
46
47 #define SYSCFG_SRAM3ERASER_SRAM3EO BIT(1)
48 #define SYSCFG_SRAM3ERASER_SRAM3ER BIT(0)
49
50 #define SYSCFG_SRAM3ERASE_TIMEOUT_US U(1000)
51
52 /*
53 * SYSCFG_CMPCR Register
54 */
55 #define SYSCFG_CMPCR_SW_CTRL BIT(1)
56 #define SYSCFG_CMPCR_READY BIT(8)
57 #define SYSCFG_CMPCR_RANSRC GENMASK_32(19, 16)
58 #define SYSCFG_CMPCR_RANSRC_SHIFT U(16)
59 #define SYSCFG_CMPCR_RAPSRC GENMASK_32(23, 20)
60 #define SYSCFG_CMPCR_ANSRC_SHIFT U(24)
61
62 #define SYSCFG_CMPCR_READY_TIMEOUT_US U(10000)
63
64 #define CMPENSETR_OFFSET U(0x4)
65 #define CMPENCLRR_OFFSET U(0x8)
66
67 /*
68 * SYSCFG_CMPENSETR Register
69 */
70 #define SYSCFG_CMPENSETR_MPU_EN BIT(0)
71
72 /*
73 * HSLV definitions
74 */
75 #define SYSCFG_HSLV_MASK GENMASK_32(15, 0)
76 #define SYSCFG_HSLV_KEY U(0x1018)
77
78 /*
79 * SYSCFG_IDC Register
80 */
81 #define SYSCFG_IDC_DEV_ID_MASK GENMASK_32(11, 0)
82 #define SYSCFG_IDC_REV_ID_MASK GENMASK_32(31, 16)
83 #define SYSCFG_IDC_REV_ID_SHIFT U(16)
84
get_syscfg_base(void)85 static vaddr_t get_syscfg_base(void)
86 {
87 static struct io_pa_va base = { .pa = SYSCFG_BASE };
88
89 return io_pa_or_va(&base, SYSCFG_IOSIZE);
90 }
91
stm32mp_syscfg_get_chip_dev_id(void)92 uint32_t stm32mp_syscfg_get_chip_dev_id(void)
93 {
94 if (IS_ENABLED(CFG_STM32MP13))
95 return io_read32(get_syscfg_base() + SYSCFG_IDC) &
96 SYSCFG_IDC_DEV_ID_MASK;
97
98 return 0;
99 }
100
enable_io_compensation(int cmpcr_offset)101 static void enable_io_compensation(int cmpcr_offset)
102 {
103 vaddr_t cmpcr_va = get_syscfg_base() + cmpcr_offset;
104 uint32_t value = 0;
105
106 if (io_read32(cmpcr_va) & SYSCFG_CMPCR_READY)
107 return;
108
109 io_setbits32(cmpcr_va + CMPENSETR_OFFSET, SYSCFG_CMPENSETR_MPU_EN);
110
111 if (IO_READ32_POLL_TIMEOUT(cmpcr_va, value, value & SYSCFG_CMPCR_READY,
112 0, SYSCFG_CMPCR_READY_TIMEOUT_US)) {
113 /* Allow an almost silent failure here */
114 EMSG("IO compensation cell not ready");
115 }
116
117 io_clrbits32(cmpcr_va, SYSCFG_CMPCR_SW_CTRL);
118
119 DMSG("SYSCFG.cmpcr = %#"PRIx32, io_read32(cmpcr_va));
120 }
121
disable_io_compensation(int cmpcr_offset)122 static __maybe_unused void disable_io_compensation(int cmpcr_offset)
123 {
124 vaddr_t cmpcr_base = get_syscfg_base() + cmpcr_offset;
125 uint32_t value_cmpcr = 0;
126 uint32_t apsrc_ansrc = 0;
127 uint32_t value_cmpcr2 = 0;
128
129 value_cmpcr = io_read32(cmpcr_base);
130 value_cmpcr2 = io_read32(cmpcr_base + CMPENSETR_OFFSET);
131 if (!(value_cmpcr & SYSCFG_CMPCR_READY &&
132 value_cmpcr2 & SYSCFG_CMPENSETR_MPU_EN))
133 return;
134
135 /* Copy APSRC (resp. ANSRC) in RAPSRC (resp. RANSRC) */
136 apsrc_ansrc = value_cmpcr >> SYSCFG_CMPCR_ANSRC_SHIFT;
137 value_cmpcr &= ~(SYSCFG_CMPCR_RANSRC | SYSCFG_CMPCR_RAPSRC);
138 value_cmpcr |= SHIFT_U32(apsrc_ansrc, SYSCFG_CMPCR_RANSRC_SHIFT);
139
140 io_write32(cmpcr_base, value_cmpcr | SYSCFG_CMPCR_SW_CTRL);
141
142 io_setbits32(cmpcr_base + CMPENCLRR_OFFSET, SYSCFG_CMPENSETR_MPU_EN);
143
144 DMSG("SYSCFG.cmpcr = %#"PRIx32, io_read32(cmpcr_base));
145 }
146
stm32mp1_iocomp(void)147 static TEE_Result stm32mp1_iocomp(void)
148 {
149 if (clk_enable(stm32mp_rcc_clock_id_to_clk(CK_CSI)) ||
150 clk_enable(stm32mp_rcc_clock_id_to_clk(SYSCFG)))
151 panic();
152
153 enable_io_compensation(SYSCFG_CMPCR);
154
155 /* Make sure the write above is visible */
156 dsb();
157
158 return TEE_SUCCESS;
159 }
160
161 driver_init(stm32mp1_iocomp);
162
163 #ifdef CFG_STM32MP13
stm32mp_set_vddsd_comp_state(enum stm32mp13_vddsd_comp_id id,bool enable)164 void stm32mp_set_vddsd_comp_state(enum stm32mp13_vddsd_comp_id id, bool enable)
165 {
166 int cmpcr_offset = 0;
167
168 /* Make sure the previous operations are visible */
169 dsb();
170
171 switch (id) {
172 case SYSCFG_IO_COMP_IDX_SD1:
173 cmpcr_offset = SYSCFG_CMPSD1CR;
174 break;
175 case SYSCFG_IO_COMP_IDX_SD2:
176 cmpcr_offset = SYSCFG_CMPSD2CR;
177 break;
178 default:
179 panic();
180 }
181
182 if (enable)
183 enable_io_compensation(cmpcr_offset);
184 else
185 disable_io_compensation(cmpcr_offset);
186
187 /* Make sure the write above is visible */
188 dsb();
189 }
190
stm32mp_set_hslv_state(enum stm32mp13_hslv_id id,bool enable)191 void stm32mp_set_hslv_state(enum stm32mp13_hslv_id id, bool enable)
192 {
193 size_t hslvenxr_offset = 0;
194 uint32_t hlvs_value = 0;
195
196 /* Make sure the previous operations are visible */
197 dsb();
198
199 assert(id < SYSCFG_HSLV_COUNT);
200
201 if (enable)
202 hlvs_value = SYSCFG_HSLV_KEY;
203
204 /* IDs are indices of SYSCFG_HSLVENxR registers */
205 hslvenxr_offset = SYSCFG_HSLVEN0R + id * sizeof(uint32_t);
206
207 io_write32(get_syscfg_base() + hslvenxr_offset, hlvs_value);
208
209 /* Value read shall be 1 on enable and 0 on disable */
210 hlvs_value = io_read32(get_syscfg_base() + hslvenxr_offset) &
211 SYSCFG_HSLV_MASK;
212 if (enable != hlvs_value)
213 panic();
214 }
215
stm32mp_enable_fixed_vdd_hslv(void)216 void stm32mp_enable_fixed_vdd_hslv(void)
217 {
218 enum stm32mp13_hslv_id id = SYSCFG_HSLV_COUNT;
219
220 for (id = SYSCFG_HSLV_IDX_TPIU; id < SYSCFG_HSLV_COUNT; id++) {
221 /* SDMMCs domains may not be supplied by VDD */
222 if (id == SYSCFG_HSLV_IDX_SDMMC1 ||
223 id == SYSCFG_HSLV_IDX_SDMMC2)
224 continue;
225
226 stm32mp_set_hslv_state(id, true);
227 }
228 }
229 #endif /* CFG_STM32MP13 */
230
231 #ifdef CFG_STM32MP15
stm32mp_enable_fixed_vdd_hslv(void)232 void stm32mp_enable_fixed_vdd_hslv(void)
233 {
234 dsb();
235
236 io_write32(get_syscfg_base() + SYSCFG_IOCTRLSETR,
237 SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
238 SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
239 SYSCFG_IOCTRLSETR_HSLVEN_ETH |
240 SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
241 SYSCFG_IOCTRLSETR_HSLVEN_SPI);
242
243 dsb();
244 }
245 #endif
246
stm32mp_syscfg_erase_sram3(void)247 TEE_Result stm32mp_syscfg_erase_sram3(void)
248 {
249 vaddr_t base = get_syscfg_base();
250 uint32_t value = 0;
251
252 if (!IS_ENABLED(CFG_STM32MP13))
253 return TEE_ERROR_NOT_SUPPORTED;
254
255 /* Unlock SYSCFG_SRAM3ERASER_SRAM3ER */
256 io_write32(base + SYSCFG_SRAM3KR, SYSCFG_SRAM3KR_KEY1);
257 io_write32(base + SYSCFG_SRAM3KR, SYSCFG_SRAM3KR_KEY2);
258
259 /* Request SRAM3 erase */
260 io_setbits32(base + SYSCFG_SRAM3ERASER, SYSCFG_SRAM3ERASER_SRAM3ER);
261
262 /* Lock SYSCFG_SRAM3ERASER_SRAM3ER */
263 io_write32(base + SYSCFG_SRAM3KR, 0);
264
265 /* Wait end of SRAM3 erase */
266 if (IO_READ32_POLL_TIMEOUT(base + SYSCFG_SRAM3ERASER, value,
267 !(value & SYSCFG_SRAM3ERASER_SRAM3EO), 0,
268 SYSCFG_SRAM3ERASE_TIMEOUT_US))
269 return TEE_ERROR_BUSY;
270
271 return TEE_SUCCESS;
272 }
273