[PATCH 2/2] rockchip: efuse: Add support for rk1808 non-secure efuse
Finley Xiao
finley.xiao at rock-chips.com
Thu Feb 20 03:38:07 CET 2020
This adds the necessary data for handling eFuse on the rk1808.
Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
---
drivers/misc/rockchip-efuse.c | 114 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index 68762d3f6f..778e29f30d 100644
--- a/drivers/misc/rockchip-efuse.c
+++ b/drivers/misc/rockchip-efuse.c
@@ -16,6 +16,46 @@
#include <malloc.h>
#include <misc.h>
+#define T_CSB_P_S 0
+#define T_PGENB_P_S 0
+#define T_LOAD_P_S 0
+#define T_ADDR_P_S 0
+#define T_STROBE_P_S (0 + 110) /* 1.1us */
+#define T_CSB_P_L (0 + 110 + 1000 + 20) /* 200ns */
+#define T_PGENB_P_L (0 + 110 + 1000 + 20)
+#define T_LOAD_P_L (0 + 110 + 1000 + 20)
+#define T_ADDR_P_L (0 + 110 + 1000 + 20)
+#define T_STROBE_P_L (0 + 110 + 1000) /* 10us */
+#define T_CSB_R_S 0
+#define T_PGENB_R_S 0
+#define T_LOAD_R_S 0
+#define T_ADDR_R_S 2
+#define T_STROBE_R_S (2 + 3)
+#define T_CSB_R_L (2 + 3 + 3 + 3)
+#define T_PGENB_R_L (2 + 3 + 3 + 3)
+#define T_LOAD_R_L (2 + 3 + 3 + 3)
+#define T_ADDR_R_L (2 + 3 + 3 + 2)
+#define T_STROBE_R_L (2 + 3 + 3)
+
+#define T_CSB_P 0x28
+#define T_PGENB_P 0x2c
+#define T_LOAD_P 0x30
+#define T_ADDR_P 0x34
+#define T_STROBE_P 0x38
+#define T_CSB_R 0x3c
+#define T_PGENB_R 0x40
+#define T_LOAD_R 0x44
+#define T_ADDR_R 0x48
+#define T_STROBE_R 0x4c
+
+#define RK1808_USER_MODE BIT(0)
+#define RK1808_INT_FINISH BIT(0)
+#define RK1808_AUTO_ENB BIT(0)
+#define RK1808_AUTO_RD BIT(1)
+#define RK1808_A_SHIFT 16
+#define RK1808_A_MASK 0x3ff
+#define RK1808_NBYTES 4
+
#define RK3288_A_SHIFT 6
#define RK3288_A_MASK 0x3ff
#define RK3288_NFUSES 32
@@ -109,6 +149,76 @@ U_BOOT_CMD(
);
#endif
+static void rk1808_efuse_timing_init(void __iomem *base)
+{
+ static bool init;
+
+ if (init)
+ return;
+
+ /* enable auto mode */
+ writel(readl(base) & (~RK1808_USER_MODE), base);
+
+ /* setup efuse timing */
+ writel((T_CSB_P_S << 16) | T_CSB_P_L, base + T_CSB_P);
+ writel((T_PGENB_P_S << 16) | T_PGENB_P_L, base + T_PGENB_P);
+ writel((T_LOAD_P_S << 16) | T_LOAD_P_L, base + T_LOAD_P);
+ writel((T_ADDR_P_S << 16) | T_ADDR_P_L, base + T_ADDR_P);
+ writel((T_STROBE_P_S << 16) | T_STROBE_P_L, base + T_STROBE_P);
+ writel((T_CSB_R_S << 16) | T_CSB_R_L, base + T_CSB_R);
+ writel((T_PGENB_R_S << 16) | T_PGENB_R_L, base + T_PGENB_R);
+ writel((T_LOAD_R_S << 16) | T_LOAD_R_L, base + T_LOAD_R);
+ writel((T_ADDR_R_S << 16) | T_ADDR_R_L, base + T_ADDR_R);
+ writel((T_STROBE_R_S << 16) | T_STROBE_R_L, base + T_STROBE_R);
+
+ init = true;
+}
+
+static int rockchip_rk1808_efuse_read(struct udevice *dev, int offset,
+ void *buf, int size)
+{
+ struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
+ struct rockchip_efuse_regs *efuse =
+ (struct rockchip_efuse_regs *)plat->base;
+ unsigned int addr_start, addr_end, addr_offset, addr_len;
+ u32 out_value, status;
+ u8 *buffer;
+ int ret = 0, i = 0;
+
+ rk1808_efuse_timing_init(plat->base);
+
+ addr_start = rounddown(offset, RK1808_NBYTES) / RK1808_NBYTES;
+ addr_end = roundup(offset + size, RK1808_NBYTES) / RK1808_NBYTES;
+ addr_offset = offset % RK1808_NBYTES;
+ addr_len = addr_end - addr_start;
+
+ buffer = calloc(1, sizeof(*buffer) * addr_len * RK1808_NBYTES);
+ if (!buffer)
+ return -ENOMEM;
+
+ while (addr_len--) {
+ writel(RK1808_AUTO_RD | RK1808_AUTO_ENB |
+ ((addr_start++ & RK1808_A_MASK) << RK1808_A_SHIFT),
+ &efuse->auto_ctrl);
+ udelay(2);
+ status = readl(&efuse->int_status);
+ if (!(status & RK1808_INT_FINISH)) {
+ ret = -EIO;
+ goto err;
+ }
+ out_value = readl(&efuse->dout2);
+ writel(RK1808_INT_FINISH, &efuse->int_status);
+
+ memcpy(&buffer[i], &out_value, RK1808_NBYTES);
+ i += RK1808_NBYTES;
+ }
+ memcpy(buf, buffer + addr_offset, size);
+err:
+ free(buffer);
+
+ return ret;
+}
+
static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset,
void *buf, int size)
{
@@ -273,6 +383,10 @@ static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev)
static const struct udevice_id rockchip_efuse_ids[] = {
{
+ .compatible = "rockchip,rk1808-efuse",
+ .data = (ulong)&rockchip_rk1808_efuse_read,
+ },
+ {
.compatible = "rockchip,rk3066a-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
},
--
2.11.0
More information about the U-Boot
mailing list