The MultiMediaCard (MMC)/Secure Digital (SD)/Secure Digital Input Output (SDIO) host driver implements a standard Linux driver interface to the ultra MMC/SD host controller (uSDHC). The host driver is part of the Linux kernel MMC framework.
Features
The i.MX8M Nano MMC driver supports:
-
MMC and SD cards
-
SDIO cards
-
SD3.0 cards
MMC on the ConnectCore 8M Nano platforms
On the ConnectCore 8M Nano system-on-module:
-
Internal eMMC is connected to uSDHC3 controller using eight data lines.
On the ConnectCore 8M Nano Development Kit:
-
J18 microSD card holder is connected to uSDHC2 controller using four data lines and a card detection line.
Kernel configuration
You can manage the MMC/uSDHC driver support through the following kernel configuration options:
-
MMC/SD/SDIO (CONFIG_MMC)
-
MMC block (CONFIG_MMC_BLOCK)
-
Secure Digital Host Controller Interface support (CONFIG_MMC_SDHCI)
-
SDHCI support on the platform-specific bus (CONFIG_MMC_SDHCI_PLTFM)
-
SDHCI platform support for the NXP eSDHC i.MX controller (CONFIG_MMC_SDHCI_ESDHC_IMX)
These options are enabled as built-in on the default ConnectCore 8M Nano kernel configuration file.
Kernel driver
The table below shows the uSDHC source files available in the kernel source directory: drivers/mmc/host/.
File | Description |
---|---|
standard stack code |
|
sdhci platform layer |
|
uSDHC driver |
|
uSDHC driver header file |
Device tree bindings and customization
The i.MX8M Nano MMC/SD/SDIO interface device tree binding is documented at Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt.
Common MMC device tree bindings are documented at Documentation/devicetree/bindings/mmc/mmc.txt.
The MMC/SD/SDIO interfaces are defined in the i.MX8M Nano CPU, ConnectCore 8M Nano system-on-module, and ConnectCore 8M Nano Development Kit device tree files.
The common i.MX8M Nano CPU device tree defines all the uSDHC ports. The platform device tree must:
-
Enable the required uSDHC port, by setting the status property to okay.
-
Select the bus-width depending on the number of data lines to use.
-
Select optional properties (broken-cd, no-1-8-v, non-removable…), depending on the interface (see binding documentation).
-
Configure the IOMUX of the pads to use for the interface.
Do not modify the uSDHC1 controller because it is used to communicate with the Wi-Fi chip and defined in the ccimx8mn-wb.dtsi include file:
/* USDHC1 (Wireless) */
&usdhc1 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_usdhc1>;
non-removable;
no-1-8-v;
bus-width = <4>;
vmmc-supply = <®_rf_wl_en>;
status = "okay";
};
Example: eMMC
On the ConnectCore 8M Nano, the eMMC is connected to uSDHC3 controller using eight data lines.
Definition of the uSDHC3
usdhc3: mmc@30b60000 {
compatible = "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc";
reg = <0x0 0x30b60000 0x0 0x10000>;
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MN_CLK_DUMMY>,
<&clk IMX8MN_CLK_NAND_USDHC_BUS>,
<&clk IMX8MN_CLK_USDHC3_ROOT>;
clock-names = "ipg", "ahb", "per";
assigned-clocks = <&clk IMX8MN_CLK_USDHC3>;
assigned-clock-rates = <400000000>;
fsl,tuning-start-tap = <20>;
fsl,tuning-step= <2>;
bus-width = <4>;
status = "disabled";
};
IOMUX configuration
/* eMMC */
pinctrl_usdhc3: usdhc3grp {
fsl,pins = <
MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190
MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0
MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0
MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0
MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0
MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0
MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0
MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0
MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0
MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0
MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190
MX8MN_IOMUXC_NAND_READY_B_USDHC3_RESET_B 0x190
>;
};
Device enabling and options
/* eMMC */
&usdhc3 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc3>;
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
bus-width = <8>;
non-removable;
status = "okay";
};
Example: microSD on the ConnectCore 8M Nano Development Kit
On the ConnectCore 8M Nano Development Kit, the microSD card holder is connected to uSDHC2 controller using four data lines and a card detection line. Runtime voltage select is not currently supported, and microSD card/bus voltage is set to 3.3V by default.
Definition of the uSDHC2
usdhc2: mmc@30b50000 {
compatible = "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc";
reg = <0x0 0x30b50000 0x0 0x10000>;
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MN_CLK_DUMMY>,
<&clk IMX8MN_CLK_NAND_USDHC_BUS>,
<&clk IMX8MN_CLK_USDHC2_ROOT>;
clock-names = "ipg", "ahb", "per";
fsl,tuning-start-tap = <20>;
fsl,tuning-step= <2>;
bus-width = <4>;
status = "disabled";
};
IOMUX configuration
pinctrl_usdhc2_gpio: usdhc2gpiogrp {
fsl,pins = <
/* Card detect */
MX8MN_IOMUXC_SD2_CD_B_GPIO2_IO12 0x1c4
/* MUX_VSELECT */
MX8MN_IOMUXC_SAI3_TXD_GPIO5_IO1 0x84
>;
};
pinctrl_usdhc2: usdhc2grp {
fsl,pins = <
MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
>;
};
Device enabling and options
/* Micro SD card */
&usdhc2 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
bus-width = <4>;
no-1-8-v;
cd-gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
/* Assert GPIO5_IO1 low for 3V3 (default) or high for 1.8V */
pinctrl-assert-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
status = "okay";
};
User space usage
The MMC block driver handles the file system read/write calls and uses the low-level MMC host controller interface driver to send the commands to the uSDHC controller.
The MMC device driver exposes the device through the file system at /dev/mmcblkX where X is a number, starting at zero, that indicates the device index.
If the block device is partitioned, the partitions will appear as /dev/mmcblkXpY where Y is a number, starting at one, that indicates the partition index.
By default, formatted partitions are auto-mounted upon detection if they are block devices.
You can also mount a partition’s file system using the mount command with the partition node, the file system type, and the mount point:
~# mkdir -p /run/media/mmcblk1p1 && mount -t vfat /dev/mmcblk1p1 /run/media/mmcblk1p1
MMC/SD/SDIO on the ConnectCore 8M Nano boards
Device node mapping
On the ConnectCore 8M Nano Development Kit device tree, the uSDHC interfaces are set up to be mapped by Linux as follows:
-
The eMMC (connected to uSDHC3) is mapped to /dev/mmcblk0.
-
The microSD card (connected to uSDHC2) is mapped to /dev/mmcblk1.
microSD card detection
The microSD card holder on the ConnectCore 8M Nano Development Kit has a card detection line.
Formatted partitions are auto-mounted upon card insertion.
If the device (microSD or eMMC) is not partitioned, you can use fdisk to create one partition of type vfat and then give it format with mkfs, for example:
If the device is partitioned but you still want to re-partition or re-format it, you must first unmount all the mounted partitions. |