uboot-mvebu: eDPU: add support for version with external switch
authorRobert Marko <robert.marko@sartura.hr>
Fri, 18 Aug 2023 10:22:29 +0000 (12:22 +0200)
committerRobert Marko <robert.marko@sartura.hr>
Tue, 19 Sep 2023 10:12:17 +0000 (12:12 +0200)
New revision of eDPU uses an Marvell MV88E6361 switch to connect the SFP
cage and G.hn IC instead of connecting them directly to the ethernet
controllers.

In order to use the same image for both boards, U-Boot is responsible for
detecting the revision and enabling/disabling DTS nodes.
So, to make it easy for users, lets add the pending U-Boot patches to build
in OpenWrt.

Signed-off-by: Robert Marko <robert.marko@sartura.hr>
package/boot/uboot-mvebu/patches/0001-arm-mvebu-Espressobin-move-FDT-fixup-into-a-separate.patch [new file with mode: 0644]
package/boot/uboot-mvebu/patches/0002-arm-mvebu-Espressobin-move-network-setup-into-a-sepa.patch [new file with mode: 0644]
package/boot/uboot-mvebu/patches/0003-arm-mvebu-eDPU-support-new-board-revision.patch [new file with mode: 0644]

diff --git a/package/boot/uboot-mvebu/patches/0001-arm-mvebu-Espressobin-move-FDT-fixup-into-a-separate.patch b/package/boot/uboot-mvebu/patches/0001-arm-mvebu-Espressobin-move-FDT-fixup-into-a-separate.patch
new file mode 100644 (file)
index 0000000..59bdc38
--- /dev/null
@@ -0,0 +1,54 @@
+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;
+ }
diff --git a/package/boot/uboot-mvebu/patches/0002-arm-mvebu-Espressobin-move-network-setup-into-a-sepa.patch b/package/boot/uboot-mvebu/patches/0002-arm-mvebu-Espressobin-move-network-setup-into-a-sepa.patch
new file mode 100644 (file)
index 0000000..175deb3
--- /dev/null
@@ -0,0 +1,53 @@
+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
diff --git a/package/boot/uboot-mvebu/patches/0003-arm-mvebu-eDPU-support-new-board-revision.patch b/package/boot/uboot-mvebu/patches/0003-arm-mvebu-eDPU-support-new-board-revision.patch
new file mode 100644 (file)
index 0000000..c27549e
--- /dev/null
@@ -0,0 +1,297 @@
+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;
+ };
+-&eth0 {
+-      /* G.hn does not work without additional configuration */
+-      status = "disabled";
+-};
+-
+ &eth1 {
+       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 @@
+ &eth0 {
+       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 = <&eth0>;
++                      };
++
++                      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