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 enum itr_return stm32_iac_itr(struct itr_handler *h __unused) 146 { 147 struct iac_driver_data *ddata = iac_dev.ddata; 148 vaddr_t base = iac_dev.pdata.base; 149 unsigned int nreg = DIV_ROUND_UP(ddata->num_ilac, _PERIPH_IDS_PER_REG); 150 unsigned int i = 0; 151 uint32_t isr = 0; 152 153 for (i = 0; i < nreg; i++) { 154 uint32_t offset = sizeof(uint32_t) * i; 155 unsigned int j = 0; 156 157 isr = io_read32(base + _IAC_ISR0 + offset); 158 isr &= io_read32(base + _IAC_IER0 + offset); 159 160 if (!isr) 161 continue; 162 163 EMSG("IAC exceptions [%d:%d]: %#"PRIx32, IAC_EXCEPT_MSB_BIT(i), 164 IAC_EXCEPT_LSB_BIT(i), isr); 165 166 for (j = 0; j < _PERIPH_IDS_PER_REG; j++) { 167 EMSG("IAC exception ID: %d", IAC_ILAC_ID(isr, i)); 168 169 io_write32(base + _IAC_ICR0 + offset, 170 BIT(IAC_FIRST_ILAC_IN_REG(isr))); 171 172 isr = io_read32(base + _IAC_ISR0 + offset); 173 isr &= io_read32(base + _IAC_IER0 + offset); 174 175 if (!isr) 176 break; 177 } 178 } 179 180 stm32_rif_access_violation_action(); 181 if (IS_ENABLED(CFG_STM32_PANIC_ON_IAC_EVENT)) 182 panic(); 183 184 return ITRR_HANDLED; 185 } 186 187 static void stm32_iac_setup(void) 188 { 189 struct iac_driver_data *ddata = iac_dev.ddata; 190 vaddr_t base = iac_dev.pdata.base; 191 unsigned int nreg = DIV_ROUND_UP(ddata->num_ilac, _PERIPH_IDS_PER_REG); 192 unsigned int i = 0; 193 194 for (i = 0; i < nreg; i++) { 195 vaddr_t reg_ofst = base + sizeof(uint32_t) * i; 196 197 /* Clear status flags */ 198 io_write32(reg_ofst + _IAC_ICR0, ~0x0); 199 /* Enable all peripherals of nreg */ 200 io_write32(reg_ofst + _IAC_IER0, ~0x0); 201 } 202 } 203 204 static TEE_Result probe_iac_device(const void *fdt, int node) 205 { 206 TEE_Result res = TEE_ERROR_GENERIC; 207 bool is_tdcid = false; 208 209 res = stm32_rifsc_check_tdcid(&is_tdcid); 210 if (res) 211 return res; 212 213 /* IAC must be managed by the trusted domain CID */ 214 if (!is_tdcid) 215 return TEE_ERROR_ACCESS_DENIED; 216 217 res = stm32_iac_parse_fdt(fdt, node); 218 if (res) 219 return res; 220 221 stm32_iac_get_hwdata(); 222 stm32_iac_setup(); 223 224 res = interrupt_alloc_add_handler(iac_dev.pdata.irq_chip, 225 iac_dev.pdata.irq, stm32_iac_itr, 226 ITRF_TRIGGER_LEVEL, NULL, 227 &iac_dev.itr); 228 if (res) 229 panic(); 230 231 interrupt_enable(iac_dev.pdata.irq_chip, iac_dev.itr->it); 232 233 return TEE_SUCCESS; 234 } 235 236 static TEE_Result stm32_iac_probe(const void *fdt, int node, 237 const void *compat_data __unused) 238 { 239 TEE_Result res = TEE_ERROR_GENERIC; 240 241 iac_dev.ddata = calloc(1, sizeof(*iac_dev.ddata)); 242 if (!iac_dev.ddata) 243 return TEE_ERROR_OUT_OF_MEMORY; 244 245 res = probe_iac_device(fdt, node); 246 if (res) 247 free(iac_dev.ddata); 248 249 return res; 250 } 251 252 static const struct dt_device_match stm32_iac_match_table[] = { 253 { .compatible = "st,stm32mp25-iac" }, 254 { } 255 }; 256 257 DEFINE_DT_DRIVER(stm32_iac_dt_driver) = { 258 .name = "stm32-iac", 259 .match_table = stm32_iac_match_table, 260 .probe = stm32_iac_probe, 261 }; 262