SDMC 配置
SDMC 包含以下配置内容:
- 内核配置
在 luban 根目录下执行 make kernel-menuconfig,进入 kernel 的功能配置,按如下选择:
Linux Device Drivers <*> MMC/SD/SDIO card support <*> MMC block device driver <*> Artinchip Memory Card Interface
- 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 的整数次幂对齐 - 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 中的配置
如果按以下功能定义三个控制器:
-
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 控制器。
- 轮询监控:主要实现每隔一段时间(一般是 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"; };