Linux SD卡/SDIO驱动开发0-基本知识

文章目录

    • Linux驱动子系统-sdio子系统
      • sdio系统概述
      • 判断sd卡是否识别
      • 判断sdio wifi是否识别
      • sd协议
        • SD BUS
        • SPI BUS
      • 硬件接口:
      • 调试的问题
    • sdmmc接口使用sdio wifi设备 无法识别设备
    • 概率不识别
    • 硬件问题,io电压异常
      • dts 含义解析

Linux驱动子系统-sdio子系统

sdio系统概述

MMC SD SDIO三种卡,从发展历程来看,是先有MMC卡,后来有SD卡,这两种都是纯粹的存储卡,而SDIO是什么呢,从字面意思理解,应该是SD+IO,也就是既有存储功能,又有IO控制功能,不过也有纯IO功能的SDIO设备(本人用到的WIFI模块就是这种)。并且,这三种卡可以使用同一个插槽,系统还能正确的识别!!,可能是由于历史原因,在开始有Linux的时候,还只存在mmc卡(不存在SD和SDIO卡),所以在linux系统里面关于这三种卡的名称统统用“mmc“来命名。

SDIO总线和USB总线类似,SDIO总线也有两端,其中一端是主机(HOST)端,另一端是设备端(DEVICE),采用HOST- DEVICE这样的设计是为了简化DEVICE的设计,所有的通信都是由HOST端发出命令开始的。在DEVICE端只要能解析HOST的命令,就可以同HOST进行通信了,SDIO的HOST可以连接多个DEVICE。

SDIO的信号传输模式有SPI、1-bit、4-bit三种。在SPI模式中,第8脚位被当成中断信号。其它脚位的功能和通信协定与SD记忆卡的标准规范一样。在SDIO总线定义中,DAT1信号线复用为中断线。在SDIO的1BIT模式下DAT0用来传输数据,DAT1用作中断线。在SDIO的4BIT模式下DAT0-DAT3用来传输数据,其中DAT1复用作中断线

判断sd卡是否识别

log信息如下:

[  115.399427] mmc0: new ultra high speed SDR50 SDHC card at address aaaa
[  115.401103] mmcblk0: mmc0:aaaa SS32G 29.7 GiB 
[  115.411808]  mmcblk0: p1
说明tf卡已经被正确识别,并且可用的分区p1
确认板子上的linux系统是否识别SD卡
    fdisk -l ---对应/dev/mmcblk0,/dev/mmcblk0p1
看看到底有没有mmc相关的分区
    cat /proc/partitions
    179       64   31166976 mmcblk0
    179       65   31165440 mmcblk0p1  
挂载
    mount /dev/mmcblk0p1 /mnt
卸载
    umount /mnt

判断sdio wifi是否识别

log如下:

[    2.464027] mmc0: new high speed SDIO card at address 0001
[    2.464116] hdj stdio_bus.c sdio_add_func 341 mmc0:0001:1

节点信息:

cat /sys/bus/sdio/devices/mmc0:0001:1/uevent //可查看SDIO设备ID
mount -t debugfs none /sys/kernel/debug
cat /sys/kernel/debug/mmcx/ios //可查看WIFI_sdio 相关信息

# cat /sys/bus/sdio/devices/mmc0\:0001\:1/uevent         
DRIVER=rtl88x2cs             
SDIO_CLASS=07   
SDIO_ID=024C:C822                           
MODALIAS=sdio:c07v024CdC822  
/sys/kernel/debug/mmc0 # cat ios   
clock:          50000000 Hz     
vdd:            21 (3.3 ~ 3.4 V)    
bus mode:       2 (push-pull)  
chip select:    0 (don't care) 
power mode:     2 (on)  
bus width:      2 (4 bits)     
timing spec:    2 (sd high-speed)
signal voltage: 0 (3.30 V)               
driver type:    0 (driver type B) 

sd协议

sdmmc 和 sdio接口 控制器相同.

  • 需要注意:
  1. 硬件所在的接口
  2. 供电的选择

sd协议:https://www.jianshu.com/p/6272e4cb1eeb
SD卡按总线速度模式来分,有下面几种:


Default Speed mode: 3.3V供电模式,频率上限25MHz,速度上限 12.5MB/sec
High Speed mode: 3.3V供电模式,频率上限50MHz,速度上限 25MB/sec
SDR12: UHS-I卡, 1.8V供电模式,频率上限25MHz,速度上限 12.5MB/sec
SDR25: UHS-I卡, 1.8V供电模式,频率上限50MHz,速度上限 25MB/sec
SDR50: UHS-I卡, 1.8V供电模式,频率上限100MHz,速度上限 50MB/sec
SDR104: UHS-I卡, 1.8V供电模式,频率上限208MHz,速度上限 104MB/sec
DDR50: UHS-I卡, 1.8V供电模式,频率上限50MHz,性能上限 50MB/sec
UHS156: UHS-II RCLK Frequency Range 26MHz - 52MHz, up to 1.56Gbps per lane.



SD BUS

物理层定义:
D0-D3 数据传送
CMD 进行CMD 和Respons
CLK 大家最熟悉的HOST时钟信号线了
VDD VSS 电源和地

SPI BUS

一般用SPI协议的接口来做
物理层定义:
CLK HOST时钟信号线了
DATAIN HOST-àSD Card数据信号线
DATAOUT SD Card àHOST数据信号线

硬件接口:

引脚号 SD卡 TF卡(SD模式) TF卡(SPI模式)
1 Data3 Data2 Rsv
2 Cmd Data3 Cs
3 Vss Cmd MOSI
4 Vdd Vdd Vdd
5 Clk Clk Clk
6 Vss Vss Vss
7 Data0 Data0 MOSO
8 Data1 Data1 Rsv
9 Data2

在这里插入图片描述

调试的问题

sdmmc接口使用sdio wifi设备
无法识别设备

log 信息


[    3.284993]  mmc_attach_sdio 1109
[    3.285330] err =0
[    3.285333]sdio.c ocr=-1862270977
[    3.285339] dwmmc_rockchip ff0c0000.dwmmc: card claims to support voltages below defined range
[    3.285341] hdj sdio.c mmc_attach_sdio 1133 rocr =200000
[    3.313615] mmc_host mmc0: Voltage change didn't complete
[    3.320214] mmc0: error -5 whilst initialising SDIO card
[    3.325550] hdj mmc0: clock 0Hz busmode 2 powermode 0 cs 0 Vdd 0 width 0 timing 0

电压问题
vcc_sd为电压域ldo供电,不需要电压调整.
wifi 模组供电请查看模组图,要求输入vdd_3.3v
将电压调整删除掉
sd-uhs-sdr12;
sd-uhs-sdr25;
sd-uhs-sdr50;
sd-uhs-sdr104;
未删除sdr104 报错如下,cmd11是电压切换功能

[    2.963507] dwmmc_rockchip ff0c0000.dwmmc: Unexpected CMD11 timeout
[    2.993507] dwmmc_rockchip ff0c0000.dwmmc: Busy; trying anyway
[    2.993513] mmc_host mmc0: Timeout sending command (cmd 0x202000 arg 0x0 status 0x0)

概率不识别

mmc1: new high speed SD card at address b368
mmcblk1: mmc1:b368 SMI 486 MiB
[mmc1] Data transmission error !!!! MINTSTS: [0x00002000]
dwmmc_rockchip ff0c0000.rksdmmc: data FIFO error (status=00002000)
mmcblk1: error ‐110 sending status command, retrying
need_retune:0,brq‐>retune_retry_done:0.

降频和增加卡检测延时增强电源稳定性,如果降频OK的话,请检查硬件layout;

&sdmmc {
card‐detect‐delay = <1200>;
}

硬件问题,io电压异常

Workqueue: kmmcd mmc_rescan
[] (unwind_backtrace+0x0/0xe0) from [] (show_stack+0x10/0x14)
[] (show_stack+0x10/0x14) from [] (dw_mci_set_ios+0x9c/0x21c)
[] (dw_mci_set_ios+0x9c/0x21c) from [] (mmc_set_chip_select+0x18/0x1c)
[] (mmc_set_chip_select+0x18/0x1c) from [] (mmc_go_idle+0x94/0xc4)
[] (mmc_go_idle+0x94/0xc4) from [] (mmc_rescan_try_freq+0x54/0xd0)
[] (mmc_rescan_try_freq+0x54/0xd0) from [] (mmc_rescan+0x2c4/0x390)
[] (mmc_rescan+0x2c4/0x390) from [] (process_one_work+0x29c/0x458)
[] (process_one_work+0x29c/0x458) from [] (worker_thread+0x194/0x2d4)
[] (worker_thread+0x194/0x2d4) from [] (kthread+0xa0/0xac)
[] (kthread+0xa0/0xac) from [] (ret_from_fork+0x14/0x3c)
1409..dw_mci_set_ios: wait for unbusy timeout....... STATUS = 0x306 [mmc1]

请检查CMD线与DATA的电压是否在空载状态下为高电平。并且检测IO电压是否过低,以及IO电压与电源域的配置
是否一致。如果是SDIO接口,建议排查VCCIO_WL电压,VBAT_WL和WIFI_REG_ON以及晶振是否正常。另可以尝
试排查走线太长导致波形质量很差,降频进行测试

dts 含义解析


&sdio0 {

    status = "okay";

    max-frequency = <150000000>;  //sd卡的配置,最大运行频率为150Mhz

    bus-width = <4>;  //此配置同SD卡功能。number of data lines,此配置标识需要使用SD卡的线宽。SD卡最大支持4线模式.

    cap-sd-highspeed;   //此配置同SD卡功能,作为SDIO外设,也有区分是否为highspeed的SDIO外设

    cap-sdio-irq;       //此配置标识该SDIO外设(通常是Wifi)是否支持sdio中断,,如果你的外设是OOB中断,

请不要加入此项。支持哪种类型的中断请联系Wifi原厂确定

    disable-wp;

    keep-power-in-suspend;  //此配置表示是否支持睡眠不断电,请默认加入该选项。Wifi一般都有深度唤醒的要求。

    mmc-pwrseq = <&sdio_pwrseq>;  //此项是SDIO外设(一般是Wifi)的电源控制。为必须项,否则Wifi无法上电工作

    non-removable;  //此项表示该插槽为不可移动设备且此项为SDIO设备必须添加项

    num-slots = <1>; //此项同SD卡的配置。指定控制器支持的插槽数。

    pinctrl-names = "default";

    pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk &sdio0_int>;

    sd-uhs-sdr104;  //此项配置决定该SDIO设备是否支持SDIO3.0模式。前提是需要Wifi的IO电压为1.8v

    supports-sdio;  //标识此插槽为SDIO功能,为必须添加项。否则无法初始化SDIO外设。

};

你可能感兴趣的:(Linux-MMC子系统)