SDHC
介绍SDHC的功能和使用方法。
模块介绍
SDHC是多媒体卡(MMC)/安全数字(SD)/安全数字输入输出(SDIO)模块的控制器。
功能介绍
MMC框架图可以分为以下几个层次:
MMC Host:这是MMC控制器驱动层,负责初始化MMC控制器以及底层的数据收发操作,直接控制底层寄存器。
MMC Core:这是核心层,负责抽象出虚拟的card设备,并提供接口供上层使用。
MMC Block:这是块设备层,负责实现块设备驱动程序,对接内核其他框架(如块设备、TTY、wifi等)。
这些层次结构共同构成了Linux系统中MMC子系统的完整框架,确保了MMC设备在系统中的正常运行和数据传输。
源码结构介绍
控制器驱动代码在drivers/mmc/host目录下:
drivers/mmc/host
|-- sdhci.c #sdhci标准代码
|-- sdhci-pltfm.c #sdhci平台层
|-- sdhci-of-k1x.c #k1 sdhci驱动
关键特性
特性
特性 | 特性说明 |
---|---|
支持eMMC5.1 | 支 持eMMC5.1协议,包括HS400,HS200 |
支持sd3.0 | 支持sd3.0协议的卡,兼容sd2.0协议 |
支持DMA | 支持DMA数据传输 |
性能参数
eMMC型号 | 顺序读(MB/s) | 顺序写(MB/s) | 随机读(MB/s) | 随机写(MB/s) |
---|---|---|---|---|
KLMAG1JETD-B041 | 295 | 53.3 | 65.4 | 45.2 |
FEMDME008G-A8A39 | 304 | 107 | 32.3 | 44 |
测试方法
fio -name=randread -direct=1 -iodepth=64 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/1
fio -name=randwrite -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/1
fio -name=read -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=512k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/1
fio -name=write -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=512k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/1
默认配置HS400 200M
配置介绍
主要包括驱动使能配置和dts配置
CONFIG配置
CONFIG_MMC 为MMC总线协议提供支持,默认情况,此选项为Y
Device Drivers
MMC/SD/SDIO card support (MMC [=y])
CONFIG_MMC_BLOCK为安装文件系统的MMC块设备驱动提供支持,默认情况,此选项为Y
Device Drivers
MMC/SD/SDIO card support (MMC [=y])
HW reset support for eMMC (PWRSEQ_EMMC [=y])
Simple HW reset support for MMC (PWRSEQ_SIMPLE [=y])
MMC block device driver (MMC_BLOCK [=y])
CONFIG_MMC_SDHCI 为MMC控制器驱动提供支持,默认情况下,此选型为Y
Device Drivers
MMC/SD/SDIO card support (MMC [=y])
Secure Digital Host Controller Interface support (MMC_SDHCI [=y])
SDHCI platform and OF driver helper (MMC_SDHCI_PLTFM [=y])
SDHCI OF support for the Spacemit K1X SDHCI controllers (MMC_SDHCI_OF_K1X [=y])
dts配置
pinctrl
sdhc 一共有三个 slot,slot1 支持 sd/sdio(1/4 bit),slot2 支持 sdio/emmc(1/4 bit),slot3 只支持 emmc(1/4/8 bit)。
方案上一般 slot1 用于 sd,slot2 用于 sdio,slot3 用于 emmc。
sd 和 sdio 都需要配置卡的信号线对应的 pinctl 为 mode0 模式,分别对应 pinctrl_mmc1 和 pinctrl_mmc2。
mmc1 的 pinctl 还有一个 fast 模式,在时钟高于 100M 时需要切换到 pinctrl_mmc1_fast 模式。
pinctrl_mmc1: mmc1_grp {
pinctrl-single,pins = <
K1X_PADCONF(MMC1_DAT3, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) /* mmc1_d3 */
K1X_PADCONF(MMC1_DAT2, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) /* mmc1_d2 */
K1X_PADCONF(MMC1_DAT1, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) /* mmc1_d1 */
K1X_PADCONF(MMC1_DAT0, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) /* mmc1_d0 */
K1X_PADCONF(MMC1_CMD, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) /* mmc1_cmd */
K1X_PADCONF(MMC1_CLK, MUX_MODE0, (EDGE_NONE | PULL_DOWN | PAD_3V_DS4)) /* mmc1_clk */
>;
};
pinctrl_mmc1_fast: mmc1_fast_grp {
pinctrl-single,pins = <
K1X_PADCONF(MMC1_DAT3, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS3)) /* mmc1_d3 */
K1X_PADCONF(MMC1_DAT2, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS3)) /* mmc1_d2 */
K1X_PADCONF(MMC1_DAT1, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS3)) /* mmc1_d1 */
K1X_PADCONF(MMC1_DAT0, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS3)) /* mmc1_d0 */
K1X_PADCONF(MMC1_CMD, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS3)) /* mmc1_cmd */
K1X_PADCONF(MMC1_CLK, MUX_MODE0, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS3)) /* mmc1_clk */
>;
};
gpio
sd 的检测是通过 gpio 完成的,需要按实际原理图来配置卡检测的 gpio。
&sdhci0 {
cd-gpios = <&gpio 80 0>;
cd-inverted;
};
比如方案使用 gpio80 来做卡的检测,还需要配置 gpio80 的 pintcl 功能。
&pinctrl {
pinctrl-single,gpio-range = <
&range GPIO_80 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4)
>;
};
&gpio{
gpio-ranges = <
&pinctrl 80 GPIO_80 4
>;
};