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