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
6 Add support for the OTP memory device found on the Rockchip RK3588 SoC.
8 While here, remove the unnecessary 'void *' casts in the OF device ID
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>
20 drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++-
21 1 file changed, 76 insertions(+), 2 deletions(-)
23 --- a/drivers/nvmem/rockchip-otp.c
24 +++ b/drivers/nvmem/rockchip-otp.c
27 #define OTPC_TIMEOUT 10000
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)
42 struct rockchip_data {
44 const char * const *clks;
45 @@ -171,6 +184,52 @@ read_end:
49 +static int rk3588_otp_read(void *context, unsigned int offset,
50 + void *val, size_t bytes)
52 + struct rockchip_otp *otp = context;
53 + unsigned int addr_start, addr_end, addr_len;
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;
63 + buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL);
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);
73 + ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST,
76 + dev_err(otp->dev, "timeout during read setup\n");
80 + data = readl(otp->base + RK3588_OTPC_DOUT0);
81 + memcpy(&buf[i], &data, RK3588_NBYTES);
87 + memcpy(val, buf + offset % RK3588_NBYTES, bytes);
95 static int rockchip_otp_read(void *context, unsigned int offset,
96 void *val, size_t bytes)
98 @@ -213,14 +272,29 @@ static const struct rockchip_data px30_d
99 .reg_read = px30_otp_read,
102 +static const char * const rk3588_otp_clocks[] = {
103 + "otp", "apb_pclk", "phy", "arb",
106 +static const struct rockchip_data rk3588_data = {
108 + .clks = rk3588_otp_clocks,
109 + .num_clks = ARRAY_SIZE(rk3588_otp_clocks),
110 + .reg_read = rk3588_otp_read,
113 static const struct of_device_id rockchip_otp_match[] = {
115 .compatible = "rockchip,px30-otp",
116 - .data = (void *)&px30_data,
117 + .data = &px30_data,
120 .compatible = "rockchip,rk3308-otp",
121 - .data = (void *)&px30_data,
122 + .data = &px30_data,
125 + .compatible = "rockchip,rk3588-otp",
126 + .data = &rk3588_data,