]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/eltec/bab7xx/asm_init.S
* Fix startup problems with VFD display on TRAB
[karo-tx-uboot.git] / board / eltec / bab7xx / asm_init.S
1 /*
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>
27 #include <74xx_7xx.h>
28 #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
73 board_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
177 noSpdError:
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
194 configSDRAM:
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 */
207                                 /* from spd for bank0/1 */
208     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
220 SD64MB2B:
221     li      r20, 0x0005         /* 64-Mbit SDRAM 2 banks */
222     b       SDRow2nd
223
224 SD64MB4B:
225     li      r20, 0x0000         /* 64-Mbit SDRAM 4 banks */
226     b       SDRow2nd
227
228 SD16MB2B:
229     li      r20, 0x000f         /* 16-Mbit SDRAM 2 banks */
230
231 SDRow2nd:
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 */
247                                 /* from spd for bank2/3 */
248     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
260 S2D64MB2B:
261     ori     r20, r20, 0x0050    /* 64-Mbit SDRAM 2 banks */
262     b       S2D64MB4B
263
264 S2D16MB2B:
265     ori     r20, r20, 0x00f0    /* 16-Mbit SDRAM 2 banks */
266
267 /*
268  * set the Memory Configuration Reg. 3
269  */
270 S2D64MB4B:
271     lis     r21, 0x8630         /* BSTOPRE = 0x80, REFREC = 6, */
272                                 /* RDLAT = 3 */
273
274 /*
275  * set the Memory Configuration Reg. 4
276  */
277     lis     r22, 0x2430         /* PRETOACT = 2, ACTOPRE = 4, */
278                                 /* WCBUF = 1, RCBUF = 1 */
279     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 */
288                                 /* (128 MB max.) */
289
290     li      r3, 0x0005          /* get number of banks from spd */
291                                 /* for bank0/1 */
292     bl      spdRead
293
294     cmpi    0, 0, r3, 2         /* 2 banks ? */
295     bne     SDRAMnobank1
296
297     mr      r17, r16
298
299 SDRAMnobank1:
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
313 noFPM23:
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
321 noEDO23:
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
329 noSDRAM23:
330     addi    r3, r13, (Mna-MessageBlock)
331     bl      Printf
332     b       configRAMcommon     /* bank2/3 isn't present or no SDRAM */
333
334 configSDRAM23:
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 */
339                                 /* (128 MB max.) */
340
341     li      r3, 0x0105          /* get number of banks from */
342                                 /* spd bank0/1 */
343     bl      spdRead
344
345     cmpi    0, 0, r3, 2         /* 2 banks ? */
346     bne     SDRAMnobank3
347
348     mr    r19, r18
349
350 SDRAMnobank3:
351     b       configRAMcommon
352
353 configFPM:
354     addi    r3, r13, (MfpmRam-MessageBlock)
355     bl      Printf
356     b       configEDO0
357 /*
358  * set the Memory Configuration Reg. 1
359  */
360 configEDO:
361     addi    r3, r13, (MedoRam-MessageBlock)
362     bl      Printf
363 configEDO0:
364     lis     r20, MCCR1_TYPE_EDO@h
365
366 getSpdRowBank01:
367     li      r3, 0x0003          /* get number of row bits from */
368                                 /* spd from bank0/1 */
369     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
393 getSpdRowBank23:
394     li     r3, 0x0103           /* get number of row bits from */
395                                 /* spd for bank2/3 */
396     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  */
415 writeRowBits:
416     lis     r21, 0x000a         /* CPX = 1, RAS6P = 4 */
417     ori     r21, r21, 0x2293    /* CAS5 = 2, CP4 = 1, */
418                                 /* CAS3 = 2, RCD2 = 2, RP = 3 */
419 /*
420  * set the Memory Configuration Reg. 4
421  */
422     lis     r22, 0x0010         /* all SDRAM parameter 0, */
423                                 /* WCBUF flow through, */
424                                 /* RCBUF registered */
425 /*
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: */
432                                 /* (8*2^row*2^column)/0x100000 MB */
433     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 */
442                                 /* spd for bank0/1 */
443     bl      spdRead
444
445     cmpi    0, 0, r3, 2         /* 2 banks ? */
446     bne     EDOnobank1
447
448     mr      r17, r16
449
450 EDOnobank1:
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
464 noFPM231:
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
472 noEDO231:
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
480 noSDRAM231:
481     addi    r3, r13, (Mfail-MessageBlock)
482     bl      Printf
483     b       configRAMcommon     /* bank2/3 isn't present or no SDRAM */
484
485 EDObank2:
486     li      r3, 0x0103          /* get row bits from spd for bank2/3 */
487     bl      spdRead
488
489     li      r18, 0              /* bank size is: */
490                                 /* (8*2^row*2^column)/0x100000 MB */
491     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 */
500                                 /* spd for bank2/3 */
501     bl      spdRead
502
503     cmpi    0, 0, r3, 2         /* 2 banks ? */
504     bne     configRAMcommon
505
506     mr      r19, r18
507
508 configRAMcommon:
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
572 nobank1:
573     ori     r23, r23, 0x0300    /* set bank1 start to unused area */
574     ori     r24, r24, 0x0300    /* set bank1 end to unused area */
575
576 bank2:
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
597 nobank2:
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
602 bank3:
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
623 nobank3:
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
628 writebound:
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
688 common1:
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
699 common2:
700     mr      r3, r15
701
702 common3:
703     li      r4, 0x1010          /* refesh cycle 1028 clocks */
704                                 /*  left shifted 2 */
705     cmpli   0, 0, r3, 0x0000    /* 15.6 us ? */
706     beq     writeRefresh
707
708     li      r4, 0x0808          /* refesh cycle 514 clocks */
709                                 /* left shifted 2 */
710     cmpli   0, 0, r3, 0x0002    /* 7.8 us ? */
711     beq     writeRefresh
712
713     li      r4, 0x2020          /* refesh cycle 2056 clocks */
714                                 /* left shifted 2 */
715     cmpli   0, 0, r3, 0x0003    /* 31.3 us ? */
716     beq     writeRefresh
717
718     li      r4, 0x4040          /* refesh cycle 4112 clocks */
719                                 /* left shifted 2 */
720     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 */
725                                 /* left shifted 2 */
726     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
733 writeRefresh:
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
761 wait200us:
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
779 wait8ref:
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  */
792 toggleError:
793     li      r0, 0
794     lis     r9, 127
795     ori     r9, r9, 65535
796 toggleError1:
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
803 toggleError2:
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, */
919                                 /* no parity */
920     eieio
921     li      r9, 0x0b
922     stb     r9, 4(r8)           /* enable the receiver and transmitter */
923     eieio
924
925 waitEmpty:
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, */
931                                 /* 2 stop bits, no parity */
932     eieio
933
934     lis     r0, 0x0001
935     mtctr   r0
936
937 waitCOM1:
938     lwz     r0, 5(r8)           /* load from port for delay */
939     bdnz    waitCOM1
940
941 waitEmpty1:
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, */
947                                 /* no parity */
948     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
1077 Printf:
1078     lis     r10, CFG_ISA_IO@h   /* COM1 port */
1079     ori     r10, r10, 0x03f8
1080
1081 WaitChr:
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  */
1099 OutHex2:
1100     li      r9, 4               /* shift reg for 2 digits */
1101     b       OHstart
1102 OutHex4:
1103     li      r9, 12              /* shift reg for 4 digits */
1104     b       OHstart
1105     .globl OutHex
1106 OutHex:
1107     li      r9, 28              /* shift reg for 8 digits */
1108 OHstart:
1109     lis     r10, CFG_ISA_IO@h   /* COM1 port */
1110     ori     r10, r10, 0x03f8
1111 OutDig:
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
1122 digIsNum:
1123     addic   r0, r0, 48
1124 nextDig:
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
1135 OutDec:
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
1159 noblank1:
1160     addi    r3, r7, 48          /* convert to ASCII */
1161
1162 OutDec4:
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 */
1175 OutDec5:
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 */
1185 OutDec6:
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
1199 OutChr:
1200     lis     r10, CFG_ISA_IO@h   /* COM1 port */
1201     ori     r10, r10, 0x03f8
1202
1203 OutChr1:
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  */
1215 spdRead:
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
1229 spdbank0:
1230     li      r12, 0x20           /* set I2C data */
1231     li      r4, 0x40            /* set I2C clock */
1232     li      r6, 0x60            /* set I2C clock and data */
1233
1234 spdRead1:
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  */
1263 AckErr:
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  */
1276 waitSpd:
1277     li      r0, 0x1000
1278     mtctr   r0
1279 wSpd:
1280     bdnz    wSpd
1281     bclr    20, 0               /* return to caller */
1282
1283 /*
1284  * establish START condition on I2C bus
1285  */
1286 spdStart:
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  */
1305 spdStop:
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
1323 spdReadByte:
1324     mfspr   r27, 8
1325     stb     r4, 1(r30)          /* set GPIO for SCL output */
1326     eieio
1327     li      r9, 0x08
1328     li      r10, 0x00
1329 loopRB:
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_ */
1341 clearBit:
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  */
1354 spdWriteByte:
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
1362 sWB1:
1363     stb     r12, 0(r30)         /* set SDA to _1_ */
1364     eieio
1365 sWB2:
1366     stb     r6, 1(r30)          /* set GPIO to output */
1367     eieio
1368 loopWB:
1369     and.    r5, r10, r8
1370     bne     sWB3
1371     stb     r7, 0(r30)          /* set SDA to _0_ */
1372     eieio
1373     b       sWB4
1374 sWB3:
1375     stb     r12, 0(r30)         /* set SDA to _1_ */
1376     eieio
1377 sWB4:
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
1384 sWB5:
1385     stb     r6, 0(r30)          /* set SDA to _1_ and SCL */
1386     eieio
1387 sWB6:
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
1394 sWB7:
1395     stb     r12, 0(r30)         /* set SDA to _1_ and reset SCL */
1396     eieio
1397 sWB8:
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  */
1408 spdReadAck:
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
1427 spdWriteAck:
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
1443 get_lnk_reg:
1444     mflr    r3                  /* return link reg */
1445     blr
1446
1447 /*
1448  * Messages for console output
1449  */
1450 .globl MessageBlock
1451 MessageBlock:
1452 Mok:
1453     .ascii  "OK\015\012\000"
1454 Mfail:
1455     .ascii  "FAILED\015\012\000"
1456 Mna:
1457     .ascii  "NA\015\012\000"
1458 MinitLogo:
1459     .ascii  "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
1460     .ascii  "\015\012Initialising RAM\015\012\000"
1461 Mspd01:
1462     .ascii  "       Reading SPD of bank0/1 ..... \000"
1463 Mspd23:
1464     .ascii  "       Reading SPD of bank2/3 ..... \000"
1465 MfpmRam:
1466     .ascii  "       RAM-Type: FPM \015\012\000"
1467 MedoRam:
1468     .ascii  "       RAM-Type: EDO \015\012\000"
1469 MsdRam:
1470     .ascii  "       RAM-Type: SDRAM \015\012\000"
1471 Mactivate:
1472     .ascii  "       Activating \000"
1473 Mmbyte:
1474     .ascii  " MB .......... \000"
1475     .align  4
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487