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