diff mbox series

[v2,2/2] board: traverse: add initial Ten64 support

Message ID 20211110044639.7070-3-matt@traverse.com.au
State Awaiting Upstream
Delegated to: Priyanka Jain
Headers show
Series Initial Traverse Ten64 board support | expand

Commit Message

Mathew McBride Nov. 10, 2021, 4:46 a.m. UTC
The Ten64 is a networking-oriented MiniITX board
using the NXP LS1088A SoC.

This patch provides the bare minimum to support
Ten64 boards under U-Boot for distroboot.

Some related drivers have not yet been submitted
and this basic support lacks some of the
opinionated defaults provided by our firmware
distribution.

Signed-off-by: Mathew McBride <matt@traverse.com.au>
---
 arch/arm/Kconfig                   |  16 ++
 arch/arm/dts/Makefile              |   2 +
 arch/arm/dts/fsl-ls1088a-ten64.dts | 377 +++++++++++++++++++++++++
 board/traverse/ten64/Kconfig       |  17 ++
 board/traverse/ten64/MAINTAINERS   |   8 +
 board/traverse/ten64/Makefile      |   6 +
 board/traverse/ten64/eth_ten64.c   |  47 ++++
 board/traverse/ten64/ten64.c       | 438 +++++++++++++++++++++++++++++
 configs/ten64_tfa_defconfig        | 119 ++++++++
 include/configs/ten64.h            |  55 ++++
 10 files changed, 1085 insertions(+)
 create mode 100644 arch/arm/dts/fsl-ls1088a-ten64.dts
 create mode 100644 board/traverse/ten64/Kconfig
 create mode 100644 board/traverse/ten64/MAINTAINERS
 create mode 100644 board/traverse/ten64/Makefile
 create mode 100644 board/traverse/ten64/eth_ten64.c
 create mode 100644 board/traverse/ten64/ten64.c
 create mode 100644 configs/ten64_tfa_defconfig
 create mode 100644 include/configs/ten64.h

Comments

Tom Rini Nov. 11, 2021, 6:20 p.m. UTC | #1
On Wed, Nov 10, 2021 at 04:46:39AM +0000, Mathew McBride wrote:

> The Ten64 is a networking-oriented MiniITX board
> using the NXP LS1088A SoC.
> 
> This patch provides the bare minimum to support
> Ten64 boards under U-Boot for distroboot.
> 
> Some related drivers have not yet been submitted
> and this basic support lacks some of the
> opinionated defaults provided by our firmware
> distribution.
> 
> Signed-off-by: Mathew McBride <matt@traverse.com.au>
> ---
>  arch/arm/Kconfig                   |  16 ++
>  arch/arm/dts/Makefile              |   2 +
>  arch/arm/dts/fsl-ls1088a-ten64.dts | 377 +++++++++++++++++++++++++

What is the status of this dts with upstream Linux?

[snip]
> +CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0500 ramdisk_size=0x3000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"

Note that ramdisk information will be passed along correctly via DT and
should not generally be set in this manner.

[snip]
> +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:8m(reserved),32m(recovery),108m(ubia),108m(ubib);nor1:1m(bl2),2m(bl3),2m(mcfirmware),512k(ubootenv),256k(dpl),256k(dpc),256k(devicetree)"

This should be the same as the fixed-partition in the dts and then not
needed here.
> diff --git a/include/configs/ten64.h b/include/configs/ten64.h
> new file mode 100644
> index 0000000000..54e65f29f1
> --- /dev/null
> +++ b/include/configs/ten64.h

Please make sure there's no already migrated CONFIG symbols in this.  A
quick 'git log configs' should make it clear what's been migrated to
Kconfig since you last checked this.

> +#define QSPI_NOR_BOOTCOMMAND	"run distro_bootcmd"
> +#define SD_BOOTCOMMAND		"run distro_bootcmd"

You should just set CONFIG_USE_BOOTCOMMAND and then CONFIG_BOOTCOMMAND
will be "run distro_bootcmd".  Thanks!
Mathew McBride Nov. 17, 2021, 10:09 p.m. UTC | #2
Hi Tom,

On Fri, Nov 12, 2021, at 5:20 AM, Tom Rini wrote:
> On Wed, Nov 10, 2021 at 04:46:39AM +0000, Mathew McBride wrote:
> 
> > Signed-off-by: Mathew McBride <matt@traverse.com.au>
> > ---
> >  arch/arm/Kconfig                   |  16 ++
> >  arch/arm/dts/Makefile              |   2 +
> >  arch/arm/dts/fsl-ls1088a-ten64.dts | 377 +++++++++++++++++++++++++
> 
> What is the status of this dts with upstream Linux?
It's been in Linux since v5.15, though there is going to be some flux between U-Boot and Linux for a short while as some devices will be introduced into one or the other other first.
e.g traverse,ten64-controller does not and will not have a Linux (kernel) counterpart but I'll try and get it added to the dt yaml's for validation.

(The upstream DTS intentionally left out some I2C devices that don't have Linux drivers or formal DT bindings yet)

> [snip]
> 
> 
> > +#define QSPI_NOR_BOOTCOMMAND "run distro_bootcmd"
> > +#define SD_BOOTCOMMAND "run distro_bootcmd"
> 
> You should just set CONFIG_USE_BOOTCOMMAND and then CONFIG_BOOTCOMMAND
> will be "run distro_bootcmd".  Thanks!
This actually comes about from fsl_setenv_bootcmd:
https://elixir.bootlin.com/u-boot/latest/source/arch/arm/cpu/armv8/fsl-layerscape/soc.c#L800
Which gets hooked into board_late_init
https://elixir.bootlin.com/u-boot/latest/source/arch/arm/cpu/armv8/fsl-layerscape/soc.c#L961

The main reason I understand that exists is because the secure boot (FSL trust architecture) setup differs a depending on where the board has booted from:
https://elixir.bootlin.com/u-boot/latest/source/include/configs/ls1088ardb.h#L448
(There is also a similar issue with mcinitcmd which does affect us)

Since trust architecture isn't supported on our board yet, it just collapses down to "run distro_bootcmd" regardless of where the board started from.

I guess this behaviour could be hidden behind a Kconfig so it's opt-in?

- Matt
Tom Rini Nov. 17, 2021, 10:29 p.m. UTC | #3
On Thu, Nov 18, 2021 at 09:09:44AM +1100, Mathew McBride wrote:
> Hi Tom,
> 
> On Fri, Nov 12, 2021, at 5:20 AM, Tom Rini wrote:
> > On Wed, Nov 10, 2021 at 04:46:39AM +0000, Mathew McBride wrote:
> > 
> > > Signed-off-by: Mathew McBride <matt@traverse.com.au>
> > > ---
> > >  arch/arm/Kconfig                   |  16 ++
> > >  arch/arm/dts/Makefile              |   2 +
> > >  arch/arm/dts/fsl-ls1088a-ten64.dts | 377 +++++++++++++++++++++++++
> > 
> > What is the status of this dts with upstream Linux?
> It's been in Linux since v5.15, though there is going to be some flux between U-Boot and Linux for a short while as some devices will be introduced into one or the other other first.
> e.g traverse,ten64-controller does not and will not have a Linux (kernel) counterpart but I'll try and get it added to the dt yaml's for validation.
> 
> (The upstream DTS intentionally left out some I2C devices that don't have Linux drivers or formal DT bindings yet)

Bindings need to be upstreamed and reviewed, and the dts here kept in
sync with the kernel, as it will be dropped in for updates.  You also
should at this point be able to get nodes (so long as there is a binding
of course) that aren't strictly used in the kernel in the dts that's in
the kernel.

> > [snip]
> > 
> > 
> > > +#define QSPI_NOR_BOOTCOMMAND "run distro_bootcmd"
> > > +#define SD_BOOTCOMMAND "run distro_bootcmd"
> > 
> > You should just set CONFIG_USE_BOOTCOMMAND and then CONFIG_BOOTCOMMAND
> > will be "run distro_bootcmd".  Thanks!
> This actually comes about from fsl_setenv_bootcmd:
> https://elixir.bootlin.com/u-boot/latest/source/arch/arm/cpu/armv8/fsl-layerscape/soc.c#L800
> Which gets hooked into board_late_init
> https://elixir.bootlin.com/u-boot/latest/source/arch/arm/cpu/armv8/fsl-layerscape/soc.c#L961
> 
> The main reason I understand that exists is because the secure boot (FSL trust architecture) setup differs a depending on where the board has booted from:
> https://elixir.bootlin.com/u-boot/latest/source/include/configs/ls1088ardb.h#L448
> (There is also a similar issue with mcinitcmd which does affect us)
> 
> Since trust architecture isn't supported on our board yet, it just collapses down to "run distro_bootcmd" regardless of where the board started from.
> 
> I guess this behaviour could be hidden behind a Kconfig so it's opt-in?

Thanks for explaining.  That's...interesting.  And something that might
be able to be cleaned up a bit in -next now that we've added some more
flexibility to how environment is constructed at build time.  But, not a
job for someone submitting a board that follows the best practices of
the rest of the family, even if those best practices aren't always so
great.
diff mbox series

Patch

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ae911d6e35..52de5e838f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1761,6 +1761,21 @@  config TARGET_SL28
 	help
 	  Support for Kontron SMARC-sAL28 board.
 
+config TARGET_TEN64
+	bool "Support ten64"
+	select ARCH_LS1088A
+	select ARCH_MISC_INIT
+	select ARM64
+	select ARMV8_MULTIENTRY
+	select ARCH_SUPPORT_TFABOOT
+	select BOARD_LATE_INIT
+	select SUPPORT_SPL
+	select FSL_DDR_INTERACTIVE if !SD_BOOT
+	select GPIO_EXTRA_HEADER
+	help
+	  Support for Traverse Technologies Ten64 board, based
+	  on NXP LS1088A.
+
 config TARGET_COLIBRI_PXA270
 	bool "Support colibri_pxa270"
 	select CPU_PXA
@@ -2197,6 +2212,7 @@  source "board/socionext/developerbox/Kconfig"
 source "board/st/stv0991/Kconfig"
 source "board/tcl/sl50/Kconfig"
 source "board/toradex/colibri_pxa270/Kconfig"
+source "board/traverse/ten64/Kconfig"
 source "board/variscite/dart_6ul/Kconfig"
 source "board/vscom/baltos/Kconfig"
 source "board/phytium/durian/Kconfig"
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index cc34da7bd8..2655707a43 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -478,6 +478,8 @@  dtb-$(CONFIG_TARGET_SL28) += fsl-ls1028a-kontron-sl28.dtb \
 	fsl-ls1028a-kontron-sl28-var3.dtb \
 	fsl-ls1028a-kontron-sl28-var4.dtb \
 
+dtb-$(CONFIG_TARGET_TEN64) += fsl-ls1088a-ten64.dtb
+
 dtb-$(CONFIG_TARGET_DRAGONBOARD410C) += dragonboard410c.dtb
 dtb-$(CONFIG_TARGET_DRAGONBOARD820C) += dragonboard820c.dtb
 dtb-$(CONFIG_TARGET_STARQLTECHN) += starqltechn.dtb
diff --git a/arch/arm/dts/fsl-ls1088a-ten64.dts b/arch/arm/dts/fsl-ls1088a-ten64.dts
new file mode 100644
index 0000000000..43b669c642
--- /dev/null
+++ b/arch/arm/dts/fsl-ls1088a-ten64.dts
@@ -0,0 +1,377 @@ 
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Travese Ten64 (LS1088) board
+ * Based on fsl-ls1088a-rdb.dts
+ * Copyright 2017-2020 NXP
+ * Copyright 2019-2021 Traverse Technologies
+ *
+ * Author: Mathew McBride <matt@traverse.com.au>
+ */
+
+/dts-v1/;
+
+#include "fsl-ls1088a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Traverse Ten64";
+	compatible = "traverse,ten64", "fsl,ls1088a";
+
+	aliases {
+		spi0 = &qspi;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	buttons {
+		compatible = "gpio-keys";
+
+		/* Fired by system controller when
+		 * external power off (e.g ATX Power Button)
+		 * asserted
+		 */
+		powerdn {
+			label = "External Power Down";
+			gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+			interrupts = <&gpio1 17 IRQ_TYPE_EDGE_FALLING>;
+			linux,code = <KEY_POWER>;
+		};
+
+		/* Rear Panel 'ADMIN' button (GPIO_H) */
+		admin {
+			label = "ADMIN button";
+			gpios = <&gpio3 8 GPIO_ACTIVE_HIGH>;
+			interrupts = <&gpio3 8 IRQ_TYPE_EDGE_RISING>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		sfp1down {
+			label = "ten64:green:sfp1:down";
+			gpios = <&gpio3 11 GPIO_ACTIVE_HIGH>;
+		};
+
+		sfp2up {
+			label = "ten64:green:sfp2:up";
+			gpios = <&gpio3 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		admin {
+			label = "ten64:admin";
+			gpios = <&sfpgpio 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	sfp_xg0: dpmac2-sfp {
+		compatible = "sff,sfp";
+		i2c-bus = <&sfplower_i2c>;
+		tx-fault-gpios = <&sfpgpio 0 GPIO_ACTIVE_HIGH>;
+		tx-disable-gpios = <&sfpgpio 1 GPIO_ACTIVE_HIGH>;
+		mod-def0-gpios = <&sfpgpio 2 GPIO_ACTIVE_LOW>;
+		los-gpios = <&sfpgpio 3 GPIO_ACTIVE_HIGH>;
+		maximum-power-milliwatt = <2000>;
+	};
+
+	sfp_xg1: dpmac1-sfp {
+		compatible = "sff,sfp";
+		i2c-bus = <&sfpupper_i2c>;
+		tx-fault-gpios = <&sfpgpio 4 GPIO_ACTIVE_HIGH>;
+		tx-disable-gpios = <&sfpgpio 5 GPIO_ACTIVE_HIGH>;
+		mod-def0-gpios = <&sfpgpio 6 GPIO_ACTIVE_LOW>;
+		los-gpios = <&sfpgpio 7 GPIO_ACTIVE_HIGH>;
+		maximum-power-milliwatt = <2000>;
+	};
+};
+
+/* XG1 - Upper SFP */
+&dpmac1 {
+	sfp = <&sfp_xg1>;
+	phy-connection-type = "10gbase-r";
+	managed = "in-band-status";
+	status = "okay";
+};
+
+/* XG0 - Lower SFP */
+&dpmac2 {
+	sfp = <&sfp_xg0>;
+	phy-connection-type = "10gbase-r";
+	managed = "in-band-status";
+	status = "okay";
+};
+
+/* DPMAC3..6 is GE4 to GE8 */
+&dpmac3 {
+	phy-handle = <&mdio1_phy5>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
+
+&dpmac4 {
+	phy-handle = <&mdio1_phy6>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
+
+&dpmac5 {
+	phy-handle = <&mdio1_phy7>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
+
+&dpmac6 {
+	phy-handle = <&mdio1_phy8>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
+
+/* DPMAC7..10 is GE0 to GE3 */
+&dpmac7 {
+	phy-handle = <&mdio1_phy1>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
+
+&dpmac8 {
+	phy-handle = <&mdio1_phy2>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
+
+&dpmac9 {
+	phy-handle = <&mdio1_phy3>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
+
+&dpmac10 {
+	phy-handle = <&mdio1_phy4>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
+
+&serial0 {
+	status = "okay";
+};
+
+&serial1 {
+	status = "okay";
+};
+
+&emdio1 {
+	status = "okay";
+
+	mdio1_phy5: ethernet-phy@c {
+		reg = <0xc>;
+	};
+
+	mdio1_phy6: ethernet-phy@d {
+		reg = <0xd>;
+	};
+
+	mdio1_phy7: ethernet-phy@e {
+		reg = <0xe>;
+	};
+
+	mdio1_phy8: ethernet-phy@f {
+		reg = <0xf>;
+	};
+
+	mdio1_phy1: ethernet-phy@1c {
+		reg = <0x1c>;
+	};
+
+	mdio1_phy2: ethernet-phy@1d {
+		reg = <0x1d>;
+	};
+
+	mdio1_phy3: ethernet-phy@1e {
+		reg = <0x1e>;
+	};
+
+	mdio1_phy4: ethernet-phy@1f {
+		reg = <0x1f>;
+	};
+};
+
+&esdhc {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	sfpgpio: gpio@76 {
+		compatible = "ti,tca9539";
+		reg = <0x76>;
+		#gpio-cells = <2>;
+		gpio-controller;
+
+		admin_led_lower {
+			gpio-hog;
+			gpios = <13 GPIO_ACTIVE_HIGH>;
+			output-low;
+		};
+	};
+
+	at97sc: tpm@29 {
+		compatible = "atmel,at97sc3204t";
+		reg = <0x29>;
+	};
+
+	uc: board-controller@7e {
+		compatible = "traverse,ten64-controller";
+		reg = <0x7e>;
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	rx8035: rtc@32 {
+		compatible = "epson,rx8035";
+		reg = <0x32>;
+	};
+};
+
+&i2c3 {
+	status = "okay";
+
+	i2c-switch@70 {
+		compatible = "nxp,pca9540";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		sfpupper_i2c: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		sfplower_i2c: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+	};
+};
+
+&qspi {
+	status = "okay";
+
+	en25s64: flash@0 {
+		compatible = "jedec,spi-nor";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0>;
+		spi-max-frequency = <20000000>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bl2";
+				reg = <0 0x100000>;
+			};
+
+			partition@100000 {
+				label = "bl3";
+				reg = <0x100000 0x200000>;
+			};
+
+			partition@300000 {
+				label = "mcfirmware";
+				reg = <0x300000 0x200000>;
+			};
+
+			partition@500000 {
+				label = "ubootenv";
+				reg = <0x500000 0x80000>;
+			};
+
+			partition@580000 {
+				label = "dpl";
+				reg = <0x580000 0x40000>;
+			};
+
+			partition@5C0000 {
+				label = "dpc";
+				reg = <0x5C0000 0x40000>;
+			};
+
+			partition@600000 {
+				label = "devicetree";
+				reg = <0x600000 0x40000>;
+			};
+		};
+	};
+
+	nand: flash@1 {
+		compatible = "spi-nand";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <1>;
+		spi-max-frequency = <20000000>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			/* reserved for future boot direct from NAND flash
+			 * (this would use the same layout as the 8MiB NOR flash)
+			 */
+			partition@0 {
+				label = "nand-boot-reserved";
+				reg = <0 0x800000>;
+			};
+
+			/* recovery / install environment */
+			partition@800000 {
+				label = "recovery";
+				reg = <0x800000 0x2000000>;
+			};
+
+			/* ubia (first OpenWrt) - a/b names to prevent confusion with ubi0/1/etc. */
+			partition@2800000 {
+				label = "ubia";
+				reg = <0x2800000 0x6C00000>;
+			};
+
+			/* ubib (second OpenWrt) */
+			partition@9400000 {
+				label = "ubib";
+				reg = <0x9400000 0x6C00000>;
+			};
+		};
+	};
+};
+
+&usb0 {
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
diff --git a/board/traverse/ten64/Kconfig b/board/traverse/ten64/Kconfig
new file mode 100644
index 0000000000..ea8e3ea20d
--- /dev/null
+++ b/board/traverse/ten64/Kconfig
@@ -0,0 +1,17 @@ 
+if TARGET_TEN64
+
+config SYS_BOARD
+	default "ten64"
+
+config SYS_VENDOR
+	default "traverse"
+
+config SYS_SOC
+	default "fsl-layerscape"
+
+config SYS_CONFIG_NAME
+	default "ten64"
+
+endif
+
+source "board/traverse/common/Kconfig"
diff --git a/board/traverse/ten64/MAINTAINERS b/board/traverse/ten64/MAINTAINERS
new file mode 100644
index 0000000000..7b53e87938
--- /dev/null
+++ b/board/traverse/ten64/MAINTAINERS
@@ -0,0 +1,8 @@ 
+TEN64 BOARD
+M:	Mathew McBride <matt@traverse.com.au>
+S:	Maintained
+F:	arch/arm/dts/fsl-ls1088a-ten64.dts
+F:	board/traverse/ten64/
+F:	board/traverse/common/
+F:	include/configs/ten64.h
+F:	configs/ten64_tfa_defconfig
diff --git a/board/traverse/ten64/Makefile b/board/traverse/ten64/Makefile
new file mode 100644
index 0000000000..fd8d5cc87b
--- /dev/null
+++ b/board/traverse/ten64/Makefile
@@ -0,0 +1,6 @@ 
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += ten64.o
+obj-y += eth_ten64.o
+
+CFLAGS_ten64.o += -DDEBUG
diff --git a/board/traverse/ten64/eth_ten64.c b/board/traverse/ten64/eth_ten64.c
new file mode 100644
index 0000000000..3f96e572b7
--- /dev/null
+++ b/board/traverse/ten64/eth_ten64.c
@@ -0,0 +1,47 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017 NXP
+ * Copyright 2019-2021 Traverse Technologies Australia
+ */
+#include <common.h>
+#include <command.h>
+#include <netdev.h>
+#include <malloc.h>
+#include <fsl_mdio.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <exports.h>
+#include <asm/arch/fsl_serdes.h>
+#include <fsl-mc/fsl_mc.h>
+#include <fsl-mc/ldpaa_wriop.h>
+
+void reset_phy(void)
+{
+	mc_env_boot();
+}
+
+int board_phy_config(struct phy_device *phydev)
+{
+	/* These settings only apply to VSC8514 */
+	if (phydev->phy_id == 0x70670) {
+		/* First, ensure LEDs are driven to rails (not tristate)
+		 * This is in the extended page 0x0010
+		 */
+		phy_write(phydev, MDIO_DEVAD_NONE, 0x1F, 0x0010);
+		phy_write(phydev, MDIO_DEVAD_NONE, 0x0E, 0x2000);
+		/* Restore to page 0 */
+		phy_write(phydev, MDIO_DEVAD_NONE, 0x1F, 0x0000);
+
+		/* Disable blink on the left LEDs, and make the activity LEDs blink faster */
+		phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0xC03);
+
+		phy_write(phydev, MDIO_DEVAD_NONE, 0x1D, 0x3421);
+	}
+
+	if (phydev->drv->config)
+		phydev->drv->config(phydev);
+
+	return 0;
+}
diff --git a/board/traverse/ten64/ten64.c b/board/traverse/ten64/ten64.c
new file mode 100644
index 0000000000..bdabc214b2
--- /dev/null
+++ b/board/traverse/ten64/ten64.c
@@ -0,0 +1,438 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Traverse Ten64 Family board
+ * Copyright 2017-2018 NXP
+ * Copyright 2019-2021 Traverse Technologies
+ */
+#include <common.h>
+#include <dm/uclass.h>
+#include <env.h>
+#include <i2c.h>
+#include <init.h>
+#include <log.h>
+#include <malloc.h>
+#include <errno.h>
+#include <misc.h>
+#include <netdev.h>
+#include <fsl_ifc.h>
+#include <fsl_ddr.h>
+#include <fsl_sec.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <fdt_support.h>
+#include <linux/delay.h>
+#include <linux/libfdt.h>
+#include <fsl-mc/fsl_mc.h>
+#include <env_internal.h>
+#include <asm/arch-fsl-layerscape/soc.h>
+#include <asm/arch/ppa.h>
+#include <hwconfig.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/soc.h>
+#include <asm/arch-fsl-layerscape/fsl_icid.h>
+
+#include <fsl_immap.h>
+
+#include "../common/ten64-controller.h"
+
+#define I2C_RETIMER_ADDR		0x27
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int ten64_read_board_info(struct t64uc_board_info *);
+static void ten64_set_macaddrs_from_board_info(struct t64uc_board_info *);
+static void ten64_board_retimer_ds110df410_init(void);
+
+enum {
+	TEN64_BOARD_REV_A = 0xFF,
+	TEN64_BOARD_REV_B = 0xFE,
+	TEN64_BOARD_REV_C = 0xFD
+};
+
+#define RESV_MEM_IN_BANK(b)	(gd->arch.resv_ram >= base[b] && \
+				 gd->arch.resv_ram < base[b] + size[b])
+
+int board_early_init_f(void)
+{
+	fsl_lsch3_early_init_f();
+	return 0;
+}
+
+static u32 ten64_get_board_rev(void)
+{
+	struct ccsr_gur *dcfg = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+	u32 board_rev_in = in_le32(&dcfg->gpporcr1);
+	return board_rev_in;
+}
+
+int checkboard(void)
+{
+	enum boot_src src = get_boot_src();
+	char boardmodel[32];
+	struct t64uc_board_info boardinfo;
+	u32 board_rev = ten64_get_board_rev();
+
+	switch (board_rev) {
+	case TEN64_BOARD_REV_A:
+		snprintf(boardmodel, 32, "1064-0201A (Alpha)");
+		break;
+	case TEN64_BOARD_REV_B:
+		snprintf(boardmodel, 32, "1064-0201B (Beta)");
+		break;
+	case TEN64_BOARD_REV_C:
+		snprintf(boardmodel, 32, "1064-0201C");
+		break;
+	default:
+		snprintf(boardmodel, 32, "1064 Revision %X", (0xFF - board_rev));
+		break;
+	}
+
+	printf("Board: %s, boot from ", boardmodel);
+	if (src == BOOT_SOURCE_SD_MMC)
+		puts("SD card\n");
+	else if (src == BOOT_SOURCE_QSPI_NOR)
+		puts("QSPI\n");
+	else
+		printf("Unknown boot source %d\n", src);
+
+	puts("Controller: ");
+	if (CONFIG_IS_ENABLED(TEN64_CONTROLLER)) {
+		/* Driver not compatible with alpha/beta board MCU firmware */
+		if (board_rev <= TEN64_BOARD_REV_C) {
+			if (ten64_read_board_info(&boardinfo)) {
+				puts("ERROR: unable to communicate\n");
+			} else {
+				printf("firmware %d.%d.%d\n",
+				       boardinfo.fwversion_major,
+				       boardinfo.fwversion_minor,
+				       boardinfo.fwversion_patch);
+				ten64_set_macaddrs_from_board_info(&boardinfo);
+			}
+		} else {
+			puts("not supported on this board revision\n");
+		}
+	} else {
+		puts("driver not enabled (no MAC addresses or other information will be read)\n");
+	}
+
+	return 0;
+}
+
+int board_init(void)
+{
+	init_final_memctl_regs();
+
+	if (CONFIG_IS_ENABLED(FSL_CAAM))
+		sec_init();
+
+	return 0;
+}
+
+int fsl_initdram(void)
+{
+	gd->ram_size = tfa_get_dram_size();
+
+	if (!gd->ram_size)
+		gd->ram_size = fsl_ddr_sdram_size();
+
+	return 0;
+}
+
+void detail_board_ddr_info(void)
+{
+	puts("\nDDR    ");
+	print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
+	print_ddr_info(0);
+}
+
+void board_quiesce_devices(void)
+{
+	if (IS_ENABLED(CONFIG_FSL_MC_ENET))
+		fsl_mc_ldpaa_exit(gd->bd);
+}
+
+void fdt_fixup_board_enet(void *fdt)
+{
+	int offset;
+
+	offset = fdt_path_offset(fdt, "/fsl-mc");
+
+	if (offset < 0)
+		offset = fdt_path_offset(fdt, "/soc/fsl-mc");
+
+	if (offset < 0) {
+		printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
+		       __func__, offset);
+		return;
+	}
+
+	if (get_mc_boot_status() == 0 &&
+	    (is_lazy_dpl_addr_valid() || get_dpl_apply_status() == 0))
+		fdt_status_okay(fdt, offset);
+	else
+		fdt_status_fail(fdt, offset);
+}
+
+/* Called after SoC board_late_init in fsl-layerscape/soc.c */
+int fsl_board_late_init(void)
+{
+	ten64_board_retimer_ds110df410_init();
+	return 0;
+}
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+	int i;
+	u16 mc_memory_bank = 0;
+
+	u64 *base;
+	u64 *size;
+	u64 mc_memory_base = 0;
+	u64 mc_memory_size = 0;
+	u16 total_memory_banks;
+
+	debug("%s blob=0x%p\n", __func__, blob);
+
+	ft_cpu_setup(blob, bd);
+
+	fdt_fixup_mc_ddr(&mc_memory_base, &mc_memory_size);
+
+	if (mc_memory_base != 0)
+		mc_memory_bank++;
+
+	total_memory_banks = CONFIG_NR_DRAM_BANKS + mc_memory_bank;
+
+	base = calloc(total_memory_banks, sizeof(u64));
+	size = calloc(total_memory_banks, sizeof(u64));
+
+	/* fixup DT for the two GPP DDR banks */
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		base[i] = gd->bd->bi_dram[i].start;
+		size[i] = gd->bd->bi_dram[i].size;
+		/* reduce size if reserved memory is within this bank */
+		if (CONFIG_IS_ENABLED(RESV_RAM) && RESV_MEM_IN_BANK(i))
+			size[i] = gd->arch.resv_ram - base[i];
+	}
+
+	if (mc_memory_base != 0) {
+		for (i = 0; i <= total_memory_banks; i++) {
+			if (base[i] == 0 && size[i] == 0) {
+				base[i] = mc_memory_base;
+				size[i] = mc_memory_size;
+				break;
+			}
+		}
+	}
+
+	fdt_fixup_memory_banks(blob, base, size, total_memory_banks);
+
+	fdt_fsl_mc_fixup_iommu_map_entry(blob);
+
+	if (CONFIG_IS_ENABLED(FSL_MC_ENET))
+		fdt_fixup_board_enet(blob);
+
+	fdt_fixup_icid(blob);
+
+	return 0;
+}
+
+#define MACADDRBITS(a, b) (u8)(((a) >> (b)) & 0xFF)
+
+/** Probe and return a udevice for the Ten64 board microcontroller.
+ * Optionally, return the I2C bus the microcontroller resides on
+ * @i2c_bus_out: return I2C bus device handle in this pointer
+ */
+static int ten64_get_micro_udevice(struct udevice **ucdev, struct udevice **i2c_bus_out)
+{
+	int ret;
+	struct udevice *i2cbus;
+
+	ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &i2cbus);
+	if (ret) {
+		printf("%s: Could not get I2C UCLASS", __func__);
+		return ret;
+	}
+	if (i2c_bus_out)
+		*i2c_bus_out = i2cbus;
+
+	ret = dm_i2c_probe(i2cbus, 0x7E, DM_I2C_CHIP_RD_ADDRESS, ucdev);
+	if (ret) {
+		printf("%s: Could not get microcontroller device\n", __func__);
+		return ret;
+	}
+	return ret;
+}
+
+static int ten64_read_board_info(struct t64uc_board_info *boardinfo)
+{
+	struct udevice *ucdev;
+	int ret;
+
+	ret = ten64_get_micro_udevice(&ucdev, NULL);
+	if (ret)
+		return ret;
+
+	ret = misc_call(ucdev, TEN64_CNTRL_GET_BOARD_INFO, NULL, 0, (void *)boardinfo, 0);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void ten64_set_macaddrs_from_board_info(struct t64uc_board_info *boardinfo)
+{
+	char ethaddr[18];
+	char enetvar[10];
+	u8 intfidx, this_dpmac_num;
+	u64 macaddr = 0;
+	/* We will copy the MAC address returned from the
+	 * uC (48 bits) into the u64 macaddr
+	 */
+	u8 *macaddr_bytes = (u8 *)&macaddr + 2;
+
+	/** MAC addresses are allocated in order of the physical port numbers,
+	 * DPMAC7->10 is "eth0" through "eth3"
+	 * DPMAC3->6 is "eth4" through "eth7"
+	 * DPMAC2 and 1 are "eth8" and "eth9" respectively
+	 */
+	int allocation_order[10] = {7, 8, 9, 10, 3, 4, 5, 6, 2, 1};
+
+	memcpy(macaddr_bytes, boardinfo->mac, 6);
+	/* MAC address bytes from uC are in big endian,
+	 * convert to CPU
+	 */
+	macaddr = __be64_to_cpu(macaddr);
+
+	for (intfidx = 0; intfidx < 10; intfidx++) {
+		snprintf(ethaddr, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
+			 MACADDRBITS(macaddr, 40),
+			 MACADDRBITS(macaddr, 32),
+			 MACADDRBITS(macaddr, 24),
+			 MACADDRBITS(macaddr, 16),
+			 MACADDRBITS(macaddr, 8),
+			 MACADDRBITS(macaddr, 0));
+
+		this_dpmac_num = allocation_order[intfidx];
+		printf("DPMAC%d: %s\n", this_dpmac_num, ethaddr);
+		snprintf(enetvar, 10,
+			 (this_dpmac_num != 1) ? "eth%daddr" : "ethaddr",
+			 this_dpmac_num - 1);
+		macaddr++;
+
+		if (!env_get(enetvar))
+			env_set(enetvar, ethaddr);
+	}
+}
+
+/* The retimer (DS110DF410) is one of the devices without
+ * a RESET line, but a power switch is on the board
+ * allowing it to be reset via uC command
+ */
+static int board_cycle_retimer(struct udevice **retim_dev)
+{
+	int ret;
+	u8 loop;
+	struct udevice *uc_dev;
+	struct udevice *i2cbus;
+
+	ret = ten64_get_micro_udevice(&uc_dev, &i2cbus);
+	if (ret)
+		return ret;
+
+	ret = dm_i2c_probe(i2cbus, I2C_RETIMER_ADDR, 0, retim_dev);
+	if (ret == 0) {
+		puts("(retimer on, resetting...) ");
+
+		ret = misc_call(uc_dev, TEN64_CNTRL_10G_OFF, NULL, 0, NULL, 0);
+		mdelay(1000);
+	}
+
+	ret = misc_call(uc_dev, TEN64_CNTRL_10G_ON, NULL, 0, NULL, 0);
+
+	// Wait for retimer to come back
+	for (loop = 0; loop < 5; loop++) {
+		ret = dm_i2c_probe(i2cbus, I2C_RETIMER_ADDR, 0, retim_dev);
+		if (ret == 0)
+			return 0;
+		mdelay(500);
+	}
+
+	return -ENOSYS;
+}
+
+/* ten64_board_retimer_ds110df410_init() - Configure the 10G retimer
+ * Adopted from the t102xqds board file
+ */
+static void ten64_board_retimer_ds110df410_init(void)
+{
+	u8 reg;
+	int ret;
+	struct udevice *retim_dev;
+	u32 board_rev = ten64_get_board_rev();
+
+	puts("Retimer: ");
+	/* Retimer power cycle not implemented on early board
+	 * revisions/controller firmwares
+	 */
+	if (CONFIG_IS_ENABLED(TEN64_CONTROLLER) &&
+	    board_rev >= TEN64_BOARD_REV_C) {
+		ret = board_cycle_retimer(&retim_dev);
+		if (ret) {
+			puts("Retimer power on failed\n");
+			return;
+		}
+	}
+
+	/* Access to Control/Shared register */
+	reg = 0x0;
+
+	ret = dm_i2c_write(retim_dev, 0xff, &reg, 1);
+	if (ret) {
+		printf("Error writing to retimer register (error %d)\n", ret);
+		return;
+	}
+
+	/* Read device revision and ID */
+	dm_i2c_read(retim_dev, 1, &reg, 1);
+	if (reg == 0xF0)
+		puts("DS110DF410 found\n");
+	else
+		printf("Unknown retimer 0x%xn\n", reg);
+
+	/* Enable Broadcast */
+	reg = 0x0c;
+	dm_i2c_write(retim_dev, 0xff, &reg, 1);
+
+	/* Perform a full reset (state, channel and clock)
+	 * for all channels
+	 * as the DS110DF410 does not have a RESET line
+	 */
+	dm_i2c_read(retim_dev, 0, &reg, 1);
+	reg |= 0x7;
+	dm_i2c_write(retim_dev, 0, &reg, 1);
+
+	/* Set rate/subrate = 0 */
+	reg = 0x6;
+	dm_i2c_write(retim_dev, 0x2F, &reg, 1);
+
+	/* Set data rate as 10.3125 Gbps */
+	reg = 0x0;
+	dm_i2c_write(retim_dev, 0x60, &reg, 1);
+	reg = 0xb2;
+	dm_i2c_write(retim_dev, 0x61, &reg, 1);
+	reg = 0x90;
+	dm_i2c_write(retim_dev, 0x62, &reg, 1);
+	reg = 0xb3;
+	dm_i2c_write(retim_dev, 0x63, &reg, 1);
+	reg = 0xff;
+	dm_i2c_write(retim_dev, 0x64, &reg, 1);
+
+	/* Invert channel 2 (Lower SFP TX to CPU) due to the SFP being inverted */
+	reg = 0x05;
+	dm_i2c_write(retim_dev, 0xFF, &reg, 1);
+	dm_i2c_read(retim_dev, 0x1F, &reg, 1);
+	reg |= 0x80;
+	dm_i2c_write(retim_dev, 0x1F, &reg, 1);
+
+	puts("OK\n");
+}
diff --git a/configs/ten64_tfa_defconfig b/configs/ten64_tfa_defconfig
new file mode 100644
index 0000000000..8d45b134fe
--- /dev/null
+++ b/configs/ten64_tfa_defconfig
@@ -0,0 +1,119 @@ 
+CONFIG_ARM=y
+CONFIG_TARGET_TEN64=y
+CONFIG_SYS_TEXT_BASE=0x82000000
+CONFIG_QSPI_AHB_INIT=y
+CONFIG_TFABOOT=y
+CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT=y
+CONFIG_SEC_FIRMWARE_ARMV8_PSCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_NR_DRAM_BANKS=2
+# CONFIG_SYS_MALLOC_F is not set
+CONFIG_FIT_VERBOSE=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_OF_FDT_OVERLAY=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4"
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0500 ramdisk_size=0x3000000 default_hugepagesz=2m hugepagesz=2m hugepages=256"
+# CONFIG_USE_BOOTCOMMAND is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_CMD_BOOTEFI_HELLO=y
+CONFIG_CMD_BOOTEFI_SELFTEST=y
+CONFIG_CMD_BOOTMENU=y
+CONFIG_CMD_GPT=y
+CONFIG_RANDOM_UUID=y
+CONFIG_CMD_DM=y
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_UBI=y
+CONFIG_CMD_UBIFS=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_POWEROFF=y
+CONFIG_CMD_WDT=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_FS_FAT=y
+CONFIG_FAT_WRITE=y
+CONFIG_MP=y
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1088a-ten64"
+CONFIG_EMC230X=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_OFFSET=0x500000
+CONFIG_ENV_SIZE=0x80000
+CONFIG_ENV_SECT_SIZE=0x80000
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DM=y
+CONFIG_SCSI_AHCI=y
+CONFIG_DM_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_CMD_FAN=y
+CONFIG_FANCONTROL=y
+CONFIG_DM_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_EON=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_E1000=y
+# CONFIG_ID_EEPROM is not set
+CONFIG_MII=y
+CONFIG_NVME=y
+CONFIG_CMD_PCI=y
+CONFIG_PCI=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCIE_LAYERSCAPE_RC=y
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_FSL_DSPI=y
+CONFIG_FSL_QSPI=y
+CONFIG_UBI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_GADGET=y
+CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
+CONFIG_DM_I2C=y
+CONFIG_DM_GPIO=y
+CONFIG_ARM_SMCCC=y
+CONFIG_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_CMD_MTD=y
+CONFIG_LOGLEVEL=7
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:8m(reserved),32m(recovery),108m(ubia),108m(ubib);nor1:1m(bl2),2m(bl3),2m(mcfirmware),512k(ubootenv),256k(dpl),256k(dpc),256k(devicetree)"
+CONFIG_MPC8XXX_GPIO=y
+CONFIG_GPIO_HOG=y
+CONFIG_DM_RTC=y
+CONFIG_RTC_RX8025=y
+CONFIG_CMD_NVEDIT_EFI=y
+CONFIG_CMD_EFIDEBUG=y
+CONFIG_DM_ETH=y
+CONFIG_PCI_INIT_R=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_VITESSE=y
+CONFIG_DM_MDIO=y
+CONFIG_FSL_LS_MDIO=y
+CONFIG_SYS_MALLOC_F=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_TPM=y
+CONFIG_CMD_TPM=y
+CONFIG_TPM_ATMEL_TWI=y
+CONFIG_MISC=y
+CONFIG_USB5744=y
+CONFIG_TEN64_CONTROLLER=y
+CONFIG_DM_SCSI=y
+CONFIG_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_WDT=y
+CONFIG_WDT_SP805=y
diff --git a/include/configs/ten64.h b/include/configs/ten64.h
new file mode 100644
index 0000000000..54e65f29f1
--- /dev/null
+++ b/include/configs/ten64.h
@@ -0,0 +1,55 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2017 NXP
+ * Copyright 2019-2021 Traverse Technologies
+ */
+
+#ifndef __TEN64_H
+#define __TEN64_H
+
+#include "ls1088a_common.h"
+
+#define CONFIG_SYS_CLK_FREQ		100000000
+#define COUNTER_FREQUENCY		25000000	/* 25MHz */
+
+#define CONFIG_DIMM_SLOTS_PER_CTLR	1
+
+#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000
+
+#define QSPI_NOR_BOOTCOMMAND	"run distro_bootcmd"
+#define SD_BOOTCOMMAND		"run distro_bootcmd"
+
+#define QSPI_MC_INIT_CMD				\
+	"sf probe 0:0 && sf read 0x80000000 0x300000 0x200000 &&"	\
+	"sf read 0x80200000 0x5C0000 0x40000 &&"				\
+	"fsl_mc start mc 0x80000000 0x80200000 && " \
+	"sf read 0x80300000 0x580000 0x40000 && fsl_mc lazyapply DPL 0x80300000\0"
+#define SD_MC_INIT_CMD				\
+	"mmcinfo; fatload mmc 0 0x80000000 mcfirmware/mc_ls1088a.itb; "\
+	"fatload mmc 0 0x80200000 dpaa2config/dpc.0x1D-0x0D.dtb; "\
+	"fsl_mc start mc 0x80000000 0x80200000\0"
+
+#define BOOT_TARGET_DEVICES(func) \
+	func(NVME, nvme, 0) \
+	func(USB, usb, 0) \
+	func(MMC, mmc, 0) \
+	func(SCSI, scsi, 0) \
+	func(DHCP, dhcp, 0) \
+	func(PXE, pxe, 0)
+#include <config_distro_bootcmd.h>
+
+#undef CONFIG_EXTRA_ENV_SETTINGS
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"BOARD=ten64\0"					\
+	"fdt_addr_r=0x90000000\0"		\
+	"fdt_high=0xa0000000\0"			\
+	"kernel_addr_r=0x81000000\0"		\
+	"load_addr=0xa0000000\0"		\
+	BOOTENV \
+	"load_efi_dtb=mtd read devicetree $fdt_addr_r && fdt addr $fdt_addr_r && " \
+	"fdt resize && fdt boardsetup\0" \
+	"bootcmd_recovery=mtd read recovery 0xa0000000; mtd read dpl 0x80100000 && " \
+	"fsl_mc apply DPL 0x80100000 && bootm 0xa0000000#ten64\0"
+
+#endif /* __TEN64_H */