diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-mvebu/efuse.c | 43 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/include/mach/efuse.h | 4 |
2 files changed, 47 insertions, 0 deletions
diff --git a/arch/arm/mach-mvebu/efuse.c b/arch/arm/mach-mvebu/efuse.c index 80318c339eb..4b043378217 100644 --- a/arch/arm/mach-mvebu/efuse.c +++ b/arch/arm/mach-mvebu/efuse.c @@ -132,6 +132,46 @@ static int prog_efuse(int nr, struct efuse_val *new_val, u32 mask0, u32 mask1) return res; } +int mvebu_prog_ld_efuse(int ld1, u32 word, u32 val) +{ + int i, res; + u32 line[EFUSE_LD_WORDS]; + + res = mvebu_efuse_init_hw(); + if (res) + return res; + + mvebu_read_ld_efuse(ld1, line); + + /* check if lock bit is already programmed */ + if (line[EFUSE_LD_WORDS - 1]) + return -EPERM; + + /* check if word is valid */ + if (word >= EFUSE_LD_WORDS) + return -EINVAL; + + /* check if there is some bit for programming */ + if (val == (line[word] & val)) + return 0; + + enable_efuse_program(); + + mvebu_read_ld_efuse(ld1, line); + line[word] |= val; + + for (i = 0; i < EFUSE_LD_WORDS; i++) { + writel(line[i], ld_efuses + i); + mdelay(1); + } + + mdelay(5); + + disable_efuse_program(); + + return 0; +} + int mvebu_efuse_init_hw(void) { int ret; @@ -254,6 +294,9 @@ int fuse_prog(u32 bank, u32 word, u32 val) { int res = 0; + if (bank == EFUSE_LD0_LINE || bank == EFUSE_LD1_LINE) + return mvebu_prog_ld_efuse(bank == EFUSE_LD1_LINE, word, val); + /* * NOTE: Fuse line should be written as whole. * So how can we do that with this API? diff --git a/arch/arm/mach-mvebu/include/mach/efuse.h b/arch/arm/mach-mvebu/include/mach/efuse.h index 122e735f2fc..b125c30beb8 100644 --- a/arch/arm/mach-mvebu/include/mach/efuse.h +++ b/arch/arm/mach-mvebu/include/mach/efuse.h @@ -70,4 +70,8 @@ int mvebu_write_efuse(int nr, struct efuse_val *val); int mvebu_lock_efuse(int nr); +void mvebu_read_ld_efuse(int ld1, u32 *line); + +int mvebu_prog_ld_efuse(int ld1, u32 word, u32 val); + #endif |