RK3588 Data sheet says: Support 32Kbit space and higher 4k address space is non-secure part.
But according to dtb:
otp: otp@fecc0000 {
compatible = “rockchip,rk3588-otp”;
reg = <0x0 0xfecc0000 0x0 0x400>;
its size is only 0x400 bytes , right?
and we start read/write from NO_SECURE_OFFSET i.e 0x300
does this mean there are 0x400 otps each of 4 bytes ?
static int rk3588_otp_write(void *context, unsigned int offset,
void *val, size_t bytes)
{
struct rockchip_otp *otp = context;
unsigned int addr_start, addr_end, addr_offset, addr_len;
int ret = 0;// i = 0;
u32 in_value;
u8 *buf;
OTP_NS_t ns_otp=(OTP_NS_t)otp->base;
dev_info(otp->dev, “inside rk3588_otp_write()\n”);
if (offset >= otp->data->size)
return -ENOMEM;
if (offset + bytes > otp->data->size)
bytes = otp->data->size - offset;
addr_start = rounddown(offset, RK3588_NBYTES) / RK3588_NBYTES;
addr_end = roundup(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
addr_offset = offset % RK3588_NBYTES;
addr_len = addr_end - addr_start;
addr_start += RK3588_NO_SECURE_OFFSET;
printk(KERN_INFO "rk3588_otp_write(): addr_start: %d, addr_end: %d, addr_len: %d, addr_offset: %d\n",addr_start,addr_end,addr_len,addr_offset);
buf = kzalloc(array3_size(addr_len, RK3588_NBYTES, sizeof(*buf)), GFP_KERNEL);
if (!buf)
return -ENOMEM;
ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks);
if (ret < 0) {
dev_err(otp->dev, "failed to enable clocks\n");
return -1;
}
//dtOtpWriteNonSecure(ns_otp,val,addr_start,addr_len);
//Copy input to buffer, considering offset inside the first word
memcpy(buf + addr_offset, val, bytes);
while (addr_len--) {
memcpy(&in_value, &buf[i], RK3588_NBYTES);
// Write the data to be programmed
writel(in_value, otp->base + OTP_NS_PROG_DATA_ADDR);
// Set AUTO_CTRL with address and write command
writel((addr_start << RK3588_ADDR_SHIFT) |
(RK3588_BURST_NUM << RK3588_BURST_SHIFT) |
RK3588_CMD_WRITE,
otp->base + RK3588_OTPC_AUTO_CTRL);
// Enable the command
writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
// Wait for write to complete
// ret = rk3588_otp_wait_status(otp, RK3588_WR_DONE);
// if (ret < 0) {
// dev_err(otp->dev, "timeout during write operation\n");
// goto write_end;
// }
udelay(10000);
udelay(10000);
printk(KERN_INFO "for i = %d ,addr_start = %d \n",i,addr_start);
addr_start++;
i += RK3588_NBYTES;
}
write_end:
clk_bulk_disable_unprepare(otp->num_clks, otp->clks);
out:
kfree(buf);
return ret;
}
is this the right code ? I just used writel() instead of your volatile objects