xref: /openbmc/linux/drivers/soc/bcm/brcmstb/pm/s2-mips.S (revision 8447d84e)
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 */
28LEAF(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
691:	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
762:	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 */
1121:	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 */
1351:	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
1581:	cache	0x00, 0(t0)
159	bne	t0, t2, 1b
160	addu	t0, s3
161
162	/* Unlock interrupt vector */
163	move	t0, zero
164
1652:	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
195END(brcm_pm_do_s2)
196
197	.globl asm_end
198asm_end:
199	nop
200
201