Merge tag 'fsl-qoriq-2022-9-6' of https://source.denx.de/u-boot/custodians/u-boot-fsl-qoriq

Reset fixes for p1_p2_rdb_pc
Fix use after free issue fix in fsl_enetc.c
Fix for fsl ddr: make bank_addr_bits reflect actual bits
sl28 board update
diff --git a/Makefile b/Makefile
index 541e942..65aca6e 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 VERSION = 2022
 PATCHLEVEL = 10
 SUBLEVEL =
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME =
 
 # *DOCUMENTATION*
@@ -1001,18 +1001,12 @@
 INPUTS-y += u-boot-with-dtb.bin
 endif
 
-ifeq ($(CONFIG_ARCH_ROCKCHIP),y)
-# On ARM64 this target is produced by binman so we don't need this dep
+ifeq ($(CONFIG_ARCH_ROCKCHIP)$(CONFIG_SPL),yy)
+# Binman image dependencies
 ifeq ($(CONFIG_ARM64),y)
-ifeq ($(CONFIG_SPL),y)
-# TODO: Get binman to generate this too
-INPUTS-y += u-boot-rockchip.bin
-endif
+INPUTS-y += u-boot.itb
 else
-ifeq ($(CONFIG_SPL),y)
-# Generate these inputs for binman which will create the output files
-INPUTS-y += idbloader.img u-boot.img
-endif
+INPUTS-y += u-boot.img
 endif
 endif
 
@@ -1497,30 +1491,7 @@
 				   --pad-to=$(CONFIG_SPL_PAD_TO)
 u-boot-with-spl.bin: $(SPL_IMAGE) $(SPL_PAYLOAD) FORCE
 	$(call if_changed,pad_cat)
-
-ifeq ($(CONFIG_ARCH_ROCKCHIP),y)
-
-# TPL + SPL
-ifeq ($(CONFIG_SPL)$(CONFIG_TPL),yy)
-MKIMAGEFLAGS_u-boot-tpl-rockchip.bin = -n $(CONFIG_SYS_SOC) -T rksd
-tpl/u-boot-tpl-rockchip.bin: tpl/u-boot-tpl.bin FORCE
-	$(call if_changed,mkimage)
-idbloader.img: tpl/u-boot-tpl-rockchip.bin spl/u-boot-spl.bin FORCE
-	$(call if_changed,cat)
-else
-MKIMAGEFLAGS_idbloader.img = -n $(CONFIG_SYS_SOC) -T rksd
-idbloader.img: spl/u-boot-spl.bin FORCE
-	$(call if_changed,mkimage)
-endif
-
-ifeq ($(CONFIG_ARM64),y)
-OBJCOPYFLAGS_u-boot-rockchip.bin = -I binary -O binary \
-	--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff
-u-boot-rockchip.bin: idbloader.img u-boot.itb FORCE
-	$(call if_changed,pad_cat)
-endif # CONFIG_ARM64
 
-endif # CONFIG_ARCH_ROCKCHIP
 
 ifeq ($(CONFIG_ARCH_LPC32XX)$(CONFIG_SPL),yy)
 MKIMAGEFLAGS_lpc32xx-spl.img = -T lpc32xximage -a $(CONFIG_SPL_TEXT_BASE)
@@ -2225,7 +2196,9 @@
 	       lpc32xx-* bl31.c bl31.elf bl31_*.bin image.map tispl.bin* \
 	       idbloader.img flash.bin flash.log defconfig keep-syms-lto.c \
 	       mkimage-out.spl.mkimage mkimage.spl.mkimage imx-boot.map \
-	       itb.fit.fit itb.fit.itb itb.map spl.map
+	       itb.fit.fit itb.fit.itb itb.map spl.map mkimage-out.rom.mkimage \
+	       mkimage.rom.mkimage rom.map simple-bin.map simple-bin-spi.map \
+	       idbloader-spi.img
 
 # Directories & files removed with 'make mrproper'
 MRPROPER_DIRS  += include/config include/generated spl tpl \
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0b72e4f..82cd456 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1974,7 +1974,7 @@
 config ARCH_ROCKCHIP
 	bool "Support Rockchip SoCs"
 	select BLK
-	select BINMAN if SPL_OPTEE || (SPL && !ARM64)
+	select BINMAN if SPL_OPTEE || SPL
 	select DM
 	select DM_GPIO
 	select DM_I2C
diff --git a/arch/arm/dts/px30-u-boot.dtsi b/arch/arm/dts/px30-u-boot.dtsi
index f102b2a..462eaf6 100644
--- a/arch/arm/dts/px30-u-boot.dtsi
+++ b/arch/arm/dts/px30-u-boot.dtsi
@@ -3,6 +3,8 @@
  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
  */
 
+#include "rockchip-u-boot.dtsi"
+
 / {
 	aliases {
 		mmc0 = &emmc;
diff --git a/arch/arm/dts/rk3288-u-boot.dtsi b/arch/arm/dts/rk3288-u-boot.dtsi
index 9eb696b..e411445 100644
--- a/arch/arm/dts/rk3288-u-boot.dtsi
+++ b/arch/arm/dts/rk3288-u-boot.dtsi
@@ -56,7 +56,7 @@
 	};
 };
 
-#ifdef CONFIG_ROCKCHIP_SPI_IMAGE
+#if defined(CONFIG_ROCKCHIP_SPI_IMAGE) && defined(CONFIG_HAS_ROM)
 &binman {
 	rom {
 		filename = "u-boot.rom";
diff --git a/arch/arm/dts/rk3288.dtsi b/arch/arm/dts/rk3288.dtsi
index 9fb6d86..53ee760 100644
--- a/arch/arm/dts/rk3288.dtsi
+++ b/arch/arm/dts/rk3288.dtsi
@@ -109,48 +109,48 @@
 		ports = <&vopl_out>, <&vopb_out>;
 	};
 
-	sdmmc: dwmmc@ff0c0000 {
+	sdmmc: mmc@ff0c0000 {
 		compatible = "rockchip,rk3288-dw-mshc";
 		max-frequency = <150000000>;
 		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
 			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0xff0c0000 0x4000>;
 		status = "disabled";
 	};
 
-	sdio0: dwmmc@ff0d0000 {
+	sdio0: mmc@ff0d0000 {
 		compatible = "rockchip,rk3288-dw-mshc";
 		max-frequency = <150000000>;
 		clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>,
 			 <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0xff0d0000 0x4000>;
 		status = "disabled";
 	};
 
-	sdio1: dwmmc@ff0e0000 {
+	sdio1: mmc@ff0e0000 {
 		compatible = "rockchip,rk3288-dw-mshc";
 		max-frequency = <150000000>;
 		clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>,
 			 <&cru SCLK_SDIO1_DRV>, <&cru SCLK_SDIO1_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0xff0e0000 0x4000>;
 		status = "disabled";
 	};
 
-	emmc: dwmmc@ff0f0000 {
+	emmc: mmc@ff0f0000 {
 		compatible = "rockchip,rk3288-dw-mshc";
 		max-frequency = <150000000>;
 		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
 			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0xff0f0000 0x4000>;
diff --git a/arch/arm/dts/rk3308-u-boot.dtsi b/arch/arm/dts/rk3308-u-boot.dtsi
index 4bfad31..ab5bfc2 100644
--- a/arch/arm/dts/rk3308-u-boot.dtsi
+++ b/arch/arm/dts/rk3308-u-boot.dtsi
@@ -3,6 +3,8 @@
  *(C) Copyright 2019 Rockchip Electronics Co., Ltd
  */
 
+#include "rockchip-u-boot.dtsi"
+
 / {
 	aliases {
 		mmc0 = &emmc;
diff --git a/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi b/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi
index 95f2652..16c3373 100644
--- a/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi
+++ b/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi
@@ -3,6 +3,8 @@
  * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH
  */
 
+#include "rockchip-u-boot.dtsi"
+
 / {
 	chosen {
 		u-boot,spl-boot-order = &sdmmc;
diff --git a/arch/arm/dts/rk3328-u-boot.dtsi b/arch/arm/dts/rk3328-u-boot.dtsi
index 1633558..d4a7540 100644
--- a/arch/arm/dts/rk3328-u-boot.dtsi
+++ b/arch/arm/dts/rk3328-u-boot.dtsi
@@ -3,6 +3,8 @@
  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
  */
 
+#include "rockchip-u-boot.dtsi"
+
 / {
 	aliases {
 		mmc0 = &emmc;
diff --git a/arch/arm/dts/rk3368-u-boot.dtsi b/arch/arm/dts/rk3368-u-boot.dtsi
index 2767c26..811d59a 100644
--- a/arch/arm/dts/rk3368-u-boot.dtsi
+++ b/arch/arm/dts/rk3368-u-boot.dtsi
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/memory/rk3368-dmc.h>
+#include "rockchip-u-boot.dtsi"
 
 / {
 	dmc: dmc@ff610000 {
diff --git a/arch/arm/dts/rk3399-u-boot.dtsi b/arch/arm/dts/rk3399-u-boot.dtsi
index 716b9a4..3c1a15f 100644
--- a/arch/arm/dts/rk3399-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-u-boot.dtsi
@@ -60,7 +60,7 @@
 
 };
 
-#ifdef CONFIG_ROCKCHIP_SPI_IMAGE
+#if defined(CONFIG_ROCKCHIP_SPI_IMAGE) && defined(CONFIG_HAS_ROM)
 &binman {
 	rom {
 		filename = "u-boot.rom";
diff --git a/arch/arm/dts/rk3568-u-boot.dtsi b/arch/arm/dts/rk3568-u-boot.dtsi
index 5a80dda..fa9b6ae 100644
--- a/arch/arm/dts/rk3568-u-boot.dtsi
+++ b/arch/arm/dts/rk3568-u-boot.dtsi
@@ -3,6 +3,8 @@
  * (C) Copyright 2021 Rockchip Electronics Co., Ltd
  */
 
+#include "rockchip-u-boot.dtsi"
+
 / {
 	aliases {
 		mmc0 = &sdhci;
diff --git a/arch/arm/dts/rockchip-u-boot.dtsi b/arch/arm/dts/rockchip-u-boot.dtsi
index eae3ee7..584f21e 100644
--- a/arch/arm/dts/rockchip-u-boot.dtsi
+++ b/arch/arm/dts/rockchip-u-boot.dtsi
@@ -17,13 +17,57 @@
 		filename = "u-boot-rockchip.bin";
 		pad-byte = <0xff>;
 
-		blob {
+		mkimage {
 			filename = "idbloader.img";
+			args = "-n", CONFIG_SYS_SOC, "-T", "rksd";
+#ifdef CONFIG_TPL
+			multiple-data-files;
+
+			u-boot-tpl {
+			};
+#endif
+			u-boot-spl {
+			};
 		};
 
+#ifdef CONFIG_ARM64
+		blob {
+			filename = "u-boot.itb";
+#else
 		u-boot-img {
+#endif
 			offset = <CONFIG_SPL_PAD_TO>;
 		};
 	};
+
+#ifdef CONFIG_ROCKCHIP_SPI_IMAGE
+	simple-bin-spi {
+		filename = "u-boot-rockchip-spi.bin";
+		pad-byte = <0xff>;
+
+		mkimage {
+			filename = "idbloader-spi.img";
+			args = "-n", CONFIG_SYS_SOC, "-T", "rkspi";
+#ifdef CONFIG_TPL
+			multiple-data-files;
+
+			u-boot-tpl {
+			};
+#endif
+			u-boot-spl {
+			};
+		};
+
+#ifdef CONFIG_ARM64
+		blob {
+			filename = "u-boot.itb";
+#else
+		u-boot-img {
+#endif
+			/* Sync with u-boot,spl-payload-offset if present */
+			offset = <CONFIG_SYS_SPI_U_BOOT_OFFS>;
+		};
+	};
+#endif
 };
 #endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index c561a77..b46cea2 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -425,12 +425,10 @@
 
 config ROCKCHIP_SPI_IMAGE
 	bool "Build a SPI image for rockchip"
-	depends on HAS_ROM
 	help
 	  Some Rockchip SoCs support booting from SPI flash. Enable this
-	  option to produce a 4MB SPI-flash image (called u-boot.rom)
-	  containing U-Boot. The image is built by binman. U-Boot sits near
-	  the start of the image.
+	  option to produce a SPI-flash image containing U-Boot. The image
+	  is built by binman. U-Boot sits near the start of the image.
 
 config LNX_KRNL_IMG_TEXT_OFFSET_BASE
 	default SYS_TEXT_BASE
diff --git a/arch/arm/mach-rockchip/rk3308/rk3308.c b/arch/arm/mach-rockchip/rk3308/rk3308.c
index 70fe0d0..dd9109b 100644
--- a/arch/arm/mach-rockchip/rk3308/rk3308.c
+++ b/arch/arm/mach-rockchip/rk3308/rk3308.c
@@ -8,6 +8,7 @@
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <asm/arch/grf_rk3308.h>
+#include <asm/arch-rockchip/bootrom.h>
 #include <asm/arch-rockchip/hardware.h>
 #include <asm/gpio.h>
 #include <debug_uart.h>
@@ -142,6 +143,11 @@
 
 #define GPIO0_A4	4
 
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+	[BROM_BOOTSOURCE_EMMC] = "/mmc@ff490000",
+	[BROM_BOOTSOURCE_SD] = "/mmc@ff480000",
+};
+
 int rk_board_init(void)
 {
 	static struct rk3308_grf * const grf = (void *)GRF_BASE;
diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c
index 01a0559..21db03b 100644
--- a/arch/arm/mach-rockchip/rk3399/rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/rk3399.c
@@ -27,7 +27,7 @@
 #define GRF_BASE	0xff770000
 
 const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
-	[BROM_BOOTSOURCE_EMMC] = "/sdhci@fe330000",
+	[BROM_BOOTSOURCE_EMMC] = "/mmc@fe330000",
 	[BROM_BOOTSOURCE_SPINOR] = "/spi@ff1d0000/flash@0",
 	[BROM_BOOTSOURCE_SD] = "/mmc@fe320000",
 };
@@ -180,9 +180,9 @@
 		u32 boot_device;
 		const char *ofpath;
 	} spl_boot_devices_tbl[] = {
-		{ BOOT_DEVICE_MMC1, "/mmc@fe320000" },
-		{ BOOT_DEVICE_MMC2, "/sdhci@fe330000" },
-		{ BOOT_DEVICE_SPI, "/spi@ff1d0000" },
+		{ BOOT_DEVICE_MMC2, "/mmc@fe320000" },
+		{ BOOT_DEVICE_MMC1, "/mmc@fe330000" },
+		{ BOOT_DEVICE_SPI, "/spi@ff1d0000/flash@0" },
 	};
 
 	for (i = 0; i < ARRAY_SIZE(spl_boot_devices_tbl); ++i)
diff --git a/board/firefly/firefly-rk3308/roc_cc_rk3308.c b/board/firefly/firefly-rk3308/roc_cc_rk3308.c
index 28dcc2a..bdf3cc0 100644
--- a/board/firefly/firefly-rk3308/roc_cc_rk3308.c
+++ b/board/firefly/firefly-rk3308/roc_cc_rk3308.c
@@ -70,7 +70,7 @@
 {
 	unsigned int val;
 
-	if (adc_channel_single_shot("saradc", 1, &val)) {
+	if (adc_channel_single_shot("saradc@ff1e0000", 1, &val)) {
 		printf("%s read adc key val failed\n", __func__);
 		return false;
 	}
diff --git a/configs/lschlv2_defconfig b/configs/lschlv2_defconfig
index e9cc632..cfccfdc 100644
--- a/configs/lschlv2_defconfig
+++ b/configs/lschlv2_defconfig
@@ -60,7 +60,6 @@
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SF_DEFAULT_SPEED=25000000
 CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_DM_ETH=y
 CONFIG_DM_MDIO=y
 CONFIG_MVGBE=y
 CONFIG_MII=y
diff --git a/configs/lsxhl_defconfig b/configs/lsxhl_defconfig
index b83a072..1945b72 100644
--- a/configs/lsxhl_defconfig
+++ b/configs/lsxhl_defconfig
@@ -61,7 +61,6 @@
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SF_DEFAULT_SPEED=25000000
 CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_DM_ETH=y
 CONFIG_DM_MDIO=y
 CONFIG_MVGBE=y
 CONFIG_MII=y
diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst
index b75576c..db3a445 100644
--- a/doc/develop/release_cycle.rst
+++ b/doc/develop/release_cycle.rst
@@ -68,7 +68,7 @@
 
 * U-Boot v2022.10-rc3 was released on Mon 22 August 2022.
 
-.. * U-Boot v2022.10-rc4 was released on Mon 05 September 2022.
+* U-Boot v2022.10-rc4 was released on Mon 05 September 2022.
 
 .. * U-Boot v2022.10-rc5 was released on Mon 19 September 2022.
 
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 7d31a9f..97bf1c6 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -728,6 +728,12 @@
 	u32 div, con;
 
 	switch (clk_id) {
+	case HCLK_SDIO:
+	case SCLK_SDIO:
+		con = readl(&cru->clksel_con[15]);
+		/* dwmmc controller have internal div 2 */
+		div = 2;
+		break;
 	case HCLK_SDMMC:
 	case SCLK_SDMMC:
 		con = readl(&cru->clksel_con[16]);
@@ -750,37 +756,46 @@
 		return DIV_TO_RATE(GPLL_HZ, div);
 }
 
+static void rk3399_dwmmc_set_clk(struct rockchip_cru *cru,
+				 unsigned int con, ulong set_rate)
+{
+	/* Select clk_sdmmc source from GPLL by default */
+	/* mmc clock defaulg div 2 internal, provide double in cru */
+	int src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate);
+
+	if (src_clk_div > 128) {
+		/* use 24MHz source for 400KHz clock */
+		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
+		assert(src_clk_div - 1 < 128);
+		rk_clrsetreg(&cru->clksel_con[con],
+			     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
+			     CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
+			     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
+	} else {
+		rk_clrsetreg(&cru->clksel_con[con],
+			     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
+			     CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
+			     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
+	}
+}
+
 static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru,
 				ulong clk_id, ulong set_rate)
 {
-	int src_clk_div;
-	int aclk_emmc = 198 * MHz;
-
 	switch (clk_id) {
+	case HCLK_SDIO:
+	case SCLK_SDIO:
+		rk3399_dwmmc_set_clk(cru, 15, set_rate);
+		break;
 	case HCLK_SDMMC:
 	case SCLK_SDMMC:
-		/* Select clk_sdmmc source from GPLL by default */
-		/* mmc clock defaulg div 2 internal, provide double in cru */
-		src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate);
-
-		if (src_clk_div > 128) {
-			/* use 24MHz source for 400KHz clock */
-			src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
-			assert(src_clk_div - 1 < 128);
-			rk_clrsetreg(&cru->clksel_con[16],
-				     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
-				     CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
-				     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
-		} else {
-			rk_clrsetreg(&cru->clksel_con[16],
-				     CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
-				     CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
-				     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
-		}
+		rk3399_dwmmc_set_clk(cru, 16, set_rate);
 		break;
-	case SCLK_EMMC:
+	case SCLK_EMMC: {
+		int aclk_emmc = 198 * MHz;
 		/* Select aclk_emmc source from GPLL */
-		src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc);
+		int src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc);
+
 		assert(src_clk_div - 1 < 32);
 
 		rk_clrsetreg(&cru->clksel_con[21],
@@ -797,6 +812,7 @@
 			     CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
 			     (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
 		break;
+	}
 	default:
 		return -EINVAL;
 	}
@@ -918,6 +934,8 @@
 	switch (clk->id) {
 	case 0 ... 63:
 		return 0;
+	case HCLK_SDIO:
+	case SCLK_SDIO:
 	case HCLK_SDMMC:
 	case SCLK_SDMMC:
 	case SCLK_EMMC:
@@ -992,6 +1010,8 @@
 	case PCLK_PERILP1:
 		return 0;
 
+	case HCLK_SDIO:
+	case SCLK_SDIO:
 	case HCLK_SDMMC:
 	case SCLK_SDMMC:
 	case SCLK_EMMC:
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index c0a06dc..cbf502b 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -85,7 +85,7 @@
 	int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
 				   struct rk3399_sdram_params *sdram);
 	int (*set_rate_index)(struct dram_info *dram,
-			      struct rk3399_sdram_params *params);
+			      struct rk3399_sdram_params *params, u32 ctl_fn);
 	void (*modify_param)(const struct chan_info *chan,
 			     struct rk3399_sdram_params *params);
 	struct rk3399_sdram_params *
@@ -1644,7 +1644,8 @@
 }
 
 static int switch_to_phy_index1(struct dram_info *dram,
-				struct rk3399_sdram_params *params)
+				struct rk3399_sdram_params *params,
+				u32 unused)
 {
 	u32 channel;
 	u32 *denali_phy;
@@ -2539,26 +2540,25 @@
 }
 
 static int lpddr4_set_rate(struct dram_info *dram,
-			   struct rk3399_sdram_params *params)
+			    struct rk3399_sdram_params *params,
+			    u32 ctl_fn)
 {
-	u32 ctl_fn;
 	u32 phy_fn;
 
-	for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
-		phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
+	phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
 
-		lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
-		lpddr4_set_ctl(dram, params, ctl_fn,
-			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
+	lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
+	lpddr4_set_ctl(dram, params, ctl_fn,
+		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
 
-		if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
-			printf("%s: change freq to %d mhz %d, %d\n", __func__,
-			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq,
-			       ctl_fn, phy_fn);
-	}
+	if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
+		printf("%s: change freq to %dMHz %d, %d\n", __func__,
+		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
+		       ctl_fn, phy_fn);
 
 	return 0;
 }
+
 #endif /* CONFIG_RAM_RK3399_LPDDR4 */
 
 /* CS0,n=1
@@ -2955,6 +2955,12 @@
 		params->ch[ch].cap_info.rank = rank;
 	}
 
+#if defined(CONFIG_RAM_RK3399_LPDDR4)
+	/* LPDDR4 needs to be trained at 400MHz */
+	lpddr4_set_rate(dram, params, 0);
+	params->base.ddr_freq = dfs_cfgs_lpddr4[0].base.ddr_freq / MHz;
+#endif
+
 	params->base.num_channels = 0;
 	for (channel = 0; channel < 2; channel++) {
 		const struct chan_info *chan = &dram->chan[channel];
@@ -2964,8 +2970,6 @@
 		if (cap_info->rank == 0) {
 			clear_channel_params(params, 1);
 			continue;
-		} else {
-			params->base.num_channels++;
 		}
 
 		if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) {
@@ -2991,6 +2995,8 @@
 			printf("no ddrconfig find, Cap not support!\n");
 			continue;
 		}
+
+		params->base.num_channels++;
 		set_ddrconfig(chan, params, channel, cap_info->ddrconfig);
 		set_cap_relate_config(chan, params, channel);
 	}
@@ -3005,7 +3011,9 @@
 	params->base.stride = calculate_stride(params);
 	dram_all_config(dram, params);
 
-	dram->ops->set_rate_index(dram, params);
+	ret = dram->ops->set_rate_index(dram, params, 1);
+	if (ret)
+		return ret;
 
 	debug("Finish SDRAM initialization...\n");
 	return 0;
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index c5e8942..f505722 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -654,12 +654,7 @@
 CONFIG_SYS_FM1_DTSEC5_PHY_ADDR
 CONFIG_SYS_FM1_QSGMII11_PHY_ADDR
 CONFIG_SYS_FM1_QSGMII21_PHY_ADDR
-CONFIG_SYS_FM2_10GEC1_PHY_ADDR
 CONFIG_SYS_FM2_CLK
-CONFIG_SYS_FM2_DTSEC1_PHY_ADDR
-CONFIG_SYS_FM2_DTSEC2_PHY_ADDR
-CONFIG_SYS_FM2_DTSEC3_PHY_ADDR
-CONFIG_SYS_FM2_DTSEC4_PHY_ADDR
 CONFIG_SYS_FM_MURAM_SIZE
 CONFIG_SYS_FPGAREG_DIPSW
 CONFIG_SYS_FPGAREG_FREQ
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index b3613d7..18bd328 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -1175,6 +1175,9 @@
     - args: Arguments to pass
     - data-to-imagename: Indicates that the -d data should be passed in as
       the image name also (-n)
+    - multiple-data-files: boolean to tell binman to pass all files as
+      datafiles to mkimage instead of creating a temporary file the result
+      of datafiles concatenation
 
 The data passed to mkimage via the -d flag is collected from subnodes of the
 mkimage node, e.g.::
@@ -1205,6 +1208,25 @@
         };
     };
 
+To pass all datafiles untouched to mkimage::
+
+    mkimage {
+        args = "-n rk3399 -T rkspi";
+        multiple-data-files;
+
+        u-boot-tpl {
+        };
+
+        u-boot-spl {
+        };
+    };
+
+This calls mkimage to create a Rockchip RK3399-specific first stage
+bootloader, made of TPL+SPL. Since this first stage bootloader requires to
+align the TPL and SPL but also some weird hacks that is handled by mkimage
+directly, binman is told to not perform the concatenation of datafiles prior
+to passing the data to mkimage.
+
 To use CONFIG options in the arguments, use a string list instead, as in
 this example which also produces four arguments::
 
diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py
index ddbd9ce..c2288c4 100644
--- a/tools/binman/etype/mkimage.py
+++ b/tools/binman/etype/mkimage.py
@@ -18,11 +18,16 @@
         - args: Arguments to pass
         - data-to-imagename: Indicates that the -d data should be passed in as
           the image name also (-n)
+        - multiple-data-files: boolean to tell binman to pass all files as
+          datafiles to mkimage instead of creating a temporary file the result
+          of datafiles concatenation
+        - filename: filename of output binary generated by mkimage
 
     The data passed to mkimage via the -d flag is collected from subnodes of the
     mkimage node, e.g.::
 
         mkimage {
+            filename = "imximage.bin";
             args = "-n test -T imximage";
 
             u-boot-spl {
@@ -35,8 +40,9 @@
         mkimage -d <data_file> -n test -T imximage <output_file>
 
     The output from mkimage then becomes part of the image produced by
-    binman. If you need to put multiple things in the data file, you can use
-    a section, or just multiple subnodes like this::
+    binman but also is written into `imximage.bin` file. If you need to put
+    multiple things in the data file, you can use a section, or just multiple
+    subnodes like this::
 
         mkimage {
             args = "-n test -T imximage";
@@ -51,6 +57,25 @@
     Note that binman places the contents (here SPL and TPL) into a single file
     and passes that to mkimage using the -d option.
 
+	To pass all datafiles untouched to mkimage::
+
+		mkimage {
+			args = "-n rk3399 -T rkspi";
+			multiple-data-files;
+
+			u-boot-tpl {
+			};
+
+			u-boot-spl {
+			};
+		};
+
+	This calls mkimage to create a Rockchip RK3399-specific first stage
+	bootloader, made of TPL+SPL. Since this first stage bootloader requires to
+	align the TPL and SPL but also some weird hacks that is handled by mkimage
+	directly, binman is told to not perform the concatenation of datafiles prior
+	to passing the data to mkimage.
+
     To use CONFIG options in the arguments, use a string list instead, as in
     this example which also produces four arguments::
 
@@ -96,8 +121,10 @@
     """
     def __init__(self, section, etype, node):
         super().__init__(section, etype, node)
+        self._multiple_data_files = fdt_util.GetBool(self._node, 'multiple-data-files')
         self._mkimage_entries = OrderedDict()
         self._imagename = None
+        self._filename = fdt_util.GetString(self._node, 'filename')
         self.align_default = None
 
     def ReadNode(self):
@@ -122,16 +149,27 @@
     def ObtainContents(self):
         # Use a non-zero size for any fake files to keep mkimage happy
         # Note that testMkimageImagename() relies on this 'mkimage' parameter
-        data, input_fname, uniq = self.collect_contents_to_file(
-            self._mkimage_entries.values(), 'mkimage', 1024)
-        if data is None:
-            return False
+        fake_size = 1024
+        if self._multiple_data_files:
+            fnames = []
+            uniq = self.GetUniqueName()
+            for entry in self._mkimage_entries.values():
+                if not entry.ObtainContents(fake_size=fake_size):
+                    return False
+                fnames.append(tools.get_input_filename(entry.GetDefaultFilename()))
+            input_fname = ":".join(fnames)
+        else:
+            data, input_fname, uniq = self.collect_contents_to_file(
+                self._mkimage_entries.values(), 'mkimage', fake_size)
+            if data is None:
+                return False
         if self._imagename:
             image_data, imagename_fname, _ = self.collect_contents_to_file(
                 [self._imagename], 'mkimage-n', 1024)
             if image_data is None:
                 return False
-        output_fname = tools.get_output_filename('mkimage-out.%s' % uniq)
+        outfile = self._filename if self._filename else 'mkimage-out.%s' % uniq
+        output_fname = tools.get_output_filename(outfile)
 
         args = ['-d', input_fname]
         if self._data_to_imagename:
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 5422940..3ced14b 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5898,6 +5898,36 @@
         self.assertIn("Node '/binman/u-boot-dtb': The zstd compression "
                       "requires a length header", str(e.exception))
 
+    def testMkimageMultipleDataFiles(self):
+        """Test passing multiple files to mkimage in a mkimage entry"""
+        data = self._DoReadFile('252_mkimage_mult_data.dts')
+        # Size of files are packed in their 4B big-endian format
+        expect = struct.pack('>I', len(U_BOOT_TPL_DATA))
+        expect += struct.pack('>I', len(U_BOOT_SPL_DATA))
+        # Size info is always followed by a 4B zero value.
+        expect += tools.get_bytes(0, 4)
+        expect += U_BOOT_TPL_DATA
+        # All but last files are 4B-aligned
+        align_pad = len(U_BOOT_TPL_DATA) % 4
+        if align_pad:
+            expect += tools.get_bytes(0, align_pad)
+        expect += U_BOOT_SPL_DATA
+        self.assertEqual(expect, data[-len(expect):])
+
+    def testMkimageMultipleNoContent(self):
+        """Test passing multiple data files to mkimage with one data file having no content"""
+        with self.assertRaises(ValueError) as exc:
+            self._DoReadFile('253_mkimage_mult_no_content.dts')
+        self.assertIn('Could not complete processing of contents',
+                      str(exc.exception))
+
+    def testMkimageFilename(self):
+        """Test using mkimage to build a binary with a filename"""
+        retcode = self._DoTestFile('254_mkimage_filename.dts')
+        self.assertEqual(0, retcode)
+        fname = tools.get_output_filename('mkimage-test.bin')
+        self.assertTrue(os.path.exists(fname))
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/252_mkimage_mult_data.dts b/tools/binman/test/252_mkimage_mult_data.dts
new file mode 100644
index 0000000..a092bc3
--- /dev/null
+++ b/tools/binman/test/252_mkimage_mult_data.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		mkimage {
+			args = "-T script";
+			multiple-data-files;
+
+			u-boot-tpl {
+			};
+
+			u-boot-spl {
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/253_mkimage_mult_no_content.dts b/tools/binman/test/253_mkimage_mult_no_content.dts
new file mode 100644
index 0000000..dd65666
--- /dev/null
+++ b/tools/binman/test/253_mkimage_mult_no_content.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		mkimage {
+			args = "-T script";
+			multiple-data-files;
+
+			_testing {
+				return-unknown-contents;
+			};
+
+			u-boot-spl {
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/254_mkimage_filename.dts b/tools/binman/test/254_mkimage_filename.dts
new file mode 100644
index 0000000..4483790
--- /dev/null
+++ b/tools/binman/test/254_mkimage_filename.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		mkimage {
+			filename = "mkimage-test.bin";
+			args = "-T script";
+
+			u-boot-spl {
+			};
+		};
+	};
+};