From 58c3e62040befff8a32a9fd157b0dcd23de194ec Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Wed, 28 Nov 2018 13:04:27 +0000 Subject: armv8: lx2160ardb : Add support for LX2160ARDB platform LX2160ARDB is an evaluation board that supports LX2160A family SoCs. This patch add base support for this board. Signed-off-by: Wasim Khan Signed-off-by: Yogesh Gaur Signed-off-by: Meenakshi Aggarwal Signed-off-by: Vabhav Sharma Signed-off-by: Sriram Dash Signed-off-by: Rajesh Bhagat Signed-off-by: Pankit Garg Signed-off-by: Yinbo Zhu Signed-off-by: Peng Ma Signed-off-by: Chuanhua Han Signed-off-by: Priyanka Jain [PK: Sqaush patches from Yinbo Zhu, Peng Ma, Chuanhua Han and re-arrange defconfig] Signed-off-by: Prabhakar Kushwaha --- board/freescale/lx2160a/Kconfig | 16 ++ board/freescale/lx2160a/MAINTAINERS | 8 + board/freescale/lx2160a/Makefile | 9 + board/freescale/lx2160a/README | 79 +++++++++ board/freescale/lx2160a/ddr.c | 20 +++ board/freescale/lx2160a/eth_lx2160ardb.c | 210 +++++++++++++++++++++++ board/freescale/lx2160a/lx2160a.c | 279 +++++++++++++++++++++++++++++++ 7 files changed, 621 insertions(+) create mode 100644 board/freescale/lx2160a/Kconfig create mode 100644 board/freescale/lx2160a/MAINTAINERS create mode 100644 board/freescale/lx2160a/Makefile create mode 100644 board/freescale/lx2160a/README create mode 100644 board/freescale/lx2160a/ddr.c create mode 100644 board/freescale/lx2160a/eth_lx2160ardb.c create mode 100644 board/freescale/lx2160a/lx2160a.c (limited to 'board/freescale/lx2160a') diff --git a/board/freescale/lx2160a/Kconfig b/board/freescale/lx2160a/Kconfig new file mode 100644 index 0000000..5562c3e --- /dev/null +++ b/board/freescale/lx2160a/Kconfig @@ -0,0 +1,16 @@ +if TARGET_LX2160ARDB + +config SYS_BOARD + default "lx2160a" + +config SYS_VENDOR + default "freescale" + +config SYS_SOC + default "fsl-layerscape" + +config SYS_CONFIG_NAME + default "lx2160ardb" + +source "board/freescale/common/Kconfig" +endif diff --git a/board/freescale/lx2160a/MAINTAINERS b/board/freescale/lx2160a/MAINTAINERS new file mode 100644 index 0000000..aeb7dbc --- /dev/null +++ b/board/freescale/lx2160a/MAINTAINERS @@ -0,0 +1,8 @@ +LX2160ARDB BOARD +M: Priyanka Jain +S: Maintained +F: board/freescale/lx2160a/ +F: include/configs/lx2160a_common.h +F: include/configs/lx2160ardb.h +F: configs/lx2160ardb_tfa_defconfig +F: arch/arm/dts/fsl-lx2160a-rdb.dts diff --git a/board/freescale/lx2160a/Makefile b/board/freescale/lx2160a/Makefile new file mode 100644 index 0000000..be3709d --- /dev/null +++ b/board/freescale/lx2160a/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2018 Freescale Semiconductor +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += lx2160a.o +obj-y += ddr.o +obj-$(CONFIG_TARGET_LX2160ARDB) += eth_lx2160ardb.o diff --git a/board/freescale/lx2160a/README b/board/freescale/lx2160a/README new file mode 100644 index 0000000..618c40b --- /dev/null +++ b/board/freescale/lx2160a/README @@ -0,0 +1,79 @@ +Overview +-------- +The LX2160A Reference Design (RDB) is a high-performance computing, +evaluation, and development platform that supports the QorIQ LX2160A +Layerscape Architecture processor and its personalities. + +LX2160A SoC Overview +-------------------------------------- +For details, please refer arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc + +LX2160ARDB board Overview +---------------------- +DDR Memory + Two ports of 72-bits (8-bits ECC) DDR4. + Each port supports four chip-selects and two DIMM + connectors. Data rate upto 3.2 GT/s. + +SERDES ports + Thress serdes controllers (24 lanes) + Serdes1: Supports two USXGMII connectors, each connected through + Aquantia AQR107 phy, two 25GbE SFP+ modules connected through an Inphi + IN112525 phy and one 40 GbE QSFP+ module connected through an Inphi + CS4223 phy. + + Serdes2: Supports one PCIe x4 (Gen1/2/3/4) connector, four SATA 3.0 + connectors + + Serdes3: Supports one PCIe x8 (Gen1/2/3/4) connector + +eSDHC + eSDHC1: Supports a SD connector for connecting SD cards + eSDHC2: Supports 128GB Micron MTFC128GAJAECE-IT eMMC + +Octal SPI (XSPI) + Supports two 64 MB onbpard octal SPI flash memories, one SPI emulator + for off-board emulation + +I2C All system devices on I2C1 multiplexed using PCA9547 multiplexer + Serial Ports + +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 + +Serial Ports Two UART ports +Ethernet Two RGMII interfaces +Debug ARM JTAG support + +Booting Options +--------------- +a) Flexspi boot +b) SD boot + +Memory map for Flexspi flash +---------------------------- +Image Flash Offset +bl2_flexspi_nor.pbl (RCW+PBI+bl2.pbl) 0x00000000 +fip.bin (bl31 + bl33(u-boot) + + header for Secure-boot(secure-boot only)) 0x00100000 +Boot firmware Environment 0x00500000 +DDR PHY Firmware (fip_ddr_all.bin) 0x00800000 +DPAA2 MC Firmware 0x00A00000 +DPAA2 DPL 0x00D00000 +DPAA2 DPC 0x00E00000 +Kernel.itb 0x01000000 + +Memory map for sd card +---------------------------- +Image SD card Offset +bl2_sd.pbl (RCW+PBI+bl2.pbl) 0x00008 +fip.bin (bl31 + bl33(u-boot) + + header for Secure-boot(secure-boot only)) 0x00800 +Boot firmware Environment 0x02800 +DDR PHY Firmware (fip_ddr_all.bin) 0x04000 +DPAA2 MC Firmware 0x05000 +DPAA2 DPL 0x06800 +DPAA2 DPC 0x07000 +Kernel.itb 0x08000 diff --git a/board/freescale/lx2160a/ddr.c b/board/freescale/lx2160a/ddr.c new file mode 100644 index 0000000..cd422bf --- /dev/null +++ b/board/freescale/lx2160a/ddr.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int fsl_initdram(void) +{ + gd->ram_size = tfa_get_dram_size(); + + if (!gd->ram_size) + gd->ram_size = fsl_ddr_sdram_size(); + + return 0; +} diff --git a/board/freescale/lx2160a/eth_lx2160ardb.c b/board/freescale/lx2160a/eth_lx2160ardb.c new file mode 100644 index 0000000..365ff73 --- /dev/null +++ b/board/freescale/lx2160a/eth_lx2160ardb.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static bool get_inphi_phy_id(struct mii_dev *bus, int addr, int devad) +{ + int phy_reg; + u32 phy_id; + + phy_reg = bus->read(bus, addr, devad, MII_PHYSID1); + phy_id = (phy_reg & 0xffff) << 16; + + phy_reg = bus->read(bus, addr, devad, MII_PHYSID2); + phy_id |= (phy_reg & 0xffff); + + if (phy_id == PHY_UID_IN112525_S03) + return true; + else + return false; +} + +int board_eth_init(bd_t *bis) +{ +#if defined(CONFIG_FSL_MC_ENET) + struct memac_mdio_info mdio_info; + struct memac_mdio_controller *reg; + int i, interface; + struct mii_dev *dev; + struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 srds_s1; + + srds_s1 = in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK; + srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; + + 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); + + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); + switch (srds_s1) { + case 19: + wriop_set_phy_address(WRIOP1_DPMAC2, 0, + CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC3, 0, + AQR107_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC4, 0, + AQR107_PHY_ADDR2); + if (get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) { + wriop_set_phy_address(WRIOP1_DPMAC5, 0, + INPHI_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC6, 0, + INPHI_PHY_ADDR1); + } + wriop_set_phy_address(WRIOP1_DPMAC17, 0, + RGMII_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC18, 0, + RGMII_PHY_ADDR2); + break; + + case 18: + wriop_set_phy_address(WRIOP1_DPMAC7, 0, + CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC8, 0, + CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC9, 0, + CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC10, 0, + CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC3, 0, + AQR107_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC4, 0, + AQR107_PHY_ADDR2); + if (get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) { + wriop_set_phy_address(WRIOP1_DPMAC5, 0, + INPHI_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC6, 0, + INPHI_PHY_ADDR1); + } + wriop_set_phy_address(WRIOP1_DPMAC17, 0, + RGMII_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC18, 0, + RGMII_PHY_ADDR2); + break; + + default: + printf("SerDes1 protocol 0x%x is not supported on LX2160ARDB\n", + srds_s1); + goto next; + } + + for (i = WRIOP1_DPMAC2; i <= WRIOP1_DPMAC10; i++) { + interface = wriop_get_enet_if(i); + switch (interface) { + case PHY_INTERFACE_MODE_XGMII: + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); + wriop_set_mdio(i, dev); + break; + case PHY_INTERFACE_MODE_25G_AUI: + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); + wriop_set_mdio(i, dev); + break; + case PHY_INTERFACE_MODE_XLAUI: + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); + wriop_set_mdio(i, dev); + break; + default: + break; + } + } + for (i = WRIOP1_DPMAC17; i <= WRIOP1_DPMAC18; i++) { + interface = wriop_get_enet_if(i); + switch (interface) { + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); + wriop_set_mdio(i, dev); + break; + default: + break; + } + } + +next: + cpu_eth_init(bis); +#endif /* CONFIG_FSL_MC_ENET */ + +#ifdef CONFIG_PHY_AQUANTIA + /* + * Export functions to be used by AQ firmware + * upload application + */ + gd->jt->strcpy = strcpy; + gd->jt->mdelay = mdelay; + gd->jt->mdio_get_current_dev = mdio_get_current_dev; + gd->jt->phy_find_by_mask = phy_find_by_mask; + gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname; + gd->jt->miiphy_set_current_dev = miiphy_set_current_dev; +#endif + return pci_eth_init(bis); +} + +#if defined(CONFIG_RESET_PHY_R) +void reset_phy(void) +{ +#if defined(CONFIG_FSL_MC_ENET) + mc_env_boot(); +#endif +} +#endif /* CONFIG_RESET_PHY_R */ + +int fdt_fixup_board_phy(void *fdt) +{ + int mdio_offset; + int ret; + struct mii_dev *dev; + + ret = 0; + + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); + if (!get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) { + mdio_offset = fdt_path_offset(fdt, "/soc/mdio@0x8B97000"); + + if (mdio_offset < 0) + mdio_offset = fdt_path_offset(fdt, "/mdio@0x8B97000"); + + if (mdio_offset < 0) { + printf("mdio@0x8B9700 node not found in dts\n"); + return mdio_offset; + } + + ret = fdt_setprop_string(fdt, mdio_offset, "status", + "disabled"); + if (ret) { + printf("Could not set disable mdio@0x8B97000 %s\n", + fdt_strerror(ret)); + return ret; + } + } + + return ret; +} diff --git a/board/freescale/lx2160a/lx2160a.c b/board/freescale/lx2160a/lx2160a.c new file mode 100644 index 0000000..a62222e --- /dev/null +++ b/board/freescale/lx2160a/lx2160a.c @@ -0,0 +1,279 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/qixis.h" +#include "../common/vid.h" +#include + +DECLARE_GLOBAL_DATA_PTR; + +static struct pl01x_serial_platdata serial0 = { +#if CONFIG_CONS_INDEX == 0 + .base = CONFIG_SYS_SERIAL0, +#elif CONFIG_CONS_INDEX == 1 + .base = CONFIG_SYS_SERIAL1, +#else +#error "Unsupported console index value." +#endif + .type = TYPE_PL011, +}; + +U_BOOT_DEVICE(nxp_serial0) = { + .name = "serial_pl01x", + .platdata = &serial0, +}; + +static struct pl01x_serial_platdata serial1 = { + .base = CONFIG_SYS_SERIAL1, + .type = TYPE_PL011, +}; + +U_BOOT_DEVICE(nxp_serial1) = { + .name = "serial_pl01x", + .platdata = &serial1, +}; + +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; +} + +static void uart_get_clock(void) +{ + serial0.clock = get_serial_clock(); + serial1.clock = get_serial_clock(); +} + +int board_early_init_f(void) +{ +#ifdef CONFIG_SYS_I2C_EARLY_INIT + i2c_early_init_f(); +#endif + /* get required clock for UART IP */ + uart_get_clock(); + + fsl_lsch3_early_init_f(); + return 0; +} + +int esdhc_status_fixup(void *blob, const char *compat) +{ + /* Enable both esdhc DT nodes for LX2160ARDB */ + do_fixup_by_compat(blob, compat, "status", "okay", + sizeof("okay"), 1); + + return 0; +} + +#if defined(CONFIG_VID) +int i2c_multiplexer_select_vid_channel(u8 channel) +{ + return select_i2c_ch_pca9547(channel); +} + +#endif + +int checkboard(void) +{ + enum boot_src src = get_boot_src(); + char buf[64]; + u8 sw; + + cpu_name(buf); + printf("Board: %s-RDB, ", buf); + + sw = QIXIS_READ(arch); + printf("Board version: %c, boot from ", (sw & 0xf) - 1 + 'A'); + + if (src == BOOT_SOURCE_SD_MMC) { + puts("SD\n"); + } else { + sw = QIXIS_READ(brdcfg[0]); + sw = (sw >> QIXIS_XMAP_SHIFT) & QIXIS_XMAP_MASK; + switch (sw) { + case 0: + case 4: + puts("FlexSPI DEV#0\n"); + break; + case 1: + puts("FlexSPI DEV#1\n"); + break; + case 2: + case 3: + puts("FlexSPI EMU\n"); + break; + default: + printf("invalid setting, xmap: %d\n", sw); + break; + } + } + printf("FPGA: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata)); + + puts("SERDES1 Reference: Clock1 = 161.13MHz Clock2 = 161.13MHz\n"); + puts("SERDES2 Reference: Clock1 = 100MHz Clock2 = 100MHz\n"); + puts("SERDES3 Reference: Clock1 = 100MHz Clock2 = 100Hz\n"); + return 0; +} + +unsigned long get_board_sys_clk(void) +{ + return 100000000; +} + +unsigned long get_board_ddr_clk(void) +{ + return 100000000; +} + +int board_init(void) +{ +#ifdef CONFIG_ENV_IS_NOWHERE + gd->env_addr = (ulong)&default_environment[0]; +#endif + + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + +#ifdef CONFIG_FSL_CAAM + sec_init(); +#endif + + return 0; +} + +void detail_board_ddr_info(void) +{ + int i; + u64 ddr_size = 0; + + puts("\nDDR "); + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) + ddr_size += gd->bd->bi_dram[i].size; + print_size(ddr_size, ""); + print_ddr_info(0); +} + +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_FSL_MC_ENET +extern int fdt_fixup_board_phy(void *fdt); + +void fdt_fixup_board_enet(void *fdt) +{ + int offset; + + offset = fdt_path_offset(fdt, "/soc/fsl-mc"); + + if (offset < 0) + offset = fdt_path_offset(fdt, "/fsl-mc"); + + if (offset < 0) { + printf("%s: fsl-mc node not found in device tree (error %d)\n", + __func__, offset); + return; + } + + if ((get_mc_boot_status() == 0) && (get_dpl_apply_status() == 0)) { + fdt_status_okay(fdt, offset); + fdt_fixup_board_phy(fdt); + } else { + fdt_status_fail(fdt, offset); + } +} + +void board_quiesce_devices(void) +{ + fsl_mc_ldpaa_exit(gd->bd); +} +#endif + +#ifdef CONFIG_OF_BOARD_SETUP + +int ft_board_setup(void *blob, bd_t *bd) +{ + int i; + u64 base[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + + ft_cpu_setup(blob, bd); + + /* fixup DT for the three 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]; + else if (gd->arch.resv_ram >= base[2] && + gd->arch.resv_ram < base[2] + size[2]) + size[2] = gd->arch.resv_ram - base[2]; +#endif + + fdt_fixup_memory_banks(blob, base, size, CONFIG_NR_DRAM_BANKS); + +#ifdef CONFIG_USB + fsl_fdt_fixup_dr_usb(blob, bd); +#endif + +#ifdef CONFIG_FSL_MC_ENET + fdt_fsl_mc_fixup_iommu_map_entry(blob); + fdt_fixup_board_enet(blob); +#endif + + return 0; +} +#endif + +void qixis_dump_switch(void) +{ + int i, nr_of_cfgsw; + + QIXIS_WRITE(cms[0], 0x00); + nr_of_cfgsw = QIXIS_READ(cms[1]); + + puts("DIP switch settings dump:\n"); + for (i = 1; i <= nr_of_cfgsw; i++) { + QIXIS_WRITE(cms[0], i); + printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1])); + } +} -- cgit v1.1