From 185e586dac02be44c7e707754cf6bb313ade2bba Mon Sep 17 00:00:00 2001 From: Pratiyush Srivastava Date: Mon, 10 Oct 2016 18:45:15 +0530 Subject: [PATCH 01/25] armv8:ls1012a: Update bootargs for fast-boot Add optimization parameters like "quiet" in bootargs to reduce the system boot time Signed-off-by: Pratiyush Mohan Srivastava Signed-off-by: Harninder Rai Reviewed-by: York Sun --- include/configs/ls1012a_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/ls1012a_common.h b/include/configs/ls1012a_common.h index 80603c9e46..20f0c6143c 100644 --- a/include/configs/ls1012a_common.h +++ b/include/configs/ls1012a_common.h @@ -110,7 +110,7 @@ "kernel_size=0x2800000\0" \ #define CONFIG_BOOTARGS "console=ttyS0,115200 root=/dev/ram0 " \ - "earlycon=uart8250,mmio,0x21c0500" + "earlycon=uart8250,mmio,0x21c0500 quiet lpj=250000" #define CONFIG_BOOTCOMMAND "sf probe 0:0; sf read $kernel_load "\ "$kernel_start $kernel_size && "\ "bootm $kernel_load" From 21640db51b905aa9bee75a01ca89446ce4795ff1 Mon Sep 17 00:00:00 2001 From: Yuan Yao Date: Tue, 11 Oct 2016 12:13:40 +0800 Subject: [PATCH 02/25] configs: ls2080ardb: Enable DSPI flash support There is the stmicro DSPI flash on LS12080ARDB. Enable DSPI flash related configure options. Signed-off-by: Yuan Yao Reviewed-by: York Sun --- include/configs/ls2080ardb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h index 32fa0eb3ee..31df781934 100644 --- a/include/configs/ls2080ardb.h +++ b/include/configs/ls2080ardb.h @@ -269,6 +269,7 @@ unsigned long get_board_sys_clk(void); #ifdef CONFIG_FSL_DSPI #define CONFIG_SPI_FLASH #define CONFIG_SPI_FLASH_BAR +#define CONFIG_SPI_FLASH_STMICRO #endif /* From 20c700f8daee0b3995c5a6d2c5f69eef1c7acd4e Mon Sep 17 00:00:00 2001 From: Feng Li Date: Thu, 3 Nov 2016 14:15:17 +0800 Subject: [PATCH 03/25] armv7: Add support of ls1021a-iot board The patch adds support for Freescale ls1021a-iot board. Signed-off-by: Feng Li [YS: rewrite commit message, fix whitespace in Kconfig] Reviewed-by: York Sun --- arch/arm/Kconfig | 15 + arch/arm/dts/Makefile | 3 +- arch/arm/dts/ls1021a-iot-duart.dts | 16 + arch/arm/dts/ls1021a-iot.dtsi | 103 +++++ board/freescale/ls1021aiot/Kconfig | 15 + board/freescale/ls1021aiot/MAINTAINERS | 7 + board/freescale/ls1021aiot/Makefile | 9 + board/freescale/ls1021aiot/README | 58 +++ board/freescale/ls1021aiot/dcu.c | 47 +++ board/freescale/ls1021aiot/ls1021aiot.c | 259 ++++++++++++ board/freescale/ls1021aiot/ls102xa_pbi.cfg | 14 + board/freescale/ls1021aiot/ls102xa_rcw_sd.cfg | 27 ++ board/freescale/ls1021aiot/psci.S | 28 ++ configs/ls1021aiot_qspi_defconfig | 15 + configs/ls1021aiot_sdcard_defconfig | 17 + include/configs/ls1021aiot.h | 367 ++++++++++++++++++ 16 files changed, 999 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/ls1021a-iot-duart.dts create mode 100644 arch/arm/dts/ls1021a-iot.dtsi create mode 100644 board/freescale/ls1021aiot/Kconfig create mode 100644 board/freescale/ls1021aiot/MAINTAINERS create mode 100644 board/freescale/ls1021aiot/Makefile create mode 100644 board/freescale/ls1021aiot/README create mode 100644 board/freescale/ls1021aiot/dcu.c create mode 100644 board/freescale/ls1021aiot/ls1021aiot.c create mode 100644 board/freescale/ls1021aiot/ls102xa_pbi.cfg create mode 100644 board/freescale/ls1021aiot/ls102xa_rcw_sd.cfg create mode 100644 board/freescale/ls1021aiot/psci.S create mode 100644 configs/ls1021aiot_qspi_defconfig create mode 100644 configs/ls1021aiot_sdcard_defconfig create mode 100644 include/configs/ls1021aiot.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d7a9b11c76..9d4d74235a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -761,6 +761,20 @@ config TARGET_LS1021ATWR select ARCH_SUPPORT_PSCI select LS1_DEEP_SLEEP +config TARGET_LS1021AIOT + bool "Support ls1021aiot" + select CPU_V7 + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT + select SUPPORT_SPL + select ARCH_LS1021A + select ARCH_SUPPORT_PSCI + help + Support for Freescale LS1021AIOT platform. + The LS1021A Freescale board (IOT) is a high-performance + development platform that supports the QorIQ LS1021A + Layerscape Architecture processor. + config TARGET_LS1043AQDS bool "Support ls1043aqds" select ARCH_LS1043A @@ -962,6 +976,7 @@ source "board/freescale/ls2080ardb/Kconfig" source "board/freescale/ls1021aqds/Kconfig" source "board/freescale/ls1043aqds/Kconfig" source "board/freescale/ls1021atwr/Kconfig" +source "board/freescale/ls1021aiot/Kconfig" source "board/freescale/ls1046aqds/Kconfig" source "board/freescale/ls1043ardb/Kconfig" source "board/freescale/ls1046ardb/Kconfig" diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 2c5b2f22c6..36133f59e3 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -143,7 +143,8 @@ dtb-$(CONFIG_TARGET_STV0991) += stv0991.dtb dtb-$(CONFIG_LS102XA) += ls1021a-qds-duart.dtb \ ls1021a-qds-lpuart.dtb \ - ls1021a-twr-duart.dtb ls1021a-twr-lpuart.dtb + ls1021a-twr-duart.dtb ls1021a-twr-lpuart.dtb \ + ls1021a-iot-duart.dtb dtb-$(CONFIG_FSL_LSCH3) += fsl-ls2080a-qds.dtb \ fsl-ls2080a-rdb.dtb dtb-$(CONFIG_FSL_LSCH2) += fsl-ls1043a-qds-duart.dtb \ diff --git a/arch/arm/dts/ls1021a-iot-duart.dts b/arch/arm/dts/ls1021a-iot-duart.dts new file mode 100644 index 0000000000..62e4c67040 --- /dev/null +++ b/arch/arm/dts/ls1021a-iot-duart.dts @@ -0,0 +1,16 @@ +/* + * Freescale ls1021a IOT board device tree source + * + * Copyright 2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +#include "ls1021a-iot.dtsi" + +/ { + chosen { + stdout-path = &uart0; + }; +}; diff --git a/arch/arm/dts/ls1021a-iot.dtsi b/arch/arm/dts/ls1021a-iot.dtsi new file mode 100644 index 0000000000..1817c62c04 --- /dev/null +++ b/arch/arm/dts/ls1021a-iot.dtsi @@ -0,0 +1,103 @@ +/* + * Freescale ls1021a IOT board device tree source + * + * Copyright 2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include "ls1021a.dtsi" + +/ { + model = "LS1021A IOT Board"; + + aliases { + enet2_rgmii_phy = &rgmii_phy1; + enet0_sgmii_phy = &sgmii_phy2; + enet1_sgmii_phy = &sgmii_phy0; + spi0 = &qspi; + spi1 = &dspi1; + }; +}; + +&qspi { + bus-num = <0>; + status = "okay"; + + qflash0: n25q128a13@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + spi-max-frequency = <20000000>; + reg = <0>; + }; +}; + +&dspi1 { + bus-num = <0>; + status = "okay"; + + dspiflash: at26df081a@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + spi-max-frequency = <16000000>; + spi-cpol; + spi-cpha; + reg = <0>; + }; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&ifc { + #address-cells = <2>; + #size-cells = <1>; + /* NOR Flash on board */ + ranges = <0x0 0x0 0x60000000 0x08000000>; + status = "okay"; + + nor@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x0 0x0 0x8000000>; + bank-width = <2>; + device-width = <1>; + }; +}; + +&lpuart0 { + status = "okay"; +}; + +&mdio0 { + sgmii_phy0: ethernet-phy@0 { + reg = <0x0>; + }; + rgmii_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + sgmii_phy2: ethernet-phy@2 { + reg = <0x2>; + }; + tbi1: tbi-phy@1f { + reg = <0x1f>; + device_type = "tbi-phy"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; diff --git a/board/freescale/ls1021aiot/Kconfig b/board/freescale/ls1021aiot/Kconfig new file mode 100644 index 0000000000..4a12c1687f --- /dev/null +++ b/board/freescale/ls1021aiot/Kconfig @@ -0,0 +1,15 @@ +if TARGET_LS1021AIOT + +config SYS_BOARD + default "ls1021aiot" + +config SYS_VENDOR + default "freescale" + +config SYS_SOC + default "ls102xa" + +config SYS_CONFIG_NAME + default "ls1021aiot" + +endif diff --git a/board/freescale/ls1021aiot/MAINTAINERS b/board/freescale/ls1021aiot/MAINTAINERS new file mode 100644 index 0000000000..2dab7988ee --- /dev/null +++ b/board/freescale/ls1021aiot/MAINTAINERS @@ -0,0 +1,7 @@ +LS1021AIOT BOARD +M: Feng Li +S: Maintained +F: board/freescale/ls1021aiot/ +F: include/configs/ls1021aiot.h +F: configs/ls1021aiot_sdcard_defconfig +F: configs/ls1021aiot_qspi_defconfig diff --git a/board/freescale/ls1021aiot/Makefile b/board/freescale/ls1021aiot/Makefile new file mode 100644 index 0000000000..05709e685c --- /dev/null +++ b/board/freescale/ls1021aiot/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2016 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ls1021aiot.o +obj-$(CONFIG_FSL_DCU_FB) += dcu.o +obj-$(CONFIG_ARMV7_PSCI) += psci.o diff --git a/board/freescale/ls1021aiot/README b/board/freescale/ls1021aiot/README new file mode 100644 index 0000000000..08b0268b9b --- /dev/null +++ b/board/freescale/ls1021aiot/README @@ -0,0 +1,58 @@ +Overview +-------- +The LS1021A-IOT is a Freescale reference board that hosts +the LS1021A SoC. + +LS1021AIOT board Overview +------------------------- + - DDR Controller + - Supports 1GB un-buffered DDR3L SDRAM discrete + devices(32-bit bus) with 4 bit ECC + - DDR power supplies 1.35V to all devices with + automatic tracking of VTT + - Soldered DDR chip + - Supprot one fixed speed + - Ethernet + - Two on-board SGMII 10/100/1G ethernet ports + - One Gbit Etherent RGMII interface to 4-ports switch + with 4x 10/100/1000 RJ145 ports + - CPLD + - 8-bit registers in CPLD for system configuration + - connected to IFC_AD[0:7] + - Power Supplies + - 12V@5A DC + - SDHC + - SDHC port connects directly to a full 8-bit SD/MMC slot + - Support for SDIO devices + - USB + - Two on-board USB 3.0 + - One on-board USB k22 + - PCIe + - Two MiniPCIe Solts + - SATA + - Support SATA Connector + - AUDIO + - AUDIO in and out + - I/O Expansion + - Arduino Shield Connector + - Port0 - CAN/GPIO/Flextimer + - Port1 - GPIO/CPLD Expansion + - Port2 - SPI/I2C/UART + +Memory map +----------- +The addresses in brackets are physical addresses. + +Start Address End Address Description Size +0x00_0100_0000 0x00_0FFF_FFFF CCSRBAR 240MB +0x00_4000_0000 0x00_43FF_FFFF QSPI(Chip select 0) 64MB +0x00_4400_0000 0x00_47FF_FFFF QSPI(Chip select 1) 64MB +0x00_6000_0000 0x00_6000_FFFF CPLD 64K +0x00_8000_0000 0x00_BFFF_FFFF DDR 1GB + +Boot description +----------------- +LS1021A-IOT support two ways of boot: +Qspi boot and SD boot +The board doesn't support boot from another +source without changing any switch/jumper. diff --git a/board/freescale/ls1021aiot/dcu.c b/board/freescale/ls1021aiot/dcu.c new file mode 100644 index 0000000000..e27647f6e6 --- /dev/null +++ b/board/freescale/ls1021aiot/dcu.c @@ -0,0 +1,47 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * + * FSL DCU Framebuffer driver + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include "div64.h" +#include "../common/dcu_sii9022a.h" + +DECLARE_GLOBAL_DATA_PTR; + +unsigned int dcu_set_pixel_clock(unsigned int pixclock) +{ + unsigned long long div; + + div = (unsigned long long)(gd->bus_clk / 1000); + div *= (unsigned long long)pixclock; + do_div(div, 1000000000); + + return div; +} + +int platform_dcu_init(unsigned int xres, unsigned int yres, + const char *port, + struct fb_videomode *dcu_fb_videomode) +{ + const char *name; + unsigned int pixel_format; + + if (strncmp(port, "twr_lcd", 4) == 0) { + name = "TWR_LCD_RGB card"; + } else { + name = "HDMI"; + dcu_set_dvi_encoder(dcu_fb_videomode); + } + + printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres); + + pixel_format = 32; + fsl_dcu_init(xres, yres, pixel_format); + + return 0; +} diff --git a/board/freescale/ls1021aiot/ls1021aiot.c b/board/freescale/ls1021aiot/ls1021aiot.c new file mode 100644 index 0000000000..3340e4db80 --- /dev/null +++ b/board/freescale/ls1021aiot/ls1021aiot.c @@ -0,0 +1,259 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../common/sleep.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define DDR_SIZE 0x40000000 + + +int checkboard(void) +{ + puts("Board: LS1021AIOT\n"); + +#ifndef CONFIG_QSPI_BOOT + struct ccsr_gur *dcfg = (struct ccsr_gur *)CONFIG_SYS_FSL_GUTS_ADDR; + u32 cpldrev; + + cpldrev = in_be32(&dcfg->gpporcr1); + + printf("CPLD: V%d.%d\n", ((cpldrev >> 28) & 0xf), ((cpldrev >> 24) & + 0xf)); +#endif + return 0; +} + +void ddrmc_init(void) +{ + struct ccsr_ddr *ddr = (struct ccsr_ddr *)CONFIG_SYS_FSL_DDR_ADDR; + u32 temp_sdram_cfg, tmp; + + out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG); + + out_be32(&ddr->cs0_bnds, DDR_CS0_BNDS); + out_be32(&ddr->cs0_config, DDR_CS0_CONFIG); + + out_be32(&ddr->timing_cfg_0, DDR_TIMING_CFG_0); + out_be32(&ddr->timing_cfg_1, DDR_TIMING_CFG_1); + out_be32(&ddr->timing_cfg_2, DDR_TIMING_CFG_2); + out_be32(&ddr->timing_cfg_3, DDR_TIMING_CFG_3); + out_be32(&ddr->timing_cfg_4, DDR_TIMING_CFG_4); + out_be32(&ddr->timing_cfg_5, DDR_TIMING_CFG_5); + + out_be32(&ddr->sdram_cfg_2, DDR_SDRAM_CFG_2); + out_be32(&ddr->ddr_cdr2, DDR_DDR_CDR2); + + out_be32(&ddr->sdram_mode, DDR_SDRAM_MODE); + out_be32(&ddr->sdram_mode_2, DDR_SDRAM_MODE_2); + + out_be32(&ddr->sdram_interval, DDR_SDRAM_INTERVAL); + + out_be32(&ddr->ddr_wrlvl_cntl, DDR_DDR_WRLVL_CNTL); + + out_be32(&ddr->ddr_wrlvl_cntl_2, DDR_DDR_WRLVL_CNTL_2); + out_be32(&ddr->ddr_wrlvl_cntl_3, DDR_DDR_WRLVL_CNTL_3); + + out_be32(&ddr->ddr_cdr1, DDR_DDR_CDR1); + + out_be32(&ddr->sdram_clk_cntl, DDR_SDRAM_CLK_CNTL); + out_be32(&ddr->ddr_zq_cntl, DDR_DDR_ZQ_CNTL); + + out_be32(&ddr->cs0_config_2, DDR_CS0_CONFIG_2); + + /* DDR erratum A-009942 */ + tmp = in_be32(&ddr->debug[28]); + out_be32(&ddr->debug[28], tmp | 0x0070006f); + + udelay(500); + + temp_sdram_cfg = (DDR_SDRAM_CFG_MEM_EN & ~SDRAM_CFG_BI); + + out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG | temp_sdram_cfg); +} + +int dram_init(void) +{ +#if (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) + ddrmc_init(); +#endif + + gd->ram_size = DDR_SIZE; + return 0; +} + +#ifdef CONFIG_FSL_ESDHC +struct fsl_esdhc_cfg esdhc_cfg[1] = { + {CONFIG_SYS_FSL_ESDHC_ADDR}, +}; + +int board_mmc_init(bd_t *bis) +{ + esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + + return fsl_esdhc_initialize(bis, &esdhc_cfg[0]); +} + +#endif + +#ifdef CONFIG_TSEC_ENET +int board_eth_init(bd_t *bis) +{ + struct fsl_pq_mdio_info mdio_info; + struct tsec_info_struct tsec_info[4]; + int num = 0; + +#ifdef CONFIG_TSEC1 + SET_STD_TSEC_INFO(tsec_info[num], 1); + if (is_serdes_configured(SGMII_TSEC1)) { + puts("eTSEC1 is in sgmii mode.\n"); + tsec_info[num].flags |= TSEC_SGMII; + } + num++; +#endif +#ifdef CONFIG_TSEC2 + SET_STD_TSEC_INFO(tsec_info[num], 2); + if (is_serdes_configured(SGMII_TSEC2)) { + puts("eTSEC2 is in sgmii mode.\n"); + tsec_info[num].flags |= TSEC_SGMII; + } + num++; +#endif + if (!num) { + printf("No TSECs initialized\n"); + return 0; + } + + mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; + mdio_info.name = DEFAULT_MII_NAME; + fsl_pq_mdio_init(bis, &mdio_info); + + tsec_eth_init(bis, tsec_info, num); + + return pci_eth_init(bis); +} +#endif + +int board_early_init_f(void) +{ + struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; + +#ifdef CONFIG_TSEC_ENET + /* clear BD & FR bits for BE BD's and frame data */ + clrbits_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR); + out_be32(&scfg->etsecmcr, SCFG_ETSECCMCR_GE2_CLK125); + +#endif + + arch_soc_init(); + + return 0; +} + +#ifdef CONFIG_SPL_BUILD +void board_init_f(ulong dummy) +{ + /* Clear the BSS */ + memset(__bss_start, 0, __bss_end - __bss_start); + + get_clocks(); + + preloader_console_init(); + + dram_init(); + + /* Allow OCRAM access permission as R/W */ + +#ifdef CONFIG_LAYERSCAPE_NS_ACCESS + enable_layerscape_ns_access(); +#endif + + board_init_r(NULL, 0); +} +#endif + +int board_init(void) +{ +#ifndef CONFIG_SYS_FSL_NO_SERDES + fsl_serdes_init(); +#endif + + ls102xa_smmu_stream_id_init(); + +#ifdef CONFIG_LAYERSCAPE_NS_ACCESS + enable_layerscape_ns_access(); +#endif + + return 0; +} + +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ +#ifdef CONFIG_SCSI_AHCI_PLAT + ls1021a_sata_init(); +#endif + + return 0; +} +#endif + +#if defined(CONFIG_MISC_INIT_R) +int misc_init_r(void) +{ +#ifdef CONFIG_FSL_DEVICE_DISABLE + device_disable(devdis_tbl, ARRAY_SIZE(devdis_tbl)); + +#endif + +#ifdef CONFIG_FSL_CAAM + return sec_init(); +#endif +} +#endif + +int ft_board_setup(void *blob, bd_t *bd) +{ + ft_cpu_setup(blob, bd); + +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); +#endif + + return 0; +} + +void flash_write16(u16 val, void *addr) +{ + u16 shftval = (((val >> 8) & 0xff) | ((val << 8) & 0xff00)); + + __raw_writew(shftval, addr); +} + +u16 flash_read16(void *addr) +{ + u16 val = __raw_readw(addr); + + return (((val) >> 8) & 0x00ff) | (((val) << 8) & 0xff00); +} diff --git a/board/freescale/ls1021aiot/ls102xa_pbi.cfg b/board/freescale/ls1021aiot/ls102xa_pbi.cfg new file mode 100644 index 0000000000..b5ac5e27e9 --- /dev/null +++ b/board/freescale/ls1021aiot/ls102xa_pbi.cfg @@ -0,0 +1,14 @@ +#PBI commands + +09570200 ffffffff +09570158 00000300 +8940007c 21f47300 + +#Configure Scratch register +09ee0200 10000000 +#Configure alternate space +09570158 00001000 +#Flush PBL data +096100c0 000FFFFF + +09ea085c 00502880 diff --git a/board/freescale/ls1021aiot/ls102xa_rcw_sd.cfg b/board/freescale/ls1021aiot/ls102xa_rcw_sd.cfg new file mode 100644 index 0000000000..a1984c713d --- /dev/null +++ b/board/freescale/ls1021aiot/ls102xa_rcw_sd.cfg @@ -0,0 +1,27 @@ +#PBL preamble and RCW header +aa55aa55 01ee0100 +# serdes protocol + +#Default with 2 x SGMII (no SATA) +0608000a 00000000 00000000 00000000 +20000000 08407900 60025a00 21046000 +00000000 00000000 00000000 20038000 +20024800 881b1340 00000000 00000000 + +#SATA set-up +#0608000a 00000000 00000000 00000000 +#70000000 08007900 60025a00 21046000 +#00000000 00000000 00000000 20038000 +#20024800 881b1340 00000000 00000000 + +#HDMI set-up +#0608000a 00000000 00000000 00000000 +#20000000 08407900 60025a00 21046000 +#00000000 00000000 00000000 20038000 +#00000000 881b1340 00000000 00000000 + +#QE testing +#0608000a 00000000 00000000 00000000 +#20000000 08407900 60025a00 21046000 +#00000000 00000000 00000000 00038000 +#20094800 881b1340 00000000 00000000 diff --git a/board/freescale/ls1021aiot/psci.S b/board/freescale/ls1021aiot/psci.S new file mode 100644 index 0000000000..564145c42a --- /dev/null +++ b/board/freescale/ls1021aiot/psci.S @@ -0,0 +1,28 @@ +/* + * Copyright 2016 NXP Semiconductor. + * Author: Feng Li + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +#include +#include + + .pushsection ._secure.text, "ax" + + .arch_extension sec + + .align 5 + +.globl psci_system_off +psci_system_off: +1: wfi + b 1b + +.globl psci_text_end +psci_text_end: + nop + .popsection diff --git a/configs/ls1021aiot_qspi_defconfig b/configs/ls1021aiot_qspi_defconfig new file mode 100644 index 0000000000..6c9140bd45 --- /dev/null +++ b/configs/ls1021aiot_qspi_defconfig @@ -0,0 +1,15 @@ +CONFIG_SYS_EXTRA_OPTIONS="QSPI_BOOT" +CONFIG_ARM=y +CONFIG_DM_SPI=y +CONFIG_DM=y +CONFIG_OF_CONTROL=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_ATMEL=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_NETDEVICES=y +CONFIG_E1000=y +CONFIG_SYS_NS16550=y +CONFIG_FSL_DSPI=y +CONFIG_FSL_QSPI=y +CONFIG_TARGET_LS1021AIOT=y +CONFIG_DEFAULT_DEVICE_TREE="ls1021a-iot-duart" diff --git a/configs/ls1021aiot_sdcard_defconfig b/configs/ls1021aiot_sdcard_defconfig new file mode 100644 index 0000000000..4b082ab0f9 --- /dev/null +++ b/configs/ls1021aiot_sdcard_defconfig @@ -0,0 +1,17 @@ +CONFIG_ARM=y +CONFIG_TARGET_LS1021AIOT=y +CONFIG_SPL=y +CONFIG_DEFAULT_DEVICE_TREE="ls1021a-iot-duart" +CONFIG_DM_SPI=y +CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,SPL_FSL_PBL,SD_BOOT,SD_BOOT_QSPI" +CONFIG_CMD_DM=y +CONFIG_DM=y +CONFIG_OF_CONTROL=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_ATMEL=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_FSL_DSPI=y +CONFIG_FSL_QSPI=y +CONFIG_NETDEVICES=y +CONFIG_E1000=y +CONFIG_SYS_NS16550=y diff --git a/include/configs/ls1021aiot.h b/include/configs/ls1021aiot.h new file mode 100644 index 0000000000..182a003603 --- /dev/null +++ b/include/configs/ls1021aiot.h @@ -0,0 +1,367 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CONFIG_LS102XA + +#define CONFIG_ARMV7_SECURE_BASE OCRAM_BASE_S_ADDR + +#define CONFIG_SYS_FSL_CLK + +#define CONFIG_BOARD_EARLY_INIT_F + +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 16 * 1024 * 1024) + +#define CONFIG_SYS_INIT_RAM_ADDR OCRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE OCRAM_SIZE + +/* XHCI Support - enabled by default */ +#define CONFIG_HAS_FSL_XHCI_USB + +#ifdef CONFIG_HAS_FSL_XHCI_USB +#define CONFIG_USB_XHCI_FSL +#define CONFIG_USB_XHCI_DWC3 +#define CONFIG_USB_MAX_CONTROLLER_COUNT 1 +#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 +#endif + +#if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_XHCI_USB) +#define CONFIG_USB_STORAGE +#define CONFIG_CMD_EXT2 +#endif + +/* + * Generic Timer Definitions + */ +#define GENERIC_TIMER_CLK 12500000 + +#define CONFIG_SYS_CLK_FREQ 100000000 +#define CONFIG_DDR_CLK_FREQ 100000000 + +/* + * DDR: 800 MHz ( 1600 MT/s data rate ) + */ + +#define DDR_SDRAM_CFG 0x470c0008 +#define DDR_CS0_BNDS 0x008000bf +#define DDR_CS0_CONFIG 0x80014302 +#define DDR_TIMING_CFG_0 0x50550004 +#define DDR_TIMING_CFG_1 0xbcb38c56 +#define DDR_TIMING_CFG_2 0x0040d120 +#define DDR_TIMING_CFG_3 0x010e1000 +#define DDR_TIMING_CFG_4 0x00000001 +#define DDR_TIMING_CFG_5 0x03401400 +#define DDR_SDRAM_CFG_2 0x00401010 +#define DDR_SDRAM_MODE 0x00061c60 +#define DDR_SDRAM_MODE_2 0x00180000 +#define DDR_SDRAM_INTERVAL 0x18600618 +#define DDR_DDR_WRLVL_CNTL 0x8655f605 +#define DDR_DDR_WRLVL_CNTL_2 0x05060607 +#define DDR_DDR_WRLVL_CNTL_3 0x05050505 +#define DDR_DDR_CDR1 0x80040000 +#define DDR_DDR_CDR2 0x00000001 +#define DDR_SDRAM_CLK_CNTL 0x02000000 +#define DDR_DDR_ZQ_CNTL 0x89080600 +#define DDR_CS0_CONFIG_2 0 +#define DDR_SDRAM_CFG_MEM_EN 0x80000000 +#define SDRAM_CFG2_D_INIT 0x00000010 +#define DDR_CDR2_VREF_TRAIN_EN 0x00000080 +#define SDRAM_CFG2_FRC_SR 0x80000000 +#define SDRAM_CFG_BI 0x00000001 + +#ifdef CONFIG_RAMBOOT_PBL +#define CONFIG_SYS_FSL_PBL_PBI \ + board/freescale/ls1021aiot/ls102xa_pbi.cfg +#endif + +#ifdef CONFIG_SD_BOOT +#define CONFIG_SYS_FSL_PBL_RCW \ + board/freescale/ls1021aiot/ls102xa_rcw_sd.cfg +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_LDSCRIPT "arch/$(ARCH)/cpu/u-boot-spl.lds" +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_ENV_SUPPORT +#define CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT +#define CONFIG_SPL_I2C_SUPPORT +#define CONFIG_SPL_WATCHDOG_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_MMC_SUPPORT +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0xe8 +#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x400 + +#define CONFIG_SPL_TEXT_BASE 0x10000000 +#define CONFIG_SPL_MAX_SIZE 0x1a000 +#define CONFIG_SPL_STACK 0x1001d000 +#define CONFIG_SPL_PAD_TO 0x1c000 +#define CONFIG_SYS_TEXT_BASE 0x82000000 + +#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SYS_TEXT_BASE + \ + CONFIG_SYS_MONITOR_LEN) +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 +#define CONFIG_SPL_BSS_START_ADDR 0x80100000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 +#define CONFIG_SYS_MONITOR_LEN 0x80000 +#define CONFIG_SYS_NO_FLASH +#endif + +#ifdef CONFIG_QSPI_BOOT +#define CONFIG_SYS_TEXT_BASE 0x40010000 +#endif + +#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI) +#define CONFIG_SYS_NO_FLASH +#endif + +#define CONFIG_NR_DRAM_BANKS 1 + +#define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000UL +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE + +#define CONFIG_FSL_CAAM /* Enable CAAM */ + +/* + * Serial Port + */ +#define CONFIG_CONS_INDEX 1 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE 1 +#define CONFIG_SYS_NS16550_CLK get_serial_clock() +#define CONFIG_BAUDRATE 115200 + +/* + * I2C + */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */ +#define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */ +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ + +/* EEPROM */ +#define CONFIG_ID_EEPROM +#define CONFIG_SYS_I2C_EEPROM_NXID +#define CONFIG_SYS_EEPROM_BUS_NUM 0 +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x51 +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 + +/* + * MMC + */ +#define CONFIG_MMC +#define CONFIG_CMD_MMC +#define CONFIG_FSL_ESDHC +#define CONFIG_GENERIC_MMC + +/* SATA */ +#define CONFIG_BOARD_LATE_INIT +#define CONFIG_CMD_SCSI +#define CONFIG_LIBATA +#define CONFIG_SCSI_AHCI +#define CONFIG_SCSI_AHCI_PLAT +#ifndef PCI_DEVICE_ID_FREESCALE_AHCI +#define PCI_DEVICE_ID_FREESCALE_AHCI 0x0440 +#endif +#define CONFIG_SCSI_DEV_LIST {PCI_VENDOR_ID_FREESCALE, \ + PCI_DEVICE_ID_FREESCALE_AHCI} + +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1 +#define CONFIG_SYS_SCSI_MAX_LUN 1 +#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ + CONFIG_SYS_SCSI_MAX_LUN) + +#define CONFIG_CMD_FAT +#define CONFIG_DOS_PARTITION + +/* SPI */ +#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI) +#define CONFIG_SPI_FLASH_SPANSION + +/* QSPI */ +#define QSPI0_AMBA_BASE 0x40000000 +#define FSL_QSPI_FLASH_SIZE (1 << 24) +#define FSL_QSPI_FLASH_NUM 2 +#define CONFIG_SPI_FLASH_BAR +#define CONFIG_SPI_FLASH_SPANSION +#endif + +/* DM SPI */ +#if defined(CONFIG_FSL_DSPI) || defined(CONFIG_FSL_QSPI) +#define CONFIG_CMD_SF +#define CONFIG_DM_SPI_FLASH +#endif + +/* + * eTSEC + */ +#define CONFIG_TSEC_ENET + +#ifdef CONFIG_TSEC_ENET +#define CONFIG_MII +#define CONFIG_MII_DEFAULT_TSEC 1 +#define CONFIG_TSEC1 1 +#define CONFIG_TSEC1_NAME "eTSEC1" +#define CONFIG_TSEC2 1 +#define CONFIG_TSEC2_NAME "eTSEC2" + +#define TSEC1_PHY_ADDR 1 +#define TSEC2_PHY_ADDR 3 + +#define TSEC1_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC2_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) + +#define TSEC1_PHYIDX 0 +#define TSEC2_PHYIDX 0 + +#define CONFIG_ETHPRIME "eTSEC2" + +#define CONFIG_PHY_GIGE +#define CONFIG_PHYLIB +#define CONFIG_PHY_ATHEROS + +#define CONFIG_HAS_ETH0 +#define CONFIG_HAS_ETH1 +#define CONFIG_HAS_ETH2 +#endif + +/* PCIe */ +#define CONFIG_PCI /* Enable PCI/PCIE */ +#define CONFIG_PCIE1 /* PCIE controler 1 */ +#define CONFIG_PCIE2 /* PCIE controler 2 */ + +/* Use common FSL Layerscape PCIe code */ +#define CONFIG_PCIE_LAYERSCAPE +#define FSL_PCIE_COMPAT "fsl,ls1021a-pcie" + +#define CONFIG_SYS_PCI_64BIT + +#define CONFIG_SYS_PCIE_CFG0_PHYS_OFF 0x00000000 +#define CONFIG_SYS_PCIE_CFG0_SIZE 0x00001000 /* 4k */ +#define CONFIG_SYS_PCIE_CFG1_PHYS_OFF 0x00001000 +#define CONFIG_SYS_PCIE_CFG1_SIZE 0x00001000 /* 4k */ + +#define CONFIG_SYS_PCIE_IO_BUS 0x00000000 +#define CONFIG_SYS_PCIE_IO_PHYS_OFF 0x00010000 +#define CONFIG_SYS_PCIE_IO_SIZE 0x00010000 /* 64k */ + +#define CONFIG_SYS_PCIE_MEM_BUS 0x08000000 +#define CONFIG_SYS_PCIE_MEM_PHYS_OFF 0x04000000 +#define CONFIG_SYS_PCIE_MEM_SIZE 0x08000000 /* 128M */ + +#ifdef CONFIG_PCI +#define CONFIG_PCI_PNP +#define CONFIG_PCI_SCAN_SHOW +#define CONFIG_CMD_PCI +#endif + +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_MII + +#define CONFIG_CMDLINE_TAG +#define CONFIG_CMDLINE_EDITING + +#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT) +#undef CONFIG_CMD_IMLS +#endif + +#define CONFIG_PEN_ADDR_BIG_ENDIAN +#define CONFIG_LAYERSCAPE_NS_ACCESS +#define CONFIG_SMP_PEN_ADDR 0x01ee0200 +#define CONFIG_TIMER_CLK_FREQ 12500000 + +#define CONFIG_HWCONFIG +#define HWCONFIG_BUFFER_SIZE 256 + +#define CONFIG_FSL_DEVICE_DISABLE + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "bootargs=root=/dev/ram0 rw console=ttyS0,115200\0" \ +"initrd_high=0xffffffff\0" \ +"fdt_high=0xffffffff\0" + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE \ + (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +#define CONFIG_CMD_GREPENV +#define CONFIG_CMD_MEMINFO + +#define CONFIG_SYS_LOAD_ADDR 0x82000000 + +#define CONFIG_LS102XA_STREAM_ID + +/* + * Stack sizes + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (30 * 1024) + +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_MONITOR_BASE CONFIG_SPL_TEXT_BASE +#else +/* start of monitor */ +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE +#endif + +#define CONFIG_SYS_QE_FW_ADDR 0x67f40000 + +/* + * Environment + */ + +#define CONFIG_ENV_OVERWRITE + +#if defined(CONFIG_SD_BOOT) +#define CONFIG_ENV_OFFSET 0x100000 +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_ENV_SIZE 0x2000 +#elif defined(CONFIG_QSPI_BOOT) +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_ENV_OFFSET 0x100000 +#define CONFIG_ENV_SECT_SIZE 0x10000 +#endif + +#define CONFIG_OF_BOARD_SETUP +#define CONFIG_OF_STDOUT_VIA_ALIAS +#define CONFIG_CMD_BOOTZ + +#define CONFIG_MISC_INIT_R + +/* Hash command with SHA acceleration supported in hardware */ + +#ifdef CONFIG_FSL_CAAM + +#define CONFIG_CMD_HASH + +#define CONFIG_SHA_HW_ACCEL + +#endif + +#include + +#endif From 9b46213b4f63578be2fbcf6b0532a0a8d4b5edb0 Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Fri, 28 Oct 2016 14:23:30 +0800 Subject: [PATCH 04/25] lpuart: add a get_lpuart_clk function It's not always true that LPUART clock is CONFIG_SYS_CLK_FREQ. This patch provides a weak function get_lpuart_clk(), so that the clock can be ovreridden on a specific board which uses different clock for LPUART. Signed-off-by: Shaohui Xie [YS: Reformat commit message] Reviewed-by: York Sun --- drivers/serial/serial_lpuart.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c index 042e9a26d1..beb4243124 100644 --- a/drivers/serial/serial_lpuart.c +++ b/drivers/serial/serial_lpuart.c @@ -170,9 +170,14 @@ static int lpuart_serial_probe(struct udevice *dev) } #else +u32 __weak get_lpuart_clk(void) +{ + return CONFIG_SYS_CLK_FREQ; +} + static void _lpuart32_serial_setbrg(struct lpuart_fsl *base, int baudrate) { - u32 clk = CONFIG_SYS_CLK_FREQ; + u32 clk = get_lpuart_clk(); u32 sbr; sbr = (clk / (16 * baudrate)); From fdc2b54cb864210437010ef84934b3d04bb723c6 Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Fri, 28 Oct 2016 14:24:02 +0800 Subject: [PATCH 05/25] armv8: ls1046aqds: add lpuart support LPUART0 is used by default, and it's using platform clock. Signed-off-by: Shaohui Xie Reviewed-by: York Sun --- arch/arm/dts/Makefile | 1 + arch/arm/dts/fsl-ls1046a-qds-lpuart.dts | 16 ++++++++ arch/arm/dts/fsl-ls1046a-qds.dtsi | 4 ++ arch/arm/dts/fsl-ls1046a.dtsi | 54 +++++++++++++++++++++++++ board/freescale/ls1046aqds/ls1046aqds.c | 18 +++++++++ configs/ls1046aqds_lpuart_defconfig | 30 ++++++++++++++ include/configs/ls1046aqds.h | 8 ++++ 7 files changed, 131 insertions(+) create mode 100644 arch/arm/dts/fsl-ls1046a-qds-lpuart.dts create mode 100644 configs/ls1046aqds_lpuart_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 36133f59e3..26f1e92ee4 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -151,6 +151,7 @@ dtb-$(CONFIG_FSL_LSCH2) += fsl-ls1043a-qds-duart.dtb \ fsl-ls1043a-qds-lpuart.dtb \ fsl-ls1043a-rdb.dtb \ fsl-ls1046a-qds-duart.dtb \ + fsl-ls1046a-qds-lpuart.dtb \ fsl-ls1046a-rdb.dtb \ fsl-ls1012a-qds.dtb \ fsl-ls1012a-rdb.dtb \ diff --git a/arch/arm/dts/fsl-ls1046a-qds-lpuart.dts b/arch/arm/dts/fsl-ls1046a-qds-lpuart.dts new file mode 100644 index 0000000000..21243d0766 --- /dev/null +++ b/arch/arm/dts/fsl-ls1046a-qds-lpuart.dts @@ -0,0 +1,16 @@ +/* + * Device Tree file for Freescale Layerscape-1046A family SoC. + * + * Copyright (C) 2016, Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +#include "fsl-ls1046a-qds.dtsi" + +/ { + chosen { + stdout-path = &lpuart0; + }; +}; diff --git a/arch/arm/dts/fsl-ls1046a-qds.dtsi b/arch/arm/dts/fsl-ls1046a-qds.dtsi index c5122930fe..a49ca08d88 100644 --- a/arch/arm/dts/fsl-ls1046a-qds.dtsi +++ b/arch/arm/dts/fsl-ls1046a-qds.dtsi @@ -75,3 +75,7 @@ &duart1 { status = "okay"; }; + +&lpuart0 { + status = "okay"; +}; diff --git a/arch/arm/dts/fsl-ls1046a.dtsi b/arch/arm/dts/fsl-ls1046a.dtsi index 87dd9976d1..359a9d13bf 100644 --- a/arch/arm/dts/fsl-ls1046a.dtsi +++ b/arch/arm/dts/fsl-ls1046a.dtsi @@ -151,6 +151,60 @@ clocks = <&clockgen 4 0>; }; + lpuart0: serial@2950000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x0 0x2950000 0x0 0x1000>; + interrupts = <0 48 0x4>; + clocks = <&clockgen 4 0>; + clock-names = "ipg"; + status = "disabled"; + }; + + lpuart1: serial@2960000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x0 0x2960000 0x0 0x1000>; + interrupts = <0 49 0x4>; + clocks = <&clockgen 4 1>; + clock-names = "ipg"; + status = "disabled"; + }; + + lpuart2: serial@2970000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x0 0x2970000 0x0 0x1000>; + interrupts = <0 50 0x4>; + clocks = <&clockgen 4 1>; + clock-names = "ipg"; + status = "disabled"; + }; + + lpuart3: serial@2980000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x0 0x2980000 0x0 0x1000>; + interrupts = <0 51 0x4>; + clocks = <&clockgen 4 1>; + clock-names = "ipg"; + status = "disabled"; + }; + + lpuart4: serial@2990000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x0 0x2990000 0x0 0x1000>; + interrupts = <0 52 0x4>; + clocks = <&clockgen 4 1>; + clock-names = "ipg"; + status = "disabled"; + }; + + lpuart5: serial@29a0000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x0 0x29a0000 0x0 0x1000>; + interrupts = <0 53 0x4>; + clocks = <&clockgen 4 1>; + clock-names = "ipg"; + status = "disabled"; + }; + qspi: quadspi@1550000 { compatible = "fsl,vf610-qspi"; #address-cells = <1>; diff --git a/board/freescale/ls1046aqds/ls1046aqds.c b/board/freescale/ls1046aqds/ls1046aqds.c index 8c18538503..552365b9d8 100644 --- a/board/freescale/ls1046aqds/ls1046aqds.c +++ b/board/freescale/ls1046aqds/ls1046aqds.c @@ -120,6 +120,13 @@ unsigned long get_board_ddr_clk(void) return 66666666; } +#ifdef CONFIG_LPUART +u32 get_lpuart_clk(void) +{ + return gd->bus_clk; +} +#endif + int select_i2c_ch_pca9547(u8 ch) { int ret; @@ -157,6 +164,9 @@ int board_early_init_f(void) struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; u32 usb_pwrfault; #endif +#ifdef CONFIG_LPUART + u8 uart; +#endif #ifdef CONFIG_SYS_I2C_EARLY_INIT i2c_early_init_f(); @@ -175,6 +185,14 @@ int board_early_init_f(void) out_be32(&scfg->usbpwrfault_selcr, usb_pwrfault); #endif +#ifdef CONFIG_LPUART + /* We use lpuart0 as system console */ + uart = QIXIS_READ(brdcfg[14]); + uart &= ~CFG_UART_MUX_MASK; + uart |= CFG_LPUART_EN << CFG_UART_MUX_SHIFT; + QIXIS_WRITE(brdcfg[14], uart); +#endif + return 0; } diff --git a/configs/ls1046aqds_lpuart_defconfig b/configs/ls1046aqds_lpuart_defconfig new file mode 100644 index 0000000000..25bb5f9f73 --- /dev/null +++ b/configs/ls1046aqds_lpuart_defconfig @@ -0,0 +1,30 @@ +CONFIG_ARM=y +CONFIG_TARGET_LS1046AQDS=y +CONFIG_SYS_FSL_DDR4=y +CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1046a-qds-lpuart" +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_SYS_EXTRA_OPTIONS="LPUART" +CONFIG_BOOTDELAY=10 +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_GREPENV=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_I2C=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y +CONFIG_DM=y +CONFIG_DM_SPI=y +CONFIG_SPI_FLASH=y +CONFIG_FSL_DSPI=y +CONFIG_DM_SERIAL=y +CONFIG_FSL_LPUART=y diff --git a/include/configs/ls1046aqds.h b/include/configs/ls1046aqds.h index c0f5bd3562..29e0aa5ee1 100644 --- a/include/configs/ls1046aqds.h +++ b/include/configs/ls1046aqds.h @@ -127,6 +127,14 @@ unsigned long get_board_ddr_clk(void); #endif #endif +/* LPUART */ +#ifdef CONFIG_LPUART +#define CONFIG_LPUART_32B_REG +#define CFG_UART_MUX_MASK 0x6 +#define CFG_UART_MUX_SHIFT 1 +#define CFG_LPUART_EN 0x2 +#endif + /* SATA */ #define CONFIG_LIBATA #define CONFIG_SCSI_AHCI From fc35addea2c0fa5add065c5ea09e206d4cba1abd Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Thu, 3 Nov 2016 17:50:51 +0530 Subject: [PATCH 06/25] armv8: ls2080a: Update serdes protocol support Add these serdes protocols Serdes1: 0x39, 0x4B, 0x4C, 0x4D Serdes2: 0x47, 0x57 Signed-off-by: Priyanka Jain Signed-off-by: Prabhakar Kushwaha Signed-off-by: Ashish Kumar [YS: Revise commit message] Reviewed-by: York Sun --- .../cpu/armv8/fsl-layerscape/ls2080a_serdes.c | 6 + board/freescale/ls2080aqds/eth.c | 122 +++++++++++++++++- 2 files changed, 125 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c index eaa44a74c5..67d605e38b 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c @@ -34,6 +34,11 @@ static struct serdes_config serdes1_cfg_tbl[] = { {0x33, {PCIE2, PCIE2, PCIE2, PCIE2, QSGMII_D, QSGMII_C, QSGMII_B, QSGMII_A} }, {0x35, {QSGMII_D, QSGMII_C, QSGMII_B, PCIE2, XFI4, XFI3, XFI2, XFI1 } }, + {0x39, {SGMII8, SGMII7, SGMII6, PCIE2, SGMII4, SGMII3, SGMII2, + PCIE1 } }, + {0x4B, {PCIE2, PCIE2, PCIE2, PCIE2, XFI4, XFI3, XFI2, XFI1 } }, + {0x4C, {XFI8, XFI7, XFI6, XFI5, PCIE1, PCIE1, PCIE1, PCIE1 } }, + {0x4D, {SGMII8, SGMII7, PCIE2, PCIE2, SGMII4, SGMII3, PCIE1, PCIE1 } }, {} }; static struct serdes_config serdes2_cfg_tbl[] = { @@ -64,6 +69,7 @@ static struct serdes_config serdes2_cfg_tbl[] = { SATA2 } }, {0x4A, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1, SATA2 } }, + {0x57, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SGMII15, SGMII16 } }, {} }; diff --git a/board/freescale/ls2080aqds/eth.c b/board/freescale/ls2080aqds/eth.c index 95ff68b364..8618506b8b 100644 --- a/board/freescale/ls2080aqds/eth.c +++ b/board/freescale/ls2080aqds/eth.c @@ -64,7 +64,7 @@ static int sgmii_riser_phy_addr[] = { }; /* Slot2 does not have EMI connections */ -#define EMI_NONE 0xFFFFFFFF +#define EMI_NONE 0xFF #define EMI1_SLOT1 0 #define EMI1_SLOT2 1 #define EMI1_SLOT3 2 @@ -470,7 +470,49 @@ static void initialize_dpmac_to_slot(void) } break; + case 0x39: + printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n", + serdes1_prtcl); + if (hwconfig_f("xqsgmii", env_hwconfig)) { + lane_to_slot_fsm1[0] = EMI1_SLOT3; + lane_to_slot_fsm1[1] = EMI1_SLOT3; + lane_to_slot_fsm1[2] = EMI1_SLOT3; + lane_to_slot_fsm1[3] = EMI_NONE; + } else { + lane_to_slot_fsm1[0] = EMI_NONE; + lane_to_slot_fsm1[1] = EMI_NONE; + lane_to_slot_fsm1[2] = EMI_NONE; + lane_to_slot_fsm1[3] = EMI_NONE; + } + lane_to_slot_fsm1[4] = EMI1_SLOT3; + lane_to_slot_fsm1[5] = EMI1_SLOT3; + lane_to_slot_fsm1[6] = EMI1_SLOT3; + lane_to_slot_fsm1[7] = EMI_NONE; + break; + + case 0x4D: + printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n", + serdes1_prtcl); + if (hwconfig_f("xqsgmii", env_hwconfig)) { + lane_to_slot_fsm1[0] = EMI1_SLOT3; + lane_to_slot_fsm1[1] = EMI1_SLOT3; + lane_to_slot_fsm1[2] = EMI_NONE; + lane_to_slot_fsm1[3] = EMI_NONE; + } else { + lane_to_slot_fsm1[0] = EMI_NONE; + lane_to_slot_fsm1[1] = EMI_NONE; + lane_to_slot_fsm1[2] = EMI_NONE; + lane_to_slot_fsm1[3] = EMI_NONE; + } + lane_to_slot_fsm1[4] = EMI1_SLOT3; + lane_to_slot_fsm1[5] = EMI1_SLOT3; + lane_to_slot_fsm1[6] = EMI_NONE; + lane_to_slot_fsm1[7] = EMI_NONE; + break; + case 0x2A: + case 0x4B: + case 0x4C: printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n", serdes1_prtcl); break; @@ -505,6 +547,38 @@ static void initialize_dpmac_to_slot(void) lane_to_slot_fsm2[7] = EMI1_SLOT6; } break; + + case 0x47: + printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n", + serdes2_prtcl); + lane_to_slot_fsm2[0] = EMI_NONE; + lane_to_slot_fsm2[1] = EMI1_SLOT5; + lane_to_slot_fsm2[2] = EMI1_SLOT5; + lane_to_slot_fsm2[3] = EMI1_SLOT5; + + if (hwconfig_f("xqsgmii", env_hwconfig)) { + lane_to_slot_fsm2[4] = EMI_NONE; + lane_to_slot_fsm2[5] = EMI1_SLOT5; + lane_to_slot_fsm2[6] = EMI1_SLOT5; + lane_to_slot_fsm2[7] = EMI1_SLOT5; + } + break; + + case 0x57: + printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n", + serdes2_prtcl); + if (hwconfig_f("xqsgmii", env_hwconfig)) { + lane_to_slot_fsm2[0] = EMI_NONE; + lane_to_slot_fsm2[1] = EMI_NONE; + lane_to_slot_fsm2[2] = EMI_NONE; + lane_to_slot_fsm2[3] = EMI_NONE; + } + lane_to_slot_fsm2[4] = EMI_NONE; + lane_to_slot_fsm2[5] = EMI_NONE; + lane_to_slot_fsm2[6] = EMI1_SLOT5; + lane_to_slot_fsm2[7] = EMI1_SLOT5; + break; + default: printf(" %s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n", __func__ , serdes2_prtcl); @@ -537,8 +611,10 @@ void ls2080a_handle_phy_interface_sgmii(int dpmac_id) switch (serdes1_prtcl) { case 0x07: + case 0x39: + case 0x4D: + lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id - 1); - lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id); slot = lane_to_slot_fsm1[lane]; switch (++slot) { @@ -559,6 +635,26 @@ void ls2080a_handle_phy_interface_sgmii(int dpmac_id) wriop_set_mdio(dpmac_id, bus); break; case 3: + if (slot == EMI_NONE) + return; + if (serdes1_prtcl == 0x39) { + wriop_set_phy_address(dpmac_id, + riser_phy_addr[dpmac_id - 2]); + if (dpmac_id >= 6 && hwconfig_f("xqsgmii", + env_hwconfig)) + wriop_set_phy_address(dpmac_id, + riser_phy_addr[dpmac_id - 3]); + } else { + wriop_set_phy_address(dpmac_id, + riser_phy_addr[dpmac_id - 2]); + if (dpmac_id >= 7 && hwconfig_f("xqsgmii", + env_hwconfig)) + wriop_set_phy_address(dpmac_id, + riser_phy_addr[dpmac_id - 3]); + } + dpmac_info[dpmac_id].board_mux = EMI1_SLOT3; + bus = mii_dev_for_muxval(EMI1_SLOT3); + wriop_set_mdio(dpmac_id, bus); break; case 4: break; @@ -579,6 +675,8 @@ serdes2: case 0x07: case 0x08: case 0x49: + case 0x47: + case 0x57: lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 + (dpmac_id - 9)); slot = lane_to_slot_fsm2[lane]; @@ -597,7 +695,23 @@ serdes2: wriop_set_mdio(dpmac_id, bus); break; case 5: - break; + if (slot == EMI_NONE) + return; + if (serdes2_prtcl == 0x47) { + wriop_set_phy_address(dpmac_id, + riser_phy_addr[dpmac_id - 10]); + if (dpmac_id >= 14 && hwconfig_f("xqsgmii", + env_hwconfig)) + wriop_set_phy_address(dpmac_id, + riser_phy_addr[dpmac_id - 11]); + } else { + wriop_set_phy_address(dpmac_id, + riser_phy_addr[dpmac_id - 11]); + } + dpmac_info[dpmac_id].board_mux = EMI1_SLOT5; + bus = mii_dev_for_muxval(EMI1_SLOT5); + wriop_set_mdio(dpmac_id, bus); + break; case 6: /* Slot housing a SGMII riser card? */ wriop_set_phy_address(dpmac_id, @@ -691,6 +805,8 @@ void ls2080a_handle_phy_interface_xsgmii(int i) switch (serdes1_prtcl) { case 0x2A: + case 0x4B: + case 0x4C: /* * 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 From b7401d0917257ee7c023feb40cd62627da025491 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Thu, 3 Nov 2016 18:05:09 +0530 Subject: [PATCH 07/25] driver: net: ldpaa_eth: Fix missing bracket issue Signed-off-by: Priyanka Jain Signed-off-by: Prabhakar Kushwaha Signed-off-by: Ashish Kumar Acked-by: Joe Hershberger Reviewed-by: York Sun --- drivers/net/ldpaa_eth/ldpaa_eth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 75b2b6b049..4e61700d5d 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -420,13 +420,14 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) goto err_dpmac_setup; #ifdef CONFIG_PHYLIB - if (priv->phydev) + if (priv->phydev) { err = phy_startup(priv->phydev); if (err) { printf("%s: Could not initialize\n", priv->phydev->dev->name); goto err_dpamc_bind; } + } #else priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device)); memset(priv->phydev, 0, sizeof(struct phy_device)); From 4359a3b9e44be89bac2bc62ed6d48e6a64164cdf Mon Sep 17 00:00:00 2001 From: Sriram Dash Date: Fri, 14 Oct 2016 12:03:50 +0530 Subject: [PATCH 08/25] powerpc: mpc512x: Add support for get_svr() for mpc512x devices Defines get_svr() for mpc512x devices Signed-off-by: Sriram Dash Reviewed-by: Bin Meng Reviewed-by: York Sun --- arch/powerpc/cpu/mpc512x/start.S | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/powerpc/cpu/mpc512x/start.S b/arch/powerpc/cpu/mpc512x/start.S index 471d401d49..dd3066ec4c 100644 --- a/arch/powerpc/cpu/mpc512x/start.S +++ b/arch/powerpc/cpu/mpc512x/start.S @@ -443,6 +443,11 @@ get_pvr: mfspr r3, PVR blr + .globl get_svr +get_svr: + mfspr r3, SVR + blr + /*-------------------------------------------------------------------*/ /* From 5eef15ea9d297d270935510d8a635f8d8bf72439 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 31 Oct 2016 10:59:16 +0800 Subject: [PATCH 09/25] fsl: serdes: fix a deadloop issue for P4080 This deadloop is introduced by commit: 71fe222 fsl: serdes: ensure accessing the initialized maps of serdes protocol deadloop detail: cpu_init_r => fsl_serdes_init => p4080_erratum_serdes_a005 => is_serdes_configured => fsl_serdes_init Signed-off-by: Hou Zhiqiang Reviewed-by: York Sun --- arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 72d5e3007d..b6c4341544 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -607,6 +607,9 @@ void fsl_serdes_init(void) soc_serdes_init(); + /* Set the first bit to indicate serdes has been initialized */ + serdes_prtcl_map |= (1 << NONE); + #ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 /* * Bank two uses the clock from bank three, so if bank two is enabled, @@ -862,9 +865,6 @@ void fsl_serdes_init(void) SRDS_RSTCTL_SDPD); } #endif - - /* Set the first bit to indicate serdes has been initialized */ - serdes_prtcl_map |= (1 << NONE); } const char *serdes_clock_to_string(u32 clock) From c435a7c8c1b872d38fcc671369f6e290d2fff08c Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Mon, 17 Oct 2016 16:20:48 +0800 Subject: [PATCH 10/25] armv8: ls2080aqds: fix SGMII repeater settings The current value to check whether the PHY was configured has dependency on MC, it expects MC to start PCS AN, this is not true during boot up, so it should be changed to remove the dependency. The PHY's register space should be restore to default after accessing extended space. Signed-off-by: Shaohui Xie Reviewed-by: York Sun --- board/freescale/ls2080aqds/eth.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/board/freescale/ls2080aqds/eth.c b/board/freescale/ls2080aqds/eth.c index 8618506b8b..59361e9111 100644 --- a/board/freescale/ls2080aqds/eth.c +++ b/board/freescale/ls2080aqds/eth.c @@ -144,8 +144,10 @@ static void sgmii_configure_repeater(int serdes_port) mdelay(10); - if ((value & 0xfff) == 0x40f) { + if ((value & 0xfff) == 0x401) { printf("DPMAC %d:PHY is ..... Configured\n", dpmac_id); + miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], + 0x1f, 0); continue; } @@ -181,28 +183,29 @@ static void sgmii_configure_repeater(int serdes_port) if (ret > 0) goto error; - mdelay(1); + mdelay(100); ret = miiphy_read(dev[mii_bus], riser_phy_addr[dpmac], 0x11, &value); if (ret > 0) goto error; - mdelay(10); - if ((value & 0xfff) == 0x40f) { + if ((value & 0xfff) == 0x401) { printf("DPMAC %d :PHY is configured ", dpmac_id); printf("after setting repeater 0x%x\n", value); i = 5; j = 5; - } else + } else { printf("DPMAC %d :PHY is failed to ", dpmac_id); printf("configure the repeater 0x%x\n", value); } + } } + miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], 0x1f, 0); } error: if (ret) From e2f95e3a6ab4e40ad5c8864ff8ee0195a1388601 Mon Sep 17 00:00:00 2001 From: Yuan Yao Date: Wed, 9 Nov 2016 11:19:54 +0800 Subject: [PATCH 11/25] arm: ls1021a: improve the core frequency to 1.2GHZ Change core clock to 1.2GHz in the configurations for SD and NAND boot. Signed-off-by: Yuan Yao Reviewed-by: York Sun --- board/freescale/ls1021aqds/ls102xa_rcw_nand.cfg | 2 +- board/freescale/ls1021aqds/ls102xa_rcw_sd_ifc.cfg | 4 ++-- board/freescale/ls1021aqds/ls102xa_rcw_sd_qspi.cfg | 4 ++-- board/freescale/ls1021atwr/ls102xa_rcw_sd_ifc.cfg | 2 +- board/freescale/ls1021atwr/ls102xa_rcw_sd_qspi.cfg | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/board/freescale/ls1021aqds/ls102xa_rcw_nand.cfg b/board/freescale/ls1021aqds/ls102xa_rcw_nand.cfg index 222c71dcb6..d76e9132e3 100644 --- a/board/freescale/ls1021aqds/ls102xa_rcw_nand.cfg +++ b/board/freescale/ls1021aqds/ls102xa_rcw_nand.cfg @@ -1,7 +1,7 @@ #PBL preamble and RCW header aa55aa55 01ee0100 # serdes protocol -0608000a 00000000 00000000 00000000 +0608000c 00000000 00000000 00000000 60000000 00407900 e0106a00 21046000 00000000 00000000 00000000 00038000 00000000 001b7200 00000000 00000000 diff --git a/board/freescale/ls1021aqds/ls102xa_rcw_sd_ifc.cfg b/board/freescale/ls1021aqds/ls102xa_rcw_sd_ifc.cfg index 9d99bd862d..f0cf9c2b38 100644 --- a/board/freescale/ls1021aqds/ls102xa_rcw_sd_ifc.cfg +++ b/board/freescale/ls1021aqds/ls102xa_rcw_sd_ifc.cfg @@ -2,13 +2,13 @@ aa55aa55 01ee0100 #enable IFC, disable QSPI and DSPI -0608000a 00000000 00000000 00000000 +0608000c 00000000 00000000 00000000 60000000 00407900 60040a00 21046000 00000000 00000000 00000000 00038000 00000000 001b7200 00000000 00000000 #disable IFC, enable QSPI and DSPI -#0608000a 00000000 00000000 00000000 +#0608000c 00000000 00000000 00000000 #60000000 00407900 60040a00 21046000 #00000000 00000000 00000000 00038000 #20024800 001b7200 00000000 00000000 diff --git a/board/freescale/ls1021aqds/ls102xa_rcw_sd_qspi.cfg b/board/freescale/ls1021aqds/ls102xa_rcw_sd_qspi.cfg index 2bd398cc53..10cc4a9ab0 100644 --- a/board/freescale/ls1021aqds/ls102xa_rcw_sd_qspi.cfg +++ b/board/freescale/ls1021aqds/ls102xa_rcw_sd_qspi.cfg @@ -2,13 +2,13 @@ aa55aa55 01ee0100 #enable IFC, disable QSPI and DSPI -#0608000a 00000000 00000000 00000000 +#0608000c 00000000 00000000 00000000 #60000000 00407900 60040a00 21046000 #00000000 00000000 00000000 00038000 #00000000 001b7200 00000000 00000000 #disable IFC, enable QSPI and DSPI -0608000a 00000000 00000000 00000000 +0608000c 00000000 00000000 00000000 60000000 00407900 60040a00 21046000 00000000 00000000 00000000 00038000 20024800 001b7200 00000000 00000000 diff --git a/board/freescale/ls1021atwr/ls102xa_rcw_sd_ifc.cfg b/board/freescale/ls1021atwr/ls102xa_rcw_sd_ifc.cfg index 205606f4d2..f94997d538 100644 --- a/board/freescale/ls1021atwr/ls102xa_rcw_sd_ifc.cfg +++ b/board/freescale/ls1021atwr/ls102xa_rcw_sd_ifc.cfg @@ -2,7 +2,7 @@ aa55aa55 01ee0100 #enable IFC, disable QSPI and DSPI -0608000a 00000000 00000000 00000000 +0608000c 00000000 00000000 00000000 30000000 00007900 60040a00 21046000 00000000 00000000 00000000 20000000 00080000 881b7340 00000000 00000000 diff --git a/board/freescale/ls1021atwr/ls102xa_rcw_sd_qspi.cfg b/board/freescale/ls1021atwr/ls102xa_rcw_sd_qspi.cfg index 6767e09388..541b604cff 100644 --- a/board/freescale/ls1021atwr/ls102xa_rcw_sd_qspi.cfg +++ b/board/freescale/ls1021atwr/ls102xa_rcw_sd_qspi.cfg @@ -2,7 +2,7 @@ aa55aa55 01ee0100 #disable IFC, enable QSPI and DSPI -0608000a 00000000 00000000 00000000 +0608000c 00000000 00000000 00000000 30000000 00007900 60040a00 21046000 00000000 00000000 00000000 20000000 20024800 881b7340 00000000 00000000 From c3aa1df28d0938259b44af24c15d50e126a1fbbc Mon Sep 17 00:00:00 2001 From: Yuan Yao Date: Wed, 9 Nov 2016 11:50:46 +0800 Subject: [PATCH 12/25] armv8: fsl-layerscape: Add README for deploying QSPI image Signed-off-by: Yuan Yao [YS: Reviese commit subject] Reviewed-by: York Sun --- .../cpu/armv8/fsl-layerscape/doc/README.qspi | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 arch/arm/cpu/armv8/fsl-layerscape/doc/README.qspi diff --git a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.qspi b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.qspi new file mode 100644 index 0000000000..de86f4b307 --- /dev/null +++ b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.qspi @@ -0,0 +1,42 @@ +QSPI Boot source support Overview +------------------- + 1. LS1043A + LS1043AQDS + 2. LS2080A + LS2080AQDS + 3. LS1012A + LS1012AQDS + LS1012ARDB + 4. LS1046A + LS1046AQDS + LS1046ARDB + +Booting from QSPI +------------------- +Booting from QSPI requires two images, RCW and u-boot-dtb.bin. +The difference between QSPI boot RCW image and NOR boot image is the PBI +command sequence for setting the boot location pointer. It's should point +to the address for u-boot in QSPI flash. + +RCW image should be written to the beginning of QSPI flash device. +Example of using u-boot command + +=> sf probe 0:0 +SF: Detected S25FL256S_64K with page size 256 Bytes, erase size 64 KiB, total 32 MiB +=> sf erase 0 + +SF: 65536 bytes @ 0x0 Erased: OK +=> sf write 0 +SF: 164 bytes @ 0x0 Written: OK + +To get the QSPI image, build u-boot with QSPI config, for example, +_qspi_defconfig. The image needed is u-boot-dtb.bin. +The u-boot image should be written to 0x10000(but 0x1000 for LS1043A, LS2080A). + +=> sf probe 0:0 +SF: Detected S25FL256S_64K with page size 256 Bytes, erase size 64 KiB, total 32 MiB +=> sf erase 10000 + +SF: 589824 bytes @ 0x10000 Erased: OK +=> sf write 10000 +SF: 580966 bytes @ 0x10000 Written: OK + +With these two images in QSPI flash device, the board can boot from QSPI. From 40836e215a06d435333422b2c64fa1c01f0c4f82 Mon Sep 17 00:00:00 2001 From: Shengzhou Liu Date: Fri, 11 Nov 2016 18:11:05 +0800 Subject: [PATCH 13/25] armv8/fsl-layerscape: Update CONFIG_LS2080A to CONFIG_FSL_LSCH3 Update CONFIG_LS2080A to CONFIG_FSL_LSCH3 to make those workaround implementing of erratum reusable for more SoCs. Signed-off-by: Shengzhou Liu Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/soc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index d68eeba349..5a4dd39a61 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -50,16 +50,16 @@ bool soc_has_aiop(void) return false; } -#ifdef CONFIG_LS2080A +#if defined(CONFIG_FSL_LSCH3) /* * This erratum requires setting a value to eddrtqcr1 to * optimal the DDR performance. */ static void erratum_a008336(void) { +#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 u32 *eddrtqcr1; -#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 #ifdef CONFIG_SYS_FSL_DCSR_DDR_ADDR eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800; if (fsl_ddr_get_version(0) == 0x50200) @@ -79,9 +79,9 @@ static void erratum_a008336(void) */ static void erratum_a008514(void) { +#ifdef CONFIG_SYS_FSL_ERRATUM_A008514 u32 *eddrtqcr1; -#ifdef CONFIG_SYS_FSL_ERRATUM_A008514 #ifdef CONFIG_SYS_FSL_DCSR_DDR3_ADDR eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800; out_le32(eddrtqcr1, 0x63b20002); @@ -176,6 +176,7 @@ static void erratum_a009203(void) #endif #endif } + void bypass_smmu(void) { u32 val; From f6a70b3a92d07cf99d83c57fd9856312d8ab2807 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Thu, 17 Nov 2016 12:29:51 +0530 Subject: [PATCH 14/25] armv8: lsch3: Add generic get_svr() in assembly Signed-off-by: Priyanka Jain Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 2 ++ arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S | 9 +++++++++ arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h | 6 +++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 0b516e37d7..e304870198 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -306,12 +306,14 @@ u32 fsl_qoriq_core_to_type(unsigned int core) return -1; /* cannot identify the cluster */ } +#ifndef CONFIG_FSL_LSCH3 uint get_svr(void) { struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); return gur_in32(&gur->svr); } +#endif #ifdef CONFIG_DISPLAY_CPUINFO int print_cpuinfo(void) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S index 5700b1fb65..6ff47b0e06 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S +++ b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S @@ -13,6 +13,9 @@ #ifdef CONFIG_MP #include #endif +#ifdef CONFIG_FSL_LSCH3 +#include +#endif ENTRY(lowlevel_init) mov x29, lr /* Save LR */ @@ -199,6 +202,12 @@ ENTRY(lowlevel_init) ENDPROC(lowlevel_init) #ifdef CONFIG_FSL_LSCH3 + .globl get_svr +get_svr: + ldr x1, =FSL_LSCH3_SVR + ldr w0, [x1] + ret + hnf_pstate_poll: /* x0 has the desired status, return 0 for success, 1 for timeout * clobber x1, x2, x3, x4, x6, x7 diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h index 7acba2730a..09c1033500 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h @@ -27,6 +27,7 @@ #define CONFIG_SYS_FSL_PMU_CLTBENR (CONFIG_SYS_FSL_PMU_ADDR + \ 0x18A0) #define FSL_PMU_PCTBENR_OFFSET (CONFIG_SYS_FSL_PMU_ADDR + 0x8A0) +#define FSL_LSCH3_SVR (CONFIG_SYS_FSL_GUTS_ADDR + 0xA4) #define CONFIG_SYS_FSL_WRIOP1_ADDR (CONFIG_SYS_IMMR + 0x7B80000) #define CONFIG_SYS_FSL_WRIOP1_MDIO1 (CONFIG_SYS_FSL_WRIOP1_ADDR + 0x16000) @@ -153,7 +154,7 @@ #define TP_CLUSTER_INIT_MASK 0x0000003f /* initiator mask */ #define TP_INIT_PER_CLUSTER 4 /* This is chassis generation 3 */ - +#ifndef __ASSEMBLY__ struct sys_info { unsigned long freq_processor[CONFIG_MAX_CPUS]; unsigned long freq_systembus; @@ -317,6 +318,5 @@ struct ccsr_reset { u32 ip_rev2; /* 0xbfc */ }; -uint get_svr(void); - +#endif /*__ASSEMBLY__*/ #endif /* __ARCH_FSL_LSCH3_IMMAP_H_ */ From f6b96ff665844291a76de139bfbaa75fc0c7d917 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Thu, 17 Nov 2016 12:29:52 +0530 Subject: [PATCH 15/25] armv8: lsch3: Use SVR based timer base address detection Timer controller base address has been changed from LS2080A SoC (and its personalities) to new SoCs like LS2088A, LS1088A. Use SVR based timer base address detection to avoid compile time #ifdef. Signed-off-by: Priyanka Jain Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 9 +++++++++ arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h | 3 ++- arch/arm/include/asm/arch-fsl-layerscape/soc.h | 8 ++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index e304870198..eb03bf44cb 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -433,6 +433,7 @@ int timer_init(void) #endif #ifdef CONFIG_LS2080A u32 __iomem *pctbenr = (u32 *)FSL_PMU_PCTBENR_OFFSET; + u32 svr_dev_id; #endif #ifdef COUNTER_FREQUENCY_REAL unsigned long cntfrq = COUNTER_FREQUENCY_REAL; @@ -455,6 +456,14 @@ int timer_init(void) * Register (PCTBENR), which allows the watchdog to operate. */ setbits_le32(pctbenr, 0xff); + /* + * For LS2080A SoC and its personalities, timer controller + * offset is different + */ + svr_dev_id = get_svr() >> 16; + if (svr_dev_id == SVR_DEV_LS2080A) + cntcr = (u32 *)SYS_FSL_LS2080A_LS2085A_TIMER_ADDR; + #endif /* Enable clock for timer diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h index 09c1033500..2df56f7a5b 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h @@ -23,7 +23,8 @@ #define CONFIG_SYS_IFC_ADDR (CONFIG_SYS_IMMR + 0x01240000) #define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_IMMR + 0x011C0500) #define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_IMMR + 0x011C0600) -#define CONFIG_SYS_FSL_TIMER_ADDR 0x023d0000 +#define SYS_FSL_LS2080A_LS2085A_TIMER_ADDR 0x023d0000 +#define CONFIG_SYS_FSL_TIMER_ADDR 0x023e0000 #define CONFIG_SYS_FSL_PMU_CLTBENR (CONFIG_SYS_FSL_PMU_ADDR + \ 0x18A0) #define FSL_PMU_PCTBENR_OFFSET (CONFIG_SYS_FSL_PMU_ADDR + 0x8A0) diff --git a/arch/arm/include/asm/arch-fsl-layerscape/soc.h b/arch/arm/include/asm/arch-fsl-layerscape/soc.h index 58e90d8d88..3ccacb91fe 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/soc.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/soc.h @@ -30,7 +30,7 @@ #define pex_lut_in32(a) in_be32(a) #define pex_lut_out32(a, v) out_be32(a, v) #endif - +#ifndef __ASSEMBLY__ struct cpu_type { char name[15]; u32 soc_ver; @@ -39,7 +39,7 @@ struct cpu_type { #define CPU_TYPE_ENTRY(n, v, nc) \ { .name = #n, .soc_ver = SVR_##v, .num_cores = (nc)} - +#endif #define SVR_WO_E 0xFFFFFE #define SVR_LS1012A 0x870400 #define SVR_LS1043A 0x879200 @@ -51,6 +51,8 @@ struct cpu_type { #define SVR_LS2085A 0x870100 #define SVR_LS2040A 0x870130 +#define SVR_DEV_LS2080A 0x8701 + #define SVR_MAJ(svr) (((svr) >> 4) & 0xf) #define SVR_MIN(svr) (((svr) >> 0) & 0xf) #define SVR_SOC_VER(svr) (((svr) >> 8) & SVR_WO_E) @@ -63,6 +65,7 @@ struct cpu_type { #define AHCI_PORT_TRANS_CFG 0x08000029 #define AHCI_PORT_AXICC_CFG 0x3fffffff +#ifndef __ASSEMBLY__ /* AHCI (sata) register map */ struct ccsr_ahci { u32 res1[0xa4/4]; /* 0x0 - 0xa4 */ @@ -105,4 +108,5 @@ void erratum_a010315(void); bool soc_has_dp_ddr(void); bool soc_has_aiop(void); +#endif #endif /* _ASM_ARMV8_FSL_LAYERSCAPE_SOC_H_ */ From 7cfbb4abe3c4755363aa3d692511bf187852adf6 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Thu, 17 Nov 2016 12:29:53 +0530 Subject: [PATCH 16/25] armv8: fsl-layerscape: Update TZASC registers type TZASC registers like TZASC_GATE_KEEPER, TZASC_REGION_ATTRIBUTES are 32-bit regsiters. So while doing register load-store operations, 32-bit intermediate register, w0 should be used. Update x0 register to w0 register type. Signed-off-by: Priyanka Jain Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S index 6ff47b0e06..ac189d3c15 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S +++ b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S @@ -148,26 +148,26 @@ ENTRY(lowlevel_init) * placeholders. */ ldr x1, =TZASC_GATE_KEEPER(0) - ldr x0, [x1] /* Filter 0 Gate Keeper Register */ - orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */ - str x0, [x1] + ldr w0, [x1] /* Filter 0 Gate Keeper Register */ + orr w0, w0, #1 << 0 /* Set open_request for Filter 0 */ + str w0, [x1] ldr x1, =TZASC_GATE_KEEPER(1) - ldr x0, [x1] /* Filter 0 Gate Keeper Register */ - orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */ - str x0, [x1] + ldr w0, [x1] /* Filter 0 Gate Keeper Register */ + orr w0, w0, #1 << 0 /* Set open_request for Filter 0 */ + str w0, [x1] ldr x1, =TZASC_REGION_ATTRIBUTES_0(0) - ldr x0, [x1] /* Region-0 Attributes Register */ - orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */ - orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */ - str x0, [x1] + ldr w0, [x1] /* Region-0 Attributes Register */ + orr w0, w0, #1 << 31 /* Set Sec global write en, Bit[31] */ + orr w0, w0, #1 << 30 /* Set Sec global read en, Bit[30] */ + str w0, [x1] ldr x1, =TZASC_REGION_ATTRIBUTES_0(1) - ldr x0, [x1] /* Region-1 Attributes Register */ - orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */ - orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */ - str x0, [x1] + ldr w0, [x1] /* Region-1 Attributes Register */ + orr w0, w0, #1 << 31 /* Set Sec global write en, Bit[31] */ + orr w0, w0, #1 << 30 /* Set Sec global read en, Bit[30] */ + str w0, [x1] ldr x1, =TZASC_REGION_ID_ACCESS_0(0) ldr w0, [x1] /* Region-0 Access Register */ From d5df606d17f80d78e4d577e80fd0034dc66486be Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Thu, 17 Nov 2016 12:29:54 +0530 Subject: [PATCH 17/25] armv8: fsl-layerscape : Check SVR for initializing TZASC LS2080 SoC and its personalities does not support TZASC But other new SoCs like LS2088A, LS1088A supports TZASC Hence, skip initializing TZASC for Ls2080A based on SVR Signed-off-by: Priyanka Jain Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S index ac189d3c15..f7b49cb9fe 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S +++ b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S @@ -15,6 +15,7 @@ #endif #ifdef CONFIG_FSL_LSCH3 #include +#include #endif ENTRY(lowlevel_init) @@ -140,6 +141,16 @@ ENTRY(lowlevel_init) #endif #ifdef CONFIG_FSL_TZASC_400 + /* + * LS2080 and its personalities does not support TZASC + * So skip TZASC related operations + */ + bl get_svr + lsr w0, w0, #16 + ldr w1, =SVR_DEV_LS2080A + cmp w0, w1 + b.eq 1f + /* Set TZASC so that: * a. We use only Region0 whose global secure write/read is EN * b. We use only Region0 whose NSAID write/read is EN @@ -182,7 +193,7 @@ ENTRY(lowlevel_init) isb dsb sy #endif - +1: #ifdef CONFIG_ARCH_LS1046A /* Initialize the L2 RAM latency */ mrs x1, S3_1_c11_c0_2 From 9ae836cde7aa8f54ee06879b1653b7260f866629 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Thu, 17 Nov 2016 12:29:55 +0530 Subject: [PATCH 18/25] armv8: fsl-layerscape: Add NXP LS2088A SoC support The QorIQ LS2088A SoC is built on layerscape architecture. It is similar to LS2080A SoC with some differences like 1)Timer controller offset is different 2)It has A72 cores 3)It supports TZASC module Signed-off-by: Priyanka Jain Reviewed-by: York Sun --- .../cpu/armv8/fsl-layerscape/doc/README.soc | 58 +++++++++++++++++++ arch/arm/cpu/armv8/fsl-layerscape/soc.c | 6 +- .../include/asm/arch-fsl-layerscape/config.h | 1 + .../arm/include/asm/arch-fsl-layerscape/cpu.h | 4 ++ .../arm/include/asm/arch-fsl-layerscape/soc.h | 4 ++ board/freescale/ls2080a/MAINTAINERS | 2 +- board/freescale/ls2080aqds/MAINTAINERS | 2 +- board/freescale/ls2080aqds/README | 12 ++-- board/freescale/ls2080ardb/MAINTAINERS | 2 +- board/freescale/ls2080ardb/README | 8 +-- 10 files changed, 84 insertions(+), 15 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc index f7b949aca2..c7496c02f5 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc +++ b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc @@ -4,6 +4,7 @@ SoC overview 2. LS2080A 3. LS1012A 4. LS1046A + 5. LS2088A LS1043A --------- @@ -169,3 +170,60 @@ The LS1046A SoC includes the following function and features: - Two DUARTs - Integrated flash controller (IFC) supporting NAND and NOR flash - QorIQ platform's trust architecture 2.1 + +LS2088A +-------- +The LS2088A integrated multicore processor combines eight ARM Cortex-A72 +processor cores with high-performance data path acceleration logic and network +and peripheral bus interfaces required for networking, telecom/datacom, +wireless infrastructure, and mil/aerospace applications. + +The LS2088A SoC includes the following function and features: + + - Eight 64-bit ARM Cortex-A72 CPUs + - 1 MB platform cache with ECC + - Two 64-bit DDR4 SDRAM memory controllers with ECC and interleaving support + - One secondary 32-bit DDR4 SDRAM memory controller, intended for use by + the AIOP + - Data path acceleration architecture (DPAA2) incorporating acceleration for + the following functions: + - Packet parsing, classification, and distribution (WRIOP) + - Queue and Hardware buffer management for scheduling, packet sequencing, and + congestion management, buffer allocation and de-allocation (QBMan) + - Cryptography acceleration (SEC) at up to 10 Gbps + - RegEx pattern matching acceleration (PME) at up to 10 Gbps + - Decompression/compression acceleration (DCE) at up to 20 Gbps + - Accelerated I/O processing (AIOP) at up to 20 Gbps + - QDMA engine + - 16 SerDes lanes at up to 10.3125 GHz + - Ethernet interfaces + - Up to eight 10 Gbps Ethernet MACs + - Up to eight 1 / 2.5 Gbps Ethernet MACs + - High-speed peripheral interfaces + - Four PCIe 3.0 controllers, one supporting SR-IOV + - Additional peripheral interfaces + - Two serial ATA (SATA 3.0) controllers + - Two high-speed USB 3.0 controllers with integrated PHY + - Enhanced secure digital host controller (eSDXC/eMMC) + - Serial peripheral interface (SPI) controller + - Quad Serial Peripheral Interface (QSPI) Controller + - Four I2C controllers + - Two DUARTs + - Integrated flash controller (IFC 2.0) supporting NAND and NOR flash + - Support for hardware virtualization and partitioning enforcement + - QorIQ platform's trust architecture 3.0 + - Service processor (SP) provides pre-boot initialization and secure-boot + capabilities + +LS2088A SoC has 3 more similar SoC personalities +1)LS2048A, few difference w.r.t. LS2088A: + a) Four 64-bit ARM v8 Cortex-A72 CPUs + +2)LS2084A, few difference w.r.t. LS2088A: + a) No AIOP + b) No 32-bit DDR3 SDRAM memory + c) 5 * 1/10G + 5 *1G WRIOP + d) No L2 switch + +3)LS2044A, few difference w.r.t. LS2084A: + a) Four 64-bit ARM v8 Cortex-A72 CPUs diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 5a4dd39a61..6c4238707d 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -31,8 +31,10 @@ bool soc_has_dp_ddr(void) struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); u32 svr = gur_in32(&gur->svr); - /* LS2085A has DP_DDR */ - if (SVR_SOC_VER(svr) == SVR_LS2085A) + /* LS2085A, LS2088A, LS2048A has DP_DDR */ + if ((SVR_SOC_VER(svr) == SVR_LS2085A) || + (SVR_SOC_VER(svr) == SVR_LS2088A) || + (SVR_SOC_VER(svr) == SVR_LS2048A)) return true; return false; diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h index 4201e0fbec..6c3ba494f8 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/config.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h @@ -25,6 +25,7 @@ #ifndef L1_CACHE_BYTES #define L1_CACHE_SHIFT 6 #define L1_CACHE_BYTES BIT(L1_CACHE_SHIFT) +#define CONFIG_FSL_TZASC_400 #endif #define CONFIG_SYS_FSL_OCRAM_BASE 0x18000000 /* initial RAM */ diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h index e2d96a1b78..a97be5c098 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h @@ -11,6 +11,10 @@ static struct cpu_type cpu_type_list[] = { CPU_TYPE_ENTRY(LS2080A, LS2080A, 8), CPU_TYPE_ENTRY(LS2085A, LS2085A, 8), CPU_TYPE_ENTRY(LS2045A, LS2045A, 4), + CPU_TYPE_ENTRY(LS2088A, LS2088A, 8), + CPU_TYPE_ENTRY(LS2084A, LS2084A, 8), + CPU_TYPE_ENTRY(LS2048A, LS2048A, 4), + CPU_TYPE_ENTRY(LS2044A, LS2044A, 4), CPU_TYPE_ENTRY(LS1043A, LS1043A, 4), CPU_TYPE_ENTRY(LS1023A, LS1023A, 2), CPU_TYPE_ENTRY(LS1046A, LS1046A, 4), diff --git a/arch/arm/include/asm/arch-fsl-layerscape/soc.h b/arch/arm/include/asm/arch-fsl-layerscape/soc.h index 3ccacb91fe..78363b602c 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/soc.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/soc.h @@ -50,6 +50,10 @@ struct cpu_type { #define SVR_LS2080A 0x870110 #define SVR_LS2085A 0x870100 #define SVR_LS2040A 0x870130 +#define SVR_LS2088A 0x870900 +#define SVR_LS2084A 0x870910 +#define SVR_LS2048A 0x870920 +#define SVR_LS2044A 0x870930 #define SVR_DEV_LS2080A 0x8701 diff --git a/board/freescale/ls2080a/MAINTAINERS b/board/freescale/ls2080a/MAINTAINERS index c8dac99889..de137ef64f 100644 --- a/board/freescale/ls2080a/MAINTAINERS +++ b/board/freescale/ls2080a/MAINTAINERS @@ -1,5 +1,5 @@ LS2080A BOARD -M: York Sun +M: York Sun , Priyanka Jain S: Maintained F: board/freescale/ls2080a/ F: include/configs/ls2080a_emu.h diff --git a/board/freescale/ls2080aqds/MAINTAINERS b/board/freescale/ls2080aqds/MAINTAINERS index 8f78b67baa..79877d7774 100644 --- a/board/freescale/ls2080aqds/MAINTAINERS +++ b/board/freescale/ls2080aqds/MAINTAINERS @@ -1,5 +1,5 @@ LS2080A BOARD -M: Prabhakar Kushwaha +M: Prabhakar Kushwaha , Priyanka Jain S: Maintained F: board/freescale/ls2080aqds/ F: board/freescale/ls2080a/ls2080aqds.c diff --git a/board/freescale/ls2080aqds/README b/board/freescale/ls2080aqds/README index f288750993..2808bd5851 100644 --- a/board/freescale/ls2080aqds/README +++ b/board/freescale/ls2080aqds/README @@ -2,14 +2,14 @@ Overview -------- The LS2080A Development System (QDS) is a high-performance computing, evaluation, and development platform that supports the QorIQ LS2080A -Layerscape Architecture processor. The LS2080AQDS provides validation and -SW development platform for the Freescale LS2080A processor series, with -a complete debugging environment. +and LS2088A Layerscape Architecture processor. The LS2080AQDS provides +validation and SW development platform for the Freescale LS2080A, LS2088A +processor series, with a complete debugging environment. -LS2080A SoC Overview +LS2080A, LS2088A SoC Overview -------------------- -Please refer arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc for LS2080A -SoC overview. +Please refer arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc for LS2080A, +LS2088A SoC overview. LS2080AQDS board Overview ----------------------- diff --git a/board/freescale/ls2080ardb/MAINTAINERS b/board/freescale/ls2080ardb/MAINTAINERS index a20c003ce7..759a14605c 100644 --- a/board/freescale/ls2080ardb/MAINTAINERS +++ b/board/freescale/ls2080ardb/MAINTAINERS @@ -1,5 +1,5 @@ LS2080A BOARD -M: Prabhakar Kushwaha +M: Prabhakar Kushwaha , Priyanka Jain S: Maintained F: board/freescale/ls2080ardb/ F: board/freescale/ls2080a/ls2080ardb.c diff --git a/board/freescale/ls2080ardb/README b/board/freescale/ls2080ardb/README index b1613ba680..0c9c574f33 100644 --- a/board/freescale/ls2080ardb/README +++ b/board/freescale/ls2080ardb/README @@ -1,13 +1,13 @@ Overview -------- The LS2080A Reference Design (RDB) is a high-performance computing, -evaluation, and development platform that supports the QorIQ LS2080A +evaluation, and development platform that supports the QorIQ LS2080A, LS2088A Layerscape Architecture processor. -LS2080A SoC Overview +LS2080A, LS2088A SoC Overview -------------------- -Please refer arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc for LS2080A -SoC overview. +Please refer arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc for LS2080A, +LS2088A SoC overview. LS2080ARDB board Overview ----------------------- From e87c673c206aa3eb75eb94e65d8d50d7fabaf598 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Thu, 17 Nov 2016 12:29:56 +0530 Subject: [PATCH 19/25] armv8/fsl-lsch3: Update code to release secondary cores NXP ARMv8 SoC LS2080A release all secondary cores in one-go. But other new SoCs like LS2088A, LS1088A release secondary cores one by one. Update code to release secondary cores based on SoC SVR Add code to release cores one by one for non LS2080A SoCs Signed-off-by: Priyanka Jain Signed-off-by: Raghav Dogra Signed-off-by: Prabhakar Kushwaha [YS: remove "inline" from declaration of initiator_type] Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 2 +- arch/arm/cpu/armv8/fsl-layerscape/cpu.h | 1 + arch/arm/cpu/armv8/fsl-layerscape/mp.c | 68 +++++++++++++++++++++++-- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index eb03bf44cb..d6ee54642d 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -191,7 +191,7 @@ void enable_caches(void) } #endif -static inline u32 initiator_type(u32 cluster, int init_id) +u32 initiator_type(u32 cluster, int init_id) { struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); u32 idx = (cluster >> (init_id * 8)) & TP_CLUSTER_INIT_MASK; diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.h b/arch/arm/cpu/armv8/fsl-layerscape/cpu.h index 8072f3ca6a..a05f8aad61 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.h +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.h @@ -5,4 +5,5 @@ */ int fsl_qoriq_core_to_cluster(unsigned int core); +u32 initiator_type(u32 cluster, int init_id); u32 cpu_mask(void); diff --git a/arch/arm/cpu/armv8/fsl-layerscape/mp.c b/arch/arm/cpu/armv8/fsl-layerscape/mp.c index f607c3900a..97c626996f 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/mp.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/mp.c @@ -9,6 +9,8 @@ #include #include #include +#include "cpu.h" +#include DECLARE_GLOBAL_DATA_PTR; @@ -22,11 +24,39 @@ phys_addr_t determine_mp_bootpg(void) return (phys_addr_t)&secondary_boot_code; } +#ifdef CONFIG_FSL_LSCH3 +void wake_secondary_core_n(int cluster, int core, int cluster_cores) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + struct ccsr_reset __iomem *rst = (void *)(CONFIG_SYS_FSL_RST_ADDR); + u32 mpidr = 0; + + mpidr = ((cluster << 8) | core); + /* + * mpidr_el1 register value of core which needs to be released + * is written to scratchrw[6] register + */ + gur_out32(&gur->scratchrw[6], mpidr); + asm volatile("dsb st" : : : "memory"); + rst->brrl |= 1 << ((cluster * cluster_cores) + core); + asm volatile("dsb st" : : : "memory"); + /* + * scratchrw[6] register value is polled + * when the value becomes zero, this means that this core is up + * and running, next core can be released now + */ + while (gur_in32(&gur->scratchrw[6]) != 0) + ; +} +#endif + int fsl_layerscape_wake_seconday_cores(void) { struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); #ifdef CONFIG_FSL_LSCH3 struct ccsr_reset __iomem *rst = (void *)(CONFIG_SYS_FSL_RST_ADDR); + u32 svr, ver, cluster, type; + int j = 0, cluster_cores = 0; #elif defined(CONFIG_FSL_LSCH2) struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR); #endif @@ -55,10 +85,40 @@ int fsl_layerscape_wake_seconday_cores(void) #ifdef CONFIG_FSL_LSCH3 gur_out32(&gur->bootlocptrh, (u32)(gd->relocaddr >> 32)); gur_out32(&gur->bootlocptrl, (u32)gd->relocaddr); - gur_out32(&gur->scratchrw[6], 1); - asm volatile("dsb st" : : : "memory"); - rst->brrl = cores; - asm volatile("dsb st" : : : "memory"); + + svr = gur_in32(&gur->svr); + ver = SVR_SOC_VER(svr); + if (ver == SVR_LS2080A || ver == SVR_LS2085A) { + gur_out32(&gur->scratchrw[6], 1); + asm volatile("dsb st" : : : "memory"); + rst->brrl = cores; + asm volatile("dsb st" : : : "memory"); + } else { + /* + * Release the cores out of reset one-at-a-time to avoid + * power spikes + */ + i = 0; + cluster = in_le32(&gur->tp_cluster[i].lower); + for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { + type = initiator_type(cluster, j); + if (type && + TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM) + cluster_cores++; + } + + do { + cluster = in_le32(&gur->tp_cluster[i].lower); + for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { + type = initiator_type(cluster, j); + if (type && + TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM) + wake_secondary_core_n(i, j, + cluster_cores); + } + i++; + } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); + } #elif defined(CONFIG_FSL_LSCH2) scfg_out32(&scfg->scratchrw[0], (u32)(gd->relocaddr >> 32)); scfg_out32(&scfg->scratchrw[1], (u32)gd->relocaddr); From 95e74a3df75bf01eaf69f5c28f9aa2db6568e901 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 16 Nov 2016 18:49:16 +0530 Subject: [PATCH 20/25] arm: exynos7420: remove custome low level init function Remove the custom low-level initialization function and reuse the default low-level initialization function. But this requires the ARMV8_MULTIENTRY config option to be enabled for Exynos7420. On Exynos7420, the boot CPU belongs to the second cluster and so with ARMV8_MULTIENTRY config option enabled, the 'branch_if_master' macro fails to detect the CPU as boot CPU. As a temporary workaround the CPU_RELEASE_ADDR is set to point to '_main'. Cc: Minkyu Kang Cc: Alison Wang Signed-off-by: Thomas Abraham Reviewed-by: Alison Wang Reviewed-by: York Sun --- arch/arm/mach-exynos/Kconfig | 1 + arch/arm/mach-exynos/soc.c | 18 ++++++++++-------- include/configs/exynos7420-common.h | 1 + 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index ce2a16f95b..07118fc3df 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -126,6 +126,7 @@ choice config TARGET_ESPRESSO7420 bool "ESPRESSO7420 board" select ARM64 + select ARMV8_MULTIENTRY select SUPPORT_SPL select OF_CONTROL select SPL_DISABLE_OF_CONTROL diff --git a/arch/arm/mach-exynos/soc.c b/arch/arm/mach-exynos/soc.c index f9c7468611..cf149ad1a8 100644 --- a/arch/arm/mach-exynos/soc.c +++ b/arch/arm/mach-exynos/soc.c @@ -9,6 +9,16 @@ #include #include +#ifdef CONFIG_TARGET_ESPRESSO7420 +/* + * Exynos7420 uses CPU0 of Cluster-1 as boot CPU. Due to this, branch_if_master + * fails to identify as the boot CPU as the master CPU. As temporary workaround, + * setup the slave CPU boot address as "_main". + */ +extern void _main(void); +void *secondary_boot_addr = (void *)_main; +#endif /* CONFIG_TARGET_ESPRESSO7420 */ + void reset_cpu(ulong addr) { #ifdef CONFIG_CPU_V7 @@ -23,11 +33,3 @@ void enable_caches(void) dcache_enable(); } #endif - -#ifdef CONFIG_ARM64 -void lowlevel_init(void) -{ - armv8_switch_to_el2(); - armv8_switch_to_el1(); -} -#endif diff --git a/include/configs/exynos7420-common.h b/include/configs/exynos7420-common.h index f7c47094ae..1cea74e954 100644 --- a/include/configs/exynos7420-common.h +++ b/include/configs/exynos7420-common.h @@ -47,6 +47,7 @@ #define CONFIG_IRAM_BASE 0x02100000 #define CONFIG_IRAM_SIZE 0x58000 #define CONFIG_IRAM_END (CONFIG_IRAM_BASE + CONFIG_IRAM_SIZE) +#define CPU_RELEASE_ADDR secondary_boot_addr /* Number of CPUs available */ #define CONFIG_CORE_COUNT 0x8 From ec6617c39741adc6c54952564579e32c3c09c66f Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Thu, 10 Nov 2016 10:49:03 +0800 Subject: [PATCH 21/25] armv8: Support loading 32-bit OS in AArch32 execution state To support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel. The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically. Signed-off-by: Ebony Zhu Signed-off-by: Alison Wang Signed-off-by: Chenhui Zhao Reviewed-by: York Sun --- arch/arm/Kconfig | 6 + arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S | 61 +++++- arch/arm/cpu/armv8/start.S | 8 + arch/arm/cpu/armv8/transition.S | 23 ++- arch/arm/include/asm/arch-fsl-layerscape/mp.h | 4 + arch/arm/include/asm/macro.h | 176 +++++++++++++----- arch/arm/include/asm/system.h | 119 +++++++++++- arch/arm/lib/bootm.c | 39 +++- arch/arm/mach-rmobile/lowlevel_init_gen3.S | 13 +- cmd/bootefi.c | 23 ++- common/image-fit.c | 19 +- 11 files changed, 418 insertions(+), 73 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9d4d74235a..49bc9d8375 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -126,6 +126,12 @@ config ENABLE_ARM_SOC_BOOT0_HOOK ARM_SOC_BOOT0_HOOK which contains the required assembler preprocessor code. +config ARM64_SUPPORT_AARCH32 + bool "ARM64 system support AArch32 execution state" + default y if ARM64 && !TARGET_THUNDERX_88XX + help + This ARM64 system supports AArch32 execution state. + choice prompt "Target select" default TARGET_HIKEY diff --git a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S index f7b49cb9fe..72f2c11baf 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S +++ b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S @@ -17,6 +17,7 @@ #include #include #endif +#include ENTRY(lowlevel_init) mov x29, lr /* Save LR */ @@ -359,11 +360,6 @@ ENTRY(secondary_boot_func) gic_wait_for_interrupt_m x0, w1 #endif - bl secondary_switch_to_el2 -#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 - bl secondary_switch_to_el1 -#endif - slave_cpu: wfe ldr x0, [x11] @@ -376,19 +372,64 @@ slave_cpu: tbz x1, #25, cpu_is_le rev x0, x0 /* BE to LE conversion */ cpu_is_le: - br x0 /* branch to the given address */ + ldr x5, [x11, #24] + ldr x6, =IH_ARCH_DEFAULT + cmp x6, x5 + b.eq 1f + +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + adr x3, secondary_switch_to_el1 + ldr x4, =ES_TO_AARCH64 +#else + ldr x3, [x11] + ldr x4, =ES_TO_AARCH32 +#endif + bl secondary_switch_to_el2 + +1: +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + adr x3, secondary_switch_to_el1 +#else + ldr x3, [x11] +#endif + ldr x4, =ES_TO_AARCH64 + bl secondary_switch_to_el2 + ENDPROC(secondary_boot_func) ENTRY(secondary_switch_to_el2) - switch_el x0, 1f, 0f, 0f + switch_el x5, 1f, 0f, 0f 0: ret -1: armv8_switch_to_el2_m x0 +1: armv8_switch_to_el2_m x3, x4, x5 ENDPROC(secondary_switch_to_el2) ENTRY(secondary_switch_to_el1) - switch_el x0, 0f, 1f, 0f + mrs x0, mpidr_el1 + ubfm x1, x0, #8, #15 + ubfm x2, x0, #0, #1 + orr x10, x2, x1, lsl #2 /* x10 has LPID */ + + lsl x1, x10, #6 + ldr x0, =__spin_table + /* physical address of this cpus spin table element */ + add x11, x1, x0 + + ldr x3, [x11] + + ldr x5, [x11, #24] + ldr x6, =IH_ARCH_DEFAULT + cmp x6, x5 + b.eq 2f + + ldr x4, =ES_TO_AARCH32 + bl switch_to_el1 + +2: ldr x4, =ES_TO_AARCH64 + +switch_to_el1: + switch_el x5, 0f, 1f, 0f 0: ret -1: armv8_switch_to_el1_m x0, x1 +1: armv8_switch_to_el1_m x3, x4, x5 ENDPROC(secondary_switch_to_el1) /* Ensure that the literals used by the secondary boot code are diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index 19c771dba3..4f5f6d8020 100644 --- a/arch/arm/cpu/armv8/start.S +++ b/arch/arm/cpu/armv8/start.S @@ -251,9 +251,17 @@ WEAK(lowlevel_init) /* * All slaves will enter EL2 and optionally EL1. */ + adr x3, lowlevel_in_el2 + ldr x4, =ES_TO_AARCH64 bl armv8_switch_to_el2 + +lowlevel_in_el2: #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + adr x3, lowlevel_in_el1 + ldr x4, =ES_TO_AARCH64 bl armv8_switch_to_el1 + +lowlevel_in_el1: #endif #endif /* CONFIG_ARMV8_MULTIENTRY */ diff --git a/arch/arm/cpu/armv8/transition.S b/arch/arm/cpu/armv8/transition.S index 253a39bd11..bbccf2b395 100644 --- a/arch/arm/cpu/armv8/transition.S +++ b/arch/arm/cpu/armv8/transition.S @@ -11,13 +11,24 @@ #include ENTRY(armv8_switch_to_el2) - switch_el x0, 1f, 0f, 0f -0: ret -1: armv8_switch_to_el2_m x0 + switch_el x5, 1f, 0f, 0f +0: + /* + * x3 is kernel entry point or switch_to_el1 + * if CONFIG_ARMV8_SWITCH_TO_EL1 is defined. + * When running in EL2 now, jump to the + * address saved in x3. + */ + br x3 +1: armv8_switch_to_el2_m x3, x4, x5 ENDPROC(armv8_switch_to_el2) ENTRY(armv8_switch_to_el1) - switch_el x0, 0f, 1f, 0f -0: ret -1: armv8_switch_to_el1_m x0, x1 + switch_el x5, 0f, 1f, 0f +0: + /* x3 is kernel entry point. When running in EL1 + * now, jump to the address saved in x3. + */ + br x3 +1: armv8_switch_to_el1_m x3, x4, x5 ENDPROC(armv8_switch_to_el1) diff --git a/arch/arm/include/asm/arch-fsl-layerscape/mp.h b/arch/arm/include/asm/arch-fsl-layerscape/mp.h index f7306ff266..ebf84b65f4 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/mp.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/mp.h @@ -36,4 +36,8 @@ void secondary_boot_func(void); int is_core_online(u64 cpu_id); u32 cpu_pos_mask(void); #endif + +#define IH_ARCH_ARM 2 /* ARM */ +#define IH_ARCH_ARM64 22 /* ARM64 */ + #endif /* _FSL_LAYERSCAPE_MP_H */ diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h index 9bb0efa5ff..2553e3e349 100644 --- a/arch/arm/include/asm/macro.h +++ b/arch/arm/include/asm/macro.h @@ -8,6 +8,11 @@ #ifndef __ASM_ARM_MACRO_H__ #define __ASM_ARM_MACRO_H__ + +#ifdef CONFIG_ARM64 +#include +#endif + #ifdef __ASSEMBLY__ /* @@ -135,13 +140,21 @@ lr .req x30 #endif .endm -.macro armv8_switch_to_el2_m, xreg1 - /* 64bit EL2 | HCE | SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1 */ - mov \xreg1, #0x5b1 - msr scr_el3, \xreg1 +/* + * Switch from EL3 to EL2 for ARMv8 + * @ep: kernel entry point + * @flag: The execution state flag for lower exception + * level, ES_TO_AARCH64 or ES_TO_AARCH32 + * @tmp: temporary register + * + * For loading 32-bit OS, x1 is machine nr and x2 is ftaddr. + * For loading 64-bit OS, x0 is physical address to the FDT blob. + * They will be passed to the guest. + */ +.macro armv8_switch_to_el2_m, ep, flag, tmp msr cptr_el3, xzr /* Disable coprocessor traps to EL3 */ - mov \xreg1, #0x33ff - msr cptr_el2, \xreg1 /* Disable coprocessor traps to EL2 */ + mov \tmp, #CPTR_EL2_RES1 + msr cptr_el2, \tmp /* Disable coprocessor traps to EL2 */ /* Initialize Generic Timers */ msr cntvoff_el2, xzr @@ -152,45 +165,90 @@ lr .req x30 * and RES0 bits (31,30,27,26,24,21,20,17,15-13,10-6) + * EE,WXN,I,SA,C,A,M to 0 */ - mov \xreg1, #0x0830 - movk \xreg1, #0x30C5, lsl #16 - msr sctlr_el2, \xreg1 + ldr \tmp, =(SCTLR_EL2_RES1 | SCTLR_EL2_EE_LE |\ + SCTLR_EL2_WXN_DIS | SCTLR_EL2_ICACHE_DIS |\ + SCTLR_EL2_SA_DIS | SCTLR_EL2_DCACHE_DIS |\ + SCTLR_EL2_ALIGN_DIS | SCTLR_EL2_MMU_DIS) + msr sctlr_el2, \tmp + + mov \tmp, sp + msr sp_el2, \tmp /* Migrate SP */ + mrs \tmp, vbar_el3 + msr vbar_el2, \tmp /* Migrate VBAR */ + + /* Check switch to AArch64 EL2 or AArch32 Hypervisor mode */ + cmp \flag, #ES_TO_AARCH32 + b.eq 1f + + /* + * The next lower exception level is AArch64, 64bit EL2 | HCE | + * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1. + */ + ldr \tmp, =(SCR_EL3_RW_AARCH64 | SCR_EL3_HCE_EN |\ + SCR_EL3_SMD_DIS | SCR_EL3_RES1 |\ + SCR_EL3_NS_EN) + msr scr_el3, \tmp /* Return to the EL2_SP2 mode from EL3 */ - mov \xreg1, sp - msr sp_el2, \xreg1 /* Migrate SP */ - mrs \xreg1, vbar_el3 - msr vbar_el2, \xreg1 /* Migrate VBAR */ - mov \xreg1, #0x3c9 - msr spsr_el3, \xreg1 /* EL2_SP2 | D | A | I | F */ - msr elr_el3, lr + ldr \tmp, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\ + SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\ + SPSR_EL_M_AARCH64 | SPSR_EL_M_EL2H) + msr spsr_el3, \tmp + msr elr_el3, \ep + eret + +1: + /* + * The next lower exception level is AArch32, 32bit EL2 | HCE | + * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1. + */ + ldr \tmp, =(SCR_EL3_RW_AARCH32 | SCR_EL3_HCE_EN |\ + SCR_EL3_SMD_DIS | SCR_EL3_RES1 |\ + SCR_EL3_NS_EN) + msr scr_el3, \tmp + + /* Return to AArch32 Hypervisor mode */ + ldr \tmp, =(SPSR_EL_END_LE | SPSR_EL_ASYN_MASK |\ + SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\ + SPSR_EL_T_A32 | SPSR_EL_M_AARCH32 |\ + SPSR_EL_M_HYP) + msr spsr_el3, \tmp + msr elr_el3, \ep eret .endm -.macro armv8_switch_to_el1_m, xreg1, xreg2 +/* + * Switch from EL2 to EL1 for ARMv8 + * @ep: kernel entry point + * @flag: The execution state flag for lower exception + * level, ES_TO_AARCH64 or ES_TO_AARCH32 + * @tmp: temporary register + * + * For loading 32-bit OS, x1 is machine nr and x2 is ftaddr. + * For loading 64-bit OS, x0 is physical address to the FDT blob. + * They will be passed to the guest. + */ +.macro armv8_switch_to_el1_m, ep, flag, tmp /* Initialize Generic Timers */ - mrs \xreg1, cnthctl_el2 - orr \xreg1, \xreg1, #0x3 /* Enable EL1 access to timers */ - msr cnthctl_el2, \xreg1 + mrs \tmp, cnthctl_el2 + /* Enable EL1 access to timers */ + orr \tmp, \tmp, #(CNTHCTL_EL2_EL1PCEN_EN |\ + CNTHCTL_EL2_EL1PCTEN_EN) + msr cnthctl_el2, \tmp msr cntvoff_el2, xzr /* Initilize MPID/MPIDR registers */ - mrs \xreg1, midr_el1 - mrs \xreg2, mpidr_el1 - msr vpidr_el2, \xreg1 - msr vmpidr_el2, \xreg2 + mrs \tmp, midr_el1 + msr vpidr_el2, \tmp + mrs \tmp, mpidr_el1 + msr vmpidr_el2, \tmp /* Disable coprocessor traps */ - mov \xreg1, #0x33ff - msr cptr_el2, \xreg1 /* Disable coprocessor traps to EL2 */ + mov \tmp, #CPTR_EL2_RES1 + msr cptr_el2, \tmp /* Disable coprocessor traps to EL2 */ msr hstr_el2, xzr /* Disable coprocessor traps to EL2 */ - mov \xreg1, #3 << 20 - msr cpacr_el1, \xreg1 /* Enable FP/SIMD at EL1 */ - - /* Initialize HCR_EL2 */ - mov \xreg1, #(1 << 31) /* 64bit EL1 */ - orr \xreg1, \xreg1, #(1 << 29) /* Disable HVC */ - msr hcr_el2, \xreg1 + mov \tmp, #CPACR_EL1_FPEN_EN + msr cpacr_el1, \tmp /* Enable FP/SIMD at EL1 */ /* SCTLR_EL1 initialization * @@ -199,18 +257,50 @@ lr .req x30 * UCI,EE,EOE,WXN,nTWE,nTWI,UCT,DZE,I,UMA,SED,ITD, * CP15BEN,SA0,SA,C,A,M to 0 */ - mov \xreg1, #0x0800 - movk \xreg1, #0x30d0, lsl #16 - msr sctlr_el1, \xreg1 + ldr \tmp, =(SCTLR_EL1_RES1 | SCTLR_EL1_UCI_DIS |\ + SCTLR_EL1_EE_LE | SCTLR_EL1_WXN_DIS |\ + SCTLR_EL1_NTWE_DIS | SCTLR_EL1_NTWI_DIS |\ + SCTLR_EL1_UCT_DIS | SCTLR_EL1_DZE_DIS |\ + SCTLR_EL1_ICACHE_DIS | SCTLR_EL1_UMA_DIS |\ + SCTLR_EL1_SED_EN | SCTLR_EL1_ITD_EN |\ + SCTLR_EL1_CP15BEN_DIS | SCTLR_EL1_SA0_DIS |\ + SCTLR_EL1_SA_DIS | SCTLR_EL1_DCACHE_DIS |\ + SCTLR_EL1_ALIGN_DIS | SCTLR_EL1_MMU_DIS) + msr sctlr_el1, \tmp + + mov \tmp, sp + msr sp_el1, \tmp /* Migrate SP */ + mrs \tmp, vbar_el2 + msr vbar_el1, \tmp /* Migrate VBAR */ + + /* Check switch to AArch64 EL1 or AArch32 Supervisor mode */ + cmp \flag, #ES_TO_AARCH32 + b.eq 1f + + /* Initialize HCR_EL2 */ + ldr \tmp, =(HCR_EL2_RW_AARCH64 | HCR_EL2_HCD_DIS) + msr hcr_el2, \tmp /* Return to the EL1_SP1 mode from EL2 */ - mov \xreg1, sp - msr sp_el1, \xreg1 /* Migrate SP */ - mrs \xreg1, vbar_el2 - msr vbar_el1, \xreg1 /* Migrate VBAR */ - mov \xreg1, #0x3c5 - msr spsr_el2, \xreg1 /* EL1_SP1 | D | A | I | F */ - msr elr_el2, lr + ldr \tmp, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\ + SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\ + SPSR_EL_M_AARCH64 | SPSR_EL_M_EL1H) + msr spsr_el2, \tmp + msr elr_el2, \ep + eret + +1: + /* Initialize HCR_EL2 */ + ldr \tmp, =(HCR_EL2_RW_AARCH32 | HCR_EL2_HCD_DIS) + msr hcr_el2, \tmp + + /* Return to AArch32 Supervisor mode from EL2 */ + ldr \tmp, =(SPSR_EL_END_LE | SPSR_EL_ASYN_MASK |\ + SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\ + SPSR_EL_T_A32 | SPSR_EL_M_AARCH32 |\ + SPSR_EL_M_SVC) + msr spsr_el2, \tmp + msr elr_el2, \ep eret .endm diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 574a0e775f..287ff5c782 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -18,6 +18,95 @@ #define CR_WXN (1 << 19) /* Write Permision Imply XN */ #define CR_EE (1 << 25) /* Exception (Big) Endian */ +#define ES_TO_AARCH64 1 +#define ES_TO_AARCH32 0 + +/* + * SCR_EL3 bits definitions + */ +#define SCR_EL3_RW_AARCH64 (1 << 10) /* Next lower level is AArch64 */ +#define SCR_EL3_RW_AARCH32 (0 << 10) /* Lower lowers level are AArch32 */ +#define SCR_EL3_HCE_EN (1 << 8) /* Hypervisor Call enable */ +#define SCR_EL3_SMD_DIS (1 << 7) /* Secure Monitor Call disable */ +#define SCR_EL3_RES1 (3 << 4) /* Reserved, RES1 */ +#define SCR_EL3_NS_EN (1 << 0) /* EL0 and EL1 in Non-scure state */ + +/* + * SPSR_EL3/SPSR_EL2 bits definitions + */ +#define SPSR_EL_END_LE (0 << 9) /* Exception Little-endian */ +#define SPSR_EL_DEBUG_MASK (1 << 9) /* Debug exception masked */ +#define SPSR_EL_ASYN_MASK (1 << 8) /* Asynchronous data abort masked */ +#define SPSR_EL_SERR_MASK (1 << 8) /* System Error exception masked */ +#define SPSR_EL_IRQ_MASK (1 << 7) /* IRQ exception masked */ +#define SPSR_EL_FIQ_MASK (1 << 6) /* FIQ exception masked */ +#define SPSR_EL_T_A32 (0 << 5) /* AArch32 instruction set A32 */ +#define SPSR_EL_M_AARCH64 (0 << 4) /* Exception taken from AArch64 */ +#define SPSR_EL_M_AARCH32 (1 << 4) /* Exception taken from AArch32 */ +#define SPSR_EL_M_SVC (0x3) /* Exception taken from SVC mode */ +#define SPSR_EL_M_HYP (0xa) /* Exception taken from HYP mode */ +#define SPSR_EL_M_EL1H (5) /* Exception taken from EL1h mode */ +#define SPSR_EL_M_EL2H (9) /* Exception taken from EL2h mode */ + +/* + * CPTR_EL2 bits definitions + */ +#define CPTR_EL2_RES1 (3 << 12 | 0x3ff) /* Reserved, RES1 */ + +/* + * SCTLR_EL2 bits definitions + */ +#define SCTLR_EL2_RES1 (3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 |\ + 1 << 11 | 3 << 4) /* Reserved, RES1 */ +#define SCTLR_EL2_EE_LE (0 << 25) /* Exception Little-endian */ +#define SCTLR_EL2_WXN_DIS (0 << 19) /* Write permission is not XN */ +#define SCTLR_EL2_ICACHE_DIS (0 << 12) /* Instruction cache disabled */ +#define SCTLR_EL2_SA_DIS (0 << 3) /* Stack Alignment Check disabled */ +#define SCTLR_EL2_DCACHE_DIS (0 << 2) /* Data cache disabled */ +#define SCTLR_EL2_ALIGN_DIS (0 << 1) /* Alignment check disabled */ +#define SCTLR_EL2_MMU_DIS (0) /* MMU disabled */ + +/* + * CNTHCTL_EL2 bits definitions + */ +#define CNTHCTL_EL2_EL1PCEN_EN (1 << 1) /* Physical timer regs accessible */ +#define CNTHCTL_EL2_EL1PCTEN_EN (1 << 0) /* Physical counter accessible */ + +/* + * HCR_EL2 bits definitions + */ +#define HCR_EL2_RW_AARCH64 (1 << 31) /* EL1 is AArch64 */ +#define HCR_EL2_RW_AARCH32 (0 << 31) /* Lower levels are AArch32 */ +#define HCR_EL2_HCD_DIS (1 << 29) /* Hypervisor Call disabled */ + +/* + * CPACR_EL1 bits definitions + */ +#define CPACR_EL1_FPEN_EN (3 << 20) /* SIMD and FP instruction enabled */ + +/* + * SCTLR_EL1 bits definitions + */ +#define SCTLR_EL1_RES1 (3 << 28 | 3 << 22 | 1 << 20 |\ + 1 << 11) /* Reserved, RES1 */ +#define SCTLR_EL1_UCI_DIS (0 << 26) /* Cache instruction disabled */ +#define SCTLR_EL1_EE_LE (0 << 25) /* Exception Little-endian */ +#define SCTLR_EL1_WXN_DIS (0 << 19) /* Write permission is not XN */ +#define SCTLR_EL1_NTWE_DIS (0 << 18) /* WFE instruction disabled */ +#define SCTLR_EL1_NTWI_DIS (0 << 16) /* WFI instruction disabled */ +#define SCTLR_EL1_UCT_DIS (0 << 15) /* CTR_EL0 access disabled */ +#define SCTLR_EL1_DZE_DIS (0 << 14) /* DC ZVA instruction disabled */ +#define SCTLR_EL1_ICACHE_DIS (0 << 12) /* Instruction cache disabled */ +#define SCTLR_EL1_UMA_DIS (0 << 9) /* User Mask Access disabled */ +#define SCTLR_EL1_SED_EN (0 << 8) /* SETEND instruction enabled */ +#define SCTLR_EL1_ITD_EN (0 << 7) /* IT instruction enabled */ +#define SCTLR_EL1_CP15BEN_DIS (0 << 5) /* CP15 barrier operation disabled */ +#define SCTLR_EL1_SA0_DIS (0 << 4) /* Stack Alignment EL0 disabled */ +#define SCTLR_EL1_SA_DIS (0 << 3) /* Stack Alignment EL1 disabled */ +#define SCTLR_EL1_DCACHE_DIS (0 << 2) /* Data cache disabled */ +#define SCTLR_EL1_ALIGN_DIS (0 << 1) /* Alignment check disabled */ +#define SCTLR_EL1_MMU_DIS (0) /* MMU disabled */ + #ifndef __ASSEMBLY__ u64 get_page_table_size(void); @@ -98,8 +187,34 @@ int __asm_flush_l3_dcache(void); int __asm_invalidate_l3_icache(void); void __asm_switch_ttbr(u64 new_ttbr); -void armv8_switch_to_el2(void); -void armv8_switch_to_el1(void); +/* + * Switch from EL3 to EL2 for ARMv8 + * + * @args: For loading 64-bit OS, fdt address. + * For loading 32-bit OS, zero. + * @mach_nr: For loading 64-bit OS, zero. + * For loading 32-bit OS, machine nr + * @fdt_addr: For loading 64-bit OS, zero. + * For loading 32-bit OS, fdt address. + * @entry_point: kernel entry point + * @es_flag: execution state flag, ES_TO_AARCH64 or ES_TO_AARCH32 + */ +void armv8_switch_to_el2(u64 args, u64 mach_nr, u64 fdt_addr, + u64 entry_point, u64 es_flag); +/* + * Switch from EL2 to EL1 for ARMv8 + * + * @args: For loading 64-bit OS, fdt address. + * For loading 32-bit OS, zero. + * @mach_nr: For loading 64-bit OS, zero. + * For loading 32-bit OS, machine nr + * @fdt_addr: For loading 64-bit OS, zero. + * For loading 32-bit OS, fdt address. + * @entry_point: kernel entry point + * @es_flag: execution state flag, ES_TO_AARCH64 or ES_TO_AARCH32 + */ +void armv8_switch_to_el1(u64 args, u64 mach_nr, u64 fdt_addr, + u64 entry_point, u64 es_flag); void gic_init(void); void gic_send_sgi(unsigned long sgino); void wait_for_wakeup(void); diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index dedcd1e9a4..6f3be8b528 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -200,10 +200,6 @@ static void do_nonsec_virt_switch(void) { smp_kick_all_cpus(); dcache_disable(); /* flush cache before swtiching to EL2 */ - armv8_switch_to_el2(); -#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 - armv8_switch_to_el1(); -#endif } #endif @@ -280,6 +276,24 @@ bool armv7_boot_nonsec(void) } #endif +#ifdef CONFIG_ARM64 +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 +static void switch_to_el1(void) +{ + if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) && + (images.os.arch == IH_ARCH_ARM)) + armv8_switch_to_el1(0, (u64)gd->bd->bi_arch_number, + (u64)images.ft_addr, + (u64)images.ep, + ES_TO_AARCH32); + else + armv8_switch_to_el1((u64)images.ft_addr, 0, 0, + images.ep, + ES_TO_AARCH64); +} +#endif +#endif + /* Subcommand: GO */ static void boot_jump_linux(bootm_headers_t *images, int flag) { @@ -299,7 +313,22 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) if (!fake) { do_nonsec_virt_switch(); - kernel_entry(images->ft_addr, NULL, NULL, NULL); + +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + armv8_switch_to_el2((u64)images->ft_addr, 0, 0, + (u64)switch_to_el1, ES_TO_AARCH64); +#else + if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) && + (images->os.arch == IH_ARCH_ARM)) + armv8_switch_to_el2(0, (u64)gd->bd->bi_arch_number, + (u64)images->ft_addr, + (u64)images->ep, + ES_TO_AARCH32); + else + armv8_switch_to_el2((u64)images->ft_addr, 0, 0, + images->ep, + ES_TO_AARCH64); +#endif } #else unsigned long machid = gd->bd->bi_arch_number; diff --git a/arch/arm/mach-rmobile/lowlevel_init_gen3.S b/arch/arm/mach-rmobile/lowlevel_init_gen3.S index 88ff56ecbf..11acce0395 100644 --- a/arch/arm/mach-rmobile/lowlevel_init_gen3.S +++ b/arch/arm/mach-rmobile/lowlevel_init_gen3.S @@ -61,11 +61,18 @@ ENTRY(lowlevel_init) /* * All slaves will enter EL2 and optionally EL1. */ + adr x3, lowlevel_in_el2 + ldr x4, =ES_TO_AARCH64 bl armv8_switch_to_el2 -#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 - bl armv8_switch_to_el1 -#endif +lowlevel_in_el2: +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + adr x3, lowlevel_in_el1 + ldr x4, =ES_TO_AARCH64 + bl armv8_switch_to_el1 + +lowlevel_in_el1: +#endif #endif /* CONFIG_ARMV8_MULTIENTRY */ bl s_init diff --git a/cmd/bootefi.c b/cmd/bootefi.c index ca411702ba..97a0fc9c7c 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -141,6 +141,18 @@ static void *copy_fdt(void *fdt) return new_fdt; } +#ifdef CONFIG_ARM64 +static unsigned long efi_run_in_el2(ulong (*entry)(void *image_handle, + struct efi_system_table *st), void *image_handle, + struct efi_system_table *st) +{ + /* Enable caches again */ + dcache_enable(); + + return entry(image_handle, st); +} +#endif + /* * Load an EFI payload into a newly allocated piece of memory, register all * EFI objects it would want to access and jump to it. @@ -231,9 +243,14 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt) if (current_el() == 3) { smp_kick_all_cpus(); dcache_disable(); /* flush cache before switch to EL2 */ - armv8_switch_to_el2(); - /* Enable caches again */ - dcache_enable(); + + /* Move into EL2 and keep running there */ + armv8_switch_to_el2((ulong)entry, (ulong)&loaded_image_info, + (ulong)&systab, (ulong)efi_run_in_el2, + ES_TO_AARCH64); + + /* Should never reach here, efi exits with longjmp */ + while (1) { } } #endif diff --git a/common/image-fit.c b/common/image-fit.c index 77dc011dc3..ea56d5bd7a 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -27,6 +27,7 @@ DECLARE_GLOBAL_DATA_PTR; #include #include #include +#include /*****************************************************************************/ /* New uImage format routines */ @@ -1161,11 +1162,18 @@ int fit_image_check_os(const void *fit, int noffset, uint8_t os) int fit_image_check_arch(const void *fit, int noffset, uint8_t arch) { uint8_t image_arch; + int aarch32_support = 0; + +#ifdef CONFIG_ARM64_SUPPORT_AARCH32 + aarch32_support = 1; +#endif if (fit_image_get_arch(fit, noffset, &image_arch)) return 0; return (arch == image_arch) || - (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64); + (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) || + (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM && + aarch32_support); } /** @@ -1614,6 +1622,9 @@ int fit_image_load(bootm_headers_t *images, ulong addr, int type_ok, os_ok; ulong load, data, len; uint8_t os; +#ifndef USE_HOSTCC + uint8_t os_arch; +#endif const char *prop_name; int ret; @@ -1697,6 +1708,12 @@ int fit_image_load(bootm_headers_t *images, ulong addr, return -ENOEXEC; } #endif + +#ifndef USE_HOSTCC + fit_image_get_arch(fit, noffset, &os_arch); + images->os.arch = os_arch; +#endif + if (image_type == IH_TYPE_FLATDT && !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) { puts("FDT image is compressed"); From e2c18e40b111470fbe1aca47b58570099695f10a Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Thu, 10 Nov 2016 10:49:04 +0800 Subject: [PATCH 22/25] armv8: fsl-layerscape: SMP support for loading 32-bit OS Spin-table method is used for secondary cores to load 32-bit OS. The architecture information will be got through checking FIT image and saved in the os_arch element of spin-table, then the secondary cores will check os_arch and jump to 32-bit OS or 64-bit OS automatically. Signed-off-by: Alison Wang Signed-off-by: Chenhui Zhao Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/mp.c | 10 ++++++++++ arch/arm/include/asm/arch-fsl-layerscape/mp.h | 2 ++ arch/arm/lib/bootm.c | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/mp.c b/arch/arm/cpu/armv8/fsl-layerscape/mp.c index 97c626996f..80fe1ade2e 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/mp.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/mp.c @@ -24,6 +24,16 @@ phys_addr_t determine_mp_bootpg(void) return (phys_addr_t)&secondary_boot_code; } +void update_os_arch_secondary_cores(uint8_t os_arch) +{ + u64 *table = get_spin_tbl_addr(); + int i; + + for (i = 1; i < CONFIG_MAX_CPUS; i++) + table[i * WORDS_PER_SPIN_TABLE_ENTRY + + SPIN_TABLE_ELEM_OS_ARCH_IDX] = os_arch; +} + #ifdef CONFIG_FSL_LSCH3 void wake_secondary_core_n(int cluster, int core, int cluster_cores) { diff --git a/arch/arm/include/asm/arch-fsl-layerscape/mp.h b/arch/arm/include/asm/arch-fsl-layerscape/mp.h index ebf84b65f4..d0832b54bc 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/mp.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/mp.h @@ -13,6 +13,7 @@ * uint64_t entry_addr; * uint64_t status; * uint64_t lpid; +* uint64_t os_arch; * }; * we pad this struct to 64 bytes so each entry is in its own cacheline * the actual spin table is an array of these structures @@ -20,6 +21,7 @@ #define SPIN_TABLE_ELEM_ENTRY_ADDR_IDX 0 #define SPIN_TABLE_ELEM_STATUS_IDX 1 #define SPIN_TABLE_ELEM_LPID_IDX 2 +#define SPIN_TABLE_ELEM_OS_ARCH_IDX 3 #define WORDS_PER_SPIN_TABLE_ENTRY 8 /* pad to 64 bytes */ #define SPIN_TABLE_ELEM_SIZE 64 diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 6f3be8b528..35e6b06733 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -277,6 +277,10 @@ bool armv7_boot_nonsec(void) #endif #ifdef CONFIG_ARM64 +__weak void update_os_arch_secondary_cores(uint8_t os_arch) +{ +} + #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 static void switch_to_el1(void) { @@ -314,6 +318,8 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) if (!fake) { do_nonsec_virt_switch(); + update_os_arch_secondary_cores(images->os.arch); + #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 armv8_switch_to_el2((u64)images->ft_addr, 0, 0, (u64)switch_to_el1, ES_TO_AARCH64); From 3db86f4bbd7a723421c8c9bf9bd09d58e17e9736 Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Thu, 10 Nov 2016 10:49:05 +0800 Subject: [PATCH 23/25] armv8: fsl-layerscape: Support loading 32-bit OS with PSCI enabled As PSCI and secure monitor firmware framework are enabled, this patch is to support loading 32-bit OS in such case. The default target exception level returned to U-Boot is EL2, so the corresponding work to switch to AArch32 EL2 and jump to 32-bit OS are done in U-Boot and secure firmware together. Signed-off-by: Alison Wang Reviewed-by: York Sun --- arch/arm/cpu/armv8/sec_firmware_asm.S | 23 +++++++++++++++++++++++ arch/arm/cpu/armv8/transition.S | 12 ++++++++++++ arch/arm/include/asm/system.h | 2 ++ 3 files changed, 37 insertions(+) diff --git a/arch/arm/cpu/armv8/sec_firmware_asm.S b/arch/arm/cpu/armv8/sec_firmware_asm.S index 0c6a46249a..1b39f1d322 100644 --- a/arch/arm/cpu/armv8/sec_firmware_asm.S +++ b/arch/arm/cpu/armv8/sec_firmware_asm.S @@ -50,4 +50,27 @@ ENTRY(_sec_firmware_support_psci_version) smc #0 ret ENDPROC(_sec_firmware_support_psci_version) + +/* + * Switch from AArch64 EL2 to AArch32 EL2 + * @param inputs: + * x0: argument, zero + * x1: machine nr + * x2: fdt address + * x3: kernel entry point + * @param outputs for secure firmware: + * x0: function id + * x1: kernel entry point + * x2: machine nr + * x3: fdt address +*/ +ENTRY(armv8_el2_to_aarch32) + mov x0, x3 + mov x3, x2 + mov x2, x1 + mov x1, x0 + ldr x0, =0xc000ff04 + smc #0 + ret +ENDPROC(armv8_el2_to_aarch32) #endif diff --git a/arch/arm/cpu/armv8/transition.S b/arch/arm/cpu/armv8/transition.S index bbccf2b395..adb9f3566b 100644 --- a/arch/arm/cpu/armv8/transition.S +++ b/arch/arm/cpu/armv8/transition.S @@ -13,6 +13,14 @@ ENTRY(armv8_switch_to_el2) switch_el x5, 1f, 0f, 0f 0: + cmp x4, #ES_TO_AARCH64 + b.eq 2f + /* + * When loading 32-bit kernel, it will jump + * to secure firmware again, and never return. + */ + bl armv8_el2_to_aarch32 +2: /* * x3 is kernel entry point or switch_to_el1 * if CONFIG_ARMV8_SWITCH_TO_EL1 is defined. @@ -32,3 +40,7 @@ ENTRY(armv8_switch_to_el1) br x3 1: armv8_switch_to_el1_m x3, x4, x5 ENDPROC(armv8_switch_to_el1) + +WEAK(armv8_el2_to_aarch32) + ret +ENDPROC(armv8_el2_to_aarch32) diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 287ff5c782..01efc43657 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -215,6 +215,8 @@ void armv8_switch_to_el2(u64 args, u64 mach_nr, u64 fdt_addr, */ void armv8_switch_to_el1(u64 args, u64 mach_nr, u64 fdt_addr, u64 entry_point, u64 es_flag); +void armv8_el2_to_aarch32(u64 args, u64 mach_nr, u64 fdt_addr, + u64 entry_point); void gic_init(void); void gic_send_sgi(unsigned long sgino); void wait_for_wakeup(void); From f9dd8553f31817353f2a04385a1a0909df9670e4 Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 23 Nov 2016 09:08:47 -0800 Subject: [PATCH 24/25] armv7: ls1021aiot: Fixing SPL compiling issues To align with SPL change 38fed8ab and 693d4c9f, add Kconfig option CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR to defconfig, and remove CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS. Signed-off-by: York Sun CC: Feng Li --- configs/ls1021aiot_sdcard_defconfig | 2 ++ include/configs/ls1021aiot.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/ls1021aiot_sdcard_defconfig b/configs/ls1021aiot_sdcard_defconfig index 4b082ab0f9..a5a391dd81 100644 --- a/configs/ls1021aiot_sdcard_defconfig +++ b/configs/ls1021aiot_sdcard_defconfig @@ -1,6 +1,8 @@ CONFIG_ARM=y CONFIG_TARGET_LS1021AIOT=y CONFIG_SPL=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0xe8 CONFIG_DEFAULT_DEVICE_TREE="ls1021a-iot-duart" CONFIG_DM_SPI=y CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,SPL_FSL_PBL,SD_BOOT,SD_BOOT_QSPI" diff --git a/include/configs/ls1021aiot.h b/include/configs/ls1021aiot.h index 182a003603..7af4bc41dc 100644 --- a/include/configs/ls1021aiot.h +++ b/include/configs/ls1021aiot.h @@ -96,7 +96,6 @@ #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_MMC_SUPPORT #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0xe8 -#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x400 #define CONFIG_SPL_TEXT_BASE 0x10000000 #define CONFIG_SPL_MAX_SIZE 0x1a000 From 020198b0c7d251cf6bde76024ecf0ee711860534 Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 23 Nov 2016 09:25:09 -0800 Subject: [PATCH 25/25] image-fit: Fix compiling error caused by autoconf.h Commit ec6617c3 includes autoconf.h in image-fit.c, causing conflict for board odroid-xu3 which overwrites CONFIG_SYS_BOARD in header file. Move the include higher and use linux/kconfig.h instead of generated/autoconf.h. Signed-off-by: York Sun CC: Alison Wang --- common/image-fit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/image-fit.c b/common/image-fit.c index ea56d5bd7a..9468e519db 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -14,6 +14,7 @@ #include #else #include +#include #include #include #include @@ -27,7 +28,6 @@ DECLARE_GLOBAL_DATA_PTR; #include #include #include -#include /*****************************************************************************/ /* New uImage format routines */