3.1.1.3. SD, eMMC and USB

The following guide shows how to flash and boot from storage media like the embedded multimedia card (eMMC), secure digital (SD) card, and USB storage devices. While this is a step-by-step guide, it is in no way extensive and does not cover all the per-platform corner-cases. For any issues/questions on this guide, please reach out to: Help e2e.

3.1.1.3.1. MMC

3.1.1.3.1.1. Listing MMC devices

Usually in all the platforms there will be two MMC instances of which one would be SD and the other would be eMMC. The index of them can vary from one class of platforms to the other. For a given platform, the device number: mmcdev=[0:1] can be found in the following way:

=> mmc list
sdhci@fa10000: 0 (eMMC)
sdhci@fa00000: 1 (SD)

The device number “0” for eMMC will be needed when flashing to the eMMC device in: Flash and boot SPL from eMMC.

3.1.1.3.1.2. Selecting MMC device and paritions

To selct an MMC device in u-boot, the command: mmc dev could be used. The general syntax is:

=> mmc dev [dev] [partition]

The following lists examples and their explanation for each MMC device and partitions according to the example in: Listing MMC devices.

=> mmc dev 0 0 # select eMMC user HW partition (UDA)
=> mmc dev 0 1 # select eMMC boot0 HW partition
=> mmc dev 0 2 # select eMMC boot1 HW partition
=> mmc dev 1 1 # select SD "boot" partition
=> mmc dev 1 2 # select SD "root" partition

3.1.1.3.1.3. View MMC partition contents

This section assumes an SD card or eMMC was prepared previously to boot the device.

Note

For eMMC, typically, the device ships without a partition table If there is a need to create a partition in UDA (to flash the rootfs), please go to: Create software partitions in eMMC UDA and format the partition: Formatting eMMC partitions from Linux before proceeding to look at the eMMC partition contents.

To verify partitions in any MMC device from u-boot prompt, use the command: mmc part.

=> mmc dev 0
switch to partitions #0, OK
mmc0(part 0) is current device
=> mmc part

Partition Map for MMC device 0  --   Partition Type: DOS

Part   Start Sector    Num Sectors     UUID           Type
 1     2048            31078400        8ece5cfe-01    83

If the partitions are formatted with a file system type that is supported by u-boot, you can view the contents of the MMC partition as show below:

=> ls mmc 0:1
<DIR>       4096 .
<DIR>       4096 ..
<SYM>          7 bin
<DIR>       4096 boot
<DIR>       4096 dev
<DIR>       4096 etc
<DIR>       4096 home
<SYM>          7 lib
<DIR>       4096 media
<DIR>       4096 mnt
<DIR>       4096 opt
<DIR>       4096 proc
<DIR>       4096 root
<DIR>       4096 run
<SYM>          8 sbin
<DIR>       4096 srv
<DIR>       4096 sys
<DIR>       4096 tmp
<DIR>       4096 usr
<DIR>       4096 var
=> ls mmc 0:1 boot/dtb/ti
<DIR>       4096 .
<DIR>       4096 ..
           60319 k3-am625-sk.dtb

Where the general syntax is:

$ ls <interface> [<dev[:partition]> [directory]]

3.1.1.3.1.4. Flash and boot SPL from eMMC

The K3 based processors supports and recommends booting from the eMMC boot0/1 HW partitions. In the following example, we use the fatload and mmc write commands to load binaries from an SD card and write them to the eMMC boot0 HW partition:

=> mmc dev 0 1
=> fatload mmc 1 ${loadaddr} tiboot3.bin
=> mmc write ${loadaddr} 0x0 0x400
=> fatload mmc 1 ${loadaddr} tispl.bin
=> mmc write ${loadaddr} 0x400 0x1000
=> fatload mmc 1 ${loadaddr} u-boot.img
=> mmc write ${loadaddr} 0x1400 0x2000
=> fatload mmc 1 ${loadaddr} sysfw.itb
=> mmc write ${loadaddr} 0x3600 0x800

3.1.1.3.1.4.1. eMMC layout

+----------------------------------+0x0      +-------------------------+0x0
|      tiboot3.bin (512 KB)        |         |                         |
+----------------------------------+0x400    |                         |
|       tispl.bin (2 MB)           |         |                         |
+----------------------------------+0x1400   |        rootfs           |
|       u-boot.img (4 MB)          |         |                         |
+----------------------------------+0x3400   |                         |
|      environment (128 KB)        |         |                         |
+----------------------------------+0x3500   |                         |
|   backup environment (128 KB)    |         |                         |
+----------------------------------+0x3600   |                         |
|          sysfw (1 MB)            |         |                         |
+----------------------------------+0x3E00   +-------------------------+
      boot0 HW partition (8 MB)                     user partition

3.1.1.3.1.4.2. eMMC boot configuration

To boot from any eMMC, the master (ROM) will require some configuration which can be set using the mmc bootbus and mmc partconf commands.

  • The mmc bootbus command sets the BOOT_BUS_WIDTH field where mmc bootbus 0 2 0 0 selects x8 (sdr/ddr) buswidth in boot operation mode.

  • The mmc partconf command can be used to configure what hardware partition to boot from. The general syntax is:

$ mmc partconf <dev> [[varname] | [<boot_ack> <boot_partition> <partition_access>]]
  • For more information on these commands, please refer to: MMC CMD.

Boot from boot0 HW partition of eMMC:

=> mmc partconf 0 1 1 1
=> mmc bootbus 0 2 0 0

Boot from boot1 HW hardware partition of eMMC:

=> mmc partconf 0 1 2 1
=> mmc bootbus 0 2 0 0

Note

When booting from boot1 HW partition, make sure to flash the partition using: mmc dev 0 2.

Boot from UDA HW partition of eMMC:

=> mmc partconf 0 1 7 1
=> mmc bootbus 0 2 0 0

Enable warm reset

On eMMC devices, warm reset will not work if EXT_CSD[162] bit is unset since the reset input signal will be ignored. Warm reset is required to be enabled in order for the eMMC to be in a “clean state” on power-on reset so that ROM can do a clean enumeration. To set the EXT_CSD[162] bit, stop at u-boot prompt and execute the following command:

=> mmc rst-function 0 1

Warning

This is a write-once field. For more information, please refer to the u-boot doc: MMC CMD.

3.1.1.3.1.5. Boot Linux from eMMC

To flash & boot the rootfs from eMMC UDA HW partition, first prepare UDA: Create software partitions in eMMC UDA. The new software partition then needs to be formatted as a ext4 filesystem: Formatting eMMC partitions from Linux, and then the rootfs has to be written. It is not possible to format a partition to ext4 in U-Boot. The Linux kernel image and DT are expected to be present in the /boot folder of rootfs.

To boot Linux from eMMC, use the following commands after flashing rootfs to UDA:

=> setenv mmcdev 0
=> setenv bootpart 0
=> boot

3.1.1.3.1.6. Flashing an MMC device using USB-DFU

To flash the eMMC device (boot0 HW partition) using USB-DFU, the device should be booted to u-boot prompt and a USB cable connected from the host machine to the device USB port configured to USB peripheral mode.

From u-boot prompt execute the following:

=> setenv dfu_alt_info ${dfu_alt_info_emmc}
=> dfu 0 mmc 0

and on the host machine have the bootloader binaries ready to flash to eMMC boot0 HW partition. Execute the dfu-util to transfer files to the device. The general syntax for dfu-util command is:

$ sudo dfu-util -R -a <dfu-target> -D <binary>

To see what are the dfu-targets, on the host machine run: sudo dfu-util -l

$ sudo dfu-util -l
dfu-util 0.9
Found DFU: [0451:6165] ver=0223, devnum=32, cfg=1, intf=0, path="1-10", alt=6, name="sysfw.itb.raw", serial="0000000000000591"
Found DFU: [0451:6165] ver=0223, devnum=32, cfg=1, intf=0, path="1-10", alt=5, name="u-env.raw", serial="0000000000000591"
Found DFU: [0451:6165] ver=0223, devnum=32, cfg=1, intf=0, path="1-10", alt=4, name="u-boot.img.raw", serial="0000000000000591"
Found DFU: [0451:6165] ver=0223, devnum=32, cfg=1, intf=0, path="1-10", alt=3, name="tispl.bin.raw", serial="0000000000000591"
Found DFU: [0451:6165] ver=0223, devnum=32, cfg=1, intf=0, path="1-10", alt=2, name="tiboot3.bin.raw", serial="0000000000000591"
Found DFU: [0451:6165] ver=0223, devnum=32, cfg=1, intf=0, path="1-10", alt=1, name="rootfs", serial="0000000000000591"
Found DFU: [0451:6165] ver=0223, devnum=32, cfg=1, intf=0, path="1-10", alt=0, name="rawemmc", serial="0000000000000591"

Then transfer each desired binary from the host to the device:

  • Host:

    $ sudo dfu-util -R -a tiboot3.bin.raw -D tiboot3.bin
    
  • Device:

    ##DOWNLOAD ... OK
    Ctrl+C to exit ...
    

3.1.1.3.1.7. Flashing an SD card from a host PC

This section assumes that you have flashed an SD card using the script “create-sdcard.sh” packaged in the installer or have made a compatible layout manually. In this case, you will need to copy the boot images:

  • tiboot3.bin

  • tispl.bin

  • u-boot.img

to the SD card boot partition. At this point, the device can boot to u-boot prompt.

3.1.1.3.2. USB

3.1.1.3.2.1. Configuring USB in Host Mode

Configuring USB in host mode documentation is pending for AM62Px please reach out to: Help e2e for additional information.

3.1.1.3.2.2. Flash and boot SPL from USB storage

Boot SPL from USB storage documentation is pending for AM62Px please reach out to: Help e2e for additional information.

3.1.1.3.2.3. Boot Linux from USB storage

Booting Linux from USB storage documentation is pending for AM62Px please reach out to: Help e2e for additional information.

3.1.1.3.2.4. Steps for working around SD card issues in u-boot

In some cases, issues can be seen while using some SD cards, like:

  • Error while trying to initialize:

    U-Boot SPL 2021.01-g74fc69c889 (May 19 2022 - 02:44:29 +0000)
    SYSFW ABI: 3.1 (firmware rev 0x0008 '8.3.2--v08.03.02 (Jolly Jellyfi')
    Trying to boot from MMC2
    spl: mmc init failed with error: -110
    SPL: failed to boot from all boot devices
    ### ERROR ### Please RESET the board ###
    

Given below are the list of various workarounds that can be done in the device tree MMC node to get SD card working. The workarounds are ordered in increasing order of reducing performance.

Note

All the mentioned below, are to be done in the MMC device tree node corresponding to the SD instance. This is usually the first (index starting from zero) instance.

  1. Restricting to a given speed mode

    By default the U-Boot driver tries to enumerate a SD card in the highest supported speed mode. Given below is the order in which the driver tries to enumerate a SD card:

    • SDR104

    • SDR50

    • DDR50

    • SD HS

    • SD legacy

    The sdhci-caps-mask can be added to the DT node to cap at a specific mode:

    • Limit to DDR50: sdhci-caps-mask = <0x00000003 0x00000000>

    • Limit to SD HS: sdhci-caps-mask = <0x00000007 0x00000000>

    • Limit to SD legacy: sdhci-caps-mask = <0x00000007 0x00200000>

    &sdhci1 {
       /* SD/MMC */
       vmmc-supply = <&vdd_mmc1>;
       vqmmc-supply = <&vdd_sd_dv>;
       pinctrl-names = "default";
       pinctrl-0 = <&main_mmc1_pins_default>;
       ti,driver-strength-ohm = <50>;
       disable-wp;
       sdhci-caps-mask = <0x00000003 0x00000000>; /* Limiting to DDR50 speed mode */
    };
    
  2. Increase power cycle period

    Increasing the delay while power cycling the SD card. This can be done by increasing the delay value in the diff indicated below,

    diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
    index f486e2a2c364..38cc956b3d53 100644
    --- a/drivers/mmc/mmc.c
    +++ b/drivers/mmc/mmc.c
    @@ -2761,7 +2761,7 @@ static int mmc_power_cycle(struct mmc *mmc)
             * SD spec recommends at least 1ms of delay. Let's wait for 2ms
             * to be on the safer side.
             */
    -       udelay(2000);
    +       udelay(4000);
          return mmc_power_on(mmc);
    }
    
  3. Reduce the bus width

    The SD interface supports a bus width of 4. It can be reduced to 1 by changing the bus-width device tree property from 4 to 1.

    diff --git a/arch/arm/dts/k3-am62-main.dtsi b/arch/arm/dts/k3-am62-main.dtsi
    index c06ec7355035..4ab29b6aa4b7 100644
    --- a/arch/arm/dts/k3-am62-main.dtsi
    +++ b/arch/arm/dts/k3-am62-main.dtsi
    @@ -373,7 +373,7 @@
                   ti,itap-del-sel-sdr12 = <0x0>;
                   ti,itap-del-sel-sdr25 = <0x0>;
                   ti,clkbuf-sel = <0x7>;
    -               bus-width = <4>;
    +               bus-width = <1>;
    };
    
    sdhci2: mmc@fa20000 {