Burning eFuses on i.MX6 and i.MX7
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:
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