Edit online

SDMC 配置

SDMC 包含以下配置内容:
  1. 内核配置

    在 luban 根目录下执行 make kernel-menuconfig,进入 kernel 的功能配置,按如下选择:

    Linux
        Device Drivers
            <*> MMC/SD/SDIO card support
                <*>   MMC block device driver
                <*>   Artinchip Memory Card Interface
  2. DTS 参数配置

    SDMC 驱动基于 Linux 内核的 MMC 子系统,MMC 子系统中提供了很多常用的参数,如下表:

    1. SDMC 的扩展 DTS 参数
    参数名称 类型 取值范围 功能说明
    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 的整数次幂对齐
  3. 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>;
    };
  4. Board 中的配置

    如果按以下功能定义三个控制器:

    1. SDMC0 - eMMC

    2. SDMC1 - SDCard

    3. 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. 热插拔配置

    SDMC 热插拔功能基于 Linux 内核的 MMC 子系统,MMC 子系统提供了两种方式实现热插拔:

    SDMC1 控制器硬件支持热插拔中断,SDMC 驱动中默认已使能,无需另外配置,下文主要是针对 SDMC0/2 控制器。

    1. 轮询监控:主要实现每隔一段时间(一般是 HZ,1s)扫描一下 mmc 硬件总线。
    2. 中断监控:通过 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";
    };