[PATCH u-boot-mvebu 5/5] arm: mvebu: a37xx: Add support for reading Security OTP values

Pali Rohár pali at kernel.org
Thu Feb 17 10:26:19 CET 2022


Only secure CM3 core can access Security OTP. It is not possible via A53
core on which is running U-Boot. Marvell for this purpose defined mbox API
for sending OTP commands between CM and A53 cores.

Implement this Marvell mbox API via U-Boot fuse API.

Banks 0-43 are used for accessing Security OTP (44 rows with 67 bits via 44
banks and words 0-2).

Write support is not implemented yet.

Signed-off-by: Pali Rohár <pali at kernel.org>
---
 arch/arm/mach-mvebu/armada3700/efuse.c | 40 ++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mvebu/armada3700/efuse.c b/arch/arm/mach-mvebu/armada3700/efuse.c
index 03778f17ea49..274d9c72c073 100644
--- a/arch/arm/mach-mvebu/armada3700/efuse.c
+++ b/arch/arm/mach-mvebu/armada3700/efuse.c
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include <linux/delay.h>
+#include <mach/mbox.h>
 #include <mach/soc.h>
 
 #define OTP_NB_REG_BASE		((void __iomem *)MVEBU_REGISTER(0x12600))
@@ -77,6 +78,42 @@ static void otp_read_parallel(void __iomem *base, u32 *data, u32 count)
 	}
 }
 
+static int rwtm_otp_read(u8 row, u32 word, u32 *data)
+{
+	u32 out[3];
+	u32 in[2];
+	int res;
+
+	/*
+	 * MBOX_CMD_OTP_READ_32B command is supported by Marvell fuse.bin
+	 * firmware and also by new (yet unreleased) CZ.NIC wtmi firmware.
+	 * But this command does not provide access to lock bit.
+	 */
+	if (word < 2) {
+		in[0] = row;
+		in[1] = word * 32;
+		res = mbox_do_cmd(MBOX_CMD_OTP_READ_32B, in, 2, out, 2);
+		if (res != -ENOSYS) {
+			if (!res)
+				*data = out[0];
+			return res;
+		}
+		/* Fallback for old version of CZ.NIC wtmi firmware. */
+	}
+
+	/*
+	 * MBOX_CMD_OTP_READ command is supported only by CZ.NIC wtmi firmware
+	 * (in all versions) and provide access to all bits, including lock bit.
+	 * Note that CZ.NIC wtmi firmware may be compiled to disallow access to
+	 * OTP (for security reasons), so this command may fail too.
+	 */
+	in[0] = row;
+	res = mbox_do_cmd(MBOX_CMD_OTP_READ, in, 1, out, 3);
+	if (!res)
+		*data = out[word];
+	return res;
+}
+
 /*
  * Banks 0-43 are used for accessing Security OTP (44 rows with 67 bits via 44 banks and words 0-2)
  * Bank 44 is used for accessing North Bridge OTP (69 bits via words 0-2)
@@ -96,8 +133,7 @@ int fuse_read(u32 bank, u32 word, u32 *val)
 	if (bank <= RWTM_MAX_BANK) {
 		if (word >= RWTM_ROW_WORDS)
 			return -EINVAL;
-		/* TODO: not implemented yet */
-		return -ENOSYS;
+		return rwtm_otp_read(bank, word, val);
 	} else if (bank == OTP_NB_BANK) {
 		u32 data[OTP_NB_WORDS];
 		if (word >= OTP_NB_WORDS)
-- 
2.20.1



More information about the U-Boot mailing list