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