From 83c00ee665b8dde813458b2b07cf97ce8409248d Mon Sep 17 00:00:00 2001 From: Robert Marko 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 --- 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 #include #include +#include #include #include #include @@ -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