Hi Finley,

    NAK for this patch, rk1808 is not support by upstream U-Boot now.


Thanks,

- Kever

On 2020/2/20 上午10:53, Finley Xiao wrote:
This adds the necessary data for handling eFuse on the rk1808.

Signed-off-by: Finley Xiao <finley.x...@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,
        },


Reply via email to