Commit 780e3f24 authored by Heiko Stuebner's avatar Heiko Stuebner
Browse files

rockchip: add support for rk3288



The rk3288 is a 4-core Cortex-A12 SoC and shares a lot of features
with later SoCs.

Working features are general non-secure mode (the gic needs special
love for that), psci-based smp bringing cpu cores online and also
taking them offline again, psci-based suspend (the simpler variant
also included in the linux kernel, deeper suspend following later)
and I was also already able to test HYP-mode and was able to boot
a virtual kernel using kvm.
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Change-Id: Ibaaa583b2e78197591a91d254339706fe732476a
parent 82e18f89
/*
* 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
/*
* 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();
}
/*
* 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 */
/*
* 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);
}
/*
* 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 */
/*
* 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)
;
}
/*
* 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 */
/*
* 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 */
/*
* 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 */
/*
* 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 */
/*
* 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 */
/*
* 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);
}
#
# 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
/*
* 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 */
#
# 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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment