Edit online

SDMC 配置

26 Nov 2024
Read time: 5 minute(s)

本节介绍了 SDMC 的参数配置流程。

内核配置

在 Luban 根目录下执行 make kernel-menuconfig,进入 kernel 的功能配置,按如下选择:
Linux
    Device Drivers
        <*> MMC/SD/SDIO card support
            <*>   MMC block device driver
            <*>   ArtInChip Memory Card Interface

SDMC 的扩展 DTS 参数

SDMC 驱动基于 Linux 内核的 MMC 子系统,而 MMC 子系统提供了很多常用的参数,详见代码 drivers/mmc/core/host.c 中的函数 mmc_of_parse()。下表展示了部分扩展 DTS 参数:

1. SDMC 的扩展 DTS 参数
参数名称 类型 取值范围 功能说明
max-frequenc Integer > 0 控制器可输出的最大频率
bus-width Integer 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 的功能支持
SDMC 驱动在此基础上扩展了下列关于 FIFO 设置的参数:
2. SDMC 的扩展 FIFO 参数
参数名称 类型 取值范围 功能说明
aic,fifo-depth Integer [1, 128] 控制器的 FIFO 深度
aic,fifo-watermark-aligned Boolean 有 - 1,无 - 0 FIFO 水位是按 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>;
};

Board 配置

本节按照以下功能定义三个控制器为例,进行 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";
};

热插拔配置

SDMC 热插拔功能基于 Linux 内核的 MMC 子系统,MMC 子系统提供了下列热插拔实现方式:
注: SDMC1 控制器硬件支持热插拔中断,且 SDMC 驱动中默认已使能,无需另外配置。本节主要介绍 SDMC0/2 控制器的热插拔配置。
  • 轮询监控:每隔一段时间扫描一次 mmc 硬件总线,一般是 HZ,1s)。
    对于 SDMC0 控制器,如需以轮询监控方式配置热插拔功能,则在 xxx/board.dts 中配置如下参数:
    &sdmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&sdmc0_pins>;
        broken-cd;
        status = "okay";
    };
  • 中断监控:通过 card detect (cd) 引脚电平变化触发中断,从而告知 CPU 当前 sdcard 插入状态发生了变化。
    对于 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";
    };
MMC 子系统中提供了以下关于热插拔的参数,如下表所示:
3. 热插拔配置参数
参数名称 类型 取值范围 功能说明
cd-inverted Boolean 有 - 1,无 - 0 gpio 检测电平翻转
cd-debounce-delay-ms Integer > 0 gpio 消抖(默认 200 ms)
broken-cd Boolean 有 - 1,无 - 0 配置为轮询监控功能
cd-gpios Array 同普通 gpio 配置 配置中断监控的 gpio 值