plat: imx8m: Add the basic support for imx8mm
authorJacky Bai <ping.bai@nxp.com>
Wed, 6 Mar 2019 09:15:06 +0000 (17:15 +0800)
committerJacky Bai <ping.bai@nxp.com>
Wed, 13 Mar 2019 02:14:59 +0000 (10:14 +0800)
The i.MX8M Mini is new SOC of the i.MX8M family. it is
focused on delivering the latest and greatest video and
audio experience combining state-of-the-art media-specific
features with high-performance processing while optimized
for lowest power consumption. The i.MX 8M Mini Media Applications
Processor is  14nm FinFET product of the growing i.MX8M family
targeting the consumer & industrial market. It is built in 14LPP
to achieve both high performance and low power consumption
and relies on a powerful fully coherent core complex based on
a quad Cortex-A53 cluster with video and graphics accelerators

this patch add the basic support for i.MX8MM.

Signed-off-by: Jacky Bai <ping.bai@nxp.com>
docs/plat/imx8m.rst
plat/imx/imx8m/imx8mm/gpc.c [new file with mode: 0644]
plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c [new file with mode: 0644]
plat/imx/imx8m/imx8mm/imx8mm_psci.c [new file with mode: 0644]
plat/imx/imx8m/imx8mm/include/platform_def.h [new file with mode: 0644]
plat/imx/imx8m/imx8mm/platform.mk [new file with mode: 0644]
plat/imx/imx8m/include/gpc.h

index ab33a8a5f93d4dab3b4ec0309009253274e91891..a69f022277009ac09b6dc6228080001342bb9df4 100644 (file)
@@ -31,6 +31,7 @@ Build Procedure
        CROSS_COMPILE=aarch64-linux-gnu- make PLAT=<Target_SoC> bl31
 
    Target_SoC should be "imx8mq" for i.MX8MQ SoC.
+   Target_SoC should be "imx8mm" for i.MX8MM SoC.
 
 Deploy TF-A Images
 -----------------
diff --git a/plat/imx/imx8m/imx8mm/gpc.c b/plat/imx/imx8m/imx8mm/gpc.c
new file mode 100644 (file)
index 0000000..ab59292
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/smccc.h>
+#include <platform_def.h>
+#include <services/std_svc.h>
+
+#include <gpc.h>
+#include <imx_sip_svc.h>
+
+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 |= 0x30c00000;
+       /* clear the MASTER0 LPM handshake */
+       val &= ~(1 << 6);
+       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, 0x81);
+       mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x81);
+       mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x81);
+       mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x81);
+       mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x81);
+       mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING,
+                     (0x59 << 10) | 0x5B | (0x2 << 20));
+
+       /* 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);
+       mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1);
+
+       /* enable all the power domain by default */
+       mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x3fcf);
+}
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
new file mode 100644 (file)
index 0000000..a541ed3
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <platform_def.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.h>
+#include <plat/common/platform.h>
+
+#include <gpc.h>
+#include <imx_uart.h>
+#include <plat_imx8.h>
+
+static const mmap_region_t imx_mmap[] = {
+       MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW),
+       MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW), /* AIPS map */
+       {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;
+}
+
+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.mx8mm.
+        */
+
+       /* 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_uart_t console;
+       int i;
+
+       /* Enable CSU NS access permission */
+       for (i = 0; i < 64; i++) {
+               mmio_write_32(IMX_CSU_BASE + i * 4, 0x00ff00ff);
+       }
+
+
+       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);
+
+       /*
+        * 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);
+
+       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/imx8mm/imx8mm_psci.c b/plat/imx/imx8m/imx8mm/imx8mm_psci.c
new file mode 100644 (file)
index 0000000..e558724
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * 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/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
new file mode 100644 (file)
index 0000000..a95ab83
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#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               0x0
+#define PLATFORM_MAX_CPU_PER_CLUSTER   4
+#define PLATFORM_CLUSTER_COUNT         1
+#define PLATFORM_CLUSTER0_CORE_COUNT   4
+#define PLATFORM_CLUSTER1_CORE_COUNT   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(0x920000)
+#define BL31_LIMIT                     U(0x940000)
+#define BL32_BASE                      U(0xbe000000)
+
+/* 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      (1ull << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE       (1ull << 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_BASE             U(0x30890000)
+#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_DDRC_BASE                  U(0x3d400000)
+#define IMX_DDRPHY_BASE                        U(0x3c000000)
+#define IMX_DDR_IPS_BASE               U(0x3d000000)
+#define IMX_ROM_BASE                   U(0x0)
+
+#define GPV_BASE                       U(0x32000000)
+#define GPV_SIZE                       U(0x800000)
+#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_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 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 COUNTER_FREQUENCY              8000000 /* 8MHz */
+
+#define IMX_WDOG_B_RESET
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
new file mode 100644 (file)
index 0000000..d50af20
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+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     \
+                               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/imx8m_psci_common.c              \
+                               plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c       \
+                               plat/imx/imx8m/imx8mm/imx8mm_psci.c             \
+                               plat/imx/imx8m/imx8mm/gpc.c                     \
+                               plat/imx/common/imx8_topology.c                 \
+                               plat/imx/common/imx_uart_console.S              \
+                               lib/xlat_tables/aarch64/xlat_tables.c           \
+                               lib/xlat_tables/xlat_tables_common.c            \
+                               lib/cpus/aarch64/cortex_a53.S                   \
+                               drivers/console/aarch64/console.S               \
+                               drivers/arm/tzc/tzc380.c                        \
+                               drivers/delay_timer/delay_timer.c               \
+                               drivers/delay_timer/generic_delay_timer.c       \
+                               ${IMX_GIC_SOURCES}
+
+USE_COHERENT_MEM       :=      1
+RESET_TO_BL31          :=      1
+A53_DISABLE_NON_TEMPORAL_HINT := 0
+MULTI_CONSOLE_API      :=      1
+
+ERRATA_A53_835769      :=      1
+ERRATA_A53_843419      :=      1
+ERRATA_A53_855873      :=      1
index ce2665d7d19f27a4f130b3e605e601409f82bf09..139132c4065a5079ac32f93a1b84fc9f7955e00e 100644 (file)
@@ -68,6 +68,9 @@
 #define SLT_PLAT_PDN                   BIT(8)
 #define SLT_PLAT_PUP                   BIT(9)
 
+#define MASTER1_MAPPING                        BIT(1)
+#define MASTER2_MAPPING                        BIT(2)
+
 /* helper macro */
 #define A53_LPM_MASK   U(0xF)
 #define A53_LPM_WAIT   U(0x5)