diff mbox series

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

Message ID 1675154554-88217-18-git-send-email-ye.li@nxp.com
State Accepted
Commit 39f700e801f23e4bf7c6f86684f8884935a53cbb
Delegated to: Stefano Babic
Headers show
Series Add i.MX8ULP A1 revision support | expand

Commit Message

Ye Li Jan. 31, 2023, 8:42 a.m. UTC
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(-)

Comments

Stefano Babic March 29, 2023, 8:15 p.m. UTC | #1
> 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>
Applied to u-boot-imx, -next, thanks !

Best regards,
Stefano Babic
diff mbox series

Patch

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;