generic: 6.1: backport various qca8k fixes patch
[openwrt/openwrt.git] / target / linux / generic / backport-6.1 / 813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch
1 From 8ab099fafbbc8c9607c399d21a774784a6cb8b45 Mon Sep 17 00:00:00 2001
2 From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
3 Date: Sun, 11 Jun 2023 15:03:17 +0100
4 Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3588
5
6 Add support for the OTP memory device found on the Rockchip RK3588 SoC.
7
8 While here, remove the unnecessary 'void *' casts in the OF device ID
9 table.
10
11 Co-developed-by: Finley Xiao <finley.xiao@rock-chips.com>
12 Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
13 Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
14 Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
15 Reviewed-by: Heiko Stuebner <heiko@sntech.de>
16 Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
17 Message-ID: <20230611140330.154222-14-srinivas.kandagatla@linaro.org>
18 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
19 ---
20 drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++-
21 1 file changed, 76 insertions(+), 2 deletions(-)
22
23 --- a/drivers/nvmem/rockchip-otp.c
24 +++ b/drivers/nvmem/rockchip-otp.c
25 @@ -54,6 +54,19 @@
26
27 #define OTPC_TIMEOUT 10000
28
29 +/* RK3588 Register */
30 +#define RK3588_OTPC_AUTO_CTRL 0x04
31 +#define RK3588_OTPC_AUTO_EN 0x08
32 +#define RK3588_OTPC_INT_ST 0x84
33 +#define RK3588_OTPC_DOUT0 0x20
34 +#define RK3588_NO_SECURE_OFFSET 0x300
35 +#define RK3588_NBYTES 4
36 +#define RK3588_BURST_NUM 1
37 +#define RK3588_BURST_SHIFT 8
38 +#define RK3588_ADDR_SHIFT 16
39 +#define RK3588_AUTO_EN BIT(0)
40 +#define RK3588_RD_DONE BIT(1)
41 +
42 struct rockchip_data {
43 int size;
44 const char * const *clks;
45 @@ -171,6 +184,52 @@ read_end:
46 return ret;
47 }
48
49 +static int rk3588_otp_read(void *context, unsigned int offset,
50 + void *val, size_t bytes)
51 +{
52 + struct rockchip_otp *otp = context;
53 + unsigned int addr_start, addr_end, addr_len;
54 + int ret, i = 0;
55 + u32 data;
56 + u8 *buf;
57 +
58 + addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES;
59 + addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
60 + addr_len = addr_end - addr_start;
61 + addr_start += RK3588_NO_SECURE_OFFSET;
62 +
63 + buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL);
64 + if (!buf)
65 + return -ENOMEM;
66 +
67 + while (addr_len--) {
68 + writel((addr_start << RK3588_ADDR_SHIFT) |
69 + (RK3588_BURST_NUM << RK3588_BURST_SHIFT),
70 + otp->base + RK3588_OTPC_AUTO_CTRL);
71 + writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
72 +
73 + ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST,
74 + RK3588_RD_DONE);
75 + if (ret < 0) {
76 + dev_err(otp->dev, "timeout during read setup\n");
77 + goto read_end;
78 + }
79 +
80 + data = readl(otp->base + RK3588_OTPC_DOUT0);
81 + memcpy(&buf[i], &data, RK3588_NBYTES);
82 +
83 + i += RK3588_NBYTES;
84 + addr_start++;
85 + }
86 +
87 + memcpy(val, buf + offset % RK3588_NBYTES, bytes);
88 +
89 +read_end:
90 + kfree(buf);
91 +
92 + return ret;
93 +}
94 +
95 static int rockchip_otp_read(void *context, unsigned int offset,
96 void *val, size_t bytes)
97 {
98 @@ -213,14 +272,29 @@ static const struct rockchip_data px30_d
99 .reg_read = px30_otp_read,
100 };
101
102 +static const char * const rk3588_otp_clocks[] = {
103 + "otp", "apb_pclk", "phy", "arb",
104 +};
105 +
106 +static const struct rockchip_data rk3588_data = {
107 + .size = 0x400,
108 + .clks = rk3588_otp_clocks,
109 + .num_clks = ARRAY_SIZE(rk3588_otp_clocks),
110 + .reg_read = rk3588_otp_read,
111 +};
112 +
113 static const struct of_device_id rockchip_otp_match[] = {
114 {
115 .compatible = "rockchip,px30-otp",
116 - .data = (void *)&px30_data,
117 + .data = &px30_data,
118 },
119 {
120 .compatible = "rockchip,rk3308-otp",
121 - .data = (void *)&px30_data,
122 + .data = &px30_data,
123 + },
124 + {
125 + .compatible = "rockchip,rk3588-otp",
126 + .data = &rk3588_data,
127 },
128 { /* sentinel */ },
129 };