1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021-2025, STMicroelectronics
4 */
5
6 #include <arm.h>
7 #include <config.h>
8 #include <drivers/clk.h>
9 #include <drivers/clk_dt.h>
10 #include <drivers/rstctrl.h>
11 #include <drivers/stm32_gpio.h>
12 #include <io.h>
13 #include <kernel/boot.h>
14 #include <kernel/delay.h>
15 #include <kernel/dt.h>
16 #include <kernel/dt_driver.h>
17 #include <kernel/panic.h>
18 #include <kernel/pm.h>
19 #include <libfdt.h>
20 #include <mm/core_memprot.h>
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include <stm32_sysconf.h>
24 #include <stm32_util.h>
25 #include <trace.h>
26
27 /*
28 * OCTOSPI registers
29 */
30 #define _OCTOSPI_CR U(0x0)
31
32 /*
33 * OCTOSPI CR register bitfields
34 */
35 #define _OCTOSPI_CR_EN BIT(0)
36
37 /*
38 * OCTOSPIM registers
39 */
40 #define _OCTOSPIM_CR U(0x0)
41
42 /*
43 * OCTOSPIM CR register bitfields
44 */
45
46 #define _OCTOSPIM_CR_MUXEN BIT(0)
47 #define _OCTOSPIM_CR_MUXEN_MODE_MASK GENMASK_32(1, 0)
48 #define _OCTOSPIM_CR_CSSEL_OVR_EN BIT(4)
49 #define _OCTOSPIM_CR_CSSEL_OVR_MASK GENMASK_32(6, 4)
50 #define _OCTOSPIM_CR_CSSEL_OVR_SHIFT U(5)
51 #define _OCTOSPIM_CR_REQ2ACK_MASK GENMASK_32(23, 16)
52 #define _OCTOSPIM_CR_REQ2ACK_SHIFT U(16)
53
54 #define OSPI_NB U(2)
55 #define OSPIM_NSEC_PER_SEC UL(1000000000)
56 #define OSPI_NB_RESET U(2)
57 #define OSPI_TIMEOUT_US_1MS U(1000)
58 #define OSPI_RESET_DELAY U(2)
59
60 #define OMM_CS_OVERRIDE_DISABLE U(0xff)
61
62 struct stm32_mm_region {
63 paddr_t start;
64 paddr_t end;
65 };
66
67 struct stm32_ospi_pdata {
68 struct clk *clock;
69 struct rstctrl *reset[OSPI_NB_RESET];
70 struct stm32_mm_region region;
71 };
72
73 struct stm32_omm_pdata {
74 struct clk *clock;
75 struct pinctrl_state *pinctrl_d;
76 struct pinctrl_state *pinctrl_s;
77 struct stm32_ospi_pdata ospi_d[OSPI_NB];
78 struct stm32_mm_region region;
79 vaddr_t base;
80 uint32_t mux;
81 uint32_t cssel_ovr;
82 uint32_t req2ack;
83 };
84
85 static struct stm32_omm_pdata *omm_d;
86
stm32_omm_parse_fdt(const void * fdt,int node)87 static TEE_Result stm32_omm_parse_fdt(const void *fdt, int node)
88 {
89 struct stm32_ospi_pdata *ospi_d = NULL;
90 size_t size = DT_INFO_INVALID_REG_SIZE;
91 TEE_Result res = TEE_ERROR_GENERIC;
92 paddr_t base = DT_INFO_INVALID_REG;
93 const fdt32_t *cuint = NULL;
94 struct io_pa_va addr = { };
95 uint8_t ospi_assigned = 0;
96 unsigned int reset_i = 0;
97 uint32_t ospi_i = 0;
98 unsigned int i = 0;
99 int ctrl_node = 0;
100 int len = 0;
101
102 if (fdt_get_reg_props_by_name(fdt, node, "regs", &base, &size) < 0)
103 panic();
104
105 addr.pa = base;
106 omm_d->base = io_pa_or_va(&addr, size);
107
108 if (fdt_get_reg_props_by_name(fdt, node, "memory_map", &base, &size) <
109 0)
110 panic();
111
112 omm_d->region.start = base;
113 omm_d->region.end = base + size;
114 if (size)
115 omm_d->region.end--;
116
117 res = clk_dt_get_by_index(fdt, node, 0, &omm_d->clock);
118 if (res)
119 return res;
120
121 res = pinctrl_get_state_by_name(fdt, node, "default",
122 &omm_d->pinctrl_d);
123 if (res && res != TEE_ERROR_ITEM_NOT_FOUND)
124 return res;
125
126 res = pinctrl_get_state_by_name(fdt, node, "sleep",
127 &omm_d->pinctrl_s);
128 if (res && res != TEE_ERROR_ITEM_NOT_FOUND)
129 return res;
130
131 omm_d->mux = fdt_read_uint32_default(fdt, node, "st,omm-mux", 0);
132 omm_d->req2ack = fdt_read_uint32_default(fdt, node,
133 "st,omm-req2ack-ns", 0);
134 omm_d->cssel_ovr = fdt_read_uint32_default(fdt, node,
135 "st,omm-cssel-ovr",
136 OMM_CS_OVERRIDE_DISABLE);
137
138 cuint = fdt_getprop(fdt, node, "memory-region", &len);
139 if (cuint) {
140 const char *mm_name[OSPI_NB] = { "mm_ospi1", "mm_ospi2" };
141 struct stm32_mm_region *region = NULL;
142 uint32_t offset = 0;
143 int pnode = 0;
144 int index = 0;
145
146 for (i = 0; i < OSPI_NB; i++) {
147 index = fdt_stringlist_search(fdt, node,
148 "memory-region-names",
149 mm_name[i]);
150 if (index < 0)
151 continue;
152
153 if (index >= (int)(len / sizeof(uint32_t)))
154 panic();
155
156 offset = fdt32_to_cpu(*(cuint + index));
157 pnode = fdt_node_offset_by_phandle(fdt, offset);
158 if (pnode < 0)
159 panic();
160
161 region = &omm_d->ospi_d[i].region;
162 if (fdt_reg_info(fdt, pnode, ®ion->start, &size) < 0)
163 panic();
164
165 region->end = region->start + size;
166 if (size)
167 region->end--;
168 }
169 }
170
171 fdt_for_each_subnode(ctrl_node, fdt, node)
172 ospi_i++;
173
174 if (ospi_i != OSPI_NB)
175 panic();
176
177 fdt_for_each_subnode(ctrl_node, fdt, node) {
178 cuint = fdt_getprop(fdt, ctrl_node, "reg", NULL);
179 if (!cuint)
180 panic();
181
182 ospi_i = fdt32_to_cpu(*cuint);
183 if (ospi_i >= OSPI_NB || (ospi_assigned & BIT(ospi_i)))
184 panic();
185
186 ospi_d = &omm_d->ospi_d[ospi_i];
187 ospi_assigned |= BIT(ospi_i);
188
189 res = clk_dt_get_by_index(fdt, ctrl_node, 0, &ospi_d->clock);
190 if (res)
191 return res;
192
193 for (reset_i = 0; reset_i < OSPI_NB_RESET; reset_i++) {
194 res = rstctrl_dt_get_by_index(fdt, ctrl_node, reset_i,
195 &ospi_d->reset[reset_i]);
196 if (res)
197 return res;
198 }
199 }
200
201 return res;
202 }
203
stm32_omm_region_contains(struct stm32_mm_region * r1,struct stm32_mm_region * r2)204 static bool stm32_omm_region_contains(struct stm32_mm_region *r1,
205 struct stm32_mm_region *r2)
206 {
207 return r1->start <= r2->start && r1->end >= r2->end;
208 }
209
stm32_omm_region_overlaps(struct stm32_mm_region * r1,struct stm32_mm_region * r2)210 static bool stm32_omm_region_overlaps(struct stm32_mm_region *r1,
211 struct stm32_mm_region *r2)
212 {
213 return r1->start <= r2->end && r1->end >= r2->start;
214 }
215
stm32_omm_set_mm(void)216 static void stm32_omm_set_mm(void)
217 {
218 struct stm32_mm_region *region[OSPI_NB] = { };
219 unsigned int valid_regions = 0;
220 size_t mm_size[OSPI_NB] = { };
221 unsigned int ospi_i = 0;
222
223 for (ospi_i = 0; ospi_i < OSPI_NB; ospi_i++) {
224 region[ospi_i] = &omm_d->ospi_d[ospi_i].region;
225
226 if (region[ospi_i]->start >= region[ospi_i]->end)
227 continue;
228
229 if (!stm32_omm_region_contains(&omm_d->region, region[ospi_i]))
230 panic();
231
232 mm_size[ospi_i] = region[ospi_i]->end - region[ospi_i]->start
233 + 1;
234 valid_regions++;
235 }
236
237 if (valid_regions == OSPI_NB &&
238 stm32_omm_region_overlaps(region[0], region[1]))
239 panic();
240
241 if (valid_regions)
242 stm32mp25_syscfg_set_amcr(mm_size[0], mm_size[1]);
243 }
244
stm32_omm_configure(void)245 static void stm32_omm_configure(void)
246 {
247 struct stm32_ospi_pdata *ospi_d = NULL;
248 unsigned long clk_rate_max = 0;
249 unsigned int reset_i = 0;
250 unsigned int ospi_i = 0;
251 uint32_t cssel_ovr = 0;
252 uint32_t req2ack = 0;
253
254 for (ospi_i = 0; ospi_i < OSPI_NB; ospi_i++) {
255 ospi_d = &omm_d->ospi_d[ospi_i];
256 clk_rate_max = MAX(clk_get_rate(ospi_d->clock), clk_rate_max);
257
258 if (clk_enable(ospi_d->clock))
259 panic();
260
261 for (reset_i = 0; reset_i < OSPI_NB_RESET; reset_i++) {
262 if (rstctrl_assert_to(ospi_d->reset[reset_i],
263 OSPI_TIMEOUT_US_1MS))
264 panic();
265 }
266
267 udelay(OSPI_RESET_DELAY);
268
269 for (reset_i = 0; reset_i < OSPI_NB_RESET; reset_i++) {
270 if (rstctrl_deassert_to(ospi_d->reset[reset_i],
271 OSPI_TIMEOUT_US_1MS))
272 panic();
273 }
274
275 clk_disable(ospi_d->clock);
276 }
277
278 if (omm_d->mux & _OCTOSPIM_CR_MUXEN && omm_d->req2ack) {
279 unsigned long hclkn = OSPIM_NSEC_PER_SEC / clk_rate_max;
280 unsigned long timing = DIV_ROUND_UP(omm_d->req2ack, hclkn) - 1;
281
282 if (timing >
283 _OCTOSPIM_CR_REQ2ACK_MASK >> _OCTOSPIM_CR_REQ2ACK_SHIFT)
284 req2ack = _OCTOSPIM_CR_REQ2ACK_MASK;
285 else
286 req2ack = timing << _OCTOSPIM_CR_REQ2ACK_SHIFT;
287 }
288
289 if (omm_d->cssel_ovr != OMM_CS_OVERRIDE_DISABLE)
290 cssel_ovr = (omm_d->cssel_ovr << _OCTOSPIM_CR_CSSEL_OVR_SHIFT) |
291 _OCTOSPIM_CR_CSSEL_OVR_EN;
292
293 if (clk_enable(omm_d->clock))
294 panic();
295
296 io_clrsetbits32(omm_d->base + _OCTOSPIM_CR,
297 _OCTOSPIM_CR_REQ2ACK_MASK |
298 _OCTOSPIM_CR_CSSEL_OVR_MASK |
299 _OCTOSPIM_CR_MUXEN_MODE_MASK,
300 req2ack | cssel_ovr | omm_d->mux);
301
302 clk_disable(omm_d->clock);
303
304 if (omm_d->mux & _OCTOSPIM_CR_MUXEN) {
305 /*
306 * If the mux is enabled, the 2 OSPI clocks have to be
307 * always enabled
308 */
309 for (ospi_i = 0; ospi_i < OSPI_NB; ospi_i++) {
310 ospi_d = &omm_d->ospi_d[ospi_i];
311
312 if (clk_enable(ospi_d->clock))
313 panic();
314 }
315 }
316 }
317
stm32_omm_setup(void)318 static void stm32_omm_setup(void)
319 {
320 stm32_omm_set_mm();
321 stm32_omm_configure();
322 if (omm_d->pinctrl_d && pinctrl_apply_state(omm_d->pinctrl_d))
323 panic();
324 }
325
stm32_omm_suspend(void)326 static void stm32_omm_suspend(void)
327 {
328 if (omm_d->pinctrl_s && pinctrl_apply_state(omm_d->pinctrl_s))
329 panic();
330 }
331
332 static TEE_Result
stm32_omm_pm(enum pm_op op,unsigned int pm_hint,const struct pm_callback_handle * pm_handle __unused)333 stm32_omm_pm(enum pm_op op, unsigned int pm_hint,
334 const struct pm_callback_handle *pm_handle __unused)
335 {
336 if (!PM_HINT_IS_STATE(pm_hint, CONTEXT))
337 return TEE_SUCCESS;
338
339 if (op == PM_OP_RESUME)
340 stm32_omm_setup();
341 else
342 stm32_omm_suspend();
343
344 return TEE_SUCCESS;
345 }
346
stm32_omm_probe(const void * fdt,int node,const void * compat_data __unused)347 static TEE_Result stm32_omm_probe(const void *fdt, int node,
348 const void *compat_data __unused)
349 {
350 TEE_Result res = TEE_ERROR_GENERIC;
351
352 omm_d = calloc(1, sizeof(*omm_d));
353 if (!omm_d)
354 return TEE_ERROR_OUT_OF_MEMORY;
355
356 res = stm32_omm_parse_fdt(fdt, node);
357 if (res)
358 goto err_free;
359
360 stm32_omm_setup();
361
362 register_pm_core_service_cb(stm32_omm_pm, NULL, "stm32-omm");
363
364 return TEE_SUCCESS;
365
366 err_free:
367 free(omm_d);
368
369 return res;
370 }
371
372 static const struct dt_device_match stm32_omm_match_table[] = {
373 { .compatible = "st,stm32mp25-omm" },
374 { }
375 };
376
377 DEFINE_DT_DRIVER(stm32_omm_dt_driver) = {
378 .name = "stm32_omm",
379 .match_table = stm32_omm_match_table,
380 .probe = stm32_omm_probe,
381 };
382