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
|
/*
* Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/linkage.h>
#include <mach/hardware.h>
/*
* mx6_wait
*
* Idle the processor (eg, wait for interrupt).
* Make sure DDR is in self-refresh.
* IRQs are already disabled.
*/
ENTRY(mx6_wait)
push {r4, r5, r6, r7, r8}
mov r7, r2 /* Store the arm_podf to be used. */
mov r6, r3
ldr r2, =ANATOP_BASE_ADDR
add r2, r2, #PERIPBASE_VIRT
ldr r8, =CCM_BASE_ADDR
add r8, r8, #PERIPBASE_VIRT
/* get the flags variables into the cache */
ldr r3, [r0]
/* get CPU ID */
mrc p15,0,r5,c0,c0,5
and r5, r5, #0x3
mov r4,#0xff
strb r4,[r0,r5]
dsb
mvn r4, #0x0
ldr r3, [r0]
cmp r3, r4
bne DO_WFI
mov r4, #0x1
ldrex r3, [r1]
cmp r3, #0x0
strexeq r3, r4, [r1]
cmpeq r3, #0x0
bne DO_WFI
mov r3, #0xff
/* Check to see if we need to switch to 24MHz */
cmp r7, #0
bne use_podf
ldr r6, =(1 << 16)
str r6, [r2, #0x04]
b cont
use_podf:
/* Change ARM_PODF to the max possible podf
* so that ARM_CLK to IPG_CLK is in 12:5 ratio.
*/
str r7, [r8, #0x10]
/* Loop till podf is accepted. */
podf_loop:
ldr r4, [r8, #0x48]
cmp r4, #0x0
bne podf_loop
/* dmb */
cont:
str r3, [r1]
dsb
mvn r4, #0x0
ldr r3, [r0]
cmp r3, r4
beq DO_WFI
mov r3, #0x0
/* Switch to 24MHz or use ARM_PODF. */
cmp r7, #0x0
bne use_podf1
str r6, [r2, #0x08]
b DO_WFI
use_podf1:
str r6, [r8, #0x10]
str r3, [r1]
DO_WFI:
dsb
wfi
mov r4, #0x0
strb r4, [r0, r5]
dsb
ldr r3, [r1]
cmp r3, #0xff
bne DONE
mov r4, #0x0
cmp r7, #0x0
bne use_podf2
ldr r6, =(1 << 16)
str r6, [r2, #0x08]
b cont1
use_podf2:
str r6, [r8, #0x10]
cont1:
mov r3, #0x0
str r3, [r1]
DONE:
pop {r4,r5, r6, r7, r8}
/* Restore registers */
mov pc, lr
.type mx6_do_wait, #object
ENTRY(mx6_do_wait)
.word mx6_wait
.size mx6_wait, . - mx6_wait
|