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