From a45ffbebc42459c39b10ad8b510c1e7b0b7a159d Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Wed, 22 Feb 2023 22:44:39 +0000 Subject: [PATCH] rockchip: otp: Add support for RK3588 Add support for rk3588 compatible. Adjust offset using driver data in main read op. Signed-off-by: Jonas Karlman Reviewed-by: Kever Yang --- drivers/misc/rockchip-otp.c | 63 +++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c index fea3ca7c28..3da99e8317 100644 --- a/drivers/misc/rockchip-otp.c +++ b/drivers/misc/rockchip-otp.c @@ -48,28 +48,41 @@ #define OTPC_TIMEOUT 10000 +#define RK3588_OTPC_AUTO_CTRL 0x0004 +#define RK3588_ADDR_SHIFT 16 +#define RK3588_ADDR(n) ((n) << RK3588_ADDR_SHIFT) +#define RK3588_BURST_SHIFT 8 +#define RK3588_BURST(n) ((n) << RK3588_BURST_SHIFT) +#define RK3588_OTPC_AUTO_EN 0x0008 +#define RK3588_AUTO_EN BIT(0) +#define RK3588_OTPC_DOUT0 0x0020 +#define RK3588_OTPC_INT_ST 0x0084 +#define RK3588_RD_DONE BIT(1) + struct rockchip_otp_plat { void __iomem *base; }; struct rockchip_otp_data { int (*read)(struct udevice *dev, int offset, void *buf, int size); + int offset; int size; int block_size; }; -static int rockchip_otp_poll_timeout(struct rockchip_otp_plat *otp, u32 flag) +static int rockchip_otp_poll_timeout(struct rockchip_otp_plat *otp, + u32 flag, u32 reg) { u32 status; int ret; - ret = readl_poll_sleep_timeout(otp->base + OTPC_INT_STATUS, status, + ret = readl_poll_sleep_timeout(otp->base + reg, status, (status & flag), 1, OTPC_TIMEOUT); if (ret) return ret; /* Clear int flag */ - writel(flag, otp->base + OTPC_INT_STATUS); + writel(flag, otp->base + reg); return 0; } @@ -90,7 +103,7 @@ static int rockchip_otp_ecc_enable(struct rockchip_otp_plat *otp, bool enable) writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL); - return rockchip_otp_poll_timeout(otp, OTPC_SBPI_DONE); + return rockchip_otp_poll_timeout(otp, OTPC_SBPI_DONE, OTPC_INT_STATUS); } static int rockchip_px30_otp_read(struct udevice *dev, int offset, @@ -113,7 +126,8 @@ static int rockchip_px30_otp_read(struct udevice *dev, int offset, writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, otp->base + OTPC_USER_ENABLE); - ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE); + ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE, + OTPC_INT_STATUS); if (ret) goto read_end; @@ -146,7 +160,8 @@ static int rockchip_rk3568_otp_read(struct udevice *dev, int offset, writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, otp->base + OTPC_USER_ENABLE); - ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE); + ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE, + OTPC_INT_STATUS); if (ret) goto read_end; @@ -159,6 +174,29 @@ read_end: return ret; } +static int rockchip_rk3588_otp_read(struct udevice *dev, int offset, + void *buf, int size) +{ + struct rockchip_otp_plat *otp = dev_get_plat(dev); + u32 *buffer = buf; + int ret; + + while (size--) { + writel(RK3588_ADDR(offset++) | RK3588_BURST(1), + otp->base + RK3588_OTPC_AUTO_CTRL); + writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN); + + ret = rockchip_otp_poll_timeout(otp, RK3588_RD_DONE, + RK3588_OTPC_INT_ST); + if (ret) + return ret; + + *buffer++ = readl(otp->base + RK3588_OTPC_DOUT0); + } + + return 0; +} + static int rockchip_otp_read(struct udevice *dev, int offset, void *buf, int size) { @@ -174,6 +212,8 @@ static int rockchip_otp_read(struct udevice *dev, int offset, if (!data->read) return -ENOSYS; + offset += data->offset; + if (data->block_size <= 1) return data->read(dev, offset, buf, size); @@ -218,6 +258,13 @@ static const struct rockchip_otp_data rk3568_data = { .block_size = 2, }; +static const struct rockchip_otp_data rk3588_data = { + .read = rockchip_rk3588_otp_read, + .offset = 0xC00, + .size = 0x400, + .block_size = 4, +}; + static const struct udevice_id rockchip_otp_ids[] = { { .compatible = "rockchip,px30-otp", @@ -231,6 +278,10 @@ static const struct udevice_id rockchip_otp_ids[] = { .compatible = "rockchip,rk3568-otp", .data = (ulong)&rk3568_data, }, + { + .compatible = "rockchip,rk3588-otp", + .data = (ulong)&rk3588_data, + }, {} }; -- 2.39.5