2 * Copyright (C) 2013-2014 ROCKCHIP, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
9 #include <linux/delay.h>
10 #include <linux/rockchip/cpu.h>
11 #include <linux/rockchip/iomap.h>
14 #define efuse_readl(offset) readl_relaxed(RK_EFUSE_VIRT + offset)
15 #define efuse_writel(val, offset) writel_relaxed(val, RK_EFUSE_VIRT + offset)
17 static u8 efuse_buf[32] = {};
19 struct rockchip_efuse {
20 int (*get_leakage)(int ch);
24 static struct rockchip_efuse efuse;
26 static int __init rk3288_efuse_readregs(u32 addr, u32 length, u8 *buf)
35 efuse_writel(EFUSE_CSB, REG_EFUSE_CTRL);
36 efuse_writel(EFUSE_LOAD | EFUSE_PGENB, REG_EFUSE_CTRL);
39 efuse_writel(efuse_readl(REG_EFUSE_CTRL) &
40 (~(EFUSE_A_MASK << EFUSE_A_SHIFT)), REG_EFUSE_CTRL);
41 efuse_writel(efuse_readl(REG_EFUSE_CTRL) |
42 ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT),
45 efuse_writel(efuse_readl(REG_EFUSE_CTRL) |
46 EFUSE_STROBE, REG_EFUSE_CTRL);
48 *buf = efuse_readl(REG_EFUSE_DOUT);
49 efuse_writel(efuse_readl(REG_EFUSE_CTRL) &
50 (~EFUSE_STROBE), REG_EFUSE_CTRL);
56 efuse_writel(efuse_readl(REG_EFUSE_CTRL) | EFUSE_CSB, REG_EFUSE_CTRL);
62 static int __init rk3288_get_efuse_version(void)
64 int ret = efuse_buf[4] & (~(0x1 << 3));
68 static int rk3288_get_leakage(int ch)
70 if ((ch < 0) || (ch > 2))
73 return efuse_buf[23+ch];
76 int rockchip_efuse_version(void)
78 return efuse.efuse_version;
81 int rockchip_get_leakage(int ch)
83 if (efuse.get_leakage)
84 return efuse.get_leakage(ch);
88 void __init rockchip_efuse_init(void)
92 if (cpu_is_rk3288()) {
93 ret = rk3288_efuse_readregs(0, 32, efuse_buf);
95 efuse.get_leakage = rk3288_get_leakage;
96 efuse.efuse_version = rk3288_get_efuse_version();
97 rockchip_set_cpu_version((efuse_buf[6] >> 4) & 3);
99 pr_err("failed to read eFuse, return %d\n", ret);