[PATCH] octeon: fix unstable eMMC on ER-8

Yu Zhao yuzhao at google.com
Mon Aug 1 00:50:36 PDT 2022


Two ER-8 devices complained rootfs corruption and failed to finish
booting [1] after they were flashed to OpenWrt. The problem was always
reproducible unless those device were powered on after they had been
off for a while. The two devices seem to be in different hardware
versions but neither has a clear marking of version.

The initial suspicion was bad blocks. However, the problem persisted
after replacing the old eMMC with a brand-new one. Upon examining the
stock firmware [2], it appears it uses a lower eMMC clock speed [3]
than OpenWrt currently does [4]. Poking into the eMMC register with
JTAG [5] confirmed this [6].

Even though the log says the contrary [7], it's very likely the stock
firmware actually uses its own DTB rather than the one passed in by
the bootloader, which OpenWrt currently uses, to override the default
clock speed.

This patch adds the DTS [8] from the stock firmware [2], and makes
ER-8 use it. Interestingly, the only change in the device tree after
this patch is the eMMC clock speed [9].

[1] SQUASHFS error: ...
    Kernel panic - not syncing: No working init found. ...

[2] ER-e200.v2.0.9-hotfix.4.5521907.tar (2022/07/18)

[3] # find /sys -name ios
    # hexdump -e '"%d\n"' /proc/device-tree/soc at 0/mmc at 1180000002000/mmc-slot at 0/spi-max-frequency
    26000000

[4] # cat /sys/kernel/debug/mmc0/ios
    clock:          52000000 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:      3 (8 bits)
    timing spec:    8 (mmc DDR52)
    signal voltage: 0 (3.30 V)
    driver type:    0 (driver type B)

[5] $ cat cn6120.cfg
    adapter driver jlink
    transport select jtag
    adapter speed 50000
    reset_config trst_and_srst

    jtag newtap cpu tap0 -irlen 5
    jtag newtap cpu tap1 -irlen 5

    target create cpu.core0 mips_mips64 -chain-position cpu.tap0 -endian big -rtos hwthread -coreid 0
    target create cpu.core1 mips_mips64 -chain-position cpu.tap1 -endian big -rtos hwthread -coreid 1
    target smp cpu.core0 cpu.core1

    cpu.core0 configure -work-area-phys 0xffffffffa2000000 -work-area-size 0x20000
    cpu.core1 configure -work-area-phys 0xffffffffa2000000 -work-area-size 0x20000

    targets cpu.core0

    flash bank flash0 cfi 0x1fc00000 0x800000 1 1 cpu.core0 x16_as_x8

    $ openocd -f cn6120.cfg
    ...
    > mdd 0x8001180000002048

[6] Register address:
    #define CVMX_MIO_EMM_SWITCH		CVMX_ADD_IO_SEG(0x0001180000002048ull)

    Register fields:
    #define MIO_EMM_SWITCH_HS_TIMING	BIT_ULL(48)
    #define MIO_EMM_SWITCH_BUS_WIDTH	GENMASK_ULL(42, 40)
    #define MIO_EMM_SWITCH_POWER_CLASS	GENMASK_ULL(35, 32)
    #define MIO_EMM_SWITCH_CLK_HI	GENMASK_ULL(31, 16)
    #define MIO_EMM_SWITCH_CLK_LO	GENMASK_ULL(15, 0)

    Register values:
    U-Boot (e201_002_80eda): MSB 0001 02 00 0006 0006 LSB
    Stock firmware:          MSB 0000 06 0a 000c 000c LSB
    OpenWrt:                 MSB 0000 06 0a 0006 0006 LSB

[7] # dmesg
    Linux version 4.9.79-UBNT (ubnt at b2f37ccb332c) ...
    ...
    Using passed Device Tree <8000000000080000>.
    Using passed Device Tree.

[8] # dtc -v
    Version: DTC 1.6.1
    # dtc -I fs -O dts /proc/device-tree/ -o ubnt_e200.dts

    Then manually reset the "local-mac-address" properties to zeros so
    that octeon_fdt_set_mac_addr() will fix then up later.

[9] $ diff -Npur old.dts new.dts
    ...
    -				spi-max-frequency = <0x3197500>;
    +				spi-max-frequency = <0x18cba80>;
    ...

Signed-off-by: Yu Zhao <yuzhao at google.com>
---
 .../mips/boot/dts/cavium-octeon/ubnt_e200.dts | 388 ++++++++++++++++++
 target/linux/octeon/image/Makefile            |   2 +
 2 files changed, 390 insertions(+)
 create mode 100644 target/linux/octeon/files/arch/mips/boot/dts/cavium-octeon/ubnt_e200.dts

diff --git a/target/linux/octeon/files/arch/mips/boot/dts/cavium-octeon/ubnt_e200.dts b/target/linux/octeon/files/arch/mips/boot/dts/cavium-octeon/ubnt_e200.dts
new file mode 100644
index 0000000000..6d517ca1ac
--- /dev/null
+++ b/target/linux/octeon/files/arch/mips/boot/dts/cavium-octeon/ubnt_e200.dts
@@ -0,0 +1,388 @@
+/dts-v1/;
+
+/ {
+	compatible = "ubnt,e200";
+	interrupt-parent = <0x01>;
+	model = "ubnt,e200";
+	#address-cells = <0x02>;
+	#size-cells = <0x02>;
+
+	memory {
+		reg = <0x00 0x00 0x00 0x10000000 0x00 0x20000000 0x00 0x70000000>;
+		device_type = "memory";
+	};
+
+	soc at 0 {
+		compatible = "simple-bus";
+		ranges;
+		#address-cells = <0x02>;
+		#size-cells = <0x02>;
+
+		dma-engine at 1180000000108 {
+			interrupts = <0x00 0x3f>;
+			compatible = "cavium,octeon-5750-bootbus-dma";
+			reg = <0x11800 0x108 0x00 0x08>;
+		};
+
+		interrupt-controller at 1070000000000 {
+			interrupt-controller;
+			compatible = "cavium,octeon-3860-ciu";
+			reg = <0x10700 0x00 0x00 0x7000>;
+			#interrupt-cells = <0x02>;
+			phandle = <0x01>;
+			linux,phandle = <0x01>;
+		};
+
+		pip at 11800a0000000 {
+			compatible = "cavium,octeon-3860-pip";
+			reg = <0x11800 0xa0000000 0x00 0x2000>;
+			#address-cells = <0x01>;
+			#size-cells = <0x00>;
+
+			interface at 1 {
+				compatible = "cavium,octeon-3860-pip-interface";
+				reg = <0x01>;
+				#address-cells = <0x01>;
+				#size-cells = <0x00>;
+
+				ethernet at 0 {
+					compatible = "cavium,octeon-3860-pip-port";
+					phy-handle = <0x09>;
+					reg = <0x00>;
+					local-mac-address = [00 00 00 00 00 00];
+				};
+
+				ethernet at 2 {
+					compatible = "cavium,octeon-3860-pip-port";
+					phy-handle = <0x0b>;
+					reg = <0x02>;
+					local-mac-address = [00 00 00 00 00 00];
+				};
+
+				ethernet at 1 {
+					compatible = "cavium,octeon-3860-pip-port";
+					phy-handle = <0x0a>;
+					reg = <0x01>;
+					local-mac-address = [00 00 00 00 00 00];
+				};
+
+				ethernet at 3 {
+					compatible = "cavium,octeon-3860-pip-port";
+					phy-handle = <0x0c>;
+					reg = <0x03>;
+					local-mac-address = [00 00 00 00 00 00];
+				};
+			};
+
+			interface at 0 {
+				compatible = "cavium,octeon-3860-pip-interface";
+				reg = <0x00>;
+				#address-cells = <0x01>;
+				#size-cells = <0x00>;
+
+				ethernet at 0 {
+					compatible = "cavium,octeon-3860-pip-port";
+					phy-handle = <0x03>;
+					reg = <0x00>;
+					local-mac-address = [00 00 00 00 00 00];
+				};
+
+				ethernet at 2 {
+					compatible = "cavium,octeon-3860-pip-port";
+					phy-handle = <0x07>;
+					reg = <0x02>;
+					local-mac-address = [00 00 00 00 00 00];
+				};
+
+				ethernet at 1 {
+					compatible = "cavium,octeon-3860-pip-port";
+					phy-handle = <0x04>;
+					reg = <0x01>;
+					local-mac-address = [00 00 00 00 00 00];
+				};
+
+				ethernet at 3 {
+					compatible = "cavium,octeon-3860-pip-port";
+					phy-handle = <0x08>;
+					reg = <0x03>;
+					local-mac-address = [00 00 00 00 00 00];
+				};
+			};
+		};
+
+		mmc at 1180000002000 {
+			interrupts = <0x01 0x13 0x00 0x3f>;
+			compatible = "cavium,octeon-6130-mmc";
+			reg = <0x11800 0x2000 0x00 0x100 0x11800 0x168 0x00 0x20>;
+			#address-cells = <0x01>;
+			#size-cells = <0x00>;
+
+			mmc-slot at 0 {
+				cavium,bus-max-width = <0x08>;
+				compatible = "cavium,octeon-6130-mmc-slot\0mmc-spi-slot";
+				voltage-ranges = <0xce4 0xce4>;
+				reg = <0x00>;
+				spi-max-frequency = <0x18cba80>;
+			};
+		};
+
+		mdio at 1180000001800 {
+			compatible = "cavium,octeon-3860-mdio";
+			reg = <0x11800 0x1800 0x00 0x40>;
+			#address-cells = <0x01>;
+			#size-cells = <0x00>;
+
+			ethernet-phy at 2 {
+				compatible = "broadcom,bcm\0ethernet-phy-ieee802.3-c22";
+				reg = <0x02>;
+				interrupt-parent = <0x02>;
+				phandle = <0x0b>;
+				linux,phandle = <0x0b>;
+			};
+
+			ethernet-phy at 1 {
+				compatible = "broadcom,bcm\0ethernet-phy-ieee802.3-c22";
+				reg = <0x01>;
+				interrupt-parent = <0x02>;
+				phandle = <0x0a>;
+				linux,phandle = <0x0a>;
+			};
+
+			ethernet-phy at 7 {
+				compatible = "broadcom,bcm\0ethernet-phy-ieee802.3-c22";
+				reg = <0x07>;
+				interrupt-parent = <0x02>;
+				phandle = <0x08>;
+				linux,phandle = <0x08>;
+			};
+
+			ethernet-phy at 5 {
+				compatible = "broadcom,bcm\0ethernet-phy-ieee802.3-c22";
+				reg = <0x05>;
+				interrupt-parent = <0x02>;
+				phandle = <0x04>;
+				linux,phandle = <0x04>;
+			};
+
+			ethernet-phy at 4 {
+				compatible = "broadcom,bcm\0ethernet-phy-ieee802.3-c22";
+				reg = <0x04>;
+				interrupt-parent = <0x02>;
+				phandle = <0x03>;
+				linux,phandle = <0x03>;
+			};
+
+			ethernet-phy at 0 {
+				compatible = "broadcom,bcm\0ethernet-phy-ieee802.3-c22";
+				reg = <0x00>;
+				interrupt-parent = <0x02>;
+				phandle = <0x09>;
+				linux,phandle = <0x09>;
+			};
+
+			ethernet-phy at 3 {
+				compatible = "broadcom,bcm\0ethernet-phy-ieee802.3-c22";
+				reg = <0x03>;
+				interrupt-parent = <0x02>;
+				phandle = <0x0c>;
+				linux,phandle = <0x0c>;
+			};
+
+			ethernet-phy at 6 {
+				compatible = "broadcom,bcm\0ethernet-phy-ieee802.3-c22";
+				reg = <0x06>;
+				interrupt-parent = <0x02>;
+				phandle = <0x07>;
+				linux,phandle = <0x07>;
+			};
+		};
+
+		bootbus at 1180000000000 {
+			compatible = "cavium,octeon-3860-bootbus";
+			reg = <0x11800 0x00 0x00 0x200>;
+			ranges = <0x00 0x00 0x00 0x1f400000 0xc00000 0x01 0x00 0x10000 0x30000000 0x00 0x02 0x00 0x00 0x1d040000 0x10000 0x03 0x00 0x00 0x1d050000 0x10000 0x04 0x00 0x00 0x1d020000 0x10000 0x05 0x00 0x10000 0x40000000 0x00 0x06 0x00 0x10000 0x50000000 0x00 0x07 0x00 0x10000 0x90000000 0x00>;
+			#address-cells = <0x02>;
+			#size-cells = <0x01>;
+
+			cavium,cs-config at 4 {
+				cavium,t-wr-hld = <0x00>;
+				compatible = "cavium,octeon-3860-bootbus-config";
+				cavium,t-ce = <0x0a>;
+				cavium,t-we = <0x64>;
+				cavium,t-rd-dly = <0x0a>;
+				cavium,t-rd-hld = <0x00>;
+				cavium,t-adr = <0x0a>;
+				cavium,pages = <0x00>;
+				cavium,t-page = <0x12c>;
+				cavium,t-pause = <0x32>;
+				cavium,cs-index = <0x04>;
+				cavium,bus-width = <0x08>;
+				cavium,t-oe = <0xa0>;
+				cavium,t-wait = <0x12c>;
+			};
+
+			cavium,cs-config at 3 {
+				cavium,t-wr-hld = <0x1e>;
+				compatible = "cavium,octeon-3860-bootbus-config";
+				cavium,t-ce = <0x1e>;
+				cavium,t-we = <0x96>;
+				cavium,wait-mode;
+				cavium,t-rd-dly = <0x00>;
+				cavium,t-rd-hld = <0x64>;
+				cavium,t-adr = <0x00>;
+				cavium,pages = <0x00>;
+				cavium,t-page = <0x12c>;
+				cavium,t-pause = <0x00>;
+				cavium,cs-index = <0x03>;
+				cavium,bus-width = <0x10>;
+				cavium,t-oe = <0x7d>;
+				cavium,t-wait = <0x1e>;
+			};
+
+			cavium,cs-config at 2 {
+				cavium,t-wr-hld = <0x12c>;
+				compatible = "cavium,octeon-3860-bootbus-config";
+				cavium,t-ce = <0x12c>;
+				cavium,t-we = <0x96>;
+				cavium,t-rd-dly = <0x00>;
+				cavium,t-rd-hld = <0x64>;
+				cavium,t-adr = <0x00>;
+				cavium,pages = <0x00>;
+				cavium,t-page = <0x12c>;
+				cavium,t-pause = <0x00>;
+				cavium,cs-index = <0x02>;
+				cavium,bus-width = <0x10>;
+				cavium,t-oe = <0x7d>;
+				cavium,t-wait = <0x12c>;
+			};
+
+			nor at 0,0 {
+				compatible = "cfi-flash";
+				reg = <0x00 0x00 0x800000>;
+				#address-cells = <0x01>;
+				#size-cells = <0x01>;
+			};
+
+			cavium,cs-config at 0 {
+				cavium,t-wr-hld = <0x23>;
+				compatible = "cavium,octeon-3860-bootbus-config";
+				cavium,t-ce = <0x32>;
+				cavium,t-we = <0x23>;
+				cavium,t-rd-dly = <0x00>;
+				cavium,t-rd-hld = <0x19>;
+				cavium,t-adr = <0x0a>;
+				cavium,pages = <0x00>;
+				cavium,t-page = <0x19>;
+				cavium,t-pause = <0x00>;
+				cavium,cs-index = <0x00>;
+				cavium,bus-width = <0x08>;
+				cavium,t-oe = <0x32>;
+				cavium,t-wait = <0x12c>;
+			};
+		};
+
+		mdio at 1180000001900 {
+			compatible = "cavium,octeon-3860-mdio";
+			reg = <0x11800 0x1900 0x00 0x40>;
+			#address-cells = <0x01>;
+			#size-cells = <0x00>;
+		};
+
+		spi at 1070000001000 {
+			interrupts = <0x00 0x3a>;
+			compatible = "cavium,octeon-3010-spi";
+			reg = <0x10700 0x1000 0x00 0x100>;
+			#address-cells = <0x01>;
+			#size-cells = <0x00>;
+		};
+
+		gpio-controller at 1070000000800 {
+			interrupt-controller;
+			interrupts = <0x00 0x10>;
+			compatible = "cavium,octeon-3860-gpio";
+			gpio-controller;
+			reg = <0x10700 0x800 0x00 0x100>;
+			#gpio-cells = <0x02>;
+			#interrupt-cells = <0x02>;
+			phandle = <0x02>;
+			linux,phandle = <0x02>;
+		};
+
+		i2c at 1180000001000 {
+			interrupts = <0x00 0x2d>;
+			compatible = "cavium,octeon-3860-twsi";
+			reg = <0x11800 0x1000 0x00 0x200>;
+			#address-cells = <0x01>;
+			#size-cells = <0x00>;
+			clock-frequency = <0x186a0>;
+		};
+
+		serial at 1180000000800 {
+			interrupts = <0x00 0x22>;
+			compatible = "cavium,octeon-3860-uart\0ns16550";
+			reg = <0x11800 0x800 0x00 0x400>;
+			current-speed = <0x1c200>;
+			reg-shift = <0x03>;
+			clock-frequency = <0x23c34600>;
+		};
+
+		serial at 1180000000c00 {
+			interrupts = <0x00 0x23>;
+			compatible = "cavium,octeon-3860-uart\0ns16550";
+			reg = <0x11800 0xc00 0x00 0x400>;
+			current-speed = <0x1c200>;
+			reg-shift = <0x03>;
+			clock-frequency = <0x23c34600>;
+		};
+
+		i2c at 1180000001200 {
+			interrupts = <0x00 0x3b>;
+			compatible = "cavium,octeon-3860-twsi";
+			reg = <0x11800 0x1200 0x00 0x200>;
+			#address-cells = <0x01>;
+			#size-cells = <0x00>;
+			clock-frequency = <0x186a0>;
+		};
+
+		uctl at 118006f000000 {
+			compatible = "cavium,octeon-6335-uctl";
+			reg = <0x11800 0x6f000000 0x00 0x100>;
+			refclk-type = "crystal";
+			refclk-frequency = <0xb71b00>;
+			ranges;
+			#address-cells = <0x02>;
+			#size-cells = <0x02>;
+
+			ehci at 16f0000000000 {
+				interrupts = <0x00 0x38>;
+				compatible = "cavium,octeon-6335-ehci\0usb-ehci";
+				reg = <0x16f00 0x00 0x00 0x100>;
+				big-endian-regs;
+			};
+
+			ohci at 16f0000000400 {
+				interrupts = <0x00 0x38>;
+				compatible = "cavium,octeon-6335-ohci\0usb-ohci";
+				reg = <0x16f00 0x400 0x00 0x100>;
+				big-endian-regs;
+			};
+		};
+
+		dma-engine at 1180000000100 {
+			interrupts = <0x00 0x3f>;
+			compatible = "cavium,octeon-5750-bootbus-dma";
+			reg = <0x11800 0x100 0x00 0x08>;
+		};
+	};
+
+	aliases {
+		smi1 = "/soc at 0/mdio at 1180000001900";
+		uart1 = "/soc at 0/serial at 1180000000c00";
+		twsi1 = "/soc at 0/i2c at 1180000001200";
+		twsi0 = "/soc at 0/i2c at 1180000001000";
+		uart0 = "/soc at 0/serial at 1180000000800";
+		pip = "/soc at 0/pip at 11800a0000000";
+		smi0 = "/soc at 0/mdio at 1180000001800";
+		flash0 = "/soc at 0/bootbus at 1180000000000/nor at 0,0";
+	};
+};
diff --git a/target/linux/octeon/image/Makefile b/target/linux/octeon/image/Makefile
index fa845a2499..f5424b50b8 100644
--- a/target/linux/octeon/image/Makefile
+++ b/target/linux/octeon/image/Makefile
@@ -49,6 +49,8 @@ define Device/ubnt_edgerouter
   BOARD_NAME := er
   CMDLINE := $(ER_CMDLINE)
   SUPPORTED_DEVICES += er
+  DEVICE_DTS := ubnt_e200
+  KERNEL += | append-dtb-to-elf
 endef
 TARGET_DEVICES += ubnt_edgerouter
 

base-commit: beeb49740bb4f68aadf92095984a2d1f9a488956
-- 
2.37.1.455.g008518b4e5-goog




More information about the openwrt-devel mailing list