Extend the otp driver to read rv1126 otp. This driver code was
adapted from the Rockchip BSP stack.

Signed-off-by: Tim Lunn <t...@feathertop.org>
---
 drivers/misc/rockchip-otp.c | 76 +++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c
index 4814e0e501..4f757083a1 100644
--- a/drivers/misc/rockchip-otp.c
+++ b/drivers/misc/rockchip-otp.c
@@ -61,11 +61,20 @@
 #define RK3588_OTPC_INT_ST             0x0084
 #define RK3588_RD_DONE                 BIT(1)
 
+#define RV1126_OTP_NVM_CEB             0x00
+#define RV1126_OTP_NVM_RSTB            0x04
+#define RV1126_OTP_NVM_ST              0x18
+#define RV1126_OTP_NVM_RADDR           0x1C
+#define RV1126_OTP_NVM_RSTART          0x20
+#define RV1126_OTP_NVM_RDATA           0x24
+#define RV1126_OTP_READ_ST             0x30
+
 struct rockchip_otp_plat {
        void __iomem *base;
 };
 
 struct rockchip_otp_data {
+       int (*init)(struct udevice *dev);
        int (*read)(struct udevice *dev, int offset, void *buf, int size);
        int offset;
        int size;
@@ -232,6 +241,48 @@ static int rockchip_rk3588_otp_read(struct udevice *dev, 
int offset,
        return 0;
 }
 
+static int rockchip_rv1126_otp_init(struct udevice *dev)
+{
+       struct rockchip_otp_plat *otp = dev_get_plat(dev);
+       int ret;
+
+       writel(0x0, otp->base + RV1126_OTP_NVM_CEB);
+       ret = rockchip_otp_poll_timeout(otp, 0x1, RV1126_OTP_NVM_ST);
+
+       if (ret)
+               return ret;
+
+       writel(0x1, otp->base + RV1126_OTP_NVM_RSTB);
+       ret = rockchip_otp_poll_timeout(otp, 0x4, RV1126_OTP_NVM_ST);
+
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int rockchip_rv1126_otp_read(struct udevice *dev, int offset, void *buf,
+                                   int size)
+{
+       struct rockchip_otp_plat *otp = dev_get_plat(dev);
+       u32 status = 0;
+       u8 *buffer = buf;
+       int ret = 0;
+
+       while (size--) {
+               writel(offset++, otp->base + RV1126_OTP_NVM_RADDR);
+               writel(0x1, otp->base + RV1126_OTP_NVM_RSTART);
+               ret = readl_poll_timeout(otp->base + RV1126_OTP_READ_ST,
+                                        status, !status, OTPC_TIMEOUT);
+               if (ret)
+                       return ret;
+
+               *buffer++ = (u8)(readl(otp->base + RV1126_OTP_NVM_RDATA) & 
0xFF);
+       }
+
+       return 0;
+}
+
 static int rockchip_otp_read(struct udevice *dev, int offset,
                             void *buf, int size)
 {
@@ -286,6 +337,20 @@ static int rockchip_otp_of_to_plat(struct udevice *dev)
        return 0;
 }
 
+static int rockchip_otp_probe(struct udevice *dev)
+{
+       struct rockchip_otp_data *data;
+
+       data = (struct rockchip_otp_data *)dev_get_driver_data(dev);
+       if (!data)
+               return -EINVAL;
+
+       if (data->init)
+               return data->init(dev);
+
+       return 0;
+}
+
 static const struct rockchip_otp_data px30_data = {
        .read = rockchip_px30_otp_read,
        .size = 0x40,
@@ -304,6 +369,12 @@ static const struct rockchip_otp_data rk3588_data = {
        .block_size = 4,
 };
 
+static const struct rockchip_otp_data rv1126_data = {
+       .init = rockchip_rv1126_otp_init,
+       .read = rockchip_rv1126_otp_read,
+       .size = 0x40,
+};
+
 static const struct udevice_id rockchip_otp_ids[] = {
        {
                .compatible = "rockchip,px30-otp",
@@ -321,6 +392,10 @@ static const struct udevice_id rockchip_otp_ids[] = {
                .compatible = "rockchip,rk3588-otp",
                .data = (ulong)&rk3588_data,
        },
+       {
+               .compatible = "rockchip,rv1126-otp",
+               .data = (ulong)&rv1126_data,
+       },
        {}
 };
 
@@ -331,4 +406,5 @@ U_BOOT_DRIVER(rockchip_otp) = {
        .of_to_plat = rockchip_otp_of_to_plat,
        .plat_auto = sizeof(struct rockchip_otp_plat),
        .ops = &rockchip_otp_ops,
+       .probe = rockchip_otp_probe,
 };
-- 
2.40.1

Reply via email to