mmc: error -110 whilst initialising SD card

mmc: error -110 whilst initialising SD card

硬件:RK3562

原理图

在这里插入图片描述

解决方案

先直接说解决方案,请检查设备树中是否有设置SDMMCsdr104模式

&sdmmc0 {
        no-sdio;
        no-mmc;
        bus-width = <4>;
        cap-mmc-highspeed;
        cap-sd-highspeed;
        disable-wp;
        sd-uhs-sdr104;
        vmmc-supply = <&vcc_3v3>;
        vqmmc-supply = <&vccio_sd>;
        pinctrl-names = "default";
        pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
        status = "okay";
};

vccio_sd: LDO_REG5 {
        regulator-always-on;
        regulator-boot-on;
        regulator-min-microvolt = <1800000>;
        regulator-max-microvolt = <3300000>;
        regulator-name = "vccio_sd";
        regulator-state-mem {
                regulator-off-in-suspend;
        };
};

如有,请检查SDMMC通信引脚电源域供电是否配置为1.8V-3.3V。SDMMC其vqmmc供电应是1.8V-3.3V。上述vccio_sd是LDO引出的regulator,其给SDMMC0通信引脚供电,设备树中需保证SDMMC0信令电压支持1.8V-3.3V电压。所以设备树中vccio_sd最小电压1.8V,最大电压3.3V。例如下图为固定电压调节器3.3V供电,不支持sdr104模式,所以mmc控制器切换后无法通信

在这里插入图片描述


  • 解决方案1
    如若硬件暂时无法更改,使用的regulator使固定电压的不支持1.8V。可以尝试注释 上述代码中的sd-uhs-sdr104;,使其运行High Speed模式。如下图所示,High Speed模式使用的3.3V,速度会有一定的损失,但可以保证TF卡正常工作,测试了下对于市面上大多的sd卡速度损失不会太大,因为都跑不满。
    在这里插入图片描述

这个图可以看到各模式使用的电压及频率
在这里插入图片描述


这个图可以对比各模式速度差异

在这里插入图片描述

  • 解决方案2
    在mmc控制器中添加no-1-8-v属性。此方法未尝试。

    RK3562的mmc控制器:
&sdhci {
        bus-width = <8>;
        no-sdio;
        no-sd;
        non-removable;
        max-frequency = <200000000>;
        mmc-hs400-1_8v;
        no-1-8-v;
        mmc-hs400-enhanced-strobe;
        full-pwr-cycle-in-suspend;
        status = "okay";
};
  • 解决方案3
    修改设备树中的regulator,设置最小值1.8V,最大值3.3V。参考上面的vccio_sd修改。注意,修改regulator需要注意其是否影响其他引脚供电。所以修改前请先确认哪些电源域使用到该regulator。

  • 解决方案4
    修改硬件,使SDMMC通信引脚电源域支持1.8v-3.3v

问题分析概述

表现为识别不了sd卡,并且报错

mmc0: error -110 whilst initialising SD card

使用的sdmmc0(在系统里叫mmc1,设备树定义),先查找一下基地址,好多抓取些日志分析

cd kernel/arch/arm64/boot/dts/rockchip
grep -nr sdmmc0 *3562*

==>rk3562.dtsi:2829:       sdmmc0: mmc@ff880000 {
==>rk3562-linux.dtsi:10:           mmc1 = &sdmmc0;

可以看到基地址为ff880000,其系统里的别名为mmc1。按这两个名称检索内核日志。
插上TK卡,打开开发板串口终端

dmesg | grep "mmc1\|ff880000"

先贴一份“正常”的日志

[    4.125830] dwmmc_rockchip ff880000.mmc: No normal pinctrl state
[    4.125834] dwmmc_rockchip ff880000.mmc: No idle pinctrl state
[    4.125998] dwmmc_rockchip ff880000.mmc: IDMAC supports 32-bit address mode.
[    4.126016] dwmmc_rockchip ff880000.mmc: Using internal DMA controller.
[    4.126023] dwmmc_rockchip ff880000.mmc: Version ID is 270a
[    4.126059] dwmmc_rockchip ff880000.mmc: DW MMC controller at irq 84,32 bit host data width,256 deep fifo
[    4.139105] mmc_host mmc1: Bus speed (slot 0) = 400000Hz (slot req 400000Hz, actual 400000HZ div = 0)
[    4.213397] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 50000000Hz, actual 50000000HZ div = 0)
[    4.213779] mmc1: new high speed SDHC card at address aaaa
[    4.214238] mmcblk1: mmc1:aaaa SK32G 29.7 GiB

为什么说是“正常”的呢?因为这里可以看到这是high speed SDHC card。我们实际插入的是支持超高速SDR104模式的TF卡。

  • 错误日志
    dmesg | grep "mmc1\|ff880000"
[    4.134141] dwmmc_rockchip ff880000.mmc: No normal pinctrl state
[    4.134160] dwmmc_rockchip ff880000.mmc: No idle pinctrl state
[    4.134312] dwmmc_rockchip ff880000.mmc: IDMAC supports 32-bit address mode.
[    4.134325] dwmmc_rockchip ff880000.mmc: Using internal DMA controller.
[    4.134333] dwmmc_rockchip ff880000.mmc: Version ID is 270a
[    4.134359] dwmmc_rockchip ff880000.mmc: DW MMC controller at irq 84,32 bit host data width,256 deep fifo
[    4.146805] mmc_host mmc1: Bus speed (slot 0) = 400000Hz (slot req 400000Hz, actual 400000HZ div = 0)
[    4.245282] mmc1: error -110 whilst initialising SD card
[    4.745314] dwmmc_rockchip ff880000.mmc: Busy; trying anyway
[    5.245354] mmc_host mmc1: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000)
[    5.260065] mmc_host mmc1: Bus speed (slot 0) = 300000Hz (slot req 300000Hz, actual 300000HZ div = 0)
[    5.783810] dwmmc_rockchip ff880000.mmc: Busy; trying anyway
[    6.283841] mmc_host mmc1: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000)
[    6.298060] mmc_host mmc1: Bus speed (slot 0) = 200000Hz (slot req 200000Hz, actual 200000HZ div = 0)
[    6.824140] dwmmc_rockchip ff880000.mmc: Busy; trying anyway
[    7.324172] mmc_host mmc1: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000)
[    7.337194] mmc_host mmc1: Bus speed (slot 0) = 100000Hz (slot req 100000Hz, actual 100000HZ div = 0)
[    7.873286] dwmmc_rockchip ff880000.mmc: Busy; trying anyway
[    8.373317] mmc_host mmc1: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000)

  • 代码分析
    打开opengrok检索错误日志,-110替换成%d。这种检索可适当缩减检索信息。定位到代码在kernel/drivers/mmc/core/sd.c
    在这里插入图片描述
/*
 * Starting point for SD card init.
 */
int mmc_attach_sd(struct mmc_host *host)
{
	int err;
	u32 ocr, rocr;

	WARN_ON(!host->claimed);

    // 省略无用代码

	/*
	 * Detect and init the card.
	 */
	err = mmc_sd_init_card(host, rocr, NULL);
	if (err)
		goto err;

	mmc_claim_host(host);
	return 0;

    // 省略无用代码
err:
	mmc_detach_bus(host);

	pr_err("%s: error %d whilst initialising SD card\n",
		mmc_hostname(host), err);

	return err;
}
  • 定位报错函数
    添加打印信息,定位报错函数,最终看到大概是电压切换的问题。
    需要添加很多日志打印,定位到具体函数,复盘问题实在不想再做一遍了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值