]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
rockchip: otp: Add support for RV1126
authorTim Lunn <tim@feathertop.org>
Tue, 31 Oct 2023 02:07:14 +0000 (13:07 +1100)
committerTom Rini <trini@konsulko.com>
Fri, 10 Nov 2023 15:58:44 +0000 (10:58 -0500)
Extend the otp driver to read rv1126 otp. This driver code was
adapted from the Rockchip BSP stack.

Signed-off-by: Tim Lunn <tim@feathertop.org>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
drivers/misc/rockchip-otp.c

index 4814e0e501c9fa077a9bf4d9aeb8b29c5c659f2e..4f757083a1b6d9e8152a470381022c2b2f31d4f3 100644 (file)
 #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,
 };