From 27132f13ca871dc3cf1aa6938995284cf5016e00 Mon Sep 17 00:00:00 2001 From: Rex-BC Chen Date: Tue, 28 Sep 2021 11:24:09 +0800 Subject: [PATCH] feat(mt8186): initialize platform for MediaTek MT8186 - Add basic platform setup. - Add MT8186 documentation at docs/plat/. - Add generic CPU helper functions. - Add basic register address. TEST=build pass BUG=b:202871018 Signed-off-by: Rex-BC Chen Change-Id: Id3e2f46a8c3ab2f3e29137e508d4c671e8f4aad5 --- .cz.json | 4 + docs/plat/index.rst | 1 + docs/plat/mt8186.rst | 21 ++++ plat/mediatek/mt8186/aarch64/plat_helpers.S | 45 ++++++++ .../mediatek/mt8186/aarch64/platform_common.c | 44 ++++++++ plat/mediatek/mt8186/bl31_plat_setup.c | 94 ++++++++++++++++ plat/mediatek/mt8186/include/plat_helpers.h | 12 +++ plat/mediatek/mt8186/include/plat_macros.S | 37 +++++++ plat/mediatek/mt8186/include/plat_private.h | 18 ++++ plat/mediatek/mt8186/include/platform_def.h | 102 ++++++++++++++++++ plat/mediatek/mt8186/plat_pm.c | 18 ++++ plat/mediatek/mt8186/plat_topology.c | 70 ++++++++++++ plat/mediatek/mt8186/platform.mk | 51 +++++++++ 13 files changed, 517 insertions(+) create mode 100644 docs/plat/mt8186.rst create mode 100644 plat/mediatek/mt8186/aarch64/plat_helpers.S create mode 100644 plat/mediatek/mt8186/aarch64/platform_common.c create mode 100644 plat/mediatek/mt8186/bl31_plat_setup.c create mode 100644 plat/mediatek/mt8186/include/plat_helpers.h create mode 100644 plat/mediatek/mt8186/include/plat_macros.S create mode 100644 plat/mediatek/mt8186/include/plat_private.h create mode 100644 plat/mediatek/mt8186/include/platform_def.h create mode 100644 plat/mediatek/mt8186/plat_pm.c create mode 100644 plat/mediatek/mt8186/plat_topology.c create mode 100644 plat/mediatek/mt8186/platform.mk diff --git a/.cz.json b/.cz.json index 5447f1704..5ed24f4a9 100644 --- a/.cz.json +++ b/.cz.json @@ -194,6 +194,10 @@ { "title": "MT8195", "scopes": ["mt8195", "plat/mediatek/me8195", "plat/mediatek/mt8195", "plat/mdeiatek/mt8195"] + }, + { + "title": "MT8186", + "scopes": ["mt8186", "plat/mediatek/mt8186"] } ] }, diff --git a/docs/plat/index.rst b/docs/plat/index.rst index 5848005ba..eadd94621 100644 --- a/docs/plat/index.rst +++ b/docs/plat/index.rst @@ -20,6 +20,7 @@ Platform Ports intel-stratix10 marvell/index mt8183 + mt8186 mt8192 mt8195 nvidia-tegra diff --git a/docs/plat/mt8186.rst b/docs/plat/mt8186.rst new file mode 100644 index 000000000..16b833a3f --- /dev/null +++ b/docs/plat/mt8186.rst @@ -0,0 +1,21 @@ +MediaTek 8186 +============= + +MediaTek 8186 (MT8186) is a 64-bit ARM SoC introduced by MediaTek in 2021. +The chip incorporates eight cores - six Cortex-A55 little cores and two Cortex-A76. +Cortex-A76 can operate at up to 2.05 GHz. +Cortex-A55 can operate at up to 2.0 GHz. + +Boot Sequence +------------- + +:: + + Boot Rom --> Coreboot --> TF-A BL31 --> Depthcharge --> Linux Kernel + +How to Build +------------ + +.. code:: shell + + make CROSS_COMPILE=aarch64-linux-gnu- PLAT=mt8186 DEBUG=1 COREBOOT=1 diff --git a/plat/mediatek/mt8186/aarch64/plat_helpers.S b/plat/mediatek/mt8186/aarch64/plat_helpers.S new file mode 100644 index 000000000..35b293f35 --- /dev/null +++ b/plat/mediatek/mt8186/aarch64/plat_helpers.S @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .globl plat_is_my_cpu_primary + .globl plat_my_core_pos + .globl plat_mediatek_calc_core_pos + +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #PLAT_PRIMARY_CPU + cset x0, eq + ret +endfunc plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * unsigned int plat_my_core_pos(void) + * This function uses the plat_mediatek_calc_core_pos() + * definition to get the index of the calling CPU. + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_mediatek_calc_core_pos +endfunc plat_my_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr); + * + * With this function: CorePos = CoreID (AFF1) + * we do it with x0 = (x0 >> 8) & 0xff + * ----------------------------------------------------- + */ +func plat_mediatek_calc_core_pos + mov x1, #MPIDR_AFFLVL_MASK + and x0, x1, x0, lsr #MPIDR_AFF1_SHIFT + ret +endfunc plat_mediatek_calc_core_pos diff --git a/plat/mediatek/mt8186/aarch64/platform_common.c b/plat/mediatek/mt8186/aarch64/platform_common.c new file mode 100644 index 000000000..745e54750 --- /dev/null +++ b/plat/mediatek/mt8186/aarch64/platform_common.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +/* Table of regions to map using the MMU. */ +const mmap_region_t plat_mmap[] = { + /* for TF text, RO, RW */ + MAP_REGION_FLAT(MTK_DEV_RNG0_BASE, MTK_DEV_RNG0_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(MTK_DEV_RNG1_BASE, MTK_DEV_RNG1_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(MTK_DEV_RNG2_BASE, MTK_DEV_RNG2_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + { 0 } +}; + +/******************************************************************************* + * Macro generating the code for the function setting up the pagetables as per + * the platform memory map & initialize the mmu, for the given exception level + ******************************************************************************/ +void plat_configure_mmu_el3(uintptr_t total_base, + uintptr_t total_size, + uintptr_t ro_start, + uintptr_t ro_limit) +{ + mmap_add_region(total_base, total_base, total_size, + MT_RW_DATA | MT_SECURE); + mmap_add_region(ro_start, ro_start, ro_limit - ro_start, + MT_CODE | MT_SECURE); + mmap_add(plat_mmap); + init_xlat_tables(); + enable_mmu_el3(0); +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return SYS_COUNTER_FREQ_IN_TICKS; +} diff --git a/plat/mediatek/mt8186/bl31_plat_setup.c b/plat/mediatek/mt8186/bl31_plat_setup.c new file mode 100644 index 000000000..3fd1c7144 --- /dev/null +++ b/plat/mediatek/mt8186/bl31_plat_setup.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2021, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* System Includes */ +#include + +/* Project Includes */ +#include +#include +#include +#include +#include + +/* Platform Includes */ +#include +#include + +static entry_point_info_t bl32_ep_info; +static entry_point_info_t bl33_ep_info; + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info; + assert(next_image_info->h.type == PARAM_EP); + + /* None of the images on this platform can have 0x0 as the entrypoint */ + if (next_image_info->pc) { + return next_image_info; + } else { + return NULL; + } +} + +/******************************************************************************* + * Perform any BL31 early platform setup. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they + * are lost (potentially). This needs to be done before the MMU is initialized + * so that the memory layout can be used while creating page tables. + * BL2 has flushed this information to memory, so we are guaranteed to pick up + * good data. + ******************************************************************************/ +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; + + params_early_setup(arg1); + +#if COREBOOT + if (coreboot_serial.type) { + console_16550_register(coreboot_serial.baseaddr, + coreboot_serial.input_hertz, + coreboot_serial.baud, + &console); + } +#else + console_16550_register(UART0_BASE, UART_CLOCK, UART_BAUDRATE, &console); +#endif + + INFO("MT8186 bl31_setup\n"); + + bl31_params_parse_helper(arg0, &bl32_ep_info, &bl33_ep_info); +} + + +/******************************************************************************* + * Perform any BL31 platform setup code + ******************************************************************************/ +void bl31_platform_setup(void) +{ +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bl31_plat_arch_setup(void) +{ + plat_configure_mmu_el3(BL31_START, + BL31_END - BL31_START, + BL_CODE_BASE, + BL_CODE_END); +} diff --git a/plat/mediatek/mt8186/include/plat_helpers.h b/plat/mediatek/mt8186/include/plat_helpers.h new file mode 100644 index 000000000..ebc9fa01f --- /dev/null +++ b/plat/mediatek/mt8186/include/plat_helpers.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLAT_HELPERS_H__ +#define __PLAT_HELPERS_H__ + +unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr); + +#endif /* __PLAT_HELPERS_H__ */ diff --git a/plat/mediatek/mt8186/include/plat_macros.S b/plat/mediatek/mt8186/include/plat_macros.S new file mode 100644 index 000000000..39727ea52 --- /dev/null +++ b/plat/mediatek/mt8186/include/plat_macros.S @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include + +.section .rodata.gic_reg_name, "aS" +gicc_regs: + .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" +gicd_pend_reg: + .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \ + " Offset:\t\t\tvalue\n" +newline: + .asciz "\n" +spacer: + .asciz ":\t\t0x" + +.section .rodata.cci_reg_name, "aS" +cci_iface_regs: + .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" + + /* --------------------------------------------- + * The below macro prints out relevant GIC + * registers whenever an unhandled exception + * is taken in BL31. + * Clobbers: x0 - x10, x26, x27, sp + * --------------------------------------------- + */ + .macro plat_crash_print_regs + /* TODO: leave implementation to GIC owner */ + .endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/mediatek/mt8186/include/plat_private.h b/plat/mediatek/mt8186/include/plat_private.h new file mode 100644 index 000000000..7ef2b8509 --- /dev/null +++ b/plat/mediatek/mt8186/include/plat_private.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_PRIVATE_H +#define PLAT_PRIVATE_H + +/******************************************************************************* + * Function and variable prototypes + ******************************************************************************/ +void plat_configure_mmu_el3(uintptr_t total_base, + uintptr_t total_size, + uintptr_t ro_start, + uintptr_t ro_limit); + +#endif /* PLAT_PRIVATE_H */ diff --git a/plat/mediatek/mt8186/include/platform_def.h b/plat/mediatek/mt8186/include/platform_def.h new file mode 100644 index 000000000..bf1bbef8a --- /dev/null +++ b/plat/mediatek/mt8186/include/platform_def.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#define PLAT_PRIMARY_CPU 0x0 + +#define MT_GIC_BASE (0x0C000000) +#define MCUCFG_BASE (0x0C530000) +#define IO_PHYS (0x10000000) + +/* Aggregate of all devices for MMU mapping */ +#define MTK_DEV_RNG0_BASE IO_PHYS +#define MTK_DEV_RNG0_SIZE 0x400000 +#define MTK_DEV_RNG1_BASE (IO_PHYS + 0x1000000) +#define MTK_DEV_RNG1_SIZE 0xa110000 +#define MTK_DEV_RNG2_BASE MT_GIC_BASE +#define MTK_DEV_RNG2_SIZE 0x600000 + + +/******************************************************************************* + * UART related constants + ******************************************************************************/ +#define UART0_BASE (IO_PHYS + 0x01002000) + +#define UART_BAUDRATE 115200 + +/******************************************************************************* + * System counter frequency related constants + ******************************************************************************/ +#define SYS_COUNTER_FREQ_IN_TICKS 13000000 +#define SYS_COUNTER_FREQ_IN_MHZ 13 + +/******************************************************************************* + * Platform binary types for linking + ******************************************************************************/ +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +/******************************************************************************* + * Generic platform constants + ******************************************************************************/ +#define PLATFORM_STACK_SIZE 0x800 + +#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" + +#define PLAT_MAX_PWR_LVL U(3) +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(9) + +#define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_MCUSYS_COUNT U(1) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(8) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) + +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(8) + +#define SOC_CHIP_ID U(0x8186) + +/******************************************************************************* + * Platform memory map related constants + ******************************************************************************/ +#define TZRAM_BASE 0x54600000 +#define TZRAM_SIZE 0x00030000 + +/******************************************************************************* + * BL31 specific defines. + ******************************************************************************/ +/* + * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if + * present). BL31_BASE is calculated using the current BL3-1 debug size plus a + * little space for growth. + */ +#define BL31_BASE (TZRAM_BASE + 0x1000) +#define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE) + +/******************************************************************************* + * Platform specific page table and MMU setup constants + ******************************************************************************/ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#define MAX_XLAT_TABLES 16 +#define MAX_MMAP_REGIONS 16 + +/******************************************************************************* + * Declarations and constants to access the mailboxes safely. Each mailbox is + * 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. Such alignment ensures that two maiboxes do not sit on the same cache + * line at any cache level. They could belong to different cpus/clusters & + * get written while being protected by different locks causing corruption of + * a valid mailbox address. + ******************************************************************************/ +#define CACHE_WRITEBACK_SHIFT 6 +#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) +#endif /* PLATFORM_DEF_H */ diff --git a/plat/mediatek/mt8186/plat_pm.c b/plat/mediatek/mt8186/plat_pm.c new file mode 100644 index 000000000..61d2cc919 --- /dev/null +++ b/plat/mediatek/mt8186/plat_pm.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +static const plat_psci_ops_t plat_psci_ops = { +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + *psci_ops = &plat_psci_ops; + + return 0; +} diff --git a/plat/mediatek/mt8186/plat_topology.c b/plat/mediatek/mt8186/plat_topology.c new file mode 100644 index 000000000..bc95c6405 --- /dev/null +++ b/plat/mediatek/mt8186/plat_topology.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include + +const unsigned char mtk_power_domain_tree_desc[] = { + /* Number of root nodes */ + PLATFORM_SYSTEM_COUNT, + /* Number of children for the root node */ + PLATFORM_MCUSYS_COUNT, + /* Number of children for the mcusys node */ + PLATFORM_CLUSTER_COUNT, + /* Number of children for the first cluster node */ + PLATFORM_CLUSTER0_CORE_COUNT, +}; + +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return mtk_power_domain_tree_desc; +} + +/******************************************************************************* + * This function implements a part of the critical interface between the psci + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is returned + * in case the MPIDR is invalid. + ******************************************************************************/ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + unsigned int cluster_id, cpu_id; + + if ((read_mpidr() & MPIDR_MT_MASK) != 0) { + /* ARMv8.2 arch */ + if ((mpidr & (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT)) != 0) { + return -1; + } + return plat_mediatek_calc_core_pos(mpidr); + } + + mpidr &= MPIDR_AFFINITY_MASK; + + if ((mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0) { + return -1; + } + + cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; + + if (cluster_id >= PLATFORM_CLUSTER_COUNT) { + return -1; + } + + /* + * Validate cpu_id by checking whether it represents a CPU in + * one of the two clusters present on the platform. + */ + if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) { + return -1; + } + + return (cpu_id + (cluster_id * 8)); +} diff --git a/plat/mediatek/mt8186/platform.mk b/plat/mediatek/mt8186/platform.mk new file mode 100644 index 000000000..2d20213ef --- /dev/null +++ b/plat/mediatek/mt8186/platform.mk @@ -0,0 +1,51 @@ +# +# Copyright (c) 2021, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +MTK_PLAT := plat/mediatek +MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} + +PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ + -I${MTK_PLAT_SOC}/include/ + +include drivers/arm/gic/v3/gicv3.mk +include lib/xlat_tables_v2/xlat_tables.mk + +PLAT_BL_COMMON_SOURCES := ${GICV3_SOURCES} \ + ${XLAT_TABLES_LIB_SRCS} \ + plat/common/aarch64/crash_console_helpers.S \ + plat/common/plat_psci_common.c + + +BL31_SOURCES += common/desc_image_load.c \ + drivers/ti/uart/aarch64/16550_console.S \ + lib/bl_aux_params/bl_aux_params.c \ + lib/cpus/aarch64/cortex_a55.S \ + lib/cpus/aarch64/cortex_a76.S \ + plat/common/plat_gicv3.c \ + ${MTK_PLAT}/common/mtk_plat_common.c \ + ${MTK_PLAT}/common/params_setup.c \ + ${MTK_PLAT_SOC}/aarch64/platform_common.c \ + ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ + ${MTK_PLAT_SOC}/bl31_plat_setup.c \ + ${MTK_PLAT_SOC}/plat_pm.c \ + ${MTK_PLAT_SOC}/plat_topology.c + +# Configs for A76 and A55 +HW_ASSISTED_COHERENCY := 1 +USE_COHERENT_MEM := 0 +CTX_INCLUDE_AARCH32_REGS := 0 +ERRATA_A55_1530923 := 1 +ERRATA_A55_1221012 := 1 + +# indicate the reset vector address can be programmed +PROGRAMMABLE_RESET_ADDRESS := 1 + +COLD_BOOT_SINGLE_CPU := 1 + +MACH_MT8186 := 1 +$(eval $(call add_define,MACH_MT8186)) + +include lib/coreboot/coreboot.mk