From 2d697b2e8becc8e6f7469b464c011cf085b330aa Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Tue, 5 Sep 2017 16:20:35 +0800 Subject: [PATCH] nvmem: rockchip-efuse: add support for rk3128-efuse This adds the necessary data for handling efuse on the rk3128. Change-Id: Ieda973675ff959b3157bb4afe6e1dcdfac65506c Signed-off-by: Liang Chen --- .../bindings/nvmem/rockchip-efuse.txt | 1 + drivers/nvmem/rockchip-efuse.c | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt index ea9f68fcced6..c55a19eec5bf 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt +++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt @@ -3,6 +3,7 @@ Required properties: - compatible: Should be one of the following. - "rockchip,rk3066a-efuse" - for RK3066a SoCs. + - "rockchip,rk3128-efuse" - for RK3128 SoCs. - "rockchip,rk3188-efuse" - for RK3188 SoCs. - "rockchip,rk3228-efuse" - for RK3228 SoCs. - "rockchip,rk3288-efuse" - for RK3288 SoCs. diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index 41d3067eb82e..9745788b3174 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -26,6 +26,7 @@ #include #include +#define RK3128_A_SHIFT 7 #define RK3288_A_SHIFT 6 #define RK3288_A_MASK 0x3ff #define RK3288_PGENB BIT(3) @@ -62,6 +63,46 @@ struct rockchip_efuse_chip { phys_addr_t phys; }; +static int rockchip_rk3128_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(RK3288_LOAD | RK3288_PGENB, efuse->base + REG_EFUSE_CTRL); + udelay(1); + while (bytes--) { + writel(readl(efuse->base + REG_EFUSE_CTRL) & + (~(RK3288_A_MASK << RK3128_A_SHIFT)), + efuse->base + REG_EFUSE_CTRL); + writel(readl(efuse->base + REG_EFUSE_CTRL) | + ((offset++ & RK3288_A_MASK) << RK3128_A_SHIFT), + efuse->base + REG_EFUSE_CTRL); + udelay(1); + writel(readl(efuse->base + REG_EFUSE_CTRL) | + RK3288_STROBE, efuse->base + REG_EFUSE_CTRL); + udelay(1); + *buf++ = readb(efuse->base + REG_EFUSE_DOUT); + writel(readl(efuse->base + REG_EFUSE_CTRL) & + (~RK3288_STROBE), efuse->base + REG_EFUSE_CTRL); + udelay(1); + } + + /* Switch to standby mode */ + writel(RK3288_PGENB | RK3288_CSB, efuse->base + REG_EFUSE_CTRL); + + clk_disable_unprepare(efuse->clk); + + return 0; +} + static int rockchip_rk3288_efuse_read(void *context, unsigned int offset, void *val, size_t bytes) { @@ -321,6 +362,10 @@ static const struct of_device_id rockchip_efuse_match[] = { .compatible = "rockchip,rk3066a-efuse", .data = (void *)&rockchip_rk3288_efuse_read, }, + { + .compatible = "rockchip,rk3128-efuse", + .data = (void *)&rockchip_rk3128_efuse_read, + }, { .compatible = "rockchip,rk3188-efuse", .data = (void *)&rockchip_rk3288_efuse_read,