SD/MMC Card (Linux)
Introduction
SD/MMC cards which use the MMC subsystem are available as block device through /dev/mmcblk{id}. The kernel normally parses the partition table and exports the partitions of the card using the appendix p{x}, e.g. /dev/mmcblk{id}p{x}.
SD/MMC Kernel Output and Debug Information
This example output was obtained with a 'Colibri iMX6ULL 256MB V1.0A' running the Linux BSP 3.0b3.
SD/MMC Driver Initialization
The following bootlog shows the detection of an SDHCI controller:
root@colibri-imx6ull:~# dmesg | egrep "(sdhci|mmc)"
[ 1.880782] sdhci: Secure Digital Host Controller Interface driver
[ 1.890679] sdhci: Copyright(c) Pierre Ossman
[ 1.898540] sdhci-pltfm: SDHCI platform and OF driver helper
[ 1.909980] sdhci-esdhc-imx 2190000.usdhc: Got CD GPIO
[ 1.984346] mmc0: SDHCI controller on 2190000.usdhc [2190000.usdhc] using ADMA
Before inserting any card no interrupts are generated yet:
root@colibri-imx6ull:~# cat /proc/interrupts | egrep "(mmc|cd)"
58: 0 GPC 22 Level mmc0
200: 0 gpio-mxc 0 Edge 2190000.usdhc cd
And the IOs debugging information is not valid yet:
root@colibri-imx6ull:~# cat /sys/kernel/debug/mmc0/ios
clock: 0 Hz
vdd: 0 (invalid)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 0 (off)
bus width: 0 (1 bits)
timing spec: 0 (legacy)
signal voltage: 0 (3.30 V)
driver type: 0 (driver type B)
With the MMC_CD card detection GPIO pin still being pulled-up:
root@colibri-imx6ull:~# cat /sys/kernel/debug/gpio | grep cd
gpio-128 ( |cd ) in hi IRQ
SD/MMC Card Insertion
On insertion, the kernel starts scanning the card in order to create devices for each partition. Depending on the Automount configuration the detected file systems get mounted automatically.
[ 286.140413] mmc0: new high speed SDHC card at address 0007
[ 286.150926] mmcblk0: mmc0:0007 SDCIT 7.29 GiB
[ 286.170497] mmcblk0: p1 p2
[ 287.691840] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
Interrupts are happening (note one card detect GPIO interrupt thereof):
root@colibri-imx6ull:~# cat /proc/interrupts | egrep "(mmc|cd)"
58: 375 GPC 22 Level mmc0
200: 1 gpio-mxc 0 Edge 2190000.usdhc cd
And the IOs debugging information should now show valid information about the inserted card:
root@colibri-imx6ull:~# cat /sys/kernel/debug/mmc0/ios
clock: 50000000 Hz
actual clock: 49500000 Hz
vdd: 21 (3.3 ~ 3.4 V)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 2 (on)
bus width: 2 (4 bits)
timing spec: 2 (sd high-speed)
signal voltage: 0 (3.30 V)
driver type: 0 (driver type B)
With the MMC_CD card detection GPIO pin now being pulled to ground:
root@colibri-imx6ull:~# cat /sys/kernel/debug/gpio | grep cd
gpio-128 ( |cd ) in lo IRQ
More specifics about the inserted card can be found in its CID/CSD:
root@colibri-imx6ull:~# cat /sys/bus/mmc/devices/mmc0\:0007/cid
413432534443495430002e35cf012800
root@colibri-imx6ull:~# cat /sys/bus/mmc/devices/mmc0\:0007/csd
400e00325b5900003a4f7f800a400000
The utility df shows the usage of the SD/MMC card:
root@colibri-imx6ull:~# df | grep mmc
/dev/mmcblk0p2 1467980 903468 470664 66% /media/mmcblk0p2
/dev/mmcblk0p1 85010 22894 62116 27% /media/mmcblk0p1
And mount shows the mounting status:
root@colibri-imx6ull:~# mount | grep mmc
/dev/mmcblk0p2 on /media/mmcblk0p2 type ext4 (rw,relatime,data=ordered)
/dev/mmcblk0p1 on /media/mmcblk0p1 type vfat (rw,relatime,gid=6,fmask=0007,dmask=0007,allow_utime=0020,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
From regular SD cards one should be able to read with sustained data rates of around 10 to 20 MB/sec:
root@colibri-imx6ull:~# hdparm -t /dev/mmcblk0
/dev/mmcblk0:
Timing buffered disk reads: 66 MB in 3.04 seconds = 21.70 MB/sec
SD/MMC Card Removal
Kernel message:
[ 441.027332] mmc0: card 0007 removed
Triggered by another card detection interrupt:
root@colibri-imx6ull:~# cat /proc/interrupts | egrep "(mmc|cd)"
58: 641 GPC 22 Level mmc0
200: 2 gpio-mxc 0 Edge 2190000.usdhc cd
UHS-I Support
Please make sure your carrier board does not pull-up any of the MMC, MMC1, or SD1 signals to 3.3 volts (e.g. remove R46 to R54 for 8-bit or R29 to R32 and R39 for 4-bit SD/MMC slot on our Apalis Evaluation Board V1.1A) before attempting to activate this feature.
Please read the SoM datasheet to get information on how to deal with additionally affected pins which may require further adjustments on the used carrier board.
SoMs with UHS-I support:
System On Module | Embedded Linux BSP version | Additionally affected pins |
---|---|---|
Apalis iMX8 | 3.0 beta 1 and later | MXM3 159 |
Apalis iMX8X 1) | 3.0 beta 3 and later | none |
Apalis T30 (on MMC1 slot only) | V2.3 beta 5 and later | none |
Apalis TK1 | 2.7 and later | MMC1: MXM3 148, 152 SD1: MXM3 156 |
Colibri iMX6DL | 2.7 and later | none |
Colibri iMX6ULL | 2.8b5 and later | none |
Colibri iMX7D/S (optional) | 2.7 and later | SODIMM 69, 71, 73 |
Colibri iMX8X | 3.0 beta 2 and later | none |
Verdin iMX8M Mini | 5.0 and later | none |
Verdin iMX8M Plus | 5.0 and later | none |
1) The Apalis iMX8X does not provide the SD1 interface, MMC1 is four data bit only.
Activation
Apalis iMX8, Apalis iMX8X, Colibri iMX8X
Remove the 'no-1-8-v' property from the relevant usdhc instance.
The PMIC used on Apalis iMX8 V1.0, Apalis iMX8X V1.0A and Colibri iMX8X V1.0B wrongly sets the signaling voltage to 1.6V instead of 1.8V. With some SD cards, this provokes communication errors. Compare with this issue
Apalis iMX8X is phased out, and it is not available for purchase anymore. The latest supported BSP and TorizonCore version is 5.4.0.
Apalis T30 V1.1x
The UHS-I feature of the Linux SDHCI driver may be activated using the mmc_uhs kernel parameter, which can be set either from within U-Boot or Linux as follows:
U-Boot
setenv defargs 'core_edp_mv=1300 usb_high_speed=1 mmc_uhs=1'
saveenv
Linux
fw_setenv defargs 'core_edp_mv=1300 usb_high_speed=1 mmc_uhs=1'
Colibri iMX6 V1.1x, Colibri iMX6ULL, Colibri iMX7D/S
The UHS-I feature of the Linux SDHCI driver may be activated for Colibri iMX6/7 by adding an SD_1_8 define to the appropriate DTS file of your board. For example for the Colibri iMX6DL add the define to imx6qdl-colibri.dtsi:
diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
index 23770786ab77..135c00edd5c4 100644
--- a/arch/arm/boot/dts/imx6qdl-colibri.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
@@ -1039,6 +1039,8 @@
* 3.3V to 1.8V under the usdhc1's drivers control which is supported starting
* with hardware revision V1.1A.
*/
+#define SD_1_8
+
#ifdef SD_1_8
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_mmc_cd>;
Verdin iMX8M Mini, Verdin iMX8M Plus
The UHS-I feature of the Linux SDHCI driver is enabled by default.
Using Card with UHS-I Enabled
The following can be compared with the numbers given above.
[ 29.256768] mmc0: new ultra high speed SDR104 SDHC card at address 0007
[ 29.269824] mmcblk0: mmc0:0007 SDCIT 7.29 GiB
[ 29.293046] mmcblk0: p1 p2
[ 30.555440] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
root@colibri-imx6ull:~# cat /sys/kernel/debug/mmc0/ios
clock: 198000000 Hz
actual clock: 99000000 Hz
vdd: 21 (3.3 ~ 3.4 V)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 2 (on)
bus width: 2 (4 bits)
timing spec: 6 (sd uhs SDR104)
signal voltage: 1 (1.80 V)
driver type: 0 (driver type B)
root@colibri-imx6ull:~# hdparm -t /dev/mmcblk0
/dev/mmcblk0:
Timing buffered disk reads: 126 MB in 3.02 seconds = 41.78 MB/sec