xref: /linux/drivers/soc/bcm/brcmstb/pm/s3-mips.S (revision 2db57789e6612ce0cf2fcbb577a1c8307b708566)
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/bmips.h>
18
19#include "pm.h"
20
21	.text
22	.set		noreorder
23	.align		5
24	.global		s3_reentry
25
26/*
27 * a0: AON_CTRL base register
28 * a1: D-Cache line size
29 */
30LEAF(brcm_pm_do_s3)
31
32	/* Get the address of s3_context */
33	la	t0, gp_regs
34	sw	ra, 0(t0)
35	sw	s0, 4(t0)
36	sw	s1, 8(t0)
37	sw	s2, 12(t0)
38	sw	s3, 16(t0)
39	sw	s4, 20(t0)
40	sw	s5, 24(t0)
41	sw	s6, 28(t0)
42	sw	s7, 32(t0)
43	sw	gp, 36(t0)
44	sw	sp, 40(t0)
45	sw	fp, 44(t0)
46
47	/* Save CP0 Status */
48	mfc0	t1, CP0_STATUS
49	sw	t1, 48(t0)
50
51	/* Write-back gp registers - cache will be gone */
52	addiu	t1, a1, -1
53	not	t1
54	and	t0, t1
55
56	/* Flush at least 64 bytes */
57	addiu	t2, t0, 64
58	and	t2, t1
59
601:	cache	0x17, 0(t0)
61	bne	t0, t2, 1b
62	addu	t0, a1
63
64	/* Drop to deep standby */
65	li	t1, PM_WARM_CONFIG
66	sw	zero, AON_CTRL_PM_CTRL(a0)
67	lw	zero, AON_CTRL_PM_CTRL(a0)
68	sw	t1, AON_CTRL_PM_CTRL(a0)
69	lw	t1, AON_CTRL_PM_CTRL(a0)
70
71	li	t1, (PM_WARM_CONFIG | PM_PWR_DOWN)
72	sw	t1, AON_CTRL_PM_CTRL(a0)
73	lw	t1, AON_CTRL_PM_CTRL(a0)
74
75	/* Enable CP0 interrupt 2 and wait for interrupt */
76	mfc0	t0, CP0_STATUS
77
78	li	t1, ~(ST0_IM | ST0_IE)
79	and	t0, t1
80	ori	t0, STATUSF_IP2
81	mtc0	t0, CP0_STATUS
82	nop
83	nop
84	nop
85	ori	t0, ST0_IE
86	mtc0	t0, CP0_STATUS
87
88        /* Wait for interrupt */
89        wait
90        nop
91
92s3_reentry:
93
94	/* Clear call/return stack */
95	li	t0, (0x06 << 16)
96	mtc0	t0, $22, 2
97	ssnop
98	ssnop
99	ssnop
100
101	/* Clear jump target buffer */
102	li	t0, (0x04 << 16)
103	mtc0	t0, $22, 2
104	ssnop
105	ssnop
106	ssnop
107
108	sync
109	nop
110
111	/* Setup mmu defaults */
112	mtc0	zero, CP0_WIRED
113	mtc0	zero, CP0_ENTRYHI
114	li	k0, PM_DEFAULT_MASK
115	mtc0	k0, CP0_PAGEMASK
116
117	li	sp, BMIPS_WARM_RESTART_VEC
118	la	k0, plat_wired_tlb_setup
119	jalr	k0
120	nop
121
122	/* Restore general purpose registers */
123	la	t0, gp_regs
124	lw	fp, 44(t0)
125	lw	sp, 40(t0)
126	lw	gp, 36(t0)
127	lw	s7, 32(t0)
128	lw	s6, 28(t0)
129	lw	s5, 24(t0)
130	lw	s4, 20(t0)
131	lw	s3, 16(t0)
132	lw	s2, 12(t0)
133	lw	s1, 8(t0)
134	lw	s0, 4(t0)
135	lw	ra, 0(t0)
136
137	/* Restore CP0 status */
138	lw	t1, 48(t0)
139	mtc0	t1, CP0_STATUS
140
141	/* Return to caller */
142	li	v0, 0
143	jr      ra
144	nop
145
146END(brcm_pm_do_s3)
147