[PATCH v2 9/9] ARM: add Novarq Tactical 1000 board
Oleksij Rempel <[email protected]>
| Newsgroups | org.infradead.lists.barebox |
|---|---|
| Message-ID | <[email protected]> |
Add board support for the Novarq Tactical 1000, a switch built around the Microchip LAN9696: 24 1G ports, 4 10G SFP+ uplinks, booted as BL33 from TF-A. This covers the pre-production revision, which is laid out as a close copy of the Microchip EV23X71A reference design. It is therefore described by including the upstream EV23X71A device tree and correcting the identity on top of it, rather than by a board device tree of its own. The compatible is novarq,tactical-1000-alpha with microchip,ev23x71a kept as a fallback: the board is not made by Microchip and is not an EV23X71A, but it is electrically that design. The shipping Tactical 1000 differs - fans, an RTC and more - and has a device tree of its own. That one is not upstream yet; supporting the board means a separate board entry including it, once it lands in Linux and reaches the dts/ snapshot. The qspi controllers the board boots from are not in the dts/ snapshot and are not upstream yet, so they are carried in arch/arm/dts/lan9691-bb.dtsi until a sync brings them in. Two things are not settled and are marked as such in the code: the hardware used for bring-up is pre-production, and the 896 MiB of DDR is u-boot's compile-time fallback rather than a figure read from this board. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Oleksij Rempel <[email protected]> --- Link to v1: https://lore.barebox.org/barebox/[email protected]/ Changes v2: - drop the &usart0 override: the included upstream board dts already sets status = "okay" with the pinctrl, so it changed nothing - drop the &sgpio block: it was character for character the same as the node in the included upstream board dts, and would have drifted apart on the next dts/ sync - lan9691-bb.dtsi: explain what the file is for and when it can be dropped, and fix the snapshot path in the comment - board.c: drop the unused bootsource.h include - Kconfig: extend the help text, checkpatch asked for a fuller paragraph - lan9691-bb.dtsi: include dt-bindings/interrupt-controller/arm-gic.h for GIC_SPI and IRQ_TYPE_LEVEL_HIGH instead of relying on the upstream dts having pulled it in first - lan9696-ev23x71a.dts: this file is new barebox code, so carry my own copyright rather than the one from the upstream dts it includes - drop the heartbeat trigger on led-sfp1-green: that is the front panel link LED for SFP port 0, and blinking it reads as link activity - drop the sdmmc nodes and the &sdmmc0 override. eMMC support is not verified on this board yet, so it is held back together with the atmel-sdhci patch rather than shipped untested - enable the board in multi_v8_defconfig instead of adding a SoC specific defconfig, so the series is actually built by an in-tree configuration - have MACH_MICROCHIP_LAN9696_EV23X71A select the clk, pinctrl, sgpio and reset drivers the board cannot come up without. They are selected from the board symbol rather than ARCH_MICROCHIP because ARCH_MICROCHIP is introduced before any of those drivers exist, and selecting unknown symbols would break bisect - lowlevel.c: say where the 896 MiB comes from. It is u-boot's compile-time fallback LAN969X_DDR_SIZE_DEF, not a measured figure, and u-boot asks TF-A first. Querying TF-A is still to be done - lan9691-bb.dtsi: add the copyright line it was missing - name the board what it is. v1 and the first v2 called this MACH_MICROCHIP_LAN9696_EV23X71A and bound to "microchip,ev23x71a", but the board is not manufactured by Microchip. It is a pre-production Novarq Tactical 1000 built on that reference design. Renamed the symbol, board directory, dts, entry point and image, and gave the device tree its own model and compatible, keeping microchip,ev23x71a as a fallback --- arch/arm/Kconfig | 21 ++++++++ arch/arm/boards/Makefile | 1 + arch/arm/boards/novarq-tactical-1000/Makefile | 4 ++ arch/arm/boards/novarq-tactical-1000/board.c | 45 ++++++++++++++++ .../boards/novarq-tactical-1000/lowlevel.c | 52 +++++++++++++++++++ arch/arm/configs/multi_v8_defconfig | 4 ++ arch/arm/dts/Makefile | 1 + arch/arm/dts/lan9691-bb.dtsi | 48 +++++++++++++++++ arch/arm/dts/novarq-tactical-1000.dts | 51 ++++++++++++++++++ images/Makefile | 1 + images/Makefile.microchip | 9 ++++ 11 files changed, 237 insertions(+) create mode 100644 arch/arm/boards/novarq-tactical-1000/Makefile create mode 100644 arch/arm/boards/novarq-tactical-1000/board.c create mode 100644 arch/arm/boards/novarq-tactical-1000/lowlevel.c create mode 100644 arch/arm/dts/lan9691-bb.dtsi create mode 100644 arch/arm/dts/novarq-tactical-1000.dts create mode 100644 images/Makefile.microchip diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index aed6084bef07..ef26ceda8b21 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -309,6 +309,27 @@ source "arch/arm/mach-tegra/Kconfig" source "arch/arm/mach-zynq/Kconfig" source "arch/arm/mach-zynqmp/Kconfig" +if ARCH_MICROCHIP + +config MACH_NOVARQ_TACTICAL_1000 + bool "Novarq Tactical 1000" + select COMMON_CLK_LAN966X + select PINCTRL_OCELOT + select GPIO_MICROCHIP_SGPIO + select RESET_CONTROLLER + select RESET_MICROCHIP_SPARX5 + help + Support for the Novarq Tactical 1000, a switch built around the + Microchip LAN9696: 24 1G ports plus 4 10G SFP+ uplinks, an ARM64 + CPU and AT91/SAMA5 compatible peripherals. barebox runs as the + BL33 payload started by TF-A and can update itself into the FIP + image on the QSPI NOR. + + This covers the pre-production revision, which is laid out as a + close copy of the Microchip EV23X71A reference design. + +endif # ARCH_MICROCHIP + config BOARD_ARM_VIRT bool select BOARD_GENERIC_DT diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index fbcf14748ad7..14652fba0206 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -117,6 +117,7 @@ obj-$(CONFIG_MACH_SAMA5D27_GIANTBOARD) += sama5d27-giantboard/ obj-$(CONFIG_MACH_SAMA5D27_SOM1) += sama5d27-som1/ obj-$(CONFIG_MACH_SAMA5D3_XPLAINED) += sama5d3_xplained/ obj-$(CONFIG_MACH_MICROCHIP_KSZ9477_EVB) += microchip-ksz9477-evb/ +obj-$(CONFIG_MACH_NOVARQ_TACTICAL_1000) += novarq-tactical-1000/ obj-$(CONFIG_MACH_MICROCHIP_SAMA5D3_EDS) += microchip-sama5d3-eds/ obj-$(CONFIG_MACH_SAMA5D4_XPLAINED) += sama5d4_xplained/ obj-$(CONFIG_MACH_SAMA5D4_WIFX) += sama5d4_wifx/ diff --git a/arch/arm/boards/novarq-tactical-1000/Makefile b/arch/arm/boards/novarq-tactical-1000/Makefile new file mode 100644 index 000000000000..5678718188b9 --- /dev/null +++ b/arch/arm/boards/novarq-tactical-1000/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only + +lwl-y += lowlevel.o +obj-y += board.o diff --git a/arch/arm/boards/novarq-tactical-1000/board.c b/arch/arm/boards/novarq-tactical-1000/board.c new file mode 100644 index 000000000000..f339ee5d271e --- /dev/null +++ b/arch/arm/boards/novarq-tactical-1000/board.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Oleksij Rempel <[email protected]> + * + * Novarq Tactical 1000, a LAN9696 based 24x1G + 4x10G switch. + * + * This supports the pre-production revision, which is built as a close + * copy of the Microchip EV23X71A reference design - hence the + * novarq,tactical-1000-alpha compatible and a device tree that includes + * the upstream EV23X71A one. The board is not manufactured by Microchip + * and is not an EV23X71A, so it does not claim to be one, but it is + * electrically that design. + * + * The shipping Tactical 1000 differs (fans, RTC, ...) and has a device + * tree of its own. Supporting that board means adding a board entry + * which includes it, not extending this one. + */ + +#include <bbu.h> +#include <common.h> +#include <deep-probe.h> +#include <init.h> + +static int tactical1000_probe(struct device *dev) +{ + bbu_register_std_file_update("nor", BBU_HANDLER_FLAG_DEFAULT, + "/dev/m25p0", filetype_fip); + return 0; +} + +static const struct of_device_id tactical1000_of_match[] = { + { + .compatible = "novarq,tactical-1000-alpha", + }, + { /* sentinel */ }, +}; + +static struct driver tactical1000_board_driver = { + .name = "board-novarq-tactical-1000", + .probe = tactical1000_probe, + .of_compatible = tactical1000_of_match, +}; +coredevice_platform_driver(tactical1000_board_driver); + +BAREBOX_DEEP_PROBE_ENABLE(tactical1000_of_match); diff --git a/arch/arm/boards/novarq-tactical-1000/lowlevel.c b/arch/arm/boards/novarq-tactical-1000/lowlevel.c new file mode 100644 index 000000000000..0ac4b40dbc99 --- /dev/null +++ b/arch/arm/boards/novarq-tactical-1000/lowlevel.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Oleksij Rempel <[email protected]> + */ + +#include <common.h> +#include <linux/sizes.h> +#include <asm/barebox-arm.h> + +extern char __dtb_z_novarq_tactical_1000_start[]; + +/* + * Novarq Tactical 1000 memory map. + * + * DDR is mapped at 0x60000000. The 896 MiB used here is deliberately + * conservative and is NOT a measured figure for this board: it is + * u-boot's compile-time default LAN969X_DDR_SIZE_DEF from + * include/configs/lan969x.h, whose comment attributes the missing + * eighth of the gigabyte to ECC. LAN969X uses in-line ECC, which does + * consume roughly an eighth of the array, so the ratio is plausible, + * but nothing here has been checked against the fitted parts. + * + * u-boot itself only uses that constant as a fallback: dram_init() + * asks TF-A via tfa_get_dram_size() first. Under-reporting is safe - + * barebox simply uses less of the array - so this is fine for + * bring-up, but querying TF-A for the real size is the correct fix and + * is still to be done. + * + * The top 2 MiB is kept out of the region handed to barebox. There is + * no derivation behind that number: it is what worked when starting + * barebox as a second stage after u-boot, and without it the handover + * did not come up. + * + * FIXME: find out whether this is still needed, and whether 2 MiB is + * the right amount, on a system running TF-A plus barebox only. + */ +#define TACTICAL1000_DRAM_BASE UL(0x60000000) +#define TACTICAL1000_DRAM_SIZE (896 * SZ_1M) +#define TACTICAL1000_UBOOT_RESERVE SZ_2M +#define TACTICAL1000_DRAM_USABLE (TACTICAL1000_DRAM_SIZE - TACTICAL1000_UBOOT_RESERVE) +#define TACTICAL1000_DRAM_USABLE_END (TACTICAL1000_DRAM_BASE + TACTICAL1000_DRAM_USABLE) + +ENTRY_FUNCTION_WITHSTACK(start_novarq_tactical_1000, + TACTICAL1000_DRAM_USABLE_END, r0, r1, r2) +{ + arm_cpu_lowlevel_init(); + relocate_to_current_adr(); + setup_c(); + + barebox_arm_entry(TACTICAL1000_DRAM_BASE, TACTICAL1000_DRAM_USABLE, + runtime_address(__dtb_z_novarq_tactical_1000_start)); +} diff --git a/arch/arm/configs/multi_v8_defconfig b/arch/arm/configs/multi_v8_defconfig index fad10669e114..7b1ddea96e8a 100644 --- a/arch/arm/configs/multi_v8_defconfig +++ b/arch/arm/configs/multi_v8_defconfig @@ -2,9 +2,11 @@ CONFIG_ARCH_ARM64_VIRT=y CONFIG_ARCH_BCM283X=y CONFIG_ARCH_IMX=y CONFIG_ARCH_K3=y +CONFIG_ARCH_MICROCHIP=y CONFIG_ARCH_SUNXI=y CONFIG_ARCH_ROCKCHIP=y CONFIG_ARCH_ZYNQMP=y +CONFIG_MACH_NOVARQ_TACTICAL_1000=y CONFIG_MACH_RPI3=y CONFIG_MACH_RPI_CM3=y CONFIG_MACH_RPI4=y @@ -197,6 +199,8 @@ CONFIG_NET_USB_SMSC95XX=y CONFIG_NET_USB_RTL8152=y CONFIG_DRIVER_SPI_FSL_QUADSPI=y CONFIG_DRIVER_SPI_IMX=y +CONFIG_SPI_ATMEL_QUADSPI=y +CONFIG_SPI_MEM=y CONFIG_SPI_NXP_FLEXSPI=y CONFIG_SPI_ROCKCHIP=y CONFIG_I2C_GPIO=y diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index b82f6c96fca2..75bc41a08b28 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -257,6 +257,7 @@ lwl-$(CONFIG_MACH_LS1046ARDB) += fsl-ls1046a-rdb.dtb.o lwl-$(CONFIG_MACH_TQMLS1046A) += fsl-ls1046a-tqmls1046a-mbls10xxa.dtb.o lwl-$(CONFIG_MACH_TQMLS1046A) += fsl-tqmls1046a-arkona-at300.dtb.o lwl-$(CONFIG_MACH_LS1021AIOT) += fsl-ls1021a-iot.dtb.o +lwl-$(CONFIG_MACH_NOVARQ_TACTICAL_1000) += novarq-tactical-1000.dtb.o lwl-$(CONFIG_MACH_ZEDBOARD) += zynq-zed.dtb.o lwl-$(CONFIG_MACH_MNT_REFORM) += imx8mq-mnt-reform2.dtb.o lwl-$(CONFIG_MACH_VARISCITE_DT8MCUSTOMBOARD_IMX8MP) += imx8mp-var-dart-dt8mcustomboard.dtb.o diff --git a/arch/arm/dts/lan9691-bb.dtsi b/arch/arm/dts/lan9691-bb.dtsi new file mode 100644 index 000000000000..5dbe671e9f67 --- /dev/null +++ b/arch/arm/dts/lan9691-bb.dtsi @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (C) 2026 Oleksij Rempel <[email protected]> + * + * Barebox-only overlay for the LAN9691 SoC. dts/src/arm64/microchip/ + * lan9691.dtsi is a wholesale snapshot of the Linux device trees and + * must not be patched locally, so SoC nodes barebox needs but that + * snapshot does not carry are added here instead - currently the qspi + * controllers. + * + * Once a dts/ sync brings a node in, drop it from here. When nothing is + * left, delete the file; nothing else needs touching. + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <arm64/microchip/clk-lan9691.h> + +&axi { + qspi0: spi@e0804000 { + compatible = "microchip,lan9691-qspi", "microchip,lan966x-qspi"; + reg = <0xe0804000 0x00000100>, + <0x20000000 0x08000000>; + reg-names = "qspi_base", "qspi_mmap"; + interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&fabric_clk>, <&clks GCK_ID_QSPI0>; + clock-names = "pclk", "gclk"; + assigned-clocks = <&clks GCK_ID_QSPI0>; + assigned-clock-rates = <100000000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + qspi2: spi@e0834000 { + compatible = "microchip,lan9691-qspi", "microchip,lan966x-qspi"; + reg = <0xe0834000 0x00000100>, + <0x30000000 0x04000000>; + reg-names = "qspi_base", "qspi_mmap"; + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&fabric_clk>, <&clks GCK_ID_QSPI2>; + clock-names = "pclk", "gclk"; + assigned-clocks = <&clks GCK_ID_QSPI2>; + assigned-clock-rates = <100000000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; +}; diff --git a/arch/arm/dts/novarq-tactical-1000.dts b/arch/arm/dts/novarq-tactical-1000.dts new file mode 100644 index 000000000000..188ca60d4e80 --- /dev/null +++ b/arch/arm/dts/novarq-tactical-1000.dts @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (C) 2026 Oleksij Rempel <[email protected]> + */ + +/dts-v1/; + +/* + * This is the pre-production Tactical 1000, which is laid out as a close + * copy of the Microchip EV23X71A reference design. So rather than carry a + * board device tree of our own, include the upstream EV23X71A one and + * correct the identity on top of it. That describes the hardware + * accurately and keeps the delta reviewable. + * + * The shipping Tactical 1000 is a different board - it gains fans, an + * RTC and more - and has its own device tree, lan9696-tactical-1000.dts. + * Production hardware should get its own board entry including that + * file instead; this one stays for the pre-production boards. + */ +#include <arm64/microchip/lan9696-ev23x71a.dts> + +#include "lan9691-bb.dtsi" + +/ { + model = "Novarq Tactical 1000 (pre-production, EV23X71A based)"; + /* + * microchip,ev23x71a is kept as a fallback on purpose: this board + * really is that design, so anything keyed on the eval board applies. + */ + compatible = "novarq,tactical-1000-alpha", "microchip,ev23x71a", + "microchip,lan9696", "microchip,lan9691"; +}; + +&{/leds/led-status} { + barebox,default-trigger = "heartbeat"; +}; + +&qspi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + #address-cells = <1>; + #size-cells = <1>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + m25p,fast-read; + }; +}; diff --git a/images/Makefile b/images/Makefile index 91425dd3a068..644b7ee0bf93 100644 --- a/images/Makefile +++ b/images/Makefile @@ -193,6 +193,7 @@ include $(srctree)/images/Makefile.versatile include $(srctree)/images/Makefile.vexpress include $(srctree)/images/Makefile.xburst include $(srctree)/images/Makefile.at91 +include $(srctree)/images/Makefile.microchip include $(srctree)/images/Makefile.zynq include $(srctree)/images/Makefile.zynqmp include $(srctree)/images/Makefile.layerscape diff --git a/images/Makefile.microchip b/images/Makefile.microchip new file mode 100644 index 000000000000..2368febe843d --- /dev/null +++ b/images/Makefile.microchip @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# barebox image generation Makefile for Microchip ARM64 SoCs +# + +# Novarq Tactical 1000 (Microchip LAN9696) +pblb-$(CONFIG_MACH_NOVARQ_TACTICAL_1000) += start_novarq_tactical_1000 +FILE_barebox-novarq-tactical-1000.img = start_novarq_tactical_1000.pblb +image-$(CONFIG_MACH_NOVARQ_TACTICAL_1000) += barebox-novarq-tactical-1000.img -- 2.47.3