hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/* 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/stackframe.h>
 
#include "pm.h"
 
   .text
   .set    noreorder
   .align    5
 
/*
 * a0: u32 params array
 */
LEAF(brcm_pm_do_s2)
 
   subu    sp, 64
   sw    ra, 0(sp)
   sw    s0, 4(sp)
   sw    s1, 8(sp)
   sw    s2, 12(sp)
   sw    s3, 16(sp)
   sw    s4, 20(sp)
   sw    s5, 24(sp)
   sw    s6, 28(sp)
   sw    s7, 32(sp)
 
   /*
    * Dereference the params array
    * s0: AON_CTRL base register
    * s1: DDR_PHY base register
    * s2: TIMERS base register
    * s3: I-Cache line size
    * s4: Restart vector address
    * s5: Restart vector size
    */
   move    t0, a0
 
   lw    s0, 0(t0)
   lw    s1, 4(t0)
   lw    s2, 8(t0)
   lw    s3, 12(t0)
   lw    s4, 16(t0)
   lw    s5, 20(t0)
 
   /* Lock this asm section into the I-cache */
   addiu    t1, s3, -1
   not    t1
 
   la    t0, brcm_pm_do_s2
   and    t0, t1
 
   la    t2, asm_end
   and    t2, t1
 
1:    cache    0x1c, 0(t0)
   bne    t0, t2, 1b
   addu    t0, s3
 
   /* Lock the interrupt vector into the I-cache */
   move    t0, zero
 
2:    move    t1, s4
   cache     0x1c, 0(t1)
   addu    t1, s3
   addu    t0, s3
   ble    t0, s5, 2b
   nop
 
   sync
 
   /* Power down request */
   li    t0, PM_S2_COMMAND
   sw    zero, AON_CTRL_PM_CTRL(s0)
   lw    zero, AON_CTRL_PM_CTRL(s0)
   sw    t0, AON_CTRL_PM_CTRL(s0)
   lw    t0, AON_CTRL_PM_CTRL(s0)
 
   /* Enable CP0 interrupt 2 and wait for interrupt */
   mfc0    t0, CP0_STATUS
   /* Save cp0 sr for restoring later */
   move    s6, t0
 
   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
 
   /* Wait for memc0 */
1:    lw    t0, DDR40_PHY_CONTROL_REGS_0_PLL_STATUS(s1)
   andi    t0, 1
   beqz    t0, 1b
   nop
 
   /* 1ms delay needed for stable recovery */
   /* Use TIMER1 to count 1 ms */
   li    t0, RESET_TIMER
   sw    t0, TIMER_TIMER1_CTRL(s2)
   lw    t0, TIMER_TIMER1_CTRL(s2)
 
   li    t0, START_TIMER
   sw    t0, TIMER_TIMER1_CTRL(s2)
   lw    t0, TIMER_TIMER1_CTRL(s2)
 
   /* Prepare delay */
   li    t0, TIMER_MASK
   lw    t1, TIMER_TIMER1_STAT(s2)
   and    t1, t0
   /* 1ms delay */
   addi    t1, 27000
 
   /* Wait for the timer value to exceed t1 */
1:    lw    t0, TIMER_TIMER1_STAT(s2)
   sgtu    t2, t1, t0
   bnez    t2, 1b
   nop
 
   /* Power back up */
   li    t1, 1
   sw    t1, AON_CTRL_HOST_MISC_CMDS(s0)
   lw    t1, AON_CTRL_HOST_MISC_CMDS(s0)
 
   sw    zero, AON_CTRL_PM_CTRL(s0)
   lw    zero, AON_CTRL_PM_CTRL(s0)
 
   /* Unlock I-cache */
   addiu    t1, s3, -1
   not    t1
 
   la    t0, brcm_pm_do_s2
   and     t0, t1
 
   la    t2, asm_end
   and    t2, t1
 
1:    cache    0x00, 0(t0)
   bne    t0, t2, 1b
   addu    t0, s3
 
   /* Unlock interrupt vector */
   move    t0, zero
 
2:    move    t1, s4
   cache     0x00, 0(t1)
   addu    t1, s3
   addu    t0, s3
   ble    t0, s5, 2b
   nop
 
   /* Restore cp0 sr */
   sync
   nop
   mtc0    s6, CP0_STATUS
   nop
 
   /* Set return value to success */
   li    v0, 0
 
   /* Return to caller */
   lw    s7, 32(sp)
   lw    s6, 28(sp)
   lw    s5, 24(sp)
   lw    s4, 20(sp)
   lw    s3, 16(sp)
   lw    s2, 12(sp)
   lw    s1, 8(sp)
   lw    s0, 4(sp)
   lw    ra, 0(sp)
   addiu    sp, 64
 
   jr ra
   nop
END(brcm_pm_do_s2)
 
   .globl asm_end
asm_end:
   nop