1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2022-2024, STMicroelectronics 4 */ 5 6 #include <arm.h> 7 #include <config.h> 8 #include <drivers/clk.h> 9 #include <drivers/clk_dt.h> 10 #include <drivers/stm32_rif.h> 11 #include <io.h> 12 #include <kernel/boot.h> 13 #include <kernel/delay.h> 14 #include <kernel/dt.h> 15 #include <kernel/dt_driver.h> 16 #include <kernel/panic.h> 17 #include <kernel/pm.h> 18 #include <libfdt.h> 19 #include <mm/core_memprot.h> 20 #include <stdbool.h> 21 #include <stdlib.h> 22 #include <stm32_util.h> 23 #include <trace.h> 24 25 #define IPCC_C1SECCFGR U(0x80) 26 #define IPCC_C1PRIVCFGR U(0x84) 27 #define IPCC_C1CIDCFGR U(0x88) 28 #define IPCC_C2SECCFGR U(0x90) 29 #define IPCC_C2PRIVCFGR U(0x94) 30 #define IPCC_C2CIDCFGR U(0x98) 31 #define IPCC_HWCFGR U(0x3F0) 32 33 /* 34 * CIDCFGR register bitfields 35 */ 36 #define IPCC_CIDCFGR_SCID_MASK GENMASK_32(6, 4) 37 #define IPCC_CIDCFGR_CONF_MASK (_CIDCFGR_CFEN | \ 38 IPCC_CIDCFGR_SCID_MASK) 39 40 /* 41 * PRIVCFGR register bitfields 42 */ 43 #define IPCC_PRIVCFGR_MASK GENMASK_32(15, 0) 44 45 /* 46 * SECCFGR register bitfields 47 */ 48 #define IPCC_SECCFGR_MASK GENMASK_32(15, 0) 49 50 /* 51 * IPCC_HWCFGR register bitfields 52 */ 53 #define IPCC_HWCFGR_CHAN_MASK GENMASK_32(7, 0) 54 55 /* 56 * Miscellaneous 57 */ 58 #define IPCC_NB_MAX_RIF_CHAN U(16) 59 60 #define IPCC_NB_MAX_CID_SUPPORTED U(7) 61 62 struct ipcc_pdata { 63 /* 64 * An IPCC has nb_channels_cfg channel configuration for its 65 * (nb_channels_cfg / 2) bi-directionnal channels 66 */ 67 unsigned int nb_channels_cfg; 68 struct clk *ipcc_clock; 69 vaddr_t base; 70 struct rif_conf_data conf_data; 71 72 STAILQ_ENTRY(ipcc_pdata) link; 73 }; 74 75 static STAILQ_HEAD(, ipcc_pdata) ipcc_list = 76 STAILQ_HEAD_INITIALIZER(ipcc_list); 77 78 /* This function expects IPCC bus clock is enabled */ 79 static void apply_rif_config(struct ipcc_pdata *ipcc_d, bool is_tdcid) 80 { 81 uint32_t priv_proc_1 = 0; 82 uint32_t priv_proc_2 = 0; 83 uint32_t sec_proc_1 = 0; 84 uint32_t sec_proc_2 = 0; 85 unsigned int i = 0; 86 bool is_cid_configured = false; 87 88 /* 89 * Check that the number of channel supported by hardware 90 * is coherent with the config 91 */ 92 assert((io_read32(ipcc_d->base + IPCC_HWCFGR) & 93 IPCC_HWCFGR_CHAN_MASK) >= 94 ipcc_d->nb_channels_cfg / 2); 95 96 /* 97 * When TDCID, OP-TEE should be the one to set the CID filtering 98 * configuration. Clearing previous configuration prevents 99 * undesired events during the only legitimate configuration. 100 */ 101 if (is_tdcid) { 102 /* IPCC Processor 1 */ 103 io_clrbits32(ipcc_d->base + IPCC_C1CIDCFGR, 104 IPCC_CIDCFGR_CONF_MASK); 105 106 /* IPCC Processor 2 */ 107 io_clrbits32(ipcc_d->base + IPCC_C2CIDCFGR, 108 IPCC_CIDCFGR_CONF_MASK); 109 } 110 111 /* Split the sec and priv configuration for IPCC processor 1 and 2 */ 112 sec_proc_1 = ipcc_d->conf_data.sec_conf[0] & 113 GENMASK_32(IPCC_NB_MAX_RIF_CHAN - 1, 0); 114 priv_proc_1 = ipcc_d->conf_data.priv_conf[0] & 115 GENMASK_32(IPCC_NB_MAX_RIF_CHAN - 1, 0); 116 117 sec_proc_2 = (ipcc_d->conf_data.sec_conf[0] & 118 GENMASK_32((IPCC_NB_MAX_RIF_CHAN * 2) - 1, 119 IPCC_NB_MAX_RIF_CHAN)) >> 120 IPCC_NB_MAX_RIF_CHAN; 121 priv_proc_2 = (ipcc_d->conf_data.priv_conf[0] & 122 GENMASK_32((IPCC_NB_MAX_RIF_CHAN * 2) - 1, 123 IPCC_NB_MAX_RIF_CHAN)) >> 124 IPCC_NB_MAX_RIF_CHAN; 125 126 /* Security and privilege RIF configuration */ 127 io_clrsetbits32(ipcc_d->base + IPCC_C1PRIVCFGR, IPCC_PRIVCFGR_MASK, 128 priv_proc_1); 129 io_clrsetbits32(ipcc_d->base + IPCC_C2PRIVCFGR, IPCC_PRIVCFGR_MASK, 130 priv_proc_2); 131 io_clrsetbits32(ipcc_d->base + IPCC_C1SECCFGR, IPCC_SECCFGR_MASK, 132 sec_proc_1); 133 io_clrsetbits32(ipcc_d->base + IPCC_C2SECCFGR, IPCC_SECCFGR_MASK, 134 sec_proc_2); 135 136 /* 137 * Evaluate RIF CID filtering configuration before setting it. 138 * Parsed configuration must have consistency. If CID filtering 139 * is enabled for an IPCC channel, then it must be the case for all 140 * channels of this processor. This is a configuration check. 141 */ 142 for (i = 0; i < IPCC_NB_MAX_RIF_CHAN; i++) { 143 if (!(BIT(i) & ipcc_d->conf_data.access_mask[0])) 144 continue; 145 146 if (!is_cid_configured && 147 (BIT(0) & ipcc_d->conf_data.cid_confs[i])) { 148 is_cid_configured = true; 149 if (i == IPCC_NB_MAX_RIF_CHAN - 1) 150 panic("Inconsistent IPCC CID filtering RIF configuration"); 151 } 152 153 if (is_cid_configured && 154 !(BIT(0) & ipcc_d->conf_data.cid_confs[i])) 155 panic("Inconsistent IPCC CID filtering RIF configuration"); 156 } 157 158 /* IPCC processor 1 CID filtering configuration */ 159 if (!is_tdcid) 160 return; 161 162 io_clrsetbits32(ipcc_d->base + IPCC_C1CIDCFGR, 163 IPCC_CIDCFGR_CONF_MASK, 164 ipcc_d->conf_data.cid_confs[0]); 165 166 /* 167 * Reset this field to evaluate CID filtering configuration 168 * for processor 2 169 */ 170 is_cid_configured = false; 171 172 for (i = IPCC_NB_MAX_RIF_CHAN; i < IPCC_NB_MAX_RIF_CHAN * 2; i++) { 173 if (!(BIT(i) & ipcc_d->conf_data.access_mask[0])) 174 continue; 175 176 if (!is_cid_configured && 177 (BIT(0) & ipcc_d->conf_data.cid_confs[i])) { 178 is_cid_configured = true; 179 if (i == (IPCC_NB_MAX_RIF_CHAN * 2) - 1) 180 panic("Inconsistent IPCC CID filtering RIF configuration"); 181 } 182 183 if (is_cid_configured && 184 !(BIT(0) & ipcc_d->conf_data.cid_confs[i])) 185 panic("Inconsistent IPCC CID filtering RIF configuration"); 186 } 187 188 /* IPCC Processor 2 CID filtering configuration */ 189 io_clrsetbits32(ipcc_d->base + IPCC_C2CIDCFGR, 190 IPCC_CIDCFGR_CONF_MASK, 191 ipcc_d->conf_data.cid_confs[IPCC_NB_MAX_RIF_CHAN]); 192 } 193 194 static void stm32_ipcc_pm_resume(struct ipcc_pdata *ipcc) 195 { 196 apply_rif_config(ipcc, true); 197 } 198 199 static void stm32_ipcc_pm_suspend(struct ipcc_pdata *ipcc __unused) 200 { 201 /* 202 * Do nothing because IPCC forbids RIF configuration read if CID 203 * filtering is enabled. We'll simply restore the device tree RIF 204 * configuration. 205 */ 206 } 207 208 static TEE_Result 209 stm32_ipcc_pm(enum pm_op op, unsigned int pm_hint, 210 const struct pm_callback_handle *pm_handle) 211 { 212 struct ipcc_pdata *ipcc = pm_handle->handle; 213 TEE_Result res = TEE_ERROR_GENERIC; 214 bool is_tdcid = false; 215 216 if (stm32_rifsc_check_tdcid(&is_tdcid)) 217 panic(); 218 219 if (!PM_HINT_IS_STATE(pm_hint, CONTEXT) || !is_tdcid) 220 return TEE_SUCCESS; 221 222 res = clk_enable(ipcc->ipcc_clock); 223 if (res) 224 return res; 225 226 if (op == PM_OP_RESUME) 227 stm32_ipcc_pm_resume(ipcc); 228 else 229 stm32_ipcc_pm_suspend(ipcc); 230 231 clk_disable(ipcc->ipcc_clock); 232 233 return TEE_SUCCESS; 234 } 235 236 static TEE_Result parse_dt(const void *fdt, int node, struct ipcc_pdata *ipcc_d) 237 { 238 int lenp = 0; 239 unsigned int i = 0; 240 TEE_Result res = TEE_ERROR_GENERIC; 241 const fdt32_t *cuint = NULL; 242 struct dt_node_info info = { }; 243 struct io_pa_va addr = { }; 244 245 fdt_fill_device_info(fdt, &info, node); 246 assert(info.reg != DT_INFO_INVALID_REG && 247 info.reg_size != DT_INFO_INVALID_REG_SIZE); 248 249 addr.pa = info.reg; 250 ipcc_d->base = io_pa_or_va_secure(&addr, info.reg_size); 251 assert(ipcc_d->base); 252 253 /* Gate the IP */ 254 res = clk_dt_get_by_index(fdt, node, 0, &ipcc_d->ipcc_clock); 255 if (res) 256 return res; 257 258 cuint = fdt_getprop(fdt, node, "st,protreg", &lenp); 259 if (!cuint) 260 panic("No RIF configuration available"); 261 262 ipcc_d->nb_channels_cfg = (unsigned int)(lenp / sizeof(uint32_t)); 263 assert(ipcc_d->nb_channels_cfg <= (IPCC_NB_MAX_RIF_CHAN * 2)); 264 265 ipcc_d->conf_data.cid_confs = calloc(IPCC_NB_MAX_RIF_CHAN * 2, 266 sizeof(uint32_t)); 267 ipcc_d->conf_data.sec_conf = calloc(1, sizeof(uint32_t)); 268 ipcc_d->conf_data.priv_conf = calloc(1, sizeof(uint32_t)); 269 ipcc_d->conf_data.access_mask = calloc(1, sizeof(uint32_t)); 270 assert(ipcc_d->conf_data.cid_confs && ipcc_d->conf_data.sec_conf && 271 ipcc_d->conf_data.priv_conf && ipcc_d->conf_data.access_mask); 272 273 for (i = 0; i < ipcc_d->nb_channels_cfg; i++) 274 stm32_rif_parse_cfg(fdt32_to_cpu(cuint[i]), &ipcc_d->conf_data, 275 IPCC_NB_MAX_RIF_CHAN * 2); 276 277 return TEE_SUCCESS; 278 } 279 280 static TEE_Result stm32_ipcc_probe(const void *fdt, int node, 281 const void *compat_data __unused) 282 { 283 TEE_Result res = TEE_ERROR_GENERIC; 284 struct ipcc_pdata *ipcc_d = NULL; 285 bool is_tdcid = false; 286 287 res = stm32_rifsc_check_tdcid(&is_tdcid); 288 if (res) 289 return res; 290 291 ipcc_d = calloc(1, sizeof(*ipcc_d)); 292 if (!ipcc_d) 293 return TEE_ERROR_OUT_OF_MEMORY; 294 295 res = parse_dt(fdt, node, ipcc_d); 296 if (res) 297 goto err; 298 299 res = clk_enable(ipcc_d->ipcc_clock); 300 if (res) 301 panic("Cannot access IPCC clock"); 302 303 apply_rif_config(ipcc_d, is_tdcid); 304 305 clk_disable(ipcc_d->ipcc_clock); 306 307 STAILQ_INSERT_TAIL(&ipcc_list, ipcc_d, link); 308 309 register_pm_core_service_cb(stm32_ipcc_pm, ipcc_d, "stm32-ipcc"); 310 311 return res; 312 313 err: 314 /* Free all allocated resources */ 315 free(ipcc_d->conf_data.access_mask); 316 free(ipcc_d->conf_data.cid_confs); 317 free(ipcc_d->conf_data.priv_conf); 318 free(ipcc_d->conf_data.sec_conf); 319 free(ipcc_d); 320 321 return res; 322 } 323 324 static const struct dt_device_match stm32_ipcc_match_table[] = { 325 { .compatible = "st,stm32mp25-ipcc" }, 326 { } 327 }; 328 329 DEFINE_DT_DRIVER(stm32_ipcc_dt_driver) = { 330 .name = "st,stm32mp-ipcc", 331 .match_table = stm32_ipcc_match_table, 332 .probe = stm32_ipcc_probe, 333 }; 334