[U-Boot] [PATCH 1/3] powerpc: add deep sleep support for generic board

From: Tang Yuantian Yuantian.Tang@freescale.com
Deep sleep for generic board is not supported on PowerPC. This patch make deep sleep work for both non-generic board and generic board on PowerPC platforms. For ARM-based QorIQ platforms, deep sleep has been already supported.
Signed-off-by: Tang Yuantian Yuantian.Tang@freescale.com --- README | 2 +- arch/powerpc/cpu/mpc85xx/cpu_init.c | 2 +- arch/powerpc/cpu/mpc85xx/fdt.c | 2 +- arch/powerpc/lib/board.c | 24 ++++++------------------ drivers/ddr/fsl/mpc85xx_ddr_gen3.c | 37 ++++++++++++++----------------------- drivers/qe/qe.c | 8 ++++---- 6 files changed, 27 insertions(+), 48 deletions(-)
diff --git a/README b/README index 48061b4..194bdf0 100644 --- a/README +++ b/README @@ -442,7 +442,7 @@ 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 + CONFIG_FSL_DEEP_SLEEP Inidcates this SoC supports deep sleep feature. If deep sleep is supported, core will start to execute uboot when wakes up.
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index bd397aa..267d366 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -479,7 +479,7 @@ ulong cpu_init_f(void) #endif
#ifdef CONFIG_SYS_DCSRBAR_PHYS -#ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_FSL_DEEP_SLEEP /* disable the console if boot from deep sleep */ if (in_be32(&gur->scrtsr[0]) & (1 << 3)) flag = GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 61d7b81..2695941 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -134,7 +134,7 @@ void ft_fixup_cpu(void *blob, u64 memory_limit) printf("Failed to reserve memory for spin table: %s\n", fdt_strerror(off)); } -#ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_FSL_DEEP_SLEEP #ifdef CONFIG_SPL_MMC_BOOT off = fdt_add_mem_rsv(blob, CONFIG_SYS_MMC_U_BOOT_START, CONFIG_SYS_MMC_U_BOOT_SIZE); diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index 50eb820..ff49116 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -113,6 +113,9 @@ ulong monitor_flash_len; #include <bedbug/type.h> #endif
+#ifdef CONFIG_FSL_DEEP_SLEEP +#include <fsl_sleep.h> +#endif /* * Utilities */ @@ -343,13 +346,6 @@ 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); @@ -367,18 +363,10 @@ void board_init_f(ulong bootflag) if ((*init_fnc_ptr) () != 0) hang();
-#ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_FSL_DEEP_SLEEP /* Jump to kernel in deep sleep case */ - if (in_be32(&gur->scrtsr[0]) & (1 << 3)) { - l2cache_init(); -#if defined(CONFIG_RAMBOOT_PBL) - disable_cpc_sram(); -#endif - enable_cpc(); - start_addr = in_be32(&scfg->sparecr[1]); - kernel_resume = (func_t)start_addr; - kernel_resume(); - } + if (is_warm_boot()) + fsl_dp_resume(); #endif
#ifdef CONFIG_POST diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c index 4d5572e..194a714 100644 --- a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c +++ b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c @@ -10,13 +10,14 @@ #include <asm/io.h> #include <fsl_ddr_sdram.h> #include <asm/processor.h> +#ifdef CONFIG_FSL_DEEP_SLEEP +#include <fsl_sleep.h> +#endif
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4) #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 * ctrl_num is the DDR controller number @@ -44,16 +45,6 @@ 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; @@ -130,8 +121,8 @@ 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); -#ifdef CONFIG_DEEP_SLEEP - if (sleep_flag) +#ifdef CONFIG_FSL_DEEP_SLEEP + if (is_warm_boot()) out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); else @@ -149,8 +140,8 @@ 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); -#ifdef CONFIG_DEEP_SLEEP - if (sleep_flag) { +#ifdef CONFIG_FSL_DEEP_SLEEP + if (is_warm_boot()) { out_be32(&ddr->init_addr, 0); out_be32(&ddr->init_ext_addr, (1 << 31)); } else @@ -399,18 +390,18 @@ step2: udelay(500); asm volatile("sync;isync");
-#ifdef CONFIG_DEEP_SLEEP - if (sleep_flag) { +#ifdef CONFIG_FSL_DEEP_SLEEP + if (is_warm_boot()) { /* enter self-refresh */ setbits_be32(&ddr->sdram_cfg_2, (1 << 31)); /* do board specific memory setup */ - board_mem_sleep_setup(); + fsl_dp_mem_setup(); } #endif
/* Let the controller go */ -#ifdef CONFIG_DEEP_SLEEP - if (sleep_flag) +#ifdef CONFIG_FSL_DEEP_SLEEP + if (is_warm_boot()) temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) | SDRAM_CFG_BI); else #endif @@ -565,8 +556,8 @@ step2: clrbits_be32(&ddr->sdram_cfg, 0x2); } #endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */ -#ifdef CONFIG_DEEP_SLEEP - if (sleep_flag) +#ifdef CONFIG_FSL_DEEP_SLEEP + if (is_warm_boot()) /* exit self-refresh */ clrbits_be32(&ddr->sdram_cfg_2, (1 << 31)); #endif diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c index 3ca01d8..4265a21 100644 --- a/drivers/qe/qe.c +++ b/drivers/qe/qe.c @@ -334,7 +334,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware) size_t calc_size = sizeof(struct qe_firmware); size_t length; const struct qe_header *hdr; -#ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_FSL_DEEP_SLEEP ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); #endif if (!firmware) { @@ -349,7 +349,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware) if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || (hdr->magic[2] != 'F')) { printf("Not a microcode\n"); -#ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_FSL_DEEP_SLEEP setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE); #endif return -EPERM; @@ -469,7 +469,7 @@ int u_qe_upload_firmware(const struct qe_firmware *firmware) size_t calc_size = sizeof(struct qe_firmware); size_t length; const struct qe_header *hdr; -#ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_FSL_DEEP_SLEEP ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); #endif if (!firmware) { @@ -484,7 +484,7 @@ int u_qe_upload_firmware(const struct qe_firmware *firmware) if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || (hdr->magic[2] != 'F')) { printf("Not a microcode\n"); -#ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_FSL_DEEP_SLEEP setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE); #endif return -EPERM;

From: Tang Yuantian Yuantian.Tang@freescale.com
Added deep sleep support on T104xRDB platforms. Support both SD/SPI boot and NOR boot.
Signed-off-by: Tang Yuantian Yuantian.Tang@freescale.com --- board/freescale/t104xrdb/spl.c | 41 +++++++++++++++---------- board/freescale/t104xrdb/t104xrdb.c | 60 +++++++++++++++++++++++++++++++++++-- include/configs/T104xRDB.h | 2 +- 3 files changed, 85 insertions(+), 18 deletions(-)
diff --git a/board/freescale/t104xrdb/spl.c b/board/freescale/t104xrdb/spl.c index e394b12..5b39ffa 100644 --- a/board/freescale/t104xrdb/spl.c +++ b/board/freescale/t104xrdb/spl.c @@ -15,6 +15,30 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_FSL_DEEP_SLEEP +bool is_warm_boot(void) +{ +#define DCFG_CCSR_CRSTSR_WDRFR (1 << 3) + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + + if (in_be32(&gur->scrtsr[0]) & DCFG_CCSR_CRSTSR_WDRFR) + return 1; + + return 0; +} + +void fsl_dp_mem_setup(void) +{ + void __iomem *cpld_base = (void *)CONFIG_SYS_CPLD_BASE; + + /* does not provide HW signals for power management */ + clrbits_8(cpld_base + 0x17, 0x40); + /* Disable MCKE isolation */ + gpio_set_value(2, 0); + udelay(1); +} +#endif + phys_size_t get_effective_memsize(void) { return CONFIG_SYS_L3_SIZE; @@ -62,9 +86,9 @@ void board_init_f(ulong bootflag) /* Update GD pointer */ gd = (gd_t *)(CONFIG_SPL_GD_ADDR);
-#ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_FSL_DEEP_SLEEP /* disable the console if boot from deep sleep */ - if (in_be32(&gur->scrtsr[0]) & (1 << 3)) + if (is_warm_boot()) gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; #endif /* compiler optimization barrier needed for GCC >= 3.4 */ @@ -132,16 +156,3 @@ void board_init_r(gd_t *gd, ulong dest_addr) nand_boot(); #endif } - -#ifdef CONFIG_DEEP_SLEEP -void board_mem_sleep_setup(void) -{ - void __iomem *cpld_base = (void *)CONFIG_SYS_CPLD_BASE; - - /* does not provide HW signals for power management */ - clrbits_8(cpld_base + 0x17, 0x40); - /* Disable MCKE isolation */ - gpio_set_value(2, 0); - udelay(1); -} -#endif diff --git a/board/freescale/t104xrdb/t104xrdb.c b/board/freescale/t104xrdb/t104xrdb.c index a5e5fff..8b41380 100644 --- a/board/freescale/t104xrdb/t104xrdb.c +++ b/board/freescale/t104xrdb/t104xrdb.c @@ -106,8 +106,20 @@ void ft_board_setup(void *blob, bd_t *bd) #endif }
-#ifdef CONFIG_DEEP_SLEEP -void board_mem_sleep_setup(void) +#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_MPC85xx_GUTS_ADDR; + + if (in_be32(&gur->scrtsr[0]) & DCFG_CCSR_CRSTSR_WDRFR) + return 1; + + return 0; +} + +void fsl_dp_mem_setup(void) { /* does not provide HW signals for power management */ CPLD_WRITE(misc_ctl_status, (CPLD_READ(misc_ctl_status) & ~0x40)); @@ -115,4 +127,48 @@ void board_mem_sleep_setup(void) gpio_set_value(2, 0); udelay(1); } + +void fsl_dp_ddr_restore(void) +{ +#define DDR_BUFF_LEN 128 + volatile u64 *src, *dst; + int i; + struct ccsr_scfg *scfg = (void *)CONFIG_SYS_MPC85xx_SCFG; + + if (!is_warm_boot()) + return; + + /* get the address of ddr date from SPARECR3 */ + src = (u64 *)in_be32(&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_MPC85xx_SCFG; + + if (!is_warm_boot()) + return 0; + + fsl_dp_ddr_restore(); + + l2cache_init(); +#if defined(CONFIG_RAMBOOT_PBL) + disable_cpc_sram(); +#endif + enable_cpc(); + + /* Get the entry address and jump to kernel */ + start_addr = in_be32(&scfg->sparecr[1]); + debug("Entry address is 0x%08x\n", start_addr); + kernel_resume = (void (*)(void))start_addr; + kernel_resume(); + + return 0; +} #endif diff --git a/include/configs/T104xRDB.h b/include/configs/T104xRDB.h index 1f5d39e..62dbfc4 100644 --- a/include/configs/T104xRDB.h +++ b/include/configs/T104xRDB.h @@ -99,7 +99,7 @@ #define CONFIG_MP /* support multiple processors */
/* support deep sleep */ -#define CONFIG_DEEP_SLEEP +#define CONFIG_FSL_DEEP_SLEEP #define CONFIG_SILENT_CONSOLE
#ifndef CONFIG_SYS_TEXT_BASE

From: Tang Yuantian Yuantian.Tang@freescale.com
Added deep sleep support on T102xRDB platforms.
Signed-off-by: Tang Yuantian Yuantian.Tang@freescale.com --- board/freescale/t102xrdb/t102xrdb.c | 66 +++++++++++++++++++++++++++++++++++++ include/configs/T102xRDB.h | 2 +- 2 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/board/freescale/t102xrdb/t102xrdb.c b/board/freescale/t102xrdb/t102xrdb.c index 8fb426e..7f8c3b0 100644 --- a/board/freescale/t102xrdb/t102xrdb.c +++ b/board/freescale/t102xrdb/t102xrdb.c @@ -149,3 +149,69 @@ void board_mem_sleep_setup(void) udelay(1); } #endif + +#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_MPC85xx_GUTS_ADDR; + + if (in_be32(&gur->scrtsr[0]) & DCFG_CCSR_CRSTSR_WDRFR) + return 1; + + return 0; +} + +void fsl_dp_mem_setup(void) +{ + /* does not provide HW signals for power management */ + CPLD_WRITE(misc_ctl_status, (CPLD_READ(misc_ctl_status) & ~0x40)); + /* Disable MCKE isolation */ + gpio_set_value(2, 0); + udelay(1); +} + +void fsl_dp_ddr_restore(void) +{ +#define DDR_BUFF_LEN 128 + volatile u64 *src, *dst; + int i; + struct ccsr_scfg *scfg = (void *)CONFIG_SYS_MPC85xx_SCFG; + + if (!is_warm_boot()) + return; + + /* get the address of ddr date from SPARECR3 */ + src = (u64 *)in_be32(&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_MPC85xx_SCFG; + + if (!is_warm_boot()) + return 0; + + fsl_dp_ddr_restore(); + + l2cache_init(); +#if defined(CONFIG_RAMBOOT_PBL) + disable_cpc_sram(); +#endif + enable_cpc(); + + /* Get the entry address and jump to kernel */ + start_addr = in_be32(&scfg->sparecr[1]); + debug("Entry address is 0x%08x\n", start_addr); + kernel_resume = (void (*)(void))start_addr; + kernel_resume(); + + return 0; +} +#endif diff --git a/include/configs/T102xRDB.h b/include/configs/T102xRDB.h index e575784..42a0240 100644 --- a/include/configs/T102xRDB.h +++ b/include/configs/T102xRDB.h @@ -35,7 +35,7 @@ #define CONFIG_ENV_OVERWRITE
/* support deep sleep */ -#define CONFIG_DEEP_SLEEP +#define CONFIG_FSL_DEEP_SLEEP #define CONFIG_SILENT_CONSOLE
#ifdef CONFIG_RAMBOOT_PBL
participants (1)
-
Yuantian.Tang@freescale.com