From 24ddbf99c76a352cc1931ccb5118bca0656034b8 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Tue, 15 Apr 2025 18:32:02 +0800 Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3568 This adds the necessary data for handling otp the rk3568. Signed-off-by: Finley Xiao Signed-off-by: Kever Yang Reviewed-by: Heiko Stuebner Tested-by: Heiko Stuebner Signed-off-by: Jonas Karlman --- drivers/nvmem/rockchip-otp.c | 69 ++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) --- a/drivers/nvmem/rockchip-otp.c +++ b/drivers/nvmem/rockchip-otp.c @@ -27,6 +27,7 @@ #define OTPC_USER_CTRL 0x0100 #define OTPC_USER_ADDR 0x0104 #define OTPC_USER_ENABLE 0x0108 +#define OTPC_USER_QP 0x0120 #define OTPC_USER_Q 0x0124 #define OTPC_INT_STATUS 0x0304 #define OTPC_SBPI_CMD0_OFFSET 0x1000 @@ -184,6 +185,58 @@ read_end: return ret; } +static int rk3568_otp_read(void *context, unsigned int offset, void *val, + size_t count) +{ + struct rockchip_otp *otp = context; + u16 *buf = val; + u32 otp_qp; + int ret; + + ret = rockchip_otp_reset(otp); + if (ret) { + dev_err(otp->dev, "failed to reset otp phy\n"); + return ret; + } + + ret = rockchip_otp_ecc_enable(otp, true); + if (ret) { + dev_err(otp->dev, "rockchip_otp_ecc_enable err\n"); + return ret; + } + + writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); + udelay(5); + + while (count--) { + writel(offset++ | OTPC_USER_ADDR_MASK, + otp->base + OTPC_USER_ADDR); + writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, + otp->base + OTPC_USER_ENABLE); + + ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, + OTPC_USER_DONE); + if (ret) { + dev_err(otp->dev, "timeout during read setup\n"); + goto read_end; + } + + otp_qp = readl(otp->base + OTPC_USER_QP); + if (((otp_qp & 0xc0) == 0xc0) || (otp_qp & 0x20)) { + ret = -EIO; + dev_err(otp->dev, "ecc check error during read setup\n"); + goto read_end; + } + + *buf++ = readl(otp->base + OTPC_USER_Q); + } + +read_end: + writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); + + return ret; +} + static int rk3588_otp_read(void *context, unsigned int offset, void *val, size_t count) { @@ -280,6 +333,18 @@ static const struct rockchip_data px30_d .reg_read = px30_otp_read, }; +static const char * const rk3568_otp_clocks[] = { + "otp", "apb_pclk", "phy", "sbpi", +}; + +static const struct rockchip_data rk3568_data = { + .size = 0x80, + .word_size = sizeof(u16), + .clks = rk3568_otp_clocks, + .num_clks = ARRAY_SIZE(rk3568_otp_clocks), + .reg_read = rk3568_otp_read, +}; + static const struct rockchip_data rk3576_data = { .size = 0x100, .read_offset = 0x700, @@ -312,6 +377,10 @@ static const struct of_device_id rockchi .data = &px30_data, }, { + .compatible = "rockchip,rk3568-otp", + .data = &rk3568_data, + }, + { .compatible = "rockchip,rk3576-otp", .data = &rk3576_data, },