diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c index 9c68b3bc1f7b1afd422e5ae5d1c7cc722dcb6823..a756f40dbec63c738379d3f260e326544d8dd31b 100644 --- a/plat/rockchip/common/aarch64/platform_common.c +++ b/plat/rockchip/common/aarch64/platform_common.c @@ -44,7 +44,7 @@ static const int cci_map[] = { coh_limit - coh_start, \ MT_DEVICE | MT_RW | MT_SECURE); \ mmap_add(plat_rk_mmap); \ - rockchip_plat_sram_mmu_el##_el(); \ + rockchip_plat_mmu_el##_el(); \ init_xlat_tables(); \ \ enable_mmu_el ## _el(0); \ diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c index 71d66c9741727857546f90a472f75eb4fba7e44e..f7564e81ca3bf090b0db09bd4616944486cf3400 100644 --- a/plat/rockchip/common/bl31_plat_setup.c +++ b/plat/rockchip/common/bl31_plat_setup.c @@ -83,8 +83,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, bl32_ep_info = *from_bl2->bl32_ep_info; bl33_ep_info = *from_bl2->bl33_ep_info; - plat_rockchip_pmusram_prepare(); - /* there may have some board sepcific message need to initialize */ params_early_setup(plat_params_from_bl2); } diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h index 867d9add9497246b78f78d1f6c4ff7e240b9f011..b9540f23e6b0499cdb22489ffa865ad4640ea038 100644 --- a/plat/rockchip/common/include/plat_private.h +++ b/plat/rockchip/common/include/plat_private.h @@ -15,12 +15,18 @@ #define __sramdata __attribute__((section(".sram.data"))) #define __sramconst __attribute__((section(".sram.rodata"))) -#define __sramfunc __attribute__((section(".sram.text"))) \ - __attribute__((noinline)) +#define __sramfunc __attribute__((section(".sram.text"))) + +#define __pmusramdata __attribute__((section(".pmusram.data"))) +#define __pmusramconst __attribute__((section(".pmusram.rodata"))) +#define __pmusramfunc __attribute__((section(".pmusram.text"))) extern uint32_t __bl31_sram_text_start, __bl31_sram_text_end; extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end; +extern uint32_t __bl31_sram_stack_start, __bl31_sram_stack_end; +extern uint32_t __bl31_sram_text_real_end, __bl31_sram_data_real_end; extern uint32_t __sram_incbin_start, __sram_incbin_end; +extern uint32_t __sram_incbin_real_end; /****************************************************************************** @@ -73,7 +79,6 @@ void plat_rockchip_gic_cpuif_enable(void); void plat_rockchip_gic_cpuif_disable(void); void plat_rockchip_gic_pcpu_init(void); -void plat_rockchip_pmusram_prepare(void); void plat_rockchip_pmu_init(void); void plat_rockchip_soc_init(void); uintptr_t plat_get_sec_entrypoint(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 void *pmu_cpuson_entrypoint_start; -extern void *pmu_cpuson_entrypoint_end; +extern void *pmu_cpuson_entrypoint; extern uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT]; extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT]; extern const mmap_region_t plat_rk_mmap[]; -void rockchip_plat_sram_mmu_el3(void); -void plat_rockchip_mem_prepare(void); +void rockchip_plat_mmu_el3(void); #endif /* __ASSEMBLY__ */ diff --git a/plat/rockchip/common/pmusram/pmu_sram.c b/plat/rockchip/common/pmusram/pmu_sram.c deleted file mode 100644 index 05ee762e9e63ac9eb7952742ee6e910ba7d43230..0000000000000000000000000000000000000000 --- a/plat/rockchip/common/pmusram/pmu_sram.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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(); -} diff --git a/plat/rockchip/common/pmusram/pmu_sram.h b/plat/rockchip/common/pmusram/pmu_sram.h deleted file mode 100644 index 24a1c25e8e6bd3af67ed342a9c9fa236ed6d3cec..0000000000000000000000000000000000000000 --- a/plat/rockchip/common/pmusram/pmu_sram.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 diff --git a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S b/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S index 8f175c3c75da8f43a8bcbbfe5f402c3257935b66..22bdffcae1f0ea38873020e95a5f49804828f48e 100644 --- a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S +++ b/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S @@ -7,23 +7,30 @@ #include <arch.h> #include <asm_macros.S> #include <platform_def.h> -#include <pmu_sram.h> - .globl pmu_cpuson_entrypoint_start - .globl pmu_cpuson_entrypoint_end + .globl pmu_cpuson_entrypoint + .macro pmusram_entry_func _name + .section .pmusram.entry, "ax" + .type \_name, %function + .func \_name + .cfi_startproc + \_name: + .endm -func pmu_cpuson_entrypoint -pmu_cpuson_entrypoint_start: - ldr x5, psram_data +pmusram_entry_func pmu_cpuson_entrypoint + +#if PSRAM_CHECK_WAKEUP_CPU check_wake_cpus: mrs x0, MPIDR_EL1 and x1, x0, #MPIDR_CPU_MASK and x0, x0, #MPIDR_CLUSTER_MASK orr x0, x0, x1 + /* primary_cpu */ - ldr w1, [x5, #PSRAM_DT_MPIDR] + ldr w1, boot_mpidr cmp w0, w1 b.eq sys_wakeup + /* * If the core is not the primary cpu, * force the core into wfe. @@ -32,25 +39,15 @@ wfe_loop: wfe b wfe_loop sys_wakeup: - /* check ddr flag for resume ddr */ - ldr w2, [x5, #PSRAM_DT_DDRFLAG] - cmp w2, #0x0 - b.eq sys_resume +#endif + +#if PSRAM_DO_DDR_RESUME ddr_resume: - ldr x2, [x5, #PSRAM_DT_SP] - mov sp, x2 - ldr x1, [x5, #PSRAM_DT_DDR_FUNC] - ldr x0, [x5, #PSRAM_DT_DDR_DATA] - blr x1 + ldr x2, =__bl31_sram_stack_end + mov sp, x2 + bl dmc_restore +#endif + bl sram_restore sys_resume: - ldr x1, sys_wakeup_entry - br x1 - - .align 3 -psram_data: - .quad PSRAM_DT_BASE -sys_wakeup_entry: - .quad psci_entrypoint -pmu_cpuson_entrypoint_end: - .word 0 + bl psci_entrypoint endfunc pmu_cpuson_entrypoint diff --git a/plat/rockchip/rk3328/drivers/pmu/pmu.c b/plat/rockchip/rk3328/drivers/pmu/pmu.c index 59d399be4b614dc6b399b0f9acdef8c34f8a1908..60f36d31b8ba8f49ef8699acb03519860290db29 100644 --- a/plat/rockchip/rk3328/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3328/drivers/pmu/pmu.c @@ -16,16 +16,12 @@ #include <platform.h> #include <platform_def.h> #include <plat_private.h> -#include <pmu_sram.h> #include <pmu.h> #include <rk3328_def.h> #include <pmu_com.h> 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 __sramdata struct rk3328_sleep_sram_data sram_data; @@ -34,22 +30,6 @@ static uint32_t cpu_warm_boot_addr; #pragma weak rk3328_pmic_suspend #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) { uint32_t pd_reg, apm_reg; @@ -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) { uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr); @@ -495,11 +485,6 @@ __sramfunc void rk3328_pmic_resume(void) 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) { sram_data.pd_sr_idle_save = mmio_read_32(DDR_UPCTL_BASE + @@ -538,7 +523,7 @@ static __sramfunc void ddr_suspend(void) dpll_suspend(); } -static __sramfunc void ddr_resume(void) +__sramfunc void dmc_restore(void) { dpll_resume(); @@ -574,7 +559,7 @@ static __sramfunc void sram_dbg_uart_suspend(void) 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 */ mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(16), 0x20000000); @@ -610,7 +595,7 @@ __sramfunc void sram_suspend(void) disable_mmu_icache_el3(); 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); /* ddr self-refresh and gating phy */ @@ -623,28 +608,8 @@ __sramfunc void sram_suspend(void) 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) { - rockchip_set_sram_sp(PSRAM_DT_BASE); - sram_suspend(); /* should never reach here */ @@ -671,6 +636,11 @@ int rockchip_soc_sys_pwr_dm_resume(void) return 0; } +void rockchip_plat_mmu_el3(void) +{ + /* TODO: support the el3 for rk3328 SoCs */ +} + void plat_rockchip_pmu_init(void) { uint32_t cpu; @@ -679,10 +649,6 @@ void plat_rockchip_pmu_init(void) cpuson_flags[cpu] = 0; 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 */ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), diff --git a/plat/rockchip/rk3328/include/plat.ld.S b/plat/rockchip/rk3328/include/plat.ld.S index ff17572d0cfa57cae6231892f5689a48ff5bc173..b3559b20f6681cdd9abbe91032e9fde7c66fd8a8 100644 --- a/plat/rockchip/rk3328/include/plat.ld.S +++ b/plat/rockchip/rk3328/include/plat.ld.S @@ -1,5 +1,5 @@ /* - * 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 */ @@ -7,39 +7,31 @@ #define __ROCKCHIP_PLAT_LD_S__ MEMORY { - SRAM (rwx): ORIGIN = SRAM_LDS_BASE, LENGTH = SRAM_LDS_SIZE + PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE } SECTIONS { - . = SRAM_LDS_BASE; - ASSERT(. == ALIGN(4096), - "SRAM_BASE address is not aligned on a page boundary.") + . = PMUSRAM_BASE; /* - * The SRAM space allocation for RK3328 - * ---------------- - * | sram text - * ---------------- - * | sram data - * ---------------- + * pmu_cpuson_entrypoint request address + * align 64K when resume, so put it in the + * start of pmusram */ - .text_sram : ALIGN(4096) { - __bl31_sram_text_start = .; - *(.sram.text) - *(.sram.rodata) - . = ALIGN(4096); - __bl31_sram_text_end = .; - } >SRAM + .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 = .; - .data_sram : ALIGN(4096) { - __bl31_sram_data_start = .; - *(.sram.data) - . = ALIGN(4096); - __bl31_sram_data_end = .; - } >SRAM - __sram_incbin_start = .; - __sram_incbin_end = .; + } >PMUSRAM } #endif /* __ROCKCHIP_PLAT_LD_S__ */ diff --git a/plat/rockchip/rk3328/include/platform_def.h b/plat/rockchip/rk3328/include/platform_def.h index 1f49fcdc965c2df5ac029b7e2849bc8ff1169ded..7304dcfad8fa6af922130fa5c2d048b5c56e077a 100644 --- a/plat/rockchip/rk3328/include/platform_def.h +++ b/plat/rockchip/rk3328/include/platform_def.h @@ -120,4 +120,7 @@ #define PLAT_RK_PRIMARY_CPU 0x0 +#define PSRAM_DO_DDR_RESUME 0 +#define PSRAM_CHECK_WAKEUP_CPU 0 + #endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk index b81d746b11280064aed1c6b9e88caa606c9d5d59..8863fb4ffc3f465378e6e4fb386962d4791c207e 100644 --- a/plat/rockchip/rk3328/platform.mk +++ b/plat/rockchip/rk3328/platform.mk @@ -41,7 +41,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \ ${RK_PLAT_COMMON}/aarch64/plat_helpers.S \ ${RK_PLAT_COMMON}/bl31_plat_setup.c \ - ${RK_PLAT_COMMON}/pmusram/pmu_sram.c \ ${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \ ${RK_PLAT_COMMON}/plat_pm.c \ ${RK_PLAT_COMMON}/plat_topology.c \ diff --git a/plat/rockchip/rk3368/drivers/pmu/pmu.c b/plat/rockchip/rk3368/drivers/pmu/pmu.c index e5e680511a15707f95da7c5b64d77d743683088d..1767967f34178188d480bfb8cb4db05f81f2e0d2 100644 --- a/plat/rockchip/rk3368/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3368/drivers/pmu/pmu.c @@ -14,7 +14,6 @@ #include <platform_def.h> #include <plat_private.h> #include <rk3368_def.h> -#include <pmu_sram.h> #include <soc.h> #include <pmu.h> #include <ddr_rk3368.h> @@ -22,9 +21,6 @@ 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; void rk3368_flash_l2_b(void) @@ -223,54 +219,19 @@ static void pmu_sleep_mode_config(void) dsb(); } -static void ddr_suspend_save(void) -{ - ddr_reg_save(1, psram_sleep_cfg->ddr_data); -} - static void pmu_set_sleep_mode(void) { - ddr_suspend_save(); pmu_sleep_mode_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_SFT_CON, pmu_sft_glbl_int_dis_b); pmu_scu_b_pwrdn(); mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), - (PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) | - CPU_BOOT_ADDR_WMASK); + ((uintptr_t)&pmu_cpuson_entrypoint >> + CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK); mmio_write_32(SGRF_BASE + SGRF_SOC_CON(2), - (PMUSRAM_BASE >> 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; + ((uintptr_t)&pmu_cpuson_entrypoint >> + CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK); } static int cpus_id_power_domain(uint32_t cluster, @@ -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) { uint32_t cpu, cluster; @@ -375,11 +346,14 @@ int rockchip_soc_sys_pwr_dm_suspend(void) nonboot_cpus_off(); pmu_set_sleep_mode(); - psram_sleep_cfg->ddr_flag = 0; - return 0; } +void rockchip_plat_mmu_el3(void) +{ + /* TODO: support the el3 for rk3368 SoCs */ +} + void plat_rockchip_pmu_init(void) { uint32_t cpu; @@ -390,8 +364,6 @@ void plat_rockchip_pmu_init(void) for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) cpuson_flags[cpu] = 0; - psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff; - nonboot_cpus_off(); INFO("%s(%d): pd status %x\n", __func__, __LINE__, mmio_read_32(PMU_BASE + PMU_PWRDN_ST)); diff --git a/plat/rockchip/rk3368/include/plat.ld.S b/plat/rockchip/rk3368/include/plat.ld.S new file mode 100644 index 0000000000000000000000000000000000000000..b3559b20f6681cdd9abbe91032e9fde7c66fd8a8 --- /dev/null +++ b/plat/rockchip/rk3368/include/plat.ld.S @@ -0,0 +1,37 @@ +/* + * 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__ */ diff --git a/plat/rockchip/rk3368/include/platform_def.h b/plat/rockchip/rk3368/include/platform_def.h index 053f6fe397f93a3ebcd6ccec16185c209190fb85..07b91e2683f3c0564771c47ee61fb3ebb5b793f3 100644 --- a/plat/rockchip/rk3368/include/platform_def.h +++ b/plat/rockchip/rk3368/include/platform_def.h @@ -122,4 +122,7 @@ #define PLAT_RK_PRIMARY_CPU 0x0 +#define PSRAM_DO_DDR_RESUME 0 +#define PSRAM_CHECK_WAKEUP_CPU 0 + #endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/rockchip/rk3368/platform.mk b/plat/rockchip/rk3368/platform.mk index 7837af98d8c8c563b28ce74c284c84e2deed01b2..f6960cf46cad9b305766870329406bf984c88c06 100644 --- a/plat/rockchip/rk3368/platform.mk +++ b/plat/rockchip/rk3368/platform.mk @@ -39,7 +39,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ${RK_PLAT_COMMON}/bl31_plat_setup.c \ ${RK_PLAT_COMMON}/params_setup.c \ ${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \ - ${RK_PLAT_COMMON}/pmusram/pmu_sram.c \ ${RK_PLAT_COMMON}/plat_pm.c \ ${RK_PLAT_COMMON}/plat_topology.c \ ${RK_PLAT_COMMON}/aarch64/platform_common.c \ @@ -50,3 +49,5 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ${RK_PLAT_SOC}/drivers/ddr/ddr_rk3368.c \ ENABLE_PLAT_COMPAT := 0 + +$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) diff --git a/plat/rockchip/rk3399/drivers/dram/dfs.c b/plat/rockchip/rk3399/drivers/dram/dfs.c index 28d0d6a7a915e383150105be4f56c612d44381b2..481dcc64edae5b56b45fe13e820f29089e62523d 100644 --- a/plat/rockchip/rk3399/drivers/dram/dfs.c +++ b/plat/rockchip/rk3399/drivers/dram/dfs.c @@ -54,6 +54,7 @@ struct rk3399_saved_status { static struct rk3399_dram_status rk3399_dram_status; static struct rk3399_saved_status rk3399_suspend_status; static uint32_t wrdqs_delay_val[2][2][4]; +static uint32_t rddqs_delay_ps; static struct rk3399_sdram_default_config ddr3_default_config = { .bl = 8, @@ -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); /* PHY_GTLVL_LAT_ADJ_START */ /* 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, 208), 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) void dram_dfs_init(void) { uint32_t trefi0, trefi1, boot_freq; + uint32_t rddqs_adjust, rddqs_slave; /* get sdram config for os reg */ get_dram_drv_odt_val(sdram_config.dramtype, @@ -1875,8 +1877,31 @@ void dram_dfs_init(void) /* Disable multicast */ mmio_clrbits_32(PHY_REG(0, 896), 1); mmio_clrbits_32(PHY_REG(1, 896), 1); - 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; + } } /* diff --git a/plat/rockchip/rk3399/drivers/dram/dram.c b/plat/rockchip/rk3399/drivers/dram/dram.c index fbf311074072507d5853153045e40dd7e7f6acae..ad79f9efb5c90b38705971c46b3c85545ee45754 100644 --- a/plat/rockchip/rk3399/drivers/dram/dram.c +++ b/plat/rockchip/rk3399/drivers/dram/dram.c @@ -10,7 +10,7 @@ #include <soc.h> #include <rk3399_def.h> -__sramdata struct rk3399_sdram_params sdram_config; +__pmusramdata struct rk3399_sdram_params sdram_config; void dram_init(void) { diff --git a/plat/rockchip/rk3399/drivers/dram/dram.h b/plat/rockchip/rk3399/drivers/dram/dram.h index 08893d4eaf58e7ad620e813796149a5fe3873adf..fede7eef8338d073dfbad71f4f6f4c3c6fa98dcf 100644 --- a/plat/rockchip/rk3399/drivers/dram/dram.h +++ b/plat/rockchip/rk3399/drivers/dram/dram.h @@ -24,7 +24,17 @@ struct rk3399_ddr_pctl_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 { diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c index 1ed3f5466fd90619e013472a6ee2ed88fbb218e6..617e39baad3994df5fa7eb89bd84f86d9cd6bf63 100644 --- a/plat/rockchip/rk3399/drivers/dram/suspend.c +++ b/plat/rockchip/rk3399/drivers/dram/suspend.c @@ -45,7 +45,8 @@ /* * 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--) { 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) } } -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 @@ -64,7 +79,7 @@ static __sramfunc uint32_t sram_get_timer_value(void) 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; @@ -81,7 +96,7 @@ static __sramfunc void sram_udelay(uint32_t 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: @@ -98,7 +113,7 @@ static __sramfunc void configure_sgrf(void) 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) { channel &= 0x1; @@ -109,7 +124,7 @@ static __sramfunc void rkclk_ddr_reset(uint32_t channel, uint32_t ctl, 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); sram_udelay(10); @@ -119,76 +134,45 @@ static __sramfunc void phy_pctrl_reset(uint32_t ch) 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) { - /* 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); - } -} + uint32_t byte; -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 */ - mmio_clrsetbits_32(PHY_REG(ch, 8), 0x1 << 24, rank << 24); - mmio_clrsetbits_32(PHY_REG(ch, 136), 0x1 << 24, rank << 24); - mmio_clrsetbits_32(PHY_REG(ch, 264), 0x1 << 24, rank << 24); - mmio_clrsetbits_32(PHY_REG(ch, 392), 0x1 << 24, rank << 24); + for (byte = 0; byte < 4; byte++) + mmio_clrsetbits_32(PHY_REG(ch, 8 + (128 * byte)), 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 */ if ((mmio_read_32(PHY_REG(ch, 84)) >> 16) & 1) 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; - /* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */ - mmio_setbits_32(PHY_REG(ch, 896), 1); - - /* - * PHY_8/136/264/392 - * phy_per_cs_training_multicast_en_X 1bit offset_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++) + for (byte = 0; byte < 4; byte++) { + /* + * 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, 63 + (128 * byte)), 0xffff << 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 */ 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, uint32_t training_flag) { @@ -433,7 +417,8 @@ static __sramfunc int data_training(uint32_t ch, 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) { /* only need to set ddrconfig */ @@ -455,7 +440,8 @@ static __sramfunc void set_ddrconfig(struct rk3399_sdram_params *sdram_params, ((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; @@ -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); } -static __sramfunc void pctl_cfg(uint32_t ch, +static __pmusramfunc void pctl_cfg(uint32_t ch, struct rk3399_sdram_params *sdram_params) { 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; - 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: @@ -509,9 +495,8 @@ static __sramfunc void pctl_cfg(uint32_t ch, sram_regcpy(PI_REG(ch, 0), (uintptr_t)¶ms_pi[0], PI_REG_NUM); - mmio_write_32(PHY_REG(ch, 910), params_phy[910]); - mmio_write_32(PHY_REG(ch, 911), params_phy[911]); - mmio_write_32(PHY_REG(ch, 912), params_phy[912]); + sram_regcpy(PHY_REG(ch, 910), (uintptr_t)&phy_regs->phy896[910 - 896], + 3); mmio_clrsetbits_32(CTL_REG(ch, 68), PWRUP_SREFRESH_EXIT, PWRUP_SREFRESH_EXIT); @@ -538,17 +523,18 @@ static __sramfunc void pctl_cfg(uint32_t ch, break; } - sram_regcpy(PHY_REG(ch, 896), (uintptr_t)¶ms_phy[896], 63); - sram_regcpy(PHY_REG(ch, 0), (uintptr_t)¶ms_phy[0], 91); - sram_regcpy(PHY_REG(ch, 128), (uintptr_t)¶ms_phy[128], 91); - sram_regcpy(PHY_REG(ch, 256), (uintptr_t)¶ms_phy[256], 91); - sram_regcpy(PHY_REG(ch, 384), (uintptr_t)¶ms_phy[384], 91); - sram_regcpy(PHY_REG(ch, 512), (uintptr_t)¶ms_phy[512], 38); - sram_regcpy(PHY_REG(ch, 640), (uintptr_t)¶ms_phy[640], 38); - sram_regcpy(PHY_REG(ch, 768), (uintptr_t)¶ms_phy[768], 38); + sram_regcpy(PHY_REG(ch, 896), (uintptr_t)&phy_regs->phy896[0], 63); + + for (i = 0; i < 4; i++) + sram_regcpy(PHY_REG(ch, 128 * i), + (uintptr_t)&phy_regs->phy0[i][0], 91); + + for (i = 0; i < 3; i++) + 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) { uint32_t ch, ch_count; @@ -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 * 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) { uint32_t count; @@ -652,15 +638,15 @@ static __sramfunc int pctl_start(uint32_t channel_mask, void dmc_save(void) { struct rk3399_sdram_params *sdram_params = &sdram_config; + struct rk3399_ddr_publ_regs *phy_regs; uint32_t *params_ctl; uint32_t *params_pi; - uint32_t *params_phy; 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_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; tmp = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)); @@ -676,25 +662,26 @@ void dmc_save(void) 0x7) != 0) ? 1 : 0; /* copy the registers CTL PI and PHY */ - sram_regcpy((uintptr_t)¶ms_ctl[0], CTL_REG(0, 0), CTL_REG_NUM); + dram_regcpy((uintptr_t)¶ms_ctl[0], CTL_REG(0, 0), CTL_REG_NUM); /* mask DENALI_CTL_00_DATA.START, only copy here, will trigger later */ params_ctl[0] &= ~(0x1 << 0); - sram_regcpy((uintptr_t)¶ms_pi[0], PI_REG(0, 0), + dram_regcpy((uintptr_t)¶ms_pi[0], PI_REG(0, 0), PI_REG_NUM); /* mask DENALI_PI_00_DATA.START, only copy here, will trigger later*/ params_pi[0] &= ~(0x1 << 0); - sram_regcpy((uintptr_t)¶ms_phy[0], PHY_REG(0, 0), 91); - sram_regcpy((uintptr_t)¶ms_phy[128], PHY_REG(0, 128), 91); - sram_regcpy((uintptr_t)¶ms_phy[256], PHY_REG(0, 256), 91); - sram_regcpy((uintptr_t)¶ms_phy[384], PHY_REG(0, 384), 91); - sram_regcpy((uintptr_t)¶ms_phy[512], PHY_REG(0, 512), 38); - sram_regcpy((uintptr_t)¶ms_phy[640], PHY_REG(0, 640), 38); - sram_regcpy((uintptr_t)¶ms_phy[768], PHY_REG(0, 768), 38); - sram_regcpy((uintptr_t)¶ms_phy[896], PHY_REG(0, 896), 63); + for (i = 0; i < 4; i++) + dram_regcpy((uintptr_t)&phy_regs->phy0[i][0], + PHY_REG(0, 128 * i), 91); + + for (i = 0; i < 3; i++) + dram_regcpy((uintptr_t)&phy_regs->phy512[i][0], + PHY_REG(0, 512 + 128 * i), 38); + + dram_regcpy((uintptr_t)&phy_regs->phy896[0], PHY_REG(0, 896), 63); for (ch = 0; ch < sdram_params->num_channels; ch++) { for (byte = 0; byte < 4; byte++) @@ -703,13 +690,13 @@ void dmc_save(void) } /* set DENALI_PHY_957_DATA.PHY_DLL_RST_EN = 0x1 */ - params_phy[957] &= ~(0x3 << 24); - params_phy[957] |= 1 << 24; - params_phy[896] |= 1; - params_phy[896] &= ~(0x3 << 8); + phy_regs->phy896[957 - 896] &= ~(0x3 << 24); + phy_regs->phy896[957 - 896] |= 1 << 24; + phy_regs->phy896[0] |= 1; + phy_regs->phy896[0] &= ~(0x3 << 8); } -__sramfunc void dmc_restore(void) +__pmusramfunc void dmc_restore(void) { struct rk3399_sdram_params *sdram_params = &sdram_config; uint32_t channel_mask = 0; @@ -720,10 +707,6 @@ __sramfunc void dmc_restore(void) retry: for (channel = 0; channel < sdram_params->num_channels; 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); } diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.h b/plat/rockchip/rk3399/drivers/dram/suspend.h index 03df421fc64ebb3c0478240f4ca813c02080c5ac..77f9c317b13858956d94a6cd24dba3651af9fc75 100644 --- a/plat/rockchip/rk3399/drivers/dram/suspend.h +++ b/plat/rockchip/rk3399/drivers/dram/suspend.h @@ -20,7 +20,6 @@ #define PI_FULL_TRAINING (0xff) void dmc_save(void); -__sramfunc void dmc_restore(void); -__sramfunc void sram_regcpy(uintptr_t dst, uintptr_t src, uint32_t num); +__pmusramfunc void dmc_restore(void); #endif /* __DRAM_H__ */ diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index 9c0a29c1f8a0f7530a133b66e6b6b840a594badb..f6c47f433a6873a166dfeba30a6a4310b6a232a9 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -19,9 +19,9 @@ #include <plat_params.h> #include <plat_private.h> #include <rk3399_def.h> -#include <pmu_sram.h> #include <secure.h> #include <soc.h> +#include <string.h> #include <pmu.h> #include <pmu_com.h> #include <pwm.h> @@ -30,10 +30,8 @@ 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 char store_sram[SRAM_BIN_LIMIT + SRAM_TEXT_LIMIT + SRAM_DATA_LIMIT]; /* * There are two ways to powering on or off on core. @@ -411,24 +409,6 @@ static void pmu_scu_b_pwrup(void) 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) { assert(cpu_id < PLATFORM_CORE_COUNT); @@ -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_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. * @@ -788,8 +780,6 @@ static void init_pmu_counts(void) * counts here. After all ATF controls all these other bits and also * 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_PWRUP_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) BIT(PMU_DDRIO1_RET_EN) | BIT(PMU_DDRIO_RET_HW_DE_REQ) | BIT(PMU_CENTER_PD_EN) | + BIT(PMU_PERILP_PD_EN) | + BIT(PMU_CLK_PERILP_SRC_GATE_EN) | BIT(PMU_PLL_PD_EN) | BIT(PMU_CLK_CENTER_SRC_GATE_EN) | BIT(PMU_OSC_DIS) | @@ -1050,6 +1042,36 @@ static void m0_configure_suspend(void) 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) { uint32_t wait_cnt = 0; @@ -1067,6 +1089,8 @@ int rockchip_soc_sys_pwr_dm_suspend(void) BIT(PMU_CLR_CCIM0) | BIT(PMU_CLR_CCIM1) | BIT(PMU_CLR_CENTER) | + BIT(PMU_CLR_PERILP) | + BIT(PMU_CLR_PERILPM0) | BIT(PMU_CLR_GIC)); sys_slp_config(); @@ -1077,8 +1101,8 @@ int rockchip_soc_sys_pwr_dm_suspend(void) pmu_sgrf_rst_hld(); mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), - (PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) | - CPU_BOOT_ADDR_WMASK); + ((uintptr_t)&pmu_cpuson_entrypoint >> + CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK); mmio_write_32(PMU_BASE + PMU_ADB400_CON, BIT_WITH_WMSK(PMU_PWRDWN_REQ_CORE_B_2GIC_SW) | @@ -1112,6 +1136,7 @@ int rockchip_soc_sys_pwr_dm_suspend(void) suspend_apio(); suspend_gpio(); + sram_save(); return 0; } @@ -1193,6 +1218,8 @@ int rockchip_soc_sys_pwr_dm_resume(void) BIT(PMU_CLR_CCIM0) | BIT(PMU_CLR_CCIM1) | BIT(PMU_CLR_CENTER) | + BIT(PMU_CLR_PERILP) | + BIT(PMU_CLR_PERILPM0) | BIT(PMU_CLR_GIC)); plat_rockchip_gic_cpuif_enable(); @@ -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) { uint32_t cpu; @@ -1260,12 +1317,6 @@ void plat_rockchip_pmu_init(void) for (cpu = 0; cpu < PLATFORM_CLUSTER_COUNT; cpu++) 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 */ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), (cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) | diff --git a/plat/rockchip/rk3399/include/plat.ld.S b/plat/rockchip/rk3399/include/plat.ld.S index 49206bea6ccb18b41a2a5d71c2cd4feab59101c7..c42d9a9aa36411e9fbdb00aa59ecac47940ea256 100644 --- a/plat/rockchip/rk3399/include/plat.ld.S +++ b/plat/rockchip/rk3399/include/plat.ld.S @@ -8,6 +8,7 @@ MEMORY { SRAM (rwx): ORIGIN = SRAM_BASE, LENGTH = SRAM_SIZE + PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE } SECTIONS @@ -29,24 +30,60 @@ SECTIONS .incbin_sram : ALIGN(4096) { __sram_incbin_start = .; *(.sram.incbin) + __sram_incbin_real_end = .; . = ALIGN(4096); __sram_incbin_end = .; } >SRAM + ASSERT((__sram_incbin_real_end - __sram_incbin_start) <= + SRAM_BIN_LIMIT, ".incbin_sram has exceeded its limit") .text_sram : ALIGN(4096) { __bl31_sram_text_start = .; *(.sram.text) *(.sram.rodata) + __bl31_sram_text_real_end = .; . = ALIGN(4096); __bl31_sram_text_end = .; } >SRAM + ASSERT((__bl31_sram_text_real_end - __bl31_sram_text_start) <= + SRAM_TEXT_LIMIT, ".text_sram has exceeded its limit") .data_sram : ALIGN(4096) { __bl31_sram_data_start = .; *(.sram.data) + __bl31_sram_data_real_end = .; . = ALIGN(4096); __bl31_sram_data_end = .; } >SRAM + ASSERT((__bl31_sram_data_real_end - __bl31_sram_data_start) <= + SRAM_DATA_LIMIT, ".data_sram has exceeded its limit") + + .stack_sram : ALIGN(4096) { + __bl31_sram_stack_start = .; + . += 4096; + __bl31_sram_stack_end = .; + } >SRAM + + . = PMUSRAM_BASE; + + /* + * pmu_cpuson_entrypoint request address + * align 64K when resume, so put it in the + * start of pmusram + */ + .pmusram : { + ASSERT(. == ALIGN(64 * 1024), + ".pmusram.entry request 64K aligned."); + *(.pmusram.entry) + __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__ */ diff --git a/plat/rockchip/rk3399/include/platform_def.h b/plat/rockchip/rk3399/include/platform_def.h index f4427d01dbbf6249c2157db340b93a417716be2f..3df2f7dc075c92d88fc4540d381af097e6f218fb 100644 --- a/plat/rockchip/rk3399/include/platform_def.h +++ b/plat/rockchip/rk3399/include/platform_def.h @@ -107,4 +107,7 @@ #define PLAT_RK_PRIMARY_CPU 0x0 +#define PSRAM_DO_DDR_RESUME 1 +#define PSRAM_CHECK_WAKEUP_CPU 0 + #endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/rockchip/rk3399/include/shared/addressmap_shared.h b/plat/rockchip/rk3399/include/shared/addressmap_shared.h index d72633e5d6c822803e69e3009d47848f85f663ce..fe23e56909d362a741f68b3659f1c0c8b95a112a 100644 --- a/plat/rockchip/rk3399/include/shared/addressmap_shared.h +++ b/plat/rockchip/rk3399/include/shared/addressmap_shared.h @@ -9,6 +9,9 @@ #define SIZE_K(n) ((n) * 1024) #define SIZE_M(n) ((n) * 1024 * 1024) +#define SRAM_TEXT_LIMIT (4 * 1024) +#define SRAM_DATA_LIMIT (4 * 1024) +#define SRAM_BIN_LIMIT (4 * 1024) /* * The parts of the shared defined registers address with AP and M0, diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk index be3e11b9e90de2a356ebeae1f7b9dbe18af8a61c..cb7999b5e65436e6e4c69868161e5d5f934a6dbd 100644 --- a/plat/rockchip/rk3399/platform.mk +++ b/plat/rockchip/rk3399/platform.mk @@ -44,7 +44,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ${RK_PLAT_COMMON}/bl31_plat_setup.c \ ${RK_PLAT_COMMON}/params_setup.c \ ${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \ - ${RK_PLAT_COMMON}/pmusram/pmu_sram.c \ ${RK_PLAT_COMMON}/plat_pm.c \ ${RK_PLAT_COMMON}/plat_topology.c \ ${RK_PLAT_COMMON}/aarch64/platform_common.c \