Commit aade20046b7ab5bd9b2afe84ccb31f0adf0c5e1e
Committed by
York Sun
1 parent
5aef4c86f3
Exists in
v2017.01-smarct4x
and in
40 other branches
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>
Showing 5 changed files with 80 additions and 4 deletions Side-by-side Diff
README
... | ... | @@ -431,6 +431,10 @@ |
431 | 431 | This CONFIG is defined when the CPC is configured as SRAM at the |
432 | 432 | time of U-boot entry and is required to be re-initialized. |
433 | 433 | |
434 | + CONFIG_DEEP_SLEEP | |
435 | + Inidcates this SoC supports deep sleep feature. If deep sleep is | |
436 | + supported, core will start to execute uboot when wakes up. | |
437 | + | |
434 | 438 | - Generic CPU options: |
435 | 439 | CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN |
436 | 440 |
arch/powerpc/cpu/mpc85xx/cpu_init.c
... | ... | @@ -350,6 +350,7 @@ |
350 | 350 | extern void m8560_cpm_reset (void); |
351 | 351 | #ifdef CONFIG_SYS_DCSRBAR_PHYS |
352 | 352 | ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); |
353 | + gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); | |
353 | 354 | #endif |
354 | 355 | #if defined(CONFIG_SECURE_BOOT) |
355 | 356 | struct law_entry law; |
... | ... | @@ -414,6 +415,13 @@ |
414 | 415 | in_be32(&gur->dcsrcr); |
415 | 416 | #endif |
416 | 417 | |
418 | +#ifdef CONFIG_SYS_DCSRBAR_PHYS | |
419 | +#ifdef CONFIG_DEEP_SLEEP | |
420 | + /* disable the console if boot from deep sleep */ | |
421 | + if (in_be32(&gur->scrtsr[0]) & (1 << 3)) | |
422 | + gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; | |
423 | +#endif | |
424 | +#endif | |
417 | 425 | #ifdef CONFIG_SYS_FSL_ERRATUM_A007212 |
418 | 426 | fsl_erratum_a007212_workaround(); |
419 | 427 | #endif |
arch/powerpc/lib/board.c
... | ... | @@ -343,6 +343,13 @@ |
343 | 343 | #ifdef CONFIG_PRAM |
344 | 344 | ulong reg; |
345 | 345 | #endif |
346 | +#ifdef CONFIG_DEEP_SLEEP | |
347 | + const ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
348 | + struct ccsr_scfg *scfg = (void *)CONFIG_SYS_MPC85xx_SCFG; | |
349 | + u32 start_addr; | |
350 | + typedef void (*func_t)(void); | |
351 | + func_t kernel_resume; | |
352 | +#endif | |
346 | 353 | |
347 | 354 | /* Pointer is writable since we allocated a register for it */ |
348 | 355 | gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); |
... | ... | @@ -359,6 +366,15 @@ |
359 | 366 | for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) |
360 | 367 | if ((*init_fnc_ptr) () != 0) |
361 | 368 | hang(); |
369 | + | |
370 | +#ifdef CONFIG_DEEP_SLEEP | |
371 | + /* Jump to kernel in deep sleep case */ | |
372 | + if (in_be32(&gur->scrtsr[0]) & (1 << 3)) { | |
373 | + start_addr = in_be32(&scfg->sparecr[1]); | |
374 | + kernel_resume = (func_t)start_addr; | |
375 | + kernel_resume(); | |
376 | + } | |
377 | +#endif | |
362 | 378 | |
363 | 379 | #ifdef CONFIG_POST |
364 | 380 | post_bootmode_init(); |
drivers/ddr/fsl/mpc85xx_ddr_gen3.c
... | ... | @@ -15,6 +15,7 @@ |
15 | 15 | #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL |
16 | 16 | #endif |
17 | 17 | |
18 | +DECLARE_GLOBAL_DATA_PTR; | |
18 | 19 | |
19 | 20 | /* |
20 | 21 | * regs has the to-be-set values for DDR controller registers |
... | ... | @@ -43,6 +44,16 @@ |
43 | 44 | u32 save1, save2; |
44 | 45 | #endif |
45 | 46 | |
47 | +#ifdef CONFIG_DEEP_SLEEP | |
48 | + const ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
49 | + bool sleep_flag = 0; | |
50 | +#endif | |
51 | + | |
52 | +#ifdef CONFIG_DEEP_SLEEP | |
53 | + if (in_be32(&gur->scrtsr[0]) & (1 << 3)) | |
54 | + sleep_flag = 1; | |
55 | +#endif | |
56 | + | |
46 | 57 | switch (ctrl_num) { |
47 | 58 | case 0: |
48 | 59 | ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; |
... | ... | @@ -119,7 +130,13 @@ |
119 | 130 | out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0); |
120 | 131 | out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1); |
121 | 132 | out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2); |
122 | - out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); | |
133 | +#ifdef CONFIG_DEEP_SLEEP | |
134 | + if (sleep_flag) | |
135 | + out_be32(&ddr->sdram_cfg_2, | |
136 | + regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); | |
137 | + else | |
138 | +#endif | |
139 | + out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); | |
123 | 140 | out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode); |
124 | 141 | out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2); |
125 | 142 | out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3); |
... | ... | @@ -132,8 +149,16 @@ |
132 | 149 | out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval); |
133 | 150 | out_be32(&ddr->sdram_data_init, regs->ddr_data_init); |
134 | 151 | out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl); |
135 | - out_be32(&ddr->init_addr, regs->ddr_init_addr); | |
136 | - out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); | |
152 | +#ifdef CONFIG_DEEP_SLEEP | |
153 | + if (sleep_flag) { | |
154 | + out_be32(&ddr->init_addr, 0); | |
155 | + out_be32(&ddr->init_ext_addr, (1 << 31)); | |
156 | + } else | |
157 | +#endif | |
158 | + { | |
159 | + out_be32(&ddr->init_addr, regs->ddr_init_addr); | |
160 | + out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); | |
161 | + } | |
137 | 162 | |
138 | 163 | out_be32(&ddr->timing_cfg_4, regs->timing_cfg_4); |
139 | 164 | out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5); |
140 | 165 | |
... | ... | @@ -374,8 +399,22 @@ |
374 | 399 | udelay(500); |
375 | 400 | asm volatile("sync;isync"); |
376 | 401 | |
402 | +#ifdef CONFIG_DEEP_SLEEP | |
403 | + if (sleep_flag) { | |
404 | + /* enter self-refresh */ | |
405 | + setbits_be32(&ddr->sdram_cfg_2, (1 << 31)); | |
406 | + /* do board specific memory setup */ | |
407 | + board_mem_sleep_setup(); | |
408 | + } | |
409 | +#endif | |
410 | + | |
377 | 411 | /* Let the controller go */ |
378 | - temp_sdram_cfg = in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; | |
412 | +#ifdef CONFIG_DEEP_SLEEP | |
413 | + if (sleep_flag) | |
414 | + temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) | SDRAM_CFG_BI); | |
415 | + else | |
416 | +#endif | |
417 | + temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI); | |
379 | 418 | out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); |
380 | 419 | asm volatile("sync;isync"); |
381 | 420 | |
... | ... | @@ -526,5 +565,10 @@ |
526 | 565 | clrbits_be32(&ddr->sdram_cfg, 0x2); |
527 | 566 | } |
528 | 567 | #endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */ |
568 | +#ifdef CONFIG_DEEP_SLEEP | |
569 | + if (sleep_flag) | |
570 | + /* exit self-refresh */ | |
571 | + clrbits_be32(&ddr->sdram_cfg_2, (1 << 31)); | |
572 | +#endif | |
529 | 573 | } |
include/fsl_ddr_sdram.h
... | ... | @@ -406,6 +406,10 @@ |
406 | 406 | int board_need_mem_reset(void) |
407 | 407 | __attribute__((weak, alias("__board_need_mem_reset"))); |
408 | 408 | |
409 | +void __weak board_mem_sleep_setup(void) | |
410 | +{ | |
411 | +} | |
412 | + | |
409 | 413 | /* |
410 | 414 | * The 85xx boards have a common prototype for fixed_sdram so put the |
411 | 415 | * declaration here. |