]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
board: traverse: add initial Ten64 support
authorMathew McBride <matt@traverse.com.au>
Mon, 31 Jan 2022 13:04:43 +0000 (18:34 +0530)
committerPriyanka Jain <priyanka.jain@nxp.com>
Tue, 1 Feb 2022 09:34:24 +0000 (15:04 +0530)
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>
[Rebased]
Signed-off-by: Priyanka Jain <priyanka.jain@nxp.com>
arch/arm/Kconfig
arch/arm/dts/Makefile
arch/arm/dts/fsl-ls1088a-ten64.dts [new file with mode: 0644]
board/traverse/ten64/Kconfig [new file with mode: 0644]
board/traverse/ten64/MAINTAINERS [new file with mode: 0644]
board/traverse/ten64/Makefile [new file with mode: 0644]
board/traverse/ten64/eth_ten64.c [new file with mode: 0644]
board/traverse/ten64/ten64.c [new file with mode: 0644]
configs/ten64_tfa_defconfig [new file with mode: 0644]
include/configs/ten64.h [new file with mode: 0644]

index 6b11c3a50d91dff4763a66ab3a8d669cfe0ae20a..eb0f5bcfe5456ff758e2dfb2e322dd207fe9b167 100644 (file)
@@ -1776,6 +1776,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_PXA27X
@@ -2225,6 +2240,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"
index 5d45d19481d3dde346c18bd316c2984765d575db..0ed8de2a8f1b7da04ff54dc6f8f917e7b7c3dd3f 100644 (file)
@@ -485,6 +485,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 (file)
index 0000000..43b669c
--- /dev/null
@@ -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 (file)
index 0000000..ea8e3ea
--- /dev/null
@@ -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 (file)
index 0000000..7b53e87
--- /dev/null
@@ -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 (file)
index 0000000..fd8d5cc
--- /dev/null
@@ -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 (file)
index 0000000..3f96e57
--- /dev/null
@@ -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 (file)
index 0000000..bdabc21
--- /dev/null
@@ -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 (file)
index 0000000..8d45b13
--- /dev/null
@@ -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 (file)
index 0000000..54e65f2
--- /dev/null
@@ -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 */