--- /dev/null
+From 8621f6d22a9589651c6f25742294dd19a26db430 Mon Sep 17 00:00:00 2001
+From: Robert Marko <robert.marko@sartura.hr>
+Date: Thu, 3 Aug 2023 13:34:13 +0200
+Subject: [PATCH 1/3] arm: mvebu: Espressobin: move FDT fixup into a separate
+ function
+
+Currently, Esspresobin FDT is being fixed up directly in ft_board_setup()
+which makes it hard to add support for any other board to be fixed up.
+
+So, lets just move the FDT fixup code to a separate function and call it
+if compatible matches, there should be no functional change.
+
+Signed-off-by: Robert Marko <robert.marko@sartura.hr>
+---
+ board/Marvell/mvebu_armada-37xx/board.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/board/Marvell/mvebu_armada-37xx/board.c
++++ b/board/Marvell/mvebu_armada-37xx/board.c
+@@ -359,18 +359,14 @@ int last_stage_init(void)
+ #endif
+
+ #ifdef CONFIG_OF_BOARD_SETUP
+-int ft_board_setup(void *blob, struct bd_info *bd)
++static int espressobin_fdt_setup(void *blob)
+ {
+-#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
+ int ret;
+ int spi_off;
+ int parts_off;
+ int part_off;
+
+ /* Fill SPI MTD partitions for Linux kernel on Espressobin */
+- if (!of_machine_is_compatible("globalscale,espressobin"))
+- return 0;
+-
+ spi_off = fdt_node_offset_by_compatible(blob, -1, "jedec,spi-nor");
+ if (spi_off < 0)
+ return 0;
+@@ -455,6 +451,14 @@ int ft_board_setup(void *blob, struct bd
+ return 0;
+ }
+
++ return 0;
++}
++
++int ft_board_setup(void *blob, struct bd_info *bd)
++{
++#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
++ if (of_machine_is_compatible("globalscale,espressobin"))
++ return espressobin_fdt_setup(blob);
+ #endif
+ return 0;
+ }
--- /dev/null
+From 3f8c18894a50fd45b81a807f217893f289500bc6 Mon Sep 17 00:00:00 2001
+From: Robert Marko <robert.marko@sartura.hr>
+Date: Thu, 3 Aug 2023 14:24:31 +0200
+Subject: [PATCH 2/3] arm: mvebu: Espressobin: move network setup into a
+ separate function
+
+Currently, Esspresobin switch is being setup directly in last_stage_init()
+which makes it hard to add support for any other board to be setup.
+
+So, lets just move the switch setup code to a separate function and call it
+if compatible matches, there should be no functional change.
+
+Signed-off-by: Robert Marko <robert.marko@sartura.hr>
+---
+ board/Marvell/mvebu_armada-37xx/board.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/board/Marvell/mvebu_armada-37xx/board.c
++++ b/board/Marvell/mvebu_armada-37xx/board.c
+@@ -300,15 +300,11 @@ static int mii_multi_chip_mode_write(str
+ return 0;
+ }
+
+-/* Bring-up board-specific network stuff */
+-int last_stage_init(void)
++static int espressobin_last_stage_init(void)
+ {
+ struct udevice *bus;
+ ofnode node;
+
+- if (!of_machine_is_compatible("globalscale,espressobin"))
+- return 0;
+-
+ node = ofnode_by_compatible(ofnode_null(), "marvell,orion-mdio");
+ if (!ofnode_valid(node) ||
+ uclass_get_device_by_ofnode(UCLASS_MDIO, node, &bus) ||
+@@ -356,6 +352,16 @@ int last_stage_init(void)
+
+ return 0;
+ }
++
++/* Bring-up board-specific network stuff */
++int last_stage_init(void)
++{
++
++ if (of_machine_is_compatible("globalscale,espressobin"))
++ return espressobin_last_stage_init();
++
++ return 0;
++}
+ #endif
+
+ #ifdef CONFIG_OF_BOARD_SETUP
--- /dev/null
+From 83c00ee665b8dde813458b2b07cf97ce8409248d Mon Sep 17 00:00:00 2001
+From: Robert Marko <robert.marko@sartura.hr>
+Date: Fri, 4 Aug 2023 22:39:06 +0200
+Subject: [PATCH 3/3] arm: mvebu: eDPU: support new board revision
+
+There is a new eDPU revision that uses Marvell 88E6361 switch onboard.
+We can rely on detecting the switch to enable and fixup the Linux DTS
+so a single DTS can be used.
+
+There is currently no support for the 88E6361 switch and thus no working
+networking in U-Boot, so we disable both ports.
+
+Signed-off-by: Robert Marko <robert.marko@sartura.hr>
+---
+ arch/arm/dts/armada-3720-eDPU-u-boot.dtsi | 13 ++-
+ arch/arm/dts/armada-3720-eDPU.dts | 47 ++++++++
+ board/Marvell/mvebu_armada-37xx/board.c | 125 ++++++++++++++++++++++
+ configs/eDPU_defconfig | 2 +
+ 4 files changed, 182 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/dts/armada-3720-eDPU-u-boot.dtsi
++++ b/arch/arm/dts/armada-3720-eDPU-u-boot.dtsi
+@@ -32,14 +32,17 @@
+ bootph-all;
+ };
+
+-ð0 {
+- /* G.hn does not work without additional configuration */
+- status = "disabled";
+-};
+-
+ ð1 {
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
++
++/*
++ * eDPU v2 has a MV88E6361 switch on the MDIO bus and U-boot is used
++ * to patch the Linux DTS if its found so enable MDIO by default.
++ */
++&mdio {
++ status = "okay";
++};
+--- a/arch/arm/dts/armada-3720-eDPU.dts
++++ b/arch/arm/dts/armada-3720-eDPU.dts
+@@ -12,3 +12,50 @@
+ ð0 {
+ phy-mode = "2500base-x";
+ };
++
++/*
++ * External MV88E6361 switch is only available on v2 of the board.
++ * U-Boot will enable the MDIO bus and switch nodes.
++ */
++&mdio {
++ status = "disabled";
++ pinctrl-names = "default";
++ pinctrl-0 = <&smi_pins>;
++
++ /* Actual device is MV88E6361 */
++ switch: switch@0 {
++ compatible = "marvell,mv88e6190";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ label = "cpu";
++ phy-mode = "2500base-x";
++ managed = "in-band-status";
++ ethernet = <ð0>;
++ };
++
++ port@9 {
++ reg = <9>;
++ label = "downlink";
++ phy-mode = "2500base-x";
++ managed = "in-band-status";
++ };
++
++ port@a {
++ reg = <10>;
++ label = "uplink";
++ phy-mode = "2500base-x";
++ managed = "in-band-status";
++ sfp = <&sfp_eth1>;
++ };
++ };
++ };
++};
+--- a/board/Marvell/mvebu_armada-37xx/board.c
++++ b/board/Marvell/mvebu_armada-37xx/board.c
+@@ -13,6 +13,7 @@
+ #include <mmc.h>
+ #include <miiphy.h>
+ #include <phy.h>
++#include <fdt_support.h>
+ #include <asm/global_data.h>
+ #include <asm/io.h>
+ #include <asm/arch/cpu.h>
+@@ -49,6 +50,7 @@ DECLARE_GLOBAL_DATA_PTR;
+ /* Single-chip mode */
+ /* Switch Port Registers */
+ #define MVEBU_SW_LINK_CTRL_REG (1)
++#define MVEBU_SW_PORT_SWITCH_ID (3)
+ #define MVEBU_SW_PORT_CTRL_REG (4)
+ #define MVEBU_SW_PORT_BASE_VLAN (6)
+
+@@ -56,6 +58,8 @@ DECLARE_GLOBAL_DATA_PTR;
+ #define MVEBU_G2_SMI_PHY_CMD_REG (24)
+ #define MVEBU_G2_SMI_PHY_DATA_REG (25)
+
++#define SWITCH_88E6361_PRODUCT_NUMBER 0x2610
++
+ /*
+ * Memory Controller Registers
+ *
+@@ -72,6 +76,27 @@ DECLARE_GLOBAL_DATA_PTR;
+ #define A3700_MC_CTRL2_SDRAM_TYPE_DDR3 2
+ #define A3700_MC_CTRL2_SDRAM_TYPE_DDR4 3
+
++static bool is_edpu_plus(void)
++{
++ struct udevice *bus;
++ ofnode node;
++ int val;
++
++ node = ofnode_by_compatible(ofnode_null(), "marvell,orion-mdio");
++ if (!ofnode_valid(node) ||
++ uclass_get_device_by_ofnode(UCLASS_MDIO, node, &bus) ||
++ device_probe(bus)) {
++ printf("Cannot find MDIO bus\n");
++ return -ENODEV;
++ }
++
++ val = dm_mdio_read(bus, 0x0, MDIO_DEVAD_NONE, MVEBU_SW_PORT_SWITCH_ID);
++ if (val == SWITCH_88E6361_PRODUCT_NUMBER)
++ return true;
++ else
++ return false;
++}
++
+ int board_early_init_f(void)
+ {
+ return 0;
+@@ -353,6 +378,41 @@ static int espressobin_last_stage_init(v
+ return 0;
+ }
+
++static int edpu_plus_last_stage_init(void)
++{
++ struct udevice *dev;
++ int ret;
++
++ if (is_edpu_plus()) {
++ ret = uclass_get_device_by_name(UCLASS_ETH,
++ "ethernet@40000",
++ &dev);
++ if (!ret) {
++ device_remove(dev, DM_REMOVE_NORMAL);
++ device_unbind(dev);
++ }
++
++ /* Currently no networking support on the eDPU+ board */
++ ret = uclass_get_device_by_name(UCLASS_ETH,
++ "ethernet@30000",
++ &dev);
++ if (!ret) {
++ device_remove(dev, DM_REMOVE_NORMAL);
++ device_unbind(dev);
++ }
++ } else {
++ ret = uclass_get_device_by_name(UCLASS_ETH,
++ "ethernet@30000",
++ &dev);
++ if (!ret) {
++ device_remove(dev, DM_REMOVE_NORMAL);
++ device_unbind(dev);
++ }
++ }
++
++ return 0;
++}
++
+ /* Bring-up board-specific network stuff */
+ int last_stage_init(void)
+ {
+@@ -360,6 +420,9 @@ int last_stage_init(void)
+ if (of_machine_is_compatible("globalscale,espressobin"))
+ return espressobin_last_stage_init();
+
++ if (of_machine_is_compatible("methode,edpu"))
++ return edpu_plus_last_stage_init();
++
+ return 0;
+ }
+ #endif
+@@ -460,12 +523,74 @@ static int espressobin_fdt_setup(void *b
+ return 0;
+ }
+
++static int edpu_plus_fdt_setup(void *blob)
++{
++ const char *ports[] = { "downlink", "uplink" };
++ uint8_t mac[ETH_ALEN];
++ const char *path;
++ int i, ret;
++
++ if (is_edpu_plus()) {
++ ret = fdt_set_status_by_compatible(blob,
++ "marvell,orion-mdio",
++ FDT_STATUS_OKAY);
++ if (ret)
++ printf("Failed to enable MDIO!\n");
++
++ ret = fdt_set_status_by_alias(blob,
++ "ethernet1",
++ FDT_STATUS_DISABLED);
++ if (ret)
++ printf("Failed to disable ethernet1!\n");
++
++ path = fdt_get_alias(blob, "ethernet0");
++ if (path)
++ do_fixup_by_path_string(blob, path, "phy-mode", "2500base-x");
++ else
++ printf("Failed to update ethernet0 phy-mode to 2500base-x!\n");
++
++ ret = fdt_set_status_by_compatible(blob,
++ "marvell,mv88e6190",
++ FDT_STATUS_OKAY);
++ if (ret)
++ printf("Failed to enable MV88E6361!\n");
++
++ /*
++ * MAC-s for Uplink and Downlink ports are stored under
++ * non standard variable names, so lets manually fixup the
++ * switch port nodes to have the desired MAC-s.
++ */
++ for (i = 0; i < 2; i++) {
++ if (eth_env_get_enetaddr(ports[i], mac)) {
++ do_fixup_by_prop(blob,
++ "label",
++ ports[i],
++ strlen(ports[i]) + 1,
++ "mac-address",
++ mac, ARP_HLEN, 1);
++
++ do_fixup_by_prop(blob,
++ "label",
++ ports[i],
++ strlen(ports[i]) + 1,
++ "local-mac-address",
++ mac, ARP_HLEN, 1);
++ }
++ }
++ }
++
++ return 0;
++}
++
+ int ft_board_setup(void *blob, struct bd_info *bd)
+ {
+ #ifdef CONFIG_ENV_IS_IN_SPI_FLASH
+ if (of_machine_is_compatible("globalscale,espressobin"))
+ return espressobin_fdt_setup(blob);
+ #endif
++ if (of_machine_is_compatible("methode,edpu"))
++ return edpu_plus_fdt_setup(blob);
++
+ return 0;
+ }
+ #endif
+--- a/configs/eDPU_defconfig
++++ b/configs/eDPU_defconfig
+@@ -17,12 +17,14 @@ CONFIG_DEBUG_UART=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_FIT=y
+ CONFIG_FIT_VERBOSE=y
++CONFIG_OF_BOARD_SETUP=y
+ CONFIG_DISTRO_DEFAULTS=y
+ CONFIG_USE_PREBOOT=y
+ # CONFIG_DISPLAY_CPUINFO is not set
+ # CONFIG_DISPLAY_BOARDINFO is not set
+ CONFIG_DISPLAY_BOARDINFO_LATE=y
+ CONFIG_BOARD_EARLY_INIT_F=y
++CONFIG_LAST_STAGE_INIT=y
+ CONFIG_SYS_MAXARGS=32
+ CONFIG_SYS_PBSIZE=1048
+ # CONFIG_CMD_ELF is not set