
On 4/6/22 14:18, Pali Rohár wrote:
Armada 385 contains 64 lines of HD eFuse and 2 lines of LD eFuse. HD eFuse is used for secure boot and each line is 64 bits long + 1 lock bit. LD eFuse lines are 256 bits long + 1 lock bit. LD 0 line is reserved for Marvell Internal Use and LD 1 line is for General Purpose Data. U-Boot already contains HD eFuse reading and programming support.
This patch implements LD eFuse reading support. LD 0 line is mapped to U-Boot fuse bank 64 and LD 1 line to fuse bank 65.
LD 0 Marvell Internal Use line seems that was burned in factory with some data and can be read by U-Boot fuse command:
=> fuse read 64 0 9
LD 1 General Purpose Data line is by default empty and can be read by U-Boot fuse command:
=> fuse read 65 0 9
Signed-off-by: Pali Rohár pali@kernel.org
Applied to u-boot-marvell/master
Thanks, Stefan
arch/arm/mach-mvebu/efuse.c | 28 ++++++++++++++++++++++++ arch/arm/mach-mvebu/include/mach/efuse.h | 5 +++++ 2 files changed, 33 insertions(+)
diff --git a/arch/arm/mach-mvebu/efuse.c b/arch/arm/mach-mvebu/efuse.c index c79eee98fe98..80318c339eb7 100644 --- a/arch/arm/mach-mvebu/efuse.c +++ b/arch/arm/mach-mvebu/efuse.c @@ -27,6 +27,7 @@
enum { MVEBU_EFUSE_CTRL_PROGRAM_ENABLE = (1 << 31),
MVEBU_EFUSE_LD1_SELECT = (1 << 6), };
struct mvebu_hd_efuse {
@@ -39,8 +40,10 @@ struct mvebu_hd_efuse { #ifndef DRY_RUN static struct mvebu_hd_efuse *efuses = (struct mvebu_hd_efuse *)(MBUS_EFUSE_BASE + 0xF9000); +static u32 *ld_efuses = (void *)MBUS_EFUSE_BASE + 0xF8F00; #else static struct mvebu_hd_efuse efuses[EFUSE_LINE_MAX + 1]; +static u32 ld_efuses[EFUSE_LD_WORDS]; #endif
static int efuse_initialised; @@ -169,6 +172,21 @@ int mvebu_read_efuse(int nr, struct efuse_val *val) return 0; }
+void mvebu_read_ld_efuse(int ld1, u32 *line) +{
- int i;
+#ifndef DRY_RUN
- if (ld1)
setbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_LD1_SELECT);
- else
clrbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_LD1_SELECT);
+#endif
- for (i = 0; i < EFUSE_LD_WORDS; i++)
line[i] = readl(ld_efuses + i);
+}
- int mvebu_write_efuse(int nr, struct efuse_val *val) { return prog_efuse(nr, val, ~0, ~0);
@@ -199,8 +217,18 @@ static int valid_prog_words; int fuse_read(u32 bank, u32 word, u32 *val) { struct efuse_val fuse_line;
u32 ld_line[EFUSE_LD_WORDS]; int res;
if ((bank == EFUSE_LD0_LINE || bank == EFUSE_LD1_LINE) && word < EFUSE_LD_WORDS) {
res = mvebu_efuse_init_hw();
if (res)
return res;
mvebu_read_ld_efuse(bank == EFUSE_LD1_LINE, ld_line);
*val = ld_line[word];
return 0;
}
if (bank < EFUSE_LINE_MIN || bank > EFUSE_LINE_MAX || word > 2) return -EINVAL;
diff --git a/arch/arm/mach-mvebu/include/mach/efuse.h b/arch/arm/mach-mvebu/include/mach/efuse.h index bbc5844d849c..122e735f2fc7 100644 --- a/arch/arm/mach-mvebu/include/mach/efuse.h +++ b/arch/arm/mach-mvebu/include/mach/efuse.h @@ -53,8 +53,13 @@ enum efuse_line {
EFUSE_LINE_MIN = 0, EFUSE_LINE_MAX = 63,
- EFUSE_LD0_LINE = 64,
- EFUSE_LD1_LINE = 65, };
+#define EFUSE_LD_WORDS 9
#endif
int mvebu_efuse_init_hw(void);
Viele Grüße, Stefan Roese