blob: 8f7e817eaa0ce136c65d02fb7dad6760048513ce [file] [log] [blame]
wdenk0442ed82002-11-03 10:24:00 +00001/*
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
Wolfgang Denk0ee70772005-09-23 11:05:55 +020045/* U-Boot - Startup Code for AMCC 4xx PowerPC based Embedded Boards
wdenk0442ed82002-11-03 10:24:00 +000046 *
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
120
121/*
122 * Set up GOT: Global Offset Table
123 *
124 * Use r14 to access the GOT
125 */
126 START_GOT
127 GOT_ENTRY(_GOT2_TABLE_)
128 GOT_ENTRY(_FIXUP_TABLE_)
129
130 GOT_ENTRY(_start)
131 GOT_ENTRY(_start_of_vectors)
132 GOT_ENTRY(_end_of_vectors)
133 GOT_ENTRY(transfer_to_handler)
134
wdenkb9a83a92003-05-30 12:48:29 +0000135 GOT_ENTRY(__init_end)
wdenk0442ed82002-11-03 10:24:00 +0000136 GOT_ENTRY(_end)
wdenkbf2f8c92003-05-22 22:52:13 +0000137 GOT_ENTRY(__bss_start)
wdenk0442ed82002-11-03 10:24:00 +0000138 END_GOT
139
140/*
141 * 440 Startup -- on reset only the top 4k of the effective
142 * address space is mapped in by an entry in the instruction
143 * and data shadow TLB. The .bootpg section is located in the
144 * top 4k & does only what's necessary to map in the the rest
145 * of the boot rom. Once the boot rom is mapped in we can
146 * proceed with normal startup.
147 *
148 * NOTE: CS0 only covers the top 2MB of the effective address
149 * space after reset.
150 */
151
152#if defined(CONFIG_440)
153 .section .bootpg,"ax"
154 .globl _start_440
155
156/**************************************************************************/
157_start_440:
158 /*----------------------------------------------------------------*/
159 /* Clear and set up some registers. */
160 /*----------------------------------------------------------------*/
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200161 iccci r0,r0 /* NOTE: operands not used for 440 */
162 dccci r0,r0 /* NOTE: operands not used for 440 */
wdenk0442ed82002-11-03 10:24:00 +0000163 sync
164 li r0,0
165 mtspr srr0,r0
166 mtspr srr1,r0
167 mtspr csrr0,r0
168 mtspr csrr1,r0
Stefan Roeseb30f2a12005-08-08 12:42:22 +0200169#if defined (CONFIG_440GX) /* NOTE: 440GX adds machine check status regs */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200170 mtspr mcsrr0,r0
171 mtspr mcsrr1,r0
172 mfspr r1, mcsr
173 mtspr mcsr,r1
wdenk544e9732004-02-06 23:19:44 +0000174#endif
wdenk0442ed82002-11-03 10:24:00 +0000175 /*----------------------------------------------------------------*/
176 /* Initialize debug */
177 /*----------------------------------------------------------------*/
178 mtspr dbcr0,r0
179 mtspr dbcr1,r0
180 mtspr dbcr2,r0
181 mtspr iac1,r0
182 mtspr iac2,r0
183 mtspr iac3,r0
184 mtspr dac1,r0
185 mtspr dac2,r0
186 mtspr dvc1,r0
187 mtspr dvc2,r0
188
189 mfspr r1,dbsr
190 mtspr dbsr,r1 /* Clear all valid bits */
191
192 /*----------------------------------------------------------------*/
193 /* CCR0 init */
194 /*----------------------------------------------------------------*/
195 /* Disable store gathering & broadcast, guarantee inst/data
196 * cache block touch, force load/store alignment
197 * (see errata 1.12: 440_33)
198 */
199 lis r1,0x0030 /* store gathering & broadcast disable */
200 ori r1,r1,0x6000 /* cache touch */
201 mtspr ccr0,r1
202
203 /*----------------------------------------------------------------*/
204 /* Setup interrupt vectors */
205 /*----------------------------------------------------------------*/
206 mtspr ivpr,r0 /* Vectors start at 0x0000_0000 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200207 li r1,0x0100
wdenk0442ed82002-11-03 10:24:00 +0000208 mtspr ivor0,r1 /* Critical input */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200209 li r1,0x0200
wdenk0442ed82002-11-03 10:24:00 +0000210 mtspr ivor1,r1 /* Machine check */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200211 li r1,0x0300
wdenk0442ed82002-11-03 10:24:00 +0000212 mtspr ivor2,r1 /* Data storage */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200213 li r1,0x0400
wdenk0442ed82002-11-03 10:24:00 +0000214 mtspr ivor3,r1 /* Instruction storage */
215 li r1,0x0500
216 mtspr ivor4,r1 /* External interrupt */
217 li r1,0x0600
218 mtspr ivor5,r1 /* Alignment */
219 li r1,0x0700
220 mtspr ivor6,r1 /* Program check */
221 li r1,0x0800
222 mtspr ivor7,r1 /* Floating point unavailable */
223 li r1,0x0c00
224 mtspr ivor8,r1 /* System call */
225 li r1,0x1000
226 mtspr ivor10,r1 /* Decrementer (PIT for 440) */
227 li r1,0x1400
228 mtspr ivor13,r1 /* Data TLB error */
229 li r1,0x1300
230 mtspr ivor14,r1 /* Instr TLB error */
231 li r1,0x2000
232 mtspr ivor15,r1 /* Debug */
233
234 /*----------------------------------------------------------------*/
235 /* Configure cache regions */
236 /*----------------------------------------------------------------*/
237 mtspr inv0,r0
238 mtspr inv1,r0
239 mtspr inv2,r0
240 mtspr inv3,r0
241 mtspr dnv0,r0
242 mtspr dnv1,r0
243 mtspr dnv2,r0
244 mtspr dnv3,r0
245 mtspr itv0,r0
246 mtspr itv1,r0
247 mtspr itv2,r0
248 mtspr itv3,r0
249 mtspr dtv0,r0
250 mtspr dtv1,r0
251 mtspr dtv2,r0
252 mtspr dtv3,r0
253
254 /*----------------------------------------------------------------*/
255 /* Cache victim limits */
256 /*----------------------------------------------------------------*/
257 /* floors 0, ceiling max to use the entire cache -- nothing locked
258 */
259 lis r1,0x0001
260 ori r1,r1,0xf800
261 mtspr ivlim,r1
262 mtspr dvlim,r1
263
264 /*----------------------------------------------------------------*/
265 /* Clear all TLB entries -- TID = 0, TS = 0 */
266 /*----------------------------------------------------------------*/
267 mtspr mmucr,r0
268 li r1,0x003f /* 64 TLB entries */
269 mtctr r1
2700: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
271 subi r1,r1,0x0001
272 bdnz 0b
273
274 /*----------------------------------------------------------------*/
275 /* TLB entry setup -- step thru tlbtab */
276 /*----------------------------------------------------------------*/
277 bl tlbtab /* Get tlbtab pointer */
278 mr r5,r0
279 li r1,0x003f /* 64 TLB entries max */
280 mtctr r1
281 li r4,0 /* TLB # */
282
283 addi r5,r5,-4
2841: lwzu r0,4(r5)
285 cmpwi r0,0
286 beq 2f /* 0 marks end */
287 lwzu r1,4(r5)
288 lwzu r2,4(r5)
289 tlbwe r0,r4,0 /* TLB Word 0 */
290 tlbwe r1,r4,1 /* TLB Word 1 */
291 tlbwe r2,r4,2 /* TLB Word 2 */
292 addi r4,r4,1 /* Next TLB */
293 bdnz 1b
294
295 /*----------------------------------------------------------------*/
296 /* Continue from 'normal' start */
297 /*----------------------------------------------------------------*/
2982: bl 3f
299 b _start
300
3013: li r0,0
302 mtspr srr1,r0 /* Keep things disabled for now */
303 mflr r1
304 mtspr srr0,r1
305 rfi
stroese434979e2003-05-23 11:18:02 +0000306#endif /* CONFIG_440 */
wdenk0442ed82002-11-03 10:24:00 +0000307
308/*
309 * r3 - 1st arg to board_init(): IMMP pointer
310 * r4 - 2nd arg to board_init(): boot flag
311 */
312 .text
313 .long 0x27051956 /* U-Boot Magic Number */
314 .globl version_string
315version_string:
316 .ascii U_BOOT_VERSION
317 .ascii " (", __DATE__, " - ", __TIME__, ")"
318 .ascii CONFIG_IDENT_STRING, "\0"
319
320/*
321 * Maybe this should be moved somewhere else because the current
322 * location (0x100) is where the CriticalInput Execption should be.
323 */
324 . = EXC_OFF_SYS_RESET
325 .globl _start
326_start:
327
328/*****************************************************************************/
329#if defined(CONFIG_440)
330
331 /*----------------------------------------------------------------*/
332 /* Clear and set up some registers. */
333 /*----------------------------------------------------------------*/
334 li r0,0x0000
335 lis r1,0xffff
336 mtspr dec,r0 /* prevent dec exceptions */
337 mtspr tbl,r0 /* prevent fit & wdt exceptions */
338 mtspr tbu,r0
339 mtspr tsr,r1 /* clear all timer exception status */
340 mtspr tcr,r0 /* disable all */
341 mtspr esr,r0 /* clear exception syndrome register */
342 mtxer r0 /* clear integer exception register */
Stefan Roeseb30f2a12005-08-08 12:42:22 +0200343#if !defined(CONFIG_440GX)
wdenk0442ed82002-11-03 10:24:00 +0000344 lis r1,0x0002 /* set CE bit (Critical Exceptions) */
345 ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
346 mtmsr r1 /* change MSR */
Stefan Roeseb30f2a12005-08-08 12:42:22 +0200347#elif !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
wdenk544e9732004-02-06 23:19:44 +0000348 bl __440gx_msr_set
349 b __440gx_msr_continue
350
351__440gx_msr_set:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200352 lis r1, 0x0002 /* set CE bit (Critical Exceptions) */
353 ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
wdenk544e9732004-02-06 23:19:44 +0000354 mtspr srr1,r1
355 mflr r1
356 mtspr srr0,r1
357 rfi
358__440gx_msr_continue:
359#endif
wdenk0442ed82002-11-03 10:24:00 +0000360
361 /*----------------------------------------------------------------*/
362 /* Debug setup -- some (not very good) ice's need an event*/
363 /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
364 /* value you need in this case 0x8cff 0000 should do the trick */
365 /*----------------------------------------------------------------*/
366#if defined(CFG_INIT_DBCR)
367 lis r1,0xffff
368 ori r1,r1,0xffff
369 mtspr dbsr,r1 /* Clear all status bits */
370 lis r0,CFG_INIT_DBCR@h
371 ori r0,r0,CFG_INIT_DBCR@l
372 mtspr dbcr0,r0
373 isync
374#endif
375
376 /*----------------------------------------------------------------*/
377 /* Setup the internal SRAM */
378 /*----------------------------------------------------------------*/
379 li r0,0
Stefan Roeseb30f2a12005-08-08 12:42:22 +0200380#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
Stefan Roese326c9712005-08-01 16:41:48 +0200381 /* Clear Dcache to use as RAM */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200382 addis r3,r0,CFG_INIT_RAM_ADDR@h
383 ori r3,r3,CFG_INIT_RAM_ADDR@l
384 addis r4,r0,CFG_INIT_RAM_END@h
385 ori r4,r4,CFG_INIT_RAM_END@l
Stefan Roese326c9712005-08-01 16:41:48 +0200386 rlwinm. r5,r4,0,27,31
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200387 rlwinm r5,r4,27,5,31
388 beq ..d_ran
389 addi r5,r5,0x0001
Stefan Roese326c9712005-08-01 16:41:48 +0200390..d_ran:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200391 mtctr r5
Stefan Roese326c9712005-08-01 16:41:48 +0200392..d_ag:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200393 dcbz r0,r3
394 addi r3,r3,32
395 bdnz ..d_ag
Stefan Roese326c9712005-08-01 16:41:48 +0200396#else
Stefan Roeseb30f2a12005-08-08 12:42:22 +0200397#if defined (CONFIG_440GX)
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200398 mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */
wdenk544e9732004-02-06 23:19:44 +0000399#endif
wdenk0442ed82002-11-03 10:24:00 +0000400 mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
401
402 li r2,0x7fff
403 ori r2,r2,0xffff
404 mfdcr r1,isram0_dpc
405 and r1,r1,r2 /* Disable parity check */
406 mtdcr isram0_dpc,r1
407 mfdcr r1,isram0_pmeg
408 andis. r1,r1,r2 /* Disable pwr mgmt */
409 mtdcr isram0_pmeg,r1
410
411 lis r1,0x8000 /* BAS = 8000_0000 */
Stefan Roeseb30f2a12005-08-08 12:42:22 +0200412#if defined(CONFIG_440GX)
wdenk544e9732004-02-06 23:19:44 +0000413 ori r1,r1,0x0980 /* first 64k */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200414 mtdcr isram0_sb0cr,r1
wdenk544e9732004-02-06 23:19:44 +0000415 lis r1,0x8001
416 ori r1,r1,0x0980 /* second 64k */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200417 mtdcr isram0_sb1cr,r1
wdenk544e9732004-02-06 23:19:44 +0000418 lis r1, 0x8002
419 ori r1,r1, 0x0980 /* third 64k */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200420 mtdcr isram0_sb2cr,r1
wdenk544e9732004-02-06 23:19:44 +0000421 lis r1, 0x8003
422 ori r1,r1, 0x0980 /* fourth 64k */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200423 mtdcr isram0_sb3cr,r1
wdenk544e9732004-02-06 23:19:44 +0000424#else
wdenk0442ed82002-11-03 10:24:00 +0000425 ori r1,r1,0x0380 /* 8k rw */
426 mtdcr isram0_sb0cr,r1
wdenk544e9732004-02-06 23:19:44 +0000427#endif
Stefan Roese326c9712005-08-01 16:41:48 +0200428#endif
wdenk0442ed82002-11-03 10:24:00 +0000429
430 /*----------------------------------------------------------------*/
431 /* Setup the stack in internal SRAM */
432 /*----------------------------------------------------------------*/
433 lis r1,CFG_INIT_RAM_ADDR@h
434 ori r1,r1,CFG_INIT_SP_OFFSET@l
435
436 li r0,0
437 stwu r0,-4(r1)
438 stwu r0,-4(r1) /* Terminate call chain */
439
440 stwu r1,-8(r1) /* Save back chain and move SP */
441 lis r0,RESET_VECTOR@h /* Address of reset vector */
442 ori r0,r0, RESET_VECTOR@l
443 stwu r1,-8(r1) /* Save back chain and move SP */
444 stw r0,+12(r1) /* Save return addr (underflow vect) */
445
446 GET_GOT
Stefan Roesec443fe92005-11-22 13:20:42 +0100447
448 bl cpu_init_f /* run low-level CPU init code (from Flash) */
wdenk0442ed82002-11-03 10:24:00 +0000449 bl board_init_f
450
451#endif /* CONFIG_440 */
452
453/*****************************************************************************/
454#ifdef CONFIG_IOP480
455 /*----------------------------------------------------------------------- */
456 /* Set up some machine state registers. */
457 /*----------------------------------------------------------------------- */
458 addi r0,r0,0x0000 /* initialize r0 to zero */
459 mtspr esr,r0 /* clear Exception Syndrome Reg */
460 mttcr r0 /* timer control register */
461 mtexier r0 /* disable all interrupts */
462 addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
463 oris r4,r4,0x2 /* set CE bit (Critical Exceptions) */
464 mtmsr r4 /* change MSR */
465 addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
466 ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
467 mtdbsr r4 /* clear/reset the dbsr */
468 mtexisr r4 /* clear all pending interrupts */
469 addis r4,r0,0x8000
470 mtexier r4 /* enable critical exceptions */
471 addis r4,r0,0x0000 /* assume 403GCX - enable core clk */
472 ori r4,r4,0x4020 /* dbling (no harm done on GA and GC */
473 mtiocr r4 /* since bit not used) & DRC to latch */
474 /* data bus on rising edge of CAS */
475 /*----------------------------------------------------------------------- */
476 /* Clear XER. */
477 /*----------------------------------------------------------------------- */
478 mtxer r0
479 /*----------------------------------------------------------------------- */
480 /* Invalidate i-cache and d-cache TAG arrays. */
481 /*----------------------------------------------------------------------- */
482 addi r3,0,1024 /* 1/4 of I-cache size, half of D-cache */
483 addi r4,0,1024 /* 1/4 of I-cache */
484..cloop:
485 iccci 0,r3
486 iccci r4,r3
487 dccci 0,r3
488 addic. r3,r3,-16 /* move back one cache line */
489 bne ..cloop /* loop back to do rest until r3 = 0 */
490
491 /* */
492 /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
493 /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
494 /* */
495
496 /* first copy IOP480 register base address into r3 */
497 addis r3,0,0x5000 /* IOP480 register base address hi */
498/* ori r3,r3,0x0000 / IOP480 register base address lo */
499
500#ifdef CONFIG_ADCIOP
501 /* use r4 as the working variable */
502 /* turn on CS3 (LOCCTL.7) */
503 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
504 andi. r4,r4,0xff7f /* make bit 7 = 0 -- CS3 mode */
505 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
506#endif
507
508#ifdef CONFIG_DASA_SIM
509 /* use r4 as the working variable */
510 /* turn on MA17 (LOCCTL.7) */
511 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
512 ori r4,r4,0x80 /* make bit 7 = 1 -- MA17 mode */
513 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
514#endif
515
516 /* turn on MA16..13 (LCS0BRD.12 = 0) */
517 lwz r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
518 andi. r4,r4,0xefff /* make bit 12 = 0 */
519 stw r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
520
521 /* make sure above stores all comlete before going on */
522 sync
523
524 /* last thing, set local init status done bit (DEVINIT.31) */
525 lwz r4,0x80(r3) /* DEVINIT is at offset 0x80 */
526 oris r4,r4,0x8000 /* make bit 31 = 1 */
527 stw r4,0x80(r3) /* DEVINIT is at offset 0x80 */
528
529 /* clear all pending interrupts and disable all interrupts */
530 li r4,-1 /* set p1 to 0xffffffff */
531 stw r4,0x1b0(r3) /* clear all pending interrupts */
532 stw r4,0x1b8(r3) /* clear all pending interrupts */
533 li r4,0 /* set r4 to 0 */
534 stw r4,0x1b4(r3) /* disable all interrupts */
535 stw r4,0x1bc(r3) /* disable all interrupts */
536
537 /* make sure above stores all comlete before going on */
538 sync
539
540 /*----------------------------------------------------------------------- */
541 /* Enable two 128MB cachable regions. */
542 /*----------------------------------------------------------------------- */
543 addis r1,r0,0x8000
544 addi r1,r1,0x0001
545 mticcr r1 /* instruction cache */
546
547 addis r1,r0,0x0000
548 addi r1,r1,0x0000
549 mtdccr r1 /* data cache */
550
551 addis r1,r0,CFG_INIT_RAM_ADDR@h
552 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
553 li r0, 0 /* Make room for stack frame header and */
554 stwu r0, -4(r1) /* clear final stack frame so that */
555 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
556
557 GET_GOT /* initialize GOT access */
558
559 bl board_init_f /* run first part of init code (from Flash) */
560
561#endif /* CONFIG_IOP480 */
562
563/*****************************************************************************/
stroese434979e2003-05-23 11:18:02 +0000564#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_405EP)
wdenk0442ed82002-11-03 10:24:00 +0000565 /*----------------------------------------------------------------------- */
566 /* Clear and set up some registers. */
567 /*----------------------------------------------------------------------- */
568 addi r4,r0,0x0000
569 mtspr sgr,r4
570 mtspr dcwr,r4
571 mtesr r4 /* clear Exception Syndrome Reg */
572 mttcr r4 /* clear Timer Control Reg */
573 mtxer r4 /* clear Fixed-Point Exception Reg */
574 mtevpr r4 /* clear Exception Vector Prefix Reg */
575 addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
576 oris r4,r4,0x0002 /* set CE bit (Critical Exceptions) */
577 mtmsr r4 /* change MSR */
578 addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
579 /* dbsr is cleared by setting bits to 1) */
580 mtdbsr r4 /* clear/reset the dbsr */
581
582 /*----------------------------------------------------------------------- */
583 /* Invalidate I and D caches. Enable I cache for defined memory regions */
584 /* to speed things up. Leave the D cache disabled for now. It will be */
585 /* enabled/left disabled later based on user selected menu options. */
586 /* Be aware that the I cache may be disabled later based on the menu */
587 /* options as well. See miscLib/main.c. */
588 /*----------------------------------------------------------------------- */
589 bl invalidate_icache
590 bl invalidate_dcache
591
592 /*----------------------------------------------------------------------- */
593 /* Enable two 128MB cachable regions. */
594 /*----------------------------------------------------------------------- */
595 addis r4,r0,0x8000
596 addi r4,r4,0x0001
597 mticcr r4 /* instruction cache */
598 isync
599
600 addis r4,r0,0x0000
601 addi r4,r4,0x0000
602 mtdccr r4 /* data cache */
603
604#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
605 /*----------------------------------------------------------------------- */
606 /* Tune the speed and size for flash CS0 */
607 /*----------------------------------------------------------------------- */
608 bl ext_bus_cntlr_init
609#endif
610
stroese434979e2003-05-23 11:18:02 +0000611#if defined(CONFIG_405EP)
612 /*----------------------------------------------------------------------- */
613 /* DMA Status, clear to come up clean */
614 /*----------------------------------------------------------------------- */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200615 addis r3,r0, 0xFFFF /* Clear all existing DMA status */
616 ori r3,r3, 0xFFFF
617 mtdcr dmasr, r3
stroese434979e2003-05-23 11:18:02 +0000618
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200619 bl ppc405ep_init /* do ppc405ep specific init */
stroese434979e2003-05-23 11:18:02 +0000620#endif /* CONFIG_405EP */
621
wdenk0442ed82002-11-03 10:24:00 +0000622#if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
623 /********************************************************************
624 * Setup OCM - On Chip Memory
625 *******************************************************************/
626 /* Setup OCM */
wdenk57b2d802003-06-27 21:31:46 +0000627 lis r0, 0x7FFF
628 ori r0, r0, 0xFFFF
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200629 mfdcr r3, ocmiscntl /* get instr-side IRAM config */
wdenk57b2d802003-06-27 21:31:46 +0000630 mfdcr r4, ocmdscntl /* get data-side IRAM config */
631 and r3, r3, r0 /* disable data-side IRAM */
632 and r4, r4, r0 /* disable data-side IRAM */
633 mtdcr ocmiscntl, r3 /* set instr-side IRAM config */
634 mtdcr ocmdscntl, r4 /* set data-side IRAM config */
635 isync
wdenk0442ed82002-11-03 10:24:00 +0000636
637 addis r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
638 mtdcr ocmdsarc, r3
639 addis r4, 0, 0xC000 /* OCM data area enabled */
640 mtdcr ocmdscntl, r4
wdenk57b2d802003-06-27 21:31:46 +0000641 isync
wdenk0442ed82002-11-03 10:24:00 +0000642#endif
643
644 /*----------------------------------------------------------------------- */
645 /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
646 /*----------------------------------------------------------------------- */
647#ifdef CFG_INIT_DCACHE_CS
648 /*----------------------------------------------------------------------- */
649 /* Memory Bank x (nothingness) initialization 1GB+64MEG */
650 /* used as temporary stack pointer for stage0 */
651 /*----------------------------------------------------------------------- */
652 li r4,PBxAP
653 mtdcr ebccfga,r4
654 lis r4,0x0380
655 ori r4,r4,0x0480
656 mtdcr ebccfgd,r4
657
658 addi r4,0,PBxCR
659 mtdcr ebccfga,r4
660 lis r4,0x400D
661 ori r4,r4,0xa000
662 mtdcr ebccfgd,r4
663
664 /* turn on data chache for this region */
665 lis r4,0x0080
666 mtdccr r4
667
668 /* set stack pointer and clear stack to known value */
669
670 lis r1,CFG_INIT_RAM_ADDR@h
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200671 ori r1,r1,CFG_INIT_SP_OFFSET@l
wdenk0442ed82002-11-03 10:24:00 +0000672
673 li r4,2048 /* we store 2048 words to stack */
674 mtctr r4
675
676 lis r2,CFG_INIT_RAM_ADDR@h /* we also clear data area */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200677 ori r2,r2,CFG_INIT_RAM_END@l /* so cant copy value from r1 */
wdenk0442ed82002-11-03 10:24:00 +0000678
679 lis r4,0xdead /* we store 0xdeaddead in the stack */
680 ori r4,r4,0xdead
681
682..stackloop:
683 stwu r4,-4(r2)
684 bdnz ..stackloop
685
686 li r0, 0 /* Make room for stack frame header and */
687 stwu r0, -4(r1) /* clear final stack frame so that */
688 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
689 /*
690 * Set up a dummy frame to store reset vector as return address.
691 * this causes stack underflow to reset board.
692 */
693 stwu r1, -8(r1) /* Save back chain and move SP */
694 addis r0, 0, RESET_VECTOR@h /* Address of reset vector */
695 ori r0, r0, RESET_VECTOR@l
696 stwu r1, -8(r1) /* Save back chain and move SP */
697 stw r0, +12(r1) /* Save return addr (underflow vect) */
698
699#elif defined(CFG_TEMP_STACK_OCM) && \
700 (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
701 /*
702 * Stack in OCM.
703 */
704
705 /* Set up Stack at top of OCM */
706 lis r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
707 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
708
709 /* Set up a zeroized stack frame so that backtrace works right */
710 li r0, 0
711 stwu r0, -4(r1)
712 stwu r0, -4(r1)
713
714 /*
715 * Set up a dummy frame to store reset vector as return address.
716 * this causes stack underflow to reset board.
717 */
718 stwu r1, -8(r1) /* Save back chain and move SP */
719 lis r0, RESET_VECTOR@h /* Address of reset vector */
720 ori r0, r0, RESET_VECTOR@l
721 stwu r1, -8(r1) /* Save back chain and move SP */
722 stw r0, +12(r1) /* Save return addr (underflow vect) */
723#endif /* CFG_INIT_DCACHE_CS */
724
725 /*----------------------------------------------------------------------- */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200726 /* Initialize SDRAM Controller */
wdenk0442ed82002-11-03 10:24:00 +0000727 /*----------------------------------------------------------------------- */
728 bl sdram_init
729
730 /*
731 * Setup temporary stack pointer only for boards
732 * that do not use SDRAM SPD I2C stuff since it
733 * is already initialized to use DCACHE or OCM
734 * stacks.
735 */
736#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
737 lis r1, CFG_INIT_RAM_ADDR@h
738 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
739
740 li r0, 0 /* Make room for stack frame header and */
741 stwu r0, -4(r1) /* clear final stack frame so that */
742 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
743 /*
744 * Set up a dummy frame to store reset vector as return address.
745 * this causes stack underflow to reset board.
746 */
747 stwu r1, -8(r1) /* Save back chain and move SP */
748 lis r0, RESET_VECTOR@h /* Address of reset vector */
749 ori r0, r0, RESET_VECTOR@l
750 stwu r1, -8(r1) /* Save back chain and move SP */
751 stw r0, +12(r1) /* Save return addr (underflow vect) */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200752#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
wdenk0442ed82002-11-03 10:24:00 +0000753
754 GET_GOT /* initialize GOT access */
755
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200756 bl cpu_init_f /* run low-level CPU init code (from Flash) */
wdenk0442ed82002-11-03 10:24:00 +0000757
758 /* NEVER RETURNS! */
759 bl board_init_f /* run first part of init code (from Flash) */
760
wdenk232fe0b2003-09-02 22:48:03 +0000761#endif /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
762 /*----------------------------------------------------------------------- */
wdenk0442ed82002-11-03 10:24:00 +0000763
764
stroese434979e2003-05-23 11:18:02 +0000765/*****************************************************************************/
wdenk0442ed82002-11-03 10:24:00 +0000766 .globl _start_of_vectors
767_start_of_vectors:
768
769#if 0
770/*TODO Fixup _start above so we can do this*/
771/* Critical input. */
772 CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
773#endif
774
775/* Machine check */
wdenk381669a2003-06-16 23:50:08 +0000776 CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
wdenk0442ed82002-11-03 10:24:00 +0000777
778/* Data Storage exception. */
779 STD_EXCEPTION(0x300, DataStorage, UnknownException)
780
781/* Instruction Storage exception. */
782 STD_EXCEPTION(0x400, InstStorage, UnknownException)
783
784/* External Interrupt exception. */
785 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
786
787/* Alignment exception. */
788 . = 0x600
789Alignment:
790 EXCEPTION_PROLOG
791 mfspr r4,DAR
792 stw r4,_DAR(r21)
793 mfspr r5,DSISR
794 stw r5,_DSISR(r21)
795 addi r3,r1,STACK_FRAME_OVERHEAD
796 li r20,MSR_KERNEL
797 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
798 lwz r6,GOT(transfer_to_handler)
799 mtlr r6
800 blrl
801.L_Alignment:
802 .long AlignmentException - _start + EXC_OFF_SYS_RESET
803 .long int_return - _start + EXC_OFF_SYS_RESET
804
805/* Program check exception */
806 . = 0x700
807ProgramCheck:
808 EXCEPTION_PROLOG
809 addi r3,r1,STACK_FRAME_OVERHEAD
810 li r20,MSR_KERNEL
811 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
812 lwz r6,GOT(transfer_to_handler)
813 mtlr r6
814 blrl
815.L_ProgramCheck:
816 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
817 .long int_return - _start + EXC_OFF_SYS_RESET
818
819 /* No FPU on MPC8xx. This exception is not supposed to happen.
820 */
821 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
822
823 /* I guess we could implement decrementer, and may have
824 * to someday for timekeeping.
825 */
826 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
827 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
828 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk874ac262003-07-24 23:38:38 +0000829 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenk0442ed82002-11-03 10:24:00 +0000830 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
831
832 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
833 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
834
835 /* On the MPC8xx, this is a software emulation interrupt. It occurs
836 * for all unimplemented and illegal instructions.
837 */
838 STD_EXCEPTION(0x1000, PIT, PITException)
839
840 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
841 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
842 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
843 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
844
845 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
846 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
847 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
848 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
849 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
850 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
851 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
852
853 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
854 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
855 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
856 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
857
858 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
859
860 .globl _end_of_vectors
861_end_of_vectors:
862
863
864 . = 0x2100
865
866/*
867 * This code finishes saving the registers to the exception frame
868 * and jumps to the appropriate handler for the exception.
869 * Register r21 is pointer into trap frame, r1 has new stack pointer.
870 */
871 .globl transfer_to_handler
872transfer_to_handler:
873 stw r22,_NIP(r21)
874 lis r22,MSR_POW@h
875 andc r23,r23,r22
876 stw r23,_MSR(r21)
877 SAVE_GPR(7, r21)
878 SAVE_4GPRS(8, r21)
879 SAVE_8GPRS(12, r21)
880 SAVE_8GPRS(24, r21)
881#if 0
882 andi. r23,r23,MSR_PR
883 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
884 beq 2f
885 addi r24,r1,STACK_FRAME_OVERHEAD
886 stw r24,PT_REGS(r23)
8872: addi r2,r23,-TSS /* set r2 to current */
888 tovirt(r2,r2,r23)
889#endif
890 mflr r23
891 andi. r24,r23,0x3f00 /* get vector offset */
892 stw r24,TRAP(r21)
893 li r22,0
894 stw r22,RESULT(r21)
895 mtspr SPRG2,r22 /* r1 is now kernel sp */
896#if 0
897 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
898 cmplw 0,r1,r2
899 cmplw 1,r1,r24
900 crand 1,1,4
901 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
902#endif
903 lwz r24,0(r23) /* virtual address of handler */
904 lwz r23,4(r23) /* where to go when done */
905 mtspr SRR0,r24
906 mtspr SRR1,r20
907 mtlr r23
908 SYNC
909 rfi /* jump to handler, enable MMU */
910
911int_return:
912 mfmsr r28 /* Disable interrupts */
913 li r4,0
914 ori r4,r4,MSR_EE
915 andc r28,r28,r4
916 SYNC /* Some chip revs need this... */
917 mtmsr r28
918 SYNC
919 lwz r2,_CTR(r1)
920 lwz r0,_LINK(r1)
921 mtctr r2
922 mtlr r0
923 lwz r2,_XER(r1)
924 lwz r0,_CCR(r1)
925 mtspr XER,r2
926 mtcrf 0xFF,r0
927 REST_10GPRS(3, r1)
928 REST_10GPRS(13, r1)
929 REST_8GPRS(23, r1)
930 REST_GPR(31, r1)
931 lwz r2,_NIP(r1) /* Restore environment */
932 lwz r0,_MSR(r1)
933 mtspr SRR0,r2
934 mtspr SRR1,r0
935 lwz r0,GPR0(r1)
936 lwz r2,GPR2(r1)
937 lwz r1,GPR1(r1)
938 SYNC
939 rfi
940
941crit_return:
942 mfmsr r28 /* Disable interrupts */
943 li r4,0
944 ori r4,r4,MSR_EE
945 andc r28,r28,r4
946 SYNC /* Some chip revs need this... */
947 mtmsr r28
948 SYNC
949 lwz r2,_CTR(r1)
950 lwz r0,_LINK(r1)
951 mtctr r2
952 mtlr r0
953 lwz r2,_XER(r1)
954 lwz r0,_CCR(r1)
955 mtspr XER,r2
956 mtcrf 0xFF,r0
957 REST_10GPRS(3, r1)
958 REST_10GPRS(13, r1)
959 REST_8GPRS(23, r1)
960 REST_GPR(31, r1)
961 lwz r2,_NIP(r1) /* Restore environment */
962 lwz r0,_MSR(r1)
963 mtspr 990,r2 /* SRR2 */
964 mtspr 991,r0 /* SRR3 */
965 lwz r0,GPR0(r1)
966 lwz r2,GPR2(r1)
967 lwz r1,GPR1(r1)
968 SYNC
969 rfci
970
971/* Cache functions.
972*/
973invalidate_icache:
974 iccci r0,r0 /* for 405, iccci invalidates the */
975 blr /* entire I cache */
976
977invalidate_dcache:
978 addi r6,0,0x0000 /* clear GPR 6 */
979 /* Do loop for # of dcache congruence classes. */
Stefan Roeseb30f2a12005-08-08 12:42:22 +0200980#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200981 lis r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS for large sized cache */
982 ori r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
wdenk544e9732004-02-06 23:19:44 +0000983#else
wdenk0442ed82002-11-03 10:24:00 +0000984 addi r7,r0, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
wdenk544e9732004-02-06 23:19:44 +0000985#endif
wdenk0442ed82002-11-03 10:24:00 +0000986 /* NOTE: dccci invalidates both */
987 mtctr r7 /* ways in the D cache */
988..dcloop:
989 dccci 0,r6 /* invalidate line */
990 addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
991 bdnz ..dcloop
992 blr
993
994flush_dcache:
995 addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
996 ori r9,r9,0x8000
997 mfmsr r12 /* save msr */
998 andc r9,r12,r9
999 mtmsr r9 /* disable EE and CE */
1000 addi r10,r0,0x0001 /* enable data cache for unused memory */
1001 mfdccr r9 /* region 0xF8000000-0xFFFFFFFF via */
1002 or r10,r10,r9 /* bit 31 in dccr */
1003 mtdccr r10
1004
1005 /* do loop for # of congruence classes. */
Stefan Roeseb30f2a12005-08-08 12:42:22 +02001006#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001007 lis r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS: for large cache sizes */
1008 ori r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
1009 lis r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */
1010 ori r11,r11,(CFG_DCACHE_SIZE / 2)@l /* D cache set size - 2 way sets */
wdenk544e9732004-02-06 23:19:44 +00001011#else
wdenk0442ed82002-11-03 10:24:00 +00001012 addi r10,r0,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
1013 addi r11,r0,(CFG_DCACHE_SIZE / 2) /* D cache set size - 2 way sets */
wdenk544e9732004-02-06 23:19:44 +00001014#endif
wdenk0442ed82002-11-03 10:24:00 +00001015 mtctr r10
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001016 addi r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
wdenk0442ed82002-11-03 10:24:00 +00001017 add r11,r10,r11 /* add to get to other side of cache line */
1018..flush_dcache_loop:
1019 lwz r3,0(r10) /* least recently used side */
1020 lwz r3,0(r11) /* the other side */
1021 dccci r0,r11 /* invalidate both sides */
1022 addi r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
1023 addi r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
1024 bdnz ..flush_dcache_loop
1025 sync /* allow memory access to complete */
1026 mtdccr r9 /* restore dccr */
1027 mtmsr r12 /* restore msr */
1028 blr
1029
1030 .globl icache_enable
1031icache_enable:
1032 mflr r8
1033 bl invalidate_icache
1034 mtlr r8
1035 isync
1036 addis r3,r0, 0x8000 /* set bit 0 */
1037 mticcr r3
1038 blr
1039
1040 .globl icache_disable
1041icache_disable:
1042 addis r3,r0, 0x0000 /* clear bit 0 */
1043 mticcr r3
1044 isync
1045 blr
1046
1047 .globl icache_status
1048icache_status:
1049 mficcr r3
1050 srwi r3, r3, 31 /* >>31 => select bit 0 */
1051 blr
1052
1053 .globl dcache_enable
1054dcache_enable:
1055 mflr r8
1056 bl invalidate_dcache
1057 mtlr r8
1058 isync
1059 addis r3,r0, 0x8000 /* set bit 0 */
1060 mtdccr r3
1061 blr
1062
1063 .globl dcache_disable
1064dcache_disable:
1065 mflr r8
1066 bl flush_dcache
1067 mtlr r8
1068 addis r3,r0, 0x0000 /* clear bit 0 */
1069 mtdccr r3
1070 blr
1071
1072 .globl dcache_status
1073dcache_status:
1074 mfdccr r3
1075 srwi r3, r3, 31 /* >>31 => select bit 0 */
1076 blr
1077
1078 .globl get_pvr
1079get_pvr:
1080 mfspr r3, PVR
1081 blr
1082
1083#if !defined(CONFIG_440)
1084 .globl wr_pit
1085wr_pit:
1086 mtspr pit, r3
1087 blr
1088#endif
1089
1090 .globl wr_tcr
1091wr_tcr:
1092 mtspr tcr, r3
1093 blr
1094
1095/*------------------------------------------------------------------------------- */
1096/* Function: in8 */
1097/* Description: Input 8 bits */
1098/*------------------------------------------------------------------------------- */
1099 .globl in8
1100in8:
1101 lbz r3,0x0000(r3)
1102 blr
1103
1104/*------------------------------------------------------------------------------- */
1105/* Function: out8 */
1106/* Description: Output 8 bits */
1107/*------------------------------------------------------------------------------- */
1108 .globl out8
1109out8:
1110 stb r4,0x0000(r3)
1111 blr
1112
1113/*------------------------------------------------------------------------------- */
1114/* Function: out16 */
1115/* Description: Output 16 bits */
1116/*------------------------------------------------------------------------------- */
1117 .globl out16
1118out16:
1119 sth r4,0x0000(r3)
1120 blr
1121
1122/*------------------------------------------------------------------------------- */
1123/* Function: out16r */
1124/* Description: Byte reverse and output 16 bits */
1125/*------------------------------------------------------------------------------- */
1126 .globl out16r
1127out16r:
1128 sthbrx r4,r0,r3
1129 blr
1130
1131/*------------------------------------------------------------------------------- */
1132/* Function: out32 */
1133/* Description: Output 32 bits */
1134/*------------------------------------------------------------------------------- */
1135 .globl out32
1136out32:
1137 stw r4,0x0000(r3)
1138 blr
1139
1140/*------------------------------------------------------------------------------- */
1141/* Function: out32r */
1142/* Description: Byte reverse and output 32 bits */
1143/*------------------------------------------------------------------------------- */
1144 .globl out32r
1145out32r:
1146 stwbrx r4,r0,r3
1147 blr
1148
1149/*------------------------------------------------------------------------------- */
1150/* Function: in16 */
1151/* Description: Input 16 bits */
1152/*------------------------------------------------------------------------------- */
1153 .globl in16
1154in16:
1155 lhz r3,0x0000(r3)
1156 blr
1157
1158/*------------------------------------------------------------------------------- */
1159/* Function: in16r */
1160/* Description: Input 16 bits and byte reverse */
1161/*------------------------------------------------------------------------------- */
1162 .globl in16r
1163in16r:
1164 lhbrx r3,r0,r3
1165 blr
1166
1167/*------------------------------------------------------------------------------- */
1168/* Function: in32 */
1169/* Description: Input 32 bits */
1170/*------------------------------------------------------------------------------- */
1171 .globl in32
1172in32:
1173 lwz 3,0x0000(3)
1174 blr
1175
1176/*------------------------------------------------------------------------------- */
1177/* Function: in32r */
1178/* Description: Input 32 bits and byte reverse */
1179/*------------------------------------------------------------------------------- */
1180 .globl in32r
1181in32r:
1182 lwbrx r3,r0,r3
1183 blr
1184
1185/*------------------------------------------------------------------------------- */
1186/* Function: ppcDcbf */
1187/* Description: Data Cache block flush */
1188/* Input: r3 = effective address */
1189/* Output: none. */
1190/*------------------------------------------------------------------------------- */
1191 .globl ppcDcbf
1192ppcDcbf:
1193 dcbf r0,r3
1194 blr
1195
1196/*------------------------------------------------------------------------------- */
1197/* Function: ppcDcbi */
1198/* Description: Data Cache block Invalidate */
1199/* Input: r3 = effective address */
1200/* Output: none. */
1201/*------------------------------------------------------------------------------- */
1202 .globl ppcDcbi
1203ppcDcbi:
1204 dcbi r0,r3
1205 blr
1206
1207/*------------------------------------------------------------------------------- */
1208/* Function: ppcSync */
1209/* Description: Processor Synchronize */
1210/* Input: none. */
1211/* Output: none. */
1212/*------------------------------------------------------------------------------- */
1213 .globl ppcSync
1214ppcSync:
1215 sync
1216 blr
1217
1218/*------------------------------------------------------------------------------*/
1219
1220/*
1221 * void relocate_code (addr_sp, gd, addr_moni)
1222 *
1223 * This "function" does not return, instead it continues in RAM
1224 * after relocating the monitor code.
1225 *
1226 * r3 = dest
1227 * r4 = src
1228 * r5 = length in bytes
1229 * r6 = cachelinesize
1230 */
1231 .globl relocate_code
1232relocate_code:
Stefan Roeseb30f2a12005-08-08 12:42:22 +02001233#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001234 dccci 0,0 /* Invalidate data cache, now no longer our stack */
Stefan Roese326c9712005-08-01 16:41:48 +02001235 sync
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001236 addi r1,r0,0x0000 /* Tlb entry #0 */
Stefan Roese326c9712005-08-01 16:41:48 +02001237 tlbre r0,r1,0x0002 /* Read contents */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001238 ori r0,r0,0x0c00 /* Or in the inhibit, write through bit */
1239 tlbwe r0,r1,0x0002 /* Save it out */
Stefan Roese326c9712005-08-01 16:41:48 +02001240 isync
1241#endif
wdenk0442ed82002-11-03 10:24:00 +00001242 mr r1, r3 /* Set new stack pointer */
1243 mr r9, r4 /* Save copy of Init Data pointer */
1244 mr r10, r5 /* Save copy of Destination Address */
1245
1246 mr r3, r5 /* Destination Address */
1247 lis r4, CFG_MONITOR_BASE@h /* Source Address */
1248 ori r4, r4, CFG_MONITOR_BASE@l
wdenkb9a83a92003-05-30 12:48:29 +00001249 lwz r5, GOT(__init_end)
1250 sub r5, r5, r4
wdenk0442ed82002-11-03 10:24:00 +00001251 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
1252
1253 /*
1254 * Fix GOT pointer:
1255 *
1256 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1257 *
1258 * Offset:
1259 */
1260 sub r15, r10, r4
1261
1262 /* First our own GOT */
1263 add r14, r14, r15
1264 /* the the one used by the C code */
1265 add r30, r30, r15
1266
1267 /*
1268 * Now relocate code
1269 */
1270
1271 cmplw cr1,r3,r4
1272 addi r0,r5,3
1273 srwi. r0,r0,2
1274 beq cr1,4f /* In place copy is not necessary */
1275 beq 7f /* Protect against 0 count */
1276 mtctr r0
1277 bge cr1,2f
1278
1279 la r8,-4(r4)
1280 la r7,-4(r3)
12811: lwzu r0,4(r8)
1282 stwu r0,4(r7)
1283 bdnz 1b
1284 b 4f
1285
12862: slwi r0,r0,2
1287 add r8,r4,r0
1288 add r7,r3,r0
12893: lwzu r0,-4(r8)
1290 stwu r0,-4(r7)
1291 bdnz 3b
1292
1293/*
1294 * Now flush the cache: note that we must start from a cache aligned
1295 * address. Otherwise we might miss one cache line.
1296 */
12974: cmpwi r6,0
1298 add r5,r3,r5
1299 beq 7f /* Always flush prefetch queue in any case */
1300 subi r0,r6,1
1301 andc r3,r3,r0
1302 mr r4,r3
13035: dcbst 0,r4
1304 add r4,r4,r6
1305 cmplw r4,r5
1306 blt 5b
1307 sync /* Wait for all dcbst to complete on bus */
1308 mr r4,r3
13096: icbi 0,r4
1310 add r4,r4,r6
1311 cmplw r4,r5
1312 blt 6b
13137: sync /* Wait for all icbi to complete on bus */
1314 isync
1315
1316/*
1317 * We are done. Do not return, instead branch to second part of board
1318 * initialization, now running from RAM.
1319 */
1320
1321 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1322 mtlr r0
1323 blr /* NEVER RETURNS! */
1324
1325in_ram:
1326
1327 /*
1328 * Relocation Function, r14 point to got2+0x8000
1329 *
1330 * Adjust got2 pointers, no need to check for 0, this code
1331 * already puts a few entries in the table.
1332 */
1333 li r0,__got2_entries@sectoff@l
1334 la r3,GOT(_GOT2_TABLE_)
1335 lwz r11,GOT(_GOT2_TABLE_)
1336 mtctr r0
1337 sub r11,r3,r11
1338 addi r3,r3,-4
13391: lwzu r0,4(r3)
1340 add r0,r0,r11
1341 stw r0,0(r3)
1342 bdnz 1b
1343
1344 /*
1345 * Now adjust the fixups and the pointers to the fixups
1346 * in case we need to move ourselves again.
1347 */
13482: li r0,__fixup_entries@sectoff@l
1349 lwz r3,GOT(_FIXUP_TABLE_)
1350 cmpwi r0,0
1351 mtctr r0
1352 addi r3,r3,-4
1353 beq 4f
13543: lwzu r4,4(r3)
1355 lwzux r0,r4,r11
1356 add r0,r0,r11
1357 stw r10,0(r3)
1358 stw r0,0(r4)
1359 bdnz 3b
13604:
1361clear_bss:
1362 /*
1363 * Now clear BSS segment
1364 */
wdenkbf2f8c92003-05-22 22:52:13 +00001365 lwz r3,GOT(__bss_start)
wdenk0442ed82002-11-03 10:24:00 +00001366 lwz r4,GOT(_end)
1367
1368 cmplw 0, r3, r4
1369 beq 6f
1370
1371 li r0, 0
13725:
1373 stw r0, 0(r3)
1374 addi r3, r3, 4
1375 cmplw 0, r3, r4
1376 bne 5b
13776:
1378
1379 mr r3, r9 /* Init Data pointer */
1380 mr r4, r10 /* Destination Address */
1381 bl board_init_r
1382
wdenk0442ed82002-11-03 10:24:00 +00001383 /*
1384 * Copy exception vector code to low memory
1385 *
1386 * r3: dest_addr
1387 * r7: source address, r8: end address, r9: target address
1388 */
1389 .globl trap_init
1390trap_init:
1391 lwz r7, GOT(_start)
1392 lwz r8, GOT(_end_of_vectors)
1393
wdenk4e112c12003-06-03 23:54:09 +00001394 li r9, 0x100 /* reset vector always at 0x100 */
wdenk0442ed82002-11-03 10:24:00 +00001395
1396 cmplw 0, r7, r8
1397 bgelr /* return if r7>=r8 - just in case */
1398
1399 mflr r4 /* save link register */
14001:
1401 lwz r0, 0(r7)
1402 stw r0, 0(r9)
1403 addi r7, r7, 4
1404 addi r9, r9, 4
1405 cmplw 0, r7, r8
1406 bne 1b
1407
1408 /*
1409 * relocate `hdlr' and `int_return' entries
1410 */
1411 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1412 li r8, Alignment - _start + EXC_OFF_SYS_RESET
14132:
1414 bl trap_reloc
1415 addi r7, r7, 0x100 /* next exception vector */
1416 cmplw 0, r7, r8
1417 blt 2b
1418
1419 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1420 bl trap_reloc
1421
1422 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1423 bl trap_reloc
1424
1425 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1426 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
14273:
1428 bl trap_reloc
1429 addi r7, r7, 0x100 /* next exception vector */
1430 cmplw 0, r7, r8
1431 blt 3b
1432
1433 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1434 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
14354:
1436 bl trap_reloc
1437 addi r7, r7, 0x100 /* next exception vector */
1438 cmplw 0, r7, r8
1439 blt 4b
1440
1441 mtlr r4 /* restore link register */
1442 blr
1443
1444 /*
1445 * Function: relocate entries for one exception vector
1446 */
1447trap_reloc:
1448 lwz r0, 0(r7) /* hdlr ... */
1449 add r0, r0, r3 /* ... += dest_addr */
1450 stw r0, 0(r7)
1451
1452 lwz r0, 4(r7) /* int_return ... */
1453 add r0, r0, r3 /* ... += dest_addr */
1454 stw r0, 4(r7)
1455
1456 blr
stroese434979e2003-05-23 11:18:02 +00001457
1458
1459/**************************************************************************/
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001460/* PPC405EP specific stuff */
stroese434979e2003-05-23 11:18:02 +00001461/**************************************************************************/
1462#ifdef CONFIG_405EP
1463ppc405ep_init:
stroese5ad6d4d2003-12-09 14:54:43 +00001464
Stefan Roese326c9712005-08-01 16:41:48 +02001465#ifdef CONFIG_BUBINGA
stroese5ad6d4d2003-12-09 14:54:43 +00001466 /*
1467 * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
1468 * function) to support FPGA and NVRAM accesses below.
1469 */
1470
1471 lis r3,GPIO0_OSRH@h /* config GPIO output select */
1472 ori r3,r3,GPIO0_OSRH@l
1473 lis r4,CFG_GPIO0_OSRH@h
1474 ori r4,r4,CFG_GPIO0_OSRH@l
1475 stw r4,0(r3)
1476 lis r3,GPIO0_OSRL@h
1477 ori r3,r3,GPIO0_OSRL@l
1478 lis r4,CFG_GPIO0_OSRL@h
1479 ori r4,r4,CFG_GPIO0_OSRL@l
1480 stw r4,0(r3)
1481
1482 lis r3,GPIO0_ISR1H@h /* config GPIO input select */
1483 ori r3,r3,GPIO0_ISR1H@l
1484 lis r4,CFG_GPIO0_ISR1H@h
1485 ori r4,r4,CFG_GPIO0_ISR1H@l
1486 stw r4,0(r3)
1487 lis r3,GPIO0_ISR1L@h
1488 ori r3,r3,GPIO0_ISR1L@l
1489 lis r4,CFG_GPIO0_ISR1L@h
1490 ori r4,r4,CFG_GPIO0_ISR1L@l
1491 stw r4,0(r3)
1492
1493 lis r3,GPIO0_TSRH@h /* config GPIO three-state select */
1494 ori r3,r3,GPIO0_TSRH@l
1495 lis r4,CFG_GPIO0_TSRH@h
1496 ori r4,r4,CFG_GPIO0_TSRH@l
1497 stw r4,0(r3)
1498 lis r3,GPIO0_TSRL@h
1499 ori r3,r3,GPIO0_TSRL@l
1500 lis r4,CFG_GPIO0_TSRL@h
1501 ori r4,r4,CFG_GPIO0_TSRL@l
1502 stw r4,0(r3)
1503
1504 lis r3,GPIO0_TCR@h /* config GPIO driver output enables */
1505 ori r3,r3,GPIO0_TCR@l
1506 lis r4,CFG_GPIO0_TCR@h
1507 ori r4,r4,CFG_GPIO0_TCR@l
1508 stw r4,0(r3)
1509
1510 li r3,pb1ap /* program EBC bank 1 for RTC access */
1511 mtdcr ebccfga,r3
1512 lis r3,CFG_EBC_PB1AP@h
1513 ori r3,r3,CFG_EBC_PB1AP@l
1514 mtdcr ebccfgd,r3
1515 li r3,pb1cr
1516 mtdcr ebccfga,r3
1517 lis r3,CFG_EBC_PB1CR@h
1518 ori r3,r3,CFG_EBC_PB1CR@l
1519 mtdcr ebccfgd,r3
1520
1521 li r3,pb1ap /* program EBC bank 1 for RTC access */
1522 mtdcr ebccfga,r3
1523 lis r3,CFG_EBC_PB1AP@h
1524 ori r3,r3,CFG_EBC_PB1AP@l
1525 mtdcr ebccfgd,r3
1526 li r3,pb1cr
1527 mtdcr ebccfga,r3
1528 lis r3,CFG_EBC_PB1CR@h
1529 ori r3,r3,CFG_EBC_PB1CR@l
1530 mtdcr ebccfgd,r3
1531
1532 li r3,pb4ap /* program EBC bank 4 for FPGA access */
1533 mtdcr ebccfga,r3
1534 lis r3,CFG_EBC_PB4AP@h
1535 ori r3,r3,CFG_EBC_PB4AP@l
1536 mtdcr ebccfgd,r3
1537 li r3,pb4cr
1538 mtdcr ebccfga,r3
1539 lis r3,CFG_EBC_PB4CR@h
1540 ori r3,r3,CFG_EBC_PB4CR@l
1541 mtdcr ebccfgd,r3
1542#endif
1543
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001544 addi r3,0,CPC0_PCI_HOST_CFG_EN
Stefan Roese326c9712005-08-01 16:41:48 +02001545#ifdef CONFIG_BUBINGA
wdenk57b2d802003-06-27 21:31:46 +00001546 /*
1547 !-----------------------------------------------------------------------
1548 ! Check FPGA for PCI internal/external arbitration
1549 ! If board is set to internal arbitration, update cpc0_pci
1550 !-----------------------------------------------------------------------
stroese434979e2003-05-23 11:18:02 +00001551 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001552 addis r5,r0,FPGA_REG1@h /* set offset for FPGA_REG1 */
1553 ori r5,r5,FPGA_REG1@l
1554 lbz r5,0x0(r5) /* read to get PCI arb selection */
1555 andi. r6,r5,FPGA_REG1_PCI_INT_ARB /* using internal arbiter ?*/
1556 beq ..pci_cfg_set /* if not set, then bypass reg write*/
stroese434979e2003-05-23 11:18:02 +00001557#endif
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001558 ori r3,r3,CPC0_PCI_ARBIT_EN
stroese434979e2003-05-23 11:18:02 +00001559..pci_cfg_set:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001560 mtdcr CPC0_PCI, r3 /* Enable internal arbiter*/
stroese434979e2003-05-23 11:18:02 +00001561
wdenk57b2d802003-06-27 21:31:46 +00001562 /*
1563 !-----------------------------------------------------------------------
1564 ! Check to see if chip is in bypass mode.
1565 ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
1566 ! CPU reset Otherwise, skip this step and keep going.
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001567 ! Note: Running BIOS in bypass mode is not supported since PLB speed
1568 ! will not be fast enough for the SDRAM (min 66MHz)
wdenk57b2d802003-06-27 21:31:46 +00001569 !-----------------------------------------------------------------------
stroese434979e2003-05-23 11:18:02 +00001570 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001571 mfdcr r5, CPC0_PLLMR1
1572 rlwinm r4,r5,1,0x1 /* get system clock source (SSCS) */
1573 cmpi cr0,0,r4,0x1
stroese434979e2003-05-23 11:18:02 +00001574
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001575 beq pll_done /* if SSCS =b'1' then PLL has */
wdenk57b2d802003-06-27 21:31:46 +00001576 /* already been set */
1577 /* and CPU has been reset */
1578 /* so skip to next section */
stroese434979e2003-05-23 11:18:02 +00001579
Stefan Roese326c9712005-08-01 16:41:48 +02001580#ifdef CONFIG_BUBINGA
stroese434979e2003-05-23 11:18:02 +00001581 /*
wdenk57b2d802003-06-27 21:31:46 +00001582 !-----------------------------------------------------------------------
1583 ! Read NVRAM to get value to write in PLLMR.
1584 ! If value has not been correctly saved, write default value
1585 ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
1586 ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
1587 !
1588 ! WARNING: This code assumes the first three words in the nvram_t
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001589 ! structure in openbios.h. Changing the beginning of
1590 ! the structure will break this code.
wdenk57b2d802003-06-27 21:31:46 +00001591 !
1592 !-----------------------------------------------------------------------
stroese434979e2003-05-23 11:18:02 +00001593 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001594 addis r3,0,NVRAM_BASE@h
1595 addi r3,r3,NVRAM_BASE@l
stroese434979e2003-05-23 11:18:02 +00001596
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001597 lwz r4, 0(r3)
1598 addis r5,0,NVRVFY1@h
1599 addi r5,r5,NVRVFY1@l
1600 cmp cr0,0,r4,r5 /* Compare 1st NVRAM Magic number*/
1601 bne ..no_pllset
1602 addi r3,r3,4
1603 lwz r4, 0(r3)
1604 addis r5,0,NVRVFY2@h
1605 addi r5,r5,NVRVFY2@l
1606 cmp cr0,0,r4,r5 /* Compare 2 NVRAM Magic number */
1607 bne ..no_pllset
1608 addi r3,r3,8 /* Skip over conf_size */
1609 lwz r4, 4(r3) /* Load PLLMR1 value from NVRAM */
1610 lwz r3, 0(r3) /* Load PLLMR0 value from NVRAM */
1611 rlwinm r5,r4,1,0x1 /* get system clock source (SSCS) */
1612 cmpi cr0,0,r5,1 /* See if PLL is locked */
1613 beq pll_write
stroese434979e2003-05-23 11:18:02 +00001614..no_pllset:
Stefan Roese326c9712005-08-01 16:41:48 +02001615#endif /* CONFIG_BUBINGA */
stroese434979e2003-05-23 11:18:02 +00001616
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001617 addis r3,0,PLLMR0_DEFAULT@h /* PLLMR0 default value */
1618 ori r3,r3,PLLMR0_DEFAULT@l /* */
1619 addis r4,0,PLLMR1_DEFAULT@h /* PLLMR1 default value */
1620 ori r4,r4,PLLMR1_DEFAULT@l /* */
stroese434979e2003-05-23 11:18:02 +00001621
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001622 b pll_write /* Write the CPC0_PLLMR with new value */
stroese434979e2003-05-23 11:18:02 +00001623
1624pll_done:
wdenk57b2d802003-06-27 21:31:46 +00001625 /*
1626 !-----------------------------------------------------------------------
1627 ! Clear Soft Reset Register
1628 ! This is needed to enable PCI if not booting from serial EPROM
1629 !-----------------------------------------------------------------------
stroese434979e2003-05-23 11:18:02 +00001630 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001631 addi r3, 0, 0x0
1632 mtdcr CPC0_SRR, r3
stroese434979e2003-05-23 11:18:02 +00001633
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001634 addis r3,0,0x0010
1635 mtctr r3
stroese434979e2003-05-23 11:18:02 +00001636pci_wait:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001637 bdnz pci_wait
stroese434979e2003-05-23 11:18:02 +00001638
1639 blr /* return to main code */
1640
1641/*
1642!-----------------------------------------------------------------------------
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001643! Function: pll_write
1644! Description: Updates the value of the CPC0_PLLMR according to CMOS27E documentation
1645! That is:
1646! 1. Pll is first disabled (de-activated by putting in bypass mode)
1647! 2. PLL is reset
1648! 3. Clock dividers are set while PLL is held in reset and bypassed
1649! 4. PLL Reset is cleared
1650! 5. Wait 100us for PLL to lock
1651! 6. A core reset is performed
stroese434979e2003-05-23 11:18:02 +00001652! Input: r3 = Value to write to CPC0_PLLMR0
1653! Input: r4 = Value to write to CPC0_PLLMR1
1654! Output r3 = none
1655!-----------------------------------------------------------------------------
1656*/
1657pll_write:
wdenk57b2d802003-06-27 21:31:46 +00001658 mfdcr r5, CPC0_UCR
1659 andis. r5,r5,0xFFFF
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001660 ori r5,r5,0x0101 /* Stop the UART clocks */
1661 mtdcr CPC0_UCR,r5 /* Before changing PLL */
stroese434979e2003-05-23 11:18:02 +00001662
wdenk57b2d802003-06-27 21:31:46 +00001663 mfdcr r5, CPC0_PLLMR1
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001664 rlwinm r5,r5,0,0x7FFFFFFF /* Disable PLL */
1665 mtdcr CPC0_PLLMR1,r5
1666 oris r5,r5,0x4000 /* Set PLL Reset */
1667 mtdcr CPC0_PLLMR1,r5
stroese434979e2003-05-23 11:18:02 +00001668
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001669 mtdcr CPC0_PLLMR0,r3 /* Set clock dividers */
1670 rlwinm r5,r4,0,0x3FFFFFFF /* Reset & Bypass new PLL dividers */
1671 oris r5,r5,0x4000 /* Set PLL Reset */
1672 mtdcr CPC0_PLLMR1,r5 /* Set clock dividers */
1673 rlwinm r5,r5,0,0xBFFFFFFF /* Clear PLL Reset */
1674 mtdcr CPC0_PLLMR1,r5
stroese434979e2003-05-23 11:18:02 +00001675
1676 /*
wdenk57b2d802003-06-27 21:31:46 +00001677 ! Wait min of 100us for PLL to lock.
1678 ! See CMOS 27E databook for more info.
1679 ! At 200MHz, that means waiting 20,000 instructions
stroese434979e2003-05-23 11:18:02 +00001680 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001681 addi r3,0,20000 /* 2000 = 0x4e20 */
1682 mtctr r3
stroese434979e2003-05-23 11:18:02 +00001683pll_wait:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001684 bdnz pll_wait
stroese434979e2003-05-23 11:18:02 +00001685
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001686 oris r5,r5,0x8000 /* Enable PLL */
1687 mtdcr CPC0_PLLMR1,r5 /* Engage */
stroese434979e2003-05-23 11:18:02 +00001688
wdenk57b2d802003-06-27 21:31:46 +00001689 /*
1690 * Reset CPU to guarantee timings are OK
1691 * Not sure if this is needed...
1692 */
1693 addis r3,0,0x1000
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001694 mtspr dbcr0,r3 /* This will cause a CPU core reset, and */
wdenk57b2d802003-06-27 21:31:46 +00001695 /* execution will continue from the poweron */
1696 /* vector of 0xfffffffc */
stroese434979e2003-05-23 11:18:02 +00001697#endif /* CONFIG_405EP */