mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 15:32:33 +00:00
130 lines
3.6 KiB
Diff
130 lines
3.6 KiB
Diff
|
From 8ab099fafbbc8c9607c399d21a774784a6cb8b45 Mon Sep 17 00:00:00 2001
|
||
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||
|
Date: Sun, 11 Jun 2023 15:03:17 +0100
|
||
|
Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3588
|
||
|
|
||
|
Add support for the OTP memory device found on the Rockchip RK3588 SoC.
|
||
|
|
||
|
While here, remove the unnecessary 'void *' casts in the OF device ID
|
||
|
table.
|
||
|
|
||
|
Co-developed-by: Finley Xiao <finley.xiao@rock-chips.com>
|
||
|
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
|
||
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||
|
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
|
||
|
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
|
||
|
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||
|
Message-ID: <20230611140330.154222-14-srinivas.kandagatla@linaro.org>
|
||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||
|
---
|
||
|
drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++-
|
||
|
1 file changed, 76 insertions(+), 2 deletions(-)
|
||
|
|
||
|
--- a/drivers/nvmem/rockchip-otp.c
|
||
|
+++ b/drivers/nvmem/rockchip-otp.c
|
||
|
@@ -54,6 +54,19 @@
|
||
|
|
||
|
#define OTPC_TIMEOUT 10000
|
||
|
|
||
|
+/* RK3588 Register */
|
||
|
+#define RK3588_OTPC_AUTO_CTRL 0x04
|
||
|
+#define RK3588_OTPC_AUTO_EN 0x08
|
||
|
+#define RK3588_OTPC_INT_ST 0x84
|
||
|
+#define RK3588_OTPC_DOUT0 0x20
|
||
|
+#define RK3588_NO_SECURE_OFFSET 0x300
|
||
|
+#define RK3588_NBYTES 4
|
||
|
+#define RK3588_BURST_NUM 1
|
||
|
+#define RK3588_BURST_SHIFT 8
|
||
|
+#define RK3588_ADDR_SHIFT 16
|
||
|
+#define RK3588_AUTO_EN BIT(0)
|
||
|
+#define RK3588_RD_DONE BIT(1)
|
||
|
+
|
||
|
struct rockchip_data {
|
||
|
int size;
|
||
|
const char * const *clks;
|
||
|
@@ -171,6 +184,52 @@ read_end:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
+static int rk3588_otp_read(void *context, unsigned int offset,
|
||
|
+ void *val, size_t bytes)
|
||
|
+{
|
||
|
+ struct rockchip_otp *otp = context;
|
||
|
+ unsigned int addr_start, addr_end, addr_len;
|
||
|
+ int ret, i = 0;
|
||
|
+ u32 data;
|
||
|
+ u8 *buf;
|
||
|
+
|
||
|
+ addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES;
|
||
|
+ addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
|
||
|
+ addr_len = addr_end - addr_start;
|
||
|
+ addr_start += RK3588_NO_SECURE_OFFSET;
|
||
|
+
|
||
|
+ buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL);
|
||
|
+ if (!buf)
|
||
|
+ return -ENOMEM;
|
||
|
+
|
||
|
+ while (addr_len--) {
|
||
|
+ writel((addr_start << RK3588_ADDR_SHIFT) |
|
||
|
+ (RK3588_BURST_NUM << RK3588_BURST_SHIFT),
|
||
|
+ otp->base + RK3588_OTPC_AUTO_CTRL);
|
||
|
+ writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
|
||
|
+
|
||
|
+ ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST,
|
||
|
+ RK3588_RD_DONE);
|
||
|
+ if (ret < 0) {
|
||
|
+ dev_err(otp->dev, "timeout during read setup\n");
|
||
|
+ goto read_end;
|
||
|
+ }
|
||
|
+
|
||
|
+ data = readl(otp->base + RK3588_OTPC_DOUT0);
|
||
|
+ memcpy(&buf[i], &data, RK3588_NBYTES);
|
||
|
+
|
||
|
+ i += RK3588_NBYTES;
|
||
|
+ addr_start++;
|
||
|
+ }
|
||
|
+
|
||
|
+ memcpy(val, buf + offset % RK3588_NBYTES, bytes);
|
||
|
+
|
||
|
+read_end:
|
||
|
+ kfree(buf);
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
static int rockchip_otp_read(void *context, unsigned int offset,
|
||
|
void *val, size_t bytes)
|
||
|
{
|
||
|
@@ -213,14 +272,29 @@ static const struct rockchip_data px30_d
|
||
|
.reg_read = px30_otp_read,
|
||
|
};
|
||
|
|
||
|
+static const char * const rk3588_otp_clocks[] = {
|
||
|
+ "otp", "apb_pclk", "phy", "arb",
|
||
|
+};
|
||
|
+
|
||
|
+static const struct rockchip_data rk3588_data = {
|
||
|
+ .size = 0x400,
|
||
|
+ .clks = rk3588_otp_clocks,
|
||
|
+ .num_clks = ARRAY_SIZE(rk3588_otp_clocks),
|
||
|
+ .reg_read = rk3588_otp_read,
|
||
|
+};
|
||
|
+
|
||
|
static const struct of_device_id rockchip_otp_match[] = {
|
||
|
{
|
||
|
.compatible = "rockchip,px30-otp",
|
||
|
- .data = (void *)&px30_data,
|
||
|
+ .data = &px30_data,
|
||
|
},
|
||
|
{
|
||
|
.compatible = "rockchip,rk3308-otp",
|
||
|
- .data = (void *)&px30_data,
|
||
|
+ .data = &px30_data,
|
||
|
+ },
|
||
|
+ {
|
||
|
+ .compatible = "rockchip,rk3588-otp",
|
||
|
+ .data = &rk3588_data,
|
||
|
},
|
||
|
{ /* sentinel */ },
|
||
|
};
|