1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Copyright (C) 2016 Broadcom Corporation |
4 | */ |
5 | |
6 | #include <asm/asm.h> |
7 | #include <asm/regdef.h> |
8 | #include <asm/mipsregs.h> |
9 | #include <asm/stackframe.h> |
10 | |
11 | #include "pm.h" |
12 | |
13 | .text |
14 | .set noreorder |
15 | .align 5 |
16 | |
17 | /* |
18 | * a0: u32 params array |
19 | */ |
20 | LEAF(brcm_pm_do_s2) |
21 | |
22 | subu sp, 64 |
23 | sw ra, 0(sp) |
24 | sw s0, 4(sp) |
25 | sw s1, 8(sp) |
26 | sw s2, 12(sp) |
27 | sw s3, 16(sp) |
28 | sw s4, 20(sp) |
29 | sw s5, 24(sp) |
30 | sw s6, 28(sp) |
31 | sw s7, 32(sp) |
32 | |
33 | /* |
34 | * Dereference the params array |
35 | * s0: AON_CTRL base register |
36 | * s1: DDR_PHY base register |
37 | * s2: TIMERS base register |
38 | * s3: I-Cache line size |
39 | * s4: Restart vector address |
40 | * s5: Restart vector size |
41 | */ |
42 | move t0, a0 |
43 | |
44 | lw s0, 0(t0) |
45 | lw s1, 4(t0) |
46 | lw s2, 8(t0) |
47 | lw s3, 12(t0) |
48 | lw s4, 16(t0) |
49 | lw s5, 20(t0) |
50 | |
51 | /* Lock this asm section into the I-cache */ |
52 | addiu t1, s3, -1 |
53 | not t1 |
54 | |
55 | la t0, brcm_pm_do_s2 |
56 | and t0, t1 |
57 | |
58 | la t2, asm_end |
59 | and t2, t1 |
60 | |
61 | 1: cache 0x1c, 0(t0) |
62 | bne t0, t2, 1b |
63 | addu t0, s3 |
64 | |
65 | /* Lock the interrupt vector into the I-cache */ |
66 | move t0, zero |
67 | |
68 | 2: move t1, s4 |
69 | cache 0x1c, 0(t1) |
70 | addu t1, s3 |
71 | addu t0, s3 |
72 | ble t0, s5, 2b |
73 | nop |
74 | |
75 | sync |
76 | |
77 | /* Power down request */ |
78 | li t0, PM_S2_COMMAND |
79 | sw zero, AON_CTRL_PM_CTRL(s0) |
80 | lw zero, AON_CTRL_PM_CTRL(s0) |
81 | sw t0, AON_CTRL_PM_CTRL(s0) |
82 | lw t0, AON_CTRL_PM_CTRL(s0) |
83 | |
84 | /* Enable CP0 interrupt 2 and wait for interrupt */ |
85 | mfc0 t0, CP0_STATUS |
86 | /* Save cp0 sr for restoring later */ |
87 | move s6, t0 |
88 | |
89 | li t1, ~(ST0_IM | ST0_IE) |
90 | and t0, t1 |
91 | ori t0, STATUSF_IP2 |
92 | mtc0 t0, CP0_STATUS |
93 | nop |
94 | nop |
95 | nop |
96 | ori t0, ST0_IE |
97 | mtc0 t0, CP0_STATUS |
98 | |
99 | /* Wait for interrupt */ |
100 | wait |
101 | nop |
102 | |
103 | /* Wait for memc0 */ |
104 | 1: lw t0, DDR40_PHY_CONTROL_REGS_0_PLL_STATUS(s1) |
105 | andi t0, 1 |
106 | beqz t0, 1b |
107 | nop |
108 | |
109 | /* 1ms delay needed for stable recovery */ |
110 | /* Use TIMER1 to count 1 ms */ |
111 | li t0, RESET_TIMER |
112 | sw t0, TIMER_TIMER1_CTRL(s2) |
113 | lw t0, TIMER_TIMER1_CTRL(s2) |
114 | |
115 | li t0, START_TIMER |
116 | sw t0, TIMER_TIMER1_CTRL(s2) |
117 | lw t0, TIMER_TIMER1_CTRL(s2) |
118 | |
119 | /* Prepare delay */ |
120 | li t0, TIMER_MASK |
121 | lw t1, TIMER_TIMER1_STAT(s2) |
122 | and t1, t0 |
123 | /* 1ms delay */ |
124 | addi t1, 27000 |
125 | |
126 | /* Wait for the timer value to exceed t1 */ |
127 | 1: lw t0, TIMER_TIMER1_STAT(s2) |
128 | sgtu t2, t1, t0 |
129 | bnez t2, 1b |
130 | nop |
131 | |
132 | /* Power back up */ |
133 | li t1, 1 |
134 | sw t1, AON_CTRL_HOST_MISC_CMDS(s0) |
135 | lw t1, AON_CTRL_HOST_MISC_CMDS(s0) |
136 | |
137 | sw zero, AON_CTRL_PM_CTRL(s0) |
138 | lw zero, AON_CTRL_PM_CTRL(s0) |
139 | |
140 | /* Unlock I-cache */ |
141 | addiu t1, s3, -1 |
142 | not t1 |
143 | |
144 | la t0, brcm_pm_do_s2 |
145 | and t0, t1 |
146 | |
147 | la t2, asm_end |
148 | and t2, t1 |
149 | |
150 | 1: cache 0x00, 0(t0) |
151 | bne t0, t2, 1b |
152 | addu t0, s3 |
153 | |
154 | /* Unlock interrupt vector */ |
155 | move t0, zero |
156 | |
157 | 2: move t1, s4 |
158 | cache 0x00, 0(t1) |
159 | addu t1, s3 |
160 | addu t0, s3 |
161 | ble t0, s5, 2b |
162 | nop |
163 | |
164 | /* Restore cp0 sr */ |
165 | sync |
166 | nop |
167 | mtc0 s6, CP0_STATUS |
168 | nop |
169 | |
170 | /* Set return value to success */ |
171 | li v0, 0 |
172 | |
173 | /* Return to caller */ |
174 | lw s7, 32(sp) |
175 | lw s6, 28(sp) |
176 | lw s5, 24(sp) |
177 | lw s4, 20(sp) |
178 | lw s3, 16(sp) |
179 | lw s2, 12(sp) |
180 | lw s1, 8(sp) |
181 | lw s0, 4(sp) |
182 | lw ra, 0(sp) |
183 | addiu sp, 64 |
184 | |
185 | jr ra |
186 | nop |
187 | END(brcm_pm_do_s2) |
188 | |
189 | .globl asm_end |
190 | asm_end: |
191 | nop |
192 | |
193 | |