5.1.2. 参数配置¶
5.1.2.1. 内核配置¶
在luban根目录下执行 make kernel-menuconfig,进入kernel的功能配置,按如下选择:
Linux
    Device Drivers
        <*> MMC/SD/SDIO card support
            <*>   MMC block device driver
            <*>   Artinchip Memory Card Interface
5.1.2.2. DTS 参数配置¶
5.1.2.2.1. SDMC 的扩展 DTS 参数¶
SDMC驱动基于Linux内核的MMC子系统,MMC子系统中提供了很多常用的参数,如下表:
| 参数名称 | 类型 | 取值范围 | 功能说明 | 
|---|---|---|---|
| max-frequenc | 正整数 | > 0 | 控制器可输出的最大频率 | 
| bus-width | 正整数 | 1, 4, 8 | 控制器的数据位宽 | 
| sd-uhs-sdr50 | boolean | 有 - 1,无 - 0 | 配置SDCard的SDR50模式 | 
| no-sd | boolean | 有 - 1,无 - 0 | 关闭SDCard的功能支持 | 
| no-sdio | boolean | 有 - 1,无 - 0 | 关闭SDIO的功能支持 | 
| no-mmc | boolean | 有 - 1,无 - 0 | 关闭eMMC的功能支持 | 
详见代码 drivers/mmc/core/host.c中的函数 mmc_of_parse()。
SDMC驱动在此基础上扩展了两个关于FIFO设置的参数,如下表:
| 参数名称 | 类型 | 取值范围 | 功能说明 | 
|---|---|---|---|
| aic,fifo-depth | 正整数 | [1, 128] | 控制器的FIFO深度 | 
| aic,fifo-watermark-aligned | boolean | 有 - 1,无 - 0 | FIFO水位是按2的整数次幂对齐 | 
5.1.2.2.2. D211 配置¶
SDMC V1.0有三个接口:SDMC0、SDMC1、SDMC2,所以在DTS中体现为三个独立的设备节点。
common/d211.dtsi中的参数配置:
sdmc0: sdmc@10440000 {
    compatible = "artinchip,aic-sdmc-v1.0";
    reg = <0x0 0x10440000 0x0 0x1000>;
    interrupts-extended = <&plic0 46 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&cmu CLK_SDMMC0>;
    clock-names = "ciu";
    resets = <&rst RESET_SDMMC0>;
    reset-names = "reset";
    #address-cells = <1>;
    #size-cells = <0>;
    max-frequency = <24000000>;
    clock-frequency = <48000000>;
    bus-width = <4>;
    fifo-depth = <128>;
};
sdmc1: sdmc@10450000 {
    compatible = "artinchip,aic-sdmc-v1.0";
    reg = <0x0 0x10450000 0x0 0x1000>;
    interrupts-extended = <&plic0 47 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&cmu CLK_SDMMC1>;
    clock-names = "ciu";
    resets = <&rst RESET_SDMMC1>;
    reset-names = "reset";
    #address-cells = <1>;
    #size-cells = <0>;
    max-frequency = <24000000>;
    clock-frequency = <48000000>;
    bus-width = <4>;
    fifo-depth = <128>;
};
sdmc2: sdmc@10460000 {
    compatible = "artinchip,aic-sdmc-v1.0";
    reg = <0x0 0x10460000 0x0 0x1000>;
    interrupts-extended = <&plic0 48 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&cmu CLK_SDMMC2>;
    clock-names = "ciu";
    resets = <&rst RESET_SDMMC2>;
    reset-names = "reset";
    #address-cells = <1>;
    #size-cells = <0>;
};
5.1.2.2.3. Board 中的配置¶
如果按以下功能定义三个控制器:
- SDMC0 - eMMC 
- SDMC1 - SDCard 
- SDMC2 - SDIO 
xxx/board.dts中的配置参数如下:
&sdmc0 {
    pinctrl-names = "default";
    pinctrl-0 = <&sdmc0_pins>;
    no-sd;
    no-sdio;
    status = "okay";
};
&sdmc1 {
    pinctrl-names = "default";
    pinctrl-0 = <&sdmc1_pins>;
    no-mmc;
    no-sdio;
    status = "okay";
};
&sdmc2 {
    pinctrl-names = "default";
    pinctrl-0 = <&sdmc2_pins>;
    no-mmc;
    no-sd;
    status = "disabled";
};
5.1.2.2.4. 热插拔配置¶
小技巧
SDMC1控制器硬件支持热插拔中断,SDMC驱动中默认已使能,无需另外配置,下文主要是针对SDMC0/2控制器。
SDMC热插拔功能基于Linux内核的MMC子系统,MMC子系统提供了两种方式实现热插拔:
- 轮询监控:主要实现每隔一段时间(一般是HZ,1s)扫描一下mmc硬件总线。 
- 中断监控:通过card detect(简称为cd)引脚电平变化触发中断,从而告知CPU说sdcard插入状态发生变化。 
MMC子系统中提供了以下关于热插拔的参数,如下表:
| 参数名称 | 类型 | 取值范围 | 功能说明 | 
|---|---|---|---|
| cd-inverted | boolean | 有 - 1,无 - 0 | gpio检测电平翻转 | 
| cd-debounce-delay-ms | 正整数 | > 0 | gpio消抖(默认200ms) | 
| broken-cd | boolean | 有 - 1,无 - 0 | 配置为轮询监控功能 | 
| cd-gpios | array | 同普通gpio配置 | 配置中断监控的gpio值 | 
下面为SDMC0控制器轮询监控方式配置热插拔:
xxx/board.dts中的配置参数如下:
&sdmc0 {
    pinctrl-names = "default";
    pinctrl-0 = <&sdmc0_pins>;
    broken-cd;
    status = "okay";
};
下面为SDMC2控制器中断监控方式配置热插拔:
xxx/board.dts中的配置参数如下:
&sdmc2 {
    pinctrl-names = "default";
    pinctrl-0 = <&sdmc2_pins>;
    cd-inverted;//根据硬件设计配置
    cd-gpios = <&gpio_c 8 GPIO_ACTIVE_HIGH>;//根据硬件设计配置
    cd-debounce-delay-ms = <250>;
    status = "okay";
};