diff options
Diffstat (limited to 'plat/imx/imx8m')
24 files changed, 1906 insertions, 91 deletions
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c index eb2801cea..1e55f058d 100644 --- a/plat/imx/imx8m/gpc_common.c +++ b/plat/imx/imx8m/gpc_common.c @@ -16,7 +16,9 @@ #include <imx8m_psci.h> #include <plat_imx8.h> -static uint32_t gpc_imr_offset[] = { 0x30, 0x40, 0x1c0, 0x1d0, }; +static uint32_t gpc_imr_offset[] = { IMR1_CORE0_A53, IMR1_CORE1_A53, IMR1_CORE2_A53, IMR1_CORE3_A53, }; + +DEFINE_BAKERY_LOCK(gpc_lock); #pragma weak imx_set_cpu_pwr_off #pragma weak imx_set_cpu_pwr_on @@ -38,16 +40,27 @@ void imx_set_cpu_secure_entry(unsigned int core_id, uintptr_t sec_entrypoint) void imx_set_cpu_pwr_off(unsigned int core_id) { + + bakery_lock_get(&gpc_lock); + /* enable the wfi power down of the core */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id)); + + bakery_lock_release(&gpc_lock); + /* assert the pcg pcr bit of the core */ mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); } void imx_set_cpu_pwr_on(unsigned int core_id) { + bakery_lock_get(&gpc_lock); + /* clear the wfi power down bit of the core */ mmio_clrbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id)); + + bakery_lock_release(&gpc_lock); + /* assert the ncpuporeset */ mmio_clrbits_32(IMX_SRC_BASE + SRC_A53RCR1, (1 << core_id)); /* assert the pcg pcr bit of the core */ @@ -67,6 +80,8 @@ void imx_set_cpu_pwr_on(unsigned int core_id) void imx_set_cpu_lpm(unsigned int core_id, bool pdn) { + bakery_lock_get(&gpc_lock); + if (pdn) { /* enable the core WFI PDN & IRQ PUP */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) | @@ -80,6 +95,8 @@ void imx_set_cpu_lpm(unsigned int core_id, bool pdn) /* deassert the pcg pcr bit of the core */ mmio_clrbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); } + + bakery_lock_release(&gpc_lock); } /* @@ -133,14 +150,12 @@ void imx_set_cluster_powerdown(unsigned int last_core, uint8_t power_state) val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_AD); val &= ~EN_L2_WFI_PDN; /* L2 cache memory is on in WAIT mode */ - if (is_local_state_off(power_state)) + if (is_local_state_off(power_state)) { val |= (L2PGE | EN_PLAT_PDN); - else - val |= EN_PLAT_PDN; + imx_a53_plat_slot_config(true); + } mmio_write_32(IMX_GPC_BASE + LPCR_A53_AD, val); - - imx_a53_plat_slot_config(true); } else { /* clear the slot and ack for cluster power down */ imx_a53_plat_slot_config(false); diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c index d6416288e..dbb772dc1 100644 --- a/plat/imx/imx8m/imx8m_psci_common.c +++ b/plat/imx/imx8m/imx8m_psci_common.c @@ -192,7 +192,7 @@ void __dead2 imx_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) * drived by the 32K OSC, so delay 30us to make sure the counter * is really running. */ - if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) { + if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) { imx_set_rbc_count(); udelay(30); } diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c index 4c5f4f0d1..40110d778 100644 --- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c +++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c @@ -97,7 +97,7 @@ void bl31_tzc380_setup(void) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - static console_uart_t console; + static console_t console; int i; /* Enable CSU NS access permission */ @@ -114,7 +114,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, IMX_CONSOLE_BAUDRATE, &console); /* This console is only used for boot stage */ - console_set_scope(&console.console, CONSOLE_FLAG_BOOT); + console_set_scope(&console, CONSOLE_FLAG_BOOT); /* * tell BL3-1 where the non-secure software image is located diff --git a/plat/imx/imx8m/imx8mm/include/gpc_reg.h b/plat/imx/imx8m/imx8mm/include/gpc_reg.h new file mode 100644 index 000000000..1a4eae546 --- /dev/null +++ b/plat/imx/imx8m/imx8mm/include/gpc_reg.h @@ -0,0 +1,129 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPC_REG_H +#define GPC_REG_H + +#define LPCR_A53_BSC 0x0 +#define LPCR_A53_BSC2 0x108 +#define LPCR_A53_AD 0x4 +#define LPCR_M4 0x8 +#define SLPCR 0x14 +#define MST_CPU_MAPPING 0x18 +#define MLPCR 0x20 +#define PGC_ACK_SEL_A53 0x24 +#define IMR1_CORE0_A53 0x30 +#define IMR1_CORE1_A53 0x40 +#define IMR1_CORE2_A53 0x1C0 +#define IMR1_CORE3_A53 0x1D0 +#define IMR1_CORE0_M4 0x50 +#define SLT0_CFG 0xB0 +#define GPC_PU_PWRHSK 0x1FC +#define PGC_CPU_0_1_MAPPING 0xEC +#define CPU_PGC_UP_TRG 0xF0 +#define PU_PGC_UP_TRG 0xF8 +#define CPU_PGC_DN_TRG 0xFC +#define PU_PGC_DN_TRG 0x104 +#define LPS_CPU1 0x114 +#define A53_CORE0_PGC 0x800 +#define A53_PLAT_PGC 0x900 +#define PLAT_PGC_PCR 0x900 +#define NOC_PGC_PCR 0xa40 +#define PGC_SCU_TIMING 0x910 + +#define MASK_DSM_TRIGGER_A53 BIT(31) +#define IRQ_SRC_A53_WUP BIT(30) +#define IRQ_SRC_A53_WUP_SHIFT 30 +#define IRQ_SRC_C1 BIT(29) +#define IRQ_SRC_C0 BIT(28) +#define IRQ_SRC_C3 BIT(23) +#define IRQ_SRC_C2 BIT(22) +#define CPU_CLOCK_ON_LPM BIT(14) +#define A53_CLK_ON_LPM BIT(14) +#define MASTER0_LPM_HSK BIT(6) +#define MASTER1_LPM_HSK BIT(7) +#define MASTER2_LPM_HSK BIT(8) + +#define L2PGE BIT(31) +#define EN_L2_WFI_PDN BIT(5) +#define EN_PLAT_PDN BIT(4) + +#define SLPCR_EN_DSM BIT(31) +#define SLPCR_RBC_EN BIT(30) +#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17) +#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16) +#define SLPCR_VSTBY BIT(2) +#define SLPCR_SBYOS BIT(1) +#define SLPCR_BYPASS_PMIC_READY BIT(0) +#define SLPCR_RBC_COUNT_SHIFT 24 +#define SLPCR_STBY_COUNT_SHFT 3 + +#define A53_DUMMY_PDN_ACK BIT(15) +#define A53_DUMMY_PUP_ACK BIT(31) +#define A53_PLAT_PDN_ACK BIT(2) +#define A53_PLAT_PUP_ACK BIT(18) +#define NOC_PDN_SLT_CTRL BIT(10) +#define NOC_PUP_SLT_CTRL BIT(11) +#define NOC_PGC_PDN_ACK BIT(3) +#define NOC_PGC_PUP_ACK BIT(19) + +#define PLAT_PUP_SLT_CTRL BIT(9) +#define PLAT_PDN_SLT_CTRL BIT(8) + +#define SLT_PLAT_PDN BIT(8) +#define SLT_PLAT_PUP BIT(9) + +#define MASTER1_MAPPING BIT(1) +#define MASTER2_MAPPING BIT(2) + +#define MIPI_PWR_REQ BIT(0) +#define PCIE_PWR_REQ BIT(1) +#define OTG1_PWR_REQ BIT(2) +#define OTG2_PWR_REQ BIT(3) +#define HSIOMIX_PWR_REQ BIT(4) +#define DDRMIX_PWR_REQ BIT(5) +#define GPU2D_PWR_REQ BIT(6) +#define GPUMIX_PWR_REQ BIT(7) +#define VPUMIX_PWR_REQ BIT(8) +#define GPU3D_PWR_REQ BIT(9) +#define DISPMIX_PWR_REQ BIT(10) +#define VPU_G1_PWR_REQ BIT(11) +#define VPU_G2_PWR_REQ BIT(12) +#define VPU_H1_PWR_REQ BIT(13) + +#define DDRMIX_ADB400_SYNC BIT(2) +#define HSIOMIX_ADB400_SYNC (0x3 << 5) +#define DISPMIX_ADB400_SYNC BIT(7) +#define VPUMIX_ADB400_SYNC BIT(8) +#define GPU3D_ADB400_SYNC BIT(9) +#define GPU2D_ADB400_SYNC BIT(10) +#define GPUMIX_ADB400_SYNC BIT(11) +#define DDRMIX_ADB400_ACK BIT(20) +#define HSIOMIX_ADB400_ACK (0x3 << 23) +#define DISPMIX_ADB400_ACK BIT(25) +#define VPUMIX_ADB400_ACK BIT(26) +#define GPU3D_ADB400_ACK BIT(27) +#define GPU2D_ADB400_ACK BIT(28) +#define GPUMIX_ADB400_ACK BIT(29) + +#define MIPI_PGC 0xc00 +#define PCIE_PGC 0xc40 +#define OTG1_PGC 0xc80 +#define OTG2_PGC 0xcc0 +#define HSIOMIX_PGC 0xd00 +#define DDRMIX_PGC 0xd40 +#define GPU2D_PGC 0xd80 +#define GPUMIX_PGC 0xdc0 +#define VPUMIX_PGC 0xe00 +#define GPU3D_PGC 0xe40 +#define DISPMIX_PGC 0xe80 +#define VPU_G1_PGC 0xec0 +#define VPU_G2_PGC 0xf00 +#define VPU_H1_PGC 0xf40 + +#define IRQ_IMR_NUM U(4) + +#endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h index 56caab7ce..1041459c8 100644 --- a/plat/imx/imx8m/imx8mm/include/platform_def.h +++ b/plat/imx/imx8m/imx8mm/include/platform_def.h @@ -29,6 +29,11 @@ #define PLAT_WAIT_RET_STATE U(1) #define PLAT_STOP_OFF_STATE U(3) +#define PLAT_PRI_BITS U(3) +#define PLAT_SDEI_CRITICAL_PRI 0x10 +#define PLAT_SDEI_NORMAL_PRI 0x20 +#define PLAT_SDEI_SGI_PRIVATE U(9) + #define BL31_BASE U(0x920000) #define BL31_LIMIT U(0x940000) @@ -47,7 +52,6 @@ #define HAB_RVT_BASE U(0x00000900) /* HAB_RVT for i.MX8MM */ -#define IMX_BOOT_UART_BASE U(0x30890000) #define IMX_BOOT_UART_CLK_IN_HZ 24000000 /* Select 24MHz oscillator */ #define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk index c0cb6c2a5..ac636fa8f 100644 --- a/plat/imx/imx8m/imx8mm/platform.mk +++ b/plat/imx/imx8m/imx8mm/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,11 +8,10 @@ PLAT_INCLUDES := -Iplat/imx/common/include \ -Iplat/imx/imx8m/include \ -Iplat/imx/imx8m/imx8mm/include -IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/arm_gicv3_common.c \ - drivers/arm/gic/v3/gic500.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/common/gic_common.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +IMX_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/common/plat_psci_common.c \ plat/imx/common/plat_imx8_gic.c @@ -30,6 +29,8 @@ BL31_SOURCES += plat/imx/common/imx8_helpers.S \ plat/imx/common/imx_sip_handler.c \ plat/imx/common/imx_sip_svc.c \ plat/imx/common/imx_uart_console.S \ + plat/imx/common/imx_ehf.c \ + plat/imx/common/imx_sdei.c \ lib/xlat_tables/aarch64/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ lib/cpus/aarch64/cortex_a53.S \ @@ -51,3 +52,9 @@ $(eval $(call add_define,BL32_BASE)) BL32_SIZE ?= 0x2000000 $(eval $(call add_define,BL32_SIZE)) + +IMX_BOOT_UART_BASE ?= 0x30890000 +$(eval $(call add_define,IMX_BOOT_UART_BASE)) + +EL3_EXCEPTION_HANDLING := 1 +SDEI_SUPPORT := 1 diff --git a/plat/imx/imx8m/imx8mn/gpc.c b/plat/imx/imx8m/imx8mn/gpc.c new file mode 100644 index 000000000..37d4226a6 --- /dev/null +++ b/plat/imx/imx8m/imx8mn/gpc.c @@ -0,0 +1,94 @@ +/* + * Copyright 2019-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> +#include <lib/psci/psci.h> +#include <lib/smccc.h> +#include <services/std_svc.h> + +#include <gpc.h> +#include <imx_sip_svc.h> +#include <platform_def.h> + +#define CCGR(x) (0x4000 + (x) * 0x10) + +void imx_gpc_init(void) +{ + unsigned int val; + int i; + + /* mask all the wakeup irq by default */ + for (i = 0; i < 4; i++) { + mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0); + } + + val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC); + /* use GIC wake_request to wakeup C0~C3 from LPM */ + val |= CORE_WKUP_FROM_GIC; + /* clear the MASTER0 LPM handshake */ + val &= ~MASTER0_LPM_HSK; + mmio_write_32(IMX_GPC_BASE + LPCR_A53_BSC, val); + + /* clear MASTER1 & MASTER2 mapping in CPU0(A53) */ + mmio_clrbits_32(IMX_GPC_BASE + MST_CPU_MAPPING, (MASTER1_MAPPING | + MASTER2_MAPPING)); + + /* set all mix/PU in A53 domain */ + mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0xffff); + + /* + * Set the CORE & SCU power up timing: + * SW = 0x1, SW2ISO = 0x1; + * the CPU CORE and SCU power up timming counter + * is drived by 32K OSC, each domain's power up + * latency is (SW + SW2ISO) / 32768 + */ + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(0) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING, + (0x59 << TMC_TMR_SHIFT) | 0x5B | (0x2 << TRC1_TMC_SHIFT)); + + /* set DUMMY PDN/PUP ACK by default for A53 domain */ + mmio_write_32(IMX_GPC_BASE + PGC_ACK_SEL_A53, + A53_DUMMY_PUP_ACK | A53_DUMMY_PDN_ACK); + + /* clear DSM by default */ + val = mmio_read_32(IMX_GPC_BASE + SLPCR); + val &= ~SLPCR_EN_DSM; + /* enable the fast wakeup wait mode */ + val |= SLPCR_A53_FASTWUP_WAIT_MODE; + /* clear the RBC */ + val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT); + /* set the STBY_COUNT to 0x5, (128 * 30)us */ + val &= ~(0x7 << SLPCR_STBY_COUNT_SHFT); + val |= (0x5 << SLPCR_STBY_COUNT_SHFT); + mmio_write_32(IMX_GPC_BASE + SLPCR, val); + + /* + * USB PHY power up needs to make sure RESET bit in SRC is clear, + * otherwise, the PU power up bit in GPC will NOT self-cleared. + * only need to do it once. + */ + mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1); + + /* enable all the power domain by default */ + for (i = 0; i < 103; i++) + mmio_write_32(IMX_CCM_BASE + CCGR(i), 0x3); + mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x485); +} diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c new file mode 100644 index 000000000..d4705eeeb --- /dev/null +++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c @@ -0,0 +1,186 @@ +/* + * Copyright 2019-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stdbool.h> + +#include <arch_helpers.h> +#include <common/bl_common.h> +#include <common/debug.h> +#include <context.h> +#include <drivers/arm/tzc380.h> +#include <drivers/console.h> +#include <drivers/generic_delay_timer.h> +#include <lib/el3_runtime/context_mgmt.h> +#include <lib/mmio.h> +#include <lib/xlat_tables/xlat_tables_v2.h> +#include <plat/common/platform.h> + +#include <gpc.h> +#include <imx_aipstz.h> +#include <imx_uart.h> +#include <imx_rdc.h> +#include <imx8m_caam.h> +#include <platform_def.h> +#include <plat_imx8.h> + +static const mmap_region_t imx_mmap[] = { + GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP, {0}, +}; + +static const struct aipstz_cfg aipstz[] = { + {IMX_AIPSTZ1, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {IMX_AIPSTZ2, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {IMX_AIPSTZ3, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {IMX_AIPSTZ4, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {0}, +}; + +static const struct imx_rdc_cfg rdc[] = { + /* Master domain assignment */ + RDC_MDAn(0x1, DID1), + + /* peripherals domain permission */ + + /* memory region */ + RDC_MEM_REGIONn(16, 0x0, 0x0, 0xff), + RDC_MEM_REGIONn(17, 0x0, 0x0, 0xff), + RDC_MEM_REGIONn(18, 0x0, 0x0, 0xff), + + /* Sentinel */ + {0}, +}; + +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +/* get SPSR for BL33 entry */ +static uint32_t get_spsr_for_bl33_entry(void) +{ + unsigned long el_status; + unsigned long mode; + uint32_t spsr; + + /* figure out what mode we enter the non-secure world */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + mode = (el_status) ? MODE_EL2 : MODE_EL1; + + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + return spsr; +} + +static void bl31_tzc380_setup(void) +{ + unsigned int val; + + val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x28); + if ((val & GPR_TZASC_EN) != GPR_TZASC_EN) + return; + + tzc380_init(IMX_TZASC_BASE); + + /* + * Need to substact offset 0x40000000 from CPU address when + * programming tzasc region for i.mx8mn. + */ + + /* Enable 1G-5G S/NS RW */ + tzc380_configure_region(0, 0x00000000, TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_4G) | + TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_ALL); +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + static console_t console; + int i; + + /* Enable CSU NS access permission */ + for (i = 0; i < 64; i++) { + mmio_write_32(IMX_CSU_BASE + i * 4, 0x00ff00ff); + } + + imx_aipstz_init(aipstz); + + imx_rdc_init(rdc); + + imx8m_caam_init(); + + console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, + IMX_CONSOLE_BAUDRATE, &console); + /* This console is only used for boot stage */ + console_set_scope(&console, CONSOLE_FLAG_BOOT); + + /* + * tell BL3-1 where the non-secure software image is located + * and the entry state information. + */ + bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET; + bl33_image_ep_info.spsr = get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + +#ifdef SPD_opteed + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = 0; + + /* Pass TEE base and size to bl33 */ + bl33_image_ep_info.args.arg1 = BL32_BASE; + bl33_image_ep_info.args.arg2 = BL32_SIZE; +#endif + + bl31_tzc380_setup(); +} + +void bl31_plat_arch_setup(void) +{ + mmap_add_region(BL31_BASE, BL31_BASE, (BL31_LIMIT - BL31_BASE), + MT_MEMORY | MT_RW | MT_SECURE); + mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, (BL_CODE_END - BL_CODE_BASE), + MT_MEMORY | MT_RO | MT_SECURE); +#if USE_COHERENT_MEM + mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE, + (BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE), + MT_DEVICE | MT_RW | MT_SECURE); +#endif + mmap_add(imx_mmap); + + init_xlat_tables(); + + enable_mmu_el3(0); +} + +void bl31_platform_setup(void) +{ + generic_delay_timer_init(); + + /* select the CKIL source to 32K OSC */ + mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1); + + plat_gic_driver_init(); + plat_gic_init(); + + imx_gpc_init(); +} + +entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type) +{ + if (type == NON_SECURE) + return &bl33_image_ep_info; + if (type == SECURE) + return &bl32_image_ep_info; + + return NULL; +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return COUNTER_FREQUENCY; +} diff --git a/plat/imx/imx8m/imx8mn/imx8mn_psci.c b/plat/imx/imx8m/imx8mn/imx8mn_psci.c new file mode 100644 index 000000000..f541fc138 --- /dev/null +++ b/plat/imx/imx8m/imx8mn/imx8mn_psci.c @@ -0,0 +1,44 @@ +/* + * Copyright 2019-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdbool.h> + +#include <arch.h> +#include <arch_helpers.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <lib/psci/psci.h> + +#include <gpc.h> +#include <imx8m_psci.h> +#include <plat_imx8.h> + +static const plat_psci_ops_t imx_plat_psci_ops = { + .pwr_domain_on = imx_pwr_domain_on, + .pwr_domain_on_finish = imx_pwr_domain_on_finish, + .pwr_domain_off = imx_pwr_domain_off, + .validate_ns_entrypoint = imx_validate_ns_entrypoint, + .validate_power_state = imx_validate_power_state, + .cpu_standby = imx_cpu_standby, + .pwr_domain_suspend = imx_domain_suspend, + .pwr_domain_suspend_finish = imx_domain_suspend_finish, + .pwr_domain_pwr_down_wfi = imx_pwr_domain_pwr_down_wfi, + .get_sys_suspend_power_state = imx_get_sys_suspend_power_state, + .system_reset = imx_system_reset, + .system_off = imx_system_off, +}; + +/* export the platform specific psci ops */ +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + /* sec_entrypoint is used for warm reset */ + imx_mailbox_init(sec_entrypoint); + + *psci_ops = &imx_plat_psci_ops; + + return 0; +} diff --git a/plat/imx/imx8m/imx8mn/include/gpc_reg.h b/plat/imx/imx8m/imx8mn/include/gpc_reg.h new file mode 100644 index 000000000..8a8136814 --- /dev/null +++ b/plat/imx/imx8m/imx8mn/include/gpc_reg.h @@ -0,0 +1,111 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPC_REG_H +#define GPC_REG_H + +#define LPCR_A53_BSC 0x0 +#define LPCR_A53_BSC2 0x108 +#define LPCR_A53_AD 0x4 +#define LPCR_M4 0x8 +#define SLPCR 0x14 +#define MST_CPU_MAPPING 0x18 +#define MLPCR 0x20 +#define PGC_ACK_SEL_A53 0x24 +#define IMR1_CORE0_A53 0x30 +#define IMR1_CORE1_A53 0x40 +#define IMR1_CORE2_A53 0x1C0 +#define IMR1_CORE3_A53 0x1D0 +#define IMR1_CORE0_M4 0x50 +#define SLT0_CFG 0xB0 +#define GPC_PU_PWRHSK 0x1FC +#define PGC_CPU_0_1_MAPPING 0xEC +#define CPU_PGC_UP_TRG 0xF0 +#define PU_PGC_UP_TRG 0xF8 +#define CPU_PGC_DN_TRG 0xFC +#define PU_PGC_DN_TRG 0x104 +#define LPS_CPU1 0x114 +#define A53_CORE0_PGC 0x800 +#define A53_PLAT_PGC 0x900 +#define PLAT_PGC_PCR 0x900 +#define NOC_PGC_PCR 0xa40 +#define PGC_SCU_TIMING 0x910 + +#define MASK_DSM_TRIGGER_A53 BIT(31) +#define IRQ_SRC_A53_WUP BIT(30) +#define IRQ_SRC_A53_WUP_SHIFT 30 +#define IRQ_SRC_C1 BIT(29) +#define IRQ_SRC_C0 BIT(28) +#define IRQ_SRC_C3 BIT(23) +#define IRQ_SRC_C2 BIT(22) +#define CPU_CLOCK_ON_LPM BIT(14) +#define A53_CLK_ON_LPM BIT(14) +#define MASTER0_LPM_HSK BIT(6) +#define MASTER1_LPM_HSK BIT(7) +#define MASTER2_LPM_HSK BIT(8) + +#define L2PGE BIT(31) +#define EN_L2_WFI_PDN BIT(5) +#define EN_PLAT_PDN BIT(4) + +#define SLPCR_EN_DSM BIT(31) +#define SLPCR_RBC_EN BIT(30) +#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17) +#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16) +#define SLPCR_VSTBY BIT(2) +#define SLPCR_SBYOS BIT(1) +#define SLPCR_BYPASS_PMIC_READY BIT(0) +#define SLPCR_RBC_COUNT_SHIFT 24 +#define SLPCR_STBY_COUNT_SHFT 3 + +#define A53_DUMMY_PDN_ACK BIT(15) +#define A53_DUMMY_PUP_ACK BIT(31) +#define A53_PLAT_PDN_ACK BIT(2) +#define A53_PLAT_PUP_ACK BIT(18) +#define NOC_PDN_SLT_CTRL BIT(10) +#define NOC_PUP_SLT_CTRL BIT(11) +#define NOC_PGC_PDN_ACK BIT(3) +#define NOC_PGC_PUP_ACK BIT(19) + +#define PLAT_PUP_SLT_CTRL BIT(9) +#define PLAT_PDN_SLT_CTRL BIT(8) + +#define SLT_PLAT_PDN BIT(8) +#define SLT_PLAT_PUP BIT(9) + +#define MASTER1_MAPPING BIT(1) +#define MASTER2_MAPPING BIT(2) + +#define TMR_TCD2_SHIFT 0 +#define TMC_TMR_SHIFT 10 +#define TRC1_TMC_SHIFT 20 + +#define MIPI_PWR_REQ BIT(0) +#define OTG1_PWR_REQ BIT(2) +#define HSIOMIX_PWR_REQ BIT(4) +#define DDRMIX_PWR_REQ BIT(5) +#define GPUMIX_PWR_REQ BIT(7) +#define DISPMIX_PWR_REQ BIT(10) + +#define DDRMIX_ADB400_SYNC BIT(2) +#define HSIOMIX_ADB400_SYNC BIT(5) +#define DISPMIX_ADB400_SYNC BIT(7) +#define GPUMIX_ADB400_SYNC (0x5 << 9) +#define DDRMIX_ADB400_ACK BIT(20) +#define HSIOMIX_ADB400_ACK BIT(23) +#define DISPMIX_ADB400_ACK BIT(25) +#define GPUMIX_ADB400_ACK (0x5 << 27) + +#define MIPI_PGC 0xc00 +#define OTG1_PGC 0xc80 +#define HSIOMIX_PGC 0xd00 +#define DDRMIX_PGC 0xd40 +#define GPUMIX_PGC 0xdc0 +#define DISPMIX_PGC 0xe80 + +#define IRQ_IMR_NUM U(4) + +#endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h new file mode 100644 index 000000000..2444e662e --- /dev/null +++ b/plat/imx/imx8m/imx8mn/include/platform_def.h @@ -0,0 +1,135 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <lib/utils_def.h> +#include <lib/xlat_tables/xlat_tables_v2.h> + +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +#define PLATFORM_STACK_SIZE 0xB00 +#define CACHE_WRITEBACK_GRANULE 64 + +#define PLAT_PRIMARY_CPU U(0x0) +#define PLATFORM_MAX_CPU_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) + +#define IMX_PWR_LVL0 MPIDR_AFFLVL0 +#define IMX_PWR_LVL1 MPIDR_AFFLVL1 +#define IMX_PWR_LVL2 MPIDR_AFFLVL2 + +#define PWR_DOMAIN_AT_MAX_LVL U(1) +#define PLAT_MAX_PWR_LVL U(2) +#define PLAT_MAX_OFF_STATE U(4) +#define PLAT_MAX_RET_STATE U(2) + +#define PLAT_WAIT_RET_STATE U(1) +#define PLAT_STOP_OFF_STATE U(3) + +#define BL31_BASE U(0x960000) +#define BL31_LIMIT U(0x980000) + +/* non-secure uboot base */ +#define PLAT_NS_IMAGE_OFFSET U(0x40200000) + +/* GICv3 base address */ +#define PLAT_GICD_BASE U(0x38800000) +#define PLAT_GICR_BASE U(0x38880000) + +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) + +#define MAX_XLAT_TABLES 8 +#define MAX_MMAP_REGIONS 16 + +#define HAB_RVT_BASE U(0x00000900) /* HAB_RVT for i.MX8MM */ + +#define IMX_BOOT_UART_CLK_IN_HZ 24000000 /* Select 24MHz oscillator */ +#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE +#define PLAT_CRASH_UART_CLK_IN_HZ 24000000 +#define IMX_CONSOLE_BAUDRATE 115200 + +#define IMX_AIPSTZ1 U(0x301f0000) +#define IMX_AIPSTZ2 U(0x305f0000) +#define IMX_AIPSTZ3 U(0x309f0000) +#define IMX_AIPSTZ4 U(0x32df0000) + +#define IMX_AIPS_BASE U(0x30000000) +#define IMX_AIPS_SIZE U(0xC00000) +#define IMX_GPV_BASE U(0x32000000) +#define IMX_GPV_SIZE U(0x800000) +#define IMX_AIPS1_BASE U(0x30200000) +#define IMX_AIPS4_BASE U(0x32c00000) +#define IMX_ANAMIX_BASE U(0x30360000) +#define IMX_CCM_BASE U(0x30380000) +#define IMX_SRC_BASE U(0x30390000) +#define IMX_GPC_BASE U(0x303a0000) +#define IMX_RDC_BASE U(0x303d0000) +#define IMX_CSU_BASE U(0x303e0000) +#define IMX_WDOG_BASE U(0x30280000) +#define IMX_SNVS_BASE U(0x30370000) +#define IMX_NOC_BASE U(0x32700000) +#define IMX_TZASC_BASE U(0x32F80000) +#define IMX_IOMUX_GPR_BASE U(0x30340000) +#define IMX_CAAM_BASE U(0x30900000) +#define IMX_DDRC_BASE U(0x3d400000) +#define IMX_DDRPHY_BASE U(0x3c000000) +#define IMX_DDR_IPS_BASE U(0x3d000000) +#define IMX_DDR_IPS_SIZE U(0x1800000) +#define IMX_ROM_BASE U(0x0) + +#define IMX_GIC_BASE PLAT_GICD_BASE +#define IMX_GIC_SIZE U(0x200000) + +#define WDOG_WSR U(0x2) +#define WDOG_WCR_WDZST BIT(0) +#define WDOG_WCR_WDBG BIT(1) +#define WDOG_WCR_WDE BIT(2) +#define WDOG_WCR_WDT BIT(3) +#define WDOG_WCR_SRS BIT(4) +#define WDOG_WCR_WDA BIT(5) +#define WDOG_WCR_SRE BIT(6) +#define WDOG_WCR_WDW BIT(7) + +#define SRC_A53RCR0 U(0x4) +#define SRC_A53RCR1 U(0x8) +#define SRC_OTG1PHY_SCR U(0x20) +#define SRC_GPR1_OFFSET U(0x74) + +#define SNVS_LPCR U(0x38) +#define SNVS_LPCR_SRTC_ENV BIT(0) +#define SNVS_LPCR_DP_EN BIT(5) +#define SNVS_LPCR_TOP BIT(6) + +#define IOMUXC_GPR10 U(0x28) +#define GPR_TZASC_EN BIT(0) +#define GPR_TZASC_EN_LOCK BIT(16) + +#define ANAMIX_MISC_CTL U(0x124) +#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50) + +#define MAX_CSU_NUM U(64) + +#define OCRAM_S_BASE U(0x00180000) +#define OCRAM_S_SIZE U(0x8000) +#define OCRAM_S_LIMIT (OCRAM_S_BASE + OCRAM_S_SIZE) +#define SAVED_DRAM_TIMING_BASE OCRAM_S_BASE + +#define COUNTER_FREQUENCY 8000000 /* 8MHz */ + +#define IMX_WDOG_B_RESET + +#define GIC_MAP MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW) +#define AIPS_MAP MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW) /* AIPS map */ +#define OCRAM_S_MAP MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_DEVICE | MT_RW) /* OCRAM_S */ +#define DDRC_MAP MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */ + +#endif /* platform_def.h */ diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk new file mode 100644 index 000000000..8c4ad1c21 --- /dev/null +++ b/plat/imx/imx8m/imx8mn/platform.mk @@ -0,0 +1,56 @@ +# +# Copyright 2019-2020 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PLAT_INCLUDES := -Iplat/imx/common/include \ + -Iplat/imx/imx8m/include \ + -Iplat/imx/imx8m/imx8mn/include +# Translation tables library +include lib/xlat_tables_v2/xlat_tables.mk + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +IMX_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/common/plat_psci_common.c \ + plat/imx/common/plat_imx8_gic.c + +BL31_SOURCES += plat/imx/common/imx8_helpers.S \ + plat/imx/imx8m/gpc_common.c \ + plat/imx/imx8m/imx_aipstz.c \ + plat/imx/imx8m/imx_rdc.c \ + plat/imx/imx8m/imx8m_caam.c \ + plat/imx/imx8m/imx8m_psci_common.c \ + plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c \ + plat/imx/imx8m/imx8mn/imx8mn_psci.c \ + plat/imx/imx8m/imx8mn/gpc.c \ + plat/imx/common/imx8_topology.c \ + plat/imx/common/imx_sip_handler.c \ + plat/imx/common/imx_sip_svc.c \ + plat/imx/common/imx_uart_console.S \ + lib/cpus/aarch64/cortex_a53.S \ + drivers/arm/tzc/tzc380.c \ + drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + ${IMX_GIC_SOURCES} \ + ${XLAT_TABLES_LIB_SRCS} + +USE_COHERENT_MEM := 1 +RESET_TO_BL31 := 1 +A53_DISABLE_NON_TEMPORAL_HINT := 0 + +ERRATA_A53_835769 := 1 +ERRATA_A53_843419 := 1 +ERRATA_A53_855873 := 1 + +BL32_BASE ?= 0xbe000000 +$(eval $(call add_define,BL32_BASE)) + +BL32_SIZE ?= 0x2000000 +$(eval $(call add_define,BL32_SIZE)) + +IMX_BOOT_UART_BASE ?= 0x30890000 +$(eval $(call add_define,IMX_BOOT_UART_BASE)) diff --git a/plat/imx/imx8m/imx8mp/gpc.c b/plat/imx/imx8m/imx8mp/gpc.c new file mode 100644 index 000000000..d660e3d88 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/gpc.c @@ -0,0 +1,379 @@ +/* + * Copyright 2019-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> +#include <lib/psci/psci.h> +#include <lib/smccc.h> +#include <services/std_svc.h> + +#include <gpc.h> +#include <imx_aipstz.h> +#include <imx_sip_svc.h> +#include <platform_def.h> + +#define CCGR(x) (0x4000 + (x) * 0x10) +#define IMR_NUM U(5) + +struct imx_noc_setting { + uint32_t domain_id; + uint32_t start; + uint32_t end; + uint32_t prioriy; + uint32_t mode; + uint32_t socket_qos_en; +}; + +enum clk_type { + CCM_ROOT_SLICE, + CCM_CCGR, +}; + +struct clk_setting { + uint32_t offset; + uint32_t val; + enum clk_type type; +}; + +enum pu_domain_id { + /* hsio ss */ + HSIOMIX, + PCIE_PHY, + USB1_PHY, + USB2_PHY, + MLMIX, + AUDIOMIX, + /* gpu ss */ + GPUMIX, + GPU2D, + GPU3D, + /* vpu ss */ + VPUMIX, + VPU_G1, + VPU_G2, + VPU_H1, + /* media ss */ + MEDIAMIX, + MEDIAMIX_ISPDWP, + MIPI_PHY1, + MIPI_PHY2, + /* HDMI ss */ + HDMIMIX, + HDMI_PHY, + DDRMIX, +}; + +/* PU domain, add some hole to minimize the uboot change */ +static struct imx_pwr_domain pu_domains[20] = { + [MIPI_PHY1] = IMX_PD_DOMAIN(MIPI_PHY1, false), + [PCIE_PHY] = IMX_PD_DOMAIN(PCIE_PHY, false), + [USB1_PHY] = IMX_PD_DOMAIN(USB1_PHY, true), + [USB2_PHY] = IMX_PD_DOMAIN(USB2_PHY, true), + [MLMIX] = IMX_MIX_DOMAIN(MLMIX, false), + [AUDIOMIX] = IMX_MIX_DOMAIN(AUDIOMIX, false), + [GPU2D] = IMX_PD_DOMAIN(GPU2D, false), + [GPUMIX] = IMX_MIX_DOMAIN(GPUMIX, false), + [VPUMIX] = IMX_MIX_DOMAIN(VPUMIX, false), + [GPU3D] = IMX_PD_DOMAIN(GPU3D, false), + [MEDIAMIX] = IMX_MIX_DOMAIN(MEDIAMIX, false), + [VPU_G1] = IMX_PD_DOMAIN(VPU_G1, false), + [VPU_G2] = IMX_PD_DOMAIN(VPU_G2, false), + [VPU_H1] = IMX_PD_DOMAIN(VPU_H1, false), + [HDMIMIX] = IMX_MIX_DOMAIN(HDMIMIX, false), + [HDMI_PHY] = IMX_PD_DOMAIN(HDMI_PHY, false), + [MIPI_PHY2] = IMX_PD_DOMAIN(MIPI_PHY2, false), + [HSIOMIX] = IMX_MIX_DOMAIN(HSIOMIX, false), + [MEDIAMIX_ISPDWP] = IMX_PD_DOMAIN(MEDIAMIX_ISPDWP, false), +}; + +static struct imx_noc_setting noc_setting[] = { + {MLMIX, 0x180, 0x180, 0x80000303, 0x0, 0x0}, + {AUDIOMIX, 0x200, 0x200, 0x80000303, 0x0, 0x0}, + {AUDIOMIX, 0x280, 0x480, 0x80000404, 0x0, 0x0}, + {GPUMIX, 0x500, 0x580, 0x80000303, 0x0, 0x0}, + {HDMIMIX, 0x600, 0x680, 0x80000202, 0x0, 0x1}, + {HDMIMIX, 0x700, 0x700, 0x80000505, 0x0, 0x0}, + {HSIOMIX, 0x780, 0x900, 0x80000303, 0x0, 0x0}, + {MEDIAMIX, 0x980, 0xb80, 0x80000202, 0x0, 0x1}, + {MEDIAMIX_ISPDWP, 0xc00, 0xd00, 0x80000505, 0x0, 0x0}, + {VPU_G1, 0xd80, 0xd80, 0x80000303, 0x0, 0x0}, + {VPU_G2, 0xe00, 0xe00, 0x80000303, 0x0, 0x0}, + {VPU_H1, 0xe80, 0xe80, 0x80000303, 0x0, 0x0} +}; + +static struct clk_setting hsiomix_clk[] = { + { 0x8380, 0x0, CCM_ROOT_SLICE }, + { 0x44d0, 0x0, CCM_CCGR }, + { 0x45c0, 0x0, CCM_CCGR }, +}; + +static struct aipstz_cfg aipstz5[] = { + {IMX_AIPSTZ5, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {0}, +}; + +static unsigned int pu_domain_status; + +static void imx_noc_qos(unsigned int domain_id) +{ + unsigned int i; + uint32_t hurry; + + if (domain_id == HDMIMIX) { + mmio_write_32(IMX_HDMI_CTL_BASE + TX_CONTROL1, 0x22018); + mmio_write_32(IMX_HDMI_CTL_BASE + TX_CONTROL1, 0x22010); + + /* set GPR to make lcdif read hurry level 0x7 */ + hurry = mmio_read_32(IMX_HDMI_CTL_BASE + TX_CONTROL0); + hurry |= 0x00077000; + mmio_write_32(IMX_HDMI_CTL_BASE + TX_CONTROL0, hurry); + } + + if (domain_id == MEDIAMIX) { + /* handle mediamix special */ + mmio_write_32(IMX_MEDIAMIX_CTL_BASE + RSTn_CSR, 0x1FFFFFF); + mmio_write_32(IMX_MEDIAMIX_CTL_BASE + CLK_EN_CSR, 0x1FFFFFF); + mmio_write_32(IMX_MEDIAMIX_CTL_BASE + RST_DIV, 0x40030000); + + /* set GPR to make lcdif read hurry level 0x7 */ + hurry = mmio_read_32(IMX_MEDIAMIX_CTL_BASE + LCDIF_ARCACHE_CTRL); + hurry |= 0xfc00; + mmio_write_32(IMX_MEDIAMIX_CTL_BASE + LCDIF_ARCACHE_CTRL, hurry); + /* set GPR to make isi write hurry level 0x7 */ + hurry = mmio_read_32(IMX_MEDIAMIX_CTL_BASE + ISI_CACHE_CTRL); + hurry |= 0x1ff00000; + mmio_write_32(IMX_MEDIAMIX_CTL_BASE + ISI_CACHE_CTRL, hurry); + } + + /* set MIX NoC */ + for (i = 0; i < ARRAY_SIZE(noc_setting); i++) { + if (noc_setting[i].domain_id == domain_id) { + udelay(50); + uint32_t offset = noc_setting[i].start; + + while (offset <= noc_setting[i].end) { + mmio_write_32(IMX_NOC_BASE + offset + 0x8, noc_setting[i].prioriy); + mmio_write_32(IMX_NOC_BASE + offset + 0xc, noc_setting[i].mode); + mmio_write_32(IMX_NOC_BASE + offset + 0x18, noc_setting[i].socket_qos_en); + offset += 0x80; + } + } + } +} + +static void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on) +{ + struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id]; + unsigned int i; + + if (domain_id == HSIOMIX) { + for (i = 0; i < ARRAY_SIZE(hsiomix_clk); i++) { + hsiomix_clk[i].val = mmio_read_32(IMX_CCM_BASE + hsiomix_clk[i].offset); + mmio_setbits_32(IMX_CCM_BASE + hsiomix_clk[i].offset, + hsiomix_clk[i].type == CCM_ROOT_SLICE ? BIT(28) : 0x3); + } + } + + if (on) { + if (pwr_domain->need_sync) { + pu_domain_status |= (1 << domain_id); + } + + if (domain_id == HDMIMIX) { + /* assert the reset */ + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_RESET_CTL0, 0x0); + /* enable all th function clock */ + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL0, 0xFFFFFFFF); + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL1, 0x7ffff87e); + } + + /* clear the PGC bit */ + mmio_clrbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1); + + /* power up the domain */ + mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, pwr_domain->pwr_req); + + /* wait for power request done */ + while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & pwr_domain->pwr_req) + ; + + if (domain_id == HDMIMIX) { + /* wait for memory repair done for HDMIMIX */ + while (!(mmio_read_32(IMX_SRC_BASE + 0x94) & BIT(8))) + ; + /* disable all the function clock */ + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL0, 0x0); + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL1, 0x0); + /* deassert the reset */ + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_RESET_CTL0, 0xffffffff); + /* enable all the clock again */ + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL0, 0xFFFFFFFF); + mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL1, 0x7ffff87e); + } + + if (domain_id == HSIOMIX) { + /* enable HSIOMIX clock */ + mmio_write_32(IMX_HSIOMIX_CTL_BASE, 0x2); + } + + /* handle the ADB400 sync */ + if (pwr_domain->need_sync) { + /* clear adb power down request */ + mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync); + + /* wait for adb power request ack */ + while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) + ; + } + + imx_noc_qos(domain_id); + + /* AIPS5 config is lost when audiomix is off, so need to re-init it */ + if (domain_id == AUDIOMIX) { + imx_aipstz_init(aipstz5); + } + } else { + if (pwr_domain->always_on) { + return; + } + + if (pwr_domain->need_sync) { + pu_domain_status &= ~(1 << domain_id); + } + + /* handle the ADB400 sync */ + if (pwr_domain->need_sync) { + /* set adb power down request */ + mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync); + + /* wait for adb power request ack */ + while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) + ; + } + + /* set the PGC bit */ + mmio_setbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1); + + /* + * leave the G1, G2, H1 power domain on until VPUMIX power off, + * otherwise system will hang due to VPUMIX ACK + */ + if (domain_id == VPU_H1 || domain_id == VPU_G1 || domain_id == VPU_G2) { + return; + } + + if (domain_id == VPUMIX) { + mmio_write_32(IMX_GPC_BASE + PU_PGC_DN_TRG, VPU_G1_PWR_REQ | + VPU_G2_PWR_REQ | VPU_H1_PWR_REQ); + + while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & (VPU_G1_PWR_REQ | + VPU_G2_PWR_REQ | VPU_H1_PWR_REQ)) + ; + } + + /* power down the domain */ + mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, pwr_domain->pwr_req); + + /* wait for power request done */ + while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & pwr_domain->pwr_req) + ; + + if (domain_id == HDMIMIX) { + /* disable all the clocks of HDMIMIX */ + mmio_write_32(IMX_HDMI_CTL_BASE + 0x40, 0x0); + mmio_write_32(IMX_HDMI_CTL_BASE + 0x50, 0x0); + } + } + + if (domain_id == HSIOMIX) { + for (i = 0; i < ARRAY_SIZE(hsiomix_clk); i++) { + mmio_write_32(IMX_CCM_BASE + hsiomix_clk[i].offset, hsiomix_clk[i].val); + } + } +} + +void imx_gpc_init(void) +{ + uint32_t val; + unsigned int i; + + /* mask all the wakeup irq by default */ + for (i = 0; i < IMR_NUM; i++) { + mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0); + mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0); + } + + val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC); + /* use GIC wake_request to wakeup C0~C3 from LPM */ + val |= CORE_WKUP_FROM_GIC; + /* clear the MASTER0 LPM handshake */ + val &= ~MASTER0_LPM_HSK; + mmio_write_32(IMX_GPC_BASE + LPCR_A53_BSC, val); + + /* clear MASTER1 & MASTER2 mapping in CPU0(A53) */ + mmio_clrbits_32(IMX_GPC_BASE + MST_CPU_MAPPING, (MASTER1_MAPPING | + MASTER2_MAPPING)); + + /* set all mix/PU in A53 domain */ + mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0x3fffff); + + /* + * Set the CORE & SCU power up timing: + * SW = 0x1, SW2ISO = 0x1; + * the CPU CORE and SCU power up timming counter + * is drived by 32K OSC, each domain's power up + * latency is (SW + SW2ISO) / 32768 + */ + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(0) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x401); + mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING, + (0x59 << TMC_TMR_SHIFT) | 0x5B | (0x2 << TRC1_TMC_SHIFT)); + + /* set DUMMY PDN/PUP ACK by default for A53 domain */ + mmio_write_32(IMX_GPC_BASE + PGC_ACK_SEL_A53, + A53_DUMMY_PUP_ACK | A53_DUMMY_PDN_ACK); + + /* clear DSM by default */ + val = mmio_read_32(IMX_GPC_BASE + SLPCR); + val &= ~SLPCR_EN_DSM; + /* enable the fast wakeup wait/stop mode */ + val |= SLPCR_A53_FASTWUP_WAIT_MODE; + val |= SLPCR_A53_FASTWUP_STOP_MODE; + /* clear the RBC */ + val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT); + /* set the STBY_COUNT to 0x5, (128 * 30)us */ + val &= ~(0x7 << SLPCR_STBY_COUNT_SHFT); + val |= (0x5 << SLPCR_STBY_COUNT_SHFT); + mmio_write_32(IMX_GPC_BASE + SLPCR, val); + + /* + * USB PHY power up needs to make sure RESET bit in SRC is clear, + * otherwise, the PU power up bit in GPC will NOT self-cleared. + * only need to do it once. + */ + mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1); + mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1); + + /* enable all the power domain by default */ + for (i = 0; i < 101; i++) { + mmio_write_32(IMX_CCM_BASE + CCGR(i), 0x3); + } + + for (i = 0; i < 20; i++) { + imx_gpc_pm_domain_enable(i, true); + } +} diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c new file mode 100644 index 000000000..22fbd5e4b --- /dev/null +++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c @@ -0,0 +1,187 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stdbool.h> + +#include <arch_helpers.h> +#include <common/bl_common.h> +#include <common/debug.h> +#include <context.h> +#include <drivers/arm/tzc380.h> +#include <drivers/console.h> +#include <drivers/generic_delay_timer.h> +#include <lib/el3_runtime/context_mgmt.h> +#include <lib/mmio.h> +#include <lib/xlat_tables/xlat_tables_v2.h> +#include <plat/common/platform.h> + +#include <gpc.h> +#include <imx_aipstz.h> +#include <imx_uart.h> +#include <imx_rdc.h> +#include <imx8m_caam.h> +#include <platform_def.h> +#include <plat_imx8.h> + +static const mmap_region_t imx_mmap[] = { + GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP, + NOC_MAP, {0}, +}; + +static const struct aipstz_cfg aipstz[] = { + {IMX_AIPSTZ1, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {IMX_AIPSTZ2, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {IMX_AIPSTZ3, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {IMX_AIPSTZ4, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {0}, +}; + +static const struct imx_rdc_cfg rdc[] = { + /* Master domain assignment */ + RDC_MDAn(0x1, DID1), + + /* peripherals domain permission */ + + /* memory region */ + + /* Sentinel */ + {0}, +}; + +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +/* get SPSR for BL33 entry */ +static uint32_t get_spsr_for_bl33_entry(void) +{ + unsigned long el_status; + unsigned long mode; + uint32_t spsr; + + /* figure out what mode we enter the non-secure world */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + mode = (el_status) ? MODE_EL2 : MODE_EL1; + + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + return spsr; +} + +static void bl31_tzc380_setup(void) +{ + unsigned int val; + + val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x28); + if ((val & GPR_TZASC_EN) != GPR_TZASC_EN) + return; + + tzc380_init(IMX_TZASC_BASE); + + /* + * Need to substact offset 0x40000000 from CPU address when + * programming tzasc region for i.mx8mp. + */ + + /* Enable 1G-5G S/NS RW */ + tzc380_configure_region(0, 0x00000000, TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_4G) | + TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_ALL); +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + static console_t console; + unsigned int i; + + /* Enable CSU NS access permission */ + for (i = 0; i < 64; i++) { + mmio_write_32(IMX_CSU_BASE + i * 4, 0x00ff00ff); + } + + imx_aipstz_init(aipstz); + + imx_rdc_init(rdc); + + imx8m_caam_init(); + + console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, + IMX_CONSOLE_BAUDRATE, &console); + /* This console is only used for boot stage */ + console_set_scope(&console, CONSOLE_FLAG_BOOT); + + /* + * tell BL3-1 where the non-secure software image is located + * and the entry state information. + */ + bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET; + bl33_image_ep_info.spsr = get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + +#ifdef SPD_opteed + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = 0; + + /* Pass TEE base and size to bl33 */ + bl33_image_ep_info.args.arg1 = BL32_BASE; + bl33_image_ep_info.args.arg2 = BL32_SIZE; +#endif + + bl31_tzc380_setup(); +} + +void bl31_plat_arch_setup(void) +{ + mmap_add_region(BL31_BASE, BL31_BASE, (BL31_LIMIT - BL31_BASE), + MT_MEMORY | MT_RW | MT_SECURE); + mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, (BL_CODE_END - BL_CODE_BASE), + MT_MEMORY | MT_RO | MT_SECURE); +#if USE_COHERENT_MEM + mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE, + (BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE), + MT_DEVICE | MT_RW | MT_SECURE); +#endif + mmap_add(imx_mmap); + + init_xlat_tables(); + + enable_mmu_el3(0); +} + +void bl31_platform_setup(void) +{ + generic_delay_timer_init(); + + /* select the CKIL source to 32K OSC */ + mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1); + + plat_gic_driver_init(); + plat_gic_init(); + + imx_gpc_init(); +} + +entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type) +{ + if (type == NON_SECURE) { + return &bl33_image_ep_info; + } + + if (type == SECURE) { + return &bl32_image_ep_info; + } + + return NULL; +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return COUNTER_FREQUENCY; +} diff --git a/plat/imx/imx8m/imx8mp/imx8mp_psci.c b/plat/imx/imx8m/imx8mp/imx8mp_psci.c new file mode 100644 index 000000000..bc7b24679 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/imx8mp_psci.c @@ -0,0 +1,44 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdbool.h> + +#include <arch.h> +#include <arch_helpers.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <lib/psci/psci.h> + +#include <gpc.h> +#include <imx8m_psci.h> +#include <plat_imx8.h> + +static const plat_psci_ops_t imx_plat_psci_ops = { + .pwr_domain_on = imx_pwr_domain_on, + .pwr_domain_on_finish = imx_pwr_domain_on_finish, + .pwr_domain_off = imx_pwr_domain_off, + .validate_ns_entrypoint = imx_validate_ns_entrypoint, + .validate_power_state = imx_validate_power_state, + .cpu_standby = imx_cpu_standby, + .pwr_domain_suspend = imx_domain_suspend, + .pwr_domain_suspend_finish = imx_domain_suspend_finish, + .pwr_domain_pwr_down_wfi = imx_pwr_domain_pwr_down_wfi, + .get_sys_suspend_power_state = imx_get_sys_suspend_power_state, + .system_reset = imx_system_reset, + .system_off = imx_system_off, +}; + +/* export the platform specific psci ops */ +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + /* sec_entrypoint is used for warm reset */ + imx_mailbox_init(sec_entrypoint); + + *psci_ops = &imx_plat_psci_ops; + + return 0; +} diff --git a/plat/imx/imx8m/imx8mp/include/gpc_reg.h b/plat/imx/imx8m/imx8mp/include/gpc_reg.h new file mode 100644 index 000000000..7909937b2 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/include/gpc_reg.h @@ -0,0 +1,151 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPC_REG_H +#define GPC_REG_H + +#define LPCR_A53_BSC 0x0 +#define LPCR_A53_BSC2 0x180 +#define LPCR_A53_AD 0x4 +#define LPCR_M4 0x8 +#define SLPCR 0x14 +#define MST_CPU_MAPPING 0x18 +#define MLPCR 0x20 +#define PGC_ACK_SEL_A53 0x24 +#define IMR1_CORE0_A53 0x30 +#define IMR1_CORE1_A53 0x44 +#define IMR1_CORE2_A53 0x194 +#define IMR1_CORE3_A53 0x1A8 +#define IMR1_CORE0_M4 0x58 + +#define SLT0_CFG 0x200 +#define GPC_PU_PWRHSK 0x190 +#define PGC_CPU_0_1_MAPPING 0x1CC +#define CPU_PGC_UP_TRG 0xD0 +#define PU_PGC_UP_TRG 0xD8 +#define CPU_PGC_DN_TRG 0xDC +#define PU_PGC_DN_TRG 0xE4 +#define LPS_CPU1 0xEC + +#define A53_CORE0_PGC 0x800 +#define A53_PLAT_PGC 0x900 +#define PLAT_PGC_PCR 0x900 +#define NOC_PGC_PCR 0xa40 +#define PGC_SCU_TIMING 0x910 + +#define MASK_DSM_TRIGGER_A53 BIT(31) +#define IRQ_SRC_A53_WUP BIT(30) +#define IRQ_SRC_A53_WUP_SHIFT 30 +#define IRQ_SRC_C1 BIT(29) +#define IRQ_SRC_C0 BIT(28) +#define IRQ_SRC_C3 BIT(23) +#define IRQ_SRC_C2 BIT(22) +#define CPU_CLOCK_ON_LPM BIT(14) +#define A53_CLK_ON_LPM BIT(14) +#define MASTER0_LPM_HSK BIT(6) +#define MASTER1_LPM_HSK BIT(7) +#define MASTER2_LPM_HSK BIT(8) + +#define L2PGE BIT(31) +#define EN_L2_WFI_PDN BIT(5) +#define EN_PLAT_PDN BIT(4) + +#define SLPCR_EN_DSM BIT(31) +#define SLPCR_RBC_EN BIT(30) +#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17) +#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16) +#define SLPCR_VSTBY BIT(2) +#define SLPCR_SBYOS BIT(1) +#define SLPCR_BYPASS_PMIC_READY BIT(0) +#define SLPCR_RBC_COUNT_SHIFT 24 +#define SLPCR_STBY_COUNT_SHFT 3 + +#define A53_DUMMY_PDN_ACK BIT(30) +#define A53_DUMMY_PUP_ACK BIT(31) +#define A53_PLAT_PDN_ACK BIT(8) +#define A53_PLAT_PUP_ACK BIT(9) + +#define NOC_PDN_SLT_CTRL BIT(12) +#define NOC_PUP_SLT_CTRL BIT(13) +#define NOC_PGC_PDN_ACK BIT(12) +#define NOC_PGC_PUP_ACK BIT(13) + +#define PLAT_PUP_SLT_CTRL BIT(9) +#define PLAT_PDN_SLT_CTRL BIT(8) + +#define SLT_PLAT_PDN BIT(8) +#define SLT_PLAT_PUP BIT(9) + +#define MASTER1_MAPPING BIT(1) +#define MASTER2_MAPPING BIT(2) + +#define TMR_TCD2_SHIFT 0 +#define TMC_TMR_SHIFT 10 +#define TRC1_TMC_SHIFT 20 + +#define MIPI_PHY1_PWR_REQ BIT(0) +#define PCIE_PHY_PWR_REQ BIT(1) +#define USB1_PHY_PWR_REQ BIT(2) +#define USB2_PHY_PWR_REQ BIT(3) +#define MLMIX_PWR_REQ BIT(4) +#define AUDIOMIX_PWR_REQ BIT(5) +#define GPU2D_PWR_REQ BIT(6) +#define GPUMIX_PWR_REQ BIT(7) +#define VPUMIX_PWR_REQ BIT(8) +#define GPU3D_PWR_REQ BIT(9) +#define MEDIAMIX_PWR_REQ BIT(10) +#define VPU_G1_PWR_REQ BIT(11) +#define VPU_G2_PWR_REQ BIT(12) +#define VPU_H1_PWR_REQ BIT(13) +#define HDMIMIX_PWR_REQ BIT(14) +#define HDMI_PHY_PWR_REQ BIT(15) +#define MIPI_PHY2_PWR_REQ BIT(16) +#define HSIOMIX_PWR_REQ BIT(17) +#define MEDIAMIX_ISPDWP_PWR_REQ BIT(18) +#define DDRMIX_PWR_REQ BIT(19) + +#define AUDIOMIX_ADB400_SYNC (BIT(4) | BIT(15)) +#define MLMIX_ADB400_SYNC (BIT(7) | BIT(8)) +#define GPUMIX_ADB400_SYNC BIT(9) +#define VPUMIX_ADB400_SYNC BIT(10) +#define DDRMIX_ADB400_SYNC BIT(11) +#define HSIOMIX_ADB400_SYNC BIT(12) +#define HDMIMIX_ADB400_SYNC BIT(13) +#define MEDIAMIX_ADB400_SYNC BIT(14) + +#define AUDIOMIX_ADB400_ACK (BIT(20) | BIT(31)) +#define MLMIX_ADB400_ACK (BIT(23) | BIT(24)) +#define GPUMIX_ADB400_ACK BIT(25) +#define VPUMIX_ADB400_ACK BIT(26) +#define DDRMIX_ADB400_ACK BIT(27) +#define HSIOMIX_ADB400_ACK BIT(28) +#define HDMIMIX_ADB400_ACK BIT(29) +#define MEDIAMIX_ADB400_ACK BIT(30) + +#define MIPI_PHY1_PGC 0xb00 +#define PCIE_PHY_PGC 0xb40 +#define USB1_PHY_PGC 0xb80 +#define USB2_PHY_PGC 0xbc0 +#define MLMIX_PGC 0xc00 +#define AUDIOMIX_PGC 0xc40 +#define GPU2D_PGC 0xc80 +#define GPUMIX_PGC 0xcc0 +#define VPUMIX_PGC 0xd00 +#define GPU3D_PGC 0xd40 +#define MEDIAMIX_PGC 0xd80 +#define VPU_G1_PGC 0xdc0 +#define VPU_G2_PGC 0xe00 +#define VPU_H1_PGC 0xe40 +#define HDMIMIX_PGC 0xe80 +#define HDMI_PHY_PGC 0xec0 +#define MIPI_PHY2_PGC 0xf00 +#define HSIOMIX_PGC 0xf40 +#define MEDIAMIX_ISPDWP_PGC 0xf80 +#define DDRMIX_PGC 0xfc0 + +#define IRQ_IMR_NUM U(5) + +#endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h new file mode 100644 index 000000000..644adc771 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/include/platform_def.h @@ -0,0 +1,154 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <lib/utils_def.h> +#include <lib/xlat_tables/xlat_tables_v2.h> + +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +#define PLATFORM_STACK_SIZE 0xB00 +#define CACHE_WRITEBACK_GRANULE 64 + +#define PLAT_PRIMARY_CPU U(0x0) +#define PLATFORM_MAX_CPU_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) + +#define IMX_PWR_LVL0 MPIDR_AFFLVL0 +#define IMX_PWR_LVL1 MPIDR_AFFLVL1 +#define IMX_PWR_LVL2 MPIDR_AFFLVL2 + +#define PWR_DOMAIN_AT_MAX_LVL U(1) +#define PLAT_MAX_PWR_LVL U(2) +#define PLAT_MAX_OFF_STATE U(4) +#define PLAT_MAX_RET_STATE U(2) + +#define PLAT_WAIT_RET_STATE U(1) +#define PLAT_STOP_OFF_STATE U(3) + +#define BL31_BASE U(0x960000) +#define BL31_LIMIT U(0x980000) + +/* non-secure uboot base */ +#define PLAT_NS_IMAGE_OFFSET U(0x40200000) + +/* GICv3 base address */ +#define PLAT_GICD_BASE U(0x38800000) +#define PLAT_GICR_BASE U(0x38880000) + +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) + +#define MAX_XLAT_TABLES 8 +#define MAX_MMAP_REGIONS 16 + +#define HAB_RVT_BASE U(0x00000900) /* HAB_RVT for i.MX8MM */ + +#define IMX_BOOT_UART_CLK_IN_HZ 24000000 /* Select 24MHz oscillator */ +#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE +#define PLAT_CRASH_UART_CLK_IN_HZ 24000000 +#define IMX_CONSOLE_BAUDRATE 115200 + +#define IMX_AIPSTZ1 U(0x301f0000) +#define IMX_AIPSTZ2 U(0x305f0000) +#define IMX_AIPSTZ3 U(0x309f0000) +#define IMX_AIPSTZ4 U(0x32df0000) +#define IMX_AIPSTZ5 U(0x30df0000) + +#define IMX_AIPS_BASE U(0x30000000) +#define IMX_AIPS_SIZE U(0x3000000) +#define IMX_GPV_BASE U(0x32000000) +#define IMX_GPV_SIZE U(0x800000) +#define IMX_AIPS1_BASE U(0x30200000) +#define IMX_AIPS4_BASE U(0x32c00000) +#define IMX_ANAMIX_BASE U(0x30360000) +#define IMX_CCM_BASE U(0x30380000) +#define IMX_SRC_BASE U(0x30390000) +#define IMX_GPC_BASE U(0x303a0000) +#define IMX_RDC_BASE U(0x303d0000) +#define IMX_CSU_BASE U(0x303e0000) +#define IMX_WDOG_BASE U(0x30280000) +#define IMX_SNVS_BASE U(0x30370000) +#define IMX_NOC_BASE U(0x32700000) +#define IMX_NOC_SIZE U(0x100000) +#define IMX_TZASC_BASE U(0x32F80000) +#define IMX_IOMUX_GPR_BASE U(0x30340000) +#define IMX_CAAM_BASE U(0x30900000) +#define IMX_DDRC_BASE U(0x3d400000) +#define IMX_DDRPHY_BASE U(0x3c000000) +#define IMX_DDR_IPS_BASE U(0x3d000000) +#define IMX_DDR_IPS_SIZE U(0x1800000) +#define IMX_ROM_BASE U(0x0) + +#define IMX_GIC_BASE PLAT_GICD_BASE +#define IMX_GIC_SIZE U(0x200000) + +#define IMX_HSIOMIX_CTL_BASE U(0x32f10000) +#define IMX_HDMI_CTL_BASE U(0x32fc0000) +#define RTX_RESET_CTL0 U(0x20) +#define RTX_CLK_CTL0 U(0x40) +#define RTX_CLK_CTL1 U(0x50) +#define TX_CONTROL0 U(0x200) +#define TX_CONTROL1 U(0x220) + +#define IMX_MEDIAMIX_CTL_BASE U(0x32ec0000) +#define RSTn_CSR U(0x0) +#define CLK_EN_CSR U(0x4) +#define RST_DIV U(0x8) +#define LCDIF_ARCACHE_CTRL U(0x4c) +#define ISI_CACHE_CTRL U(0x50) + +#define WDOG_WSR U(0x2) +#define WDOG_WCR_WDZST BIT(0) +#define WDOG_WCR_WDBG BIT(1) +#define WDOG_WCR_WDE BIT(2) +#define WDOG_WCR_WDT BIT(3) +#define WDOG_WCR_SRS BIT(4) +#define WDOG_WCR_WDA BIT(5) +#define WDOG_WCR_SRE BIT(6) +#define WDOG_WCR_WDW BIT(7) + +#define SRC_A53RCR0 U(0x4) +#define SRC_A53RCR1 U(0x8) +#define SRC_OTG1PHY_SCR U(0x20) +#define SRC_OTG2PHY_SCR U(0x24) +#define SRC_GPR1_OFFSET U(0x74) + +#define SNVS_LPCR U(0x38) +#define SNVS_LPCR_SRTC_ENV BIT(0) +#define SNVS_LPCR_DP_EN BIT(5) +#define SNVS_LPCR_TOP BIT(6) + +#define IOMUXC_GPR10 U(0x28) +#define GPR_TZASC_EN BIT(0) +#define GPR_TZASC_EN_LOCK BIT(16) + +#define ANAMIX_MISC_CTL U(0x124) +#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50) + +#define MAX_CSU_NUM U(64) + +#define OCRAM_S_BASE U(0x00180000) +#define OCRAM_S_SIZE U(0x8000) +#define OCRAM_S_LIMIT (OCRAM_S_BASE + OCRAM_S_SIZE) +#define SAVED_DRAM_TIMING_BASE OCRAM_S_BASE + +#define COUNTER_FREQUENCY 8000000 /* 8MHz */ + +#define IMX_WDOG_B_RESET + +#define GIC_MAP MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW) +#define AIPS_MAP MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW) /* AIPS map */ +#define OCRAM_S_MAP MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_MEMORY | MT_RW) /* OCRAM_S */ +#define DDRC_MAP MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */ +#define NOC_MAP MAP_REGION_FLAT(IMX_NOC_BASE, IMX_NOC_SIZE, MT_DEVICE | MT_RW) /* NOC QoS */ + +#endif /* platform_def.h */ diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk new file mode 100644 index 000000000..1d11e3df4 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/platform.mk @@ -0,0 +1,56 @@ +# +# Copyright 2019-2020 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PLAT_INCLUDES := -Iplat/imx/common/include \ + -Iplat/imx/imx8m/include \ + -Iplat/imx/imx8m/imx8mp/include +# Translation tables library +include lib/xlat_tables_v2/xlat_tables.mk + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +IMX_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/common/plat_psci_common.c \ + plat/imx/common/plat_imx8_gic.c + +BL31_SOURCES += plat/imx/common/imx8_helpers.S \ + plat/imx/imx8m/gpc_common.c \ + plat/imx/imx8m/imx_aipstz.c \ + plat/imx/imx8m/imx_rdc.c \ + plat/imx/imx8m/imx8m_caam.c \ + plat/imx/imx8m/imx8m_psci_common.c \ + plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c \ + plat/imx/imx8m/imx8mp/imx8mp_psci.c \ + plat/imx/imx8m/imx8mp/gpc.c \ + plat/imx/common/imx8_topology.c \ + plat/imx/common/imx_sip_handler.c \ + plat/imx/common/imx_sip_svc.c \ + plat/imx/common/imx_uart_console.S \ + lib/cpus/aarch64/cortex_a53.S \ + drivers/arm/tzc/tzc380.c \ + drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + ${IMX_GIC_SOURCES} \ + ${XLAT_TABLES_LIB_SRCS} + +USE_COHERENT_MEM := 1 +RESET_TO_BL31 := 1 +A53_DISABLE_NON_TEMPORAL_HINT := 0 + +ERRATA_A53_835769 := 1 +ERRATA_A53_843419 := 1 +ERRATA_A53_855873 := 1 + +BL32_BASE ?= 0x56000000 +$(eval $(call add_define,BL32_BASE)) + +BL32_SIZE ?= 0x2000000 +$(eval $(call add_define,BL32_SIZE)) + +IMX_BOOT_UART_BASE ?= 0x30890000 +$(eval $(call add_define,IMX_BOOT_UART_BASE)) diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c index 942ae459c..367c9411d 100644 --- a/plat/imx/imx8m/imx8mq/gpc.c +++ b/plat/imx/imx8m/imx8mq/gpc.c @@ -19,9 +19,14 @@ /* use wfi power down the core */ void imx_set_cpu_pwr_off(unsigned int core_id) { + bakery_lock_get(&gpc_lock); + /* enable the wfi power down of the core */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) | (1 << (core_id + 20))); + + bakery_lock_release(&gpc_lock); + /* assert the pcg pcr bit of the core */ mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); }; @@ -29,6 +34,8 @@ void imx_set_cpu_pwr_off(unsigned int core_id) /* if out of lpm, we need to do reverse steps */ void imx_set_cpu_lpm(unsigned int core_id, bool pdn) { + bakery_lock_get(&gpc_lock); + if (pdn) { /* enable the core WFI PDN & IRQ PUP */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) | @@ -42,6 +49,8 @@ void imx_set_cpu_lpm(unsigned int core_id, bool pdn) /* deassert the pcg pcr bit of the core */ mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); } + + bakery_lock_release(&gpc_lock); } void imx_pup_pdn_slot_config(int last_core, bool pdn) diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c index a347389a2..05b59705f 100644 --- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c +++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c @@ -133,7 +133,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, imx8m_caam_init(); #if DEBUG_CONSOLE - static console_uart_t console; + static console_t console; console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, IMX_CONSOLE_BAUDRATE, &console); diff --git a/plat/imx/imx8m/imx8mq/include/gpc_reg.h b/plat/imx/imx8m/imx8mq/include/gpc_reg.h new file mode 100644 index 000000000..f171bd9d0 --- /dev/null +++ b/plat/imx/imx8m/imx8mq/include/gpc_reg.h @@ -0,0 +1,89 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPC_REG_H +#define GPC_REG_H + +#define LPCR_A53_BSC 0x0 +#define LPCR_A53_BSC2 0x108 +#define LPCR_A53_AD 0x4 +#define LPCR_M4 0x8 +#define SLPCR 0x14 +#define MST_CPU_MAPPING 0x18 +#define MLPCR 0x20 +#define PGC_ACK_SEL_A53 0x24 +#define IMR1_CORE0_A53 0x30 +#define IMR1_CORE1_A53 0x40 +#define IMR1_CORE2_A53 0x1C0 +#define IMR1_CORE3_A53 0x1D0 +#define IMR1_CORE0_M4 0x50 +#define SLT0_CFG 0xB0 +#define GPC_PU_PWRHSK 0x1FC +#define PGC_CPU_0_1_MAPPING 0xEC +#define CPU_PGC_UP_TRG 0xF0 +#define PU_PGC_UP_TRG 0xF8 +#define CPU_PGC_DN_TRG 0xFC +#define PU_PGC_DN_TRG 0x104 +#define LPS_CPU1 0x114 +#define A53_CORE0_PGC 0x800 +#define A53_PLAT_PGC 0x900 +#define PLAT_PGC_PCR 0x900 +#define NOC_PGC_PCR 0xa40 +#define PGC_SCU_TIMING 0x910 + +#define MASK_DSM_TRIGGER_A53 BIT(31) +#define IRQ_SRC_A53_WUP BIT(30) +#define IRQ_SRC_A53_WUP_SHIFT 30 +#define IRQ_SRC_C1 BIT(29) +#define IRQ_SRC_C0 BIT(28) +#define IRQ_SRC_C3 BIT(23) +#define IRQ_SRC_C2 BIT(22) +#define CPU_CLOCK_ON_LPM BIT(14) +#define A53_CLK_ON_LPM BIT(14) +#define MASTER0_LPM_HSK BIT(6) +#define MASTER1_LPM_HSK BIT(7) +#define MASTER2_LPM_HSK BIT(8) + +#define L2PGE BIT(31) +#define EN_L2_WFI_PDN BIT(5) +#define EN_PLAT_PDN BIT(4) + +#define SLPCR_EN_DSM BIT(31) +#define SLPCR_RBC_EN BIT(30) +#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17) +#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16) +#define SLPCR_VSTBY BIT(2) +#define SLPCR_SBYOS BIT(1) +#define SLPCR_BYPASS_PMIC_READY BIT(0) +#define SLPCR_RBC_COUNT_SHIFT 24 +#define SLPCR_STBY_COUNT_SHFT 3 + +#define A53_DUMMY_PDN_ACK BIT(15) +#define A53_DUMMY_PUP_ACK BIT(31) +#define A53_PLAT_PDN_ACK BIT(2) +#define A53_PLAT_PUP_ACK BIT(18) +#define NOC_PDN_SLT_CTRL BIT(10) +#define NOC_PUP_SLT_CTRL BIT(11) +#define NOC_PGC_PDN_ACK BIT(3) +#define NOC_PGC_PUP_ACK BIT(19) + +#define DDRMIX_PWR_REQ BIT(5) +#define DDRMIX_ADB400_SYNC BIT(1) +#define DDRMIX_ADB400_ACK BIT(18) +#define DDRMIX_PGC 0xd40 + +#define PLAT_PUP_SLT_CTRL BIT(9) +#define PLAT_PDN_SLT_CTRL BIT(8) + +#define SLT_PLAT_PDN BIT(8) +#define SLT_PLAT_PUP BIT(9) + +#define MASTER1_MAPPING BIT(1) +#define MASTER2_MAPPING BIT(2) + +#define IRQ_IMR_NUM U(4) + +#endif /* GPC_REG_H */ diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk index 80ebe4062..546101043 100644 --- a/plat/imx/imx8m/imx8mq/platform.mk +++ b/plat/imx/imx8m/imx8mq/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,11 +8,10 @@ PLAT_INCLUDES := -Iplat/imx/common/include \ -Iplat/imx/imx8m/include \ -Iplat/imx/imx8m/imx8mq/include -IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/arm_gicv3_common.c \ - drivers/arm/gic/v3/gic500.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/common/gic_common.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +IMX_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/common/plat_psci_common.c \ plat/imx/common/plat_imx8_gic.c diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h index 139132c40..075da91b1 100644 --- a/plat/imx/imx8m/include/gpc.h +++ b/plat/imx/imx8m/include/gpc.h @@ -7,69 +7,7 @@ #ifndef IMX8M_GPC_H #define IMX8M_GPC_H -#define LPCR_A53_BSC 0x0 -#define LPCR_A53_BSC2 0x108 -#define LPCR_A53_AD 0x4 -#define LPCR_M4 0x8 -#define SLPCR 0x14 -#define MST_CPU_MAPPING 0x18 -#define MLPCR 0x20 -#define PGC_ACK_SEL_A53 0x24 -#define IMR1_CORE0_A53 0x30 -#define IMR1_CORE1_A53 0x40 -#define IMR1_CORE2_A53 0x1C0 -#define IMR1_CORE3_A53 0x1D0 -#define IMR1_CORE0_M4 0x50 -#define SLT0_CFG 0xB0 -#define GPC_PU_PWRHSK 0x1FC -#define PGC_CPU_0_1_MAPPING 0xEC -#define CPU_PGC_UP_TRG 0xF0 -#define PU_PGC_UP_TRG 0xF8 -#define CPU_PGC_DN_TRG 0xFC -#define PU_PGC_DN_TRG 0x104 -#define A53_CORE0_PGC 0x800 -#define A53_PLAT_PGC 0x900 -#define PLAT_PGC_PCR 0x900 -#define PGC_SCU_TIMING 0x910 - -#define MASK_DSM_TRIGGER_A53 BIT(31) -#define IRQ_SRC_A53_WUP BIT(30) -#define IRQ_SRC_A53_WUP_SHIFT 30 -#define IRQ_SRC_C1 BIT(29) -#define IRQ_SRC_C0 BIT(28) -#define IRQ_SRC_C3 BIT(23) -#define IRQ_SRC_C2 BIT(22) -#define CPU_CLOCK_ON_LPM BIT(14) -#define A53_CLK_ON_LPM BIT(14) -#define MASTER0_LPM_HSK BIT(6) - -#define L2PGE BIT(31) -#define EN_L2_WFI_PDN BIT(5) -#define EN_PLAT_PDN BIT(4) - -#define SLPCR_EN_DSM BIT(31) -#define SLPCR_RBC_EN BIT(30) -#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17) -#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16) -#define SLPCR_VSTBY BIT(2) -#define SLPCR_SBYOS BIT(1) -#define SLPCR_BYPASS_PMIC_READY BIT(0) -#define SLPCR_RBC_COUNT_SHIFT 24 -#define SLPCR_STBY_COUNT_SHFT 3 - -#define A53_DUMMY_PDN_ACK BIT(15) -#define A53_DUMMY_PUP_ACK BIT(31) -#define A53_PLAT_PDN_ACK BIT(2) -#define A53_PLAT_PUP_ACK BIT(18) - -#define PLAT_PUP_SLT_CTRL BIT(9) -#define PLAT_PDN_SLT_CTRL BIT(8) - -#define SLT_PLAT_PDN BIT(8) -#define SLT_PLAT_PUP BIT(9) - -#define MASTER1_MAPPING BIT(1) -#define MASTER2_MAPPING BIT(2) +#include <gpc_reg.h> /* helper macro */ #define A53_LPM_MASK U(0xF) @@ -78,7 +16,7 @@ #define LPM_MODE(local_state) ((local_state) == PLAT_WAIT_RET_STATE ? A53_LPM_WAIT : A53_LPM_STOP) #define DSM_MODE_MASK BIT(31) - +#define CORE_WKUP_FROM_GIC (IRQ_SRC_C0 | IRQ_SRC_C1 | IRQ_SRC_C2 | IRQ_SRC_C3) #define A53_CORE_WUP_SRC(core_id) (1 << ((core_id) < 2 ? 28 + (core_id) : 22 + (core_id) - 2)) #define COREx_PGC_PCR(core_id) (0x800 + (core_id) * 0x40) #define COREx_WFI_PDN(core_id) (1 << ((core_id) < 2 ? (core_id) * 2 : ((core_id) - 2) * 2 + 16)) @@ -87,9 +25,37 @@ #define SLTx_CFG(n) ((SLT0_CFG + ((n) * 4))) #define SLT_COREx_PUP(core_id) (0x2 << ((core_id) * 2)) -#define IRQ_IMR_NUM 4 #define IMR_MASK_ALL 0xffffffff +#define IMX_PD_DOMAIN(name, on) \ + { \ + .pwr_req = name##_PWR_REQ, \ + .pgc_offset = name##_PGC, \ + .need_sync = false, \ + .always_on = true, \ + } + +#define IMX_MIX_DOMAIN(name, on) \ + { \ + .pwr_req = name##_PWR_REQ, \ + .pgc_offset = name##_PGC, \ + .adb400_sync = name##_ADB400_SYNC, \ + .adb400_ack = name##_ADB400_ACK, \ + .need_sync = true, \ + .always_on = true, \ + } + +struct imx_pwr_domain { + uint32_t pwr_req; + uint32_t adb400_sync; + uint32_t adb400_ack; + uint32_t pgc_offset; + bool need_sync; + bool always_on; +}; + +DECLARE_BAKERY_LOCK(gpc_lock); + /* function declare */ void imx_gpc_init(void); void imx_set_cpu_secure_entry(unsigned int core_index, uintptr_t sec_entrypoint); diff --git a/plat/imx/imx8m/include/imx_rdc.h b/plat/imx/imx8m/include/imx_rdc.h index 6be8550da..e25b0e6d4 100644 --- a/plat/imx/imx8m/include/imx_rdc.h +++ b/plat/imx/imx8m/include/imx_rdc.h @@ -13,9 +13,9 @@ #define MDAn(x) (IMX_RDC_BASE + 0x200 + (x) * 4) #define PDAPn(x) (IMX_RDC_BASE + 0x400 + (x) * 4) -#define MRSAn(x) (IMX_RDC_BASE + 0x800 + (x) * 4) -#define MREAn(x) (IMX_RDC_BASE + 0x804 + (x) * 4) -#define MRCn(x) (IMX_RDC_BASE + 0x808 + (x) * 4) +#define MRSAn(x) (IMX_RDC_BASE + 0x800 + (x) * 0x10) +#define MREAn(x) (IMX_RDC_BASE + 0x804 + (x) * 0x10) +#define MRCn(x) (IMX_RDC_BASE + 0x808 + (x) * 0x10) #define LCK BIT(31) #define SREQ BIT(30) |