From 5aceeee7e8bb44d3b3e67cff350e04cf0579da37 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 19 Oct 2021 10:43:38 +0200 Subject: [PATCH] nvmem: stm32: detect bsec pta presence for stm32mp15 On STM32MP15, the SMC backend is optional when OP-TEE is used; the PTA BSEC should be used as it is done on STM32MP13 platform, but the BSEC SMC can be also used: it is a legacy mode in OP-TEE, not recommended but used in previous OP-TEE firmware. The presence of OP-TEE is dynamically detected in STM32MP15x device tree and the supported NVMEM backend is dynamically detected: - PTA with stm32_bsec_pta_find - SMC with stm32_bsec_check Without PTA and SMC detection, the probe is defered for STM32MP15 device. On STM32MP13x platform, only the PTA is supported with cfg->ta = true and this detection is skipped. Signed-off-by: Patrick Delaunay Change-Id: I59210046e368cfc22bd3cca2afe1653674f8ece8 Reviewed-on: https://gerrit.st.com/c/mpu/oe/st/linux-stm32/+/266103 Reviewed-by: CITOOLS --- drivers/nvmem/stm32-romem.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c index dfdedbcca9b9..4a6ce6fee281 100644 --- a/drivers/nvmem/stm32-romem.c +++ b/drivers/nvmem/stm32-romem.c @@ -73,6 +73,17 @@ static int stm32_bsec_smc(u8 op, u32 otp, u32 data, u32 *result) #endif } +static bool stm32_bsec_check(void) +{ + u32 val; + int ret; + + /* check that the OP-TEE support the BSEC SMC (legacy mode) */ + ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val); + + return !ret; +} + static int stm32_bsec_read(void *context, unsigned int offset, void *buf, size_t bytes) { @@ -147,6 +158,20 @@ static int stm32_bsec_write(void *context, unsigned int offset, void *buf, return 0; } +static bool optee_presence_check(void) +{ + struct device_node *np; + bool tee_detected = false; + + /* check that the OP-TEE node is present and available. */ + np = of_find_node_by_path("/firmware/optee"); + if (np && of_device_is_available(np)) + tee_detected = true; + of_node_put(np); + + return tee_detected; +} + static int stm32_romem_probe(struct platform_device *pdev) { const struct stm32_romem_cfg *cfg; @@ -182,12 +207,16 @@ static int stm32_romem_probe(struct platform_device *pdev) } else { priv->cfg.size = cfg->size; priv->lower = cfg->lower; - if (cfg->ta) { + if (cfg->ta || optee_presence_check()) { priv->ta = stm32_bsec_pta_find(dev); /* wait for OP-TEE client driver to be up and ready */ - if (!priv->ta) - return -EPROBE_DEFER; - + if (!priv->ta) { + /* BSEC PTA is required or SMC not ready */ + if (cfg->ta || !stm32_bsec_check()) + return -EPROBE_DEFER; + } + } + if (priv->ta) { priv->cfg.reg_read = stm32_bsec_pta_read; priv->cfg.reg_write = stm32_bsec_pta_write; } else {