1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2022-2024, STMicroelectronics 4 */ 5 #include <drivers/stm32_rif.h> 6 #include <io.h> 7 #include <kernel/boot.h> 8 #include <kernel/dt.h> 9 #include <kernel/interrupt.h> 10 #include <kernel/panic.h> 11 #include <libfdt.h> 12 #include <mm/core_memprot.h> 13 #include <tee_api_defines.h> 14 #include <trace.h> 15 #include <util.h> 16 17 /* IAC offset register */ 18 #define _IAC_IER0 U(0x000) 19 #define _IAC_ISR0 U(0x080) 20 #define _IAC_ICR0 U(0x100) 21 #define _IAC_IISR0 U(0x36C) 22 23 #define _IAC_HWCFGR2 U(0x3EC) 24 #define _IAC_HWCFGR1 U(0x3F0) 25 #define _IAC_VERR U(0x3F4) 26 27 /* IAC_HWCFGR2 register fields */ 28 #define _IAC_HWCFGR2_CFG1_MASK GENMASK_32(3, 0) 29 #define _IAC_HWCFGR2_CFG1_SHIFT 0 30 #define _IAC_HWCFGR2_CFG2_MASK GENMASK_32(7, 4) 31 #define _IAC_HWCFGR2_CFG2_SHIFT 4 32 33 /* IAC_HWCFGR1 register fields */ 34 #define _IAC_HWCFGR1_CFG1_MASK GENMASK_32(3, 0) 35 #define _IAC_HWCFGR1_CFG1_SHIFT 0 36 #define _IAC_HWCFGR1_CFG2_MASK GENMASK_32(7, 4) 37 #define _IAC_HWCFGR1_CFG2_SHIFT 4 38 #define _IAC_HWCFGR1_CFG3_MASK GENMASK_32(11, 8) 39 #define _IAC_HWCFGR1_CFG3_SHIFT 8 40 #define _IAC_HWCFGR1_CFG4_MASK GENMASK_32(15, 12) 41 #define _IAC_HWCFGR1_CFG4_SHIFT 12 42 #define _IAC_HWCFGR1_CFG5_MASK GENMASK_32(24, 16) 43 #define _IAC_HWCFGR1_CFG5_SHIFT 16 44 45 /* IAC_VERR register fields */ 46 #define _IAC_VERR_MINREV_MASK GENMASK_32(3, 0) 47 #define _IAC_VERR_MINREV_SHIFT 0 48 #define _IAC_VERR_MAJREV_MASK GENMASK_32(7, 4) 49 #define _IAC_VERR_MAJREV_SHIFT 4 50 51 /* Periph ID per register */ 52 #define _PERIPH_IDS_PER_REG 32 53 54 #define _IAC_FLD_PREP(field, value) (SHIFT_U32((value), \ 55 (field ## _SHIFT)) & \ 56 (field ## _MASK)) 57 #define _IAC_FLD_GET(field, value) (((uint32_t)(value) & \ 58 (field ## _MASK)) >> \ 59 (field ## _SHIFT)) 60 61 #define IAC_EXCEPT_MSB_BIT(x) ((x) * _PERIPH_IDS_PER_REG + \ 62 _PERIPH_IDS_PER_REG - 1) 63 #define IAC_EXCEPT_LSB_BIT(x) ((x) * _PERIPH_IDS_PER_REG) 64 #define IAC_FIRST_ILAC_IN_REG(x) (__builtin_ffs((x)) - 1) 65 #define IAC_ILAC_ID(reg_val, offset) (IAC_FIRST_ILAC_IN_REG(reg_val) + \ 66 IAC_EXCEPT_LSB_BIT(offset)) 67 68 /** 69 * struct iac_driver_data - Hardware information on the IAC peripheral 70 * 71 * @version: Peripheral version number 72 * @num_ilac: Number of IAC lines 73 */ 74 struct iac_driver_data { 75 uint32_t version; 76 uint8_t num_ilac; 77 }; 78 79 /** 80 * struct stm32_iac_platdata - Platform data for the IAC driver 81 * 82 * @irq_chip: Reference to the main IRQ chip of the platform 83 * @base: Virtual base address of the IAC peripheral 84 * @irq: ID of the IAC interrupt 85 */ 86 struct stm32_iac_platdata { 87 struct itr_chip *irq_chip; 88 vaddr_t base; 89 size_t irq; 90 }; 91 92 /** 93 * struct iac_device - IAC device private data 94 * @pdata: Platform data read from the DT 95 * @ddata: Device data read from the hardware 96 * @itr: Interrupt handler reference 97 */ 98 struct iac_device { 99 struct stm32_iac_platdata pdata; 100 struct iac_driver_data *ddata; 101 struct itr_handler *itr; 102 }; 103 104 static struct iac_device iac_dev; 105 106 static void stm32_iac_get_hwdata(void) 107 { 108 struct iac_driver_data *ddata = iac_dev.ddata; 109 vaddr_t base = iac_dev.pdata.base; 110 uint32_t regval = 0; 111 112 regval = io_read32(base + _IAC_HWCFGR1); 113 ddata->num_ilac = _IAC_FLD_GET(_IAC_HWCFGR1_CFG5, regval); 114 115 ddata->version = io_read32(base + _IAC_VERR); 116 117 DMSG("IAC version %"PRIu32".%"PRIu32, 118 _IAC_FLD_GET(_IAC_VERR_MAJREV, ddata->version), 119 _IAC_FLD_GET(_IAC_VERR_MINREV, ddata->version)); 120 121 DMSG("HW cap: enabled, num ilac:[%"PRIu8"]", ddata->num_ilac); 122 } 123 124 static TEE_Result stm32_iac_parse_fdt(const void *fdt, int node) 125 { 126 struct stm32_iac_platdata *pdata = &iac_dev.pdata; 127 TEE_Result res = TEE_ERROR_GENERIC; 128 struct dt_node_info dt_info = { }; 129 struct io_pa_va base = { }; 130 131 fdt_fill_device_info(fdt, &dt_info, node); 132 if (dt_info.reg == DT_INFO_INVALID_REG) 133 return TEE_ERROR_BAD_PARAMETERS; 134 135 res = interrupt_dt_get(fdt, node, &pdata->irq_chip, &pdata->irq); 136 if (res) 137 return res; 138 139 base.pa = dt_info.reg; 140 pdata->base = io_pa_or_va_secure(&base, dt_info.reg_size); 141 142 return TEE_SUCCESS; 143 } 144 145 static __noreturn void access_violation_action(void) 146 { 147 DMSG("Ooops..."); 148 panic(); 149 } 150 151 static enum itr_return stm32_iac_itr(struct itr_handler *h __unused) 152 { 153 struct iac_driver_data *ddata = iac_dev.ddata; 154 vaddr_t base = iac_dev.pdata.base; 155 unsigned int nreg = DIV_ROUND_UP(ddata->num_ilac, _PERIPH_IDS_PER_REG); 156 unsigned int i = 0; 157 uint32_t isr = 0; 158 159 for (i = 0; i < nreg; i++) { 160 uint32_t offset = sizeof(uint32_t) * i; 161 unsigned int j = 0; 162 163 isr = io_read32(base + _IAC_ISR0 + offset); 164 isr &= io_read32(base + _IAC_IER0 + offset); 165 166 if (!isr) 167 continue; 168 169 EMSG("IAC exceptions [%d:%d]: %#"PRIx32, IAC_EXCEPT_MSB_BIT(i), 170 IAC_EXCEPT_LSB_BIT(i), isr); 171 172 for (j = 0; j < _PERIPH_IDS_PER_REG; j++) { 173 EMSG("IAC exception ID: %d", IAC_ILAC_ID(isr, i)); 174 175 io_write32(base + _IAC_ICR0 + offset, 176 BIT(IAC_FIRST_ILAC_IN_REG(isr))); 177 178 isr = io_read32(base + _IAC_ISR0 + offset); 179 isr &= io_read32(base + _IAC_IER0 + offset); 180 181 if (!isr) 182 break; 183 } 184 } 185 186 access_violation_action(); 187 188 return ITRR_HANDLED; 189 } 190 191 static void stm32_iac_setup(void) 192 { 193 struct iac_driver_data *ddata = iac_dev.ddata; 194 vaddr_t base = iac_dev.pdata.base; 195 unsigned int nreg = DIV_ROUND_UP(ddata->num_ilac, _PERIPH_IDS_PER_REG); 196 unsigned int i = 0; 197 198 for (i = 0; i < nreg; i++) { 199 vaddr_t reg_ofst = base + sizeof(uint32_t) * i; 200 201 /* Clear status flags */ 202 io_write32(reg_ofst + _IAC_ICR0, ~0x0); 203 /* Enable all peripherals of nreg */ 204 io_write32(reg_ofst + _IAC_IER0, ~0x0); 205 } 206 } 207 208 static TEE_Result probe_iac_device(const void *fdt, int node) 209 { 210 TEE_Result res = TEE_ERROR_GENERIC; 211 bool is_tdcid = false; 212 213 res = stm32_rifsc_check_tdcid(&is_tdcid); 214 if (res) 215 return res; 216 217 /* IAC must be managed by the trusted domain CID */ 218 if (!is_tdcid) 219 return TEE_ERROR_ACCESS_DENIED; 220 221 res = stm32_iac_parse_fdt(fdt, node); 222 if (res) 223 return res; 224 225 stm32_iac_get_hwdata(); 226 stm32_iac_setup(); 227 228 res = interrupt_alloc_add_handler(iac_dev.pdata.irq_chip, 229 iac_dev.pdata.irq, stm32_iac_itr, 230 ITRF_TRIGGER_LEVEL, NULL, 231 &iac_dev.itr); 232 if (res) 233 panic(); 234 235 interrupt_enable(iac_dev.pdata.irq_chip, iac_dev.itr->it); 236 237 return TEE_SUCCESS; 238 } 239 240 static TEE_Result stm32_iac_probe(const void *fdt, int node, 241 const void *compat_data __unused) 242 { 243 TEE_Result res = TEE_ERROR_GENERIC; 244 245 iac_dev.ddata = calloc(1, sizeof(*iac_dev.ddata)); 246 if (!iac_dev.ddata) 247 return TEE_ERROR_OUT_OF_MEMORY; 248 249 res = probe_iac_device(fdt, node); 250 if (res) 251 free(iac_dev.ddata); 252 253 return res; 254 } 255 256 static const struct dt_device_match stm32_iac_match_table[] = { 257 { .compatible = "st,stm32mp25-iac" }, 258 { } 259 }; 260 261 DEFINE_DT_DRIVER(stm32_iac_dt_driver) = { 262 .name = "stm32-iac", 263 .match_table = stm32_iac_match_table, 264 .probe = stm32_iac_probe, 265 }; 266