1 /* SPDX-License-Identifier: GPL-2.0 */
2 #include <linux/linkage.h>
3 #include <asm/blackfin.h>
6 #include <asm/context.S>
8 #define PM_STACK (COREA_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
11 ENTRY(_enter_hibernate)
12 /* switch stack to L1 scratch, prepare for ddr srfr */
18 call _bfin_hibernate_syscontrol;
20 P0.H = HI(DPM0_RESTORE4);
21 P0.L = LO(DPM0_RESTORE4);
22 P1.H = _bf609_pm_data;
23 P1.L = _bf609_pm_data;
28 R3.H = HI(0x00000010);
29 R3.L = LO(0x00000010);
31 bfin_init_pm_bench_cycles;
36 ENDPROC(_enter_hibernate)
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.
41 ENTRY(_dummy_deepsleep)
46 /* get wake up interrupt ID */
47 P0.l = LO(SEC_SCI_BASE + SEC_CSID);
48 P0.h = HI(SEC_SCI_BASE + SEC_CSID);
51 /* ACK wake up interrupt in SEC */
58 /* restore EVT 11 entry */
70 ENDPROC(_dummy_deepsleep)
72 ENTRY(_enter_deepsleep)
76 /* Change EVT 11 entry to dummy handler for wake up event */
79 p1.h = _dummy_deepsleep;
80 p1.l = _dummy_deepsleep;
92 /* should put ddr to self refresh mode before sleep */
95 /* Set DPM controller to deep sleep mode */
98 R3.H = HI(0x00000008);
99 R3.L = LO(0x00000008);
103 /* Enable evt 11 in IMASK before idle, otherwise core doesn't wake up. */
109 bfin_init_pm_bench_cycles;
111 /* Fall into deep sleep in idle*/
115 /* Restore PLL after wake up from deep sleep */
116 call _bf609_resume_ccbuf;
118 /* turn ddr out of self refresh mode */
119 call _bf609_ddr_sr_exit;
123 (R7:0,P5:0) = [SP++];
126 ENDPROC(_enter_deepsleep)
129 ENTRY(_bf609_hibernate)
133 P0.H = _bf609_pm_data;
134 P0.L = _bf609_pm_data;
137 R2.H = .Lpm_resume_here;
138 R2.L = .Lpm_resume_here;
143 P1.H = _enter_hibernate;
144 P1.L = _enter_hibernate;
149 bfin_core_mmr_restore;
150 bfin_cpu_reg_restore;
152 [--sp] = RETI; /* Clear Global Interrupt Disable */
157 ENDPROC(_bf609_hibernate)