SDMMC使用参考¶
REVISION HISTORY¶
| Revision No. | Description |
Date |
|---|---|---|
| 1.0 | 04/15/2025 | |
| 2.0 | 01/04/2026 |
1. 概述¶
Kernel下MMC采用标准的Linux框架,能够使用标准接口驱动MMC Device(eMMC card,SD card或SDIO device)。
MMC子系统由card层,core层和host层构成。Card层将整个MMC Device注册成MMC Block Device,可支持上层的数据请求工作;Core层实现MMC/SD/SDIO协议中初始化流程和读写等工作。Host层可以调动硬件,把core层传下来的cmd或data request通过FCIE/SDIO Engine与eMMC/SD/SDIO card进行数据通信。

SD host层的整体框架共有三层,分别是MDrv层,Hal层和Support层,以及接在Support层上的MMC设备,各个层次的作用如下:
Drv层:
Drv层主要完成host的注册,完善mmc_host和mmc_host_ops结构体的描述,向core层增加Host的信息,还会额外提供一些封装接口来给用户层设置或获得Engine和卡的状态,比如:debug_get_sdmmc_clock,set_sdmmc_driving_control等。此外,Drv层还会完成MIE和热插拔中断注册,以保证后续信号的正常传输和卡的拔插检测。
Hal层:
Hal层直接设置寄存器,与HW Engine密切相关,主要包括操作Host Engine的hal_sdmmc_v5.c文件,命令和数据的发送接收就是在这个文件里实现。决定Host Engine接哪组pad pin,并对其上下拉等操作的是hal_sdmmc_platform_common.c文件。中断处理相关的是hal_sdmmc_intr.c文件,还有时间处理相关的hal_sdmmc_timer.c文件等。
Support层:
该层属于硬件支持层,驱动相关的最终实现都需要硬件的支持。
MMC device:
MMC设备,比如SD/SDIO卡,直接接在驱动的硬件支持上,是驱动的最终操作对象。
2. 关键字说明¶
IP:连接SD/SDIO卡的Host Engine
IP bank:驱动访问SD/SDIO卡所使用的Host Engine的寄存器地址
SDSC:标准容量卡,不超过2GB的卡
SDHC:高容量卡,大于2GB又不超过32GB的卡
SDXC:扩展容量卡,大于32GB的卡
3. 功能描述¶
| 封装 | SD卡 | 总线带宽 | 时钟范围 | SD3.0支持的速率模式 | SD2.0支持的速率模式 | IP bank | 产品 |
|---|---|---|---|---|---|---|---|
| BGA14 | SD0 Card | 1,4 | 300k-48M | Not supported | Default Speed,High Speed | FCIE:0x1410 | pcupid |
| BGA14 | SD1 Card | 1,4 | 300k-48M | Not supported | Default Speed,High Speed | SDIO:0x1413 | pcupid |
| BGA | SD0 Card | 1,4 | 300k-200M | SDR50,SDR104,DDR50 | Default Speed,High Speed | 0x1413 | souffle |
| BGA | SD1 Card | 1,4 | 300k-100M | SDR50 | Default Speed,High Speed | 0x1416 | souffle |
| QFN | SD0 Card | 1,4 | 300k-200M | SDR50,SDR104,DDR50 | Default Speed,High Speed | 0x1413 | souffle |
| BGA | SD0 Card | 1,4 | 300k-48M | - | Default Speed,High Speed | 0x1413(non-pm) | iford |
| BGA | WIFI Card | 1,4 | 300k-48M | - | Default Speed,High Speed | 0x42(pm) | iford |
| FCCSP | SD0 Card | 1,4 | 300k-48M | SDR50,SDR104,DDR50 | Default Speed,High Speed | 0x1413 | ifackel |
| FCCSP | SD1 Card | 1,4 | 300k-48M | - | Default Speed,High Speed | 0x1413 | ifackel |
| BGA | SD0 Card | 1,4 | 300k-200M | SDR50,SDR104,DDR50 | Default Speed,High Speed | 0x1413 | jaguar1 |
| BGA | SD1 Card | 1,4 | 300k-100M | SDR50 | Default Speed,High Speed | 0x1416 | jaguar1 |
| QFN | SD Card | 1,4 | 300k-48M | - | Default Speed,High Speed | 0x1410 | ibopper |
| QFN | SD0 Card | 1,4 | 300k-48M | - | Default Speed,High Speed | 0x1413 | ifado |
| QFN | SD1 Card | 1,4 | 300k-48M | - | Default Speed,High Speed | 0x1410 | ifado |
| FCCSP | SD0 Card | 1,4 | 300k-48M | SDR50,SDR104,DDR50 | Default Speed,High Speed | 0x1413 | mhera |
注:pcupid BGA封装的板子拥有2个SD卡插槽,其中SD0默认接的IP类型是FCIE,不支持接SDIO设备,SD1的IP类型是SDIO,支持接SDIO设备,而QFN封装只有1个SD卡插槽,默认接的IP 类型是SDIO,支持接SDIO设备。
总线带宽设置:
SD支持配置1 -1bit mode/4 – 4bit mode 两种总线带宽,默认使用4bit mode。SDIO卡需要设置带宽为1 bit mode可以设置设备树中的sdio-use-1bit参数。
时钟设置:
不同速率模式可以设置的时钟范围如下图所示, 可以通过修改设备树中的max-frequency参数来设置最大时钟大小。

配置不同的总线带宽及时钟频率会影响数据传输速率,SD3.0支持使用SDR50,SDR104和DDR50速率模式,若要使用可以在设备树中对应槽位配置sd-uhs-sdr50/sd-uhs-sdr104/sd-uhs-ddr50。
使用High Speed速率模式时,硬件上支持的时钟频率及理论速度参考下列表格(x4 总线宽度)。
| No | 时钟频率(Hz) | 传输速率(MB/s) |
|---|---|---|
| 0 | 300000 | 1.5 |
| 1 | 12000000 | 6 |
| 2 | 20000000 | 10 |
| 3 | 32000000 | 16 |
| 4 | 36000000 | 18 |
| 5 | 40000000 | 20 |
| 6 | 43200000 | 21.6 |
| 7 | 48000000 | 24 |
配置使用SDR50,DDR50,SDR104速率模式时,理论速率参考下列表格(x4 总线宽度)。
| No | 时钟频率(Hz) | 传输速率(MB/s) |
|---|---|---|
| 0 | 12000000-100000000 (SDR50) | 6-50 |
| 1 | 12000000-50000000 (DDR50) | 12-50 |
| 2 | 12000000-208000000 (SDR104) | 6-104 |
注意,实际读写速率受读写过程中的cmd传输消耗,mmc设备性能等因素影响,达不到理论速度,测试性能建议使用fio工具读写大文件进行测试。
速率模式:
(1)查看SD卡速率模式
cat /sys/kernel/debug/mmc1/ios

(2)设置SD卡速率模式
SD卡速率模式可直接在dtsi文件配置

4. 硬件连接介绍¶
4.1. mhera¶

硬件连接对应的软件padmux设定如下:
1. padmux {
2. compatible = "sgs-padmux";
3. schematic =
4. // SDMMC0
5. <PAD_SD0_D1 PINMUX_FOR_SD0_MODE_1 MDRV_PUSE_SDIO0_D1>,
6. <PAD_SD0_D0 PINMUX_FOR_SD0_MODE_1 MDRV_PUSE_SDIO0_D0>,
7. <PAD_SD0_CLK PINMUX_FOR_SD0_MODE_1 MDRV_PUSE_SDIO0_CLK>,
8. <PAD_SD0_CMD PINMUX_FOR_SD0_MODE_1 MDRV_PUSE_SDIO0_CMD>,
9. <PAD_SD0_D3 PINMUX_FOR_SD0_MODE_1 MDRV_PUSE_SDIO0_D3>,
10. <PAD_SD0_D2 PINMUX_FOR_SD0_MODE_1 MDRV_PUSE_SDIO0_D2>,
11. <PAD_SD0_GPIO0 PINMUX_FOR_GPIO_MODE MDRV_PUSE_SDIO0_PWR>,
12. <PAD_SD0_CDZ PINMUX_FOR_SD0_CDZ_MODE_1 MDRV_PUSE_SDIO0_CDZ>,
13. };
第一列表示sd的pad名称,第二列表示pad mode,根据pad的使用情况设定,第三列是驱动程序使用的标识,各字段名称与设备类型无关,配置设备类型参考后面章节的设备节点参数说明。
5. Uboot用法介绍¶
5.1. uboot config配置¶
1. make menuconfig
2. # sgs drivers -->
3. # -*- SGS SD/MMC Card Interface Support
4. # Sgs SDMMC DDR Mode (sdr/ddr Mode) --->) --->
5. # Sgs SDMMC RECEIVE RESPONSE Mode (polling Mode) --->) --->
6. # [ ] Support SD30
7. # [ ] Support EMMC50
8. # [ ] Support SDMMC Command
9. # [ ] Support SDMMC AT/SMOKE test
10.# [ ] SELECT EMMC
11.# [ ] enable fcie ip drive sd atop
12.# -*- Sgs mmc host
13.# [ ] Support SDIO driver
boot下SDMMC驱动所在目录为drivers/sgs_common/sdmmc,编译需要开启SGS_MMC_HOST编译选项,打开方式如上。
| 功能 | 描述 | 备注 |
|---|---|---|
| SELECT EMMC | FCIE IP选择配置为EMMC功能 | 仅pcupid/iford/jaguar1产品使用,使用EMMC时候需要开启 |
| Support SDIO driver | 配置驱动支持识别SDIO卡 | 根据需要开启 |
| enable fcie ip drive sd atop | FCIE IP选择使用SDPLL为时钟源 | 仅ifackel产品使用,FCIE IP跑SD3.0时需要开启 |
5.2. Dts参数配置说明¶
可以通过配置dtsi中sgs_mmc0项设定host层driver的基本参数。dtsi的参数展示如下:
sgs_mmc0: sgs_mmc0 {
compatible = "sgs-mmc";
bus-width = <4>;
max-frequency = <48000000>;
cap-sd-highspeed = <1>;
ip-order = <2>;
pad-order = <1>;
pwr-on-delay = <10>;
pwr-off-delay = <50>;
fake-cdz = <0>;
rev-cdz = <0>;
pwr-pad = <PAD_GPIOE_07>;
cdz-pad = <PAD_GPIOE_06>;
clk-driving = <1>;
cmd-driving = <1>;
data-driving = <1>;
en-clk-phase = <0>;
rx-clk-phase = <0>;
tx-clk-phase = <0>;
status = "okay";
};
释义如下:
| 参数 | 释义 | 备注 |
|---|---|---|
| bus-width | 配置卡槽的buswidth | 4 – 4bit mode |
| max-frequency | 配置对应卡槽支持的最大时钟频率 | uboot支持48MHz |
| ip-order | 配置对应卡槽的IP编号 | 禁止修改 |
| pad-order | 指定卡接哪组pad | 公版软件未使用,无需修改 |
| pwr-on-delay | 配置卡槽上电后软件的延时时间,延时后再去识别卡,以ms为单位 | SDIO设备一般需要配置delay时间以便SDIO设备加载固件及状态ready,具体时间以SDIO设备厂家的建议为准(EMMC/SD设备节点无需修改) |
| pwr-off-delay | 配置卡槽下电后软件的延时时间,卡识别前会重新下电再上电卡槽,以ms为单位 | SDIO设备一般需要配置delay时间以便SDIO设备加载固件及状态ready,具体时间以SDIO设备厂家的建议为准(EMMC/SD设备节点无需修改) |
| fake-cdz | 配置是否忽视Card detect,置1表示默认认为该槽有卡接入 | 针对固定在板上的设备,如部分SDIO设备,建议将卡槽对应项配置为1 |
| rev-cdz | 该参数可配置是否颠倒当前Board的Card detect条件 | 默认低电平检查到卡,若硬件设计卡插入后CDZ电平为高电平,则将此项配置为1 |
| pwr-pad | 配置对应卡槽的Power pin脚 | 公版软件未使用,无需修改 |
| cdz-pad | 配置对应卡槽的CDZ pin脚 | 公版软件未使用,无需修改 |
| clk-driving | 配置对应卡槽的clock pad pin的driving能力 | 该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项 |
| cmd-driving | 配置对应卡槽的command pad pin的driving能力 | 该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项 |
| data-driving | 配置对应卡槽的data[3:0] pad pin的driving能力 | 该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项 |
| en-clk_phase | 配置对应卡槽是否使能 clock phase tuning | 当设备读写通信出现CRC问题时候,可以通过改变rx,tx的采样点来解决 |
| rx-clk_phase | 配置对应卡槽的clock tx相位,需en-clk_phase置1此参数才有效 | 档位:0-3,需en-clk_phase置1此参数才有效,每个挡位相位间隔90° |
| tx-clk_phase | 配置对应卡槽的clock rx相位,需en-clk_phase置1此参数才有效 | 档位:0-3,需en-clk_phase置1此参数才有效,每个挡位相位间隔90° |
5.3. Uboot cmd参数说明¶
(1) fatls
格式:
说明:读取某接口下第n个设备的第n个分区中的某目录下的所有文件内容。
interface:SD卡和eMMC卡都属于MMC设备
dev: 设备编号,根据ip编号,缺省为0
part:与mmc part命令下的分区号对应。
directory:目录,使用绝对路径。
示例:打印出SD第一个分区内,根目录的内容
(2) fatload
格式:
说明:从某接口下第n个设备的第n个分区中的某个文件读取特定大小数据到指定地址的ddr中。
addr:目标内存地址,ddr地址,使用真实物理地址。
filename:需要load的文件名,使用绝对路径文件名。
bytes:load的数据大小,以byte为单位,16进制数,若为0则读取整份文件。
pos:目标文件中的偏移量。如目标文件数据"123456", 若pos为1,则load文件时从‘1’位置开始读取。
示例:将SD第一个分区内根目录下的demo.sh文件读取512个byte到ddr的0x21000000处
(3) fatwrite
格式:
说明:从指定地址的ddr中读取特定大小数据<bytes>写到某接口下第n个设备的第n个分区中的某个文件中
addr:源内存地址,ddr地址,使用真实物理地址。
filename:需要write的文件名,使用绝对路径文件名。
bytes:write的数据大小,以byte为单位,16进制数。
示例:从ddr的0x21000000处读取512个byte写到SD第一个分区内根目录下的demo.sh文件
(4) fatinfo
格式:
说明:显示某接口下第n个设备的第n个分区信息
(5) fatsize
格式:
说明:find某接口下第n个设备的第n个分区的文件并计算文件大小
5.4. Uboot cmd使用实例¶
(1) fdisk
fdisk用来管理linux的磁盘,进行分区和格式化等操作
fdisk -p 显示分区信息

(2) fdisk -d 0: 删除设备0的所有分区

(3) fdisk -c 0 0x32000: 创建分区1并指定分区大小为0x32000个block

(4) fdisk -c 0 0x4800: 创建分区2并指定分区大小为0x4800个block

(5) fdisk -c 0 0x64000: 创建分区3并指定分区大小为0x64000个block

(6) fdisk -c 0 0x96000: 创建分区5并指定分区大小为0x96000个block,此处分区4是扩展分区mbr,需要跳过

(7) fdisk -c 0 0x400000: 创建分区6并指定分区大小为0x400000个block

6. Kernel用法介绍¶
6.1. Kernel Config配置¶
1. 关联到的驱动模块
Card层(mmc_block.ko)与Core层(mmc_host.ko)使用linux标准code,Host层(kdrv_sdmmc.ko)由sgs维护,在menuconfig可将它们选择编译进kernel或编译为ko。
2. enable 对应的驱动模块
1. make menuconfig
2. # Device Drivers -->
3. # <*> MMC/SD/SDIO card support --> (mmc_core.ko)
4. # <*> MMC block device driver (mmc_block.ko)
5. # [*] SGS SoC platform drivers -->
6. # <M> SGS SD/MMC Card Interface Support (kdrv_sdmmc.ko)
7. # Sgs SDMMC DDR Mode (sdr/ddr Mode) --->) --->
8. # Sgs SDMMC RECEIVE RESPONSE Mode (interrupt Mode) --->) --->
9. # [*] Support SD30
10.# [*] Support EMMC50
11.# [ ] Support SDMMC Command
12.# [ ] Support SDMMC AT/SMOKE test
13.# [ ] SELECT EMMC
14.# [ ] enable fcie ip drive sd atop
15.# [ ] Support SDMMC debuginfo
16.# [ ] Sgs mmc host
| 功能 | 描述 | 备注 |
|---|---|---|
| Support SD30 | 配置驱动支持SD3.0协议 | 仅ifackel,jaguar1产品支持此功能 |
| Support EMMC50 | 配置驱动支持EMMC5.0协议 | 仅pcupid, ifackel,jaguar1产品支持此功能 |
| Support SDMMC Command | 开启后会额外提供一些debugfs调试接口 | 根据需要开启 |
| Support SDMMC UT verify | 驱动功能调试开关 | 不需要开启 |
| Support SDMMC AT/SMOKE test | 自动化测试开关 | 不需要开启 |
| SELECT EMMC | FCIE IP选择配置为EMMC功能 | 仅pcupid产品使用,使用EMMC时候需要开启 |
| enable fcie ip drive sd atop | FCIE IP选择使用SDPLL为时钟源 | 仅ifackel产品使用,FCIE IP跑SD3.0时需要开启 |
| Support SDMMC debuginfo | 开启debugfs调试信息节点 | debug时候开启 |
6.2. Dts配置参数说明¶
可以通过配置dtsi中sgs_sdmmc1项设定Host层driver的基本参数。dtsi的参数展示如下:
sgs_sdmmc1: sgs_sdmmc1 {
compatible = "sgs,sdmmc";
bus-width = <4>;
max-frequency = <48000000>;
//non-removable;
//broken-cd;
//cap-sd-highspeed;
//sd-uhs-sdr50;
//sd-uhs-sdr104;
//sd-uhs-ddr50;
//cap-sdio-irq;
//no-sdio;
//no-sd;
//no-mmc;
reg = <0x0 0x1F282600 0x0 0x200>;//1413
pll-reg = <0x1F283200 0x200>;//1419
cifd-reg = <0x1F282800 0x200>;//1414
pwr-save-reg = <0x1F282A00 0x200>;//1415
ip-order = /bits/ 8 <0>;
pad-order = /bits/ 8 <0>;
trans-mode = /bits/ 8 <1>;
cifd-mcg-off = /bits/ 8 <0>; // mcg on/off in cifd
ssc-switch = /bits/ 8 <0>;
fake-cdz = /bits/ 8 <0>;
rev-cdz = /bits/ 8 <0>;
cdz-pad = <PAD_GPIOA_06>;
pwr-pad = <PAD_GPIOA_07>;
pwr-on-delay = <1000>;
pwr-off-delay = <300>;
dev-ctrl-delay = <1>;
en-pwr-high-valid = <0>;
en-ctrl-high-valid = <0>;
sdio-use-1bit = /bits/ 8 <0>;
clk-driving = <1>;
cmd-driving = <1>;
data-driving = <1>;
en-clk-phase = /bits/ 8 <0>; //0/1
rx-clk-phase = <0>; //0-3
tx-clk-phase = <0>; //0-3
en-eight-phase = /bits/ 8 <0>; //0/1
rx-eight-phase = /bits/ 8 <0>; //0/1
tx-clk-phase = <0>; //0-3
en-eight-phase = /bits/ 8 <0>; //0/1
rx-eight-phase = /bits/ 8 <0>; //0/1
tx-eight-phase = /bits/ 8 <0>; //0/1
interrupts = <GIC_SPI INT_IRQ_SD IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI INT_FIQ_SD_CDZ_IN_0 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "mie0_irq", "cdz_slot0_irq";
clocks = <&CLK_sd>;
clock-names = "clk_sdmmc0";
status = "ok";
};
如上图所示,SD/SDIO设备树配置节点释义分别为:
| 参数 | 释义 | 备注 |
|---|---|---|
| bus-width | 配置对应卡槽的buswidth | 4 - 4bit mode |
| max-frequency | 配置对应卡槽支持的最大时钟频率 | |
| non-removable | 配置是否不可移除设备,置1表示默认该设备不可移除 | eMMC/SDIO设备一般设置为不可移除属性 |
| broken-cd | 配置是否使用cdz中断 | 不可插拔设备配置此属性 |
| cap-mmc-highspeed | 配置设备是否支持mmc highspeed总线速率模式 | 默认开启支持mmc highspeed mode |
| cap-sd-highspeed | 配置设备是否支持sd highspeed总线速率模式 | 默认开启支持sd highspeed mode |
| sd-uhs-sdr50 | 配置是否启用sdr50总线速率模式 | pcupid不支持 |
| sd-uhs-sdr104 | 配置是否启用sdr104总线速率模式 | pcupid不支持 |
| sd-uhs-ddr50 | 配置是否启用ddr总线速率模式 | pcupid不支持 |
| cap-sdio-irq | 配置是否启用sdio中断模式 | SDIO设备使用,使用SDIO设备时一起注释掉no-sdio |
| no-mmc | 配置设备不支持eMMC协议 | SD/SDIO设备不支持eMMC协议 |
| no-sd | 配置设备不支持sd协议 | EMMC/SDIO设备不支持sd协议 |
| no-sdio | 配置设备不支持sdio协议 | EMMC/SD设备不支持sdio协议 |
| reg | 配置SD/SDIO Host Engine Bank地址 | 禁止修改 |
| pll-reg | 配置SD/SDIO Host Engine PLL Bank地址 | 禁止修改 |
| cifd-reg | 配置SD/SDIO Host Engine CIFD Bank地址 | 禁止修改 |
| pwr-save-reg | 配置SD/SDIO Host Engine PSM Bank地址 | 禁止修改 |
| ip-order | 配置对应卡槽的IP编号 | 禁止修改 |
| pad-order | 配置对应卡槽的padmux mode编号 | 公版软件未使用,无需修改 |
| trans-mode | 配置对应的卡槽的数据传输模式 | 无需修改 |
| fake-cdz | 配置对应卡槽是否忽视Card Detect | 不可插拔设备配置为1 |
| rev-cdz | 配置CDZ检测方向 | 默认低电平检查到卡,若硬件设计卡插入后CDZ电平为高电平,则将此项配置为1 |
| pwr-on-delay | 配置卡槽上电后软件的延时时间,延时后再去识别卡,以ms为单位 | SDIO设备一般需要配置delay时间以便SDIO设备加载固件及状态ready,具体时间以SDIO设备厂家的建议为准(EMMC/SD设备节点无需修改) |
| pwr-off-delay | 配置卡槽下电后软件的延时时间,卡识别前会重新下电再上电卡槽,以ms为单位 | SDIO设备一般需要配置delay时间以便SDIO设备加载固件及状态ready,具体时间以SDIO设备厂家的建议为准(EMMC/SD设备节点无需修改) |
| dev-ctrl-delay | 配置ctrl pin极性翻转前后的延时时间,以ms为单位 | 如果设备需要额外的使能pin控制芯片使能,根据设备厂商建议的控制时序进行设定 |
| en-pwr-high-valid | 配置电源输出有效极性 | 0表示低电平使能,1表示高电平使能 |
| en-ctrl-high-valid | 配置ctrl pin输出极性 | 0表示低电平使能,1表示高电平使能 |
| sdio-use-1bit | 配置对应卡槽buswidth为1bit mode | SD/SDIO设备均可设置 |
| ssc-switch | 配置是否开启展频 | 根据需要开启 |
| support-cmd23 | 配置是否支持预设传输Block数功能 | eMMC设备使用 |
| clk-driving | 配置对应卡槽的clock line的driving | 该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项 |
| cmd-driving | 配置对应卡槽的cmd line的driving | 该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项 |
| data-driving | 配置对应卡槽的data line的driving | 该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项 |
| en-clk-phase | 配置对应卡槽是否使能clock phase tuning | 0 - 禁用 / 1 - 使能 |
| rx-clk-phase | 配置对应卡槽的clock rx phase | 详情使用见clk phase使用说明 |
| tx-clk-phase | 配置对应卡槽的clock tx phase | 详情使用见clk phase使用说明 |
| en-eight-phase | 配置对应卡槽是否使能clock 8 phase tuning | 0 - 禁用 / 1 - 使能, pcupid暂未启用 |
| rx-eight-phase | 配置对应卡槽的clock rx phase | 详情使用见clk phase使用说明 |
| tx-eight-phase | 配置对应卡槽的clock tx phase | 详情使用见clk phase使用说明 |
| interrupts | 配置中断信息 | 禁止修改 |
| interrupt-names | 配置中断名称 | 禁止修改 |
| clocks | 配置eMMC Host Engine时钟源 | 禁止修改 |
| clock-names | 配置时钟源名称 | 禁止修改 |
clk phase使用说明:
当使用四相位模式时候,en-clk-phase需要设置为1,然后根据需要设定的相位设置rx-clk-phase和tx-clk-phase的值,相位间隔90°。 当使用八相位模式时候,en-clk-phase和en-eight-phase需要设置为1,然后根据需要设定的相位设置rx-clk-phase,tx-clk-phase,rx-eight-phase和tx-eight-phase的值,相位间隔45°。
不同相位对应的phase值
- 四相位模式
| 相位 | rx-clk-phase | tx-clk-phase |
|---|---|---|
| 0° | 0 | 0 |
| 90° | 1 | 1 |
| 180° | 2 | 2 |
| 270° | 3 | 3 |
- 八相位模式
| 相位 | rx-clk-phase | rx-eight-phase | tx-clk-phase | tx-eight-phase |
|---|---|---|---|---|
| 0° | 0 | 0 | 0 | 0 |
| 45° | 1 | 0 | 1 | 0 |
| 90° | 2 | 0 | 2 | 0 |
| 135° | 3 | 0 | 3 | 0 |
| 180° | 0 | 1 | 0 | 1 |
| 225° | 1 | 1 | 1 | 1 |
| 270° | 2 | 1 | 2 | 1 |
| 315° | 3 | 1 | 3 | 1 |
-
注1:硬件设定tx phase默认已经是180°,所以相位设置180°时候,测量tx的波形会和没开启phase时候一样,设置0°时候会和没开启phase时候相位相差180°。
-
注2:rx和tx可以单独设定。
-
注3:使用四相位模式时候,时钟会四分频,使用八相位模式时候,时钟会八分频,软件设定已经在开启phase功能时候,自动把时钟频率设定对应X4和X8。在使用四相位模式时候,时钟频率为48M时,软件设置48M X 4即192M,但是硬件限制了没有192M时钟源,会向下使用108M时钟源(四分频为27M),因此会降频。所以使用48M时钟时候建议使用八相位模式(48M X 8 = 384M),这样设定phase后时钟频率输出还是48M,使用其它时钟频率需要按照前文描述选择使用哪种模式。
-
注4:当开启展频时候,时钟源会选择spi_synth_pll, spi_synth_pll产生的时钟频率是连续的,且设置范围为12M-266M。因此若需要打出48M时钟需要选择四相位模式(八相位输出最大时钟为266M/8 = 33M)。此外由于spi_synth_pll也是flash使用的时钟源,因此当flash和展频需要同时使用时候,建议切换flash到其它时钟源。
SD卡在dts文件中配置示例
sgs_sdmmc1: sgs_sdmmc1 {
//non-removable;
//broken-cd;
cap-sd-highspeed;
//cap-sdio-irq;
no-sdio;
//no-sd;
no-mmc;
fake-cdz = /bits/ 8 <0>;
};
SDIO卡在dts文件中配置示例
sgs_sdmmc1: sgs_sdmmc1 {
//non-removable;
//broken-cd;
cap-sd-highspeed;
cap-sdio-irq;
//no-sdio;
no-sd;
no-mmc;
fake-cdz = /bits/ 8 <0>;
};
驱动中控制power pin和dev ctrl pin的时序
设备在重新初始化时候才会有下电过程

6.3. Sample Code¶
None.
6.4. 模块使用介绍¶
Linux 系统启动后,SD 驱动程序正常加载,SD卡被识别后,会创建相应的块设备节点 /dev/mmcblk*。使用 fdisk、mkfs、mount 和 dd 工具为 MMC 设备申请分区、格式化分区、挂载分区以及读写已挂载的分区。
此外,驱动程序提供 sysfs 供调试使用,可以进入 /sys/class/mmc_host/mmc1/device/ 目录执行以下操作:
1. cd /sys/class/mmc_host/mmc0/device/
2.
3. # 查看设备使用的时钟频率
4. cat debug_get_sdmmc_clock
5.
6. # 查看设备最近的读写通信状态
7. cat debug_get_sdmmc_status
6.
7. # 设置设备IO驱动能力
8. echo [slotIndex] [signalLine] [drvLevel] > set_sdmmc_driving_control
9. echo [slotIndex] [drvLevel] > set_sdmmc_driving_control
10. echo [signalLine] [drvLevel] > set_sdmmc_driving_control
11. echo [drvLevel] > set_sdmmc_driving_control
12. #[slotIndex]: 0-1
13. #[signalLine]: "clk"/"cmd"/"data"/"all"
14. #[drvLevel]: 0-3
15.
16. # 重新扫描卡
17. echo [slot] > sdmmc_rescan
18.
19. # 设置展频参数
20. ssc set param usage:
21. 1. echo [slotIndex] [modulation] [deviation] > sdmmc_setssc
22. operation [slotIndex] is slot number:0-2.
23. operation [modulation] value is between [20, 40], origin default is 20
24. operation [deviation] value is between [1000, 3001], origin default is 3001
25. e.g. echo 0 20 1001 > sdmmc_setssc
26. 2. echo [slotIndex] [disable ssc] > sdmmc_setssc
27. disable: e.g. echo 0 0 > sdmmc_setssc
28. enable: e.g. echo 0 1 > sdmmc_setssc
29.
30. # 设置clock phase
31. set phase param usage:
32. 1. echo [mode] [tx-clk-phase] [rx-clk-phase] [tx-eight-phase] [rx-eight-phase] > sdmmc_clk_phase
33. operation [mode] is phase mode:4 or 8
34. operation [tx/rx-clk-phase] value is between [0, 3]
35. operation [tx/rx-eight-phase] value is between [0, 1]
36. e.g. Four-phase mode(180°):
37. echo 4 2 2 > sdmmc_clk_phase
38. e.g. Eight-phase mode(180°):
39. echo 8 0 0 1 1 > sdmmc_clk_phase
40. 2. echo [enable/disable clk phase] > sdmmc_clk_phase
41. disable: e.g. echo 0 > sdmmc_clk_phase
42. enable: e.g. echo [4/8] > sdmmc_clk_phase
展频参数使用说明:
有三个参数可能会影响SSC功能的调制速率:SET,SPAN和STEP。
-
PLL_SET = (MPLL*524288)/(SYN_CLK)
SPAN (14 bits)
STEP (12 bits)
SPAN = (MPLL * 131072) / (PLL_SET * Fmodulation)
STEP = (PLL_SET * Rdeviation) / SPAN
Fmodulation为SSC的调制频率,范围为(20KHz~40KHz)
Rdeviation 是 SSC 的偏差(最大偏差为 +-3%)
示例:
设置展频调制频率为40KHz,偏差为+-1%
echo 0 40 1000 > sdmmc_setssc
-
SYN_CLK = 75Mhz
ref_clk = 432Mhz
Modulation is 40KHz
Deviation is 1%
SET = ( 432MHz * 524288) / (75MHz ) = 3019899 = 0x2E147B
SPAN = (432MHz * 131072)/ ( 3019899 * 40KHz) = 468 = 0x1D4
STEP = (3019899 * 1%) /468 = 64 = 0x40

7. API参考¶
无
8. Debug & FAQ¶
驱动提供debug节点用于获取调试信息,进入/sys/devices/virtual/sgs/mmcx目录后可以看到有debug节点,下面介绍debug节点用法。

输入echo help > debug后再cat debug可以查询debug 用法。
8.1. 查询设备节点状态¶
echo state > debug;cat debug

| 属性 | 描述 |
|---|---|
| MCG | MCG(Manual Clock Gating Control)是指当ip处于idle状态,hw关闭clk以达到节省功耗的目的 |
| MIE interrupt | 驱动是否使能中断模式, 默认使用中断模式 |
| HotPlug | 设备是否支持热插拔,取决于设备树节点是否配置了non-removable属性 |
| Tansfermode | 驱动支持配置ADMA模式和DMA模式,默认且推荐用ADMA模式 |
| Supported Device | 当前设备节点支持接入的设备(eMMC,SD or SDIO) ,和设备树节点中的no-sdio,no-sd,no-mmc这三个属性有关 |
| Host Capabilities | 当前host支持的设备能力,数值含义具体查询linux内核数据结构struct mmc_host中的caps定义 |
| More Host Capabilities | 当前host额外支持的设备能力,数值含义具体查询linux内核数据结构struct mmc_host中的caps2定义 |
| Supported Bus Width | host支持配置的总线数据宽度 |
| Supported Bus Timing | host支持配置的总线速率模式 |
| Supported Max Frequency | host支持的最大时钟频率 |
| RST/CDZ Pin | 显示EMMC reset pin或者可插拔SD/SDIO卡的卡检测pin的gpio index, 以及该gpio pin的电平状态,如果是配置可插拔卡,插卡没反应需要检查该pin的电平状态是否正确 |
| Control Power Pin | 如果有配置电源控制pin,会显示该pin的gpio index以及电平状态,卡识别失败时候需要检查改pin电平是否正确 |
| Current Driving | 显示clk,cmd和data线配置的driving值 |
| Card Info | 如果设备识别成功,会显示设备的工作状态信息,没有成功识别到设备会显示“Device not recognized”,可检查该项看设备是否工作在预设的状态下 |
| Clock Phase | 显示时钟phase配置信息 |
| SSC switch | 显示展频配置信息 |
8.2. 查询设备的工作状态¶
echo status > debug;cat debug

| 属性 | 描述 |
|---|---|
| Current transfer freqency | 显示当前设备工作的时钟频率 |
| Current transfer command | 显示host和设备最近一次通信的CMD和参数 |
| Current transfer result | 显示host和设备最近一次通信状态是否正常 |
| MIEEvent_ForInt | 显示host和设备最近一次通信记录的中断信息 |
| Trig_MIE_INTR | 显示host和设备最近一次通信记录是否有进入中断服务程序,0x0001表示有进入中断服务程序 |
MIEEvent_ForInt中断信息:
| 位 | 描述 |
|---|---|
| BIT0 | 数据传输结束中断 |
| BIT1 | 命令发送完成中断 |
| BIT2 | 数据传输异常中断 |
| BIT3 | SDIO D1中断 |
| BIT4 | 卡busy结束中断 |
| BIT6 | 卡插拔中断 |
8.3. 读寄存器信息¶
echo reg > debug;cat debug

主要需要关注MMC1:0X1413中offset 0xD的寄存器值,其中BIT8-BIT11表示data线的电平状态,默认状态下是高电平, 其它寄存器信息提供给RD分析。
BIT0-BIT6是设备异常时指示的错误状态
| 位 | 描述 |
|---|---|
| BIT0 | 读数据有crc校验错误 |
| BIT1 | 写数据有crc校验错误 |
| BIT2 | 读写数据超时 |
| BIT3 | host未收到cmd响应 |
| BIT4 | host收到的cmd响应有crc校验错误 |
| BIT6 | 设备处于busy状态 |
出现异常时常见log打印的错误码类型有:
(1)SD_STS:0xFF01 读CRC错误
(2)SD_STS:0xFF02 写CRC错误
(3)SD_STS:0xFF04 写数据超时
(4)SD_STS:0xFF08 命令发送未响应
(5)SD_STS:0xFF10 命令响应存在CRC错误
(6)SD_STS:0xFF20 读数据超时
(7)SD_STS:0xFF40 设备处于忙状态
SD卡状态寄存器说明:

可以根据驱动报错log中的(E: 0xXXXX)信息查找对应的SD卡状态来判断目前卡出现了什么问题。
根据SD卡实际可能遇到的问题,分为以下几个类型:
识别卡失败
若卡识别失败,需要确定是响应获取失败还是传输信号不好有CRC问题,区分问题可以通过驱动打印的日志确定,具体区别以及debug方法如下:
-
SD卡不回复命令响应
现象:驱动log报(E: 0x0008)信息
debug方法:首先确定电压和clock是否正常,其次可以抓波形看host是否有command发出去,若前面两个都没有问题,再确定卡是否有回复响应,若没有响应检查device状态。
相关日志:

-
命令响应存在CRC问题
现象:驱动log报(E: 0x0010)信息
debug方法:若有CRC问题,先需要排除硬件问题,比如:device接触是否良好,是否有外接干扰等。然后再尝试更改dts里的driving档位,若还有问题则需要考虑调整clock phase。
相关日志:

读写失败
若是在正常读写过程中遇到问题,需要确定是读写超时问题,还是信号不好有CRC问题,区分问题可以通过log确定,超时问题有timeout的字眼,debug方法如下:
-
读写超时
现象:驱动报错log里有timeout的字眼
debug方法:首先需要确定当前clock频率以及bus width是否是期望配置的值,其次可以将驱动里的超时时间再加大试试,若还有超时问题,则需要抓波形详细分析。
读写超时时间在驱动对应芯片目录的hal_card_platform_config.h文件中设定:

-
读写CRC问题
现象:驱动log报(E: 0x0001)或(E: 0x0002)信息
debug方法:debug方法见前文,另外读写过程中的CRC问题,若对速率要求不是很高,可以考虑降频或者降bus width。
相关日志:

卡读写速度慢
首先检查卡时钟频率和bus width是否正常,另外可以测试对比下不同型号卡的读写速度。
注:SD卡读写受命令及其响应的传输时间,卡busy时间,停止命令时间等多重因素影响,实际读写速率是低于其理论速率的; 读写速度测试应该测试应用层的读写带宽,即传输一个大文件进行测试。