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