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