Commit aade20046b7ab5bd9b2afe84ccb31f0adf0c5e1e

Authored by Tang Yuantian
Committed by York Sun
1 parent 5aef4c86f3

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

... ... @@ -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.