mpc85xx/t104x: Add deep sleep framework support
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> Reviewed-by: York Sun <yorksun@freescale.com>
This commit is contained in:
parent
5aef4c86f3
commit
aade20046b
4
README
4
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
|
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.
|
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:
|
- Generic CPU options:
|
||||||
CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN
|
CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
|
|
@ -350,6 +350,7 @@ void cpu_init_f (void)
|
||||||
extern void m8560_cpm_reset (void);
|
extern void m8560_cpm_reset (void);
|
||||||
#ifdef CONFIG_SYS_DCSRBAR_PHYS
|
#ifdef CONFIG_SYS_DCSRBAR_PHYS
|
||||||
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||||
|
gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_SECURE_BOOT)
|
#if defined(CONFIG_SECURE_BOOT)
|
||||||
struct law_entry law;
|
struct law_entry law;
|
||||||
|
@ -414,6 +415,13 @@ void cpu_init_f (void)
|
||||||
in_be32(&gur->dcsrcr);
|
in_be32(&gur->dcsrcr);
|
||||||
#endif
|
#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
|
#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
|
||||||
fsl_erratum_a007212_workaround();
|
fsl_erratum_a007212_workaround();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -343,6 +343,13 @@ void board_init_f(ulong bootflag)
|
||||||
#ifdef CONFIG_PRAM
|
#ifdef CONFIG_PRAM
|
||||||
ulong reg;
|
ulong reg;
|
||||||
#endif
|
#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 */
|
/* Pointer is writable since we allocated a register for it */
|
||||||
gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
|
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)
|
if ((*init_fnc_ptr) () != 0)
|
||||||
hang();
|
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
|
#ifdef CONFIG_POST
|
||||||
post_bootmode_init();
|
post_bootmode_init();
|
||||||
post_run(NULL, POST_ROM | post_bootmode_get(NULL));
|
post_run(NULL, POST_ROM | post_bootmode_get(NULL));
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
|
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* regs has the to-be-set values for DDR controller registers
|
* 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;
|
u32 save1, save2;
|
||||||
#endif
|
#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) {
|
switch (ctrl_num) {
|
||||||
case 0:
|
case 0:
|
||||||
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
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_0, regs->timing_cfg_0);
|
||||||
out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
|
out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
|
||||||
out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
|
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, regs->ddr_sdram_mode);
|
||||||
out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
|
out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
|
||||||
out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
|
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_interval, regs->ddr_sdram_interval);
|
||||||
out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
|
out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
|
||||||
out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
|
out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
|
||||||
out_be32(&ddr->init_addr, regs->ddr_init_addr);
|
#ifdef CONFIG_DEEP_SLEEP
|
||||||
out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
|
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_4, regs->timing_cfg_4);
|
||||||
out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5);
|
out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5);
|
||||||
|
@ -374,8 +399,22 @@ step2:
|
||||||
udelay(500);
|
udelay(500);
|
||||||
asm volatile("sync;isync");
|
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 */
|
/* 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);
|
out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
||||||
asm volatile("sync;isync");
|
asm volatile("sync;isync");
|
||||||
|
|
||||||
|
@ -526,4 +565,9 @@ step2:
|
||||||
clrbits_be32(&ddr->sdram_cfg, 0x2);
|
clrbits_be32(&ddr->sdram_cfg, 0x2);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */
|
#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
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,6 +406,10 @@ static int __board_need_mem_reset(void)
|
||||||
int board_need_mem_reset(void)
|
int board_need_mem_reset(void)
|
||||||
__attribute__((weak, alias("__board_need_mem_reset")));
|
__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
|
* The 85xx boards have a common prototype for fixed_sdram so put the
|
||||||
* declaration here.
|
* declaration here.
|
||||||
|
|
Loading…
Reference in New Issue