diff --git a/docs/plat/mt8183.rst b/docs/plat/mt8183.rst new file mode 100644 index 0000000..c559e19 --- /dev/null +++ b/docs/plat/mt8183.rst @@ -0,0 +1,20 @@ +Description +=========== + +MediaTek 8183 (MT8183) is a 64-bit ARM SoC introduced by MediaTek in early 2018. +The chip incorporates eight cores - four Cortex-A53 little cores and Cortex-A73. +Both clusters can operate at up to 2 GHz. + +Boot Sequence +============= + +:: + + Boot Rom --> Coreboot --> TF-A BL31 --> Depthcharge --> Linux Kernel + +How to Build +============ + +.. code:: shell + + make CROSS_COMPILE=aarch64-linux-gnu- PLAT=mt8183 DEBUG=1 diff --git a/plat/mediatek/mt8183/aarch64/plat_helpers.S b/plat/mediatek/mt8183/aarch64/plat_helpers.S new file mode 100644 index 0000000..5c39633 --- /dev/null +++ b/plat/mediatek/mt8183/aarch64/plat_helpers.S @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019, 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 + +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); + * + * result: CorePos = CoreId + (ClusterId << 2) + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret +endfunc plat_my_core_pos diff --git a/plat/mediatek/mt8183/aarch64/platform_common.c b/plat/mediatek/mt8183/aarch64/platform_common.c new file mode 100644 index 0000000..ff0aaeb --- /dev/null +++ b/plat/mediatek/mt8183/aarch64/platform_common.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +/* Table of regions to map using the MMU. */ +const mmap_region_t plat_mmap[] = { + /* for TF text, RO, RW */ + MAP_REGION_FLAT(TZRAM_BASE, TZRAM_SIZE, + MT_MEMORY | MT_RW | MT_SECURE), + 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, + uintptr_t coh_start, + uintptr_t coh_limit) +{ + mmap_add_region(total_base, total_base, total_size, + MT_MEMORY | MT_RW | MT_SECURE); + mmap_add_region(ro_start, ro_start, ro_limit - ro_start, + MT_MEMORY | MT_RO | MT_SECURE); + mmap_add_region(coh_start, coh_start, coh_limit - coh_start, + MT_DEVICE | MT_RW | 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/mt8183/bl31_plat_setup.c b/plat/mediatek/mt8183/bl31_plat_setup.c new file mode 100644 index 0000000..1e5367f --- /dev/null +++ b/plat/mediatek/mt8183/bl31_plat_setup.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static entry_point_info_t bl32_ep_info; +static entry_point_info_t bl33_ep_info; + +static void platform_setup_cpu(void) +{ + mmio_write_32((uintptr_t)&mt8183_mcucfg->mp0_rw_rsvd0, 0x00000001); + + VERBOSE("addr of cci_adb400_dcm_config: 0x%x\n", + mmio_read_32((uintptr_t)&mt8183_mcucfg->cci_adb400_dcm_config)); + VERBOSE("addr of sync_dcm_config: 0x%x\n", + mmio_read_32((uintptr_t)&mt8183_mcucfg->sync_dcm_config)); + + VERBOSE("mp0_spmc: 0x%x\n", + mmio_read_32((uintptr_t)&mt8183_mcucfg->mp0_cputop_spmc_ctl)); + VERBOSE("mp1_spmc: 0x%x\n", + mmio_read_32((uintptr_t)&mt8183_mcucfg->mp1_cputop_spmc_ctl)); +} + +/******************************************************************************* + * 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; + + /* 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) +{ + struct mtk_bl31_params *arg_from_bl2 = (struct mtk_bl31_params *)arg0; + + static console_16550_t console; + console_16550_register(UART0_BASE, UART_CLOCK, UART_BAUDRATE, &console); + + NOTICE("MT8183 bl31_setup\n"); + + assert(arg_from_bl2 != NULL); + assert(arg_from_bl2->h.type == PARAM_BL31); + assert(arg_from_bl2->h.version >= VERSION_1); + + bl32_ep_info = *arg_from_bl2->bl32_ep_info; + bl33_ep_info = *arg_from_bl2->bl33_ep_info; +} + + +/******************************************************************************* + * Perform any BL31 platform setup code + ******************************************************************************/ +void bl31_platform_setup(void) +{ + platform_setup_cpu(); + generic_delay_timer_init(); +} + +/******************************************************************************* + * 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) +{ + enable_scu(read_mpidr()); + + plat_configure_mmu_el3(BL_CODE_BASE, + BL_COHERENT_RAM_END - BL_CODE_BASE, + BL_CODE_BASE, + BL_CODE_END, + BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END); +} diff --git a/plat/mediatek/mt8183/include/mcucfg.h b/plat/mediatek/mt8183/include/mcucfg.h new file mode 100644 index 0000000..c84f2a7 --- /dev/null +++ b/plat/mediatek/mt8183/include/mcucfg.h @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT8183_MCUCFG_H +#define MT8183_MCUCFG_H + +#include +#include + +struct mt8183_mcucfg_regs { + uint32_t mp0_ca7l_cache_config; /* 0x0 */ + struct { + uint32_t mem_delsel0; + uint32_t mem_delsel1; + } mp0_cpu[4]; /* 0x4 */ + uint32_t mp0_cache_mem_delsel0; /* 0x24 */ + uint32_t mp0_cache_mem_delsel1; /* 0x28 */ + uint32_t mp0_axi_config; /* 0x2C */ + uint32_t mp0_misc_config[10]; /* 0x30 */ + uint32_t mp0_ca7l_cfg_dis; /* 0x58 */ + uint32_t mp0_ca7l_clken_ctrl; /* 0x5C */ + uint32_t mp0_ca7l_rst_ctrl; /* 0x60 */ + uint32_t mp0_ca7l_misc_config; /* 0x64 */ + uint32_t mp0_ca7l_dbg_pwr_ctrl; /* 0x68 */ + uint32_t mp0_rw_rsvd0; /* 0x6C */ + uint32_t mp0_rw_rsvd1; /* 0x70 */ + uint32_t mp0_ro_rsvd; /* 0x74 */ + uint32_t reserved0_0[98]; /* 0x78 */ + uint32_t mp1_ca7l_cache_config; /* 0x200 */ + uint32_t mp1_miscdbg; /* 0x204 */ + uint32_t reserved0_1[9]; /* 0x208 */ + uint32_t mp1_axi_config; /* 0x22C */ + uint32_t mp1_misc_config[10]; /* 0x230 */ + uint32_t reserved0_2[3]; /* 0x258 */ + uint32_t mp1_ca7l_misc_config; /* 0x264 */ + uint32_t reserved0_3[310]; /* 0x268 */ + uint32_t cci_adb400_dcm_config; /* 0x740 */ + uint32_t sync_dcm_config; /* 0x744 */ + uint32_t reserved0_4[16]; /* 0x748 */ + uint32_t mp0_cputop_spmc_ctl; /* 0x788 */ + uint32_t mp1_cputop_spmc_ctl; /* 0x78C */ + uint32_t mp1_cputop_spmc_sram_ctl; /* 0x790 */ + uint32_t reserved0_5[23]; /* 0x794 */ + uint32_t l2_cfg_mp0; /* 0x7F0 */ + uint32_t l2_cfg_mp1; /* 0x7F4 */ + uint32_t reserved0_6[1282]; /* 0x7F8 */ + uint32_t cpusys0_sparkvretcntrl; /* 0x1C00 */ + uint32_t cpusys0_sparken; /* 0x1C04 */ + uint32_t cpusys0_amuxsel; /* 0x1C08 */ + uint32_t reserved0_7[9]; /* 0x1C0C */ + uint32_t cpusys0_cpu0_spmc_ctl; /* 0x1C30 */ + uint32_t cpusys0_cpu1_spmc_ctl; /* 0x1C34 */ + uint32_t cpusys0_cpu2_spmc_ctl; /* 0x1C38 */ + uint32_t cpusys0_cpu3_spmc_ctl; /* 0x1C3C */ + uint32_t reserved0_8[370]; /* 0x1C40 */ + uint32_t mp2_cpucfg; /* 0x2208 */ + uint32_t mp2_axi_config; /* 0x220C */ + uint32_t reserved0_9[36]; /* 0x2210 */ + uint32_t mp2_cputop_spm_ctl; /* 0x22A0 */ + uint32_t mp2_cputop_spm_sta; /* 0x22A4 */ + uint32_t reserved0_10[98]; /* 0x22A8 */ + uint32_t cpusys2_cpu0_spmc_ctl; /* 0x2430 */ + uint32_t cpusys2_cpu0_spmc_sta; /* 0x2434 */ + uint32_t cpusys2_cpu1_spmc_ctl; /* 0x2438 */ + uint32_t cpusys2_cpu1_spmc_sta; /* 0x243C */ + uint32_t reserved0_11[176]; /* 0x2440 */ + uint32_t spark2ld0; /* 0x2700 */ + uint32_t reserved0_12[1355]; /* 0x2704 */ + uint32_t cpusys1_cpu0_spmc_ctl; /* 0x3C30 */ + uint32_t cpusys1_cpu1_spmc_ctl; /* 0x3C34 */ + uint32_t cpusys1_cpu2_spmc_ctl; /* 0x3C38 */ + uint32_t cpusys1_cpu3_spmc_ctl; /* 0x3C3C */ +}; + +static struct mt8183_mcucfg_regs *const mt8183_mcucfg = (void *)MCUCFG_BASE; + +enum { + SW_SPARK_EN = 1 << 0, + SW_NO_WAIT_FOR_Q_CHANNEL = 1 << 1, + SW_FSM_OVERRIDE = 1 << 2, + SW_LOGIC_PRE1_PDB = 1 << 3, + SW_LOGIC_PRE2_PDB = 1 << 4, + SW_LOGIC_PDB = 1 << 5, + SW_ISO = 1 << 6, + SW_SRAM_SLEEPB = 0x3f << 7, + SW_SRAM_ISOINTB = 1 << 13, + SW_CLK_DIS = 1 << 14, + SW_CKISO = 1 << 15, + SW_PD = 0x3f << 16, + SW_HOT_PLUG_RESET = 1 << 22, + SW_PWR_ON_OVERRIDE_EN = 1 << 23, + SW_PWR_ON = 1 << 24, + SW_COQ_DIS = 1 << 25, + LOGIC_PDBO_ALL_OFF_ACK = 1 << 26, + LOGIC_PDBO_ALL_ON_ACK = 1 << 27, + LOGIC_PRE2_PDBO_ALL_ON_ACK = 1 << 28, + LOGIC_PRE1_PDBO_ALL_ON_ACK = 1 << 29 +}; + +enum { + CPU_SW_SPARK_EN = 1 << 0, + CPU_SW_NO_WAIT_FOR_Q_CHANNEL = 1 << 1, + CPU_SW_FSM_OVERRIDE = 1 << 2, + CPU_SW_LOGIC_PRE1_PDB = 1 << 3, + CPU_SW_LOGIC_PRE2_PDB = 1 << 4, + CPU_SW_LOGIC_PDB = 1 << 5, + CPU_SW_ISO = 1 << 6, + CPU_SW_SRAM_SLEEPB = 1 << 7, + CPU_SW_SRAM_ISOINTB = 1 << 8, + CPU_SW_CLK_DIS = 1 << 9, + CPU_SW_CKISO = 1 << 10, + CPU_SW_PD = 0x1f << 11, + CPU_SW_HOT_PLUG_RESET = 1 << 16, + CPU_SW_POWR_ON_OVERRIDE_EN = 1 << 17, + CPU_SW_PWR_ON = 1 << 18, + CPU_SPARK2LDO_ALLSWOFF = 1 << 19, + CPU_PDBO_ALL_ON_ACK = 1 << 20, + CPU_PRE2_PDBO_ALLON_ACK = 1 << 21, + CPU_PRE1_PDBO_ALLON_ACK = 1 << 22 +}; + +enum { + MP2_AXI_CONFIG_ACINACTM = 1 << 0, + MPx_AXI_CONFIG_ACINACTM = 1 << 4, + MPX_CA7_MISC_CONFIG_STANDBYWFIL2 = 1 << 28 +}; + +enum { + MP0_CPU0_STANDBYWFE = 1 << 20, + MP0_CPU1_STANDBYWFE = 1 << 21, + MP0_CPU2_STANDBYWFE = 1 << 22, + MP0_CPU3_STANDBYWFE = 1 << 23 +}; + +enum { + MP1_CPU0_STANDBYWFE = 1 << 20, + MP1_CPU1_STANDBYWFE = 1 << 21, + MP1_CPU2_STANDBYWFE = 1 << 22, + MP1_CPU3_STANDBYWFE = 1 << 23 +}; + +enum { + B_SW_HOT_PLUG_RESET = 1 << 30, + B_SW_PD_OFFSET = 18, + B_SW_PD = 0x3f << B_SW_PD_OFFSET, + B_SW_SRAM_SLEEPB_OFFSET = 12, + B_SW_SRAM_SLEEPB = 0x3f << B_SW_SRAM_SLEEPB_OFFSET +}; + +enum { + B_SW_SRAM_ISOINTB = 1 << 9, + B_SW_ISO = 1 << 8, + B_SW_LOGIC_PDB = 1 << 7, + B_SW_LOGIC_PRE2_PDB = 1 << 6, + B_SW_LOGIC_PRE1_PDB = 1 << 5, + B_SW_FSM_OVERRIDE = 1 << 4, + B_SW_PWR_ON = 1 << 3, + B_SW_PWR_ON_OVERRIDE_EN = 1 << 2 +}; + +enum { + B_FSM_STATE_OUT_OFFSET = 6, + B_FSM_STATE_OUT_MASK = 0x1f << B_FSM_STATE_OUT_OFFSET, + B_SW_LOGIC_PDBO_ALL_OFF_ACK = 1 << 5, + B_SW_LOGIC_PDBO_ALL_ON_ACK = 1 << 4, + B_SW_LOGIC_PRE2_PDBO_ALL_ON_ACK = 1 << 3, + B_SW_LOGIC_PRE1_PDBO_ALL_ON_ACK = 1 << 2, + B_FSM_OFF = 0 << B_FSM_STATE_OUT_OFFSET, + B_FSM_ON = 1 << B_FSM_STATE_OUT_OFFSET, + B_FSM_RET = 2 << B_FSM_STATE_OUT_OFFSET +}; + +/* APB Module infracfg_ao */ +enum { + INFRA_TOPAXI_PROTECTEN_1 = INFRACFG_AO_BASE + 0x250, + INFRA_TOPAXI_PROTECTSTA1_1 = INFRACFG_AO_BASE + 0x258, + INFRA_TOPAXI_PROTECTEN_1_SET = INFRACFG_AO_BASE + 0x2A8, + INFRA_TOPAXI_PROTECTEN_1_CLR = INFRACFG_AO_BASE + 0x2AC +}; + +enum { + IDX_PROTECT_MP0_CACTIVE = 10, + IDX_PROTECT_MP1_CACTIVE = 11, + IDX_PROTECT_ICC0_CACTIVE = 12, + IDX_PROTECT_ICD0_CACTIVE = 13, + IDX_PROTECT_ICC1_CACTIVE = 14, + IDX_PROTECT_ICD1_CACTIVE = 15, + IDX_PROTECT_L2C0_CACTIVE = 26, + IDX_PROTECT_L2C1_CACTIVE = 27 +}; + +/* cpu boot mode */ +enum { + MP0_CPUCFG_64BIT_SHIFT = 12, + MP1_CPUCFG_64BIT_SHIFT = 28, + MP0_CPUCFG_64BIT = 0xf << MP0_CPUCFG_64BIT_SHIFT, + MP1_CPUCFG_64BIT = 0xf << MP1_CPUCFG_64BIT_SHIFT +}; + +/* scu related */ +enum { + MP0_ACINACTM_SHIFT = 4, + MP1_ACINACTM_SHIFT = 4, + MP2_ACINACTM_SHIFT = 0, + MP0_ACINACTM = 1 << MP0_ACINACTM_SHIFT, + MP1_ACINACTM = 1 << MP1_ACINACTM_SHIFT, + MP2_ACINACTM = 1 << MP2_ACINACTM_SHIFT +}; + +enum { + MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT = 0, + MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT = 4, + MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT = 8, + MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT = 12, + MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT = 16, + + MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK = + 0xf << MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK = + 0xf << MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK = + 0xf << MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK = + 0xf << MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK = + 0xf << MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT +}; + +enum { + MP1_AINACTS_SHIFT = 4, + MP1_AINACTS = 1 << MP1_AINACTS_SHIFT +}; + +enum { + MP1_SW_CG_GEN_SHIFT = 12, + MP1_SW_CG_GEN = 1 << MP1_SW_CG_GEN_SHIFT +}; + +enum { + MP1_L2RSTDISABLE_SHIFT = 14, + MP1_L2RSTDISABLE = 1 << MP1_L2RSTDISABLE_SHIFT +}; + +#endif /* MT8183_MCUCFG_H */ diff --git a/plat/mediatek/mt8183/include/plat_debug.h b/plat/mediatek/mt8183/include/plat_debug.h new file mode 100644 index 0000000..e51a6ea --- /dev/null +++ b/plat/mediatek/mt8183/include/plat_debug.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEBUG_H +#define PLATFORM_DEBUG_H + +#define sync_writel(addr, val) \ + do { mmio_write_32((addr), (val)); dsbsy(); } while (0) + +#define MCU_BIU_BASE 0x0c530000 +#define MISC1_CFG_BASE 0xb00 +#define CA15M_CFG_BASE 0x2000 +#define DFD_INTERNAL_CTL (MCU_BIU_BASE + MISC1_CFG_BASE + 0x00) +#define CA15M_DBG_CONTROL (MCU_BIU_BASE + CA15M_CFG_BASE + 0x728) +#define CA15M_PWR_RST_CTL (MCU_BIU_BASE + CA15M_CFG_BASE + 0x08) +#define VPROC_EXT_CTL 0x10006290 + +#define CFG_SF_CTRL 0x0c510014 +#define CFG_SF_INI 0x0c510010 + +#define BIT_CA15M_L2PARITY_EN (1 << 1) +#define BIT_CA15M_LASTPC_DIS (1 << 8) + +#define MP1_CPUTOP_PWR_CON 0x10006218 + +#define MCU_ALL_PWR_ON_CTRL 0x0c530b58 +#define PLAT_MTK_CIRCULAR_BUFFER_UNLOCK 0xefab4133 +#define PLAT_MTK_CIRCULAR_BUFFER_LOCK 0xefab4134 + +extern void circular_buffer_setup(void); +extern void l2c_parity_check_setup(void); +extern void clear_all_on_mux(void); +#endif /* PLATFORM_DEBUG_H */ diff --git a/plat/mediatek/mt8183/include/plat_macros.S b/plat/mediatek/mt8183/include/plat_macros.S new file mode 100644 index 0000000..cac7769 --- /dev/null +++ b/plat/mediatek/mt8183/include/plat_macros.S @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#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 and + * CCI registers whenever an unhandled exception + * is taken in BL31. + * Clobbers: x0 - x10, x26, x27, sp + * --------------------------------------------- + */ + .macro plat_crash_print_regs + mov_imm x26, BASE_GICD_BASE + mov_imm x27, BASE_GICC_BASE + /* Load the gicc reg list to x6 */ + adr x6, gicc_regs + /* Load the gicc regs to gp regs used by str_in_crash_buf_print */ + ldr w8, [x27, #GICC_HPPIR] + ldr w9, [x27, #GICC_AHPPIR] + ldr w10, [x27, #GICC_CTLR] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + + /* Print the GICD_ISPENDR regs */ + add x7, x26, #GICD_ISPENDR + adr x4, gicd_pend_reg + bl asm_print_str +gicd_ispendr_loop: + sub x4, x7, x26 + cmp x4, #0x280 + b.eq exit_print_gic_regs + bl asm_print_hex + + adr x4, spacer + bl asm_print_str + + ldr x4, [x7], #8 + bl asm_print_hex + + adr x4, newline + bl asm_print_str + b gicd_ispendr_loop +exit_print_gic_regs: + + adr x6, cci_iface_regs + /* Store in x7 the base address of the first interface */ + mov_imm x7, (PLAT_MT_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX)) + ldr w8, [x7, #SNOOP_CTRL_REG] + /* Store in x7 the base address of the second interface */ + mov_imm x7, (PLAT_MT_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX)) + ldr w9, [x7, #SNOOP_CTRL_REG] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + .endm diff --git a/plat/mediatek/mt8183/include/plat_private.h b/plat/mediatek/mt8183/include/plat_private.h new file mode 100644 index 0000000..e57ae45 --- /dev/null +++ b/plat/mediatek/mt8183/include/plat_private.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019, 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, + uintptr_t coh_start, + uintptr_t coh_limit); + +void plat_cci_init(void); +void plat_cci_enable(void); +void plat_cci_disable(void); +void plat_cci_init_sf(void); +void plat_gic_init(void); + +/* Declarations for plat_topology.c */ +int mt_setup_topology(void); + +#endif /* PLAT_PRIVATE_H */ diff --git a/plat/mediatek/mt8183/include/platform_def.h b/plat/mediatek/mt8183/include/platform_def.h new file mode 100644 index 0000000..7820988 --- /dev/null +++ b/plat/mediatek/mt8183/include/platform_def.h @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include + +#define PLAT_PRIMARY_CPU 0x0 + +#define IO_PHYS 0x10000000 +#define INFRACFG_AO_BASE (IO_PHYS + 0x1000) +#define PERI_BASE (IO_PHYS + 0x3000) +#define GPIO_BASE (IO_PHYS + 0x5000) +#define SPM_BASE (IO_PHYS + 0x6000) +#define SLEEP_REG_MD_BASE (IO_PHYS + 0xf000) +#define RGU_BASE (IO_PHYS + 0x7000) +#define I2C4_BASE_SE (IO_PHYS + 0x1008000) +#define I2C2_BASE_SE (IO_PHYS + 0x1009000) +#define PMIC_WRAP_BASE (IO_PHYS + 0xd000) +#define MCUCFG_BASE 0x0c530000 +#define CFG_SF_CTRL 0x0c510014 +#define CFG_SF_INI 0x0c510010 +#define EMI_MPU_BASE (IO_PHYS + 0x226000) +#define TRNG_base (IO_PHYS + 0x20f000) +#define MT_GIC_BASE 0x0c000000 +#define PLAT_MT_CCI_BASE 0x0c500000 +#define CCI_SIZE 0x00010000 +#define EINT_BASE 0x1000b000 +#define DVFSRC_BASE (IO_PHYS + 0x12000) + +#define SSPM_CFGREG_BASE (IO_PHYS + 0x440000) +#define SSPM_MBOX_3_BASE (IO_PHYS + 0x480000) + +#define INFRACFG_AO_BASE (IO_PHYS + 0x1000) + +#define APMIXEDSYS (IO_PHYS + 0xC000) +#define ARMPLL_LL_CON0 (APMIXEDSYS + 0x200) +#define ARMPLL_L_CON0 (APMIXEDSYS + 0x210) +#define MAINPLL_CON0 (APMIXEDSYS + 0x220) +#define CCIPLL_CON0 (APMIXEDSYS + 0x290) + +#define TOP_CKMUXSEL (INFRACFG_AO_BASE + 0x0) + +#define armpll_mux1_sel_big_mask (0xf << 4) +#define armpll_mux1_sel_big_ARMSPLL (0x1 << 4) +#define armpll_mux1_sel_sml_mask (0xf << 8) +#define armpll_mux1_sel_sml_ARMSPLL (0x1 << 8) + + +/* Aggregate of all devices in the first GB */ +#define MTK_DEV_RNG0_BASE IO_PHYS +#define MTK_DEV_RNG0_SIZE 0x490000 +#define MTK_DEV_RNG1_BASE (IO_PHYS + 0x1000000) +#define MTK_DEV_RNG1_SIZE 0x4000000 +#define MTK_DEV_RNG2_BASE 0x0c000000 +#define MTK_DEV_RNG2_SIZE 0x600000 +#define MT_MCUSYS_SIZE 0x90000 +#define RAM_CONSOLE_BASE 0x11d000 +#define RAM_CONSOLE_SIZE 0x1000 + +/******************************************************************************* + * MSDC + ******************************************************************************/ +#define MSDC0_BASE (IO_PHYS + 0x01230000) + +/******************************************************************************* + * MCUSYS related constants + ******************************************************************************/ +#define MT_L2_WRITE_ACCESS_RATE (MCUCFG_BASE + 0x604) +#define MP0_CA7L_CACHE_CONFIG (MCUCFG_BASE + 0x7f0) +#define MP1_CA7L_CACHE_CONFIG (MCUCFG_BASE + 0x7f4) + +/******************************************************************************* + * GIC related constants + ******************************************************************************/ +#define MT_POLARITY_LOW 0 +#define MT_POLARITY_HIGH 1 +#define MT_EDGE_SENSITIVE 1 +#define MT_LEVEL_SENSITIVE 0 + +/******************************************************************************* + * UART related constants + ******************************************************************************/ +#define UART0_BASE (IO_PHYS + 0x01002000) + +#define UART_BAUDRATE 115200 +#define UART_CLOCK 26000000 + +/******************************************************************************* + * System counter frequency related constants + ******************************************************************************/ +#define SYS_COUNTER_FREQ_IN_TICKS 13000000 +#define SYS_COUNTER_FREQ_IN_MHZ 13 + +/******************************************************************************* + * GIC-400 & interrupt handling related constants + ******************************************************************************/ + +/* Base MTK_platform compatible GIC memory map */ +#define BASE_GICD_BASE MT_GIC_BASE +#define BASE_GICC_BASE (MT_GIC_BASE + 0x400000) +#define MT_GIC_RDIST_BASE (MT_GIC_BASE + 0x100000) +#define BASE_GICR_BASE (MT_GIC_BASE + 0x100000) +#define BASE_GICH_BASE (MT_GIC_BASE + 0x4000) +#define BASE_GICV_BASE (MT_GIC_BASE + 0x6000) +#define INT_POL_CTL0 (MCUCFG_BASE + 0xa80) +#define SEC_POL_CTL_EN0 (MCUCFG_BASE + 0xa00) +#define GIC_SYNC_DCM (MCUCFG_BASE + 0x758) +#define GIC_SYNC_DCM_MASK 0x3 +#define GIC_SYNC_DCM_ON 0x3 +#define GIC_SYNC_DCM_OFF 0x0 +#define GIC_PRIVATE_SIGNALS 32 + +#define PLAT_ARM_GICD_BASE BASE_GICD_BASE +#define PLAT_ARM_GICC_BASE BASE_GICC_BASE + +#define PLAT_ARM_G1S_IRQ_PROPS(grp) ( \ +INTR_PROP_DESC(MT_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ +INTR_PROP_DESC(MT_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ +INTR_PROP_DESC(MT_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ +INTR_PROP_DESC(MT_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ +INTR_PROP_DESC(MT_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ +INTR_PROP_DESC(MT_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ +INTR_PROP_DESC(MT_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ +INTR_PROP_DESC(MT_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE)) \ + +#define PLAT_ARM_G0_IRQ_PROPS(grp) + +/******************************************************************************* + * CCI-400 related constants + ******************************************************************************/ +#define PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX 4 +#define PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX 3 + +/******************************************************************************* + * WDT Registers + ******************************************************************************/ +#define MTK_WDT_BASE (IO_PHYS + 0x00007000) +#define MTK_WDT_SIZE 0x1000 +#define MTK_WDT_MODE (MTK_WDT_BASE + 0x0000) +#define MTK_WDT_LENGTH (MTK_WDT_BASE + 0x0004) +#define MTK_WDT_RESTART (MTK_WDT_BASE + 0x0008) +#define MTK_WDT_STATUS (MTK_WDT_BASE + 0x000C) +#define MTK_WDT_INTERVAL (MTK_WDT_BASE + 0x0010) +#define MTK_WDT_SWRST (MTK_WDT_BASE + 0x0014) +#define MTK_WDT_SWSYSRST (MTK_WDT_BASE + 0x0018) +#define MTK_WDT_NONRST_REG (MTK_WDT_BASE + 0x0020) +#define MTK_WDT_NONRST_REG2 (MTK_WDT_BASE + 0x0024) +#define MTK_WDT_REQ_MODE (MTK_WDT_BASE + 0x0030) +#define MTK_WDT_REQ_IRQ_EN (MTK_WDT_BASE + 0x0034) +#define MTK_WDT_EXT_REQ_CON (MTK_WDT_BASE + 0x0038) +#define MTK_WDT_DEBUG_CTL (MTK_WDT_BASE + 0x0040) +#define MTK_WDT_LATCH_CTL (MTK_WDT_BASE + 0x0044) +#define MTK_WDT_DEBUG_CTL2 (MTK_WDT_BASE + 0x00A0) +#define MTK_WDT_COUNTER (MTK_WDT_BASE + 0x0514) + +/* WDT_STATUS */ +#define MTK_WDT_STATUS_SPM_THERMAL_RST (1 << 0) +#define MTK_WDT_STATUS_SPM_RST (1 << 1) +#define MTK_WDT_STATUS_EINT_RST (1 << 2) +#define MTK_WDT_STATUS_SYSRST_RST (1 << 3) /* from PMIC */ +#define MTK_WDT_STATUS_DVFSP_RST (1 << 4) +#define MTK_WDT_STATUS_PMCU_RST (1 << 16) +#define MTK_WDT_STATUS_MDDBG_RST (1 << 17) +#define MTK_WDT_STATUS_THERMAL_DIRECT_RST (1 << 18) +#define MTK_WDT_STATUS_DEBUG_RST (1 << 19) +#define MTK_WDT_STATUS_SECURITY_RST (1 << 28) +#define MTK_WDT_STATUS_IRQ_ASSERT (1 << 29) +#define MTK_WDT_STATUS_SW_WDT_RST (1 << 30) +#define MTK_WDT_STATUS_HW_WDT_RST (1 << 31) + +/* RGU other related */ +#define MTK_WDT_MODE_DUAL_MODE 0x0040 +#define MTK_WDT_MODE_IRQ 0x0008 +#define MTK_WDT_MODE_KEY 0x22000000 +#define MTK_WDT_MODE_EXTEN 0x0004 +#define MTK_WDT_SWRST_KEY 0x1209 +#define MTK_WDT_RESTART_KEY 0x1971 + +/******************************************************************************* + * TRNG Registers + ******************************************************************************/ +#define TRNG_BASE_ADDR TRNG_base +#define TRNG_BASE_SIZE 0x1000 +#define TRNG_CTRL (TRNG_base + 0x0000) +#define TRNG_TIME (TRNG_base + 0x0004) +#define TRNG_DATA (TRNG_base + 0x0008) +#define TRNG_PDN_base 0x10001000 +#define TRNG_PDN_BASE_ADDR TRNG_PDN_BASE_ADDR +#define TRNG_PDN_BASE_SIZE 0x1000 +#define TRNG_PDN_SET (TRNG_PDN_base + 0x0088) +#define TRNG_PDN_CLR (TRNG_PDN_base + 0x008c) +#define TRNG_PDN_STATUS (TRNG_PDN_base + 0x0094) +#define TRNG_CTRL_RDY 0x80000000 +#define TRNG_CTRL_START 0x00000001 +#define TRNG_PDN_VALUE 0x200 + +/* FIQ platform related define */ +#define MT_IRQ_SEC_SGI_0 8 +#define MT_IRQ_SEC_SGI_1 9 +#define MT_IRQ_SEC_SGI_2 10 +#define MT_IRQ_SEC_SGI_3 11 +#define MT_IRQ_SEC_SGI_4 12 +#define MT_IRQ_SEC_SGI_5 13 +#define MT_IRQ_SEC_SGI_6 14 +#define MT_IRQ_SEC_SGI_7 15 + +#define FIQ_SMP_CALL_SGI 13 +#define WDT_IRQ_BIT_ID 174 +#define ATF_LOG_IRQ_ID 277 + +#define ATF_AMMS_IRQ_ID 338 +#define PCCIF1_IRQ0_BIT_ID 185 +#define PCCIF1_IRQ1_BIT_ID 186 + +#define DEBUG_XLAT_TABLE 0 + +/******************************************************************************* + * Platform binary types for linking + ******************************************************************************/ +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +/******************************************************************************* + * Generic platform constants + ******************************************************************************/ + +/* Size of cacheable stacks */ +#if DEBUG_XLAT_TABLE +#define PLATFORM_STACK_SIZE 0x800 +#elif IMAGE_BL1 +#define PLATFORM_STACK_SIZE 0x440 +#elif IMAGE_BL2 +#define PLATFORM_STACK_SIZE 0x400 +#elif IMAGE_BL31 +#define PLATFORM_STACK_SIZE 0x800 +#elif IMAGE_BL32 +#define PLATFORM_STACK_SIZE 0x440 +#endif + +#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" +#define PLAT_MAX_PWR_LVL U(2) +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(2) + +#define PLATFORM_CACHE_LINE_SIZE 64 +#define PLATFORM_SYSTEM_COUNT 1 +#define PLATFORM_CLUSTER_COUNT 2 +#define PLATFORM_CLUSTER0_CORE_COUNT 4 +#define PLATFORM_CLUSTER1_CORE_COUNT 4 +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ + PLATFORM_CLUSTER0_CORE_COUNT) +#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \ + PLATFORM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) + +/******************************************************************************* + * Platform memory map related constants + ******************************************************************************/ + +#define TZRAM_BASE 0x54600000 +#define TZRAM_SIZE 0x00020000 + +/******************************************************************************* + * BL31 specific defines. + ******************************************************************************/ +/* + * Put BL31 at the top of the Trusted SRAM (just below the shared memory, if + * present). BL31_BASE is calculated using the current BL31 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 4 +#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/mt8183/include/power_tracer.h b/plat/mediatek/mt8183/include/power_tracer.h new file mode 100644 index 0000000..c93be64 --- /dev/null +++ b/plat/mediatek/mt8183/include/power_tracer.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef POWER_TRACER_H +#define POWER_TRACER_H + +#define CPU_UP 0 +#define CPU_DOWN 1 +#define CPU_SUSPEND 2 +#define CLUSTER_UP 3 +#define CLUSTER_DOWN 4 +#define CLUSTER_SUSPEND 5 + +void trace_power_flow(u_register_t mpidr, unsigned char mode); + +#endif /* POWER_TRACER_H */ + diff --git a/plat/mediatek/mt8183/include/scu.h b/plat/mediatek/mt8183/include/scu.h new file mode 100644 index 0000000..96b80c5 --- /dev/null +++ b/plat/mediatek/mt8183/include/scu.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCU_H +#define SCU_H + +void disable_scu(u_register_t mpidr); +void enable_scu(u_register_t mpidr); + +#endif /* SCU_H */ diff --git a/plat/mediatek/mt8183/plat_debug.c b/plat/mediatek/mt8183/plat_debug.c new file mode 100644 index 0000000..51816db --- /dev/null +++ b/plat/mediatek/mt8183/plat_debug.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +void circular_buffer_setup(void) +{ + /* Clear DBG_CONTROL.lastpc_disable to enable circular buffer */ + sync_writel(CA15M_DBG_CONTROL, + mmio_read_32(CA15M_DBG_CONTROL) & ~(BIT_CA15M_LASTPC_DIS)); +} + +void circular_buffer_unlock(void) +{ + unsigned int i; + + /* Disable big vproc external off (set CPU_EXT_BUCK_ISO to 0x0) */ + sync_writel(VPROC_EXT_CTL, mmio_read_32(VPROC_EXT_CTL) & ~(0x1 << 1)); + + /* Release vproc apb mask (set 0x0C53_2008[1] to 0x0) */ + sync_writel(CA15M_PWR_RST_CTL, mmio_read_32(CA15M_PWR_RST_CTL) & ~(0x1 << 1)); + + for (i = 1; i <= 4; ++i) + sync_writel(MP1_CPUTOP_PWR_CON + i * 4, + (mmio_read_32(MP1_CPUTOP_PWR_CON + i * 4) & ~(0x4))|(0x4)); + + /* Set DFD.en */ + sync_writel(DFD_INTERNAL_CTL, 0x1); +} + +void circular_buffer_lock(void) +{ + /* Clear DFD.en */ + sync_writel(DFD_INTERNAL_CTL, 0x0); +} + +void clear_all_on_mux(void) +{ + sync_writel(MCU_ALL_PWR_ON_CTRL, + mmio_read_32(MCU_ALL_PWR_ON_CTRL) & ~(1 << 2)); + sync_writel(MCU_ALL_PWR_ON_CTRL, + mmio_read_32(MCU_ALL_PWR_ON_CTRL) & ~(1 << 1)); +} + +void l2c_parity_check_setup(void) +{ + /* Enable DBG_CONTROL.l2parity_en */ + sync_writel(CA15M_DBG_CONTROL, + mmio_read_32(CA15M_DBG_CONTROL) | BIT_CA15M_L2PARITY_EN); +} diff --git a/plat/mediatek/mt8183/plat_pm.c b/plat/mediatek/mt8183/plat_pm.c new file mode 100644 index 0000000..dd54d70 --- /dev/null +++ b/plat/mediatek/mt8183/plat_pm.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* common headers */ +#include +#include +#include +#include +#include +#include + +/* mediatek platform specific headers */ +#include +#include +#include +#include +#include + +/******************************************************************************* + * MTK_platform handler called when an affinity instance is about to be turned + * on. The level and mpidr determine the affinity instance. + ******************************************************************************/ +static uintptr_t secure_entrypoint; + +static const plat_psci_ops_t plat_plat_pm_ops = { + .cpu_standby = NULL, + .pwr_domain_on = NULL, + .pwr_domain_on_finish = NULL, + .pwr_domain_off = NULL, + .pwr_domain_suspend = NULL, + .pwr_domain_suspend_finish = NULL, + .system_off = NULL, + .system_reset = NULL, + .validate_power_state = NULL, + .get_sys_suspend_power_state = NULL, +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + *psci_ops = &plat_plat_pm_ops; + secure_entrypoint = sec_entrypoint; + return 0; +} diff --git a/plat/mediatek/mt8183/plat_topology.c b/plat/mediatek/mt8183/plat_topology.c new file mode 100644 index 0000000..7b1dd03 --- /dev/null +++ b/plat/mediatek/mt8183/plat_topology.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#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_CLUSTER_COUNT, + /* Number of children for the first cluster node */ + PLATFORM_CLUSTER0_CORE_COUNT, + /* Number of children for the second cluster node */ + PLATFORM_CLUSTER1_CORE_COUNT +}; + +/******************************************************************************* + * This function returns the MT8173 default topology tree information. + ******************************************************************************/ +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; + + mpidr &= MPIDR_AFFINITY_MASK; + + if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) + 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 * 4)); +} diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk new file mode 100644 index 0000000..2ceb459 --- /dev/null +++ b/plat/mediatek/mt8183/platform.mk @@ -0,0 +1,53 @@ +# +# Copyright (c) 2019, ARM Limited and Contributors. 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/ + +PLAT_BL_COMMON_SOURCES := lib/xlat_tables/aarch64/xlat_tables.c \ + lib/xlat_tables/xlat_tables_common.c \ + plat/common/plat_gicv2.c \ + plat/common/plat_psci_common.c \ + plat/common/aarch64/crash_console_helpers.S + +BL31_SOURCES += drivers/arm/cci/cci.c \ + drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + drivers/gpio/gpio.c \ + drivers/ti/uart/aarch64/16550_console.S \ + lib/cpus/aarch64/aem_generic.S \ + lib/cpus/aarch64/cortex_a53.S \ + lib/cpus/aarch64/cortex_a73.S \ + ${MTK_PLAT}/common/mtk_plat_common.c \ + ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ + ${MTK_PLAT_SOC}/aarch64/platform_common.c \ + ${MTK_PLAT_SOC}/plat_pm.c \ + ${MTK_PLAT_SOC}/plat_topology.c \ + ${MTK_PLAT_SOC}/bl31_plat_setup.c \ + ${MTK_PLAT_SOC}/plat_debug.c \ + ${MTK_PLAT_SOC}/scu.c + +# Enable workarounds for selected Cortex-A53 erratas. +ERRATA_A53_826319 := 0 +ERRATA_A53_836870 := 1 +ERRATA_A53_855873 := 1 + +# indicate the reset vector address can be programmed +PROGRAMMABLE_RESET_ADDRESS := 1 + +COLD_BOOT_SINGLE_CPU := 1 + +MULTI_CONSOLE_API := 1 + +MACH_MT8183 := 1 +$(eval $(call add_define,MACH_MT8183)) + diff --git a/plat/mediatek/mt8183/scu.c b/plat/mediatek/mt8183/scu.c new file mode 100644 index 0000000..c4f1c3f --- /dev/null +++ b/plat/mediatek/mt8183/scu.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void disable_scu(u_register_t mpidr) +{ + uintptr_t axi_config = 0; + uint32_t axi_value; + + switch (mpidr & MPIDR_CLUSTER_MASK) { + case 0x000: + axi_config = (uintptr_t)&mt8183_mcucfg->mp0_axi_config; + axi_value = MP0_ACINACTM; + break; + case 0x100: + axi_config = (uintptr_t)&mt8183_mcucfg->mp2_axi_config; + axi_value = MP2_ACINACTM; + break; + default: + ERROR("%s: mpidr does not exist\n", __func__); + panic(); + } + mmio_setbits_32(axi_config, axi_value); +} + +void enable_scu(u_register_t mpidr) +{ + uintptr_t axi_config = 0; + uint32_t axi_value; + + switch (mpidr & MPIDR_CLUSTER_MASK) { + case 0x000: + axi_config = (uintptr_t)&mt8183_mcucfg->mp0_axi_config; + axi_value = MP0_ACINACTM; + break; + case 0x100: + axi_config = (uintptr_t)&mt8183_mcucfg->mp2_axi_config; + axi_value = MP2_ACINACTM; + break; + default: + ERROR("%s: mpidr does not exist\n", __func__); + panic(); + } + mmio_clrbits_32(axi_config, axi_value); +}