1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2022-2024, 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/stm32_gpio.h> 11 #include <drivers/stm32_rif.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_util.h> 24 #include <trace.h> 25 26 #define _HPDMA_SECCFGR U(0x000) 27 #define _HPDMA_PRIVCFGR U(0x004) 28 #define _HPDMA_RCFGLOCKR U(0x008) 29 #define _HPDMA_CIDCFGR(x) (U(0x054) + U(0x080) * (x)) 30 #define _HPDMA_SEMCR(x) (U(0x058) + U(0x080) * (x)) 31 32 /* 33 * CFGR register bitfields 34 */ 35 #define _HPDMA_CFGR_ENABLE BIT(31) 36 37 /* 38 * CIDCFGR register bitfields 39 */ 40 #define _HPDMA_CIDCFGR_SEMWL_MASK GENMASK_32(23, 16) 41 #define _HPDMA_CIDCFGR_SEMWL_SHIFT U(16) 42 #define _HPDMA_CIDCFGR_SCID_MASK GENMASK_32(5, 4) 43 #define _HPDMA_CIDCFGR_SCID_SHIFT U(4) 44 #define _HPDMA_CIDCFGR_CONF_MASK (_CIDCFGR_CFEN | \ 45 _CIDCFGR_SEMEN | \ 46 _HPDMA_CIDCFGR_SCID_MASK |\ 47 _HPDMA_CIDCFGR_SEMWL_MASK) 48 49 /* 50 * PRIVCFGR register bitfields 51 */ 52 #define _HPDMA_PRIVCFGR_MASK GENMASK_32(15, 0) 53 54 /* 55 * RCFGLOCKR register bitfields 56 */ 57 #define _HPDMA_RCFGLOCKR_MASK GENMASK_32(15, 0) 58 59 /* 60 * SECCFGR register bitfields 61 */ 62 #define _HPDMA_SECCFGR_EN BIT(0) 63 #define _HPDMA_SECCFGR_MASK GENMASK_32(15, 0) 64 65 /* 66 * SEMCR register bitfields 67 */ 68 #define _HPDMA_SEMCR_SCID_MASK GENMASK_32(5, 4) 69 #define _HPDMA_SEMCR_SCID_SHIFT U(4) 70 71 /* 72 * Miscellaneous 73 */ 74 75 #define HPDMA_RIF_CHANNELS U(16) 76 77 #define HPDMA_NB_MAX_CID_SUPPORTED U(3) 78 79 struct hpdma_pdata { 80 struct clk *hpdma_clock; 81 struct rif_conf_data *conf_data; 82 unsigned int nb_channels; 83 vaddr_t base; 84 bool errata_ahbrisab; 85 86 SLIST_ENTRY(hpdma_pdata) link; 87 }; 88 89 static SLIST_HEAD(, hpdma_pdata) hpdma_list = 90 SLIST_HEAD_INITIALIZER(hpdma_list); 91 92 static TEE_Result handle_available_semaphores(struct hpdma_pdata *hpdma_d) 93 { 94 TEE_Result res = TEE_ERROR_GENERIC; 95 uint32_t cidcfgr = 0; 96 unsigned int i = 0; 97 98 for (i = 0; i < HPDMA_RIF_CHANNELS; i++) { 99 if (!(BIT(i) & hpdma_d->conf_data->access_mask[0])) 100 continue; 101 102 cidcfgr = io_read32(hpdma_d->base + _HPDMA_CIDCFGR(i)); 103 104 if (!stm32_rif_semaphore_enabled_and_ok(cidcfgr, RIF_CID1)) 105 continue; 106 107 if (!(io_read32(hpdma_d->base + _HPDMA_SECCFGR) & BIT(i))) { 108 res = 109 stm32_rif_release_semaphore(hpdma_d->base + 110 _HPDMA_SEMCR(i), 111 HPDMA_NB_MAX_CID_SUPPORTED); 112 if (res) { 113 EMSG("Cannot release semaphore for resource %u", 114 i); 115 return res; 116 } 117 } else { 118 res = 119 stm32_rif_acquire_semaphore(hpdma_d->base + 120 _HPDMA_SEMCR(i), 121 HPDMA_NB_MAX_CID_SUPPORTED); 122 if (res) { 123 EMSG("Cannot acquire semaphore for resource %u", 124 i); 125 return res; 126 } 127 } 128 } 129 130 return TEE_SUCCESS; 131 } 132 133 /* This function expects HPDMA bus clock is enabled */ 134 static TEE_Result apply_rif_config(struct hpdma_pdata *hpdma_d, bool is_tdcid) 135 { 136 TEE_Result res = TEE_ERROR_ACCESS_DENIED; 137 unsigned int i = 0; 138 139 if (!hpdma_d->conf_data) 140 return TEE_SUCCESS; 141 142 if (is_tdcid) { 143 for (i = 0; i < HPDMA_RIF_CHANNELS; i++) { 144 if (!(BIT(i) & hpdma_d->conf_data->access_mask[0])) 145 continue; 146 /* 147 * When TDCID, OP-TEE should be the one to set the CID 148 * filtering configuration. Clearing previous 149 * configuration prevents undesired events during the 150 * only legitimate configuration. 151 */ 152 io_clrbits32(hpdma_d->base + _HPDMA_CIDCFGR(i), 153 _HPDMA_CIDCFGR_CONF_MASK); 154 } 155 } else { 156 res = handle_available_semaphores(hpdma_d); 157 if (res) 158 panic(); 159 } 160 161 /* Security and privilege RIF configuration */ 162 io_clrsetbits32(hpdma_d->base + _HPDMA_PRIVCFGR, _HPDMA_PRIVCFGR_MASK & 163 hpdma_d->conf_data->access_mask[0], 164 hpdma_d->conf_data->priv_conf[0]); 165 io_clrsetbits32(hpdma_d->base + _HPDMA_SECCFGR, _HPDMA_SECCFGR_MASK & 166 hpdma_d->conf_data->access_mask[0], 167 hpdma_d->conf_data->sec_conf[0]); 168 169 /* Skip CID/semaphore configuration if not in TDCID state. */ 170 if (!is_tdcid) 171 goto end; 172 173 for (i = 0; i < HPDMA_RIF_CHANNELS; i++) { 174 uint32_t cid_conf = hpdma_d->conf_data->cid_confs[i]; 175 176 if (!(BIT(i) & hpdma_d->conf_data->access_mask[0])) 177 continue; 178 179 /* 180 * Errata: When CID filtering is enabled on one of RISAB 3/4/5 181 * instances, we forbid the use of CID0 for any initiator on the 182 * bus to handle transient CID0 transactions on these RAMs. 183 */ 184 if (hpdma_d->errata_ahbrisab && 185 (!(cid_conf & _CIDCFGR_CFEN) || 186 (!(cid_conf & _CIDCFGR_SEMEN) && 187 ((cid_conf & _HPDMA_CIDCFGR_SCID_MASK) >> 188 _HPDMA_CIDCFGR_SCID_SHIFT) == RIF_CID0) || 189 (cid_conf & _CIDCFGR_SEMEN && 190 cid_conf & BIT(RIF_CID0 + _HPDMA_CIDCFGR_SEMWL_SHIFT)))) { 191 EMSG("HPDMA channel cannot hold CID0 value"); 192 if (!IS_ENABLED(CFG_INSECURE)) 193 panic(); 194 } 195 196 io_clrsetbits32(hpdma_d->base + _HPDMA_CIDCFGR(i), 197 _HPDMA_CIDCFGR_CONF_MASK, cid_conf); 198 } 199 200 /* 201 * Lock RIF configuration if configured. This cannot be undone until 202 * next reset. 203 */ 204 io_setbits32(hpdma_d->base + _HPDMA_RCFGLOCKR, 205 hpdma_d->conf_data->lock_conf[0]); 206 207 res = handle_available_semaphores(hpdma_d); 208 if (res) 209 panic(); 210 211 end: 212 if (IS_ENABLED(CFG_TEE_CORE_DEBUG)) { 213 /* Check that RIF config are applied, panic otherwise */ 214 if ((io_read32(hpdma_d->base + _HPDMA_PRIVCFGR) & 215 hpdma_d->conf_data->access_mask[0]) != 216 hpdma_d->conf_data->priv_conf[0]) 217 panic("HPDMA channel priv conf is incorrect"); 218 219 if ((io_read32(hpdma_d->base + _HPDMA_SECCFGR) & 220 hpdma_d->conf_data->access_mask[0]) != 221 hpdma_d->conf_data->sec_conf[0]) 222 panic("HPDMA channel sec conf is incorrect"); 223 } 224 225 return TEE_SUCCESS; 226 } 227 228 static TEE_Result parse_dt(const void *fdt, int node, 229 struct hpdma_pdata *hpdma_d) 230 { 231 TEE_Result res = TEE_ERROR_GENERIC; 232 unsigned int i = 0; 233 int lenp = 0; 234 const fdt32_t *cuint = NULL; 235 struct dt_node_info info = { }; 236 struct io_pa_va addr = { }; 237 238 fdt_fill_device_info(fdt, &info, node); 239 assert(info.reg != DT_INFO_INVALID_REG && 240 info.reg_size != DT_INFO_INVALID_REG_SIZE); 241 242 addr.pa = info.reg; 243 hpdma_d->base = io_pa_or_va_secure(&addr, info.reg_size); 244 245 /* Gate the IP */ 246 res = clk_dt_get_by_index(fdt, node, 0, &hpdma_d->hpdma_clock); 247 if (res) 248 return res; 249 250 hpdma_d->errata_ahbrisab = fdt_getprop(fdt, node, "st,errata-ahbrisab", 251 NULL); 252 253 cuint = fdt_getprop(fdt, node, "st,protreg", &lenp); 254 if (!cuint) { 255 DMSG("No RIF configuration available"); 256 return TEE_SUCCESS; 257 } 258 259 hpdma_d->conf_data = calloc(1, sizeof(*hpdma_d->conf_data)); 260 if (!hpdma_d->conf_data) 261 panic(); 262 263 hpdma_d->nb_channels = (unsigned int)(lenp / sizeof(uint32_t)); 264 assert(hpdma_d->nb_channels <= HPDMA_RIF_CHANNELS); 265 266 hpdma_d->conf_data->cid_confs = calloc(HPDMA_RIF_CHANNELS, 267 sizeof(uint32_t)); 268 hpdma_d->conf_data->sec_conf = calloc(1, sizeof(uint32_t)); 269 hpdma_d->conf_data->priv_conf = calloc(1, sizeof(uint32_t)); 270 hpdma_d->conf_data->access_mask = calloc(1, sizeof(uint32_t)); 271 hpdma_d->conf_data->lock_conf = calloc(1, sizeof(uint32_t)); 272 if (!hpdma_d->conf_data->cid_confs || !hpdma_d->conf_data->sec_conf || 273 !hpdma_d->conf_data->priv_conf || 274 !hpdma_d->conf_data->access_mask || !hpdma_d->conf_data->lock_conf) 275 panic("Missing memory capacity for HPDMA RIF configuration"); 276 277 for (i = 0; i < hpdma_d->nb_channels; i++) 278 stm32_rif_parse_cfg(fdt32_to_cpu(cuint[i]), hpdma_d->conf_data, 279 HPDMA_RIF_CHANNELS); 280 281 return TEE_SUCCESS; 282 } 283 284 static void stm32_hpdma_pm_resume(struct hpdma_pdata *hpdma) 285 { 286 if (apply_rif_config(hpdma, true)) 287 panic("Failed to resume HPDMA"); 288 } 289 290 static void stm32_hpdma_pm_suspend(struct hpdma_pdata *hpdma) 291 { 292 size_t i = 0; 293 294 for (i = 0; i < HPDMA_RIF_CHANNELS; i++) 295 hpdma->conf_data->cid_confs[i] = io_read32(hpdma->base + 296 _HPDMA_CIDCFGR(i)) & 297 _HPDMA_CIDCFGR_CONF_MASK; 298 299 hpdma->conf_data->priv_conf[0] = io_read32(hpdma->base + 300 _HPDMA_PRIVCFGR) & 301 _HPDMA_PRIVCFGR_MASK; 302 hpdma->conf_data->sec_conf[0] = io_read32(hpdma->base + 303 _HPDMA_SECCFGR) & 304 _HPDMA_SECCFGR_MASK; 305 hpdma->conf_data->lock_conf[0] = io_read32(hpdma->base + 306 _HPDMA_RCFGLOCKR) & 307 _HPDMA_RCFGLOCKR_MASK; 308 309 /* 310 * The access mask is modified to restore the conf for all 311 * resources. 312 */ 313 hpdma->conf_data->access_mask[0] = GENMASK_32(HPDMA_RIF_CHANNELS - 1, 314 0); 315 } 316 317 static TEE_Result 318 stm32_hpdma_pm(enum pm_op op, unsigned int pm_hint, 319 const struct pm_callback_handle *pm_handle) 320 { 321 struct hpdma_pdata *hpdma = pm_handle->handle; 322 TEE_Result res = TEE_ERROR_GENERIC; 323 bool is_tdcid = false; 324 325 res = stm32_rifsc_check_tdcid(&is_tdcid); 326 if (res) 327 panic(); 328 329 if (!PM_HINT_IS_STATE(pm_hint, CONTEXT) || !is_tdcid) 330 return TEE_SUCCESS; 331 332 res = clk_enable(hpdma->hpdma_clock); 333 if (res) 334 return res; 335 336 if (op == PM_OP_RESUME) 337 stm32_hpdma_pm_resume(hpdma); 338 else 339 stm32_hpdma_pm_suspend(hpdma); 340 341 clk_disable(hpdma->hpdma_clock); 342 343 return TEE_SUCCESS; 344 } 345 346 static TEE_Result stm32_hpdma_probe(const void *fdt, int node, 347 const void *compat_data __unused) 348 { 349 TEE_Result res = TEE_ERROR_GENERIC; 350 struct hpdma_pdata *hpdma_d = NULL; 351 bool is_tdcid = false; 352 353 res = stm32_rifsc_check_tdcid(&is_tdcid); 354 if (res) 355 return res; 356 357 hpdma_d = calloc(1, sizeof(*hpdma_d)); 358 if (!hpdma_d) 359 return TEE_ERROR_OUT_OF_MEMORY; 360 361 res = parse_dt(fdt, node, hpdma_d); 362 if (res) { 363 free(hpdma_d); 364 return res; 365 } 366 367 if (clk_enable(hpdma_d->hpdma_clock)) 368 panic("Cannot access hpdma clock"); 369 370 res = apply_rif_config(hpdma_d, is_tdcid); 371 if (res) 372 panic("Failed to apply RIF config"); 373 374 clk_disable(hpdma_d->hpdma_clock); 375 376 SLIST_INSERT_HEAD(&hpdma_list, hpdma_d, link); 377 378 register_pm_core_service_cb(stm32_hpdma_pm, hpdma_d, "stm32-hpdma"); 379 380 return TEE_SUCCESS; 381 } 382 383 static const struct dt_device_match stm32_hpdma_match_table[] = { 384 { .compatible = "st,stm32-dma3" }, 385 { } 386 }; 387 388 DEFINE_DT_DRIVER(stm32_hpdma_dt_driver) = { 389 .name = "st,stm32-hpdma", 390 .match_table = stm32_hpdma_match_table, 391 .probe = stm32_hpdma_probe, 392 }; 393