Merge tag 'reset-for-v5.3' of git://git.pengutronix.de/git/pza/linux into arm/drivers
[sfrench/cifs-2.6.git] / drivers / soc / bcm / brcmstb / pm / s2-mips.S
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