]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/eltec/bab7xx/asm_init.S
imported Freescale specific U-Boot additions for i.MX28,... release L2.6.31_10.08.01
[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 <asm/processor.h>
28 #include <74xx_7xx.h>
29 #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
74 board_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 CONFIG_SYS_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
178 noSpdError:
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
195 configSDRAM:
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 */
208                                 /* from spd for bank0/1 */
209     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
221 SD64MB2B:
222     li      r20, 0x0005         /* 64-Mbit SDRAM 2 banks */
223     b       SDRow2nd
224
225 SD64MB4B:
226     li      r20, 0x0000         /* 64-Mbit SDRAM 4 banks */
227     b       SDRow2nd
228
229 SD16MB2B:
230     li      r20, 0x000f         /* 16-Mbit SDRAM 2 banks */
231
232 SDRow2nd:
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 */
248                                 /* from spd for bank2/3 */
249     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
261 S2D64MB2B:
262     ori     r20, r20, 0x0050    /* 64-Mbit SDRAM 2 banks */
263     b       S2D64MB4B
264
265 S2D16MB2B:
266     ori     r20, r20, 0x00f0    /* 16-Mbit SDRAM 2 banks */
267
268 /*
269  * set the Memory Configuration Reg. 3
270  */
271 S2D64MB4B:
272     lis     r21, 0x8630         /* BSTOPRE = 0x80, REFREC = 6, */
273                                 /* RDLAT = 3 */
274
275 /*
276  * set the Memory Configuration Reg. 4
277  */
278     lis     r22, 0x2430         /* PRETOACT = 2, ACTOPRE = 4, */
279                                 /* WCBUF = 1, RCBUF = 1 */
280     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 */
289                                 /* (128 MB max.) */
290
291     li      r3, 0x0005          /* get number of banks from spd */
292                                 /* for bank0/1 */
293     bl      spdRead
294
295     cmpi    0, 0, r3, 2         /* 2 banks ? */
296     bne     SDRAMnobank1
297
298     mr      r17, r16
299
300 SDRAMnobank1:
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
314 noFPM23:
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
322 noEDO23:
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
330 noSDRAM23:
331     addi    r3, r13, (Mna-MessageBlock)
332     bl      Printf
333     b       configRAMcommon     /* bank2/3 isn't present or no SDRAM */
334
335 configSDRAM23:
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 */
340                                 /* (128 MB max.) */
341
342     li      r3, 0x0105          /* get number of banks from */
343                                 /* spd bank0/1 */
344     bl      spdRead
345
346     cmpi    0, 0, r3, 2         /* 2 banks ? */
347     bne     SDRAMnobank3
348
349     mr    r19, r18
350
351 SDRAMnobank3:
352     b       configRAMcommon
353
354 configFPM:
355     addi    r3, r13, (MfpmRam-MessageBlock)
356     bl      Printf
357     b       configEDO0
358 /*
359  * set the Memory Configuration Reg. 1
360  */
361 configEDO:
362     addi    r3, r13, (MedoRam-MessageBlock)
363     bl      Printf
364 configEDO0:
365     lis     r20, MCCR1_TYPE_EDO@h
366
367 getSpdRowBank01:
368     li      r3, 0x0003          /* get number of row bits from */
369                                 /* spd from bank0/1 */
370     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
394 getSpdRowBank23:
395     li     r3, 0x0103           /* get number of row bits from */
396                                 /* spd for bank2/3 */
397     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  */
416 writeRowBits:
417     lis     r21, 0x000a         /* CPX = 1, RAS6P = 4 */
418     ori     r21, r21, 0x2293    /* CAS5 = 2, CP4 = 1, */
419                                 /* CAS3 = 2, RCD2 = 2, RP = 3 */
420 /*
421  * set the Memory Configuration Reg. 4
422  */
423     lis     r22, 0x0010         /* all SDRAM parameter 0, */
424                                 /* WCBUF flow through, */
425                                 /* RCBUF registered */
426 /*
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: */
433                                 /* (8*2^row*2^column)/0x100000 MB */
434     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 */
443                                 /* spd for bank0/1 */
444     bl      spdRead
445
446     cmpi    0, 0, r3, 2         /* 2 banks ? */
447     bne     EDOnobank1
448
449     mr      r17, r16
450
451 EDOnobank1:
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
465 noFPM231:
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
473 noEDO231:
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
481 noSDRAM231:
482     addi    r3, r13, (Mfail-MessageBlock)
483     bl      Printf
484     b       configRAMcommon     /* bank2/3 isn't present or no SDRAM */
485
486 EDObank2:
487     li      r3, 0x0103          /* get row bits from spd for bank2/3 */
488     bl      spdRead
489
490     li      r18, 0              /* bank size is: */
491                                 /* (8*2^row*2^column)/0x100000 MB */
492     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 */
501                                 /* spd for bank2/3 */
502     bl      spdRead
503
504     cmpi    0, 0, r3, 2         /* 2 banks ? */
505     bne     configRAMcommon
506
507     mr      r19, r18
508
509 configRAMcommon:
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
573 nobank1:
574     ori     r23, r23, 0x0300    /* set bank1 start to unused area */
575     ori     r24, r24, 0x0300    /* set bank1 end to unused area */
576
577 bank2:
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
598 nobank2:
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
603 bank3:
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
624 nobank3:
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
629 writebound:
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
689 common1:
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
700 common2:
701     mr      r3, r15
702
703 common3:
704     li      r4, 0x1010          /* refesh cycle 1028 clocks */
705                                 /*  left shifted 2 */
706     cmpli   0, 0, r3, 0x0000    /* 15.6 us ? */
707     beq     writeRefresh
708
709     li      r4, 0x0808          /* refesh cycle 514 clocks */
710                                 /* left shifted 2 */
711     cmpli   0, 0, r3, 0x0002    /* 7.8 us ? */
712     beq     writeRefresh
713
714     li      r4, 0x2020          /* refesh cycle 2056 clocks */
715                                 /* left shifted 2 */
716     cmpli   0, 0, r3, 0x0003    /* 31.3 us ? */
717     beq     writeRefresh
718
719     li      r4, 0x4040          /* refesh cycle 4112 clocks */
720                                 /* left shifted 2 */
721     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 */
726                                 /* left shifted 2 */
727     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
734 writeRefresh:
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
762 wait200us:
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
780 wait8ref:
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  */
793 toggleError:
794     li      r0, 0
795     lis     r9, 127
796     ori     r9, r9, 65535
797 toggleError1:
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
804 toggleError2:
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, CONFIG_SYS_ISA_IO@h
839     ori     r6, r6, CONFIG_SYS_ISA_IO@l
840
841 /*
842  * Set offset to base address for config registers.
843  */
844 #if defined(CONFIG_SYS_NS87308_BADDR_0x)
845     addi    r4, r0, 0x0279
846 #elif defined(CONFIG_SYS_NS87308_BADDR_10)
847     addi    r4, r0, 0x015C
848 #elif defined(CONFIG_SYS_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, CONFIG_SYS_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, CONFIG_SYS_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, */
920                                 /* no parity */
921     eieio
922     li      r9, 0x0b
923     stb     r9, 4(r8)           /* enable the receiver and transmitter */
924     eieio
925
926 waitEmpty:
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, */
932                                 /* 2 stop bits, no parity */
933     eieio
934
935     lis     r0, 0x0001
936     mtctr   r0
937
938 waitCOM1:
939     lwz     r0, 5(r8)           /* load from port for delay */
940     bdnz    waitCOM1
941
942 waitEmpty1:
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, */
948                                 /* no parity */
949     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, CONFIG_SYS_ISA_IO@h
976     ori     r3, r3, CONFIG_SYS_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
1078 Printf:
1079     lis     r10, CONFIG_SYS_ISA_IO@h   /* COM1 port */
1080     ori     r10, r10, 0x03f8
1081
1082 WaitChr:
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  */
1100 OutHex2:
1101     li      r9, 4               /* shift reg for 2 digits */
1102     b       OHstart
1103 OutHex4:
1104     li      r9, 12              /* shift reg for 4 digits */
1105     b       OHstart
1106     .globl OutHex
1107 OutHex:
1108     li      r9, 28              /* shift reg for 8 digits */
1109 OHstart:
1110     lis     r10, CONFIG_SYS_ISA_IO@h   /* COM1 port */
1111     ori     r10, r10, 0x03f8
1112 OutDig:
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
1123 digIsNum:
1124     addic   r0, r0, 48
1125 nextDig:
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
1136 OutDec:
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, CONFIG_SYS_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
1160 noblank1:
1161     addi    r3, r7, 48          /* convert to ASCII */
1162
1163 OutDec4:
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 */
1176 OutDec5:
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 */
1186 OutDec6:
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
1200 OutChr:
1201     lis     r10, CONFIG_SYS_ISA_IO@h   /* COM1 port */
1202     ori     r10, r10, 0x03f8
1203
1204 OutChr1:
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  */
1216 spdRead:
1217     mfspr   r26, 8              /* save link register */
1218
1219     lis     r30, CONFIG_SYS_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
1230 spdbank0:
1231     li      r12, 0x20           /* set I2C data */
1232     li      r4, 0x40            /* set I2C clock */
1233     li      r6, 0x60            /* set I2C clock and data */
1234
1235 spdRead1:
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  */
1264 AckErr:
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  */
1277 waitSpd:
1278     li      r0, 0x1000
1279     mtctr   r0
1280 wSpd:
1281     bdnz    wSpd
1282     bclr    20, 0               /* return to caller */
1283
1284 /*
1285  * establish START condition on I2C bus
1286  */
1287 spdStart:
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  */
1306 spdStop:
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
1324 spdReadByte:
1325     mfspr   r27, 8
1326     stb     r4, 1(r30)          /* set GPIO for SCL output */
1327     eieio
1328     li      r9, 0x08
1329     li      r10, 0x00
1330 loopRB:
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_ */
1342 clearBit:
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  */
1355 spdWriteByte:
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
1363 sWB1:
1364     stb     r12, 0(r30)         /* set SDA to _1_ */
1365     eieio
1366 sWB2:
1367     stb     r6, 1(r30)          /* set GPIO to output */
1368     eieio
1369 loopWB:
1370     and.    r5, r10, r8
1371     bne     sWB3
1372     stb     r7, 0(r30)          /* set SDA to _0_ */
1373     eieio
1374     b       sWB4
1375 sWB3:
1376     stb     r12, 0(r30)         /* set SDA to _1_ */
1377     eieio
1378 sWB4:
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
1385 sWB5:
1386     stb     r6, 0(r30)          /* set SDA to _1_ and SCL */
1387     eieio
1388 sWB6:
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
1395 sWB7:
1396     stb     r12, 0(r30)         /* set SDA to _1_ and reset SCL */
1397     eieio
1398 sWB8:
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  */
1409 spdReadAck:
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
1428 spdWriteAck:
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
1444 get_lnk_reg:
1445     mflr    r3                  /* return link reg */
1446     blr
1447
1448 /*
1449  * Messages for console output
1450  */
1451 .globl MessageBlock
1452 MessageBlock:
1453 Mok:
1454     .ascii  "OK\015\012\000"
1455 Mfail:
1456     .ascii  "FAILED\015\012\000"
1457 Mna:
1458     .ascii  "NA\015\012\000"
1459 MinitLogo:
1460     .ascii  "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
1461     .ascii  "\015\012Initialising RAM\015\012\000"
1462 Mspd01:
1463     .ascii  "       Reading SPD of bank0/1 ..... \000"
1464 Mspd23:
1465     .ascii  "       Reading SPD of bank2/3 ..... \000"
1466 MfpmRam:
1467     .ascii  "       RAM-Type: FPM \015\012\000"
1468 MedoRam:
1469     .ascii  "       RAM-Type: EDO \015\012\000"
1470 MsdRam:
1471     .ascii  "       RAM-Type: SDRAM \015\012\000"
1472 Mactivate:
1473     .ascii  "       Activating \000"
1474 Mmbyte:
1475     .ascii  " MB .......... \000"
1476     .align  4