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