GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
+164
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <common/bl_common.h>
|
||||
#include <cortex_a12.h>
|
||||
#include <plat_private.h>
|
||||
#include <plat_pmu_macros.S>
|
||||
|
||||
.globl cpuson_entry_point
|
||||
.globl cpuson_flags
|
||||
.globl platform_cpu_warmboot
|
||||
.globl plat_secondary_cold_boot_setup
|
||||
.globl plat_report_exception
|
||||
.globl plat_is_my_cpu_primary
|
||||
.globl plat_my_core_pos
|
||||
.globl plat_reset_handler
|
||||
.globl plat_panic_handler
|
||||
|
||||
/*
|
||||
* void plat_reset_handler(void);
|
||||
*
|
||||
* Determine the SOC type and call the appropriate reset
|
||||
* handler.
|
||||
*
|
||||
*/
|
||||
func plat_reset_handler
|
||||
bx lr
|
||||
endfunc plat_reset_handler
|
||||
|
||||
func plat_my_core_pos
|
||||
ldcopr r0, MPIDR
|
||||
and r1, r0, #MPIDR_CPU_MASK
|
||||
#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
|
||||
and r0, r0, #PLAT_RK_MPIDR_CLUSTER_MASK
|
||||
#else
|
||||
and r0, r0, #MPIDR_CLUSTER_MASK
|
||||
#endif
|
||||
add r0, r1, r0, LSR #PLAT_RK_CLST_TO_CPUID_SHIFT
|
||||
bx lr
|
||||
endfunc plat_my_core_pos
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* void plat_secondary_cold_boot_setup (void);
|
||||
*
|
||||
* This function performs any platform specific actions
|
||||
* needed for a secondary cpu after a cold reset e.g
|
||||
* mark the cpu's presence, mechanism to place it in a
|
||||
* holding pen etc.
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func plat_secondary_cold_boot_setup
|
||||
/* rk3288 does not do cold boot for secondary CPU */
|
||||
cb_panic:
|
||||
b cb_panic
|
||||
endfunc plat_secondary_cold_boot_setup
|
||||
|
||||
func plat_is_my_cpu_primary
|
||||
ldcopr r0, MPIDR
|
||||
#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
|
||||
ldr r1, =(PLAT_RK_MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
|
||||
#else
|
||||
ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
|
||||
#endif
|
||||
and r0, r1
|
||||
cmp r0, #PLAT_RK_PRIMARY_CPU
|
||||
moveq r0, #1
|
||||
movne r0, #0
|
||||
bx lr
|
||||
endfunc plat_is_my_cpu_primary
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* void plat_panic_handler(void)
|
||||
* Call system reset function on panic. Set up an emergency stack so we
|
||||
* can run C functions (it only needs to last for a few calls until we
|
||||
* reboot anyway).
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func plat_panic_handler
|
||||
bl plat_set_my_stack
|
||||
b rockchip_soc_soft_reset
|
||||
endfunc plat_panic_handler
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* void platform_cpu_warmboot (void);
|
||||
* cpus online or resume entrypoint
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func platform_cpu_warmboot _align=16
|
||||
push { r4 - r7, lr }
|
||||
ldcopr r0, MPIDR
|
||||
and r5, r0, #MPIDR_CPU_MASK
|
||||
#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
|
||||
and r6, r0, #PLAT_RK_MPIDR_CLUSTER_MASK
|
||||
#else
|
||||
and r6, r0, #MPIDR_CLUSTER_MASK
|
||||
#endif
|
||||
mov r0, r6
|
||||
|
||||
func_rockchip_clst_warmboot
|
||||
/* --------------------------------------------------------------------
|
||||
* big cluster id is 1
|
||||
* big cores id is from 0-3, little cores id 4-7
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
add r7, r5, r6, LSR #PLAT_RK_CLST_TO_CPUID_SHIFT
|
||||
/* --------------------------------------------------------------------
|
||||
* get per cpuup flag
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
ldr r4, =cpuson_flags
|
||||
add r4, r4, r7, lsl #2
|
||||
ldr r1, [r4]
|
||||
/* --------------------------------------------------------------------
|
||||
* check cpuon reason
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
cmp r1, #PMU_CPU_AUTO_PWRDN
|
||||
beq boot_entry
|
||||
cmp r1, #PMU_CPU_HOTPLUG
|
||||
beq boot_entry
|
||||
/* --------------------------------------------------------------------
|
||||
* If the boot core cpuson_flags or cpuson_entry_point is not
|
||||
* expection. force the core into wfe.
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
wfe_loop:
|
||||
wfe
|
||||
b wfe_loop
|
||||
boot_entry:
|
||||
mov r1, #0
|
||||
str r1, [r4]
|
||||
/* --------------------------------------------------------------------
|
||||
* get per cpuup boot addr
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
ldr r5, =cpuson_entry_point
|
||||
ldr r2, [r5, r7, lsl #2] /* ehem. #3 */
|
||||
pop { r4 - r7, lr }
|
||||
|
||||
bx r2
|
||||
endfunc platform_cpu_warmboot
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Per-CPU Secure entry point - resume or power up
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
.section tzfw_coherent_mem, "a"
|
||||
.align 3
|
||||
cpuson_entry_point:
|
||||
.rept PLATFORM_CORE_COUNT
|
||||
.quad 0
|
||||
.endr
|
||||
cpuson_flags:
|
||||
.rept PLATFORM_CORE_COUNT
|
||||
.word 0
|
||||
.endr
|
||||
rockchip_clst_warmboot_data
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <lib/utils.h>
|
||||
#include <lib/xlat_tables/xlat_tables.h>
|
||||
|
||||
#include <plat_private.h>
|
||||
|
||||
void plat_configure_mmu_svc_mon(unsigned long total_base,
|
||||
unsigned long total_size,
|
||||
unsigned long ro_start,
|
||||
unsigned long ro_limit,
|
||||
unsigned long coh_start,
|
||||
unsigned long 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_rk_mmap);
|
||||
rockchip_plat_mmu_svc_mon();
|
||||
init_xlat_tables();
|
||||
enable_mmu_svc_mon(0);
|
||||
}
|
||||
|
||||
unsigned int plat_get_syscnt_freq2(void)
|
||||
{
|
||||
return SYS_COUNTER_FREQ_IN_TICKS;
|
||||
}
|
||||
|
||||
/*
|
||||
* generic pm code does cci handling, but rockchip arm32 platforms
|
||||
* have ever only 1 cluster, so nothing to do.
|
||||
*/
|
||||
void plat_cci_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void plat_cci_enable(void)
|
||||
{
|
||||
}
|
||||
|
||||
void plat_cci_disable(void)
|
||||
{
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <platform_def.h>
|
||||
|
||||
.globl pmu_cpuson_entrypoint
|
||||
.macro pmusram_entry_func _name
|
||||
.section .pmusram.entry, "ax"
|
||||
.type \_name, %function
|
||||
.cfi_startproc
|
||||
\_name:
|
||||
.endm
|
||||
|
||||
pmusram_entry_func pmu_cpuson_entrypoint
|
||||
|
||||
#if PSRAM_CHECK_WAKEUP_CPU
|
||||
check_wake_cpus:
|
||||
ldcopr r0, MPIDR
|
||||
and r1, r0, #MPIDR_CPU_MASK
|
||||
#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
|
||||
and r0, r0, #PLAT_RK_MPIDR_CLUSTER_MASK
|
||||
#else
|
||||
and r0, r0, #MPIDR_CLUSTER_MASK
|
||||
#endif
|
||||
orr r0, r0, r1
|
||||
|
||||
/* primary_cpu */
|
||||
ldr r1, boot_mpidr
|
||||
cmp r0, r1
|
||||
beq sys_wakeup
|
||||
|
||||
/*
|
||||
* If the core is not the primary cpu,
|
||||
* force the core into wfe.
|
||||
*/
|
||||
wfe_loop:
|
||||
wfe
|
||||
b wfe_loop
|
||||
sys_wakeup:
|
||||
#endif
|
||||
|
||||
#if PSRAM_DO_DDR_RESUME
|
||||
ddr_resume:
|
||||
ldr r2, =__bl32_sram_stack_end
|
||||
mov sp, r2
|
||||
bl dmc_resume
|
||||
#endif
|
||||
bl sram_restore
|
||||
sys_resume:
|
||||
bl sp_min_warm_entrypoint
|
||||
endfunc pmu_cpuson_entrypoint
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <common/bl_common.h>
|
||||
#include <cortex_a53.h>
|
||||
#include <cortex_a72.h>
|
||||
#include <plat_private.h>
|
||||
#include <plat_pmu_macros.S>
|
||||
|
||||
.globl cpuson_entry_point
|
||||
.globl cpuson_flags
|
||||
.globl platform_cpu_warmboot
|
||||
.globl plat_secondary_cold_boot_setup
|
||||
.globl plat_report_exception
|
||||
.globl plat_is_my_cpu_primary
|
||||
.globl plat_my_core_pos
|
||||
.globl plat_reset_handler
|
||||
.globl plat_panic_handler
|
||||
|
||||
/*
|
||||
* void plat_reset_handler(void);
|
||||
*
|
||||
* Determine the SOC type and call the appropriate reset
|
||||
* handler.
|
||||
*
|
||||
*/
|
||||
func plat_reset_handler
|
||||
mrs x0, midr_el1
|
||||
ubfx x0, x0, MIDR_PN_SHIFT, #12
|
||||
cmp w0, #((CORTEX_A72_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
|
||||
b.eq handler_a72
|
||||
b handler_end
|
||||
handler_a72:
|
||||
/*
|
||||
* This handler does the following:
|
||||
* Set the L2 Data RAM latency for Cortex-A72.
|
||||
* Set the L2 Tag RAM latency to for Cortex-A72.
|
||||
*/
|
||||
mov x0, #((5 << CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
|
||||
(0x1 << 5))
|
||||
msr CORTEX_A72_L2CTLR_EL1, x0
|
||||
isb
|
||||
handler_end:
|
||||
ret
|
||||
endfunc plat_reset_handler
|
||||
|
||||
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 #PLAT_RK_CLST_TO_CPUID_SHIFT
|
||||
ret
|
||||
endfunc plat_my_core_pos
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* void plat_secondary_cold_boot_setup (void);
|
||||
*
|
||||
* This function performs any platform specific actions
|
||||
* needed for a secondary cpu after a cold reset e.g
|
||||
* mark the cpu's presence, mechanism to place it in a
|
||||
* holding pen etc.
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func plat_secondary_cold_boot_setup
|
||||
/* rk3368 does not do cold boot for secondary CPU */
|
||||
cb_panic:
|
||||
b cb_panic
|
||||
endfunc plat_secondary_cold_boot_setup
|
||||
|
||||
func plat_is_my_cpu_primary
|
||||
mrs x0, mpidr_el1
|
||||
and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
|
||||
cmp x0, #PLAT_RK_PRIMARY_CPU
|
||||
cset x0, eq
|
||||
ret
|
||||
endfunc plat_is_my_cpu_primary
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* void plat_panic_handler(void)
|
||||
* Call system reset function on panic. Set up an emergency stack so we
|
||||
* can run C functions (it only needs to last for a few calls until we
|
||||
* reboot anyway).
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func plat_panic_handler
|
||||
msr spsel, #0
|
||||
bl plat_set_my_stack
|
||||
b rockchip_soc_soft_reset
|
||||
endfunc plat_panic_handler
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* void platform_cpu_warmboot (void);
|
||||
* cpus online or resume enterpoint
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func platform_cpu_warmboot _align=16
|
||||
mrs x0, MPIDR_EL1
|
||||
and x19, x0, #MPIDR_CPU_MASK
|
||||
and x20, x0, #MPIDR_CLUSTER_MASK
|
||||
mov x0, x20
|
||||
func_rockchip_clst_warmboot
|
||||
/* --------------------------------------------------------------------
|
||||
* big cluster id is 1
|
||||
* big cores id is from 0-3, little cores id 4-7
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
add x21, x19, x20, lsr #PLAT_RK_CLST_TO_CPUID_SHIFT
|
||||
/* --------------------------------------------------------------------
|
||||
* get per cpuup flag
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
adr x4, cpuson_flags
|
||||
add x4, x4, x21, lsl #2
|
||||
ldr w1, [x4]
|
||||
/* --------------------------------------------------------------------
|
||||
* check cpuon reason
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
cmp w1, PMU_CPU_AUTO_PWRDN
|
||||
b.eq boot_entry
|
||||
cmp w1, PMU_CPU_HOTPLUG
|
||||
b.eq boot_entry
|
||||
/* --------------------------------------------------------------------
|
||||
* If the boot core cpuson_flags or cpuson_entry_point is not
|
||||
* expection. force the core into wfe.
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
wfe_loop:
|
||||
wfe
|
||||
b wfe_loop
|
||||
boot_entry:
|
||||
str wzr, [x4]
|
||||
/* --------------------------------------------------------------------
|
||||
* get per cpuup boot addr
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
adr x5, cpuson_entry_point
|
||||
ldr x2, [x5, x21, lsl #3]
|
||||
br x2
|
||||
endfunc platform_cpu_warmboot
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Per-CPU Secure entry point - resume or power up
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
.section tzfw_coherent_mem, "a"
|
||||
.align 3
|
||||
cpuson_entry_point:
|
||||
.rept PLATFORM_CORE_COUNT
|
||||
.quad 0
|
||||
.endr
|
||||
cpuson_flags:
|
||||
.rept PLATFORM_CORE_COUNT
|
||||
.word 0
|
||||
.endr
|
||||
rockchip_clst_warmboot_data
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/arm/cci.h>
|
||||
#include <lib/utils.h>
|
||||
#include <lib/xlat_tables/xlat_tables.h>
|
||||
|
||||
#include <plat_private.h>
|
||||
|
||||
#ifdef PLAT_RK_CCI_BASE
|
||||
static const int cci_map[] = {
|
||||
PLAT_RK_CCI_CLUSTER0_SL_IFACE_IX,
|
||||
PLAT_RK_CCI_CLUSTER1_SL_IFACE_IX
|
||||
};
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* 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
|
||||
******************************************************************************/
|
||||
#define DEFINE_CONFIGURE_MMU_EL(_el) \
|
||||
void plat_configure_mmu_el ## _el(unsigned long total_base, \
|
||||
unsigned long total_size, \
|
||||
unsigned long ro_start, \
|
||||
unsigned long ro_limit, \
|
||||
unsigned long coh_start, \
|
||||
unsigned long 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_rk_mmap); \
|
||||
rockchip_plat_mmu_el##_el(); \
|
||||
init_xlat_tables(); \
|
||||
\
|
||||
enable_mmu_el ## _el(0); \
|
||||
}
|
||||
|
||||
/* Define EL3 variants of the function initialising the MMU */
|
||||
DEFINE_CONFIGURE_MMU_EL(3)
|
||||
|
||||
unsigned int plat_get_syscnt_freq2(void)
|
||||
{
|
||||
return SYS_COUNTER_FREQ_IN_TICKS;
|
||||
}
|
||||
|
||||
void plat_cci_init(void)
|
||||
{
|
||||
#ifdef PLAT_RK_CCI_BASE
|
||||
/* Initialize CCI driver */
|
||||
cci_init(PLAT_RK_CCI_BASE, cci_map, ARRAY_SIZE(cci_map));
|
||||
#endif
|
||||
}
|
||||
|
||||
void plat_cci_enable(void)
|
||||
{
|
||||
/*
|
||||
* Enable CCI coherency for this cluster.
|
||||
* No need for locks as no other cpu is active at the moment.
|
||||
*/
|
||||
#ifdef PLAT_RK_CCI_BASE
|
||||
cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
|
||||
#endif
|
||||
}
|
||||
|
||||
void plat_cci_disable(void)
|
||||
{
|
||||
#ifdef PLAT_RK_CCI_BASE
|
||||
cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
|
||||
#endif
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <platform_def.h>
|
||||
|
||||
.globl pmu_cpuson_entrypoint
|
||||
.macro pmusram_entry_func _name
|
||||
.section .pmusram.entry, "ax"
|
||||
.type \_name, %function
|
||||
.cfi_startproc
|
||||
\_name:
|
||||
.endm
|
||||
|
||||
pmusram_entry_func pmu_cpuson_entrypoint
|
||||
|
||||
#if PSRAM_CHECK_WAKEUP_CPU
|
||||
check_wake_cpus:
|
||||
mrs x0, MPIDR_EL1
|
||||
and x1, x0, #MPIDR_CPU_MASK
|
||||
and x0, x0, #MPIDR_CLUSTER_MASK
|
||||
orr x0, x0, x1
|
||||
|
||||
/* primary_cpu */
|
||||
ldr w1, boot_mpidr
|
||||
cmp w0, w1
|
||||
b.eq sys_wakeup
|
||||
|
||||
/*
|
||||
* If the core is not the primary cpu,
|
||||
* force the core into wfe.
|
||||
*/
|
||||
wfe_loop:
|
||||
wfe
|
||||
b wfe_loop
|
||||
sys_wakeup:
|
||||
#endif
|
||||
|
||||
#if PSRAM_DO_DDR_RESUME
|
||||
ddr_resume:
|
||||
ldr x2, =__bl31_sram_stack_end
|
||||
mov sp, x2
|
||||
bl dmc_resume
|
||||
#endif
|
||||
bl sram_restore
|
||||
sys_resume:
|
||||
bl bl31_warm_entrypoint
|
||||
endfunc pmu_cpuson_entrypoint
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/desc_image_load.h>
|
||||
#include <drivers/console.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <drivers/ti/uart/uart_16550.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <plat_private.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#pragma weak params_early_setup
|
||||
void params_early_setup(u_register_t plat_param_from_bl2)
|
||||
{
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Perform any BL3-1 early platform setup. Here is an opportunity to copy
|
||||
* parameters passed by the calling EL (S-EL1 in BL2 & 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 (rockchip_get_uart_base() != 0)
|
||||
console_16550_register(rockchip_get_uart_base(),
|
||||
rockchip_get_uart_clock(),
|
||||
rockchip_get_uart_baudrate(), &console);
|
||||
|
||||
VERBOSE("bl31_setup\n");
|
||||
|
||||
bl31_params_parse_helper(arg0, &bl32_ep_info, &bl33_ep_info);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Perform any BL3-1 platform setup code
|
||||
******************************************************************************/
|
||||
void bl31_platform_setup(void)
|
||||
{
|
||||
generic_delay_timer_init();
|
||||
plat_rockchip_soc_init();
|
||||
|
||||
/* Initialize the gic cpu and distributor interfaces */
|
||||
plat_rockchip_gic_driver_init();
|
||||
plat_rockchip_gic_init();
|
||||
plat_rockchip_pmu_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)
|
||||
{
|
||||
plat_cci_init();
|
||||
plat_cci_enable();
|
||||
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);
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/console.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <plat_private.h>
|
||||
#include <soc.h>
|
||||
|
||||
#include "ddr_parameter.h"
|
||||
|
||||
/*
|
||||
* The miniloader delivers the parameters about ddr usage info from address
|
||||
* 0x02000000 and the data format is defined as below figure. It tells ATF the
|
||||
* areas of ddr that are used by platform, we treat them as non-secure regions
|
||||
* by default. Then we should parse the other part regions and configurate them
|
||||
* as secure regions to avoid illegal access.
|
||||
*
|
||||
* [ddr usage info data format]
|
||||
* 0x02000000
|
||||
* -----------------------------------------------------------------------------
|
||||
* | <name> | <size> | <description> |
|
||||
* -----------------------------------------------------------------------------
|
||||
* | count | 4byte | the array numbers of the |
|
||||
* | | | 'addr_array' and 'size_array' |
|
||||
* -----------------------------------------------------------------------------
|
||||
* | reserved | 4byte | just for 'addr_array' 8byte aligned |
|
||||
* -----------------------------------------------------------------------------
|
||||
* | addr_array[count] | per 8byte | memory region base address |
|
||||
* -----------------------------------------------------------------------------
|
||||
* | size_array[count] | per 8byte | memory region size (byte) |
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* function: read parameters info(ns-regions) and try to parse s-regions info
|
||||
*
|
||||
* @addr: head address to the ddr usage struct from miniloader
|
||||
* @max_mb: the max ddr capacity(MB) that the platform support
|
||||
*/
|
||||
struct param_ddr_usage ddr_region_usage_parse(uint64_t addr, uint64_t max_mb)
|
||||
{
|
||||
uint64_t base, top;
|
||||
uint32_t i, addr_offset, size_offset;
|
||||
struct param_ddr_usage p;
|
||||
|
||||
memset(&p, 0, sizeof(p));
|
||||
|
||||
/* read how many blocks of ns-regions, read from offset: 0x0 */
|
||||
p.ns_nr = mmio_read_32(addr + REGION_NR_OFFSET);
|
||||
if ((p.ns_nr > DDR_REGION_NR_MAX) || (p.ns_nr == 0)) {
|
||||
ERROR("over or zero region, nr=%d, max=%d\n",
|
||||
p.ns_nr, DDR_REGION_NR_MAX);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* whole ddr regions boundary, it will be used when parse s-regions */
|
||||
p.boundary = max_mb;
|
||||
|
||||
/* calculate ns-region base addr and size offset */
|
||||
addr_offset = REGION_ADDR_OFFSET;
|
||||
size_offset = REGION_ADDR_OFFSET + p.ns_nr * REGION_DATA_PER_BYTES;
|
||||
|
||||
/* read all ns-regions base and top address */
|
||||
for (i = 0; i < p.ns_nr; i++) {
|
||||
base = mmio_read_64(addr + addr_offset);
|
||||
top = base + mmio_read_64(addr + size_offset);
|
||||
/*
|
||||
* translate byte to MB and store info,
|
||||
* Miniloader will promise every ns-region is MB aligned.
|
||||
*/
|
||||
p.ns_base[i] = RG_SIZE_MB(base);
|
||||
p.ns_top[i] = RG_SIZE_MB(top);
|
||||
|
||||
addr_offset += REGION_DATA_PER_BYTES;
|
||||
size_offset += REGION_DATA_PER_BYTES;
|
||||
}
|
||||
|
||||
/*
|
||||
* a s-region's base starts from previous ns-region's top, and a
|
||||
* s-region's top ends with next ns-region's base. maybe like this:
|
||||
*
|
||||
* case1: ns-regison start from 0MB
|
||||
* -----------------------------------------------
|
||||
* | ns0 | S0 | ns1 | S1 | ns2 |
|
||||
* 0----------------------------------------------- max_mb
|
||||
*
|
||||
*
|
||||
* case2: ns-regison not start from 0MB
|
||||
* -----------------------------------------------
|
||||
* | S0 | ns0 | ns1 | ns2 | S1 |
|
||||
* 0----------------------------------------------- max_mb
|
||||
*/
|
||||
|
||||
/* like above case2 figure, ns-region is not start from 0MB */
|
||||
if (p.ns_base[0] != 0) {
|
||||
p.s_base[p.s_nr] = 0;
|
||||
p.s_top[p.s_nr] = p.ns_base[0];
|
||||
p.s_nr++;
|
||||
}
|
||||
|
||||
/*
|
||||
* notice: if ns-regions not start from 0MB, p.s_nr = 1 now, otherwise 0
|
||||
*/
|
||||
for (i = 0; i < p.ns_nr; i++) {
|
||||
/*
|
||||
* if current ns-regions top covers boundary,
|
||||
* that means s-regions are all parsed yet, so finsh.
|
||||
*/
|
||||
if (p.ns_top[i] == p.boundary)
|
||||
goto out;
|
||||
|
||||
/* s-region's base starts from previous ns-region's top */
|
||||
p.s_base[p.s_nr] = p.ns_top[i];
|
||||
|
||||
/* s-region's top ends with next ns-region's base */
|
||||
if (i + 1 < p.ns_nr)
|
||||
p.s_top[p.s_nr] = p.ns_base[i + 1];
|
||||
else
|
||||
p.s_top[p.s_nr] = p.boundary;
|
||||
p.s_nr++;
|
||||
}
|
||||
out:
|
||||
return p;
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef DDR_PARAMETER_H
|
||||
#define DDR_PARAMETER_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/console.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <plat_private.h>
|
||||
#include <soc.h>
|
||||
|
||||
#define DDR_REGION_NR_MAX 10
|
||||
#define REGION_NR_OFFSET 0
|
||||
#define REGION_ADDR_OFFSET 8
|
||||
#define REGION_DATA_PER_BYTES 8
|
||||
#define RG_SIZE_MB(byte) ((byte) >> 20)
|
||||
|
||||
/* unit: MB */
|
||||
struct param_ddr_usage {
|
||||
uint64_t boundary;
|
||||
|
||||
uint32_t ns_nr;
|
||||
uint64_t ns_base[DDR_REGION_NR_MAX];
|
||||
uint64_t ns_top[DDR_REGION_NR_MAX];
|
||||
|
||||
uint32_t s_nr;
|
||||
uint64_t s_base[DDR_REGION_NR_MAX + 1];
|
||||
uint64_t s_top[DDR_REGION_NR_MAX + 1];
|
||||
};
|
||||
|
||||
struct param_ddr_usage ddr_region_usage_parse(uint64_t addr, uint64_t max_mb);
|
||||
|
||||
#endif /* DDR_PARAMETER_H */
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PMU_COM_H
|
||||
#define PMU_COM_H
|
||||
|
||||
#ifndef CHECK_CPU_WFIE_BASE
|
||||
#define CHECK_CPU_WFIE_BASE (PMU_BASE + PMU_CORE_PWR_ST)
|
||||
#endif
|
||||
/*
|
||||
* Use this macro to instantiate lock before it is used in below
|
||||
* rockchip_pd_lock_xxx() macros
|
||||
*/
|
||||
DECLARE_BAKERY_LOCK(rockchip_pd_lock);
|
||||
|
||||
/*
|
||||
* These are wrapper macros to the powe domain Bakery Lock API.
|
||||
*/
|
||||
#define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock)
|
||||
#define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock)
|
||||
#define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock)
|
||||
|
||||
/*****************************************************************************
|
||||
* power domain on or off
|
||||
*****************************************************************************/
|
||||
enum pmu_pd_state {
|
||||
pmu_pd_on = 0,
|
||||
pmu_pd_off = 1
|
||||
};
|
||||
|
||||
#pragma weak plat_ic_get_pending_interrupt_id
|
||||
#pragma weak pmu_power_domain_ctr
|
||||
#pragma weak check_cpu_wfie
|
||||
|
||||
static inline uint32_t pmu_power_domain_st(uint32_t pd)
|
||||
{
|
||||
uint32_t pwrdn_st = mmio_read_32(PMU_BASE + PMU_PWRDN_ST) & BIT(pd);
|
||||
|
||||
if (pwrdn_st)
|
||||
return pmu_pd_off;
|
||||
else
|
||||
return pmu_pd_on;
|
||||
}
|
||||
|
||||
static int pmu_power_domain_ctr(uint32_t pd, uint32_t pd_state)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t loop = 0;
|
||||
int ret = 0;
|
||||
|
||||
rockchip_pd_lock_get();
|
||||
|
||||
val = mmio_read_32(PMU_BASE + PMU_PWRDN_CON);
|
||||
if (pd_state == pmu_pd_off)
|
||||
val |= BIT(pd);
|
||||
else
|
||||
val &= ~BIT(pd);
|
||||
|
||||
mmio_write_32(PMU_BASE + PMU_PWRDN_CON, val);
|
||||
dsb();
|
||||
|
||||
while ((pmu_power_domain_st(pd) != pd_state) && (loop < PD_CTR_LOOP)) {
|
||||
udelay(1);
|
||||
loop++;
|
||||
}
|
||||
|
||||
if (pmu_power_domain_st(pd) != pd_state) {
|
||||
WARN("%s: %d, %d, error!\n", __func__, pd, pd_state);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
rockchip_pd_lock_rls();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int check_cpu_wfie(uint32_t cpu_id, uint32_t wfie_msk)
|
||||
{
|
||||
uint32_t cluster_id, loop = 0;
|
||||
|
||||
if (cpu_id >= PLATFORM_CLUSTER0_CORE_COUNT) {
|
||||
cluster_id = 1;
|
||||
cpu_id -= PLATFORM_CLUSTER0_CORE_COUNT;
|
||||
} else {
|
||||
cluster_id = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* wfe/wfi tracking not possible, hopefully the host
|
||||
* was sucessful in enabling wfe/wfi.
|
||||
* We'll give a bit of additional time, like the kernel does.
|
||||
*/
|
||||
if ((cluster_id && clstb_cpu_wfe < 0) ||
|
||||
(!cluster_id && clstl_cpu_wfe < 0)) {
|
||||
mdelay(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cluster_id)
|
||||
wfie_msk <<= (clstb_cpu_wfe + cpu_id);
|
||||
else
|
||||
wfie_msk <<= (clstl_cpu_wfe + cpu_id);
|
||||
|
||||
while (!(mmio_read_32(CHECK_CPU_WFIE_BASE) & wfie_msk) &&
|
||||
(loop < CHK_CPU_LOOP)) {
|
||||
udelay(1);
|
||||
loop++;
|
||||
}
|
||||
|
||||
if ((mmio_read_32(CHECK_CPU_WFIE_BASE) & wfie_msk) == 0) {
|
||||
WARN("%s: %d, %d, %d, error!\n", __func__,
|
||||
cluster_id, cpu_id, wfie_msk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* PMU_COM_H */
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef ROCKCHIP_PLAT_MACROS_S
|
||||
#define ROCKCHIP_PLAT_MACROS_S
|
||||
|
||||
#include <drivers/arm/cci.h>
|
||||
#include <drivers/arm/gic_common.h>
|
||||
#include <drivers/arm/gicv2.h>
|
||||
#include <drivers/arm/gicv3.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
.section .rodata.gic_reg_name, "aS"
|
||||
/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */
|
||||
gicc_regs:
|
||||
.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
|
||||
|
||||
/* Applicable only to GICv3 with SRE enabled */
|
||||
icc_regs:
|
||||
.asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", ""
|
||||
|
||||
/* Registers common to both GICv2 and GICv3 */
|
||||
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 utility macro prints out relevant GIC
|
||||
* and CCI registers whenever an unhandled
|
||||
* exception is taken in BL31.
|
||||
* Expects: GICD base in x26, GICC base in x27
|
||||
* Clobbers: x0 - x10, sp
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
.macro plat_crash_print_regs
|
||||
|
||||
mov_imm x26, PLAT_RK_GICD_BASE
|
||||
mov_imm x27, PLAT_RK_GICC_BASE
|
||||
|
||||
/* Check for GICv3 system register access */
|
||||
mrs x7, id_aa64pfr0_el1
|
||||
ubfx x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
|
||||
cmp x7, #1
|
||||
b.ne print_gicv2
|
||||
|
||||
/* Check for SRE enable */
|
||||
mrs x8, ICC_SRE_EL3
|
||||
tst x8, #ICC_SRE_SRE_BIT
|
||||
b.eq print_gicv2
|
||||
|
||||
/* Load the icc reg list to x6 */
|
||||
adr x6, icc_regs
|
||||
/* Load the icc regs to gp regs used by str_in_crash_buf_print */
|
||||
mrs x8, ICC_HPPIR0_EL1
|
||||
mrs x9, ICC_HPPIR1_EL1
|
||||
mrs x10, ICC_CTLR_EL3
|
||||
/* Store to the crash buf and print to console */
|
||||
bl str_in_crash_buf_print
|
||||
b print_gic_common
|
||||
|
||||
print_gicv2:
|
||||
/* 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_gic_common:
|
||||
/* 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:
|
||||
|
||||
#if PLATFORM_CLUSTER_COUNT > 1
|
||||
adr x6, cci_iface_regs
|
||||
/* Store in x7 the base address of the first interface */
|
||||
mov_imm x7, (PLAT_RK_CCI_BASE + SLAVE_IFACE_OFFSET( \
|
||||
PLAT_RK_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_RK_CCI_BASE + SLAVE_IFACE_OFFSET( \
|
||||
PLAT_RK_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
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* ROCKCHIP_PLAT_MACROS_S */
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLAT_PARAMS_H
|
||||
#define PLAT_PARAMS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <export/plat/rockchip/common/plat_params_exp.h>
|
||||
|
||||
#endif /* PLAT_PARAMS_H */
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLAT_PRIVATE_H
|
||||
#define PLAT_PRIVATE_H
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <lib/psci/psci.h>
|
||||
#include <lib/xlat_tables/xlat_tables.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <plat_params.h>
|
||||
|
||||
#define __sramdata __attribute__((section(".sram.data")))
|
||||
#define __sramconst __attribute__((section(".sram.rodata")))
|
||||
#define __sramfunc __attribute__((section(".sram.text")))
|
||||
|
||||
#define __pmusramdata __attribute__((section(".pmusram.data")))
|
||||
#define __pmusramconst __attribute__((section(".pmusram.rodata")))
|
||||
#define __pmusramfunc __attribute__((section(".pmusram.text")))
|
||||
|
||||
extern uint32_t __bl31_sram_text_start, __bl31_sram_text_end;
|
||||
extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end;
|
||||
extern uint32_t __bl31_sram_stack_start, __bl31_sram_stack_end;
|
||||
extern uint32_t __bl31_sram_text_real_end, __bl31_sram_data_real_end;
|
||||
extern uint32_t __sram_incbin_start, __sram_incbin_end;
|
||||
extern uint32_t __sram_incbin_real_end;
|
||||
|
||||
/******************************************************************************
|
||||
* The register have write-mask bits, it is mean, if you want to set the bits,
|
||||
* you needs set the write-mask bits at the same time,
|
||||
* The write-mask bits is in high 16-bits.
|
||||
* The fllowing macro definition helps access write-mask bits reg efficient!
|
||||
******************************************************************************/
|
||||
#define REG_MSK_SHIFT 16
|
||||
|
||||
#ifndef WMSK_BIT
|
||||
#define WMSK_BIT(nr) BIT((nr) + REG_MSK_SHIFT)
|
||||
#endif
|
||||
|
||||
/* set one bit with write mask */
|
||||
#ifndef BIT_WITH_WMSK
|
||||
#define BIT_WITH_WMSK(nr) (BIT(nr) | WMSK_BIT(nr))
|
||||
#endif
|
||||
|
||||
#ifndef BITS_SHIFT
|
||||
#define BITS_SHIFT(bits, shift) (bits << (shift))
|
||||
#endif
|
||||
|
||||
#ifndef BITS_WITH_WMASK
|
||||
#define BITS_WITH_WMASK(bits, msk, shift)\
|
||||
(BITS_SHIFT(bits, shift) | BITS_SHIFT(msk, (shift + REG_MSK_SHIFT)))
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Function and variable prototypes
|
||||
*****************************************************************************/
|
||||
#ifdef __aarch64__
|
||||
void plat_configure_mmu_el3(unsigned long total_base,
|
||||
unsigned long total_size,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
unsigned long);
|
||||
|
||||
void rockchip_plat_mmu_el3(void);
|
||||
#else
|
||||
void plat_configure_mmu_svc_mon(unsigned long total_base,
|
||||
unsigned long total_size,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
unsigned long);
|
||||
|
||||
void rockchip_plat_mmu_svc_mon(void);
|
||||
#endif
|
||||
|
||||
void plat_cci_init(void);
|
||||
void plat_cci_enable(void);
|
||||
void plat_cci_disable(void);
|
||||
|
||||
void plat_delay_timer_init(void);
|
||||
|
||||
void params_early_setup(u_register_t plat_params_from_bl2);
|
||||
|
||||
void plat_rockchip_gic_driver_init(void);
|
||||
void plat_rockchip_gic_init(void);
|
||||
void plat_rockchip_gic_cpuif_enable(void);
|
||||
void plat_rockchip_gic_cpuif_disable(void);
|
||||
void plat_rockchip_gic_pcpu_init(void);
|
||||
|
||||
void plat_rockchip_pmu_init(void);
|
||||
void plat_rockchip_soc_init(void);
|
||||
uintptr_t plat_get_sec_entrypoint(void);
|
||||
|
||||
void platform_cpu_warmboot(void);
|
||||
|
||||
struct bl_aux_gpio_info *plat_get_rockchip_gpio_reset(void);
|
||||
struct bl_aux_gpio_info *plat_get_rockchip_gpio_poweroff(void);
|
||||
struct bl_aux_gpio_info *plat_get_rockchip_suspend_gpio(uint32_t *count);
|
||||
struct bl_aux_rk_apio_info *plat_get_rockchip_suspend_apio(void);
|
||||
void plat_rockchip_gpio_init(void);
|
||||
void plat_rockchip_save_gpio(void);
|
||||
void plat_rockchip_restore_gpio(void);
|
||||
|
||||
int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint);
|
||||
int rockchip_soc_hlvl_pwr_dm_off(uint32_t lvl,
|
||||
plat_local_state_t lvl_state);
|
||||
int rockchip_soc_cores_pwr_dm_off(void);
|
||||
int rockchip_soc_sys_pwr_dm_suspend(void);
|
||||
int rockchip_soc_cores_pwr_dm_suspend(void);
|
||||
int rockchip_soc_hlvl_pwr_dm_suspend(uint32_t lvl,
|
||||
plat_local_state_t lvl_state);
|
||||
int rockchip_soc_hlvl_pwr_dm_on_finish(uint32_t lvl,
|
||||
plat_local_state_t lvl_state);
|
||||
int rockchip_soc_cores_pwr_dm_on_finish(void);
|
||||
int rockchip_soc_sys_pwr_dm_resume(void);
|
||||
|
||||
int rockchip_soc_hlvl_pwr_dm_resume(uint32_t lvl,
|
||||
plat_local_state_t lvl_state);
|
||||
int rockchip_soc_cores_pwr_dm_resume(void);
|
||||
void __dead2 rockchip_soc_soft_reset(void);
|
||||
void __dead2 rockchip_soc_system_off(void);
|
||||
void __dead2 rockchip_soc_cores_pd_pwr_dn_wfi(
|
||||
const psci_power_state_t *target_state);
|
||||
void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void);
|
||||
|
||||
extern const unsigned char rockchip_power_domain_tree_desc[];
|
||||
|
||||
extern void *pmu_cpuson_entrypoint;
|
||||
extern u_register_t cpuson_entry_point[PLATFORM_CORE_COUNT];
|
||||
extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
|
||||
|
||||
extern const mmap_region_t plat_rk_mmap[];
|
||||
|
||||
uint32_t rockchip_get_uart_base(void);
|
||||
uint32_t rockchip_get_uart_baudrate(void);
|
||||
uint32_t rockchip_get_uart_clock(void);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
/******************************************************************************
|
||||
* cpu up status
|
||||
* The bits of macro value is not more than 12 bits for cmp instruction!
|
||||
******************************************************************************/
|
||||
#define PMU_CPU_HOTPLUG 0xf00
|
||||
#define PMU_CPU_AUTO_PWRDN 0xf0
|
||||
#define PMU_CLST_RET 0xa5
|
||||
|
||||
#endif /* PLAT_PRIVATE_H */
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ROCKCHIP_SIP_SVC_H
|
||||
#define ROCKCHIP_SIP_SVC_H
|
||||
|
||||
/* SMC function IDs for SiP Service queries */
|
||||
#define SIP_SVC_CALL_COUNT 0x8200ff00
|
||||
#define SIP_SVC_UID 0x8200ff01
|
||||
#define SIP_SVC_VERSION 0x8200ff03
|
||||
|
||||
/* rockchip SiP Service Calls version numbers */
|
||||
#define RK_SIP_SVC_VERSION_MAJOR 0x0
|
||||
#define RK_SIP_SVC_VERSION_MINOR 0x1
|
||||
|
||||
/* Number of ROCKCHIP SiP Calls implemented */
|
||||
#define RK_COMMON_SIP_NUM_CALLS 0x3
|
||||
|
||||
enum {
|
||||
RK_SIP_E_SUCCESS = 0,
|
||||
RK_SIP_E_INVALID_PARAM = -1
|
||||
};
|
||||
|
||||
#endif /* ROCKCHIP_SIP_SVC_H */
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <lib/bl_aux_params/bl_aux_params.h>
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/console.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <libfdt.h>
|
||||
#include <lib/coreboot.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include <plat_params.h>
|
||||
#include <plat_private.h>
|
||||
|
||||
static struct bl_aux_gpio_info rst_gpio = { .index = UINT_MAX } ;
|
||||
static struct bl_aux_gpio_info poweroff_gpio = { .index = UINT_MAX };
|
||||
static struct bl_aux_gpio_info suspend_gpio[10];
|
||||
uint32_t suspend_gpio_cnt;
|
||||
static struct bl_aux_rk_apio_info suspend_apio;
|
||||
|
||||
#if COREBOOT
|
||||
static int dt_process_fdt(u_register_t param_from_bl2)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#else
|
||||
static uint32_t rk_uart_base = PLAT_RK_UART_BASE;
|
||||
static uint32_t rk_uart_baudrate = PLAT_RK_UART_BAUDRATE;
|
||||
static uint32_t rk_uart_clock = PLAT_RK_UART_CLOCK;
|
||||
#define FDT_BUFFER_SIZE 0x20000
|
||||
static uint64_t fdt_buffer[FDT_BUFFER_SIZE / 8];
|
||||
|
||||
void *plat_get_fdt(void)
|
||||
{
|
||||
return &fdt_buffer[0];
|
||||
}
|
||||
|
||||
static void plat_rockchip_dt_process_fdt_uart(void *fdt)
|
||||
{
|
||||
const char *path_name = "/chosen";
|
||||
const char *prop_name = "stdout-path";
|
||||
int node_offset;
|
||||
int stdout_path_len;
|
||||
const char *stdout_path;
|
||||
const char *separator;
|
||||
const char *baud_start;
|
||||
char serial_char;
|
||||
int serial_no;
|
||||
uint32_t uart_base;
|
||||
uint32_t baud;
|
||||
|
||||
node_offset = fdt_path_offset(fdt, path_name);
|
||||
if (node_offset < 0)
|
||||
return;
|
||||
|
||||
stdout_path = fdt_getprop(fdt, node_offset, prop_name,
|
||||
&stdout_path_len);
|
||||
if (stdout_path == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* We expect something like:
|
||||
* "serial0:baudrate"
|
||||
*/
|
||||
if (strncmp("serial", stdout_path, 6) != 0)
|
||||
return;
|
||||
|
||||
serial_char = stdout_path[6];
|
||||
serial_no = serial_char - '0';
|
||||
|
||||
switch (serial_no) {
|
||||
case 0:
|
||||
uart_base = UART0_BASE;
|
||||
break;
|
||||
case 1:
|
||||
uart_base = UART1_BASE;
|
||||
break;
|
||||
case 2:
|
||||
uart_base = UART2_BASE;
|
||||
break;
|
||||
#ifdef UART3_BASE
|
||||
case 3:
|
||||
uart_base = UART3_BASE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef UART4_BASE
|
||||
case 4:
|
||||
uart_base = UART4_BASE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef UART5_BASE
|
||||
case 5:
|
||||
uart_base = UART5_BASE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
rk_uart_base = uart_base;
|
||||
|
||||
separator = strchr(stdout_path, ':');
|
||||
if (!separator)
|
||||
return;
|
||||
|
||||
baud = 0;
|
||||
baud_start = separator + 1;
|
||||
while (*baud_start != '\0') {
|
||||
/*
|
||||
* uart binding is <baud>{<parity>{<bits>{...}}}
|
||||
* So the baudrate either is the whole string, or
|
||||
* we end in the parity characters.
|
||||
*/
|
||||
if (*baud_start == 'n' || *baud_start == 'o' ||
|
||||
*baud_start == 'e')
|
||||
break;
|
||||
|
||||
baud = baud * 10 + (*baud_start - '0');
|
||||
baud_start++;
|
||||
}
|
||||
|
||||
rk_uart_baudrate = baud;
|
||||
}
|
||||
|
||||
static int dt_process_fdt(u_register_t param_from_bl2)
|
||||
{
|
||||
void *fdt = plat_get_fdt();
|
||||
int ret;
|
||||
|
||||
ret = fdt_open_into((void *)param_from_bl2, fdt, FDT_BUFFER_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
plat_rockchip_dt_process_fdt_uart(fdt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t rockchip_get_uart_base(void)
|
||||
{
|
||||
#if COREBOOT
|
||||
return coreboot_serial.baseaddr;
|
||||
#else
|
||||
return rk_uart_base;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t rockchip_get_uart_baudrate(void)
|
||||
{
|
||||
#if COREBOOT
|
||||
return coreboot_serial.baud;
|
||||
#else
|
||||
return rk_uart_baudrate;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t rockchip_get_uart_clock(void)
|
||||
{
|
||||
#if COREBOOT
|
||||
return coreboot_serial.input_hertz;
|
||||
#else
|
||||
return rk_uart_clock;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct bl_aux_gpio_info *plat_get_rockchip_gpio_reset(void)
|
||||
{
|
||||
if (rst_gpio.index == UINT_MAX)
|
||||
return NULL;
|
||||
|
||||
return &rst_gpio;
|
||||
}
|
||||
|
||||
struct bl_aux_gpio_info *plat_get_rockchip_gpio_poweroff(void)
|
||||
{
|
||||
if (poweroff_gpio.index == UINT_MAX)
|
||||
return NULL;
|
||||
|
||||
return &poweroff_gpio;
|
||||
}
|
||||
|
||||
struct bl_aux_gpio_info *plat_get_rockchip_suspend_gpio(uint32_t *count)
|
||||
{
|
||||
*count = suspend_gpio_cnt;
|
||||
|
||||
return &suspend_gpio[0];
|
||||
}
|
||||
|
||||
struct bl_aux_rk_apio_info *plat_get_rockchip_suspend_apio(void)
|
||||
{
|
||||
return &suspend_apio;
|
||||
}
|
||||
|
||||
static bool rk_aux_param_handler(struct bl_aux_param_header *param)
|
||||
{
|
||||
/* Store platform parameters for later processing if needed. */
|
||||
switch (param->type) {
|
||||
case BL_AUX_PARAM_RK_RESET_GPIO:
|
||||
rst_gpio = ((struct bl_aux_param_gpio *)param)->gpio;
|
||||
return true;
|
||||
case BL_AUX_PARAM_RK_POWEROFF_GPIO:
|
||||
poweroff_gpio = ((struct bl_aux_param_gpio *)param)->gpio;
|
||||
return true;
|
||||
case BL_AUX_PARAM_RK_SUSPEND_GPIO:
|
||||
if (suspend_gpio_cnt >= ARRAY_SIZE(suspend_gpio)) {
|
||||
ERROR("Exceeded the supported suspend GPIO number.\n");
|
||||
return true;
|
||||
}
|
||||
suspend_gpio[suspend_gpio_cnt++] =
|
||||
((struct bl_aux_param_gpio *)param)->gpio;
|
||||
return true;
|
||||
case BL_AUX_PARAM_RK_SUSPEND_APIO:
|
||||
suspend_apio = ((struct bl_aux_param_rk_apio *)param)->apio;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void params_early_setup(u_register_t plat_param_from_bl2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Test if this is a FDT passed as a platform-specific parameter
|
||||
* block.
|
||||
*/
|
||||
ret = dt_process_fdt(plat_param_from_bl2);
|
||||
if (!ret) {
|
||||
return;
|
||||
} else if (ret != -FDT_ERR_BADMAGIC) {
|
||||
/*
|
||||
* If we found an FDT but couldn't parse it (e.g. corrupt, not
|
||||
* enough space), return and don't attempt to parse the param
|
||||
* as something else, since we know that will also fail. All
|
||||
* we're doing is setting up UART, this doesn't need to be
|
||||
* fatal.
|
||||
*/
|
||||
WARN("%s: found FDT but could not parse: error %d\n",
|
||||
__func__, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
bl_aux_params_parse(plat_param_from_bl2, rk_aux_param_handler);
|
||||
}
|
||||
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/console.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/psci/psci.h>
|
||||
|
||||
#include <plat_private.h>
|
||||
|
||||
/* Macros to read the rk power domain state */
|
||||
#define RK_CORE_PWR_STATE(state) \
|
||||
((state)->pwr_domain_state[MPIDR_AFFLVL0])
|
||||
#define RK_CLUSTER_PWR_STATE(state) \
|
||||
((state)->pwr_domain_state[MPIDR_AFFLVL1])
|
||||
#define RK_SYSTEM_PWR_STATE(state) \
|
||||
((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
|
||||
|
||||
static uintptr_t rockchip_sec_entrypoint;
|
||||
|
||||
#pragma weak rockchip_soc_cores_pwr_dm_on
|
||||
#pragma weak rockchip_soc_hlvl_pwr_dm_off
|
||||
#pragma weak rockchip_soc_cores_pwr_dm_off
|
||||
#pragma weak rockchip_soc_sys_pwr_dm_suspend
|
||||
#pragma weak rockchip_soc_cores_pwr_dm_suspend
|
||||
#pragma weak rockchip_soc_hlvl_pwr_dm_suspend
|
||||
#pragma weak rockchip_soc_hlvl_pwr_dm_on_finish
|
||||
#pragma weak rockchip_soc_cores_pwr_dm_on_finish
|
||||
#pragma weak rockchip_soc_sys_pwr_dm_resume
|
||||
#pragma weak rockchip_soc_hlvl_pwr_dm_resume
|
||||
#pragma weak rockchip_soc_cores_pwr_dm_resume
|
||||
#pragma weak rockchip_soc_soft_reset
|
||||
#pragma weak rockchip_soc_system_off
|
||||
#pragma weak rockchip_soc_sys_pd_pwr_dn_wfi
|
||||
#pragma weak rockchip_soc_cores_pd_pwr_dn_wfi
|
||||
|
||||
int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int rockchip_soc_hlvl_pwr_dm_off(uint32_t lvl,
|
||||
plat_local_state_t lvl_state)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int rockchip_soc_cores_pwr_dm_off(void)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int rockchip_soc_sys_pwr_dm_suspend(void)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int rockchip_soc_cores_pwr_dm_suspend(void)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int rockchip_soc_hlvl_pwr_dm_suspend(uint32_t lvl,
|
||||
plat_local_state_t lvl_state)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int rockchip_soc_hlvl_pwr_dm_on_finish(uint32_t lvl,
|
||||
plat_local_state_t lvl_state)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int rockchip_soc_cores_pwr_dm_on_finish(void)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int rockchip_soc_sys_pwr_dm_resume(void)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int rockchip_soc_hlvl_pwr_dm_resume(uint32_t lvl,
|
||||
plat_local_state_t lvl_state)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int rockchip_soc_cores_pwr_dm_resume(void)
|
||||
{
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void __dead2 rockchip_soc_soft_reset(void)
|
||||
{
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
void __dead2 rockchip_soc_system_off(void)
|
||||
{
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
void __dead2 rockchip_soc_cores_pd_pwr_dn_wfi(
|
||||
const psci_power_state_t *target_state)
|
||||
{
|
||||
psci_power_down_wfi();
|
||||
}
|
||||
|
||||
void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
|
||||
{
|
||||
psci_power_down_wfi();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Rockchip standard platform handler called to check the validity of the power
|
||||
* state parameter.
|
||||
******************************************************************************/
|
||||
int rockchip_validate_power_state(unsigned int power_state,
|
||||
psci_power_state_t *req_state)
|
||||
{
|
||||
int pstate = psci_get_pstate_type(power_state);
|
||||
int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
|
||||
int i;
|
||||
|
||||
assert(req_state);
|
||||
|
||||
if (pwr_lvl > PLAT_MAX_PWR_LVL)
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
/* Sanity check the requested state */
|
||||
if (pstate == PSTATE_TYPE_STANDBY) {
|
||||
/*
|
||||
* It's probably to enter standby only on power level 0
|
||||
* ignore any other power level.
|
||||
*/
|
||||
if (pwr_lvl != MPIDR_AFFLVL0)
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
req_state->pwr_domain_state[MPIDR_AFFLVL0] =
|
||||
PLAT_MAX_RET_STATE;
|
||||
} else {
|
||||
for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++)
|
||||
req_state->pwr_domain_state[i] =
|
||||
PLAT_MAX_OFF_STATE;
|
||||
|
||||
for (i = (pwr_lvl + 1); i <= PLAT_MAX_PWR_LVL; i++)
|
||||
req_state->pwr_domain_state[i] =
|
||||
PLAT_MAX_RET_STATE;
|
||||
}
|
||||
|
||||
/* We expect the 'state id' to be zero */
|
||||
if (psci_get_pstate_id(power_state))
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
void rockchip_get_sys_suspend_power_state(psci_power_state_t *req_state)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
|
||||
req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* RockChip handler called when a CPU is about to enter standby.
|
||||
******************************************************************************/
|
||||
void rockchip_cpu_standby(plat_local_state_t cpu_state)
|
||||
{
|
||||
u_register_t scr;
|
||||
|
||||
assert(cpu_state == PLAT_MAX_RET_STATE);
|
||||
|
||||
scr = read_scr_el3();
|
||||
/* Enable PhysicalIRQ bit for NS world to wake the CPU */
|
||||
write_scr_el3(scr | SCR_IRQ_BIT);
|
||||
isb();
|
||||
dsb();
|
||||
wfi();
|
||||
|
||||
/*
|
||||
* Restore SCR to the original value, synchronisation of scr_el3 is
|
||||
* done by eret while el3_exit to save some execution cycles.
|
||||
*/
|
||||
write_scr_el3(scr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* RockChip handler called when a power domain is about to be turned on. The
|
||||
* mpidr determines the CPU to be turned on.
|
||||
******************************************************************************/
|
||||
int rockchip_pwr_domain_on(u_register_t mpidr)
|
||||
{
|
||||
return rockchip_soc_cores_pwr_dm_on(mpidr, rockchip_sec_entrypoint);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* RockChip handler called when a power domain is about to be turned off. The
|
||||
* target_state encodes the power state that each level should transition to.
|
||||
******************************************************************************/
|
||||
void rockchip_pwr_domain_off(const psci_power_state_t *target_state)
|
||||
{
|
||||
uint32_t lvl;
|
||||
plat_local_state_t lvl_state;
|
||||
int ret;
|
||||
|
||||
assert(RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE);
|
||||
|
||||
plat_rockchip_gic_cpuif_disable();
|
||||
|
||||
if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
|
||||
plat_cci_disable();
|
||||
|
||||
rockchip_soc_cores_pwr_dm_off();
|
||||
|
||||
for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
|
||||
lvl_state = target_state->pwr_domain_state[lvl];
|
||||
ret = rockchip_soc_hlvl_pwr_dm_off(lvl, lvl_state);
|
||||
if (ret == PSCI_E_NOT_SUPPORTED)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* RockChip handler called when a power domain is about to be suspended. The
|
||||
* target_state encodes the power state that each level should transition to.
|
||||
******************************************************************************/
|
||||
void rockchip_pwr_domain_suspend(const psci_power_state_t *target_state)
|
||||
{
|
||||
uint32_t lvl;
|
||||
plat_local_state_t lvl_state;
|
||||
int ret;
|
||||
|
||||
if (RK_CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
|
||||
return;
|
||||
|
||||
/* Prevent interrupts from spuriously waking up this cpu */
|
||||
plat_rockchip_gic_cpuif_disable();
|
||||
|
||||
if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
|
||||
rockchip_soc_sys_pwr_dm_suspend();
|
||||
else
|
||||
rockchip_soc_cores_pwr_dm_suspend();
|
||||
|
||||
/* Perform the common cluster specific operations */
|
||||
if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
|
||||
plat_cci_disable();
|
||||
|
||||
if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
|
||||
return;
|
||||
|
||||
for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
|
||||
lvl_state = target_state->pwr_domain_state[lvl];
|
||||
ret = rockchip_soc_hlvl_pwr_dm_suspend(lvl, lvl_state);
|
||||
if (ret == PSCI_E_NOT_SUPPORTED)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* RockChip handler called when a power domain has just been powered on after
|
||||
* being turned off earlier. The target_state encodes the low power state that
|
||||
* each level has woken up from.
|
||||
******************************************************************************/
|
||||
void rockchip_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
uint32_t lvl;
|
||||
plat_local_state_t lvl_state;
|
||||
int ret;
|
||||
|
||||
assert(RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE);
|
||||
|
||||
for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
|
||||
lvl_state = target_state->pwr_domain_state[lvl];
|
||||
ret = rockchip_soc_hlvl_pwr_dm_on_finish(lvl, lvl_state);
|
||||
if (ret == PSCI_E_NOT_SUPPORTED)
|
||||
break;
|
||||
}
|
||||
|
||||
rockchip_soc_cores_pwr_dm_on_finish();
|
||||
|
||||
/* Perform the common cluster specific operations */
|
||||
if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
|
||||
/* Enable coherency if this cluster was off */
|
||||
plat_cci_enable();
|
||||
}
|
||||
|
||||
/* Enable the gic cpu interface */
|
||||
plat_rockchip_gic_pcpu_init();
|
||||
|
||||
/* Program the gic per-cpu distributor or re-distributor interface */
|
||||
plat_rockchip_gic_cpuif_enable();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* RockChip handler called when a power domain has just been powered on after
|
||||
* having been suspended earlier. The target_state encodes the low power state
|
||||
* that each level has woken up from.
|
||||
* TODO: At the moment we reuse the on finisher and reinitialize the secure
|
||||
* context. Need to implement a separate suspend finisher.
|
||||
******************************************************************************/
|
||||
void rockchip_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
uint32_t lvl;
|
||||
plat_local_state_t lvl_state;
|
||||
int ret;
|
||||
|
||||
/* Nothing to be done on waking up from retention from CPU level */
|
||||
if (RK_CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
|
||||
return;
|
||||
|
||||
if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
|
||||
rockchip_soc_sys_pwr_dm_resume();
|
||||
goto comm_finish;
|
||||
}
|
||||
|
||||
for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
|
||||
lvl_state = target_state->pwr_domain_state[lvl];
|
||||
ret = rockchip_soc_hlvl_pwr_dm_resume(lvl, lvl_state);
|
||||
if (ret == PSCI_E_NOT_SUPPORTED)
|
||||
break;
|
||||
}
|
||||
|
||||
rockchip_soc_cores_pwr_dm_resume();
|
||||
|
||||
/*
|
||||
* Program the gic per-cpu distributor or re-distributor interface.
|
||||
* For sys power domain operation, resuming of the gic needs to operate
|
||||
* in rockchip_soc_sys_pwr_dm_resume(), according to the sys power mode
|
||||
* implements.
|
||||
*/
|
||||
plat_rockchip_gic_cpuif_enable();
|
||||
|
||||
comm_finish:
|
||||
/* Perform the common cluster specific operations */
|
||||
if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
|
||||
/* Enable coherency if this cluster was off */
|
||||
plat_cci_enable();
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* RockChip handlers to reboot the system
|
||||
******************************************************************************/
|
||||
static void __dead2 rockchip_system_reset(void)
|
||||
{
|
||||
rockchip_soc_soft_reset();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* RockChip handlers to power off the system
|
||||
******************************************************************************/
|
||||
static void __dead2 rockchip_system_poweroff(void)
|
||||
{
|
||||
rockchip_soc_system_off();
|
||||
}
|
||||
|
||||
static void __dead2 rockchip_pd_pwr_down_wfi(
|
||||
const psci_power_state_t *target_state)
|
||||
{
|
||||
if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
|
||||
rockchip_soc_sys_pd_pwr_dn_wfi();
|
||||
else
|
||||
rockchip_soc_cores_pd_pwr_dn_wfi(target_state);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Export the platform handlers via plat_rockchip_psci_pm_ops. The rockchip
|
||||
* standard
|
||||
* platform layer will take care of registering the handlers with PSCI.
|
||||
******************************************************************************/
|
||||
const plat_psci_ops_t plat_rockchip_psci_pm_ops = {
|
||||
.cpu_standby = rockchip_cpu_standby,
|
||||
.pwr_domain_on = rockchip_pwr_domain_on,
|
||||
.pwr_domain_off = rockchip_pwr_domain_off,
|
||||
.pwr_domain_suspend = rockchip_pwr_domain_suspend,
|
||||
.pwr_domain_on_finish = rockchip_pwr_domain_on_finish,
|
||||
.pwr_domain_suspend_finish = rockchip_pwr_domain_suspend_finish,
|
||||
.pwr_domain_pwr_down_wfi = rockchip_pd_pwr_down_wfi,
|
||||
.system_reset = rockchip_system_reset,
|
||||
.system_off = rockchip_system_poweroff,
|
||||
.validate_power_state = rockchip_validate_power_state,
|
||||
.get_sys_suspend_power_state = rockchip_get_sys_suspend_power_state
|
||||
};
|
||||
|
||||
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
|
||||
const plat_psci_ops_t **psci_ops)
|
||||
{
|
||||
*psci_ops = &plat_rockchip_psci_pm_ops;
|
||||
rockchip_sec_entrypoint = sec_entrypoint;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t plat_get_sec_entrypoint(void)
|
||||
{
|
||||
assert(rockchip_sec_entrypoint);
|
||||
return rockchip_sec_entrypoint;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <arch.h>
|
||||
#include <lib/psci/psci.h>
|
||||
|
||||
#include <plat_private.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* This function returns the RockChip default topology tree information.
|
||||
******************************************************************************/
|
||||
const unsigned char *plat_get_power_domain_tree_desc(void)
|
||||
{
|
||||
return rockchip_power_domain_tree_desc;
|
||||
}
|
||||
|
||||
int plat_core_pos_by_mpidr(u_register_t mpidr)
|
||||
{
|
||||
unsigned int cluster_id, cpu_id;
|
||||
|
||||
cpu_id = mpidr & MPIDR_AFFLVL_MASK;
|
||||
#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
|
||||
cluster_id = mpidr & PLAT_RK_MPIDR_CLUSTER_MASK;
|
||||
#else
|
||||
cluster_id = mpidr & MPIDR_CLUSTER_MASK;
|
||||
#endif
|
||||
|
||||
cpu_id += (cluster_id >> PLAT_RK_CLST_TO_CPUID_SHIFT);
|
||||
|
||||
if (cpu_id >= PLATFORM_CORE_COUNT)
|
||||
return -1;
|
||||
|
||||
return cpu_id;
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <platform_def.h>
|
||||
#include <cpus_on_fixed_addr.h>
|
||||
|
||||
.globl sys_sleep_flag_sram
|
||||
.globl pmu_cpuson_entrypoint
|
||||
|
||||
.macro pmusram_entry_func _name
|
||||
.section .pmusram.entry, "ax"
|
||||
.type \_name, %function
|
||||
.cfi_startproc
|
||||
\_name:
|
||||
.endm
|
||||
|
||||
pmusram_entry_func pmu_cpuson_entrypoint
|
||||
adr x5, sys_sleep_flag_sram
|
||||
ldr w2, [x5, #PSRAM_DT_PM_FLAG]
|
||||
|
||||
tbz w2, #PM_WARM_BOOT_SHT, sys_resume_sp
|
||||
ldr x1, =platform_cpu_warmboot
|
||||
br x1
|
||||
sys_resume_sp:
|
||||
adr x5, sys_sleep_flag_sram
|
||||
ldr x1, [x5, #PSRAM_DT_SP]
|
||||
mov sp, x1
|
||||
ddr_resume:
|
||||
ldr x1, [x5, #PSRAM_DT_DDR_FUNC]
|
||||
cmp x1, #0
|
||||
b.eq sys_resume
|
||||
blr x1
|
||||
sys_resume:
|
||||
ldr x1, =bl31_warm_entrypoint
|
||||
br x1
|
||||
endfunc pmu_cpuson_entrypoint
|
||||
|
||||
.section .pmusram.data, "a"
|
||||
.align 3
|
||||
sys_sleep_flag_sram:
|
||||
.rept PSRAM_DT_SIZE_WORDS
|
||||
.word 0
|
||||
.endr
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __CPU_ON_FIXED_ADDR_H__
|
||||
#define __CPU_ON_FIXED_ADDR_H__
|
||||
|
||||
/*****************************************************************************
|
||||
* define data offset in struct psram_data
|
||||
*****************************************************************************/
|
||||
#define PSRAM_DT_SP 0x0
|
||||
#define PSRAM_DT_DDR_FUNC 0x8
|
||||
#define PSRAM_DT_DDR_DATA 0x10
|
||||
#define PSRAM_DT_DDRFLAG 0x18
|
||||
#define PSRAM_DT_MPIDR 0x1c
|
||||
#define PSRAM_DT_PM_FLAG 0x20
|
||||
#define PSRAM_DT_END 0x24
|
||||
|
||||
/* reserve 4 byte */
|
||||
#define PSRAM_DT_END_RES4 (PSRAM_DT_END + 4)
|
||||
|
||||
#define PSRAM_DT_SIZE_WORDS (PSRAM_DT_END_RES4 / 4)
|
||||
|
||||
#define PM_WARM_BOOT_SHT 0
|
||||
#define PM_WARM_BOOT_BIT (1 << PM_WARM_BOOT_SHT)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
struct psram_data_t {
|
||||
uint64_t sp;
|
||||
uint64_t ddr_func;
|
||||
uint64_t ddr_data;
|
||||
uint32_t ddr_flag;
|
||||
uint32_t boot_mpidr;
|
||||
uint32_t pm_flag;
|
||||
};
|
||||
|
||||
CASSERT(__builtin_offsetof(struct psram_data_t, sp) == PSRAM_DT_SP,
|
||||
assert_psram_dt_sp_offset_mistmatch);
|
||||
CASSERT(__builtin_offsetof(struct psram_data_t, ddr_func) == PSRAM_DT_DDR_FUNC,
|
||||
assert_psram_dt_ddr_func_offset_mistmatch);
|
||||
CASSERT(__builtin_offsetof(struct psram_data_t, ddr_data) == PSRAM_DT_DDR_DATA,
|
||||
assert_psram_dt_ddr_data_offset_mistmatch);
|
||||
CASSERT(__builtin_offsetof(struct psram_data_t, ddr_flag) == PSRAM_DT_DDRFLAG,
|
||||
assert_psram_dt_ddr_flag_offset_mistmatch);
|
||||
CASSERT(__builtin_offsetof(struct psram_data_t, boot_mpidr) == PSRAM_DT_MPIDR,
|
||||
assert_psram_dt_mpidr_offset_mistmatch);
|
||||
|
||||
extern struct psram_data_t sys_sleep_flag_sram;
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2016-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/interrupt_props.h>
|
||||
#include <drivers/arm/gicv2.h>
|
||||
#include <lib/utils.h>
|
||||
|
||||
/******************************************************************************
|
||||
* The following functions are defined as weak to allow a platform to override
|
||||
* the way the GICv2 driver is initialised and used.
|
||||
*****************************************************************************/
|
||||
#pragma weak plat_rockchip_gic_driver_init
|
||||
#pragma weak plat_rockchip_gic_init
|
||||
#pragma weak plat_rockchip_gic_cpuif_enable
|
||||
#pragma weak plat_rockchip_gic_cpuif_disable
|
||||
#pragma weak plat_rockchip_gic_pcpu_init
|
||||
|
||||
/******************************************************************************
|
||||
* List of interrupts.
|
||||
*****************************************************************************/
|
||||
static const interrupt_prop_t g0_interrupt_props[] = {
|
||||
PLAT_RK_GICV2_G0_IRQS
|
||||
};
|
||||
|
||||
/*
|
||||
* Ideally `rockchip_gic_data` structure definition should be a `const` but it
|
||||
* is kept as modifiable for overwriting with different GICD and GICC base when
|
||||
* running on FVP with VE memory map.
|
||||
*/
|
||||
gicv2_driver_data_t rockchip_gic_data = {
|
||||
.gicd_base = PLAT_RK_GICD_BASE,
|
||||
.gicc_base = PLAT_RK_GICC_BASE,
|
||||
.interrupt_props = g0_interrupt_props,
|
||||
.interrupt_props_num = ARRAY_SIZE(g0_interrupt_props),
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* RockChip common helper to initialize the GICv2 only driver.
|
||||
*****************************************************************************/
|
||||
void plat_rockchip_gic_driver_init(void)
|
||||
{
|
||||
gicv2_driver_init(&rockchip_gic_data);
|
||||
}
|
||||
|
||||
void plat_rockchip_gic_init(void)
|
||||
{
|
||||
gicv2_distif_init();
|
||||
gicv2_pcpu_distif_init();
|
||||
gicv2_cpuif_enable();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RockChip common helper to enable the GICv2 CPU interface
|
||||
*****************************************************************************/
|
||||
void plat_rockchip_gic_cpuif_enable(void)
|
||||
{
|
||||
gicv2_cpuif_enable();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RockChip common helper to disable the GICv2 CPU interface
|
||||
*****************************************************************************/
|
||||
void plat_rockchip_gic_cpuif_disable(void)
|
||||
{
|
||||
gicv2_cpuif_disable();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RockChip common helper to initialize the per cpu distributor interface
|
||||
* in GICv2
|
||||
*****************************************************************************/
|
||||
void plat_rockchip_gic_pcpu_init(void)
|
||||
{
|
||||
gicv2_pcpu_distif_init();
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <common/bl_common.h>
|
||||
#include <common/interrupt_props.h>
|
||||
#include <drivers/arm/gicv3.h>
|
||||
#include <lib/utils.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
/******************************************************************************
|
||||
* The following functions are defined as weak to allow a platform to override
|
||||
* the way the GICv3 driver is initialised and used.
|
||||
*****************************************************************************/
|
||||
#pragma weak plat_rockchip_gic_driver_init
|
||||
#pragma weak plat_rockchip_gic_init
|
||||
#pragma weak plat_rockchip_gic_cpuif_enable
|
||||
#pragma weak plat_rockchip_gic_cpuif_disable
|
||||
#pragma weak plat_rockchip_gic_pcpu_init
|
||||
|
||||
/* The GICv3 driver only needs to be initialized in EL3 */
|
||||
uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
|
||||
|
||||
static const interrupt_prop_t g01s_interrupt_props[] = {
|
||||
PLAT_RK_GICV3_G0_IRQS,
|
||||
PLAT_RK_GICV3_G1S_IRQS
|
||||
};
|
||||
|
||||
static unsigned int plat_rockchip_mpidr_to_core_pos(unsigned long mpidr)
|
||||
{
|
||||
return (unsigned int)plat_core_pos_by_mpidr(mpidr);
|
||||
}
|
||||
|
||||
const gicv3_driver_data_t rockchip_gic_data = {
|
||||
.gicd_base = PLAT_RK_GICD_BASE,
|
||||
.gicr_base = PLAT_RK_GICR_BASE,
|
||||
.interrupt_props = g01s_interrupt_props,
|
||||
.interrupt_props_num = ARRAY_SIZE(g01s_interrupt_props),
|
||||
.rdistif_num = PLATFORM_CORE_COUNT,
|
||||
.rdistif_base_addrs = rdistif_base_addrs,
|
||||
.mpidr_to_core_pos = plat_rockchip_mpidr_to_core_pos,
|
||||
};
|
||||
|
||||
void plat_rockchip_gic_driver_init(void)
|
||||
{
|
||||
/*
|
||||
* The GICv3 driver is initialized in EL3 and does not need
|
||||
* to be initialized again in SEL1. 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.
|
||||
*/
|
||||
#ifdef IMAGE_BL31
|
||||
gicv3_driver_init(&rockchip_gic_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RockChip common helper to initialize the GIC. Only invoked
|
||||
* by BL31
|
||||
*****************************************************************************/
|
||||
void plat_rockchip_gic_init(void)
|
||||
{
|
||||
gicv3_distif_init();
|
||||
gicv3_rdistif_init(plat_my_core_pos());
|
||||
gicv3_cpuif_enable(plat_my_core_pos());
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RockChip common helper to enable the GIC CPU interface
|
||||
*****************************************************************************/
|
||||
void plat_rockchip_gic_cpuif_enable(void)
|
||||
{
|
||||
gicv3_cpuif_enable(plat_my_core_pos());
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RockChip common helper to disable the GIC CPU interface
|
||||
*****************************************************************************/
|
||||
void plat_rockchip_gic_cpuif_disable(void)
|
||||
{
|
||||
gicv3_cpuif_disable(plat_my_core_pos());
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RockChip common helper to initialize the per-cpu redistributor interface
|
||||
* in GICv3
|
||||
*****************************************************************************/
|
||||
void plat_rockchip_gic_pcpu_init(void)
|
||||
{
|
||||
gicv3_rdistif_init(plat_my_core_pos());
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <common/runtime_svc.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <tools_share/uuid.h>
|
||||
|
||||
#include <plat_sip_calls.h>
|
||||
#include <rockchip_sip_svc.h>
|
||||
|
||||
/* Rockchip SiP Service UUID */
|
||||
DEFINE_SVC_UUID2(rk_sip_svc_uid,
|
||||
0xe2c76fe8, 0x3e31, 0xe611, 0xb7, 0x0d,
|
||||
0x8f, 0x88, 0xee, 0x74, 0x7b, 0x72);
|
||||
|
||||
#pragma weak rockchip_plat_sip_handler
|
||||
uintptr_t rockchip_plat_sip_handler(uint32_t smc_fid,
|
||||
u_register_t x1,
|
||||
u_register_t x2,
|
||||
u_register_t x3,
|
||||
u_register_t x4,
|
||||
void *cookie,
|
||||
void *handle,
|
||||
u_register_t flags)
|
||||
{
|
||||
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is responsible for handling all SiP calls from the NS world
|
||||
*/
|
||||
uintptr_t sip_smc_handler(uint32_t smc_fid,
|
||||
u_register_t x1,
|
||||
u_register_t x2,
|
||||
u_register_t x3,
|
||||
u_register_t x4,
|
||||
void *cookie,
|
||||
void *handle,
|
||||
u_register_t flags)
|
||||
{
|
||||
uint32_t ns;
|
||||
|
||||
/* Determine which security state this SMC originated from */
|
||||
ns = is_caller_non_secure(flags);
|
||||
if (!ns)
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
|
||||
switch (smc_fid) {
|
||||
case SIP_SVC_CALL_COUNT:
|
||||
/* Return the number of Rockchip SiP Service Calls. */
|
||||
SMC_RET1(handle,
|
||||
RK_COMMON_SIP_NUM_CALLS + RK_PLAT_SIP_NUM_CALLS);
|
||||
|
||||
case SIP_SVC_UID:
|
||||
/* Return UID to the caller */
|
||||
SMC_UUID_RET(handle, rk_sip_svc_uid);
|
||||
|
||||
case SIP_SVC_VERSION:
|
||||
/* Return the version of current implementation */
|
||||
SMC_RET2(handle, RK_SIP_SVC_VERSION_MAJOR,
|
||||
RK_SIP_SVC_VERSION_MINOR);
|
||||
|
||||
default:
|
||||
return rockchip_plat_sip_handler(smc_fid, x1, x2, x3, x4,
|
||||
cookie, handle, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define a runtime service descriptor for fast SMC calls */
|
||||
DECLARE_RT_SVC(
|
||||
rockchip_sip_svc,
|
||||
OEN_SIP_START,
|
||||
OEN_SIP_END,
|
||||
SMC_TYPE_FAST,
|
||||
NULL,
|
||||
sip_smc_handler
|
||||
);
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL)
|
||||
|
||||
u_register_t plat_get_stack_protector_canary(void)
|
||||
{
|
||||
/*
|
||||
* Ideally, a random number should be returned instead of the
|
||||
* combination of a timer's value and a compile-time constant.
|
||||
* As the virt platform does not have any random number generator,
|
||||
* this is better than nothing but not necessarily really secure.
|
||||
*/
|
||||
return RANDOM_CANARY_VALUE ^ read_cntpct_el0();
|
||||
}
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2016-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/console.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <drivers/ti/uart/uart_16550.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <plat_private.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
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.
|
||||
* A NULL pointer is returned if the image does not exist.
|
||||
******************************************************************************/
|
||||
entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
|
||||
{
|
||||
entry_point_info_t *next_image_info;
|
||||
|
||||
next_image_info = &bl33_ep_info;
|
||||
|
||||
if (next_image_info->pc == 0U) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return next_image_info;
|
||||
}
|
||||
|
||||
#pragma weak params_early_setup
|
||||
void params_early_setup(u_register_t plat_param_from_bl2)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int plat_is_my_cpu_primary(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Perform any BL32 specific platform actions.
|
||||
******************************************************************************/
|
||||
void sp_min_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 (rockchip_get_uart_base() != 0)
|
||||
console_16550_register(rockchip_get_uart_base(),
|
||||
rockchip_get_uart_clock(),
|
||||
rockchip_get_uart_baudrate(), &console);
|
||||
|
||||
VERBOSE("sp_min_setup\n");
|
||||
|
||||
bl31_params_parse_helper(arg0, NULL, &bl33_ep_info);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Perform any sp_min platform setup code
|
||||
******************************************************************************/
|
||||
void sp_min_platform_setup(void)
|
||||
{
|
||||
generic_delay_timer_init();
|
||||
plat_rockchip_soc_init();
|
||||
|
||||
/* Initialize the gic cpu and distributor interfaces */
|
||||
plat_rockchip_gic_driver_init();
|
||||
plat_rockchip_gic_init();
|
||||
plat_rockchip_pmu_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 sp_min_plat_arch_setup(void)
|
||||
{
|
||||
plat_cci_init();
|
||||
plat_cci_enable();
|
||||
|
||||
plat_configure_mmu_svc_mon(BL_CODE_BASE,
|
||||
BL_COHERENT_RAM_END - BL_CODE_BASE,
|
||||
BL_CODE_BASE,
|
||||
BL_CODE_END,
|
||||
BL_COHERENT_RAM_BASE,
|
||||
BL_COHERENT_RAM_END);
|
||||
}
|
||||
|
||||
void sp_min_plat_fiq_handler(uint32_t id)
|
||||
{
|
||||
VERBOSE("[sp_min] interrupt #%d\n", id);
|
||||
}
|
||||
Reference in New Issue
Block a user