aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/board/freescale/ls1088a
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/board/freescale/ls1088a')
-rw-r--r--roms/u-boot/board/freescale/ls1088a/Kconfig61
-rw-r--r--roms/u-boot/board/freescale/ls1088a/MAINTAINERS37
-rw-r--r--roms/u-boot/board/freescale/ls1088a/Makefile10
-rw-r--r--roms/u-boot/board/freescale/ls1088a/README145
-rw-r--r--roms/u-boot/board/freescale/ls1088a/ddr.c138
-rw-r--r--roms/u-boot/board/freescale/ls1088a/ddr.h48
-rw-r--r--roms/u-boot/board/freescale/ls1088a/eth_ls1088aqds.c835
-rw-r--r--roms/u-boot/board/freescale/ls1088a/eth_ls1088ardb.c106
-rw-r--r--roms/u-boot/board/freescale/ls1088a/ls1088a.c1059
-rw-r--r--roms/u-boot/board/freescale/ls1088a/ls1088a_qixis.h55
10 files changed, 2494 insertions, 0 deletions
diff --git a/roms/u-boot/board/freescale/ls1088a/Kconfig b/roms/u-boot/board/freescale/ls1088a/Kconfig
new file mode 100644
index 000000000..8bb828e3f
--- /dev/null
+++ b/roms/u-boot/board/freescale/ls1088a/Kconfig
@@ -0,0 +1,61 @@
+if TARGET_LS1088AQDS
+
+config SYS_BOARD
+ default "ls1088a"
+
+config SYS_VENDOR
+ default "freescale"
+
+config SYS_SOC
+ default "fsl-layerscape"
+
+config SYS_CONFIG_NAME
+ default "ls1088aqds"
+
+if FSL_LS_PPA
+config SYS_LS_PPA_FW_ADDR
+ hex "PPA Firmware Addr"
+ default 0x20400000 if SYS_LS_PPA_FW_IN_XIP
+ default 0x400000 if SYS_LS_PPA_FW_IN_MMC || SYS_LS_PPA_FW_IN_NAND
+
+if CHAIN_OF_TRUST
+config SYS_LS_PPA_ESBC_ADDR
+ hex "PPA Firmware HDR Addr"
+ default 0x20680000 if SYS_LS_PPA_FW_IN_XIP
+ default 0x680000 if SYS_LS_PPA_FW_IN_MMC || SYS_LS_PPA_FW_IN_NAND
+endif
+endif
+
+source "board/freescale/common/Kconfig"
+endif
+
+if TARGET_LS1088ARDB
+
+config SYS_BOARD
+ default "ls1088a"
+
+config SYS_VENDOR
+ default "freescale"
+
+config SYS_SOC
+ default "fsl-layerscape"
+
+config SYS_CONFIG_NAME
+ default "ls1088ardb"
+
+if FSL_LS_PPA
+config SYS_LS_PPA_FW_ADDR
+ hex "PPA Firmware Addr"
+ default 0x20400000 if SYS_LS_PPA_FW_IN_XIP
+ default 0x400000 if SYS_LS_PPA_FW_IN_MMC || SYS_LS_PPA_FW_IN_NAND
+
+if CHAIN_OF_TRUST
+config SYS_LS_PPA_ESBC_ADDR
+ hex "PPA Firmware HDR Addr"
+ default 0x20680000 if SYS_LS_PPA_FW_IN_XIP
+ default 0x680000 if SYS_LS_PPA_FW_IN_MMC || SYS_LS_PPA_FW_IN_NAND
+endif
+endif
+
+source "board/freescale/common/Kconfig"
+endif
diff --git a/roms/u-boot/board/freescale/ls1088a/MAINTAINERS b/roms/u-boot/board/freescale/ls1088a/MAINTAINERS
new file mode 100644
index 000000000..5c7925a95
--- /dev/null
+++ b/roms/u-boot/board/freescale/ls1088a/MAINTAINERS
@@ -0,0 +1,37 @@
+LS1088ARDB BOARD
+M: Ashish Kumar <Ashish.Kumar@nxp.com>
+M: Rajesh Bhagat <rajesh.bhagat@nxp.com>
+S: Maintained
+F: board/freescale/ls1088a/
+F: include/configs/ls1088ardb.h
+F: configs/ls1088ardb_qspi_defconfig
+F: configs/ls1088ardb_sdcard_qspi_defconfig
+F: configs/ls1088ardb_tfa_defconfig
+F: configs/ls1088ardb_tfa_SECURE_BOOT_defconfig
+
+LS1088AQDS BOARD
+M: Ashish Kumar <Ashish.Kumar@nxp.com>
+M: Rajesh Bhagat <rajesh.bhagat@nxp.com>
+S: Maintained
+F: board/freescale/ls1088a/
+F: include/configs/ls1088aqds.h
+F: configs/ls1088aqds_qspi_defconfig
+F: configs/ls1088aqds_sdcard_qspi_defconfig
+F: configs/ls1088aqds_defconfig
+F: configs/ls1088aqds_sdcard_ifc_defconfig
+F: configs/ls1088aqds_tfa_defconfig
+
+LS1088AQDS_QSPI_SECURE_BOOT BOARD
+M: Udit Agarwal <udit.agarwal@nxp.com>
+S: Maintained
+F: configs/ls1088aqds_qspi_SECURE_BOOT_defconfig
+
+LS1088ARDB_QSPI_SECURE_BOOT BOARD
+M: Udit Agarwal <udit.agarwal@nxp.com>
+S: Maintained
+F: configs/ls1088ardb_qspi_SECURE_BOOT_defconfig
+
+LS1088ARDB_SD_SECURE_BOOT BOARD
+M: Udit Agarwal <udit.agarwal@nxp.com>
+S: Maintained
+F: configs/ls1088ardb_sdcard_qspi_SECURE_BOOT_defconfig
diff --git a/roms/u-boot/board/freescale/ls1088a/Makefile b/roms/u-boot/board/freescale/ls1088a/Makefile
new file mode 100644
index 000000000..c2b0e7dc0
--- /dev/null
+++ b/roms/u-boot/board/freescale/ls1088a/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2017 NXP
+
+obj-y += ls1088a.o
+obj-y += ddr.o
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_TARGET_LS1088ARDB) += eth_ls1088ardb.o
+obj-$(CONFIG_TARGET_LS1088AQDS) += eth_ls1088aqds.o
+endif
diff --git a/roms/u-boot/board/freescale/ls1088a/README b/roms/u-boot/board/freescale/ls1088a/README
new file mode 100644
index 000000000..aa0fb6ac6
--- /dev/null
+++ b/roms/u-boot/board/freescale/ls1088a/README
@@ -0,0 +1,145 @@
+Overview
+--------
+The LS1088A Reference Design (RDB) is a high-performance computing,
+evaluation, and development platform that supports ARM SoC LS1088A and its
+derivatives.
+
+
+LS1088A SoC Overview
+--------------------------------------
+Please refer arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc
+
+RDB Default Switch Settings (1: ON; 0: OFF)
+-------------------------------------------
+
+For QSPI Boot
+SW1 0011 0001
+SW2 x100 0000
+SW3 1111 0010
+SW4 1001 0011
+SW5 1111 0000
+
+For SD Boot
+SW1 0010 0000
+SW2 0100 0000
+SW3 1111 0010
+SW4 1001 0011
+SW5 1111 0000
+
+For eMMC Boot
+SW1 0010 0000
+SW2 1100 0000
+SW3 1111 0010
+SW4 1001 0011
+SW5 1111 0000
+
+Alternately you can use this command to switch from QSPI to SD
+
+=> i2c mw 66 0x60 0x20; i2c mw 66 10 10;i2c mw 66 10 21
+
+ LS1088ARDB board Overview
+ -------------------------
+ - SERDES Connections, 16 lanes supporting:
+ - PCI Express - 3.0
+ - SATA 3.0
+ - XFI
+ - QSGMII
+ - DDR Controller
+ - One ports of 72-bits (8-bits ECC, 64-bits DATA) DDR4. Each port supports four
+ chip-selects on one DIMM connector. Support is up to 2133MT/s, Although MAX default
+ with FSL refernce software is 2100MT/s
+ - 2 QSPI-NOR Spansion(S25FS512SDSMFI011) flash of size 64MB
+ - IFC/Local Bus
+ - One 2 GB NAND flash with ECC support, not as boot source
+ - CPLD of size 2K
+ - USB 3.0
+ - Two high speed USB 3.0 ports
+ - First USB 3.0 port configured as Host with Type-A connector
+ - Second USB 3.0 port configured as OTG with micro-AB connector
+ - SDHC/eMMC
+ - SDHC slot and onboard eMMC are muxed together
+ - 4 I2C controllers
+ - Two SATA onboard connectors
+ - 2 UART
+ - JTAG support
+ - QSPI emulator support
+ - TDM riser support
+
+QDS Default Switch Settings (1: ON; 0: OFF)
+-------------------------------------------
+
+For 16b IFC-NOR
+SW1 0001 0010
+SW2 x110 1111
+
+For QSPI Boot
+SW1 0011 0001
+SW2 0110 1111
+
+For SD Boot
+SW1 0010 0000
+SW2 0110 1111
+
+For eMMC Boot
+SW1 0010 0000
+SW2 1110 1111
+
+For I2C (ext. addr.)
+SW1 0010 0100
+SW2 1110 1111
+
+SW3 to SW12 are identical for all boot source
+
+SW3 0010 0100
+SW4 0010 0000
+SW5 1110 0111
+SW6 1110 1000
+SW7 0001 1101
+SW8 0000 1101
+SW9 1100 1010
+SW10 1110 1000
+SW11 1111 0100
+SW12 1111 1111
+
+ LS1088AQDS board Overview
+ -------------------------
+ - SERDES Connections, 16 lanes supporting:
+ - PCI Express - 3.0
+ - SATA 3.0
+ - 2 XFI
+ - QSGMII, SGMII with help for Riser card
+ - 2 RGMII
+ - 5 slot for Riser card or PCIe NIC
+ - DDR Controller
+ - One ports of 72-bits (8-bits ECC, 64-bits DATA) DDR4. Each port supports four
+ chip-selects on one DIMM connector. Support is up to 2133MT/s, Although MAX default
+ with FSL refernce software is 2100MT/s
+ - 2 QSPI-NOR Spansion(S25FS512SDSMFI011) flash of size 64MB
+ - IFC/Local Bus
+ - One 2 GB NAND flash with ECC support, not as boot source
+ - CPLD of size 2K
+ - USB 3.0
+ - Two high speed USB 3.0 ports
+ - First USB 3.0 port configured as Host with Type-A connector
+ - Second USB 3.0 port configured as OTG with micro-AB connector
+ - SDHC/eMMC
+ - SDHC/eMMC slot via adaptor
+ - 4 I2C controllers
+ - Two SATA onboard connectors
+ - 2 UART
+ - JTAG support
+ - DSPI
+ - PROMJET support
+ - QSPI emulator support
+ - TDM riser support
+
+QSPI flash memory map valid for both QDS and RDB
+ Image Flash Offset
+ RCW+PBI 0x00000000
+ Boot firmware (U-Boot) 0x00100000
+ Boot firmware Environment 0x00300000
+ PPA firmware 0x00400000
+ DPAA2 MC 0x00A00000
+ DPAA2 DPL 0x00D00000
+ DPAA2 DPC 0x00E00000
+ Kernel.itb 0x01000000
diff --git a/roms/u-boot/board/freescale/ls1088a/ddr.c b/roms/u-boot/board/freescale/ls1088a/ddr.c
new file mode 100644
index 000000000..995c42960
--- /dev/null
+++ b/roms/u-boot/board/freescale/ls1088a/ddr.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017 NXP
+ */
+
+#include <common.h>
+#include <fsl_ddr_sdram.h>
+#include <fsl_ddr_dimm_params.h>
+#include <log.h>
+#include <asm/arch/soc.h>
+#include <asm/arch/clock.h>
+#include <asm/global_data.h>
+#include "ddr.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_VID) && (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
+static void fsl_ddr_setup_0v9_volt(memctl_options_t *popts)
+{
+ int vdd;
+
+ vdd = get_core_volt_from_fuse();
+ /* Nothing to do for silicons doesn't support VID */
+ if (vdd < 0)
+ return;
+
+ if (vdd == 900) {
+ popts->ddr_cdr1 |= DDR_CDR1_V0PT9_EN;
+ debug("VID: configure DDR to support 900 mV\n");
+ }
+}
+#endif
+
+void fsl_ddr_board_options(memctl_options_t *popts,
+ dimm_params_t *pdimm,
+ unsigned int ctrl_num)
+{
+ const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
+ ulong ddr_freq;
+
+ if (ctrl_num > 1) {
+ printf("Not supported controller number %d\n", ctrl_num);
+ return;
+ }
+ if (!pdimm->n_ranks)
+ return;
+
+ /*
+ * we use identical timing for all slots. If needed, change the code
+ * to pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num];
+ */
+ pbsp = udimms[0];
+
+ /* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr
+ * freqency and n_banks specified in board_specific_parameters table.
+ */
+ ddr_freq = get_ddr_freq(0) / 1000000;
+ while (pbsp->datarate_mhz_high) {
+ if (pbsp->n_ranks == pdimm->n_ranks) {
+ if (ddr_freq <= pbsp->datarate_mhz_high) {
+ popts->clk_adjust = pbsp->clk_adjust;
+ popts->wrlvl_start = pbsp->wrlvl_start;
+ popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
+ popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
+ goto found;
+ }
+ pbsp_highest = pbsp;
+ }
+ pbsp++;
+ }
+
+ if (pbsp_highest) {
+ printf("Error: board specific timing not found for %lu MT/s\n",
+ ddr_freq);
+ printf("Trying to use the highest speed (%u) parameters\n",
+ pbsp_highest->datarate_mhz_high);
+ popts->clk_adjust = pbsp_highest->clk_adjust;
+ popts->wrlvl_start = pbsp_highest->wrlvl_start;
+ popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
+ popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
+ } else {
+ panic("DIMM is not supported by this board");
+ }
+found:
+ debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n"
+ "\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, wrlvl_ctrl_3 0x%x\n",
+ pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb,
+ pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
+ pbsp->wrlvl_ctl_3);
+
+
+
+ popts->half_strength_driver_enable = 0;
+ /*
+ * Write leveling override
+ */
+ popts->wrlvl_override = 1;
+ popts->wrlvl_sample = 0xf;
+
+
+ /* Enable ZQ calibration */
+ popts->zq_en = 1;
+
+ /* Enable DDR hashing */
+ popts->addr_hash = 1;
+
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+#if defined(CONFIG_VID) && (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
+ fsl_ddr_setup_0v9_volt(popts);
+#endif
+
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
+ DDR_CDR2_VREF_TRAIN_EN | DDR_CDR2_VREF_RANGE_2;
+}
+
+#ifdef CONFIG_TFABOOT
+int fsl_initdram(void)
+{
+ gd->ram_size = tfa_get_dram_size();
+
+ if (!gd->ram_size)
+ gd->ram_size = fsl_ddr_sdram_size();
+
+ return 0;
+}
+#else
+int fsl_initdram(void)
+{
+ puts("Initializing DDR....using SPD\n");
+
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+ gd->ram_size = fsl_ddr_sdram_size();
+#else
+ gd->ram_size = fsl_ddr_sdram();
+#endif
+ return 0;
+}
+#endif /* CONFIG_TFABOOT */
diff --git a/roms/u-boot/board/freescale/ls1088a/ddr.h b/roms/u-boot/board/freescale/ls1088a/ddr.h
new file mode 100644
index 000000000..b35c4ae2d
--- /dev/null
+++ b/roms/u-boot/board/freescale/ls1088a/ddr.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2017 NXP
+ */
+
+#ifndef __LS1088A_DDR_H__
+#define __LS1088A_DDR_H__
+struct board_specific_parameters {
+ u32 n_ranks;
+ u32 datarate_mhz_high;
+ u32 rank_gb;
+ u32 clk_adjust;
+ u32 wrlvl_start;
+ u32 wrlvl_ctl_2;
+ u32 wrlvl_ctl_3;
+};
+
+/*
+ * These tables contain all valid speeds we want to override with board
+ * specific parameters. datarate_mhz_high values need to be in ascending order
+ * for each n_ranks group.
+ */
+
+static const struct board_specific_parameters udimm0[] = {
+ /*
+ * memory controller 0
+ * num| hi| rank| clk| wrlvl | wrlvl | wrlvl
+ * ranks| mhz| GB |adjst| start | ctl2 | ctl3
+ */
+#if defined(CONFIG_TARGET_LS1088ARDB)
+
+ {2, 1666, 0, 8, 8, 0x090A0B0E, 0x0F10110D,},
+ {2, 1900, 0, 8, 9, 0x0A0B0C10, 0x1112140E,},
+ {2, 2300, 0, 8, 9, 0x0A0C0E11, 0x1214160F,},
+ {}
+#elif defined(CONFIG_TARGET_LS1088AQDS)
+ {2, 1666, 0, 8, 8, 0x0A0A0C0E, 0x0F10110C,},
+ {2, 1900, 0, 8, 9, 0x0A0B0C10, 0x1112140E,},
+ {2, 2300, 0, 4, 9, 0x0A0C0D11, 0x1214150E,},
+ {}
+
+#endif
+};
+
+static const struct board_specific_parameters *udimms[] = {
+ udimm0,
+};
+#endif
diff --git a/roms/u-boot/board/freescale/ls1088a/eth_ls1088aqds.c b/roms/u-boot/board/freescale/ls1088a/eth_ls1088aqds.c
new file mode 100644
index 000000000..140733de6
--- /dev/null
+++ b/roms/u-boot/board/freescale/ls1088a/eth_ls1088aqds.c
@@ -0,0 +1,835 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017 NXP
+ */
+
+#include <common.h>
+#include <command.h>
+#include <env.h>
+#include <log.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <asm/arch/fsl_serdes.h>
+#include <hwconfig.h>
+#include <fsl_mdio.h>
+#include <malloc.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <i2c.h>
+#include <miiphy.h>
+#include <fsl-mc/fsl_mc.h>
+#include <fsl-mc/ldpaa_wriop.h>
+#include <linux/delay.h>
+
+#include "../common/qixis.h"
+
+#include "ls1088a_qixis.h"
+
+#ifndef CONFIG_DM_ETH
+#ifdef CONFIG_FSL_MC_ENET
+
+#define SFP_TX 0
+
+ /* - In LS1088A A there are only 16 SERDES lanes, spread across 2 SERDES banks.
+ * Bank 1 -> Lanes A, B, C, D,
+ * Bank 2 -> Lanes A,B, C, D,
+ */
+
+ /* Mapping of 8 SERDES lanes to LS1088A QDS board slots. A value of '0' here
+ * means that the mapping must be determined dynamically, or that the lane
+ * maps to something other than a board slot.
+ */
+
+static u8 lane_to_slot_fsm1[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
+ * housed.
+ */
+
+static int xqsgii_riser_phy_addr[] = {
+ XQSGMII_CARD_PHY1_PORT0_ADDR,
+ XQSGMII_CARD_PHY2_PORT0_ADDR,
+ XQSGMII_CARD_PHY3_PORT0_ADDR,
+ XQSGMII_CARD_PHY4_PORT0_ADDR,
+ XQSGMII_CARD_PHY3_PORT2_ADDR,
+ XQSGMII_CARD_PHY1_PORT2_ADDR,
+ XQSGMII_CARD_PHY4_PORT2_ADDR,
+ XQSGMII_CARD_PHY2_PORT2_ADDR,
+};
+
+static int sgmii_riser_phy_addr[] = {
+ SGMII_CARD_PORT1_PHY_ADDR,
+ SGMII_CARD_PORT2_PHY_ADDR,
+ SGMII_CARD_PORT3_PHY_ADDR,
+ SGMII_CARD_PORT4_PHY_ADDR,
+};
+
+/* Slot2 does not have EMI connections */
+#define EMI_NONE 0xFF
+#define EMI1_RGMII1 0
+#define EMI1_RGMII2 1
+#define EMI1_SLOT1 2
+
+static const char * const mdio_names[] = {
+ "LS1088A_QDS_MDIO0",
+ "LS1088A_QDS_MDIO1",
+ "LS1088A_QDS_MDIO2",
+ DEFAULT_WRIOP_MDIO2_NAME,
+};
+
+struct ls1088a_qds_mdio {
+ u8 muxval;
+ struct mii_dev *realbus;
+};
+
+struct reg_pair {
+ uint addr;
+ u8 *val;
+};
+
+static void sgmii_configure_repeater(int dpmac)
+{
+ struct mii_dev *bus;
+ uint8_t a = 0xf;
+ int i, j, k, ret;
+ unsigned short value;
+ const char *dev = "LS1088A_QDS_MDIO2";
+ int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b};
+ int i2c_phy_addr = 0;
+ int phy_addr = 0;
+
+ uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
+ uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
+ uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
+ uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
+
+ u8 reg_val[6] = {0x18, 0x38, 0x4, 0x14, 0xb5, 0x20};
+ struct reg_pair reg_pair[10] = {
+ {6, &reg_val[0]}, {4, &reg_val[1]},
+ {8, &reg_val[2]}, {0xf, NULL},
+ {0x11, NULL}, {0x16, NULL},
+ {0x18, NULL}, {0x23, &reg_val[3]},
+ {0x2d, &reg_val[4]}, {4, &reg_val[5]},
+ };
+#if CONFIG_IS_ENABLED(DM_I2C)
+ struct udevice *udev;
+#endif
+
+ /* Set I2c to Slot 1 */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ ret = i2c_write(0x77, 0, 0, &a, 1);
+#else
+ ret = i2c_get_chip_for_busnum(0, 0x77, 1, &udev);
+ if (!ret)
+ ret = dm_i2c_write(udev, 0, &a, 1);
+#endif
+ if (ret)
+ goto error;
+
+ switch (dpmac) {
+ case 1:
+ i2c_phy_addr = i2c_addr[1];
+ phy_addr = 4;
+ break;
+ case 2:
+ i2c_phy_addr = i2c_addr[0];
+ phy_addr = 0;
+ break;
+ case 3:
+ i2c_phy_addr = i2c_addr[3];
+ phy_addr = 0xc;
+ break;
+ case 7:
+ i2c_phy_addr = i2c_addr[2];
+ phy_addr = 8;
+ break;
+ }
+
+ /* Check the PHY status */
+ ret = miiphy_set_current_dev(dev);
+ if (ret > 0)
+ goto error;
+
+ bus = mdio_get_current_dev();
+ debug("Reading from bus %s\n", bus->name);
+
+ ret = miiphy_write(dev, phy_addr, 0x1f, 3);
+ if (ret > 0)
+ goto error;
+
+ mdelay(10);
+ ret = miiphy_read(dev, phy_addr, 0x11, &value);
+ if (ret > 0)
+ goto error;
+
+ mdelay(10);
+
+ if ((value & 0xfff) == 0x401) {
+ miiphy_write(dev, phy_addr, 0x1f, 0);
+ printf("DPMAC %d:PHY is ..... Configured\n", dpmac);
+ return;
+ }
+
+#if CONFIG_IS_ENABLED(DM_I2C)
+ i2c_get_chip_for_busnum(0, i2c_phy_addr, 1, &udev);
+#endif
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ reg_pair[3].val = &ch_a_eq[i];
+ reg_pair[4].val = &ch_a_ctl2[j];
+ reg_pair[5].val = &ch_b_eq[i];
+ reg_pair[6].val = &ch_b_ctl2[j];
+ for (k = 0; k < 10; k++) {
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ ret = i2c_write(i2c_phy_addr,
+ reg_pair[k].addr,
+ 1, reg_pair[k].val, 1);
+#else
+ ret = i2c_get_chip_for_busnum(0,
+ i2c_phy_addr,
+ 1, &udev);
+ if (!ret)
+ ret = dm_i2c_write(udev,
+ reg_pair[k].addr,
+ reg_pair[k].val, 1);
+#endif
+ if (ret)
+ goto error;
+ }
+
+ mdelay(100);
+ ret = miiphy_read(dev, phy_addr, 0x11, &value);
+ if (ret > 0)
+ goto error;
+
+ mdelay(100);
+ ret = miiphy_read(dev, phy_addr, 0x11, &value);
+ if (ret > 0)
+ goto error;
+
+ if ((value & 0xfff) == 0x401) {
+ printf("DPMAC %d :PHY is configured ",
+ dpmac);
+ printf("after setting repeater 0x%x\n",
+ value);
+ i = 5;
+ j = 5;
+ } else {
+ printf("DPMAC %d :PHY is failed to ",
+ dpmac);
+ printf("configure the repeater 0x%x\n", value);
+ }
+ }
+ }
+ miiphy_write(dev, phy_addr, 0x1f, 0);
+error:
+ if (ret)
+ printf("DPMAC %d ..... FAILED to configure PHY\n", dpmac);
+ return;
+}
+
+static void qsgmii_configure_repeater(int dpmac)
+{
+ uint8_t a = 0xf;
+ int i, j, k;
+ int i2c_phy_addr = 0;
+ int phy_addr = 0;
+ int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b};
+
+ uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
+ uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
+ uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
+ uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
+
+ u8 reg_val[6] = {0x18, 0x38, 0x4, 0x14, 0xb5, 0x20};
+ struct reg_pair reg_pair[10] = {
+ {6, &reg_val[0]}, {4, &reg_val[1]},
+ {8, &reg_val[2]}, {0xf, NULL},
+ {0x11, NULL}, {0x16, NULL},
+ {0x18, NULL}, {0x23, &reg_val[3]},
+ {0x2d, &reg_val[4]}, {4, &reg_val[5]},
+ };
+
+ const char *dev = mdio_names[EMI1_SLOT1];
+ int ret = 0;
+ unsigned short value;
+#if CONFIG_IS_ENABLED(DM_I2C)
+ struct udevice *udev;
+#endif
+
+ /* Set I2c to Slot 1 */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ ret = i2c_write(0x77, 0, 0, &a, 1);
+#else
+ ret = i2c_get_chip_for_busnum(0, 0x77, 1, &udev);
+ if (!ret)
+ ret = dm_i2c_write(udev, 0, &a, 1);
+#endif
+ if (ret)
+ goto error;
+
+ switch (dpmac) {
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ i2c_phy_addr = i2c_addr[2];
+ phy_addr = 8;
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ i2c_phy_addr = i2c_addr[3];
+ phy_addr = 0xc;
+ break;
+ }
+
+ /* Check the PHY status */
+ ret = miiphy_set_current_dev(dev);
+ ret = miiphy_write(dev, phy_addr, 0x1f, 3);
+ mdelay(10);
+ ret = miiphy_read(dev, phy_addr, 0x11, &value);
+ mdelay(10);
+ ret = miiphy_read(dev, phy_addr, 0x11, &value);
+ mdelay(10);
+ if ((value & 0xf) == 0xf) {
+ miiphy_write(dev, phy_addr, 0x1f, 0);
+ printf("DPMAC %d :PHY is ..... Configured\n", dpmac);
+ return;
+ }
+
+#if CONFIG_IS_ENABLED(DM_I2C)
+ i2c_get_chip_for_busnum(0, i2c_phy_addr, 1, &udev);
+#endif
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ reg_pair[3].val = &ch_a_eq[i];
+ reg_pair[4].val = &ch_a_ctl2[j];
+ reg_pair[5].val = &ch_b_eq[i];
+ reg_pair[6].val = &ch_b_ctl2[j];
+
+ for (k = 0; k < 10; k++) {
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ ret = i2c_write(i2c_phy_addr,
+ reg_pair[k].addr,
+ 1, reg_pair[k].val, 1);
+#else
+ ret = i2c_get_chip_for_busnum(0,
+ i2c_addr[dpmac],
+ 1, &udev);
+ if (!ret)
+ ret = dm_i2c_write(udev,
+ reg_pair[k].addr,
+ reg_pair[k].val, 1);
+#endif
+ if (ret)
+ goto error;
+ }
+
+ ret = miiphy_read(dev, phy_addr, 0x11, &value);
+ if (ret > 0)
+ goto error;
+ mdelay(1);
+ ret = miiphy_read(dev, phy_addr, 0x11, &value);
+ if (ret > 0)
+ goto error;
+ mdelay(10);
+ if ((value & 0xf) == 0xf) {
+ miiphy_write(dev, phy_addr, 0x1f, 0);
+ printf("DPMAC %d :PHY is ..... Configured\n",
+ dpmac);
+ return;
+ }
+ }
+ }
+error:
+ printf("DPMAC %d :PHY ..... FAILED to configure PHY\n", dpmac);
+ return;
+}
+
+static const char *ls1088a_qds_mdio_name_for_muxval(u8 muxval)
+{
+ return mdio_names[muxval];
+}
+
+struct mii_dev *mii_dev_for_muxval(u8 muxval)
+{
+ struct mii_dev *bus;
+ const char *name = ls1088a_qds_mdio_name_for_muxval(muxval);
+
+ if (!name) {
+ printf("No bus for muxval %x\n", muxval);
+ return NULL;
+ }
+
+ bus = miiphy_get_dev_by_name(name);
+
+ if (!bus) {
+ printf("No bus by name %s\n", name);
+ return NULL;
+ }
+
+ return bus;
+}
+
+static void ls1088a_qds_enable_SFP_TX(u8 muxval)
+{
+ u8 brdcfg9;
+
+ brdcfg9 = QIXIS_READ(brdcfg[9]);
+ brdcfg9 &= ~BRDCFG9_SFPTX_MASK;
+ brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT);
+ QIXIS_WRITE(brdcfg[9], brdcfg9);
+}
+
+static void ls1088a_qds_mux_mdio(u8 muxval)
+{
+ u8 brdcfg4;
+
+ if (muxval <= 5) {
+ brdcfg4 = QIXIS_READ(brdcfg[4]);
+ brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
+ brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
+ QIXIS_WRITE(brdcfg[4], brdcfg4);
+ }
+}
+
+static int ls1088a_qds_mdio_read(struct mii_dev *bus, int addr,
+ int devad, int regnum)
+{
+ struct ls1088a_qds_mdio *priv = bus->priv;
+
+ ls1088a_qds_mux_mdio(priv->muxval);
+
+ return priv->realbus->read(priv->realbus, addr, devad, regnum);
+}
+
+static int ls1088a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
+ int regnum, u16 value)
+{
+ struct ls1088a_qds_mdio *priv = bus->priv;
+
+ ls1088a_qds_mux_mdio(priv->muxval);
+
+ return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
+}
+
+static int ls1088a_qds_mdio_reset(struct mii_dev *bus)
+{
+ struct ls1088a_qds_mdio *priv = bus->priv;
+
+ return priv->realbus->reset(priv->realbus);
+}
+
+static int ls1088a_qds_mdio_init(char *realbusname, u8 muxval)
+{
+ struct ls1088a_qds_mdio *pmdio;
+ struct mii_dev *bus = mdio_alloc();
+
+ if (!bus) {
+ printf("Failed to allocate ls1088a_qds MDIO bus\n");
+ return -1;
+ }
+
+ pmdio = malloc(sizeof(*pmdio));
+ if (!pmdio) {
+ printf("Failed to allocate ls1088a_qds private data\n");
+ free(bus);
+ return -1;
+ }
+
+ bus->read = ls1088a_qds_mdio_read;
+ bus->write = ls1088a_qds_mdio_write;
+ bus->reset = ls1088a_qds_mdio_reset;
+ sprintf(bus->name, ls1088a_qds_mdio_name_for_muxval(muxval));
+
+ pmdio->realbus = miiphy_get_dev_by_name(realbusname);
+
+ if (!pmdio->realbus) {
+ printf("No bus with name %s\n", realbusname);
+ free(bus);
+ free(pmdio);
+ return -1;
+ }
+
+ pmdio->muxval = muxval;
+ bus->priv = pmdio;
+
+ return mdio_register(bus);
+}
+
+/*
+ * Initialize the dpmac_info array.
+ *
+ */
+static void initialize_dpmac_to_slot(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+ u32 serdes1_prtcl, cfg;
+
+ cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
+ FSL_CHASSIS3_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
+ serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg);
+
+ switch (serdes1_prtcl) {
+ case 0x12:
+ printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
+ serdes1_prtcl);
+ lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1;
+ lane_to_slot_fsm1[1] = EMI1_SLOT1 - 1;
+ lane_to_slot_fsm1[2] = EMI1_SLOT1 - 1;
+ lane_to_slot_fsm1[3] = EMI1_SLOT1 - 1;
+ break;
+ case 0x15:
+ case 0x1D:
+ printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
+ serdes1_prtcl);
+ lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1;
+ lane_to_slot_fsm1[1] = EMI1_SLOT1 - 1;
+ lane_to_slot_fsm1[2] = EMI_NONE;
+ lane_to_slot_fsm1[3] = EMI_NONE;
+ break;
+ case 0x1E:
+ printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
+ serdes1_prtcl);
+ lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1;
+ lane_to_slot_fsm1[1] = EMI1_SLOT1 - 1;
+ lane_to_slot_fsm1[2] = EMI1_SLOT1 - 1;
+ lane_to_slot_fsm1[3] = EMI_NONE;
+ break;
+ case 0x3A:
+ printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
+ serdes1_prtcl);
+ lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1;
+ lane_to_slot_fsm1[1] = EMI_NONE;
+ lane_to_slot_fsm1[2] = EMI1_SLOT1 - 1;
+ lane_to_slot_fsm1[3] = EMI1_SLOT1 - 1;
+ break;
+
+ default:
+ printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
+ __func__, serdes1_prtcl);
+ break;
+ }
+}
+
+void ls1088a_handle_phy_interface_sgmii(int dpmac_id)
+{
+ struct mii_dev *bus;
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+ u32 serdes1_prtcl, cfg;
+
+ cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
+ FSL_CHASSIS3_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
+ serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg);
+
+ int *riser_phy_addr;
+ char *env_hwconfig = env_get("hwconfig");
+
+ if (hwconfig_f("xqsgmii", env_hwconfig))
+ riser_phy_addr = &xqsgii_riser_phy_addr[0];
+ else
+ riser_phy_addr = &sgmii_riser_phy_addr[0];
+
+ switch (serdes1_prtcl) {
+ case 0x12:
+ case 0x15:
+ case 0x1E:
+ case 0x3A:
+ switch (dpmac_id) {
+ case 1:
+ wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[1]);
+ break;
+ case 2:
+ wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[0]);
+ break;
+ case 3:
+ wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[3]);
+ break;
+ case 7:
+ wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[2]);
+ break;
+ default:
+ printf("WRIOP: Wrong DPMAC%d set to SGMII", dpmac_id);
+ break;
+ }
+ break;
+ default:
+ printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
+ __func__, serdes1_prtcl);
+ return;
+ }
+ dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
+ bus = mii_dev_for_muxval(EMI1_SLOT1);
+ wriop_set_mdio(dpmac_id, bus);
+}
+
+void ls1088a_handle_phy_interface_qsgmii(int dpmac_id)
+{
+ struct mii_dev *bus;
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+ u32 serdes1_prtcl, cfg;
+
+ cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
+ FSL_CHASSIS3_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
+ serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg);
+
+ switch (serdes1_prtcl) {
+ case 0x1D:
+ case 0x1E:
+ switch (dpmac_id) {
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ wriop_set_phy_address(dpmac_id, 0, dpmac_id + 9);
+ break;
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ wriop_set_phy_address(dpmac_id, 0, dpmac_id + 1);
+ break;
+ }
+
+ dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
+ bus = mii_dev_for_muxval(EMI1_SLOT1);
+ wriop_set_mdio(dpmac_id, bus);
+ break;
+ default:
+ printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
+ serdes1_prtcl);
+ break;
+ }
+}
+
+void ls1088a_handle_phy_interface_xsgmii(int i)
+{
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+ u32 serdes1_prtcl, cfg;
+
+ cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
+ FSL_CHASSIS3_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
+ serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg);
+
+ switch (serdes1_prtcl) {
+ case 0x15:
+ case 0x1D:
+ case 0x1E:
+ wriop_set_phy_address(i, 0, i + 26);
+ ls1088a_qds_enable_SFP_TX(SFP_TX);
+ break;
+ default:
+ printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
+ serdes1_prtcl);
+ break;
+ }
+}
+
+static void ls1088a_handle_phy_interface_rgmii(int dpmac_id)
+{
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+ u32 serdes1_prtcl, cfg;
+ struct mii_dev *bus;
+
+ cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
+ FSL_CHASSIS3_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
+ serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg);
+
+ switch (dpmac_id) {
+ case 4:
+ wriop_set_phy_address(dpmac_id, 0, RGMII_PHY1_ADDR);
+ dpmac_info[dpmac_id].board_mux = EMI1_RGMII1;
+ bus = mii_dev_for_muxval(EMI1_RGMII1);
+ wriop_set_mdio(dpmac_id, bus);
+ break;
+ case 5:
+ wriop_set_phy_address(dpmac_id, 0, RGMII_PHY2_ADDR);
+ dpmac_info[dpmac_id].board_mux = EMI1_RGMII2;
+ bus = mii_dev_for_muxval(EMI1_RGMII2);
+ wriop_set_mdio(dpmac_id, bus);
+ break;
+ default:
+ printf("qds: WRIOP: Unsupported RGMII SerDes Protocol 0x%02x\n",
+ serdes1_prtcl);
+ break;
+ }
+}
+#endif
+
+int board_eth_init(struct bd_info *bis)
+{
+ int error = 0, i;
+#ifdef CONFIG_FSL_MC_ENET
+ struct memac_mdio_info *memac_mdio0_info;
+ char *env_hwconfig = env_get("hwconfig");
+
+ initialize_dpmac_to_slot();
+
+ memac_mdio0_info = (struct memac_mdio_info *)malloc(
+ sizeof(struct memac_mdio_info));
+ memac_mdio0_info->regs =
+ (struct memac_mdio_controller *)
+ CONFIG_SYS_FSL_WRIOP1_MDIO1;
+ memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
+
+ /* Register the real MDIO1 bus */
+ fm_memac_mdio_init(bis, memac_mdio0_info);
+ /* Register the muxing front-ends to the MDIO buses */
+ ls1088a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_RGMII1);
+ ls1088a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_RGMII2);
+ ls1088a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
+
+ for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
+ switch (wriop_get_enet_if(i)) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ ls1088a_handle_phy_interface_rgmii(i);
+ break;
+ case PHY_INTERFACE_MODE_QSGMII:
+ ls1088a_handle_phy_interface_qsgmii(i);
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ ls1088a_handle_phy_interface_sgmii(i);
+ break;
+ case PHY_INTERFACE_MODE_XGMII:
+ ls1088a_handle_phy_interface_xsgmii(i);
+ break;
+ default:
+ break;
+
+ if (i == 16)
+ i = NUM_WRIOP_PORTS;
+ }
+ }
+
+ error = cpu_eth_init(bis);
+
+ if (hwconfig_f("xqsgmii", env_hwconfig)) {
+ for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
+ switch (wriop_get_enet_if(i)) {
+ case PHY_INTERFACE_MODE_QSGMII:
+ qsgmii_configure_repeater(i);
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ sgmii_configure_repeater(i);
+ break;
+ default:
+ break;
+ }
+
+ if (i == 16)
+ i = NUM_WRIOP_PORTS;
+ }
+ }
+#endif
+ error = pci_eth_init(bis);
+ return error;
+}
+#endif // !CONFIG_DM_ETH
+
+#if defined(CONFIG_RESET_PHY_R)
+void reset_phy(void)
+{
+ mc_env_boot();
+}
+#endif /* CONFIG_RESET_PHY_R */
+
+#if defined(CONFIG_DM_ETH) && defined(CONFIG_MULTI_DTB_FIT)
+
+/* Structure to hold SERDES protocols supported in case of
+ * CONFIG_DM_ETH enabled (network interfaces are described in the DTS).
+ *
+ * @serdes_block: the index of the SERDES block
+ * @serdes_protocol: the decimal value of the protocol supported
+ * @dts_needed: DTS notes describing the current configuration are needed
+ *
+ * When dts_needed is true, the board_fit_config_name_match() function
+ * will try to exactly match the current configuration of the block with a DTS
+ * name provided.
+ */
+static struct serdes_configuration {
+ u8 serdes_block;
+ u32 serdes_protocol;
+ bool dts_needed;
+} supported_protocols[] = {
+ /* Serdes block #1 */
+ {1, 21, true},
+ {1, 29, true},
+};
+
+#define SUPPORTED_SERDES_PROTOCOLS ARRAY_SIZE(supported_protocols)
+
+static bool protocol_supported(u8 serdes_block, u32 protocol)
+{
+ struct serdes_configuration serdes_conf;
+ int i;
+
+ for (i = 0; i < SUPPORTED_SERDES_PROTOCOLS; i++) {
+ serdes_conf = supported_protocols[i];
+ if (serdes_conf.serdes_block == serdes_block &&
+ serdes_conf.serdes_protocol == protocol)
+ return true;
+ }
+
+ return false;
+}
+
+static void get_str_protocol(u8 serdes_block, u32 protocol, char *str)
+{
+ struct serdes_configuration serdes_conf;
+ int i;
+
+ for (i = 0; i < SUPPORTED_SERDES_PROTOCOLS; i++) {
+ serdes_conf = supported_protocols[i];
+ if (serdes_conf.serdes_block == serdes_block &&
+ serdes_conf.serdes_protocol == protocol) {
+ if (serdes_conf.dts_needed == true)
+ sprintf(str, "%u", protocol);
+ else
+ sprintf(str, "x");
+ return;
+ }
+ }
+}
+
+int board_fit_config_name_match(const char *name)
+{
+ struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ char expected_dts[100];
+ char srds_s1_str[2];
+ u32 srds_s1, cfg;
+
+ cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
+ FSL_CHASSIS3_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
+ srds_s1 = serdes_get_number(FSL_SRDS_1, cfg);
+
+ /* Check for supported protocols. The default DTS will be used
+ * in this case
+ */
+ if (!protocol_supported(1, srds_s1))
+ return -1;
+
+ get_str_protocol(1, srds_s1, srds_s1_str);
+
+ sprintf(expected_dts, "fsl-ls1088a-qds-%s-x", srds_s1_str);
+
+ if (!strcmp(name, expected_dts))
+ return 0;
+
+ return -1;
+}
+#endif
diff --git a/roms/u-boot/board/freescale/ls1088a/eth_ls1088ardb.c b/roms/u-boot/board/freescale/ls1088a/eth_ls1088ardb.c
new file mode 100644
index 000000000..a8e9ef15d
--- /dev/null
+++ b/roms/u-boot/board/freescale/ls1088a/eth_ls1088ardb.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017 NXP
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.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>
+
+#ifndef CONFIG_DM_ETH
+int board_eth_init(struct bd_info *bis)
+{
+#if defined(CONFIG_FSL_MC_ENET)
+ int i, interface;
+ struct memac_mdio_info mdio_info;
+ struct mii_dev *dev;
+ struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ struct memac_mdio_controller *reg;
+ u32 srds_s1, cfg;
+
+ cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
+ FSL_CHASSIS3_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
+
+ srds_s1 = serdes_get_number(FSL_SRDS_1, cfg);
+
+ reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO1;
+ mdio_info.regs = reg;
+ mdio_info.name = DEFAULT_WRIOP_MDIO1_NAME;
+
+ /* Register the EMI 1 */
+ fm_memac_mdio_init(bis, &mdio_info);
+
+ reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO2;
+ mdio_info.regs = reg;
+ mdio_info.name = DEFAULT_WRIOP_MDIO2_NAME;
+
+ /* Register the EMI 2 */
+ fm_memac_mdio_init(bis, &mdio_info);
+
+ switch (srds_s1) {
+ case 0x1D:
+ /*
+ * XFI does not need a PHY to work, but to avoid U-boot use
+ * default PHY address which is zero to a MAC when it found
+ * a MAC has no PHY address, we give a PHY address to XFI
+ * MAC error.
+ */
+ wriop_set_phy_address(WRIOP1_DPMAC1, 0, 0x0a);
+ wriop_set_phy_address(WRIOP1_DPMAC2, 0, AQ_PHY_ADDR1);
+ wriop_set_phy_address(WRIOP1_DPMAC3, 0, QSGMII1_PORT1_PHY_ADDR);
+ wriop_set_phy_address(WRIOP1_DPMAC4, 0, QSGMII1_PORT2_PHY_ADDR);
+ wriop_set_phy_address(WRIOP1_DPMAC5, 0, QSGMII1_PORT3_PHY_ADDR);
+ wriop_set_phy_address(WRIOP1_DPMAC6, 0, QSGMII1_PORT4_PHY_ADDR);
+ wriop_set_phy_address(WRIOP1_DPMAC7, 0, QSGMII2_PORT1_PHY_ADDR);
+ wriop_set_phy_address(WRIOP1_DPMAC8, 0, QSGMII2_PORT2_PHY_ADDR);
+ wriop_set_phy_address(WRIOP1_DPMAC9, 0, QSGMII2_PORT3_PHY_ADDR);
+ wriop_set_phy_address(WRIOP1_DPMAC10, 0,
+ QSGMII2_PORT4_PHY_ADDR);
+
+ break;
+ default:
+ printf("SerDes1 protocol 0x%x is not supported on LS1088ARDB\n",
+ srds_s1);
+ break;
+ }
+
+ for (i = WRIOP1_DPMAC3; i <= WRIOP1_DPMAC10; i++) {
+ interface = wriop_get_enet_if(i);
+ switch (interface) {
+ case PHY_INTERFACE_MODE_QSGMII:
+ dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME);
+ wriop_set_mdio(i, dev);
+ break;
+ default:
+ break;
+ }
+ }
+
+ dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME);
+ wriop_set_mdio(WRIOP1_DPMAC2, dev);
+
+ cpu_eth_init(bis);
+#endif /* CONFIG_FMAN_ENET */
+
+ return pci_eth_init(bis);
+}
+#endif
+
+#if defined(CONFIG_RESET_PHY_R)
+void reset_phy(void)
+{
+ mc_env_boot();
+}
+#endif /* CONFIG_RESET_PHY_R */
diff --git a/roms/u-boot/board/freescale/ls1088a/ls1088a.c b/roms/u-boot/board/freescale/ls1088a/ls1088a.c
new file mode 100644
index 000000000..f5dc449d8
--- /dev/null
+++ b/roms/u-boot/board/freescale/ls1088a/ls1088a.c
@@ -0,0 +1,1059 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017-2018 NXP
+ */
+#include <common.h>
+#include <env.h>
+#include <i2c.h>
+#include <init.h>
+#include <log.h>
+#include <malloc.h>
+#include <errno.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 "../common/qixis.h"
+#include "ls1088a_qixis.h"
+#include "../common/vid.h"
+#include <fsl_immap.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_TARGET_LS1088AQDS
+#ifdef CONFIG_TFABOOT
+struct ifc_regs ifc_cfg_ifc_nor_boot[CONFIG_SYS_FSL_IFC_BANK_COUNT] = {
+ {
+ "nor0",
+ CONFIG_SYS_NOR0_CSPR_EARLY,
+ CONFIG_SYS_NOR0_CSPR_EXT,
+ CONFIG_SYS_NOR_AMASK,
+ CONFIG_SYS_NOR_CSOR,
+ {
+ CONFIG_SYS_NOR_FTIM0,
+ CONFIG_SYS_NOR_FTIM1,
+ CONFIG_SYS_NOR_FTIM2,
+ CONFIG_SYS_NOR_FTIM3
+ },
+ 0,
+ CONFIG_SYS_NOR0_CSPR,
+ 0,
+ },
+ {
+ "nor1",
+ CONFIG_SYS_NOR1_CSPR_EARLY,
+ CONFIG_SYS_NOR0_CSPR_EXT,
+ CONFIG_SYS_NOR_AMASK_EARLY,
+ CONFIG_SYS_NOR_CSOR,
+ {
+ CONFIG_SYS_NOR_FTIM0,
+ CONFIG_SYS_NOR_FTIM1,
+ CONFIG_SYS_NOR_FTIM2,
+ CONFIG_SYS_NOR_FTIM3
+ },
+ 0,
+ CONFIG_SYS_NOR1_CSPR,
+ CONFIG_SYS_NOR_AMASK,
+ },
+ {
+ "nand",
+ CONFIG_SYS_NAND_CSPR,
+ CONFIG_SYS_NAND_CSPR_EXT,
+ CONFIG_SYS_NAND_AMASK,
+ CONFIG_SYS_NAND_CSOR,
+ {
+ CONFIG_SYS_NAND_FTIM0,
+ CONFIG_SYS_NAND_FTIM1,
+ CONFIG_SYS_NAND_FTIM2,
+ CONFIG_SYS_NAND_FTIM3
+ },
+ },
+ {
+ "fpga",
+ CONFIG_SYS_FPGA_CSPR,
+ CONFIG_SYS_FPGA_CSPR_EXT,
+ SYS_FPGA_AMASK,
+ CONFIG_SYS_FPGA_CSOR,
+ {
+ SYS_FPGA_CS_FTIM0,
+ SYS_FPGA_CS_FTIM1,
+ SYS_FPGA_CS_FTIM2,
+ SYS_FPGA_CS_FTIM3
+ },
+ 0,
+ SYS_FPGA_CSPR_FINAL,
+ 0,
+ }
+};
+
+struct ifc_regs ifc_cfg_qspi_nor_boot[CONFIG_SYS_FSL_IFC_BANK_COUNT] = {
+ {
+ "nand",
+ CONFIG_SYS_NAND_CSPR,
+ CONFIG_SYS_NAND_CSPR_EXT,
+ CONFIG_SYS_NAND_AMASK,
+ CONFIG_SYS_NAND_CSOR,
+ {
+ CONFIG_SYS_NAND_FTIM0,
+ CONFIG_SYS_NAND_FTIM1,
+ CONFIG_SYS_NAND_FTIM2,
+ CONFIG_SYS_NAND_FTIM3
+ },
+ },
+ {
+ "reserved",
+ },
+ {
+ "fpga",
+ CONFIG_SYS_FPGA_CSPR,
+ CONFIG_SYS_FPGA_CSPR_EXT,
+ SYS_FPGA_AMASK,
+ CONFIG_SYS_FPGA_CSOR,
+ {
+ SYS_FPGA_CS_FTIM0,
+ SYS_FPGA_CS_FTIM1,
+ SYS_FPGA_CS_FTIM2,
+ SYS_FPGA_CS_FTIM3
+ },
+ 0,
+ SYS_FPGA_CSPR_FINAL,
+ 0,
+ }
+};
+
+void ifc_cfg_boot_info(struct ifc_regs_info *regs_info)
+{
+ enum boot_src src = get_boot_src();
+
+ if (src == BOOT_SOURCE_QSPI_NOR)
+ regs_info->regs = ifc_cfg_qspi_nor_boot;
+ else
+ regs_info->regs = ifc_cfg_ifc_nor_boot;
+
+ regs_info->cs_size = CONFIG_SYS_FSL_IFC_BANK_COUNT;
+}
+#endif /* CONFIG_TFABOOT */
+#endif /* CONFIG_TARGET_LS1088AQDS */
+
+int board_early_init_f(void)
+{
+#if defined(CONFIG_SYS_I2C_EARLY_INIT) && defined(CONFIG_TARGET_LS1088AQDS)
+ i2c_early_init_f();
+#endif
+ fsl_lsch3_early_init_f();
+ return 0;
+}
+
+#ifdef CONFIG_FSL_QIXIS
+unsigned long long get_qixis_addr(void)
+{
+ unsigned long long addr;
+
+ if (gd->flags & GD_FLG_RELOC)
+ addr = QIXIS_BASE_PHYS;
+ else
+ addr = QIXIS_BASE_PHYS_EARLY;
+
+ /*
+ * IFC address under 256MB is mapped to 0x30000000, any address above
+ * is mapped to 0x5_10000000 up to 4GB.
+ */
+ addr = addr > 0x10000000 ? addr + 0x500000000ULL : addr + 0x30000000;
+
+ return addr;
+}
+#endif
+
+#if defined(CONFIG_VID)
+int init_func_vid(void)
+{
+ if (adjust_vdd(0) < 0)
+ printf("core voltage not adjusted\n");
+
+ return 0;
+}
+
+u16 soc_get_fuse_vid(int vid_index)
+{
+ static const u16 vdd[32] = {
+ 10250,
+ 9875,
+ 9750,
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 9000,
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 10000, /* 1.0000V */
+ 10125,
+ 10250,
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ };
+
+ return vdd[vid_index];
+};
+#endif
+
+int is_pb_board(void)
+{
+ u8 board_id;
+
+ board_id = QIXIS_READ(id);
+ if (board_id == LS1088ARDB_PB_BOARD)
+ return 1;
+ else
+ return 0;
+}
+
+int fixup_ls1088ardb_pb_banner(void *fdt)
+{
+ fdt_setprop_string(fdt, 0, "model", "LS1088ARDB-PB Board");
+
+ return 0;
+}
+
+#if !defined(CONFIG_SPL_BUILD)
+int checkboard(void)
+{
+#ifdef CONFIG_TFABOOT
+ enum boot_src src = get_boot_src();
+#endif
+ char buf[64];
+ u8 sw;
+ static const char *const freq[] = {"100", "125", "156.25",
+ "100 separate SSCG"};
+ int clock;
+
+#ifdef CONFIG_TARGET_LS1088AQDS
+ printf("Board: LS1088A-QDS, ");
+#else
+ if (is_pb_board())
+ printf("Board: LS1088ARDB-PB, ");
+ else
+ printf("Board: LS1088A-RDB, ");
+#endif
+
+ sw = QIXIS_READ(arch);
+ printf("Board Arch: V%d, ", sw >> 4);
+
+#ifdef CONFIG_TARGET_LS1088AQDS
+ printf("Board version: %c, boot from ", (sw & 0xf) + 'A' - 1);
+#else
+ printf("Board version: %c, boot from ", (sw & 0xf) + 'A');
+#endif
+
+ memset((u8 *)buf, 0x00, ARRAY_SIZE(buf));
+
+ sw = QIXIS_READ(brdcfg[0]);
+ sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
+
+#ifdef CONFIG_TFABOOT
+ if (src == BOOT_SOURCE_SD_MMC)
+ puts("SD card\n");
+#else
+#ifdef CONFIG_SD_BOOT
+ puts("SD card\n");
+#endif
+#endif /* CONFIG_TFABOOT */
+ switch (sw) {
+#ifdef CONFIG_TARGET_LS1088AQDS
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ printf("vBank: %d\n", sw);
+ break;
+ case 8:
+ puts("PromJet\n");
+ break;
+ case 15:
+ puts("IFCCard\n");
+ break;
+ case 14:
+#else
+ case 0:
+#endif
+ puts("QSPI:");
+ sw = QIXIS_READ(brdcfg[0]);
+ sw = (sw & QIXIS_QMAP_MASK) >> QIXIS_QMAP_SHIFT;
+ if (sw == 0 || sw == 4)
+ puts("0\n");
+ else if (sw == 1)
+ puts("1\n");
+ else
+ puts("EMU\n");
+ break;
+
+ default:
+ printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
+ break;
+ }
+
+#ifdef CONFIG_TARGET_LS1088AQDS
+ printf("FPGA: v%d (%s), build %d",
+ (int)QIXIS_READ(scver), qixis_read_tag(buf),
+ (int)qixis_read_minor());
+ /* the timestamp string contains "\n" at the end */
+ printf(" on %s", qixis_read_time(buf));
+#else
+ printf("CPLD: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata));
+#endif
+
+ /*
+ * Display the actual SERDES reference clocks as configured by the
+ * dip switches on the board. Note that the SWx registers could
+ * technically be set to force the reference clocks to match the
+ * values that the SERDES expects (or vice versa). For now, however,
+ * we just display both values and hope the user notices when they
+ * don't match.
+ */
+ puts("SERDES1 Reference : ");
+ sw = QIXIS_READ(brdcfg[2]);
+ clock = (sw >> 6) & 3;
+ printf("Clock1 = %sMHz ", freq[clock]);
+ clock = (sw >> 4) & 3;
+ printf("Clock2 = %sMHz", freq[clock]);
+
+ puts("\nSERDES2 Reference : ");
+ clock = (sw >> 2) & 3;
+ printf("Clock1 = %sMHz ", freq[clock]);
+ clock = (sw >> 0) & 3;
+ printf("Clock2 = %sMHz\n", freq[clock]);
+
+ return 0;
+}
+#endif
+
+bool if_board_diff_clk(void)
+{
+#ifdef CONFIG_TARGET_LS1088AQDS
+ u8 diff_conf = QIXIS_READ(brdcfg[11]);
+ return diff_conf & 0x40;
+#else
+ u8 diff_conf = QIXIS_READ(dutcfg[11]);
+ return diff_conf & 0x80;
+#endif
+}
+
+unsigned long get_board_sys_clk(void)
+{
+ u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
+
+ switch (sysclk_conf & 0x0f) {
+ case QIXIS_SYSCLK_83:
+ return 83333333;
+ case QIXIS_SYSCLK_100:
+ return 100000000;
+ case QIXIS_SYSCLK_125:
+ return 125000000;
+ case QIXIS_SYSCLK_133:
+ return 133333333;
+ case QIXIS_SYSCLK_150:
+ return 150000000;
+ case QIXIS_SYSCLK_160:
+ return 160000000;
+ case QIXIS_SYSCLK_166:
+ return 166666666;
+ }
+
+ return 66666666;
+}
+
+unsigned long get_board_ddr_clk(void)
+{
+ u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
+
+ if (if_board_diff_clk())
+ return get_board_sys_clk();
+ switch ((ddrclk_conf & 0x30) >> 4) {
+ case QIXIS_DDRCLK_100:
+ return 100000000;
+ case QIXIS_DDRCLK_125:
+ return 125000000;
+ case QIXIS_DDRCLK_133:
+ return 133333333;
+ }
+
+ return 66666666;
+}
+
+int select_i2c_ch_pca9547(u8 ch)
+{
+ int ret;
+
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
+#else
+ struct udevice *dev;
+
+ ret = i2c_get_chip_for_busnum(0, I2C_MUX_PCA_ADDR_PRI, 1, &dev);
+ if (!ret)
+ ret = dm_i2c_write(dev, 0, &ch, 1);
+#endif
+ if (ret) {
+ puts("PCA: failed to select proper channel\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+#if !defined(CONFIG_SPL_BUILD)
+void board_retimer_init(void)
+{
+ u8 reg;
+
+ /* Retimer is connected to I2C1_CH5 */
+ select_i2c_ch_pca9547(I2C_MUX_CH5);
+
+ /* Access to Control/Shared register */
+ reg = 0x0;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR, 0xff, 1, &reg, 1);
+#else
+ struct udevice *dev;
+
+ i2c_get_chip_for_busnum(0, I2C_RETIMER_ADDR, 1, &dev);
+ dm_i2c_write(dev, 0xff, &reg, 1);
+#endif
+
+ /* Read device revision and ID */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_read(I2C_RETIMER_ADDR, 1, 1, &reg, 1);
+#else
+ dm_i2c_read(dev, 1, &reg, 1);
+#endif
+ debug("Retimer version id = 0x%x\n", reg);
+
+ /* Enable Broadcast. All writes target all channel register sets */
+ reg = 0x0c;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR, 0xff, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0xff, &reg, 1);
+#endif
+
+ /* Reset Channel Registers */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_read(I2C_RETIMER_ADDR, 0, 1, &reg, 1);
+#else
+ dm_i2c_read(dev, 0, &reg, 1);
+#endif
+ reg |= 0x4;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR, 0, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0, &reg, 1);
+#endif
+
+ /* Set data rate as 10.3125 Gbps */
+ reg = 0x90;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR, 0x60, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x60, &reg, 1);
+#endif
+ reg = 0xb3;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR, 0x61, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x61, &reg, 1);
+#endif
+ reg = 0x90;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR, 0x62, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x62, &reg, 1);
+#endif
+ reg = 0xb3;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR, 0x63, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x63, &reg, 1);
+#endif
+ reg = 0xcd;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR, 0x64, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x64, &reg, 1);
+#endif
+
+ /* Select VCO Divider to full rate (000) */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_read(I2C_RETIMER_ADDR, 0x2F, 1, &reg, 1);
+#else
+ dm_i2c_read(dev, 0x2F, &reg, 1);
+#endif
+ reg &= 0x0f;
+ reg |= 0x70;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR, 0x2F, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x2F, &reg, 1);
+#endif
+
+#ifdef CONFIG_TARGET_LS1088AQDS
+ /* Retimer is connected to I2C1_CH5 */
+ select_i2c_ch_pca9547(I2C_MUX_CH5);
+
+ /* Access to Control/Shared register */
+ reg = 0x0;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR2, 0xff, 1, &reg, 1);
+#else
+ i2c_get_chip_for_busnum(0, I2C_RETIMER_ADDR2, 1, &dev);
+ dm_i2c_write(dev, 0xff, &reg, 1);
+#endif
+
+ /* Read device revision and ID */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_read(I2C_RETIMER_ADDR2, 1, 1, &reg, 1);
+#else
+ dm_i2c_read(dev, 1, &reg, 1);
+#endif
+ debug("Retimer version id = 0x%x\n", reg);
+
+ /* Enable Broadcast. All writes target all channel register sets */
+ reg = 0x0c;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR2, 0xff, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0xff, &reg, 1);
+#endif
+
+ /* Reset Channel Registers */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_read(I2C_RETIMER_ADDR2, 0, 1, &reg, 1);
+#else
+ dm_i2c_read(dev, 0, &reg, 1);
+#endif
+ reg |= 0x4;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR2, 0, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0, &reg, 1);
+#endif
+
+ /* Set data rate as 10.3125 Gbps */
+ reg = 0x90;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR2, 0x60, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x60, &reg, 1);
+#endif
+ reg = 0xb3;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR2, 0x61, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x61, &reg, 1);
+#endif
+ reg = 0x90;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR2, 0x62, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x62, &reg, 1);
+#endif
+ reg = 0xb3;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR2, 0x63, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x63, &reg, 1);
+#endif
+ reg = 0xcd;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR2, 0x64, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x64, &reg, 1);
+#endif
+
+ /* Select VCO Divider to full rate (000) */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_read(I2C_RETIMER_ADDR2, 0x2F, 1, &reg, 1);
+#else
+ dm_i2c_read(dev, 0x2F, &reg, 1);
+#endif
+ reg &= 0x0f;
+ reg |= 0x70;
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ i2c_write(I2C_RETIMER_ADDR2, 0x2F, 1, &reg, 1);
+#else
+ dm_i2c_write(dev, 0x2F, &reg, 1);
+#endif
+
+#endif
+ /*return the default channel*/
+ select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
+}
+
+#ifdef CONFIG_MISC_INIT_R
+int misc_init_r(void)
+{
+#ifdef CONFIG_TARGET_LS1088ARDB
+ u8 brdcfg5;
+
+ if (hwconfig("esdhc-force-sd")) {
+ brdcfg5 = QIXIS_READ(brdcfg[5]);
+ brdcfg5 &= ~BRDCFG5_SPISDHC_MASK;
+ brdcfg5 |= BRDCFG5_FORCE_SD;
+ QIXIS_WRITE(brdcfg[5], brdcfg5);
+ }
+#endif
+
+#ifdef CONFIG_TARGET_LS1088AQDS
+ u8 brdcfg4, brdcfg5;
+
+ if (hwconfig("dspi-on-board")) {
+ brdcfg4 = QIXIS_READ(brdcfg[4]);
+ brdcfg4 &= ~BRDCFG4_USBOSC_MASK;
+ brdcfg4 |= BRDCFG4_SPI;
+ QIXIS_WRITE(brdcfg[4], brdcfg4);
+
+ brdcfg5 = QIXIS_READ(brdcfg[5]);
+ brdcfg5 &= ~BRDCFG5_SPR_MASK;
+ brdcfg5 |= BRDCFG5_SPI_ON_BOARD;
+ QIXIS_WRITE(brdcfg[5], brdcfg5);
+ } else if (hwconfig("dspi-off-board")) {
+ brdcfg4 = QIXIS_READ(brdcfg[4]);
+ brdcfg4 &= ~BRDCFG4_USBOSC_MASK;
+ brdcfg4 |= BRDCFG4_SPI;
+ QIXIS_WRITE(brdcfg[4], brdcfg4);
+
+ brdcfg5 = QIXIS_READ(brdcfg[5]);
+ brdcfg5 &= ~BRDCFG5_SPR_MASK;
+ brdcfg5 |= BRDCFG5_SPI_OFF_BOARD;
+ QIXIS_WRITE(brdcfg[5], brdcfg5);
+ }
+#endif
+ return 0;
+}
+#endif
+#endif
+
+int i2c_multiplexer_select_vid_channel(u8 channel)
+{
+ return select_i2c_ch_pca9547(channel);
+}
+
+#ifdef CONFIG_TARGET_LS1088AQDS
+/* read the current value(SVDD) of the LTM Regulator Voltage */
+int get_serdes_volt(void)
+{
+ int ret, vcode = 0;
+ u8 chan = PWM_CHANNEL0;
+
+ /* Select the PAGE 0 using PMBus commands PAGE for VDD */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ ret = i2c_write(I2C_SVDD_MONITOR_ADDR,
+ PMBUS_CMD_PAGE, 1, &chan, 1);
+#else
+ struct udevice *dev;
+
+ ret = i2c_get_chip_for_busnum(0, I2C_SVDD_MONITOR_ADDR, 1, &dev);
+ if (!ret)
+ ret = dm_i2c_write(dev, PMBUS_CMD_PAGE,
+ &chan, 1);
+#endif
+
+ if (ret) {
+ printf("VID: failed to select VDD Page 0\n");
+ return ret;
+ }
+
+ /* Read the output voltage using PMBus command READ_VOUT */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ ret = i2c_read(I2C_SVDD_MONITOR_ADDR,
+ PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2);
+#else
+ dm_i2c_read(dev, PMBUS_CMD_READ_VOUT, (void *)&vcode, 2);
+#endif
+ if (ret) {
+ printf("VID: failed to read the volatge\n");
+ return ret;
+ }
+
+ return vcode;
+}
+
+int set_serdes_volt(int svdd)
+{
+ int ret, vdd_last;
+ u8 buff[5] = {0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND,
+ svdd & 0xFF, (svdd & 0xFF00) >> 8};
+
+ /* Write the desired voltage code to the SVDD regulator */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ ret = i2c_write(I2C_SVDD_MONITOR_ADDR,
+ PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5);
+#else
+ struct udevice *dev;
+
+ ret = i2c_get_chip_for_busnum(0, I2C_SVDD_MONITOR_ADDR, 1, &dev);
+ if (!ret)
+ ret = dm_i2c_write(dev, PMBUS_CMD_PAGE_PLUS_WRITE,
+ (void *)&buff, 5);
+#endif
+ if (ret) {
+ printf("VID: I2C failed to write to the volatge regulator\n");
+ return -1;
+ }
+
+ /* Wait for the volatge to get to the desired value */
+ do {
+ vdd_last = get_serdes_volt();
+ if (vdd_last < 0) {
+ printf("VID: Couldn't read sensor abort VID adjust\n");
+ return -1;
+ }
+ } while (vdd_last != svdd);
+
+ return 1;
+}
+#else
+int get_serdes_volt(void)
+{
+ return 0;
+}
+
+int set_serdes_volt(int svdd)
+{
+ int ret;
+ u8 brdcfg4;
+
+ printf("SVDD changing of RDB\n");
+
+ /* Read the BRDCFG54 via CLPD */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ ret = i2c_read(CONFIG_SYS_I2C_FPGA_ADDR,
+ QIXIS_BRDCFG4_OFFSET, 1, (void *)&brdcfg4, 1);
+#else
+ struct udevice *dev;
+
+ ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_FPGA_ADDR, 1, &dev);
+ if (!ret)
+ ret = dm_i2c_read(dev, QIXIS_BRDCFG4_OFFSET,
+ (void *)&brdcfg4, 1);
+#endif
+
+ if (ret) {
+ printf("VID: I2C failed to read the CPLD BRDCFG4\n");
+ return -1;
+ }
+
+ brdcfg4 = brdcfg4 | 0x08;
+
+ /* Write to the BRDCFG4 */
+#if !CONFIG_IS_ENABLED(DM_I2C)
+ ret = i2c_write(CONFIG_SYS_I2C_FPGA_ADDR,
+ QIXIS_BRDCFG4_OFFSET, 1, (void *)&brdcfg4, 1);
+#else
+ ret = dm_i2c_write(dev, QIXIS_BRDCFG4_OFFSET,
+ (void *)&brdcfg4, 1);
+#endif
+
+ if (ret) {
+ debug("VID: I2C failed to set the SVDD CPLD BRDCFG4\n");
+ return -1;
+ }
+
+ /* Wait for the volatge to get to the desired value */
+ udelay(10000);
+
+ return 1;
+}
+#endif
+
+/* this function disables the SERDES, changes the SVDD Voltage and enables it*/
+int board_adjust_vdd(int vdd)
+{
+ int ret = 0;
+
+ debug("%s: vdd = %d\n", __func__, vdd);
+
+ /* Special settings to be performed when voltage is 900mV */
+ if (vdd == 900) {
+ ret = setup_serdes_volt(vdd);
+ if (ret < 0) {
+ ret = -1;
+ goto exit;
+ }
+ }
+exit:
+ return ret;
+}
+
+#if !defined(CONFIG_SPL_BUILD)
+int board_init(void)
+{
+ init_final_memctl_regs();
+#if defined(CONFIG_TARGET_LS1088ARDB) && defined(CONFIG_FSL_MC_ENET)
+ u32 __iomem *irq_ccsr = (u32 __iomem *)ISC_BASE;
+#endif
+
+ select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
+ board_retimer_init();
+
+#ifdef CONFIG_ENV_IS_NOWHERE
+ gd->env_addr = (ulong)&default_environment[0];
+#endif
+
+#if defined(CONFIG_TARGET_LS1088ARDB) && defined(CONFIG_FSL_MC_ENET)
+ /* invert AQR105 IRQ pins polarity */
+ out_le32(irq_ccsr + IRQCR_OFFSET / 4, AQR105_IRQ_MASK);
+#endif
+
+#ifdef CONFIG_FSL_CAAM
+ sec_init();
+#endif
+#ifdef CONFIG_FSL_LS_PPA
+ ppa_init();
+#endif
+
+#if !defined(CONFIG_SYS_EARLY_PCI_INIT) && defined(CONFIG_DM_ETH)
+ pci_init();
+#endif
+
+ 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);
+}
+
+#ifdef CONFIG_FSL_MC_ENET
+void board_quiesce_devices(void)
+{
+ 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);
+}
+#endif
+
+#ifdef CONFIG_OF_BOARD_SETUP
+void fsl_fdt_fixup_flash(void *fdt)
+{
+ int offset;
+#ifdef CONFIG_TFABOOT
+ u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
+ u32 val;
+#endif
+
+/*
+ * IFC-NOR and QSPI are muxed on SoC.
+ * So disable IFC node in dts if QSPI is enabled or
+ * disable QSPI node in dts in case QSPI is not enabled.
+ */
+
+#ifdef CONFIG_TFABOOT
+ enum boot_src src = get_boot_src();
+ bool disable_ifc = false;
+
+ switch (src) {
+ case BOOT_SOURCE_IFC_NOR:
+ disable_ifc = false;
+ break;
+ case BOOT_SOURCE_QSPI_NOR:
+ disable_ifc = true;
+ break;
+ default:
+ val = in_le32(dcfg_ccsr + DCFG_RCWSR15 / 4);
+ if (DCFG_RCWSR15_IFCGRPABASE_QSPI == (val & (u32)0x3))
+ disable_ifc = true;
+ break;
+ }
+
+ if (disable_ifc) {
+ offset = fdt_path_offset(fdt, "/soc/ifc/nor");
+
+ if (offset < 0)
+ offset = fdt_path_offset(fdt, "/ifc/nor");
+ } else {
+ offset = fdt_path_offset(fdt, "/soc/quadspi");
+
+ if (offset < 0)
+ offset = fdt_path_offset(fdt, "/quadspi");
+ }
+
+#else
+#ifdef CONFIG_FSL_QSPI
+ offset = fdt_path_offset(fdt, "/soc/ifc/nor");
+
+ if (offset < 0)
+ offset = fdt_path_offset(fdt, "/ifc/nor");
+#else
+ offset = fdt_path_offset(fdt, "/soc/quadspi");
+
+ if (offset < 0)
+ offset = fdt_path_offset(fdt, "/quadspi");
+#endif
+#endif
+ if (offset < 0)
+ return;
+
+ fdt_status_disabled(fdt, offset);
+}
+
+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;
+
+ 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;
+ }
+
+#ifdef CONFIG_RESV_RAM
+ /* reduce size if reserved memory is within this bank */
+ if (gd->arch.resv_ram >= base[0] &&
+ gd->arch.resv_ram < base[0] + size[0])
+ size[0] = gd->arch.resv_ram - base[0];
+ else if (gd->arch.resv_ram >= base[1] &&
+ gd->arch.resv_ram < base[1] + size[1])
+ size[1] = gd->arch.resv_ram - base[1];
+#endif
+
+ 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);
+
+ fsl_fdt_fixup_flash(blob);
+
+#ifdef CONFIG_FSL_MC_ENET
+ fdt_fixup_board_enet(blob);
+#endif
+
+ fdt_fixup_icid(blob);
+
+ if (is_pb_board())
+ fixup_ls1088ardb_pb_banner(blob);
+
+ return 0;
+}
+#endif
+#endif /* defined(CONFIG_SPL_BUILD) */
+
+#ifdef CONFIG_TFABOOT
+#ifdef CONFIG_MTD_NOR_FLASH
+int is_flash_available(void)
+{
+ char *env_hwconfig = env_get("hwconfig");
+ enum boot_src src = get_boot_src();
+ int is_nor_flash_available = 1;
+
+ switch (src) {
+ case BOOT_SOURCE_IFC_NOR:
+ is_nor_flash_available = 1;
+ break;
+ case BOOT_SOURCE_QSPI_NOR:
+ is_nor_flash_available = 0;
+ break;
+ /*
+ * In Case of SD boot,if qspi is defined in env_hwconfig
+ * disable nor flash probe.
+ */
+ default:
+ if (hwconfig_f("qspi", env_hwconfig))
+ is_nor_flash_available = 0;
+ break;
+ }
+ return is_nor_flash_available;
+}
+#endif
+
+#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
+void *env_sf_get_env_addr(void)
+{
+ return (void *)(CONFIG_SYS_FSL_QSPI_BASE + CONFIG_ENV_OFFSET);
+}
+#endif
+#endif
diff --git a/roms/u-boot/board/freescale/ls1088a/ls1088a_qixis.h b/roms/u-boot/board/freescale/ls1088a/ls1088a_qixis.h
new file mode 100644
index 000000000..e3502eb1d
--- /dev/null
+++ b/roms/u-boot/board/freescale/ls1088a/ls1088a_qixis.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2017 NXP
+ */
+
+#ifndef __LS1088AQDS_QIXIS_H__
+#define __LS1088AQDS_QIXIS_H__
+
+/* Definitions of QIXIS Registers for LS1088AQDS */
+
+/* SYSCLK */
+#define QIXIS_SYSCLK_66 0x0
+#define QIXIS_SYSCLK_83 0x1
+#define QIXIS_SYSCLK_100 0x2
+#define QIXIS_SYSCLK_125 0x3
+#define QIXIS_SYSCLK_133 0x4
+#define QIXIS_SYSCLK_150 0x5
+#define QIXIS_SYSCLK_160 0x6
+#define QIXIS_SYSCLK_166 0x7
+
+/* DDRCLK */
+#define QIXIS_DDRCLK_66 0x0
+#define QIXIS_DDRCLK_100 0x1
+#define QIXIS_DDRCLK_125 0x2
+#define QIXIS_DDRCLK_133 0x3
+
+/* BRDCFG2 - SD clock*/
+#define QIXIS_SDCLK1_100 0x0
+#define QIXIS_SDCLK1_125 0x1
+#define QIXIS_SDCLK1_165 0x2
+#define QIXIS_SDCLK1_100_SP 0x3
+
+#define BRDCFG4_EMISEL_MASK 0xE0
+#define BRDCFG4_EMISEL_SHIFT 5
+#define BRDCFG9_SFPTX_MASK 0x10
+#define BRDCFG9_SFPTX_SHIFT 4
+
+/* Definitions of QIXIS Registers for LS1088ARDB */
+
+/* BRDCFG5 */
+#define BRDCFG5_SPISDHC_MASK 0x0C
+#define BRDCFG5_FORCE_SD 0x08
+
+/* Definitions of QIXIS Registers for LS1088AQDS */
+
+/* BRDCFG4 */
+#define BRDCFG4_USBOSC_MASK 0x01
+#define BRDCFG4_SPI 0x01
+
+/* BRDCFG5 */
+#define BRDCFG5_SPR_MASK 0x0f
+#define BRDCFG5_SPI_ON_BOARD 0x0a
+#define BRDCFG5_SPI_OFF_BOARD 0x0f
+
+#endif