[PATCH 17/23] misc: fuse: Lock 8ULP ECC-protected fuse when programming

Ye Li
2023-01-31T08:50:37Z

The ECC fuse on 8ULP can't be written twice. If any user did it, the
ECC value would be wrong then cause accessing problem to the fuse.
The patch will lock the ECC fuse word to avoid this problem.
For iMX9, the OTP controller automatically prevents an ECC fuse word to
be written twice. So it does not need the setting.

Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
---
drivers/misc/sentinel/fuse.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/sentinel/fuse.c b/drivers/misc/sentinel/fuse.c
index aa691d3..99342d3 100644
--- a/drivers/misc/sentinel/fuse.c
+++ b/drivers/misc/sentinel/fuse.c
@@ -60,6 +60,11 @@ struct fsb_map_entry fsb_mapping_table[] = {
{ 46, 8 },
};

+/* None ECC banks such like Redundancy or Bit protect */
+u32 nonecc_fuse_banks[] = {
+ 0, 1, 8, 12, 16, 22, 24, 25, 26, 27, 36, 41, 51, 56
+};
+
struct s400_map_entry s400_api_mapping_table[] = {
{ 1, 8 }, /* LOCK */
{ 2, 8 }, /* ECID */
@@ -280,11 +285,26 @@ int fuse_prog(u32 bank, u32 word, u32 val)
{
u32 res;
int ret;
+ bool lock = false;

if (bank >= FUSE_BANKS || word >= WORDS_PER_BANKS || !val)
return -EINVAL;

- ret = ahab_write_fuse((bank * 8 + word), val, false, &res);
+ /* Lock 8ULP ECC fuse word, so second programming will return failure.
+ * iMX9 OTP can protect ECC fuse, so not need it
+ */
+#if defined(CONFIG_IMX8ULP)
+ u32 i;
+ for (i = 0; i < ARRAY_SIZE(nonecc_fuse_banks); i++) {
+ if (nonecc_fuse_banks[i] == bank)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(nonecc_fuse_banks))
+ lock = true;
+#endif
+
+ ret = ahab_write_fuse((bank * 8 + word), val, lock, &res);
if (ret) {
printf("ahab write fuse failed %d, 0x%x\n", ret, res);
return ret;
--
2.7.4