All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mathew McBride <matt@traverse.com.au>
To: u-boot@lists.denx.de, Priyanka Jain <priyanka.jain@nxp.com>
Cc: Mathew McBride <matt@traverse.com.au>
Subject: [PATCH v2 2/2] board: traverse: add initial Ten64 support
Date: Wed, 10 Nov 2021 04:46:39 +0000	[thread overview]
Message-ID: <20211110044639.7070-3-matt@traverse.com.au> (raw)
In-Reply-To: <20211110044639.7070-1-matt@traverse.com.au>

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


  parent reply	other threads:[~2021-11-10  4:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2021-11-11 18:20   ` [PATCH v2 2/2] board: traverse: add initial Ten64 support Tom Rini
2021-11-17 22:09     ` Mathew McBride
2021-11-17 22:29       ` Tom Rini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211110044639.7070-3-matt@traverse.com.au \
    --to=matt@traverse.com.au \
    --cc=priyanka.jain@nxp.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.