GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,213 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <arch.h>
#include <asm_macros.S>
#include <assert_macros.S>
#include <cpu_macros.S>
#include <cortex_a55.h>
#include <platform_def.h>
/* Global functions */
.globl plat_is_my_cpu_primary
.globl plat_my_core_pos
.globl plat_get_my_entrypoint
.globl plat_secondary_cold_boot_setup
.globl platform_mem_init
.globl plat_crash_console_init
.globl plat_crash_console_putc
.globl plat_crash_console_flush
.globl plat_reset_handler
/* Global variables */
.globl lotus_sec_entry_point
.globl ns_image_entrypoint
.globl lotus_bl31_phys_base
/* ---------------------
* Common CPU init code
* ---------------------
*/
.macro cpu_init_common
/* --------------------------------
* Enable the cycle count register
* --------------------------------
*/
mrs x0, pmcr_el0
ubfx x0, x0, #11, #5 // read PMCR.N field
mov x1, #1
lsl x0, x1, x0
sub x0, x0, #1 // mask of event counters
orr x0, x0, #0x80000000 // disable overflow intrs
msr pmintenclr_el1, x0
msr pmuserenr_el0, x1 // enable user mode access
/* ----------------------------------------------------------------
* Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
* register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
* registers from EL0.
* ----------------------------------------------------------------
*/
mrs x0, cntkctl_el1
orr x0, x0, #EL0VCTEN_BIT
msr cntkctl_el1, x0
.endm
/* -----------------------------------------------------
* unsigned int plat_is_my_cpu_primary(void);
*
* This function checks if this is the Primary CPU
* -----------------------------------------------------
*/
func plat_is_my_cpu_primary
mrs x0, mpidr_el1
and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
cmp x0, #PLAT_LOTUS_PRIMARY_CPU
cset x0, eq
ret
endfunc plat_is_my_cpu_primary
/* -----------------------------------------------------
* unsigned int plat_my_core_pos(void);
*
* result: CorePos = CoreId + (ClusterId << 2)
* -----------------------------------------------------
*/
func plat_my_core_pos
mrs x0, mpidr_el1
and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK
add x0, x1, x0, LSR #8
ret
endfunc plat_my_core_pos
/* -----------------------------------------------------
* unsigned long plat_get_my_entrypoint (void);
*
* Main job of this routine is to distinguish between
* a cold and warm boot. If the tegra_sec_entry_point for
* this CPU is present, then it's a warm boot.
*
* -----------------------------------------------------
*/
func plat_get_my_entrypoint
adr x1, lotus_sec_entry_point
ldr x0, [x1]
ret
endfunc plat_get_my_entrypoint
/* -----------------------------------------------------
* void plat_secondary_cold_boot_setup (void);
*
* This function performs any platform specific actions
* needed for a secondary cpu after a cold reset. Right
* now this is a stub function.
* -----------------------------------------------------
*/
func plat_secondary_cold_boot_setup
mov x0, #0
ret
endfunc plat_secondary_cold_boot_setup
/* ---------------------------------------------
* int plat_crash_console_init(void)
* Function to initialize the crash console
* without a C Runtime to print crash report.
* Clobber list : x0 - x4
* ---------------------------------------------
*/
func plat_crash_console_init
mov_imm x0, PLAT_LOTUS_UART_BASE
mov_imm x1, PLAT_LOTUS_UART_CLOCK_IN_HZ
mov_imm x2, PLAT_LOTUS_UART_BAUDRATE
b console_pl011_core_init
endfunc plat_crash_console_init
/* ---------------------------------------------
* int plat_crash_console_putc(int c)
* Function to print a character on the crash
* console without a C Runtime.
* Clobber list : x1, x2
* ---------------------------------------------
*/
func plat_crash_console_putc
mov_imm x1, PLAT_LOTUS_UART_BASE
b console_pl011_core_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
* void plat_crash_console_flush()
* Function to force a write of all buffered
* data that hasn't been output.
* Out : void.
* Clobber list : r0
* ---------------------------------------------
*/
func plat_crash_console_flush
mov_imm x0, PLAT_LOTUS_UART_BASE
b console_pl011_core_flush
endfunc plat_crash_console_flush
/* --------------------------------------------------------
* void platform_mem_init (void);
*
* Any memory init, relocation to be done before the
* platform boots. Called very early in the boot process.
* --------------------------------------------------------
*/
func platform_mem_init
mov x0, #0
ret
endfunc platform_mem_init
/* ---------------------------------------------------
* Function to handle a platform reset and store
* input parameters passed by BL2.
* ---------------------------------------------------
*/
func plat_reset_handler
/* -----------------------------------
* derive and save the phys_base addr
* -----------------------------------
*/
#if 0
adr x17, lotus_bl31_phys_base
ldr x18, [x17]
cbnz x18, 1f
adr x18, bl31_entrypoint
str x18, [x17]
1: cpu_init_common
#endif
ret
endfunc plat_reset_handler
.data
.align 3
/* --------------------------------------------------
* CPU Secure entry point - resume from suspend
* --------------------------------------------------
*/
lotus_sec_entry_point:
.quad 0
/* --------------------------------------------------
* NS world's cold boot entry point
* --------------------------------------------------
*/
ns_image_entrypoint:
.quad 0
/* --------------------------------------------------
* BL31's physical base address
* --------------------------------------------------
*/
lotus_bl31_phys_base:
.quad 0
@@ -0,0 +1,57 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <arch_helpers.h>
#include <bl_common.h>
#include <debug.h>
#include <platform_def.h>
#include <xlat_tables_v2.h>
#include <mmio.h>
/* Table of regions to map using the MMU. */
const mmap_region_t plat_mmap[] = {
MAP_REGION_FLAT(DRAM_NS_BASE, DRAM_NS_SIZE,
MT_MEMORY | MT_RW | MT_NS),
MAP_REGION_FLAT(SRAM_BASE, SRAM_SIZE,
MT_NON_CACHEABLE | MT_RW | MT_EXECUTE | MT_SECURE),
MAP_REGION_FLAT(DEVICE_BASE, DEVICE_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
{ 0 }
};
/*******************************************************************************
* Macro generating the code for the function setting up the pagetables as per
* the platform memory map & initialize the mmu, for the given exception level
******************************************************************************/
#define DEFINE_CONFIGURE_MMU_EL(_el) \
void configure_mmu_el ## _el(unsigned long total_base, \
unsigned long total_size, \
unsigned long ro_start, \
unsigned long ro_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(plat_mmap); \
init_xlat_tables(); \
\
enable_mmu_el ## _el(0); \
}
/* Define EL3 variants of the function initialising the MMU */
DEFINE_CONFIGURE_MMU_EL(3)
unsigned int plat_get_syscnt_freq2(void)
{
INFO("Sys counter freq: %d\n", SYS_COUNTER_FREQ_IN_TICKS);
return SYS_COUNTER_FREQ_IN_TICKS;
}
@@ -0,0 +1,119 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <assert.h>
#include <bl_common.h>
#include <common_def.h>
#include <console.h>
#include <debug.h>
#include <generic_delay_timer.h>
#include <mmio.h>
#include <pl011.h>
#include <plat_private.h>
#include <platform.h>
#include <plat_lotus.h>
struct bl31_params {
param_header_t h;
image_info_t *bl31_image_info;
entry_point_info_t *bl32_ep_info;
image_info_t *bl32_image_info;
entry_point_info_t *bl33_ep_info;
image_info_t *bl33_image_info;
};
static entry_point_info_t bl33_image_ep_info, bl32_image_ep_info;
/*******************************************************************************
* This variable holds the non-secure image entry address
******************************************************************************/
extern uint64_t ns_image_entrypoint;
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for
* security state specified. BL33 corresponds to the non-secure image type
* while BL32 corresponds to the secure image type.
******************************************************************************/
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
{
entry_point_info_t *next_image_info;
assert(sec_state_is_valid(type));
next_image_info = (type == NON_SECURE)
? &bl33_image_ep_info : &bl32_image_ep_info;
/*
* None of the images on the ARM development platforms can have 0x0
* as the entrypoint
*/
if (next_image_info->pc)
return next_image_info;
else
return NULL;
}
/*******************************************************************************
* Perform any BL31 specific platform actions. Populate the BL33 and BL32 image
* info.
******************************************************************************/
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
struct bl31_params *from_bl2 = (struct bl31_params *)arg0;
uint32_t cpu_ver;
/*
* Configure the UART port to be used as the console
*/
lotus_console_boot_init();
cpu_ver = cpu_get_rev_var();
INFO("BL31 Early setup\n");
INFO("CPU Cortex-A55 r%dp%d\n", (cpu_ver >> 4) & 0xf, cpu_ver & 0xf);
/*
* Copy BL3-3, BL3-2 entry point information.
*/
bl33_image_ep_info = *from_bl2->bl33_ep_info;
bl32_image_ep_info = *from_bl2->bl32_ep_info;
SET_SECURITY_STATE(bl33_image_ep_info.h.attr,
NON_SECURE);
SET_SECURITY_STATE(bl32_image_ep_info.h.attr,
SECURE);
INFO("--%s %d\n", __func__, __LINE__);
}
/*******************************************************************************
* Initialize the gic, configure the SCR.
******************************************************************************/
void bl31_platform_setup(void)
{
INFO("BL31 Platform setup\n");
plat_lotus_pmc_init();
plat_lotus_gic_driver_init();
plat_lotus_gic_init();
plat_delay_timer_init();
INFO("--%s %d\n", __func__, __LINE__);
}
/*******************************************************************************
* Perform the very early platform specific architectural setup here. At the
* moment this only intializes the mmu in a quick and dirty way.
******************************************************************************/
void bl31_plat_arch_setup(void)
{
INFO("BL31 Arch setup\n");
configure_mmu_el3(BL31_START,
BL31_END - BL31_START,
BL_CODE_BASE,
BL_CODE_END);
INFO("--%s %d\n", __func__, __LINE__);
}
@@ -0,0 +1,135 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
#include <delay_timer.h>
#include <errno.h>
#include <mmio.h>
#include <platform_def.h>
#include <plat_private.h>
#include <platform.h>
#include <xmfalcon_def.h>
/* ARM64 REG */
#define REG_SYS_CTRL_BASE 0x12020000
#define REG_SYS_CPU_AARCH_MODE (REG_SYS_CTRL_BASE + 0x800C)
#define REG_SYS_RVBAR_ADDR0 (REG_SYS_CTRL_BASE + 0x8010)
#define REG_SYS_RVBAR_ADDR1 (REG_SYS_CTRL_BASE + 0x8014)
#define REG_PERI_CRG_BASE 0x12010000
#define REG_PERI_CRG30 (REG_PERI_CRG_BASE + 0x78)
#define REG_CPU_CORE_SRST REG_PERI_CRG30
#define REG_SYS_SOFT_RESET 0x12020008
#define REG_PWR_CTRL0 0x120f0010
#define START_STANDBY_MASK BIT(0)
#define START_POWERDOWN_MASK BIT(1)
#define writel(val, addr) mmio_write_32((uintptr_t)addr, (uint32_t)val)
#define readl(addr) mmio_read_32((uintptr_t)addr)
static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint)
{
uint32_t cpu, val, cpu_dbg_disable;
cpu = plat_core_pos_by_mpidr(mpidr);
if (cpu != 1) {
ERROR("Can not power on cpu other than cpu1\n");
return -1;
}
writel((uint32_t)((entrypoint >> 2) & 0xFFFFFFFF), REG_SYS_RVBAR_ADDR1);
writel(0, REG_SYS_RVBAR_ADDR0);
writel(readl(REG_SYS_CPU_AARCH_MODE) | (0x3 << 14), REG_SYS_CPU_AARCH_MODE);
val = readl(REG_MISC_CTRL129);
cpu_dbg_disable = val >> 1;
if (cpu_dbg_disable) {
val &= ~0x2;
writel(val, REG_MISC_CTRL129);
udelay(10);
}
val = readl(REG_CPU_CORE_SRST);
val &= ~((uint32_t)(0x1 << 1));
writel(val, REG_CPU_CORE_SRST);
if (cpu_dbg_disable) {
udelay(10);
writel(readl(REG_MISC_CTRL129) | 0x2, REG_MISC_CTRL129);
}
return 0;
}
static int cores_pwr_domain_on_finish(void)
{
return 0;
}
static int sys_pwr_domain_resume(void)
{
return 0;
}
static int sys_pwr_domain_suspend(void)
{
return 0;
}
static int sys_pwr_reset(void)
{
INFO("System: will restart.");
dsb();
isb();
writel(0xdeadbeef, REG_SYS_SOFT_RESET);
while(1) {
wfi();
ERROR("System wfi failed.\n");
}
return 0;
}
static void sys_pwr_standby(void)
{
writel(readl(REG_PWR_CTRL0) | START_STANDBY_MASK, REG_PWR_CTRL0);
mdelay(50);
ERROR("sys_pwr_standby failed\n");
panic();
}
static void sys_pwr_poweroff(void)
{
writel(readl(REG_PWR_CTRL0) | START_POWERDOWN_MASK, REG_PWR_CTRL0);
mdelay(50);
ERROR("sys_pwr_poweroff failed\n");
panic();
}
static struct lotus_pm_ops_cb pm_ops = {
.cores_pwr_dm_on = cores_pwr_domain_on,
.cores_pwr_dm_on_finish = cores_pwr_domain_on_finish,
.sys_pwr_dm_suspend = sys_pwr_domain_suspend,
.sys_pwr_dm_resume = sys_pwr_domain_resume,
.sys_gbl_soft_reset = sys_pwr_reset,
.sys_gbl_standby = sys_pwr_standby,
.sys_gbl_poweroff = sys_pwr_poweroff,
};
void plat_lotus_pmc_init(void)
{
plat_setup_lotus_pm_ops(&pm_ops);
}
@@ -0,0 +1,15 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <platform_def.h>
.section .rodata.gic_reg_name, "aS"
.macro plat_crash_print_regs
nop
.endm
@@ -0,0 +1,52 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __PLAT_PRIVATE_H__
#define __PLAT_PRIVATE_H__
/*******************************************************************************
* For socs pm ops
******************************************************************************/
struct lotus_pm_ops_cb {
int (*cores_pwr_dm_on)(unsigned long mpidr, uint64_t entrypoint);
int (*cores_pwr_dm_off)(void);
int (*cores_pwr_dm_on_finish)(void);
int (*cores_pwr_dm_suspend)(void);
int (*cores_pwr_dm_resume)(void);
int (*sys_pwr_dm_suspend)(void);
int (*sys_pwr_dm_resume)(void);
int (*sys_gbl_soft_reset)(void);
void (*sys_gbl_standby)(void);
void (*sys_gbl_poweroff)(void);
};
/*******************************************************************************
* Function and variable prototypes
******************************************************************************/
void configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
unsigned long,
unsigned long);
void plat_delay_timer_init(void);
void plat_lotus_gic_driver_init(void);
void plat_lotus_gic_init(void);
void plat_lotus_gic_cpuif_enable(void);
void plat_lotus_gic_cpuif_disable(void);
void plat_lotus_gic_pcpu_init(void);
void plat_lotus_pmc_init(void);
void plat_setup_lotus_pm_ops(struct lotus_pm_ops_cb *ops);
void lotus_suspend_save_param(void);
void lotus_cpu_suspend(void);
void lotus_sys_suspend(void);
void lotus_invalidate_icache(void);
extern unsigned int lotus_sys_suspend_size;
#endif /* __PLAT_PRIVATE_H__ */
@@ -0,0 +1,77 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __PLATFORM_DEF_H__
#define __PLATFORM_DEF_H__
#include <common_def.h>
#include <arch.h>
#include <xmfalcon_def.h>
#define DEBUG_XLAT_TABLE 0
/*******************************************************************************
* Platform binary types for linking
******************************************************************************/
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
/* Size of cacheable stacks */
#if DEBUG_XLAT_TABLE
#define PLATFORM_STACK_SIZE 0x800
#elif IMAGE_BL1
#define PLATFORM_STACK_SIZE 0x440
#elif IMAGE_BL2
#define PLATFORM_STACK_SIZE 0x400
#elif IMAGE_BL31
#define PLATFORM_STACK_SIZE 0x800
#elif IMAGE_BL32
#define PLATFORM_STACK_SIZE 0x440
#endif
/* Cache line size */
#define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
/* Power domain */
#define PLATFORM_CLUSTER_COUNT 1
#define PLATFORM_MAX_CPUS_PER_CLUSTER 2
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
PLATFORM_MAX_CPUS_PER_CLUSTER)
#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
PLATFORM_CLUSTER_COUNT + 1)
/* Power states */
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1
#define PLAT_MAX_OFF_STATE U(2)
#define PLAT_MAX_RET_STATE U(1)
/* BL31 specific defines. */
#define BL31_SIZE 0x32000
#define BL31_BASE 0x40008000
#define BL31_LIMIT (BL31_BASE + BL31_SIZE - 1)
/* Platform specific page table and MMU setup */
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#define MAX_XLAT_TABLES 6
#define MAX_MMAP_REGIONS 16
/* GICD and GICC and GICR base */
#define PLAT_LOTUS_GICD_BASE XMFALCON_GICD_BASE
#define PLAT_LOTUS_GICC_BASE XMFALCON_GICC_BASE
#define PLAT_LOTUS_UART_BASE XMFALCON_UART0_BASE
#define PLAT_LOTUS_UART_CLOCK XMFALCON_UART_CLK
#define PLAT_LOTUS_UART_CLOCK_IN_HZ XMFALCON_UART_CLK_IN_HZ
#define PLAT_LOTUS_UART_BAUDRATE XMFALCON_BAUDRATE
#define PLAT_LOTUS_PRIMARY_CPU 0x0
#endif /* __PLATFORM_DEF_H__ */
@@ -0,0 +1,67 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __XMFALCON_H__
#define __XMFALCON_H__
/* SRAM mem */
#define SRAM_BASE 0x04010000
#define SRAM_SIZE 0x10000
/* IO mem */
#define DEVICE_BASE 0x04020000
#define DEVICE_SIZE 0x10FE0000
/* DDR mem */
#define DRAM_NS_BASE 0x40000000
#define DRAM_NS_SIZE 0x80000000
/* UART */
#define XMFALCON_UART0_BASE (0x12040000)
#define XMFALCON_BAUDRATE (115200)
#define XMFALCON_UART_CLK (24000000)
#define XMFALCON_UART_CLK_IN_HZ (XMFALCON_UART_CLK / 1000000)
/* System counter */
#ifdef CONFIG_FPGA
#define SYS_COUNTER_FREQ_IN_TICKS 30000000
#else
#define SYS_COUNTER_FREQ_IN_TICKS 50000000
#endif
#define SYS_COUNTER_FREQ_IN_MHZ (SYS_COUNTER_FREQ_IN_TICKS / 1000000)
/* Timer */
#define TIMER0_REG_BASE 0x12000000
#define REG_TIMER_RELOAD 0x0
#define REG_TIMER_VALUE 0x4
#define REG_TIMER_CONTROL 0x8
#define LOTUS_TIMER_BASE TIMER0_REG_BASE
#define LOTUS_TIMER_VALUE (LOTUS_TIMER_BASE + REG_TIMER_VALUE)
#define LOTUS_TIMER_FREQ_IN_TICKS 24000000
#define LOTUS_TIMER_FREQ_IN_MHZ (LOTUS_TIMER_FREQ_IN_TICKS / 1000000)
/* GIC-400 */
#define XMFALCON_GICD_BASE (0x10401000)
#define XMFALCON_GICC_BASE (0x10402000)
/* Acpu suspend firmware load address */
#define LOTUS_PM_CODE_START SRAM_BASE
#define LOTUS_PM_CODE_SIZE SRAM_SIZE
#define STR_FLAG_ADDR 0x120f0048
#define STR_FLAG_VALUE 0xC3321142
#define DRAM_SIZE_ADDR 0x120200C0
#define PWR_CTRL0_ADDRESS 0x120f0010
#define PWM_CTRL0_STANDBY BIT(0)
#define PWM_CTRL0_POWERDOWN BIT(1)
#define REG_MISC_CTRL129 0x12029108
#endif /* __XMFALCON_H__ */
@@ -0,0 +1,27 @@
#include <asm_macros.S>
#include <cortex_a55.h>
.globl lotus_sys_suspend;
.extern lotus_pm_ddr_saving;
func lotus_sys_suspend
/*****set sp address:0x121203c0(the end of lpds) ******/
mov x0, #0x1212
lsl x0, x0, #16
add x0, x0, #0x03c0
mov sp, x0
/***** DDR CODE ******/
bl lotus_ddr_saving
/***** power down ****/
endfunc lotus_sys_suspend
.global lotus_ddr_saving
.balign 4
lotus_ddr_saving:
.incbin "./str_bit/str_bit.bin"
.balign 4
.globl lotus_sys_suspend_size;
lotus_sys_suspend_size:
.word . - lotus_sys_suspend
@@ -0,0 +1,39 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <arch_helpers.h>
#include <delay_timer.h>
#include <platform_def.h>
#include <lib/mmio.h>
#define USE_SYS_COUNTER 1
static uint32_t plat_get_timer_value(void)
{
#ifdef USE_SYS_COUNTER
/* Generic delay timer implementation expects the timer to be a down
* counter. We apply bitwise NOT operator to the tick values returned
* by read_cntpct_el0() to simulate the down counter. */
return (uint32_t)(~read_cntpct_el0());
#else
return (uint32_t)(~mmio_read_32(LOTUS_TIMER_VALUE));
#endif
}
static const timer_ops_t plat_timer_ops = {
.get_timer_value = plat_get_timer_value,
.clk_mult = 1,
#ifdef USE_SYS_COUNTER
.clk_div = SYS_COUNTER_FREQ_IN_MHZ,
#else
.clk_div = LOTUS_TIMER_FREQ_IN_MHZ,
#endif
};
void plat_delay_timer_init(void)
{
timer_init(&plat_timer_ops);
}
@@ -0,0 +1,258 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h>
#include <context.h>
#include <context_mgmt.h>
#include <debug.h>
#include <mmio.h>
#include <platform.h>
#include <plat_lotus.h>
#include <platform_def.h>
#include <psci.h>
#include <plat_private.h>
#include <xmfalcon_def.h>
#include <delay_timer.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
extern uintptr_t lotus_bl31_phys_base;
extern uintptr_t lotus_sec_entry_point;
static struct lotus_pm_ops_cb *lotus_ops;
/*******************************************************************************
* This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND`
* call to get the `power_state` parameter. This allows the platform to encode
* the appropriate State-ID field within the `power_state` parameter which can
* be utilized in `pwr_domain_suspend()` to suspend to system affinity level.
******************************************************************************/
void lotus_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
/* lower affinities use PLAT_MAX_OFF_STATE */
for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
}
/*******************************************************************************
* Handler called when an affinity instance is about to enter standby.
******************************************************************************/
void lotus_cpu_standby(plat_local_state_t cpu_state)
{
/*
* Enter standby state
* dsb is good practice before using wfi to enter low power states
*/
dsb();
wfi();
}
/*******************************************************************************
* Handler called when an affinity instance is about to be turned on. The
* level and mpidr determine the affinity instance.
******************************************************************************/
int lotus_pwr_domain_on(u_register_t mpidr)
{
if ((lotus_ops != NULL) && (lotus_ops->cores_pwr_dm_on != NULL))
lotus_ops->cores_pwr_dm_on(mpidr, lotus_sec_entry_point);
return PSCI_E_SUCCESS;
}
/*******************************************************************************
* Handler called when a power domain is about to be turned off. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
void lotus_pwr_domain_off(const psci_power_state_t *target_state)
{
}
/*******************************************************************************
* Handler called when called when a power domain is about to be suspended. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
void lotus_pwr_domain_suspend(const psci_power_state_t *target_state)
{
/* gic must save data */
plat_lotus_gic_save();
//lotus_console_runtime_end();
}
/*******************************************************************************
* Handler called when a power domain has just been powered on after
* being turned off earlier. The target_state encodes the low power state that
* each level has woken up from.
******************************************************************************/
void lotus_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
if ((lotus_ops != NULL) && (lotus_ops->cores_pwr_dm_on_finish != NULL))
lotus_ops->cores_pwr_dm_on_finish();
/* Enable the gic cpu interface */
plat_lotus_gic_pcpu_init();
/* Program the gic per-cpu distributor or re-distributor interface */
plat_lotus_gic_cpuif_enable();
}
/*******************************************************************************
* Handler called when a power domain has just been powered on after
* having been suspended earlier. The target_state encodes the low power state
* that each level has woken up from.
******************************************************************************/
void lotus_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
{
const plat_local_state_t *pwr_domain_state = target_state->pwr_domain_state;
unsigned int stateid_afflvl1 = pwr_domain_state[MPIDR_AFFLVL1];
/* system is going to powerdown */
if (stateid_afflvl1 == PLAT_MAX_OFF_STATE) {
//lotus_console_runtime_init();
/* gic must restore data */
plat_lotus_gic_restore();
}
}
/*******************************************************************************
* Handler called when the system wants to be powered off
******************************************************************************/
__dead2 void lotus_system_off(void)
{
if ((lotus_ops != NULL) && (lotus_ops->sys_gbl_poweroff != NULL))
lotus_ops->sys_gbl_poweroff();
ERROR("System Off: operation not handled.\n");
panic();
}
/*******************************************************************************
* Handler called when the system wants to be restarted.
******************************************************************************/
__dead2 void lotus_system_reset(void)
{
/* per-SoC system reset handler */
if ((lotus_ops != NULL) && (lotus_ops->sys_gbl_soft_reset != NULL))
lotus_ops->sys_gbl_soft_reset();
ERROR("System Off: operation not handled.\n");
panic();
}
/*******************************************************************************
* Handler called to check the validity of the power state parameter.
******************************************************************************/
int32_t lotus_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
int i;
if (req_state == NULL) {
panic();
}
if (pwr_lvl > PLAT_MAX_PWR_LVL)
return PSCI_E_INVALID_PARAMS;
for (i = 0; i <= pwr_lvl; i++)
req_state->pwr_domain_state[i] =
PLAT_MAX_OFF_STATE;
return PSCI_E_SUCCESS;
}
/*******************************************************************************
* Platform handler called to check the validity of the non secure entrypoint.
******************************************************************************/
int lotus_validate_ns_entrypoint(uintptr_t entrypoint)
{
/*
* Check if the non secure entrypoint lies within the non
* secure DRAM.
*/
return PSCI_E_SUCCESS;
}
/*******************************************************************************
* Platform handler called to enter wfi when pwr domain power down.
******************************************************************************/
__dead2 void lotus_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
{
unsigned int target_idx = plat_my_core_pos();
if (target_idx == 0) {
//set str flag
*(unsigned int *)STR_FLAG_ADDR = STR_FLAG_VALUE;
memset((void *)LOTUS_PM_CODE_START, 0, LOTUS_PM_CODE_SIZE);
memcpy((void *)LOTUS_PM_CODE_START, &lotus_sys_suspend, lotus_sys_suspend_size);
lotus_suspend_save_param();
lotus_invalidate_icache();
INFO("Power Down ");
//flush dcache all ddr range
flush_dcache_range((unsigned long)DRAM_NS_BASE, mmio_read_32((uintptr_t)DRAM_SIZE_ADDR));
lotus_cpu_suspend();
} else {
isb();
dsb();
wfi();
}
ERROR("Core %d Power-down not supported", target_idx);
panic();
}
/*******************************************************************************
* Export the platform handlers to enable psci to invoke them
******************************************************************************/
static const plat_psci_ops_t lotus_plat_psci_ops = {
.cpu_standby = lotus_cpu_standby,
.pwr_domain_on = lotus_pwr_domain_on,
.pwr_domain_off = lotus_pwr_domain_off,
.pwr_domain_suspend = lotus_pwr_domain_suspend,
.pwr_domain_on_finish = lotus_pwr_domain_on_finish,
.pwr_domain_suspend_finish = lotus_pwr_domain_suspend_finish,
.pwr_domain_pwr_down_wfi = lotus_pwr_domain_pwr_down_wfi,
.system_off = lotus_system_off,
.system_reset = lotus_system_reset,
.validate_power_state = lotus_validate_power_state,
.validate_ns_entrypoint = lotus_validate_ns_entrypoint,
.get_sys_suspend_power_state = lotus_get_sys_suspend_power_state,
};
/*******************************************************************************
* Export the platform specific power ops and initialize Power Controller
******************************************************************************/
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
/*
* Flush entrypoint variable to PoC since it will be
* accessed after a reset with the caches turned off.
*/
lotus_sec_entry_point = sec_entrypoint;
flush_dcache_range((uintptr_t)&lotus_sec_entry_point, sizeof(uintptr_t));
/*
* Initialize PSCI ops struct
*/
*psci_ops = &lotus_plat_psci_ops;
return 0;
}
void plat_setup_lotus_pm_ops(struct lotus_pm_ops_cb *ops)
{
lotus_ops = ops;
}
@@ -0,0 +1,66 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <arch.h>
#include <platform_def.h>
#include <psci.h>
#include <stdio.h>
#include <debug.h>
const unsigned char lotus_power_domain_tree_desc[] = {
/* No of root nodes */
PLATFORM_CLUSTER_COUNT,
/* No of clusters */
/* PLATFORM_CLUSTER_COUNT, */
/* No of CPU cores */
PLATFORM_CORE_COUNT,
};
/*******************************************************************************
* This function returns the Tegra default topology tree information.
******************************************************************************/
const unsigned char *plat_get_power_domain_tree_desc(void)
{
return lotus_power_domain_tree_desc;
}
/*******************************************************************************
* This function implements a part of the critical interface between the psci
* generic layer and the platform that allows the former to query the platform
* to convert an MPIDR to a unique linear index. An error code (-1) is returned
* in case the MPIDR is invalid.
******************************************************************************/
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
unsigned int cluster_id, cpu_id;
INFO("mpidr=0x%lx\n", mpidr);
mpidr &= MPIDR_AFFINITY_MASK;
if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
return -1;
return mpidr & MPIDR_CPU_MASK;
cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
cpu_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
INFO("cluster_id=%d, cpu_id=%d\n", cluster_id, cpu_id);
if (cluster_id >= PLATFORM_CLUSTER_COUNT)
return -1;
/*
* Validate cpu_id by checking whether it represents a CPU in
* one of the two clusters present on the platform.
*/
if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
return -1;
return (cpu_id + (cluster_id * PLATFORM_MAX_CPUS_PER_CLUSTER));
}
@@ -0,0 +1,82 @@
#
# Copyright (c) Lotus. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
LOTUS_PLAT := plat/lotus
LOTUS_PLAT_SOC := ${LOTUS_PLAT}/${PLAT}
PLAT_INCLUDES := -I${LOTUS_PLAT}/ \
-I${LOTUS_PLAT}/include/ \
-Iinclude/plat/common/ \
-Iinclude/common/ \
-Iinclude/drivers/ \
-Iinclude/drivers/arm/ \
-Iinclude/lib/xlat_tables/ \
-Iinclude/lib/ \
-Iinclude/lib/el3_runtime/ \
-Iinclude/lib/psci/ \
-I${LOTUS_PLAT_SOC}/ \
-I${LOTUS_PLAT_SOC}/include/
# Include GICv2 driver files
# include drivers/arm/gic/v2/gicv2.mk
LOTUS_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 \
${LOTUS_PLAT}/common/lotus_gicv2.c
PLAT_BL_COMMON_SOURCES := lib/xlat_tables_v2/xlat_tables_context.c \
lib/xlat_tables_v2/xlat_tables_utils.c \
lib/xlat_tables_v2/xlat_tables_core.c \
lib/xlat_tables_v2/aarch64/enable_mmu.S \
lib/xlat_tables_v2/aarch64/xlat_tables_arch.c \
plat/common/plat_psci_common.c
BL31_SOURCES += $(LOTUS_GIC_SOURCES) \
drivers/arm/pl011/aarch64/pl011_console.S \
drivers/delay_timer/delay_timer.c \
lib/cpus/aarch64/aem_generic.S \
lib/cpus/aarch64/cortex_a55.S \
plat/common/aarch64/platform_mp_stack.S \
${LOTUS_PLAT}/common/lotus_bl31_setup.c \
${LOTUS_PLAT}/common/lotus_console.c \
${LOTUS_PLAT_SOC}/aarch64/plat_helpers.S \
${LOTUS_PLAT_SOC}/aarch64/platform_common.c \
${LOTUS_PLAT_SOC}/plat_topology.c \
${LOTUS_PLAT_SOC}/drivers/pmc/pmc.c \
${LOTUS_PLAT_SOC}/bl31_plat_setup.c \
${LOTUS_PLAT_SOC}/plat_pm.c \
${LOTUS_PLAT_SOC}/plat_delay_timer.c \
${LOTUS_PLAT_SOC}/resume_entry_32bit.S \
${LOTUS_PLAT_SOC}/sleep.S \
${LOTUS_PLAT_SOC}/lotus_suspend.S
HW_ASSISTED_COHERENCY := 1
USE_COHERENT_MEM := 0
ENABLE_PLAT_COMPAT := 0
CTX_INCLUDE_FPREGS := 1
NEED_BL33 := yes
MULTI_CONSOLE_API := 1
PROGRAMMABLE_RESET_ADDRESS := 1
CONFIG_XMFALCON := 1
ERRATA_ABI_SUPPORT := 1
CORTEX_A55_H_INC := 1
ERRATA_A55_1530923 := 1
# Do not enable SVE
ENABLE_SVE_FOR_NS := 0
#CONFIG_FPGA := 0
CONFIG_LOTUS := 1
$(eval $(call add_define,CONFIG_LOTUS))
$(eval $(call add_define,CONFIG_BL31_BASE))
#$(eval $(call add_define,CONFIG_FPGA))
$(eval $(call add_define,CONFIG_XMFALCON))
ifeq (${SPD},opteed)
$(eval $(call add_define,CONFIG_LOTUS_OPTEED))
endif
@@ -0,0 +1,7 @@
.balign 4
.global resume_entry_start_32
resume_entry_start_32:
.incbin "./resume_entry_32bit/resume_entry_32bit.bin"
.global resume_entry_end_32
resume_entry_end_32:
@@ -0,0 +1,67 @@
#===============================================================================
# export variables
#===============================================================================
TARGET := resume_entry_32bit
LOAD_ADDR = 0x0
#
# Include the make variables (CC, etc...)
#
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
LDR = $(CROSS_COMPILE)ldr
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB = $(CROSS_COMPILE)RANLIB
PHONY: help
GREEN="\e[32;1m"
NORMAL="\e[39m"
RED="\e[31m"
LDSCRIPT := linker.lds
LDFLAGS := -Bstatic -T $(LDSCRIPT) -Ttext $(LOAD_ADDR)
CFLAGS += -march=armv7-a -Wall -g -c -fPIC -nostdinc -fno-builtin
SFLAGS := $(CFLAGS)
CSRC = ${wildcard *.c lib/*.c}
ASRC = $(wildcard *.S lib/*.S)
COBJS := $(patsubst %.c, %.o, $(CSRC))
AOBJS += $(patsubst %.S, %.o, $(ASRC))
COBJS:=$(COBJS:%.C=%.o)
AOBJS:=$(AOBJS:%.S=%.o)
all: $(AOBJS) $(COBJS)
$(LD) $^ $(LDFLAGS) -Map $(TARGET).map -o $(TARGET).elf
$(OBJCOPY) -O binary $(TARGET).elf $(TARGET).bin
$(OBJDUMP) $(TARGET).elf -S -D >$(TARGET).dump
help:
@echo -e ${GREEN}
@echo "make CROSS_COMPILE=arm-gcc12.2.0-linux- all -- Build the bin, Use 32bit compiler"
@echo "make CROSS_COMPILE=arm-gcc12.2.0-linux- clean -- Clean all"
@echo -e ${NORMAL}
%.o: %.S
$(CC) $(SFLAGS) -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -o $@ $<
.PHONY : clean
clean:
-rm -rf $(COBJS) $(AOBJS) $(TARGET).elf $(TARGET).bin $(TARGET).map $(LIBS)
@@ -0,0 +1,28 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(main)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
start.o
*(.text)
}
. = ALIGN(4);
.rodata :
{
*(.rodata)
}
. = ALIGN(4);
.data :
{
*(.data)
}
}
@@ -0,0 +1,34 @@
.balign 4
#define ADDR_CEP64 (0x12120054)
.globl atf_32bit_resume
atf_32bit_resume:
/* Load 64bit resume address from TEE_GEN4 which is store in aux code */
ldr r3, =ADDR_CEP64
ldr r2, [r3]
lsr r2, r2, #2
/* Set 64bit resume address to PERI_CPU_RVBARADDR */
mov r3, #0x8000
movt r3, #0x1202
str r2, [r3, #0x10]
mov r2, #0
str r2, [r3, #0x14]
/* Set all cpus booting-up in 64bit mode */
ldr r2, [r3, #0x0c]
orr r2, r2, #0xc0
str r2, [r3, #0x0c]
/* Warm reset */
isb
dsb
mrc 15, 0, r3, cr12, cr0, 2
orr r3, r3, #0x3
mcr 15, 0, r3, cr12, cr0, 2
isb
1: wfi
b 1b
@@ -0,0 +1,56 @@
#include <asm_macros.S>
#include <cortex_a55.h>
#include <xmfalcon_def.h>
.global lotus_cpu_suspend
.global lotus_suspend_save_param
.global a55_core_pwr_dwn
.globl lotus_invalidate_icache
func a55_core_pwr_dwn
/* ---------------------------------------------
* Enable CPU power down bit in power control register
* ---------------------------------------------
*/
mrs x0, CORTEX_A55_CPUPWRCTLR_EL1
orr x0, x0, #CORTEX_A55_CORE_PWRDN_EN_MASK
msr CORTEX_A55_CPUPWRCTLR_EL1, x0
isb
dsb sy
loop_wfi:
dsb sy
isb
wfi
b loop_wfi
endfunc a55_core_pwr_dwn
func lotus_invalidate_icache
ic iallu
ret
endfunc lotus_invalidate_icache
func lotus_suspend_save_param
/* set scu boot entry point */
ldr w0, =resume_entry_start_32
ldr x1, =0x12120050
str w0, [x1]
/* set 64bit entry point */
ldr w0, =bl31_warm_entrypoint
ldr x1, =0x12120054
str w0, [x1]
ret
endfunc lotus_suspend_save_param
func lotus_cpu_suspend
/* disable mmu_el3. */
bl disable_mmu_el3
ldr x2, =LOTUS_PM_CODE_START
br x2
ret
endfunc lotus_cpu_suspend
@@ -0,0 +1,67 @@
#===============================================================================
# export variables
#===============================================================================
TARGET := str_bit
LOAD_ADDR = 0x0
#
# Include the make variables (CC, etc...)
#
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
LDR = $(CROSS_COMPILE)ldr
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB = $(CROSS_COMPILE)RANLIB
PHONY: help
GREEN="\e[32;1m"
NORMAL="\e[39m"
RED="\e[31m"
LDSCRIPT := linker.lds
LDFLAGS := -Bstatic -T $(LDSCRIPT) -Ttext $(LOAD_ADDR)
CFLAGS += -march=armv8-a -Wall -g -c -fPIC -nostdinc -fno-builtin
SFLAGS := $(CFLAGS)
CSRC = ${wildcard *.c lib/*.c}
ASRC = $(wildcard *.S lib/*.S)
COBJS := $(patsubst %.c, %.o, $(CSRC))
AOBJS += $(patsubst %.S, %.o, $(ASRC))
COBJS:=$(COBJS:%.C=%.o)
AOBJS:=$(AOBJS:%.S=%.o)
all: $(AOBJS) $(COBJS)
$(LD) $^ $(LDFLAGS) -Map $(TARGET).map -o $(TARGET).elf
$(OBJCOPY) -O binary $(TARGET).elf $(TARGET).bin
$(OBJDUMP) $(TARGET).elf -S -D >$(TARGET).dump
help:
@echo -e ${GREEN}
@echo "make CROSS_COMPILE=aarch64-gcc12.2.0-linux- all -- Build the bin, Use 64bit compiler"
@echo "make CROSS_COMPILE=aarch64-gcc12.2.0-linux- clean -- Clean all"
@echo -e ${NORMAL}
%.o: %.S
$(CC) $(SFLAGS) -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -o $@ $<
.PHONY : clean
clean:
-rm -rf $(COBJS) $(AOBJS) $(TARGET).elf $(TARGET).bin $(TARGET).map $(LIBS) $(TARGET).dump
@@ -0,0 +1,42 @@
.global str_delay_us
str_delay_us:
loop1:
b delay_1us
sub x0, x0, #1
cmp w0, #0x0
b.ne loop1 // b.any
ret
delay_1us:
mov x3, #0x1000000
loop2:
nop
sub x3, x3, #1
cmp x3, #0x0
b.ne loop2
ret
#ifdef CRC_CHECK
.global crc16_asm
crc16_asm:
.word 0xd2800004
.word 0x529fffe3
.word 0x6b04003f
.word 0x54000068
.word 0x2a2303e0
.word 0xd65f03c0
.word 0x38646802
.word 0x91000484
.word 0x4a020062
.word 0x12001c45
.word 0x531c0c42
.word 0x4a050042
.word 0x531d7045
.word 0x4a0220a5
.word 0x4a4210a2
.word 0x4a432043
.word 0x17fffff2
#endif
@@ -0,0 +1,30 @@
OUTPUT_FORMAT("elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
ENTRY(lotus_pm_ddr_saving)
SECTIONS
{
. = 0x00000000;
. = ALIGN(8);
.text :
{
str.o
delay.o
*(.text)
}
. = ALIGN(8);
.rodata :
{
*(.rodata)
}
. = ALIGN(8);
.data :
{
*(.data)
}
}
@@ -0,0 +1,260 @@
/*
* Copyright (c) Lotus. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
//#define CRC_CHECK
extern void str_delay_us(int us);
#ifdef CRC_CHECK
extern unsigned short crc16_asm(unsigned char *data, unsigned int length);
#endif
void lotus_pm_ddr_saving(void)
{
unsigned int ddr_type;
ddr_type = *(volatile unsigned int *)(0x120d0000);
ddr_type &= 0x7;
*(volatile unsigned int *)(0x12040000) = 'e';
#ifdef CRC_CHECK
*(volatile unsigned int *)(0x12120350) = crc16_asm((unsigned char *)0x40000000,0x10000000);
#endif
__asm__ volatile("dsb sy");
__asm__ volatile("isb");
while(*(volatile unsigned int *)(0x120d2900) != 0x1);
// enter ddr selfflush channel0
*(volatile unsigned int *)(0x120d315c) = 0x7200a0;
*(volatile unsigned int *)(0x120d313c) = 0x1000005;
*(volatile unsigned int *)(0x120d3138) = 0x1;
*(volatile unsigned int *)(0x120d3138) = 0x0;
if (ddr_type == 3) { //LPDDR4
// enter ddr selfflush channel1
*(volatile unsigned int *)(0x120d415c) = 0x7200a0;
*(volatile unsigned int *)(0x120d413c) = 0x1000005;
*(volatile unsigned int *)(0x120d4138) = 0x1;
*(volatile unsigned int *)(0x120d4138) = 0x0;
}
str_delay_us(1);
//read ddr training result to lpds
*(volatile unsigned int *)(0x12120080) = *(volatile unsigned int *)(0x12103104);
*(volatile unsigned int *)(0x12120084) = *(volatile unsigned int *)(0x12103120);
*(volatile unsigned int *)(0x12120088) = *(volatile unsigned int *)(0x12103124);
*(volatile unsigned int *)(0x1212008c) = *(volatile unsigned int *)(0x12103128);
*(volatile unsigned int *)(0x12120090) = *(volatile unsigned int *)(0x1210312c);
*(volatile unsigned int *)(0x12120094) = *(volatile unsigned int *)(0x12103130);
*(volatile unsigned int *)(0x12120098) = *(volatile unsigned int *)(0x12103134);
*(volatile unsigned int *)(0x1212009c) = *(volatile unsigned int *)(0x12103138);
*(volatile unsigned int *)(0x121200a0) = *(volatile unsigned int *)(0x1210313c);
*(volatile unsigned int *)(0x121200a4) = *(volatile unsigned int *)(0x12103110);
*(volatile unsigned int *)(0x121200a8) = *(volatile unsigned int *)(0x12103100);
*(volatile unsigned int *)(0x121200ac) = *(volatile unsigned int *)(0x12104108);
*(volatile unsigned int *)(0x121200b0) = *(volatile unsigned int *)(0x12104130);
*(volatile unsigned int *)(0x121200b4) = *(volatile unsigned int *)(0x12104134);
*(volatile unsigned int *)(0x121200b8) = *(volatile unsigned int *)(0x12104138);
*(volatile unsigned int *)(0x121200bc) = *(volatile unsigned int *)(0x1210413c);
*(volatile unsigned int *)(0x121200c0) = *(volatile unsigned int *)(0x12104140);
*(volatile unsigned int *)(0x121200c4) = *(volatile unsigned int *)(0x12105108);
*(volatile unsigned int *)(0x121200c8) = *(volatile unsigned int *)(0x12105130);
*(volatile unsigned int *)(0x121200cc) = *(volatile unsigned int *)(0x12105134);
*(volatile unsigned int *)(0x121200d0) = *(volatile unsigned int *)(0x12105138);
*(volatile unsigned int *)(0x121200d4) = *(volatile unsigned int *)(0x1210513c);
*(volatile unsigned int *)(0x121200d8) = *(volatile unsigned int *)(0x12105140);
*(volatile unsigned int *)(0x121200dc) = *(volatile unsigned int *)(0x12106108);
*(volatile unsigned int *)(0x121200e0) = *(volatile unsigned int *)(0x12106130);
*(volatile unsigned int *)(0x121200e4) = *(volatile unsigned int *)(0x12106134);
*(volatile unsigned int *)(0x121200e8) = *(volatile unsigned int *)(0x12106138);
*(volatile unsigned int *)(0x121200ec) = *(volatile unsigned int *)(0x1210613c);
*(volatile unsigned int *)(0x121200f0) = *(volatile unsigned int *)(0x12106140);
*(volatile unsigned int *)(0x121200f4) = *(volatile unsigned int *)(0x12107108);
*(volatile unsigned int *)(0x121200f8) = *(volatile unsigned int *)(0x12107130);
*(volatile unsigned int *)(0x121200fc) = *(volatile unsigned int *)(0x12107134);
*(volatile unsigned int *)(0x12120100) = *(volatile unsigned int *)(0x12107138);
*(volatile unsigned int *)(0x12120104) = *(volatile unsigned int *)(0x1210713c);
*(volatile unsigned int *)(0x12120108) = *(volatile unsigned int *)(0x12107140);
*(volatile unsigned int *)(0x1212010c) = *(volatile unsigned int *)(0x12104100);
*(volatile unsigned int *)(0x12120110) = *(volatile unsigned int *)(0x12104110);
*(volatile unsigned int *)(0x12120114) = *(volatile unsigned int *)(0x12104114);
*(volatile unsigned int *)(0x12120118) = *(volatile unsigned int *)(0x12104118);
*(volatile unsigned int *)(0x1212011c) = *(volatile unsigned int *)(0x1210411c);
*(volatile unsigned int *)(0x12120120) = *(volatile unsigned int *)(0x12104120);
*(volatile unsigned int *)(0x12120124) = *(volatile unsigned int *)(0x12105100);
*(volatile unsigned int *)(0x12120128) = *(volatile unsigned int *)(0x12105110);
*(volatile unsigned int *)(0x1212012c) = *(volatile unsigned int *)(0x12105114);
*(volatile unsigned int *)(0x12120130) = *(volatile unsigned int *)(0x12105118);
*(volatile unsigned int *)(0x12120134) = *(volatile unsigned int *)(0x1210511c);
*(volatile unsigned int *)(0x12120138) = *(volatile unsigned int *)(0x12105120);
*(volatile unsigned int *)(0x1212013c) = *(volatile unsigned int *)(0x12106100);
*(volatile unsigned int *)(0x12120140) = *(volatile unsigned int *)(0x12106110);
*(volatile unsigned int *)(0x12120144) = *(volatile unsigned int *)(0x12106114);
*(volatile unsigned int *)(0x12120148) = *(volatile unsigned int *)(0x12106118);
*(volatile unsigned int *)(0x1212014c) = *(volatile unsigned int *)(0x1210611c);
*(volatile unsigned int *)(0x12120150) = *(volatile unsigned int *)(0x12106120);
*(volatile unsigned int *)(0x12120154) = *(volatile unsigned int *)(0x12107100);
*(volatile unsigned int *)(0x12120158) = *(volatile unsigned int *)(0x12107110);
*(volatile unsigned int *)(0x1212015c) = *(volatile unsigned int *)(0x12107114);
*(volatile unsigned int *)(0x12120160) = *(volatile unsigned int *)(0x12107118);
*(volatile unsigned int *)(0x12120164) = *(volatile unsigned int *)(0x1210711c);
*(volatile unsigned int *)(0x12120168) = *(volatile unsigned int *)(0x12107120);
*(volatile unsigned int *)(0x1212016c) = *(volatile unsigned int *)(0x12101204);
*(volatile unsigned int *)(0x12120170) = *(volatile unsigned int *)(0x1210410c);
*(volatile unsigned int *)(0x12120174) = *(volatile unsigned int *)(0x1210510c);
*(volatile unsigned int *)(0x12120178) = *(volatile unsigned int *)(0x1210610c);
*(volatile unsigned int *)(0x1212017c) = *(volatile unsigned int *)(0x1210710c);
*(volatile unsigned int *)(0x12120180) = *(volatile unsigned int *)(0x12103200);
*(volatile unsigned int *)(0x12120184) = *(volatile unsigned int *)(0x12104160);
*(volatile unsigned int *)(0x12120188) = *(volatile unsigned int *)(0x12105160);
*(volatile unsigned int *)(0x1212018c) = *(volatile unsigned int *)(0x12106160);
*(volatile unsigned int *)(0x12120190) = *(volatile unsigned int *)(0x12107160);
//ZQCAL
*(volatile unsigned int *)(0x12120194) = *(volatile unsigned int *)(0x12100010);
//PHYCTRL
*(volatile unsigned int *)(0x12120198) = *(volatile unsigned int *)(0x12101004);
*(volatile unsigned int *)(0x1212019C) = *(volatile unsigned int *)(0x1210101c);
*(volatile unsigned int *)(0x121201a0) = *(volatile unsigned int *)(0x12101200);
//DFICLK_CACTRL
*(volatile unsigned int *)(0x121201a4) = *(volatile unsigned int *)(0x12103108);
*(volatile unsigned int *)(0x121201a8) = *(volatile unsigned int *)(0x12103114);
*(volatile unsigned int *)(0x121201ac) = *(volatile unsigned int *)(0x12103118);
*(volatile unsigned int *)(0x121201b0) = *(volatile unsigned int *)(0x12103140);
*(volatile unsigned int *)(0x121201b4) = *(volatile unsigned int *)(0x12103144);
*(volatile unsigned int *)(0x121201b8) = *(volatile unsigned int *)(0x12103148);
*(volatile unsigned int *)(0x121201bc) = *(volatile unsigned int *)(0x12103200);
*(volatile unsigned int *)(0x121201c0) = *(volatile unsigned int *)(0x12103204);
*(volatile unsigned int *)(0x121201c4) = *(volatile unsigned int *)(0x12103208);
*(volatile unsigned int *)(0x121201c8) = *(volatile unsigned int *)(0x1210320C);
*(volatile unsigned int *)(0x121201cc) = *(volatile unsigned int *)(0x12103298);
*(volatile unsigned int *)(0x121201d0) = *(volatile unsigned int *)(0x1210329C);
*(volatile unsigned int *)(0x121201d4) = *(volatile unsigned int *)(0x121032A0);
*(volatile unsigned int *)(0x121201d8) = *(volatile unsigned int *)(0x121032A4);
*(volatile unsigned int *)(0x121201dc) = *(volatile unsigned int *)(0x121032A8);
*(volatile unsigned int *)(0x121201e0) = *(volatile unsigned int *)(0x121032AC);
//DFICLK_DQCTRL
*(volatile unsigned int *)(0x121201e4) = *(volatile unsigned int *)(0x12104000);
*(volatile unsigned int *)(0x121201e8) = *(volatile unsigned int *)(0x12104004);
*(volatile unsigned int *)(0x121201ec) = *(volatile unsigned int *)(0x12104124);
*(volatile unsigned int *)(0x121201f0) = *(volatile unsigned int *)(0x12104128);
*(volatile unsigned int *)(0x121201f4) = *(volatile unsigned int *)(0x1210414c);
*(volatile unsigned int *)(0x121201f8) = *(volatile unsigned int *)(0x12104150);
*(volatile unsigned int *)(0x121201fc) = *(volatile unsigned int *)(0x12104158);
*(volatile unsigned int *)(0x12120200) = *(volatile unsigned int *)(0x1210415c);
*(volatile unsigned int *)(0x12120204) = *(volatile unsigned int *)(0x12104160);
*(volatile unsigned int *)(0x12120208) = *(volatile unsigned int *)(0x12104164);
*(volatile unsigned int *)(0x1212020c) = *(volatile unsigned int *)(0x12104168);
*(volatile unsigned int *)(0x12120210) = *(volatile unsigned int *)(0x1210416c);
*(volatile unsigned int *)(0x12120214) = *(volatile unsigned int *)(0x12105000);
*(volatile unsigned int *)(0x12120218) = *(volatile unsigned int *)(0x12105004);
*(volatile unsigned int *)(0x1212021c) = *(volatile unsigned int *)(0x12105124);
*(volatile unsigned int *)(0x12120220) = *(volatile unsigned int *)(0x12105128);
*(volatile unsigned int *)(0x12120224) = *(volatile unsigned int *)(0x1210514c);
*(volatile unsigned int *)(0x12120228) = *(volatile unsigned int *)(0x12105150);
*(volatile unsigned int *)(0x1212022c) = *(volatile unsigned int *)(0x12105158);
*(volatile unsigned int *)(0x12120230) = *(volatile unsigned int *)(0x1210515c);
*(volatile unsigned int *)(0x12120234) = *(volatile unsigned int *)(0x12105160);
*(volatile unsigned int *)(0x12120238) = *(volatile unsigned int *)(0x12105164);
*(volatile unsigned int *)(0x1212023c) = *(volatile unsigned int *)(0x12105168);
*(volatile unsigned int *)(0x12120240) = *(volatile unsigned int *)(0x1210516c);
*(volatile unsigned int *)(0x12120244) = *(volatile unsigned int *)(0x12106000);
*(volatile unsigned int *)(0x12120248) = *(volatile unsigned int *)(0x12106004);
*(volatile unsigned int *)(0x1212024c) = *(volatile unsigned int *)(0x12106124);
*(volatile unsigned int *)(0x12120250) = *(volatile unsigned int *)(0x12106128);
*(volatile unsigned int *)(0x12120254) = *(volatile unsigned int *)(0x1210614c);
*(volatile unsigned int *)(0x12120258) = *(volatile unsigned int *)(0x12106150);
*(volatile unsigned int *)(0x1212025c) = *(volatile unsigned int *)(0x12106158);
*(volatile unsigned int *)(0x12120260) = *(volatile unsigned int *)(0x1210615c);
*(volatile unsigned int *)(0x12120264) = *(volatile unsigned int *)(0x12106160);
*(volatile unsigned int *)(0x12120268) = *(volatile unsigned int *)(0x12106164);
*(volatile unsigned int *)(0x1212026c) = *(volatile unsigned int *)(0x12106168);
*(volatile unsigned int *)(0x12120270) = *(volatile unsigned int *)(0x1210616c);
*(volatile unsigned int *)(0x12120274) = *(volatile unsigned int *)(0x12107000);
*(volatile unsigned int *)(0x12120278) = *(volatile unsigned int *)(0x12107004);
*(volatile unsigned int *)(0x1212027c) = *(volatile unsigned int *)(0x12107124);
*(volatile unsigned int *)(0x12120280) = *(volatile unsigned int *)(0x12107128);
*(volatile unsigned int *)(0x12120284) = *(volatile unsigned int *)(0x1210714c);
*(volatile unsigned int *)(0x12120288) = *(volatile unsigned int *)(0x12107150);
*(volatile unsigned int *)(0x1212028c) = *(volatile unsigned int *)(0x12107158);
*(volatile unsigned int *)(0x12120290) = *(volatile unsigned int *)(0x1210715c);
*(volatile unsigned int *)(0x12120294) = *(volatile unsigned int *)(0x12107160);
*(volatile unsigned int *)(0x12120298) = *(volatile unsigned int *)(0x12107164);
*(volatile unsigned int *)(0x1212029c) = *(volatile unsigned int *)(0x12107168);
*(volatile unsigned int *)(0x121202a0) = *(volatile unsigned int *)(0x1210716c);
*(volatile unsigned int *)(0x121202a4) = *(volatile unsigned int *)(0x12101220);
*(volatile unsigned int *)(0x121202a8) = *(volatile unsigned int *)(0x12101224);
*(volatile unsigned int *)(0x121202ac) = *(volatile unsigned int *)(0x12101228);
*(volatile unsigned int *)(0x121202b0) = *(volatile unsigned int *)(0x1210122C);
*(volatile unsigned int *)(0x121202b4) = *(volatile unsigned int *)(0x12101230);
*(volatile unsigned int *)(0x121202b8) = *(volatile unsigned int *)(0x12101234);
*(volatile unsigned int *)(0x121202bc) = *(volatile unsigned int *)(0x12101238);
*(volatile unsigned int *)(0x121202c0) = *(volatile unsigned int *)(0x1210123C);
*(volatile unsigned int *)(0x121202c4) = *(volatile unsigned int *)(0x12101248);
*(volatile unsigned int *)(0x121202c8) = *(volatile unsigned int *)(0x1210124C);
*(volatile unsigned int *)(0x121202cc) = *(volatile unsigned int *)(0x12101250);
*(volatile unsigned int *)(0x121202d0) = *(volatile unsigned int *)(0x12101254);
*(volatile unsigned int *)(0x121202d4) = *(volatile unsigned int *)(0x12101258);
*(volatile unsigned int *)(0x121202d8) = *(volatile unsigned int *)(0x12102220);
*(volatile unsigned int *)(0x121202dc) = *(volatile unsigned int *)(0x12102224);
*(volatile unsigned int *)(0x121202e0) = *(volatile unsigned int *)(0x12102228);
*(volatile unsigned int *)(0x121202e4) = *(volatile unsigned int *)(0x1210222C);
*(volatile unsigned int *)(0x121202e8) = *(volatile unsigned int *)(0x12102230);
*(volatile unsigned int *)(0x121202ec) = *(volatile unsigned int *)(0x12102234);
*(volatile unsigned int *)(0x121202f0) = *(volatile unsigned int *)(0x12102238);
*(volatile unsigned int *)(0x121202f4) = *(volatile unsigned int *)(0x1210223C);
*(volatile unsigned int *)(0x121202f8) = *(volatile unsigned int *)(0x12102248);
*(volatile unsigned int *)(0x121202fc) = *(volatile unsigned int *)(0x1210224C);
*(volatile unsigned int *)(0x12120300) = *(volatile unsigned int *)(0x12102250);
*(volatile unsigned int *)(0x12120304) = *(volatile unsigned int *)(0x12102254);
*(volatile unsigned int *)(0x12120308) = *(volatile unsigned int *)(0x12102258);
if (ddr_type == 3) { //LPDDR4
*(volatile unsigned int *)(0x12101020) = 0x50000; //swicth to channel1
*(volatile unsigned int *)(0x1212030c) = *(volatile unsigned int *)(0x12103104);
*(volatile unsigned int *)(0x12120310) = *(volatile unsigned int *)(0x12103120);
*(volatile unsigned int *)(0x12120314) = *(volatile unsigned int *)(0x12103124);
*(volatile unsigned int *)(0x12120318) = *(volatile unsigned int *)(0x12103128);
*(volatile unsigned int *)(0x1212031c) = *(volatile unsigned int *)(0x1210312c);
*(volatile unsigned int *)(0x12120320) = *(volatile unsigned int *)(0x12103130);
*(volatile unsigned int *)(0x12120324) = *(volatile unsigned int *)(0x12103134);
*(volatile unsigned int *)(0x12120328) = *(volatile unsigned int *)(0x12103138);
*(volatile unsigned int *)(0x1212032c) = *(volatile unsigned int *)(0x1210313c);
*(volatile unsigned int *)(0x12120330) = *(volatile unsigned int *)(0x12103110);
*(volatile unsigned int *)(0x12120334) = *(volatile unsigned int *)(0x12103100);
*(volatile unsigned int *)(0x12101020) = 0x0; //switch back to channel0
}
//DDR SIZE register
*(volatile unsigned int *)(0x12120338) = *(volatile unsigned int *)(0x120200c0);
*(volatile unsigned int *)(0x12040000) = 'n';
// enable io_retention_en
*(volatile unsigned int *)(0x120f0008) = 0x10;
str_delay_us(50);
__asm__ volatile("dsb sy");
__asm__ volatile("isb");
//entry standby
*(volatile unsigned int *)(0x120f0010) = (*(volatile unsigned int *)(0x120f0010)) | 0x1; //bit0 start_standby;bit1 start_powerdown
*(volatile unsigned int *)(0x12040000) = 'd';
while(1);
}