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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
/*
* Freescale MX28 low level RAM frequency manipulation
*
* Author: Vitaly Wool <vital@embeddedalley.com>
*
* Copyright 2008-2010 Freescale Semiconductor, Inc.
* Copyright 2008 Embedded Alley Solutions, 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 <asm/assembler.h>
#include <asm/system.h>
#include <asm/pgtable-hwdef.h>
#include <mach/hardware.h>
#include <mach/regs-power.h>
#include "regs-clkctrl.h"
#include "regs-dram.h"
#include "regs-digctl.h"
#include "emi_settings.h"
.global cpu_arm926_switch_mm
.align 8
ENTRY(mxs_ram_freq_scale)
stmfd sp!, {r1 - r10, lr}
ldr r5, [r0, #SCALING_DATA_NEW_FREQ_OFFSET]
ldr r6, [r0, #SCALING_DATA_CUR_FREQ_OFFSET]
ldr r7, [r0, #SCALING_DATA_EMI_DIV_OFFSET]
mov r7, r7, LSL #BP_CLKCTRL_EMI_DIV_EMI
ldr r8, [r0, #SCALING_DATA_FRAC_DIV_OFFSET]
mov r8, r8, LSL #BP_CLKCTRL_FRAC0_EMIFRAC
@copy memory setting to iram
mov r2, #MX28_DRAMCTRLREGNUM
adr r0, __mx28_emisetting
1: ldr r3, [r1]
str r3, [r0]
add r0, r0, #4
add r1, r1, #4
subs r2, r2, #1
bne 1b
@set temp static to iram.
adr r9, __mxs_temp_stack
@ clean cache
ldr r1, __mxs_flush_cache_addr
mov lr, pc
mov pc, r1
mov r2, #MX28_SOC_IO_ADDRESS(CLKCTRL_PHYS_ADDR)&0xFF
orr r2, r2, #MX28_SOC_IO_ADDRESS(CLKCTRL_PHYS_ADDR)&0xFF00
orr r2, r2, #MX28_SOC_IO_ADDRESS(CLKCTRL_PHYS_ADDR)&0xFF0000
orr r2, r2, #MX28_SOC_IO_ADDRESS(CLKCTRL_PHYS_ADDR)&0xFF000000
mov r0, r2
bl lock_vector_tlb
mov r0, #MX28_SOC_IO_ADDRESS(DRAM_PHYS_ADDR)&0xFF
orr r0, r0, #MX28_SOC_IO_ADDRESS(DRAM_PHYS_ADDR)&0xFF00
orr r0, r0, #MX28_SOC_IO_ADDRESS(DRAM_PHYS_ADDR)&0xFF0000
orr r0, r0, #MX28_SOC_IO_ADDRESS(DRAM_PHYS_ADDR)&0xFF000000
@ Make sure emi not busy
2:
ldr r1, [r0, #HW_DRAM_CTL08]
tst r1, #BM_DRAM_CTL08_CONTROLLER_BUSY
bne 2b
@ put DRAM into self refresh
ldr r1, [r0, #HW_DRAM_CTL17]
orr r1, r1, #BM_DRAM_CTL17_SREFRESH
str r1, [r0, #HW_DRAM_CTL17]
3:
ldr r1, [r0, #HW_DRAM_CTL172]
tst r1, #BM_DRAM_CTL172_CKE_STATUS
beq 3b
ldr r1, [r0, #HW_DRAM_CTL58]
orr r1, #BF_DRAM_CTL58_INT_MASK(0x100)
str r1, [r0, #HW_DRAM_CTL58]
@stop emi controller
ldr r1, [r0, #HW_DRAM_CTL16]
bic r1, r1, #BM_DRAM_CTL16_START
str r1, [r0, #HW_DRAM_CTL16]
@clear lock status HW_DRAM_CTL164_CLR(BF_DRAM_CTL164_INT_ACK(0x3ff));
ldr r1, [r0, #HW_DRAM_CTL164]
bic r1, r1, #BF_DRAM_CTL164_INT_ACK(0xff)
bic r1, r1, #BF_DRAM_CTL164_INT_ACK(0x300)
str r1, [r0, #HW_DRAM_CTL164]
ldr r1, [r2, #HW_CLKCTRL_FRAC0]
and r1, #BM_CLKCTRL_FRAC0_EMIFRAC
ldr r3, [r2, #HW_CLKCTRL_EMI]
and r3, #BM_CLKCTRL_EMI_DIV_EMI
/*
* The fractional divider and integer divider must be written in such
* an order to guarantee that when going from a lower frequency to a
* higher frequency that any intermediate frequencies do not exceed
* the final frequency. For this reason, we must make sure to check
* the current divider values with the new divider values and write
* them in the correct order.
*/
ldr r9, [r2, #HW_CLKCTRL_FRAC0]
bic r9, #BM_CLKCTRL_FRAC0_EMIFRAC
orr r9, r8
ldr r10, [r2, #HW_CLKCTRL_EMI]
bic r10, #BM_CLKCTRL_EMI_DIV_EMI
orr r10, r7
cmp r8, r1
strgt r9, [r2, #HW_CLKCTRL_FRAC0]
cmp r7, r3
strgt r10, [r2, #HW_CLKCTRL_EMI]
cmp r8, r1
strlt r9, [r2, #HW_CLKCTRL_FRAC0]
cmp r7, r3
strlt r10, [r2, #HW_CLKCTRL_EMI]
@copy memory setting to iram
mov r3, r0
adr r4, __mx28_emisetting
mov r6, #MX28_DRAMCTRLREGNUM
8: ldr r5, [r4]
str r5, [r3]
add r3, r3, #4
add r4, r4, #4
subs r6, r6, #1
bne 8b
7: ldr r1, [r2, #HW_CLKCTRL_EMI]
tst r1, #BM_CLKCTRL_EMI_BUSY_REF_EMI
bne 7b
@Restart memory controller
ldr r1, [r0, #HW_DRAM_CTL16]
orr r1, #BM_DRAM_CTL16_START
str r1, [r0, #HW_DRAM_CTL16]
/*Wait DLL is locked*/
9:
ldr r1, [r0, #HW_DRAM_CTL21]
tst r1, #BM_DRAM_CTL21_DLLLOCKREG
beq 9b
@11. Exit Memory self-refresh
ldr r1, [r0, #HW_DRAM_CTL17]
bic r1, r1, #BM_DRAM_CTL17_SREFRESH
str r1, [r0, #HW_DRAM_CTL17]
@Wait Memory device exit into self-refresh
10:
ldr r1, [r0, #HW_DRAM_CTL172]
tst r1, #BM_DRAM_CTL172_CKE_STATUS
bne 10b
mov r2, #MX28_SOC_IO_ADDRESS(DIGCTL_PHYS_ADDR)&0xFF
orr r2, r2, #MX28_SOC_IO_ADDRESS(DIGCTL_PHYS_ADDR)&0xFF00
orr r2, r2, #MX28_SOC_IO_ADDRESS(DIGCTL_PHYS_ADDR)&0xFF0000
orr r2, r2, #MX28_SOC_IO_ADDRESS(DIGCTL_PHYS_ADDR)&0xFF000000
ldr r0, [r2, #HW_DIGCTL_MICROSECONDS];
add r0, #100
11: ldr r1, [r2, #HW_DIGCTL_MICROSECONDS];
cmp r1, r0
blt 11b
@ restore regs and return
ldmfd sp!, {r1 - r10, lr}
mov pc, lr
.space 0x100
__mxs_temp_stack:
.word 0
__mx28_emisetting:
.space MX28_DRAMCTRLREGNUM*4
lock_vector_tlb:
mov r1, r0 @ set r1 to the value of the address to be locked down
mcr p15,0,r1,c8,c7,1 @ invalidate TLB single entry to ensure that
@ LockAddr is not already in the TLB
mrc p15,0,r0,c10,c0,0 @ read the lockdown register
orr r0,r0,#1 @ set the preserve bit
mcr p15,0,r0,c10,c0,0 @ write to the lockdown register
ldr r1,[r1] @ TLB will miss, and entry will be loaded
mrc p15,0,r0,c10,c0,0 @ read the lockdown register (victim will have
@ incremented)
bic r0,r0,#1 @ clear preserve bit
mcr p15,0,r0,c10,c0,0 @ write to the lockdown registerADR r1,LockAddr
mov pc,lr
__mxs_flush_cache_addr:
.word arm926_flush_kern_cache_all
ENTRY(mxs_ram_funcs_sz)
.word . - mxs_ram_freq_scale
ENTRY(mxs_ram_freq_scale_end)
|