1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Copyright 2014 Freescale Semiconductor, Inc. 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #include <common.h> 8*4882a593Smuzhiyun #include <asm/immap_85xx.h> 9*4882a593Smuzhiyun #include "sleep.h" 10*4882a593Smuzhiyun #ifdef CONFIG_U_QE 11*4882a593Smuzhiyun #include <fsl_qe.h> 12*4882a593Smuzhiyun #endif 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR; 15*4882a593Smuzhiyun board_mem_sleep_setup(void)16*4882a593Smuzhiyunvoid __weak board_mem_sleep_setup(void) 17*4882a593Smuzhiyun { 18*4882a593Smuzhiyun } 19*4882a593Smuzhiyun board_sleep_prepare(void)20*4882a593Smuzhiyunvoid __weak board_sleep_prepare(void) 21*4882a593Smuzhiyun { 22*4882a593Smuzhiyun } 23*4882a593Smuzhiyun is_warm_boot(void)24*4882a593Smuzhiyunbool is_warm_boot(void) 25*4882a593Smuzhiyun { 26*4882a593Smuzhiyun struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun if (in_be32(&gur->scrtsr[0]) & DCFG_CCSR_CRSTSR_WDRFR) 29*4882a593Smuzhiyun return 1; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun return 0; 32*4882a593Smuzhiyun } 33*4882a593Smuzhiyun fsl_dp_disable_console(void)34*4882a593Smuzhiyunvoid fsl_dp_disable_console(void) 35*4882a593Smuzhiyun { 36*4882a593Smuzhiyun gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; 37*4882a593Smuzhiyun } 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun /* 40*4882a593Smuzhiyun * When wakeup from deep sleep, the first 128 bytes space 41*4882a593Smuzhiyun * will be used to do DDR training which corrupts the data 42*4882a593Smuzhiyun * in there. This function will restore them. 43*4882a593Smuzhiyun */ dp_ddr_restore(void)44*4882a593Smuzhiyunstatic void dp_ddr_restore(void) 45*4882a593Smuzhiyun { 46*4882a593Smuzhiyun u64 *src, *dst; 47*4882a593Smuzhiyun int i; 48*4882a593Smuzhiyun struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_MPC85xx_SCFG; 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun /* get the address of ddr date from SPARECR3 */ 51*4882a593Smuzhiyun src = (u64 *)(in_be32(&scfg->sparecr[2]) + DDR_BUFF_LEN - 8); 52*4882a593Smuzhiyun dst = (u64 *)(CONFIG_SYS_SDRAM_BASE + DDR_BUFF_LEN - 8); 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun for (i = 0; i < DDR_BUFF_LEN / 8; i++) 55*4882a593Smuzhiyun *dst-- = *src--; 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun flush_dcache(); 58*4882a593Smuzhiyun } 59*4882a593Smuzhiyun dp_resume_prepare(void)60*4882a593Smuzhiyunstatic void dp_resume_prepare(void) 61*4882a593Smuzhiyun { 62*4882a593Smuzhiyun dp_ddr_restore(); 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun board_sleep_prepare(); 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun l2cache_init(); 67*4882a593Smuzhiyun #if defined(CONFIG_RAMBOOT_PBL) 68*4882a593Smuzhiyun disable_cpc_sram(); 69*4882a593Smuzhiyun #endif 70*4882a593Smuzhiyun enable_cpc(); 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun #ifdef CONFIG_U_QE 73*4882a593Smuzhiyun u_qe_resume(); 74*4882a593Smuzhiyun #endif 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun } 77*4882a593Smuzhiyun fsl_dp_resume(void)78*4882a593Smuzhiyunint fsl_dp_resume(void) 79*4882a593Smuzhiyun { 80*4882a593Smuzhiyun u32 start_addr; 81*4882a593Smuzhiyun void (*kernel_resume)(void); 82*4882a593Smuzhiyun struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_MPC85xx_SCFG; 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun if (!is_warm_boot()) 85*4882a593Smuzhiyun return 0; 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun dp_resume_prepare(); 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun /* Get the entry address and jump to kernel */ 90*4882a593Smuzhiyun start_addr = in_be32(&scfg->sparecr[1]); 91*4882a593Smuzhiyun debug("Entry address is 0x%08x\n", start_addr); 92*4882a593Smuzhiyun kernel_resume = (void (*)(void))start_addr; 93*4882a593Smuzhiyun kernel_resume(); 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun return 0; 96*4882a593Smuzhiyun } 97