]>
Commit | Line | Data |
---|---|---|
a7787b78 TY |
1 | /* |
2 | * Copyright 2014 Freescale Semiconductor, Inc. | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <asm/io.h> | |
9 | #if !defined(CONFIG_ARMV7_NONSEC) || !defined(CONFIG_ARMV7_VIRT) | |
10 | #error " Deep sleep needs non-secure mode support. " | |
11 | #else | |
12 | #include <asm/secure.h> | |
13 | #endif | |
14 | #include <asm/armv7.h> | |
15 | #include <asm/cache.h> | |
16 | ||
17 | #if defined(CONFIG_LS102XA) | |
18 | #include <asm/arch/immap_ls102xa.h> | |
19 | #endif | |
20 | ||
21 | #include "sleep.h" | |
1fb5ff9a ZQ |
22 | #ifdef CONFIG_U_QE |
23 | #include "../../../drivers/qe/qe.h" | |
24 | #endif | |
a7787b78 TY |
25 | |
26 | DECLARE_GLOBAL_DATA_PTR; | |
27 | ||
28 | void __weak board_mem_sleep_setup(void) | |
29 | { | |
30 | } | |
31 | ||
32 | void __weak board_sleep_prepare(void) | |
33 | { | |
34 | } | |
35 | ||
36 | bool is_warm_boot(void) | |
37 | { | |
38 | struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; | |
39 | ||
40 | if (in_be32(&gur->crstsr) & DCFG_CCSR_CRSTSR_WDRFR) | |
41 | return 1; | |
42 | ||
43 | return 0; | |
44 | } | |
45 | ||
46 | void fsl_dp_disable_console(void) | |
47 | { | |
48 | gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; | |
49 | } | |
50 | ||
51 | /* | |
52 | * When wakeup from deep sleep, the first 128 bytes space | |
53 | * will be used to do DDR training which corrupts the data | |
54 | * in there. This function will restore them. | |
55 | */ | |
56 | static void dp_ddr_restore(void) | |
57 | { | |
58 | u64 *src, *dst; | |
59 | int i; | |
60 | struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; | |
61 | ||
62 | /* get the address of ddr date from SPARECR3 */ | |
63 | src = (u64 *)in_le32(&scfg->sparecr[2]); | |
64 | dst = (u64 *)CONFIG_SYS_SDRAM_BASE; | |
65 | ||
66 | for (i = 0; i < DDR_BUFF_LEN / 8; i++) | |
67 | *dst++ = *src++; | |
68 | ||
69 | flush_dcache_all(); | |
70 | } | |
71 | ||
72 | static void dp_resume_prepare(void) | |
73 | { | |
74 | dp_ddr_restore(); | |
75 | board_sleep_prepare(); | |
76 | armv7_init_nonsec(); | |
77 | cleanup_before_linux(); | |
1fb5ff9a ZQ |
78 | #ifdef CONFIG_U_QE |
79 | u_qe_resume(); | |
80 | #endif | |
a7787b78 TY |
81 | } |
82 | ||
83 | int fsl_dp_resume(void) | |
84 | { | |
85 | u32 start_addr; | |
86 | void (*kernel_resume)(void); | |
87 | struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; | |
88 | ||
89 | if (!is_warm_boot()) | |
90 | return 0; | |
91 | ||
92 | dp_resume_prepare(); | |
93 | ||
94 | /* Get the entry address and jump to kernel */ | |
95 | start_addr = in_le32(&scfg->sparecr[1]); | |
96 | debug("Entry address is 0x%08x\n", start_addr); | |
97 | kernel_resume = (void (*)(void))start_addr; | |
98 | secure_ram_addr(_do_nonsec_entry)(kernel_resume, 0, 0, 0); | |
99 | ||
100 | return 0; | |
101 | } |