diff --git a/.travis.yml b/.travis.yml index d24aeacead2..30fe2ead26b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -195,6 +195,9 @@ script: - $make PLATFORM=imx-mx6qsabresd - $make PLATFORM=imx-mx6dlsabresd + # i.MX7Dual SABRE + - $make PLATFORM=imx-mx7dsabresd + # Texas Instruments DRA7xx - $make PLATFORM=ti-dra7xx diff --git a/MAINTAINERS.md b/MAINTAINERS.md index f8ff35be244..1a881d8af7e 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -14,6 +14,7 @@ for these platforms. | FSL i.MX6 Quad SABRE SD Board |`Yan Yan `,`Feng Yu `| | FSL i.MX6 UltraLite EVK Board |`Peng Fan `| | NXP i.MX6 ULL EVK Board |`Peng Fan `| +| NXP i.MX7 Dual SabreSD Board |`Peng Fan `| | ARM Foundation FVP |`Linaro `| | HiKey Board (HiSilicon Kirin 620) |`Linaro `| | HiSilicon D02 |`Linaro `| diff --git a/README.md b/README.md index 6d8fab89188..8aa6e945743 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ platforms have different sub-maintainers, please refer to the file | [FSL i.MX6 Quad SABRE Lite Board](https://boundarydevices.com/product/sabre-lite-imx6-sbc/) |`PLATFORM=imx`| Yes | | [FSL i.MX6 Quad SABRE SD Board](http://www.nxp.com/products/software-and-tools/hardware-development-tools/sabre-development-system/sabre-board-for-smart-devices-based-on-the-i.mx-6quad-applications-processors:RD-IMX6Q-SABRE) |`PLATFORM=imx`| Yes | | [FSL i.MX6 UltraLite EVK Board](http://www.freescale.com/products/arm-processors/i.mx-applications-processors-based-on-arm-cores/i.mx-6-processors/i.mx6qp/i.mx6ultralite-evaluation-kit:MCIMX6UL-EVK) |`PLATFORM=imx`| Yes | +| [NXP i.MX7Dual SabreSD Board](http://www.nxp.com/products/software-and-tools/hardware-development-tools/sabre-development-system/sabre-board-for-smart-devices-based-on-the-i.mx-7dual-applications-processors:MCIMX7SABRE) |`PLATFORM=imx-mx7dsabresd`| Yes | | [ARM Foundation FVP](https://developer.arm.com/products/system-design/fixed-virtual-platforms) |`PLATFORM=vexpress-fvp`| Yes | | [HiSilicon D02](http://open-estuary.org/d02-2)|`PLATFORM=d02`| No | | [HiKey Board (HiSilicon Kirin 620)](https://www.96boards.org/products/hikey)|`PLATFORM=hikey`| Yes | diff --git a/core/arch/arm/plat-imx/conf.mk b/core/arch/arm/plat-imx/conf.mk index 93d604515b3..76ef44943c2 100644 --- a/core/arch/arm/plat-imx/conf.mk +++ b/core/arch/arm/plat-imx/conf.mk @@ -7,6 +7,7 @@ mx6q-flavorlist = mx6qsabrelite mx6qsabresd mx6d-flavorlist = mx6dl-flavorlist = mx6dlsabresd mx6s-flavorlist = +mx7-flavorlist = mx7dsabresd ifneq (,$(filter $(PLATFORM_FLAVOR),$(mx6ul-flavorlist))) $(call force,CFG_MX6UL,y) @@ -20,10 +21,19 @@ else ifneq (,$(filter $(PLATFORM_FLAVOR),$(mx6dl-flavorlist))) $(call force,CFG_MX6DL,y) else ifneq (,$(filter $(PLATFORM_FLAVOR),$(mx6s-flavorlist))) $(call force,CFG_MX6S,y) +else ifneq (,$(filter $(PLATFORM_FLAVOR),$(mx7-flavorlist))) +$(call force,CFG_MX7,y) else $(error Unsupported PLATFORM_FLAVOR "$(PLATFORM_FLAVOR)") endif +ifneq (,$(filter $(PLATFORM_FLAVOR),mx7dsabresd)) +CFG_DDR_SIZE ?= 0x40000000 +CFG_DT ?= y +CFG_NS_ENTRY_ADDR ?= 0x80800000 +CFG_PSCI_ARM32 ?= y +CFG_TEE_CORE_NB_CORE ?= 2 +endif # Common i.MX6 config core_arm32-platform-aflags += -mfpu=neon @@ -60,6 +70,11 @@ CFG_BOOT_SYNC_CPU ?= y CFG_BOOT_SECONDARY_REQUEST ?= y endif +ifeq ($(filter y, $(CFG_MX7)), y) +include core/arch/arm/cpu/cortex-a7.mk -ta-targets = ta_arm32 +$(call force,CFG_SECURE_TIME_SOURCE_REE,y) +CFG_BOOT_SECONDARY_REQUEST ?= y +endif +ta-targets = ta_arm32 diff --git a/core/arch/arm/plat-imx/config/config_imx7.h b/core/arch/arm/plat-imx/config/config_imx7.h new file mode 100644 index 00000000000..4066c678c9c --- /dev/null +++ b/core/arch/arm/plat-imx/config/config_imx7.h @@ -0,0 +1,70 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * Peng Fan + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CFG_UART_BASE +#define CFG_UART_BASE (UART1_BASE) +#endif + +#ifndef CFG_DDR_SIZE +#error "CFG_DDR_SIZE not defined" +#endif + +#define DRAM0_BASE 0x80000000 +#define DRAM0_SIZE CFG_DDR_SIZE + +/* Location of trusted dram */ +#define TZDRAM_BASE (DRAM0_BASE + CFG_DDR_SIZE - 32 * 1024 * 1024) +#define TZDRAM_SIZE (30 * 1024 * 1024) + +/* Full GlobalPlatform test suite requires CFG_SHMEM_SIZE to be at least 2MB */ +#define CFG_SHMEM_START (TZDRAM_BASE + TZDRAM_SIZE) +#define CFG_SHMEM_SIZE 0x200000 + +#define CFG_TEE_RAM_VA_SIZE (1024 * 1024) + +/* + * Everything is in TZDRAM. + * +------------------+ + * | | TEE_RAM | + * + TZDRAM +---------+ + * | | TA_RAM | + * +--------+---------+ + */ +#define CFG_TEE_RAM_PH_SIZE CFG_TEE_RAM_VA_SIZE +#define CFG_TEE_RAM_START TZDRAM_BASE +#define CFG_TA_RAM_START ROUNDUP((TZDRAM_BASE + CFG_TEE_RAM_VA_SIZE), \ + CORE_MMU_DEVICE_SIZE) +#define CFG_TA_RAM_SIZE ROUNDDOWN((TZDRAM_SIZE - CFG_TEE_RAM_VA_SIZE), \ + CORE_MMU_DEVICE_SIZE) + +#ifndef CFG_TEE_LOAD_ADDR +#define CFG_TEE_LOAD_ADDR CFG_TEE_RAM_START +#endif + +#define CONSOLE_UART_BASE (CFG_UART_BASE) diff --git a/core/arch/arm/plat-imx/gpcv2.c b/core/arch/arm/plat-imx/gpcv2.c new file mode 100644 index 00000000000..ec3a5303abd --- /dev/null +++ b/core/arch/arm/plat-imx/gpcv2.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2017 NXP + * All rights reserved. + * + * Peng Fan + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +static vaddr_t gpc_base(void) +{ + return core_mmu_get_va(GPC_BASE, MEM_AREA_IO_SEC); +} + +void imx_gpcv2_set_core_pgc(bool enable, uint32_t offset) +{ + uint32_t val = read32(gpc_base() + offset) & (~GPC_PGC_PCG_MASK); + + if (enable) + val |= GPC_PGC_PCG_MASK; + + write32(val, gpc_base() + offset); +} + +void imx_gpcv2_set_core1_pdn_by_software(void) +{ + uint32_t val = read32(gpc_base() + GPC_CPU_PGC_SW_PDN_REQ); + + imx_gpcv2_set_core_pgc(true, GPC_PGC_C1); + + val |= GPC_PGC_SW_PDN_PUP_REQ_CORE1_MASK; + + write32(val, gpc_base() + GPC_CPU_PGC_SW_PDN_REQ); + + while ((read32(gpc_base() + GPC_CPU_PGC_SW_PDN_REQ) & + GPC_PGC_SW_PDN_PUP_REQ_CORE1_MASK) != 0) + ; + + imx_gpcv2_set_core_pgc(false, GPC_PGC_C1); +} + +void imx_gpcv2_set_core1_pup_by_software(void) +{ + uint32_t val = read32(gpc_base() + GPC_CPU_PGC_SW_PUP_REQ); + + imx_gpcv2_set_core_pgc(true, GPC_PGC_C1); + + val |= GPC_PGC_SW_PDN_PUP_REQ_CORE1_MASK; + + write32(val, gpc_base() + GPC_CPU_PGC_SW_PUP_REQ); + + while ((read32(gpc_base() + GPC_CPU_PGC_SW_PUP_REQ) & + GPC_PGC_SW_PDN_PUP_REQ_CORE1_MASK) != 0) + ; + + imx_gpcv2_set_core_pgc(false, GPC_PGC_C1); +} diff --git a/core/arch/arm/plat-imx/imx-common.c b/core/arch/arm/plat-imx/imx-common.c index 953d7d1ab27..3e584e84158 100644 --- a/core/arch/arm/plat-imx/imx-common.c +++ b/core/arch/arm/plat-imx/imx-common.c @@ -35,16 +35,111 @@ #include #include +static uint32_t imx_digproc(void) +{ + static uint32_t reg; + vaddr_t anatop_addr; + + if (!reg) { + anatop_addr = core_mmu_get_va(ANATOP_BASE, MEM_AREA_IO_SEC); + + /* TODO: Handle SL here */ +#ifdef CFG_MX7 + reg = read32(anatop_addr + OFFSET_DIGPROG_IMX7D); +#else + reg = read32(anatop_addr + OFFSET_DIGPROG); +#endif + } + + return reg; +} + +static uint32_t imx_soc_rev_major(void) +{ + return ((imx_digproc() & 0xff00) >> 8) + 1; +} + +uint32_t imx_soc_type(void) +{ + return (imx_digproc() >> 16) & 0xff; +} + +bool soc_is_imx6ul(void) +{ + return imx_soc_type() == SOC_MX6UL; +} + +bool soc_is_imx6ull(void) +{ + return imx_soc_type() == SOC_MX6ULL; +} + +bool soc_is_imx6sdl(void) +{ + return imx_soc_type() == SOC_MX6DL; +} + +bool soc_is_imx6dq(void) +{ + return (imx_soc_type() == SOC_MX6Q) && (imx_soc_rev_major() == 1); +} + +bool soc_is_imx6dqp(void) +{ + return (imx_soc_type() == SOC_MX6Q) && (imx_soc_rev_major() == 2); +} + +bool soc_is_imx7s(void) +{ + vaddr_t addr = core_mmu_get_va(OCOTP_BASE + 0x450, MEM_AREA_IO_SEC); + uint32_t val = read32(addr); + + if (soc_is_imx7ds()) { + if (val & 1) + return true; + else + return false; + } + + return false; +} + +bool soc_is_imx7d(void) +{ + vaddr_t addr = core_mmu_get_va(OCOTP_BASE + 0x450, MEM_AREA_IO_SEC); + uint32_t val = read32(addr); + + if (soc_is_imx7ds()) { + if (val & 1) + return false; + else + return true; + } + + return false; +} + +bool soc_is_imx7ds(void) +{ + return imx_soc_type() == SOC_MX7D; +} + uint32_t imx_get_src_gpr(int cpu) { vaddr_t va = core_mmu_get_va(SRC_BASE, MEM_AREA_IO_SEC); - return read32(va + SRC_GPR1 + cpu * 8 + 4); + if (soc_is_imx7d()) + return read32(va + SRC_GPR1_MX7 + cpu * 8 + 4); + else + return read32(va + SRC_GPR1 + cpu * 8 + 4); } void imx_set_src_gpr(int cpu, uint32_t val) { vaddr_t va = core_mmu_get_va(SRC_BASE, MEM_AREA_IO_SEC); - write32(val, va + SRC_GPR1 + cpu * 8 + 4); + if (soc_is_imx7d()) + write32(val, va + SRC_GPR1_MX7 + cpu * 8 + 4); + else + write32(val, va + SRC_GPR1 + cpu * 8 + 4); } diff --git a/core/arch/arm/plat-imx/imx-regs.h b/core/arch/arm/plat-imx/imx-regs.h index 77a02818464..860c7adf5f1 100644 --- a/core/arch/arm/plat-imx/imx-regs.h +++ b/core/arch/arm/plat-imx/imx-regs.h @@ -132,32 +132,114 @@ #define IOMUXC_GPR10_OCRAM_TZ_ADDR_LOCK_OFFSET_6UL (27) #define IOMUXC_GPR10_OCRAM_TZ_ADDR_LOCK_MASK_6UL GENMASK_32(31, 27) -/* Central Security Unit register values */ -#define CSU_BASE 0x021C0000 -#define CSU_CSL_START 0x0 -#define CSU_CSL_END 0xA0 -#define CSU_CSL5 0x14 -#define CSU_CSL16 0x40 -#define CSU_ACCESS_ALL 0x00FF00FF -#define CSU_SETTING_LOCK 0x01000100 - #if defined(CFG_MX6UL) || defined(CFG_MX6ULL) #define DRAM0_BASE 0x80000000 #else #define DRAM0_BASE 0x10000000 #endif -#define SRC_SCR 0x000 -#define SRC_GPR1 0x020 -#define SRC_SCR_CPU_ENABLE_ALL SHIFT_U32(0x7, 22) -#define SRC_SCR_CORE1_RST_OFFSET 14 -#define SRC_SCR_CORE1_ENABLE_OFFSET 22 +#elif defined(CFG_MX7) +#define GIC_BASE 0x31000000 +#define GIC_SIZE 0x8000 +#define GICC_OFFSET 0x2000 +#define GICD_OFFSET 0x1000 + +#define CAAM_BASE 0x30900000 +#define UART1_BASE 0x30860000 +#define UART2_BASE 0x30890000 +#define UART3_BASE 0x30880000 + +#define AIPS1_BASE 0x30000000 +#define AIPS1_SIZE 0x400000 +#define AIPS2_BASE 0x30400000 +#define AIPS2_SIZE 0x400000 +#define AIPS3_BASE 0x30800000 +#define AIPS3_SIZE 0x400000 + +#define WDOG_BASE 0x30280000 +#define LPSR_BASE 0x30270000 +#define IOMUXC_BASE 0x30330000 +#define IOMUXC_GPR_BASE 0x30340000 +#define OCOTP_BASE 0x30350000 +#define ANATOP_BASE 0x30360000 +#define SNVS_BASE 0x30370000 +#define CCM_BASE 0x30380000 +#define SRC_BASE 0x30390000 +#define GPC_BASE 0x303A0000 +#define TZASC_BASE 0x30780000 +#define DDRC_PHY_BASE 0x30790000 +#define MMDC_P0_BASE 0x307A0000 +#define DDRC_BASE 0x307A0000 +#define IRAM_BASE 0x00900000 +#define IRAM_S_BASE 0x00180000 + +#define CSU_CSL_START 0x303E0000 +#define CSU_CSL_END 0x303E0100 +#define CSU_CSL_59 (0x303E0000 + 59 * 4) +#define CSU_CSL_28 (0x303E0000 + 28 * 4) +#define CSU_CSL_15 (0x303E0000 + 15 * 4) +#define CSU_CSL_12 (0x303E0000 + 12 * 4) +#define CSU_ACCESS_ALL 0x00FF00FF +#define CSU_SETTING_LOCK 0x01000100 + +#define TRUSTZONE_OCRAM_START 0x180000 + +#define IOMUXC_GPR9_OFFSET 0x24 +#define IOMUXC_GPR9_TZASC1_MUX_CONTROL_OFFSET 0 + +#define IOMUXC_GPR11_OFFSET 0x2C +#define IOMUXC_GPR11_OCRAM_S_TZ_ADDR_OFFSET 11 +#define IOMUXC_GPR11_OCRAM_S_TZ_ADDR_MASK GENMASK_32(13, 11) + +#define IOMUXC_GPR11_OCRAM_S_TZ_EN_OFFSET 10 +#define IOMUXC_GPR11_OCRAM_S_TZ_EN_MASK GENMASK_32(10, 10) + +#define IOMUXC_GPR11_OCRAM_S_TZ_EN_LOCK_OFFSET 26 +#define IOMUXC_GPR11_OCRAM_S_TZ_EN_LOCK_MASK GENMASK_32(26, 26) +#define IOMUXC_GPR11_OCRAM_S_TZ_ADDR_LOCK_OFFSET GENMASK_32(29, 27) #else -#error "CFG_MX6 not defined" +#error "CFG_MX6/7 not defined" #endif #define IOMUXC_GPR4_OFFSET 0x10 #define IOMUXC_GPR5_OFFSET 0x14 #define ARM_WFI_STAT_MASK(n) BIT(n) +#define ARM_WFI_STAT_MASK_7D(n) BIT(25 + ((n) & 1)) + +#define SRC_SCR 0x000 +#define SRC_GPR1 0x020 +#define SRC_GPR2 0x024 +#define SRC_SCR_CORE1_RST_OFFSET 14 +#define SRC_SCR_CORE1_ENABLE_OFFSET 22 +#define SRC_SCR_CPU_ENABLE_ALL SHIFT_U32(0x7, 22) + +#define SRC_GPR1_MX7 0x074 +#define SRC_A7RCR0 0x004 +#define SRC_A7RCR1 0x008 +#define SRC_A7RCR0_A7_CORE_RESET0_OFFSET 0 +#define SRC_A7RCR1_A7_CORE1_ENABLE_OFFSET 1 + +#define SNVS_LPCR_OFF 0x38 +#define SNVS_LPCR_TOP_MASK BIT(6) +#define SNVS_LPCR_DP_EN_MASK BIT(5) +#define SNVS_LPCR_SRTC_ENV_MASK 1 + +#define WCR_OFF 0 + +#define OFFSET_DIGPROG 0x260 +#define OFFSET_DIGPROG_IMX6SL 0x280 +#define OFFSET_DIGPROG_IMX7D 0x800 + +/* GPC V2 */ +#define GPC_PGC_C1 0x840 +#define GPC_PGC_C1_PUPSCR 0x844 + +#define GPC_PGC_PCG_MASK BIT(0) + +#define GPC_CPU_PGC_SW_PUP_REQ 0xf0 +#define GPC_PU_PGC_SW_PUP_REQ 0xf8 +#define GPC_CPU_PGC_SW_PDN_REQ 0xfc +#define GPC_PU_PGC_SW_PDN_REQ 0x104 +#define GPC_PGC_SW_PDN_PUP_REQ_CORE1_MASK BIT(1) #endif diff --git a/core/arch/arm/plat-imx/imx.h b/core/arch/arm/plat-imx/imx.h index 144ac1d77e1..953a3b560f8 100644 --- a/core/arch/arm/plat-imx/imx.h +++ b/core/arch/arm/plat-imx/imx.h @@ -30,7 +30,31 @@ #define PLAT_IMX_IMX_H #include +#include + +#define SOC_MX6SL 0x60 +#define SOC_MX6DL 0x61 +#define SOC_MX6SX 0x62 +#define SOC_MX6Q 0x63 +#define SOC_MX6UL 0x64 +#define SOC_MX6ULL 0x65 +#define SOC_MX6SLL 0x67 +#define SOC_MX6D 0x6A +#define SOC_MX7D 0x72 uint32_t imx_get_src_gpr(int cpu); void imx_set_src_gpr(int cpu, uint32_t val); + +bool soc_is_imx6ul(void); +bool soc_is_imx6ull(void); +bool soc_is_imx6sdl(void); +bool soc_is_imx6dq(void); +bool soc_is_imx6dqp(void); +bool soc_is_imx7ds(void); +bool soc_is_imx7d(void); +bool soc_is_imx7s(void); +uint32_t imx_soc_type(void); +void imx_gpcv2_set_core1_pdn_by_software(void); +void imx_gpcv2_set_core1_pup_by_software(void); +void imx_gpcv2_set_core_pgc(bool enable, uint32_t offset); #endif diff --git a/core/arch/arm/plat-imx/imx7.c b/core/arch/arm/plat-imx/imx7.c new file mode 100644 index 00000000000..96132bd3e50 --- /dev/null +++ b/core/arch/arm/plat-imx/imx7.c @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2017 NXP + * All rights reserved. + * + * Peng Fan + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +register_phys_mem(MEM_AREA_IO_SEC, SRC_BASE, CORE_MMU_DEVICE_SIZE); +register_phys_mem(MEM_AREA_IO_SEC, IOMUXC_BASE, CORE_MMU_DEVICE_SIZE); +register_phys_mem(MEM_AREA_IO_SEC, CCM_BASE, CORE_MMU_DEVICE_SIZE); +register_phys_mem(MEM_AREA_IO_SEC, ANATOP_BASE, CORE_MMU_DEVICE_SIZE); +register_phys_mem(MEM_AREA_IO_SEC, GPC_BASE, CORE_MMU_DEVICE_SIZE); +register_phys_mem(MEM_AREA_IO_SEC, DDRC_BASE, CORE_MMU_DEVICE_SIZE); +register_phys_mem(MEM_AREA_IO_SEC, AIPS1_BASE, AIPS1_SIZE); +register_phys_mem(MEM_AREA_IO_SEC, AIPS2_BASE, AIPS2_SIZE); +register_phys_mem(MEM_AREA_IO_SEC, AIPS3_BASE, AIPS3_SIZE); + +void plat_cpu_reset_late(void) +{ + uintptr_t addr; + uint32_t val; + + if (get_core_pos() != 0) + return; + + /* + * Configure imx7 CSU, first grant all peripherals + * TODO: fine tune the permissions + */ + for (addr = CSU_CSL_START; addr != CSU_CSL_END; addr += 4) + write32(CSU_ACCESS_ALL, core_mmu_get_va(addr, MEM_AREA_IO_SEC)); + + dsb(); + /* Protect OCRAM_S */ + write32(0x003300FF, core_mmu_get_va(CSU_CSL_59, MEM_AREA_IO_SEC)); + /* Proect TZASC */ + write32(0x00FF0033, core_mmu_get_va(CSU_CSL_28, MEM_AREA_IO_SEC)); + /* + * Proect CSU + * Note: Ater this settings, CSU seems still can be read, + * in non-secure world but can not be written. + */ + write32(0x00FF0033, core_mmu_get_va(CSU_CSL_15, MEM_AREA_IO_SEC)); + /* + * Proect SRC + * write32(0x003300FF, get_base(CSU_CSL_12, MEM_AREA_IO_SEC)); + */ + dsb(); + + /* lock the settings */ + for (addr = CSU_CSL_START; addr != CSU_CSL_END; addr += 4) { + val = read32(core_mmu_get_va(addr, MEM_AREA_IO_SEC)); + write32(val | CSU_SETTING_LOCK, + core_mmu_get_va(addr, MEM_AREA_IO_SEC)); + } +} diff --git a/core/arch/arm/plat-imx/main.c b/core/arch/arm/plat-imx/main.c index f02ba47e995..ea43d4b3727 100644 --- a/core/arch/arm/plat-imx/main.c +++ b/core/arch/arm/plat-imx/main.c @@ -64,6 +64,7 @@ static struct imx_uart_data console_data; register_phys_mem(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, CORE_MMU_DEVICE_SIZE); register_phys_mem(MEM_AREA_IO_SEC, GIC_BASE, CORE_MMU_DEVICE_SIZE); +register_phys_mem(MEM_AREA_IO_SEC, ANATOP_BASE, CORE_MMU_DEVICE_SIZE); const struct thread_handlers *generic_boot_get_handlers(void) { @@ -97,7 +98,8 @@ void main_init_gic(void) itr_init(&gic_data.chip); } -#if defined(CFG_MX6Q) || defined(CFG_MX6D) || defined(CFG_MX6DL) +#if defined(CFG_MX6Q) || defined(CFG_MX6D) || defined(CFG_MX6DL) || \ + defined(CFG_MX7) void main_secondary_init_gic(void) { gic_cpu_init(&gic_data); diff --git a/core/arch/arm/plat-imx/platform_config.h b/core/arch/arm/plat-imx/platform_config.h index 4a71b42f13c..28c5ff8f475 100644 --- a/core/arch/arm/plat-imx/platform_config.h +++ b/core/arch/arm/plat-imx/platform_config.h @@ -30,11 +30,16 @@ #ifndef PLATFORM_CONFIG_H #define PLATFORM_CONFIG_H +#include + #define STACK_ALIGNMENT 64 -/* For i.MX 6UltraLite and 6ULL EVK board */ +/* For i.MX7D/S platforms */ +#if defined(CFG_MX7) +#include -#if defined(CFG_MX6UL) || defined(CFG_MX6ULL) +/* For i.MX 6UltraLite and 6ULL EVK board */ +#elif defined(CFG_MX6UL) || defined(CFG_MX6ULL) #include #ifdef CFG_WITH_PAGER diff --git a/core/arch/arm/plat-imx/psci.c b/core/arch/arm/plat-imx/psci.c index a0a70e0ba07..3f182d2a7db 100644 --- a/core/arch/arm/plat-imx/psci.c +++ b/core/arch/arm/plat-imx/psci.c @@ -60,6 +60,21 @@ int psci_cpu_on(uint32_t core_idx, uint32_t entry, /* set secondary cores' NS entry addresses */ ns_entry_addrs[core_idx] = entry; + if (soc_is_imx7ds()) { + write32((uint32_t)CFG_TEE_LOAD_ADDR, + va + SRC_GPR1_MX7 + core_idx * 8); + + imx_gpcv2_set_core1_pup_by_software(); + + /* release secondary core */ + val = read32(va + SRC_A7RCR1); + val |= BIT32(SRC_A7RCR1_A7_CORE1_ENABLE_OFFSET + + (core_idx - 1)); + write32(val, va + SRC_A7RCR1); + + return PSCI_RET_SUCCESS; + } + /* boot secondary cores from OP-TEE load address */ write32((uint32_t)CFG_TEE_LOAD_ADDR, va + SRC_GPR1 + core_idx * 8); @@ -103,7 +118,10 @@ int psci_affinity_info(uint32_t affinity, cpu = affinity; - wfi = read32(gpr5) & ARM_WFI_STAT_MASK(cpu); + if (soc_is_imx7d()) + wfi = true; + else + wfi = read32(gpr5) & ARM_WFI_STAT_MASK(cpu); if ((imx_get_src_gpr(cpu) == 0) || !wfi) return PSCI_AFFINITY_LEVEL_ON; @@ -113,14 +131,23 @@ int psci_affinity_info(uint32_t affinity, * Wait secondary cpus ready to be killed * TODO: Change to non dead loop */ - while (read32(va + SRC_GPR1 + cpu * 8 + 4) != UINT32_MAX) - ; - - /* Kill cpu */ - val = read32(va + SRC_SCR); - val &= ~BIT32(SRC_SCR_CORE1_ENABLE_OFFSET + cpu - 1); - val |= BIT32(SRC_SCR_CORE1_RST_OFFSET + cpu - 1); - write32(val, va + SRC_SCR); + if (soc_is_imx7d()) { + while (read32(va + SRC_GPR1_MX7 + cpu * 8 + 4) != UINT_MAX) + ; + + val = read32(va + SRC_A7RCR1); + val &= ~BIT32(SRC_A7RCR1_A7_CORE1_ENABLE_OFFSET + (cpu - 1)); + write32(val, va + SRC_A7RCR1); + } else { + while (read32(va + SRC_GPR1 + cpu * 8 + 4) != UINT32_MAX) + ; + + /* Kill cpu */ + val = read32(va + SRC_SCR); + val &= ~BIT32(SRC_SCR_CORE1_ENABLE_OFFSET + cpu - 1); + val |= BIT32(SRC_SCR_CORE1_RST_OFFSET + cpu - 1); + write32(val, va + SRC_SCR); + } /* Clean arg */ imx_set_src_gpr(cpu, 0); diff --git a/core/arch/arm/plat-imx/sub.mk b/core/arch/arm/plat-imx/sub.mk index e42213caad9..90df1233e47 100644 --- a/core/arch/arm/plat-imx/sub.mk +++ b/core/arch/arm/plat-imx/sub.mk @@ -2,7 +2,7 @@ global-incdirs-y += . srcs-y += main.c imx-common.c srcs-$(CFG_PL310) += imx_pl310.c -srcs-$(CFG_PSCI_ARM32) += psci.c +srcs-$(CFG_PSCI_ARM32) += psci.c gpcv2.c cflags-psci.c-y += -Wno-suggest-attribute=noreturn ifneq (,$(filter y, $(CFG_MX6Q) $(CFG_MX6D) $(CFG_MX6DL))) @@ -13,3 +13,5 @@ ifneq (,$(filter y, $(CFG_MX6UL) $(CFG_MX6ULL))) srcs-y += a7_plat_init.S srcs-y += imx6ul.c endif + +srcs-$(CFG_MX7) += imx7.c a7_plat_init.S