Merge branch '2021-03-20-mediatek-updates' into next

- A number of MediaTek platform updates
diff --git a/Makefile b/Makefile
index 36b867a..b72d8d2 100644
--- a/Makefile
+++ b/Makefile
@@ -1728,6 +1728,9 @@
 
 ifeq ($(CONFIG_SPL),y)
 spl/u-boot-spl-mtk.bin: spl/u-boot-spl
+
+u-boot-mtk.bin: u-boot-with-spl.bin
+	$(call if_changed,copy)
 else
 MKIMAGEFLAGS_u-boot-mtk.bin = -T mtk_image \
 	-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f5fe327..9a8de46 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1013,6 +1013,7 @@
 	mt7622-bananapi-bpi-r64.dtb \
 	mt7623n-bananapi-bpi-r2.dtb \
 	mt7629-rfb.dtb \
+	mt8183-pumpkin.dtb \
 	mt8512-bm1-emmc.dtb \
 	mt8516-pumpkin.dtb \
 	mt8518-ap1-emmc.dtb
diff --git a/arch/arm/dts/mt7629-rfb-u-boot.dtsi b/arch/arm/dts/mt7629-rfb-u-boot.dtsi
index 164afd6..c17e82a 100644
--- a/arch/arm/dts/mt7629-rfb-u-boot.dtsi
+++ b/arch/arm/dts/mt7629-rfb-u-boot.dtsi
@@ -5,24 +5,6 @@
  * Author: Weijie Gao <weijie.gao@mediatek.com>
  */
 
-#include <config.h>
-/ {
-	binman {
-		filename = "u-boot-mtk.bin";
-		pad-byte = <0xff>;
-
-#ifdef CONFIG_SPL
-		blob {
-			filename = "spl/u-boot-spl-mtk.bin";
-			size = <CONFIG_SPL_PAD_TO>;
-		};
-
-		u-boot-img {
-		};
-#endif
-	};
-};
-
 &infracfg {
 	u-boot,dm-pre-reloc;
 };
diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts
index df43cc4..f2e4e95 100644
--- a/arch/arm/dts/mt7629-rfb.dts
+++ b/arch/arm/dts/mt7629-rfb.dts
@@ -36,6 +36,16 @@
 };
 
 &pinctrl {
+	state_default: pinmux_conf {
+		u-boot,dm-pre-reloc;
+
+		mux {
+			function = "jtag";
+			groups = "ephy_leds_jtag";
+			u-boot,dm-pre-reloc;
+		};
+	};
+
 	snfi_pins: snfi-pins {
 		mux {
 			function = "flash";
diff --git a/arch/arm/dts/mt7629.dtsi b/arch/arm/dts/mt7629.dtsi
index 0539426..7dea780 100644
--- a/arch/arm/dts/mt7629.dtsi
+++ b/arch/arm/dts/mt7629.dtsi
@@ -152,6 +152,12 @@
 		compatible = "mediatek,mt7629-pinctrl";
 		reg = <0x10217000 0x8000>;
 
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinmux_conf {
+		};
+
 		gpio: gpio-controller {
 			gpio-controller;
 			#gpio-cells = <2>;
diff --git a/arch/arm/dts/mt8183-pumpkin.dts b/arch/arm/dts/mt8183-pumpkin.dts
new file mode 100644
index 0000000..470a769
--- /dev/null
+++ b/arch/arm/dts/mt8183-pumpkin.dts
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2021 BayLibre SAS.
+ * Author: Fabien Parent <fparent@baylibre.com>
+ */
+
+/dts-v1/;
+
+#include <config.h>
+#include "mt8183.dtsi"
+
+/ {
+	model = "MediaTek MT8183 pumpkin board";
+	compatible = "mediatek,mt8183-pumpkin", "mediatek,mt8183";
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x80000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
+		bl31_secmon_reserved: secmon@54600000 {
+			no-map;
+			reg = <0 0x54600000 0x0 0x30000>;
+		};
+
+		/* 12 MiB reserved for OP-TEE (BL32)
+		 * +-----------------------+ 0x43e0_0000
+		 * |      SHMEM 2MiB       |
+		 * +-----------------------+ 0x43c0_0000
+		 * |        | TA_RAM  8MiB |
+		 * + TZDRAM +--------------+ 0x4340_0000
+		 * |        | TEE_RAM 2MiB |
+		 * +-----------------------+ 0x4320_0000
+		 */
+		optee_reserved: optee@43200000 {
+			no-map;
+			reg = <0 0x43200000 0 0x00c00000>;
+		};
+	};
+
+	chosen {
+		stdout-path = &uart0;
+	};
+
+	reg_1p8v: regulator-1p8v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-1.8V";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&watchdog {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&mmc0 {
+	bus-width = <4>;
+	max-frequency = <200000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	cap-mmc-hw-reset;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_1p8v>;
+	non-removable;
+	status = "okay";
+};
+
+&usb {
+	status = "okay";
+};
+
+&ssusb {
+	mediatek,force-vbus;
+	maximum-speed = "high-speed";
+	dr_mode = "peripheral";
+	status = "okay";
+};
diff --git a/arch/arm/dts/mt8183.dtsi b/arch/arm/dts/mt8183.dtsi
new file mode 100644
index 0000000..294aa2b
--- /dev/null
+++ b/arch/arm/dts/mt8183.dtsi
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Ben Ho <ben.ho@mediatek.com>
+ *         Erin Lo <erin.lo@mediatek.com>
+ *         Fabien Parent <fparent@baylibre.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/mt8183-clk.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
+
+/ {
+	compatible = "mediatek,mt8183";
+	interrupt-parent = <&sysirq>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+				core1 {
+					cpu = <&cpu1>;
+				};
+				core2 {
+					cpu = <&cpu2>;
+				};
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+				core1 {
+					cpu = <&cpu5>;
+				};
+				core2 {
+					cpu = <&cpu6>;
+				};
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x000>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <741>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x001>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <741>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x002>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <741>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x003>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <741>;
+		};
+
+		cpu4: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a73";
+			reg = <0x100>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <1024>;
+		};
+
+		cpu5: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a73";
+			reg = <0x101>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <1024>;
+		};
+
+		cpu6: cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a73";
+			reg = <0x102>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <1024>;
+		};
+
+		cpu7: cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a73";
+			reg = <0x103>;
+			enable-method = "psci";
+			capacity-dmips-mhz = <1024>;
+		};
+	};
+
+	clk26m: oscillator {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "clk26m";
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "simple-bus";
+		ranges;
+
+		watchdog: watchdog@10007000 {
+			compatible = "mediatek,mt8183-wdt",
+				      "mediatek,wdt";
+			reg = <0 0x10007000 0 0x100>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@c000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <4>;
+			interrupt-parent = <&gic>;
+			interrupt-controller;
+			reg = <0 0x0c000000 0 0x40000>,  /* GICD */
+			      <0 0x0c100000 0 0x200000>, /* GICR */
+			      <0 0x0c400000 0 0x2000>,   /* GICC */
+			      <0 0x0c410000 0 0x1000>,   /* GICH */
+			      <0 0x0c420000 0 0x2000>;   /* GICV */
+
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+			ppi-partitions {
+				ppi_cluster0: interrupt-partition-0 {
+					affinity = <&cpu0 &cpu1 &cpu2 &cpu3>;
+				};
+				ppi_cluster1: interrupt-partition-1 {
+					affinity = <&cpu4 &cpu5 &cpu6 &cpu7>;
+				};
+			};
+		};
+
+		sysirq: interrupt-controller@c530a80 {
+			compatible = "mediatek,mt8183-sysirq",
+				     "mediatek,mt6577-sysirq";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
+			reg = <0 0x0c530a80 0 0x50>;
+		};
+
+		topckgen: syscon@10000000 {
+			compatible = "mediatek,mt8183-topckgen", "syscon";
+			reg = <0 0x10000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		infracfg: syscon@10001000 {
+			compatible = "mediatek,mt8183-infracfg", "syscon";
+			reg = <0 0x10001000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		apmixedsys: syscon@1000c000 {
+			compatible = "mediatek,mt8183-apmixedsys", "syscon";
+			reg = <0 0x1000c000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		uart0: serial@11002000 {
+			compatible = "mediatek,mt8183-uart",
+				     "mediatek,hsuart";
+			reg = <0 0x11002000 0 0x1000>;
+			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
+			clock-frequency = <26000000>;
+			clocks = <&clk26m>, <&infracfg CLK_INFRA_UART0>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		mmc0: mmc@11230000 {
+			compatible = "mediatek,mt8183-mmc";
+			reg = <0 0x11230000 0 0x1000>,
+			      <0 0x11f50000 0 0x1000>;
+			interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&topckgen CLK_TOP_MUX_MSDC50_0>,
+				 <&infracfg CLK_INFRA_MSDC0>,
+				 <&infracfg CLK_INFRA_MSDC0_SCK>;
+			clock-names = "source", "hclk", "source_cg";
+			status = "disabled";
+		};
+
+		u3phy: usb-phy@11f40000 {
+			compatible = "mediatek,generic-tphy-v2";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			status = "okay";
+
+			u2port0: usb-phy2@11f40000 {
+				reg = <0 0x11f40000 0 0x700>;
+				clocks = <&clk26m>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+				status = "okay";
+			};
+
+			u3port0: usb-phy3@11f40700 {
+				reg = <0 0x11f40700 0 0x900>;
+				clocks = <&clk26m>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+				status = "okay";
+			};
+		};
+
+		usb: usb@11200000 {
+			compatible ="mediatek,mt8183-mtu3", "mediatek,mtu3";
+			reg = <0 0x11200000 0 0x3e00>,
+			      <0 0x11203e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>;
+			phys = <&u2port0 PHY_TYPE_USB2>;
+			clocks = <&infracfg CLK_INFRA_UNIPRO_SCK>,
+				 <&infracfg CLK_INFRA_USB>;
+			clock-names = "sys_ck", "ref_ck";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			status = "disabled";
+
+			ssusb: ssusb@11200000 {
+				compatible = "mediatek,ssusb";
+				reg = <0 0x11200000 0 0x3e00>;
+				reg-names = "mac";
+				interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>;
+				status = "disabled";
+			};
+
+			usb_host: xhci@11200000 {
+				compatible = "mediatek,mtk-xhci";
+				reg = <0 0x11200000 0 0x1000>;
+				reg-names = "mac";
+				interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_LOW>;
+				clocks = <&infracfg CLK_INFRA_UNIPRO_SCK>,
+					 <&infracfg CLK_INFRA_USB>;
+				clock-names = "sys_ck", "ref_ck";
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index 7f40ba9..e067604 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -36,12 +36,20 @@
 	bool "MediaTek MT7629 SoC"
 	select CPU_V7A
 	select SPL
-	select BINMAN
 	help
 	  The MediaTek MT7629 is a ARM-based SoC with a dual-core Cortex-A7
 	  including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet,
 	  switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
 
+config TARGET_MT8183
+	bool "MediaTek MT8183 SoC"
+	select ARM64
+	help
+	  The MediaTek MT8183 is a ARM64-based SoC with a quad-core Cortex-A73 and
+	  a quad-core Cortex-A53. It is including UART, SPI, USB3.0 dual role,
+	  SD and MMC cards, UFS, PWM, I2C, I2S, S/PDIF, and several LPDDR3
+	  and LPDDR4 options.
+
 config TARGET_MT8512
         bool "MediaTek MT8512 M1 Board"
         select ARM64
@@ -75,8 +83,9 @@
 source "board/mediatek/mt7622/Kconfig"
 source "board/mediatek/mt7623/Kconfig"
 source "board/mediatek/mt7629/Kconfig"
+source "board/mediatek/mt8183/Kconfig"
 source "board/mediatek/mt8512/Kconfig"
+source "board/mediatek/mt8516/Kconfig"
 source "board/mediatek/mt8518/Kconfig"
-source "board/mediatek/pumpkin/Kconfig"
 
 endif
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index 290d2c7..0f5b0c1 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -7,5 +7,6 @@
 obj-$(CONFIG_TARGET_MT7622) += mt7622/
 obj-$(CONFIG_TARGET_MT7623) += mt7623/
 obj-$(CONFIG_TARGET_MT7629) += mt7629/
+obj-$(CONFIG_TARGET_MT8183) += mt8183/
 obj-$(CONFIG_TARGET_MT8516) += mt8516/
 obj-$(CONFIG_TARGET_MT8518) += mt8518/
diff --git a/board/mediatek/pumpkin/Makefile b/arch/arm/mach-mediatek/mt8183/Makefile
similarity index 65%
rename from board/mediatek/pumpkin/Makefile
rename to arch/arm/mach-mediatek/mt8183/Makefile
index 75fce4a..886ab7e 100644
--- a/board/mediatek/pumpkin/Makefile
+++ b/arch/arm/mach-mediatek/mt8183/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier:	GPL-2.0
 
-obj-y += pumpkin.o
+obj-y += init.o
diff --git a/arch/arm/mach-mediatek/mt8183/init.c b/arch/arm/mach-mediatek/mt8183/init.c
new file mode 100644
index 0000000..877f387
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt8183/init.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Fabien Parent <fparent@baylibre.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <ram.h>
+#include <asm/arch/misc.h>
+#include <asm/armv8/mmu.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+#include <dm/uclass.h>
+#include <dt-bindings/clock/mt8516-clk.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	int ret;
+
+	ret = fdtdec_setup_memory_banksize();
+	if (ret)
+		return ret;
+
+	return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = gd->ram_base;
+	gd->bd->bi_dram[0].size = gd->ram_size;
+
+	return 0;
+}
+
+int mtk_pll_early_init(void)
+{
+	return 0;
+}
+
+int mtk_soc_early_init(void)
+{
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	psci_system_reset();
+}
+
+int print_cpuinfo(void)
+{
+	printf("CPU:   MediaTek MT8183\n");
+	return 0;
+}
+
+static struct mm_region mt8183_mem_map[] = {
+	{
+		/* DDR */
+		.virt = 0x40000000UL,
+		.phys = 0x40000000UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE,
+	}, {
+		.virt = 0x00000000UL,
+		.phys = 0x00000000UL,
+		.size = 0x20000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		0,
+	}
+};
+struct mm_region *mem_map = mt8183_mem_map;
diff --git a/board/mediatek/pumpkin/Kconfig b/board/mediatek/mt8183/Kconfig
similarity index 66%
copy from board/mediatek/pumpkin/Kconfig
copy to board/mediatek/mt8183/Kconfig
index 34b1c0b..b75c3b8 100644
--- a/board/mediatek/pumpkin/Kconfig
+++ b/board/mediatek/mt8183/Kconfig
@@ -1,10 +1,10 @@
-if TARGET_MT8516
+if TARGET_MT8183
 
 config SYS_BOARD
-	default "pumpkin"
+	default "mt8183"
 
 config SYS_CONFIG_NAME
-	default "pumpkin"
+	default "mt8183"
 
 config MTK_BROM_HEADER_INFO
 	string
diff --git a/board/mediatek/mt8183/MAINTAINERS b/board/mediatek/mt8183/MAINTAINERS
new file mode 100644
index 0000000..a49995e
--- /dev/null
+++ b/board/mediatek/mt8183/MAINTAINERS
@@ -0,0 +1,6 @@
+MT8183 Pumpkin
+M:	Fabien Parent <fparent@baylibre.com>
+S:	Maintained
+F:	board/mediatek/mt8183
+F:	include/configs/mt8183.h
+F:	configs/mt8183_pumpkin_defconfig
diff --git a/board/mediatek/mt8183/Makefile b/board/mediatek/mt8183/Makefile
new file mode 100644
index 0000000..90b5b72
--- /dev/null
+++ b/board/mediatek/mt8183/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y += mt8183_pumpkin.o
diff --git a/board/mediatek/pumpkin/pumpkin.c b/board/mediatek/mt8183/mt8183_pumpkin.c
similarity index 68%
copy from board/mediatek/pumpkin/pumpkin.c
copy to board/mediatek/mt8183/mt8183_pumpkin.c
index 37daf1c..db613eb 100644
--- a/board/mediatek/pumpkin/pumpkin.c
+++ b/board/mediatek/mt8183/mt8183_pumpkin.c
@@ -1,18 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (C) 2019 BayLibre SAS
+ * Copyright (C) 2020 BayLibre SAS
+ * Author: Fabien Parent <fparent@baylibre.com>
  */
 
 #include <common.h>
 #include <dm.h>
+#include <net.h>
 
 int board_init(void)
 {
-	return 0;
-}
-
-int board_late_init(void)
-{
 	struct udevice *dev;
 	int ret;
 
@@ -24,5 +21,8 @@
 		}
 	}
 
+	if (CONFIG_IS_ENABLED(USB_ETHER))
+		usb_ether_init();
+
 	return 0;
 }
diff --git a/board/mediatek/pumpkin/Kconfig b/board/mediatek/mt8516/Kconfig
similarity index 76%
rename from board/mediatek/pumpkin/Kconfig
rename to board/mediatek/mt8516/Kconfig
index 34b1c0b..a87d387 100644
--- a/board/mediatek/pumpkin/Kconfig
+++ b/board/mediatek/mt8516/Kconfig
@@ -1,10 +1,10 @@
 if TARGET_MT8516
 
 config SYS_BOARD
-	default "pumpkin"
+	default "mt8516"
 
 config SYS_CONFIG_NAME
-	default "pumpkin"
+	default "mt8516"
 
 config MTK_BROM_HEADER_INFO
 	string
diff --git a/board/mediatek/mt8516/MAINTAINERS b/board/mediatek/mt8516/MAINTAINERS
new file mode 100644
index 0000000..2f0d8f6
--- /dev/null
+++ b/board/mediatek/mt8516/MAINTAINERS
@@ -0,0 +1,6 @@
+MT8516 Pumpkin
+M:	Fabien Parent <fparent@baylibre.com>
+S:	Maintained
+F:	board/mediatek/mt8516
+F:	include/configs/mt8516.h
+F:	configs/mt8516_pumpkin_defconfig
diff --git a/board/mediatek/mt8516/Makefile b/board/mediatek/mt8516/Makefile
new file mode 100644
index 0000000..1d4815d
--- /dev/null
+++ b/board/mediatek/mt8516/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier:	GPL-2.0
+
+obj-y += mt8516_pumpkin.o
diff --git a/board/mediatek/pumpkin/pumpkin.c b/board/mediatek/mt8516/mt8516_pumpkin.c
similarity index 84%
rename from board/mediatek/pumpkin/pumpkin.c
rename to board/mediatek/mt8516/mt8516_pumpkin.c
index 37daf1c..42f3863 100644
--- a/board/mediatek/pumpkin/pumpkin.c
+++ b/board/mediatek/mt8516/mt8516_pumpkin.c
@@ -5,6 +5,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <net.h>
 
 int board_init(void)
 {
@@ -24,5 +25,8 @@
 		}
 	}
 
+	if (CONFIG_IS_ENABLED(USB_ETHER))
+		usb_ether_init();
+
 	return 0;
 }
diff --git a/board/mediatek/pumpkin/MAINTAINERS b/board/mediatek/pumpkin/MAINTAINERS
deleted file mode 100644
index 16beadc..0000000
--- a/board/mediatek/pumpkin/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-Pumpkin
-M:	Fabien Parent <fparent@baylibre.com>
-S:	Maintained
-F:	board/mediatek/pumpkin
-F:	include/configs/pumpkin.h
-F:	configs/pumpkin_defconfig
diff --git a/configs/mt7622_rfb_defconfig b/configs/mt7622_rfb_defconfig
index fa427d8..c12ce5c 100644
--- a/configs/mt7622_rfb_defconfig
+++ b/configs/mt7622_rfb_defconfig
@@ -4,7 +4,10 @@
 CONFIG_SYS_TEXT_BASE=0x41e00000
 CONFIG_SYS_MALLOC_F_LEN=0x4000
 CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=25000000
 CONFIG_DEFAULT_DEVICE_TREE="mt7622-rfb"
+CONFIG_DEBUG_UART=y
 CONFIG_FIT=y
 CONFIG_DEFAULT_FDT_FILE="mt7622-rfb"
 CONFIG_LOGLEVEL=7
@@ -51,8 +54,6 @@
 CONFIG_DM_SPI=y
 CONFIG_MTK_SNOR=y
 CONFIG_SYSRESET_WATCHDOG=y
-CONFIG_TIMER=y
-CONFIG_MTK_TIMER=y
 CONFIG_WDT_MTK=y
 CONFIG_LZO=y
 CONFIG_HEXDUMP=y
diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig
index 2e94f97..cd9f7aa 100644
--- a/configs/mt7629_rfb_defconfig
+++ b/configs/mt7629_rfb_defconfig
@@ -10,7 +10,11 @@
 CONFIG_TARGET_MT7629=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_SPL_STACK_R_ADDR=0x40800000
+CONFIG_SPL_PAYLOAD="u-boot-lzma.img"
+CONFIG_BUILD_TARGET="u-boot-mtk.bin"
 CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb"
+CONFIG_SPL_IMAGE="spl/u-boot-spl-mtk.bin"
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_BOOTDELAY=3
@@ -18,6 +22,7 @@
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_STACK_R=y
 CONFIG_SPL_NOR_SUPPORT=y
 CONFIG_SPL_WATCHDOG_SUPPORT=y
 CONFIG_HUSH_PARSER=y
@@ -87,4 +92,5 @@
 CONFIG_USB_KEYBOARD=y
 CONFIG_WDT_MTK=y
 CONFIG_LZMA=y
+CONFIG_SPL_LZMA=y
 # CONFIG_EFI_LOADER is not set
diff --git a/configs/mt8183_pumpkin_defconfig b/configs/mt8183_pumpkin_defconfig
new file mode 100644
index 0000000..b0bdcb3
--- /dev/null
+++ b/configs/mt8183_pumpkin_defconfig
@@ -0,0 +1,81 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x4c000000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+CONFIG_ENV_OFFSET=0x0
+CONFIG_DM_GPIO=y
+CONFIG_TARGET_MT8183=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=26000000
+# CONFIG_PSCI_RESET is not set
+CONFIG_DEFAULT_DEVICE_TREE="mt8183-pumpkin"
+CONFIG_DEBUG_UART=y
+# CONFIG_ANDROID_BOOT_IMAGE is not set
+CONFIG_FIT=y
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_DEFAULT_FDT_FILE="mt8183-pumpkin"
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTI is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_GO is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_MEMORY is not set
+CONFIG_CMD_CLK=y
+CONFIG_CMD_GPT=y
+# CONFIG_RANDOM_UUID is not set
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_BLOCK_CACHE is not set
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_MMC_ENV_PART=2
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DEVRES=y
+CONFIG_CLK=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x4d000000
+CONFIG_FASTBOOT_BUF_SIZE=0x8000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT=y
+# CONFIG_INPUT is not set
+CONFIG_DM_MMC=y
+# CONFIG_MMC_QUIRKS is not set
+CONFIG_MMC_MTK=y
+CONFIG_DM_ETH=y
+CONFIG_PHY=y
+CONFIG_PHY_MTK_TPHY=y
+CONFIG_BAUDRATE=921600
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_MTK_SERIAL=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_MTU3=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VENDOR_NUM=0x0e8d
+CONFIG_USB_GADGET_PRODUCT_NUM=0x201c
+CONFIG_USB_ETHER=y
+CONFIG_WDT=y
+CONFIG_WDT_MTK=y
+# CONFIG_REGEX is not set
+CONFIG_OF_LIBFDT_OVERLAY=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/pumpkin_defconfig b/configs/mt8516_pumpkin_defconfig
similarity index 100%
rename from configs/pumpkin_defconfig
rename to configs/mt8516_pumpkin_defconfig
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7629.c b/drivers/pinctrl/mediatek/pinctrl-mt7629.c
index 7ce64fd..5d4bec2 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt7629.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7629.c
@@ -201,6 +201,10 @@
 static int mt7629_wf5g_led_pins[] = { 18, };
 static int mt7629_wf5g_led_funcs[] = { 1, };
 
+/* LED for EPHY used as JTAG */
+static int mt7629_ephy_leds_jtag_pins[] = { 12, 13, 14, 15, 16, };
+static int mt7629_ephy_leds_jtag_funcs[] = { 7, 7, 7, 7, 7, };
+
 /* Watchdog */
 static int mt7629_watchdog_pins[] = { 11, };
 static int mt7629_watchdog_funcs[] = { 1, };
@@ -297,6 +301,7 @@
 	PINCTRL_PIN_GROUP("ephy_led2", mt7629_ephy_led2),
 	PINCTRL_PIN_GROUP("ephy_led3", mt7629_ephy_led3),
 	PINCTRL_PIN_GROUP("ephy_led4", mt7629_ephy_led4),
+	PINCTRL_PIN_GROUP("ephy_leds_jtag", mt7629_ephy_leds_jtag),
 	PINCTRL_PIN_GROUP("wf2g_led", mt7629_wf2g_led),
 	PINCTRL_PIN_GROUP("wf5g_led", mt7629_wf5g_led),
 	PINCTRL_PIN_GROUP("watchdog", mt7629_watchdog),
@@ -364,6 +369,7 @@
 static const char *const mt7629_wdt_groups[] = { "watchdog", };
 static const char *const mt7629_wifi_groups[] = { "wf0_5g", "wf0_2g", };
 static const char *const mt7629_flash_groups[] = { "snfi", "spi_nor" };
+static const char *const mt7629_jtag_groups[] = { "ephy_leds_jtag" };
 
 static const struct mtk_function_desc mt7629_functions[] = {
 	{"eth",	mt7629_ethernet_groups, ARRAY_SIZE(mt7629_ethernet_groups)},
@@ -376,6 +382,7 @@
 	{"watchdog", mt7629_wdt_groups, ARRAY_SIZE(mt7629_wdt_groups)},
 	{"wifi", mt7629_wifi_groups, ARRAY_SIZE(mt7629_wifi_groups)},
 	{"flash", mt7629_flash_groups, ARRAY_SIZE(mt7629_flash_groups)},
+	{"jtag", mt7629_jtag_groups, ARRAY_SIZE(mt7629_jtag_groups)},
 };
 
 static struct mtk_pinctrl_soc mt7629_data = {
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index 4dd3f73..3bd23be 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -219,7 +219,7 @@
 {
 	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
 
-	if (!priv->soc->grps[selector].name)
+	if (!priv->soc->pins[selector].name)
 		return mtk_pinctrl_dummy_name;
 
 	return priv->soc->pins[selector].name;
@@ -232,6 +232,19 @@
 	return priv->soc->npins;
 }
 
+static int mtk_get_pin_muxing(struct udevice *dev, unsigned int selector,
+			      char *buf, int size)
+{
+	int val, err;
+
+	err = mtk_hw_get_value(dev, selector, PINCTRL_PIN_REG_MODE, &val);
+	if (err)
+		return err;
+
+	snprintf(buf, size, "Aux Func.%d", val);
+	return 0;
+}
+
 static const char *mtk_get_group_name(struct udevice *dev,
 				      unsigned int selector)
 {
@@ -512,6 +525,7 @@
 const struct pinctrl_ops mtk_pinctrl_ops = {
 	.get_pins_count = mtk_get_pins_count,
 	.get_pin_name = mtk_get_pin_name,
+	.get_pin_muxing = mtk_get_pin_muxing,
 	.get_groups_count = mtk_get_groups_count,
 	.get_group_name = mtk_get_group_name,
 	.get_functions_count = mtk_get_functions_count,
@@ -526,6 +540,8 @@
 	.set_state = pinctrl_generic_set_state,
 };
 
+#if CONFIG_IS_ENABLED(DM_GPIO) || \
+    (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT))
 static int mtk_gpio_get(struct udevice *dev, unsigned int off)
 {
 	int val, err;
@@ -633,12 +649,13 @@
 
 	return 0;
 }
+#endif
 
 int mtk_pinctrl_common_probe(struct udevice *dev,
 			     struct mtk_pinctrl_soc *soc)
 {
 	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
-	int ret;
+	int ret = 0;
 
 	priv->base = dev_read_addr_ptr(dev);
 	if (!priv->base)
@@ -646,9 +663,10 @@
 
 	priv->soc = soc;
 
+#if CONFIG_IS_ENABLED(DM_GPIO) || \
+    (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT))
 	ret = mtk_gpiochip_register(dev);
-	if (ret)
-		return ret;
+#endif
 
-	return 0;
+	return ret;
 }
diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c
index 6d41602..4145d9f 100644
--- a/drivers/serial/serial_mtk.c
+++ b/drivers/serial/serial_mtk.c
@@ -73,74 +73,64 @@
 struct mtk_serial_priv {
 	struct mtk_serial_regs __iomem *regs;
 	u32 clock;
+	bool force_highspeed;
 };
 
 static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud)
 {
-	bool support_clk12m_baud115200;
-	u32 quot, samplecount, realbaud;
+	u32 quot, realbaud, samplecount = 1;
 
-	if ((baud <= 115200) && (priv->clock == 12000000))
-		support_clk12m_baud115200 = true;
-	else
-		support_clk12m_baud115200 = false;
+	/* Special case for low baud clock */
+	if (baud <= 115200 && priv->clock <= 12000000) {
+		writel(3, &priv->regs->highspeed);
 
-	if (baud <= 115200) {
-		writel(0, &priv->regs->highspeed);
-		quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud);
+		quot = DIV_ROUND_CLOSEST(priv->clock, 256 * baud);
+		if (quot == 0)
+			quot = 1;
 
-		if (support_clk12m_baud115200) {
-			writel(3, &priv->regs->highspeed);
-			quot = DIV_ROUND_CLOSEST(priv->clock, 256 * baud);
-			if (quot == 0)
-				quot = 1;
+		samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud);
 
-			samplecount = DIV_ROUND_CLOSEST(priv->clock,
-							quot * baud);
-			if (samplecount != 0) {
-				realbaud = priv->clock / samplecount / quot;
-				if ((realbaud > BAUD_ALLOW_MAX(baud)) ||
-				    (realbaud < BAUD_ALLOW_MIX(baud))) {
-					pr_info("baud %d can't be handled\n",
-						baud);
-				}
-			} else {
-				pr_info("samplecount is 0\n");
-			}
+		realbaud = priv->clock / samplecount / quot;
+		if (realbaud > BAUD_ALLOW_MAX(baud) ||
+		    realbaud < BAUD_ALLOW_MIX(baud)) {
+			pr_info("baud %d can't be handled\n", baud);
 		}
+
+		goto set_baud;
+	}
+
+	if (priv->force_highspeed)
+		goto use_hs3;
+
+	if (baud <= 115200) {
+		writel(0, &priv->regs->highspeed);
+		quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud);
 	} else if (baud <= 576000) {
 		writel(2, &priv->regs->highspeed);
 
 		/* Set to next lower baudrate supported */
 		if ((baud == 500000) || (baud == 576000))
 			baud = 460800;
+
 		quot = DIV_ROUND_UP(priv->clock, 4 * baud);
 	} else {
+use_hs3:
 		writel(3, &priv->regs->highspeed);
+
 		quot = DIV_ROUND_UP(priv->clock, 256 * baud);
+		samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud);
 	}
 
+set_baud:
 	/* set divisor */
 	writel(UART_LCR_WLS_8 | UART_LCR_DLAB, &priv->regs->lcr);
 	writel(quot & 0xff, &priv->regs->dll);
 	writel((quot >> 8) & 0xff, &priv->regs->dlm);
 	writel(UART_LCR_WLS_8, &priv->regs->lcr);
 
-	if (baud > 460800) {
-		u32 tmp;
-
-		tmp = DIV_ROUND_CLOSEST(priv->clock, quot * baud);
-		writel(tmp - 1, &priv->regs->sample_count);
-		writel((tmp - 2) >> 1, &priv->regs->sample_point);
-	} else {
-		writel(0, &priv->regs->sample_count);
-		writel(0xff, &priv->regs->sample_point);
-	}
-
-	if (support_clk12m_baud115200) {
-		writel(samplecount - 1, &priv->regs->sample_count);
-		writel((samplecount - 2) >> 1, &priv->regs->sample_point);
-	}
+	/* set highspeed mode sample count & point */
+	writel(samplecount - 1, &priv->regs->sample_count);
+	writel((samplecount - 2) >> 1, &priv->regs->sample_point);
 }
 
 static int _mtk_serial_putc(struct mtk_serial_priv *priv, const char ch)
@@ -248,6 +238,8 @@
 		return -EINVAL;
 	}
 
+	priv->force_highspeed = dev_read_bool(dev, "mediatek,force-highspeed");
+
 	return 0;
 }
 
diff --git a/include/configs/mt8183.h b/include/configs/mt8183.h
new file mode 100644
index 0000000..8e7afbb
--- /dev/null
+++ b/include/configs/mt8183.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration for MT8183 based boards
+ *
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Fabien Parent <fparent@baylibre.com
+ */
+
+#ifndef __MT8183_H
+#define __MT8183_H
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_MALLOC_LEN		SZ_4M
+
+#define CONFIG_CPU_ARMV8
+#define COUNTER_FREQUENCY		13000000
+
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE	-4
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SYS_NS16550_COM1		0x11005200
+#define CONFIG_SYS_NS16550_CLK		26000000
+
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE + SZ_2M - \
+						 GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_SYS_BOOTM_LEN		SZ_64M
+
+/* Environment settings */
+#include <config_distro_bootcmd.h>
+
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0)
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"scriptaddr=0x40000000\0" \
+	BOOTENV
+
+#endif
diff --git a/include/configs/mt8516.h b/include/configs/mt8516.h
new file mode 100644
index 0000000..a1c5d81
--- /dev/null
+++ b/include/configs/mt8516.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration for Pumpkin board
+ *
+ * Copyright (C) 2019 BayLibre, SAS
+ * Author: Fabien Parent <fparent@baylibre.com
+ */
+
+#ifndef __MT8516_H
+#define __MT8516_H
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_MALLOC_LEN		SZ_4M
+
+#define CONFIG_CPU_ARMV8
+#define COUNTER_FREQUENCY		13000000
+
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE	-4
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SYS_NS16550_COM1		0x11005000
+#define CONFIG_SYS_NS16550_CLK		26000000
+
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE + SZ_2M - \
+						 GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_SYS_BOOTM_LEN		SZ_64M
+
+/* Environment settings */
+#include <config_distro_bootcmd.h>
+
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0)
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"scriptaddr=0x40000000\0" \
+	BOOTENV
+
+#endif
diff --git a/include/configs/pumpkin.h b/include/configs/pumpkin.h
deleted file mode 100644
index 9c52cae..0000000
--- a/include/configs/pumpkin.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Pumpkin board
- *
- * Copyright (C) 2019 BayLibre, SAS
- * Author: Fabien Parent <fparent@baylibre.com
- */
-
-#ifndef __PUMPKIN_H
-#define __PUMPKIN_H
-
-#include <linux/sizes.h>
-
-#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_TEXT_BASE
-#define CONFIG_SYS_MALLOC_LEN		SZ_4M
-
-#define CONFIG_CPU_ARMV8
-#define COUNTER_FREQUENCY		13000000
-
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE	-4
-#define CONFIG_SYS_NS16550_MEM32
-#define CONFIG_SYS_NS16550_COM1		0x11005000
-#define CONFIG_SYS_NS16550_CLK		26000000
-
-#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE + SZ_2M - \
-						 GENERATED_GBL_DATA_SIZE)
-
-#define CONFIG_SYS_BOOTM_LEN		SZ_64M
-
-/* Environment settings */
-#include <config_distro_bootcmd.h>
-
-#define MMCBOOT \
-	"mmcdev=0\0" \
-	"kernel_partition=2\0" \
-	"rootfs_partition=3\0" \
-	"mmc_discover_partition=" \
-		"part start mmc ${mmcdev} ${kernel_partition} kernel_part_addr;" \
-		"part size mmc ${mmcdev} ${kernel_partition} kernel_part_size;\0" \
-	"mmcboot=" \
-		"mmc dev ${mmcdev};" \
-		"run mmc_discover_partition;" \
-		"mmc read ${kerneladdr} ${kernel_part_addr} ${kernel_part_size};" \
-		"setenv bootargs ${bootargs} root=/dev/mmcblk${mmcdev}p${rootfs_partition} rootwait; " \
-		"bootm ${kerneladdr}; \0"
-
-#define CONFIG_EXTRA_ENV_SETTINGS \
-	"kerneladdr=0x4A000000\0" \
-	MMCBOOT \
-	"bootcmd=run mmcboot;\0"
-
-#endif
diff --git a/tools/mtk_image.c b/tools/mtk_image.c
index bde1e5d..418c5fd 100644
--- a/tools/mtk_image.c
+++ b/tools/mtk_image.c
@@ -243,8 +243,13 @@
 	}
 };
 
+/* Indicates whether we're generating or verifying */
+static bool img_gen;
+static uint32_t img_size;
+
 /* Image type selected by user */
 static enum brlyt_img_type hdr_media;
+static uint32_t hdr_offset;
 static int use_lk_hdr;
 static bool is_arm64_image;
 
@@ -275,6 +280,7 @@
 
 	/* User passed arguments from image name */
 	static const char *media = "";
+	static const char *hdr_offs = "";
 	static const char *nandinfo = "";
 	static const char *lk = "";
 	static const char *arm64_param = "";
@@ -317,6 +323,9 @@
 			if (!strcmp(key, "media"))
 				media = val;
 
+			if (!strcmp(key, "hdroffset"))
+				hdr_offs = val;
+
 			if (!strcmp(key, "nandinfo"))
 				nandinfo = val;
 
@@ -359,6 +368,10 @@
 		}
 	}
 
+	/* parse device header offset */
+	if (hdr_offs && hdr_offs[0])
+		hdr_offset = strtoul(hdr_offs, NULL, 0);
+
 	if (arm64_param && arm64_param[0] == '1')
 		is_arm64_image = true;
 
@@ -422,6 +435,7 @@
 static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
 {
 	union gen_boot_header *gbh = (union gen_boot_header *)ptr;
+	uint32_t gfh_offset, total_size, devh_size;
 	struct brom_layout_header *bh;
 	struct gfh_header *gfh;
 	const char *bootmedia;
@@ -453,7 +467,32 @@
 	    le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC))
 		return -1;
 
+	devh_size = sizeof(struct gen_device_header);
+
-	gfh = (struct gfh_header *)(ptr + le32_to_cpu(bh->header_size));
+	if (img_gen) {
+		gfh_offset = devh_size;
+	} else {
+		gfh_offset = le32_to_cpu(bh->header_size);
+
+		if (gfh_offset + sizeof(struct gfh_header) > img_size) {
+			/*
+			 * This may happen if the hdr_offset used to generate
+			 * this image is not zero.
+			 * Since device header size is not fixed, we can't
+			 * cover all possible cases.
+			 * Assuming the image is valid only if the real
+			 * device header size equals to devh_size.
+			 */
+			total_size = le32_to_cpu(bh->total_size);
+
+			if (total_size - gfh_offset > img_size - devh_size)
+				return -1;
+
+			gfh_offset = devh_size;
+		}
+	}
+
+	gfh = (struct gfh_header *)(ptr + gfh_offset);
 
 	if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
 		return -1;
@@ -549,6 +588,8 @@
 	if (le32_to_cpu(lk->magic) == LK_PART_MAGIC)
 		return 0;
 
+	img_size = image_size;
+
 	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
 		return mtk_image_verify_nand_header(ptr, 0);
 	else
@@ -682,8 +723,8 @@
 
 	/* BRLYT header */
 	put_brom_layout_header(&hdr->brlyt, hdr_media);
-	hdr->brlyt.header_size = cpu_to_le32(sizeof(struct gen_device_header));
-	hdr->brlyt.total_size = cpu_to_le32(filesize);
+	hdr->brlyt.header_size = cpu_to_le32(hdr_offset + sizeof(*hdr));
+	hdr->brlyt.total_size = cpu_to_le32(hdr_offset + filesize);
 	hdr->brlyt.header_size_2 = hdr->brlyt.header_size;
 	hdr->brlyt.total_size_2 = hdr->brlyt.total_size;
 
@@ -747,6 +788,9 @@
 		return;
 	}
 
+	img_gen = true;
+	img_size = sbuf->st_size;
+
 	if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
 		mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
 	else