This adds the necessary data for handling eFuse on the rk3328.

Signed-off-by: Finley Xiao <finley.x...@rock-chips.com>
---
 drivers/misc/rockchip-efuse.c | 69 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index 175a7fe2f5..68762d3f6f 100644
--- a/drivers/misc/rockchip-efuse.c
+++ b/drivers/misc/rockchip-efuse.c
@@ -13,6 +13,7 @@
 #include <dm.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <malloc.h>
 #include <misc.h>
 
 #define RK3288_A_SHIFT          6
@@ -24,6 +25,15 @@
 #define RK3288_STROBE           BIT(1)
 #define RK3288_CSB              BIT(0)
 
+#define RK3328_INT_STATUS      0x0018
+#define RK3328_DOUT            0x0020
+#define RK3328_AUTO_CTRL       0x0024
+#define RK3328_INT_FINISH      BIT(0)
+#define RK3328_AUTO_ENB                BIT(0)
+#define RK3328_AUTO_RD         BIT(1)
+#define RK3328_NO_SECURE_BYTES 32
+#define RK3328_SECURE_BYTES    96
+
 #define RK3399_A_SHIFT          16
 #define RK3399_A_MASK           0x3ff
 #define RK3399_NFUSES           32
@@ -47,6 +57,10 @@ struct rockchip_efuse_regs {
        u32 jtag_pass; /* 0x10  JTAG password */
        u32 strobe_finish_ctrl;
                       /* 0x14  efuse strobe finish control register */
+       u32 int_status;/* 0x18 */
+       u32 reserved;  /* 0x1c */
+       u32 dout2;     /* 0x20 */
+       u32 auto_ctrl; /* 0x24 */
 };
 
 struct rockchip_efuse_platdata {
@@ -138,6 +152,57 @@ static int rockchip_rk3288_efuse_read(struct udevice *dev, 
int offset,
        return 0;
 }
 
+static int rockchip_rk3328_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, j = 0;
+
+       /* Max non-secure Byte */
+       if (size > RK3328_NO_SECURE_BYTES)
+               size = RK3328_NO_SECURE_BYTES;
+
+       /* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */
+       offset += RK3328_SECURE_BYTES;
+       addr_start = rounddown(offset, RK3399_BYTES_PER_FUSE) /
+                              RK3399_BYTES_PER_FUSE;
+       addr_end = roundup(offset + size, RK3399_BYTES_PER_FUSE) /
+                          RK3399_BYTES_PER_FUSE;
+       addr_offset = offset % RK3399_BYTES_PER_FUSE;
+       addr_len = addr_end - addr_start;
+
+       buffer = calloc(1, sizeof(*buffer) * addr_len * RK3399_BYTES_PER_FUSE);
+       if (!buffer)
+               return -ENOMEM;
+
+       for (j = 0; j < addr_len; j++) {
+               writel(RK3328_AUTO_RD | RK3328_AUTO_ENB |
+                      ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT),
+                      &efuse->auto_ctrl);
+               udelay(5);
+               status = readl(&efuse->int_status);
+               if (!(status & RK3328_INT_FINISH)) {
+                       ret = -EIO;
+                       goto err;
+               }
+               out_value = readl(&efuse->dout2);
+               writel(RK3328_INT_FINISH, &efuse->int_status);
+
+               memcpy(&buffer[i], &out_value, RK3399_BYTES_PER_FUSE);
+               i += RK3399_BYTES_PER_FUSE;
+       }
+       memcpy(buf, buffer + addr_offset, size);
+err:
+       free(buffer);
+
+       return ret;
+}
+
 static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset,
                                      void *buf, int size)
 {
@@ -224,6 +289,10 @@ static const struct udevice_id rockchip_efuse_ids[] = {
                .data = (ulong)&rockchip_rk3288_efuse_read,
        },
        {
+               .compatible = "rockchip,rk3328-efuse",
+               .data = (ulong)&rockchip_rk3328_efuse_read,
+       },
+       {
                .compatible = "rockchip,rk3399-efuse",
                .data = (ulong)&rockchip_rk3399_efuse_read,
        },
-- 
2.11.0



Reply via email to