blob: d8869381accd1d9deff7763cedcac7e2f0925da2 [file] [log] [blame]
stefano babic6708a602007-08-30 23:01:49 +02001/*
2 * This was originally from the Lubbock u-boot port.
3 *
4 * Most of this taken from Redboot hal_platform_setup.h with cleanup
5 *
6 * NOTE: I haven't clean this up considerably, just enough to get it
7 * running. See hal_platform_setup.h for the source. See
8 * board/cradle/lowlevel_init.S for another PXA250 setup that is
9 * much cleaner.
10 *
11 * See file CREDITS for list of people who contributed to this
12 * project.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 * MA 02111-1307 USA
28 */
29
30#include <config.h>
31#include <version.h>
32#include <asm/arch/pxa-regs.h>
33
34/* wait for coprocessor write complete */
35 .macro CPWAIT reg
36 mrc p15,0,\reg,c2,c0,0
37 mov \reg,\reg
38 sub pc,pc,#4
39 .endm
40
41
42/*
43 * Memory setup
44 */
45
46.globl lowlevel_init
47lowlevel_init:
48
49 /* Set up GPIO pins first ----------------------------------------- */
50
51 ldr r0, =GPSR0
52 ldr r1, =CFG_GPSR0_VAL
53 str r1, [r0]
54
55 ldr r0, =GPSR1
56 ldr r1, =CFG_GPSR1_VAL
57 str r1, [r0]
58
59 ldr r0, =GPSR2
60 ldr r1, =CFG_GPSR2_VAL
61 str r1, [r0]
62
63 ldr r0, =GPSR3
64 ldr r1, =CFG_GPSR3_VAL
65 str r1, [r0]
66
67 ldr r0, =GPCR0
68 ldr r1, =CFG_GPCR0_VAL
69 str r1, [r0]
70
71 ldr r0, =GPCR1
72 ldr r1, =CFG_GPCR1_VAL
73 str r1, [r0]
74
75 ldr r0, =GPCR2
76 ldr r1, =CFG_GPCR2_VAL
77 str r1, [r0]
78
79 ldr r0, =GPCR3
80 ldr r1, =CFG_GPCR3_VAL
81 str r1, [r0]
82
83 ldr r0, =GRER0
84 ldr r1, =CFG_GRER0_VAL
85 str r1, [r0]
86
87 ldr r0, =GRER1
88 ldr r1, =CFG_GRER1_VAL
89 str r1, [r0]
90
91 ldr r0, =GRER2
92 ldr r1, =CFG_GRER2_VAL
93 str r1, [r0]
94
95 ldr r0, =GRER3
96 ldr r1, =CFG_GRER3_VAL
97 str r1, [r0]
98
99 ldr r0, =GFER0
100 ldr r1, =CFG_GFER0_VAL
101 str r1, [r0]
102
103 ldr r0, =GFER1
104 ldr r1, =CFG_GFER1_VAL
105 str r1, [r0]
106
107 ldr r0, =GFER2
108 ldr r1, =CFG_GFER2_VAL
109 str r1, [r0]
110
111 ldr r0, =GFER3
112 ldr r1, =CFG_GFER3_VAL
113 str r1, [r0]
114
115 ldr r0, =GPDR0
116 ldr r1, =CFG_GPDR0_VAL
117 str r1, [r0]
118
119 ldr r0, =GPDR1
120 ldr r1, =CFG_GPDR1_VAL
121 str r1, [r0]
122
123 ldr r0, =GPDR2
124 ldr r1, =CFG_GPDR2_VAL
125 str r1, [r0]
126
127 ldr r0, =GPDR3
128 ldr r1, =CFG_GPDR3_VAL
129 str r1, [r0]
130
131 ldr r0, =GAFR0_L
132 ldr r1, =CFG_GAFR0_L_VAL
133 str r1, [r0]
134
135 ldr r0, =GAFR0_U
136 ldr r1, =CFG_GAFR0_U_VAL
137 str r1, [r0]
138
139 ldr r0, =GAFR1_L
140 ldr r1, =CFG_GAFR1_L_VAL
141 str r1, [r0]
142
143 ldr r0, =GAFR1_U
144 ldr r1, =CFG_GAFR1_U_VAL
145 str r1, [r0]
146
147 ldr r0, =GAFR2_L
148 ldr r1, =CFG_GAFR2_L_VAL
149 str r1, [r0]
150
151 ldr r0, =GAFR2_U
152 ldr r1, =CFG_GAFR2_U_VAL
153 str r1, [r0]
154
155 ldr r0, =GAFR3_L
156 ldr r1, =CFG_GAFR3_L_VAL
157 str r1, [r0]
158
159 ldr r0, =GAFR3_U
160 ldr r1, =CFG_GAFR3_U_VAL
161 str r1, [r0]
162
163 ldr r0, =PSSR /* enable GPIO pins */
164 ldr r1, =CFG_PSSR_VAL
165 str r1, [r0]
166
167 /* ---------------------------------------------------------------- */
168 /* Enable memory interface */
169 /* */
170 /* The sequence below is based on the recommended init steps */
171 /* detailed in the Intel PXA250 Operating Systems Developers Guide, */
172 /* Chapter 10. */
173 /* ---------------------------------------------------------------- */
174
175 /* ---------------------------------------------------------------- */
176 /* Step 1: Wait for at least 200 microsedonds to allow internal */
177 /* clocks to settle. Only necessary after hard reset... */
178 /* FIXME: can be optimized later */
179 /* ---------------------------------------------------------------- */
180
181 ldr r3, =OSCR /* reset the OS Timer Count to zero */
182 mov r2, #0
183 str r2, [r3]
184 ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
185 /* so 0x300 should be plenty */
1861:
187 ldr r2, [r3]
188 cmp r4, r2
189 bgt 1b
190
191mem_init:
192
193 ldr r1, =MEMC_BASE /* get memory controller base addr. */
194
195 /* ---------------------------------------------------------------- */
196 /* Step 2a: Initialize Asynchronous static memory controller */
197 /* ---------------------------------------------------------------- */
198
199 /* MSC registers: timing, bus width, mem type */
200
201 /* MSC0: nCS(0,1) */
202 ldr r2, =CFG_MSC0_VAL
203 str r2, [r1, #MSC0_OFFSET]
204 ldr r2, [r1, #MSC0_OFFSET] /* read back to ensure */
205 /* that data latches */
206 /* MSC1: nCS(2,3) */
207 ldr r2, =CFG_MSC1_VAL
208 str r2, [r1, #MSC1_OFFSET]
209 ldr r2, [r1, #MSC1_OFFSET]
210
211 /* MSC2: nCS(4,5) */
212 ldr r2, =CFG_MSC2_VAL
213 str r2, [r1, #MSC2_OFFSET]
214 ldr r2, [r1, #MSC2_OFFSET]
215
216 /* ---------------------------------------------------------------- */
217 /* Step 2b: Initialize Card Interface */
218 /* ---------------------------------------------------------------- */
219
220 /* MECR: Memory Expansion Card Register */
221 ldr r2, =CFG_MECR_VAL
222 str r2, [r1, #MECR_OFFSET]
223 ldr r2, [r1, #MECR_OFFSET]
224
225 /* MCMEM0: Card Interface slot 0 timing */
226 ldr r2, =CFG_MCMEM0_VAL
227 str r2, [r1, #MCMEM0_OFFSET]
228 ldr r2, [r1, #MCMEM0_OFFSET]
229
230 /* MCMEM1: Card Interface slot 1 timing */
231 ldr r2, =CFG_MCMEM1_VAL
232 str r2, [r1, #MCMEM1_OFFSET]
233 ldr r2, [r1, #MCMEM1_OFFSET]
234
235 /* MCATT0: Card Interface Attribute Space Timing, slot 0 */
236 ldr r2, =CFG_MCATT0_VAL
237 str r2, [r1, #MCATT0_OFFSET]
238 ldr r2, [r1, #MCATT0_OFFSET]
239
240 /* MCATT1: Card Interface Attribute Space Timing, slot 1 */
241 ldr r2, =CFG_MCATT1_VAL
242 str r2, [r1, #MCATT1_OFFSET]
243 ldr r2, [r1, #MCATT1_OFFSET]
244
245 /* MCIO0: Card Interface I/O Space Timing, slot 0 */
246 ldr r2, =CFG_MCIO0_VAL
247 str r2, [r1, #MCIO0_OFFSET]
248 ldr r2, [r1, #MCIO0_OFFSET]
249
250 /* MCIO1: Card Interface I/O Space Timing, slot 1 */
251 ldr r2, =CFG_MCIO1_VAL
252 str r2, [r1, #MCIO1_OFFSET]
253 ldr r2, [r1, #MCIO1_OFFSET]
254
255 /* ---------------------------------------------------------------- */
256 /* Step 2c: Write FLYCNFG FIXME: what's that??? */
257 /* ---------------------------------------------------------------- */
258 ldr r2, =CFG_FLYCNFG_VAL
259 str r2, [r1, #FLYCNFG_OFFSET]
260 str r2, [r1, #FLYCNFG_OFFSET]
261
262 /* ---------------------------------------------------------------- */
263 /* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */
264 /* ---------------------------------------------------------------- */
265
266 /* Before accessing MDREFR we need a valid DRI field, so we set */
267 /* this to power on defaults + DRI field. */
268
269 ldr r4, [r1, #MDREFR_OFFSET]
270 ldr r2, =0xFFF
271 bic r4, r4, r2
272
273 ldr r3, =CFG_MDREFR_VAL
274 and r3, r3, r2
275
276 orr r4, r4, r3
277 str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
278
279 orr r4, r4, #MDREFR_K0RUN
280 orr r4, r4, #MDREFR_K0DB4
281 orr r4, r4, #MDREFR_K0FREE
282 orr r4, r4, #MDREFR_K0DB2
283 orr r4, r4, #MDREFR_K1DB2
284 bic r4, r4, #MDREFR_K1FREE
285 bic r4, r4, #MDREFR_K2FREE
286
287 str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
288 ldr r4, [r1, #MDREFR_OFFSET]
289
290 /* Note: preserve the mdrefr value in r4 */
291
292
293 /* ---------------------------------------------------------------- */
294 /* Step 3: Initialize Synchronous Static Memory (Flash/Peripherals) */
295 /* ---------------------------------------------------------------- */
296
297 /* Initialize SXCNFG register. Assert the enable bits */
298
299 /* Write SXMRS to cause an MRS command to all enabled banks of */
300 /* synchronous static memory. Note that SXLCR need not be written */
301 /* at this time. */
302
303 ldr r2, =CFG_SXCNFG_VAL
304 str r2, [r1, #SXCNFG_OFFSET]
305
306 /* ---------------------------------------------------------------- */
307 /* Step 4: Initialize SDRAM */
308 /* ---------------------------------------------------------------- */
309
310 bic r4, r4, #(MDREFR_K2FREE |MDREFR_K1FREE | MDREFR_K0FREE)
311
312 orr r4, r4, #MDREFR_K1RUN
313 bic r4, r4, #MDREFR_K2DB2
314 str r4, [r1, #MDREFR_OFFSET]
315 ldr r4, [r1, #MDREFR_OFFSET]
316
317 bic r4, r4, #MDREFR_SLFRSH
318 str r4, [r1, #MDREFR_OFFSET]
319 ldr r4, [r1, #MDREFR_OFFSET]
320
321 orr r4, r4, #MDREFR_E1PIN
322 str r4, [r1, #MDREFR_OFFSET]
323 ldr r4, [r1, #MDREFR_OFFSET]
324
325 nop
326 nop
327
328
329 /* Step 4d: write MDCNFG with MDCNFG:DEx deasserted (set to 0), to */
330 /* configure but not enable each SDRAM partition pair. */
331
332 ldr r4, =CFG_MDCNFG_VAL
333 bic r4, r4, #(MDCNFG_DE0|MDCNFG_DE1)
334 bic r4, r4, #(MDCNFG_DE2|MDCNFG_DE3)
335
336 str r4, [r1, #MDCNFG_OFFSET] /* write back MDCNFG */
337 ldr r4, [r1, #MDCNFG_OFFSET]
338
339
340 /* Step 4e: Wait for the clock to the SDRAMs to stabilize, */
341 /* 100..200 µsec. */
342
343 ldr r3, =OSCR /* reset the OS Timer Count to zero */
344 mov r2, #0
345 str r2, [r3]
346 ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
347 /* so 0x300 should be plenty */
3481:
349 ldr r2, [r3]
350 cmp r4, r2
351 bgt 1b
352
353
354 /* Step 4f: Trigger a number (usually 8) refresh cycles by */
355 /* attempting non-burst read or write accesses to disabled */
356 /* SDRAM, as commonly specified in the power up sequence */
357 /* documented in SDRAM data sheets. The address(es) used */
358 /* for this purpose must not be cacheable. */
359
360 ldr r3, =CFG_DRAM_BASE
361 str r2, [r3]
362 str r2, [r3]
363 str r2, [r3]
364 str r2, [r3]
365 str r2, [r3]
366 str r2, [r3]
367 str r2, [r3]
368 str r2, [r3]
369
370
371 /* Step 4g: Write MDCNFG with enable bits asserted */
372 /* (MDCNFG:DEx set to 1). */
373
374 ldr r3, [r1, #MDCNFG_OFFSET]
375 mov r4, r3
376 orr r3, r3, #MDCNFG_DE0
377 str r3, [r1, #MDCNFG_OFFSET]
378 mov r0, r3
379
380 /* Step 4h: Write MDMRS. */
381
382 ldr r2, =CFG_MDMRS_VAL
383 str r2, [r1, #MDMRS_OFFSET]
384
385 /* enable APD */
386 ldr r3, [r1, #MDREFR_OFFSET]
387 orr r3, r3, #MDREFR_APD
388 str r3, [r1, #MDREFR_OFFSET]
389
390 /* We are finished with Intel's memory controller initialisation */
391
392
393setvoltage:
394
395 mov r10, lr
396 bl initPXAvoltage /* In case the board is rebooting with a */
397 mov lr, r10 /* low voltage raise it up to a good one. */
398
399#if 1
400 b initirqs
401#endif
402
403wakeup:
404 /* Are we waking from sleep? */
405 ldr r0, =RCSR
406 ldr r1, [r0]
407 and r1, r1, #(RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR)
408 str r1, [r0]
409 teq r1, #RCSR_SMR
410
411 bne initirqs
412
413 ldr r0, =PSSR
414 mov r1, #PSSR_PH
415 str r1, [r0]
416
417 /* if so, resume at PSPR */
418 ldr r0, =PSPR
419 ldr r1, [r0]
420 mov pc, r1
421
422 /* ---------------------------------------------------------------- */
423 /* Disable (mask) all interrupts at interrupt controller */
424 /* ---------------------------------------------------------------- */
425
426initirqs:
427
428 mov r1, #0 /* clear int. level register (IRQ, not FIQ) */
429 ldr r2, =ICLR
430 str r1, [r2]
431
432 ldr r2, =ICMR /* mask all interrupts at the controller */
433 str r1, [r2]
434
435 /* ---------------------------------------------------------------- */
436 /* Clock initialisation */
437 /* ---------------------------------------------------------------- */
438
439initclks:
440
441 /* Disable the peripheral clocks, and set the core clock frequency */
442
443 /* Turn Off on-chip peripheral clocks (except for memory) */
444 /* for re-configuration. */
445 ldr r1, =CKEN
446 ldr r2, =CFG_CKEN
447 str r2, [r1]
448
449 /* ... and write the core clock config register */
450 ldr r2, =CFG_CCCR
451 ldr r1, =CCCR
452 str r2, [r1]
453
454 /* Turn on turbo mode */
455 mrc p14, 0, r2, c6, c0, 0
456 orr r2, r2, #0xB /* Turbo, Fast-Bus, Freq change**/
457 mcr p14, 0, r2, c6, c0, 0
458
459 /* Re-write MDREFR */
460 ldr r1, =MEMC_BASE
461 ldr r2, [r1, #MDREFR_OFFSET]
462 str r2, [r1, #MDREFR_OFFSET]
463#ifdef RTC
464 /* enable the 32Khz oscillator for RTC and PowerManager */
465 ldr r1, =OSCC
466 mov r2, #OSCC_OON
467 str r2, [r1]
468
469 /* NOTE: spin here until OSCC.OOK get set, meaning the PLL */
470 /* has settled. */
47160:
472 ldr r2, [r1]
473 ands r2, r2, #1
474 beq 60b
475#else
476#error "RTC not defined"
477#endif
478
479 /* Interrupt init: Mask all interrupts */
480 ldr r0, =ICMR /* enable no sources */
481 mov r1, #0
482 str r1, [r0]
483 /* FIXME */
484
485#ifdef NODEBUG
486 /*Disable software and data breakpoints */
487 mov r0,#0
488 mcr p15,0,r0,c14,c8,0 /* ibcr0 */
489 mcr p15,0,r0,c14,c9,0 /* ibcr1 */
490 mcr p15,0,r0,c14,c4,0 /* dbcon */
491
492 /*Enable all debug functionality */
493 mov r0,#0x80000000
494 mcr p14,0,r0,c10,c0,0 /* dcsr */
495#endif
496
497 /* ---------------------------------------------------------------- */
498 /* End lowlevel_init */
499 /* ---------------------------------------------------------------- */
500
501endlowlevel_init:
502
503 mov pc, lr