Burning eFuses on i.MX6 and i.MX7

3 minute read

What are eFuses?

The i.MX processors include eFuses (Fuse Box) used to store unchangeable data. The MAC address, security keys and boot modes configurations are examples of data which should be configure only once per board, additionally the eFuses can be also used to enable or disable chip features.

For a complete list of eFuses and their application please refer to the fusemap chapter on the processors reference manual.

At the hardware level the eFuse consists of a non-volatile memory that can be programmed only once, in the i.MX6 and i.MX7 families this memory is 4Kbit size in a 512x8 or 128x8 memory architecture. The On-Chip OTP Controller OCOTP_CTRL is the IP responsible for controlling and managing the eFuses.

The OTP Fuses are different on each SoC, the next table shows the difference for each:

Processor OTP Fuses
i.MX6ULL 512x8
i.MX6UL 512x8
i.MX6SLL 512x8
i.MX6SL 128x8
i.MX6SX 512x8
i.MX6S 512x8
i.MX6DL 512x8
i.MX6D 512x8
i.MX6DP 512x8
i.MX6Q 512x8
i.MX6QP 512x8
i.MX7S 128x8
i.MX7D 128x8

How do eFuses work?

The image below from the i.MX6Q Reference Manual shows the OCOTP system level diagram:

i.MX6Q On-Chip OTP Controller

For software convenience the OCOTP concatenates the 8-bit memory blocks in a 32-bit word as following on the i.MX6Q:

  • Bank: Group of 8 words.
  • Word: Group of 32 eFuses.
  • eFuse: 1 bit.

Independently of the memory architecture the OCOTP IP concatenates the memory block as the example above, for a 4Kbit memory we have 16 Banks with 8 words each and each word containing 32 eFuses, in total 4096 eFuses.

The OCOTP controller also loads the content of the Fuse Box into shadow registers after each operation, the fuse burning can be confirmed by reading the OCOTP registers.

Note: On the i.MX7S and i.MX7D each bank has 4 words.

Calculating Fuse Bank and Word

For i.MX6 family the eFuses base address is 0x400.

On the i.MX6Q The MAC address is located at 0x620[31:0] (Lower MAC address) and 0x630[15:0] (Upper MAC address), the following example in U-Boot documentation can be used for calculating the bank and word for the Lower MAC address.

(0x620 - 0x400)/0x10 = 0x22 Hexadecimal = 34 Decimal

As the fuses are arranged in banks of 8 words:

34 / 8 = 4 and the remainder is 2, so in this case:

Bank = 4
Word = 2

This fuse word is shadowed in the register OCOTP_MAC0 (0x021BC620h)

The same cannot be applied to i.MX7D and i.MX7S. Please refer to
the "6.4.5 OCOTP Memory Map/Register Definition" chapter on the
processor Reference Manual for a correct bank and word values.

Burning eFuses in U-Boot

The fuse API CONFIG_CMD_FUSE can be used to burn eFuses in U-Boot terminal:

The command fuse prog is irreversible and can brick your device.

=> fuse read <bank> <word> [<cnt>]
Reads the eFuse value from the shadow register.

=> fuse sense <bank> <word> [<cnt>]
Reads the eFuse value directly from the fusebox.

=> fuse prog [-y] <bank> <word> <hexval>
Write directly in the fusebox
#NOTE: This operation is irreversible and can brick your device.

=> fuse override <bank> <word> <hexval> [<hexval>...]
Override just the shadow register this operation doesn't affects the fusebox,
so it's cleaned after a reset.
This command may be useful for testing purpose.

For an example please check the following post.

Burning eFuses in user space

For linux-imx users the eFuses can be programmed at user space level through Freescale On-Chip OTP Memory Support driver FSL_OTP:

# ls /sys/fsl_otp/HW_OCOTP_MAC*
/sys/fsl_otp/HW_OCOTP_MAC0  /sys/fsl_otp/HW_OCOTP_MAC1

Reading and writing can be done using the echo and cat commands.

For an example please check the following post.

Burning eFuses in mfgtools

Similar to the topic above the mfgtools can be used to burn eFuses, edit your ucl2.xml as following:

<CMD state="Updater" type="push" body="$ echo 0xFUSE_VALUE > /sys/fsl_otp/HW_OCOTP_FUSE1">Program FUSE1 </CMD>
<CMD state="Updater" type="push" body="$ echo 0xFUSE_VALUE > /sys/fsl_otp/HW_OCOTP_FUSE2">Program FUSE2 </CMD>

Note: The FSL_OTP driver is not enabled by default on imx_v7_mfg_defconfig, it’s necessary to enable it manually.

This can be achieved by setting the following in Kernel menuconfig:

$ make imx_v7_mfg_defconfig
$ make menuconfig
Device Drivers
	-> Character devices
		-> <*> Freescale On-Chip OTP Memory Support