Add support for rk3588 compatible.

Adjust offset using driver data in main read op.

Signed-off-by: Jonas Karlman <jo...@kwiboo.se>
---
 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 243c173cdb18..babb6ce2f241 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.1

Reply via email to