sd卡、sdio接口调试
sd、emmc都是在mmc基础上演化而来的,sdio是在sd上发展而来的。他们三则有很多相似之处。在linux中都是在mmc框架中处理。sdio卡主要是使用sdio接口的wifi、蓝牙等设备。
一、卡识别
在卡识别阶段,主控会用默认电压(所有sd卡都支持的电压)和默认时钟频率(所有sd卡都支持的频率)进行卡识别,主控会读取sd卡中的ocr寄存器获取sd卡支持的电压,读取csd寄存器读取sd卡支持大最大速度等信息。之后主控会将接口电压和时钟频率切换到sd卡支持的电压和频率。卡检测的时候分为中断检测和轮询检测,中断检测通常用在可拔插的sd卡。在设备树上可以配置这两种检测方式。如果在sdio节点中加入broken-cd;参数,表示使用轮询检测。如果设置cd-gpios则使用中断检测。设备树中mmc节点的参数含义可以在linux/Documentation/devicetree/bindings/mmc/mmc-controller.yaml中 看到
卡无法识别可能原因:
1、电压不匹配
sd卡供电电压固定为3.3v,而sd卡支持1.8v电压,主控识别到sd卡支持1.8v就会将接口电压切换到1.8v,这就导致接口电压和sd卡供电电压不同。解决方法是在设备树中的mmc节点设置一个"no-1-8-v"参数,这样主控就不会将电压切换到1.8v。但这不是所有卡都这样,有些卡3.3v供电,接口电压可以是1.8v。
对于sdio卡,如果有个VDDIO引脚,这个引脚需要给1.8或者3.3v,该引脚的电平需要和sdio接口电平匹配,比如VDDIO供电3.3v,那么sdio接口电平也应该是3.3v。
2、检测引脚设置不正确
如何sd卡用cd引脚检测的,检查设备树中cd_gpio是否设置正确
关于时钟频率问题,设备树中的mmc节点通常会有max-frequency 参数,表示最大不超过该时钟频率。例如max-frequency=100MHZ,sd卡支持的频率为150MHZ,则主控会将频率设置到100MHZ,如何sd卡支持的频率为50MHZ,则主控会将频率降低到50MHZ。可以cat /sys/kernel/debug/mmc0/clock 查看当前使用的时钟频率
3、hi3516_3519dv500 mmc驱动问题
在轮询检测中,会调用drivers/mmc/host/sdhci.c中的sdhci_get_cd函数,该函数最后判断return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);会返回0,这里是读取mmc控制器偏移地址0x24的第十六位,手册中偏移地址为0x24的寄存器12~19位是保留的。这里有bug,需要在sdhci_get_cd前面加上
if (gpio_cd == -ENOSYS)
return 1;
4、hi3516_3519dv500 sd电源控制引脚SDIO0_CARD_POWER_EN_N问题
在轮询检测时,mmc_rescan_try_freq会调用mmc_power_up和mmc_power_off函数,开始检测sd卡前打开sd卡电源,检测不到就关闭电源。实际测试sd电源出现频繁开关情况,无法识别到sd卡,将该电源引脚设置为gpio口,收到打开sd卡电源

浙公网安备 33010602011771号