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)&params_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)&params_phy[896], 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);
-	sram_regcpy(PHY_REG(ch, 256), (uintptr_t)&params_phy[256], 91);
-	sram_regcpy(PHY_REG(ch, 384), (uintptr_t)&params_phy[384], 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);
-	sram_regcpy(PHY_REG(ch, 768), (uintptr_t)&params_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)&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 */
 	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);
 
 	/* mask DENALI_PI_00_DATA.START, only copy here, will trigger later*/
 	params_pi[0] &= ~(0x1 << 0);
 
-	sram_regcpy((uintptr_t)&params_phy[0], PHY_REG(0, 0), 91);
-	sram_regcpy((uintptr_t)&params_phy[128], PHY_REG(0, 128), 91);
-	sram_regcpy((uintptr_t)&params_phy[256], PHY_REG(0, 256), 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);
-	sram_regcpy((uintptr_t)&params_phy[640], PHY_REG(0, 640), 38);
-	sram_regcpy((uintptr_t)&params_phy[768], PHY_REG(0, 768), 38);
-	sram_regcpy((uintptr_t)&params_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	\