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; 79*307d268bSGatien 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 890cf1cd13SGatien Chevallier /* This function expects HPDMA bus clock is enabled */ 900cf1cd13SGatien Chevallier static TEE_Result apply_rif_config(struct hpdma_pdata *hpdma_d, bool is_tdcid) 910cf1cd13SGatien Chevallier { 920cf1cd13SGatien Chevallier TEE_Result res = TEE_ERROR_ACCESS_DENIED; 930cf1cd13SGatien Chevallier uint32_t cidcfgr = 0; 940cf1cd13SGatien Chevallier unsigned int i = 0; 950cf1cd13SGatien Chevallier 96*307d268bSGatien Chevallier if (!hpdma_d->conf_data) 97*307d268bSGatien Chevallier return TEE_SUCCESS; 98*307d268bSGatien Chevallier 990cf1cd13SGatien Chevallier for (i = 0; i < HPDMA_RIF_CHANNELS; i++) { 100*307d268bSGatien Chevallier if (!(BIT(i) & hpdma_d->conf_data->access_mask[0])) 1010cf1cd13SGatien Chevallier continue; 1020cf1cd13SGatien Chevallier /* 1030cf1cd13SGatien Chevallier * When TDCID, OP-TEE should be the one to set the CID filtering 1040cf1cd13SGatien Chevallier * configuration. Clearing previous configuration prevents 1050cf1cd13SGatien Chevallier * undesired events during the only legitimate configuration. 1060cf1cd13SGatien Chevallier */ 1070cf1cd13SGatien Chevallier if (is_tdcid) 1080cf1cd13SGatien Chevallier io_clrbits32(hpdma_d->base + _HPDMA_CIDCFGR(i), 1090cf1cd13SGatien Chevallier _HPDMA_CIDCFGR_CONF_MASK); 1100cf1cd13SGatien Chevallier 1110cf1cd13SGatien Chevallier cidcfgr = io_read32(hpdma_d->base + _HPDMA_CIDCFGR(i)); 1120cf1cd13SGatien Chevallier 1130cf1cd13SGatien Chevallier /* Check if the channel is in semaphore mode */ 1140cf1cd13SGatien Chevallier if (!stm32_rif_semaphore_enabled_and_ok(cidcfgr, RIF_CID1)) 1150cf1cd13SGatien Chevallier continue; 1160cf1cd13SGatien Chevallier 1170cf1cd13SGatien Chevallier /* If not TDCID, we want to acquire semaphores assigned to us */ 1180cf1cd13SGatien Chevallier res = stm32_rif_acquire_semaphore(hpdma_d->base + 1190cf1cd13SGatien Chevallier _HPDMA_SEMCR(i), 1200cf1cd13SGatien Chevallier HPDMA_NB_MAX_CID_SUPPORTED); 1210cf1cd13SGatien Chevallier if (res) { 1220cf1cd13SGatien Chevallier EMSG("Couldn't acquire semaphore for channel %u", i); 1230cf1cd13SGatien Chevallier return res; 1240cf1cd13SGatien Chevallier } 1250cf1cd13SGatien Chevallier } 1260cf1cd13SGatien Chevallier 1270cf1cd13SGatien Chevallier /* Security and privilege RIF configuration */ 1280cf1cd13SGatien Chevallier io_clrsetbits32(hpdma_d->base + _HPDMA_PRIVCFGR, _HPDMA_PRIVCFGR_MASK & 129*307d268bSGatien Chevallier hpdma_d->conf_data->access_mask[0], 130*307d268bSGatien Chevallier hpdma_d->conf_data->priv_conf[0]); 1310cf1cd13SGatien Chevallier io_clrsetbits32(hpdma_d->base + _HPDMA_SECCFGR, _HPDMA_SECCFGR_MASK & 132*307d268bSGatien Chevallier hpdma_d->conf_data->access_mask[0], 133*307d268bSGatien Chevallier hpdma_d->conf_data->sec_conf[0]); 1340cf1cd13SGatien Chevallier 1350cf1cd13SGatien Chevallier /* Skip CID/semaphore configuration if not in TDCID state. */ 1360cf1cd13SGatien Chevallier if (!is_tdcid) 1370cf1cd13SGatien Chevallier goto end; 1380cf1cd13SGatien Chevallier 1390cf1cd13SGatien Chevallier for (i = 0; i < HPDMA_RIF_CHANNELS; i++) { 140*307d268bSGatien Chevallier if (!(BIT(i) & hpdma_d->conf_data->access_mask[0])) 1410cf1cd13SGatien Chevallier continue; 1420cf1cd13SGatien Chevallier 1430cf1cd13SGatien Chevallier io_clrsetbits32(hpdma_d->base + _HPDMA_CIDCFGR(i), 1440cf1cd13SGatien Chevallier _HPDMA_CIDCFGR_CONF_MASK, 145*307d268bSGatien Chevallier hpdma_d->conf_data->cid_confs[i]); 1460cf1cd13SGatien Chevallier 1470cf1cd13SGatien Chevallier cidcfgr = io_read32(hpdma_d->base + _HPDMA_CIDCFGR(i)); 1480cf1cd13SGatien Chevallier 1490cf1cd13SGatien Chevallier /* 1500cf1cd13SGatien Chevallier * Take semaphore if the resource is in semaphore 1510cf1cd13SGatien Chevallier * mode and secured. 1520cf1cd13SGatien Chevallier */ 1530cf1cd13SGatien Chevallier if (!stm32_rif_semaphore_enabled_and_ok(cidcfgr, RIF_CID1) || 1540cf1cd13SGatien Chevallier !(io_read32(hpdma_d->base + _HPDMA_SECCFGR) & BIT(i))) { 1550cf1cd13SGatien Chevallier res = 1560cf1cd13SGatien Chevallier stm32_rif_release_semaphore(hpdma_d->base + 1570cf1cd13SGatien Chevallier _HPDMA_SEMCR(i), 1580cf1cd13SGatien Chevallier HPDMA_NB_MAX_CID_SUPPORTED); 1590cf1cd13SGatien Chevallier if (res) { 1600cf1cd13SGatien Chevallier EMSG("Couldn't release semaphore for res%u", i); 1610cf1cd13SGatien Chevallier return TEE_ERROR_ACCESS_DENIED; 1620cf1cd13SGatien Chevallier } 1630cf1cd13SGatien Chevallier } else { 1640cf1cd13SGatien Chevallier res = 1650cf1cd13SGatien Chevallier stm32_rif_acquire_semaphore(hpdma_d->base + 1660cf1cd13SGatien Chevallier _HPDMA_SEMCR(i), 1670cf1cd13SGatien Chevallier HPDMA_NB_MAX_CID_SUPPORTED); 1680cf1cd13SGatien Chevallier if (res) { 1690cf1cd13SGatien Chevallier EMSG("Couldn't acquire semaphore for res%u", i); 1700cf1cd13SGatien Chevallier return TEE_ERROR_ACCESS_DENIED; 1710cf1cd13SGatien Chevallier } 1720cf1cd13SGatien Chevallier } 1730cf1cd13SGatien Chevallier } 1740cf1cd13SGatien Chevallier 1750cf1cd13SGatien Chevallier /* 1760cf1cd13SGatien Chevallier * Lock RIF configuration if configured. This cannot be undone until 1770cf1cd13SGatien Chevallier * next reset. 1780cf1cd13SGatien Chevallier */ 1790cf1cd13SGatien Chevallier io_clrsetbits32(hpdma_d->base + _HPDMA_RCFGLOCKR, _HPDMA_RCFGLOCKR_MASK, 180*307d268bSGatien Chevallier hpdma_d->conf_data->lock_conf[0]); 1810cf1cd13SGatien Chevallier 1820cf1cd13SGatien Chevallier end: 1830cf1cd13SGatien Chevallier if (IS_ENABLED(CFG_TEE_CORE_DEBUG)) { 1840cf1cd13SGatien Chevallier /* Check that RIF config are applied, panic otherwise */ 1850cf1cd13SGatien Chevallier if ((io_read32(hpdma_d->base + _HPDMA_PRIVCFGR) & 186*307d268bSGatien Chevallier hpdma_d->conf_data->access_mask[0]) != 187*307d268bSGatien Chevallier hpdma_d->conf_data->priv_conf[0]) 1880cf1cd13SGatien Chevallier panic("HPDMA channel priv conf is incorrect"); 1890cf1cd13SGatien Chevallier 1900cf1cd13SGatien Chevallier if ((io_read32(hpdma_d->base + _HPDMA_SECCFGR) & 191*307d268bSGatien Chevallier hpdma_d->conf_data->access_mask[0]) != 192*307d268bSGatien Chevallier hpdma_d->conf_data->sec_conf[0]) 1930cf1cd13SGatien Chevallier panic("HPDMA channel sec conf is incorrect"); 1940cf1cd13SGatien Chevallier } 1950cf1cd13SGatien Chevallier 1960cf1cd13SGatien Chevallier return TEE_SUCCESS; 1970cf1cd13SGatien Chevallier } 1980cf1cd13SGatien Chevallier 1990cf1cd13SGatien Chevallier static TEE_Result parse_dt(const void *fdt, int node, 2000cf1cd13SGatien Chevallier struct hpdma_pdata *hpdma_d) 2010cf1cd13SGatien Chevallier { 2020cf1cd13SGatien Chevallier TEE_Result res = TEE_ERROR_GENERIC; 2030cf1cd13SGatien Chevallier unsigned int i = 0; 2040cf1cd13SGatien Chevallier int lenp = 0; 2050cf1cd13SGatien Chevallier const fdt32_t *cuint = NULL; 2060cf1cd13SGatien Chevallier struct dt_node_info info = { }; 2070cf1cd13SGatien Chevallier struct io_pa_va addr = { }; 2080cf1cd13SGatien Chevallier 2090cf1cd13SGatien Chevallier fdt_fill_device_info(fdt, &info, node); 2100cf1cd13SGatien Chevallier assert(info.reg != DT_INFO_INVALID_REG && 2110cf1cd13SGatien Chevallier info.reg_size != DT_INFO_INVALID_REG_SIZE); 2120cf1cd13SGatien Chevallier 2130cf1cd13SGatien Chevallier addr.pa = info.reg; 2140cf1cd13SGatien Chevallier hpdma_d->base = io_pa_or_va_secure(&addr, info.reg_size); 2150cf1cd13SGatien Chevallier 2160cf1cd13SGatien Chevallier /* Gate the IP */ 2170cf1cd13SGatien Chevallier res = clk_dt_get_by_index(fdt, node, 0, &hpdma_d->hpdma_clock); 2180cf1cd13SGatien Chevallier if (res) 2190cf1cd13SGatien Chevallier return res; 2200cf1cd13SGatien Chevallier 2210cf1cd13SGatien Chevallier cuint = fdt_getprop(fdt, node, "st,protreg", &lenp); 222*307d268bSGatien Chevallier if (!cuint) { 223*307d268bSGatien Chevallier DMSG("No RIF configuration available"); 224*307d268bSGatien Chevallier return TEE_SUCCESS; 225*307d268bSGatien Chevallier } 226*307d268bSGatien Chevallier 227*307d268bSGatien Chevallier hpdma_d->conf_data = calloc(1, sizeof(*hpdma_d->conf_data)); 228*307d268bSGatien Chevallier if (!hpdma_d->conf_data) 229*307d268bSGatien Chevallier panic(); 2300cf1cd13SGatien Chevallier 2310cf1cd13SGatien Chevallier hpdma_d->nb_channels = (unsigned int)(lenp / sizeof(uint32_t)); 2320cf1cd13SGatien Chevallier assert(hpdma_d->nb_channels <= HPDMA_RIF_CHANNELS); 2330cf1cd13SGatien Chevallier 234*307d268bSGatien Chevallier hpdma_d->conf_data->cid_confs = calloc(HPDMA_RIF_CHANNELS, 2350cf1cd13SGatien Chevallier sizeof(uint32_t)); 236*307d268bSGatien Chevallier hpdma_d->conf_data->sec_conf = calloc(1, sizeof(uint32_t)); 237*307d268bSGatien Chevallier hpdma_d->conf_data->priv_conf = calloc(1, sizeof(uint32_t)); 238*307d268bSGatien Chevallier hpdma_d->conf_data->access_mask = calloc(1, sizeof(uint32_t)); 239*307d268bSGatien Chevallier hpdma_d->conf_data->lock_conf = calloc(1, sizeof(uint32_t)); 240*307d268bSGatien Chevallier if (!hpdma_d->conf_data->cid_confs || !hpdma_d->conf_data->sec_conf || 241*307d268bSGatien Chevallier !hpdma_d->conf_data->priv_conf || 242*307d268bSGatien Chevallier !hpdma_d->conf_data->access_mask || !hpdma_d->conf_data->lock_conf) 243*307d268bSGatien Chevallier panic("Missing memory capacity for HPDMA RIF configuration"); 2440cf1cd13SGatien Chevallier 2450cf1cd13SGatien Chevallier for (i = 0; i < hpdma_d->nb_channels; i++) 246*307d268bSGatien Chevallier stm32_rif_parse_cfg(fdt32_to_cpu(cuint[i]), hpdma_d->conf_data, 2470cf1cd13SGatien Chevallier HPDMA_RIF_CHANNELS); 2480cf1cd13SGatien Chevallier 2490cf1cd13SGatien Chevallier return TEE_SUCCESS; 2500cf1cd13SGatien Chevallier } 2510cf1cd13SGatien Chevallier 2520cf1cd13SGatien Chevallier static void stm32_hpdma_pm_resume(struct hpdma_pdata *hpdma) 2530cf1cd13SGatien Chevallier { 2540cf1cd13SGatien Chevallier if (apply_rif_config(hpdma, true)) 2550cf1cd13SGatien Chevallier panic("Failed to resume HPDMA"); 2560cf1cd13SGatien Chevallier } 2570cf1cd13SGatien Chevallier 2580cf1cd13SGatien Chevallier static void stm32_hpdma_pm_suspend(struct hpdma_pdata *hpdma) 2590cf1cd13SGatien Chevallier { 2600cf1cd13SGatien Chevallier size_t i = 0; 2610cf1cd13SGatien Chevallier 2620cf1cd13SGatien Chevallier for (i = 0; i < HPDMA_RIF_CHANNELS; i++) 263*307d268bSGatien Chevallier hpdma->conf_data->cid_confs[i] = io_read32(hpdma->base + 2640cf1cd13SGatien Chevallier _HPDMA_CIDCFGR(i)) & 2650cf1cd13SGatien Chevallier _HPDMA_CIDCFGR_CONF_MASK; 2660cf1cd13SGatien Chevallier 267*307d268bSGatien Chevallier hpdma->conf_data->priv_conf[0] = io_read32(hpdma->base + 2680cf1cd13SGatien Chevallier _HPDMA_PRIVCFGR) & 2690cf1cd13SGatien Chevallier _HPDMA_PRIVCFGR_MASK; 270*307d268bSGatien Chevallier hpdma->conf_data->sec_conf[0] = io_read32(hpdma->base + 2710cf1cd13SGatien Chevallier _HPDMA_SECCFGR) & 2720cf1cd13SGatien Chevallier _HPDMA_SECCFGR_MASK; 273*307d268bSGatien Chevallier hpdma->conf_data->lock_conf[0] = io_read32(hpdma->base + 2740cf1cd13SGatien Chevallier _HPDMA_RCFGLOCKR) & 2750cf1cd13SGatien Chevallier _HPDMA_RCFGLOCKR_MASK; 2760cf1cd13SGatien Chevallier 2770cf1cd13SGatien Chevallier /* 2780cf1cd13SGatien Chevallier * The access mask is modified to restore the conf for all 2790cf1cd13SGatien Chevallier * resources. 2800cf1cd13SGatien Chevallier */ 281*307d268bSGatien Chevallier hpdma->conf_data->access_mask[0] = GENMASK_32(HPDMA_RIF_CHANNELS - 1, 282*307d268bSGatien Chevallier 0); 2830cf1cd13SGatien Chevallier } 2840cf1cd13SGatien Chevallier 2850cf1cd13SGatien Chevallier static TEE_Result 2860cf1cd13SGatien Chevallier stm32_hpdma_pm(enum pm_op op, unsigned int pm_hint, 2870cf1cd13SGatien Chevallier const struct pm_callback_handle *pm_handle) 2880cf1cd13SGatien Chevallier { 2890cf1cd13SGatien Chevallier struct hpdma_pdata *hpdma = pm_handle->handle; 2900cf1cd13SGatien Chevallier TEE_Result res = TEE_ERROR_GENERIC; 2910cf1cd13SGatien Chevallier bool is_tdcid = false; 2920cf1cd13SGatien Chevallier 2930cf1cd13SGatien Chevallier res = stm32_rifsc_check_tdcid(&is_tdcid); 2940cf1cd13SGatien Chevallier if (res) 2950cf1cd13SGatien Chevallier panic(); 2960cf1cd13SGatien Chevallier 2970cf1cd13SGatien Chevallier if (!PM_HINT_IS_STATE(pm_hint, CONTEXT) || !is_tdcid) 2980cf1cd13SGatien Chevallier return TEE_SUCCESS; 2990cf1cd13SGatien Chevallier 3000cf1cd13SGatien Chevallier res = clk_enable(hpdma->hpdma_clock); 3010cf1cd13SGatien Chevallier if (res) 3020cf1cd13SGatien Chevallier return res; 3030cf1cd13SGatien Chevallier 3040cf1cd13SGatien Chevallier if (op == PM_OP_RESUME) 3050cf1cd13SGatien Chevallier stm32_hpdma_pm_resume(hpdma); 3060cf1cd13SGatien Chevallier else 3070cf1cd13SGatien Chevallier stm32_hpdma_pm_suspend(hpdma); 3080cf1cd13SGatien Chevallier 3090cf1cd13SGatien Chevallier clk_disable(hpdma->hpdma_clock); 3100cf1cd13SGatien Chevallier 3110cf1cd13SGatien Chevallier return TEE_SUCCESS; 3120cf1cd13SGatien Chevallier } 3130cf1cd13SGatien Chevallier 3140cf1cd13SGatien Chevallier static TEE_Result stm32_hpdma_probe(const void *fdt, int node, 3150cf1cd13SGatien Chevallier const void *compat_data __unused) 3160cf1cd13SGatien Chevallier { 3170cf1cd13SGatien Chevallier TEE_Result res = TEE_ERROR_GENERIC; 3180cf1cd13SGatien Chevallier struct hpdma_pdata *hpdma_d = NULL; 3190cf1cd13SGatien Chevallier bool is_tdcid = false; 3200cf1cd13SGatien Chevallier 3210cf1cd13SGatien Chevallier res = stm32_rifsc_check_tdcid(&is_tdcid); 3220cf1cd13SGatien Chevallier if (res) 3230cf1cd13SGatien Chevallier return res; 3240cf1cd13SGatien Chevallier 3250cf1cd13SGatien Chevallier hpdma_d = calloc(1, sizeof(*hpdma_d)); 3260cf1cd13SGatien Chevallier if (!hpdma_d) 3270cf1cd13SGatien Chevallier return TEE_ERROR_OUT_OF_MEMORY; 3280cf1cd13SGatien Chevallier 3290cf1cd13SGatien Chevallier res = parse_dt(fdt, node, hpdma_d); 3300cf1cd13SGatien Chevallier if (res) { 3310cf1cd13SGatien Chevallier free(hpdma_d); 3320cf1cd13SGatien Chevallier return res; 3330cf1cd13SGatien Chevallier } 3340cf1cd13SGatien Chevallier 3350cf1cd13SGatien Chevallier if (clk_enable(hpdma_d->hpdma_clock)) 3360cf1cd13SGatien Chevallier panic("Cannot access hpdma clock"); 3370cf1cd13SGatien Chevallier 3380cf1cd13SGatien Chevallier res = apply_rif_config(hpdma_d, is_tdcid); 3390cf1cd13SGatien Chevallier if (res) 3400cf1cd13SGatien Chevallier panic("Failed to apply RIF config"); 3410cf1cd13SGatien Chevallier 3420cf1cd13SGatien Chevallier clk_disable(hpdma_d->hpdma_clock); 3430cf1cd13SGatien Chevallier 3440cf1cd13SGatien Chevallier SLIST_INSERT_HEAD(&hpdma_list, hpdma_d, link); 3450cf1cd13SGatien Chevallier 3460cf1cd13SGatien Chevallier register_pm_core_service_cb(stm32_hpdma_pm, hpdma_d, "stm32-hpdma"); 3470cf1cd13SGatien Chevallier 3480cf1cd13SGatien Chevallier return TEE_SUCCESS; 3490cf1cd13SGatien Chevallier } 3500cf1cd13SGatien Chevallier 3510cf1cd13SGatien Chevallier static const struct dt_device_match stm32_hpdma_match_table[] = { 3520cf1cd13SGatien Chevallier { .compatible = "st,stm32-dma3" }, 3530cf1cd13SGatien Chevallier { } 3540cf1cd13SGatien Chevallier }; 3550cf1cd13SGatien Chevallier 3560cf1cd13SGatien Chevallier DEFINE_DT_DRIVER(stm32_hpdma_dt_driver) = { 3570cf1cd13SGatien Chevallier .name = "st,stm32-hpdma", 3580cf1cd13SGatien Chevallier .match_table = stm32_hpdma_match_table, 3590cf1cd13SGatien Chevallier .probe = stm32_hpdma_probe, 3600cf1cd13SGatien Chevallier }; 361