misc: fuse: Lock 8ULP ECC-protected fuse when programming
authorYe Li <ye.li@nxp.com>
Tue, 31 Jan 2023 08:42:28 +0000 (16:42 +0800)
committerStefano Babic <sbabic@denx.de>
Wed, 29 Mar 2023 18:15:42 +0000 (20:15 +0200)
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

index aa691d3..99342d3 100644 (file)
@@ -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;