OCOTP write support on i.mx8m

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

OCOTP write support on i.mx8m

Jump to solution
19,239 Views
richard_hu
Contributor V

Hello, Sir:

We'd like to burn MAC address after booting into linux system.
I check there is an ocotp node added in "fsl-imx8mq.dtsi".

    ocotp: ocotp-ctrl@30350000 {
        compatible = "fsl,imx8mq-ocotp", "fsl,imx7d-ocotp", "syscon";
        reg = <0 0x30350000 0 0x10000>;
        clocks = <&clk IMX8MQ_CLK_OCOTP_ROOT>;
        /* For nvmem subnodes */
        #address-cells = <1>;
        #size-cells = <1>;
    };

But i check fsl_otp.c

There is no corresponding ocotp register mapping table for i.mx8m to be added.

So, i make an experiment to enable FSL_OTP driver in kernel configuration.

Symbol: FSL_OTP [=n]                                                                                                                         │
  │ Type  : tristate                                                                                                                             │
  │ Prompt: Freescale On-Chip OTP Memory Support                                                                                                 │
  │   Location:                                                                                                                                  │
  │     -> Device Drivers                                                                                                                        │
  │ (1)   -> Character devices                                                                                                                   │
  │   Defined at drivers/char/Kconfig:94                                                                                                         │
  │   Depends on: HAS_IOMEM [=y] && OF [=y]

And i use following command to burn MAC address into HW_OCOTP_MAC_ADDR1 and HW_OCOTP_MAC_ADDR0.

Then this board can only boot from serial downloand mode. (I think the fuses of boot mode are changed).
It explans the register mapping is wrong in fsl_otp.c .

My question is that fsl_otp.c doesn't support i.mx8m, why ocotp node is still added in fsl-imx8mq.dtsi?
Is there any plan to support fsl_otp.c for i.mx8m?

BR,

Richard

Labels (1)
Tags (2)
0 Kudos
1 Solution
15,860 Views
marius_grigoras
NXP Employee
NXP Employee

Hi everyone,

I'm really sorry for delay here.

Finally we have a solution which is upstreamed already.

 

The following patch from Linux community seems to fix nvmem fuse write for 8m/8MMini.

https://patchwork.kernel.org/cover/10928999/

The above changes are made for 4.14.y branch so we ported them on our latest release 4.14.98_2.0.0_ga (attached patch) - special thanks to Irina Patru.

 

So this should fix the write operation for both mx8m/mm.

 

We validated this by writing to the register corresponding to MAC address:

from struct import pack

f = open('/sys/devices/platform/30350000.ocotp-ctrl/imx-ocotp0/nvmem', 'br+')

f.seek(0x90)  # SRK0 position

f.write(pack('<L', 0xffffffff))

f.close()

 

There is not deadlock and fuse value is preserved after reboot:

# hexdump /sys/devices/platform/30350000.ocotp-ctrl/imx-ocotp0/nvmem

[…]

0000090 ffff ffff 0004 0000 0000 0000 0000 0000

00000a0 bada bada bada bada bada bada bada bada

[…]

 

Thank you,

Marius

View solution in original post

14 Replies
15,860 Views
andreacelani
Contributor II

Hello,

I have added the IMX8M support to the fsl_otp.c driver, so it is possible to read and write IMX8M fuse from the Linux user space, with simple command like this:

$ cat /sys/fsl_otp/HW_OCOTP_TESTER0

0xf0609912

I have posted the source code into a separate thread (OCOTP Shadow register reload ) because I have a problem with the OCOTP shadows reload function. It will be very useful if someone can check the new driver.

Kind regards,

                     Andrea.

0 Kudos
15,861 Views
caleb_pentecost
Contributor I

Hello,

I am having a very similar issue on an imx8mq device. I would like to write a value to the MAC_ADDR0 and MAC_ADDR1 fuses, but am unable to do so with the fsl_otp driver in linux.

I can write these fuses manually via uBoot with the commands:

fuse prog 9 0 12345678
fuse prog 9 1 000090ab

And I can even successfully read these mac addresses back out in linux with the fsl_opt driver:

root@imx8mq:/sys/fsl_otp# cat HW_OCOTP_MAC_ADDR0
0x12345678
root@imx8mq:/sys/fsl_otp# cat HW_OCOTP_MAC_ADDR1
0x90ab

However, I am unable to burn any fuses with this driver:

root@imx8mq:/sys/fsl_otp# echo "0x00000001" > HW_OCOTP_MAC_ADDR2
root@imx8mq:/sys/fsl_otp# cat HW_OCOTP_MAC_ADDR2
0x0

Is there perhaps something that I am doing wrong? Is the fsl_otp driver unable to burn fuses on the imx8mq? Is there another driver that can be used that supports this functionality?

Thank you,

~Caleb

15,858 Views
igorpadykov
NXP Employee
NXP Employee

one can try with fuse programming in uboot nxp L4.14.62_1.0.0

uboot-imx - i.MX U-Boot 

Best regards
igor

0 Kudos
15,858 Views
joussen
Contributor I

Hi Igor,

any update on this topic? We need to program some fuses from Linux using the 4.9.51 SDK.

Kind regards, Mario

0 Kudos
15,858 Views
igorpadykov
NXP Employee
NXP Employee
0 Kudos
15,861 Views
joussen
Contributor I

Can you share some more information on how to use it?

Right now our kernel is compiled with

CONFIG_NVMEM_IMX_OCOTP=y
CONFIG_NVMEM_IMX_SCU_OCOTP=y

and the device tree contains

 ocotp: ocotp-ctrl@30350000 {
 compatible = "fsl,imx8mq-ocotp", "fsl,imx7d-ocotp", "syscon";
 reg = <0 0x30350000 0 0x10000>;
 clocks = <&clk IMX8MQ_CLK_OCOTP_ROOT>;
 /* For nvmem subnodes */
 #address-cells = <1>;
 #size-cells = <1>;
 };

so we get /sys/devices/platform/30350000.ocotp-ctrl/imx-ocotp0/nvmem.

But what do we do with it?

Kind regards, Mario

0 Kudos
15,861 Views
marius_grigoras
NXP Employee
NXP Employee

Hi Mario,

I'm Marius (from NXP) - working for SE (Systems Engineering) Security group.

 

First of all, please use your private community group.

 

Secondly, indeed, there is a big change with the OTP driver from Linux. This was working just fine (both read/write operations) for i.mx6/7 and but starting with 4.14 GA release we support only read operations for all i.MX families.

Currently there is no plan to extend the functionality of the nvmem driver past read support.

The 4.14 kernel currently only supports reads even for the mx6 and mx7 families through the NVMEM driver.

Customers should use only u-boot level to program the fuses.

We never recommended in our i.MX8M (secure boot at least) documentation to use the Linux driver or the commands from Linux user-space to program the fuses.

Maybe there is somebody recommended them this way..or they just are familiar with the old way from i.mx6/7 families in the previous Linux BSPs.

 

But I have also some good news, you can use uuu (aka mfgtool 3.0) if you want a more powerful tool (if u-boot is not enough) and to automate the fuses programming. A snapshot from some internal uuu doc –  (is working also with your chip):

 

2.1.2 - Programing eFuses using UUU (Universal Update Utility)

 

The UUU (Universal Update Utility) is a SDP protocol flash programming tool:

Github - UUU (Universal Update Utility) - mfgtools 3.0

 

The uuu.auto file contains a set of commands used for properly flashing the targeted device:

Wiki - UUU Sample Scripts

 

Users can add U-Boot commands to program a set of eFuses depending on their specific use case. The command lines below added in i.MX8QXP uuu.auto file can be used as an example on how to program the MAC1_ADDR[47:00] fuses in i.MX8QXP:

 SDPS: boot -f imx-boot-imx8qxpmek-sd.bin-flash
+FB: ucmd fuse prog -y 0 708 0xa295fc11
+FB: ucmd fuse prog -y 0 709 0x000017b4
 FB: ucmd setenv fastboot_dev mmc
 FB: ucmd setenv mmcdev ${emmc_dev}
 FB: ucmd mmc dev ${emmc_dev}

 

Thank you,

Marius

15,860 Views
joussen
Contributor I

Hi Marius,

unfortunately I don't think that we can use UUU. Does UUU supports the 4.9.51 SDK? Additionally we need a process that can be initiated from a running Linux system.

What are the plans to bring write access from Linux back?

Kind regards, Mario

0 Kudos
15,860 Views
marius_grigoras
NXP Employee
NXP Employee

Hi Mario,

Unfortunately, I have negative answers for both of the questions.

Thank you,

Marius

0 Kudos
15,861 Views
marius_grigoras
NXP Employee
NXP Employee

Hi everyone,

I'm really sorry for delay here.

Finally we have a solution which is upstreamed already.

 

The following patch from Linux community seems to fix nvmem fuse write for 8m/8MMini.

https://patchwork.kernel.org/cover/10928999/

The above changes are made for 4.14.y branch so we ported them on our latest release 4.14.98_2.0.0_ga (attached patch) - special thanks to Irina Patru.

 

So this should fix the write operation for both mx8m/mm.

 

We validated this by writing to the register corresponding to MAC address:

from struct import pack

f = open('/sys/devices/platform/30350000.ocotp-ctrl/imx-ocotp0/nvmem', 'br+')

f.seek(0x90)  # SRK0 position

f.write(pack('<L', 0xffffffff))

f.close()

 

There is not deadlock and fuse value is preserved after reboot:

# hexdump /sys/devices/platform/30350000.ocotp-ctrl/imx-ocotp0/nvmem

[…]

0000090 ffff ffff 0004 0000 0000 0000 0000 0000

00000a0 bada bada bada bada bada bada bada bada

[…]

 

Thank you,

Marius

5,216 Views
craig_chen
Contributor II

@marius_grigoras 

Use sysfs node(/sys/devices/platform/30350000.ocotp-ctrl/imx-ocotp0/nvmem) write MAC address the actual offset is mapping as below? which is correct or all not?

offset 0x90 mapping OTP Bank9 Word0

offset 0x91 mapping OTP Bank9 Word1

offset 0x92 mapping OTP Bank9 Word2

or 

from offset 0x90 direct write 12bytes is mapping two eth MAC address

 

Best Regards

Craig 

0 Kudos
15,857 Views
caleb_pentecost
Contributor I

For reference, it appears that this driver is being loaded to expose the virtual files:

drivers/char/fsl_otp.c · 72c6f89cb0e8df491c2708d4b71e73fe8539da39 · Librem5 / linux-emcraft · GitLab 

That driver is included as dictated by the FSL_OTP flag:

drivers/char/Makefile · 72c6f89cb0e8df491c2708d4b71e73fe8539da39 · Librem5 / linux-emcraft · GitLab 

And the driver is being loaded as if the device was an "imx7" device since that is how the .dtsi is enumerating the otp resources:
arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi · 72c6f89cb0e8df491c2708d4b71e73fe8539da39 · Librem5 /... 

(Keep in mind, the Git repository linked is not the same one I am using, but the source files appear identical)

Thank you,

~Caleb

0 Kudos
15,859 Views
igorpadykov
NXP Employee
NXP Employee

Hi Richard

for i.MX8M seems this is linux/drivers/nvmem/imx-ocotp.c
imx-ocotp.c\nvmem\drivers - linux-imx - i.MX Linux kernel 

Also one can use uboot to program the fuse values (below example

enabling secure more with programming SEC_CONFIG[1]).
       fuse prog 1 3 0x2000000

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
15,859 Views
richard_hu
Contributor V

Hello, igor:

Thanks for your reply.

We will take a look on it.

BR,

Richard

0 Kudos