Commit c906d2a8 authored by davidcunado-arm's avatar davidcunado-arm Committed by GitHub
Browse files

Merge pull request #967 from rockchip-linux/rockchip-cleanup-20170606

 RK3399: Shrink M0 SRAM code to fit in PMUSRAM
parents 0437c421 84597b57
...@@ -44,7 +44,7 @@ static const int cci_map[] = { ...@@ -44,7 +44,7 @@ static const int cci_map[] = {
coh_limit - coh_start, \ coh_limit - coh_start, \
MT_DEVICE | MT_RW | MT_SECURE); \ MT_DEVICE | MT_RW | MT_SECURE); \
mmap_add(plat_rk_mmap); \ mmap_add(plat_rk_mmap); \
rockchip_plat_sram_mmu_el##_el(); \ rockchip_plat_mmu_el##_el(); \
init_xlat_tables(); \ init_xlat_tables(); \
\ \
enable_mmu_el ## _el(0); \ enable_mmu_el ## _el(0); \
......
...@@ -83,8 +83,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, ...@@ -83,8 +83,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
bl32_ep_info = *from_bl2->bl32_ep_info; bl32_ep_info = *from_bl2->bl32_ep_info;
bl33_ep_info = *from_bl2->bl33_ep_info; bl33_ep_info = *from_bl2->bl33_ep_info;
plat_rockchip_pmusram_prepare();
/* there may have some board sepcific message need to initialize */ /* there may have some board sepcific message need to initialize */
params_early_setup(plat_params_from_bl2); params_early_setup(plat_params_from_bl2);
} }
......
...@@ -15,12 +15,18 @@ ...@@ -15,12 +15,18 @@
#define __sramdata __attribute__((section(".sram.data"))) #define __sramdata __attribute__((section(".sram.data")))
#define __sramconst __attribute__((section(".sram.rodata"))) #define __sramconst __attribute__((section(".sram.rodata")))
#define __sramfunc __attribute__((section(".sram.text"))) \ #define __sramfunc __attribute__((section(".sram.text")))
__attribute__((noinline))
#define __pmusramdata __attribute__((section(".pmusram.data")))
#define __pmusramconst __attribute__((section(".pmusram.rodata")))
#define __pmusramfunc __attribute__((section(".pmusram.text")))
extern uint32_t __bl31_sram_text_start, __bl31_sram_text_end; extern uint32_t __bl31_sram_text_start, __bl31_sram_text_end;
extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end; extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end;
extern uint32_t __bl31_sram_stack_start, __bl31_sram_stack_end;
extern uint32_t __bl31_sram_text_real_end, __bl31_sram_data_real_end;
extern uint32_t __sram_incbin_start, __sram_incbin_end; extern uint32_t __sram_incbin_start, __sram_incbin_end;
extern uint32_t __sram_incbin_real_end;
/****************************************************************************** /******************************************************************************
...@@ -73,7 +79,6 @@ void plat_rockchip_gic_cpuif_enable(void); ...@@ -73,7 +79,6 @@ void plat_rockchip_gic_cpuif_enable(void);
void plat_rockchip_gic_cpuif_disable(void); void plat_rockchip_gic_cpuif_disable(void);
void plat_rockchip_gic_pcpu_init(void); void plat_rockchip_gic_pcpu_init(void);
void plat_rockchip_pmusram_prepare(void);
void plat_rockchip_pmu_init(void); void plat_rockchip_pmu_init(void);
void plat_rockchip_soc_init(void); void plat_rockchip_soc_init(void);
uintptr_t plat_get_sec_entrypoint(void); uintptr_t plat_get_sec_entrypoint(void);
...@@ -110,15 +115,13 @@ void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void); ...@@ -110,15 +115,13 @@ void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void);
extern const unsigned char rockchip_power_domain_tree_desc[]; extern const unsigned char rockchip_power_domain_tree_desc[];
extern void *pmu_cpuson_entrypoint_start; extern void *pmu_cpuson_entrypoint;
extern void *pmu_cpuson_entrypoint_end;
extern uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT]; extern uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT];
extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT]; extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
extern const mmap_region_t plat_rk_mmap[]; extern const mmap_region_t plat_rk_mmap[];
void rockchip_plat_sram_mmu_el3(void); void rockchip_plat_mmu_el3(void);
void plat_rockchip_mem_prepare(void);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
......
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <console.h>
#include <debug.h>
#include <platform.h>
#include <plat_private.h>
/*****************************************************************************
* sram only surpport 32-bits access
******************************************************************************/
void u32_align_cpy(uint32_t *dst, const uint32_t *src, size_t bytes)
{
uint32_t i;
for (i = 0; i < bytes; i++)
dst[i] = src[i];
}
void rockchip_plat_sram_mmu_el3(void)
{
#ifdef PLAT_EXTRA_LD_SCRIPT
size_t sram_size;
/* sram.text size */
sram_size = (char *)&__bl31_sram_text_end -
(char *)&__bl31_sram_text_start;
mmap_add_region((unsigned long)&__bl31_sram_text_start,
(unsigned long)&__bl31_sram_text_start,
sram_size, MT_MEMORY | MT_RO | MT_SECURE);
/* sram.data size */
sram_size = (char *)&__bl31_sram_data_end -
(char *)&__bl31_sram_data_start;
mmap_add_region((unsigned long)&__bl31_sram_data_start,
(unsigned long)&__bl31_sram_data_start,
sram_size, MT_MEMORY | MT_RW | MT_SECURE);
/* sram.incbin size */
sram_size = (char *)&__sram_incbin_end - (char *)&__sram_incbin_start;
mmap_add_region((unsigned long)&__sram_incbin_start,
(unsigned long)&__sram_incbin_start,
sram_size, MT_NON_CACHEABLE | MT_RW | MT_SECURE);
#else
/* TODO: Support other SoCs, Just support RK3399 now */
return;
#endif
}
void plat_rockchip_mem_prepare(void)
{
/* The code for resuming cpu from suspend must be excuted in pmusram */
plat_rockchip_pmusram_prepare();
}
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PMU_SRAM_H__
#define __PMU_SRAM_H__
/*****************************************************************************
* define data offset in struct psram_data
*****************************************************************************/
#define PSRAM_DT_SP 0x0
#define PSRAM_DT_DDR_FUNC 0x8
#define PSRAM_DT_DDR_DATA 0x10
#define PSRAM_DT_DDRFLAG 0x18
#define PSRAM_DT_MPIDR 0x1c
#define PSRAM_DT_END 0x20
/******************************************************************************
* Allocate data region for struct psram_data_t in pmusram
******************************************************************************/
/* Needed aligned 16 bytes for sp stack top */
#define PSRAM_DT_SIZE (((PSRAM_DT_END + 16) / 16) * 16)
#define PSRAM_DT_BASE ((PMUSRAM_BASE + PMUSRAM_RSIZE) - PSRAM_DT_SIZE)
#define PSRAM_SP_TOP PSRAM_DT_BASE
#ifndef __ASSEMBLY__
struct psram_data_t {
uint64_t sp;
uint64_t ddr_func;
uint64_t ddr_data;
uint32_t ddr_flag;
uint32_t boot_mpidr;
};
CASSERT(sizeof(struct psram_data_t) <= PSRAM_DT_SIZE,
assert_psram_dt_size_mismatch);
CASSERT(__builtin_offsetof(struct psram_data_t, sp) == PSRAM_DT_SP,
assert_psram_dt_sp_offset_mistmatch);
CASSERT(__builtin_offsetof(struct psram_data_t, ddr_func) == PSRAM_DT_DDR_FUNC,
assert_psram_dt_ddr_func_offset_mistmatch);
CASSERT(__builtin_offsetof(struct psram_data_t, ddr_data) == PSRAM_DT_DDR_DATA,
assert_psram_dt_ddr_data_offset_mistmatch);
CASSERT(__builtin_offsetof(struct psram_data_t, ddr_flag) == PSRAM_DT_DDRFLAG,
assert_psram_dt_ddr_flag_offset_mistmatch);
CASSERT(__builtin_offsetof(struct psram_data_t, boot_mpidr) == PSRAM_DT_MPIDR,
assert_psram_dt_mpidr_offset_mistmatch);
void u32_align_cpy(uint32_t *dst, const uint32_t *src, size_t bytes);
#endif /* __ASSEMBLY__ */
#endif
...@@ -7,23 +7,30 @@ ...@@ -7,23 +7,30 @@
#include <arch.h> #include <arch.h>
#include <asm_macros.S> #include <asm_macros.S>
#include <platform_def.h> #include <platform_def.h>
#include <pmu_sram.h>
.globl pmu_cpuson_entrypoint_start .globl pmu_cpuson_entrypoint
.globl pmu_cpuson_entrypoint_end .macro pmusram_entry_func _name
.section .pmusram.entry, "ax"
.type \_name, %function
.func \_name
.cfi_startproc
\_name:
.endm
func pmu_cpuson_entrypoint pmusram_entry_func pmu_cpuson_entrypoint
pmu_cpuson_entrypoint_start:
ldr x5, psram_data #if PSRAM_CHECK_WAKEUP_CPU
check_wake_cpus: check_wake_cpus:
mrs x0, MPIDR_EL1 mrs x0, MPIDR_EL1
and x1, x0, #MPIDR_CPU_MASK and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK and x0, x0, #MPIDR_CLUSTER_MASK
orr x0, x0, x1 orr x0, x0, x1
/* primary_cpu */ /* primary_cpu */
ldr w1, [x5, #PSRAM_DT_MPIDR] ldr w1, boot_mpidr
cmp w0, w1 cmp w0, w1
b.eq sys_wakeup b.eq sys_wakeup
/* /*
* If the core is not the primary cpu, * If the core is not the primary cpu,
* force the core into wfe. * force the core into wfe.
...@@ -32,25 +39,15 @@ wfe_loop: ...@@ -32,25 +39,15 @@ wfe_loop:
wfe wfe
b wfe_loop b wfe_loop
sys_wakeup: sys_wakeup:
/* check ddr flag for resume ddr */ #endif
ldr w2, [x5, #PSRAM_DT_DDRFLAG]
cmp w2, #0x0 #if PSRAM_DO_DDR_RESUME
b.eq sys_resume
ddr_resume: ddr_resume:
ldr x2, [x5, #PSRAM_DT_SP] ldr x2, =__bl31_sram_stack_end
mov sp, x2 mov sp, x2
ldr x1, [x5, #PSRAM_DT_DDR_FUNC] bl dmc_restore
ldr x0, [x5, #PSRAM_DT_DDR_DATA] #endif
blr x1 bl sram_restore
sys_resume: sys_resume:
ldr x1, sys_wakeup_entry bl psci_entrypoint
br x1
.align 3
psram_data:
.quad PSRAM_DT_BASE
sys_wakeup_entry:
.quad psci_entrypoint
pmu_cpuson_entrypoint_end:
.word 0
endfunc pmu_cpuson_entrypoint endfunc pmu_cpuson_entrypoint
...@@ -16,16 +16,12 @@ ...@@ -16,16 +16,12 @@
#include <platform.h> #include <platform.h>
#include <platform_def.h> #include <platform_def.h>
#include <plat_private.h> #include <plat_private.h>
#include <pmu_sram.h>
#include <pmu.h> #include <pmu.h>
#include <rk3328_def.h> #include <rk3328_def.h>
#include <pmu_com.h> #include <pmu_com.h>
DEFINE_BAKERY_LOCK(rockchip_pd_lock); DEFINE_BAKERY_LOCK(rockchip_pd_lock);
static struct psram_data_t *psram_sleep_cfg =
(struct psram_data_t *)PSRAM_DT_BASE;
static struct rk3328_sleep_ddr_data ddr_data; static struct rk3328_sleep_ddr_data ddr_data;
static __sramdata struct rk3328_sleep_sram_data sram_data; static __sramdata struct rk3328_sleep_sram_data sram_data;
...@@ -34,22 +30,6 @@ static uint32_t cpu_warm_boot_addr; ...@@ -34,22 +30,6 @@ static uint32_t cpu_warm_boot_addr;
#pragma weak rk3328_pmic_suspend #pragma weak rk3328_pmic_suspend
#pragma weak rk3328_pmic_resume #pragma weak rk3328_pmic_resume
void plat_rockchip_pmusram_prepare(void)
{
uint32_t *sram_dst, *sram_src;
size_t sram_size = 2;
/*
* pmu sram code and data prepare
*/
sram_dst = (uint32_t *)PMUSRAM_BASE;
sram_src = (uint32_t *)&pmu_cpuson_entrypoint_start;
sram_size = (uint32_t *)&pmu_cpuson_entrypoint_end -
(uint32_t *)sram_src;
u32_align_cpy(sram_dst, sram_src, sram_size);
psram_sleep_cfg->sp = PSRAM_DT_BASE;
}
static inline uint32_t get_cpus_pwr_domain_cfg_info(uint32_t cpu_id) static inline uint32_t get_cpus_pwr_domain_cfg_info(uint32_t cpu_id)
{ {
uint32_t pd_reg, apm_reg; uint32_t pd_reg, apm_reg;
...@@ -140,6 +120,16 @@ static void nonboot_cpus_off(void) ...@@ -140,6 +120,16 @@ static void nonboot_cpus_off(void)
} }
} }
void sram_save(void)
{
/* TODO: support the sdram save for rk3328 SoCs*/
}
void sram_restore(void)
{
/* TODO: support the sdram restore for rk3328 SoCs */
}
int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint) int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
{ {
uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr); uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
...@@ -495,11 +485,6 @@ __sramfunc void rk3328_pmic_resume(void) ...@@ -495,11 +485,6 @@ __sramfunc void rk3328_pmic_resume(void)
sram_udelay(100); sram_udelay(100);
} }
static inline void rockchip_set_sram_sp(uint64_t set_sp)
{
__asm volatile("mov sp, %0\n"::"r" (set_sp) : "sp");
}
static __sramfunc void ddr_suspend(void) static __sramfunc void ddr_suspend(void)
{ {
sram_data.pd_sr_idle_save = mmio_read_32(DDR_UPCTL_BASE + sram_data.pd_sr_idle_save = mmio_read_32(DDR_UPCTL_BASE +
...@@ -538,7 +523,7 @@ static __sramfunc void ddr_suspend(void) ...@@ -538,7 +523,7 @@ static __sramfunc void ddr_suspend(void)
dpll_suspend(); dpll_suspend();
} }
static __sramfunc void ddr_resume(void) __sramfunc void dmc_restore(void)
{ {
dpll_resume(); dpll_resume();
...@@ -574,7 +559,7 @@ static __sramfunc void sram_dbg_uart_suspend(void) ...@@ -574,7 +559,7 @@ static __sramfunc void sram_dbg_uart_suspend(void)
mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(2), 0x00040004); mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(2), 0x00040004);
} }
static __sramfunc void sram_dbg_uart_resume(void) __sramfunc void sram_dbg_uart_resume(void)
{ {
/* restore uart clk and reset fifo */ /* restore uart clk and reset fifo */
mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(16), 0x20000000); mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(16), 0x20000000);
...@@ -610,7 +595,7 @@ __sramfunc void sram_suspend(void) ...@@ -610,7 +595,7 @@ __sramfunc void sram_suspend(void)
disable_mmu_icache_el3(); disable_mmu_icache_el3();
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
(PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) | ((uintptr_t)&pmu_cpuson_entrypoint >> CPU_BOOT_ADDR_ALIGN) |
CPU_BOOT_ADDR_WMASK); CPU_BOOT_ADDR_WMASK);
/* ddr self-refresh and gating phy */ /* ddr self-refresh and gating phy */
...@@ -623,28 +608,8 @@ __sramfunc void sram_suspend(void) ...@@ -623,28 +608,8 @@ __sramfunc void sram_suspend(void)
sram_soc_enter_lp(); sram_soc_enter_lp();
} }
static __sramfunc void sys_resume_first(void)
{
sram_dbg_uart_resume();
rk3328_pmic_resume();
/* ddr self-refresh exit */
ddr_resume();
/* disable apm cfg */
mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(0), CORES_PM_DISABLE);
/* the warm booting address of cpus */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
(cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) |
CPU_BOOT_ADDR_WMASK);
}
void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void) void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
{ {
rockchip_set_sram_sp(PSRAM_DT_BASE);
sram_suspend(); sram_suspend();
/* should never reach here */ /* should never reach here */
...@@ -671,6 +636,11 @@ int rockchip_soc_sys_pwr_dm_resume(void) ...@@ -671,6 +636,11 @@ int rockchip_soc_sys_pwr_dm_resume(void)
return 0; return 0;
} }
void rockchip_plat_mmu_el3(void)
{
/* TODO: support the el3 for rk3328 SoCs */
}
void plat_rockchip_pmu_init(void) void plat_rockchip_pmu_init(void)
{ {
uint32_t cpu; uint32_t cpu;
...@@ -679,10 +649,6 @@ void plat_rockchip_pmu_init(void) ...@@ -679,10 +649,6 @@ void plat_rockchip_pmu_init(void)
cpuson_flags[cpu] = 0; cpuson_flags[cpu] = 0;
cpu_warm_boot_addr = (uint64_t)platform_cpu_warmboot; cpu_warm_boot_addr = (uint64_t)platform_cpu_warmboot;
psram_sleep_cfg->ddr_func = (uint64_t)sys_resume_first;
psram_sleep_cfg->ddr_data = 0x00;
psram_sleep_cfg->ddr_flag = 0x01;
psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
/* the warm booting address of cpus */ /* the warm booting address of cpus */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
......
/* /*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -7,39 +7,31 @@ ...@@ -7,39 +7,31 @@
#define __ROCKCHIP_PLAT_LD_S__ #define __ROCKCHIP_PLAT_LD_S__
MEMORY { MEMORY {
SRAM (rwx): ORIGIN = SRAM_LDS_BASE, LENGTH = SRAM_LDS_SIZE PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
} }
SECTIONS SECTIONS
{ {
. = SRAM_LDS_BASE; . = PMUSRAM_BASE;
ASSERT(. == ALIGN(4096),
"SRAM_BASE address is not aligned on a page boundary.")
/* /*
* The SRAM space allocation for RK3328 * pmu_cpuson_entrypoint request address
* ---------------- * align 64K when resume, so put it in the
* | sram text * start of pmusram
* ----------------
* | sram data
* ----------------
*/ */
.text_sram : ALIGN(4096) { .text_pmusram : {
__bl31_sram_text_start = .; ASSERT(. == ALIGN(64 * 1024),
*(.sram.text) ".pmusram.entry request 64K aligned.");
*(.sram.rodata) *(.pmusram.entry)
. = ALIGN(4096); __bl31_pmusram_text_start = .;
__bl31_sram_text_end = .; *(.pmusram.text)
} >SRAM *(.pmusram.rodata)
__bl31_pmusram_text_end = .;
__bl31_pmusram_data_start = .;
*(.pmusram.data)
__bl31_pmusram_data_end = .;
.data_sram : ALIGN(4096) { } >PMUSRAM
__bl31_sram_data_start = .;
*(.sram.data)
. = ALIGN(4096);
__bl31_sram_data_end = .;
} >SRAM
__sram_incbin_start = .;
__sram_incbin_end = .;
} }
#endif /* __ROCKCHIP_PLAT_LD_S__ */ #endif /* __ROCKCHIP_PLAT_LD_S__ */
...@@ -120,4 +120,7 @@ ...@@ -120,4 +120,7 @@
#define PLAT_RK_PRIMARY_CPU 0x0 #define PLAT_RK_PRIMARY_CPU 0x0
#define PSRAM_DO_DDR_RESUME 0
#define PSRAM_CHECK_WAKEUP_CPU 0
#endif /* __PLATFORM_DEF_H__ */ #endif /* __PLATFORM_DEF_H__ */
...@@ -41,7 +41,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ...@@ -41,7 +41,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \ ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \
${RK_PLAT_COMMON}/aarch64/plat_helpers.S \ ${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
${RK_PLAT_COMMON}/bl31_plat_setup.c \ ${RK_PLAT_COMMON}/bl31_plat_setup.c \
${RK_PLAT_COMMON}/pmusram/pmu_sram.c \
${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \ ${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/plat_pm.c \ ${RK_PLAT_COMMON}/plat_pm.c \
${RK_PLAT_COMMON}/plat_topology.c \ ${RK_PLAT_COMMON}/plat_topology.c \
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <platform_def.h> #include <platform_def.h>
#include <plat_private.h> #include <plat_private.h>
#include <rk3368_def.h> #include <rk3368_def.h>
#include <pmu_sram.h>
#include <soc.h> #include <soc.h>
#include <pmu.h> #include <pmu.h>
#include <ddr_rk3368.h> #include <ddr_rk3368.h>
...@@ -22,9 +21,6 @@ ...@@ -22,9 +21,6 @@
DEFINE_BAKERY_LOCK(rockchip_pd_lock); DEFINE_BAKERY_LOCK(rockchip_pd_lock);
static struct psram_data_t *psram_sleep_cfg =
(struct psram_data_t *)PSRAM_DT_BASE;
static uint32_t cpu_warm_boot_addr; static uint32_t cpu_warm_boot_addr;
void rk3368_flash_l2_b(void) void rk3368_flash_l2_b(void)
...@@ -223,54 +219,19 @@ static void pmu_sleep_mode_config(void) ...@@ -223,54 +219,19 @@ static void pmu_sleep_mode_config(void)
dsb(); dsb();
} }
static void ddr_suspend_save(void)
{
ddr_reg_save(1, psram_sleep_cfg->ddr_data);
}
static void pmu_set_sleep_mode(void) static void pmu_set_sleep_mode(void)
{ {
ddr_suspend_save();
pmu_sleep_mode_config(); pmu_sleep_mode_config();
soc_sleep_config(); soc_sleep_config();
regs_updata_bit_set(PMU_BASE + PMU_PWRMD_CORE, pmu_mdcr_global_int_dis); regs_updata_bit_set(PMU_BASE + PMU_PWRMD_CORE, pmu_mdcr_global_int_dis);
regs_updata_bit_set(PMU_BASE + PMU_SFT_CON, pmu_sft_glbl_int_dis_b); regs_updata_bit_set(PMU_BASE + PMU_SFT_CON, pmu_sft_glbl_int_dis_b);
pmu_scu_b_pwrdn(); pmu_scu_b_pwrdn();
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
(PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) | ((uintptr_t)&pmu_cpuson_entrypoint >>
CPU_BOOT_ADDR_WMASK); CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK);
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(2), mmio_write_32(SGRF_BASE + SGRF_SOC_CON(2),
(PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) | ((uintptr_t)&pmu_cpuson_entrypoint >>
CPU_BOOT_ADDR_WMASK); CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK);
}
void plat_rockchip_pmusram_prepare(void)
{
uint32_t *sram_dst, *sram_src;
size_t sram_size = 2;
uint32_t code_size;
/* pmu sram code and data prepare */
sram_dst = (uint32_t *)PMUSRAM_BASE;
sram_src = (uint32_t *)&pmu_cpuson_entrypoint_start;
sram_size = (uint32_t *)&pmu_cpuson_entrypoint_end -
(uint32_t *)sram_src;
u32_align_cpy(sram_dst, sram_src, sram_size);
/* ddr code */
sram_dst += sram_size;
sram_src = ddr_get_resume_code_base();
code_size = ddr_get_resume_code_size();
u32_align_cpy(sram_dst, sram_src, code_size / 4);
psram_sleep_cfg->ddr_func = (uint64_t)sram_dst;
/* ddr data */
sram_dst += (code_size / 4);
psram_sleep_cfg->ddr_data = (uint64_t)sram_dst;
assert((uint64_t)(sram_dst + ddr_get_resume_data_size() / 4)
< PSRAM_SP_BOTTOM);
psram_sleep_cfg->sp = PSRAM_SP_TOP;
} }
static int cpus_id_power_domain(uint32_t cluster, static int cpus_id_power_domain(uint32_t cluster,
...@@ -319,6 +280,16 @@ static void nonboot_cpus_off(void) ...@@ -319,6 +280,16 @@ static void nonboot_cpus_off(void)
} }
} }
void sram_save(void)
{
/* TODO: support the sdram save for rk3368 SoCs*/
}
void sram_restore(void)
{
/* TODO: support the sdram restore for rk3368 SoCs */
}
int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint) int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
{ {
uint32_t cpu, cluster; uint32_t cpu, cluster;
...@@ -375,11 +346,14 @@ int rockchip_soc_sys_pwr_dm_suspend(void) ...@@ -375,11 +346,14 @@ int rockchip_soc_sys_pwr_dm_suspend(void)
nonboot_cpus_off(); nonboot_cpus_off();
pmu_set_sleep_mode(); pmu_set_sleep_mode();
psram_sleep_cfg->ddr_flag = 0;
return 0; return 0;
} }
void rockchip_plat_mmu_el3(void)
{
/* TODO: support the el3 for rk3368 SoCs */
}
void plat_rockchip_pmu_init(void) void plat_rockchip_pmu_init(void)
{ {
uint32_t cpu; uint32_t cpu;
...@@ -390,8 +364,6 @@ void plat_rockchip_pmu_init(void) ...@@ -390,8 +364,6 @@ void plat_rockchip_pmu_init(void)
for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
cpuson_flags[cpu] = 0; cpuson_flags[cpu] = 0;
psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
nonboot_cpus_off(); nonboot_cpus_off();
INFO("%s(%d): pd status %x\n", __func__, __LINE__, INFO("%s(%d): pd status %x\n", __func__, __LINE__,
mmio_read_32(PMU_BASE + PMU_PWRDN_ST)); mmio_read_32(PMU_BASE + PMU_PWRDN_ST));
......
/*
* 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__
MEMORY {
PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
}
SECTIONS
{
. = PMUSRAM_BASE;
/*
* pmu_cpuson_entrypoint request address
* align 64K when resume, so put it in the
* start of pmusram
*/
.text_pmusram : {
ASSERT(. == ALIGN(64 * 1024),
".pmusram.entry request 64K aligned.");
*(.pmusram.entry)
__bl31_pmusram_text_start = .;
*(.pmusram.text)
*(.pmusram.rodata)
__bl31_pmusram_text_end = .;
__bl31_pmusram_data_start = .;
*(.pmusram.data)
__bl31_pmusram_data_end = .;
} >PMUSRAM
}
#endif /* __ROCKCHIP_PLAT_LD_S__ */
...@@ -122,4 +122,7 @@ ...@@ -122,4 +122,7 @@
#define PLAT_RK_PRIMARY_CPU 0x0 #define PLAT_RK_PRIMARY_CPU 0x0
#define PSRAM_DO_DDR_RESUME 0
#define PSRAM_CHECK_WAKEUP_CPU 0
#endif /* __PLATFORM_DEF_H__ */ #endif /* __PLATFORM_DEF_H__ */
...@@ -39,7 +39,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ...@@ -39,7 +39,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_COMMON}/bl31_plat_setup.c \ ${RK_PLAT_COMMON}/bl31_plat_setup.c \
${RK_PLAT_COMMON}/params_setup.c \ ${RK_PLAT_COMMON}/params_setup.c \
${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \ ${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/pmusram/pmu_sram.c \
${RK_PLAT_COMMON}/plat_pm.c \ ${RK_PLAT_COMMON}/plat_pm.c \
${RK_PLAT_COMMON}/plat_topology.c \ ${RK_PLAT_COMMON}/plat_topology.c \
${RK_PLAT_COMMON}/aarch64/platform_common.c \ ${RK_PLAT_COMMON}/aarch64/platform_common.c \
...@@ -50,3 +49,5 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ...@@ -50,3 +49,5 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_SOC}/drivers/ddr/ddr_rk3368.c \ ${RK_PLAT_SOC}/drivers/ddr/ddr_rk3368.c \
ENABLE_PLAT_COMPAT := 0 ENABLE_PLAT_COMPAT := 0
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
...@@ -54,6 +54,7 @@ struct rk3399_saved_status { ...@@ -54,6 +54,7 @@ struct rk3399_saved_status {
static struct rk3399_dram_status rk3399_dram_status; static struct rk3399_dram_status rk3399_dram_status;
static struct rk3399_saved_status rk3399_suspend_status; static struct rk3399_saved_status rk3399_suspend_status;
static uint32_t wrdqs_delay_val[2][2][4]; static uint32_t wrdqs_delay_val[2][2][4];
static uint32_t rddqs_delay_ps;
static struct rk3399_sdram_default_config ddr3_default_config = { static struct rk3399_sdram_default_config ddr3_default_config = {
.bl = 8, .bl = 8,
...@@ -1599,7 +1600,7 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config, ...@@ -1599,7 +1600,7 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config,
mmio_clrsetbits_32(PHY_REG(i, 394), 0xf, tmp); mmio_clrsetbits_32(PHY_REG(i, 394), 0xf, tmp);
/* PHY_GTLVL_LAT_ADJ_START */ /* PHY_GTLVL_LAT_ADJ_START */
/* DENALI_PHY_80/208/336/464 4bits offset_16 */ /* DENALI_PHY_80/208/336/464 4bits offset_16 */
tmp = delay_frac_ps / 1000; tmp = rddqs_delay_ps / (1000000 / pdram_timing->mhz) + 2;
mmio_clrsetbits_32(PHY_REG(i, 80), 0xf << 16, tmp << 16); mmio_clrsetbits_32(PHY_REG(i, 80), 0xf << 16, tmp << 16);
mmio_clrsetbits_32(PHY_REG(i, 208), 0xf << 16, tmp << 16); mmio_clrsetbits_32(PHY_REG(i, 208), 0xf << 16, tmp << 16);
mmio_clrsetbits_32(PHY_REG(i, 336), 0xf << 16, tmp << 16); mmio_clrsetbits_32(PHY_REG(i, 336), 0xf << 16, tmp << 16);
...@@ -1830,6 +1831,7 @@ static void dram_low_power_config(void) ...@@ -1830,6 +1831,7 @@ static void dram_low_power_config(void)
void dram_dfs_init(void) void dram_dfs_init(void)
{ {
uint32_t trefi0, trefi1, boot_freq; uint32_t trefi0, trefi1, boot_freq;
uint32_t rddqs_adjust, rddqs_slave;
/* get sdram config for os reg */ /* get sdram config for os reg */
get_dram_drv_odt_val(sdram_config.dramtype, get_dram_drv_odt_val(sdram_config.dramtype,
...@@ -1875,8 +1877,31 @@ void dram_dfs_init(void) ...@@ -1875,8 +1877,31 @@ void dram_dfs_init(void)
/* Disable multicast */ /* Disable multicast */
mmio_clrbits_32(PHY_REG(0, 896), 1); mmio_clrbits_32(PHY_REG(0, 896), 1);
mmio_clrbits_32(PHY_REG(1, 896), 1); mmio_clrbits_32(PHY_REG(1, 896), 1);
dram_low_power_config(); dram_low_power_config();
/*
* If boot_freq isn't in the bypass mode, it can get the
* rddqs_delay_ps from the result of gate training
*/
if (((mmio_read_32(PHY_REG(0, 86)) >> 8) & 0xf) != 0xc) {
/*
* Select PHY's frequency set to current_index
* index for get the result of gate Training
* from registers
*/
mmio_clrsetbits_32(PHY_REG(0, 896), 0x3 << 8,
rk3399_dram_status.current_index << 8);
rddqs_slave = (mmio_read_32(PHY_REG(0, 77)) >> 16) & 0x3ff;
rddqs_slave = rddqs_slave * 1000000 / boot_freq / 512;
rddqs_adjust = mmio_read_32(PHY_REG(0, 78)) & 0xf;
rddqs_adjust = rddqs_adjust * 1000000 / boot_freq;
rddqs_delay_ps = rddqs_slave + rddqs_adjust -
(1000000 / boot_freq / 2);
} else {
rddqs_delay_ps = 3500;
}
} }
/* /*
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include <soc.h> #include <soc.h>
#include <rk3399_def.h> #include <rk3399_def.h>
__sramdata struct rk3399_sdram_params sdram_config; __pmusramdata struct rk3399_sdram_params sdram_config;
void dram_init(void) void dram_init(void)
{ {
......
...@@ -24,7 +24,17 @@ struct rk3399_ddr_pctl_regs { ...@@ -24,7 +24,17 @@ struct rk3399_ddr_pctl_regs {
}; };
struct rk3399_ddr_publ_regs { struct rk3399_ddr_publ_regs {
uint32_t denali_phy[PHY_REG_NUM]; /*
* PHY registers from 0 to 511.
* Only registers 0-90 of each 128 register range are used.
*/
uint32_t phy0[4][91];
/*
* PHY registers from 512 to 895.
* Only registers 0-37 of each 128 register range are used.
*/
uint32_t phy512[3][38];
uint32_t phy896[63];
}; };
struct rk3399_ddr_pi_regs { struct rk3399_ddr_pi_regs {
......
...@@ -45,7 +45,8 @@ ...@@ -45,7 +45,8 @@
/* /*
* Copy @num registers from @src to @dst * Copy @num registers from @src to @dst
*/ */
__sramfunc void sram_regcpy(uintptr_t dst, uintptr_t src, uint32_t num) static __pmusramfunc void sram_regcpy(uintptr_t dst, uintptr_t src,
uint32_t num)
{ {
while (num--) { while (num--) {
mmio_write_32(dst, mmio_read_32(src)); mmio_write_32(dst, mmio_read_32(src));
...@@ -54,7 +55,21 @@ __sramfunc void sram_regcpy(uintptr_t dst, uintptr_t src, uint32_t num) ...@@ -54,7 +55,21 @@ __sramfunc void sram_regcpy(uintptr_t dst, uintptr_t src, uint32_t num)
} }
} }
static __sramfunc uint32_t sram_get_timer_value(void) /*
* Copy @num registers from @src to @dst
* This is intentionally a copy of the sram_regcpy function. PMUSRAM functions
* cannot be called from code running in DRAM.
*/
static void dram_regcpy(uintptr_t dst, uintptr_t src, uint32_t num)
{
while (num--) {
mmio_write_32(dst, mmio_read_32(src));
dst += sizeof(uint32_t);
src += sizeof(uint32_t);
}
}
static __pmusramfunc uint32_t sram_get_timer_value(void)
{ {
/* /*
* Generic delay timer implementation expects the timer to be a down * Generic delay timer implementation expects the timer to be a down
...@@ -64,7 +79,7 @@ static __sramfunc uint32_t sram_get_timer_value(void) ...@@ -64,7 +79,7 @@ static __sramfunc uint32_t sram_get_timer_value(void)
return (uint32_t)(~read_cntpct_el0()); return (uint32_t)(~read_cntpct_el0());
} }
static __sramfunc void sram_udelay(uint32_t usec) static __pmusramfunc void sram_udelay(uint32_t usec)
{ {
uint32_t start, cnt, delta, delta_us; uint32_t start, cnt, delta, delta_us;
...@@ -81,7 +96,7 @@ static __sramfunc void sram_udelay(uint32_t usec) ...@@ -81,7 +96,7 @@ static __sramfunc void sram_udelay(uint32_t usec)
} while (delta_us < usec); } while (delta_us < usec);
} }
static __sramfunc void configure_sgrf(void) static __pmusramfunc void configure_sgrf(void)
{ {
/* /*
* SGRF_DDR_RGN_DPLL_CLK and SGRF_DDR_RGN_RTC_CLK: * SGRF_DDR_RGN_DPLL_CLK and SGRF_DDR_RGN_RTC_CLK:
...@@ -98,7 +113,7 @@ static __sramfunc void configure_sgrf(void) ...@@ -98,7 +113,7 @@ static __sramfunc void configure_sgrf(void)
SGRF_DDR_RGN_BYPS); SGRF_DDR_RGN_BYPS);
} }
static __sramfunc void rkclk_ddr_reset(uint32_t channel, uint32_t ctl, static __pmusramfunc void rkclk_ddr_reset(uint32_t channel, uint32_t ctl,
uint32_t phy) uint32_t phy)
{ {
channel &= 0x1; channel &= 0x1;
...@@ -109,7 +124,7 @@ static __sramfunc void rkclk_ddr_reset(uint32_t channel, uint32_t ctl, ...@@ -109,7 +124,7 @@ static __sramfunc void rkclk_ddr_reset(uint32_t channel, uint32_t ctl,
CRU_SFTRST_DDR_PHY(channel, phy)); CRU_SFTRST_DDR_PHY(channel, phy));
} }
static __sramfunc void phy_pctrl_reset(uint32_t ch) static __pmusramfunc void phy_pctrl_reset(uint32_t ch)
{ {
rkclk_ddr_reset(ch, 1, 1); rkclk_ddr_reset(ch, 1, 1);
sram_udelay(10); sram_udelay(10);
...@@ -119,76 +134,45 @@ static __sramfunc void phy_pctrl_reset(uint32_t ch) ...@@ -119,76 +134,45 @@ static __sramfunc void phy_pctrl_reset(uint32_t ch)
sram_udelay(10); sram_udelay(10);
} }
static __sramfunc void phy_dll_bypass_set(uint32_t ch, uint32_t hz) static __pmusramfunc void set_cs_training_index(uint32_t ch, uint32_t rank)
{ {
if (hz <= 125 * MHz) { uint32_t byte;
/* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
mmio_setbits_32(PHY_REG(ch, 86), (0x3 << 2) << 8);
mmio_setbits_32(PHY_REG(ch, 214), (0x3 << 2) << 8);
mmio_setbits_32(PHY_REG(ch, 342), (0x3 << 2) << 8);
mmio_setbits_32(PHY_REG(ch, 470), (0x3 << 2) << 8);
/* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
mmio_setbits_32(PHY_REG(ch, 547), (0x3 << 2) << 16);
mmio_setbits_32(PHY_REG(ch, 675), (0x3 << 2) << 16);
mmio_setbits_32(PHY_REG(ch, 803), (0x3 << 2) << 16);
} else {
/* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
mmio_clrbits_32(PHY_REG(ch, 86), (0x3 << 2) << 8);
mmio_clrbits_32(PHY_REG(ch, 214), (0x3 << 2) << 8);
mmio_clrbits_32(PHY_REG(ch, 342), (0x3 << 2) << 8);
mmio_clrbits_32(PHY_REG(ch, 470), (0x3 << 2) << 8);
/* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
mmio_clrbits_32(PHY_REG(ch, 547), (0x3 << 2) << 16);
mmio_clrbits_32(PHY_REG(ch, 675), (0x3 << 2) << 16);
mmio_clrbits_32(PHY_REG(ch, 803), (0x3 << 2) << 16);
}
}
static __sramfunc void set_cs_training_index(uint32_t ch, uint32_t rank)
{
/* PHY_8/136/264/392 phy_per_cs_training_index_X 1bit offset_24 */ /* PHY_8/136/264/392 phy_per_cs_training_index_X 1bit offset_24 */
mmio_clrsetbits_32(PHY_REG(ch, 8), 0x1 << 24, rank << 24); for (byte = 0; byte < 4; byte++)
mmio_clrsetbits_32(PHY_REG(ch, 136), 0x1 << 24, rank << 24); mmio_clrsetbits_32(PHY_REG(ch, 8 + (128 * byte)), 0x1 << 24,
mmio_clrsetbits_32(PHY_REG(ch, 264), 0x1 << 24, rank << 24); rank << 24);
mmio_clrsetbits_32(PHY_REG(ch, 392), 0x1 << 24, rank << 24);
} }
static __sramfunc void select_per_cs_training_index(uint32_t ch, uint32_t rank) static __pmusramfunc void select_per_cs_training_index(uint32_t ch,
uint32_t rank)
{ {
/* PHY_84 PHY_PER_CS_TRAINING_EN_0 1bit offset_16 */ /* PHY_84 PHY_PER_CS_TRAINING_EN_0 1bit offset_16 */
if ((mmio_read_32(PHY_REG(ch, 84)) >> 16) & 1) if ((mmio_read_32(PHY_REG(ch, 84)) >> 16) & 1)
set_cs_training_index(ch, rank); set_cs_training_index(ch, rank);
} }
static void override_write_leveling_value(uint32_t ch) static __pmusramfunc void override_write_leveling_value(uint32_t ch)
{ {
uint32_t byte; uint32_t byte;
/* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */ for (byte = 0; byte < 4; byte++) {
mmio_setbits_32(PHY_REG(ch, 896), 1); /*
* PHY_8/136/264/392
/* * phy_per_cs_training_multicast_en_X 1bit offset_16
* PHY_8/136/264/392 */
* phy_per_cs_training_multicast_en_X 1bit offset_16 mmio_clrsetbits_32(PHY_REG(ch, 8 + (128 * byte)), 0x1 << 16,
*/ 1 << 16);
mmio_clrsetbits_32(PHY_REG(ch, 8), 0x1 << 16, 1 << 16);
mmio_clrsetbits_32(PHY_REG(ch, 136), 0x1 << 16, 1 << 16);
mmio_clrsetbits_32(PHY_REG(ch, 264), 0x1 << 16, 1 << 16);
mmio_clrsetbits_32(PHY_REG(ch, 392), 0x1 << 16, 1 << 16);
for (byte = 0; byte < 4; byte++)
mmio_clrsetbits_32(PHY_REG(ch, 63 + (128 * byte)), mmio_clrsetbits_32(PHY_REG(ch, 63 + (128 * byte)),
0xffff << 16, 0xffff << 16,
0x200 << 16); 0x200 << 16);
}
/* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
mmio_clrbits_32(PHY_REG(ch, 896), 1);
/* CTL_200 ctrlupd_req 1bit offset_8 */ /* CTL_200 ctrlupd_req 1bit offset_8 */
mmio_clrsetbits_32(CTL_REG(ch, 200), 0x1 << 8, 0x1 << 8); mmio_clrsetbits_32(CTL_REG(ch, 200), 0x1 << 8, 0x1 << 8);
} }
static __sramfunc int data_training(uint32_t ch, static __pmusramfunc int data_training(uint32_t ch,
struct rk3399_sdram_params *sdram_params, struct rk3399_sdram_params *sdram_params,
uint32_t training_flag) uint32_t training_flag)
{ {
...@@ -433,7 +417,8 @@ static __sramfunc int data_training(uint32_t ch, ...@@ -433,7 +417,8 @@ static __sramfunc int data_training(uint32_t ch,
return 0; return 0;
} }
static __sramfunc void set_ddrconfig(struct rk3399_sdram_params *sdram_params, static __pmusramfunc void set_ddrconfig(
struct rk3399_sdram_params *sdram_params,
unsigned char channel, uint32_t ddrconfig) unsigned char channel, uint32_t ddrconfig)
{ {
/* only need to set ddrconfig */ /* only need to set ddrconfig */
...@@ -455,7 +440,8 @@ static __sramfunc void set_ddrconfig(struct rk3399_sdram_params *sdram_params, ...@@ -455,7 +440,8 @@ static __sramfunc void set_ddrconfig(struct rk3399_sdram_params *sdram_params,
((cs0_cap / 32) & 0xff) | (((cs1_cap / 32) & 0xff) << 8)); ((cs0_cap / 32) & 0xff) | (((cs1_cap / 32) & 0xff) << 8));
} }
static __sramfunc void dram_all_config(struct rk3399_sdram_params *sdram_params) static __pmusramfunc void dram_all_config(
struct rk3399_sdram_params *sdram_params)
{ {
unsigned int i; unsigned int i;
...@@ -491,13 +477,13 @@ static __sramfunc void dram_all_config(struct rk3399_sdram_params *sdram_params) ...@@ -491,13 +477,13 @@ static __sramfunc void dram_all_config(struct rk3399_sdram_params *sdram_params)
mmio_clrsetbits_32(CRU_BASE + CRU_GLB_RST_CON, 0x3, 0x3); mmio_clrsetbits_32(CRU_BASE + CRU_GLB_RST_CON, 0x3, 0x3);
} }
static __sramfunc void pctl_cfg(uint32_t ch, static __pmusramfunc void pctl_cfg(uint32_t ch,
struct rk3399_sdram_params *sdram_params) struct rk3399_sdram_params *sdram_params)
{ {
const uint32_t *params_ctl = sdram_params->pctl_regs.denali_ctl; const uint32_t *params_ctl = sdram_params->pctl_regs.denali_ctl;
const uint32_t *params_phy = sdram_params->phy_regs.denali_phy;
const uint32_t *params_pi = sdram_params->pi_regs.denali_pi; const uint32_t *params_pi = sdram_params->pi_regs.denali_pi;
uint32_t tmp, tmp1, tmp2; const struct rk3399_ddr_publ_regs *phy_regs = &sdram_params->phy_regs;
uint32_t tmp, tmp1, tmp2, i;
/* /*
* Workaround controller bug: * Workaround controller bug:
...@@ -509,9 +495,8 @@ static __sramfunc void pctl_cfg(uint32_t ch, ...@@ -509,9 +495,8 @@ static __sramfunc void pctl_cfg(uint32_t ch,
sram_regcpy(PI_REG(ch, 0), (uintptr_t)&params_pi[0], sram_regcpy(PI_REG(ch, 0), (uintptr_t)&params_pi[0],
PI_REG_NUM); PI_REG_NUM);
mmio_write_32(PHY_REG(ch, 910), params_phy[910]); sram_regcpy(PHY_REG(ch, 910), (uintptr_t)&phy_regs->phy896[910 - 896],
mmio_write_32(PHY_REG(ch, 911), params_phy[911]); 3);
mmio_write_32(PHY_REG(ch, 912), params_phy[912]);
mmio_clrsetbits_32(CTL_REG(ch, 68), PWRUP_SREFRESH_EXIT, mmio_clrsetbits_32(CTL_REG(ch, 68), PWRUP_SREFRESH_EXIT,
PWRUP_SREFRESH_EXIT); PWRUP_SREFRESH_EXIT);
...@@ -538,17 +523,18 @@ static __sramfunc void pctl_cfg(uint32_t ch, ...@@ -538,17 +523,18 @@ static __sramfunc void pctl_cfg(uint32_t ch,
break; break;
} }
sram_regcpy(PHY_REG(ch, 896), (uintptr_t)&params_phy[896], 63); sram_regcpy(PHY_REG(ch, 896), (uintptr_t)&phy_regs->phy896[0], 63);
sram_regcpy(PHY_REG(ch, 0), (uintptr_t)&params_phy[0], 91);
sram_regcpy(PHY_REG(ch, 128), (uintptr_t)&params_phy[128], 91); for (i = 0; i < 4; i++)
sram_regcpy(PHY_REG(ch, 256), (uintptr_t)&params_phy[256], 91); sram_regcpy(PHY_REG(ch, 128 * i),
sram_regcpy(PHY_REG(ch, 384), (uintptr_t)&params_phy[384], 91); (uintptr_t)&phy_regs->phy0[i][0], 91);
sram_regcpy(PHY_REG(ch, 512), (uintptr_t)&params_phy[512], 38);
sram_regcpy(PHY_REG(ch, 640), (uintptr_t)&params_phy[640], 38); for (i = 0; i < 3; i++)
sram_regcpy(PHY_REG(ch, 768), (uintptr_t)&params_phy[768], 38); sram_regcpy(PHY_REG(ch, 512 + 128 * i),
(uintptr_t)&phy_regs->phy512[i][0], 38);
} }
static __sramfunc int dram_switch_to_next_index( static __pmusramfunc int dram_switch_to_next_index(
struct rk3399_sdram_params *sdram_params) struct rk3399_sdram_params *sdram_params)
{ {
uint32_t ch, ch_count; uint32_t ch, ch_count;
...@@ -583,7 +569,7 @@ static __sramfunc int dram_switch_to_next_index( ...@@ -583,7 +569,7 @@ static __sramfunc int dram_switch_to_next_index(
* Needs to be done for both channels at once in case of a shared reset signal * Needs to be done for both channels at once in case of a shared reset signal
* between channels. * between channels.
*/ */
static __sramfunc int pctl_start(uint32_t channel_mask, static __pmusramfunc int pctl_start(uint32_t channel_mask,
struct rk3399_sdram_params *sdram_params) struct rk3399_sdram_params *sdram_params)
{ {
uint32_t count; uint32_t count;
...@@ -652,15 +638,15 @@ static __sramfunc int pctl_start(uint32_t channel_mask, ...@@ -652,15 +638,15 @@ static __sramfunc int pctl_start(uint32_t channel_mask,
void dmc_save(void) void dmc_save(void)
{ {
struct rk3399_sdram_params *sdram_params = &sdram_config; struct rk3399_sdram_params *sdram_params = &sdram_config;
struct rk3399_ddr_publ_regs *phy_regs;
uint32_t *params_ctl; uint32_t *params_ctl;
uint32_t *params_pi; uint32_t *params_pi;
uint32_t *params_phy;
uint32_t refdiv, postdiv2, postdiv1, fbdiv; uint32_t refdiv, postdiv2, postdiv1, fbdiv;
uint32_t tmp, ch, byte; uint32_t tmp, ch, byte, i;
phy_regs = &sdram_params->phy_regs;
params_ctl = sdram_params->pctl_regs.denali_ctl; params_ctl = sdram_params->pctl_regs.denali_ctl;
params_pi = sdram_params->pi_regs.denali_pi; params_pi = sdram_params->pi_regs.denali_pi;
params_phy = sdram_params->phy_regs.denali_phy;
fbdiv = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 0)) & 0xfff; fbdiv = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 0)) & 0xfff;
tmp = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)); tmp = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1));
...@@ -676,25 +662,26 @@ void dmc_save(void) ...@@ -676,25 +662,26 @@ void dmc_save(void)
0x7) != 0) ? 1 : 0; 0x7) != 0) ? 1 : 0;
/* copy the registers CTL PI and PHY */ /* copy the registers CTL PI and PHY */
sram_regcpy((uintptr_t)&params_ctl[0], CTL_REG(0, 0), CTL_REG_NUM); dram_regcpy((uintptr_t)&params_ctl[0], CTL_REG(0, 0), CTL_REG_NUM);
/* mask DENALI_CTL_00_DATA.START, only copy here, will trigger later */ /* mask DENALI_CTL_00_DATA.START, only copy here, will trigger later */
params_ctl[0] &= ~(0x1 << 0); params_ctl[0] &= ~(0x1 << 0);
sram_regcpy((uintptr_t)&params_pi[0], PI_REG(0, 0), dram_regcpy((uintptr_t)&params_pi[0], PI_REG(0, 0),
PI_REG_NUM); PI_REG_NUM);
/* mask DENALI_PI_00_DATA.START, only copy here, will trigger later*/ /* mask DENALI_PI_00_DATA.START, only copy here, will trigger later*/
params_pi[0] &= ~(0x1 << 0); params_pi[0] &= ~(0x1 << 0);
sram_regcpy((uintptr_t)&params_phy[0], PHY_REG(0, 0), 91); for (i = 0; i < 4; i++)
sram_regcpy((uintptr_t)&params_phy[128], PHY_REG(0, 128), 91); dram_regcpy((uintptr_t)&phy_regs->phy0[i][0],
sram_regcpy((uintptr_t)&params_phy[256], PHY_REG(0, 256), 91); PHY_REG(0, 128 * i), 91);
sram_regcpy((uintptr_t)&params_phy[384], PHY_REG(0, 384), 91);
sram_regcpy((uintptr_t)&params_phy[512], PHY_REG(0, 512), 38); for (i = 0; i < 3; i++)
sram_regcpy((uintptr_t)&params_phy[640], PHY_REG(0, 640), 38); dram_regcpy((uintptr_t)&phy_regs->phy512[i][0],
sram_regcpy((uintptr_t)&params_phy[768], PHY_REG(0, 768), 38); PHY_REG(0, 512 + 128 * i), 38);
sram_regcpy((uintptr_t)&params_phy[896], PHY_REG(0, 896), 63);
dram_regcpy((uintptr_t)&phy_regs->phy896[0], PHY_REG(0, 896), 63);
for (ch = 0; ch < sdram_params->num_channels; ch++) { for (ch = 0; ch < sdram_params->num_channels; ch++) {
for (byte = 0; byte < 4; byte++) for (byte = 0; byte < 4; byte++)
...@@ -703,13 +690,13 @@ void dmc_save(void) ...@@ -703,13 +690,13 @@ void dmc_save(void)
} }
/* set DENALI_PHY_957_DATA.PHY_DLL_RST_EN = 0x1 */ /* set DENALI_PHY_957_DATA.PHY_DLL_RST_EN = 0x1 */
params_phy[957] &= ~(0x3 << 24); phy_regs->phy896[957 - 896] &= ~(0x3 << 24);
params_phy[957] |= 1 << 24; phy_regs->phy896[957 - 896] |= 1 << 24;
params_phy[896] |= 1; phy_regs->phy896[0] |= 1;
params_phy[896] &= ~(0x3 << 8); phy_regs->phy896[0] &= ~(0x3 << 8);
} }
__sramfunc void dmc_restore(void) __pmusramfunc void dmc_restore(void)
{ {
struct rk3399_sdram_params *sdram_params = &sdram_config; struct rk3399_sdram_params *sdram_params = &sdram_config;
uint32_t channel_mask = 0; uint32_t channel_mask = 0;
...@@ -720,10 +707,6 @@ __sramfunc void dmc_restore(void) ...@@ -720,10 +707,6 @@ __sramfunc void dmc_restore(void)
retry: retry:
for (channel = 0; channel < sdram_params->num_channels; channel++) { for (channel = 0; channel < sdram_params->num_channels; channel++) {
phy_pctrl_reset(channel); phy_pctrl_reset(channel);
phy_dll_bypass_set(channel, sdram_params->ddr_freq);
if (channel >= sdram_params->num_channels)
continue;
pctl_cfg(channel, sdram_params); pctl_cfg(channel, sdram_params);
} }
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#define PI_FULL_TRAINING (0xff) #define PI_FULL_TRAINING (0xff)
void dmc_save(void); void dmc_save(void);
__sramfunc void dmc_restore(void); __pmusramfunc void dmc_restore(void);
__sramfunc void sram_regcpy(uintptr_t dst, uintptr_t src, uint32_t num);
#endif /* __DRAM_H__ */ #endif /* __DRAM_H__ */
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
#include <plat_params.h> #include <plat_params.h>
#include <plat_private.h> #include <plat_private.h>
#include <rk3399_def.h> #include <rk3399_def.h>
#include <pmu_sram.h>
#include <secure.h> #include <secure.h>
#include <soc.h> #include <soc.h>
#include <string.h>
#include <pmu.h> #include <pmu.h>
#include <pmu_com.h> #include <pmu_com.h>
#include <pwm.h> #include <pwm.h>
...@@ -30,10 +30,8 @@ ...@@ -30,10 +30,8 @@
DEFINE_BAKERY_LOCK(rockchip_pd_lock); DEFINE_BAKERY_LOCK(rockchip_pd_lock);
static struct psram_data_t *psram_sleep_cfg =
(struct psram_data_t *)PSRAM_DT_BASE;
static uint32_t cpu_warm_boot_addr; static uint32_t cpu_warm_boot_addr;
static char store_sram[SRAM_BIN_LIMIT + SRAM_TEXT_LIMIT + SRAM_DATA_LIMIT];
/* /*
* There are two ways to powering on or off on core. * There are two ways to powering on or off on core.
...@@ -411,24 +409,6 @@ static void pmu_scu_b_pwrup(void) ...@@ -411,24 +409,6 @@ static void pmu_scu_b_pwrup(void)
mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, BIT(ACINACTM_CLUSTER_B_CFG)); mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, BIT(ACINACTM_CLUSTER_B_CFG));
} }
void plat_rockchip_pmusram_prepare(void)
{
uint32_t *sram_dst, *sram_src;
size_t sram_size;
/*
* pmu sram code and data prepare
*/
sram_dst = (uint32_t *)PMUSRAM_BASE;
sram_src = (uint32_t *)&pmu_cpuson_entrypoint_start;
sram_size = (uint32_t *)&pmu_cpuson_entrypoint_end -
(uint32_t *)sram_src;
u32_align_cpy(sram_dst, sram_src, sram_size);
psram_sleep_cfg->sp = PSRAM_DT_BASE;
}
static inline uint32_t get_cpus_pwr_domain_cfg_info(uint32_t cpu_id) static inline uint32_t get_cpus_pwr_domain_cfg_info(uint32_t cpu_id)
{ {
assert(cpu_id < PLATFORM_CORE_COUNT); assert(cpu_id < PLATFORM_CORE_COUNT);
...@@ -781,6 +761,18 @@ static void init_pmu_counts(void) ...@@ -781,6 +761,18 @@ static void init_pmu_counts(void)
mmio_write_32(PMU_BASE + PMU_CENTER_PWRDN_CNT, CYCL_24M_CNT_MS(1)); mmio_write_32(PMU_BASE + PMU_CENTER_PWRDN_CNT, CYCL_24M_CNT_MS(1));
mmio_write_32(PMU_BASE + PMU_CENTER_PWRUP_CNT, CYCL_24M_CNT_MS(1)); mmio_write_32(PMU_BASE + PMU_CENTER_PWRUP_CNT, CYCL_24M_CNT_MS(1));
/*
* when we enable PMU_CLR_PERILP, it will shut down the SRAM, but
* M0 code run in SRAM, and we need it to check whether cpu enter
* FSM status, so we must wait M0 finish their code and enter WFI,
* then we can shutdown SRAM, according FSM order:
* ST_NORMAL->..->ST_SCU_L_PWRDN->..->ST_CENTER_PWRDN->ST_PERILP_PWRDN
* we can add delay when shutdown ST_SCU_L_PWRDN to guarantee M0 get
* the FSM status and enter WFI, then enable PMU_CLR_PERILP.
*/
mmio_write_32(PMU_BASE + PMU_SCU_L_PWRDN_CNT, CYCL_24M_CNT_MS(5));
mmio_write_32(PMU_BASE + PMU_SCU_L_PWRUP_CNT, CYCL_24M_CNT_US(1));
/* /*
* Set CPU/GPU to 1 us. * Set CPU/GPU to 1 us.
* *
...@@ -788,8 +780,6 @@ static void init_pmu_counts(void) ...@@ -788,8 +780,6 @@ static void init_pmu_counts(void)
* counts here. After all ATF controls all these other bits and also * counts here. After all ATF controls all these other bits and also
* chooses which clock these counters use. * chooses which clock these counters use.
*/ */
mmio_write_32(PMU_BASE + PMU_SCU_L_PWRDN_CNT, CYCL_24M_CNT_US(1));
mmio_write_32(PMU_BASE + PMU_SCU_L_PWRUP_CNT, CYCL_24M_CNT_US(1));
mmio_write_32(PMU_BASE + PMU_SCU_B_PWRDN_CNT, CYCL_24M_CNT_US(1)); mmio_write_32(PMU_BASE + PMU_SCU_B_PWRDN_CNT, CYCL_24M_CNT_US(1));
mmio_write_32(PMU_BASE + PMU_SCU_B_PWRUP_CNT, CYCL_24M_CNT_US(1)); mmio_write_32(PMU_BASE + PMU_SCU_B_PWRUP_CNT, CYCL_24M_CNT_US(1));
mmio_write_32(PMU_BASE + PMU_GPU_PWRDN_CNT, CYCL_24M_CNT_US(1)); mmio_write_32(PMU_BASE + PMU_GPU_PWRDN_CNT, CYCL_24M_CNT_US(1));
...@@ -837,6 +827,8 @@ static void sys_slp_config(void) ...@@ -837,6 +827,8 @@ static void sys_slp_config(void)
BIT(PMU_DDRIO1_RET_EN) | BIT(PMU_DDRIO1_RET_EN) |
BIT(PMU_DDRIO_RET_HW_DE_REQ) | BIT(PMU_DDRIO_RET_HW_DE_REQ) |
BIT(PMU_CENTER_PD_EN) | BIT(PMU_CENTER_PD_EN) |
BIT(PMU_PERILP_PD_EN) |
BIT(PMU_CLK_PERILP_SRC_GATE_EN) |
BIT(PMU_PLL_PD_EN) | BIT(PMU_PLL_PD_EN) |
BIT(PMU_CLK_CENTER_SRC_GATE_EN) | BIT(PMU_CLK_CENTER_SRC_GATE_EN) |
BIT(PMU_OSC_DIS) | BIT(PMU_OSC_DIS) |
...@@ -1050,6 +1042,36 @@ static void m0_configure_suspend(void) ...@@ -1050,6 +1042,36 @@ static void m0_configure_suspend(void)
mmio_write_32(M0_PARAM_ADDR + PARAM_M0_FUNC, M0_FUNC_SUSPEND); mmio_write_32(M0_PARAM_ADDR + PARAM_M0_FUNC, M0_FUNC_SUSPEND);
} }
void sram_save(void)
{
size_t text_size = (char *)&__bl31_sram_text_real_end -
(char *)&__bl31_sram_text_start;
size_t data_size = (char *)&__bl31_sram_data_real_end -
(char *)&__bl31_sram_data_start;
size_t incbin_size = (char *)&__sram_incbin_real_end -
(char *)&__sram_incbin_start;
memcpy(&store_sram[0], &__bl31_sram_text_start, text_size);
memcpy(&store_sram[text_size], &__bl31_sram_data_start, data_size);
memcpy(&store_sram[text_size + data_size], &__sram_incbin_start,
incbin_size);
}
void sram_restore(void)
{
size_t text_size = (char *)&__bl31_sram_text_real_end -
(char *)&__bl31_sram_text_start;
size_t data_size = (char *)&__bl31_sram_data_real_end -
(char *)&__bl31_sram_data_start;
size_t incbin_size = (char *)&__sram_incbin_real_end -
(char *)&__sram_incbin_start;
memcpy(&__bl31_sram_text_start, &store_sram[0], text_size);
memcpy(&__bl31_sram_data_start, &store_sram[text_size], data_size);
memcpy(&__sram_incbin_start, &store_sram[text_size + data_size],
incbin_size);
}
int rockchip_soc_sys_pwr_dm_suspend(void) int rockchip_soc_sys_pwr_dm_suspend(void)
{ {
uint32_t wait_cnt = 0; uint32_t wait_cnt = 0;
...@@ -1067,6 +1089,8 @@ int rockchip_soc_sys_pwr_dm_suspend(void) ...@@ -1067,6 +1089,8 @@ int rockchip_soc_sys_pwr_dm_suspend(void)
BIT(PMU_CLR_CCIM0) | BIT(PMU_CLR_CCIM0) |
BIT(PMU_CLR_CCIM1) | BIT(PMU_CLR_CCIM1) |
BIT(PMU_CLR_CENTER) | BIT(PMU_CLR_CENTER) |
BIT(PMU_CLR_PERILP) |
BIT(PMU_CLR_PERILPM0) |
BIT(PMU_CLR_GIC)); BIT(PMU_CLR_GIC));
sys_slp_config(); sys_slp_config();
...@@ -1077,8 +1101,8 @@ int rockchip_soc_sys_pwr_dm_suspend(void) ...@@ -1077,8 +1101,8 @@ int rockchip_soc_sys_pwr_dm_suspend(void)
pmu_sgrf_rst_hld(); pmu_sgrf_rst_hld();
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
(PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) | ((uintptr_t)&pmu_cpuson_entrypoint >>
CPU_BOOT_ADDR_WMASK); CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK);
mmio_write_32(PMU_BASE + PMU_ADB400_CON, mmio_write_32(PMU_BASE + PMU_ADB400_CON,
BIT_WITH_WMSK(PMU_PWRDWN_REQ_CORE_B_2GIC_SW) | BIT_WITH_WMSK(PMU_PWRDWN_REQ_CORE_B_2GIC_SW) |
...@@ -1112,6 +1136,7 @@ int rockchip_soc_sys_pwr_dm_suspend(void) ...@@ -1112,6 +1136,7 @@ int rockchip_soc_sys_pwr_dm_suspend(void)
suspend_apio(); suspend_apio();
suspend_gpio(); suspend_gpio();
sram_save();
return 0; return 0;
} }
...@@ -1193,6 +1218,8 @@ int rockchip_soc_sys_pwr_dm_resume(void) ...@@ -1193,6 +1218,8 @@ int rockchip_soc_sys_pwr_dm_resume(void)
BIT(PMU_CLR_CCIM0) | BIT(PMU_CLR_CCIM0) |
BIT(PMU_CLR_CCIM1) | BIT(PMU_CLR_CCIM1) |
BIT(PMU_CLR_CENTER) | BIT(PMU_CLR_CENTER) |
BIT(PMU_CLR_PERILP) |
BIT(PMU_CLR_PERILPM0) |
BIT(PMU_CLR_GIC)); BIT(PMU_CLR_GIC));
plat_rockchip_gic_cpuif_enable(); plat_rockchip_gic_cpuif_enable();
...@@ -1245,6 +1272,36 @@ void __dead2 rockchip_soc_system_off(void) ...@@ -1245,6 +1272,36 @@ void __dead2 rockchip_soc_system_off(void)
; ;
} }
void rockchip_plat_mmu_el3(void)
{
size_t sram_size;
/* sram.text size */
sram_size = (char *)&__bl31_sram_text_end -
(char *)&__bl31_sram_text_start;
mmap_add_region((unsigned long)&__bl31_sram_text_start,
(unsigned long)&__bl31_sram_text_start,
sram_size, MT_MEMORY | MT_RO | MT_SECURE);
/* sram.data size */
sram_size = (char *)&__bl31_sram_data_end -
(char *)&__bl31_sram_data_start;
mmap_add_region((unsigned long)&__bl31_sram_data_start,
(unsigned long)&__bl31_sram_data_start,
sram_size, MT_MEMORY | MT_RW | MT_SECURE);
sram_size = (char *)&__bl31_sram_stack_end -
(char *)&__bl31_sram_stack_start;
mmap_add_region((unsigned long)&__bl31_sram_stack_start,
(unsigned long)&__bl31_sram_stack_start,
sram_size, MT_MEMORY | MT_RW | MT_SECURE);
sram_size = (char *)&__sram_incbin_end - (char *)&__sram_incbin_start;
mmap_add_region((unsigned long)&__sram_incbin_start,
(unsigned long)&__sram_incbin_start,
sram_size, MT_NON_CACHEABLE | MT_RW | MT_SECURE);
}
void plat_rockchip_pmu_init(void) void plat_rockchip_pmu_init(void)
{ {
uint32_t cpu; uint32_t cpu;
...@@ -1260,12 +1317,6 @@ void plat_rockchip_pmu_init(void) ...@@ -1260,12 +1317,6 @@ void plat_rockchip_pmu_init(void)
for (cpu = 0; cpu < PLATFORM_CLUSTER_COUNT; cpu++) for (cpu = 0; cpu < PLATFORM_CLUSTER_COUNT; cpu++)
clst_warmboot_data[cpu] = 0; clst_warmboot_data[cpu] = 0;
psram_sleep_cfg->ddr_func = (uint64_t)dmc_restore;
psram_sleep_cfg->ddr_data = (uint64_t)&sdram_config;
psram_sleep_cfg->ddr_flag = 0x01;
psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
/* config cpu's warm boot address */ /* config cpu's warm boot address */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
(cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) | (cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) |
......
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