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