[U-Boot] [PATCH 1/2] mpc85xx: Add deep sleep support on T1040QDS

From: Tang Yuantian yuantian.tang@freescale.com
Add deep sleep support on T1040QDS platform.
Signed-off-by: Tang Yuantian Yuantian.Tang@freescale.com --- board/freescale/t1040qds/t1040qds.c | 12 ++++++++++++ include/configs/T1040QDS.h | 4 ++++ 2 files changed, 16 insertions(+)
diff --git a/board/freescale/t1040qds/t1040qds.c b/board/freescale/t1040qds/t1040qds.c index 3dec447..f1d7cde 100644 --- a/board/freescale/t1040qds/t1040qds.c +++ b/board/freescale/t1040qds/t1040qds.c @@ -18,6 +18,7 @@ #include <asm/fsl_portals.h> #include <asm/fsl_liodn.h> #include <fm_eth.h> +#include <asm/mpc85xx_gpio.h>
#include "../common/qixis.h" #include "t1040qds.h" @@ -245,3 +246,14 @@ int board_need_mem_reset(void) { return 1; } + +#ifdef CONFIG_DEEP_SLEEP +void board_mem_sleep_setup(void) +{ + /* does not provide HW signals for power management */ + QIXIS_WRITE(pwr_ctl[1], (QIXIS_READ(pwr_ctl[1]) & ~0x2)); + /* Disable MCKE isolation */ + gpio_set_value(2, 0); + udelay(1); +} +#endif diff --git a/include/configs/T1040QDS.h b/include/configs/T1040QDS.h index 030ea7e..745a2f2 100644 --- a/include/configs/T1040QDS.h +++ b/include/configs/T1040QDS.h @@ -43,6 +43,10 @@ #define CONFIG_SYS_BOOK3E_HV /* Category E.HV supported */ #define CONFIG_MP /* support multiple processors */
+/* support deep sleep */ +#define CONFIG_DEEP_SLEEP +#define CONFIG_SILENT_CONSOLE + #ifndef CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_TEXT_BASE 0xeff40000 #endif

From: Tang Yuantian yuantian.tang@freescale.com
Add deep sleep support on T104xRDB platforms.
Signed-off-by: Tang Yuantian Yuantian.Tang@freescale.com --- board/freescale/t104xrdb/t104xrdb.c | 10 ++++++++++ include/configs/T104xRDB.h | 4 ++++ 2 files changed, 14 insertions(+)
diff --git a/board/freescale/t104xrdb/t104xrdb.c b/board/freescale/t104xrdb/t104xrdb.c index b48133a..fb5b849 100644 --- a/board/freescale/t104xrdb/t104xrdb.c +++ b/board/freescale/t104xrdb/t104xrdb.c @@ -17,6 +17,7 @@ #include <asm/fsl_portals.h> #include <asm/fsl_liodn.h> #include <fm_eth.h> +#include <asm/mpc85xx_gpio.h>
#include "t104xrdb.h" #include "cpld.h" @@ -104,3 +105,12 @@ void ft_board_setup(void *blob, bd_t *bd) fdt_fixup_fman_ethernet(blob); #endif } + +#ifdef CONFIG_DEEP_SLEEP +void board_mem_sleep_setup(void) +{ + /* Disable MCKE isolation */ + gpio_set_value(2, 0); + udelay(1); +} +#endif diff --git a/include/configs/T104xRDB.h b/include/configs/T104xRDB.h index eaaf37d..0159b97 100644 --- a/include/configs/T104xRDB.h +++ b/include/configs/T104xRDB.h @@ -25,6 +25,10 @@ #define CONFIG_SYS_BOOK3E_HV /* Category E.HV supported */ #define CONFIG_MP /* support multiple processors */
+/* support deep sleep */ +#define CONFIG_DEEP_SLEEP +#define CONFIG_SILENT_CONSOLE + #ifndef CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_TEXT_BASE 0xeff40000 #endif

On 04/17/2014 12:33 AM, Tang Yuantian wrote:
From: Tang Yuantian yuantian.tang@freescale.com
Add deep sleep support on T104xRDB platforms.
Signed-off-by: Tang Yuantian Yuantian.Tang@freescale.com
Applied to u-boot-mpc85xx/master, thanks.
York

From: Tang Yuantian yuantian.tang@freescale.com
When T104x soc wakes up from deep sleep, control is passed to the primary core that starts executing uboot. After re-initialized some IP blocks, like DDRC, kernel will take responsibility to continue to restore environment it leaves before.
Signed-off-by: Tang Yuantian Yuantian.Tang@freescale.com --- based on: git://git.denx.de/u-boot-mpc85xx.git branch: next tested on: t1040qds and t1040rdb platforms.
v4: - refactor the framework. In the new patch, the entry is placed just after DDRC's initialization when resume. v3: - fix out-of-tree compile warning v2: - added explaination for CONFIG_DEEP_SLEEP - fixed some issues README | 4 +++ arch/powerpc/cpu/mpc85xx/cpu_init.c | 8 ++++++ arch/powerpc/lib/board.c | 16 ++++++++++++ drivers/ddr/fsl/mpc85xx_ddr_gen3.c | 52 ++++++++++++++++++++++++++++++++++--- include/fsl_ddr_sdram.h | 4 +++ 5 files changed, 80 insertions(+), 4 deletions(-)
diff --git a/README b/README index 83a1b25..31e37cb 100644 --- a/README +++ b/README @@ -431,6 +431,10 @@ The following options need to be configured: This CONFIG is defined when the CPC is configured as SRAM at the time of U-boot entry and is required to be re-initialized.
+ CONFIG_DEEP_SLEEP + Inidcates this SoC supports deep sleep feature. If deep sleep is + supported, core will start to execute uboot when wakes up. + - Generic CPU options: CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index 941c20e..867abb6 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -350,6 +350,7 @@ void cpu_init_f (void) extern void m8560_cpm_reset (void); #ifdef CONFIG_SYS_DCSRBAR_PHYS ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); #endif #if defined(CONFIG_SECURE_BOOT) struct law_entry law; @@ -414,6 +415,13 @@ void cpu_init_f (void) in_be32(&gur->dcsrcr); #endif
+#ifdef CONFIG_SYS_DCSRBAR_PHYS +#ifdef CONFIG_DEEP_SLEEP + /* disable the console if boot from deep sleep */ + if (in_be32(&gur->scrtsr[0]) & (1 << 3)) + gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; +#endif +#endif #ifdef CONFIG_SYS_FSL_ERRATUM_A007212 fsl_erratum_a007212_workaround(); #endif diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index f86c6f3..8b03d3a 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -343,6 +343,13 @@ void board_init_f(ulong bootflag) #ifdef CONFIG_PRAM ulong reg; #endif +#ifdef CONFIG_DEEP_SLEEP + const ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + struct ccsr_scfg *scfg = (void *)CONFIG_SYS_MPC85xx_SCFG; + u32 start_addr; + typedef void (*func_t)(void); + func_t kernel_resume; +#endif
/* Pointer is writable since we allocated a register for it */ gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); @@ -360,6 +367,15 @@ void board_init_f(ulong bootflag) if ((*init_fnc_ptr) () != 0) hang();
+#ifdef CONFIG_DEEP_SLEEP + /* Jump to kernel in deep sleep case */ + if (in_be32(&gur->scrtsr[0]) & (1 << 3)) { + start_addr = in_be32(&scfg->sparecr[1]); + kernel_resume = (func_t)start_addr; + kernel_resume(); + } +#endif + #ifdef CONFIG_POST post_bootmode_init(); post_run(NULL, POST_ROM | post_bootmode_get(NULL)); diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c index c805086..4d5572e 100644 --- a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c +++ b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c @@ -15,6 +15,7 @@ #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL #endif
+DECLARE_GLOBAL_DATA_PTR;
/* * regs has the to-be-set values for DDR controller registers @@ -43,6 +44,16 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, u32 save1, save2; #endif
+#ifdef CONFIG_DEEP_SLEEP + const ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + bool sleep_flag = 0; +#endif + +#ifdef CONFIG_DEEP_SLEEP + if (in_be32(&gur->scrtsr[0]) & (1 << 3)) + sleep_flag = 1; +#endif + switch (ctrl_num) { case 0: ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; @@ -119,7 +130,13 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0); out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1); out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2); - out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); +#ifdef CONFIG_DEEP_SLEEP + if (sleep_flag) + out_be32(&ddr->sdram_cfg_2, + regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); + else +#endif + out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode); out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2); out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3); @@ -132,8 +149,16 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval); out_be32(&ddr->sdram_data_init, regs->ddr_data_init); out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl); - out_be32(&ddr->init_addr, regs->ddr_init_addr); - out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); +#ifdef CONFIG_DEEP_SLEEP + if (sleep_flag) { + out_be32(&ddr->init_addr, 0); + out_be32(&ddr->init_ext_addr, (1 << 31)); + } else +#endif + { + out_be32(&ddr->init_addr, regs->ddr_init_addr); + out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); + }
out_be32(&ddr->timing_cfg_4, regs->timing_cfg_4); out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5); @@ -374,8 +399,22 @@ step2: udelay(500); asm volatile("sync;isync");
+#ifdef CONFIG_DEEP_SLEEP + if (sleep_flag) { + /* enter self-refresh */ + setbits_be32(&ddr->sdram_cfg_2, (1 << 31)); + /* do board specific memory setup */ + board_mem_sleep_setup(); + } +#endif + /* Let the controller go */ - temp_sdram_cfg = in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; +#ifdef CONFIG_DEEP_SLEEP + if (sleep_flag) + temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) | SDRAM_CFG_BI); + else +#endif + temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI); out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); asm volatile("sync;isync");
@@ -526,4 +565,9 @@ step2: clrbits_be32(&ddr->sdram_cfg, 0x2); } #endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */ +#ifdef CONFIG_DEEP_SLEEP + if (sleep_flag) + /* exit self-refresh */ + clrbits_be32(&ddr->sdram_cfg_2, (1 << 31)); +#endif } diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h index e39b716..e8a2db9 100644 --- a/include/fsl_ddr_sdram.h +++ b/include/fsl_ddr_sdram.h @@ -406,6 +406,10 @@ static int __board_need_mem_reset(void) int board_need_mem_reset(void) __attribute__((weak, alias("__board_need_mem_reset")));
+void __weak board_mem_sleep_setup(void) +{ +} + /* * The 85xx boards have a common prototype for fixed_sdram so put the * declaration here.

On 04/17/2014 12:33 AM, Tang Yuantian wrote:
From: Tang Yuantian yuantian.tang@freescale.com
When T104x soc wakes up from deep sleep, control is passed to the primary core that starts executing uboot. After re-initialized some IP blocks, like DDRC, kernel will take responsibility to continue to restore environment it leaves before.
Signed-off-by: Tang Yuantian Yuantian.Tang@freescale.com
based on: git://git.denx.de/u-boot-mpc85xx.git branch: next tested on: t1040qds and t1040rdb platforms.
v4:
- refactor the framework. In the new patch, the entry is placed just after DDRC's initialization when resume.
v3:
- fix out-of-tree compile warning
v2:
- added explaination for CONFIG_DEEP_SLEEP
- fixed some issues
Applied to u-boot-mpc85xx/master, thanks.
York

On 04/17/2014 12:33 AM, Tang Yuantian wrote:
From: Tang Yuantian yuantian.tang@freescale.com
Add deep sleep support on T1040QDS platform.
Signed-off-by: Tang Yuantian Yuantian.Tang@freescale.com
Applied to u-boot-mpc85xx/master, thanks.
York
participants (2)
-
Tang Yuantian
-
York Sun