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 */
20LEAF(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
611: 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
682: 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 */
1041: 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 */
1271: 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
1501: cache 0x00, 0(t0)
151 bne t0, t2, 1b
152 addu t0, s3
153
154 /* Unlock interrupt vector */
155 move t0, zero
156
1572: 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
187END(brcm_pm_do_s2)
188
189 .globl asm_end
190asm_end:
191 nop
192
193

source code of linux/drivers/soc/bcm/brcmstb/pm/s2-mips.S