blob: 2a9b33e12cafa43ace68d77c003e53b85b8833e9 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * (C) Copyright 2001 ELTEC Elektronik AG
3 * Frank Gottschling <fgottschling@eltec.de>
4 *
5 * ELTEC BAB PPC RAM initialization
6 *
7 * See file CREDITS for list of people who contributed to this
8 * project.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 */
25
26#include <config.h>
Wolfgang Denk47f57792005-08-08 01:03:24 +020027#include <asm/processor.h>
wdenk9dd2b882002-12-03 21:28:10 +000028#include <74xx_7xx.h>
wdenkc6097192002-11-03 00:24:07 +000029#include <mpc106.h>
30#include <version.h>
31
32#include <ppc_asm.tmpl>
33#include <ppc_defs.h>
34
35/*
36 * This following contains the entry code for the initialization code
37 * for the MPC 106, a PCI Bridge/Memory Controller.
38 * Register usage:
39 * r0 = ramtest scratch register, toggleError loop counter
40 * r1 = 0xfec0 0cf8 CONFIG_ADDRESS
41 * r2 = 0xfee0 0cfc CONFIG_DATA
42 * r3 = scratch register, subroutine argument and return value, ramtest size
43 * r4 = scratch register, spdRead clock mask, OutHex loop count
44 * r5 = ramtest scratch register
45 * r6 = toggleError 1st value, spdRead port mask
46 * r7 = toggleError 2nd value, ramtest scratch register,
47 * spdRead scratch register (0x00)
48 * r8 = ramtest scratch register, spdRead scratch register (0x80)
49 * r9 = ramtest scratch register, toggleError loop end, OutHex digit
50 * r10 = ramtest scratch register, spdWriteByte parameter,
51 * spdReadByte return value, printf pointer to COM1
52 * r11 = startType
53 * r12 = ramtest scratch register, spdRead data mask
54 * r13 = pointer to message block
55 * r14 = pointer to GOT
56 * r15 = scratch register, SPD save
57 * r16 = bank0 size, total memory size
58 * r17 = bank1 size
59 * r18 = bank2 size
60 * r19 = bank3 size
61 * r20 = MCCR1, MSAR1
62 * r21 = MCCR3, MEAR1
63 * r22 = MCCR4, MBER
64 * r23 = EMSAR1
65 * r24 = EMEAR1
66 * r25 = save link register 1st level
67 * r26 = save link register 2nd level
68 * r27 = save link register 3rd level
69 * r30 = pointer to GPIO for spdRead
70 */
71
72
73.globl board_asm_init
74board_asm_init:
75/*
76 * setup pointer to message block
77 */
78 mflr r25 /* save away link register */
79 bl get_lnk_reg /* r3=addr of next instruction */
80 subi r4, r3, 8 /* r4=board_asm_init addr */
81 addi r13, r4, (MessageBlock-board_asm_init)
82/*
83 * dcache_disable
84 */
85 mfspr r3, HID0
86 li r4, HID0_DCE
87 andc r3, r3, r4
88 mr r2, r3
89 ori r3, r3, HID0_DCI
90 sync
91 mtspr HID0, r3
92 mtspr HID0, r2
93 isync
94 sync
95/*
96 * icache_disable
97 */
98 mfspr r3, HID0
99 li r4, 0
100 ori r4, r4, HID0_ICE
101 andc r3, r3, r4
102 sync
103 mtspr HID0, r3
104/*
105 * invalidate caches
106 */
107 ori r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
108 or r4, r4, r3
109 isync
110 mtspr HID0, r4
111 andc r4, r4, r3
112 isync
113 mtspr HID0, r4
114 isync
115/*
116 * icache_enable
117 */
118 mfspr r3, HID0
119 ori r3, r3, (HID0_ICE | HID0_ICFI)
120 sync
121 mtspr HID0, r3
122
123 lis r1, 0xfec0
124 ori r1, r1, 0x0cf8
125 lis r2, 0xfee0
126 ori r2, r2, 0xcfc
127
128#ifdef CFG_ADDRESS_MAP_A
129/*
130 * Switch to address map A if necessary.
131 */
132 lis r3, MPC106_REG@h
133 ori r3, r3, PCI_PICR1
134 stwbrx r3, 0, r1
135 sync
136 lwbrx r4, 0, r2
137 sync
138 lis r0, PICR1_XIO_MODE@h
139 ori r0, r0, PICR1_XIO_MODE@l
140 andc r4, r4, r0
141 lis r0, PICR1_ADDRESS_MAP@h
142 ori r0, r0, PICR1_ADDRESS_MAP@l
143 or r4, r4, r0
144 stwbrx r4, 0, r2
145 sync
146#endif
147
148/*
149 * Do the init for the SIO.
150 */
151 bl .sioInit
152
153 addi r3, r13, (MinitLogo-MessageBlock)
154 bl Printf
155
156 addi r3, r13, (Mspd01-MessageBlock)
157 bl Printf
158/*
159 * Memory cofiguration using SPD information stored on the SODIMMs
160 */
161 li r17, 0
162 li r18, 0
163 li r19, 0
164
165 li r3, 0x0002 /* get RAM type from spd for bank0/1 */
166 bl spdRead
167
168 cmpi 0, 0, r3, -1 /* error ? */
169 bne noSpdError
170
171 addi r3, r13, (Mfail-MessageBlock)
172 bl Printf
173
174 li r6, 0xe0 /* error codes in r6 and r7 */
175 li r7, 0x00
176 b toggleError /* fail - loop forever */
177
178noSpdError:
179 mr r15, r3 /* save r3 */
180
181 addi r3, r13, (Mok-MessageBlock)
182 bl Printf
183
184 cmpli 0, 0, r15, 0x0001 /* FPM ? */
185 beq configFPM
186 cmpli 0, 0, r15, 0x0002 /* EDO ? */
187 beq configEDO
188 cmpli 0, 0, r15, 0x0004 /* SDRAM ? */
189 beq configSDRAM
190
191 li r6, 0xe0 /* error codes in r6 and r7 */
192 li r7, 0x01
193 b toggleError /* fail - loop forever */
194
195configSDRAM:
196 addi r3, r13, (MsdRam-MessageBlock)
197 bl Printf
198/*
199 * set the Memory Configuration Reg. 1
200 */
201 li r3, 0x001f /* get bank size from spd bank0/1 */
202 bl spdRead
203
204 andi. r3, r3, 0x0038
205 beq SD16MB2B
206
207 li r3, 0x0011 /* get number of internal banks */
wdenk57b2d802003-06-27 21:31:46 +0000208 /* from spd for bank0/1 */
wdenkc6097192002-11-03 00:24:07 +0000209 bl spdRead
210
211 cmpli 0, 0, r3, 0x02
212 beq SD64MB2B
213
214 cmpli 0, 0, r3, 0x04
215 beq SD64MB4B
216
217 li r6, 0xe0 /* error codes in r6 and r7 */
218 li r7, 0x02
219 b toggleError /* fail - loop forever */
220
221SD64MB2B:
222 li r20, 0x0005 /* 64-Mbit SDRAM 2 banks */
223 b SDRow2nd
224
225SD64MB4B:
226 li r20, 0x0000 /* 64-Mbit SDRAM 4 banks */
227 b SDRow2nd
228
229SD16MB2B:
230 li r20, 0x000f /* 16-Mbit SDRAM 2 banks */
231
232SDRow2nd:
233 li r3, 0x0102 /* get RAM type spd for bank2/3 */
234 bl spdRead
235
236 cmpli 0, 0, r3, 0x0004
237 bne S2D64MB4B /* bank2/3 isn't present or no SDRAM */
238
239 li r3, 0x011f /* get bank size from spd bank2/3 */
240 bl spdRead
241
242 andi. r3, r3, 0x0038
243 beq S2D16MB2B
244/*
245 * set the Memory Configuration Reg. 2
246 */
247 li r3, 0x0111 /* get number of internal banks */
wdenk57b2d802003-06-27 21:31:46 +0000248 /* from spd for bank2/3 */
wdenkc6097192002-11-03 00:24:07 +0000249 bl spdRead
250
251 cmpli 0, 0, r3, 0x02
252 beq S2D64MB2B
253
254 cmpli 0, 0, r3, 0x04
255 beq S2D64MB4B
256
257 li r6, 0xe0 /* error codes in r6 and r7 */
258 li r7, 0x03
259 b toggleError /* fail - loop forever */
260
261S2D64MB2B:
262 ori r20, r20, 0x0050 /* 64-Mbit SDRAM 2 banks */
263 b S2D64MB4B
264
265S2D16MB2B:
266 ori r20, r20, 0x00f0 /* 16-Mbit SDRAM 2 banks */
267
268/*
269 * set the Memory Configuration Reg. 3
270 */
271S2D64MB4B:
272 lis r21, 0x8630 /* BSTOPRE = 0x80, REFREC = 6, */
wdenk57b2d802003-06-27 21:31:46 +0000273 /* RDLAT = 3 */
wdenkc6097192002-11-03 00:24:07 +0000274
275/*
276 * set the Memory Configuration Reg. 4
277 */
278 lis r22, 0x2430 /* PRETOACT = 2, ACTOPRE = 4, */
wdenk57b2d802003-06-27 21:31:46 +0000279 /* WCBUF = 1, RCBUF = 1 */
wdenkc6097192002-11-03 00:24:07 +0000280 ori r22, r22, 0x2220 /* SDMODE = 0x022, ACTORW = 2 */
281
282/*
283 * get the size of bank 0-3
284 */
285 li r3, 0x001f /* get bank size from spd bank0/1 */
286 bl spdRead
287
288 rlwinm r16, r3, 2, 24, 29 /* calculate size in MByte */
wdenk57b2d802003-06-27 21:31:46 +0000289 /* (128 MB max.) */
wdenkc6097192002-11-03 00:24:07 +0000290
291 li r3, 0x0005 /* get number of banks from spd */
wdenk57b2d802003-06-27 21:31:46 +0000292 /* for bank0/1 */
wdenkc6097192002-11-03 00:24:07 +0000293 bl spdRead
294
295 cmpi 0, 0, r3, 2 /* 2 banks ? */
296 bne SDRAMnobank1
297
298 mr r17, r16
299
300SDRAMnobank1:
301 addi r3, r13, (Mspd23-MessageBlock)
302 bl Printf
303
304 li r3, 0x0102 /* get RAM type spd for bank2/3 */
305 bl spdRead
306
307 cmpli 0, 0, r3, 0x0001 /* FPM ? */
308 bne noFPM23 /* handle as EDO */
309 addi r3, r13, (Mok-MessageBlock)
310 bl Printf
311 addi r3, r13, (MfpmRam-MessageBlock)
312 bl Printf
313 b configRAMcommon
314noFPM23:
315 cmpli 0, 0, r3, 0x0002 /* EDO ? */
316 bne noEDO23
317 addi r3, r13, (Mok-MessageBlock)
318 bl Printf
319 addi r3, r13, (MedoRam-MessageBlock)
320 bl Printf
321 b configRAMcommon
322noEDO23:
323 cmpli 0, 0, r3, 0x0004 /* SDRAM ? */
324 bne noSDRAM23
325 addi r3, r13, (Mok-MessageBlock)
326 bl Printf
327 addi r3, r13, (MsdRam-MessageBlock)
328 bl Printf
329 b configSDRAM23
330noSDRAM23:
331 addi r3, r13, (Mna-MessageBlock)
332 bl Printf
333 b configRAMcommon /* bank2/3 isn't present or no SDRAM */
334
335configSDRAM23:
336 li r3, 0x011f /* get bank size from spd bank2/3 */
337 bl spdRead
338
339 rlwinm r18, r3, 2, 24, 29 /* calculate size in MByte */
wdenk57b2d802003-06-27 21:31:46 +0000340 /* (128 MB max.) */
wdenkc6097192002-11-03 00:24:07 +0000341
342 li r3, 0x0105 /* get number of banks from */
wdenk57b2d802003-06-27 21:31:46 +0000343 /* spd bank0/1 */
wdenkc6097192002-11-03 00:24:07 +0000344 bl spdRead
345
346 cmpi 0, 0, r3, 2 /* 2 banks ? */
347 bne SDRAMnobank3
348
349 mr r19, r18
350
351SDRAMnobank3:
352 b configRAMcommon
353
354configFPM:
355 addi r3, r13, (MfpmRam-MessageBlock)
356 bl Printf
357 b configEDO0
358/*
359 * set the Memory Configuration Reg. 1
360 */
361configEDO:
362 addi r3, r13, (MedoRam-MessageBlock)
363 bl Printf
364configEDO0:
365 lis r20, MCCR1_TYPE_EDO@h
366
367getSpdRowBank01:
368 li r3, 0x0003 /* get number of row bits from */
wdenk57b2d802003-06-27 21:31:46 +0000369 /* spd from bank0/1 */
wdenkc6097192002-11-03 00:24:07 +0000370 bl spdRead
371 ori r20, r20, (MCCR1_BK0_9BITS | MCCR1_BK1_9BITS)
372 cmpli 0, 0, r3, 0x0009 /* bank0 - 9 row bits */
373 beq getSpdRowBank23
374
375 ori r20, r20, (MCCR1_BK0_10BITS | MCCR1_BK1_10BITS)
376 cmpli 0, 0, r3, 0x000a /* bank0 - 10 row bits */
377 beq getSpdRowBank23
378
379 ori r20, r20, (MCCR1_BK0_11BITS | MCCR1_BK1_11BITS)
380 cmpli 0, 0, r3, 0x000b /* bank0 - 11 row bits */
381 beq getSpdRowBank23
382
383 ori r20, r20, (MCCR1_BK0_12BITS | MCCR1_BK1_12BITS)
384 cmpli 0, 0, r3, 0x000c /* bank0 - 12 row bits */
385 beq getSpdRowBank23
386
387 cmpli 0, 0, r3, 0x000d /* bank0 - 13 row bits */
388 beq getSpdRowBank23
389
390 li r6, 0xe0 /* error codes in r6 and r7 */
391 li r7, 0x10
392 b toggleError /* fail - loop forever */
393
394getSpdRowBank23:
395 li r3, 0x0103 /* get number of row bits from */
wdenk57b2d802003-06-27 21:31:46 +0000396 /* spd for bank2/3 */
wdenkc6097192002-11-03 00:24:07 +0000397 bl spdRead
398
399 ori r20, r20, (MCCR1_BK2_9BITS | MCCR1_BK3_9BITS)
400 cmpli 0, 0, r3, 0x0009 /* bank0 - 9 row bits */
401 beq writeRowBits
402
403 ori r20, r20, (MCCR1_BK2_10BITS | MCCR1_BK3_10BITS)
404 cmpli 0, 0, r3, 0x000a /* bank0 - 10 row bits */
405 beq writeRowBits
406
407 ori r20, r20, (MCCR1_BK2_11BITS | MCCR1_BK3_11BITS)
408 cmpli 0, 0, r3, 0x000b /* bank0 - 11 row bits */
409 beq writeRowBits
410
411 ori r20, r20, (MCCR1_BK2_12BITS | MCCR1_BK3_12BITS)
412
413/*
414 * set the Memory Configuration Reg. 3
415 */
416writeRowBits:
417 lis r21, 0x000a /* CPX = 1, RAS6P = 4 */
418 ori r21, r21, 0x2293 /* CAS5 = 2, CP4 = 1, */
wdenk57b2d802003-06-27 21:31:46 +0000419 /* CAS3 = 2, RCD2 = 2, RP = 3 */
wdenkc6097192002-11-03 00:24:07 +0000420/*
421 * set the Memory Configuration Reg. 4
422 */
423 lis r22, 0x0010 /* all SDRAM parameter 0, */
wdenk57b2d802003-06-27 21:31:46 +0000424 /* WCBUF flow through, */
425 /* RCBUF registered */
wdenkc6097192002-11-03 00:24:07 +0000426/*
427 * get the size of bank 0-3
428 */
429 li r3, 0x0003 /* get row bits from spd bank0/1 */
430 bl spdRead
431
432 li r16, 0 /* bank size is: */
wdenk57b2d802003-06-27 21:31:46 +0000433 /* (8*2^row*2^column)/0x100000 MB */
wdenkc6097192002-11-03 00:24:07 +0000434 ori r16, r16, 0x8000
435 rlwnm r16, r16, r3, 0, 31
436
437 li r3, 0x0004 /* get column bits from spd bank0/1 */
438 bl spdRead
439
440 rlwnm r16, r16, r3, 0, 31
441
442 li r3, 0x0005 /* get number of banks from */
wdenk57b2d802003-06-27 21:31:46 +0000443 /* spd for bank0/1 */
wdenkc6097192002-11-03 00:24:07 +0000444 bl spdRead
445
446 cmpi 0, 0, r3, 2 /* 2 banks ? */
447 bne EDOnobank1
448
449 mr r17, r16
450
451EDOnobank1:
452 addi r3, r13, (Mspd23-MessageBlock)
453 bl Printf
454
455 li r3, 0x0102 /* get RAM type spd for bank2/3 */
456 bl spdRead
457
458 cmpli 0, 0, r3, 0x0001 /* FPM ? */
459 bne noFPM231 /* handle as EDO */
460 addi r3, r13, (Mok-MessageBlock)
461 bl Printf
462 addi r3, r13, (MfpmRam-MessageBlock)
463 bl Printf
464 b EDObank2
465noFPM231:
466 cmpli 0, 0, r3, 0x0002 /* EDO ? */
467 bne noEDO231
468 addi r3, r13, (Mok-MessageBlock)
469 bl Printf
470 addi r3, r13, (MedoRam-MessageBlock)
471 bl Printf
472 b EDObank2
473noEDO231:
474 cmpli 0, 0, r3, 0x0004 /* SDRAM ? */
475 bne noSDRAM231
476 addi r3, r13, (Mok-MessageBlock)
477 bl Printf
478 addi r3, r13, (MsdRam-MessageBlock)
479 bl Printf
480 b configRAMcommon
481noSDRAM231:
482 addi r3, r13, (Mfail-MessageBlock)
483 bl Printf
484 b configRAMcommon /* bank2/3 isn't present or no SDRAM */
485
486EDObank2:
487 li r3, 0x0103 /* get row bits from spd for bank2/3 */
488 bl spdRead
489
490 li r18, 0 /* bank size is: */
wdenk57b2d802003-06-27 21:31:46 +0000491 /* (8*2^row*2^column)/0x100000 MB */
wdenkc6097192002-11-03 00:24:07 +0000492 ori r18, r18, 0x8000
493 rlwnm r18, r18, r3, 0, 31
494
495 li r3, 0x0104 /* get column bits from spd bank2/3 */
496 bl spdRead
497
498 rlwnm r18, r18, r3, 0, 31
499
500 li r3, 0x0105 /* get number of banks from */
wdenk57b2d802003-06-27 21:31:46 +0000501 /* spd for bank2/3 */
wdenkc6097192002-11-03 00:24:07 +0000502 bl spdRead
503
504 cmpi 0, 0, r3, 2 /* 2 banks ? */
505 bne configRAMcommon
506
507 mr r19, r18
508
509configRAMcommon:
510 lis r1, MPC106_REG_ADDR@h
511 ori r1, r1, MPC106_REG_ADDR@l
512 lis r2, MPC106_REG_DATA@h
513 ori r2, r2, MPC106_REG_DATA@l
514
515 li r0, 0
516
517/*
518 * If we are already running in RAM (debug mode), we should
519 * NOT reset the MEMGO flag. Otherwise we will stop all memory
520 * accesses.
521 */
522#ifdef IN_RAM
523 lis r4, MCCR1_MEMGO@h
524 ori r4, r4, MCCR1_MEMGO@l
525 or r20, r20, r4
526#endif
527
528/*
529 * set the Memory Configuration Reg. 1
530 */
531 lis r3, MPC106_REG@h /* start building new reg number */
532 ori r3, r3, MPC106_MCCR1 /* register number 0xf0 */
533 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
534 eieio /* make sure mem. access is complete */
535 stwbrx r20, r0, r2 /* write data to CONFIG_DATA */
536/*
537 * set the Memory Configuration Reg. 3
538 */
539 lis r3, MPC106_REG@h /* start building new reg number */
540 ori r3, r3, MPC106_MCCR3 /* register number 0xf8 */
541 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
542 eieio /* make sure mem. access is complete */
543 stwbrx r21, r0, r2 /* write data to CONFIG_DATA */
544/*
545 * set the Memory Configuration Reg. 4
546 */
547 lis r3, MPC106_REG@h /* start building new reg number */
548 ori r3, r3, MPC106_MCCR4 /* register number 0xfc */
549 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
550 eieio /* make sure mem. access is complete */
551 stwbrx r22, r0, r2 /* write data to CONFIG_DATA */
552/*
553 * set the memory boundary registers for bank 0-3
554 */
555 li r20, 0
556 li r23, 0
557 li r24, 0
558 subi r21, r16, 1 /* calculate end address bank0 */
559 li r22, (MBER_BANK0)
560
561 cmpi 0, 0, r17, 0 /* bank1 present ? */
562 beq nobank1
563
564 rlwinm r3, r16, 8, 16, 23 /* calculate start address of bank1 */
565 or r20, r20, r3
566 add r16, r16, r17 /* add to total memory size */
567 subi r3, r16, 1 /* calculate end address of bank1 */
568 rlwinm r3, r3, 8, 16, 23
569 or r21, r21, r3
570 ori r22, r22, (MBER_BANK1) /* enable bank1 */
571 b bank2
572
573nobank1:
574 ori r23, r23, 0x0300 /* set bank1 start to unused area */
575 ori r24, r24, 0x0300 /* set bank1 end to unused area */
576
577bank2:
578 cmpi 0, 0, r18, 0 /* bank2 present ? */
579 beq nobank2
580
581 andi. r3, r16, 0x00ff /* calculate start address of bank2 */
582 andi. r4, r16, 0x0300
583 rlwinm r3, r3, 16, 8, 15
584 or r20, r20, r3
585 rlwinm r3, r4, 8, 8, 15
586 or r23, r23, r3
587 add r16, r16, r18 /* add to total memory size */
588 subi r3, r16, 1 /* calculate end address of bank2 */
589 andi. r4, r3, 0x0300
590 andi. r3, r3, 0x00ff
591 rlwinm r3, r3, 16, 8, 15
592 or r21, r21, r3
593 rlwinm r3, r4, 8, 8, 15
594 or r24, r24, r3
595 ori r22, r22, (MBER_BANK2) /* enable bank2 */
596 b bank3
597
598nobank2:
599 lis r3, 0x0003
600 or r23, r23, r3 /* set bank2 start to unused area */
601 or r24, r24, r3 /* set bank2 end to unused area */
602
603bank3:
604 cmpi 0, 0, r19, 0 /* bank3 present ? */
605 beq nobank3
606
607 andi. r3, r16, 0x00ff /* calculate start address of bank3 */
608 andi. r4, r16, 0x0300
609 rlwinm r3, r3, 24, 0, 7
610 or r20, r20, r3
611 rlwinm r3, r4, 16, 0, 7
612 or r23, r23, r3
613 add r16, r16, r19 /* add to total memory size */
614 subi r3, r16, 1 /* calculate end address of bank3 */
615 andi. r4, r3, 0x0300
616 andi. r3, r3, 0x00ff
617 rlwinm r3, r3, 24, 0, 7
618 or r21, r21, r3
619 rlwinm r3, r4, 16, 0, 7
620 or r24, r24, r3
621 ori r22, r22, (MBER_BANK3) /* enable bank3 */
622 b writebound
623
624nobank3:
625 lis r3, 0x0300
626 or r23, r23, r3 /* set bank3 start to unused area */
627 or r24, r24, r3 /* set bank3 end to unused area */
628
629writebound:
630 lis r3, MPC106_REG@h /* start building new reg number */
631 ori r3, r3, MPC106_MSAR1 /* register number 0x80 */
632 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
633 eieio /* make sure mem. access is complete */
634 stwbrx r20, r0, r2 /* write data to CONFIG_DATA */
635
636 lis r3, MPC106_REG@h /* start building new reg number */
637 ori r3, r3, MPC106_MEAR1 /* register number 0x90 */
638 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
639 eieio /* make sure mem. access is complete */
640 stwbrx r21, r0, r2 /* write data to CONFIG_DATA */
641
642 lis r3, MPC106_REG@h /* start building new reg number */
643 ori r3, r3, MPC106_EMSAR1 /* register number 0x88 */
644 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
645 eieio /* make sure mem. access is complete */
646 stwbrx r23, r0, r2 /* write data to CONFIG_DATA */
647
648 lis r3, MPC106_REG@h /* start building new reg number */
649 ori r3, r3, MPC106_EMEAR1 /* register number 0x98 */
650 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
651 eieio /* make sure mem. access is complete */
652 stwbrx r24, r0, r2 /* write data to CONFIG_DATA */
653
654/*
655 * set boundaries of unused banks to unused address space
656 */
657 lis r4, 0x0303
658 ori r4, r4, 0x0303 /* bank 4-7 start and end adresses */
659 lis r3, MPC106_REG@h /* start building new reg number */
660 ori r3, r3, MPC106_EMSAR2 /* register number 0x8C */
661 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
662 eieio /* make sure mem. access is complete */
663 stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
664
665 lis r3, MPC106_REG@h /* start building new reg number */
666 ori r3, r3, MPC106_EMEAR2 /* register number 0x9C */
667 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
668 eieio /* make sure mem. access is complete */
669 stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
670
671/*
672 * set the Memory Configuration Reg. 2
673 */
674 lis r3, MPC106_REG@h /* start building new reg number */
675 ori r3, r3, MPC106_MCCR2 /* register number 0xf4 */
676 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
677 eieio /* make sure mem. access is complete */
678
679 li r3, 0x000c /* get refresh from spd for bank0/1 */
680 bl spdRead
681
682 cmpi 0, 0, r3, -1 /* error ? */
683 bne common1
684
685 li r6, 0xe0 /* error codes in r6 and r7 */
686 li r7, 0x20
687 b toggleError /* fail - loop forever */
688
689common1:
690 andi. r15, r3, 0x007f /* mask selfrefresh bit */
691 li r3, 0x010c /* get refresh from spd for bank2/3 */
692 bl spdRead
693
694 cmpi 0, 0, r3, -1 /* error ? */
695 beq common2
696 andi. r3, r3, 0x007f /* mask selfrefresh bit */
697 cmp 0, 0, r3, r15 /* find the lower */
698 blt common3
699
700common2:
701 mr r3, r15
702
703common3:
704 li r4, 0x1010 /* refesh cycle 1028 clocks */
wdenk57b2d802003-06-27 21:31:46 +0000705 /* left shifted 2 */
wdenkc6097192002-11-03 00:24:07 +0000706 cmpli 0, 0, r3, 0x0000 /* 15.6 us ? */
707 beq writeRefresh
708
709 li r4, 0x0808 /* refesh cycle 514 clocks */
wdenk57b2d802003-06-27 21:31:46 +0000710 /* left shifted 2 */
wdenkc6097192002-11-03 00:24:07 +0000711 cmpli 0, 0, r3, 0x0002 /* 7.8 us ? */
712 beq writeRefresh
713
714 li r4, 0x2020 /* refesh cycle 2056 clocks */
wdenk57b2d802003-06-27 21:31:46 +0000715 /* left shifted 2 */
wdenkc6097192002-11-03 00:24:07 +0000716 cmpli 0, 0, r3, 0x0003 /* 31.3 us ? */
717 beq writeRefresh
718
719 li r4, 0x4040 /* refesh cycle 4112 clocks */
wdenk57b2d802003-06-27 21:31:46 +0000720 /* left shifted 2 */
wdenkc6097192002-11-03 00:24:07 +0000721 cmpli 0, 0, r3, 0x0004 /* 62.5 us ? */
722 beq writeRefresh
723
724 li r4, 0
725 ori r4, r4, 0x8080 /* refesh cycle 8224 clocks */
wdenk57b2d802003-06-27 21:31:46 +0000726 /* left shifted 2 */
wdenkc6097192002-11-03 00:24:07 +0000727 cmpli 0, 0, r3, 0x0005 /* 125 us ? */
728 beq writeRefresh
729
730 li r6, 0xe0 /* error codes in r6 and r7 */
731 li r7, 0x21
732 b toggleError /* fail - loop forever */
733
734writeRefresh:
735 stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
736
737/*
738 * DRAM BANKS SHOULD BE ENABLED
739 */
740 addi r3, r13, (Mactivate-MessageBlock)
741 bl Printf
742 mr r3, r16
743 bl OutDec
744 addi r3, r13, (Mmbyte-MessageBlock)
745 bl Printf
746
747 lis r3, MPC106_REG@h /* start building new reg number */
748 ori r3, r3, MPC106_MBER /* register number 0xa0 */
749 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
750 eieio /* make sure mem. access is complete */
751 stb r22, 0(r2) /* write data to CONFIG_DATA */
752 li r8, 0x63 /* PGMAX = 99 */
753 stb r8, 3(r2) /* write data to CONFIG_DATA */
754
755/*
756 * DRAM SHOULD NOW BE CONFIGURED AND ENABLED
757 * MUST WAIT 200us BEFORE ACCESSING
758 */
759 li r0, 0x7800
760 mtctr r0
761
762wait200us:
763 bdnz wait200us
764
765 lis r3, MPC106_REG@h /* start building new reg number */
766 ori r3, r3, MPC106_MCCR1 /* register number 0xf0 */
767 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
768 eieio /* make sure mem. access is complete */
769
770 lwbrx r4, r0, r2 /* load r4 from CONFIG_DATA */
771
772 lis r0, MCCR1_MEMGO@h /* MEMGO=1 */
773 ori r0, r0, MCCR1_MEMGO@l
774 or r4, r4, r0 /* set the MEMGO bit */
775 stwbrx r4, r0, r2 /* write mdfd data to CONFIG_DATA */
776
777 li r0, 0x7000
778 mtctr r0
779
780wait8ref:
781 bdnz wait8ref
782
783 addi r3, r13, (Mok-MessageBlock)
784 bl Printf
785
786 mtlr r25
787 blr
788
789/*
790 * Infinite loop called in case of an error during RAM initialisation.
791 * error codes in r6 and r7.
792 */
793toggleError:
794 li r0, 0
795 lis r9, 127
796 ori r9, r9, 65535
797toggleError1:
798 addic r0, r0, 1
799 cmpw cr1, r0, r9
800 ble cr1, toggleError1
801 li r0, 0
802 lis r9, 127
803 ori r9, r9, 65535
804toggleError2:
805 addic r0, r0, 1
806 cmpw cr1, r0, r9
807 ble cr1, toggleError2
808 b toggleError
809
810
811/******************************************************************************
812 * This function performs a basic initialisation of the superio chip
813 * to enable basic console output and SPD access during RAM initialisation.
814 *
815 * Upon completion, SIO resource registers are mapped as follows:
816 * Resource Enabled Address
817 * UART1 Yes 3F8-3FF COM1
818 * UART2 Yes 2F8-2FF COM2
819 * GPIO Yes 220-227
820 */
821.set SIO_LUNINDEX, 0x07 /* SIO LUN index register */
822.set SIO_CNFG1, 0x21 /* SIO configuration #1 register */
823.set SIO_PCSCI, 0x23 /* SIO PCS configuration index reg */
824.set SIO_PCSCD, 0x24 /* SIO PCS configuration data reg */
825.set SIO_ACTIVATE, 0x30 /* SIO activate register */
826.set SIO_IOBASEHI, 0x60 /* SIO I/O port base address, 15:8 */
827.set SIO_IOBASELO, 0x61 /* SIO I/O port base address, 7:0 */
828.set SIO_LUNENABLE, 0x01 /* SIO LUN enable */
829
830.sioInit:
831 mfspr r7, 8 /* save link register */
832
833.sioInit_87308:
834
835/*
836 * Get base addr of ISA I/O space
837 */
838 lis r6, CFG_ISA_IO@h
839 ori r6, r6, CFG_ISA_IO@l
840
841/*
842 * Set offset to base address for config registers.
843 */
844#if defined(CFG_NS87308_BADDR_0x)
845 addi r4, r0, 0x0279
846#elif defined(CFG_NS87308_BADDR_10)
847 addi r4, r0, 0x015C
848#elif defined(CFG_NS87308_BADDR_11)
849 addi r4, r0, 0x002E
850#endif
851 add r6, r6, r4 /* add offset to base */
852 or r3, r6, r6 /* make a copy */
853
854/*
855 * PMC (LUN 8)
856 */
857 addi r4, r0, SIO_LUNINDEX /* select PMC LUN */
858 addi r5, r0, 0x8
859 bl .sio_bw
860 addi r4, r0, SIO_IOBASEHI /* initialize PMC address to 0x460 */
861 addi r5, r0, 0x04
862 bl .sio_bw
863 addi r4, r0, SIO_IOBASELO
864 addi r5, r0, 0x60
865 bl .sio_bw
866 addi r4, r0, SIO_ACTIVATE /* enable PMC */
867 addi r5, r0, SIO_LUNENABLE
868 bl .sio_bw
869
870 lis r8, CFG_ISA_IO@h
871 ori r8, r8, 0x0460
872 li r9, 0x03
873 stb r9, 0(r8) /* select PMC2 register */
874 eieio
875 li r9, 0x00
876 stb r9, 1(r8) /* SuperI/O clock src: 24MHz via X1 */
877 eieio
878
879/*
880 * map UART1 (LUN 6) or UART2 (LUN 5) to COM1 (0x3F8)
881 */
882 addi r4, r0, SIO_LUNINDEX /* select COM1 LUN */
883 addi r5, r0, 0x6
884 bl .sio_bw
885
886 addi r4, r0, SIO_IOBASEHI /* initialize COM1 address to 0x3F8 */
887 addi r5, r0, 0x03
888 bl .sio_bw
889
890 addi r4, r0, SIO_IOBASELO
891 addi r5, r0, 0xF8
892 bl .sio_bw
893
894 addi r4, r0, SIO_ACTIVATE /* enable COM1 */
895 addi r5, r0, SIO_LUNENABLE
896 bl .sio_bw
897
898/*
899 * Init COM1 for polled output
900 */
901 lis r8, CFG_ISA_IO@h
902 ori r8, r8, 0x03f8
903 li r9, 0x00
904 stb r9, 1(r8) /* int disabled */
905 eieio
906 li r9, 0x00
907 stb r9, 4(r8) /* modem ctrl */
908 eieio
909 li r9, 0x80
910 stb r9, 3(r8) /* link ctrl, bank select */
911 eieio
912 li r9, 115200/CONFIG_BAUDRATE
913 stb r9, 0(r8) /* baud rate (LSB)*/
914 eieio
915 rotrwi r9, r9, 8
916 stb r9, 1(r8) /* baud rate (MSB) */
917 eieio
918 li r9, 0x03
919 stb r9, 3(r8) /* 8 data bits, 1 stop bit, */
wdenk57b2d802003-06-27 21:31:46 +0000920 /* no parity */
wdenkc6097192002-11-03 00:24:07 +0000921 eieio
922 li r9, 0x0b
923 stb r9, 4(r8) /* enable the receiver and transmitter */
924 eieio
925
926waitEmpty:
927 lbz r9, 5(r8) /* transmit empty */
928 andi. r9, r9, 0x40
929 beq waitEmpty
930 li r9, 0x47
931 stb r9, 3(r8) /* send break, 8 data bits, */
wdenk57b2d802003-06-27 21:31:46 +0000932 /* 2 stop bits, no parity */
wdenkc6097192002-11-03 00:24:07 +0000933 eieio
934
935 lis r0, 0x0001
936 mtctr r0
937
938waitCOM1:
939 lwz r0, 5(r8) /* load from port for delay */
940 bdnz waitCOM1
941
942waitEmpty1:
943 lbz r9, 5(r8) /* transmit empty */
944 andi. r9, r9, 0x40
945 beq waitEmpty1
946 li r9, 0x07
947 stb r9, 3(r8) /* 8 data bits, 2 stop bits, */
wdenk57b2d802003-06-27 21:31:46 +0000948 /* no parity */
wdenkc6097192002-11-03 00:24:07 +0000949 eieio
950
951/*
952 * GPIO (LUN 7)
953 */
954 addi r4, r0, SIO_LUNINDEX /* select GPIO LUN */
955 addi r5, r0, 0x7
956 bl .sio_bw
957
958 addi r4, r0, SIO_IOBASEHI /* initialize GPIO address to 0x220 */
959 addi r5, r0, 0x02
960 bl .sio_bw
961
962 addi r4, r0, SIO_IOBASELO
963 addi r5, r0, 0x20
964 bl .sio_bw
965
966 addi r4, r0, SIO_ACTIVATE /* enable GPIO */
967 addi r5, r0, SIO_LUNENABLE
968 bl .sio_bw
969
970.sioInit_done:
971
972/*
973 * Get base addr of ISA I/O space
974 */
975 lis r3, CFG_ISA_IO@h
976 ori r3, r3, CFG_ISA_IO@l
977
978 addi r3, r3, 0x015C /* adjust to superI/O 87308 base */
979 or r6, r3, r3 /* make a copy */
980/*
981 * CS0
982 */
983 addi r4, r0, SIO_PCSCI /* select PCSCIR */
984 addi r5, r0, 0x00
985 bl .sio_bw
986 addi r4, r0, SIO_PCSCD /* select PCSCDR */
987 addi r5, r0, 0x00
988 bl .sio_bw
989 addi r4, r0, SIO_PCSCI /* select PCSCIR */
990 addi r5, r0, 0x01
991 bl .sio_bw
992 addi r4, r0, SIO_PCSCD /* select PCSCDR */
993 addi r5, r0, 0x76
994 bl .sio_bw
995 addi r4, r0, SIO_PCSCI /* select PCSCIR */
996 addi r5, r0, 0x02
997 bl .sio_bw
998 addi r4, r0, SIO_PCSCD /* select PCSCDR */
999 addi r5, r0, 0x40
1000 bl .sio_bw
1001/*
1002 * CS1
1003 */
1004 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1005 addi r5, r0, 0x05
1006 bl .sio_bw
1007 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1008 addi r5, r0, 0x00
1009 bl .sio_bw
1010 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1011 addi r5, r0, 0x05
1012 bl .sio_bw
1013 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1014 addi r5, r0, 0x70
1015 bl .sio_bw
1016 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1017 addi r5, r0, 0x06
1018 bl .sio_bw
1019 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1020 addi r5, r0, 0x1C
1021 bl .sio_bw
1022/*
1023 * CS2
1024 */
1025 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1026 addi r5, r0, 0x08
1027 bl .sio_bw
1028 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1029 addi r5, r0, 0x00
1030 bl .sio_bw
1031 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1032 addi r5, r0, 0x09
1033 bl .sio_bw
1034 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1035 addi r5, r0, 0x71
1036 bl .sio_bw
1037 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1038 addi r5, r0, 0x0A
1039 bl .sio_bw
1040 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1041 addi r5, r0, 0x1C
1042 bl .sio_bw
1043
1044 mtspr 8, r7 /* restore link register */
1045 bclr 20, 0 /* return to caller */
1046
1047/*
1048 * this function writes a register to the SIO chip
1049 */
1050.sio_bw:
1051 stb r4, 0(r3) /* write index register with register offset */
1052 eieio
1053 sync
1054 stb r5, 1(r3) /* 1st write */
1055 eieio
1056 sync
1057 stb r5, 1(r3) /* 2nd write */
1058 eieio
1059 sync
1060 bclr 20, 0 /* return to caller */
1061/*
1062 * this function reads a register from the SIO chip
1063 */
1064.sio_br:
1065 stb r4, 0(r3) /* write index register with register offset */
1066 eieio
1067 sync
1068 lbz r3, 1(r3) /* retrieve specified reg offset contents */
1069 eieio
1070 sync
1071 bclr 20, 0 /* return to caller */
1072
1073/*
1074 * Print a message to COM1 in polling mode
1075 * r10=COM1 port, r3=(char*)string
1076 */
1077.globl Printf
1078Printf:
1079 lis r10, CFG_ISA_IO@h /* COM1 port */
1080 ori r10, r10, 0x03f8
1081
1082WaitChr:
1083 lbz r0, 5(r10) /* read link status */
1084 eieio
1085 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1086 beq cr0, WaitChr /* wait till empty */
1087 lbzx r0, r0, r3 /* get char */
1088 stb r0, 0(r10) /* write to transmit reg */
1089 eieio
1090 addi r3, r3, 1 /* next char */
1091 lbzx r0, r0, r3 /* get char */
1092 cmpwi cr1, r0, 0 /* end of string ? */
1093 bne cr1, WaitChr
1094 blr
1095
1096/*
1097 * Print 8/4/2 digits hex value to COM1 in polling mode
1098 * r10=COM1 port, r3=val
1099 */
1100OutHex2:
1101 li r9, 4 /* shift reg for 2 digits */
1102 b OHstart
1103OutHex4:
1104 li r9, 12 /* shift reg for 4 digits */
1105 b OHstart
1106 .globl OutHex
1107OutHex:
1108 li r9, 28 /* shift reg for 8 digits */
1109OHstart:
1110 lis r10, CFG_ISA_IO@h /* COM1 port */
1111 ori r10, r10, 0x03f8
1112OutDig:
1113 lbz r0, 5(r10) /* read link status */
1114 eieio
1115 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1116 beq cr0, OutDig
1117 sraw r0, r3, r9
1118 clrlwi r0, r0, 28
1119 cmpwi cr1, r0, 9
1120 ble cr1, digIsNum
1121 addic r0, r0, 55
1122 b nextDig
1123digIsNum:
1124 addic r0, r0, 48
1125nextDig:
1126 stb r0, 0(r10) /* write to transmit reg */
1127 eieio
1128 addic. r9, r9, -4
1129 bge OutDig
1130 blr
1131/*
1132 * Print 3 digits hdec value to COM1 in polling mode
1133 * r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch
1134 */
1135.globl OutDec
1136OutDec:
1137 li r6, 10
1138 divwu r0, r3, r6 /* r0 = r3 / 10, r9 = r3 mod 10 */
1139 mullw r10, r0, r6
1140 subf r9, r10, r3
1141
1142 mr r3, r0
1143 divwu r0, r3, r6 /* r0 = r3 / 10, r8 = r3 mod 10 */
1144 mullw r10, r0, r6
1145 subf r8, r10, r3
1146
1147 mr r3, r0
1148 divwu r0, r3, r6 /* r0 = r3 / 10, r7 = r3 mod 10 */
1149 mullw r10, r0, r6
1150 subf r7, r10, r3
1151
1152 lis r10, CFG_ISA_IO@h /* COM1 port */
1153 ori r10, r10, 0x03f8
1154
1155 or. r7, r7, r7
1156 bne noblank1
1157 li r3, 0x20
1158 b OutDec4
1159
1160noblank1:
1161 addi r3, r7, 48 /* convert to ASCII */
1162
1163OutDec4:
1164 lbz r0, 0(r13) /* slow down dummy read */
1165 lbz r0, 5(r10) /* read link status */
1166 eieio
1167 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1168 beq cr0, OutDec4
1169 stb r3, 0(r10) /* x00 to transmit */
1170 eieio
1171
1172 or. r7, r7, r8
1173 beq OutDec5
1174
1175 addi r3, r8, 48 /* convert to ASCII */
1176OutDec5:
1177 lbz r0, 0(r13) /* slow down dummy read */
1178 lbz r0, 5(r10) /* read link status */
1179 eieio
1180 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1181 beq cr0, OutDec5
1182 stb r3, 0(r10) /* x0 to transmit */
1183 eieio
1184
1185 addi r3, r9, 48 /* convert to ASCII */
1186OutDec6:
1187 lbz r0, 0(r13) /* slow down dummy read */
1188 lbz r0, 5(r10) /* read link status */
1189 eieio
1190 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1191 beq cr0, OutDec6
1192 stb r3, 0(r10) /* x to transmit */
1193 eieio
1194 blr
1195/*
1196 * Print a char to COM1 in polling mode
1197 * r10=COM1 port, r3=char
1198 */
1199.globl OutChr
1200OutChr:
1201 lis r10, CFG_ISA_IO@h /* COM1 port */
1202 ori r10, r10, 0x03f8
1203
1204OutChr1:
1205 lbz r0, 5(r10) /* read link status */
1206 eieio
1207 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1208 beq cr0, OutChr1 /* wait till empty */
1209 stb r3, 0(r10) /* write to transmit reg */
1210 eieio
1211 blr
1212/*
1213 * Input: r3 adr to read
1214 * Output: r3 val or -1 for error
1215 */
1216spdRead:
1217 mfspr r26, 8 /* save link register */
1218
1219 lis r30, CFG_ISA_IO@h
1220 ori r30, r30, 0x220 /* GPIO Port 1 */
1221 li r7, 0x00
1222 li r8, 0x100
1223 and. r5, r3, r8
1224 beq spdbank0
1225 li r12, 0x08
1226 li r4, 0x10
1227 li r6, 0x18
1228 b spdRead1
1229
1230spdbank0:
1231 li r12, 0x20 /* set I2C data */
1232 li r4, 0x40 /* set I2C clock */
1233 li r6, 0x60 /* set I2C clock and data */
1234
1235spdRead1:
1236 li r8, 0x80
1237
1238 bl spdStart /* access I2C bus as master */
1239 li r10, 0xa0 /* write to SPD */
1240 bl spdWriteByte
1241 bl spdReadAck /* ACK returns in r10 */
1242 cmpw cr0, r10, r7
1243 bne AckErr /* r10 must be 0, if ACK received */
1244 mr r10, r3 /* adr to read */
1245 bl spdWriteByte
1246 bl spdReadAck
1247 cmpw cr0, r10, r7
1248 bne AckErr
1249 bl spdStart
1250 li r10, 0xa1 /* read from SPD */
1251 bl spdWriteByte
1252 bl spdReadAck
1253 cmpw cr0, r10, r7
1254 bne AckErr
1255 bl spdReadByte /* return val in r10 */
1256 bl spdWriteAck
1257 bl spdStop /* release I2C bus */
1258 mr r3, r10
1259 mtspr 8, r26 /* restore link register */
1260 blr
1261/*
1262 * ACK error occurred
1263 */
1264AckErr:
1265 bl spdStop
1266 orc r3, r0, r0 /* return -1 */
1267 mtspr 8, r26 /* restore link register */
1268 blr
1269
1270/*
1271 * Routines to read from RAM spd.
1272 * r30 - GPIO Port1 address in all cases.
1273 * r4 - clock mask for SPD
1274 * r6 - port mask for SPD
1275 * r12 - data mask for SPD
1276 */
1277waitSpd:
1278 li r0, 0x1000
1279 mtctr r0
1280wSpd:
1281 bdnz wSpd
1282 bclr 20, 0 /* return to caller */
1283
1284/*
1285 * establish START condition on I2C bus
1286 */
1287spdStart:
1288 mfspr r27, 8 /* save link register */
1289 stb r6, 0(r30) /* set SDA and SCL */
1290 eieio
1291 stb r6, 1(r30) /* switch GPIO to output */
1292 eieio
1293 bl waitSpd
1294 stb r4, 0(r30) /* reset SDA */
1295 eieio
1296 bl waitSpd
1297 stb r7, 0(r30) /* reset SCL */
1298 eieio
1299 bl waitSpd
1300 mtspr 8, r27
1301 bclr 20, 0 /* return to caller */
1302
1303/*
1304 * establish STOP condition on I2C bus
1305 */
1306spdStop:
1307 mfspr r27, 8 /* save link register */
1308 stb r7, 0(r30) /* reset SCL and SDA */
1309 eieio
1310 stb r6, 1(r30) /* switch GPIO to output */
1311 eieio
1312 bl waitSpd
1313 stb r4, 0(r30) /* set SCL */
1314 eieio
1315 bl waitSpd
1316 stb r6, 0(r30) /* set SDA and SCL */
1317 eieio
1318 bl waitSpd
1319 stb r7, 1(r30) /* switch GPIO to input */
1320 eieio
1321 mtspr 8, r27
1322 bclr 20, 0 /* return to caller */
1323
1324spdReadByte:
1325 mfspr r27, 8
1326 stb r4, 1(r30) /* set GPIO for SCL output */
1327 eieio
1328 li r9, 0x08
1329 li r10, 0x00
1330loopRB:
1331 stb r7, 0(r30) /* reset SDA and SCL */
1332 eieio
1333 bl waitSpd
1334 stb r4, 0(r30) /* set SCL */
1335 eieio
1336 bl waitSpd
1337 lbz r5, 0(r30) /* read from GPIO Port1 */
1338 rlwinm r10, r10, 1, 0, 31
1339 and. r5, r5, r12
1340 beq clearBit
1341 ori r10, r10, 0x01 /* append _1_ */
1342clearBit:
1343 stb r7, 0(r30) /* reset SCL */
1344 eieio
1345 bl waitSpd
1346 addic. r9, r9, -1
1347 bne loopRB
1348 mtspr 8, r27
1349 bclr 20, 0 /* return (r10) to caller */
1350
1351/*
1352 * spdWriteByte writes bits 24 - 31 of r10 to I2C.
1353 * r8 contains bit mask 0x80
1354 */
1355spdWriteByte:
1356 mfspr r27, 8 /* save link register */
1357 li r9, 0x08 /* write octet */
1358 and. r5, r10, r8
1359 bne sWB1
1360 stb r7, 0(r30) /* set SDA to _0_ */
1361 eieio
1362 b sWB2
1363sWB1:
1364 stb r12, 0(r30) /* set SDA to _1_ */
1365 eieio
1366sWB2:
1367 stb r6, 1(r30) /* set GPIO to output */
1368 eieio
1369loopWB:
1370 and. r5, r10, r8
1371 bne sWB3
1372 stb r7, 0(r30) /* set SDA to _0_ */
1373 eieio
1374 b sWB4
1375sWB3:
1376 stb r12, 0(r30) /* set SDA to _1_ */
1377 eieio
1378sWB4:
1379 bl waitSpd
1380 and. r5, r10, r8
1381 bne sWB5
1382 stb r4, 0(r30) /* set SDA to _0_ and SCL */
1383 eieio
1384 b sWB6
1385sWB5:
1386 stb r6, 0(r30) /* set SDA to _1_ and SCL */
1387 eieio
1388sWB6:
1389 bl waitSpd
1390 and. r5, r10, r8
1391 bne sWB7
1392 stb r7, 0(r30) /* set SDA to _0_ and reset SCL */
1393 eieio
1394 b sWB8
1395sWB7:
1396 stb r12, 0(r30) /* set SDA to _1_ and reset SCL */
1397 eieio
1398sWB8:
1399 bl waitSpd
1400 rlwinm r10, r10, 1, 0, 31 /* next bit */
1401 addic. r9, r9, -1
1402 bne loopWB
1403 mtspr 8, r27
1404 bclr 20, 0 /* return to caller */
1405
1406/*
1407 * Read ACK from SPD, return value in r10
1408 */
1409spdReadAck:
1410 mfspr r27, 8 /* save link register */
1411 stb r4, 1(r30) /* set GPIO to output */
1412 eieio
1413 stb r7, 0(r30) /* reset SDA and SCL */
1414 eieio
1415 bl waitSpd
1416 stb r4, 0(r30) /* set SCL */
1417 eieio
1418 bl waitSpd
1419 lbz r10, 0(r30) /* read GPIO Port 1 and mask SDA */
1420 and r10, r10, r12
1421 bl waitSpd
1422 stb r7, 0(r30) /* reset SDA and SCL */
1423 eieio
1424 bl waitSpd
1425 mtspr 8, r27
1426 bclr 20, 0 /* return (r10) to caller */
1427
1428spdWriteAck:
1429 mfspr r27, 8
1430 stb r12, 0(r30) /* set SCL */
1431 eieio
1432 stb r6, 1(r30) /* set GPIO to output */
1433 eieio
1434 bl waitSpd
1435 stb r6, 0(r30) /* SDA and SCL */
1436 eieio
1437 bl waitSpd
1438 stb r12, 0(r30) /* reset SCL */
1439 eieio
1440 bl waitSpd
1441 mtspr 8, r27
1442 bclr 20, 0 /* return to caller */
1443
1444get_lnk_reg:
1445 mflr r3 /* return link reg */
1446 blr
1447
1448/*
1449 * Messages for console output
1450 */
1451.globl MessageBlock
1452MessageBlock:
1453Mok:
1454 .ascii "OK\015\012\000"
1455Mfail:
1456 .ascii "FAILED\015\012\000"
1457Mna:
1458 .ascii "NA\015\012\000"
1459MinitLogo:
1460 .ascii "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
1461 .ascii "\015\012Initialising RAM\015\012\000"
1462Mspd01:
1463 .ascii " Reading SPD of bank0/1 ..... \000"
1464Mspd23:
1465 .ascii " Reading SPD of bank2/3 ..... \000"
1466MfpmRam:
1467 .ascii " RAM-Type: FPM \015\012\000"
1468MedoRam:
1469 .ascii " RAM-Type: EDO \015\012\000"
1470MsdRam:
1471 .ascii " RAM-Type: SDRAM \015\012\000"
1472Mactivate:
1473 .ascii " Activating \000"
1474Mmbyte:
1475 .ascii " MB .......... \000"
1476 .align 4