summaryrefslogtreecommitdiffstats
path: root/plat/imx/imx7
diff options
context:
space:
mode:
Diffstat (limited to 'plat/imx/imx7')
-rw-r--r--plat/imx/imx7/common/imx7.mk112
-rw-r--r--plat/imx/imx7/common/imx7_bl2_el3_common.c198
-rw-r--r--plat/imx/imx7/common/imx7_bl2_mem_params_desc.c81
-rw-r--r--plat/imx/imx7/common/imx7_helpers.S59
-rw-r--r--plat/imx/imx7/common/imx7_image_load.c24
-rw-r--r--plat/imx/imx7/common/imx7_rotpk.S15
-rw-r--r--plat/imx/imx7/common/imx7_trusted_boot.c36
-rw-r--r--plat/imx/imx7/include/imx7_def.h20
-rw-r--r--plat/imx/imx7/include/imx_hab_arch.h12
-rw-r--r--plat/imx/imx7/include/imx_regs.h108
-rw-r--r--plat/imx/imx7/picopi/include/platform_def.h204
-rw-r--r--plat/imx/imx7/picopi/picopi_bl2_el3_setup.c134
-rw-r--r--plat/imx/imx7/picopi/platform.mk40
-rw-r--r--plat/imx/imx7/warp7/include/platform_def.h218
-rw-r--r--plat/imx/imx7/warp7/platform.mk37
-rw-r--r--plat/imx/imx7/warp7/warp7_bl2_el3_setup.c143
16 files changed, 1441 insertions, 0 deletions
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
new file mode 100644
index 0000000..f4f5bfc
--- /dev/null
+++ b/plat/imx/imx7/common/imx7.mk
@@ -0,0 +1,112 @@
+#
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Architecture
+$(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING))
+
+TF_CFLAGS += -mfpu=neon
+ASFLAGS += -mfpu=neon
+
+# Platform
+PLAT_INCLUDES := -Idrivers/imx/uart \
+ -Iplat/imx/common/include \
+ -Iplat/imx/imx7/include \
+ -Idrivers/imx/timer \
+ -Idrivers/imx/usdhc \
+ -Iinclude/common/tbbr
+
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
+BL2_SOURCES += common/desc_image_load.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/mmc/mmc.c \
+ drivers/io/io_block.c \
+ drivers/io/io_fip.c \
+ drivers/io/io_memmap.c \
+ drivers/io/io_storage.c \
+ drivers/imx/timer/imx_gpt.c \
+ drivers/imx/uart/imx_uart.c \
+ drivers/imx/uart/imx_crash_uart.S \
+ lib/aarch32/arm32_aeabi_divmod.c \
+ lib/aarch32/arm32_aeabi_divmod_a32.S \
+ lib/cpus/aarch32/cortex_a7.S \
+ lib/optee/optee_utils.c \
+ plat/imx/common/imx_aips.c \
+ plat/imx/common/imx_caam.c \
+ plat/imx/common/imx_clock.c \
+ plat/imx/common/imx_csu.c \
+ plat/imx/common/imx_io_mux.c \
+ plat/imx/common/imx_snvs.c \
+ plat/imx/common/imx_wdog.c \
+ plat/imx/common/imx7_clock.c \
+ plat/imx/imx7/common/imx7_bl2_mem_params_desc.c \
+ plat/imx/imx7/common/imx7_bl2_el3_common.c \
+ plat/imx/imx7/common/imx7_helpers.S \
+ plat/imx/imx7/common/imx7_image_load.c \
+ plat/imx/common/imx_io_storage.c \
+ plat/imx/common/aarch32/imx_uart_console.S \
+ ${XLAT_TABLES_LIB_SRCS}
+
+ifneq (${TRUSTED_BOARD_BOOT},0)
+
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+include drivers/auth/mbedtls/mbedtls_x509.mk
+
+AUTH_SOURCES := drivers/auth/auth_mod.c \
+ drivers/auth/crypto_mod.c \
+ drivers/auth/img_parser_mod.c \
+ drivers/auth/tbbr/tbbr_cot_common.c
+
+BL2_SOURCES += ${AUTH_SOURCES} \
+ plat/common/tbbr/plat_tbbr.c \
+ plat/imx/imx7/common/imx7_trusted_boot.c \
+ plat/imx/imx7/common/imx7_rotpk.S \
+ drivers/auth/tbbr/tbbr_cot_bl2.c
+
+ROT_KEY = $(BUILD_PLAT)/rot_key.pem
+ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
+
+$(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
+$(eval $(call MAKE_LIB_DIRS))
+
+$(BUILD_PLAT)/bl2/imx7_rotpk.o: $(ROTPK_HASH)
+
+certificates: $(ROT_KEY)
+
+$(ROT_KEY): | $(BUILD_PLAT)
+ @echo " OPENSSL $@"
+ @if [ ! -f $(ROT_KEY) ]; then \
+ ${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
+ fi
+
+$(ROTPK_HASH): $(ROT_KEY)
+ @echo " OPENSSL $@"
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
+endif
+
+# Add the build options to pack BLx images and kernel device tree
+# in the FIP if the platform requires.
+ifneq ($(BL2),)
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
+endif
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2))
+endif
+ifneq ($(HW_CONFIG),)
+$(eval $(call TOOL_ADD_IMG,HW_CONFIG,--hw-config))
+endif
+
+# Verify build config
+# -------------------
+
+ifeq (${ARCH},aarch64)
+ $(error Error: AArch64 not supported on i.mx7)
+endif
diff --git a/plat/imx/imx7/common/imx7_bl2_el3_common.c b/plat/imx/imx7/common/imx7_bl2_el3_common.c
new file mode 100644
index 0000000..4e5028c
--- /dev/null
+++ b/plat/imx/imx7/common/imx7_bl2_el3_common.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/mmc.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <lib/mmio.h>
+#include <lib/optee_utils.h>
+#include <lib/utils.h>
+
+#include <imx_aips.h>
+#include <imx_caam.h>
+#include <imx_clock.h>
+#include <imx_csu.h>
+#include <imx_gpt.h>
+#include <imx_uart.h>
+#include <imx_snvs.h>
+#include <imx_wdog.h>
+#include <imx7_def.h>
+
+#ifndef AARCH32_SP_OPTEE
+#error "Must build with OPTEE support included"
+#endif
+
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+ return IMX7_UBOOT_BASE;
+}
+
+static uint32_t imx7_get_spsr_for_bl32_entry(void)
+{
+ return SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE,
+ DISABLE_ALL_EXCEPTIONS);
+}
+
+static uint32_t imx7_get_spsr_for_bl33_entry(void)
+{
+ return SPSR_MODE32(MODE32_svc,
+ plat_get_ns_image_entrypoint() & 0x1,
+ SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
+}
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ int err = 0;
+ bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+ bl_mem_params_node_t *hw_cfg_mem_params = NULL;
+
+ bl_mem_params_node_t *pager_mem_params = NULL;
+ bl_mem_params_node_t *paged_mem_params = NULL;
+
+ assert(bl_mem_params);
+
+ switch (image_id) {
+ case BL32_IMAGE_ID:
+ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ assert(pager_mem_params);
+
+ paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+ assert(paged_mem_params);
+
+ err = parse_optee_header(&bl_mem_params->ep_info,
+ &pager_mem_params->image_info,
+ &paged_mem_params->image_info);
+ if (err != 0)
+ WARN("OPTEE header parse error.\n");
+
+ /*
+ * When ATF loads the DTB the address of the DTB is passed in
+ * arg2, if an hw config image is present use the base address
+ * as DTB address an pass it as arg2
+ */
+ hw_cfg_mem_params = get_bl_mem_params_node(HW_CONFIG_ID);
+
+ bl_mem_params->ep_info.args.arg0 =
+ bl_mem_params->ep_info.args.arg1;
+ bl_mem_params->ep_info.args.arg1 = 0;
+ if (hw_cfg_mem_params)
+ bl_mem_params->ep_info.args.arg2 =
+ hw_cfg_mem_params->image_info.image_base;
+ else
+ bl_mem_params->ep_info.args.arg2 = 0;
+ bl_mem_params->ep_info.args.arg3 = 0;
+ bl_mem_params->ep_info.spsr = imx7_get_spsr_for_bl32_entry();
+ break;
+
+ case BL33_IMAGE_ID:
+ /* AArch32 only core: OP-TEE expects NSec EP in register LR */
+ pager_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
+ assert(pager_mem_params);
+ pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
+
+ /* BL33 expects to receive the primary CPU MPID (through r0) */
+ bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
+ bl_mem_params->ep_info.spsr = imx7_get_spsr_for_bl33_entry();
+ break;
+
+ default:
+ /* Do nothing in default case */
+ break;
+ }
+
+ return err;
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+ /* Setup the MMU here */
+}
+
+static void imx7_setup_system_counter(void)
+{
+ unsigned long freq = SYS_COUNTER_FREQ_IN_TICKS;
+
+ /* Set the frequency table index to our target frequency */
+ write_cntfrq(freq);
+
+ /* Enable system counter @ frequency table index 0, halt on debug */
+ mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF,
+ CNTCR_FCREQ(0) | CNTCR_HDBG | CNTCR_EN);
+}
+
+static void imx7_setup_wdog_clocks(void)
+{
+ uint32_t wdog_en_bits = (uint32_t)WDOG_DEFAULT_CLK_SELECT;
+
+ imx_clock_set_wdog_clk_root_bits(wdog_en_bits);
+ imx_clock_enable_wdog(0);
+ imx_clock_enable_wdog(1);
+ imx_clock_enable_wdog(2);
+ imx_clock_enable_wdog(3);
+}
+
+
+/*
+ * bl2_el3_early_platform_setup()
+ * MMU off
+ */
+void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
+ u_register_t arg3, u_register_t arg4)
+{
+ static console_t console;
+ int console_scope = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME;
+
+ /* Initialize common components */
+ imx_aips_init();
+ imx_csu_init();
+ imx_snvs_init();
+ imx_gpt_ops_init(GPT1_BASE_ADDR);
+ imx_clock_init();
+ imx7_setup_system_counter();
+ imx7_setup_wdog_clocks();
+
+ /* Platform specific setup */
+ imx7_platform_setup(arg1, arg2, arg3, arg4);
+
+ /* Init UART, clock should be enabled in imx7_platform_setup() */
+ console_imx_uart_register(PLAT_IMX7_BOOT_UART_BASE,
+ PLAT_IMX7_BOOT_UART_CLK_IN_HZ,
+ PLAT_IMX7_CONSOLE_BAUDRATE,
+ &console);
+ console_set_scope(&console, console_scope);
+
+ /* Open handles to persistent storage */
+ plat_imx_io_setup();
+
+ /* Setup higher-level functionality CAAM, RTC etc */
+ imx_caam_init();
+ imx_wdog_init();
+
+ /* Print out the expected memory map */
+ VERBOSE("\tOPTEE 0x%08x-0x%08x\n", IMX7_OPTEE_BASE, IMX7_OPTEE_LIMIT);
+ VERBOSE("\tATF/BL2 0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT);
+ VERBOSE("\tSHRAM 0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT);
+ VERBOSE("\tFIP 0x%08x-0x%08x\n", IMX_FIP_BASE, IMX_FIP_LIMIT);
+ VERBOSE("\tDTB-OVERLAY 0x%08x-0x%08x\n", IMX7_DTB_OVERLAY_BASE, IMX7_DTB_OVERLAY_LIMIT);
+ VERBOSE("\tDTB 0x%08x-0x%08x\n", IMX7_DTB_BASE, IMX7_DTB_LIMIT);
+ VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", IMX7_UBOOT_BASE, IMX7_UBOOT_LIMIT);
+}
+
+/*
+ * bl2_platform_setup()
+ * MMU on - enabled by bl2_el3_plat_arch_setup()
+ */
+void bl2_platform_setup(void)
+{
+}
diff --git a/plat/imx/imx7/common/imx7_bl2_mem_params_desc.c b/plat/imx/imx7/common/imx7_bl2_mem_params_desc.c
new file mode 100644
index 0000000..f9b2983
--- /dev/null
+++ b/plat/imx/imx7/common/imx7_bl2_mem_params_desc.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <plat/common/platform.h>
+
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+ {
+ .image_id = BL32_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+ entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL32_BASE,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
+ image_info_t, 0),
+
+ .image_info.image_base = IMX7_OPTEE_BASE,
+ .image_info.image_max_size = IMX7_OPTEE_SIZE,
+
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
+ {
+ .image_id = BL32_EXTRA1_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+ entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
+ image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .image_info.image_base = IMX7_OPTEE_BASE,
+ .image_info.image_max_size = IMX7_OPTEE_SIZE,
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+ {
+ /* This is a zero sized image so we don't set base or size */
+ .image_id = BL32_EXTRA2_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+ {
+ .image_id = BL33_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+ entry_point_info_t,
+ NON_SECURE | EXECUTABLE),
+ # ifdef PRELOADED_BL33_BASE
+ .ep_info.pc = PRELOADED_BL33_BASE,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+ # else
+ .ep_info.pc = BL33_BASE,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = IMX7_UBOOT_BASE,
+ .image_info.image_max_size = IMX7_UBOOT_SIZE,
+ # endif /* PRELOADED_BL33_BASE */
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs);
diff --git a/plat/imx/imx7/common/imx7_helpers.S b/plat/imx/imx7/common/imx7_helpers.S
new file mode 100644
index 0000000..661fd29
--- /dev/null
+++ b/plat/imx/imx7/common/imx7_helpers.S
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) Linaro 2018-2019 Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <platform_def.h>
+#include <imx_hab.h>
+
+ .globl platform_mem_init
+ .globl plat_get_my_entrypoint
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
+ .globl plat_panic_handler
+
+ /* ---------------------------------------------
+ * int plat_mem_init(void)
+ * Function to initialize memory.
+ * The HAB hands off the DDR controller already
+ * setup and ready to use.
+ * Implement the mandatory function as a NOP
+ * ---------------------------------------------
+ */
+func platform_mem_init
+ bx lr
+endfunc platform_mem_init
+
+func plat_get_my_entrypoint
+ mov r0, #0
+ bx lr
+endfunc plat_get_my_entrypoint
+
+func plat_crash_console_init
+ mov_imm r0, PLAT_IMX7_BOOT_UART_BASE
+ mov_imm r1, PLAT_IMX7_BOOT_UART_CLK_IN_HZ
+ mov_imm r2, PLAT_IMX7_CONSOLE_BAUDRATE
+ b imx_crash_uart_init
+endfunc plat_crash_console_init
+
+func plat_crash_console_putc
+ mov_imm r1, PLAT_IMX7_BOOT_UART_BASE
+ b imx_crash_uart_putc
+endfunc plat_crash_console_putc
+
+func plat_crash_console_flush
+ /* Placeholder */
+ mov r0, #0
+ bx lr
+endfunc plat_crash_console_flush
+
+func plat_panic_handler
+ mov r3, #HAB_ROM_VECTOR_TABLE_FAILSAFE
+ ldr r3, [r3, #0]
+ blx r3
+endfunc plat_panic_handler
diff --git a/plat/imx/imx7/common/imx7_image_load.c b/plat/imx/imx7/common/imx7_image_load.c
new file mode 100644
index 0000000..c3e47b9
--- /dev/null
+++ b/plat/imx/imx7/common/imx7_image_load.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <plat/common/platform.h>
+
+void plat_flush_next_bl_params(void)
+{
+ flush_bl_params_desc();
+}
+
+bl_load_info_t *plat_get_bl_image_load_info(void)
+{
+ return get_bl_load_info_from_mem_params_desc();
+}
+
+bl_params_t *plat_get_next_bl_params(void)
+{
+ return get_next_bl_params_from_mem_params_desc();
+}
diff --git a/plat/imx/imx7/common/imx7_rotpk.S b/plat/imx/imx7/common/imx7_rotpk.S
new file mode 100644
index 0000000..8bd53c2
--- /dev/null
+++ b/plat/imx/imx7/common/imx7_rotpk.S
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .global imx7_rotpk_hash
+ .global imx7_rotpk_hash_end
+imx7_rotpk_hash:
+ /* DER header */
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ /* SHA256 */
+ .incbin ROTPK_HASH
+imx7_rotpk_hash_end:
diff --git a/plat/imx/imx7/common/imx7_trusted_boot.c b/plat/imx/imx7/common/imx7_trusted_boot.c
new file mode 100644
index 0000000..cd27128
--- /dev/null
+++ b/plat/imx/imx7/common/imx7_trusted_boot.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+extern char imx7_rotpk_hash[], imx7_rotpk_hash_end[];
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ *key_ptr = imx7_rotpk_hash;
+ *key_len = imx7_rotpk_hash_end - imx7_rotpk_hash;
+ *flags = ROTPK_IS_HASH;
+
+ return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ *nv_ctr = 0;
+
+ return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ return 1;
+}
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/imx/imx7/include/imx7_def.h b/plat/imx/imx7/include/imx7_def.h
new file mode 100644
index 0000000..d92a2d1
--- /dev/null
+++ b/plat/imx/imx7/include/imx7_def.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX7_DEF_H
+#define IMX7_DEF_H
+
+#include <stdint.h>
+
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void plat_imx_io_setup(void);
+void imx7_platform_setup(u_register_t arg1, u_register_t arg2,
+ u_register_t arg3, u_register_t arg4);
+
+#endif /*IMX7_DEF_H */
diff --git a/plat/imx/imx7/include/imx_hab_arch.h b/plat/imx/imx7/include/imx_hab_arch.h
new file mode 100644
index 0000000..2a34c6a
--- /dev/null
+++ b/plat/imx/imx7/include/imx_hab_arch.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef IMX_HAB_ARCH_H
+#define IMX_HAB_ARCH_H
+
+/* Define the offset the High Assurance Boot callback table is at */
+#define HAB_CALLBACK_OFFSET 0x100
+
+#endif /* IMX_HAB_ARCH_H */
diff --git a/plat/imx/imx7/include/imx_regs.h b/plat/imx/imx7/include/imx_regs.h
new file mode 100644
index 0000000..3c7e20f
--- /dev/null
+++ b/plat/imx/imx7/include/imx_regs.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_REGS_H
+#define IMX_REGS_H
+
+/* Define the processor memory map */
+
+#define OCRAM_S_ALIAS_BASE 0x00000000 /* CM4 Alias Code */
+#define ROM_HIGH_BASE 0x00008000 /* ROM high 64k */
+#define ROM_HIGH_PROT_BASE 0x00017000 /* ROM high 64k protected */
+#define CAAM_BASE 0x00020000 /* CAAM block base address */
+#define OCRAM_S_BASE 0x00180000 /* OCRAM_S */
+#define ROM_LOW_BASE 0x007f8000 /* ROM low 64k */
+#define OCRAM_BASE 0x00900000 /* OCRAM base */
+#define CM4_ALIAS_CODE_BASE 0x04000000 /* CM4 alias code */
+#define TCM_BASE 0x1fff0000 /* TCM */
+#define BOOTROM_CP_BASE 0x20020000 /* Boot ROM (all 96KB) */
+#define CM4_ALIAS_SYSTEM_BASE 0x20100000 /* CM4 Alias system */
+#define EIM_BASE 0x28000000 /* EIM */
+
+/* BootROM absolute base address */
+#define BOOTROM_BASE 0x00000000 /* BootROM */
+
+/* Peripherals like GPIO live in the AIPS range */
+#define AIPS1_BASE 0x30000000 /* AIPS1 */
+#define AIPS2_BASE 0x30400000 /* AIPS2 */
+#define AIPS3_BASE 0x30800000 /* AIPS3 */
+#define AIPS4_BASE 0x30c00000 /* AIPS4 */
+
+/* ARM peripherals like GIC */
+#define ARM_PERIPHERAL_GIC_BASE 0x31000000 /* GIC */
+
+/* Configuration ports */
+#define GPV0_BASE 0x32000000 /* Main config port */
+#define GPV1_BASE 0x32100000 /* Wakeup config port */
+#define GPV2_BASE 0x32200000 /* Per_s config port */
+#define GPV3_BASE 0x32300000 /* Per_m config port */
+#define GPV4_BASE 0x32400000 /* Enet config port */
+#define GPV5_BASE 0x32500000 /* Display config port */
+#define GPV6_BASE 0x32600000 /* M4 conig port */
+
+/* MMAP peripherals - like APBH DMA */
+#define APBH_DMA_BASE 0x33000000 /* APBH DMA block */
+
+/* QSPI RX BUFFERS */
+#define QSPI_RX_BUFFER_BASE 0x34000000 /* QSPI RX buffers */
+
+/* QSPI1 FLASH */
+#define QSPI_FLASH_BASE 0x60000000 /* QSPI1 flash */
+
+/* AIPS1 block addresses */
+#define AIPSTZ_CONFIG_OFFSET 0x001f0000
+#define CCM_BASE (AIPS1_BASE + 0x380000)
+
+/* Define the maximum number of UART blocks on this SoC */
+#define MXC_UART1_BASE (AIPS3_BASE + 0x060000)
+#define MXC_UART2_BASE (AIPS3_BASE + 0x070000)
+#define MXC_UART3_BASE (AIPS3_BASE + 0x080000)
+#define MXC_UART4_BASE (AIPS3_BASE + 0x260000)
+#define MXC_UART5_BASE (AIPS3_BASE + 0x270000)
+#define MXC_UART6_BASE (AIPS3_BASE + 0x280000)
+#define MXC_UART7_BASE (AIPS3_BASE + 0x290000)
+#define MXC_MAX_UART_NUM 0x07
+
+/* Define the maximum number of USDHCI blocks on this SoC */
+#define MXC_MAX_USDHC_NUM 3
+
+/* Define the number of CSU registers for this SoC */
+#define MXC_MAX_CSU_REGS 0x40
+#define CSU_BASE (AIPS1_BASE + 0x3E0000)
+
+/* IO Mux block base */
+#define MXC_IO_MUXC_BASE (AIPS1_BASE + 0x330000)
+
+/* SNVS base */
+#define SNVS_BASE (AIPS1_BASE + 0x370000)
+
+/* GP Timer base */
+#define GPT1_BASE_ADDR (AIPS1_BASE + 0x2d0000)
+
+/* MMC base */
+#define USDHC1_BASE (AIPS1_BASE + 0xb40000)
+#define USDHC2_BASE (AIPS1_BASE + 0xb50000)
+#define USDHC3_BASE (AIPS1_BASE + 0xb60000)
+
+/* Arm optional memory mapped counter module base address */
+#define SYS_CNTCTL_BASE (AIPS2_BASE + 0x2c0000)
+
+/* Define CAAM AIPS offset */
+#define CAAM_AIPS_BASE (AIPS3_BASE + 0x100000)
+#define CAAM_NUM_JOB_RINGS 0x03
+#define CAAM_NUM_RTIC 0x04
+#define CAAM_NUM_DECO 0x01
+
+/* Define watchdog base addresses */
+#define WDOG1_BASE (AIPS1_BASE + 0x280000)
+#define WDOG2_BASE (AIPS1_BASE + 0x290000)
+#define WDOG3_BASE (AIPS1_BASE + 0x2A0000)
+#define WDOG4_BASE (AIPS1_BASE + 0x280000)
+
+/* Define the maximum number of WDOG blocks on this SoC */
+#define MXC_MAX_WDOG_NUM 0x04
+
+#endif /* IMX_REGS_H */
diff --git a/plat/imx/imx7/picopi/include/platform_def.h b/plat/imx/imx7/picopi/include/platform_def.h
new file mode 100644
index 0000000..5f2975d
--- /dev/null
+++ b/plat/imx/imx7/picopi/include/platform_def.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <plat/common/common_def.h>
+
+#define PLATFORM_STACK_SIZE 0x1000
+
+#define PLATFORM_MAX_CPUS_PER_CLUSTER U(2)
+#define PLATFORM_CLUSTER_COUNT U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
+
+#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT
+
+#define PICOPI_PRIMARY_CPU U(0)
+
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1
+
+#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_OFF_STATE 2
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN 0
+
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET 1
+
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains.
+ */
+#define PLAT_LOCAL_STATE_OFF 2
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH 4
+#define PLAT_LOCAL_PSTATE_MASK ((1 << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ * i.MX7 has a 32 byte cacheline size
+ * i.MX 7Dual Applications Processor Reference Manual, Rev. 1, 01/2018 pg 298
+ */
+#define CACHE_WRITEBACK_SHIFT 4
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Partition memory into secure BootROM, OCRAM_S, non-secure DRAM, secure DRAM
+ */
+#define BOOT_ROM_BASE 0x00000000
+#define BOOT_ROM_SIZE 0x00020000
+
+#define OCRAM_S_BASE 0x00180000
+#define OCRAM_S_SIZE 0x00008000
+
+/* Controller maps 2GB, board contains 512 MB. 0x80000000 - 0xa0000000 */
+#define DRAM_BASE 0x80000000
+#define DRAM_SIZE 0x20000000
+#define DRAM_LIMIT (DRAM_BASE + DRAM_SIZE)
+
+/* Place OPTEE at minus 32 MB from the end of memory. 0x9e000000 - 0xa0000000 */
+#define IMX7_OPTEE_SIZE 0x02000000
+#define IMX7_OPTEE_BASE (DRAM_LIMIT - IMX7_OPTEE_SIZE)
+#define IMX7_OPTEE_LIMIT (IMX7_OPTEE_BASE + IMX7_OPTEE_SIZE)
+
+/* Place ATF directly beneath OPTEE. 0x9df00000 - 0x9e000000 */
+#define BL2_RAM_SIZE 0x00100000
+#define BL2_RAM_BASE (IMX7_OPTEE_BASE - BL2_RAM_SIZE)
+#define BL2_RAM_LIMIT (BL2_RAM_BASE + BL2_RAM_SIZE)
+
+/* Optional Mailbox. Only relevant on i.MX7D. 0x9deff000 - 0x9df00000*/
+#define SHARED_RAM_SIZE 0x00001000
+#define SHARED_RAM_BASE (BL2_RAM_BASE - SHARED_RAM_SIZE)
+#define SHARED_RAM_LIMIT (SHARED_RAM_BASE + SHARED_RAM_SIZE)
+
+/* Define the absolute location of u-boot 0x87800000 - 0x87900000 */
+#define IMX7_UBOOT_SIZE 0x00100000
+#define IMX7_UBOOT_BASE (DRAM_BASE + 0x7800000)
+#define IMX7_UBOOT_LIMIT (IMX7_UBOOT_BASE + IMX7_UBOOT_SIZE)
+
+/* Define FIP image absolute location 0x80000000 - 0x80100000 */
+#define IMX_FIP_SIZE 0x00100000
+#define IMX_FIP_BASE (DRAM_BASE)
+#define IMX_FIP_LIMIT (IMX_FIP_BASE + IMX_FIP_SIZE)
+
+/* Define FIP image location at 1MB offset */
+#define IMX_FIP_MMC_BASE (1024 * 1024)
+
+/* Define the absolute location of DTB 0x83000000 - 0x83100000 */
+#define IMX7_DTB_SIZE 0x00100000
+#define IMX7_DTB_BASE (DRAM_BASE + 0x03000000)
+#define IMX7_DTB_LIMIT (IMX7_DTB_BASE + IMX7_DTB_SIZE)
+
+/* Define the absolute location of DTB Overlay 0x83100000 - 0x83101000 */
+#define IMX7_DTB_OVERLAY_SIZE 0x00001000
+#define IMX7_DTB_OVERLAY_BASE IMX7_DTB_LIMIT
+#define IMX7_DTB_OVERLAY_LIMIT (IMX7_DTB_OVERLAY_BASE + \
+ IMX7_DTB_OVERLAY_SIZE)
+/*
+ * BL2 specific defines.
+ *
+ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
+ * size plus a little space for growth.
+ */
+#define BL2_BASE BL2_RAM_BASE
+#define BL2_LIMIT (BL2_RAM_BASE + BL2_RAM_SIZE)
+
+/*
+ * BL3-2/OPTEE
+ */
+# define BL32_BASE IMX7_OPTEE_BASE
+# define BL32_LIMIT (IMX7_OPTEE_BASE + IMX7_OPTEE_SIZE)
+
+/*
+ * BL3-3/U-BOOT
+ */
+#define BL33_BASE IMX7_UBOOT_BASE
+#define BL33_LIMIT (IMX7_UBOOT_BASE + IMX7_UBOOT_SIZE)
+
+/*
+ * ATF's view of memory
+ *
+ * 0xa0000000 +-----------------+
+ * | DDR | BL32/OPTEE
+ * 0x9e000000 +-----------------+
+ * | DDR | BL23 ATF
+ * 0x9df00000 +-----------------+
+ * | DDR | Shared MBOX RAM
+ * 0x9de00000 +-----------------+
+ * | DDR | Unallocated
+ * 0x87900000 +-----------------+
+ * | DDR | BL33/U-BOOT
+ * 0x87800000 +-----------------+
+ * | DDR | Unallocated
+ * 0x83100000 +-----------------+
+ * | DDR | DTB
+ * 0x83000000 +-----------------+
+ * | DDR | Unallocated
+ * 0x80100000 +-----------------+
+ * | DDR | FIP
+ * 0x80000000 +-----------------+
+ * | SOC I/0 |
+ * 0x00a00000 +-----------------+
+ * | OCRAM | Not used
+ * 0x00900000 +-----------------+
+ * | SOC I/0 |
+ * 0x00188000 +-----------------+
+ * | OCRAM_S | Not used
+ * 0x00180000 +-----------------+
+ * | SOC I/0 |
+ * 0x00020000 +-----------------+
+ * | BootROM | BL1
+ * 0x00000000 +-----------------+
+ */
+
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#define MAX_MMAP_REGIONS 10
+#define MAX_XLAT_TABLES 6
+#define MAX_IO_DEVICES 2
+#define MAX_IO_HANDLES 3
+#define MAX_IO_BLOCK_DEVICES 1
+
+/* UART defines */
+#define PLAT_IMX7_BOOT_UART_BASE MXC_UART5_BASE
+#define PLAT_IMX7_BOOT_UART_CLK_IN_HZ 24000000
+#define PLAT_IMX7_CONSOLE_BAUDRATE 115200
+
+/* MMC defines */
+#ifndef PLAT_PICOPI_SD
+#define PLAT_PICOPI_SD 3
+#endif
+
+#if PLAT_PICOPI_SD == 1
+#define PLAT_PICOPI_BOOT_MMC_BASE USDHC1_BASE
+#endif /* PLAT_PICOPI_SD == 1 */
+
+#if PLAT_PICOPI_SD == 2
+#define PLAT_PICOPI_BOOT_MMC_BASE USDHC2_BASE
+#endif /* PLAT_PICOPI_SD == 2 */
+
+#if PLAT_PICOPI_SD == 3
+#define PLAT_PICOPI_BOOT_MMC_BASE USDHC3_BASE
+#endif /* PLAT_PICOPI_SD == 3 */
+
+/*
+ * System counter
+ */
+#define SYS_COUNTER_FREQ_IN_TICKS 8000000 /* 8 MHz */
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx7/picopi/picopi_bl2_el3_setup.c b/plat/imx/imx7/picopi/picopi_bl2_el3_setup.c
new file mode 100644
index 0000000..2df96ae
--- /dev/null
+++ b/plat/imx/imx7/picopi/picopi_bl2_el3_setup.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/mmc.h>
+#include <lib/utils.h>
+
+#include <imx_caam.h>
+#include <imx_clock.h>
+#include <imx_io_mux.h>
+#include <imx_uart.h>
+#include <imx_usdhc.h>
+#include <imx7_def.h>
+
+#define UART5_CLK_SELECT (CCM_TARGET_ROOT_ENABLE |\
+ CCM_TRGT_MUX_UART5_CLK_ROOT_OSC_24M)
+
+#define USDHC_CLK_SELECT (CCM_TARGET_ROOT_ENABLE |\
+ CCM_TRGT_MUX_NAND_USDHC_BUS_CLK_ROOT_AHB |\
+ CCM_TARGET_POST_PODF(2))
+
+#define USB_CLK_SELECT (CCM_TARGET_ROOT_ENABLE |\
+ CCM_TRGT_MUX_USB_HSIC_CLK_ROOT_SYS_PLL)
+
+#define PICOPI_UART5_RX_MUX \
+ IOMUXC_SW_MUX_CTL_PAD_I2C4_SCL_ALT1_UART5_RX_DATA
+
+#define PICOPI_UART5_TX_MUX \
+ IOMUXC_SW_MUX_CTL_PAD_I2C4_SDA_ALT1_UART5_TX_DATA
+
+#define PICOPI_SD3_FEATURES \
+ (IOMUXC_SW_PAD_CTL_PAD_SD3_PU_47K | \
+ IOMUXC_SW_PAD_CTL_PAD_SD3_PE | \
+ IOMUXC_SW_PAD_CTL_PAD_SD3_HYS | \
+ IOMUXC_SW_PAD_CTL_PAD_SD3_SLEW_SLOW | \
+ IOMUXC_SW_PAD_CTL_PAD_SD3_DSE_3_X6)
+
+static struct mmc_device_info mmc_info;
+
+static void picopi_setup_pinmux(void)
+{
+ /* Configure UART5 TX */
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_I2C4_SDA_OFFSET,
+ PICOPI_UART5_TX_MUX);
+ /* Configure UART5 RX */
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_I2C4_SCL_OFFSET,
+ PICOPI_UART5_RX_MUX);
+
+ /* Configure USDHC3 */
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_CLK_OFFSET, 0);
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_CMD_OFFSET, 0);
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA0_OFFSET, 0);
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA1_OFFSET, 0);
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA2_OFFSET, 0);
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA3_OFFSET, 0);
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA4_OFFSET, 0);
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA5_OFFSET, 0);
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA6_OFFSET, 0);
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA7_OFFSET, 0);
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO14_OFFSET,
+ IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO14_ALT1_SD3_CD_B);
+
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_CLK_OFFSET,
+ PICOPI_SD3_FEATURES);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_CMD_OFFSET,
+ PICOPI_SD3_FEATURES);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA0_OFFSET,
+ PICOPI_SD3_FEATURES);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA1_OFFSET,
+ PICOPI_SD3_FEATURES);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA2_OFFSET,
+ PICOPI_SD3_FEATURES);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA3_OFFSET,
+ PICOPI_SD3_FEATURES);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA4_OFFSET,
+ PICOPI_SD3_FEATURES);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA5_OFFSET,
+ PICOPI_SD3_FEATURES);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA6_OFFSET,
+ PICOPI_SD3_FEATURES);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA7_OFFSET,
+ PICOPI_SD3_FEATURES);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO14_OFFSET,
+ PICOPI_SD3_FEATURES);
+}
+
+static void picopi_usdhc_setup(void)
+{
+ imx_usdhc_params_t params;
+
+ zeromem(&params, sizeof(imx_usdhc_params_t));
+ params.reg_base = PLAT_PICOPI_BOOT_MMC_BASE;
+ params.clk_rate = 25000000;
+ params.bus_width = MMC_BUS_WIDTH_8;
+ mmc_info.mmc_dev_type = MMC_IS_EMMC;
+ imx_usdhc_init(&params, &mmc_info);
+}
+
+static void picopi_setup_usb_clocks(void)
+{
+ uint32_t usb_en_bits = (uint32_t)USB_CLK_SELECT;
+
+ imx_clock_set_usb_clk_root_bits(usb_en_bits);
+ imx_clock_enable_usb(CCM_CCGR_ID_USB_IPG);
+ imx_clock_enable_usb(CCM_CCGR_ID_USB_PHY_480MCLK);
+ imx_clock_enable_usb(CCM_CCGR_ID_USB_OTG1_PHY);
+ imx_clock_enable_usb(CCM_CCGR_ID_USB_OTG2_PHY);
+}
+
+void imx7_platform_setup(u_register_t arg1, u_register_t arg2,
+ u_register_t arg3, u_register_t arg4)
+{
+ uint32_t uart5_en_bits = (uint32_t)UART5_CLK_SELECT;
+ uint32_t usdhc_clock_sel = PLAT_PICOPI_SD - 1;
+
+ /* Initialize clocks etc */
+ imx_clock_enable_uart(4, uart5_en_bits);
+ imx_clock_enable_usdhc(usdhc_clock_sel, USDHC_CLK_SELECT);
+
+ picopi_setup_usb_clocks();
+
+ /* Setup pin-muxes */
+ picopi_setup_pinmux();
+
+ picopi_usdhc_setup();
+}
diff --git a/plat/imx/imx7/picopi/platform.mk b/plat/imx/imx7/picopi/platform.mk
new file mode 100644
index 0000000..5901001
--- /dev/null
+++ b/plat/imx/imx7/picopi/platform.mk
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Include imx7 common
+include plat/imx/imx7/common/imx7.mk
+
+# Platform
+PLAT_INCLUDES += -Iplat/imx/imx7/picopi/include \
+
+BL2_SOURCES += drivers/imx/usdhc/imx_usdhc.c \
+ plat/imx/imx7/picopi/picopi_bl2_el3_setup.c \
+
+# Build config flags
+# ------------------
+
+ARM_CORTEX_A7 := yes
+WORKAROUND_CVE_2017_5715 := 0
+
+RESET_TO_BL31 := 0
+
+# Non-TF Boot ROM
+BL2_AT_EL3 := 1
+
+# Indicate single-core
+COLD_BOOT_SINGLE_CPU := 1
+
+# Have different sections for code and rodata
+SEPARATE_CODE_AND_RODATA := 1
+
+# Use Coherent memory
+USE_COHERENT_MEM := 1
+
+# Use multi console API
+MULTI_CONSOLE_API := 1
+
+PLAT_PICOPI_UART :=5
+$(eval $(call add_define,PLAT_PICOPI_UART))
diff --git a/plat/imx/imx7/warp7/include/platform_def.h b/plat/imx/imx7/warp7/include/platform_def.h
new file mode 100644
index 0000000..683e50d
--- /dev/null
+++ b/plat/imx/imx7/warp7/include/platform_def.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <plat/common/common_def.h>
+
+#define PLATFORM_STACK_SIZE 0x1000
+
+#define PLATFORM_MAX_CPUS_PER_CLUSTER U(2)
+#define PLATFORM_CLUSTER_COUNT U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
+#define PLATFORM_CLUSTER1_CORE_COUNT U(0)
+
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \
+ PLATFORM_CLUSTER1_CORE_COUNT)
+
+#define WARP7_PRIMARY_CPU U(0)
+
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1
+
+#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_OFF_STATE 2
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN 0
+
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET 1
+
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains.
+ */
+#define PLAT_LOCAL_STATE_OFF 2
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH 4
+#define PLAT_LOCAL_PSTATE_MASK ((1 << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ * i.MX7 has a 32 byte cacheline size
+ * i.MX 7Solo Applications Processor Reference Manual, Rev. 0.1, 08/2016 pg 244
+ */
+#define CACHE_WRITEBACK_SHIFT 4
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Partition memory into secure BootROM, OCRAM_S, non-secure DRAM, secure DRAM
+ */
+#define BOOT_ROM_BASE 0x00000000
+#define BOOT_ROM_SIZE 0x00020000
+
+#define OCRAM_S_BASE 0x00180000
+#define OCRAM_S_SIZE 0x00008000
+
+/* Controller maps 2GB, board contains 512 MB. 0x80000000 - 0xa0000000 */
+#define DRAM_BASE 0x80000000
+#define DRAM_SIZE 0x20000000
+#define DRAM_LIMIT (DRAM_BASE + DRAM_SIZE)
+
+/* Place OPTEE at minus 32 MB from the end of memory. 0x9e000000 - 0xa0000000 */
+#define IMX7_OPTEE_SIZE 0x02000000
+#define IMX7_OPTEE_BASE (DRAM_LIMIT - IMX7_OPTEE_SIZE)
+#define IMX7_OPTEE_LIMIT (IMX7_OPTEE_BASE + IMX7_OPTEE_SIZE)
+
+/* Place ATF directly beneath OPTEE. 0x9df00000 - 0x9e000000 */
+#define BL2_RAM_SIZE 0x00100000
+#define BL2_RAM_BASE (IMX7_OPTEE_BASE - BL2_RAM_SIZE)
+#define BL2_RAM_LIMIT (BL2_RAM_BASE + BL2_RAM_SIZE)
+
+/* Optional Mailbox. Only relevant on i.MX7D. 0x9deff000 - 0x9df00000*/
+#define SHARED_RAM_SIZE 0x00001000
+#define SHARED_RAM_BASE (BL2_RAM_BASE - SHARED_RAM_SIZE)
+#define SHARED_RAM_LIMIT (SHARED_RAM_BASE + SHARED_RAM_SIZE)
+
+/* Define the absolute location of u-boot 0x87800000 - 0x87900000 */
+#define IMX7_UBOOT_SIZE 0x00100000
+#define IMX7_UBOOT_BASE (DRAM_BASE + 0x7800000)
+#define IMX7_UBOOT_LIMIT (IMX7_UBOOT_BASE + IMX7_UBOOT_SIZE)
+
+/* Define FIP image absolute location 0x80000000 - 0x80100000 */
+#define IMX_FIP_SIZE 0x00100000
+#define IMX_FIP_BASE (DRAM_BASE)
+#define IMX_FIP_LIMIT (IMX_FIP_BASE + IMX_FIP_SIZE)
+
+/* Define FIP image location at 1MB offset */
+#define IMX_FIP_MMC_BASE (1024 * 1024)
+
+/* Define the absolute location of DTB 0x83000000 - 0x83100000 */
+#define IMX7_DTB_SIZE 0x00100000
+#define IMX7_DTB_BASE (DRAM_BASE + 0x03000000)
+#define IMX7_DTB_LIMIT (IMX7_DTB_BASE + IMX7_DTB_SIZE)
+
+/* Define the absolute location of DTB Overlay 0x83100000 - 0x83101000 */
+#define IMX7_DTB_OVERLAY_SIZE 0x00001000
+#define IMX7_DTB_OVERLAY_BASE IMX7_DTB_LIMIT
+#define IMX7_DTB_OVERLAY_LIMIT (IMX7_DTB_OVERLAY_BASE + \
+ IMX7_DTB_OVERLAY_SIZE)
+
+/*
+ * BL2 specific defines.
+ *
+ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
+ * size plus a little space for growth.
+ */
+#define BL2_BASE BL2_RAM_BASE
+#define BL2_LIMIT (BL2_RAM_BASE + BL2_RAM_SIZE)
+
+/*
+ * BL3-2/OPTEE
+ */
+# define BL32_BASE IMX7_OPTEE_BASE
+# define BL32_LIMIT (IMX7_OPTEE_BASE + IMX7_OPTEE_SIZE)
+
+/*
+ * BL3-3/U-BOOT
+ */
+#define BL33_BASE IMX7_UBOOT_BASE
+#define BL33_LIMIT (IMX7_UBOOT_BASE + IMX7_UBOOT_SIZE)
+
+/*
+ * ATF's view of memory
+ *
+ * 0xa0000000 +-----------------+
+ * | DDR | BL32/OPTEE
+ * 0x9e000000 +-----------------+
+ * | DDR | BL23 ATF
+ * 0x9df00000 +-----------------+
+ * | DDR | Shared MBOX RAM
+ * 0x9de00000 +-----------------+
+ * | DDR | Unallocated
+ * 0x87900000 +-----------------+
+ * | DDR | BL33/U-BOOT
+ * 0x87800000 +-----------------+
+ * | DDR | Unallocated
+ * 0x83101000 +-----------------+
+ * | DDR | DTB Overlay
+ * 0x83100000 +-----------------+
+ * | DDR | DTB
+ * 0x83000000 +-----------------+
+ * | DDR | Unallocated
+ * 0x80100000 +-----------------+
+ * | DDR | FIP
+ * 0x80000000 +-----------------+
+ * | SOC I/0 |
+ * 0x00a00000 +-----------------+
+ * | OCRAM | Not used
+ * 0x00900000 +-----------------+
+ * | SOC I/0 |
+ * 0x00188000 +-----------------+
+ * | OCRAM_S | Not used
+ * 0x00180000 +-----------------+
+ * | SOC I/0 |
+ * 0x00020000 +-----------------+
+ * | BootROM | BL1
+ * 0x00000000 +-----------------+
+ */
+
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#define MAX_MMAP_REGIONS 10
+#define MAX_XLAT_TABLES 6
+#define MAX_IO_DEVICES 2
+#define MAX_IO_HANDLES 3
+#define MAX_IO_BLOCK_DEVICES 1U
+
+/* UART defines */
+#if PLAT_WARP7_UART == 1
+#define PLAT_WARP7_UART_BASE MXC_UART1_BASE
+#elif PLAT_WARP7_UART == 6
+#define IMX_UART_DTE
+#define PLAT_WARP7_UART_BASE MXC_UART6_BASE
+#else
+#error "define PLAT_WARP7_UART=1 or PLAT_WARP7_UART=6"
+#endif
+
+#define PLAT_IMX7_BOOT_UART_BASE PLAT_WARP7_UART_BASE
+#define PLAT_IMX7_BOOT_UART_CLK_IN_HZ 24000000
+#define PLAT_IMX7_CONSOLE_BAUDRATE 115200
+
+/* MMC defines */
+#ifndef PLAT_WARP7_SD
+#define PLAT_WARP7_SD 3
+#endif
+
+#if PLAT_WARP7_SD == 1
+#define PLAT_WARP7_BOOT_MMC_BASE USDHC1_BASE
+#endif /* PLAT_WARP7_SD == 1 */
+
+#if PLAT_WARP7_SD == 2
+#define PLAT_WARP7_BOOT_MMC_BASE USDHC2_BASE
+#endif /* PLAT_WARP7_SD == 2 */
+
+#if PLAT_WARP7_SD == 3
+#define PLAT_WARP7_BOOT_MMC_BASE USDHC3_BASE
+#endif /* PLAT_WARP7_SD == 3 */
+
+/*
+ * System counter
+ */
+#define SYS_COUNTER_FREQ_IN_TICKS 8000000 /* 8 MHz */
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx7/warp7/platform.mk b/plat/imx/imx7/warp7/platform.mk
new file mode 100644
index 0000000..ea0f001
--- /dev/null
+++ b/plat/imx/imx7/warp7/platform.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Include imx7 common
+include plat/imx/imx7/common/imx7.mk
+
+# Platform
+PLAT_INCLUDES += -Iplat/imx/imx7/warp7/include
+
+BL2_SOURCES += drivers/imx/usdhc/imx_usdhc.c \
+ plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
+
+# Build config flags
+# ------------------
+
+ARM_CORTEX_A7 := yes
+WORKAROUND_CVE_2017_5715 := 0
+
+RESET_TO_BL31 := 0
+
+# Non-TF Boot ROM
+BL2_AT_EL3 := 1
+
+# Indicate single-core
+COLD_BOOT_SINGLE_CPU := 1
+
+# Have different sections for code and rodata
+SEPARATE_CODE_AND_RODATA := 1
+
+# Use Coherent memory
+USE_COHERENT_MEM := 1
+
+PLAT_WARP7_UART :=1
+$(eval $(call add_define,PLAT_WARP7_UART))
diff --git a/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c b/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
new file mode 100644
index 0000000..ec13ade
--- /dev/null
+++ b/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/mmc.h>
+#include <lib/utils.h>
+
+#include <imx_caam.h>
+#include <imx_clock.h>
+#include <imx_io_mux.h>
+#include <imx_uart.h>
+#include <imx_usdhc.h>
+#include <imx7_def.h>
+
+#define UART1_CLK_SELECT (CCM_TARGET_ROOT_ENABLE |\
+ CCM_TRGT_MUX_UART1_CLK_ROOT_OSC_24M)
+
+#define UART6_CLK_SELECT (CCM_TARGET_ROOT_ENABLE |\
+ CCM_TRGT_MUX_UART6_CLK_ROOT_OSC_24M)
+
+#define USDHC_CLK_SELECT (CCM_TARGET_ROOT_ENABLE |\
+ CCM_TRGT_MUX_NAND_USDHC_BUS_CLK_ROOT_AHB |\
+ CCM_TARGET_POST_PODF(2))
+
+#define USB_CLK_SELECT (CCM_TARGET_ROOT_ENABLE |\
+ CCM_TRGT_MUX_USB_HSIC_CLK_ROOT_SYS_PLL)
+
+#define WARP7_UART1_TX_MUX \
+ IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA_ALT0_UART1_TX_DATA
+
+#define WARP7_UART1_TX_FEATURES \
+ (IOMUXC_SW_PAD_CTL_PAD_UART1_TX_DATA_PS_3_100K_PU | \
+ IOMUXC_SW_PAD_CTL_PAD_UART1_TX_DATA_PE_EN | \
+ IOMUXC_SW_PAD_CTL_PAD_UART1_TX_DATA_HYS_EN | \
+ IOMUXC_SW_PAD_CTL_PAD_UART1_TX_DATA_DSE_1_X4)
+
+#define WARP7_UART1_RX_MUX \
+ IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA_ALT0_UART1_RX_DATA
+
+#define WARP7_UART1_RX_FEATURES \
+ (IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA_PS_3_100K_PU | \
+ IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA_PE_EN | \
+ IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA_HYS_EN | \
+ IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA_DSE_1_X4)
+
+#define WARP7_UART6_TX_MUX \
+ IOMUXC_SW_MUX_CTL_PAD_ECSPI1_MOSI_ALT1_UART6_TX_DATA
+
+#define WARP7_UART6_TX_FEATURES \
+ (IOMUXC_SW_PAD_CTL_PAD_ECSPI1_MOSI_PS_3_100K_PU | \
+ IOMUXC_SW_PAD_CTL_PAD_ECSPI1_MOSI_PE_EN | \
+ IOMUXC_SW_PAD_CTL_PAD_ECSPI1_MOSI_HYS_EN | \
+ IOMUXC_SW_PAD_CTL_PAD_ECSPI1_MOSI_DSE_1_X4)
+
+#define WARP7_UART6_RX_MUX \
+ IOMUXC_SW_MUX_CTL_PAD_ECSPI1_SCLK_ALT1_UART6_RX_DATA
+
+#define WARP7_UART6_RX_FEATURES \
+ (IOMUXC_SW_PAD_CTL_PAD_ECSPI1_SCLK_PS_3_100K_PU | \
+ IOMUXC_SW_PAD_CTL_PAD_ECSPI1_SCLK_PE_EN | \
+ IOMUXC_SW_PAD_CTL_PAD_ECSPI1_SCLK_HYS_EN | \
+ IOMUXC_SW_PAD_CTL_PAD_ECSPI1_SCLK_DSE_1_X4)
+
+static struct mmc_device_info mmc_info;
+
+static void warp7_setup_pinmux(void)
+{
+ /* Configure UART1 TX */
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA_OFFSET,
+ WARP7_UART1_TX_MUX);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_UART1_TX_DATA_OFFSET,
+ WARP7_UART1_TX_FEATURES);
+
+ /* Configure UART1 RX */
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA_OFFSET,
+ WARP7_UART1_RX_MUX);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA_OFFSET,
+ WARP7_UART1_RX_FEATURES);
+
+ /* Configure UART6 TX */
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_ECSPI1_MOSI_OFFSET,
+ WARP7_UART6_TX_MUX);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_ECSPI1_MOSI_OFFSET,
+ WARP7_UART6_TX_FEATURES);
+
+ /* Configure UART6 RX */
+ imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_ECSPI1_SCLK_OFFSET,
+ WARP7_UART6_RX_MUX);
+ imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_ECSPI1_SCLK_OFFSET,
+ WARP7_UART6_RX_FEATURES);
+}
+
+static void warp7_usdhc_setup(void)
+{
+ imx_usdhc_params_t params;
+
+ zeromem(&params, sizeof(imx_usdhc_params_t));
+ params.reg_base = PLAT_WARP7_BOOT_MMC_BASE;
+ params.clk_rate = 25000000;
+ params.bus_width = MMC_BUS_WIDTH_8;
+ mmc_info.mmc_dev_type = MMC_IS_EMMC;
+ imx_usdhc_init(&params, &mmc_info);
+}
+
+static void warp7_setup_usb_clocks(void)
+{
+ uint32_t usb_en_bits = (uint32_t)USB_CLK_SELECT;
+
+ imx_clock_set_usb_clk_root_bits(usb_en_bits);
+ imx_clock_enable_usb(CCM_CCGR_ID_USB_IPG);
+ imx_clock_enable_usb(CCM_CCGR_ID_USB_PHY_480MCLK);
+ imx_clock_enable_usb(CCM_CCGR_ID_USB_OTG1_PHY);
+ imx_clock_enable_usb(CCM_CCGR_ID_USB_OTG2_PHY);
+}
+
+void imx7_platform_setup(u_register_t arg1, u_register_t arg2,
+ u_register_t arg3, u_register_t arg4)
+{
+ uint32_t uart1_en_bits = (uint32_t)UART1_CLK_SELECT;
+ uint32_t uart6_en_bits = (uint32_t)UART6_CLK_SELECT;
+ uint32_t usdhc_clock_sel = PLAT_WARP7_SD - 1;
+
+ /* Initialize clocks etc */
+ imx_clock_enable_uart(0, uart1_en_bits);
+ imx_clock_enable_uart(5, uart6_en_bits);
+
+ imx_clock_enable_usdhc(usdhc_clock_sel, USDHC_CLK_SELECT);
+
+ warp7_setup_usb_clocks();
+
+ /* Setup pin-muxes */
+ warp7_setup_pinmux();
+
+ warp7_usdhc_setup();
+}