1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2022-2024, STMicroelectronics 4 */ 5 #include <drivers/clk.h> 6 #include <drivers/clk_dt.h> 7 #include <drivers/stm32_rif.h> 8 #include <drivers/stm32_serc.h> 9 #include <io.h> 10 #include <kernel/boot.h> 11 #include <kernel/dt.h> 12 #include <kernel/interrupt.h> 13 #include <kernel/panic.h> 14 #include <kernel/pm.h> 15 #include <libfdt.h> 16 #include <mm/core_memprot.h> 17 #include <tee_api_defines.h> 18 #include <trace.h> 19 #include <util.h> 20 21 /* SERC offset register */ 22 #define _SERC_IER0 U(0x000) 23 #define _SERC_ISR0 U(0x040) 24 #define _SERC_ICR0 U(0x080) 25 #define _SERC_ENABLE U(0x100) 26 27 #define _SERC_HWCFGR U(0x3F0) 28 #define _SERC_VERR U(0x3F4) 29 30 /* SERC_ENABLE register fields */ 31 #define _SERC_ENABLE_SERFEN BIT(0) 32 33 /* SERC_HWCFGR register fields */ 34 #define _SERC_HWCFGR_CFG1_MASK GENMASK_32(7, 0) 35 #define _SERC_HWCFGR_CFG1_SHIFT U(0) 36 #define _SERC_HWCFGR_CFG2_MASK GENMASK_32(18, 16) 37 #define _SERC_HWCFGR_CFG2_SHIFT U(16) 38 39 /* SERC_VERR register fields */ 40 #define _SERC_VERR_MINREV_MASK GENMASK_32(3, 0) 41 #define _SERC_VERR_MINREV_SHIFT U(0) 42 #define _SERC_VERR_MAJREV_MASK GENMASK_32(7, 4) 43 #define _SERC_VERR_MAJREV_SHIFT U(4) 44 45 /* Periph id per register */ 46 #define _PERIPH_IDS_PER_REG U(32) 47 48 #define _SERC_FLD_PREP(field, value) (SHIFT_U32((value), \ 49 (field ## _SHIFT)) & \ 50 (field ## _MASK)) 51 #define _SERC_FLD_GET(field, value) (((uint32_t)(value) & \ 52 (field ## _MASK)) >> \ 53 (field ## _SHIFT)) 54 55 #define SERC_EXCEPT_MSB_BIT(x) ((x) * _PERIPH_IDS_PER_REG + \ 56 _PERIPH_IDS_PER_REG - 1) 57 #define SERC_EXCEPT_LSB_BIT(x) ((x) * _PERIPH_IDS_PER_REG) 58 59 /** 60 * struct serc_driver_data - Hardware information on the SERC peripheral 61 * 62 * @version: Peripheral version number 63 * @num_ilac: Number of SERC lines 64 */ 65 struct serc_driver_data { 66 uint32_t version; 67 uint8_t num_ilac; 68 }; 69 70 /** 71 * struct stm32_serc_platdata - Platform data for the SERC driver 72 * 73 * @irq_chip: Reference to the SERC's IRQ chip 74 * @clock: Reference on the SERC clock 75 * @base: Base address of the SERC peripheral 76 * @irq: ID of the SERC interrupt 77 */ 78 struct stm32_serc_platdata { 79 struct itr_chip *irq_chip; 80 struct clk *clock; 81 vaddr_t base; 82 size_t irq; 83 }; 84 85 /** 86 * struct serc_device - SERC device private data 87 * @pdata: Platform data read from the DT 88 * @ddata: Device data read from the hardware 89 * @itr: Interrupt handler reference 90 */ 91 struct serc_device { 92 struct stm32_serc_platdata pdata; 93 struct serc_driver_data *ddata; 94 struct itr_handler *itr; 95 }; 96 97 static struct serc_device serc_dev; 98 99 static void stm32_serc_get_hwdata(void) 100 { 101 struct stm32_serc_platdata *pdata = &serc_dev.pdata; 102 struct serc_driver_data *ddata = serc_dev.ddata; 103 vaddr_t base = pdata->base; 104 uint32_t regval = 0; 105 106 regval = io_read32(base + _SERC_HWCFGR); 107 108 ddata->num_ilac = _SERC_FLD_GET(_SERC_HWCFGR_CFG1, regval); 109 110 ddata->version = io_read32(base + _SERC_VERR); 111 112 DMSG("SERC version %"PRIu32".%"PRIu32, 113 _SERC_FLD_GET(_SERC_VERR_MAJREV, ddata->version), 114 _SERC_FLD_GET(_SERC_VERR_MINREV, ddata->version)); 115 116 DMSG("HW cap: num ilac:[%"PRIu8"]", ddata->num_ilac); 117 } 118 119 static TEE_Result stm32_serc_parse_fdt(const void *fdt, int node) 120 { 121 struct stm32_serc_platdata *pdata = &serc_dev.pdata; 122 TEE_Result res = TEE_ERROR_GENERIC; 123 struct dt_node_info dt_info = { }; 124 struct io_pa_va base = { }; 125 126 fdt_fill_device_info(fdt, &dt_info, node); 127 if (dt_info.reg == DT_INFO_INVALID_REG) 128 return TEE_ERROR_BAD_PARAMETERS; 129 130 res = interrupt_dt_get(fdt, node, &pdata->irq_chip, &pdata->irq); 131 if (res) 132 return res; 133 134 base.pa = dt_info.reg; 135 pdata->base = io_pa_or_va_secure(&base, dt_info.reg_size); 136 137 return clk_dt_get_by_index(fdt, node, 0, &pdata->clock); 138 } 139 140 void stm32_serc_handle_ilac(void) 141 { 142 struct stm32_serc_platdata *pdata = &serc_dev.pdata; 143 struct serc_driver_data *ddata = serc_dev.ddata; 144 unsigned int nreg = 0; 145 bool do_panic = false; 146 unsigned int i = 0; 147 vaddr_t base = 0; 148 uint32_t isr = 0; 149 150 if (!ddata || !pdata) 151 return; 152 153 nreg = DIV_ROUND_UP(ddata->num_ilac, _PERIPH_IDS_PER_REG); 154 base = pdata->base; 155 156 for (i = 0; i < nreg; i++) { 157 uint32_t offset = sizeof(uint32_t) * i; 158 unsigned int j = 0; 159 160 isr = io_read32(base + _SERC_ISR0 + offset); 161 isr &= io_read32(base + _SERC_IER0 + offset); 162 163 if (!isr) 164 continue; 165 166 do_panic = true; 167 EMSG("SERC exceptions [%d:%d]: %#"PRIx32, 168 SERC_EXCEPT_MSB_BIT(i), SERC_EXCEPT_LSB_BIT(i), isr); 169 170 for (j = 0; j < _PERIPH_IDS_PER_REG; j++) { 171 EMSG("SERC exception ID: %d", 172 SERC_EXCEPT_LSB_BIT(i) + __builtin_ffs(isr) - 1); 173 174 io_write32(base + _SERC_ICR0 + offset, 175 BIT(__builtin_ffs(isr) - 1)); 176 177 isr = io_read32(base + _SERC_ISR0 + offset); 178 isr &= io_read32(base + _SERC_IER0 + offset); 179 180 if (!isr) 181 break; 182 } 183 } 184 185 stm32_rif_access_violation_action(); 186 if (IS_ENABLED(CFG_STM32_PANIC_ON_SERC_EVENT) && do_panic) 187 panic(); 188 } 189 190 static enum itr_return stm32_serc_itr(struct itr_handler *h __unused) 191 { 192 stm32_serc_handle_ilac(); 193 194 return ITRR_HANDLED; 195 } 196 197 static void stm32_serc_setup(void) 198 { 199 struct stm32_serc_platdata *pdata = &serc_dev.pdata; 200 struct serc_driver_data *ddata = serc_dev.ddata; 201 vaddr_t base = serc_dev.pdata.base; 202 uint32_t nreg = DIV_ROUND_UP(ddata->num_ilac, _PERIPH_IDS_PER_REG); 203 uint32_t i = 0; 204 205 io_setbits32(pdata->base + _SERC_ENABLE, _SERC_ENABLE_SERFEN); 206 207 for (i = 0; i < nreg; i++) { 208 vaddr_t reg_ofst = base + sizeof(uint32_t) * i; 209 210 /* Clear status flags */ 211 io_write32(reg_ofst + _SERC_ICR0, ~0x0); 212 /* Enable all peripherals of nreg */ 213 io_write32(reg_ofst + _SERC_IER0, ~0x0); 214 } 215 } 216 217 static TEE_Result probe_serc_device(const void *fdt, int node) 218 { 219 TEE_Result res = TEE_ERROR_GENERIC; 220 221 res = stm32_serc_parse_fdt(fdt, node); 222 if (res) 223 return res; 224 225 /* Unbalanced clock enable to have the SERC running */ 226 if (clk_enable(serc_dev.pdata.clock)) 227 panic(); 228 229 stm32_serc_get_hwdata(); 230 stm32_serc_setup(); 231 232 res = interrupt_alloc_add_handler(serc_dev.pdata.irq_chip, 233 serc_dev.pdata.irq, stm32_serc_itr, 234 ITRF_TRIGGER_LEVEL, NULL, 235 &serc_dev.itr); 236 if (res) 237 panic(); 238 239 interrupt_enable(serc_dev.pdata.irq_chip, serc_dev.itr->it); 240 241 return TEE_SUCCESS; 242 } 243 244 static TEE_Result stm32_serc_pm(enum pm_op op, unsigned int pm_hint, 245 const struct pm_callback_handle *hdl __unused) 246 { 247 if (!PM_HINT_IS_STATE(pm_hint, CONTEXT)) 248 return TEE_SUCCESS; 249 250 if (op == PM_OP_RESUME) { 251 if (clk_enable(serc_dev.pdata.clock)) 252 panic(); 253 stm32_serc_setup(); 254 } else { 255 clk_disable(serc_dev.pdata.clock); 256 } 257 258 return TEE_SUCCESS; 259 } 260 261 static TEE_Result stm32_serc_probe(const void *fdt, int node, 262 const void *compat_data __unused) 263 { 264 TEE_Result res = TEE_ERROR_GENERIC; 265 266 serc_dev.ddata = calloc(1, sizeof(*serc_dev.ddata)); 267 if (!serc_dev.ddata) 268 return TEE_ERROR_OUT_OF_MEMORY; 269 270 res = probe_serc_device(fdt, node); 271 if (res) { 272 free(serc_dev.ddata); 273 return res; 274 } 275 276 register_pm_core_service_cb(stm32_serc_pm, NULL, "stm32-serc"); 277 278 return TEE_SUCCESS; 279 } 280 281 static const struct dt_device_match stm32_serc_match_table[] = { 282 { .compatible = "st,stm32mp25-serc" }, 283 { } 284 }; 285 286 DEFINE_DT_DRIVER(stm32_serc_dt_driver) = { 287 .name = "stm32-serc", 288 .match_table = stm32_serc_match_table, 289 .probe = stm32_serc_probe, 290 }; 291