License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[linux-2.6-block.git] / arch / blackfin / mach-bf609 / dpm.S
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
c7e48e1e
SZ
2#include <linux/linkage.h>
3#include <asm/blackfin.h>
4#include <asm/dpmc.h>
5
6#include <asm/context.S>
7
8#define PM_STACK (COREA_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
9
10.section .l1.text
11ENTRY(_enter_hibernate)
12 /* switch stack to L1 scratch, prepare for ddr srfr */
13 P0.H = HI(PM_STACK);
14 P0.L = LO(PM_STACK);
15 SP = P0;
16
17 call _bf609_ddr_sr;
18 call _bfin_hibernate_syscontrol;
19
20 P0.H = HI(DPM0_RESTORE4);
21 P0.L = LO(DPM0_RESTORE4);
22 P1.H = _bf609_pm_data;
23 P1.L = _bf609_pm_data;
24 [P0] = P1;
25
26 P0.H = HI(DPM0_CTL);
27 P0.L = LO(DPM0_CTL);
28 R3.H = HI(0x00000010);
29 R3.L = LO(0x00000010);
30
31 bfin_init_pm_bench_cycles;
32
33 [P0] = R3;
34
35 SSYNC;
36ENDPROC(_enter_hibernate)
37
38/* DPM wake up interrupt won't wake up core on bf60x if its core IMASK
39 * is disabled. This behavior differ from bf5xx serial processor.
40 */
41ENTRY(_dummy_deepsleep)
42 [--sp] = SYSCFG;
43 [--sp] = (R7:0,P5:0);
44 cli r0;
45
46 /* get wake up interrupt ID */
47 P0.l = LO(SEC_SCI_BASE + SEC_CSID);
48 P0.h = HI(SEC_SCI_BASE + SEC_CSID);
49 R0 = [P0];
50
51 /* ACK wake up interrupt in SEC */
52 P1.l = LO(SEC_END);
53 P1.h = HI(SEC_END);
54
55 [P1] = R0;
56 SSYNC;
57
58 /* restore EVT 11 entry */
59 p0.h = hi(EVT11);
60 p0.l = lo(EVT11);
61 p1.h = _evt_evt11;
62 p1.l = _evt_evt11;
63
64 [p0] = p1;
65 SSYNC;
66
67 (R7:0,P5:0) = [sp++];
68 SYSCFG = [sp++];
69 RTI;
70ENDPROC(_dummy_deepsleep)
71
72ENTRY(_enter_deepsleep)
68bcdd48 73 LINK 0xC;
c7e48e1e
SZ
74 [--sp] = (R7:0,P5:0);
75
76 /* Change EVT 11 entry to dummy handler for wake up event */
77 p0.h = hi(EVT11);
78 p0.l = lo(EVT11);
79 p1.h = _dummy_deepsleep;
80 p1.l = _dummy_deepsleep;
81
82 [p0] = p1;
83
84 P0.H = HI(PM_STACK);
85 P0.L = LO(PM_STACK);
86
87 EX_SCRATCH_REG = SP;
88 SP = P0;
89
90 SSYNC;
91
92 /* should put ddr to self refresh mode before sleep */
93 call _bf609_ddr_sr;
94
95 /* Set DPM controller to deep sleep mode */
96 P0.H = HI(DPM0_CTL);
97 P0.L = LO(DPM0_CTL);
98 R3.H = HI(0x00000008);
99 R3.L = LO(0x00000008);
100 [P0] = R3;
101 CSYNC;
102
103 /* Enable evt 11 in IMASK before idle, otherwise core doesn't wake up. */
104 r0.l = 0x800;
105 r0.h = 0;
106 sti r0;
107 SSYNC;
108
928a8e69
SZ
109 bfin_init_pm_bench_cycles;
110
c7e48e1e
SZ
111 /* Fall into deep sleep in idle*/
112 idle;
113 SSYNC;
114
115 /* Restore PLL after wake up from deep sleep */
116 call _bf609_resume_ccbuf;
117
118 /* turn ddr out of self refresh mode */
119 call _bf609_ddr_sr_exit;
120
121 SP = EX_SCRATCH_REG;
122
123 (R7:0,P5:0) = [SP++];
124 UNLINK;
125 RTS;
126ENDPROC(_enter_deepsleep)
127
128.section .text
129ENTRY(_bf609_hibernate)
130 bfin_cpu_reg_save;
131 bfin_core_mmr_save;
132
133 P0.H = _bf609_pm_data;
134 P0.L = _bf609_pm_data;
135 R1.H = 0xDEAD;
136 R1.L = 0xBEEF;
137 R2.H = .Lpm_resume_here;
138 R2.L = .Lpm_resume_here;
139 [P0++] = R1;
140 [P0++] = R2;
141 [P0++] = SP;
142
143 P1.H = _enter_hibernate;
144 P1.L = _enter_hibernate;
145
146 call (P1);
147.Lpm_resume_here:
148
149 bfin_core_mmr_restore;
150 bfin_cpu_reg_restore;
151
152 [--sp] = RETI; /* Clear Global Interrupt Disable */
153 SP += 4;
154
155 RTS;
156
157ENDPROC(_bf609_hibernate)
158