I have modified the OCOTP driver "fsl_otp.c" and I have added the support to the IMX8M.
Now I can write and read the OCOTP register from Linux user space with simple command like this:
$ cat /sys/fsl_otp/HW_OCOTP_TESTER0
0xf0609912
Anyway, I have a problem after a write operation. For example, if I try to write "0xaa" to the HW_OCOTP_GP10, I got a strange result, as in the followings:
$ cat /sys/fsl_otp/HW_OCOTP_GP10
0x0
$ echo 0xaa > /sys/fsl_otp/HW_OCOTP_GP10
$ cat /sys/fsl_otp/HW_OCOTP_GP10
0xd503201f
Anyway, if I power off and power on again the board, I can be able to see the following result:
$ cat /sys/fsl_otp/HW_OCOTP_GP10
0xaa
So the write operation was success, but there was a problem reloading a register after a write operation.
Finally, I have found the problem in the shadows register reload code:
/* Reload all the shadow registers */
__raw_writel(BM_OCOTP_CTRL_RELOAD_SHADOWS,
otp_base + HW_OCOTP_CTRL_SET);
udelay(1);
ret = otp_wait_busy(BM_OCOTP_CTRL_RELOAD_SHADOWS);
if (ret){
printk("Reload all the shadow registers failed\n");
}
This code is executed in the function fsl_otp_store(...) just after the write operation. The code try to reload all
the shadows register, so that any subsequent read operation gets the correct value from the shadow area.
After this code is executed, all the shadows register index are shifted by one, as you can see from the
following result, where all registers have a progressive index:
$cat /sys/fsl_otp/HW_OCOTP_ROM_PATCH6
0x83b8
$cat /sys/fsl_otp/HW_OCOTP_ROM_PATCH7
0xd503201f
$cat /sys/fsl_otp/HW_OCOTP_GP10
0x0
$cat /sys/fsl_otp/HW_OCOTP_GP11
0x0
$echo 0xaa > /sys/fsl_otp/HW_OCOTP_GP10
$cat /sys/fsl_otp/HW_OCOTP_ROM_PATCH6
0x55000801
$cat /sys/fsl_otp/HW_OCOTP_ROM_PATCH7
0x83b8
$cat /sys/fsl_otp/HW_OCOTP_GP10
0xd503201f
$cat /sys/fsl_otp/HW_OCOTP_GP11
0xaa
I have found a workaround for this issue. I added a FIX_IMX8M_OFFSET_INDEX_AFTER_RELOAD define, that add an offset to the register index after a write operation. With this workaround the driver works as expected:
$ cat /sys/fsl_otp/HW_OCOTP_GP10
0x0
$ echo 0xaa > /sys/fsl_otp/HW_OCOTP_GP10
$ cat /sys/fsl_otp/HW_OCOTP_GP10
0xaa
So, the OCOTP shadow register reload does not work correctly. Is it a known issue of IMX8M?