All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Initial Traverse Ten64 board support
@ 2021-11-10  4:46 Mathew McBride
  2021-11-10  4:46 ` [PATCH v2 1/2] board: traverse: add Ten64 board controller driver Mathew McBride
  2021-11-10  4:46 ` [PATCH v2 2/2] board: traverse: add initial Ten64 support Mathew McBride
  0 siblings, 2 replies; 6+ messages in thread
From: Mathew McBride @ 2021-11-10  4:46 UTC (permalink / raw)
  To: u-boot, Priyanka Jain; +Cc: Mathew McBride

This patchset adds initial support for the Traverse Ten64
family, which is a networking focused Mini-ITX board using
NXP's LS1088A.

This patchset is the bare minimum necessary to get a system
running on U-Boot and booting via distroboot/EFI.

There are still a few more drivers to come, such as the
I2C setup for the USB5744 hub and EMC2301 fan controller.

Additionally, this patchset does not contain any of the
defaults (e.g bootmenu settings) we have in our official
firmware releases.

This set contains two additions:
- The driver for the board microcontroller
  The microcontroller holds the board MAC address
  and controls some board functions (like power to the
  10G retimer).
  This has been placed in boards/traverse/common/ as future
  Traverse products may use it as well.
- The board file itself

Changes in v2:
- Delete #if CONFIG_IS_DEFINED(..) uses
  Most of these are unlikely (such as compiling U-Boot
  with Ethernet and DPAA2) and the rest should go away
  with compiler optimization
- Move microcontroller constants (e.g API call numbers)
  to enum

Mathew McBride (2):
  board: traverse: add Ten64 board controller driver
  board: traverse: add initial Ten64 support

 arch/arm/Kconfig                         |  16 +
 arch/arm/dts/Makefile                    |   2 +
 arch/arm/dts/fsl-ls1088a-ten64.dts       | 377 +++++++++++++++++++
 board/traverse/common/Kconfig            |   6 +
 board/traverse/common/Makefile           |   1 +
 board/traverse/common/ten64-controller.h |  28 ++
 board/traverse/common/ten64_controller.c | 240 +++++++++++++
 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 +++
 14 files changed, 1360 insertions(+)
 create mode 100644 arch/arm/dts/fsl-ls1088a-ten64.dts
 create mode 100644 board/traverse/common/Kconfig
 create mode 100644 board/traverse/common/Makefile
 create mode 100644 board/traverse/common/ten64-controller.h
 create mode 100644 board/traverse/common/ten64_controller.c
 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

-- 
2.30.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/2] board: traverse: add Ten64 board controller driver
  2021-11-10  4:46 [PATCH v2 0/2] Initial Traverse Ten64 board support Mathew McBride
@ 2021-11-10  4:46 ` Mathew McBride
  2021-11-10  4:46 ` [PATCH v2 2/2] board: traverse: add initial Ten64 support Mathew McBride
  1 sibling, 0 replies; 6+ messages in thread
From: Mathew McBride @ 2021-11-10  4:46 UTC (permalink / raw)
  To: u-boot, Priyanka Jain; +Cc: Mathew McBride

Traverse Technologies Ten64 family boards use a microcontroller
to control low level board functions like startup and reset,
as well as holding details such as the board MAC address.

Communication between the CPU and microcontroller is via
I2C.

To keep the driver structure clean between the Ten64 board
file, DM_I2C, and a future utility command, this driver
has been implemented as a misc uclass device.

Signed-off-by: Mathew McBride <matt@traverse.com.au>
---
 board/traverse/common/Kconfig            |   6 +
 board/traverse/common/Makefile           |   1 +
 board/traverse/common/ten64-controller.h |  28 +++
 board/traverse/common/ten64_controller.c | 240 +++++++++++++++++++++++
 4 files changed, 275 insertions(+)
 create mode 100644 board/traverse/common/Kconfig
 create mode 100644 board/traverse/common/Makefile
 create mode 100644 board/traverse/common/ten64-controller.h
 create mode 100644 board/traverse/common/ten64_controller.c

diff --git a/board/traverse/common/Kconfig b/board/traverse/common/Kconfig
new file mode 100644
index 0000000000..d34832bd0d
--- /dev/null
+++ b/board/traverse/common/Kconfig
@@ -0,0 +1,6 @@
+config TEN64_CONTROLLER
+	bool "Enable Ten64 board controller driver"
+	depends on TARGET_TEN64
+	help
+		Support for the board microcontroller on the Traverse
+		Ten64 family of boards.
diff --git a/board/traverse/common/Makefile b/board/traverse/common/Makefile
new file mode 100644
index 0000000000..d31e3535b9
--- /dev/null
+++ b/board/traverse/common/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TEN64_CONTROLLER) += ten64_controller.o
diff --git a/board/traverse/common/ten64-controller.h b/board/traverse/common/ten64-controller.h
new file mode 100644
index 0000000000..fed6af470d
--- /dev/null
+++ b/board/traverse/common/ten64-controller.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+#ifndef TEN64_CNTRL_H
+#define TEN64_CNTRL_H
+
+/**
+ * struct t64uc_board_info - Board Information Structure
+ * @mac: Base MAC address
+ * @cpuId: Microcontroller unique serial number
+ * @fwversion_major: Microcontroller version number (Major)
+ * @fwversion_minor: Microcontroller version number (Minor)
+ * @fwversion_patch: Microcontroller version number (Patch)
+ */
+struct t64uc_board_info {
+	u8 mac[6];
+	u32 cpuId[4];
+	u8 fwversion_major;
+	u8 fwversion_minor;
+	u8 fwversion_patch;
+} __packed;
+
+enum {
+	TEN64_CNTRL_GET_BOARD_INFO,
+	TEN64_CNTRL_10G_OFF,
+	TEN64_CNTRL_10G_ON,
+	TEN64_CNTRL_SET_NEXT_BOOTSRC
+};
+
+#endif
diff --git a/board/traverse/common/ten64_controller.c b/board/traverse/common/ten64_controller.c
new file mode 100644
index 0000000000..d6ef8a8d0d
--- /dev/null
+++ b/board/traverse/common/ten64_controller.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/* Ten64 Board Microcontroller Driver
+ * Copyright 2021 Traverse Technologies Australia
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <misc.h>
+#include <i2c.h>
+#include <hexdump.h>
+#include <dm/device_compat.h>
+#include <inttypes.h>
+#include <linux/delay.h>
+
+#include "ten64-controller.h"
+
+/* Microcontroller command set and structure
+ * These should not be used outside this file
+ */
+
+#define T64_UC_DATA_MAX_SIZE            128U
+#define T64_UC_API_MSG_HEADER_SIZE      4U
+#define T64_UC_API_HEADER_PREAMB        0xcabe
+
+enum {
+	TEN64_UC_CMD_SET_BOARD_MAC = 0x10,
+	TEN64_UC_CMD_GET_BOARD_INFO = 0x11,
+	TEN64_UC_CMD_GET_STATE = 0x20,
+	TEN64_UC_CMD_SET_RESET_BTN_HOLD_TIME = 0x21,
+	TEN64_UC_CMD_ENABLE_RESET_BUTTON = 0x22,
+	TEN64_UC_CMD_SET_NEXT_BOOTSRC = 0x23,
+	TEN64_UC_CMD_ENABLE_10G = 0x24,
+	TEN64_UC_CMD_FWUP_GET_INFO = 0xA0,
+	TEN64_UC_CMD_FWUP_INIT = 0xA1,
+	TEN64_UC_CMD_FWUP_XFER = 0xA2,
+	TEN64_UC_CMD_FWUP_CHECK = 0xA3,
+	TEN64_UC_CMD_FWUPBOOT = 0x0A
+};
+
+/** struct t64uc_message - Wire Format for microcontroller messages
+ * @preamb: Message preamble (always 0xcabe)
+ * @cmd: Command to invoke
+ * @len: Length of data
+ * @data: Command data, up to 128 bytes
+ */
+struct t64uc_message {
+	u16 preamb;
+	u8 cmd;
+	u8 len;
+	u8 data[T64_UC_DATA_MAX_SIZE];
+}  __packed;
+
+enum {
+	T64_CTRL_IO_SET = 1U,
+	T64_CTRL_IO_CLEAR = 2U,
+	T64_CTRL_IO_TOGGLE = 3U,
+	T64_CTRL_IO_RESET = 4U,
+	T64_CTRL_IO_UNKNOWN = 5U
+};
+
+/** struct t64uc_board_10g_enable - Wrapper for 10G enable command
+ * @control: state to set the 10G retimer - either
+ *	     T64_CTRL_IO_CLEAR (0x02) for off or
+ *	     T64_CTRL_IO_SET (0x01) for on.
+ *
+ * This struct exists to simplify the wrapping of the
+ * command value into a microcontroller message and passing into
+ * functions.
+ */
+struct t64uc_board_10g_enable {
+	u8 control;
+} __packed;
+
+/** ten64_controller_send_recv_command() - Wrapper function to
+ * send a command to the microcontroller.
+ * @uc_chip: the DM I2C chip handle for the microcontroller
+ * @uc_cmd: the microcontroller API command code
+ * @uc_cmd_data: pointer to the data struct for this command
+ * @uc_data_len: size of command data struct
+ * @return_data: place to store response from microcontroller, NULL if not expected
+ * @expected_return_len: expected size of microcontroller command response
+ * @return_message_wait: wait this long (in us) before reading the response
+ *
+ * Invoke a microcontroller command and receive a response.
+ * This function includes communicating with the microcontroller over
+ * I2C and encoding a message in the wire format.
+ *
+ * Return: 0 if successful, error code otherwise.
+ * Returns -EBADMSG if the microcontroller response could not be validated,
+ * other error codes may be passed from dm_i2c_xfer()
+ */
+static int ten64_controller_send_recv_command(struct udevice *ucdev, u8 uc_cmd,
+					      void *uc_cmd_data, u8 cmd_data_len,
+					      void *return_data, u8 expected_return_len,
+					      u16 return_message_wait)
+{
+	int ret;
+	struct t64uc_message send, recv;
+	struct i2c_msg command_message, return_message;
+	struct dm_i2c_chip *chip = dev_get_parent_plat(ucdev);
+
+	dev_dbg(ucdev, "%s sending cmd %02X len %d\n", __func__, uc_cmd, cmd_data_len);
+
+	send.preamb = T64_UC_API_HEADER_PREAMB;
+	send.cmd = uc_cmd;
+	send.len = cmd_data_len;
+	if (uc_cmd_data && cmd_data_len > 0)
+		memcpy(send.data, uc_cmd_data, cmd_data_len);
+
+	command_message.addr = chip->chip_addr;
+	command_message.len = T64_UC_API_MSG_HEADER_SIZE + send.len;
+	command_message.buf = (void *)&send;
+	command_message.flags = I2C_M_STOP;
+
+	ret = dm_i2c_xfer(ucdev, &command_message, 1);
+	if (!return_data)
+		return ret;
+
+	udelay(return_message_wait);
+
+	return_message.addr = chip->chip_addr;
+	return_message.len = T64_UC_API_MSG_HEADER_SIZE + expected_return_len;
+	return_message.buf = (void *)&recv;
+	return_message.flags = I2C_M_RD;
+
+	ret = dm_i2c_xfer(ucdev, &return_message, 1);
+	if (ret)
+		return ret;
+
+	if (recv.preamb != T64_UC_API_HEADER_PREAMB) {
+		dev_err(ucdev, "%s: No preamble received in microcontroller response\n",
+			__func__);
+		return -EBADMSG;
+	}
+	if (recv.cmd != uc_cmd) {
+		dev_err(ucdev, "%s: command response mismatch, got %02X expecting %02X\n",
+			__func__, recv.cmd, uc_cmd);
+		return -EBADMSG;
+	}
+	if (recv.len != expected_return_len) {
+		dev_err(ucdev, "%s: received message has unexpected length, got %d expected %d\n",
+			__func__, recv.len, expected_return_len);
+		return -EBADMSG;
+	}
+	memcpy(return_data, recv.data, expected_return_len);
+	return ret;
+}
+
+/** ten64_controller_send_command() - Send command to microcontroller without
+ * expecting a response (for example, invoking a control command)
+ * @uc_chip: the DM I2C chip handle for the microcontroller
+ * @uc_cmd: the microcontroller API command code
+ * @uc_cmd_data: pointer to the data struct for this command
+ * @uc_data_len: size of command data struct
+ */
+static int ten64_controller_send_command(struct udevice *ucdev, u8 uc_cmd,
+					 void *uc_cmd_data, u8 cmd_data_len)
+{
+	return ten64_controller_send_recv_command(ucdev, uc_cmd,
+						  uc_cmd_data, cmd_data_len,
+						  NULL, 0, 0);
+}
+
+/** ten64_controller_get_board_info() -Get board information from microcontroller
+ * @dev: The microcontroller device handle
+ * @out: Pointer to a t64uc_board_info struct that has been allocated by the caller
+ */
+static int ten64_controller_get_board_info(struct udevice *dev, struct t64uc_board_info *out)
+{
+	int ret;
+
+	ret = ten64_controller_send_recv_command(dev, TEN64_UC_CMD_GET_BOARD_INFO,
+						 NULL, 0, out,
+						 sizeof(struct t64uc_board_info),
+						 10000);
+	if (ret) {
+		dev_err(dev, "%s unable to send board info command: %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * ten64_controller_10g_enable_command() - Sends a 10G (Retimer) enable command
+ * to the microcontroller.
+ * @ucdev: The microcontroller udevice
+ * @value: The value flag for the 10G state
+ */
+static int ten64_controller_10g_enable_command(struct udevice *ucdev, u8 value)
+{
+	int ret;
+	struct t64uc_board_10g_enable enable_msg;
+
+	enable_msg.control = value;
+
+	ret = ten64_controller_send_command(ucdev, TEN64_UC_CMD_ENABLE_10G,
+					    &enable_msg, sizeof(enable_msg));
+	if (ret) {
+		dev_err(ucdev, "ERROR sending uC 10G Enable message: %d\n", ret);
+		return -1;
+	}
+
+	return 0;
+}
+
+int ten64_controller_call(struct udevice *dev, int msgid, void *tx_msg, int tx_size,
+			  void *rx_msg, int rx_size)
+{
+	switch (msgid) {
+	case TEN64_CNTRL_GET_BOARD_INFO:
+		return ten64_controller_get_board_info(dev, (struct t64uc_board_info *)rx_msg);
+	case TEN64_CNTRL_10G_OFF:
+		return ten64_controller_10g_enable_command(dev, T64_CTRL_IO_CLEAR);
+	case TEN64_CNTRL_10G_ON:
+		return ten64_controller_10g_enable_command(dev, T64_CTRL_IO_SET);
+	default:
+		dev_err(dev, "%s: Unknown operation %d\n", __func__, msgid);
+	}
+	return -EINVAL;
+}
+
+static struct misc_ops ten64_ctrl_ops  = {
+	.call = ten64_controller_call
+};
+
+static const struct udevice_id ten64_controller_ids[] = {
+	{.compatible = "traverse,ten64-controller"},
+	{}
+};
+
+U_BOOT_DRIVER(ten64_controller) = {
+	.name = "ten64-controller-i2c",
+	.id = UCLASS_MISC,
+	.of_match = ten64_controller_ids,
+	.ops = &ten64_ctrl_ops
+};
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] board: traverse: add initial Ten64 support
  2021-11-10  4:46 [PATCH v2 0/2] Initial Traverse Ten64 board support Mathew McBride
  2021-11-10  4:46 ` [PATCH v2 1/2] board: traverse: add Ten64 board controller driver Mathew McBride
@ 2021-11-10  4:46 ` Mathew McBride
  2021-11-11 18:20   ` Tom Rini
  1 sibling, 1 reply; 6+ messages in thread
From: Mathew McBride @ 2021-11-10  4:46 UTC (permalink / raw)
  To: u-boot, Priyanka Jain; +Cc: Mathew McBride

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

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 */
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] board: traverse: add initial Ten64 support
  2021-11-10  4:46 ` [PATCH v2 2/2] board: traverse: add initial Ten64 support Mathew McBride
@ 2021-11-11 18:20   ` Tom Rini
  2021-11-17 22:09     ` Mathew McBride
  0 siblings, 1 reply; 6+ messages in thread
From: Tom Rini @ 2021-11-11 18:20 UTC (permalink / raw)
  To: Mathew McBride; +Cc: u-boot, Priyanka Jain

[-- Attachment #1: Type: text/plain, Size: 1867 bytes --]

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!

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] board: traverse: add initial Ten64 support
  2021-11-11 18:20   ` Tom Rini
@ 2021-11-17 22:09     ` Mathew McBride
  2021-11-17 22:29       ` Tom Rini
  0 siblings, 1 reply; 6+ messages in thread
From: Mathew McBride @ 2021-11-17 22:09 UTC (permalink / raw)
  To: Tom Rini; +Cc: u-boot, Priyanka Jain

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] board: traverse: add initial Ten64 support
  2021-11-17 22:09     ` Mathew McBride
@ 2021-11-17 22:29       ` Tom Rini
  0 siblings, 0 replies; 6+ messages in thread
From: Tom Rini @ 2021-11-17 22:29 UTC (permalink / raw)
  To: Mathew McBride; +Cc: u-boot, Priyanka Jain

[-- Attachment #1: Type: text/plain, Size: 2771 bytes --]

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.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-11-17 22:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-10  4:46 [PATCH v2 0/2] Initial Traverse Ten64 board support Mathew McBride
2021-11-10  4:46 ` [PATCH v2 1/2] board: traverse: add Ten64 board controller driver Mathew McBride
2021-11-10  4:46 ` [PATCH v2 2/2] board: traverse: add initial Ten64 support Mathew McBride
2021-11-11 18:20   ` Tom Rini
2021-11-17 22:09     ` Mathew McBride
2021-11-17 22:29       ` Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.