10cf1cd13SGatien Chevallier // SPDX-License-Identifier: BSD-2-Clause 20cf1cd13SGatien Chevallier /* 30cf1cd13SGatien Chevallier * Copyright (c) 2022-2024, STMicroelectronics 40cf1cd13SGatien Chevallier */ 50cf1cd13SGatien Chevallier 60cf1cd13SGatien Chevallier #include <arm.h> 70cf1cd13SGatien Chevallier #include <config.h> 80cf1cd13SGatien Chevallier #include <drivers/clk.h> 90cf1cd13SGatien Chevallier #include <drivers/clk_dt.h> 100cf1cd13SGatien Chevallier #include <drivers/stm32_gpio.h> 110cf1cd13SGatien Chevallier #include <drivers/stm32_rif.h> 120cf1cd13SGatien Chevallier #include <io.h> 130cf1cd13SGatien Chevallier #include <kernel/boot.h> 140cf1cd13SGatien Chevallier #include <kernel/delay.h> 150cf1cd13SGatien Chevallier #include <kernel/dt.h> 160cf1cd13SGatien Chevallier #include <kernel/dt_driver.h> 170cf1cd13SGatien Chevallier #include <kernel/panic.h> 180cf1cd13SGatien Chevallier #include <kernel/pm.h> 190cf1cd13SGatien Chevallier #include <libfdt.h> 200cf1cd13SGatien Chevallier #include <mm/core_memprot.h> 210cf1cd13SGatien Chevallier #include <stdbool.h> 220cf1cd13SGatien Chevallier #include <stdlib.h> 230cf1cd13SGatien Chevallier #include <stm32_util.h> 240cf1cd13SGatien Chevallier #include <trace.h> 250cf1cd13SGatien Chevallier 260cf1cd13SGatien Chevallier #define _HPDMA_SECCFGR U(0x000) 270cf1cd13SGatien Chevallier #define _HPDMA_PRIVCFGR U(0x004) 280cf1cd13SGatien Chevallier #define _HPDMA_RCFGLOCKR U(0x008) 290cf1cd13SGatien Chevallier #define _HPDMA_CIDCFGR(x) (U(0x054) + U(0x080) * (x)) 300cf1cd13SGatien Chevallier #define _HPDMA_SEMCR(x) (U(0x058) + U(0x080) * (x)) 310cf1cd13SGatien Chevallier 320cf1cd13SGatien Chevallier /* 330cf1cd13SGatien Chevallier * CFGR register bitfields 340cf1cd13SGatien Chevallier */ 350cf1cd13SGatien Chevallier #define _HPDMA_CFGR_ENABLE BIT(31) 360cf1cd13SGatien Chevallier 370cf1cd13SGatien Chevallier /* 380cf1cd13SGatien Chevallier * CIDCFGR register bitfields 390cf1cd13SGatien Chevallier */ 400cf1cd13SGatien Chevallier #define _HPDMA_CIDCFGR_SEMWL_MASK GENMASK_32(23, 16) 410cf1cd13SGatien Chevallier #define _HPDMA_CIDCFGR_SCID_MASK GENMASK_32(5, 4) 420cf1cd13SGatien Chevallier #define _HPDMA_CIDCFGR_CONF_MASK (_CIDCFGR_CFEN | \ 430cf1cd13SGatien Chevallier _CIDCFGR_SEMEN | \ 440cf1cd13SGatien Chevallier _HPDMA_CIDCFGR_SCID_MASK |\ 450cf1cd13SGatien Chevallier _HPDMA_CIDCFGR_SEMWL_MASK) 460cf1cd13SGatien Chevallier 470cf1cd13SGatien Chevallier /* 480cf1cd13SGatien Chevallier * PRIVCFGR register bitfields 490cf1cd13SGatien Chevallier */ 500cf1cd13SGatien Chevallier #define _HPDMA_PRIVCFGR_MASK GENMASK_32(15, 0) 510cf1cd13SGatien Chevallier 520cf1cd13SGatien Chevallier /* 530cf1cd13SGatien Chevallier * RCFGLOCKR register bitfields 540cf1cd13SGatien Chevallier */ 550cf1cd13SGatien Chevallier #define _HPDMA_RCFGLOCKR_MASK GENMASK_32(15, 0) 560cf1cd13SGatien Chevallier 570cf1cd13SGatien Chevallier /* 580cf1cd13SGatien Chevallier * SECCFGR register bitfields 590cf1cd13SGatien Chevallier */ 600cf1cd13SGatien Chevallier #define _HPDMA_SECCFGR_EN BIT(0) 610cf1cd13SGatien Chevallier #define _HPDMA_SECCFGR_MASK GENMASK_32(15, 0) 620cf1cd13SGatien Chevallier 630cf1cd13SGatien Chevallier /* 640cf1cd13SGatien Chevallier * SEMCR register bitfields 650cf1cd13SGatien Chevallier */ 660cf1cd13SGatien Chevallier #define _HPDMA_SEMCR_SCID_MASK GENMASK_32(5, 4) 670cf1cd13SGatien Chevallier #define _HPDMA_SEMCR_SCID_SHIFT U(4) 680cf1cd13SGatien Chevallier 690cf1cd13SGatien Chevallier /* 700cf1cd13SGatien Chevallier * Miscellaneous 710cf1cd13SGatien Chevallier */ 720cf1cd13SGatien Chevallier 730cf1cd13SGatien Chevallier #define HPDMA_RIF_CHANNELS U(16) 740cf1cd13SGatien Chevallier 750cf1cd13SGatien Chevallier #define HPDMA_NB_MAX_CID_SUPPORTED U(3) 760cf1cd13SGatien Chevallier 770cf1cd13SGatien Chevallier struct hpdma_pdata { 780cf1cd13SGatien Chevallier struct clk *hpdma_clock; 79307d268bSGatien Chevallier struct rif_conf_data *conf_data; 800cf1cd13SGatien Chevallier unsigned int nb_channels; 810cf1cd13SGatien Chevallier vaddr_t base; 820cf1cd13SGatien Chevallier 830cf1cd13SGatien Chevallier SLIST_ENTRY(hpdma_pdata) link; 840cf1cd13SGatien Chevallier }; 850cf1cd13SGatien Chevallier 860cf1cd13SGatien Chevallier static SLIST_HEAD(, hpdma_pdata) hpdma_list = 870cf1cd13SGatien Chevallier SLIST_HEAD_INITIALIZER(hpdma_list); 880cf1cd13SGatien Chevallier 89*5c2c026aSGatien Chevallier static TEE_Result handle_available_semaphores(struct hpdma_pdata *hpdma_d) 90*5c2c026aSGatien Chevallier { 91*5c2c026aSGatien Chevallier TEE_Result res = TEE_ERROR_GENERIC; 92*5c2c026aSGatien Chevallier uint32_t cidcfgr = 0; 93*5c2c026aSGatien Chevallier unsigned int i = 0; 94*5c2c026aSGatien Chevallier 95*5c2c026aSGatien Chevallier for (i = 0; i < HPDMA_RIF_CHANNELS; i++) { 96*5c2c026aSGatien Chevallier if (!(BIT(i) & hpdma_d->conf_data->access_mask[0])) 97*5c2c026aSGatien Chevallier continue; 98*5c2c026aSGatien Chevallier 99*5c2c026aSGatien Chevallier cidcfgr = io_read32(hpdma_d->base + _HPDMA_CIDCFGR(i)); 100*5c2c026aSGatien Chevallier 101*5c2c026aSGatien Chevallier if (!stm32_rif_semaphore_enabled_and_ok(cidcfgr, RIF_CID1)) 102*5c2c026aSGatien Chevallier continue; 103*5c2c026aSGatien Chevallier 104*5c2c026aSGatien Chevallier if (!(io_read32(hpdma_d->base + _HPDMA_SECCFGR) & BIT(i))) { 105*5c2c026aSGatien Chevallier res = 106*5c2c026aSGatien Chevallier stm32_rif_release_semaphore(hpdma_d->base + 107*5c2c026aSGatien Chevallier _HPDMA_SEMCR(i), 108*5c2c026aSGatien Chevallier HPDMA_NB_MAX_CID_SUPPORTED); 109*5c2c026aSGatien Chevallier if (res) { 110*5c2c026aSGatien Chevallier EMSG("Cannot release semaphore for resource %u", 111*5c2c026aSGatien Chevallier i); 112*5c2c026aSGatien Chevallier return res; 113*5c2c026aSGatien Chevallier } 114*5c2c026aSGatien Chevallier } else { 115*5c2c026aSGatien Chevallier res = 116*5c2c026aSGatien Chevallier stm32_rif_acquire_semaphore(hpdma_d->base + 117*5c2c026aSGatien Chevallier _HPDMA_SEMCR(i), 118*5c2c026aSGatien Chevallier HPDMA_NB_MAX_CID_SUPPORTED); 119*5c2c026aSGatien Chevallier if (res) { 120*5c2c026aSGatien Chevallier EMSG("Cannot acquire semaphore for resource %u", 121*5c2c026aSGatien Chevallier i); 122*5c2c026aSGatien Chevallier return res; 123*5c2c026aSGatien Chevallier } 124*5c2c026aSGatien Chevallier } 125*5c2c026aSGatien Chevallier } 126*5c2c026aSGatien Chevallier 127*5c2c026aSGatien Chevallier return TEE_SUCCESS; 128*5c2c026aSGatien Chevallier } 129*5c2c026aSGatien Chevallier 1300cf1cd13SGatien Chevallier /* This function expects HPDMA bus clock is enabled */ 1310cf1cd13SGatien Chevallier static TEE_Result apply_rif_config(struct hpdma_pdata *hpdma_d, bool is_tdcid) 1320cf1cd13SGatien Chevallier { 1330cf1cd13SGatien Chevallier TEE_Result res = TEE_ERROR_ACCESS_DENIED; 1340cf1cd13SGatien Chevallier unsigned int i = 0; 1350cf1cd13SGatien Chevallier 136307d268bSGatien Chevallier if (!hpdma_d->conf_data) 137307d268bSGatien Chevallier return TEE_SUCCESS; 138307d268bSGatien Chevallier 139*5c2c026aSGatien Chevallier if (is_tdcid) { 1400cf1cd13SGatien Chevallier for (i = 0; i < HPDMA_RIF_CHANNELS; i++) { 141307d268bSGatien Chevallier if (!(BIT(i) & hpdma_d->conf_data->access_mask[0])) 1420cf1cd13SGatien Chevallier continue; 1430cf1cd13SGatien Chevallier /* 144*5c2c026aSGatien Chevallier * When TDCID, OP-TEE should be the one to set the CID 145*5c2c026aSGatien Chevallier * filtering configuration. Clearing previous 146*5c2c026aSGatien Chevallier * configuration prevents undesired events during the 147*5c2c026aSGatien Chevallier * only legitimate configuration. 1480cf1cd13SGatien Chevallier */ 1490cf1cd13SGatien Chevallier io_clrbits32(hpdma_d->base + _HPDMA_CIDCFGR(i), 1500cf1cd13SGatien Chevallier _HPDMA_CIDCFGR_CONF_MASK); 1510cf1cd13SGatien Chevallier } 152*5c2c026aSGatien Chevallier } else { 153*5c2c026aSGatien Chevallier res = handle_available_semaphores(hpdma_d); 154*5c2c026aSGatien Chevallier if (res) 155*5c2c026aSGatien Chevallier panic(); 1560cf1cd13SGatien Chevallier } 1570cf1cd13SGatien Chevallier 1580cf1cd13SGatien Chevallier /* Security and privilege RIF configuration */ 1590cf1cd13SGatien Chevallier io_clrsetbits32(hpdma_d->base + _HPDMA_PRIVCFGR, _HPDMA_PRIVCFGR_MASK & 160307d268bSGatien Chevallier hpdma_d->conf_data->access_mask[0], 161307d268bSGatien Chevallier hpdma_d->conf_data->priv_conf[0]); 1620cf1cd13SGatien Chevallier io_clrsetbits32(hpdma_d->base + _HPDMA_SECCFGR, _HPDMA_SECCFGR_MASK & 163307d268bSGatien Chevallier hpdma_d->conf_data->access_mask[0], 164307d268bSGatien Chevallier hpdma_d->conf_data->sec_conf[0]); 1650cf1cd13SGatien Chevallier 1660cf1cd13SGatien Chevallier /* Skip CID/semaphore configuration if not in TDCID state. */ 1670cf1cd13SGatien Chevallier if (!is_tdcid) 1680cf1cd13SGatien Chevallier goto end; 1690cf1cd13SGatien Chevallier 1700cf1cd13SGatien Chevallier for (i = 0; i < HPDMA_RIF_CHANNELS; i++) { 171307d268bSGatien Chevallier if (!(BIT(i) & hpdma_d->conf_data->access_mask[0])) 1720cf1cd13SGatien Chevallier continue; 1730cf1cd13SGatien Chevallier 1740cf1cd13SGatien Chevallier io_clrsetbits32(hpdma_d->base + _HPDMA_CIDCFGR(i), 1750cf1cd13SGatien Chevallier _HPDMA_CIDCFGR_CONF_MASK, 176307d268bSGatien Chevallier hpdma_d->conf_data->cid_confs[i]); 1770cf1cd13SGatien Chevallier } 1780cf1cd13SGatien Chevallier 1790cf1cd13SGatien Chevallier /* 1800cf1cd13SGatien Chevallier * Lock RIF configuration if configured. This cannot be undone until 1810cf1cd13SGatien Chevallier * next reset. 1820cf1cd13SGatien Chevallier */ 183*5c2c026aSGatien Chevallier io_setbits32(hpdma_d->base + _HPDMA_RCFGLOCKR, 184307d268bSGatien Chevallier hpdma_d->conf_data->lock_conf[0]); 1850cf1cd13SGatien Chevallier 186*5c2c026aSGatien Chevallier res = handle_available_semaphores(hpdma_d); 187*5c2c026aSGatien Chevallier if (res) 188*5c2c026aSGatien Chevallier panic(); 189*5c2c026aSGatien Chevallier 1900cf1cd13SGatien Chevallier end: 1910cf1cd13SGatien Chevallier if (IS_ENABLED(CFG_TEE_CORE_DEBUG)) { 1920cf1cd13SGatien Chevallier /* Check that RIF config are applied, panic otherwise */ 1930cf1cd13SGatien Chevallier if ((io_read32(hpdma_d->base + _HPDMA_PRIVCFGR) & 194307d268bSGatien Chevallier hpdma_d->conf_data->access_mask[0]) != 195307d268bSGatien Chevallier hpdma_d->conf_data->priv_conf[0]) 1960cf1cd13SGatien Chevallier panic("HPDMA channel priv conf is incorrect"); 1970cf1cd13SGatien Chevallier 1980cf1cd13SGatien Chevallier if ((io_read32(hpdma_d->base + _HPDMA_SECCFGR) & 199307d268bSGatien Chevallier hpdma_d->conf_data->access_mask[0]) != 200307d268bSGatien Chevallier hpdma_d->conf_data->sec_conf[0]) 2010cf1cd13SGatien Chevallier panic("HPDMA channel sec conf is incorrect"); 2020cf1cd13SGatien Chevallier } 2030cf1cd13SGatien Chevallier 2040cf1cd13SGatien Chevallier return TEE_SUCCESS; 2050cf1cd13SGatien Chevallier } 2060cf1cd13SGatien Chevallier 2070cf1cd13SGatien Chevallier static TEE_Result parse_dt(const void *fdt, int node, 2080cf1cd13SGatien Chevallier struct hpdma_pdata *hpdma_d) 2090cf1cd13SGatien Chevallier { 2100cf1cd13SGatien Chevallier TEE_Result res = TEE_ERROR_GENERIC; 2110cf1cd13SGatien Chevallier unsigned int i = 0; 2120cf1cd13SGatien Chevallier int lenp = 0; 2130cf1cd13SGatien Chevallier const fdt32_t *cuint = NULL; 2140cf1cd13SGatien Chevallier struct dt_node_info info = { }; 2150cf1cd13SGatien Chevallier struct io_pa_va addr = { }; 2160cf1cd13SGatien Chevallier 2170cf1cd13SGatien Chevallier fdt_fill_device_info(fdt, &info, node); 2180cf1cd13SGatien Chevallier assert(info.reg != DT_INFO_INVALID_REG && 2190cf1cd13SGatien Chevallier info.reg_size != DT_INFO_INVALID_REG_SIZE); 2200cf1cd13SGatien Chevallier 2210cf1cd13SGatien Chevallier addr.pa = info.reg; 2220cf1cd13SGatien Chevallier hpdma_d->base = io_pa_or_va_secure(&addr, info.reg_size); 2230cf1cd13SGatien Chevallier 2240cf1cd13SGatien Chevallier /* Gate the IP */ 2250cf1cd13SGatien Chevallier res = clk_dt_get_by_index(fdt, node, 0, &hpdma_d->hpdma_clock); 2260cf1cd13SGatien Chevallier if (res) 2270cf1cd13SGatien Chevallier return res; 2280cf1cd13SGatien Chevallier 2290cf1cd13SGatien Chevallier cuint = fdt_getprop(fdt, node, "st,protreg", &lenp); 230307d268bSGatien Chevallier if (!cuint) { 231307d268bSGatien Chevallier DMSG("No RIF configuration available"); 232307d268bSGatien Chevallier return TEE_SUCCESS; 233307d268bSGatien Chevallier } 234307d268bSGatien Chevallier 235307d268bSGatien Chevallier hpdma_d->conf_data = calloc(1, sizeof(*hpdma_d->conf_data)); 236307d268bSGatien Chevallier if (!hpdma_d->conf_data) 237307d268bSGatien Chevallier panic(); 2380cf1cd13SGatien Chevallier 2390cf1cd13SGatien Chevallier hpdma_d->nb_channels = (unsigned int)(lenp / sizeof(uint32_t)); 2400cf1cd13SGatien Chevallier assert(hpdma_d->nb_channels <= HPDMA_RIF_CHANNELS); 2410cf1cd13SGatien Chevallier 242307d268bSGatien Chevallier hpdma_d->conf_data->cid_confs = calloc(HPDMA_RIF_CHANNELS, 2430cf1cd13SGatien Chevallier sizeof(uint32_t)); 244307d268bSGatien Chevallier hpdma_d->conf_data->sec_conf = calloc(1, sizeof(uint32_t)); 245307d268bSGatien Chevallier hpdma_d->conf_data->priv_conf = calloc(1, sizeof(uint32_t)); 246307d268bSGatien Chevallier hpdma_d->conf_data->access_mask = calloc(1, sizeof(uint32_t)); 247307d268bSGatien Chevallier hpdma_d->conf_data->lock_conf = calloc(1, sizeof(uint32_t)); 248307d268bSGatien Chevallier if (!hpdma_d->conf_data->cid_confs || !hpdma_d->conf_data->sec_conf || 249307d268bSGatien Chevallier !hpdma_d->conf_data->priv_conf || 250307d268bSGatien Chevallier !hpdma_d->conf_data->access_mask || !hpdma_d->conf_data->lock_conf) 251307d268bSGatien Chevallier panic("Missing memory capacity for HPDMA RIF configuration"); 2520cf1cd13SGatien Chevallier 2530cf1cd13SGatien Chevallier for (i = 0; i < hpdma_d->nb_channels; i++) 254307d268bSGatien Chevallier stm32_rif_parse_cfg(fdt32_to_cpu(cuint[i]), hpdma_d->conf_data, 2550cf1cd13SGatien Chevallier HPDMA_RIF_CHANNELS); 2560cf1cd13SGatien Chevallier 2570cf1cd13SGatien Chevallier return TEE_SUCCESS; 2580cf1cd13SGatien Chevallier } 2590cf1cd13SGatien Chevallier 2600cf1cd13SGatien Chevallier static void stm32_hpdma_pm_resume(struct hpdma_pdata *hpdma) 2610cf1cd13SGatien Chevallier { 2620cf1cd13SGatien Chevallier if (apply_rif_config(hpdma, true)) 2630cf1cd13SGatien Chevallier panic("Failed to resume HPDMA"); 2640cf1cd13SGatien Chevallier } 2650cf1cd13SGatien Chevallier 2660cf1cd13SGatien Chevallier static void stm32_hpdma_pm_suspend(struct hpdma_pdata *hpdma) 2670cf1cd13SGatien Chevallier { 2680cf1cd13SGatien Chevallier size_t i = 0; 2690cf1cd13SGatien Chevallier 2700cf1cd13SGatien Chevallier for (i = 0; i < HPDMA_RIF_CHANNELS; i++) 271307d268bSGatien Chevallier hpdma->conf_data->cid_confs[i] = io_read32(hpdma->base + 2720cf1cd13SGatien Chevallier _HPDMA_CIDCFGR(i)) & 2730cf1cd13SGatien Chevallier _HPDMA_CIDCFGR_CONF_MASK; 2740cf1cd13SGatien Chevallier 275307d268bSGatien Chevallier hpdma->conf_data->priv_conf[0] = io_read32(hpdma->base + 2760cf1cd13SGatien Chevallier _HPDMA_PRIVCFGR) & 2770cf1cd13SGatien Chevallier _HPDMA_PRIVCFGR_MASK; 278307d268bSGatien Chevallier hpdma->conf_data->sec_conf[0] = io_read32(hpdma->base + 2790cf1cd13SGatien Chevallier _HPDMA_SECCFGR) & 2800cf1cd13SGatien Chevallier _HPDMA_SECCFGR_MASK; 281307d268bSGatien Chevallier hpdma->conf_data->lock_conf[0] = io_read32(hpdma->base + 2820cf1cd13SGatien Chevallier _HPDMA_RCFGLOCKR) & 2830cf1cd13SGatien Chevallier _HPDMA_RCFGLOCKR_MASK; 2840cf1cd13SGatien Chevallier 2850cf1cd13SGatien Chevallier /* 2860cf1cd13SGatien Chevallier * The access mask is modified to restore the conf for all 2870cf1cd13SGatien Chevallier * resources. 2880cf1cd13SGatien Chevallier */ 289307d268bSGatien Chevallier hpdma->conf_data->access_mask[0] = GENMASK_32(HPDMA_RIF_CHANNELS - 1, 290307d268bSGatien Chevallier 0); 2910cf1cd13SGatien Chevallier } 2920cf1cd13SGatien Chevallier 2930cf1cd13SGatien Chevallier static TEE_Result 2940cf1cd13SGatien Chevallier stm32_hpdma_pm(enum pm_op op, unsigned int pm_hint, 2950cf1cd13SGatien Chevallier const struct pm_callback_handle *pm_handle) 2960cf1cd13SGatien Chevallier { 2970cf1cd13SGatien Chevallier struct hpdma_pdata *hpdma = pm_handle->handle; 2980cf1cd13SGatien Chevallier TEE_Result res = TEE_ERROR_GENERIC; 2990cf1cd13SGatien Chevallier bool is_tdcid = false; 3000cf1cd13SGatien Chevallier 3010cf1cd13SGatien Chevallier res = stm32_rifsc_check_tdcid(&is_tdcid); 3020cf1cd13SGatien Chevallier if (res) 3030cf1cd13SGatien Chevallier panic(); 3040cf1cd13SGatien Chevallier 3050cf1cd13SGatien Chevallier if (!PM_HINT_IS_STATE(pm_hint, CONTEXT) || !is_tdcid) 3060cf1cd13SGatien Chevallier return TEE_SUCCESS; 3070cf1cd13SGatien Chevallier 3080cf1cd13SGatien Chevallier res = clk_enable(hpdma->hpdma_clock); 3090cf1cd13SGatien Chevallier if (res) 3100cf1cd13SGatien Chevallier return res; 3110cf1cd13SGatien Chevallier 3120cf1cd13SGatien Chevallier if (op == PM_OP_RESUME) 3130cf1cd13SGatien Chevallier stm32_hpdma_pm_resume(hpdma); 3140cf1cd13SGatien Chevallier else 3150cf1cd13SGatien Chevallier stm32_hpdma_pm_suspend(hpdma); 3160cf1cd13SGatien Chevallier 3170cf1cd13SGatien Chevallier clk_disable(hpdma->hpdma_clock); 3180cf1cd13SGatien Chevallier 3190cf1cd13SGatien Chevallier return TEE_SUCCESS; 3200cf1cd13SGatien Chevallier } 3210cf1cd13SGatien Chevallier 3220cf1cd13SGatien Chevallier static TEE_Result stm32_hpdma_probe(const void *fdt, int node, 3230cf1cd13SGatien Chevallier const void *compat_data __unused) 3240cf1cd13SGatien Chevallier { 3250cf1cd13SGatien Chevallier TEE_Result res = TEE_ERROR_GENERIC; 3260cf1cd13SGatien Chevallier struct hpdma_pdata *hpdma_d = NULL; 3270cf1cd13SGatien Chevallier bool is_tdcid = false; 3280cf1cd13SGatien Chevallier 3290cf1cd13SGatien Chevallier res = stm32_rifsc_check_tdcid(&is_tdcid); 3300cf1cd13SGatien Chevallier if (res) 3310cf1cd13SGatien Chevallier return res; 3320cf1cd13SGatien Chevallier 3330cf1cd13SGatien Chevallier hpdma_d = calloc(1, sizeof(*hpdma_d)); 3340cf1cd13SGatien Chevallier if (!hpdma_d) 3350cf1cd13SGatien Chevallier return TEE_ERROR_OUT_OF_MEMORY; 3360cf1cd13SGatien Chevallier 3370cf1cd13SGatien Chevallier res = parse_dt(fdt, node, hpdma_d); 3380cf1cd13SGatien Chevallier if (res) { 3390cf1cd13SGatien Chevallier free(hpdma_d); 3400cf1cd13SGatien Chevallier return res; 3410cf1cd13SGatien Chevallier } 3420cf1cd13SGatien Chevallier 3430cf1cd13SGatien Chevallier if (clk_enable(hpdma_d->hpdma_clock)) 3440cf1cd13SGatien Chevallier panic("Cannot access hpdma clock"); 3450cf1cd13SGatien Chevallier 3460cf1cd13SGatien Chevallier res = apply_rif_config(hpdma_d, is_tdcid); 3470cf1cd13SGatien Chevallier if (res) 3480cf1cd13SGatien Chevallier panic("Failed to apply RIF config"); 3490cf1cd13SGatien Chevallier 3500cf1cd13SGatien Chevallier clk_disable(hpdma_d->hpdma_clock); 3510cf1cd13SGatien Chevallier 3520cf1cd13SGatien Chevallier SLIST_INSERT_HEAD(&hpdma_list, hpdma_d, link); 3530cf1cd13SGatien Chevallier 3540cf1cd13SGatien Chevallier register_pm_core_service_cb(stm32_hpdma_pm, hpdma_d, "stm32-hpdma"); 3550cf1cd13SGatien Chevallier 3560cf1cd13SGatien Chevallier return TEE_SUCCESS; 3570cf1cd13SGatien Chevallier } 3580cf1cd13SGatien Chevallier 3590cf1cd13SGatien Chevallier static const struct dt_device_match stm32_hpdma_match_table[] = { 3600cf1cd13SGatien Chevallier { .compatible = "st,stm32-dma3" }, 3610cf1cd13SGatien Chevallier { } 3620cf1cd13SGatien Chevallier }; 3630cf1cd13SGatien Chevallier 3640cf1cd13SGatien Chevallier DEFINE_DT_DRIVER(stm32_hpdma_dt_driver) = { 3650cf1cd13SGatien Chevallier .name = "st,stm32-hpdma", 3660cf1cd13SGatien Chevallier .match_table = stm32_hpdma_match_table, 3670cf1cd13SGatien Chevallier .probe = stm32_hpdma_probe, 3680cf1cd13SGatien Chevallier }; 369