Merge changes from topic "rk3288" into integration

* changes:
  rockchip: document platform
  rockchip: add support for rk3288
  rockchip: add common aarch32 support
  rockchip: rk3328: drop double declaration of entry_point storage
  rockchip: Allow socs with undefined wfe check bits
  rockchip: move pmusram assembler code to a aarch64 subdir
  sp_min: allow inclusion of a platform-specific linker script
  sp_min: make sp_min_warm_entrypoint public
  drivers: ti: uart: add a aarch32 variant
This commit is contained in:
Soby Mathew 2019-04-26 12:42:44 +00:00 committed by TrustedFirmware Code Review
commit 8742f8574b
33 changed files with 2331 additions and 12 deletions

View File

@ -16,6 +16,9 @@ MEMORY {
RAM (rwx): ORIGIN = BL32_BASE, LENGTH = BL32_LIMIT - BL32_BASE
}
#ifdef PLAT_SP_MIN_EXTRA_LD_SCRIPT
#include <plat_sp_min.ld.S>
#endif
SECTIONS
{

View File

@ -7,7 +7,6 @@
#ifndef SP_MIN_PRIVATE_H
#define SP_MIN_PRIVATE_H
void sp_min_warm_entrypoint(void);
void sp_min_main(void);
void sp_min_warm_boot(void);
void sp_min_fiq(void);

54
docs/plat/rockchip.rst Normal file
View File

@ -0,0 +1,54 @@
Trusted Firmware-A for Rockchip SoCs
====================================
Trusted Firmware-A supports a number of Rockchip ARM SoCs from both
AARCH32 and AARCH64 fields.
This includes right now:
- rk3288: Quad-Core Cortex-A17 (past A12)
- rk3328: Quad-Core Cortex-A53
- rk3368: Octa-Core Cortex-A53
- rk3399: Hexa-Core Cortex-A53/A72
Boot Sequence
=============
For AARCH32:
Bootrom --> BL1/BL2 --> BL32 --> BL33 --> Linux kernel
For AARCH64:
Bootrom --> BL1/BL2 --> BL31 --> BL33 --> Linux kernel
BL1/2 and BL33 can currently be supplied from either:
- Coreboot + Depthcharge
- U-Boot - either separately as TPL+SPL or only SPL
How to build
============
Rockchip SoCs expect TF-A's BL31 (AARCH64) or BL32 (AARCH32) to get
integrated with other boot software like U-Boot or Coreboot, so only
these images need to get build from the TF-A repository.
For AARCH64 architectures the build command looks like
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399 bl32
while AARCH32 needs a slightly different command
make ARCH=aarch32 CROSS_COMPILE=arm-linux-gnueabihf- PLAT=rk3288 AARCH32_SP=sp_min bl32
Both need replacing the PLAT argument with the platform from above you
want to build for and the CROSS_COMPILE argument with you cross-
compilation toolchain.
How to deploy
=============
Both upstream U-Boot and Coreboot projects contain instructions on where
to put the built images during their respective build process.
So after successfully building TF-A just follow their build instructions
to continue.

View File

@ -0,0 +1,267 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <assert_macros.S>
#include <console_macros.S>
#include <drivers/ti/uart/uart_16550.h>
/*
* "core" functions are low-level implementations that don't require
* writable memory and are thus safe to call in BL1 crash context.
*/
.globl console_16550_core_init
.globl console_16550_core_putc
.globl console_16550_core_getc
.globl console_16550_core_flush
.globl console_16550_putc
.globl console_16550_getc
.globl console_16550_flush
/* -----------------------------------------------
* int console_16550_core_init(uintptr_t base_addr,
* unsigned int uart_clk, unsigned int baud_rate)
* Function to initialize the console without a
* C Runtime to print debug information. This
* function will be accessed by console_init and
* crash reporting.
* In: r0 - console base address
* r1 - Uart clock in Hz
* r2 - Baud rate
* Out: return 1 on success, 0 on error
* Clobber list : r1, r2, r3
* -----------------------------------------------
*/
func console_16550_core_init
/* Check the input base address */
cmp r0, #0
beq init_fail
/* Check baud rate and uart clock for sanity */
cmp r1, #0
beq init_fail
cmp r2, #0
beq init_fail
/* Program the baudrate */
/* Divisor = Uart clock / (16 * baudrate) */
lsl r2, r2, #4
udiv r2, r1, r2
and r1, r2, #0xff /* w1 = DLL */
lsr r2, r2, #8
and r2, r2, #0xff /* w2 = DLLM */
ldr r3, [r0, #UARTLCR]
orr r3, r3, #UARTLCR_DLAB
str r3, [r0, #UARTLCR] /* enable DLL, DLLM programming */
str r1, [r0, #UARTDLL] /* program DLL */
str r2, [r0, #UARTDLLM] /* program DLLM */
mov r2, #~UARTLCR_DLAB
and r3, r3, r2
str r3, [r0, #UARTLCR] /* disable DLL, DLLM programming */
/* 8n1 */
mov r3, #3
str r3, [r0, #UARTLCR]
/* no interrupt */
mov r3, #0
str r3, [r0, #UARTIER]
#ifdef TI_16550_MDR_QUIRK
/* UART must be enabled on some platforms via the MDR register */
str r3, [r0, #UARTMDR1]
#endif /* TI_16550_MDR_QUIRK */
/* enable fifo, DMA */
mov r3, #(UARTFCR_FIFOEN | UARTFCR_DMAEN)
str r3, [r0, #UARTFCR]
/* DTR + RTS */
mov r3, #3
str r3, [r0, #UARTMCR]
mov r0, #1
bx lr
init_fail:
mov r0, #0
bx lr
endfunc console_16550_core_init
.globl console_16550_register
/* -------------------------------------------------------
* int console_stm32_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
* struct console_stm32 *console);
* Function to initialize and register a new STM32
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: r0 - UART register base address
* r1 - UART clock in Hz
* r2 - Baud rate
* r3 - pointer to empty console_stm32 struct
* Out: return 1 on success, 0 on error
* Clobber list : r0, r1, r2
* -------------------------------------------------------
*/
func console_16550_register
push {r4, lr}
mov r4, r3
cmp r4, #0
beq register_fail
str r0, [r4, #CONSOLE_T_16550_BASE]
bl console_16550_core_init
cmp r0, #0
beq register_fail
mov r0, r4
pop {r4, lr}
finish_console_register 16550 putc=1, getc=1, flush=1
register_fail:
pop {r4, pc}
endfunc console_16550_register
/* --------------------------------------------------------
* int console_16550_core_putc(int c, uintptr_t base_addr)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : r0 - character to be printed
* r1 - console base address
* Out : return -1 on error else return character.
* Clobber list : r2
* --------------------------------------------------------
*/
func console_16550_core_putc
#if ENABLE_ASSERTIONS
cmp r1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
/* Prepend '\r' to '\n' */
cmp r0, #0xA
bne 2f
/* Check if the transmit FIFO is full */
1: ldr r2, [r1, #UARTLSR]
and r2, r2, #(UARTLSR_TEMT | UARTLSR_THRE)
cmp r2, #(UARTLSR_TEMT | UARTLSR_THRE)
bne 1b
mov r2, #0xD /* '\r' */
str r2, [r1, #UARTTX]
/* Check if the transmit FIFO is full */
2: ldr r2, [r1, #UARTLSR]
and r2, r2, #(UARTLSR_TEMT | UARTLSR_THRE)
cmp r2, #(UARTLSR_TEMT | UARTLSR_THRE)
bne 2b
str r0, [r1, #UARTTX]
bx lr
endfunc console_16550_core_putc
/* --------------------------------------------------------
* int console_16550_putc(int c, console_16550_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : r0 - character to be printed
* r1 - pointer to console_t structure
* Out : return -1 on error else return character.
* Clobber list : r2
* --------------------------------------------------------
*/
func console_16550_putc
#if ENABLE_ASSERTIONS
cmp r1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
ldr r1, [r1, #CONSOLE_T_16550_BASE]
b console_16550_core_putc
endfunc console_16550_putc
/* ---------------------------------------------
* int console_16550_core_getc(uintptr_t base_addr)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 on if no character is available.
* In : r0 - console base address
* Clobber list : r0, r1
* ---------------------------------------------
*/
func console_16550_core_getc
#if ENABLE_ASSERTIONS
cmp r0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
/* Check if the receive FIFO is empty */
1: ldr r1, [r0, #UARTLSR]
tst r1, #UARTLSR_RDR_BIT
beq no_char
ldr r1, [r0, #UARTRX]
mov r0, r1
bx lr
no_char:
mov r0, #ERROR_NO_PENDING_CHAR
bx lr
endfunc console_16550_core_getc
/* ---------------------------------------------
* int console_16550_getc(console_16550_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 on if no character is available.
* In : r0 - pointer to console_t stucture
* Out : r0 - character if available, else -1
* Clobber list : r0, r1
* ---------------------------------------------
*/
func console_16550_getc
#if ENABLE_ASSERTIONS
cmp r0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
ldr r0, [r0, #CONSOLE_T_16550_BASE]
b console_16550_core_getc
endfunc console_16550_getc
/* ---------------------------------------------
* int console_16550_core_flush(uintptr_t base_addr)
* Function to force a write of all buffered
* data that hasn't been output.
* In : r0 - console base address
* Out : return -1 on error else return 0.
* Clobber list : r0, r1
* ---------------------------------------------
*/
func console_16550_core_flush
#if ENABLE_ASSERTIONS
cmp r0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
/* Loop until the transmit FIFO is empty */
1: ldr r1, [r0, #UARTLSR]
and r1, r1, #(UARTLSR_TEMT | UARTLSR_THRE)
cmp r1, #(UARTLSR_TEMT | UARTLSR_THRE)
bne 1b
mov r0, #0
bx lr
endfunc console_16550_core_flush
/* ---------------------------------------------
* int console_16550_flush(console_pl011_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : r0 - pointer to console_t structure
* Out : return -1 on error else return 0.
* Clobber list : r0, r1
* ---------------------------------------------
*/
func console_16550_flush
#if ENABLE_ASSERTIONS
cmp r0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
ldr r0, [r0, #CONSOLE_T_16550_BASE]
b console_16550_core_flush
endfunc console_16550_flush

View File

@ -18,6 +18,7 @@ void sp_min_platform_setup(void);
void sp_min_plat_runtime_setup(void);
void sp_min_plat_arch_setup(void);
entry_point_info_t *sp_min_plat_get_bl33_ep_info(void);
void sp_min_warm_entrypoint(void);
/* Platforms that enable SP_MIN_WITH_SECURE_FIQ shall implement this api */
void sp_min_plat_fiq_handler(uint32_t id);

View File

@ -208,6 +208,8 @@ RockChip platform port
:M: Tony Xie <tony.xie@rock-chips.com>
:G: `TonyXie06`_
:G: `rockchip-linux`_
:M: Heiko Stuebner <heiko@sntech.de>
:G: `mmind`_
:F: plat/rockchip/
STM32MP1 platform port
@ -277,6 +279,7 @@ Xilinx platform port
.. _niej: https://github.com/niej
.. _kostapr: https://github.com/kostapr
.. _masahir0y: https://github.com/masahir0y
.. _mmind: https://github.com/mmind
.. _mtk09422: https://github.com/mtk09422
.. _npoushin: https://github.com/npoushin
.. _qoriq-open-source: https://github.com/qoriq-open-source

View File

@ -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

View File

@ -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)
{
}

View File

@ -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

View File

@ -88,6 +88,17 @@ static int check_cpu_wfie(uint32_t cpu_id, uint32_t wfie_msk)
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

View File

@ -68,6 +68,16 @@ struct rockchip_bl31_params {
/******************************************************************************
* Function and variable prototypes
*****************************************************************************/
#ifdef AARCH32
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);
#else
void plat_configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
unsigned long,
@ -75,6 +85,9 @@ void plat_configure_mmu_el3(unsigned long total_base,
unsigned long,
unsigned long);
void rockchip_plat_mmu_el3(void);
#endif
void plat_cci_init(void);
void plat_cci_enable(void);
void plat_cci_disable(void);
@ -128,13 +141,11 @@ 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 uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT];
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[];
void rockchip_plat_mmu_el3(void);
#endif /* __ASSEMBLY__ */
/******************************************************************************

View File

@ -24,7 +24,11 @@ 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);

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2016-2018, 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 <drivers/console.h>
#include <drivers/generic_delay_timer.h>
#include <drivers/ti/uart/uart_16550.h>
#include <lib/coreboot.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(void *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_16550_t console;
struct rockchip_bl31_params *arg_from_bl2 = (struct rockchip_bl31_params *) arg0;
void *plat_params_from_bl2 = (void *) arg1;
params_early_setup(plat_params_from_bl2);
#if COREBOOT
if (coreboot_serial.type)
console_16550_register(coreboot_serial.baseaddr,
coreboot_serial.input_hertz,
coreboot_serial.baud,
&console);
#else
console_16550_register(PLAT_RK_UART_BASE, PLAT_RK_UART_CLOCK,
PLAT_RK_UART_BAUDRATE, &console);
#endif
VERBOSE("sp_min_setup\n");
/* Passing a NULL context is a critical programming error */
assert(arg_from_bl2);
assert(arg_from_bl2->h.type == PARAM_BL31);
assert(arg_from_bl2->h.version >= VERSION_1);
bl33_ep_info = *arg_from_bl2->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);
}

View File

@ -0,0 +1,17 @@
/*
* 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>
.macro func_rockchip_clst_warmboot
/* Nothing to do for rk3288 */
.endm
.macro rockchip_clst_warmboot_data
/* Nothing to do for rk3288 */
.endm

View File

@ -0,0 +1,391 @@
/*
* Copyright (c) 2016, 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/delay_timer.h>
#include <lib/mmio.h>
#include <plat/common/platform.h>
#include <plat_private.h>
#include <pmu.h>
#include <pmu_com.h>
#include <rk3288_def.h>
#include <secure.h>
#include <soc.h>
DEFINE_BAKERY_LOCK(rockchip_pd_lock);
static uint32_t cpu_warm_boot_addr;
static uint32_t store_pmu_pwrmode_con;
static uint32_t store_sgrf_soc_con0;
static uint32_t store_sgrf_cpu_con0;
/* These enum are variants of low power mode */
enum {
ROCKCHIP_ARM_OFF_LOGIC_NORMAL = 0,
ROCKCHIP_ARM_OFF_LOGIC_DEEP = 1,
};
static inline int rk3288_pmu_bus_idle(uint32_t req, uint32_t idle)
{
uint32_t mask = BIT(req);
uint32_t idle_mask = 0;
uint32_t idle_target = 0;
uint32_t val;
uint32_t wait_cnt = 0;
switch (req) {
case bus_ide_req_gpu:
idle_mask = BIT(pmu_idle_ack_gpu) | BIT(pmu_idle_gpu);
idle_target = (idle << pmu_idle_ack_gpu) |
(idle << pmu_idle_gpu);
break;
case bus_ide_req_core:
idle_mask = BIT(pmu_idle_ack_core) | BIT(pmu_idle_core);
idle_target = (idle << pmu_idle_ack_core) |
(idle << pmu_idle_core);
break;
case bus_ide_req_cpup:
idle_mask = BIT(pmu_idle_ack_cpup) | BIT(pmu_idle_cpup);
idle_target = (idle << pmu_idle_ack_cpup) |
(idle << pmu_idle_cpup);
break;
case bus_ide_req_bus:
idle_mask = BIT(pmu_idle_ack_bus) | BIT(pmu_idle_bus);
idle_target = (idle << pmu_idle_ack_bus) |
(idle << pmu_idle_bus);
break;
case bus_ide_req_dma:
idle_mask = BIT(pmu_idle_ack_dma) | BIT(pmu_idle_dma);
idle_target = (idle << pmu_idle_ack_dma) |
(idle << pmu_idle_dma);
break;
case bus_ide_req_peri:
idle_mask = BIT(pmu_idle_ack_peri) | BIT(pmu_idle_peri);
idle_target = (idle << pmu_idle_ack_peri) |
(idle << pmu_idle_peri);
break;
case bus_ide_req_video:
idle_mask = BIT(pmu_idle_ack_video) | BIT(pmu_idle_video);
idle_target = (idle << pmu_idle_ack_video) |
(idle << pmu_idle_video);
break;
case bus_ide_req_hevc:
idle_mask = BIT(pmu_idle_ack_hevc) | BIT(pmu_idle_hevc);
idle_target = (idle << pmu_idle_ack_hevc) |
(idle << pmu_idle_hevc);
break;
case bus_ide_req_vio:
idle_mask = BIT(pmu_idle_ack_vio) | BIT(pmu_idle_vio);
idle_target = (pmu_idle_ack_vio) |
(idle << pmu_idle_vio);
break;
case bus_ide_req_alive:
idle_mask = BIT(pmu_idle_ack_alive) | BIT(pmu_idle_alive);
idle_target = (idle << pmu_idle_ack_alive) |
(idle << pmu_idle_alive);
break;
default:
ERROR("%s: Unsupported the idle request\n", __func__);
break;
}
val = mmio_read_32(PMU_BASE + PMU_BUS_IDE_REQ);
if (idle)
val |= mask;
else
val &= ~mask;
mmio_write_32(PMU_BASE + PMU_BUS_IDE_REQ, val);
while ((mmio_read_32(PMU_BASE +
PMU_BUS_IDE_ST) & idle_mask) != idle_target) {
wait_cnt++;
if (!(wait_cnt % MAX_WAIT_CONUT))
WARN("%s:st=%x(%x)\n", __func__,
mmio_read_32(PMU_BASE + PMU_BUS_IDE_ST),
idle_mask);
}
return 0;
}
static bool rk3288_sleep_disable_osc(void)
{
static const uint32_t reg_offset[] = { GRF_UOC0_CON0, GRF_UOC1_CON0,
GRF_UOC2_CON0 };
uint32_t reg, i;
/*
* if any usb phy is still on(GRF_SIDDQ==0), that means we need the
* function of usb wakeup, so do not switch to 32khz, since the usb phy
* clk does not connect to 32khz osc
*/
for (i = 0; i < ARRAY_SIZE(reg_offset); i++) {
reg = mmio_read_32(GRF_BASE + reg_offset[i]);
if (!(reg & GRF_SIDDQ))
return false;
}
return true;
}
static void pmu_set_sleep_mode(int level)
{
uint32_t mode_set, mode_set1;
bool osc_disable = rk3288_sleep_disable_osc();
mode_set = BIT(pmu_mode_glb_int_dis) | BIT(pmu_mode_l2_flush_en) |
BIT(pmu_mode_sref0_enter) | BIT(pmu_mode_sref1_enter) |
BIT(pmu_mode_ddrc0_gt) | BIT(pmu_mode_ddrc1_gt) |
BIT(pmu_mode_en) | BIT(pmu_mode_chip_pd) |
BIT(pmu_mode_scu_pd);
mode_set1 = BIT(pmu_mode_clr_core) | BIT(pmu_mode_clr_cpup);
if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP) {
/* arm off, logic deep sleep */
mode_set |= BIT(pmu_mode_bus_pd) | BIT(pmu_mode_pmu_use_lf) |
BIT(pmu_mode_ddrio1_ret) |
BIT(pmu_mode_ddrio0_ret) |
BIT(pmu_mode_pmu_alive_use_lf) |
BIT(pmu_mode_pll_pd);
if (osc_disable)
mode_set |= BIT(pmu_mode_osc_dis);
mode_set1 |= BIT(pmu_mode_clr_alive) | BIT(pmu_mode_clr_bus) |
BIT(pmu_mode_clr_peri) | BIT(pmu_mode_clr_dma);
mmio_write_32(PMU_BASE + PMU_WAKEUP_CFG1,
pmu_armint_wakeup_en);
/*
* In deep suspend we use PMU_PMU_USE_LF to let the rk3288
* switch its main clock supply to the alternative 32kHz
* source. Therefore set 30ms on a 32kHz clock for pmic
* stabilization. Similar 30ms on 24MHz for the other
* mode below.
*/
mmio_write_32(PMU_BASE + PMU_STABL_CNT, 32 * 30);
/* only wait for stabilization, if we turned the osc off */
mmio_write_32(PMU_BASE + PMU_OSC_CNT,
osc_disable ? 32 * 30 : 0);
} else {
/*
* arm off, logic normal
* if pmu_clk_core_src_gate_en is not set,
* wakeup will be error
*/
mode_set |= BIT(pmu_mode_core_src_gt);
mmio_write_32(PMU_BASE + PMU_WAKEUP_CFG1,
BIT(pmu_armint_wakeup_en) |
BIT(pmu_gpioint_wakeup_en));
/* 30ms on a 24MHz clock for pmic stabilization */
mmio_write_32(PMU_BASE + PMU_STABL_CNT, 24000 * 30);
/* oscillator is still running, so no need to wait */
mmio_write_32(PMU_BASE + PMU_OSC_CNT, 0);
}
mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, mode_set);
mmio_write_32(PMU_BASE + PMU_PWRMODE_CON1, mode_set1);
}
static int cpus_power_domain_on(uint32_t cpu_id)
{
uint32_t cpu_pd;
cpu_pd = PD_CPU0 + cpu_id;
/* if the core has been on, power it off first */
if (pmu_power_domain_st(cpu_pd) == pmu_pd_on) {
/* put core in reset - some sort of A12/A17 bug */
mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(0),
BIT(cpu_id) | (BIT(cpu_id) << 16));
pmu_power_domain_ctr(cpu_pd, pmu_pd_off);
}
pmu_power_domain_ctr(cpu_pd, pmu_pd_on);
/* pull core out of reset */
mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(0), BIT(cpu_id) << 16);
return 0;
}
static int cpus_power_domain_off(uint32_t cpu_id)
{
uint32_t cpu_pd = PD_CPU0 + cpu_id;
if (pmu_power_domain_st(cpu_pd) == pmu_pd_off)
return 0;
if (check_cpu_wfie(cpu_id, CKECK_WFEI_MSK))
return -EINVAL;
/* put core in reset - some sort of A12/A17 bug */
mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(0),
BIT(cpu_id) | (BIT(cpu_id) << 16));
pmu_power_domain_ctr(cpu_pd, pmu_pd_off);
return 0;
}
static void nonboot_cpus_off(void)
{
uint32_t boot_cpu, cpu;
boot_cpu = plat_my_core_pos();
boot_cpu = MPIDR_AFFLVL0_VAL(read_mpidr());
/* turn off noboot cpus */
for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
if (cpu == boot_cpu)
continue;
cpus_power_domain_off(cpu);
}
}
void sram_save(void)
{
/* TODO: support the sdram save for rk3288 SoCs*/
}
void sram_restore(void)
{
/* TODO: support the sdram restore for rk3288 SoCs */
}
int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
{
uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
assert(cpu_id < PLATFORM_CORE_COUNT);
assert(cpuson_flags[cpu_id] == 0);
cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
cpuson_entry_point[cpu_id] = entrypoint;
dsb();
cpus_power_domain_on(cpu_id);
/*
* We communicate with the bootrom to active the cpus other
* than cpu0, after a blob of initialize code, they will
* stay at wfe state, once they are actived, they will check
* the mailbox:
* sram_base_addr + 4: 0xdeadbeaf
* sram_base_addr + 8: start address for pc
* The cpu0 need to wait the other cpus other than cpu0 entering
* the wfe state.The wait time is affected by many aspects.
* (e.g: cpu frequency, bootrom frequency, sram frequency, ...)
*/
mdelay(1); /* ensure the cpus other than cpu0 to startup */
/* tell the bootrom mailbox where to start from */
mmio_write_32(SRAM_BASE + 8, cpu_warm_boot_addr);
mmio_write_32(SRAM_BASE + 4, 0xDEADBEAF);
dsb();
sev();
return 0;
}
int rockchip_soc_cores_pwr_dm_on_finish(void)
{
return 0;
}
int rockchip_soc_sys_pwr_dm_resume(void)
{
mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, store_pmu_pwrmode_con);
mmio_write_32(SGRF_BASE + SGRF_CPU_CON(0),
store_sgrf_cpu_con0 | SGRF_DAPDEVICE_MSK);
/* disable fastboot mode */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0),
store_sgrf_soc_con0 | SGRF_FAST_BOOT_DIS);
secure_watchdog_ungate();
clk_gate_con_restore();
clk_sel_con_restore();
clk_plls_resume();
secure_gic_init();
plat_rockchip_gic_init();
return 0;
}
int rockchip_soc_sys_pwr_dm_suspend(void)
{
nonboot_cpus_off();
store_sgrf_cpu_con0 = mmio_read_32(SGRF_BASE + SGRF_CPU_CON(0));
store_sgrf_soc_con0 = mmio_read_32(SGRF_BASE + SGRF_SOC_CON(0));
store_pmu_pwrmode_con = mmio_read_32(PMU_BASE + PMU_PWRMODE_CON);
/* save clk-gates and ungate all for suspend */
clk_gate_con_save();
clk_gate_con_disable();
clk_sel_con_save();
pmu_set_sleep_mode(ROCKCHIP_ARM_OFF_LOGIC_NORMAL);
clk_plls_suspend();
secure_watchdog_gate();
/*
* The dapswjdp can not auto reset before resume, that cause it may
* access some illegal address during resume. Let's disable it before
* suspend, and the MASKROM will enable it back.
*/
mmio_write_32(SGRF_BASE + SGRF_CPU_CON(0), SGRF_DAPDEVICE_MSK);
/*
* SGRF_FAST_BOOT_EN - system to boot from FAST_BOOT_ADDR
*/
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0), SGRF_FAST_BOOT_ENA);
/* boot-address of resuming system is from this register value */
mmio_write_32(SGRF_BASE + SGRF_FAST_BOOT_ADDR,
(uint32_t)&pmu_cpuson_entrypoint);
/* flush all caches - otherwise we might loose the resume address */
dcsw_op_all(DC_OP_CISW);
return 0;
}
void rockchip_plat_mmu_svc_mon(void)
{
}
void plat_rockchip_pmu_init(void)
{
uint32_t cpu;
cpu_warm_boot_addr = (uint32_t)platform_cpu_warmboot;
/* on boot all power-domains are on */
for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
cpuson_flags[cpu] = pmu_pd_on;
nonboot_cpus_off();
}

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PMU_H
#define PMU_H
/* Allocate sp reginon in pmusram */
#define PSRAM_SP_SIZE 0x80
#define PSRAM_SP_BOTTOM (PSRAM_SP_TOP - PSRAM_SP_SIZE)
/*****************************************************************************
* pmu con,reg
*****************************************************************************/
#define PMU_WAKEUP_CFG0 0x0
#define PMU_WAKEUP_CFG1 0x4
#define PMU_PWRDN_CON 0x8
#define PMU_PWRDN_ST 0xc
#define PMU_PWRMODE_CON 0x18
#define PMU_BUS_IDE_REQ 0x10
#define PMU_BUS_IDE_ST 0x14
#define PMU_OSC_CNT 0x20
#define PMU_PLL_CNT 0x24
#define PMU_STABL_CNT 0x28
#define PMU_DDRIO0_PWR_CNT 0x2c
#define PMU_DDRIO1_PWR_CNT 0x30
#define PMU_WKUPRST_CNT 0x44
#define PMU_SFT_CON 0x48
#define PMU_PWRMODE_CON1 0x90
enum pmu_pdid {
PD_CPU0 = 0,
PD_CPU1,
PD_CPU2,
PD_CPU3,
PD_BUS = 5,
PD_PERI,
PD_VIO,
PD_VIDEO,
PD_GPU,
PD_SCU = 11,
PD_HEVC = 14,
PD_END
};
enum pmu_bus_ide {
bus_ide_req_bus = 0,
bus_ide_req_peri,
bus_ide_req_gpu,
bus_ide_req_video,
bus_ide_req_vio,
bus_ide_req_core,
bus_ide_req_alive,
bus_ide_req_dma,
bus_ide_req_cpup,
bus_ide_req_hevc,
bus_ide_req_end
};
enum pmu_pwrmode {
pmu_mode_en = 0,
pmu_mode_core_src_gt,
pmu_mode_glb_int_dis,
pmu_mode_l2_flush_en,
pmu_mode_bus_pd,
pmu_mode_cpu0_pd,
pmu_mode_scu_pd,
pmu_mode_pll_pd = 7,
pmu_mode_chip_pd,
pmu_mode_pwr_off_comb,
pmu_mode_pmu_alive_use_lf,
pmu_mode_pmu_use_lf,
pmu_mode_osc_dis = 12,
pmu_mode_input_clamp,
pmu_mode_wkup_rst,
pmu_mode_sref0_enter,
pmu_mode_sref1_enter,
pmu_mode_ddrio0_ret,
pmu_mode_ddrio1_ret,
pmu_mode_ddrc0_gt,
pmu_mode_ddrc1_gt,
pmu_mode_ddrio0_ret_deq,
pmu_mode_ddrio1_ret_deq,
};
enum pmu_pwrmode1 {
pmu_mode_clr_bus = 0,
pmu_mode_clr_core,
pmu_mode_clr_cpup,
pmu_mode_clr_alive,
pmu_mode_clr_dma,
pmu_mode_clr_peri,
pmu_mode_clr_gpu,
pmu_mode_clr_video,
pmu_mode_clr_hevc,
pmu_mode_clr_vio
};
enum pmu_sft_con {
pmu_sft_ddrio0_ret_cfg = 6,
pmu_sft_ddrio1_ret_cfg = 9,
pmu_sft_l2flsh = 15,
};
enum pmu_wakeup_cfg1 {
pmu_armint_wakeup_en = 0,
pmu_gpio_wakeup_negedge,
pmu_sdmmc0_wakeup_en,
pmu_gpioint_wakeup_en,
};
enum pmu_bus_idle_st {
pmu_idle_bus = 0,
pmu_idle_peri,
pmu_idle_gpu,
pmu_idle_video,
pmu_idle_vio,
pmu_idle_core,
pmu_idle_alive,
pmu_idle_dma,
pmu_idle_cpup,
pmu_idle_hevc,
pmu_idle_ack_bus = 16,
pmu_idle_ack_peri,
pmu_idle_ack_gpu,
pmu_idle_ack_video,
pmu_idle_ack_vio,
pmu_idle_ack_core,
pmu_idle_ack_alive,
pmu_idle_ack_dma,
pmu_idle_ack_cpup,
pmu_idle_ack_hevc,
};
#define CHECK_CPU_WFIE_BASE (0)
#define clstl_cpu_wfe -1
#define clstb_cpu_wfe -1
#define CKECK_WFEI_MSK 0
#define PD_CTR_LOOP 500
#define CHK_CPU_LOOP 500
#define MAX_WAIT_CONUT 1000
#endif /* PMU_H */

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <plat_private.h>
#include <secure.h>
#include <soc.h>
static void sgrf_ddr_rgn_global_bypass(uint32_t bypass)
{
if (bypass)
/* set bypass (non-secure regions) for whole ddr regions */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(21),
SGRF_DDR_RGN_BYPS);
else
/* cancel bypass for whole ddr regions */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(21),
SGRF_DDR_RGN_NO_BYPS);
}
/**
* There are 8 + 1 regions for DDR secure control:
* DDR_RGN_0 ~ DDR_RGN_7: Per DDR_RGNs grain size is 1MB
* DDR_RGN_X - the memories of exclude DDR_RGN_0 ~ DDR_RGN_7
*
* SGRF_SOC_CON6 - start address of RGN_0 + control
* SGRF_SOC_CON7 - end address of RGN_0
* ...
* SGRF_SOC_CON20 - start address of the RGN_7 + control
* SGRF_SOC_CON21 - end address of the RGN_7 + RGN_X control
*
* @rgn - the DDR regions 0 ~ 7 which are can be configured.
* The @st and @ed indicate the start and end addresses for which to set
* the security, and the unit is byte. When the st_mb == 0, ed_mb == 0, the
* address range 0x0 ~ 0xfffff is secure.
*
* For example, if we would like to set the range [0, 32MB) is security via
* DDR_RGN0, then rgn == 0, st_mb == 0, ed_mb == 31.
*/
static void sgrf_ddr_rgn_config(uint32_t rgn, uintptr_t st, uintptr_t ed)
{
uintptr_t st_mb, ed_mb;
assert(rgn <= 7);
assert(st < ed);
/* check aligned 1MB */
assert(st % SIZE_M(1) == 0);
assert(ed % SIZE_M(1) == 0);
st_mb = st / SIZE_M(1);
ed_mb = ed / SIZE_M(1);
/* set ddr region addr start */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2)),
BITS_WITH_WMASK(st_mb, SGRF_DDR_RGN_ADDR_WMSK, 0));
/* set ddr region addr end */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2) + 1),
BITS_WITH_WMASK((ed_mb - 1), SGRF_DDR_RGN_ADDR_WMSK, 0));
/* select region security */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2)),
SGRF_DDR_RGN_SECURE_SEL);
/* enable region security */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2)),
SGRF_DDR_RGN_SECURE_EN);
}
void secure_watchdog_gate(void)
{
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0), SGRF_PCLK_WDT_GATE);
}
void secure_watchdog_ungate(void)
{
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0), SGRF_PCLK_WDT_UNGATE);
}
__pmusramfunc void sram_secure_timer_init(void)
{
mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, 0);
mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT0, 0xffffffff);
mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT1, 0xffffffff);
/* auto reload & enable the timer */
mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, TIMER_EN);
}
void secure_gic_init(void)
{
/* (re-)enable non-secure access to the gic*/
mmio_write_32(CORE_AXI_BUS_BASE + CORE_AXI_SECURITY0,
AXI_SECURITY0_GIC);
}
void secure_timer_init(void)
{
mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, 0);
mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT0, 0xffffffff);
mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT1, 0xffffffff);
/* auto reload & enable the timer */
mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, TIMER_EN);
}
void secure_sgrf_init(void)
{
/*
* We use the first sram part to talk to the bootrom,
* so make it secure.
*/
mmio_write_32(TZPC_BASE + TZPC_R0SIZE, TZPC_SRAM_SECURE_4K(1));
secure_gic_init();
/* set all master ip to non-secure */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(2), SGRF_SOC_CON2_MST_NS);
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(3), SGRF_SOC_CON3_MST_NS);
/* setting all configurable ip into non-secure */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4),
SGRF_SOC_CON4_SECURE_WMSK /*TODO:|SGRF_STIMER_SECURE*/);
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(5), SGRF_SOC_CON5_SECURE_WMSK);
/* secure dma to non-secure */
mmio_write_32(TZPC_BASE + TZPC_DECPROT1SET, 0xff);
mmio_write_32(TZPC_BASE + TZPC_DECPROT2SET, 0xff);
mmio_write_32(SGRF_BASE + SGRF_BUSDMAC_CON(1), 0x3800);
dsb();
/* rst dma1 */
mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(1),
RST_DMA1_MSK | (RST_DMA1_MSK << 16));
/* rst dma2 */
mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(4),
RST_DMA2_MSK | (RST_DMA2_MSK << 16));
dsb();
/* release dma1 rst*/
mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(1), (RST_DMA1_MSK << 16));
/* release dma2 rst*/
mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(4), (RST_DMA2_MSK << 16));
}
void secure_sgrf_ddr_rgn_init(void)
{
sgrf_ddr_rgn_config(0, TZRAM_BASE, TZRAM_SIZE);
sgrf_ddr_rgn_global_bypass(0);
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SECURE_H
#define SECURE_H
/******************************************************************************
* TZPC TrustZone controller
******************************************************************************/
#define TZPC_R0SIZE 0x0
#define TZPC_SRAM_SECURE_4K(n) ((n) > 0x200 ? 0x200 : (n))
#define TZPC_DECPROT1STAT 0x80c
#define TZPC_DECPROT1SET 0x810
#define TZPC_DECPROT1CLR 0x814
#define TZPC_DECPROT2STAT 0x818
#define TZPC_DECPROT2SET 0x818
#define TZPC_DECPROT2CLR 0x820
/**************************************************
* sgrf reg, offset
**************************************************/
/*
* soc_con0-5 start at 0x0, soc_con6-... start art 0x50
* adjusted for the 5 lower registers
*/
#define SGRF_SOC_CON(n) ((((n) < 6) ? 0x0 : 0x38) + (n) * 4)
#define SGRF_BUSDMAC_CON(n) (0x20 + (n) * 4)
#define SGRF_CPU_CON(n) (0x40 + (n) * 4)
#define SGRF_SOC_STATUS(n) (0x100 + (n) * 4)
#define SGRF_FAST_BOOT_ADDR 0x120
/* SGRF_SOC_CON0 */
#define SGRF_FAST_BOOT_ENA BIT_WITH_WMSK(8)
#define SGRF_FAST_BOOT_DIS WMSK_BIT(8)
#define SGRF_PCLK_WDT_GATE BIT_WITH_WMSK(6)
#define SGRF_PCLK_WDT_UNGATE WMSK_BIT(6)
#define SGRF_PCLK_STIMER_GATE BIT_WITH_WMSK(4)
#define SGRF_SOC_CON2_MST_NS 0xffe0ffe0
#define SGRF_SOC_CON3_MST_NS 0x003f003f
/* SGRF_SOC_CON4 */
#define SGRF_SOC_CON4_SECURE_WMSK 0xffff0000
#define SGRF_DDRC1_SECURE BIT_WITH_WMSK(12)
#define SGRF_DDRC0_SECURE BIT_WITH_WMSK(11)
#define SGRF_PMUSRAM_SECURE BIT_WITH_WMSK(8)
#define SGRF_WDT_SECURE BIT_WITH_WMSK(7)
#define SGRF_STIMER_SECURE BIT_WITH_WMSK(6)
/* SGRF_SOC_CON5 */
#define SGRF_SLV_SEC_BYPS BIT_WITH_WMSK(15)
#define SGRF_SLV_SEC_NO_BYPS WMSK_BIT(15)
#define SGRF_SOC_CON5_SECURE_WMSK 0x00ff0000
/* ddr regions in SGRF_SOC_CON6 and following */
#define SGRF_DDR_RGN_SECURE_SEL BIT_WITH_WMSK(15)
#define SGRF_DDR_RGN_SECURE_EN BIT_WITH_WMSK(14)
#define SGRF_DDR_RGN_ADDR_WMSK 0x0fff
/* SGRF_SOC_CON21 */
/* All security of the DDR RGNs are bypassed */
#define SGRF_DDR_RGN_BYPS BIT_WITH_WMSK(15)
#define SGRF_DDR_RGN_NO_BYPS WMSK_BIT(15)
/* SGRF_CPU_CON0 */
#define SGRF_DAPDEVICE_ENA BIT_WITH_WMSK(0)
#define SGRF_DAPDEVICE_MSK WMSK_BIT(0)
/*****************************************************************************
* core-axi
*****************************************************************************/
#define CORE_AXI_SECURITY0 0x08
#define AXI_SECURITY0_GIC BIT(0)
/*****************************************************************************
* secure timer
*****************************************************************************/
#define TIMER_LOAD_COUNT0 0x00
#define TIMER_LOAD_COUNT1 0x04
#define TIMER_CURRENT_VALUE0 0x08
#define TIMER_CURRENT_VALUE1 0x0C
#define TIMER_CONTROL_REG 0x10
#define TIMER_INTSTATUS 0x18
#define TIMER_EN 0x1
#define STIMER1_BASE (STIME_BASE + 0x20)
/* export secure operating APIs */
void secure_watchdog_gate(void);
void secure_watchdog_ungate(void);
void secure_gic_init(void);
void secure_timer_init(void);
void secure_sgrf_init(void);
void secure_sgrf_ddr_rgn_init(void);
__pmusramfunc void sram_secure_timer_init(void);
#endif /* SECURE_H */

View File

@ -0,0 +1,215 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <platform_def.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <lib/mmio.h>
#include <plat_private.h>
#include <rk3288_def.h>
#include <soc.h>
#include <secure.h>
/* sleep data for pll suspend */
static struct deepsleep_data_s slp_data;
/* Table of regions to map using the MMU. */
const mmap_region_t plat_rk_mmap[] = {
MAP_REGION_FLAT(GIC400_BASE, GIC400_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(STIME_BASE, STIME_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SGRF_BASE, SGRF_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(TZPC_BASE, TZPC_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
MT_MEMORY | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SRAM_BASE, SRAM_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(PMU_BASE, PMU_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(UART_DBG_BASE, UART_DBG_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(CRU_BASE, CRU_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(GRF_BASE, GRF_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(DDR_PCTL0_BASE, DDR_PCTL0_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(DDR_PHY0_BASE, DDR_PHY0_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(DDR_PCTL1_BASE, DDR_PCTL1_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(DDR_PHY1_BASE, DDR_PHY1_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SERVICE_BUS_BASE, SERVICE_BUS_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(CORE_AXI_BUS_BASE, CORE_AXI_BUS_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
{ 0 }
};
/* The RockChip power domain tree descriptor */
const unsigned char rockchip_power_domain_tree_desc[] = {
/* No of root nodes */
PLATFORM_SYSTEM_COUNT,
/* No of children for the root node */
PLATFORM_CLUSTER_COUNT,
/* No of children for the first cluster node */
PLATFORM_CLUSTER0_CORE_COUNT,
};
void plat_rockchip_soc_init(void)
{
secure_timer_init();
secure_sgrf_init();
/*
* We cannot enable ddr security at this point, as the kernel
* seems to have an issue with it even living in the same 128MB
* memory block. Only when moving the kernel to the second
* 128MB block does it not conflict, but then we'd loose this
* memory area for use. Late maybe enable
* secure_sgrf_ddr_rgn_init();
*/
}
void regs_update_bits(uintptr_t addr, uint32_t val,
uint32_t mask, uint32_t shift)
{
uint32_t tmp, orig;
orig = mmio_read_32(addr);
tmp = orig & ~(mask << shift);
tmp |= (val & mask) << shift;
if (tmp != orig)
mmio_write_32(addr, tmp);
dsb();
}
static void pll_save(uint32_t pll_id)
{
uint32_t *pll = slp_data.pll_con[pll_id];
pll[0] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 0));
pll[1] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 1));
pll[2] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 2));
pll[3] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 3));
}
void clk_plls_suspend(void)
{
pll_save(NPLL_ID);
pll_save(CPLL_ID);
pll_save(GPLL_ID);
pll_save(APLL_ID);
slp_data.pll_mode = mmio_read_32(CRU_BASE + PLL_MODE_CON);
/*
* Switch PLLs other than DPLL (for SDRAM) to slow mode to
* avoid crashes on resume. The Mask ROM on the system will
* put APLL, CPLL, and GPLL into slow mode at resume time
* anyway (which is why we restore them), but we might not
* even make it to the Mask ROM if this isn't done at suspend
* time.
*
* NOTE: only APLL truly matters here, but we'll do them all.
*/
mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000);
}
void clk_plls_resume(void)
{
/* restore pll-modes */
mmio_write_32(CRU_BASE + PLL_MODE_CON,
slp_data.pll_mode | REG_SOC_WMSK);
}
void clk_gate_con_save(void)
{
uint32_t i = 0;
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
slp_data.cru_gate_con[i] =
mmio_read_32(CRU_BASE + CRU_CLKGATES_CON(i));
}
void clk_gate_con_disable(void)
{
uint32_t i;
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i), REG_SOC_WMSK);
}
void clk_gate_con_restore(void)
{
uint32_t i;
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i),
REG_SOC_WMSK | slp_data.cru_gate_con[i]);
}
void clk_sel_con_save(void)
{
uint32_t i = 0;
for (i = 0; i < CRU_CLKSELS_CON_CNT; i++)
slp_data.cru_sel_con[i] =
mmio_read_32(CRU_BASE + CRU_CLKSELS_CON(i));
}
void clk_sel_con_restore(void)
{
uint32_t i, val;
for (i = 0; i < CRU_CLKSELS_CON_CNT; i++) {
/* fractional dividers don't have write-masks */
if ((i >= 7 && i <= 9) ||
(i >= 17 && i <= 20) ||
(i == 23) || (i == 41))
val = slp_data.cru_sel_con[i];
else
val = slp_data.cru_sel_con[i] | REG_SOC_WMSK;
mmio_write_32(CRU_BASE + CRU_CLKSELS_CON(i), val);
}
}
void __dead2 rockchip_soc_soft_reset(void)
{
uint32_t temp_val;
/*
* Switch PLLs other than DPLL (for SDRAM) to slow mode to
* avoid crashes on resume. The Mask ROM on the system will
* put APLL, CPLL, and GPLL into slow mode at resume time
* anyway (which is why we restore them), but we might not
* even make it to the Mask ROM if this isn't done at suspend
* time.
*
* NOTE: only APLL truly matters here, but we'll do them all.
*/
mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000);
temp_val = mmio_read_32(CRU_BASE + CRU_GLB_RST_CON);
temp_val &= ~PMU_RST_MASK;
temp_val |= PMU_RST_BY_SECOND_SFT;
mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, temp_val);
mmio_write_32(CRU_BASE + CRU_GLB_SRST_SND, 0xeca8);
/*
* Maybe the HW needs some times to reset the system,
* so we do not hope the core to excute valid codes.
*/
while (1)
;
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SOC_H
#define SOC_H
enum plls_id {
APLL_ID = 0,
DPLL_ID,
CPLL_ID,
GPLL_ID,
NPLL_ID,
END_PLL_ID,
};
#define CYCL_24M_CNT_US(us) (24 * (us))
#define CYCL_24M_CNT_MS(ms) ((ms) * CYCL_24M_CNT_US(1000))
/*****************************************************************************
* grf regs
*****************************************************************************/
#define GRF_UOC0_CON0 0x320
#define GRF_UOC1_CON0 0x334
#define GRF_UOC2_CON0 0x348
#define GRF_SIDDQ BIT(13)
/*****************************************************************************
* cru reg, offset
*****************************************************************************/
#define CRU_SOFTRST_CON 0x1b8
#define CRU_SOFTRSTS_CON(n) (CRU_SOFTRST_CON + ((n) * 4))
#define CRU_SOFTRSTS_CON_CNT 11
#define RST_DMA1_MSK 0x4
#define RST_DMA2_MSK 0x1
#define CRU_CLKSEL_CON 0x60
#define CRU_CLKSELS_CON(i) (CRU_CLKSEL_CON + ((i) * 4))
#define CRU_CLKSELS_CON_CNT 42
#define CRU_CLKGATE_CON 0x160
#define CRU_CLKGATES_CON(i) (CRU_CLKGATE_CON + ((i) * 4))
#define CRU_CLKGATES_CON_CNT 18
#define CRU_GLB_SRST_FST 0x1b0
#define CRU_GLB_SRST_SND 0x1b4
#define CRU_GLB_RST_CON 0x1f0
#define CRU_CONS_GATEID(i) (16 * (i))
#define GATE_ID(reg, bit) (((reg) * 16) + (bit))
#define PMU_RST_MASK 0x3
#define PMU_RST_BY_FIRST_SFT (0 << 2)
#define PMU_RST_BY_SECOND_SFT (1 << 2)
#define PMU_RST_NOT_BY_SFT (2 << 2)
/***************************************************************************
* pll
***************************************************************************/
#define PLL_CON_COUNT 4
#define PLL_CONS(id, i) ((id) * 0x10 + ((i) * 4))
#define PLL_PWR_DN_MSK BIT(1)
#define PLL_PWR_DN REG_WMSK_BITS(1, 1, 0x1)
#define PLL_PWR_ON REG_WMSK_BITS(0, 1, 0x1)
#define PLL_RESET REG_WMSK_BITS(1, 5, 0x1)
#define PLL_RESET_RESUME REG_WMSK_BITS(0, 5, 0x1)
#define PLL_BYPASS_MSK BIT(0)
#define PLL_BYPASS_W_MSK (PLL_BYPASS_MSK << 16)
#define PLL_BYPASS REG_WMSK_BITS(1, 0, 0x1)
#define PLL_NO_BYPASS REG_WMSK_BITS(0, 0, 0x1)
#define PLL_MODE_CON 0x50
struct deepsleep_data_s {
uint32_t pll_con[END_PLL_ID][PLL_CON_COUNT];
uint32_t pll_mode;
uint32_t cru_sel_con[CRU_CLKSELS_CON_CNT];
uint32_t cru_gate_con[CRU_CLKGATES_CON_CNT];
};
#define REG_W_MSK(bits_shift, msk) \
((msk) << ((bits_shift) + 16))
#define REG_VAL_CLRBITS(val, bits_shift, msk) \
((val) & (~((msk) << bits_shift)))
#define REG_SET_BITS(bits, bits_shift, msk) \
(((bits) & (msk)) << (bits_shift))
#define REG_WMSK_BITS(bits, bits_shift, msk) \
(REG_W_MSK(bits_shift, msk) | \
REG_SET_BITS(bits, bits_shift, msk))
#define REG_SOC_WMSK 0xffff0000
#define regs_update_bit_set(addr, shift) \
regs_update_bits((addr), 0x1, 0x1, (shift))
#define regs_update_bit_clr(addr, shift) \
regs_update_bits((addr), 0x0, 0x1, (shift))
void regs_update_bits(uintptr_t addr, uint32_t val,
uint32_t mask, uint32_t shift);
void clk_plls_suspend(void);
void clk_plls_resume(void);
void clk_gate_con_save(void);
void clk_gate_con_disable(void);
void clk_gate_con_restore(void);
void clk_sel_con_save(void);
void clk_sel_con_restore(void);
#endif /* SOC_H */

View File

@ -0,0 +1,12 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLAT_SIP_CALLS_H
#define PLAT_SIP_CALLS_H
#define RK_PLAT_SIP_NUM_CALLS 0
#endif /* PLAT_SIP_CALLS_H */

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef ROCKCHIP_PLAT_LD_S
#define ROCKCHIP_PLAT_LD_S
#include <lib/xlat_tables/xlat_tables_defs.h>
MEMORY {
SRAM (rwx): ORIGIN = SRAM_BASE, LENGTH = SRAM_SIZE
PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
}
SECTIONS
{
. = SRAM_BASE;
ASSERT(. == ALIGN(PAGE_SIZE),
"SRAM_BASE address is not aligned on a page boundary.")
.text_sram : ALIGN(PAGE_SIZE) {
__bl32_sram_text_start = .;
*(.sram.text)
*(.sram.rodata)
__bl32_sram_text_real_end = .;
. = ALIGN(PAGE_SIZE);
__bl32_sram_text_end = .;
} >SRAM
ASSERT((__bl32_sram_text_real_end - __bl32_sram_text_start) <=
SRAM_TEXT_LIMIT, ".text_sram has exceeded its limit")
.data_sram : ALIGN(PAGE_SIZE) {
__bl32_sram_data_start = .;
*(.sram.data)
__bl32_sram_data_real_end = .;
. = ALIGN(PAGE_SIZE);
__bl32_sram_data_end = .;
} >SRAM
ASSERT((__bl32_sram_data_real_end - __bl32_sram_data_start) <=
SRAM_DATA_LIMIT, ".data_sram has exceeded its limit")
.stack_sram : ALIGN(PAGE_SIZE) {
__bl32_sram_stack_start = .;
. += PAGE_SIZE;
__bl32_sram_stack_end = .;
} >SRAM
. = PMUSRAM_BASE;
/*
* pmu_cpuson_entrypoint request address
* align 64K when resume, so put it in the
* start of pmusram
*/
.pmusram : {
ASSERT(. == ALIGN(64 * 1024),
".pmusram.entry request 64K aligned.");
*(.pmusram.entry)
__bl32_pmusram_text_start = .;
*(.pmusram.text)
*(.pmusram.rodata)
__bl32_pmusram_text_end = .;
__bl32_pmusram_data_start = .;
*(.pmusram.data)
__bl32_pmusram_data_end = .;
} >PMUSRAM
}
#endif /* ROCKCHIP_PLAT_LD_S */

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLATFORM_DEF_H
#define PLATFORM_DEF_H
#include <arch.h>
#include <lib/utils_def.h>
#include <plat/common/common_def.h>
#include <bl32_param.h>
#include <rk3288_def.h>
/*******************************************************************************
* Platform binary types for linking
******************************************************************************/
#define PLATFORM_LINKER_FORMAT "elf32-littlearm"
#define PLATFORM_LINKER_ARCH arm
/*******************************************************************************
* Generic platform constants
******************************************************************************/
/* Size of cacheable stacks */
#if defined(IMAGE_BL1)
#define PLATFORM_STACK_SIZE 0x440
#elif defined(IMAGE_BL2)
#define PLATFORM_STACK_SIZE 0x400
#elif defined(IMAGE_BL32)
#define PLATFORM_STACK_SIZE 0x800
#endif
#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2
#define PLATFORM_SYSTEM_COUNT 1
#define PLATFORM_CLUSTER_COUNT 1
#define PLATFORM_CLUSTER0_CORE_COUNT 4
#define PLATFORM_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)
#define PLAT_RK_CLST_TO_CPUID_SHIFT 6
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
/*
* This macro defines the deepest retention state possible. A higher state
* id will represent an invalid or a power down state.
*/
#define PLAT_MAX_RET_STATE U(1)
/*
* This macro defines the deepest power down states possible. Any state ID
* higher than this is invalid.
*/
#define PLAT_MAX_OFF_STATE U(2)
/*******************************************************************************
* Platform specific page table and MMU setup constants
******************************************************************************/
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define MAX_XLAT_TABLES 8
#define MAX_MMAP_REGIONS 18
/*******************************************************************************
* 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)
/*
* Define GICD and GICC and GICR base
*/
#define PLAT_RK_GICD_BASE RK3288_GICD_BASE
#define PLAT_RK_GICC_BASE RK3288_GICC_BASE
#define PLAT_RK_UART_BASE RK3288_UART2_BASE
#define PLAT_RK_UART_CLOCK RK3288_UART_CLOCK
#define PLAT_RK_UART_BAUDRATE RK3288_BAUDRATE
/* ClusterId is always 0x5 on rk3288, filter it */
#define PLAT_RK_MPIDR_CLUSTER_MASK 0
#define PLAT_RK_PRIMARY_CPU 0x0
#define PSRAM_DO_DDR_RESUME 0
#define PSRAM_CHECK_WAKEUP_CPU 0
#endif /* PLATFORM_DEF_H */

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef BL32_PARAM_H
#define BL32_PARAM_H
/*******************************************************************************
* Platform memory map related constants
******************************************************************************/
/* TF txet, ro, rw, Size: 2MB */
#define TZRAM_BASE (0x0)
#define TZRAM_SIZE (0x200000)
/*******************************************************************************
* BL32 specific defines.
******************************************************************************/
/*
* Put BL32 at the top of the Trusted RAM
*/
#define BL32_BASE (TZRAM_BASE + 0x100000)
#define BL32_LIMIT (TZRAM_BASE + TZRAM_SIZE)
#endif /* BL32_PARAM_H */

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <lib/mmio.h>
#include <plat_sip_calls.h>
#include <rockchip_sip_svc.h>
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);
}

View File

@ -0,0 +1,67 @@
#
# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
ARM_CORTEX_A12 := yes
ARM_ARCH_MAJOR := 7
RK_PLAT := plat/rockchip
RK_PLAT_SOC := ${RK_PLAT}/${PLAT}
RK_PLAT_COMMON := ${RK_PLAT}/common
include lib/libfdt/libfdt.mk
PLAT_INCLUDES := -I${RK_PLAT_COMMON}/ \
-I${RK_PLAT_COMMON}/include/ \
-I${RK_PLAT_COMMON}/aarch32/ \
-I${RK_PLAT_COMMON}/drivers/pmu/ \
-I${RK_PLAT_SOC}/ \
-I${RK_PLAT_SOC}/drivers/pmu/ \
-I${RK_PLAT_SOC}/drivers/secure/ \
-I${RK_PLAT_SOC}/drivers/soc/ \
-I${RK_PLAT_SOC}/include/ \
-I${RK_PLAT_SOC}/include/shared/ \
RK_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v2/gicv2_main.c \
drivers/arm/gic/v2/gicv2_helpers.c \
plat/common/plat_gicv2.c \
${RK_PLAT}/common/rockchip_gicv2.c
PLAT_BL_COMMON_SOURCES := plat/common/aarch32/crash_console_helpers.S \
plat/common/plat_psci_common.c
PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \
lib/xlat_tables/aarch32/xlat_tables.c
BL32_SOURCES += ${RK_GIC_SOURCES} \
drivers/arm/cci/cci.c \
drivers/ti/uart/aarch32/16550_console.S \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
lib/cpus/aarch32/cortex_a12.S \
$(LIBFDT_SRCS) \
${RK_PLAT_COMMON}/aarch32/plat_helpers.S \
${RK_PLAT_COMMON}/params_setup.c \
${RK_PLAT_COMMON}/aarch32/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/plat_pm.c \
${RK_PLAT_COMMON}/plat_topology.c \
${RK_PLAT_COMMON}/aarch32/platform_common.c \
${RK_PLAT_COMMON}/rockchip_sip_svc.c \
${RK_PLAT_SOC}/plat_sip_calls.c \
${RK_PLAT_SOC}/drivers/pmu/pmu.c \
${RK_PLAT_SOC}/drivers/secure/secure.c \
${RK_PLAT_SOC}/drivers/soc/soc.c \
MULTI_CONSOLE_API := 1
include lib/coreboot/coreboot.mk
$(eval $(call add_define,PLAT_SP_MIN_EXTRA_LD_SCRIPT))
# Do not enable SVE
ENABLE_SVE_FOR_NS := 0
WORKAROUND_CVE_2017_5715 := 0

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RK3288_DEF_H
#define RK3288_DEF_H
/* Special value used to verify platform parameters from BL2 to BL31 */
#define RK_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
#define SIZE_K(n) ((n) * 1024)
#define SIZE_M(n) ((n) * 1024 * 1024)
#define SRAM_TEXT_LIMIT (4 * 1024)
#define SRAM_DATA_LIMIT (4 * 1024)
#define DDR_PCTL0_BASE 0xff610000
#define DDR_PCTL0_SIZE SIZE_K(64)
#define DDR_PHY0_BASE 0xff620000
#define DDR_PHY0_SIZE SIZE_K(64)
#define DDR_PCTL1_BASE 0xff630000
#define DDR_PCTL1_SIZE SIZE_K(64)
#define DDR_PHY1_BASE 0xff640000
#define DDR_PHY1_SIZE SIZE_K(64)
#define UART_DBG_BASE 0xff690000
#define UART_DBG_SIZE SIZE_K(64)
/* 96k instead of 64k? */
#define SRAM_BASE 0xff700000
#define SRAM_SIZE SIZE_K(64)
#define PMUSRAM_BASE 0xff720000
#define PMUSRAM_SIZE SIZE_K(4)
#define PMUSRAM_RSIZE SIZE_K(4)
#define PMU_BASE 0xff730000
#define PMU_SIZE SIZE_K(64)
#define SGRF_BASE 0xff740000
#define SGRF_SIZE SIZE_K(64)
#define CRU_BASE 0xff760000
#define CRU_SIZE SIZE_K(64)
#define GRF_BASE 0xff770000
#define GRF_SIZE SIZE_K(64)
/* timer 6+7 can be set as secure in SGRF */
#define STIME_BASE 0xff810000
#define STIME_SIZE SIZE_K(64)
#define SERVICE_BUS_BASE 0xffac0000
#define SERVICE_BUS_SIZE SIZE_K(64)
#define TZPC_BASE 0xffb00000
#define TZPC_SIZE SIZE_K(64)
#define GIC400_BASE 0xffc00000
#define GIC400_SIZE SIZE_K(64)
#define CORE_AXI_BUS_BASE 0xffd00000
#define CORE_AXI_BUS_SIZE SIZE_M(1)
#define COLD_BOOT_BASE 0xffff0000
/**************************************************************************
* UART related constants
**************************************************************************/
#define RK3288_UART2_BASE UART_DBG_BASE
#define RK3288_BAUDRATE 115200
#define RK3288_UART_CLOCK 24000000
/******************************************************************************
* System counter frequency related constants
******************************************************************************/
#define SYS_COUNTER_FREQ_IN_TICKS 24000000
/******************************************************************************
* GIC-400 & interrupt handling related constants
******************************************************************************/
/* Base rk_platform compatible GIC memory map */
#define RK3288_GICD_BASE (GIC400_BASE + 0x1000)
#define RK3288_GICC_BASE (GIC400_BASE + 0x2000)
#define RK3288_GICR_BASE 0 /* no GICR in GIC-400 */
/******************************************************************************
* sgi, ppi
******************************************************************************/
#define RK_IRQ_SEC_PHY_TIMER 29
/* what are these, and are they present on rk3288? */
#define RK_IRQ_SEC_SGI_0 8
#define RK_IRQ_SEC_SGI_1 9
#define RK_IRQ_SEC_SGI_2 10
#define RK_IRQ_SEC_SGI_3 11
#define RK_IRQ_SEC_SGI_4 12
#define RK_IRQ_SEC_SGI_5 13
#define RK_IRQ_SEC_SGI_6 14
#define RK_IRQ_SEC_SGI_7 15
/*
* Define a list of Group 0 interrupts.
*/
#define PLAT_RK_GICV2_G0_IRQS \
INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
#endif /* RK3288_DEF_H */

View File

@ -0,0 +1,8 @@
#
# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \
plat/rockchip/common/sp_min_plat_setup.c

View File

@ -49,8 +49,6 @@ enum pmu_cores_pm_by_wfi {
extern void *pmu_cpuson_entrypoint_start;
extern void *pmu_cpuson_entrypoint_end;
extern uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT];
extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
#define CORES_PM_DISABLE 0x0

View File

@ -14,7 +14,7 @@ PLAT_INCLUDES := -Idrivers/arm/gic/common/ \
-Idrivers/arm/gic/v2/ \
-I${RK_PLAT_COMMON}/ \
-I${RK_PLAT_COMMON}/include/ \
-I${RK_PLAT_COMMON}/pmusram \
-I${RK_PLAT_COMMON}/aarch64/ \
-I${RK_PLAT_COMMON}/drivers/pmu/ \
-I${RK_PLAT_COMMON}/drivers/parameter/ \
-I${RK_PLAT_SOC}/ \
@ -44,7 +44,7 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \
${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
${RK_PLAT_COMMON}/bl31_plat_setup.c \
${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/aarch64/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/plat_pm.c \
${RK_PLAT_COMMON}/plat_topology.c \
${RK_PLAT_COMMON}/aarch64/platform_common.c \

View File

@ -12,7 +12,7 @@ include lib/libfdt/libfdt.mk
PLAT_INCLUDES := -I${RK_PLAT_COMMON}/ \
-I${RK_PLAT_COMMON}/include/ \
-I${RK_PLAT_COMMON}/pmusram \
-I${RK_PLAT_COMMON}/aarch64/ \
-I${RK_PLAT_COMMON}/drivers/pmu/ \
-I${RK_PLAT_SOC}/ \
-I${RK_PLAT_SOC}/drivers/pmu/ \
@ -41,7 +41,7 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
${RK_PLAT_COMMON}/bl31_plat_setup.c \
${RK_PLAT_COMMON}/params_setup.c \
${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/aarch64/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/plat_pm.c \
${RK_PLAT_COMMON}/plat_topology.c \
${RK_PLAT_COMMON}/aarch64/platform_common.c \

View File

@ -12,7 +12,7 @@ include lib/libfdt/libfdt.mk
PLAT_INCLUDES := -I${RK_PLAT_COMMON}/ \
-I${RK_PLAT_COMMON}/include/ \
-I${RK_PLAT_COMMON}/pmusram \
-I${RK_PLAT_COMMON}/aarch64/ \
-I${RK_PLAT_COMMON}/drivers/pmu/ \
-I${RK_PLAT_SOC}/ \
-I${RK_PLAT_SOC}/drivers/pmu/ \
@ -49,7 +49,7 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
${RK_PLAT_COMMON}/bl31_plat_setup.c \
${RK_PLAT_COMMON}/params_setup.c \
${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/aarch64/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/plat_pm.c \
${RK_PLAT_COMMON}/plat_topology.c \
${RK_PLAT_COMMON}/aarch64/platform_common.c \