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