diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.yaml b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.yaml index 4dd06326424b..c4b6fd52fd46 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.yaml +++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.yaml @@ -16,6 +16,7 @@ properties: compatible: enum: - rockchip,rk3066a-efuse + - rockchip,rk3128-efuse - rockchip,rk3188-efuse - rockchip,rk3228-efuse - rockchip,rk3288-efuse diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index b11326553e78..e2b4bf4e3f6b 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -18,6 +18,7 @@ #include #include +#define RK3128_A_SHIFT 7 #define RK3288_A_SHIFT 6 #define RK3288_A_MASK 0x3ff #define RK3288_PGENB BIT(3) @@ -54,6 +55,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) { @@ -313,6 +354,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,