]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/eltec/elppc/asm_init.S
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / board / eltec / elppc / asm_init.S
1 /*
2  * (C) Copyright 2001 ELTEC Elektronik AG
3  * Frank Gottschling <fgottschling@eltec.de>
4  *
5  * ELTEC ELPPC 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 <version.h>
29 #include <mpc106.h>
30
31 #include <ppc_asm.tmpl>
32 #include <ppc_defs.h>
33
34 .globl board_asm_init
35 board_asm_init:
36
37 /*
38  * setup pointer to message block
39  */
40     mflr    r13                 /* save away link register */
41     bl      get_lnk_reg         /* r3=addr of next instruction */
42     subi    r4, r3, 8           /* r4=board_asm_init addr */
43     addi    r29, r4, (MessageBlock-board_asm_init)
44
45 /*
46  * dcache_disable
47  */
48     mfspr   r3, HID0
49     li      r4, HID0_DCE
50     andc    r3, r3, r4
51     mr      r2, r3
52     ori     r3, r3, HID0_DCI
53     sync
54     mtspr   HID0, r3
55     mtspr   HID0, r2
56     isync
57     sync
58 /*
59  * icache_disable
60  */
61     mfspr   r3, HID0
62     li      r4, 0
63     ori     r4, r4, HID0_ICE
64     andc    r3, r3, r4
65     sync
66     mtspr   HID0, r3
67 /*
68  * invalidate caches
69  */
70     ori     r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
71     or      r4, r4, r3
72     isync
73     mtspr   HID0, r4
74     andc    r4, r4, r3
75     isync
76     mtspr   HID0, r4
77     isync
78 /*
79  * icache_enable
80  */
81     mfspr   r3, HID0
82     ori     r3, r3, (HID0_ICE | HID0_ICFI)
83     sync
84     mtspr   HID0, r3
85
86
87 /*
88  * setup memory controller
89  */
90     lis     r1, MPC106_REG_ADDR@h
91     ori     r1, r1, MPC106_REG_ADDR@l
92     lis     r2, MPC106_REG_DATA@h
93     ori     r2, r2, MPC106_REG_DATA@l
94
95     /* Configure PICR1 */
96     lis     r3, MPC106_REG@h
97     ori     r3, r3, PCI_PICR1
98     stwbrx  r3, 0, r1
99     addis   r3, r0, 0xFF14
100     ori     r3, r3, 0x1CC8
101     eieio
102     stwbrx  r3, 0, r2
103
104     /* Configure PICR2 */
105     lis     r3, MPC106_REG@h
106     ori     r3, r3, PCI_PICR2
107     stwbrx  r3, 0, r1
108     addis   r3, r0, 0x0000
109     ori     r3, r3, 0x0000
110     eieio
111     stwbrx  r3, 0, r2
112
113     /* Configure EUMBAR */
114     lis     r3, MPC106_REG@h
115     ori     r3, r3, 0x0078      /* offest of EUMBAR in PCI config space */
116     stwbrx  r3, 0, r1
117     lis     r3, MPC107_EUMB_ADDR@h
118     eieio
119     stwbrx  r3, 0, r2
120
121     /* Configure Address Map B Option Reg */
122     lis     r3, MPC106_REG@h
123     ori     r3, r3, 0x00e0      /* offest of AMBOR in PCI config space */
124     stwbrx  r3, 0, r1
125     lis     r3, 0
126     eieio
127     stwbrx  r3, 0, r2
128
129     /* Configure I2C Controller */
130     lis     r14, MPC107_I2C_ADDR@h  /* base of I2C controller */
131     ori     r14, r14, MPC107_I2C_ADDR@l
132     lis     r3, 0x2b10          /* I2C clock = 100MHz/1024 */
133     stw     r3, 4(r14)
134     li      r3, 0               /* clear arbitration */
135     eieio
136     stw     r3, 12(r14)
137
138     /* Configure MCCR1 */
139     lis     r3, MPC106_REG@h
140     ori     r3, r3, MPC106_MCCR1
141     stwbrx  r3, 0, r1
142     addis   r3, r0, 0x0660      /* don't set MEMGO now ! */
143     ori     r3, r3, 0x0000
144     eieio
145     stwbrx  r3, 0, r2
146
147     /* Configure MCCR2 */
148     lis     r3, MPC106_REG@h
149     ori     r3, r3, MPC106_MCCR2
150     stwbrx  r3, 0, r1
151     addis   r3, r0, 0x0400
152     ori     r3, r3, 0x1800
153     eieio
154     stwbrx  r3, 0, r2
155
156
157     /* Configure MCCR3 */
158     lis     r3, MPC106_REG@h
159     ori     r3, r3, MPC106_MCCR3
160     stwbrx  r3, 0, r1
161     addis   r3, r0, 0x0230
162     ori     r3, r3, 0x0000
163     eieio
164     stwbrx  r3, 0, r2
165
166     /* Configure MCCR4 */
167     lis     r3, MPC106_REG@h
168     ori     r3, r3, MPC106_MCCR4
169     stwbrx  r3, 0, r1
170     addis   r3, r0, 0x2532
171     ori     r3, r3, 0x2220
172     eieio
173     stwbrx  r3, 0, r2
174
175 /*
176  * configure memory interface (MICRs)
177  */
178     addis   r3, r0, 0x8000      /* ADDR_80 */
179     ori     r3, r3, 0x0080      /* SMEMADD1 */
180     stwbrx  r3, 0, r1
181     addis   r3, r0, 0xFFFF
182     ori     r3, r3, 0x4000
183     eieio
184     stwbrx  r3, 0, r2
185
186     addis   r3, r0, 0x8000      /* ADDR_84 */
187     ori     r3, r3, 0x0084      /* SMEMADD2 */
188     stwbrx  r3, 0, r1
189     addis   r3, r0, 0xFFFF
190     ori     r3, r3, 0xFFFF
191     eieio
192     stwbrx  r3, 0, r2
193
194     addis   r3, r0, 0x8000      /* ADDR_88 */
195     ori     r3, r3, 0x0088      /* EXTSMEM1 */
196     stwbrx  r3, 0, r1
197     addis   r3, r0, 0x0303
198     ori     r3, r3, 0x0000
199     eieio
200     stwbrx  r3, 0, r2
201
202     addis   r3, r0, 0x8000      /* ADDR_8C */
203     ori     r3, r3, 0x008c      /* EXTSMEM2 */
204     stwbrx  r3, 0, r1
205     addis   r3, r0, 0x0303
206     ori     r3, r3, 0x0303
207     eieio
208     stwbrx  r3, 0, r2
209
210     addis   r3, r0, 0x8000      /* ADDR_90 */
211     ori     r3, r3, 0x0090      /* EMEMADD1 */
212     stwbrx  r3, 0, r1
213     addis   r3, r0, 0xFFFF
214     ori     r3, r3, 0x7F3F
215     eieio
216     stwbrx  r3, 0, r2
217
218     addis   r3, r0, 0x8000      /* ADDR_94 */
219     ori     r3, r3, 0x0094      /* EMEMADD2 */
220     stwbrx  r3, 0, r1
221     addis   r3, r0, 0xFFFF
222     ori     r3, r3, 0xFFFF
223     eieio
224     stwbrx  r3, 0, r2
225
226     addis   r3, r0, 0x8000      /* ADDR_98 */
227     ori     r3, r3, 0x0098      /* EXTEMEM1 */
228     stwbrx  r3, 0, r1
229     addis   r3, r0, 0x0303
230     ori     r3, r3, 0x0000
231     eieio
232     stwbrx  r3, 0, r2
233
234     addis   r3, r0, 0x8000      /* ADDR_9C */
235     ori     r3, r3, 0x009c      /* EXTEMEM2 */
236     stwbrx  r3, 0, r1
237     addis   r3, r0, 0x0303
238     ori     r3, r3, 0x0303
239     eieio
240     stwbrx  r3, 0, r2
241
242     addis   r3, r0, 0x8000      /* ADDR_A0 */
243     ori     r3, r3, 0x00a0      /* MEMBNKEN */
244     stwbrx  r3, 0, r1
245     addis   r3, r0, 0x0000
246     ori     r3, r3, 0x0003
247     eieio
248     stwbrx  r3, 0, r2
249
250 /*
251  * must wait at least 100us after HRESET to issue a MEMGO
252  */
253     lis     r0, 1
254     mtctr   r0
255 memStartWait:
256     bdnz    memStartWait
257
258 /*
259  * enable RAM Operations through MCCR1 (MEMGO)
260  */
261     lis     r3, 0x8000
262     ori     r3, r3, 0x00f0
263     stwbrx  r3, r0, r1
264     sync
265     lwbrx   r3, 0, r2
266     lis     r0, 0x0008
267     or      r3, r0, r3
268     stwbrx  r3, 0, r2
269     sync
270
271 /*
272  * set LEDs first time
273  */
274     li      r3, 0x1
275     lis     r30, CONFIG_SYS_USR_LED_BASE@h
276     stb     r3, 2(r30)
277     sync
278
279 /*
280  * init COM1 for polled output
281  */
282     lis     r8, CONFIG_SYS_NS16550_COM1@h  /* COM1 base address*/
283     ori     r8, r8, CONFIG_SYS_NS16550_COM1@l
284     li      r9, 0x00
285     stb     r9, 1(r8)           /* int disabled */
286     eieio
287     li      r9, 0x00
288     stb     r9, 4(r8)           /* modem ctrl */
289     eieio
290     li      r9, 0x80
291     stb     r9, 3(r8)           /* link ctrl */
292     eieio
293     li      r9, (CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE)
294     stb     r9, 0(r8)           /* baud rate (LSB)*/
295     eieio
296     li      r9, ((CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE) >> 8)
297     stb     r9, 1(r8)           /* baud rate (MSB) */
298     eieio
299     li      r9, 0x07
300     stb     r9, 3(r8)           /* 8 data bits, 2 stop bit, no parity */
301     eieio
302     li      r9, 0x0b
303     stb     r9, 4(r8)           /* enable the receiver and transmitter (modem ctrl) */
304     eieio
305 waitEmpty:
306     lbz     r9, 5(r8)           /* transmit empty */
307     andi.   r9, r9, 0x40
308     beq     waitEmpty
309     li      r9, 0x47
310     stb     r9, 3(r8)           /* send break, 8 data bits, 2 stop bit, no parity */
311     eieio
312
313     lis     r0, 0x0001
314     mtctr   r0
315 waitCOM1:
316     lwz     r0, 5(r8)           /* load from port for delay */
317     bdnz    waitCOM1
318
319 waitEmpty1:
320     lbz     r9, 5(r8)           /* transmit empty */
321     andi.   r9, r9, 0x40
322     beq     waitEmpty1
323     li      r9, 0x07
324     stb     r9, 3(r8)           /* 8 data bits, 2 stop bit, no parity */
325     eieio
326
327 /*
328  * intro message from message block
329  */
330     addi    r3, r29, (MnewLine-MessageBlock)
331     bl      Printf
332     addi    r3, r29, (MinitLogo-MessageBlock)
333     bl      Printf
334
335 /*
336  * memory cofiguration using SPD information stored on the SODIMMs
337  */
338     addi    r3, r29, (Mspd01-MessageBlock)
339     bl      Printf
340
341     li      r17, 0
342
343     li      r3, 0x0002          /* get RAM type from spd for bank0/1 */
344     bl      spdRead
345
346     cmpi    0, 0, r3, -1        /* error ? */
347     bne     noSpdError
348
349     addi    r3, r29, (Mfail-MessageBlock)
350     bl      Printf
351
352     li      r6, 0xe             /* error codes in r6 and r7  */
353     li      r7, 0x0
354     b       toggleError         /* fail - loop forever */
355
356 noSpdError:
357     mr      r15, r3             /* save r3 */
358
359     addi    r3, r29, (Mok-MessageBlock)
360     bl      Printf
361
362     cmpli   0, 0, r15, 0x0004   /* SDRAM ? */
363     beq     isSDRAM
364
365     addi    r3, r29, (MramTyp-MessageBlock)
366     bl      Printf
367
368     li      r6, 0xd             /* error codes in r6 and r7  */
369     li      r7, 0x0
370     b       toggleError         /* fail - loop forever */
371
372 isSDRAM:
373     li      r3, 0x0012          /* get supported CAS latencies from byte 18 */
374     bl      spdRead
375     mr      r15, r3
376     li      r3, 0x09
377     andi.   r0, r15, 0x04
378     bne     maxCLis3
379     li      r3, 0x17
380 maxCLis3:
381     andi.   r0, r15, 0x02
382     bne     CL2
383
384     addi    r3, r29, (MramTyp-MessageBlock)
385     bl      Printf
386
387     li      r6, 0xc             /* error codes in r6 and r7  */
388     li      r7, 0x0
389     b       toggleError         /* fail - loop forever */
390 CL2:
391     bl      spdRead
392     cmpli   0, 0, r3, 0xa1      /* cycle time must be 10ns max. */
393     blt     speedOk
394
395     addi    r3, r29, (MramTyp-MessageBlock)
396     bl      Printf
397
398     li      r6, 0xb             /* error codes in r6 and r7  */
399     li      r7, 0x0
400     b       toggleError         /* fail - loop forever */
401 speedOk:
402     lis     r20, 0x06e8         /* preset MCR1 value */
403
404     li      r3, 0x0011          /* get number of internal banks from spd for bank0/1 */
405     bl      spdRead
406
407     cmpli   0, 0, r3, 0x02
408     beq     SD_2B
409     cmpli   0, 0, r3, 0x04
410     beq     SD_4B
411 memConfErr:
412     addi    r3, r29, (MramConfErr-MessageBlock)
413     bl      Printf
414
415     li      r6, 0xa             /* error codes in r6 and r7  */
416     li      r7, 0x0
417     b       toggleError         /* fail - loop forever */
418
419 SD_2B:
420     li      r3, 0x0003          /* get number of row bits from spd for bank0/1 */
421     bl      spdRead
422     cmpli   0, 0, r3, 0x0b
423     beq     row11x2
424     cmpli   0, 0, r3, 0x0c
425     beq     row12x2or13x2
426     cmpli   0, 0, r3, 0x0d
427     beq     row12x2or13x2
428     b       memConfErr
429 SD_4B:
430     li      r3, 0x0003          /* get number of row bits from spd for bank0/1 */
431     bl      spdRead
432     cmpli   0, 0, r3, 0x0b
433     beq     row11x4or12x4
434     cmpli   0, 0, r3, 0x0c
435     beq     row11x4or12x4
436     cmpli   0, 0, r3, 0x0d
437     beq     row13x4
438     b       memConfErr
439 row12x2or13x2:
440     ori     r20, r20, 0x05
441     b       row11x4or12x4
442 row13x4:
443     ori     r20, r20, 0x0a
444     b       row11x4or12x4
445 row11x2:
446     ori     r20, r20, 0x0f
447 row11x4or12x4:
448     /* get the size of bank 0-1 */
449
450     li      r3, 0x001f          /* get bank size from spd for bank0/1 */
451     bl      spdRead
452
453     rlwinm  r16, r3, 2, 24, 29  /* calculate size in MByte (128 MB max.) */
454
455     li      r3, 0x0005          /* get number of banks from spd for bank0/1 */
456     bl      spdRead
457
458     cmpi    0, 0, r3, 2         /* 2 banks ? */
459     bne     SDRAMnobank1
460
461     mr      r17, r16
462
463 SDRAMnobank1:
464     li      r3, 0x000c          /* get refresh from spd for bank0/1 */
465     bl      spdRead
466     andi.   r3, r3, 0x007f      /* mask selfrefresh bit */
467     li      r4, 0x1800          /* refesh cycle 1536 clocks left shifted 2 */
468     cmpli   0, 0, r3, 0x0000    /* 15.6 us ? */
469     beq     writeRefresh
470
471     li      r4, 0x0c00          /* refesh cycle 768 clocks left shifted 2 */
472     cmpli   0, 0, r3, 0x0002    /* 7.8 us ? */
473     beq     writeRefresh
474
475     li      r4, 0x3000          /* refesh cycle 3072 clocks left shifted 2 */
476     cmpli   0, 0, r3, 0x0003    /* 31.3 us ? */
477     beq     writeRefresh
478
479     li      r4, 0x6000          /* refesh cycle 6144 clocks left shifted 2 */
480     cmpli   0, 0, r3, 0x0004    /* 62.5 us ? */
481     beq     writeRefresh
482
483     li      r4, 0
484     ori     r4, r4, 0xc000      /* refesh cycle 8224 clocks left shifted 2 */
485     cmpli   0, 0, r3, 0x0005    /* 125 us ? */
486     beq     writeRefresh
487
488     b       memConfErr
489
490 writeRefresh:
491     lis     r21, 0x0400         /* preset MCCR2 value */
492     or      r21, r21, r4
493
494     /* Overwrite MCCR1 */
495     lis     r3, MPC106_REG@h
496     ori     r3, r3, MPC106_MCCR1
497     stwbrx  r3, 0, r1
498     eieio
499     stwbrx  r20, 0, r2
500
501     /* Overwrite MCCR2 */
502     lis     r3, MPC106_REG@h
503     ori     r3, r3, MPC106_MCCR2
504     stwbrx  r3, 0, r1
505     eieio
506     stwbrx  r21, 0, r2
507
508     /* set the memory boundary registers for bank 0-3 */
509     li      r20, 0
510     lis     r23, 0x0303
511     lis     r24, 0x0303
512     subi    r21, r16, 1         /* calculate end address bank0 */
513     li      r22, 1
514
515     cmpi    0, 0, r17, 0        /* bank1 present ? */
516     beq     nobank1
517
518     andi.   r3, r16, 0x00ff     /* calculate start address of bank1 */
519     andi.   r4, r16, 0x0300
520     rlwinm  r3, r3, 8, 16, 23
521     or      r20, r20, r3
522     or      r23, r23, r4
523
524     add     r16, r16, r17       /* add to total memory size */
525
526     subi    r3, r16, 1          /* calculate end address of bank1 */
527     andi.   r4, r3, 0x0300
528     andi.   r3, r3, 0x00ff
529     rlwinm  r3, r3, 8, 16, 23
530     or      r21, r21, r3
531     or      r24, r24, r4
532
533     ori     r22, r22, 2         /* enable bank1 */
534     b       bankOk
535 nobank1:
536     ori     r23, r23, 0x0300    /* set bank1 start to unused area */
537     ori     r24, r24, 0x0300    /* set bank1 end to unused area */
538 bankOk:
539     addi    r3, r29, (Mactivate-MessageBlock)
540     bl      Printf
541     mr      r3, r16
542     bl      OutDec
543     addi    r3, r29, (Mact0123e-MessageBlock)
544     bl      Printf
545
546 /*
547  * overwrite MSAR1, MEAR1, EMSAR1, and EMEAR1
548  */
549     addis   r3, r0, 0x8000      /* ADDR_80 */
550     ori     r3, r3, 0x0080      /* MSAR1 */
551     stwbrx  r3, 0, r1
552     eieio
553     stwbrx  r20, 0, r2
554
555     addis   r3, r0, 0x8000      /* ADDR_88 */
556     ori     r3, r3, 0x0088      /* EMSAR1 */
557     stwbrx  r3, 0, r1
558     eieio
559     stwbrx  r23, 0, r2
560
561     addis   r3, r0, 0x8000      /* ADDR_90 */
562     ori     r3, r3, 0x0090      /* MEAR1 */
563     stwbrx  r3, 0, r1
564     eieio
565     stwbrx  r21, 0, r2
566
567     addis   r3, r0, 0x8000      /* ADDR_98 */
568     ori     r3, r3, 0x0098      /* EMEAR1 */
569     stwbrx  r3, 0, r1
570     eieio
571     stwbrx  r24, 0, r2
572
573     addis   r3, r0, 0x8000      /* ADDR_A0 */
574     ori     r3, r3, 0x00a0      /* MBER */
575     stwbrx  r3, 0, r1
576     eieio
577     stwbrx  r22, 0, r2
578
579 /*
580  * delay to let SDRAM go through several initialization/refresh cycles
581  */
582     lis     r3, 3
583     mtctr   r3
584 memStartWait_1:
585     bdnz    memStartWait_1
586     eieio
587
588 /*
589  * set LEDs end
590  */
591     li      r3, 0xf
592     lis     r30, CONFIG_SYS_USR_LED_BASE@h
593     stb     r3, 2(r30)
594     sync
595
596     mtlr    r13
597     blr                         /* EXIT board_asm_init ... */
598
599 /*----------------------------------------------------------------------------*/
600 /*
601  * print a message to COM1 in polling mode (r10=COM1 port, r3=(char*)string)
602  */
603
604 Printf:
605     lis     r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
606     ori     r10, r10, CONFIG_SYS_NS16550_COM1@l
607 WaitChr:
608     lbz     r0, 5(r10)          /* read link status */
609     eieio
610     andi.   r0, r0, 0x40        /* mask transmitter empty bit */
611     beq     cr0, WaitChr        /* wait till empty */
612     lbzx    r0, r0, r3          /* get char */
613     stb     r0, 0(r10)          /* write to transmit reg */
614     eieio
615     addi    r3, r3, 1           /* next char */
616     lbzx    r0, r0, r3          /* get char */
617     cmpwi   cr1, r0, 0          /* end of string ? */
618     bne     cr1, WaitChr
619     blr
620
621 /*
622  * print a char to COM1 in polling mode (r10=COM1 port, r3=char)
623  */
624 OutChr:
625     lis     r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
626     ori     r10, r10, CONFIG_SYS_NS16550_COM1@l
627 OutChr1:
628     lbz     r0, 5(r10)          /* read link status */
629     eieio
630     andi.   r0, r0, 0x40        /* mask transmitter empty bit */
631     beq     cr0, OutChr1        /* wait till empty */
632     stb     r3, 0(r10)          /* write to transmit reg */
633     eieio
634     blr
635
636 /*
637  * print 8/4/2 digits hex value to COM1 in polling mode (r10=COM1 port, r3=val)
638  */
639 OutHex2:
640     li      r9, 4               /* shift reg for 2 digits */
641     b       OHstart
642 OutHex4:
643     li      r9, 12              /* shift reg for 4 digits */
644     b       OHstart
645 OutHex:
646     li      r9, 28              /* shift reg for 8 digits */
647 OHstart:
648     lis     r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
649     ori     r10, r10, CONFIG_SYS_NS16550_COM1@l
650 OutDig:
651     lbz     r0, 0(r29)          /* slow down dummy read */
652     lbz     r0, 5(r10)          /* read link status */
653     eieio
654     andi.   r0, r0, 0x40        /* mask transmitter empty bit */
655     beq     cr0, OutDig
656     sraw    r0, r3, r9
657     clrlwi  r0, r0, 28
658     cmpwi   cr1, r0, 9
659     ble     cr1, digIsNum
660     addic   r0, r0, 55
661     b       nextDig
662 digIsNum:
663     addic   r0, r0, 48
664 nextDig:
665     stb     r0, 0(r10)          /* write to transmit reg */
666     eieio
667     addic.  r9, r9, -4
668     bge     OutDig
669     blr
670
671 /*
672  * print 3 digits hdec value to COM1 in polling mode
673  * (r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch)
674  */
675 OutDec:
676     li      r6, 10
677     divwu   r0, r3, r6          /* r0 = r3 / 10, r9 = r3 mod 10 */
678     mullw   r10, r0, r6
679     subf    r9, r10, r3
680     mr      r3, r0
681     divwu   r0, r3, r6          /* r0 = r3 / 10, r8 = r3 mod 10 */
682     mullw   r10, r0, r6
683     subf    r8, r10, r3
684     mr      r3, r0
685     divwu   r0, r3, r6          /* r0 = r3 / 10, r7 = r3 mod 10 */
686     mullw   r10, r0, r6
687     subf    r7, r10, r3
688     lis     r10, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
689     ori     r10, r10, CONFIG_SYS_NS16550_COM1@l
690     or.     r7, r7, r7
691     bne     noblank1
692     li      r3, 0x20
693     b       OutDec4
694 noblank1:
695     addi    r3, r7, 48          /* convert to ASCII */
696 OutDec4:
697     lbz     r0, 0(r29)          /* slow down dummy read */
698     lbz     r0, 5(r10)          /* read link status */
699     eieio
700     andi.   r0, r0, 0x40        /* mask transmitter empty bit */
701     beq     cr0, OutDec4
702     stb     r3, 0(r10)          /* x00 to transmit */
703     eieio
704     or.     r7, r7, r8
705     beq     OutDec5
706     addi    r3, r8, 48          /* convert to ASCII */
707 OutDec5:
708     lbz     r0, 0(r29)          /* slow down dummy read */
709     lbz     r0, 5(r10)          /* read link status */
710     eieio
711     andi.   r0, r0, 0x40        /* mask transmitter empty bit */
712     beq     cr0, OutDec5
713     stb     r3, 0(r10)          /* x0  to transmit */
714     eieio
715     addi    r3, r9, 48          /* convert to ASCII */
716 OutDec6:
717     lbz     r0, 0(r29)          /* slow down dummy read */
718     lbz     r0, 5(r10)          /* read link status */
719     eieio
720     andi.   r0, r0, 0x40        /* mask transmitter empty bit */
721     beq     cr0, OutDec6
722     stb     r3, 0(r10)          /* x   to transmit */
723     eieio
724     blr
725
726 /*
727  * hang endless loop
728  */
729 toggleError:                    /* fail type in r6, r7=0xff, toggle LEDs */
730     stb     r7, 2(r30)          /* r7 to LED */
731     li      r0, 0
732     lis     r9, 127
733     ori     r9, r9, 65535
734 toggleError1:
735     addic   r0, r0, 1
736     cmpw    cr1, r0, r9
737     ble     cr1, toggleError1
738     stb     r6, 2(r30)          /* r6 to LED */
739     li      r0, 0
740     lis     r9, 127
741     ori     r9, r9, 65535
742 toggleError2:
743     addic   r0, r0, 1
744     cmpw    cr1, r0, r9
745     ble     cr1, toggleError2
746     b       toggleError
747
748 /*
749  * routines to read from ram spd
750  */
751 spdWaitIdle:
752     lis     r0, 0x1             /* timeout for about 100us */
753     mtctr   r0
754 iSpd:
755     lbz     r10, 12(r14)
756     andi.   r10, r10, 0x20      /* mask and test MBB */
757     beq     idle
758     bdnz    iSpd
759     orc.    r10, r0, r0         /* return -1 to caller */
760 idle:
761     bclr    20, 0               /* return to caller */
762
763 waitSpd:
764     lis     r0, 0x10            /* timeout for about 1.5ms */
765     mtctr   r0
766 wSpd:
767     lbz     r10, 12(r14)
768     andi.   r10, r10, 0x82
769     cmpli   0, 0, r10, 0x82     /* test MCF and MIF set */
770     beq     wend
771     bdnz    wSpd
772     orc.    r10, r0, r0         /* return -1 to caller */
773     bclr    20, 0               /* return to caller */
774
775 wend:
776     li      r10, 0
777     stb     r10, 12(r14)        /* clear status */
778     bclr    20, 0               /* return to caller */
779
780 /*
781  * spdread
782  * in:  r3 adr to read
783  * out: r3 val or -1 for error
784  * uses r10, assumes that r14 points to I2C controller
785  */
786 spdRead:
787     mfspr   r25, 8              /* save link register */
788
789     bl      spdWaitIdle
790     bne     spdErr
791
792     li      r10, 0x80           /* start with MEN */
793     stb     r10, 8(r14)
794     eieio
795
796     li      r10, 0xb0           /* start as master */
797     stb     r10, 8(r14)
798     eieio
799
800     li      r10, 0xa0           /* write device 0xA0 */
801     stb     r10, 16(r14)
802     eieio
803     bl      waitSpd
804     bne     spdErr
805
806     lbz     r10, 12(r14)        /* test ACK */
807     andi.   r10, r10, 0x01
808     bne     gotNoAck
809
810     stb     r3, 16(r14)         /* data address */
811     eieio
812     bl      waitSpd
813     bne     spdErr
814
815
816     li      r10, 0xb4           /* switch to read - restart */
817     stb     r10, 8(r14)
818     eieio
819
820     li      r10, 0xa1           /* read device 0xA0 */
821     stb     r10, 16(r14)
822     eieio
823     bl      waitSpd
824     bne     spdErr
825
826     li      r10, 0xa8           /* no ACK */
827     stb     r10, 8(r14)
828     eieio
829
830     lbz     r10, 16(r14)        /* trigger read next byte */
831     eieio
832     bl      waitSpd
833     bne     spdErr
834
835     li      r10, 0x88           /* generate STOP condition */
836     stb     r10, 8(r14)
837     eieio
838
839     lbz     r3, 16(r14)         /* return read byte */
840
841     mtspr   8, r25              /* restore link register */
842     blr
843
844 gotNoAck:
845     li      r10, 0x80           /* generate STOP condition */
846     stb     r10, 8(r14)
847     eieio
848 spdErr:
849     orc     r3, r0, r0          /* return -1 */
850     mtspr   8, r25              /* restore link register */
851     blr
852
853 get_lnk_reg:
854     mflr    r3                  /* return link reg */
855     blr
856
857 MessageBlock:
858
859 MinitLogo:
860     .ascii  "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
861     .ascii  "\015\012Initialising RAM\015\012\000"
862 Mspd01:
863     .ascii  "       Reading SPD of SODIMM ...... \000"
864 MramTyp:
865     .ascii  "\015\012\SDRAM with CL=2 at 100 MHz required!\015\012\000"
866 MramConfErr:
867     .ascii  "\015\012\Unsupported SODIMM Configuration!\015\012\000"
868 Mactivate:
869     .ascii  "       Activating \000"
870 Mact0123e:
871     .ascii  " MByte.\015\012\000"
872 Mok:
873     .ascii  "OK \015\012\000"
874 Mfail:
875     .ascii  "FAILED \015\012\000"
876 MnewLine:
877     .ascii  "\015\012\000"
878     .align 4