blob: 647088f721a2eefe0beedce2780d33375a7eac6a [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 Denk0c8721a2005-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
wdenk3b57fe02003-05-30 12:48:29 +0000135 GOT_ENTRY(__init_end)
wdenk0442ed82002-11-03 10:24:00 +0000136 GOT_ENTRY(_end)
wdenk5d232d02003-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 Denkf901a832005-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 Roese6e7fb6e2005-11-29 18:18:21 +0100169#if defined(CONFIG_440GX) || defined(CONFIG_440SP) /* NOTE: 440GX adds machine check status regs */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200170 mtspr mcsrr0,r0
171 mtspr mcsrr1,r0
172 mfspr r1, mcsr
173 mtspr mcsr,r1
wdenkba56f622004-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 Denkf901a832005-08-06 01:42:58 +0200207 li r1,0x0100
wdenk0442ed82002-11-03 10:24:00 +0000208 mtspr ivor0,r1 /* Critical input */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200209 li r1,0x0200
wdenk0442ed82002-11-03 10:24:00 +0000210 mtspr ivor1,r1 /* Machine check */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200211 li r1,0x0300
wdenk0442ed82002-11-03 10:24:00 +0000212 mtspr ivor2,r1 /* Data storage */
Wolfgang Denkf901a832005-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
stroeseb867d702003-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 */
wdenk0442ed82002-11-03 10:24:00 +0000343
344 /*----------------------------------------------------------------*/
345 /* Debug setup -- some (not very good) ice's need an event*/
346 /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
347 /* value you need in this case 0x8cff 0000 should do the trick */
348 /*----------------------------------------------------------------*/
349#if defined(CFG_INIT_DBCR)
350 lis r1,0xffff
351 ori r1,r1,0xffff
352 mtspr dbsr,r1 /* Clear all status bits */
353 lis r0,CFG_INIT_DBCR@h
354 ori r0,r0,CFG_INIT_DBCR@l
355 mtspr dbcr0,r0
356 isync
357#endif
358
359 /*----------------------------------------------------------------*/
360 /* Setup the internal SRAM */
361 /*----------------------------------------------------------------*/
362 li r0,0
Stefan Roese846b0dd2005-08-08 12:42:22 +0200363#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
Stefan Roesec157d8e2005-08-01 16:41:48 +0200364 /* Clear Dcache to use as RAM */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200365 addis r3,r0,CFG_INIT_RAM_ADDR@h
366 ori r3,r3,CFG_INIT_RAM_ADDR@l
367 addis r4,r0,CFG_INIT_RAM_END@h
368 ori r4,r4,CFG_INIT_RAM_END@l
Stefan Roesec157d8e2005-08-01 16:41:48 +0200369 rlwinm. r5,r4,0,27,31
Wolfgang Denkf901a832005-08-06 01:42:58 +0200370 rlwinm r5,r4,27,5,31
371 beq ..d_ran
372 addi r5,r5,0x0001
Stefan Roesec157d8e2005-08-01 16:41:48 +0200373..d_ran:
Wolfgang Denkf901a832005-08-06 01:42:58 +0200374 mtctr r5
Stefan Roesec157d8e2005-08-01 16:41:48 +0200375..d_ag:
Wolfgang Denkf901a832005-08-06 01:42:58 +0200376 dcbz r0,r3
377 addi r3,r3,32
378 bdnz ..d_ag
Stefan Roesec157d8e2005-08-01 16:41:48 +0200379#else
Stefan Roese6e7fb6e2005-11-29 18:18:21 +0100380#if defined (CONFIG_440GX) || defined(CONFIG_440SP)
Wolfgang Denkf901a832005-08-06 01:42:58 +0200381 mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */
wdenkba56f622004-02-06 23:19:44 +0000382#endif
wdenk0442ed82002-11-03 10:24:00 +0000383 mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
384
385 li r2,0x7fff
386 ori r2,r2,0xffff
387 mfdcr r1,isram0_dpc
388 and r1,r1,r2 /* Disable parity check */
389 mtdcr isram0_dpc,r1
390 mfdcr r1,isram0_pmeg
391 andis. r1,r1,r2 /* Disable pwr mgmt */
392 mtdcr isram0_pmeg,r1
393
394 lis r1,0x8000 /* BAS = 8000_0000 */
Stefan Roese6e7fb6e2005-11-29 18:18:21 +0100395#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
wdenkba56f622004-02-06 23:19:44 +0000396 ori r1,r1,0x0980 /* first 64k */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200397 mtdcr isram0_sb0cr,r1
wdenkba56f622004-02-06 23:19:44 +0000398 lis r1,0x8001
399 ori r1,r1,0x0980 /* second 64k */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200400 mtdcr isram0_sb1cr,r1
wdenkba56f622004-02-06 23:19:44 +0000401 lis r1, 0x8002
402 ori r1,r1, 0x0980 /* third 64k */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200403 mtdcr isram0_sb2cr,r1
wdenkba56f622004-02-06 23:19:44 +0000404 lis r1, 0x8003
405 ori r1,r1, 0x0980 /* fourth 64k */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200406 mtdcr isram0_sb3cr,r1
wdenkba56f622004-02-06 23:19:44 +0000407#else
wdenk0442ed82002-11-03 10:24:00 +0000408 ori r1,r1,0x0380 /* 8k rw */
409 mtdcr isram0_sb0cr,r1
wdenkba56f622004-02-06 23:19:44 +0000410#endif
Stefan Roesec157d8e2005-08-01 16:41:48 +0200411#endif
wdenk0442ed82002-11-03 10:24:00 +0000412
413 /*----------------------------------------------------------------*/
414 /* Setup the stack in internal SRAM */
415 /*----------------------------------------------------------------*/
416 lis r1,CFG_INIT_RAM_ADDR@h
417 ori r1,r1,CFG_INIT_SP_OFFSET@l
wdenk0442ed82002-11-03 10:24:00 +0000418 li r0,0
419 stwu r0,-4(r1)
420 stwu r0,-4(r1) /* Terminate call chain */
421
422 stwu r1,-8(r1) /* Save back chain and move SP */
423 lis r0,RESET_VECTOR@h /* Address of reset vector */
424 ori r0,r0, RESET_VECTOR@l
425 stwu r1,-8(r1) /* Save back chain and move SP */
426 stw r0,+12(r1) /* Save return addr (underflow vect) */
427
428 GET_GOT
Stefan Roese5568e612005-11-22 13:20:42 +0100429
430 bl cpu_init_f /* run low-level CPU init code (from Flash) */
wdenk0442ed82002-11-03 10:24:00 +0000431 bl board_init_f
432
433#endif /* CONFIG_440 */
434
435/*****************************************************************************/
436#ifdef CONFIG_IOP480
437 /*----------------------------------------------------------------------- */
438 /* Set up some machine state registers. */
439 /*----------------------------------------------------------------------- */
440 addi r0,r0,0x0000 /* initialize r0 to zero */
441 mtspr esr,r0 /* clear Exception Syndrome Reg */
442 mttcr r0 /* timer control register */
443 mtexier r0 /* disable all interrupts */
wdenk0442ed82002-11-03 10:24:00 +0000444 addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
445 ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
446 mtdbsr r4 /* clear/reset the dbsr */
447 mtexisr r4 /* clear all pending interrupts */
448 addis r4,r0,0x8000
449 mtexier r4 /* enable critical exceptions */
450 addis r4,r0,0x0000 /* assume 403GCX - enable core clk */
451 ori r4,r4,0x4020 /* dbling (no harm done on GA and GC */
452 mtiocr r4 /* since bit not used) & DRC to latch */
453 /* data bus on rising edge of CAS */
454 /*----------------------------------------------------------------------- */
455 /* Clear XER. */
456 /*----------------------------------------------------------------------- */
457 mtxer r0
458 /*----------------------------------------------------------------------- */
459 /* Invalidate i-cache and d-cache TAG arrays. */
460 /*----------------------------------------------------------------------- */
461 addi r3,0,1024 /* 1/4 of I-cache size, half of D-cache */
462 addi r4,0,1024 /* 1/4 of I-cache */
463..cloop:
464 iccci 0,r3
465 iccci r4,r3
466 dccci 0,r3
467 addic. r3,r3,-16 /* move back one cache line */
468 bne ..cloop /* loop back to do rest until r3 = 0 */
469
470 /* */
471 /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
472 /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
473 /* */
474
475 /* first copy IOP480 register base address into r3 */
476 addis r3,0,0x5000 /* IOP480 register base address hi */
477/* ori r3,r3,0x0000 / IOP480 register base address lo */
478
479#ifdef CONFIG_ADCIOP
480 /* use r4 as the working variable */
481 /* turn on CS3 (LOCCTL.7) */
482 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
483 andi. r4,r4,0xff7f /* make bit 7 = 0 -- CS3 mode */
484 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
485#endif
486
487#ifdef CONFIG_DASA_SIM
488 /* use r4 as the working variable */
489 /* turn on MA17 (LOCCTL.7) */
490 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
491 ori r4,r4,0x80 /* make bit 7 = 1 -- MA17 mode */
492 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
493#endif
494
495 /* turn on MA16..13 (LCS0BRD.12 = 0) */
496 lwz r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
497 andi. r4,r4,0xefff /* make bit 12 = 0 */
498 stw r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
499
500 /* make sure above stores all comlete before going on */
501 sync
502
503 /* last thing, set local init status done bit (DEVINIT.31) */
504 lwz r4,0x80(r3) /* DEVINIT is at offset 0x80 */
505 oris r4,r4,0x8000 /* make bit 31 = 1 */
506 stw r4,0x80(r3) /* DEVINIT is at offset 0x80 */
507
508 /* clear all pending interrupts and disable all interrupts */
509 li r4,-1 /* set p1 to 0xffffffff */
510 stw r4,0x1b0(r3) /* clear all pending interrupts */
511 stw r4,0x1b8(r3) /* clear all pending interrupts */
512 li r4,0 /* set r4 to 0 */
513 stw r4,0x1b4(r3) /* disable all interrupts */
514 stw r4,0x1bc(r3) /* disable all interrupts */
515
516 /* make sure above stores all comlete before going on */
517 sync
518
519 /*----------------------------------------------------------------------- */
520 /* Enable two 128MB cachable regions. */
521 /*----------------------------------------------------------------------- */
522 addis r1,r0,0x8000
523 addi r1,r1,0x0001
524 mticcr r1 /* instruction cache */
525
526 addis r1,r0,0x0000
527 addi r1,r1,0x0000
528 mtdccr r1 /* data cache */
529
530 addis r1,r0,CFG_INIT_RAM_ADDR@h
531 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
532 li r0, 0 /* Make room for stack frame header and */
533 stwu r0, -4(r1) /* clear final stack frame so that */
534 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
535
536 GET_GOT /* initialize GOT access */
537
538 bl board_init_f /* run first part of init code (from Flash) */
539
540#endif /* CONFIG_IOP480 */
541
542/*****************************************************************************/
stroeseb867d702003-05-23 11:18:02 +0000543#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_405EP)
wdenk0442ed82002-11-03 10:24:00 +0000544 /*----------------------------------------------------------------------- */
545 /* Clear and set up some registers. */
546 /*----------------------------------------------------------------------- */
547 addi r4,r0,0x0000
548 mtspr sgr,r4
549 mtspr dcwr,r4
550 mtesr r4 /* clear Exception Syndrome Reg */
551 mttcr r4 /* clear Timer Control Reg */
552 mtxer r4 /* clear Fixed-Point Exception Reg */
553 mtevpr r4 /* clear Exception Vector Prefix Reg */
wdenk0442ed82002-11-03 10:24:00 +0000554 addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
555 /* dbsr is cleared by setting bits to 1) */
556 mtdbsr r4 /* clear/reset the dbsr */
557
558 /*----------------------------------------------------------------------- */
559 /* Invalidate I and D caches. Enable I cache for defined memory regions */
560 /* to speed things up. Leave the D cache disabled for now. It will be */
561 /* enabled/left disabled later based on user selected menu options. */
562 /* Be aware that the I cache may be disabled later based on the menu */
563 /* options as well. See miscLib/main.c. */
564 /*----------------------------------------------------------------------- */
565 bl invalidate_icache
566 bl invalidate_dcache
567
568 /*----------------------------------------------------------------------- */
569 /* Enable two 128MB cachable regions. */
570 /*----------------------------------------------------------------------- */
571 addis r4,r0,0x8000
572 addi r4,r4,0x0001
573 mticcr r4 /* instruction cache */
574 isync
575
576 addis r4,r0,0x0000
577 addi r4,r4,0x0000
578 mtdccr r4 /* data cache */
579
580#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
581 /*----------------------------------------------------------------------- */
582 /* Tune the speed and size for flash CS0 */
583 /*----------------------------------------------------------------------- */
584 bl ext_bus_cntlr_init
585#endif
586
stroeseb867d702003-05-23 11:18:02 +0000587#if defined(CONFIG_405EP)
588 /*----------------------------------------------------------------------- */
589 /* DMA Status, clear to come up clean */
590 /*----------------------------------------------------------------------- */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200591 addis r3,r0, 0xFFFF /* Clear all existing DMA status */
592 ori r3,r3, 0xFFFF
593 mtdcr dmasr, r3
stroeseb867d702003-05-23 11:18:02 +0000594
Wolfgang Denkf901a832005-08-06 01:42:58 +0200595 bl ppc405ep_init /* do ppc405ep specific init */
stroeseb867d702003-05-23 11:18:02 +0000596#endif /* CONFIG_405EP */
597
wdenk0442ed82002-11-03 10:24:00 +0000598#if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
599 /********************************************************************
600 * Setup OCM - On Chip Memory
601 *******************************************************************/
602 /* Setup OCM */
wdenk8bde7f72003-06-27 21:31:46 +0000603 lis r0, 0x7FFF
604 ori r0, r0, 0xFFFF
Wolfgang Denkf901a832005-08-06 01:42:58 +0200605 mfdcr r3, ocmiscntl /* get instr-side IRAM config */
wdenk8bde7f72003-06-27 21:31:46 +0000606 mfdcr r4, ocmdscntl /* get data-side IRAM config */
607 and r3, r3, r0 /* disable data-side IRAM */
608 and r4, r4, r0 /* disable data-side IRAM */
609 mtdcr ocmiscntl, r3 /* set instr-side IRAM config */
610 mtdcr ocmdscntl, r4 /* set data-side IRAM config */
611 isync
wdenk0442ed82002-11-03 10:24:00 +0000612
613 addis r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
614 mtdcr ocmdsarc, r3
615 addis r4, 0, 0xC000 /* OCM data area enabled */
616 mtdcr ocmdscntl, r4
wdenk8bde7f72003-06-27 21:31:46 +0000617 isync
wdenk0442ed82002-11-03 10:24:00 +0000618#endif
619
620 /*----------------------------------------------------------------------- */
621 /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
622 /*----------------------------------------------------------------------- */
623#ifdef CFG_INIT_DCACHE_CS
624 /*----------------------------------------------------------------------- */
625 /* Memory Bank x (nothingness) initialization 1GB+64MEG */
626 /* used as temporary stack pointer for stage0 */
627 /*----------------------------------------------------------------------- */
628 li r4,PBxAP
629 mtdcr ebccfga,r4
630 lis r4,0x0380
631 ori r4,r4,0x0480
632 mtdcr ebccfgd,r4
633
634 addi r4,0,PBxCR
635 mtdcr ebccfga,r4
636 lis r4,0x400D
637 ori r4,r4,0xa000
638 mtdcr ebccfgd,r4
639
640 /* turn on data chache for this region */
641 lis r4,0x0080
642 mtdccr r4
643
644 /* set stack pointer and clear stack to known value */
645
646 lis r1,CFG_INIT_RAM_ADDR@h
Wolfgang Denkf901a832005-08-06 01:42:58 +0200647 ori r1,r1,CFG_INIT_SP_OFFSET@l
wdenk0442ed82002-11-03 10:24:00 +0000648
649 li r4,2048 /* we store 2048 words to stack */
650 mtctr r4
651
652 lis r2,CFG_INIT_RAM_ADDR@h /* we also clear data area */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200653 ori r2,r2,CFG_INIT_RAM_END@l /* so cant copy value from r1 */
wdenk0442ed82002-11-03 10:24:00 +0000654
655 lis r4,0xdead /* we store 0xdeaddead in the stack */
656 ori r4,r4,0xdead
657
658..stackloop:
659 stwu r4,-4(r2)
660 bdnz ..stackloop
661
662 li r0, 0 /* Make room for stack frame header and */
663 stwu r0, -4(r1) /* clear final stack frame so that */
664 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
665 /*
666 * Set up a dummy frame to store reset vector as return address.
667 * this causes stack underflow to reset board.
668 */
669 stwu r1, -8(r1) /* Save back chain and move SP */
670 addis r0, 0, RESET_VECTOR@h /* Address of reset vector */
671 ori r0, r0, RESET_VECTOR@l
672 stwu r1, -8(r1) /* Save back chain and move SP */
673 stw r0, +12(r1) /* Save return addr (underflow vect) */
674
675#elif defined(CFG_TEMP_STACK_OCM) && \
676 (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
677 /*
678 * Stack in OCM.
679 */
680
681 /* Set up Stack at top of OCM */
682 lis r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
683 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
684
685 /* Set up a zeroized stack frame so that backtrace works right */
686 li r0, 0
687 stwu r0, -4(r1)
688 stwu r0, -4(r1)
689
690 /*
691 * Set up a dummy frame to store reset vector as return address.
692 * this causes stack underflow to reset board.
693 */
694 stwu r1, -8(r1) /* Save back chain and move SP */
695 lis r0, RESET_VECTOR@h /* Address of reset vector */
696 ori r0, r0, RESET_VECTOR@l
697 stwu r1, -8(r1) /* Save back chain and move SP */
698 stw r0, +12(r1) /* Save return addr (underflow vect) */
699#endif /* CFG_INIT_DCACHE_CS */
700
701 /*----------------------------------------------------------------------- */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200702 /* Initialize SDRAM Controller */
wdenk0442ed82002-11-03 10:24:00 +0000703 /*----------------------------------------------------------------------- */
704 bl sdram_init
705
706 /*
707 * Setup temporary stack pointer only for boards
708 * that do not use SDRAM SPD I2C stuff since it
709 * is already initialized to use DCACHE or OCM
710 * stacks.
711 */
712#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
713 lis r1, CFG_INIT_RAM_ADDR@h
714 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
715
716 li r0, 0 /* Make room for stack frame header and */
717 stwu r0, -4(r1) /* clear final stack frame so that */
718 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
719 /*
720 * Set up a dummy frame to store reset vector as return address.
721 * this causes stack underflow to reset board.
722 */
723 stwu r1, -8(r1) /* Save back chain and move SP */
724 lis r0, RESET_VECTOR@h /* Address of reset vector */
725 ori r0, r0, RESET_VECTOR@l
726 stwu r1, -8(r1) /* Save back chain and move SP */
727 stw r0, +12(r1) /* Save return addr (underflow vect) */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200728#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
wdenk0442ed82002-11-03 10:24:00 +0000729
730 GET_GOT /* initialize GOT access */
731
Wolfgang Denkf901a832005-08-06 01:42:58 +0200732 bl cpu_init_f /* run low-level CPU init code (from Flash) */
wdenk0442ed82002-11-03 10:24:00 +0000733
734 /* NEVER RETURNS! */
735 bl board_init_f /* run first part of init code (from Flash) */
736
wdenk12f34242003-09-02 22:48:03 +0000737#endif /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
738 /*----------------------------------------------------------------------- */
wdenk0442ed82002-11-03 10:24:00 +0000739
740
stroeseb867d702003-05-23 11:18:02 +0000741/*****************************************************************************/
wdenk0442ed82002-11-03 10:24:00 +0000742 .globl _start_of_vectors
743_start_of_vectors:
744
745#if 0
746/*TODO Fixup _start above so we can do this*/
747/* Critical input. */
748 CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
749#endif
750
751/* Machine check */
wdenk2abbe072003-06-16 23:50:08 +0000752 CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
wdenk0442ed82002-11-03 10:24:00 +0000753
754/* Data Storage exception. */
755 STD_EXCEPTION(0x300, DataStorage, UnknownException)
756
757/* Instruction Storage exception. */
758 STD_EXCEPTION(0x400, InstStorage, UnknownException)
759
760/* External Interrupt exception. */
761 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
762
763/* Alignment exception. */
764 . = 0x600
765Alignment:
766 EXCEPTION_PROLOG
767 mfspr r4,DAR
768 stw r4,_DAR(r21)
769 mfspr r5,DSISR
770 stw r5,_DSISR(r21)
771 addi r3,r1,STACK_FRAME_OVERHEAD
772 li r20,MSR_KERNEL
773 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
774 lwz r6,GOT(transfer_to_handler)
775 mtlr r6
776 blrl
777.L_Alignment:
778 .long AlignmentException - _start + EXC_OFF_SYS_RESET
779 .long int_return - _start + EXC_OFF_SYS_RESET
780
781/* Program check exception */
782 . = 0x700
783ProgramCheck:
784 EXCEPTION_PROLOG
785 addi r3,r1,STACK_FRAME_OVERHEAD
786 li r20,MSR_KERNEL
787 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
788 lwz r6,GOT(transfer_to_handler)
789 mtlr r6
790 blrl
791.L_ProgramCheck:
792 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
793 .long int_return - _start + EXC_OFF_SYS_RESET
794
795 /* No FPU on MPC8xx. This exception is not supposed to happen.
796 */
797 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
798
799 /* I guess we could implement decrementer, and may have
800 * to someday for timekeeping.
801 */
802 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
803 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
804 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk27b207f2003-07-24 23:38:38 +0000805 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenk0442ed82002-11-03 10:24:00 +0000806 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
807
808 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
809 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
810
811 /* On the MPC8xx, this is a software emulation interrupt. It occurs
812 * for all unimplemented and illegal instructions.
813 */
814 STD_EXCEPTION(0x1000, PIT, PITException)
815
816 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
817 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
818 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
819 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
820
821 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
822 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
823 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
824 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
825 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
826 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
827 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
828
829 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
830 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
831 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
832 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
833
834 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
835
836 .globl _end_of_vectors
837_end_of_vectors:
838
839
840 . = 0x2100
841
842/*
843 * This code finishes saving the registers to the exception frame
844 * and jumps to the appropriate handler for the exception.
845 * Register r21 is pointer into trap frame, r1 has new stack pointer.
846 */
847 .globl transfer_to_handler
848transfer_to_handler:
849 stw r22,_NIP(r21)
850 lis r22,MSR_POW@h
851 andc r23,r23,r22
852 stw r23,_MSR(r21)
853 SAVE_GPR(7, r21)
854 SAVE_4GPRS(8, r21)
855 SAVE_8GPRS(12, r21)
856 SAVE_8GPRS(24, r21)
857#if 0
858 andi. r23,r23,MSR_PR
859 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
860 beq 2f
861 addi r24,r1,STACK_FRAME_OVERHEAD
862 stw r24,PT_REGS(r23)
8632: addi r2,r23,-TSS /* set r2 to current */
864 tovirt(r2,r2,r23)
865#endif
866 mflr r23
867 andi. r24,r23,0x3f00 /* get vector offset */
868 stw r24,TRAP(r21)
869 li r22,0
870 stw r22,RESULT(r21)
871 mtspr SPRG2,r22 /* r1 is now kernel sp */
872#if 0
873 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
874 cmplw 0,r1,r2
875 cmplw 1,r1,r24
876 crand 1,1,4
877 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
878#endif
879 lwz r24,0(r23) /* virtual address of handler */
880 lwz r23,4(r23) /* where to go when done */
881 mtspr SRR0,r24
882 mtspr SRR1,r20
883 mtlr r23
884 SYNC
885 rfi /* jump to handler, enable MMU */
886
887int_return:
888 mfmsr r28 /* Disable interrupts */
889 li r4,0
890 ori r4,r4,MSR_EE
891 andc r28,r28,r4
892 SYNC /* Some chip revs need this... */
893 mtmsr r28
894 SYNC
895 lwz r2,_CTR(r1)
896 lwz r0,_LINK(r1)
897 mtctr r2
898 mtlr r0
899 lwz r2,_XER(r1)
900 lwz r0,_CCR(r1)
901 mtspr XER,r2
902 mtcrf 0xFF,r0
903 REST_10GPRS(3, r1)
904 REST_10GPRS(13, r1)
905 REST_8GPRS(23, r1)
906 REST_GPR(31, r1)
907 lwz r2,_NIP(r1) /* Restore environment */
908 lwz r0,_MSR(r1)
909 mtspr SRR0,r2
910 mtspr SRR1,r0
911 lwz r0,GPR0(r1)
912 lwz r2,GPR2(r1)
913 lwz r1,GPR1(r1)
914 SYNC
915 rfi
916
917crit_return:
918 mfmsr r28 /* Disable interrupts */
919 li r4,0
920 ori r4,r4,MSR_EE
921 andc r28,r28,r4
922 SYNC /* Some chip revs need this... */
923 mtmsr r28
924 SYNC
925 lwz r2,_CTR(r1)
926 lwz r0,_LINK(r1)
927 mtctr r2
928 mtlr r0
929 lwz r2,_XER(r1)
930 lwz r0,_CCR(r1)
931 mtspr XER,r2
932 mtcrf 0xFF,r0
933 REST_10GPRS(3, r1)
934 REST_10GPRS(13, r1)
935 REST_8GPRS(23, r1)
936 REST_GPR(31, r1)
937 lwz r2,_NIP(r1) /* Restore environment */
938 lwz r0,_MSR(r1)
939 mtspr 990,r2 /* SRR2 */
940 mtspr 991,r0 /* SRR3 */
941 lwz r0,GPR0(r1)
942 lwz r2,GPR2(r1)
943 lwz r1,GPR1(r1)
944 SYNC
945 rfci
946
947/* Cache functions.
948*/
949invalidate_icache:
950 iccci r0,r0 /* for 405, iccci invalidates the */
951 blr /* entire I cache */
952
953invalidate_dcache:
954 addi r6,0,0x0000 /* clear GPR 6 */
955 /* Do loop for # of dcache congruence classes. */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200956 lis r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS for large sized cache */
957 ori r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
wdenk0442ed82002-11-03 10:24:00 +0000958 /* NOTE: dccci invalidates both */
959 mtctr r7 /* ways in the D cache */
960..dcloop:
961 dccci 0,r6 /* invalidate line */
962 addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
963 bdnz ..dcloop
964 blr
965
966flush_dcache:
967 addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
968 ori r9,r9,0x8000
969 mfmsr r12 /* save msr */
970 andc r9,r12,r9
971 mtmsr r9 /* disable EE and CE */
972 addi r10,r0,0x0001 /* enable data cache for unused memory */
973 mfdccr r9 /* region 0xF8000000-0xFFFFFFFF via */
974 or r10,r10,r9 /* bit 31 in dccr */
975 mtdccr r10
976
977 /* do loop for # of congruence classes. */
Wolfgang Denkf901a832005-08-06 01:42:58 +0200978 lis r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS: for large cache sizes */
979 ori r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
980 lis r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */
981 ori r11,r11,(CFG_DCACHE_SIZE / 2)@l /* D cache set size - 2 way sets */
wdenk0442ed82002-11-03 10:24:00 +0000982 mtctr r10
Wolfgang Denkf901a832005-08-06 01:42:58 +0200983 addi r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
wdenk0442ed82002-11-03 10:24:00 +0000984 add r11,r10,r11 /* add to get to other side of cache line */
985..flush_dcache_loop:
986 lwz r3,0(r10) /* least recently used side */
987 lwz r3,0(r11) /* the other side */
988 dccci r0,r11 /* invalidate both sides */
989 addi r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
990 addi r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
991 bdnz ..flush_dcache_loop
992 sync /* allow memory access to complete */
993 mtdccr r9 /* restore dccr */
994 mtmsr r12 /* restore msr */
995 blr
996
997 .globl icache_enable
998icache_enable:
999 mflr r8
1000 bl invalidate_icache
1001 mtlr r8
1002 isync
1003 addis r3,r0, 0x8000 /* set bit 0 */
1004 mticcr r3
1005 blr
1006
1007 .globl icache_disable
1008icache_disable:
1009 addis r3,r0, 0x0000 /* clear bit 0 */
1010 mticcr r3
1011 isync
1012 blr
1013
1014 .globl icache_status
1015icache_status:
1016 mficcr r3
1017 srwi r3, r3, 31 /* >>31 => select bit 0 */
1018 blr
1019
1020 .globl dcache_enable
1021dcache_enable:
1022 mflr r8
1023 bl invalidate_dcache
1024 mtlr r8
1025 isync
1026 addis r3,r0, 0x8000 /* set bit 0 */
1027 mtdccr r3
1028 blr
1029
1030 .globl dcache_disable
1031dcache_disable:
1032 mflr r8
1033 bl flush_dcache
1034 mtlr r8
1035 addis r3,r0, 0x0000 /* clear bit 0 */
1036 mtdccr r3
1037 blr
1038
1039 .globl dcache_status
1040dcache_status:
1041 mfdccr r3
1042 srwi r3, r3, 31 /* >>31 => select bit 0 */
1043 blr
1044
1045 .globl get_pvr
1046get_pvr:
1047 mfspr r3, PVR
1048 blr
1049
1050#if !defined(CONFIG_440)
1051 .globl wr_pit
1052wr_pit:
1053 mtspr pit, r3
1054 blr
1055#endif
1056
1057 .globl wr_tcr
1058wr_tcr:
1059 mtspr tcr, r3
1060 blr
1061
1062/*------------------------------------------------------------------------------- */
1063/* Function: in8 */
1064/* Description: Input 8 bits */
1065/*------------------------------------------------------------------------------- */
1066 .globl in8
1067in8:
1068 lbz r3,0x0000(r3)
1069 blr
1070
1071/*------------------------------------------------------------------------------- */
1072/* Function: out8 */
1073/* Description: Output 8 bits */
1074/*------------------------------------------------------------------------------- */
1075 .globl out8
1076out8:
1077 stb r4,0x0000(r3)
1078 blr
1079
1080/*------------------------------------------------------------------------------- */
1081/* Function: out16 */
1082/* Description: Output 16 bits */
1083/*------------------------------------------------------------------------------- */
1084 .globl out16
1085out16:
1086 sth r4,0x0000(r3)
1087 blr
1088
1089/*------------------------------------------------------------------------------- */
1090/* Function: out16r */
1091/* Description: Byte reverse and output 16 bits */
1092/*------------------------------------------------------------------------------- */
1093 .globl out16r
1094out16r:
1095 sthbrx r4,r0,r3
1096 blr
1097
1098/*------------------------------------------------------------------------------- */
1099/* Function: out32 */
1100/* Description: Output 32 bits */
1101/*------------------------------------------------------------------------------- */
1102 .globl out32
1103out32:
1104 stw r4,0x0000(r3)
1105 blr
1106
1107/*------------------------------------------------------------------------------- */
1108/* Function: out32r */
1109/* Description: Byte reverse and output 32 bits */
1110/*------------------------------------------------------------------------------- */
1111 .globl out32r
1112out32r:
1113 stwbrx r4,r0,r3
1114 blr
1115
1116/*------------------------------------------------------------------------------- */
1117/* Function: in16 */
1118/* Description: Input 16 bits */
1119/*------------------------------------------------------------------------------- */
1120 .globl in16
1121in16:
1122 lhz r3,0x0000(r3)
1123 blr
1124
1125/*------------------------------------------------------------------------------- */
1126/* Function: in16r */
1127/* Description: Input 16 bits and byte reverse */
1128/*------------------------------------------------------------------------------- */
1129 .globl in16r
1130in16r:
1131 lhbrx r3,r0,r3
1132 blr
1133
1134/*------------------------------------------------------------------------------- */
1135/* Function: in32 */
1136/* Description: Input 32 bits */
1137/*------------------------------------------------------------------------------- */
1138 .globl in32
1139in32:
1140 lwz 3,0x0000(3)
1141 blr
1142
1143/*------------------------------------------------------------------------------- */
1144/* Function: in32r */
1145/* Description: Input 32 bits and byte reverse */
1146/*------------------------------------------------------------------------------- */
1147 .globl in32r
1148in32r:
1149 lwbrx r3,r0,r3
1150 blr
1151
1152/*------------------------------------------------------------------------------- */
1153/* Function: ppcDcbf */
1154/* Description: Data Cache block flush */
1155/* Input: r3 = effective address */
1156/* Output: none. */
1157/*------------------------------------------------------------------------------- */
1158 .globl ppcDcbf
1159ppcDcbf:
1160 dcbf r0,r3
1161 blr
1162
1163/*------------------------------------------------------------------------------- */
1164/* Function: ppcDcbi */
1165/* Description: Data Cache block Invalidate */
1166/* Input: r3 = effective address */
1167/* Output: none. */
1168/*------------------------------------------------------------------------------- */
1169 .globl ppcDcbi
1170ppcDcbi:
1171 dcbi r0,r3
1172 blr
1173
1174/*------------------------------------------------------------------------------- */
1175/* Function: ppcSync */
1176/* Description: Processor Synchronize */
1177/* Input: none. */
1178/* Output: none. */
1179/*------------------------------------------------------------------------------- */
1180 .globl ppcSync
1181ppcSync:
1182 sync
1183 blr
1184
1185/*------------------------------------------------------------------------------*/
1186
1187/*
1188 * void relocate_code (addr_sp, gd, addr_moni)
1189 *
1190 * This "function" does not return, instead it continues in RAM
1191 * after relocating the monitor code.
1192 *
1193 * r3 = dest
1194 * r4 = src
1195 * r5 = length in bytes
1196 * r6 = cachelinesize
1197 */
1198 .globl relocate_code
1199relocate_code:
Stefan Roese846b0dd2005-08-08 12:42:22 +02001200#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
Stefan Roesea4c8d132006-06-02 16:18:04 +02001201 /*
1202 * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
1203 * to speed up the boot process. Now this cache needs to be disabled.
1204 */
1205 iccci 0,0 /* Invalidate inst cache */
1206 dccci 0,0 /* Invalidate data cache, now no longer our stack */
Stefan Roesec157d8e2005-08-01 16:41:48 +02001207 sync
Stefan Roesea4c8d132006-06-02 16:18:04 +02001208 isync
Stefan Roese6e7fb6e2005-11-29 18:18:21 +01001209 addi r1,r0,0x0000 /* TLB entry #0 */
Stefan Roesec157d8e2005-08-01 16:41:48 +02001210 tlbre r0,r1,0x0002 /* Read contents */
Stefan Roese6e7fb6e2005-11-29 18:18:21 +01001211 ori r0,r0,0x0c00 /* Or in the inhibit, write through bit */
Wolfgang Denkf901a832005-08-06 01:42:58 +02001212 tlbwe r0,r1,0x0002 /* Save it out */
Stefan Roesea4c8d132006-06-02 16:18:04 +02001213 sync
Stefan Roesec157d8e2005-08-01 16:41:48 +02001214 isync
1215#endif
wdenk0442ed82002-11-03 10:24:00 +00001216 mr r1, r3 /* Set new stack pointer */
1217 mr r9, r4 /* Save copy of Init Data pointer */
1218 mr r10, r5 /* Save copy of Destination Address */
1219
1220 mr r3, r5 /* Destination Address */
1221 lis r4, CFG_MONITOR_BASE@h /* Source Address */
1222 ori r4, r4, CFG_MONITOR_BASE@l
wdenk3b57fe02003-05-30 12:48:29 +00001223 lwz r5, GOT(__init_end)
1224 sub r5, r5, r4
wdenk0442ed82002-11-03 10:24:00 +00001225 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
1226
1227 /*
1228 * Fix GOT pointer:
1229 *
1230 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1231 *
1232 * Offset:
1233 */
1234 sub r15, r10, r4
1235
1236 /* First our own GOT */
1237 add r14, r14, r15
1238 /* the the one used by the C code */
1239 add r30, r30, r15
1240
1241 /*
1242 * Now relocate code
1243 */
1244
1245 cmplw cr1,r3,r4
1246 addi r0,r5,3
1247 srwi. r0,r0,2
1248 beq cr1,4f /* In place copy is not necessary */
1249 beq 7f /* Protect against 0 count */
1250 mtctr r0
1251 bge cr1,2f
1252
1253 la r8,-4(r4)
1254 la r7,-4(r3)
12551: lwzu r0,4(r8)
1256 stwu r0,4(r7)
1257 bdnz 1b
1258 b 4f
1259
12602: slwi r0,r0,2
1261 add r8,r4,r0
1262 add r7,r3,r0
12633: lwzu r0,-4(r8)
1264 stwu r0,-4(r7)
1265 bdnz 3b
1266
1267/*
1268 * Now flush the cache: note that we must start from a cache aligned
1269 * address. Otherwise we might miss one cache line.
1270 */
12714: cmpwi r6,0
1272 add r5,r3,r5
1273 beq 7f /* Always flush prefetch queue in any case */
1274 subi r0,r6,1
1275 andc r3,r3,r0
1276 mr r4,r3
12775: dcbst 0,r4
1278 add r4,r4,r6
1279 cmplw r4,r5
1280 blt 5b
1281 sync /* Wait for all dcbst to complete on bus */
1282 mr r4,r3
12836: icbi 0,r4
1284 add r4,r4,r6
1285 cmplw r4,r5
1286 blt 6b
12877: sync /* Wait for all icbi to complete on bus */
1288 isync
1289
1290/*
1291 * We are done. Do not return, instead branch to second part of board
1292 * initialization, now running from RAM.
1293 */
1294
1295 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1296 mtlr r0
1297 blr /* NEVER RETURNS! */
1298
1299in_ram:
1300
1301 /*
1302 * Relocation Function, r14 point to got2+0x8000
1303 *
1304 * Adjust got2 pointers, no need to check for 0, this code
1305 * already puts a few entries in the table.
1306 */
1307 li r0,__got2_entries@sectoff@l
1308 la r3,GOT(_GOT2_TABLE_)
1309 lwz r11,GOT(_GOT2_TABLE_)
1310 mtctr r0
1311 sub r11,r3,r11
1312 addi r3,r3,-4
13131: lwzu r0,4(r3)
1314 add r0,r0,r11
1315 stw r0,0(r3)
1316 bdnz 1b
1317
1318 /*
1319 * Now adjust the fixups and the pointers to the fixups
1320 * in case we need to move ourselves again.
1321 */
13222: li r0,__fixup_entries@sectoff@l
1323 lwz r3,GOT(_FIXUP_TABLE_)
1324 cmpwi r0,0
1325 mtctr r0
1326 addi r3,r3,-4
1327 beq 4f
13283: lwzu r4,4(r3)
1329 lwzux r0,r4,r11
1330 add r0,r0,r11
1331 stw r10,0(r3)
1332 stw r0,0(r4)
1333 bdnz 3b
13344:
1335clear_bss:
1336 /*
1337 * Now clear BSS segment
1338 */
wdenk5d232d02003-05-22 22:52:13 +00001339 lwz r3,GOT(__bss_start)
wdenk0442ed82002-11-03 10:24:00 +00001340 lwz r4,GOT(_end)
1341
1342 cmplw 0, r3, r4
1343 beq 6f
1344
1345 li r0, 0
13465:
1347 stw r0, 0(r3)
1348 addi r3, r3, 4
1349 cmplw 0, r3, r4
1350 bne 5b
13516:
1352
1353 mr r3, r9 /* Init Data pointer */
1354 mr r4, r10 /* Destination Address */
1355 bl board_init_r
1356
wdenk0442ed82002-11-03 10:24:00 +00001357 /*
1358 * Copy exception vector code to low memory
1359 *
1360 * r3: dest_addr
1361 * r7: source address, r8: end address, r9: target address
1362 */
1363 .globl trap_init
1364trap_init:
1365 lwz r7, GOT(_start)
1366 lwz r8, GOT(_end_of_vectors)
1367
wdenk682011f2003-06-03 23:54:09 +00001368 li r9, 0x100 /* reset vector always at 0x100 */
wdenk0442ed82002-11-03 10:24:00 +00001369
1370 cmplw 0, r7, r8
1371 bgelr /* return if r7>=r8 - just in case */
1372
1373 mflr r4 /* save link register */
13741:
1375 lwz r0, 0(r7)
1376 stw r0, 0(r9)
1377 addi r7, r7, 4
1378 addi r9, r9, 4
1379 cmplw 0, r7, r8
1380 bne 1b
1381
1382 /*
1383 * relocate `hdlr' and `int_return' entries
1384 */
1385 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1386 li r8, Alignment - _start + EXC_OFF_SYS_RESET
13872:
1388 bl trap_reloc
1389 addi r7, r7, 0x100 /* next exception vector */
1390 cmplw 0, r7, r8
1391 blt 2b
1392
1393 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1394 bl trap_reloc
1395
1396 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1397 bl trap_reloc
1398
1399 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1400 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
14013:
1402 bl trap_reloc
1403 addi r7, r7, 0x100 /* next exception vector */
1404 cmplw 0, r7, r8
1405 blt 3b
1406
1407 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1408 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
14094:
1410 bl trap_reloc
1411 addi r7, r7, 0x100 /* next exception vector */
1412 cmplw 0, r7, r8
1413 blt 4b
1414
Stefan Roese9a7b4082006-03-13 09:42:28 +01001415#if !defined(CONFIG_440_GX)
1416 addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
1417 oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
1418 mtmsr r7 /* change MSR */
1419#else
1420 bl __440gx_msr_set
1421 b __440gx_msr_continue
1422
1423__440gx_msr_set:
1424 addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
1425 oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
1426 mtspr srr1,r7
1427 mflr r7
1428 mtspr srr0,r7
1429 rfi
1430__440gx_msr_continue:
1431#endif
1432
wdenk0442ed82002-11-03 10:24:00 +00001433 mtlr r4 /* restore link register */
1434 blr
1435
1436 /*
1437 * Function: relocate entries for one exception vector
1438 */
1439trap_reloc:
1440 lwz r0, 0(r7) /* hdlr ... */
1441 add r0, r0, r3 /* ... += dest_addr */
1442 stw r0, 0(r7)
1443
1444 lwz r0, 4(r7) /* int_return ... */
1445 add r0, r0, r3 /* ... += dest_addr */
1446 stw r0, 4(r7)
1447
1448 blr
stroeseb867d702003-05-23 11:18:02 +00001449
1450
1451/**************************************************************************/
Wolfgang Denkf901a832005-08-06 01:42:58 +02001452/* PPC405EP specific stuff */
stroeseb867d702003-05-23 11:18:02 +00001453/**************************************************************************/
1454#ifdef CONFIG_405EP
1455ppc405ep_init:
stroeseb828dda2003-12-09 14:54:43 +00001456
Stefan Roesec157d8e2005-08-01 16:41:48 +02001457#ifdef CONFIG_BUBINGA
stroeseb828dda2003-12-09 14:54:43 +00001458 /*
1459 * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
1460 * function) to support FPGA and NVRAM accesses below.
1461 */
1462
1463 lis r3,GPIO0_OSRH@h /* config GPIO output select */
1464 ori r3,r3,GPIO0_OSRH@l
1465 lis r4,CFG_GPIO0_OSRH@h
1466 ori r4,r4,CFG_GPIO0_OSRH@l
1467 stw r4,0(r3)
1468 lis r3,GPIO0_OSRL@h
1469 ori r3,r3,GPIO0_OSRL@l
1470 lis r4,CFG_GPIO0_OSRL@h
1471 ori r4,r4,CFG_GPIO0_OSRL@l
1472 stw r4,0(r3)
1473
1474 lis r3,GPIO0_ISR1H@h /* config GPIO input select */
1475 ori r3,r3,GPIO0_ISR1H@l
1476 lis r4,CFG_GPIO0_ISR1H@h
1477 ori r4,r4,CFG_GPIO0_ISR1H@l
1478 stw r4,0(r3)
1479 lis r3,GPIO0_ISR1L@h
1480 ori r3,r3,GPIO0_ISR1L@l
1481 lis r4,CFG_GPIO0_ISR1L@h
1482 ori r4,r4,CFG_GPIO0_ISR1L@l
1483 stw r4,0(r3)
1484
1485 lis r3,GPIO0_TSRH@h /* config GPIO three-state select */
1486 ori r3,r3,GPIO0_TSRH@l
1487 lis r4,CFG_GPIO0_TSRH@h
1488 ori r4,r4,CFG_GPIO0_TSRH@l
1489 stw r4,0(r3)
1490 lis r3,GPIO0_TSRL@h
1491 ori r3,r3,GPIO0_TSRL@l
1492 lis r4,CFG_GPIO0_TSRL@h
1493 ori r4,r4,CFG_GPIO0_TSRL@l
1494 stw r4,0(r3)
1495
1496 lis r3,GPIO0_TCR@h /* config GPIO driver output enables */
1497 ori r3,r3,GPIO0_TCR@l
1498 lis r4,CFG_GPIO0_TCR@h
1499 ori r4,r4,CFG_GPIO0_TCR@l
1500 stw r4,0(r3)
1501
1502 li r3,pb1ap /* program EBC bank 1 for RTC access */
1503 mtdcr ebccfga,r3
1504 lis r3,CFG_EBC_PB1AP@h
1505 ori r3,r3,CFG_EBC_PB1AP@l
1506 mtdcr ebccfgd,r3
1507 li r3,pb1cr
1508 mtdcr ebccfga,r3
1509 lis r3,CFG_EBC_PB1CR@h
1510 ori r3,r3,CFG_EBC_PB1CR@l
1511 mtdcr ebccfgd,r3
1512
1513 li r3,pb1ap /* program EBC bank 1 for RTC access */
1514 mtdcr ebccfga,r3
1515 lis r3,CFG_EBC_PB1AP@h
1516 ori r3,r3,CFG_EBC_PB1AP@l
1517 mtdcr ebccfgd,r3
1518 li r3,pb1cr
1519 mtdcr ebccfga,r3
1520 lis r3,CFG_EBC_PB1CR@h
1521 ori r3,r3,CFG_EBC_PB1CR@l
1522 mtdcr ebccfgd,r3
1523
1524 li r3,pb4ap /* program EBC bank 4 for FPGA access */
1525 mtdcr ebccfga,r3
1526 lis r3,CFG_EBC_PB4AP@h
1527 ori r3,r3,CFG_EBC_PB4AP@l
1528 mtdcr ebccfgd,r3
1529 li r3,pb4cr
1530 mtdcr ebccfga,r3
1531 lis r3,CFG_EBC_PB4CR@h
1532 ori r3,r3,CFG_EBC_PB4CR@l
1533 mtdcr ebccfgd,r3
1534#endif
1535
Wolfgang Denkf901a832005-08-06 01:42:58 +02001536 addi r3,0,CPC0_PCI_HOST_CFG_EN
Stefan Roesec157d8e2005-08-01 16:41:48 +02001537#ifdef CONFIG_BUBINGA
wdenk8bde7f72003-06-27 21:31:46 +00001538 /*
1539 !-----------------------------------------------------------------------
1540 ! Check FPGA for PCI internal/external arbitration
1541 ! If board is set to internal arbitration, update cpc0_pci
1542 !-----------------------------------------------------------------------
stroeseb867d702003-05-23 11:18:02 +00001543 */
Wolfgang Denkf901a832005-08-06 01:42:58 +02001544 addis r5,r0,FPGA_REG1@h /* set offset for FPGA_REG1 */
1545 ori r5,r5,FPGA_REG1@l
1546 lbz r5,0x0(r5) /* read to get PCI arb selection */
1547 andi. r6,r5,FPGA_REG1_PCI_INT_ARB /* using internal arbiter ?*/
1548 beq ..pci_cfg_set /* if not set, then bypass reg write*/
stroeseb867d702003-05-23 11:18:02 +00001549#endif
Wolfgang Denkf901a832005-08-06 01:42:58 +02001550 ori r3,r3,CPC0_PCI_ARBIT_EN
stroeseb867d702003-05-23 11:18:02 +00001551..pci_cfg_set:
Wolfgang Denkf901a832005-08-06 01:42:58 +02001552 mtdcr CPC0_PCI, r3 /* Enable internal arbiter*/
stroeseb867d702003-05-23 11:18:02 +00001553
wdenk8bde7f72003-06-27 21:31:46 +00001554 /*
1555 !-----------------------------------------------------------------------
1556 ! Check to see if chip is in bypass mode.
1557 ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
1558 ! CPU reset Otherwise, skip this step and keep going.
Wolfgang Denkf901a832005-08-06 01:42:58 +02001559 ! Note: Running BIOS in bypass mode is not supported since PLB speed
1560 ! will not be fast enough for the SDRAM (min 66MHz)
wdenk8bde7f72003-06-27 21:31:46 +00001561 !-----------------------------------------------------------------------
stroeseb867d702003-05-23 11:18:02 +00001562 */
Wolfgang Denkf901a832005-08-06 01:42:58 +02001563 mfdcr r5, CPC0_PLLMR1
1564 rlwinm r4,r5,1,0x1 /* get system clock source (SSCS) */
1565 cmpi cr0,0,r4,0x1
stroeseb867d702003-05-23 11:18:02 +00001566
Wolfgang Denkf901a832005-08-06 01:42:58 +02001567 beq pll_done /* if SSCS =b'1' then PLL has */
wdenk8bde7f72003-06-27 21:31:46 +00001568 /* already been set */
1569 /* and CPU has been reset */
1570 /* so skip to next section */
stroeseb867d702003-05-23 11:18:02 +00001571
Stefan Roesec157d8e2005-08-01 16:41:48 +02001572#ifdef CONFIG_BUBINGA
stroeseb867d702003-05-23 11:18:02 +00001573 /*
wdenk8bde7f72003-06-27 21:31:46 +00001574 !-----------------------------------------------------------------------
1575 ! Read NVRAM to get value to write in PLLMR.
1576 ! If value has not been correctly saved, write default value
1577 ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
1578 ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
1579 !
1580 ! WARNING: This code assumes the first three words in the nvram_t
Wolfgang Denkf901a832005-08-06 01:42:58 +02001581 ! structure in openbios.h. Changing the beginning of
1582 ! the structure will break this code.
wdenk8bde7f72003-06-27 21:31:46 +00001583 !
1584 !-----------------------------------------------------------------------
stroeseb867d702003-05-23 11:18:02 +00001585 */
Wolfgang Denkf901a832005-08-06 01:42:58 +02001586 addis r3,0,NVRAM_BASE@h
1587 addi r3,r3,NVRAM_BASE@l
stroeseb867d702003-05-23 11:18:02 +00001588
Wolfgang Denkf901a832005-08-06 01:42:58 +02001589 lwz r4, 0(r3)
1590 addis r5,0,NVRVFY1@h
1591 addi r5,r5,NVRVFY1@l
1592 cmp cr0,0,r4,r5 /* Compare 1st NVRAM Magic number*/
1593 bne ..no_pllset
1594 addi r3,r3,4
1595 lwz r4, 0(r3)
1596 addis r5,0,NVRVFY2@h
1597 addi r5,r5,NVRVFY2@l
1598 cmp cr0,0,r4,r5 /* Compare 2 NVRAM Magic number */
1599 bne ..no_pllset
1600 addi r3,r3,8 /* Skip over conf_size */
1601 lwz r4, 4(r3) /* Load PLLMR1 value from NVRAM */
1602 lwz r3, 0(r3) /* Load PLLMR0 value from NVRAM */
1603 rlwinm r5,r4,1,0x1 /* get system clock source (SSCS) */
1604 cmpi cr0,0,r5,1 /* See if PLL is locked */
1605 beq pll_write
stroeseb867d702003-05-23 11:18:02 +00001606..no_pllset:
Stefan Roesec157d8e2005-08-01 16:41:48 +02001607#endif /* CONFIG_BUBINGA */
stroeseb867d702003-05-23 11:18:02 +00001608
Wolfgang Denkf901a832005-08-06 01:42:58 +02001609 addis r3,0,PLLMR0_DEFAULT@h /* PLLMR0 default value */
1610 ori r3,r3,PLLMR0_DEFAULT@l /* */
1611 addis r4,0,PLLMR1_DEFAULT@h /* PLLMR1 default value */
1612 ori r4,r4,PLLMR1_DEFAULT@l /* */
stroeseb867d702003-05-23 11:18:02 +00001613
Wolfgang Denkf901a832005-08-06 01:42:58 +02001614 b pll_write /* Write the CPC0_PLLMR with new value */
stroeseb867d702003-05-23 11:18:02 +00001615
1616pll_done:
wdenk8bde7f72003-06-27 21:31:46 +00001617 /*
1618 !-----------------------------------------------------------------------
1619 ! Clear Soft Reset Register
1620 ! This is needed to enable PCI if not booting from serial EPROM
1621 !-----------------------------------------------------------------------
stroeseb867d702003-05-23 11:18:02 +00001622 */
Wolfgang Denkf901a832005-08-06 01:42:58 +02001623 addi r3, 0, 0x0
1624 mtdcr CPC0_SRR, r3
stroeseb867d702003-05-23 11:18:02 +00001625
Wolfgang Denkf901a832005-08-06 01:42:58 +02001626 addis r3,0,0x0010
1627 mtctr r3
stroeseb867d702003-05-23 11:18:02 +00001628pci_wait:
Wolfgang Denkf901a832005-08-06 01:42:58 +02001629 bdnz pci_wait
stroeseb867d702003-05-23 11:18:02 +00001630
1631 blr /* return to main code */
1632
1633/*
1634!-----------------------------------------------------------------------------
Wolfgang Denkf901a832005-08-06 01:42:58 +02001635! Function: pll_write
1636! Description: Updates the value of the CPC0_PLLMR according to CMOS27E documentation
1637! That is:
1638! 1. Pll is first disabled (de-activated by putting in bypass mode)
1639! 2. PLL is reset
1640! 3. Clock dividers are set while PLL is held in reset and bypassed
1641! 4. PLL Reset is cleared
1642! 5. Wait 100us for PLL to lock
1643! 6. A core reset is performed
stroeseb867d702003-05-23 11:18:02 +00001644! Input: r3 = Value to write to CPC0_PLLMR0
1645! Input: r4 = Value to write to CPC0_PLLMR1
1646! Output r3 = none
1647!-----------------------------------------------------------------------------
1648*/
1649pll_write:
wdenk8bde7f72003-06-27 21:31:46 +00001650 mfdcr r5, CPC0_UCR
1651 andis. r5,r5,0xFFFF
Wolfgang Denkf901a832005-08-06 01:42:58 +02001652 ori r5,r5,0x0101 /* Stop the UART clocks */
1653 mtdcr CPC0_UCR,r5 /* Before changing PLL */
stroeseb867d702003-05-23 11:18:02 +00001654
wdenk8bde7f72003-06-27 21:31:46 +00001655 mfdcr r5, CPC0_PLLMR1
Wolfgang Denkf901a832005-08-06 01:42:58 +02001656 rlwinm r5,r5,0,0x7FFFFFFF /* Disable PLL */
1657 mtdcr CPC0_PLLMR1,r5
1658 oris r5,r5,0x4000 /* Set PLL Reset */
1659 mtdcr CPC0_PLLMR1,r5
stroeseb867d702003-05-23 11:18:02 +00001660
Wolfgang Denkf901a832005-08-06 01:42:58 +02001661 mtdcr CPC0_PLLMR0,r3 /* Set clock dividers */
1662 rlwinm r5,r4,0,0x3FFFFFFF /* Reset & Bypass new PLL dividers */
1663 oris r5,r5,0x4000 /* Set PLL Reset */
1664 mtdcr CPC0_PLLMR1,r5 /* Set clock dividers */
1665 rlwinm r5,r5,0,0xBFFFFFFF /* Clear PLL Reset */
1666 mtdcr CPC0_PLLMR1,r5
stroeseb867d702003-05-23 11:18:02 +00001667
1668 /*
wdenk8bde7f72003-06-27 21:31:46 +00001669 ! Wait min of 100us for PLL to lock.
1670 ! See CMOS 27E databook for more info.
1671 ! At 200MHz, that means waiting 20,000 instructions
stroeseb867d702003-05-23 11:18:02 +00001672 */
Wolfgang Denkf901a832005-08-06 01:42:58 +02001673 addi r3,0,20000 /* 2000 = 0x4e20 */
1674 mtctr r3
stroeseb867d702003-05-23 11:18:02 +00001675pll_wait:
Wolfgang Denkf901a832005-08-06 01:42:58 +02001676 bdnz pll_wait
stroeseb867d702003-05-23 11:18:02 +00001677
Wolfgang Denkf901a832005-08-06 01:42:58 +02001678 oris r5,r5,0x8000 /* Enable PLL */
1679 mtdcr CPC0_PLLMR1,r5 /* Engage */
stroeseb867d702003-05-23 11:18:02 +00001680
wdenk8bde7f72003-06-27 21:31:46 +00001681 /*
1682 * Reset CPU to guarantee timings are OK
1683 * Not sure if this is needed...
1684 */
1685 addis r3,0,0x1000
Wolfgang Denkf901a832005-08-06 01:42:58 +02001686 mtspr dbcr0,r3 /* This will cause a CPU core reset, and */
wdenk8bde7f72003-06-27 21:31:46 +00001687 /* execution will continue from the poweron */
1688 /* vector of 0xfffffffc */
stroeseb867d702003-05-23 11:18:02 +00001689#endif /* CONFIG_405EP */