Search by Tags

SD/MMC Card (Linux)

 

Article updated at 02 Jun 2022
Compare with Revision




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

Note: 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. Note: 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.

Note: 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

Note: 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