#include <log.h>
#include <misc.h>
#include <asm/io.h>
+#include <asm/arch/bsec.h>
#include <asm/arch/stm32mp1_smc.h>
#include <linux/arm-smccc.h>
#include <linux/iopoll.h>
#define BSEC_OTP_WRDATA_OFF 0x008
#define BSEC_OTP_STATUS_OFF 0x00C
#define BSEC_OTP_LOCK_OFF 0x010
+#define BSEC_DENABLE_OFF 0x014
#define BSEC_DISTURBED_OFF 0x01C
#define BSEC_ERROR_OFF 0x034
#define BSEC_WRLOCK_OFF 0x04C /* OTP write permananet lock */
#define BSEC_MODE_PROGFAIL_MASK 0x10
#define BSEC_MODE_PWR_MASK 0x20
+/* DENABLE Register */
+#define BSEC_DENABLE_DBGSWENABLE BIT(10)
+
/*
* OTP Lock services definition
* Value must corresponding to the bit number in the register
return !!(readl(address + bank) & bit);
}
-#ifndef CONFIG_TFABOOT
/**
* bsec_check_error() - Check status of one otp
* @base: base address of bsec IP
return ret;
}
-#endif /* CONFIG_TFABOOT */
/* BSEC MISC driver *******************************************************/
struct stm32mp_bsec_platdata {
static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
{
-#ifdef CONFIG_TFABOOT
- return stm32_smc(STM32_SMC_BSEC,
- STM32_SMC_READ_OTP,
- otp, 0, val);
-#else
- struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+ struct stm32mp_bsec_platdata *plat;
u32 tmp_data = 0;
int ret;
+ if (IS_ENABLED(CONFIG_TFABOOT))
+ return stm32_smc(STM32_SMC_BSEC,
+ STM32_SMC_READ_OTP,
+ otp, 0, val);
+
+ plat = dev_get_platdata(dev);
+
/* read current shadow value */
ret = bsec_read_shadow(plat->base, &tmp_data, otp);
if (ret)
/* restore shadow value */
ret = bsec_write_shadow(plat->base, tmp_data, otp);
+
return ret;
-#endif
}
static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
{
-#ifdef CONFIG_TFABOOT
- return stm32_smc(STM32_SMC_BSEC,
- STM32_SMC_READ_SHADOW,
- otp, 0, val);
-#else
- struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+ struct stm32mp_bsec_platdata *plat;
+
+ if (IS_ENABLED(CONFIG_TFABOOT))
+ return stm32_smc(STM32_SMC_BSEC,
+ STM32_SMC_READ_SHADOW,
+ otp, 0, val);
+
+ plat = dev_get_platdata(dev);
return bsec_read_shadow(plat->base, val, otp);
-#endif
}
static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp)
static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp)
{
-#ifdef CONFIG_TFABOOT
- return stm32_smc_exec(STM32_SMC_BSEC,
- STM32_SMC_PROG_OTP,
- otp, val);
-#else
- struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+ struct stm32mp_bsec_platdata *plat;
+
+ if (IS_ENABLED(CONFIG_TFABOOT))
+ return stm32_smc_exec(STM32_SMC_BSEC,
+ STM32_SMC_PROG_OTP,
+ otp, val);
+
+ plat = dev_get_platdata(dev);
return bsec_program_otp(plat->base, val, otp);
-#endif
+
}
static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
{
-#ifdef CONFIG_TFABOOT
- return stm32_smc_exec(STM32_SMC_BSEC,
- STM32_SMC_WRITE_SHADOW,
- otp, val);
-#else
- struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+ struct stm32mp_bsec_platdata *plat;
+
+ if (IS_ENABLED(CONFIG_TFABOOT))
+ return stm32_smc_exec(STM32_SMC_BSEC,
+ STM32_SMC_WRITE_SHADOW,
+ otp, val);
+
+ plat = dev_get_platdata(dev);
return bsec_write_shadow(plat->base, val, otp);
-#endif
}
static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp)
{
-#ifdef CONFIG_TFABOOT
+ if (!IS_ENABLED(CONFIG_TFABOOT))
+ return -ENOTSUPP;
+
if (val == 1)
return stm32_smc_exec(STM32_SMC_BSEC,
STM32_SMC_WRLOCK_OTP,
return 0; /* nothing to do */
return -EINVAL;
-#else
- return -ENOTSUPP;
-#endif
}
static int stm32mp_bsec_read(struct udevice *dev, int offset,
return 0;
}
-#ifndef CONFIG_TFABOOT
static int stm32mp_bsec_probe(struct udevice *dev)
{
int otp;
- struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+ struct stm32mp_bsec_platdata *plat;
- /* update unlocked shadow for OTP cleared by the rom code */
- for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++)
- if (!bsec_read_SR_lock(plat->base, otp))
- bsec_shadow_register(plat->base, otp);
+ /*
+ * update unlocked shadow for OTP cleared by the rom code
+ * only executed in U-Boot proper when TF-A is not used
+ */
+
+ if (!IS_ENABLED(CONFIG_TFABOOT) && !IS_ENABLED(CONFIG_SPL_BUILD)) {
+ plat = dev_get_platdata(dev);
+
+ for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++)
+ if (!bsec_read_SR_lock(plat->base, otp))
+ bsec_shadow_register(plat->base, otp);
+ }
return 0;
}
-#endif
static const struct udevice_id stm32mp_bsec_ids[] = {
{ .compatible = "st,stm32mp15-bsec" },
.id = UCLASS_MISC,
.of_match = stm32mp_bsec_ids,
.ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata,
- .platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata),
+ .platdata_auto = sizeof(struct stm32mp_bsec_platdata),
.ops = &stm32mp_bsec_ops,
-#ifndef CONFIG_TFABOOT
.probe = stm32mp_bsec_probe,
-#endif
};
+
+bool bsec_dbgswenable(void)
+{
+ struct udevice *dev;
+ struct stm32mp_bsec_platdata *plat;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stm32mp_bsec), &dev);
+ if (ret || !dev) {
+ pr_debug("bsec driver not available\n");
+ return false;
+ }
+
+ plat = dev_get_platdata(dev);
+ if (readl(plat->base + BSEC_DENABLE_OFF) & BSEC_DENABLE_DBGSWENABLE)
+ return true;
+
+ return false;
+}