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.MX8QXP MMC driver supports:
-
MMC and SD cards
-
SDIO cards
-
SD3.0 cards
MMC on the ConnectCore 8X platforms
On the ConnectCore 8X system-on-module:
-
Internal eMMC is connected to uSDHC1 controller using eight data lines.
On the ConnectCore 8X SBC Pro:
-
microSD card holder is connected to uSDHC2 controller using four data lines and a card detection line. It is available on the bottom side of the board.
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 8X 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.MX8QXP 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.MX8QXP CPU, ConnectCore 8X system-on-module, and ConnectCore 8X SBC Pro device tree files.
The common i.MX8QXP 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.
Example: eMMC
On the ConnectCore 8X, the eMMC is connected to uSDHC1 controller using eight data lines.
Definition of the uSDHC1
usdhc1: usdhc@5b010000 {
compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x0 0x5b010000 0x0 0x10000>;
clocks = <&clk IMX8QXP_SDHC0_IPG_CLK>,
<&clk IMX8QXP_SDHC0_CLK>,
<&clk IMX8QXP_CLK_DUMMY>;
clock-names = "ipg", "per", "ahb";
assigned-clocks = <&clk IMX8QXP_SDHC0_SEL>, <&clk IMX8QXP_SDHC0_DIV>;
assigned-clock-parents = <&clk IMX8QXP_CONN_PLL1_CLK>;
assigned-clock-rates = <0>, <400000000>;
power-domains = <&pd_conn_sdch0>;
fsl,tuning-start-tap = <20>;
fsl,tuning-step= <2>;
status = "okay";
};
IOMUX configuration
/* eMMC */
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000041
>;
};
Device enabling and options
/* eMMC */
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
bus-width = <8>;
non-removable;
/*
* This property should be removed once the eMMC voltage is configured
* to 1.8V.
*/
no-1-8-v;
status = "okay";
};
Example: microSD on the ConnectCore 8X SBC Pro
On the ConnectCore 8X SBC Pro, the microSD card holder is connected to uSDHC2 controller using four data lines and a card detection line.
Definition of the uSDHC2
usdhc2: usdhc@5b020000 {
compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x0 0x5b020000 0x0 0x10000>;
clocks = <&clk IMX8QXP_SDHC1_IPG_CLK>,
<&clk IMX8QXP_SDHC1_CLK>,
<&clk IMX8QXP_CLK_DUMMY>;
clock-names = "ipg", "per", "ahb";
assigned-clocks = <&clk IMX8QXP_SDHC1_SEL>, <&clk IMX8QXP_SDHC1_DIV>;
assigned-clock-parents = <&clk IMX8QXP_CONN_PLL1_CLK>;
assigned-clock-rates = <0>, <200000000>;
power-domains = <&pd_conn_sdch1>;
fsl,tuning-start-tap = <20>;
fsl,tuning-step= <2>;
status = "okay";
};
IOMUX configuration
pinctrl_usdhc2_gpio: usdhc2gpiogrp {
fsl,pins = <
/* Card detect */
SC_P_USDHC1_CD_B_LSIO_GPIO4_IO22 0x06000021
>;
};
pinctrl_usdhc2: usdhc2grp {
fsl,pins = <
SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
>;
};
pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
fsl,pins = <
SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
>;
};
pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
fsl,pins = <
SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041
SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021
SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021
SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021
SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021
SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021
>;
};
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 = <&gpio4 22 GPIO_ACTIVE_HIGH>;
status = "okay";
};