Merge remote-tracking branches 'asoc/topic/cygnus', 'asoc/topic/da7213', 'asoc/topic...
[sfrench/cifs-2.6.git] / arch / blackfin / mach-bf609 / dpm.S
1 /* SPDX-License-Identifier: GPL-2.0 */
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
11 ENTRY(_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;
36 ENDPROC(_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  */
41 ENTRY(_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;
70 ENDPROC(_dummy_deepsleep)
71
72 ENTRY(_enter_deepsleep)
73         LINK 0xC;
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
109         bfin_init_pm_bench_cycles;
110
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;
126 ENDPROC(_enter_deepsleep)
127
128 .section .text
129 ENTRY(_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
157 ENDPROC(_bf609_hibernate)
158