SDMMC使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 04/15/2025

    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进行数据通信。

    图1-1 SDMMC Host层框架

    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
    pcupid SD0 Card 1,4 300k-48M Not supported Default Speed,High Speed FCIE:0x1410
    pcupid SD1 Card 1,4 300k-48M Not supported Default Speed,High Speed SDIO:0x1413

    注:Pcupid有两个IP,其中一个IP类型是FCIE IP,支持接EMMC或SD卡,另一个IP类型是SDIO IP,支持接SD卡或SDIO卡。也就是说,芯片规格最大只支持两个MMC设备。

    总线带宽设置:

    SD支持配置1 -1bit mode/4 – 4bit mode 两种总线带宽,默认使用4bit mode。SDIO卡需要设置带宽为1 bit mode可以设置设备树中的sdio-use-1bit参数。

    时钟设置:

    支持配置300KHz-48MHz范围内的时钟频率,可以通过修改设备树中的max-frequency参数来设置最大时钟大小,最终设置的clock频率是当前bus speed支持的最大频率。

    图3-1 SDMMC 总线速率模式

    配置不同的总线带宽及时钟频率会影响数据传输速率,SD3.0支持使用SDR50,SDR104和DDR50速率模式,若要使用可以在设备树中对应槽位配置sd-uhs-sdr50/sd-uhs-sdr104/sd-uhs-ddr50, pcupid不支持SD3.0。

    pcupid支持SD2.0,实际一般使用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

    注意,实际读写速率受读写过程中的cmd传输消耗,mmc设备性能等因素影响,达不到理论速度,测试性能建议使用fio工具读写大文件进行测试。

    速率模式:

    (1)查看SD卡速率模式

    cat /sys/kernel/debug/mmc1/ios

    (2)设置SD卡速率模式

    SD卡速率模式可直接在dtsi文件配置


    4. 硬件连接介绍

    4.1. pcupid

    图4-1 SD0 硬件原理图

    图4-2 SD1 硬件原理图

    硬件连接对应的软件padmux设定如下:

    1.    padmux {
    2.        compatible = "sstar-padmux";
    3.        schematic =
    4.            // SDMMC0
    5.            <PAD_GPIOE_00            PINMUX_FOR_SD_BOOT_MODE_1        MDRV_PUSE_EMMC_D1>,
    6.            <PAD_GPIOE_01            PINMUX_FOR_SD_BOOT_MODE_1        MDRV_PUSE_EMMC_D0>,
    7.            <PAD_GPIOE_02            PINMUX_FOR_SD_BOOT_MODE_1        MDRV_PUSE_EMMC_CLK>,
    8.            <PAD_GPIOE_03            PINMUX_FOR_SD_BOOT_MODE_1        MDRV_PUSE_EMMC_CMD>,
    9.            <PAD_GPIOE_04            PINMUX_FOR_SD_BOOT_MODE_1        MDRV_PUSE_EMMC_D3>,
    10.           <PAD_GPIOE_05            PINMUX_FOR_SD_BOOT_MODE_1        MDRV_PUSE_EMMC_D2>,
    11.           <PAD_GPIOE_07            PINMUX_FOR_GPIO_MODE             MDRV_PUSE_EMMC_PWR>,
    12.           <PAD_GPIOE_06            PINMUX_FOR_SD_BOOT_MODE_1        MDRV_PUSE_EMMC_RST>,
    13.           // SDMMC1
    14.           <PAD_GPIOA_00            PINMUX_FOR_SDIO_MODE_1           MDRV_PUSE_SDIO0_D1>,
    15.           <PAD_GPIOA_01            PINMUX_FOR_SDIO_MODE_1           MDRV_PUSE_SDIO0_D0>,
    16.           <PAD_GPIOA_02            PINMUX_FOR_SDIO_MODE_1           MDRV_PUSE_SDIO0_CLK>,
    17.           <PAD_GPIOA_03            PINMUX_FOR_SDIO_MODE_1           MDRV_PUSE_SDIO0_CMD>,
    18.           <PAD_GPIOA_04            PINMUX_FOR_SDIO_MODE_1           MDRV_PUSE_SDIO0_D3>,
    19.           <PAD_GPIOA_05            PINMUX_FOR_SDIO_MODE_1           MDRV_PUSE_SDIO0_D2>,
    20.           <PAD_GPIOA_07            PINMUX_FOR_GPIO_MODE             MDRV_PUSE_SDIO0_PWR>,
    21.           <PAD_GPIOA_06            PINMUX_FOR_SDIO_CDZ_MODE_1       MDRV_PUSE_SDIO0_CDZ>,
    22.    };
    

    第一列表示sd的pad名称,第二列表示pad mode,根据pad的使用情况设定,第三列是驱动程序使用的标识,各字段名称与设备类型无关,配置设备类型参考后面章节的设备节点参数说明。 SD0对应软件SDMMC0设备,也就是PAD_GPIOE_XX这组pad,pad mode可以选择PINMUX_FOR_SD_BOOT_MODE_1或者PINMUX_FOR_SDIO_MODE_2,使用SD启动需要使用PINMUX_FOR_SD_BOOT_MODE_1。 SD1对应软件SDMMC1,也就是PAD_GPIOA_XX这组pad,pad mode只可以是PINMUX_FOR_SDIO_MODE_1。 由于PINMUX_FOR_SDIO_MODE_1和PINMUX_FOR_SDIO_MODE_2使用的是同一个IP,因此不能同时设定在SDMMC0和SDMMC1上面。 另外要注意的是使用sdio设备只能接在SDMMC1上面。

    注:使用SD卡时候可以选择使用sdmmc0或sdmmc1,使用SDIO卡时候只能选择sdmmc1

    5. Uboot用法介绍

    5.1. uboot config配置

    1. make menuconfig
    2. # SigmaStar drivers -->
    3. #    <*> SigmaStar mmc host
    

    boot下SDMMC驱动所在目录为drivers/sstar/mmc_host/,编译需要开启SSTAR_MMC_HOST编译选项,打开方式如上。

    5.2. Dts参数配置说明

    可以通过配置dtsi中sstar_mmc0项设定host层driver的基本参数。dtsi的参数展示如下:

            sstar_mmc0: sstar_mmc0 {
                compatible = "sstar-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能力 GPIOE这组pad挡位是0-1,GPIOA这组pad挡位是0-3,该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项
    cmd-driving 配置对应卡槽的command pad pin的driving能力 GPIOE这组pad挡位是0-1,GPIOA这组pad挡位是0-3,该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项
    data-driving 配置对应卡槽的data[3:0] pad pin的driving能力 GPIOE这组pad挡位是0-1,GPIOA这组pad挡位是0-3,该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项
    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

    格式:

    fatls <interface> [<dev[:part]>] [directory]
    

    说明:读取某接口下第n个设备的第n个分区中的某目录下的所有文件内容。

    interface:SD卡和eMMC卡都属于MMC设备

    dev: 设备编号,根据ip编号,缺省为0

    part:与mmc part命令下的分区号对应。

    directory:目录,使用绝对路径。

    示例:打印出SD第一个分区内,根目录的内容

    fatls mmc 0:1 /
    

    (2) fatload

    格式:

    fatload <interface> <dev<:part>> <addr> <filename> <bytes <pos>>
    

    说明:从某接口下第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处

    fatload mmc 0:1 0x21000000 /demo.sh 0x200
    

    (3) fatwrite

    格式:

    fatwrite <interface> <dev<:part>> <addr> <filename> <bytes>
    

    说明:从指定地址的ddr中读取特定大小数据<bytes>写到某接口下第n个设备的第n个分区中的某个文件中

    addr:源内存地址,ddr地址,使用真实物理地址。

    filename:需要write的文件名,使用绝对路径文件名。

    bytes:write的数据大小,以byte为单位,16进制数。

    示例:从ddr的0x21000000处读取512个byte写到SD第一个分区内根目录下的demo.sh文件

    fatwrite mmc 0:1 0x21000000 /demo.sh 0x200
    

    (4) fatinfo

    格式:

    fatinfo <interface> <dev<:part>>
    

    说明:显示某接口下第n个设备的第n个分区信息

    (5) fatsize

    格式:

    fatsize <interface> <dev<:part>> <filename>
    

    说明: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)由Sigmastar维护,在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. #    [*] SStar SoC platform drivers -->
    6. #        <*> SStar SD/MMC Card Interface Support        (kdrv_sdmmc.ko)
    7. #        [ ]     Support SD30
    8. #        [ ]     Support EMMC50
    9. #        [*]     Support SDMMC Command
    10.#        [*]       Support SDMMC UT verify
    

    6.2. Dts配置参数说明

    可以通过配置dtsi中sstar_sdmmc1项设定Host层driver的基本参数。dtsi的参数展示如下:

            sstar_sdmmc1: sstar_sdmmc1 {
                compatible = "sstar,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>;
                //support-runtime-pm = /bits/ 8 <0>;
                fake-cdz = /bits/ 8 <0>;
                rev-cdz = /bits/ 8 <0>;
                rev-pwr = /bits/ 8 <0>;
                rev-ctrl = /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>;
                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 配置对应卡槽支持的最大时钟频率 pcupid最大时钟频率支持到48MHz
    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
    rev-pwr 配置power控制方向 默认power pin低电平上电,若硬件设计高电平上电,则将此项配置为1
    rev-ctrl 配置ctrl pin控制方向 一些sdio卡可能会需要额外的pin去控制设备使能,如chip en。默认ctrl pin先拉高再拉低,此项配置为1后ctrl pin会先拉低再拉高。
    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为单位 一些sdio卡可能会需要额外的pin去控制设备使能,如chip en,具体延时时间以SDIO设备厂家的建议为准
    sdio-use-1bit 配置对应卡槽buswidth为1bit mode SD/SDIO设备均可设置
    ssc-switch 配置是否开启展频 根据需要开启
    support-cmd23 配置是否支持预设传输Block数功能 eMMC设备使用
    support-runtime-pm 配置是否支持运行时电源管理 根据需要开启
    clk-driving 配置对应卡槽的clock line的driving GPIOE这组pad挡位是0-1,GPIOA这组pad挡位是0-3,该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项
    cmd-driving 配置对应卡槽的cmd line的driving GPIOE这组pad挡位是0-1,GPIOA这组pad挡位是0-3,该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项
    data-driving 配置对应卡槽的data line的driving GPIOE这组pad挡位是0-1,GPIOA这组pad挡位是0-3,该项一般不需要修改,若遇到信号质量问题可以结合波形调整此项
    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
      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
      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可以单独设定。

    SD卡在dts文件中配置示例:

            sstar_sdmmc1: sstar_sdmmc1 {
                //non-removable;
                //broken-cd;
                cap-sd-highspeed;
                //cap-sdio-irq;
                no-sdio;
                //no-sd;
                no-mmc;
                fake-cdz = /bits/ 8 <0>;
            };
    

    SDIO卡在dts文件中配置示例:

            sstar_sdmmc1: sstar_sdmmc1 {
                //non-removable;
                //broken-cd;
                cap-sd-highspeed;
                cap-sdio-irq;
                //no-sdio;
                no-sd;
                no-mmc;
                fake-cdz = /bits/ 8 <0>;
            };
    

    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:\n");
    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

    出现异常时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时间,停止命令时间等多重因素影响,实际读写速率是低于其理论速率的; 读写速度测试应该测试应用层的读写带宽,即传输一个大文件进行测试。