前言
此系列博文是在解决了openwrt在NanoPi R2s上启动失败的解决过程记录,顺带也熟悉了rk3328系列的芯片的启动过程和openwrt中对uboot和最终镜像的生成过程。
问题现象
在master主线的版本编译后,烧写到闪迪的32G TF卡后,发现不能启动,通过串口,得到以下输出。
U-Boot TPL 2021.01 (Jun 13 2021 - 22:02:19)
DDR4, 333MHz
BW=32 Col=10 Bk=4 BG=2 CS0 Row=15 CS=1 Die BW=16 Size=1024MB
Trying to boot from BOOTROM
Returning to boot ROM...
U-Boot SPL 2021.01 (Jun 13 2021 - 22:02:19 +0000)
Trying to boot from MMC1
mmc_load_image_raw_sector: mmc block read error
SPL: failed to boot from all boot devices
问题分析
通过添加日志,定位mmc_load_image_raw_sector
接口,有如下日志:
U-Boot TPL 2021.01 (Jun 13 2021 - 22:02:19)
DDR4, 333MHz
BW=32 Col=10 Bk=4 BG=2 CS0 Row=15 CS=1 Die BW=16 Size=1024MB
Trying to boot from BOOTROM
Returning to boot ROM...
U-Boot SPL 2021.01 (Jun 13 2021 - 22:02:19 +0000)
Trying to boot from MMC1
Buswidth = 0, clock: 0
Buswidth = 0, clock: 0
Buswidth = 1, clock: 0
Buswidth = 1, clock: 400000
CMD_SEND:0
ARG 0x00000000
Sending CMD0
MMC_RSP_NONE
CMD_SEND:8
ARG 0x000001aa
Sending CMD8
MMC_RSP_R1,5,6,7 0x000001aa
CMD_SEND:55
ARG 0x00000000
Sending CMD55
MMC_RSP_R1,5,6,7 0x00800120
CMD_SEND:41
ARG 0x40300000
Sending CMD41
MMC_RSP_R3,4 0x00ff8000
CMD_SEND:55
ARG 0x00000000
Sending CMD55
MMC_RSP_R1,5,6,7 0x00000120
CMD_SEND:41
ARG 0x40300000
Sending CMD41
MMC_RSP_R3,4 0x00ff8000
CMD_SEND:55
ARG 0x00000000
Sending CMD55
MMC_RSP_R1,5,6,7 0x00000120
CMD_SEND:41
ARG 0x40300000
Sending CMD41
MMC_RSP_R3,4 0x00ff8000
CMD_SEND:55
ARG 0x00000000
Sending CMD55
MMC_RSP_R1,5,6,7 0x00000120
CMD_SEND:41
ARG 0x40300000
Sending CMD41
MMC_RSP_R3,4 0x00ff8000
CMD_SEND:55
ARG 0x00000000
Sending CMD55
MMC_RSP_R1,5,6,7 0x00000120
CMD_SEND:41
ARG 0x40300000
Sending CMD41
MMC_RSP_R3,4 0x00ff8000
CMD_SEND:55
ARG 0x00000000
Sending CMD55
MMC_RSP_R1,5,6,7 0x00000120
CMD_SEND:41
ARG 0x40300000
Sending CMD41
MMC_RSP_R3,4 0x80ff8000
CMD_SEND:2
ARG 0x00000000
Sending CMD2
MMC_RSP_R2 0x03534453
0x44303332
0x80ffffff
0xff0062c5
DUMPING DATA
000 - 03 53 44 53
004 - 44 30 33 32
008 - 80 ff ff ff
012 - ff 00 62 c5
CMD_SEND:3
ARG 0x00000000
Sending CMD3
MMC_RSP_R1,5,6,7 0xd5550520
CMD_SEND:9
ARG 0xd5550000
Sending CMD9
MMC_RSP_R2 0x00260032
0x515981e9
0xbef9cfff
0x92404053
DUMPING DATA
000 - 00 26 00 32
004 - 51 59 81 e9
008 - be f9 cf ff
012 - 92 40 40 53
CMD_SEND:7
ARG 0xd5550000
Sending CMD7
MMC_RSP_R1,5,6,7 0x00000700
CMD_SEND:55
ARG 0xd5550000
Sending CMD55
MMC_RSP_R1,5,6,7 0x00000920
CMD_SEND:51
ARG 0x00000000
Sending CMD51
MMC_RSP_R1,5,6,7 0x00000920
CMD_SEND:55
ARG 0xd5550000
Sending CMD55
MMC_RSP_R1,5,6,7 0x00000920
CMD_SEND:6
ARG 0x00000000
Sending CMD6
MMC_RSP_R1,5,6,7 0x00000920
Buswidth = 1, clock: 400000
Buswidth = 1, clock: 25000000
spl: mmc boot mode: raw
CMD_SEND:16
ARG 0x00000200
Sending CMD16
MMC_RSP_R1,5,6,7 0x00000900
CMD_SEND:17
ARG 0x00800000
Sending CMD17
MMC_RSP_R1,5,6,7 0x00000900
hdr read sector 4000, count=1
dump header...
magic:0x0
hcrc: 0x0
size: 0x0
load: 0x0
==============
mmc_load_image_raw_sector: mmc block read error
spl: mmc boot mode: fs
SPL: failed to boot from all boot devices
### ERROR ### Please RESET the board ###
可以看出在协商后,MMC总线宽度为1,而不是4,这是不能正常进行通信的。通过查找MMC协议手册,BUS宽度是可以通过协商然后确定的。接下来就查看原理图,再对比linux下的设备树,TF卡的电源通过vcc_sd和vcc_io_sdio控制,而在rk3328-nanopi-r2s-u-boot.dtsi
和rk3328-nanopi-r2s.dts
中,有如下内容:
/* Need this and all the pinctrl/gpio stuff above to set pinmux */
&vcc_sd {
u-boot,dm-spl;
};
vcc_io_sdio: sdmmcio-regulator {
compatible = "regulator-gpio";
enable-active-high;
gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>;
pinctrl-0 = <&sdio_vcc_pin>;
pinctrl-names = "default";
regulator-name = "vcc_io_sdio";
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-settling-time-us = <5000>;
regulator-type = "voltage";
startup-delay-us = <2000>;
states = <1800000 0x1
3300000 0x0>;
vin-supply = <&vcc_io_33>;
};
vcc_sd: sdmmc-regulator {
compatible = "regulator-fixed";
gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&sdmmc0m1_gpio>;
pinctrl-names = "default";
regulator-name = "vcc_sd";
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vcc_io_33>;
};
&sdmmc {
bus-width = <4>;
cap-sd-highspeed;
disable-wp;
pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>;
pinctrl-names = "default";
sd-uhs-sdr12;
sd-uhs-sdr25;
sd-uhs-sdr50;
sd-uhs-sdr104;
vmmc-supply = <&vcc_sd>;
vqmmc-supply = <&vcc_io_sdio>;
status = "okay";
};
可以看出通过 GPIO1 RK_PD4 控制SD卡的IO电压,通过GPIO0 RK_PD6控制SD的供电电压,前者电压可以配置,后面是固定电压。然后尝试开启MMC的IO可配置选项,再使能对应的pinctrl,并且因为不能启动的卡容量为32G,需要开启UHS支持,接下来进修改,编译后烧写测试。
修改如下:
diff --git a/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi b/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi
index 9e2ced1541..d5469748a2 100644
--- a/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi
+++ b/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi
@@ -33,6 +33,10 @@
u-boot,dm-spl;
};
+&vcc_io_sdio {
+ u-boot,dm-spl;
+};
+
&gmac2io {
snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
diff --git a/arch/arm/dts/rk3328-nanopi-r2s.dts b/arch/arm/dts/rk3328-nanopi-r2s.dts
index 5445c5cb3d..452e4764e6 100644
--- a/arch/arm/dts/rk3328-nanopi-r2s.dts
+++ b/arch/arm/dts/rk3328-nanopi-r2s.dts
@@ -323,7 +323,7 @@
bus-width = <4>;
cap-sd-highspeed;
disable-wp;
- pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>;
+ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>, <&sdmmc0m1_gpio>;
pinctrl-names = "default";
sd-uhs-sdr12;
sd-uhs-sdr25;
diff --git a/configs/nanopi-r2s-rk3328_defconfig b/configs/nanopi-r2s-rk3328_defconfig
index 52996266a1..a7969bd7ab 100644
--- a/configs/nanopi-r2s-rk3328_defconfig
+++ b/configs/nanopi-r2s-rk3328_defconfig
@@ -56,6 +56,10 @@ CONFIG_FASTBOOT_BUF_ADDR=0x800800
CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_SPL_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_SPL_MMC_UHS_SUPPORT=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_SF_DEFAULT_SPEED=20000000
结果
经过上面的修改,发现系统能够正常启动了,说明总线宽度正常协商好了,电压范围也OK,下面是正常启动的日志。
U-Boot TPL 2021.01 (Jun 13 2021 - 22:02:19)
DDR4, 333MHz
BW=32 Col=10 Bk=4 BG=2 CS0 Row=15 CS=1 Die BW=16 Size=1024MB
Trying to boot from BOOTROM
Returning to boot ROM...
U-Boot SPL 2021.01 (Jun 13 2021 - 22:02:19 +0000)
Trying to boot from MMC1
Found FIT
NOTICE: BL31: v2.3():v2.3
NOTICE: BL31: Built : 15:56:43, Apr 20 2020
NOTICE: BL31:Rockchip release version: v1.2
U-Boot 2021.01 (Jun 13 2021 - 22:02:19 +0000) OpenWrt
Model: FriendlyElec NanoPi R2S
DRAM: 1022 MiB
PMIC: RK8050 (on=0x40, off=0x00)
MMC: mmc@ff500000: 1
Loading Environment from MMC... MMC Device 0 not found
*** Warning - No MMC card found, using default environment
In: serial@ff130000
Out: serial@ff130000
Err: serial@ff130000
Model: FriendlyElec NanoPi R2S
Net: eth0: ethernet@ff540000
Hit any key to stop autoboot: 0
=>
总结
在多次尝试后,拿了一张以前的4G金士顿得到TF卡进行对比,发现金士顿的低速卡是OK的;通过日志就发现协商完两者总线宽度不正常,这个时候去简单搜了下协议,发现不同的速度对应不同的频率和电压,发现是不是电压配置不正确还是哪个GPIO没有配置对。
这个时候就去查看同SOC的板子,比较,新增了对dts的修改,再打开了对应的CONFIG选项,果真成功了!!!遇到问题要不断的发现蛛丝马迹,多想一下可能的解决方案,这个时候难题往往就能解决了。