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>
This commit is contained in:
parent
912517345b
commit
8ab099fafb
|
@ -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_data = {
|
|||
.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 */ },
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue