
From: Tang Yuantian Yuantian.Tang@freescale.com
Add deep sleep support on Freescale LS1021QDS platform.
Signed-off-by: Tang Yuantian Yuantian.Tang@freescale.com --- board/freescale/ls1021aqds/ddr.c | 7 ++++ board/freescale/ls1021aqds/ls1021aqds.c | 60 +++++++++++++++++++++++++++++++++ include/configs/ls1021aqds.h | 4 +++ 3 files changed, 71 insertions(+)
diff --git a/board/freescale/ls1021aqds/ddr.c b/board/freescale/ls1021aqds/ddr.c index 5898e33..6dad4cc 100644 --- a/board/freescale/ls1021aqds/ddr.c +++ b/board/freescale/ls1021aqds/ddr.c @@ -8,6 +8,9 @@ #include <fsl_ddr_sdram.h> #include <fsl_ddr_dimm_params.h> #include "ddr.h" +#ifdef CONFIG_FSL_DEEP_SLEEP +#include <fsl_sleep.h> +#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -156,6 +159,10 @@ phys_size_t initdram(int board_type) puts("Initializing DDR....using SPD\n"); dram_size = fsl_ddr_sdram();
+#ifdef CONFIG_FSL_DEEP_SLEEP + fsl_dp_ddr_restore(); +#endif + return dram_size; }
diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c index 12e83f7..e9dce36 100644 --- a/board/freescale/ls1021aqds/ls1021aqds.c +++ b/board/freescale/ls1021aqds/ls1021aqds.c @@ -253,3 +253,63 @@ u16 flash_read16(void *addr)
return (((val) >> 8) & 0x00ff) | (((val) << 8) & 0xff00); } + +#ifdef CONFIG_FSL_DEEP_SLEEP +/* determine if it is a warm boot */ +bool is_warm_boot(void) +{ +#define DCFG_CCSR_CRSTSR_WDRFR (1 << 3) + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + + if (in_be32(&gur->crstsr) & DCFG_CCSR_CRSTSR_WDRFR) + return 1; + + return 0; +} + +void fsl_dp_mem_setup(void) +{ + /* does not provide HW signals for power management */ + QIXIS_WRITE(pwr_ctl[1], (QIXIS_READ(pwr_ctl[1]) & ~0x2)); + udelay(1); +} + +void fsl_dp_ddr_restore(void) +{ +#define DDR_BUFF_LEN 128 + u64 *src, *dst; + int i; + struct ccsr_scfg *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + + if (!is_warm_boot()) + return; + + /* get the address of ddr date from SPARECR3, little endian */ + src = (u64 *)in_le32(&scfg->sparecr[2]); + dst = (u64 *)CONFIG_SYS_SDRAM_BASE; + for (i = 0; i < DDR_BUFF_LEN / 8; i++) + *dst++ = *src++; +} + +int fsl_dp_resume(void) +{ + u32 start_addr; + void (*kernel_resume)(void); + struct ccsr_scfg *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + + if (!is_warm_boot()) + return 0; + + enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev)); + armv7_init_nonsec(); + cleanup_before_linux(); + + /* Get the entry address and jump to kernel */ + start_addr = in_le32(&scfg->sparecr[1]); + debug("Entry address is 0x%08x\n", start_addr); + kernel_resume = (void (*)(void))start_addr; + secure_ram_addr(_do_nonsec_entry)(kernel_resume, 0, 0, 0); + + return 0; +} +#endif diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index bb47813..448a07e 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -19,6 +19,10 @@ #define CONFIG_SKIP_LOWLEVEL_INIT #define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_FSL_DEEP_SLEEP +#ifdef CONFIG_FSL_DEEP_SLEEP +#define CONFIG_SILENT_CONSOLE +#endif /* * Size of malloc() pool */