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