3.3.3.24. MMCSD

3.3.3.24.1. Introduction

The multimedia card secure digital (MMCSD) host controller provides an interface between a local host (LH) such as a microprocessor unit (MPU) or digital signal processor (DSP) and either embedded multimedia card (eMMC), secure digital (SD), or secure digital input/output (SDIO) devices. The MMCSD host controller handles MMCSD and SDIO protocol with minimal LH intervention.

Main features of the MMCSD host controllers:

  • Full compliance with MMCSD command/response sets as defined in the Specification.

  • Support:

    • 4-bit transfer mode specifications for SD and SDIO cards

    • 8-bit transfer mode specifications for eMMC

    • Built-in 1024-byte buffer for read or write

    • 32-bit-wide access bus to maximize bus throughput

    • Single interrupt line for multiple interrupt source events

    • Two slave DMA channels (1 for TX, 1 for RX)

    • Designed for low power and programmable clock generation

    • Maximum operating frequency of 48MHz

    • MMCSD card hot insertion and removal

The following image shows the MMCSD Driver Architecture:

../../../../../_images/Mmcsd_Driver.png

3.3.3.24.2. References

  1. JEDEC eMMC homepage

  2. SD organization homepage

3.3.3.24.3. Features

The SD driver supports the following features:

  • The driver is built in-kernel (part of vmlinux)

  • SD cards including SD High Speed and secure digital high capacity (SDHC) cards

  • Uses block bounce buffer to aggregate scattered blocks

3.3.3.24.4. Supported ultra high speed (UHS) modes

Platform

SDR104

DDR50

SDR50

SDR25

SDR12

DRA74-EVM

Y

Y

Y

Y

Y

DRA72-EVM

Y

Y

Y

Y

Y

DRA71-EVM

Y

Y

Y

Y

Y

DRA72-EVM-REVC

Y

Y

Y

Y

Y

AM57XX-EVM

N

N

N

N

N

AM57XX-EVM-REVA3

N

N

N

N

N

AM572X-IDK

N

N

N

N

N

AM571X-IDK

N

N

N

N

N

AM654-SR2-EVM

Y

Y

Y

Y

Y

Note

In AM654-SR1-EVM none of the UHS modes are supported.

Important Info: Certain UHS cards do not enumerate. The list of functional UHS cards is given in the following tables

FUNCTIONAL UHS CARDS

ATP 32GB UHS CARD AF32GUD3

STRONTIUM NITRO 466x UHS CARD

SANDISK EXTREME UHS CARD

SANDISK ULTRA UHS CARD

SAMSUNG EVO+ UHS CARD

SAMSUNG EVO UHS CARD

KINGSTON UHS CARD (DDR mode)

TRANSCEND PREMIUM 400X UHS CARD (Non fatal error and then it re-enumerates in UHS mode)

FUNCTIONAL (WITH LIMITED CAPABILITY) UHS CARD

SONY UHS CARD - Voltage switching fails and enumerates in high speed

GSKILL UHS CARD - Voltage switching fails and enumerates in high speed

PATRIOT 8G UHS CARD - Voltage switching fails and enumerates in high speed

Known Workaround: For cards that don’t enumerate in UHS mode, removing the PULLUP resistor in CLK line and changing the GPIO to PULLDOWN increases the frequency that the card enumerates in UHS modes.

Platform

DDR

HS200

DRA74-EVM

Y

Y

DRA72-EVM

Y

Y

DRA71-EVM

Y

Y

DRA72-EVM-REVC

Y

Y

AM57XX-EVM

Y

N

AM57XX-EVM-REVA3

Y

N

AM572X-IDK

Y

N

AM571X-IDK

Y

N

AM654-SR2-EVM

Y

Y

3.3.3.24.5. Driver configuration

The default kernel configuration enables support for MMCSD(built-in to kernel).

The selection of MMCSD/SDIO driver can be modified using the linux kernel configuration tool. Launch it by the following command:

$ make menuconfig  ARCH=arm

Building into Kernel

Ensure that the following config options are set to ‘y’: * CONFIG_MMC * CONFIG_MMC_BLOCK * CONFIG_MMC_SDHCI * CONFIG_MMC_SDHCI_OMAP (for DRA7XX and AM57XX devices) * CONFIG_MMC_OMAP (for AM335X and AM437X devices)

Building as Loadable Kernel Module

Depending on your configuration, any of the above options can be set to ‘m’ to build them as a module. Use the following command to install all modules tp your filesystem.

$ sudo -E make modules_install ARCH=arm INSTALL_MOD_PATH=path/to/filesystem

Boot the kernel up-to kernel prompt and use modprobe to insert the driver module and all its dependencies.

$ modprobe sdhci-omap             # for DRA7XX and AM57XX devices
$ modprobe omap_hsmmc             # for AM335X and AM437X devices

If udev is running and the SD card is already inserted, the required modules will be loaded and any valid filesystem will be automatically mounted if they exist on the card.

Enabling eMMC Card Background operations support

eMMC cards need to occasionally spend some time cleaning up garbage and perform cache/buffer related operations. These are strictly on the card side and do not involve the host. They occur at one of the three levels based on the importance/severity of the operation:

  1. Normal

  2. Important

  3. Critical

If an operation is delayed for too long, it becomes critical, taking priority over the regular read/write from host. This can cause host operations to be delayed or take more time than expected. To avoid such issues the multimedia card (MMC) HW and core driver provide a framework that can check for pending background operations and give the card some time to service them before they become critical. This feature is already part of the framework and to start using it the User needs to enable: EXT_CSD : BKOPS_EN [163] BIT 0.

This can be done using the “mmc-utils” tool from user space or using the “mmc” command in U-boot.

Command to enable bkops from userspace using mmc-utils, assuming eMMC instance to be mmcblk0

root@<machine>:mmc bkops enable /dev/mmcblk0

You can find the instance of eMMC by reading the ios timing spec from debug filesystem (debugfs):

root@<machine>:~# cat /sys/kernel/debug/mmc0/ios
----
timing spec:    9 (mmc HS200)
---

or by looking for boot partitions, eMMC has two boot partitions mmcblk<x>boot0 and mmcblk<x>boot1

root@<machine>:/# ls /dev/mmcblk*boot*
/dev/mmcblk0boot0  /dev/mmcblk0boot1

3.3.3.24.6. MMC support in Linux

There is no missing MMC support for AM57X devices device.

3.3.3.24.7. Steps for working around SD card issues in Linux

Steps for working around SD card issues in Linux documentation is pending for AM57X devices please reach out to: Help e2e for additional information.


3.3.3.24.8. Listing MMC devices from Linux

eMMC and SD cards register with the MMC subsystem and are available as a block device as /dev/mmcblkn. To find the device index n corresponding to an eMMC device, check which device includes mmcblknboot0 and mmcblknboot1. Here, mmcblk0* is in eMMC.

root@<machine>:~# ls -l /dev/mmcblk*
brw-rw---- 1 root disk 179,  0 Jan  1 00:10 /dev/mmcblk0
brw-rw---- 1 root disk 179, 32 Jan  8  2025 /dev/mmcblk0boot0
brw-rw---- 1 root disk 179, 64 Jan  8  2025 /dev/mmcblk0boot1
brw-rw---- 1 root disk 179,  1 Jan  1 00:14 /dev/mmcblk0p1
crw------- 1 root root 239,  0 Jan  1 00:00 /dev/mmcblk0rpmb
brw-rw---- 1 root disk 179, 96 Jan  8  2025 /dev/mmcblk1
brw-rw---- 1 root disk 179, 97 Jan  1 00:00 /dev/mmcblk1p1
brw-rw---- 1 root disk 179, 98 Jan  8  2025 /dev/mmcblk1p2

The disk partitions for each MMC device are displayed as /dev/mmcblknpx. To check existing or mounted disk partitions for an eMMC device, use the command lsblk, such as:

root@<machine>:~# lsblk
NAME         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
mmcblk0      179:0    0 14.8G  0 disk
mmcblk0boot0 179:32   0 31.5M  1 disk
mmcblk0boot1 179:64   0 31.5M  1 disk
mmcblk1      179:96   0 14.8G  0 disk
|-mmcblk1p1  179:97   0  128M  0 part /run/media/boot-mmcblk1p1
`-mmcblk1p2  179:98   0  1.9G  0 part /

Use the mount and umount commands to mount and unmount formatted disk partitions, usually to virtual file allocation table (vfat) or fourth extended file system (ext4) types.

3.3.3.24.9. Create partitions in eMMC UDA

In eMMC, the user data area (UDA) HW partition is the primary storage space generally used to flash the root filesystem (rootfs). To create disk partitions in UDA, use the fdisk command. For ex: fdisk /dev/mmcblkn in which n is typically 0 or 1. In the previous example, eMMC is fdisk /dev/mmcblk0.

For documentation on using fdisk command, go to: fdisk how-to.

Erase eMMC UDA

In Linux, before creating disk partitions, we can optionally erase eMMC UDA by using dd command:

root@<machine>:~# umount /dev/mmcblk0*
root@<machine>:~# dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=n

where n should be determined according to the following formula: count = total size UDA (bytes) / bs.

3.3.3.24.9.1. Create “boot” partition

In this example create a “boot” partition of size 400 MiB which can be formatted to vfat type and will store the boot loader binaries.

root@<machine>:~# fdisk /dev/mmcblk0

Welcome to fdisk (util-linux 2.39.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): n
Partition type
p   primary (0 primary, 0 extended, 4 free)
e   extended (container for logical partitions)
Select (default p):

Using default response p.
Partition number (1-4, default 1):
First sector (2048-31080447, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-31080447, default 31080447): +400M

Created a new partition 1 of type 'Linux' and of size 400 MiB.
Partition #1 contains a vfat signature.

Do you want to remove the signature? [Y]es/[N]o: y

The signature will be removed by a write command.

Command (m for help): a
Selected partition 1
The bootable flag on partition 1 is enabled now.

Command (m for help): t
Selected partition 1
Hex code or alias (type L to list all): c
Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'.

Command (m for help): w
The partition table has been altered.
[  644.818358]  mmcblk0: p1
Calling ioctl() to re-read partition table.
Syncing disks.

Make sure bootable flag is set for “boot” partition, ROM might not boot from this partition if bootable flag is not set.

3.3.3.24.9.2. Create “root” partition

In this example create a “root” partition which can be formatted to ext4 type and will store Linux kernel Image, DTB, and the rootfs.

root@<machine>:~# fdisk /dev/mmcblk0

Welcome to fdisk (util-linux 2.39.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

This disk is currently in use - repartitioning is probably a bad idea.
It's recommended to umount all file systems, and swapoff all swap
partitions on this disk.


Command (m for help): n
Partition type
p   primary (1 primary, 0 extended, 3 free)
e   extended (container for logical partitions)
Select (default p):

Using default response p.
Partition number (2-4, default 2):
First sector (821248-31080447, default 821248):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (821248-31080447, default 31080447):

Created a new partition 2 of type 'Linux' and of size 14.4 GiB.

Command (m for help): t
Partition number (1,2, default 2): 2
Hex code or alias (type L to list all): 83

Changed type of partition 'Linux' to 'Linux'.

Command (m for help): w
The partition table has been altered.
Syncing disks.

3.3.3.24.10. Formatting eMMC partitions from Linux

After creating a partition/s, the partition can be formatted with the mkfs command. For ex: mkfs -t ext4 /dev/mmcblkn where mmcblk{n} is the MMC device with the new disk partitions to format. The general syntax for formatting disk partitions in Linux is:

mkfs.vfat [OPTIONS] TARGET [BLOCKS]
mkfs.ext4 [-c|-l filename] [-b block-size] [-C cluster-size]

3.3.3.24.10.1. Format to vfat

In this example, format the “boot” partition to type vfat.

root@<machine>:~# mkfs.vfat -F 32 -n "boot" /dev/mmcblk0p1

3.3.3.24.10.2. Format to ext4

In this example, format the “root” partition to type ext4.

root@<machine>:~# mkfs.ext4 -L "root" /dev/mmcblk0p2

Verify partitions

Verify setup of mmcblk0p1 and mmcblk0p2 with lsblk command.

root@<machine>:~# lsblk -o name,mountpoint,label,size,uuid
NAME         MOUNTPOINT                LABEL  SIZE UUID
mmcblk0                                      14.8G
|-mmcblk0p1                            boot   400M E4D4-4879
`-mmcblk0p2                            root  14.4G 74d40075-07e4-4bce-9401-6fccef68e934
mmcblk0boot0                                 31.5M
mmcblk0boot1                                 31.5M
mmcblk1                                      29.7G
|-mmcblk1p1  /run/media/boot-mmcblk1p1 boot   128M 681F-55DD
`-mmcblk1p2  /                         root   8.7G ead4c8bb-fa37-4c4d-9ba3-47a1f3824764

3.3.3.24.11. Flash eMMC for MMCSD boot

In this example, we show one simple method for flashing to eMMC for MMCSD boot from eMMC UDA in filesystem (FS) mode. Know this is not the only method for flashing the eMMC for this boot mode.

This example assumes the current boot mode is MMCSD boot from SD (FS mode)

3.3.3.24.11.1. Flash to eMMC “boot” partition

root@<machine>:~# umount /run/media/*
root@<machine>:~# mkdir /mnt/eboot /mnt/sdboot
root@<machine>:~# mount /dev/mmcblk0p1 /mnt/eboot
root@<machine>:~# mount /dev/mmcblk1p1 /mnt/sdboot

Verify the partitions are mounted to the correct folders by using lsblk command in the column labeled MOUNTPOINTS.

root@<machine>:~# lsblk
NAME         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
mmcblk0      179:0    0 14.8G  0 disk
|-mmcblk0p1  179:1    0  400M  0 part /mnt/eboot
`-mmcblk0p2  179:2    0 14.4G  0 part
mmcblk0boot0 179:32   0 31.5M  1 disk
mmcblk0boot1 179:64   0 31.5M  1 disk
mmcblk1      179:96   0 29.7G  0 disk
|-mmcblk1p1  179:97   0  128M  0 part /mnt/sdboot
`-mmcblk1p2  179:98   0  8.7G  0 part /

Now we can copy boot loader binaries to eMMC and umount the partitions when writes finish.

root@<machine>:~# ls /mnt/sdboot/
tiboot3.bin  tispl.bin       u-boot.img  uEnv.txt
root@<machine>:~# cp /mnt/sdboot/* /mnt/eboot/
root@<machine>:~# sync && umount /mnt/*

3.3.3.24.11.2. Flash to eMMC “root” partition

root@<machine>:~# umount /run/media/*
root@<machine>:~# mkdir /mnt/eroot /mnt/sdroot
root@<machine>:~# mount /dev/mmcblk0p2 /mnt/eroot
[69229.982452] EXT4-fs (mmcblk0p2): mounted filesystem 74d40075-07e4-4bce-9401-6fccef68e934 r/w with ordered data mode. Quota mode: none.
root@<machine>:~# mount /dev/mmcblk1p2 /mnt/sdroot

Verify the partitions are mounted to the correct folders by using lsblk command in the column labeled MOUNTPOINTS.

root@<machine>:~# lsblk
NAME         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
mmcblk0      179:0    0 14.8G  0 disk
|-mmcblk0p1  179:1    0  400M  0 part
`-mmcblk0p2  179:2    0 14.4G  0 part /mnt/eroot
mmcblk0boot0 179:32   0 31.5M  1 disk
mmcblk0boot1 179:64   0 31.5M  1 disk
mmcblk1      179:96   0 29.7G  0 disk
|-mmcblk1p1  179:97   0  128M  0 part
`-mmcblk1p2  179:98   0  8.7G  0 part /mnt/sdroot
                                      /

Now we can copy rootfs to eMMC (either from SD rootfs or from tar file) and umount the partitions when writes finish.

From SD

root@<machine>:~# ls /mnt/sdroot
bin   dev  home  lost+found  mnt  proc       run   srv  tmp  var
boot  etc  lib        media       opt  root  sbin  sys  usr
root@<machine>:~# cp -r -a /mnt/sdroot/* /mnt/eroot
root@<machine>:~# sync
root@<machine>:~# umount /mnt/*
[70154.205154] EXT4-fs (mmcblk0p2): unmounting filesystem 74d40075-07e4-4bce-9401-6fccef68e934.

From tar file

This sections requires for tisdk-base-image-<soc>evm.rootfs.tar.xz to have been previously copied to the SD card rootfs.

root@<machine>:~# ls
tisdk-base-image-<soc>-evm.rootfs.tar.xz
root@<machine>:~# tar -xpf tisdk-base-image-<soc>-evm.rootfs.tar.xz -C /mnt/eroot
root@<machine>:~# sync
root@<machine>:~# umount /mnt/*