Commit bd08def3 authored by Anson Huang's avatar Anson Huang
Browse files

Support for NXP's imx SoC common function



This patch adds support for NXP's imx SoC common
function support like topology, gic implementation.
Signed-off-by: default avatarAnson Huang <Anson.Huang@nxp.com>
parent 27b9d5ea
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
#include <platform_def.h>
#include <cortex_a35.h>
.globl plat_is_my_cpu_primary
.globl plat_my_core_pos
.globl plat_calc_core_pos
.globl plat_reset_handler
.globl plat_get_my_entrypoint
.globl plat_secondary_cold_boot_setup
.globl plat_crash_console_init
.globl plat_crash_console_putc
.globl platform_mem_init
.globl imx_mailbox_init
/* --------------------------------------------------------------------
* Helper macro that reads the part number of the current CPU and jumps
* to the given label if it matches the CPU MIDR provided.
*
* Clobbers x0.
* --------------------------------------------------------------------
*/
.macro jump_if_cpu_midr _cpu_midr, _label
mrs x0, midr_el1
ubfx x0, x0, MIDR_PN_SHIFT, #12
cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
b.eq \_label
.endm
/* ----------------------------------------------
* The mailbox_base is used to distinguish warm/cold
* reset. The mailbox_base is in the data section, not
* in .bss, this allows function to start using this
* variable before the runtime memory is initialized.
* ----------------------------------------------
*/
.section .data.mailbox_base
.align 3
mailbox_base: .quad 0x0
/* ----------------------------------------------
* unsigned int plat_is_my_cpu_primary(void);
* This function checks if this is the primary CPU
* ----------------------------------------------
*/
func plat_is_my_cpu_primary
mrs x0, mpidr_el1
and x0, x0, #(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_calc_core_pos()
* to get the index of the calling CPU.
* ----------------------------------------------
*/
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
/*
* unsigned int plat_calc_core_pos(uint64_t mpidr)
* helper function to calculate the core position.
* With this function.
*/
func plat_calc_core_pos
and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK
add x0, x1, x0, LSR #6
ret
endfunc plat_calc_core_pos
/* ---------------------------------------------
* function to get the entrypoint.
* ---------------------------------------------
*/
func plat_get_my_entrypoint
adrp x1, mailbox_base
ldr x0, [x1, :lo12:mailbox_base]
ret
endfunc plat_get_my_entrypoint
func imx_mailbox_init
adrp x1, mailbox_base
str x0, [x1, :lo12:mailbox_base]
ret
endfunc imx_mailbox_init
func plat_secondary_cold_boot_setup
b .
endfunc plat_secondary_cold_boot_setup
func plat_crash_console_init
ret
endfunc plat_crash_console_init
func plat_crash_console_putc
ret
endfunc plat_crash_console_putc
func platform_mem_init
ret
endfunc platform_mem_init
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <platform.h>
const unsigned char imx_power_domain_tree_desc[] = {
PWR_DOMAIN_AT_MAX_LVL,
PLATFORM_CLUSTER_COUNT,
PLATFORM_CORE_COUNT,
};
const unsigned char *plat_get_power_domain_tree_desc(void)
{
return imx_power_domain_tree_desc;
}
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_AFFLVL1_VAL(mpidr);
cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
if (cluster_id > PLATFORM_CLUSTER_COUNT ||
cpu_id > PLATFORM_MAX_CPU_PER_CLUSTER)
return -1;
return (cpu_id + (cluster_id * 4));
}
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PLAT_IMX8_H__
#define __PLAT_IMX8_H__
#include <gicv3.h>
unsigned int plat_calc_core_pos(uint64_t mpidr);
void imx_mailbox_init(uintptr_t base_addr);
void plat_gic_driver_init(void);
void plat_gic_init(void);
void plat_gic_cpuif_enable(void);
void plat_gic_cpuif_disable(void);
void plat_gic_pcpu_init(void);
#endif /*__PLAT_IMX8_H__ */
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* the below macros print out relevant GIC
* registers whenever an unhandled exception is
* taken in BL3-1
*/
.macro plat_print_gic_regs
/* TODO */
.endm
/*
* the below macros print out relevant interconnect
* registers whenever an unhandled exception is
* taken in BL3-1
*/
.macro plat_print_interconnect_regs
/* TODO */
.endm
/* ---------------------------------------------
* The below required platform porting macro
* prints out relevant platform registers
* whenever an unhandled exception is taken in
* BL31.
* ---------------------------------------------
*/
.macro plat_crash_print_regs
/* TODO */
.endm
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <bl_common.h>
#include <gicv3.h>
#include <plat_imx8.h>
#include <platform.h>
#include <platform_def.h>
#include <utils.h>
/* the GICv3 driver only needs to be initialized in EL3 */
uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
/* array of Group1 secure interrupts to be configured by the gic driver */
const unsigned int g1s_interrupt_array[] = { 6 };
/* array of Group0 interrupts to be configured by the gic driver */
const unsigned int g0_interrupt_array[] = { 7 };
static unsigned int plat_imx_mpidr_to_core_pos(unsigned long mpidr)
{
return (unsigned int)plat_core_pos_by_mpidr(mpidr);
}
const gicv3_driver_data_t arm_gic_data = {
.gicd_base = PLAT_GICD_BASE,
.gicr_base = PLAT_GICR_BASE,
.g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array),
.g1s_interrupt_num = ARRAY_SIZE(g1s_interrupt_array),
.g0_interrupt_array = g0_interrupt_array,
.g1s_interrupt_array = g1s_interrupt_array,
.rdistif_num = PLATFORM_CORE_COUNT,
.rdistif_base_addrs = rdistif_base_addrs,
.mpidr_to_core_pos = plat_imx_mpidr_to_core_pos,
};
void plat_gic_driver_init(void)
{
/*
* the GICv3 driver is initialized in EL3 and does not need
* to be initialized again in S-EL1. This is because the S-EL1
* can use GIC system registers to manage interrupts and does
* not need GIC interface base addresses to be configured.
*/
#if IMAGE_BL31
gicv3_driver_init(&arm_gic_data);
#endif
}
void plat_gic_init(void)
{
gicv3_distif_init();
gicv3_rdistif_init(plat_my_core_pos());
gicv3_cpuif_enable(plat_my_core_pos());
}
void plat_gic_cpuif_enable(void)
{
gicv3_cpuif_enable(plat_my_core_pos());
}
void plat_gic_cpuif_disable(void)
{
gicv3_cpuif_disable(plat_my_core_pos());
}
void plat_gic_pcpu_init(void)
{
gicv3_rdistif_init(plat_my_core_pos());
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment