* [PATCH 2/2] stm32mp1: bsec: add missing dev in function comment
2022-02-15 15:08 [PATCH 1/2] stm32mp: bsec: add permanent lock write support Patrick Delaunay
@ 2022-02-15 15:08 ` Patrick Delaunay
2022-02-23 8:28 ` Patrice CHOTARD
2022-03-15 8:00 ` Patrice CHOTARD
2022-02-16 9:40 ` [PATCH 1/2] stm32mp: bsec: add permanent lock write support Johann Neuhauser
` (2 subsequent siblings)
3 siblings, 2 replies; 7+ messages in thread
From: Patrick Delaunay @ 2022-02-15 15:08 UTC (permalink / raw)
To: u-boot; +Cc: Patrick Delaunay, Patrice Chotard, U-Boot STM32
Add the missing @dev reference in some function description.
Fixes: b66bfdf238b9 ("arm: stm32mp: bsec: migrate trace to log macro")
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---
arch/arm/mach-stm32mp/bsec.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
index fd6e1a3957..506caa0a31 100644
--- a/arch/arm/mach-stm32mp/bsec.c
+++ b/arch/arm/mach-stm32mp/bsec.c
@@ -167,6 +167,7 @@ static int bsec_power_safmem(u32 base, bool power)
/**
* bsec_shadow_register() - copy safmen otp to bsec data
+ * @dev: bsec IP device
* @base: base address of bsec IP
* @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
* Return: 0 if no error
@@ -210,6 +211,7 @@ static int bsec_shadow_register(struct udevice *dev, u32 base, u32 otp)
/**
* bsec_read_shadow() - read an otp data value from shadow
+ * @dev: bsec IP device
* @base: base address of bsec IP
* @val: read value
* @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
@@ -224,6 +226,7 @@ static int bsec_read_shadow(struct udevice *dev, u32 base, u32 *val, u32 otp)
/**
* bsec_write_shadow() - write value in BSEC data register in shadow
+ * @dev: bsec IP device
* @base: base address of bsec IP
* @val: value to write
* @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
@@ -242,6 +245,7 @@ static int bsec_write_shadow(struct udevice *dev, u32 base, u32 val, u32 otp)
/**
* bsec_program_otp() - program a bit in SAFMEM
+ * @dev: bsec IP device
* @base: base address of bsec IP
* @val: value to program
* @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 2/2] stm32mp1: bsec: add missing dev in function comment
2022-02-15 15:08 ` [PATCH 2/2] stm32mp1: bsec: add missing dev in function comment Patrick Delaunay
@ 2022-02-23 8:28 ` Patrice CHOTARD
2022-03-15 8:00 ` Patrice CHOTARD
1 sibling, 0 replies; 7+ messages in thread
From: Patrice CHOTARD @ 2022-02-23 8:28 UTC (permalink / raw)
To: Patrick Delaunay, u-boot; +Cc: U-Boot STM32
Hi Patrick
On 2/15/22 16:08, Patrick Delaunay wrote:
> Add the missing @dev reference in some function description.
>
> Fixes: b66bfdf238b9 ("arm: stm32mp: bsec: migrate trace to log macro")
> Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
>
> arch/arm/mach-stm32mp/bsec.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
> index fd6e1a3957..506caa0a31 100644
> --- a/arch/arm/mach-stm32mp/bsec.c
> +++ b/arch/arm/mach-stm32mp/bsec.c
> @@ -167,6 +167,7 @@ static int bsec_power_safmem(u32 base, bool power)
>
> /**
> * bsec_shadow_register() - copy safmen otp to bsec data
> + * @dev: bsec IP device
> * @base: base address of bsec IP
> * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
> * Return: 0 if no error
> @@ -210,6 +211,7 @@ static int bsec_shadow_register(struct udevice *dev, u32 base, u32 otp)
>
> /**
> * bsec_read_shadow() - read an otp data value from shadow
> + * @dev: bsec IP device
> * @base: base address of bsec IP
> * @val: read value
> * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
> @@ -224,6 +226,7 @@ static int bsec_read_shadow(struct udevice *dev, u32 base, u32 *val, u32 otp)
>
> /**
> * bsec_write_shadow() - write value in BSEC data register in shadow
> + * @dev: bsec IP device
> * @base: base address of bsec IP
> * @val: value to write
> * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
> @@ -242,6 +245,7 @@ static int bsec_write_shadow(struct udevice *dev, u32 base, u32 val, u32 otp)
>
> /**
> * bsec_program_otp() - program a bit in SAFMEM
> + * @dev: bsec IP device
> * @base: base address of bsec IP
> * @val: value to program
> * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
Thanks
Patrice
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 2/2] stm32mp1: bsec: add missing dev in function comment
2022-02-15 15:08 ` [PATCH 2/2] stm32mp1: bsec: add missing dev in function comment Patrick Delaunay
2022-02-23 8:28 ` Patrice CHOTARD
@ 2022-03-15 8:00 ` Patrice CHOTARD
1 sibling, 0 replies; 7+ messages in thread
From: Patrice CHOTARD @ 2022-03-15 8:00 UTC (permalink / raw)
To: Patrick Delaunay, u-boot; +Cc: U-Boot STM32
Hi PAtrick
On 2/15/22 16:08, Patrick Delaunay wrote:
> Add the missing @dev reference in some function description.
>
> Fixes: b66bfdf238b9 ("arm: stm32mp: bsec: migrate trace to log macro")
> Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
>
> arch/arm/mach-stm32mp/bsec.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
> index fd6e1a3957..506caa0a31 100644
> --- a/arch/arm/mach-stm32mp/bsec.c
> +++ b/arch/arm/mach-stm32mp/bsec.c
> @@ -167,6 +167,7 @@ static int bsec_power_safmem(u32 base, bool power)
>
> /**
> * bsec_shadow_register() - copy safmen otp to bsec data
> + * @dev: bsec IP device
> * @base: base address of bsec IP
> * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
> * Return: 0 if no error
> @@ -210,6 +211,7 @@ static int bsec_shadow_register(struct udevice *dev, u32 base, u32 otp)
>
> /**
> * bsec_read_shadow() - read an otp data value from shadow
> + * @dev: bsec IP device
> * @base: base address of bsec IP
> * @val: read value
> * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
> @@ -224,6 +226,7 @@ static int bsec_read_shadow(struct udevice *dev, u32 base, u32 *val, u32 otp)
>
> /**
> * bsec_write_shadow() - write value in BSEC data register in shadow
> + * @dev: bsec IP device
> * @base: base address of bsec IP
> * @val: value to write
> * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
> @@ -242,6 +245,7 @@ static int bsec_write_shadow(struct udevice *dev, u32 base, u32 val, u32 otp)
>
> /**
> * bsec_program_otp() - program a bit in SAFMEM
> + * @dev: bsec IP device
> * @base: base address of bsec IP
> * @val: value to program
> * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
Applied to u-boot-stm32
Thanks
Patrice
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [PATCH 1/2] stm32mp: bsec: add permanent lock write support
2022-02-15 15:08 [PATCH 1/2] stm32mp: bsec: add permanent lock write support Patrick Delaunay
2022-02-15 15:08 ` [PATCH 2/2] stm32mp1: bsec: add missing dev in function comment Patrick Delaunay
@ 2022-02-16 9:40 ` Johann Neuhauser
2022-02-23 8:27 ` Patrice CHOTARD
2022-03-15 8:00 ` Patrice CHOTARD
3 siblings, 0 replies; 7+ messages in thread
From: Johann Neuhauser @ 2022-02-16 9:40 UTC (permalink / raw)
To: Patrick Delaunay, u-boot@lists.denx.de; +Cc: Patrice Chotard, U-Boot STM32
> -----Original Message-----
> From: Patrick Delaunay [mailto:patrick.delaunay@foss.st.com]
> Sent: Tuesday, February 15, 2022 4:09 PM
>
> Add support of the permanent lock support in U-Boot proper
> when BSEC is not managed by secure monitor (TF-A SP_MIN or OP-TEE).
>
> This patch avoid issue with stm32key command and fuse command
> on basic boot for this missing feature of U-Boot BSEC driver.
>
> Reported-by: Johann Neuhauser <jneuhauser@dh-electronics.com>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
>
> arch/arm/mach-stm32mp/bsec.c | 90 +++++++++++++++++++++++++++++++++---
> 1 file changed, 84 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
> index 27d1829501..fd6e1a3957 100644
> --- a/arch/arm/mach-stm32mp/bsec.c
> +++ b/arch/arm/mach-stm32mp/bsec.c
> @@ -18,6 +18,7 @@
> #include <linux/iopoll.h>
>
> #define BSEC_OTP_MAX_VALUE 95
> +#define BSEC_OTP_UPPER_START 32
> #define BSEC_TIMEOUT_US 10000
>
> /* BSEC REGISTER OFFSET (base relative) */
> @@ -41,6 +42,7 @@
> /* BSEC_CONTROL Register */
> #define BSEC_READ 0x000
> #define BSEC_WRITE 0x100
> +#define BSEC_LOCK 0x200
>
> /* LOCK Register */
> #define OTP_LOCK_MASK 0x1F
> @@ -61,6 +63,11 @@
> */
> #define BSEC_LOCK_PROGRAM 0x04
>
> +/*
> + * OTP status: bit 0 permanent lock
> + */
> +#define BSEC_LOCK_PERM BIT(0)
> +
> /**
> * bsec_lock() - manage lock for each type SR/SP/SW
> * @address: address of bsec IP register
> @@ -284,6 +291,65 @@ static int bsec_program_otp(struct udevice *dev, long base, u32 val, u32 otp)
> return ret;
> }
>
> +/**
> + * bsec_permanent_lock_otp() - permanent lock of OTP in SAFMEM
> + * @dev: bsec IP device
> + * @base: base address of bsec IP
> + * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
> + * Return: 0 if no error
> + */
> +static int bsec_permanent_lock_otp(struct udevice *dev, long base, uint32_t otp)
> +{
> + int ret;
> + bool power_up = false;
> + u32 val, addr;
> +
> + /* check if safemem is power up */
> + if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) {
> + ret = bsec_power_safmem(base, true);
> + if (ret)
> + return ret;
> +
> + power_up = true;
> + }
> +
> + /*
> + * low OTPs = 2 bits word for low OTPs, 1 bits per word for upper OTP
> + * and only 16 bits used in WRDATA
> + */
> + if (otp < BSEC_OTP_UPPER_START) {
> + addr = otp / 8;
> + val = 0x03 << ((otp * 2) & 0xF);
> + } else {
> + addr = BSEC_OTP_UPPER_START / 8 +
> + ((otp - BSEC_OTP_UPPER_START) / 16);
> + val = 0x01 << (otp & 0xF);
> + }
> +
> + /* set value in write register*/
> + writel(val, base + BSEC_OTP_WRDATA_OFF);
> +
> + /* set BSEC_OTP_CTRL_OFF with the otp addr and lock request*/
> + writel(addr | BSEC_WRITE | BSEC_LOCK, base + BSEC_OTP_CTRL_OFF);
> +
> + /* check otp status*/
> + ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
> + val, (val & BSEC_MODE_BUSY_MASK) == 0,
> + BSEC_TIMEOUT_US);
> + if (ret)
> + return ret;
> +
> + if (val & BSEC_MODE_PROGFAIL_MASK)
> + ret = -EACCES;
> + else
> + ret = bsec_check_error(base, otp);
> +
> + if (power_up)
> + bsec_power_safmem(base, false);
> +
> + return ret;
> +}
> +
> /* BSEC MISC driver *******************************************************/
> struct stm32mp_bsec_plat {
> u32 base;
> @@ -339,9 +405,14 @@ static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
> static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp)
> {
> struct stm32mp_bsec_plat *plat = dev_get_plat(dev);
> + u32 wrlock;
>
> /* return OTP permanent write lock status */
> - *val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
> + wrlock = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
> +
> + *val = 0;
> + if (wrlock)
> + *val = BSEC_LOCK_PERM;
>
> return 0;
> }
> @@ -377,15 +448,22 @@ static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
>
> static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp)
> {
> - if (!IS_ENABLED(CONFIG_ARM_SMCCC) || IS_ENABLED(CONFIG_SPL_BUILD))
> - return -ENOTSUPP;
> + struct stm32mp_bsec_plat *plat;
> +
> + /* only permanent write lock is supported in U-Boot */
> + if (!(val & BSEC_LOCK_PERM)) {
> + dev_dbg(dev, "lock option without BSEC_LOCK_PERM: %x\n", val);
> + return 0; /* nothing to do */
> + }
>
> - if (val == 1)
> + if (IS_ENABLED(CONFIG_ARM_SMCCC) && !IS_ENABLED(CONFIG_SPL_BUILD))
> return stm32_smc_exec(STM32_SMC_BSEC,
> STM32_SMC_WRLOCK_OTP,
> otp, 0);
> - if (val == 0)
> - return 0; /* nothing to do */
> +
> + plat = dev_get_plat(dev);
> +
> + return bsec_permanent_lock_otp(dev, plat->base, otp);
>
> return -EINVAL;
> }
> --
> 2.25.1
Tested-by: Johann Neuhauser <jneuhauser@dh-electronics.com>
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 1/2] stm32mp: bsec: add permanent lock write support
2022-02-15 15:08 [PATCH 1/2] stm32mp: bsec: add permanent lock write support Patrick Delaunay
2022-02-15 15:08 ` [PATCH 2/2] stm32mp1: bsec: add missing dev in function comment Patrick Delaunay
2022-02-16 9:40 ` [PATCH 1/2] stm32mp: bsec: add permanent lock write support Johann Neuhauser
@ 2022-02-23 8:27 ` Patrice CHOTARD
2022-03-15 8:00 ` Patrice CHOTARD
3 siblings, 0 replies; 7+ messages in thread
From: Patrice CHOTARD @ 2022-02-23 8:27 UTC (permalink / raw)
To: Patrick Delaunay, u-boot; +Cc: Johann Neuhauser, U-Boot STM32
Hi Patrick
2 minor remarks below
On 2/15/22 16:08, Patrick Delaunay wrote:
> Add support of the permanent lock support in U-Boot proper
> when BSEC is not managed by secure monitor (TF-A SP_MIN or OP-TEE).
>
> This patch avoid issue with stm32key command and fuse command
s/avoid/avoids
> on basic boot for this missing feature of U-Boot BSEC driver.
>
> Reported-by: Johann Neuhauser <jneuhauser@dh-electronics.com>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
>
> arch/arm/mach-stm32mp/bsec.c | 90 +++++++++++++++++++++++++++++++++---
> 1 file changed, 84 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
> index 27d1829501..fd6e1a3957 100644
> --- a/arch/arm/mach-stm32mp/bsec.c
> +++ b/arch/arm/mach-stm32mp/bsec.c
> @@ -18,6 +18,7 @@
> #include <linux/iopoll.h>
>
> #define BSEC_OTP_MAX_VALUE 95
> +#define BSEC_OTP_UPPER_START 32
> #define BSEC_TIMEOUT_US 10000
>
> /* BSEC REGISTER OFFSET (base relative) */
> @@ -41,6 +42,7 @@
> /* BSEC_CONTROL Register */
> #define BSEC_READ 0x000
> #define BSEC_WRITE 0x100
> +#define BSEC_LOCK 0x200
>
> /* LOCK Register */
> #define OTP_LOCK_MASK 0x1F
> @@ -61,6 +63,11 @@
> */
> #define BSEC_LOCK_PROGRAM 0x04
>
> +/*
> + * OTP status: bit 0 permanent lock
> + */
> +#define BSEC_LOCK_PERM BIT(0)
> +
> /**
> * bsec_lock() - manage lock for each type SR/SP/SW
> * @address: address of bsec IP register
> @@ -284,6 +291,65 @@ static int bsec_program_otp(struct udevice *dev, long base, u32 val, u32 otp)
> return ret;
> }
>
> +/**
> + * bsec_permanent_lock_otp() - permanent lock of OTP in SAFMEM
> + * @dev: bsec IP device
> + * @base: base address of bsec IP
> + * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
> + * Return: 0 if no error
> + */
> +static int bsec_permanent_lock_otp(struct udevice *dev, long base, uint32_t otp)
> +{
> + int ret;
> + bool power_up = false;
> + u32 val, addr;
> +
> + /* check if safemem is power up */
> + if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) {
> + ret = bsec_power_safmem(base, true);
> + if (ret)
> + return ret;
> +
> + power_up = true;
> + }
> +
> + /*
> + * low OTPs = 2 bits word for low OTPs, 1 bits per word for upper OTP
s/2 bits word/2 bits per word
> + * and only 16 bits used in WRDATA
> + */
> + if (otp < BSEC_OTP_UPPER_START) {
> + addr = otp / 8;
> + val = 0x03 << ((otp * 2) & 0xF);
> + } else {
> + addr = BSEC_OTP_UPPER_START / 8 +
> + ((otp - BSEC_OTP_UPPER_START) / 16);
> + val = 0x01 << (otp & 0xF);
> + }
> +
> + /* set value in write register*/
> + writel(val, base + BSEC_OTP_WRDATA_OFF);
> +
> + /* set BSEC_OTP_CTRL_OFF with the otp addr and lock request*/
> + writel(addr | BSEC_WRITE | BSEC_LOCK, base + BSEC_OTP_CTRL_OFF);
> +
> + /* check otp status*/
> + ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
> + val, (val & BSEC_MODE_BUSY_MASK) == 0,
> + BSEC_TIMEOUT_US);
> + if (ret)
> + return ret;
> +
> + if (val & BSEC_MODE_PROGFAIL_MASK)
> + ret = -EACCES;
> + else
> + ret = bsec_check_error(base, otp);
> +
> + if (power_up)
> + bsec_power_safmem(base, false);
> +
> + return ret;
> +}
> +
> /* BSEC MISC driver *******************************************************/
> struct stm32mp_bsec_plat {
> u32 base;
> @@ -339,9 +405,14 @@ static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
> static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp)
> {
> struct stm32mp_bsec_plat *plat = dev_get_plat(dev);
> + u32 wrlock;
>
> /* return OTP permanent write lock status */
> - *val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
> + wrlock = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
> +
> + *val = 0;
> + if (wrlock)
> + *val = BSEC_LOCK_PERM;
>
> return 0;
> }
> @@ -377,15 +448,22 @@ static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
>
> static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp)
> {
> - if (!IS_ENABLED(CONFIG_ARM_SMCCC) || IS_ENABLED(CONFIG_SPL_BUILD))
> - return -ENOTSUPP;
> + struct stm32mp_bsec_plat *plat;
> +
> + /* only permanent write lock is supported in U-Boot */
> + if (!(val & BSEC_LOCK_PERM)) {
> + dev_dbg(dev, "lock option without BSEC_LOCK_PERM: %x\n", val);
> + return 0; /* nothing to do */
> + }
>
> - if (val == 1)
> + if (IS_ENABLED(CONFIG_ARM_SMCCC) && !IS_ENABLED(CONFIG_SPL_BUILD))
> return stm32_smc_exec(STM32_SMC_BSEC,
> STM32_SMC_WRLOCK_OTP,
> otp, 0);
> - if (val == 0)
> - return 0; /* nothing to do */
> +
> + plat = dev_get_plat(dev);
> +
> + return bsec_permanent_lock_otp(dev, plat->base, otp);
>
> return -EINVAL;
> }
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
Thanks
Patrice
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 1/2] stm32mp: bsec: add permanent lock write support
2022-02-15 15:08 [PATCH 1/2] stm32mp: bsec: add permanent lock write support Patrick Delaunay
` (2 preceding siblings ...)
2022-02-23 8:27 ` Patrice CHOTARD
@ 2022-03-15 8:00 ` Patrice CHOTARD
3 siblings, 0 replies; 7+ messages in thread
From: Patrice CHOTARD @ 2022-03-15 8:00 UTC (permalink / raw)
To: Patrick Delaunay, u-boot; +Cc: Johann Neuhauser, U-Boot STM32
HI Patrick
On 2/15/22 16:08, Patrick Delaunay wrote:
> Add support of the permanent lock support in U-Boot proper
> when BSEC is not managed by secure monitor (TF-A SP_MIN or OP-TEE).
>
> This patch avoid issue with stm32key command and fuse command
> on basic boot for this missing feature of U-Boot BSEC driver.
>
> Reported-by: Johann Neuhauser <jneuhauser@dh-electronics.com>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
>
> arch/arm/mach-stm32mp/bsec.c | 90 +++++++++++++++++++++++++++++++++---
> 1 file changed, 84 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
> index 27d1829501..fd6e1a3957 100644
> --- a/arch/arm/mach-stm32mp/bsec.c
> +++ b/arch/arm/mach-stm32mp/bsec.c
> @@ -18,6 +18,7 @@
> #include <linux/iopoll.h>
>
> #define BSEC_OTP_MAX_VALUE 95
> +#define BSEC_OTP_UPPER_START 32
> #define BSEC_TIMEOUT_US 10000
>
> /* BSEC REGISTER OFFSET (base relative) */
> @@ -41,6 +42,7 @@
> /* BSEC_CONTROL Register */
> #define BSEC_READ 0x000
> #define BSEC_WRITE 0x100
> +#define BSEC_LOCK 0x200
>
> /* LOCK Register */
> #define OTP_LOCK_MASK 0x1F
> @@ -61,6 +63,11 @@
> */
> #define BSEC_LOCK_PROGRAM 0x04
>
> +/*
> + * OTP status: bit 0 permanent lock
> + */
> +#define BSEC_LOCK_PERM BIT(0)
> +
> /**
> * bsec_lock() - manage lock for each type SR/SP/SW
> * @address: address of bsec IP register
> @@ -284,6 +291,65 @@ static int bsec_program_otp(struct udevice *dev, long base, u32 val, u32 otp)
> return ret;
> }
>
> +/**
> + * bsec_permanent_lock_otp() - permanent lock of OTP in SAFMEM
> + * @dev: bsec IP device
> + * @base: base address of bsec IP
> + * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
> + * Return: 0 if no error
> + */
> +static int bsec_permanent_lock_otp(struct udevice *dev, long base, uint32_t otp)
> +{
> + int ret;
> + bool power_up = false;
> + u32 val, addr;
> +
> + /* check if safemem is power up */
> + if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) {
> + ret = bsec_power_safmem(base, true);
> + if (ret)
> + return ret;
> +
> + power_up = true;
> + }
> +
> + /*
> + * low OTPs = 2 bits word for low OTPs, 1 bits per word for upper OTP
> + * and only 16 bits used in WRDATA
> + */
> + if (otp < BSEC_OTP_UPPER_START) {
> + addr = otp / 8;
> + val = 0x03 << ((otp * 2) & 0xF);
> + } else {
> + addr = BSEC_OTP_UPPER_START / 8 +
> + ((otp - BSEC_OTP_UPPER_START) / 16);
> + val = 0x01 << (otp & 0xF);
> + }
> +
> + /* set value in write register*/
> + writel(val, base + BSEC_OTP_WRDATA_OFF);
> +
> + /* set BSEC_OTP_CTRL_OFF with the otp addr and lock request*/
> + writel(addr | BSEC_WRITE | BSEC_LOCK, base + BSEC_OTP_CTRL_OFF);
> +
> + /* check otp status*/
> + ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
> + val, (val & BSEC_MODE_BUSY_MASK) == 0,
> + BSEC_TIMEOUT_US);
> + if (ret)
> + return ret;
> +
> + if (val & BSEC_MODE_PROGFAIL_MASK)
> + ret = -EACCES;
> + else
> + ret = bsec_check_error(base, otp);
> +
> + if (power_up)
> + bsec_power_safmem(base, false);
> +
> + return ret;
> +}
> +
> /* BSEC MISC driver *******************************************************/
> struct stm32mp_bsec_plat {
> u32 base;
> @@ -339,9 +405,14 @@ static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
> static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp)
> {
> struct stm32mp_bsec_plat *plat = dev_get_plat(dev);
> + u32 wrlock;
>
> /* return OTP permanent write lock status */
> - *val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
> + wrlock = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
> +
> + *val = 0;
> + if (wrlock)
> + *val = BSEC_LOCK_PERM;
>
> return 0;
> }
> @@ -377,15 +448,22 @@ static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
>
> static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp)
> {
> - if (!IS_ENABLED(CONFIG_ARM_SMCCC) || IS_ENABLED(CONFIG_SPL_BUILD))
> - return -ENOTSUPP;
> + struct stm32mp_bsec_plat *plat;
> +
> + /* only permanent write lock is supported in U-Boot */
> + if (!(val & BSEC_LOCK_PERM)) {
> + dev_dbg(dev, "lock option without BSEC_LOCK_PERM: %x\n", val);
> + return 0; /* nothing to do */
> + }
>
> - if (val == 1)
> + if (IS_ENABLED(CONFIG_ARM_SMCCC) && !IS_ENABLED(CONFIG_SPL_BUILD))
> return stm32_smc_exec(STM32_SMC_BSEC,
> STM32_SMC_WRLOCK_OTP,
> otp, 0);
> - if (val == 0)
> - return 0; /* nothing to do */
> +
> + plat = dev_get_plat(dev);
> +
> + return bsec_permanent_lock_otp(dev, plat->base, otp);
>
> return -EINVAL;
> }
Applied to u-boot-stm32
Thanks
Patrice
^ permalink raw reply [flat|nested] 7+ messages in thread