summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-mvebu/efuse.c43
-rw-r--r--arch/arm/mach-mvebu/include/mach/efuse.h4
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