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 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 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 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 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 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 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 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 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 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