[PATCH 1/2] rockchip: otp: Add support for RV1126

Tim Lunn tim at feathertop.org
Tue Oct 31 03:07:14 CET 2023


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

Signed-off-by: Tim Lunn <tim at 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



More information about the U-Boot mailing list