From cb71a30857db25ccfa96c144f434a370814e74a7 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Fri, 27 Oct 2023 13:44:11 +1300 Subject: [PATCH 1/4] arm: mvebu: AC5: Use finer grained memory map The ATF implementation for AC5/AC5X ends up with bl31 living in some internal SRAM. This is in the middle of the large MMIO region that we were using. Adjust this to be finer grained blocks based on the address map from the AC5X Family Control and Management Subsystem Functional Datasheet. Signed-off-by: Chris Packham --- arch/arm/mach-mvebu/alleycat5/cpu.c | 66 ++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-mvebu/alleycat5/cpu.c b/arch/arm/mach-mvebu/alleycat5/cpu.c index 8204d962751..0f72ae1709b 100644 --- a/arch/arm/mach-mvebu/alleycat5/cpu.c +++ b/arch/arm/mach-mvebu/alleycat5/cpu.c @@ -16,7 +16,10 @@ DECLARE_GLOBAL_DATA_PTR; -#define RAM_SIZE SZ_1G +#define AC5_PTE_BLOCK_DEVICE \ + (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | \ + PTE_BLOCK_NON_SHARE | \ + PTE_BLOCK_PXN | PTE_BLOCK_UXN) static struct mm_region ac5_mem_map[] = { { @@ -31,30 +34,63 @@ static struct mm_region ac5_mem_map[] = { .phys = 0x00000000, .virt = 0xa0000000, .size = 0x100000, - - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN + .attrs = AC5_PTE_BLOCK_DEVICE, }, { /* MMIO regions */ .phys = 0x100000, .virt = 0x100000, .size = 0x3ff00000, - - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN + .attrs = AC5_PTE_BLOCK_DEVICE, }, { - /* MMIO regions */ .phys = 0x7F000000, .virt = 0x7F000000, - .size = 0x21000000, - - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN + .size = SZ_8M, + .attrs = AC5_PTE_BLOCK_DEVICE, + }, + { + .phys = 0x7F800000, + .virt = 0x7F800000, + .size = SZ_4M, + .attrs = AC5_PTE_BLOCK_DEVICE, + }, + { + .phys = 0x7FC00000, + .virt = 0x7FC00000, + .size = SZ_512K, + .attrs = AC5_PTE_BLOCK_DEVICE, + }, + { + .phys = 0x7FC80000, + .virt = 0x7FC80000, + .size = SZ_512K, + .attrs = AC5_PTE_BLOCK_DEVICE, + }, + { + .phys = 0x7FD00000, + .virt = 0x7FD00000, + .size = SZ_512K, + .attrs = AC5_PTE_BLOCK_DEVICE, + }, + /* ATF region 0x7FE00000-0x7FE20000 not mapped */ + { + .phys = 0x7FE80000, + .virt = 0x7FE80000, + .size = SZ_512K, + .attrs = AC5_PTE_BLOCK_DEVICE, + }, + { + .phys = 0x7FFF0000, + .virt = 0x7FFF0000, + .size = SZ_1M, + .attrs = AC5_PTE_BLOCK_DEVICE, + }, + { + .phys = 0x80000000, + .virt = 0x80000000, + .size = SZ_2G, + .attrs = AC5_PTE_BLOCK_DEVICE, }, { 0, From 9a43eb12db36a5b77d904749dabe9141e67180a1 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 29 Nov 2023 11:11:06 +0100 Subject: [PATCH 2/4] 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 Reviewed-by: Stefan Roese --- board/Marvell/mvebu_armada-37xx/board.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/board/Marvell/mvebu_armada-37xx/board.c b/board/Marvell/mvebu_armada-37xx/board.c index 04124d8014d..1471caa9a68 100644 --- a/board/Marvell/mvebu_armada-37xx/board.c +++ b/board/Marvell/mvebu_armada-37xx/board.c @@ -363,18 +363,14 @@ EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, last_stage_init); #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; @@ -459,6 +455,14 @@ int ft_board_setup(void *blob, struct bd_info *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; } From fde58124c3831cce0e046e0ec7cb4222d72c4fa7 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 29 Nov 2023 11:11:07 +0100 Subject: [PATCH 3/4] 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 Reviewed-by: Stefan Roese --- board/Marvell/mvebu_armada-37xx/board.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/board/Marvell/mvebu_armada-37xx/board.c b/board/Marvell/mvebu_armada-37xx/board.c index 1471caa9a68..f532486b70b 100644 --- a/board/Marvell/mvebu_armada-37xx/board.c +++ b/board/Marvell/mvebu_armada-37xx/board.c @@ -301,14 +301,12 @@ static int mii_multi_chip_mode_write(struct udevice *bus, int dev_smi_addr, return 0; } -/* Bring-up board-specific network stuff */ -static int last_stage_init(void) +static int espressobin_last_stage_init(void) { struct udevice *bus; ofnode node; - if (!CONFIG_IS_ENABLED(DM_MDIO) || - !of_machine_is_compatible("globalscale,espressobin")) + if (!CONFIG_IS_ENABLED(DM_MDIO)) return 0; node = ofnode_by_compatible(ofnode_null(), "marvell,orion-mdio"); @@ -358,8 +356,17 @@ static int last_stage_init(void) return 0; } -EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, last_stage_init); +/* Bring-up board-specific network stuff */ +static int last_stage_init(void) +{ + + if (of_machine_is_compatible("globalscale,espressobin")) + return espressobin_last_stage_init(); + + return 0; +} +EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, last_stage_init); #endif #ifdef CONFIG_OF_BOARD_SETUP From 46471e6c1d58442140259f7e44a5c3e0d6e02351 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 29 Nov 2023 11:11:08 +0100 Subject: [PATCH 4/4] 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 Reviewed-by: Stefan Roese --- 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 | 128 ++++++++++++++++++++++ configs/eDPU_defconfig | 1 + 4 files changed, 184 insertions(+), 5 deletions(-) diff --git a/arch/arm/dts/armada-3720-eDPU-u-boot.dtsi b/arch/arm/dts/armada-3720-eDPU-u-boot.dtsi index cb02b70e54d..c3d450dd83b 100644 --- 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"; +}; diff --git a/arch/arm/dts/armada-3720-eDPU.dts b/arch/arm/dts/armada-3720-eDPU.dts index 57fc698e55d..d6d37a1f6f3 100644 --- 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>; + }; + }; + }; +}; diff --git a/board/Marvell/mvebu_armada-37xx/board.c b/board/Marvell/mvebu_armada-37xx/board.c index f532486b70b..1685b12b847 100644 --- a/board/Marvell/mvebu_armada-37xx/board.c +++ b/board/Marvell/mvebu_armada-37xx/board.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,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) @@ -57,6 +59,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 * @@ -73,6 +77,30 @@ 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; + + if (!CONFIG_IS_ENABLED(DM_MDIO)) + return false; + + 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; @@ -357,6 +385,41 @@ static int espressobin_last_stage_init(void) 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 */ static int last_stage_init(void) { @@ -364,6 +427,9 @@ static 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; } EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, last_stage_init); @@ -465,12 +531,74 @@ static int espressobin_fdt_setup(void *blob) 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 diff --git a/configs/eDPU_defconfig b/configs/eDPU_defconfig index 0b33ff297af..545fd4356a7 100644 --- a/configs/eDPU_defconfig +++ b/configs/eDPU_defconfig @@ -17,6 +17,7 @@ CONFIG_DEBUG_UART=y CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_DISTRO_DEFAULTS=y +CONFIG_OF_BOARD_SETUP=y CONFIG_USE_PREBOOT=y CONFIG_SYS_PBSIZE=1048 # CONFIG_DISPLAY_CPUINFO is not set