nvmem: rockchip-efuse: add rk3366-efuse support
authorFinley Xiao <finley.xiao@rock-chips.com>
Wed, 16 Nov 2016 06:50:05 +0000 (14:50 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 16 Nov 2016 10:33:48 +0000 (18:33 +0800)
This adds the necessary data for handling efuse on the rk3366.

Change-Id: Ia9b03776172c9a66faa7320f7e1890549538a32a
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt
drivers/nvmem/rockchip-efuse.c

index 94aeeea..fba905b 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
   - "rockchip,rk3066a-efuse" - for RK3066a SoCs.
   - "rockchip,rk3188-efuse" - for RK3188 SoCs.
   - "rockchip,rk3288-efuse" - for RK3288 SoCs.
+  - "rockchip,rk3366-efuse" - for RK3366 SoCs.
   - "rockchip,rk3399-efuse" - for RK3399 SoCs.
 - reg: Should contain the registers location and exact eFuse size
 - clocks: Should be the clock id of eFuse
index 92417ae..0995634 100644 (file)
 #define RK3288_STROBE          BIT(1)
 #define RK3288_CSB             BIT(0)
 
+#define RK3366_A_SHIFT         6
+#define RK3366_A_MASK          0x3ff
+#define RK3366_RDEN            BIT(2)
+#define RK3366_AEN             BIT(1)
+
 #define RK3399_A_SHIFT         16
 #define RK3399_A_MASK          0x3ff
 #define RK3399_NBYTES          4
@@ -92,6 +97,46 @@ static int rockchip_rk3288_efuse_read(void *context, unsigned int offset,
        return 0;
 }
 
+static int rockchip_rk3366_efuse_read(void *context, unsigned int offset,
+                                     void *val, size_t bytes)
+{
+       struct rockchip_efuse_chip *efuse = context;
+       u8 *buf = val;
+       int ret;
+
+       ret = clk_prepare_enable(efuse->clk);
+       if (ret < 0) {
+               dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
+               return ret;
+       }
+
+       writel(RK3366_RDEN, efuse->base + REG_EFUSE_CTRL);
+       udelay(1);
+       while (bytes--) {
+               writel(readl(efuse->base + REG_EFUSE_CTRL) &
+                      (~(RK3366_A_MASK << RK3366_A_SHIFT)),
+                      efuse->base + REG_EFUSE_CTRL);
+               writel(readl(efuse->base + REG_EFUSE_CTRL) |
+                      ((offset++ & RK3366_A_MASK) << RK3366_A_SHIFT),
+                      efuse->base + REG_EFUSE_CTRL);
+               udelay(1);
+               writel(readl(efuse->base + REG_EFUSE_CTRL) |
+                      RK3366_AEN, efuse->base + REG_EFUSE_CTRL);
+               udelay(1);
+               *buf++ = readb(efuse->base + REG_EFUSE_DOUT);
+               writel(readl(efuse->base + REG_EFUSE_CTRL) &
+                      (~RK3366_AEN), efuse->base + REG_EFUSE_CTRL);
+               udelay(1);
+       }
+
+       writel(readl(efuse->base + REG_EFUSE_CTRL) &
+              (~RK3366_RDEN), efuse->base + REG_EFUSE_CTRL);
+
+       clk_disable_unprepare(efuse->clk);
+
+       return 0;
+}
+
 static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
                                      void *val, size_t bytes)
 {
@@ -173,6 +218,10 @@ static const struct of_device_id rockchip_efuse_match[] = {
                .compatible = "rockchip,rk3288-efuse",
                .data = (void *)&rockchip_rk3288_efuse_read,
        },
+       {
+               .compatible = "rockchip,rk3366-efuse",
+               .data = (void *)&rockchip_rk3366_efuse_read,
+       },
        {
                .compatible = "rockchip,rk3399-efuse",
                .data = (void *)&rockchip_rk3399_efuse_read,