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 <p...@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

Reply via email to