From ba4815a63a07e474731b1c19daa41e4d5f2b077f Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Wed, 16 Nov 2016 14:50:05 +0800 Subject: [PATCH] nvmem: rockchip-efuse: add rk3366-efuse support This adds the necessary data for handling efuse on the rk3366. Change-Id: Ia9b03776172c9a66faa7320f7e1890549538a32a Signed-off-by: Finley Xiao --- .../bindings/nvmem/rockchip-efuse.txt | 1 + drivers/nvmem/rockchip-efuse.c | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt index 94aeeeabadd5..fba905b32aac 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt +++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt @@ -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 diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index 92417aec0df6..0995634ba1ba 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -32,6 +32,11 @@ #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, -- 2.34.1