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