]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/ppc4xx/start.S
Add support for AMCC Sequoia PPC440EPx eval board
[people/ms/u-boot.git] / cpu / ppc4xx / start.S
CommitLineData
0442ed86
WD
1/*
2 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
3 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4 * Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24/*------------------------------------------------------------------------------+ */
25/* */
26/* This source code has been made available to you by IBM on an AS-IS */
27/* basis. Anyone receiving this source is licensed under IBM */
28/* copyrights to use it in any way he or she deems fit, including */
29/* copying it, modifying it, compiling it, and redistributing it either */
30/* with or without modifications. No license under IBM patents or */
31/* patent applications is to be implied by the copyright license. */
32/* */
33/* Any user of this software should understand that IBM cannot provide */
34/* technical support for this software and will not be responsible for */
35/* any consequences resulting from the use of this software. */
36/* */
37/* Any person who transfers this source code or any derivative work */
38/* must include the IBM copyright notice, this paragraph, and the */
39/* preceding two paragraphs in the transferred software. */
40/* */
41/* COPYRIGHT I B M CORPORATION 1995 */
42/* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M */
43/*------------------------------------------------------------------------------- */
44
0c8721a4 45/* U-Boot - Startup Code for AMCC 4xx PowerPC based Embedded Boards
0442ed86
WD
46 *
47 *
48 * The processor starts at 0xfffffffc and the code is executed
49 * from flash/rom.
50 * in memory, but as long we don't jump around before relocating.
51 * board_init lies at a quite high address and when the cpu has
52 * jumped there, everything is ok.
53 * This works because the cpu gives the FLASH (CS0) the whole
54 * address space at startup, and board_init lies as a echo of
55 * the flash somewhere up there in the memorymap.
56 *
57 * board_init will change CS0 to be positioned at the correct
58 * address and (s)dram will be positioned at address 0
59 */
60#include <config.h>
61#include <mpc8xx.h>
62#include <ppc4xx.h>
63#include <version.h>
64
65#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
66
67#include <ppc_asm.tmpl>
68#include <ppc_defs.h>
69
70#include <asm/cache.h>
71#include <asm/mmu.h>
72
73#ifndef CONFIG_IDENT_STRING
74#define CONFIG_IDENT_STRING ""
75#endif
76
77#ifdef CFG_INIT_DCACHE_CS
78# if (CFG_INIT_DCACHE_CS == 0)
79# define PBxAP pb0ap
80# define PBxCR pb0cr
81# endif
82# if (CFG_INIT_DCACHE_CS == 1)
83# define PBxAP pb1ap
84# define PBxCR pb1cr
85# endif
86# if (CFG_INIT_DCACHE_CS == 2)
87# define PBxAP pb2ap
88# define PBxCR pb2cr
89# endif
90# if (CFG_INIT_DCACHE_CS == 3)
91# define PBxAP pb3ap
92# define PBxCR pb3cr
93# endif
94# if (CFG_INIT_DCACHE_CS == 4)
95# define PBxAP pb4ap
96# define PBxCR pb4cr
97# endif
98# if (CFG_INIT_DCACHE_CS == 5)
99# define PBxAP pb5ap
100# define PBxCR pb5cr
101# endif
102# if (CFG_INIT_DCACHE_CS == 6)
103# define PBxAP pb6ap
104# define PBxCR pb6cr
105# endif
106# if (CFG_INIT_DCACHE_CS == 7)
107# define PBxAP pb7ap
108# define PBxCR pb7cr
109# endif
110#endif /* CFG_INIT_DCACHE_CS */
111
112/* We don't want the MMU yet.
113*/
114#undef MSR_KERNEL
115#define MSR_KERNEL ( MSR_ME ) /* Machine Check */
116
117
118 .extern ext_bus_cntlr_init
119 .extern sdram_init
887e2ec9
SR
120#ifdef CONFIG_NAND_U_BOOT
121 .extern reconfig_tlb0
122#endif
0442ed86
WD
123
124/*
125 * Set up GOT: Global Offset Table
126 *
127 * Use r14 to access the GOT
128 */
887e2ec9 129#if !defined(CONFIG_NAND_SPL)
0442ed86
WD
130 START_GOT
131 GOT_ENTRY(_GOT2_TABLE_)
132 GOT_ENTRY(_FIXUP_TABLE_)
133
134 GOT_ENTRY(_start)
135 GOT_ENTRY(_start_of_vectors)
136 GOT_ENTRY(_end_of_vectors)
137 GOT_ENTRY(transfer_to_handler)
138
3b57fe0a 139 GOT_ENTRY(__init_end)
0442ed86 140 GOT_ENTRY(_end)
5d232d0e 141 GOT_ENTRY(__bss_start)
0442ed86 142 END_GOT
887e2ec9
SR
143#endif /* CONFIG_NAND_SPL */
144
145#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
146 /*
147 * NAND U-Boot image is started from offset 0
148 */
149 .text
150 bl reconfig_tlb0
151 GET_GOT
152 bl cpu_init_f /* run low-level CPU init code (from Flash) */
153 bl board_init_f
154#endif
0442ed86
WD
155
156/*
157 * 440 Startup -- on reset only the top 4k of the effective
158 * address space is mapped in by an entry in the instruction
159 * and data shadow TLB. The .bootpg section is located in the
160 * top 4k & does only what's necessary to map in the the rest
161 * of the boot rom. Once the boot rom is mapped in we can
162 * proceed with normal startup.
163 *
164 * NOTE: CS0 only covers the top 2MB of the effective address
165 * space after reset.
166 */
167
168#if defined(CONFIG_440)
887e2ec9 169#if !defined(CONFIG_NAND_SPL)
0442ed86 170 .section .bootpg,"ax"
887e2ec9 171#endif
0442ed86
WD
172 .globl _start_440
173
174/**************************************************************************/
175_start_440:
887e2ec9
SR
176 /*--------------------------------------------------------------------+
177 | 440EPX BUP Change - Hardware team request
178 +--------------------------------------------------------------------*/
179#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
180 sync
181 nop
182 nop
183#endif
6c5879f3
MB
184 /*----------------------------------------------------------------+
185 | Core bug fix. Clear the esr
186 +-----------------------------------------------------------------*/
edd6cf20 187 li r0,0
b87dfd28 188 mtspr esr,r0
0442ed86
WD
189 /*----------------------------------------------------------------*/
190 /* Clear and set up some registers. */
191 /*----------------------------------------------------------------*/
f901a83b
WD
192 iccci r0,r0 /* NOTE: operands not used for 440 */
193 dccci r0,r0 /* NOTE: operands not used for 440 */
0442ed86
WD
194 sync
195 li r0,0
196 mtspr srr0,r0
197 mtspr srr1,r0
198 mtspr csrr0,r0
199 mtspr csrr1,r0
887e2ec9
SR
200 /* NOTE: 440GX adds machine check status regs */
201#if defined(CONFIG_440) && !defined(CONFIG_440GP)
f901a83b
WD
202 mtspr mcsrr0,r0
203 mtspr mcsrr1,r0
887e2ec9 204 mfspr r1,mcsr
f901a83b 205 mtspr mcsr,r1
ba56f625 206#endif
0442ed86
WD
207 /*----------------------------------------------------------------*/
208 /* Initialize debug */
209 /*----------------------------------------------------------------*/
887e2ec9
SR
210 mfspr r1,dbcr0
211 andis. r1, r1, 0x8000 /* test DBCR0[EDM] bit */
212 bne skip_debug_init /* if set, don't clear debug register */
0442ed86
WD
213 mtspr dbcr0,r0
214 mtspr dbcr1,r0
215 mtspr dbcr2,r0
216 mtspr iac1,r0
217 mtspr iac2,r0
218 mtspr iac3,r0
219 mtspr dac1,r0
220 mtspr dac2,r0
221 mtspr dvc1,r0
222 mtspr dvc2,r0
223
224 mfspr r1,dbsr
225 mtspr dbsr,r1 /* Clear all valid bits */
887e2ec9 226skip_debug_init:
0442ed86
WD
227
228 /*----------------------------------------------------------------*/
229 /* CCR0 init */
230 /*----------------------------------------------------------------*/
231 /* Disable store gathering & broadcast, guarantee inst/data
232 * cache block touch, force load/store alignment
233 * (see errata 1.12: 440_33)
234 */
235 lis r1,0x0030 /* store gathering & broadcast disable */
236 ori r1,r1,0x6000 /* cache touch */
237 mtspr ccr0,r1
238
6c5879f3
MB
239#if defined (CONFIG_440SPE)
240 /*----------------------------------------------------------------+
241 | Initialize Core Configuration Reg1.
242 | a. ICDPEI: Record even parity. Normal operation.
243 | b. ICTPEI: Record even parity. Normal operation.
244 | c. DCTPEI: Record even parity. Normal operation.
245 | d. DCDPEI: Record even parity. Normal operation.
246 | e. DCUPEI: Record even parity. Normal operation.
247 | f. DCMPEI: Record even parity. Normal operation.
248 | g. FCOM: Normal operation
249 | h. MMUPEI: Record even parity. Normal operation.
250 | i. FFF: Flush only as much data as necessary.
edd6cf20 251 | j. TCS: Timebase increments from CPU clock.
6c5879f3 252 +-----------------------------------------------------------------*/
edd6cf20 253 li r0,0
6c5879f3
MB
254 mtspr ccr1, r0
255
256 /*----------------------------------------------------------------+
257 | Reset the timebase.
258 | The previous write to CCR1 sets the timebase source.
259 +-----------------------------------------------------------------*/
6c5879f3
MB
260 mtspr tbl, r0
261 mtspr tbu, r0
262#endif
263
0442ed86
WD
264 /*----------------------------------------------------------------*/
265 /* Setup interrupt vectors */
266 /*----------------------------------------------------------------*/
267 mtspr ivpr,r0 /* Vectors start at 0x0000_0000 */
f901a83b 268 li r1,0x0100
0442ed86 269 mtspr ivor0,r1 /* Critical input */
f901a83b 270 li r1,0x0200
0442ed86 271 mtspr ivor1,r1 /* Machine check */
f901a83b 272 li r1,0x0300
0442ed86 273 mtspr ivor2,r1 /* Data storage */
f901a83b 274 li r1,0x0400
0442ed86
WD
275 mtspr ivor3,r1 /* Instruction storage */
276 li r1,0x0500
277 mtspr ivor4,r1 /* External interrupt */
278 li r1,0x0600
279 mtspr ivor5,r1 /* Alignment */
280 li r1,0x0700
281 mtspr ivor6,r1 /* Program check */
282 li r1,0x0800
283 mtspr ivor7,r1 /* Floating point unavailable */
284 li r1,0x0c00
285 mtspr ivor8,r1 /* System call */
286 li r1,0x1000
287 mtspr ivor10,r1 /* Decrementer (PIT for 440) */
288 li r1,0x1400
289 mtspr ivor13,r1 /* Data TLB error */
290 li r1,0x1300
291 mtspr ivor14,r1 /* Instr TLB error */
292 li r1,0x2000
293 mtspr ivor15,r1 /* Debug */
294
295 /*----------------------------------------------------------------*/
296 /* Configure cache regions */
297 /*----------------------------------------------------------------*/
298 mtspr inv0,r0
299 mtspr inv1,r0
300 mtspr inv2,r0
301 mtspr inv3,r0
302 mtspr dnv0,r0
303 mtspr dnv1,r0
304 mtspr dnv2,r0
305 mtspr dnv3,r0
306 mtspr itv0,r0
307 mtspr itv1,r0
308 mtspr itv2,r0
309 mtspr itv3,r0
310 mtspr dtv0,r0
311 mtspr dtv1,r0
312 mtspr dtv2,r0
313 mtspr dtv3,r0
314
315 /*----------------------------------------------------------------*/
316 /* Cache victim limits */
317 /*----------------------------------------------------------------*/
318 /* floors 0, ceiling max to use the entire cache -- nothing locked
319 */
320 lis r1,0x0001
321 ori r1,r1,0xf800
322 mtspr ivlim,r1
323 mtspr dvlim,r1
324
6c5879f3
MB
325 /*----------------------------------------------------------------+
326 |Initialize MMUCR[STID] = 0.
327 +-----------------------------------------------------------------*/
328 mfspr r0,mmucr
329 addis r1,0,0xFFFF
330 ori r1,r1,0xFF00
331 and r0,r0,r1
332 mtspr mmucr,r0
333
0442ed86
WD
334 /*----------------------------------------------------------------*/
335 /* Clear all TLB entries -- TID = 0, TS = 0 */
336 /*----------------------------------------------------------------*/
6c5879f3 337 addis r0,0,0x0000
0442ed86
WD
338 li r1,0x003f /* 64 TLB entries */
339 mtctr r1
6c5879f3
MB
340rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
341 tlbwe r0,r1,0x0001
342 tlbwe r0,r1,0x0002
0442ed86 343 subi r1,r1,0x0001
6c5879f3 344 bdnz rsttlb
0442ed86
WD
345
346 /*----------------------------------------------------------------*/
347 /* TLB entry setup -- step thru tlbtab */
348 /*----------------------------------------------------------------*/
692519b1
RJ
349#if defined(CONFIG_440SPE)
350 /*----------------------------------------------------------------*/
351 /* We have different TLB tables for revA and rev B of 440SPe */
352 /*----------------------------------------------------------------*/
353 mfspr r1, PVR
354 lis r0,0x5342
355 ori r0,r0,0x1891
356 cmpw r7,r1,r0
357 bne r7,..revA
358 bl tlbtabB
359 b ..goon
360..revA:
361 bl tlbtabA
362..goon:
363#else
0442ed86 364 bl tlbtab /* Get tlbtab pointer */
692519b1 365#endif
0442ed86
WD
366 mr r5,r0
367 li r1,0x003f /* 64 TLB entries max */
368 mtctr r1
369 li r4,0 /* TLB # */
370
371 addi r5,r5,-4
3721: lwzu r0,4(r5)
373 cmpwi r0,0
374 beq 2f /* 0 marks end */
375 lwzu r1,4(r5)
376 lwzu r2,4(r5)
377 tlbwe r0,r4,0 /* TLB Word 0 */
378 tlbwe r1,r4,1 /* TLB Word 1 */
379 tlbwe r2,r4,2 /* TLB Word 2 */
380 addi r4,r4,1 /* Next TLB */
381 bdnz 1b
382
383 /*----------------------------------------------------------------*/
384 /* Continue from 'normal' start */
385 /*----------------------------------------------------------------*/
887e2ec9
SR
3862:
387
388#if defined(CONFIG_NAND_SPL)
389 /*
390 * Enable internal SRAM
391 */
392 lis r2,0x7fff
393 ori r2,r2,0xffff
394 mfdcr r1,isram0_dpc
395 and r1,r1,r2 /* Disable parity check */
396 mtdcr isram0_dpc,r1
397 mfdcr r1,isram0_pmeg
398 and r1,r1,r2 /* Disable pwr mgmt */
399 mtdcr isram0_pmeg,r1
400
401 /*
402 * Copy SPL from cache into internal SRAM
403 */
404 li r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
405 mtctr r4
406 lis r2,CFG_NAND_BOOT_SPL_SRC@h
407 ori r2,r2,CFG_NAND_BOOT_SPL_SRC@l
408 lis r3,CFG_NAND_BOOT_SPL_DST@h
409 ori r3,r3,CFG_NAND_BOOT_SPL_DST@l
410spl_loop:
411 lwzu r4,4(r2)
412 stwu r4,4(r3)
413 bdnz spl_loop
414
415 /*
416 * Jump to code in RAM
417 */
418 bl 00f
41900: mflr r10
420 lis r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
421 ori r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
422 sub r10,r10,r3
423 addi r10,r10,28
424 mtlr r10
425 blr
426
427start_ram:
428 sync
429 isync
430#endif
431
432 bl 3f
0442ed86
WD
433 b _start
434
4353: li r0,0
436 mtspr srr1,r0 /* Keep things disabled for now */
437 mflr r1
438 mtspr srr0,r1
439 rfi
b867d705 440#endif /* CONFIG_440 */
0442ed86
WD
441
442/*
443 * r3 - 1st arg to board_init(): IMMP pointer
444 * r4 - 2nd arg to board_init(): boot flag
445 */
887e2ec9 446#ifndef CONFIG_NAND_SPL
0442ed86
WD
447 .text
448 .long 0x27051956 /* U-Boot Magic Number */
449 .globl version_string
450version_string:
451 .ascii U_BOOT_VERSION
452 .ascii " (", __DATE__, " - ", __TIME__, ")"
453 .ascii CONFIG_IDENT_STRING, "\0"
454
455/*
456 * Maybe this should be moved somewhere else because the current
457 * location (0x100) is where the CriticalInput Execption should be.
458 */
459 . = EXC_OFF_SYS_RESET
887e2ec9 460#endif
0442ed86
WD
461 .globl _start
462_start:
463
464/*****************************************************************************/
465#if defined(CONFIG_440)
466
467 /*----------------------------------------------------------------*/
468 /* Clear and set up some registers. */
469 /*----------------------------------------------------------------*/
470 li r0,0x0000
471 lis r1,0xffff
472 mtspr dec,r0 /* prevent dec exceptions */
473 mtspr tbl,r0 /* prevent fit & wdt exceptions */
474 mtspr tbu,r0
475 mtspr tsr,r1 /* clear all timer exception status */
476 mtspr tcr,r0 /* disable all */
477 mtspr esr,r0 /* clear exception syndrome register */
478 mtxer r0 /* clear integer exception register */
0442ed86
WD
479
480 /*----------------------------------------------------------------*/
481 /* Debug setup -- some (not very good) ice's need an event*/
482 /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
483 /* value you need in this case 0x8cff 0000 should do the trick */
484 /*----------------------------------------------------------------*/
485#if defined(CFG_INIT_DBCR)
486 lis r1,0xffff
487 ori r1,r1,0xffff
488 mtspr dbsr,r1 /* Clear all status bits */
489 lis r0,CFG_INIT_DBCR@h
490 ori r0,r0,CFG_INIT_DBCR@l
491 mtspr dbcr0,r0
492 isync
493#endif
494
495 /*----------------------------------------------------------------*/
496 /* Setup the internal SRAM */
497 /*----------------------------------------------------------------*/
498 li r0,0
887e2ec9
SR
499
500#ifdef CFG_INIT_RAM_DCACHE
c157d8e2 501 /* Clear Dcache to use as RAM */
f901a83b
WD
502 addis r3,r0,CFG_INIT_RAM_ADDR@h
503 ori r3,r3,CFG_INIT_RAM_ADDR@l
504 addis r4,r0,CFG_INIT_RAM_END@h
505 ori r4,r4,CFG_INIT_RAM_END@l
c157d8e2 506 rlwinm. r5,r4,0,27,31
f901a83b
WD
507 rlwinm r5,r4,27,5,31
508 beq ..d_ran
509 addi r5,r5,0x0001
c157d8e2 510..d_ran:
f901a83b 511 mtctr r5
c157d8e2 512..d_ag:
f901a83b
WD
513 dcbz r0,r3
514 addi r3,r3,32
515 bdnz ..d_ag
887e2ec9
SR
516#endif /* CFG_INIT_RAM_DCACHE */
517
518 /* 440EP & 440GR are only 440er PPC's without internal SRAM */
519#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
520 /* not all PPC's have internal SRAM usable as L2-cache */
521#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
f901a83b 522 mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */
ba56f625 523#endif
0442ed86 524
887e2ec9 525 lis r2,0x7fff
0442ed86
WD
526 ori r2,r2,0xffff
527 mfdcr r1,isram0_dpc
528 and r1,r1,r2 /* Disable parity check */
529 mtdcr isram0_dpc,r1
530 mfdcr r1,isram0_pmeg
887e2ec9 531 and r1,r1,r2 /* Disable pwr mgmt */
0442ed86
WD
532 mtdcr isram0_pmeg,r1
533
534 lis r1,0x8000 /* BAS = 8000_0000 */
6e7fb6ea 535#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
ba56f625 536 ori r1,r1,0x0980 /* first 64k */
f901a83b 537 mtdcr isram0_sb0cr,r1
ba56f625
WD
538 lis r1,0x8001
539 ori r1,r1,0x0980 /* second 64k */
f901a83b 540 mtdcr isram0_sb1cr,r1
ba56f625
WD
541 lis r1, 0x8002
542 ori r1,r1, 0x0980 /* third 64k */
f901a83b 543 mtdcr isram0_sb2cr,r1
ba56f625
WD
544 lis r1, 0x8003
545 ori r1,r1, 0x0980 /* fourth 64k */
f901a83b 546 mtdcr isram0_sb3cr,r1
6c5879f3
MB
547#elif defined(CONFIG_440SPE)
548 lis r1,0x0000 /* BAS = 0000_0000 */
549 ori r1,r1,0x0984 /* first 64k */
550 mtdcr isram0_sb0cr,r1
551 lis r1,0x0001
552 ori r1,r1,0x0984 /* second 64k */
553 mtdcr isram0_sb1cr,r1
554 lis r1, 0x0002
555 ori r1,r1, 0x0984 /* third 64k */
556 mtdcr isram0_sb2cr,r1
557 lis r1, 0x0003
558 ori r1,r1, 0x0984 /* fourth 64k */
559 mtdcr isram0_sb3cr,r1
887e2ec9 560#elif defined(CONFIG_440GP)
0442ed86
WD
561 ori r1,r1,0x0380 /* 8k rw */
562 mtdcr isram0_sb0cr,r1
887e2ec9 563 mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
c157d8e2 564#endif
887e2ec9 565#endif /* #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) */
0442ed86
WD
566
567 /*----------------------------------------------------------------*/
568 /* Setup the stack in internal SRAM */
569 /*----------------------------------------------------------------*/
570 lis r1,CFG_INIT_RAM_ADDR@h
571 ori r1,r1,CFG_INIT_SP_OFFSET@l
0442ed86
WD
572 li r0,0
573 stwu r0,-4(r1)
574 stwu r0,-4(r1) /* Terminate call chain */
575
576 stwu r1,-8(r1) /* Save back chain and move SP */
577 lis r0,RESET_VECTOR@h /* Address of reset vector */
578 ori r0,r0, RESET_VECTOR@l
579 stwu r1,-8(r1) /* Save back chain and move SP */
580 stw r0,+12(r1) /* Save return addr (underflow vect) */
581
887e2ec9
SR
582#ifdef CONFIG_NAND_SPL
583 bl nand_boot /* will not return */
584#else
0442ed86 585 GET_GOT
5568e613
SR
586
587 bl cpu_init_f /* run low-level CPU init code (from Flash) */
0442ed86 588 bl board_init_f
887e2ec9 589#endif
0442ed86
WD
590
591#endif /* CONFIG_440 */
592
593/*****************************************************************************/
594#ifdef CONFIG_IOP480
595 /*----------------------------------------------------------------------- */
596 /* Set up some machine state registers. */
597 /*----------------------------------------------------------------------- */
598 addi r0,r0,0x0000 /* initialize r0 to zero */
599 mtspr esr,r0 /* clear Exception Syndrome Reg */
600 mttcr r0 /* timer control register */
601 mtexier r0 /* disable all interrupts */
0442ed86
WD
602 addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
603 ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
604 mtdbsr r4 /* clear/reset the dbsr */
605 mtexisr r4 /* clear all pending interrupts */
606 addis r4,r0,0x8000
607 mtexier r4 /* enable critical exceptions */
608 addis r4,r0,0x0000 /* assume 403GCX - enable core clk */
609 ori r4,r4,0x4020 /* dbling (no harm done on GA and GC */
610 mtiocr r4 /* since bit not used) & DRC to latch */
611 /* data bus on rising edge of CAS */
612 /*----------------------------------------------------------------------- */
613 /* Clear XER. */
614 /*----------------------------------------------------------------------- */
615 mtxer r0
616 /*----------------------------------------------------------------------- */
617 /* Invalidate i-cache and d-cache TAG arrays. */
618 /*----------------------------------------------------------------------- */
619 addi r3,0,1024 /* 1/4 of I-cache size, half of D-cache */
620 addi r4,0,1024 /* 1/4 of I-cache */
621..cloop:
622 iccci 0,r3
623 iccci r4,r3
624 dccci 0,r3
625 addic. r3,r3,-16 /* move back one cache line */
626 bne ..cloop /* loop back to do rest until r3 = 0 */
627
628 /* */
629 /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
630 /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
631 /* */
632
633 /* first copy IOP480 register base address into r3 */
634 addis r3,0,0x5000 /* IOP480 register base address hi */
635/* ori r3,r3,0x0000 / IOP480 register base address lo */
636
637#ifdef CONFIG_ADCIOP
638 /* use r4 as the working variable */
639 /* turn on CS3 (LOCCTL.7) */
640 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
641 andi. r4,r4,0xff7f /* make bit 7 = 0 -- CS3 mode */
642 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
643#endif
644
645#ifdef CONFIG_DASA_SIM
646 /* use r4 as the working variable */
647 /* turn on MA17 (LOCCTL.7) */
648 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
649 ori r4,r4,0x80 /* make bit 7 = 1 -- MA17 mode */
650 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
651#endif
652
653 /* turn on MA16..13 (LCS0BRD.12 = 0) */
654 lwz r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
655 andi. r4,r4,0xefff /* make bit 12 = 0 */
656 stw r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
657
658 /* make sure above stores all comlete before going on */
659 sync
660
661 /* last thing, set local init status done bit (DEVINIT.31) */
662 lwz r4,0x80(r3) /* DEVINIT is at offset 0x80 */
663 oris r4,r4,0x8000 /* make bit 31 = 1 */
664 stw r4,0x80(r3) /* DEVINIT is at offset 0x80 */
665
666 /* clear all pending interrupts and disable all interrupts */
667 li r4,-1 /* set p1 to 0xffffffff */
668 stw r4,0x1b0(r3) /* clear all pending interrupts */
669 stw r4,0x1b8(r3) /* clear all pending interrupts */
670 li r4,0 /* set r4 to 0 */
671 stw r4,0x1b4(r3) /* disable all interrupts */
672 stw r4,0x1bc(r3) /* disable all interrupts */
673
674 /* make sure above stores all comlete before going on */
675 sync
676
677 /*----------------------------------------------------------------------- */
678 /* Enable two 128MB cachable regions. */
679 /*----------------------------------------------------------------------- */
680 addis r1,r0,0x8000
681 addi r1,r1,0x0001
682 mticcr r1 /* instruction cache */
683
684 addis r1,r0,0x0000
685 addi r1,r1,0x0000
686 mtdccr r1 /* data cache */
687
688 addis r1,r0,CFG_INIT_RAM_ADDR@h
689 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
690 li r0, 0 /* Make room for stack frame header and */
691 stwu r0, -4(r1) /* clear final stack frame so that */
692 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
693
694 GET_GOT /* initialize GOT access */
695
696 bl board_init_f /* run first part of init code (from Flash) */
697
698#endif /* CONFIG_IOP480 */
699
700/*****************************************************************************/
b867d705 701#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_405EP)
0442ed86
WD
702 /*----------------------------------------------------------------------- */
703 /* Clear and set up some registers. */
704 /*----------------------------------------------------------------------- */
705 addi r4,r0,0x0000
706 mtspr sgr,r4
707 mtspr dcwr,r4
708 mtesr r4 /* clear Exception Syndrome Reg */
709 mttcr r4 /* clear Timer Control Reg */
710 mtxer r4 /* clear Fixed-Point Exception Reg */
711 mtevpr r4 /* clear Exception Vector Prefix Reg */
0442ed86
WD
712 addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
713 /* dbsr is cleared by setting bits to 1) */
714 mtdbsr r4 /* clear/reset the dbsr */
715
716 /*----------------------------------------------------------------------- */
717 /* Invalidate I and D caches. Enable I cache for defined memory regions */
718 /* to speed things up. Leave the D cache disabled for now. It will be */
719 /* enabled/left disabled later based on user selected menu options. */
720 /* Be aware that the I cache may be disabled later based on the menu */
721 /* options as well. See miscLib/main.c. */
722 /*----------------------------------------------------------------------- */
723 bl invalidate_icache
724 bl invalidate_dcache
725
726 /*----------------------------------------------------------------------- */
727 /* Enable two 128MB cachable regions. */
728 /*----------------------------------------------------------------------- */
729 addis r4,r0,0x8000
730 addi r4,r4,0x0001
731 mticcr r4 /* instruction cache */
732 isync
733
734 addis r4,r0,0x0000
735 addi r4,r4,0x0000
736 mtdccr r4 /* data cache */
737
738#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
739 /*----------------------------------------------------------------------- */
740 /* Tune the speed and size for flash CS0 */
741 /*----------------------------------------------------------------------- */
742 bl ext_bus_cntlr_init
743#endif
744
b867d705
SR
745#if defined(CONFIG_405EP)
746 /*----------------------------------------------------------------------- */
747 /* DMA Status, clear to come up clean */
748 /*----------------------------------------------------------------------- */
f901a83b
WD
749 addis r3,r0, 0xFFFF /* Clear all existing DMA status */
750 ori r3,r3, 0xFFFF
751 mtdcr dmasr, r3
b867d705 752
f901a83b 753 bl ppc405ep_init /* do ppc405ep specific init */
b867d705
SR
754#endif /* CONFIG_405EP */
755
0442ed86
WD
756#if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
757 /********************************************************************
758 * Setup OCM - On Chip Memory
759 *******************************************************************/
760 /* Setup OCM */
8bde7f77
WD
761 lis r0, 0x7FFF
762 ori r0, r0, 0xFFFF
f901a83b 763 mfdcr r3, ocmiscntl /* get instr-side IRAM config */
8bde7f77
WD
764 mfdcr r4, ocmdscntl /* get data-side IRAM config */
765 and r3, r3, r0 /* disable data-side IRAM */
766 and r4, r4, r0 /* disable data-side IRAM */
767 mtdcr ocmiscntl, r3 /* set instr-side IRAM config */
768 mtdcr ocmdscntl, r4 /* set data-side IRAM config */
769 isync
0442ed86
WD
770
771 addis r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
772 mtdcr ocmdsarc, r3
773 addis r4, 0, 0xC000 /* OCM data area enabled */
774 mtdcr ocmdscntl, r4
8bde7f77 775 isync
0442ed86
WD
776#endif
777
778 /*----------------------------------------------------------------------- */
779 /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
780 /*----------------------------------------------------------------------- */
781#ifdef CFG_INIT_DCACHE_CS
782 /*----------------------------------------------------------------------- */
783 /* Memory Bank x (nothingness) initialization 1GB+64MEG */
784 /* used as temporary stack pointer for stage0 */
785 /*----------------------------------------------------------------------- */
786 li r4,PBxAP
787 mtdcr ebccfga,r4
788 lis r4,0x0380
789 ori r4,r4,0x0480
790 mtdcr ebccfgd,r4
791
792 addi r4,0,PBxCR
793 mtdcr ebccfga,r4
794 lis r4,0x400D
795 ori r4,r4,0xa000
796 mtdcr ebccfgd,r4
797
798 /* turn on data chache for this region */
799 lis r4,0x0080
800 mtdccr r4
801
802 /* set stack pointer and clear stack to known value */
803
804 lis r1,CFG_INIT_RAM_ADDR@h
f901a83b 805 ori r1,r1,CFG_INIT_SP_OFFSET@l
0442ed86
WD
806
807 li r4,2048 /* we store 2048 words to stack */
808 mtctr r4
809
810 lis r2,CFG_INIT_RAM_ADDR@h /* we also clear data area */
f901a83b 811 ori r2,r2,CFG_INIT_RAM_END@l /* so cant copy value from r1 */
0442ed86
WD
812
813 lis r4,0xdead /* we store 0xdeaddead in the stack */
814 ori r4,r4,0xdead
815
816..stackloop:
817 stwu r4,-4(r2)
818 bdnz ..stackloop
819
820 li r0, 0 /* Make room for stack frame header and */
821 stwu r0, -4(r1) /* clear final stack frame so that */
822 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
823 /*
824 * Set up a dummy frame to store reset vector as return address.
825 * this causes stack underflow to reset board.
826 */
827 stwu r1, -8(r1) /* Save back chain and move SP */
828 addis r0, 0, RESET_VECTOR@h /* Address of reset vector */
829 ori r0, r0, RESET_VECTOR@l
830 stwu r1, -8(r1) /* Save back chain and move SP */
831 stw r0, +12(r1) /* Save return addr (underflow vect) */
832
833#elif defined(CFG_TEMP_STACK_OCM) && \
834 (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
835 /*
836 * Stack in OCM.
837 */
838
839 /* Set up Stack at top of OCM */
840 lis r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
841 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
842
843 /* Set up a zeroized stack frame so that backtrace works right */
844 li r0, 0
845 stwu r0, -4(r1)
846 stwu r0, -4(r1)
847
848 /*
849 * Set up a dummy frame to store reset vector as return address.
850 * this causes stack underflow to reset board.
851 */
852 stwu r1, -8(r1) /* Save back chain and move SP */
853 lis r0, RESET_VECTOR@h /* Address of reset vector */
854 ori r0, r0, RESET_VECTOR@l
855 stwu r1, -8(r1) /* Save back chain and move SP */
856 stw r0, +12(r1) /* Save return addr (underflow vect) */
857#endif /* CFG_INIT_DCACHE_CS */
858
859 /*----------------------------------------------------------------------- */
f901a83b 860 /* Initialize SDRAM Controller */
0442ed86
WD
861 /*----------------------------------------------------------------------- */
862 bl sdram_init
863
864 /*
865 * Setup temporary stack pointer only for boards
866 * that do not use SDRAM SPD I2C stuff since it
867 * is already initialized to use DCACHE or OCM
868 * stacks.
869 */
870#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
871 lis r1, CFG_INIT_RAM_ADDR@h
872 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
873
874 li r0, 0 /* Make room for stack frame header and */
875 stwu r0, -4(r1) /* clear final stack frame so that */
876 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
877 /*
878 * Set up a dummy frame to store reset vector as return address.
879 * this causes stack underflow to reset board.
880 */
881 stwu r1, -8(r1) /* Save back chain and move SP */
882 lis r0, RESET_VECTOR@h /* Address of reset vector */
883 ori r0, r0, RESET_VECTOR@l
884 stwu r1, -8(r1) /* Save back chain and move SP */
885 stw r0, +12(r1) /* Save return addr (underflow vect) */
f901a83b 886#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
0442ed86
WD
887
888 GET_GOT /* initialize GOT access */
889
f901a83b 890 bl cpu_init_f /* run low-level CPU init code (from Flash) */
0442ed86
WD
891
892 /* NEVER RETURNS! */
893 bl board_init_f /* run first part of init code (from Flash) */
894
12f34241
WD
895#endif /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
896 /*----------------------------------------------------------------------- */
0442ed86
WD
897
898
887e2ec9 899#ifndef CONFIG_NAND_SPL
b867d705 900/*****************************************************************************/
0442ed86
WD
901 .globl _start_of_vectors
902_start_of_vectors:
903
904#if 0
905/*TODO Fixup _start above so we can do this*/
906/* Critical input. */
907 CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
908#endif
909
910/* Machine check */
2abbe075 911 CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
0442ed86
WD
912
913/* Data Storage exception. */
914 STD_EXCEPTION(0x300, DataStorage, UnknownException)
915
916/* Instruction Storage exception. */
917 STD_EXCEPTION(0x400, InstStorage, UnknownException)
918
919/* External Interrupt exception. */
920 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
921
922/* Alignment exception. */
923 . = 0x600
924Alignment:
925 EXCEPTION_PROLOG
926 mfspr r4,DAR
927 stw r4,_DAR(r21)
928 mfspr r5,DSISR
929 stw r5,_DSISR(r21)
930 addi r3,r1,STACK_FRAME_OVERHEAD
931 li r20,MSR_KERNEL
932 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
933 lwz r6,GOT(transfer_to_handler)
934 mtlr r6
935 blrl
936.L_Alignment:
937 .long AlignmentException - _start + EXC_OFF_SYS_RESET
938 .long int_return - _start + EXC_OFF_SYS_RESET
939
940/* Program check exception */
941 . = 0x700
942ProgramCheck:
943 EXCEPTION_PROLOG
944 addi r3,r1,STACK_FRAME_OVERHEAD
945 li r20,MSR_KERNEL
946 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
947 lwz r6,GOT(transfer_to_handler)
948 mtlr r6
949 blrl
950.L_ProgramCheck:
951 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
952 .long int_return - _start + EXC_OFF_SYS_RESET
953
954 /* No FPU on MPC8xx. This exception is not supposed to happen.
955 */
956 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
957
958 /* I guess we could implement decrementer, and may have
959 * to someday for timekeeping.
960 */
961 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
962 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
963 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
27b207fd 964 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
0442ed86
WD
965 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
966
967 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
968 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
969
970 /* On the MPC8xx, this is a software emulation interrupt. It occurs
971 * for all unimplemented and illegal instructions.
972 */
973 STD_EXCEPTION(0x1000, PIT, PITException)
974
975 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
976 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
977 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
978 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
979
980 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
981 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
982 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
983 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
984 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
985 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
986 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
987
988 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
989 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
990 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
991 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
992
993 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
994
995 .globl _end_of_vectors
996_end_of_vectors:
997
998
999 . = 0x2100
1000
1001/*
1002 * This code finishes saving the registers to the exception frame
1003 * and jumps to the appropriate handler for the exception.
1004 * Register r21 is pointer into trap frame, r1 has new stack pointer.
1005 */
1006 .globl transfer_to_handler
1007transfer_to_handler:
1008 stw r22,_NIP(r21)
1009 lis r22,MSR_POW@h
1010 andc r23,r23,r22
1011 stw r23,_MSR(r21)
1012 SAVE_GPR(7, r21)
1013 SAVE_4GPRS(8, r21)
1014 SAVE_8GPRS(12, r21)
1015 SAVE_8GPRS(24, r21)
1016#if 0
1017 andi. r23,r23,MSR_PR
1018 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
1019 beq 2f
1020 addi r24,r1,STACK_FRAME_OVERHEAD
1021 stw r24,PT_REGS(r23)
10222: addi r2,r23,-TSS /* set r2 to current */
1023 tovirt(r2,r2,r23)
1024#endif
1025 mflr r23
1026 andi. r24,r23,0x3f00 /* get vector offset */
1027 stw r24,TRAP(r21)
1028 li r22,0
1029 stw r22,RESULT(r21)
1030 mtspr SPRG2,r22 /* r1 is now kernel sp */
1031#if 0
1032 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
1033 cmplw 0,r1,r2
1034 cmplw 1,r1,r24
1035 crand 1,1,4
1036 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
1037#endif
1038 lwz r24,0(r23) /* virtual address of handler */
1039 lwz r23,4(r23) /* where to go when done */
1040 mtspr SRR0,r24
1041 mtspr SRR1,r20
1042 mtlr r23
1043 SYNC
1044 rfi /* jump to handler, enable MMU */
1045
1046int_return:
1047 mfmsr r28 /* Disable interrupts */
1048 li r4,0
1049 ori r4,r4,MSR_EE
1050 andc r28,r28,r4
1051 SYNC /* Some chip revs need this... */
1052 mtmsr r28
1053 SYNC
1054 lwz r2,_CTR(r1)
1055 lwz r0,_LINK(r1)
1056 mtctr r2
1057 mtlr r0
1058 lwz r2,_XER(r1)
1059 lwz r0,_CCR(r1)
1060 mtspr XER,r2
1061 mtcrf 0xFF,r0
1062 REST_10GPRS(3, r1)
1063 REST_10GPRS(13, r1)
1064 REST_8GPRS(23, r1)
1065 REST_GPR(31, r1)
1066 lwz r2,_NIP(r1) /* Restore environment */
1067 lwz r0,_MSR(r1)
1068 mtspr SRR0,r2
1069 mtspr SRR1,r0
1070 lwz r0,GPR0(r1)
1071 lwz r2,GPR2(r1)
1072 lwz r1,GPR1(r1)
1073 SYNC
1074 rfi
1075
1076crit_return:
1077 mfmsr r28 /* Disable interrupts */
1078 li r4,0
1079 ori r4,r4,MSR_EE
1080 andc r28,r28,r4
1081 SYNC /* Some chip revs need this... */
1082 mtmsr r28
1083 SYNC
1084 lwz r2,_CTR(r1)
1085 lwz r0,_LINK(r1)
1086 mtctr r2
1087 mtlr r0
1088 lwz r2,_XER(r1)
1089 lwz r0,_CCR(r1)
1090 mtspr XER,r2
1091 mtcrf 0xFF,r0
1092 REST_10GPRS(3, r1)
1093 REST_10GPRS(13, r1)
1094 REST_8GPRS(23, r1)
1095 REST_GPR(31, r1)
1096 lwz r2,_NIP(r1) /* Restore environment */
1097 lwz r0,_MSR(r1)
1098 mtspr 990,r2 /* SRR2 */
1099 mtspr 991,r0 /* SRR3 */
1100 lwz r0,GPR0(r1)
1101 lwz r2,GPR2(r1)
1102 lwz r1,GPR1(r1)
1103 SYNC
1104 rfci
887e2ec9 1105#endif /* CONFIG_NAND_SPL */
0442ed86
WD
1106
1107/* Cache functions.
1108*/
1109invalidate_icache:
1110 iccci r0,r0 /* for 405, iccci invalidates the */
1111 blr /* entire I cache */
1112
1113invalidate_dcache:
1114 addi r6,0,0x0000 /* clear GPR 6 */
1115 /* Do loop for # of dcache congruence classes. */
f901a83b
WD
1116 lis r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS for large sized cache */
1117 ori r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
0442ed86
WD
1118 /* NOTE: dccci invalidates both */
1119 mtctr r7 /* ways in the D cache */
1120..dcloop:
1121 dccci 0,r6 /* invalidate line */
1122 addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
1123 bdnz ..dcloop
1124 blr
1125
1126flush_dcache:
1127 addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
1128 ori r9,r9,0x8000
1129 mfmsr r12 /* save msr */
1130 andc r9,r12,r9
1131 mtmsr r9 /* disable EE and CE */
1132 addi r10,r0,0x0001 /* enable data cache for unused memory */
1133 mfdccr r9 /* region 0xF8000000-0xFFFFFFFF via */
1134 or r10,r10,r9 /* bit 31 in dccr */
1135 mtdccr r10
1136
1137 /* do loop for # of congruence classes. */
f901a83b
WD
1138 lis r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS: for large cache sizes */
1139 ori r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
1140 lis r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */
1141 ori r11,r11,(CFG_DCACHE_SIZE / 2)@l /* D cache set size - 2 way sets */
0442ed86 1142 mtctr r10
f901a83b 1143 addi r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
0442ed86
WD
1144 add r11,r10,r11 /* add to get to other side of cache line */
1145..flush_dcache_loop:
1146 lwz r3,0(r10) /* least recently used side */
1147 lwz r3,0(r11) /* the other side */
1148 dccci r0,r11 /* invalidate both sides */
1149 addi r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
1150 addi r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
1151 bdnz ..flush_dcache_loop
1152 sync /* allow memory access to complete */
1153 mtdccr r9 /* restore dccr */
1154 mtmsr r12 /* restore msr */
1155 blr
1156
1157 .globl icache_enable
1158icache_enable:
1159 mflr r8
1160 bl invalidate_icache
1161 mtlr r8
1162 isync
1163 addis r3,r0, 0x8000 /* set bit 0 */
1164 mticcr r3
1165 blr
1166
1167 .globl icache_disable
1168icache_disable:
1169 addis r3,r0, 0x0000 /* clear bit 0 */
1170 mticcr r3
1171 isync
1172 blr
1173
1174 .globl icache_status
1175icache_status:
1176 mficcr r3
1177 srwi r3, r3, 31 /* >>31 => select bit 0 */
1178 blr
1179
1180 .globl dcache_enable
1181dcache_enable:
1182 mflr r8
1183 bl invalidate_dcache
1184 mtlr r8
1185 isync
1186 addis r3,r0, 0x8000 /* set bit 0 */
1187 mtdccr r3
1188 blr
1189
1190 .globl dcache_disable
1191dcache_disable:
1192 mflr r8
1193 bl flush_dcache
1194 mtlr r8
1195 addis r3,r0, 0x0000 /* clear bit 0 */
1196 mtdccr r3
1197 blr
1198
1199 .globl dcache_status
1200dcache_status:
1201 mfdccr r3
1202 srwi r3, r3, 31 /* >>31 => select bit 0 */
1203 blr
1204
1205 .globl get_pvr
1206get_pvr:
1207 mfspr r3, PVR
1208 blr
1209
1210#if !defined(CONFIG_440)
1211 .globl wr_pit
1212wr_pit:
1213 mtspr pit, r3
1214 blr
1215#endif
1216
1217 .globl wr_tcr
1218wr_tcr:
1219 mtspr tcr, r3
1220 blr
1221
1222/*------------------------------------------------------------------------------- */
1223/* Function: in8 */
1224/* Description: Input 8 bits */
1225/*------------------------------------------------------------------------------- */
1226 .globl in8
1227in8:
1228 lbz r3,0x0000(r3)
1229 blr
1230
1231/*------------------------------------------------------------------------------- */
1232/* Function: out8 */
1233/* Description: Output 8 bits */
1234/*------------------------------------------------------------------------------- */
1235 .globl out8
1236out8:
1237 stb r4,0x0000(r3)
1238 blr
1239
1240/*------------------------------------------------------------------------------- */
1241/* Function: out16 */
1242/* Description: Output 16 bits */
1243/*------------------------------------------------------------------------------- */
1244 .globl out16
1245out16:
1246 sth r4,0x0000(r3)
1247 blr
1248
1249/*------------------------------------------------------------------------------- */
1250/* Function: out16r */
1251/* Description: Byte reverse and output 16 bits */
1252/*------------------------------------------------------------------------------- */
1253 .globl out16r
1254out16r:
1255 sthbrx r4,r0,r3
1256 blr
1257
1258/*------------------------------------------------------------------------------- */
1259/* Function: out32 */
1260/* Description: Output 32 bits */
1261/*------------------------------------------------------------------------------- */
1262 .globl out32
1263out32:
1264 stw r4,0x0000(r3)
1265 blr
1266
1267/*------------------------------------------------------------------------------- */
1268/* Function: out32r */
1269/* Description: Byte reverse and output 32 bits */
1270/*------------------------------------------------------------------------------- */
1271 .globl out32r
1272out32r:
1273 stwbrx r4,r0,r3
1274 blr
1275
1276/*------------------------------------------------------------------------------- */
1277/* Function: in16 */
1278/* Description: Input 16 bits */
1279/*------------------------------------------------------------------------------- */
1280 .globl in16
1281in16:
1282 lhz r3,0x0000(r3)
1283 blr
1284
1285/*------------------------------------------------------------------------------- */
1286/* Function: in16r */
1287/* Description: Input 16 bits and byte reverse */
1288/*------------------------------------------------------------------------------- */
1289 .globl in16r
1290in16r:
1291 lhbrx r3,r0,r3
1292 blr
1293
1294/*------------------------------------------------------------------------------- */
1295/* Function: in32 */
1296/* Description: Input 32 bits */
1297/*------------------------------------------------------------------------------- */
1298 .globl in32
1299in32:
1300 lwz 3,0x0000(3)
1301 blr
1302
1303/*------------------------------------------------------------------------------- */
1304/* Function: in32r */
1305/* Description: Input 32 bits and byte reverse */
1306/*------------------------------------------------------------------------------- */
1307 .globl in32r
1308in32r:
1309 lwbrx r3,r0,r3
1310 blr
1311
1312/*------------------------------------------------------------------------------- */
1313/* Function: ppcDcbf */
1314/* Description: Data Cache block flush */
1315/* Input: r3 = effective address */
1316/* Output: none. */
1317/*------------------------------------------------------------------------------- */
1318 .globl ppcDcbf
1319ppcDcbf:
1320 dcbf r0,r3
1321 blr
1322
1323/*------------------------------------------------------------------------------- */
1324/* Function: ppcDcbi */
1325/* Description: Data Cache block Invalidate */
1326/* Input: r3 = effective address */
1327/* Output: none. */
1328/*------------------------------------------------------------------------------- */
1329 .globl ppcDcbi
1330ppcDcbi:
1331 dcbi r0,r3
1332 blr
1333
1334/*------------------------------------------------------------------------------- */
1335/* Function: ppcSync */
1336/* Description: Processor Synchronize */
1337/* Input: none. */
1338/* Output: none. */
1339/*------------------------------------------------------------------------------- */
1340 .globl ppcSync
1341ppcSync:
1342 sync
1343 blr
1344
1345/*------------------------------------------------------------------------------*/
1346
887e2ec9 1347#ifndef CONFIG_NAND_SPL
0442ed86
WD
1348/*
1349 * void relocate_code (addr_sp, gd, addr_moni)
1350 *
1351 * This "function" does not return, instead it continues in RAM
1352 * after relocating the monitor code.
1353 *
1354 * r3 = dest
1355 * r4 = src
1356 * r5 = length in bytes
1357 * r6 = cachelinesize
1358 */
1359 .globl relocate_code
1360relocate_code:
887e2ec9
SR
1361#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
1362 defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
1363 defined(CONFIG_440SPE)
a4c8d138
SR
1364 /*
1365 * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
1366 * to speed up the boot process. Now this cache needs to be disabled.
1367 */
1368 iccci 0,0 /* Invalidate inst cache */
1369 dccci 0,0 /* Invalidate data cache, now no longer our stack */
c157d8e2 1370 sync
a4c8d138 1371 isync
6e7fb6ea 1372 addi r1,r0,0x0000 /* TLB entry #0 */
c157d8e2 1373 tlbre r0,r1,0x0002 /* Read contents */
6e7fb6ea 1374 ori r0,r0,0x0c00 /* Or in the inhibit, write through bit */
f901a83b 1375 tlbwe r0,r1,0x0002 /* Save it out */
a4c8d138 1376 sync
c157d8e2
SR
1377 isync
1378#endif
0442ed86
WD
1379 mr r1, r3 /* Set new stack pointer */
1380 mr r9, r4 /* Save copy of Init Data pointer */
1381 mr r10, r5 /* Save copy of Destination Address */
1382
1383 mr r3, r5 /* Destination Address */
1384 lis r4, CFG_MONITOR_BASE@h /* Source Address */
1385 ori r4, r4, CFG_MONITOR_BASE@l
3b57fe0a
WD
1386 lwz r5, GOT(__init_end)
1387 sub r5, r5, r4
0442ed86
WD
1388 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
1389
1390 /*
1391 * Fix GOT pointer:
1392 *
1393 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1394 *
1395 * Offset:
1396 */
1397 sub r15, r10, r4
1398
1399 /* First our own GOT */
1400 add r14, r14, r15
1401 /* the the one used by the C code */
1402 add r30, r30, r15
1403
1404 /*
1405 * Now relocate code
1406 */
1407
1408 cmplw cr1,r3,r4
1409 addi r0,r5,3
1410 srwi. r0,r0,2
1411 beq cr1,4f /* In place copy is not necessary */
1412 beq 7f /* Protect against 0 count */
1413 mtctr r0
1414 bge cr1,2f
1415
1416 la r8,-4(r4)
1417 la r7,-4(r3)
14181: lwzu r0,4(r8)
1419 stwu r0,4(r7)
1420 bdnz 1b
1421 b 4f
1422
14232: slwi r0,r0,2
1424 add r8,r4,r0
1425 add r7,r3,r0
14263: lwzu r0,-4(r8)
1427 stwu r0,-4(r7)
1428 bdnz 3b
1429
1430/*
1431 * Now flush the cache: note that we must start from a cache aligned
1432 * address. Otherwise we might miss one cache line.
1433 */
14344: cmpwi r6,0
1435 add r5,r3,r5
1436 beq 7f /* Always flush prefetch queue in any case */
1437 subi r0,r6,1
1438 andc r3,r3,r0
1439 mr r4,r3
14405: dcbst 0,r4
1441 add r4,r4,r6
1442 cmplw r4,r5
1443 blt 5b
1444 sync /* Wait for all dcbst to complete on bus */
1445 mr r4,r3
14466: icbi 0,r4
1447 add r4,r4,r6
1448 cmplw r4,r5
1449 blt 6b
14507: sync /* Wait for all icbi to complete on bus */
1451 isync
1452
1453/*
1454 * We are done. Do not return, instead branch to second part of board
1455 * initialization, now running from RAM.
1456 */
1457
1458 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1459 mtlr r0
1460 blr /* NEVER RETURNS! */
1461
1462in_ram:
1463
1464 /*
1465 * Relocation Function, r14 point to got2+0x8000
1466 *
1467 * Adjust got2 pointers, no need to check for 0, this code
1468 * already puts a few entries in the table.
1469 */
1470 li r0,__got2_entries@sectoff@l
1471 la r3,GOT(_GOT2_TABLE_)
1472 lwz r11,GOT(_GOT2_TABLE_)
1473 mtctr r0
1474 sub r11,r3,r11
1475 addi r3,r3,-4
14761: lwzu r0,4(r3)
1477 add r0,r0,r11
1478 stw r0,0(r3)
1479 bdnz 1b
1480
1481 /*
1482 * Now adjust the fixups and the pointers to the fixups
1483 * in case we need to move ourselves again.
1484 */
14852: li r0,__fixup_entries@sectoff@l
1486 lwz r3,GOT(_FIXUP_TABLE_)
1487 cmpwi r0,0
1488 mtctr r0
1489 addi r3,r3,-4
1490 beq 4f
14913: lwzu r4,4(r3)
1492 lwzux r0,r4,r11
1493 add r0,r0,r11
1494 stw r10,0(r3)
1495 stw r0,0(r4)
1496 bdnz 3b
14974:
1498clear_bss:
1499 /*
1500 * Now clear BSS segment
1501 */
5d232d0e 1502 lwz r3,GOT(__bss_start)
0442ed86
WD
1503 lwz r4,GOT(_end)
1504
1505 cmplw 0, r3, r4
1506 beq 6f
1507
1508 li r0, 0
15095:
1510 stw r0, 0(r3)
1511 addi r3, r3, 4
1512 cmplw 0, r3, r4
1513 bne 5b
15146:
1515
1516 mr r3, r9 /* Init Data pointer */
1517 mr r4, r10 /* Destination Address */
1518 bl board_init_r
1519
0442ed86
WD
1520 /*
1521 * Copy exception vector code to low memory
1522 *
1523 * r3: dest_addr
1524 * r7: source address, r8: end address, r9: target address
1525 */
1526 .globl trap_init
1527trap_init:
1528 lwz r7, GOT(_start)
1529 lwz r8, GOT(_end_of_vectors)
1530
682011ff 1531 li r9, 0x100 /* reset vector always at 0x100 */
0442ed86
WD
1532
1533 cmplw 0, r7, r8
1534 bgelr /* return if r7>=r8 - just in case */
1535
1536 mflr r4 /* save link register */
15371:
1538 lwz r0, 0(r7)
1539 stw r0, 0(r9)
1540 addi r7, r7, 4
1541 addi r9, r9, 4
1542 cmplw 0, r7, r8
1543 bne 1b
1544
1545 /*
1546 * relocate `hdlr' and `int_return' entries
1547 */
1548 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1549 li r8, Alignment - _start + EXC_OFF_SYS_RESET
15502:
1551 bl trap_reloc
1552 addi r7, r7, 0x100 /* next exception vector */
1553 cmplw 0, r7, r8
1554 blt 2b
1555
1556 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1557 bl trap_reloc
1558
1559 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1560 bl trap_reloc
1561
1562 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1563 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
15643:
1565 bl trap_reloc
1566 addi r7, r7, 0x100 /* next exception vector */
1567 cmplw 0, r7, r8
1568 blt 3b
1569
1570 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1571 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
15724:
1573 bl trap_reloc
1574 addi r7, r7, 0x100 /* next exception vector */
1575 cmplw 0, r7, r8
1576 blt 4b
1577
887e2ec9 1578#if !defined(CONFIG_440)
9a7b408c
SR
1579 addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
1580 oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
1581 mtmsr r7 /* change MSR */
1582#else
887e2ec9
SR
1583 bl __440_msr_set
1584 b __440_msr_continue
9a7b408c 1585
887e2ec9 1586__440_msr_set:
9a7b408c
SR
1587 addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
1588 oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
1589 mtspr srr1,r7
1590 mflr r7
1591 mtspr srr0,r7
1592 rfi
887e2ec9 1593__440_msr_continue:
9a7b408c
SR
1594#endif
1595
0442ed86
WD
1596 mtlr r4 /* restore link register */
1597 blr
1598
1599 /*
1600 * Function: relocate entries for one exception vector
1601 */
1602trap_reloc:
1603 lwz r0, 0(r7) /* hdlr ... */
1604 add r0, r0, r3 /* ... += dest_addr */
1605 stw r0, 0(r7)
1606
1607 lwz r0, 4(r7) /* int_return ... */
1608 add r0, r0, r3 /* ... += dest_addr */
1609 stw r0, 4(r7)
1610
1611 blr
887e2ec9 1612#endif /* CONFIG_NAND_SPL */
b867d705
SR
1613
1614
1615/**************************************************************************/
f901a83b 1616/* PPC405EP specific stuff */
b867d705
SR
1617/**************************************************************************/
1618#ifdef CONFIG_405EP
1619ppc405ep_init:
b828dda6 1620
c157d8e2 1621#ifdef CONFIG_BUBINGA
b828dda6
SR
1622 /*
1623 * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
1624 * function) to support FPGA and NVRAM accesses below.
1625 */
1626
1627 lis r3,GPIO0_OSRH@h /* config GPIO output select */
1628 ori r3,r3,GPIO0_OSRH@l
1629 lis r4,CFG_GPIO0_OSRH@h
1630 ori r4,r4,CFG_GPIO0_OSRH@l
1631 stw r4,0(r3)
1632 lis r3,GPIO0_OSRL@h
1633 ori r3,r3,GPIO0_OSRL@l
1634 lis r4,CFG_GPIO0_OSRL@h
1635 ori r4,r4,CFG_GPIO0_OSRL@l
1636 stw r4,0(r3)
1637
1638 lis r3,GPIO0_ISR1H@h /* config GPIO input select */
1639 ori r3,r3,GPIO0_ISR1H@l
1640 lis r4,CFG_GPIO0_ISR1H@h
1641 ori r4,r4,CFG_GPIO0_ISR1H@l
1642 stw r4,0(r3)
1643 lis r3,GPIO0_ISR1L@h
1644 ori r3,r3,GPIO0_ISR1L@l
1645 lis r4,CFG_GPIO0_ISR1L@h
1646 ori r4,r4,CFG_GPIO0_ISR1L@l
1647 stw r4,0(r3)
1648
1649 lis r3,GPIO0_TSRH@h /* config GPIO three-state select */
1650 ori r3,r3,GPIO0_TSRH@l
1651 lis r4,CFG_GPIO0_TSRH@h
1652 ori r4,r4,CFG_GPIO0_TSRH@l
1653 stw r4,0(r3)
1654 lis r3,GPIO0_TSRL@h
1655 ori r3,r3,GPIO0_TSRL@l
1656 lis r4,CFG_GPIO0_TSRL@h
1657 ori r4,r4,CFG_GPIO0_TSRL@l
1658 stw r4,0(r3)
1659
1660 lis r3,GPIO0_TCR@h /* config GPIO driver output enables */
1661 ori r3,r3,GPIO0_TCR@l
1662 lis r4,CFG_GPIO0_TCR@h
1663 ori r4,r4,CFG_GPIO0_TCR@l
1664 stw r4,0(r3)
1665
1666 li r3,pb1ap /* program EBC bank 1 for RTC access */
1667 mtdcr ebccfga,r3
1668 lis r3,CFG_EBC_PB1AP@h
1669 ori r3,r3,CFG_EBC_PB1AP@l
1670 mtdcr ebccfgd,r3
1671 li r3,pb1cr
1672 mtdcr ebccfga,r3
1673 lis r3,CFG_EBC_PB1CR@h
1674 ori r3,r3,CFG_EBC_PB1CR@l
1675 mtdcr ebccfgd,r3
1676
1677 li r3,pb1ap /* program EBC bank 1 for RTC access */
1678 mtdcr ebccfga,r3
1679 lis r3,CFG_EBC_PB1AP@h
1680 ori r3,r3,CFG_EBC_PB1AP@l
1681 mtdcr ebccfgd,r3
1682 li r3,pb1cr
1683 mtdcr ebccfga,r3
1684 lis r3,CFG_EBC_PB1CR@h
1685 ori r3,r3,CFG_EBC_PB1CR@l
1686 mtdcr ebccfgd,r3
1687
1688 li r3,pb4ap /* program EBC bank 4 for FPGA access */
1689 mtdcr ebccfga,r3
1690 lis r3,CFG_EBC_PB4AP@h
1691 ori r3,r3,CFG_EBC_PB4AP@l
1692 mtdcr ebccfgd,r3
1693 li r3,pb4cr
1694 mtdcr ebccfga,r3
1695 lis r3,CFG_EBC_PB4CR@h
1696 ori r3,r3,CFG_EBC_PB4CR@l
1697 mtdcr ebccfgd,r3
1698#endif
1699
f901a83b 1700 addi r3,0,CPC0_PCI_HOST_CFG_EN
c157d8e2 1701#ifdef CONFIG_BUBINGA
8bde7f77
WD
1702 /*
1703 !-----------------------------------------------------------------------
1704 ! Check FPGA for PCI internal/external arbitration
1705 ! If board is set to internal arbitration, update cpc0_pci
1706 !-----------------------------------------------------------------------
b867d705 1707 */
f901a83b
WD
1708 addis r5,r0,FPGA_REG1@h /* set offset for FPGA_REG1 */
1709 ori r5,r5,FPGA_REG1@l
1710 lbz r5,0x0(r5) /* read to get PCI arb selection */
1711 andi. r6,r5,FPGA_REG1_PCI_INT_ARB /* using internal arbiter ?*/
1712 beq ..pci_cfg_set /* if not set, then bypass reg write*/
b867d705 1713#endif
f901a83b 1714 ori r3,r3,CPC0_PCI_ARBIT_EN
b867d705 1715..pci_cfg_set:
f901a83b 1716 mtdcr CPC0_PCI, r3 /* Enable internal arbiter*/
8bde7f77
WD
1717
1718 /*
1719 !-----------------------------------------------------------------------
1720 ! Check to see if chip is in bypass mode.
1721 ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
1722 ! CPU reset Otherwise, skip this step and keep going.
f901a83b
WD
1723 ! Note: Running BIOS in bypass mode is not supported since PLB speed
1724 ! will not be fast enough for the SDRAM (min 66MHz)
8bde7f77 1725 !-----------------------------------------------------------------------
b867d705 1726 */
f901a83b
WD
1727 mfdcr r5, CPC0_PLLMR1
1728 rlwinm r4,r5,1,0x1 /* get system clock source (SSCS) */
1729 cmpi cr0,0,r4,0x1
b867d705 1730
f901a83b 1731 beq pll_done /* if SSCS =b'1' then PLL has */
8bde7f77
WD
1732 /* already been set */
1733 /* and CPU has been reset */
1734 /* so skip to next section */
b867d705 1735
c157d8e2 1736#ifdef CONFIG_BUBINGA
b867d705 1737 /*
8bde7f77
WD
1738 !-----------------------------------------------------------------------
1739 ! Read NVRAM to get value to write in PLLMR.
1740 ! If value has not been correctly saved, write default value
1741 ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
1742 ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
1743 !
1744 ! WARNING: This code assumes the first three words in the nvram_t
f901a83b
WD
1745 ! structure in openbios.h. Changing the beginning of
1746 ! the structure will break this code.
8bde7f77
WD
1747 !
1748 !-----------------------------------------------------------------------
b867d705 1749 */
f901a83b
WD
1750 addis r3,0,NVRAM_BASE@h
1751 addi r3,r3,NVRAM_BASE@l
1752
1753 lwz r4, 0(r3)
1754 addis r5,0,NVRVFY1@h
1755 addi r5,r5,NVRVFY1@l
1756 cmp cr0,0,r4,r5 /* Compare 1st NVRAM Magic number*/
1757 bne ..no_pllset
1758 addi r3,r3,4
1759 lwz r4, 0(r3)
1760 addis r5,0,NVRVFY2@h
1761 addi r5,r5,NVRVFY2@l
1762 cmp cr0,0,r4,r5 /* Compare 2 NVRAM Magic number */
1763 bne ..no_pllset
1764 addi r3,r3,8 /* Skip over conf_size */
1765 lwz r4, 4(r3) /* Load PLLMR1 value from NVRAM */
1766 lwz r3, 0(r3) /* Load PLLMR0 value from NVRAM */
1767 rlwinm r5,r4,1,0x1 /* get system clock source (SSCS) */
1768 cmpi cr0,0,r5,1 /* See if PLL is locked */
1769 beq pll_write
b867d705 1770..no_pllset:
c157d8e2 1771#endif /* CONFIG_BUBINGA */
b867d705 1772
f901a83b
WD
1773 addis r3,0,PLLMR0_DEFAULT@h /* PLLMR0 default value */
1774 ori r3,r3,PLLMR0_DEFAULT@l /* */
1775 addis r4,0,PLLMR1_DEFAULT@h /* PLLMR1 default value */
1776 ori r4,r4,PLLMR1_DEFAULT@l /* */
b867d705 1777
f901a83b 1778 b pll_write /* Write the CPC0_PLLMR with new value */
b867d705
SR
1779
1780pll_done:
8bde7f77
WD
1781 /*
1782 !-----------------------------------------------------------------------
1783 ! Clear Soft Reset Register
1784 ! This is needed to enable PCI if not booting from serial EPROM
1785 !-----------------------------------------------------------------------
b867d705 1786 */
f901a83b
WD
1787 addi r3, 0, 0x0
1788 mtdcr CPC0_SRR, r3
b867d705 1789
f901a83b
WD
1790 addis r3,0,0x0010
1791 mtctr r3
b867d705 1792pci_wait:
f901a83b 1793 bdnz pci_wait
b867d705
SR
1794
1795 blr /* return to main code */
1796
1797/*
1798!-----------------------------------------------------------------------------
f901a83b
WD
1799! Function: pll_write
1800! Description: Updates the value of the CPC0_PLLMR according to CMOS27E documentation
1801! That is:
1802! 1. Pll is first disabled (de-activated by putting in bypass mode)
1803! 2. PLL is reset
1804! 3. Clock dividers are set while PLL is held in reset and bypassed
1805! 4. PLL Reset is cleared
1806! 5. Wait 100us for PLL to lock
1807! 6. A core reset is performed
b867d705
SR
1808! Input: r3 = Value to write to CPC0_PLLMR0
1809! Input: r4 = Value to write to CPC0_PLLMR1
1810! Output r3 = none
1811!-----------------------------------------------------------------------------
1812*/
1813pll_write:
8bde7f77
WD
1814 mfdcr r5, CPC0_UCR
1815 andis. r5,r5,0xFFFF
f901a83b
WD
1816 ori r5,r5,0x0101 /* Stop the UART clocks */
1817 mtdcr CPC0_UCR,r5 /* Before changing PLL */
8bde7f77
WD
1818
1819 mfdcr r5, CPC0_PLLMR1
f901a83b
WD
1820 rlwinm r5,r5,0,0x7FFFFFFF /* Disable PLL */
1821 mtdcr CPC0_PLLMR1,r5
1822 oris r5,r5,0x4000 /* Set PLL Reset */
1823 mtdcr CPC0_PLLMR1,r5
1824
1825 mtdcr CPC0_PLLMR0,r3 /* Set clock dividers */
1826 rlwinm r5,r4,0,0x3FFFFFFF /* Reset & Bypass new PLL dividers */
1827 oris r5,r5,0x4000 /* Set PLL Reset */
1828 mtdcr CPC0_PLLMR1,r5 /* Set clock dividers */
1829 rlwinm r5,r5,0,0xBFFFFFFF /* Clear PLL Reset */
1830 mtdcr CPC0_PLLMR1,r5
b867d705
SR
1831
1832 /*
8bde7f77
WD
1833 ! Wait min of 100us for PLL to lock.
1834 ! See CMOS 27E databook for more info.
1835 ! At 200MHz, that means waiting 20,000 instructions
b867d705 1836 */
f901a83b
WD
1837 addi r3,0,20000 /* 2000 = 0x4e20 */
1838 mtctr r3
b867d705 1839pll_wait:
f901a83b 1840 bdnz pll_wait
8bde7f77 1841
f901a83b
WD
1842 oris r5,r5,0x8000 /* Enable PLL */
1843 mtdcr CPC0_PLLMR1,r5 /* Engage */
8bde7f77
WD
1844
1845 /*
1846 * Reset CPU to guarantee timings are OK
1847 * Not sure if this is needed...
1848 */
1849 addis r3,0,0x1000
f901a83b 1850 mtspr dbcr0,r3 /* This will cause a CPU core reset, and */
8bde7f77
WD
1851 /* execution will continue from the poweron */
1852 /* vector of 0xfffffffc */
b867d705 1853#endif /* CONFIG_405EP */