diff options
author | Tom Rini <trini@konsulko.com> | 2017-09-12 12:02:50 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-09-12 12:02:50 -0400 |
commit | 8a33cb8b6bdf8a35f931fcc3d8aa15254cfc4b23 (patch) | |
tree | 3eaf43d4936e1b8846f0260d95ba10271ee31a0f /board | |
parent | fa6365b7c7cf06f3de0aaf55d1c8cd1e5bb30151 (diff) | |
parent | 42f43aa25876d1c77002ee5f333ab36dcb01d719 (diff) | |
download | u-boot-8a33cb8b6bdf8a35f931fcc3d8aa15254cfc4b23.tar.gz |
Merge git://git.denx.de/u-boot-fsl-qoriq
Diffstat (limited to 'board')
-rw-r--r-- | board/freescale/ls1012afrdm/ls1012afrdm.c | 4 | ||||
-rw-r--r-- | board/freescale/ls1012aqds/ls1012aqds.c | 4 | ||||
-rw-r--r-- | board/freescale/ls1012ardb/ls1012ardb.c | 3 | ||||
-rw-r--r-- | board/freescale/ls1021aqds/ls1021aqds.c | 9 | ||||
-rw-r--r-- | board/freescale/ls1088a/Kconfig | 31 | ||||
-rw-r--r-- | board/freescale/ls1088a/MAINTAINERS | 15 | ||||
-rw-r--r-- | board/freescale/ls1088a/Makefile | 10 | ||||
-rw-r--r-- | board/freescale/ls1088a/README | 145 | ||||
-rw-r--r-- | board/freescale/ls1088a/ddr.c | 102 | ||||
-rw-r--r-- | board/freescale/ls1088a/ddr.h | 49 | ||||
-rw-r--r-- | board/freescale/ls1088a/eth_ls1088aqds.c | 683 | ||||
-rw-r--r-- | board/freescale/ls1088a/eth_ls1088ardb.c | 102 | ||||
-rw-r--r-- | board/freescale/ls1088a/ls1088a.c | 406 | ||||
-rw-r--r-- | board/freescale/ls1088a/ls1088a_qixis.h | 39 | ||||
-rw-r--r-- | board/freescale/ls2080aqds/ls2080aqds.c | 7 | ||||
-rw-r--r-- | board/freescale/ls2080ardb/MAINTAINERS | 5 | ||||
-rw-r--r-- | board/freescale/ls2080ardb/ls2080ardb.c | 4 |
17 files changed, 1607 insertions, 11 deletions
diff --git a/board/freescale/ls1012afrdm/ls1012afrdm.c b/board/freescale/ls1012afrdm/ls1012afrdm.c index 25d22d25bf..9afd1c469e 100644 --- a/board/freescale/ls1012afrdm/ls1012afrdm.c +++ b/board/freescale/ls1012afrdm/ls1012afrdm.c @@ -71,7 +71,9 @@ int board_early_init_f(void) int board_init(void) { - struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); + /* * Set CCI-400 control override register to enable barrier * transaction diff --git a/board/freescale/ls1012aqds/ls1012aqds.c b/board/freescale/ls1012aqds/ls1012aqds.c index 97ab3400ad..406194da27 100644 --- a/board/freescale/ls1012aqds/ls1012aqds.c +++ b/board/freescale/ls1012aqds/ls1012aqds.c @@ -106,8 +106,8 @@ int misc_init_r(void) int board_init(void) { - struct ccsr_cci400 *cci = (struct ccsr_cci400 *) - CONFIG_SYS_CCI400_ADDR; + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); /* Set CCI-400 control override register to enable barrier * transaction */ diff --git a/board/freescale/ls1012ardb/ls1012ardb.c b/board/freescale/ls1012ardb/ls1012ardb.c index a21e4c4aeb..c6c1c71202 100644 --- a/board/freescale/ls1012ardb/ls1012ardb.c +++ b/board/freescale/ls1012ardb/ls1012ardb.c @@ -104,7 +104,8 @@ int board_early_init_f(void) int board_init(void) { - struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); /* * Set CCI-400 control override register to enable barrier * transaction diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c index d81d8abc9b..8b3f4ad78d 100644 --- a/board/freescale/ls1021aqds/ls1021aqds.c +++ b/board/freescale/ls1021aqds/ls1021aqds.c @@ -204,7 +204,8 @@ int board_early_init_f(void) #ifdef CONFIG_SPL_BUILD void board_init_f(ulong dummy) { - struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); unsigned int major; #ifdef CONFIG_NAND_BOOT @@ -425,7 +426,8 @@ int misc_init_r(void) int board_init(void) { - struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); unsigned int major; #ifdef CONFIG_SYS_FSL_ERRATUM_A010315 @@ -460,7 +462,8 @@ int board_init(void) #if defined(CONFIG_DEEP_SLEEP) void board_sleep_prepare(void) { - struct ccsr_cci400 __iomem *cci = (void *)CONFIG_SYS_CCI400_ADDR; + struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); unsigned int major; major = get_soc_major_rev(); diff --git a/board/freescale/ls1088a/Kconfig b/board/freescale/ls1088a/Kconfig new file mode 100644 index 0000000000..1ada661743 --- /dev/null +++ b/board/freescale/ls1088a/Kconfig @@ -0,0 +1,31 @@ +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" + +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" + +endif diff --git a/board/freescale/ls1088a/MAINTAINERS b/board/freescale/ls1088a/MAINTAINERS new file mode 100644 index 0000000000..e1e6d4bbc5 --- /dev/null +++ b/board/freescale/ls1088a/MAINTAINERS @@ -0,0 +1,15 @@ +LS1088ARDB BOARD +M: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com> +M: Ashish Kumar <Ashish.Kumar@nxp.com> +S: Maintained +F: board/freescale/ls1088a/ +F: include/configs/ls1088ardb.h +F: configs/ls1088ardb_qspi_defconfig + +LS1088AQDS BOARD +M: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com> +M: Ashish Kumar <Ashish.Kumar@nxp.com> +S: Maintained +F: board/freescale/ls1088a/ +F: include/configs/ls1088aqds.h +F: configs/ls1088aqds_qspi_defconfig diff --git a/board/freescale/ls1088a/Makefile b/board/freescale/ls1088a/Makefile new file mode 100644 index 0000000000..bdcce9e6bc --- /dev/null +++ b/board/freescale/ls1088a/Makefile @@ -0,0 +1,10 @@ +# +# Copyright 2017 NXP +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ls1088a.o +obj-$(CONFIG_TARGET_LS1088ARDB) += eth_ls1088ardb.o +obj-$(CONFIG_TARGET_LS1088AQDS) += eth_ls1088aqds.o +obj-y += ddr.o diff --git a/board/freescale/ls1088a/README b/board/freescale/ls1088a/README new file mode 100644 index 0000000000..aa0fb6ac67 --- /dev/null +++ b/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/board/freescale/ls1088a/ddr.c b/board/freescale/ls1088a/ddr.c new file mode 100644 index 0000000000..0ecfd653b4 --- /dev/null +++ b/board/freescale/ls1088a/ddr.c @@ -0,0 +1,102 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <fsl_ddr_sdram.h> +#include <fsl_ddr_dimm_params.h> +#include <asm/arch/soc.h> +#include <asm/arch/clock.h> +#include "ddr.h" + +DECLARE_GLOBAL_DATA_PTR; + +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); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) | + DDR_CDR2_VREF_TRAIN_EN | DDR_CDR2_VREF_RANGE_2; +} + + +int fsl_initdram(void) +{ + puts("Initializing DDR....using SPD\n"); + + gd->ram_size = fsl_ddr_sdram(); + + return 0; +} diff --git a/board/freescale/ls1088a/ddr.h b/board/freescale/ls1088a/ddr.h new file mode 100644 index 0000000000..a1ad709e86 --- /dev/null +++ b/board/freescale/ls1088a/ddr.h @@ -0,0 +1,49 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#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, 4, 7, 0x09090B0D, 0x0E10120B,}, + {2, 2300, 0, 8, 9, 0x0A0C0E11, 0x1214160F,}, + {} +#elif defined(CONFIG_TARGET_LS1088AQDS) + {2, 1666, 0, 8, 8, 0x0A0A0C0E, 0x0F10110C,}, + {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,}, + {2, 2300, 0, 4, 9, 0x0A0C0D11, 0x1214150E,}, + {} + +#endif +}; + +static const struct board_specific_parameters *udimms[] = { + udimm0, +}; +#endif diff --git a/board/freescale/ls1088a/eth_ls1088aqds.c b/board/freescale/ls1088a/eth_ls1088aqds.c new file mode 100644 index 0000000000..c19f59a11c --- /dev/null +++ b/board/freescale/ls1088a/eth_ls1088aqds.c @@ -0,0 +1,683 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.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 <fm_eth.h> +#include <i2c.h> +#include <miiphy.h> +#include <fsl-mc/ldpaa_wriop.h> + +#include "../common/qixis.h" + +#include "ls1088a_qixis.h" + +#define MC_BOOT_ENV_VAR "mcinitcmd" + +#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; +}; + +static void sgmii_configure_repeater(int dpmac) +{ + struct mii_dev *bus; + uint8_t a = 0xf; + int i, j, 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}; + + /* Set I2c to Slot 1 */ + i2c_write(0x77, 0, 0, &a, 1); + + 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; + } + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + a = 0x18; + i2c_write(i2c_phy_addr, 6, 1, &a, 1); + a = 0x38; + i2c_write(i2c_phy_addr, 4, 1, &a, 1); + a = 0x4; + i2c_write(i2c_phy_addr, 8, 1, &a, 1); + + i2c_write(i2c_phy_addr, 0xf, 1, + &ch_a_eq[i], 1); + i2c_write(i2c_phy_addr, 0x11, 1, + &ch_a_ctl2[j], 1); + + i2c_write(i2c_phy_addr, 0x16, 1, + &ch_b_eq[i], 1); + i2c_write(i2c_phy_addr, 0x18, 1, + &ch_b_ctl2[j], 1); + + a = 0x14; + i2c_write(i2c_phy_addr, 0x23, 1, &a, 1); + a = 0xb5; + i2c_write(i2c_phy_addr, 0x2d, 1, &a, 1); + a = 0x20; + i2c_write(i2c_phy_addr, 4, 1, &a, 1); + 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; + 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}; + + const char *dev = mdio_names[EMI1_SLOT1]; + int ret = 0; + unsigned short value; + + /* Set I2c to Slot 1 */ + i2c_write(0x77, 0, 0, &a, 1); + + 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; + } + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + a = 0x18; + i2c_write(i2c_phy_addr, 6, 1, &a, 1); + a = 0x38; + i2c_write(i2c_phy_addr, 4, 1, &a, 1); + a = 0x4; + i2c_write(i2c_phy_addr, 8, 1, &a, 1); + + i2c_write(i2c_phy_addr, 0xf, 1, &ch_a_eq[i], 1); + i2c_write(i2c_phy_addr, 0x11, 1, &ch_a_ctl2[j], 1); + + i2c_write(i2c_phy_addr, 0x16, 1, &ch_b_eq[i], 1); + i2c_write(i2c_phy_addr, 0x18, 1, &ch_b_ctl2[j], 1); + + a = 0x14; + i2c_write(i2c_phy_addr, 0x23, 1, &a, 1); + a = 0xb5; + i2c_write(i2c_phy_addr, 0x2d, 1, &a, 1); + a = 0x20; + i2c_write(i2c_phy_addr, 4, 1, &a, 1); + mdelay(100); + 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, riser_phy_addr[1]); + break; + case 2: + wriop_set_phy_address(dpmac_id, riser_phy_addr[0]); + break; + case 3: + wriop_set_phy_address(dpmac_id, riser_phy_addr[3]); + break; + case 7: + wriop_set_phy_address(dpmac_id, 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, dpmac_id + 9); + break; + case 7: + case 8: + case 9: + case 10: + wriop_set_phy_address(dpmac_id, 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, 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, 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, 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(bd_t *bis) +{ + int error = 0, i; + char *mc_boot_env_var; +#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: + 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; + } + } + + mc_boot_env_var = env_get(MC_BOOT_ENV_VAR); + if (mc_boot_env_var) + run_command_list(mc_boot_env_var, -1, 0); + 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; +} diff --git a/board/freescale/ls1088a/eth_ls1088ardb.c b/board/freescale/ls1088a/eth_ls1088ardb.c new file mode 100644 index 0000000000..853d815da5 --- /dev/null +++ b/board/freescale/ls1088a/eth_ls1088ardb.c @@ -0,0 +1,102 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#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/ldpaa_wriop.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define MC_BOOT_ENV_VAR "mcinitcmd" +int board_eth_init(bd_t *bis) +{ +#if defined(CONFIG_FSL_MC_ENET) + char *mc_boot_env_var; + 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, 0x0a); + wriop_set_phy_address(WRIOP1_DPMAC2, AQ_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC3, QSGMII1_PORT1_PHY_ADDR); + wriop_set_phy_address(WRIOP1_DPMAC4, QSGMII1_PORT2_PHY_ADDR); + wriop_set_phy_address(WRIOP1_DPMAC5, QSGMII1_PORT3_PHY_ADDR); + wriop_set_phy_address(WRIOP1_DPMAC6, QSGMII1_PORT4_PHY_ADDR); + wriop_set_phy_address(WRIOP1_DPMAC7, QSGMII2_PORT1_PHY_ADDR); + wriop_set_phy_address(WRIOP1_DPMAC8, QSGMII2_PORT2_PHY_ADDR); + wriop_set_phy_address(WRIOP1_DPMAC9, QSGMII2_PORT3_PHY_ADDR); + wriop_set_phy_address(WRIOP1_DPMAC10, 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); + + mc_boot_env_var = env_get(MC_BOOT_ENV_VAR); + if (mc_boot_env_var) + run_command_list(mc_boot_env_var, -1, 0); + cpu_eth_init(bis); +#endif /* CONFIG_FMAN_ENET */ + + return pci_eth_init(bis); +} diff --git a/board/freescale/ls1088a/ls1088a.c b/board/freescale/ls1088a/ls1088a.c new file mode 100644 index 0000000000..96d9ae7f1d --- /dev/null +++ b/board/freescale/ls1088a/ls1088a.c @@ -0,0 +1,406 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <i2c.h> +#include <malloc.h> +#include <errno.h> +#include <netdev.h> +#include <fsl_ifc.h> +#include <fsl_ddr.h> +#include <fsl_sec.h> +#include <asm/io.h> +#include <fdt_support.h> +#include <libfdt.h> +#include <fsl-mc/fsl_mc.h> +#include <environment.h> +#include <asm/arch-fsl-layerscape/soc.h> +#include <asm/arch/ppa.h> + +#include "../common/qixis.h" +#include "ls1088a_qixis.h" + +DECLARE_GLOBAL_DATA_PTR; + +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; +} + +int checkboard(void) +{ + 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 + 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_SD_BOOT + puts("SD card\n"); +#endif + 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; +} + +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; + + ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1); + if (ret) { + puts("PCA: failed to select proper channel\n"); + return ret; + } + + return 0; +} + +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; + i2c_write(I2C_RETIMER_ADDR, 0xff, 1, ®, 1); + + /* Read device revision and ID */ + i2c_read(I2C_RETIMER_ADDR, 1, 1, ®, 1); + debug("Retimer version id = 0x%x\n", reg); + + /* Enable Broadcast. All writes target all channel register sets */ + reg = 0x0c; + i2c_write(I2C_RETIMER_ADDR, 0xff, 1, ®, 1); + + /* Reset Channel Registers */ + i2c_read(I2C_RETIMER_ADDR, 0, 1, ®, 1); + reg |= 0x4; + i2c_write(I2C_RETIMER_ADDR, 0, 1, ®, 1); + + /* Set data rate as 10.3125 Gbps */ + reg = 0x90; + i2c_write(I2C_RETIMER_ADDR, 0x60, 1, ®, 1); + reg = 0xb3; + i2c_write(I2C_RETIMER_ADDR, 0x61, 1, ®, 1); + reg = 0x90; + i2c_write(I2C_RETIMER_ADDR, 0x62, 1, ®, 1); + reg = 0xb3; + i2c_write(I2C_RETIMER_ADDR, 0x63, 1, ®, 1); + reg = 0xcd; + i2c_write(I2C_RETIMER_ADDR, 0x64, 1, ®, 1); + + /* Select VCO Divider to full rate (000) */ + i2c_read(I2C_RETIMER_ADDR, 0x2F, 1, ®, 1); + reg &= 0x0f; + reg |= 0x70; + i2c_write(I2C_RETIMER_ADDR, 0x2F, 1, ®, 1); + +#ifdef CONFIG_TARGET_LS1088AQDS + /* Retimer is connected to I2C1_CH5 */ + select_i2c_ch_pca9547(I2C_MUX_CH5); + + /* Access to Control/Shared register */ + reg = 0x0; + i2c_write(I2C_RETIMER_ADDR2, 0xff, 1, ®, 1); + + /* Read device revision and ID */ + i2c_read(I2C_RETIMER_ADDR2, 1, 1, ®, 1); + debug("Retimer version id = 0x%x\n", reg); + + /* Enable Broadcast. All writes target all channel register sets */ + reg = 0x0c; + i2c_write(I2C_RETIMER_ADDR2, 0xff, 1, ®, 1); + + /* Reset Channel Registers */ + i2c_read(I2C_RETIMER_ADDR2, 0, 1, ®, 1); + reg |= 0x4; + i2c_write(I2C_RETIMER_ADDR2, 0, 1, ®, 1); + + /* Set data rate as 10.3125 Gbps */ + reg = 0x90; + i2c_write(I2C_RETIMER_ADDR2, 0x60, 1, ®, 1); + reg = 0xb3; + i2c_write(I2C_RETIMER_ADDR2, 0x61, 1, ®, 1); + reg = 0x90; + i2c_write(I2C_RETIMER_ADDR2, 0x62, 1, ®, 1); + reg = 0xb3; + i2c_write(I2C_RETIMER_ADDR2, 0x63, 1, ®, 1); + reg = 0xcd; + i2c_write(I2C_RETIMER_ADDR2, 0x64, 1, ®, 1); + + /* Select VCO Divider to full rate (000) */ + i2c_read(I2C_RETIMER_ADDR2, 0x2F, 1, ®, 1); + reg &= 0x0f; + reg |= 0x70; + i2c_write(I2C_RETIMER_ADDR2, 0x2F, 1, ®, 1); +#endif + /*return the default channel*/ + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); +} + +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_LS_PPA + ppa_init(); +#endif + return 0; +} + +int board_early_init_f(void) +{ + fsl_lsch3_early_init_f(); + 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); +} + +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ +#ifdef CONFIG_FSL_CAAM + sec_init(); +#endif + return 0; +} +#endif + +#ifdef CONFIG_FSL_MC_ENET +void fdt_fixup_board_enet(void *fdt) +{ + int offset; + + offset = fdt_path_offset(fdt, "/fsl-mc"); + + if (offset < 0) + offset = fdt_path_offset(fdt, "/fsl,dprc@0"); + + 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) + fdt_status_okay(fdt, offset); + else + fdt_status_fail(fdt, offset); +} +#endif + +#ifdef CONFIG_OF_BOARD_SETUP +int ft_board_setup(void *blob, bd_t *bd) +{ + int err, i; + u64 base[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + + ft_cpu_setup(blob, bd); + + /* 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 + + fdt_fixup_memory_banks(blob, base, size, CONFIG_NR_DRAM_BANKS); + +#ifdef CONFIG_FSL_MC_ENET + fdt_fixup_board_enet(blob); + err = fsl_mc_ldpaa_exit(bd); + if (err) + return err; +#endif + + return 0; +} +#endif diff --git a/board/freescale/ls1088a/ls1088a_qixis.h b/board/freescale/ls1088a/ls1088a_qixis.h new file mode 100644 index 0000000000..4790461b47 --- /dev/null +++ b/board/freescale/ls1088a/ls1088a_qixis.h @@ -0,0 +1,39 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#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 + +#endif diff --git a/board/freescale/ls2080aqds/ls2080aqds.c b/board/freescale/ls2080aqds/ls2080aqds.c index 83773d0af5..1842d14e87 100644 --- a/board/freescale/ls2080aqds/ls2080aqds.c +++ b/board/freescale/ls2080aqds/ls2080aqds.c @@ -226,15 +226,14 @@ int board_init(void) #endif select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); rtc_enable_32khz_output(); +#ifdef CONFIG_FSL_CAAM + sec_init(); +#endif #ifdef CONFIG_FSL_LS_PPA ppa_init(); #endif -#ifdef CONFIG_FSL_CAAM - sec_init(); -#endif - return 0; } diff --git a/board/freescale/ls2080ardb/MAINTAINERS b/board/freescale/ls2080ardb/MAINTAINERS index 91f13ea717..8da1c6d0ae 100644 --- a/board/freescale/ls2080ardb/MAINTAINERS +++ b/board/freescale/ls2080ardb/MAINTAINERS @@ -21,3 +21,8 @@ LS2080A_SECURE_BOOT BOARD M: Saksham Jain <saksham.jain@nxp.freescale.com> S: Maintained F: configs/ls2080ardb_SECURE_BOOT_defconfig + +LS2088A_QSPI_SECURE_BOOT BOARD +M: Udit Agarwal <udit.agarwal@nxp.com> +S: Maintained +F: configs/ls2088ardb_qspi_SECURE_BOOT_defconfig diff --git a/board/freescale/ls2080ardb/ls2080ardb.c b/board/freescale/ls2080ardb/ls2080ardb.c index 07ba0266d5..666562d106 100644 --- a/board/freescale/ls2080ardb/ls2080ardb.c +++ b/board/freescale/ls2080ardb/ls2080ardb.c @@ -218,6 +218,10 @@ int board_init(void) #ifdef CONFIG_FSL_QIXIS QIXIS_WRITE(rst_ctl, QIXIS_RST_CTL_RESET_EN); #endif + +#ifdef CONFIG_FSL_CAAM + sec_init(); +#endif #ifdef CONFIG_FSL_LS_PPA ppa_init(); #endif |