2 * (C) Copyright 2001 ELTEC Elektronik AG
3 * Frank Gottschling <fgottschling@eltec.de>
5 * ELTEC BAB PPC RAM initialization
7 * See file CREDITS for list of people who contributed to this
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.
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.
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,
31 #include <ppc_asm.tmpl>
35 * This following contains the entry code for the initialization code
36 * for the MPC 106, a PCI Bridge/Memory Controller.
38 * r0 = ramtest scratch register, toggleError loop counter
39 * r1 = 0xfec0 0cf8 CONFIG_ADDRESS
40 * r2 = 0xfee0 0cfc CONFIG_DATA
41 * r3 = scratch register, subroutine argument and return value, ramtest size
42 * r4 = scratch register, spdRead clock mask, OutHex loop count
43 * r5 = ramtest scratch register
44 * r6 = toggleError 1st value, spdRead port mask
45 * r7 = toggleError 2nd value, ramtest scratch register,
46 * spdRead scratch register (0x00)
47 * r8 = ramtest scratch register, spdRead scratch register (0x80)
48 * r9 = ramtest scratch register, toggleError loop end, OutHex digit
49 * r10 = ramtest scratch register, spdWriteByte parameter,
50 * spdReadByte return value, printf pointer to COM1
52 * r12 = ramtest scratch register, spdRead data mask
53 * r13 = pointer to message block
54 * r14 = pointer to GOT
55 * r15 = scratch register, SPD save
56 * r16 = bank0 size, total memory size
65 * r25 = save link register 1st level
66 * r26 = save link register 2nd level
67 * r27 = save link register 3rd level
68 * r30 = pointer to GPIO for spdRead
75 * setup pointer to message block
77 mflr r25 /* save away link register */
78 bl get_lnk_reg /* r3=addr of next instruction */
79 subi r4, r3, 8 /* r4=board_asm_init addr */
80 addi r13, r4, (MessageBlock-board_asm_init)
106 ori r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
118 ori r3, r3, (HID0_ICE | HID0_ICFI)
127 #ifdef CFG_ADDRESS_MAP_A
129 * Switch to address map A if necessary.
132 ori r3, r3, PCI_PICR1
137 lis r0, PICR1_XIO_MODE@h
138 ori r0, r0, PICR1_XIO_MODE@l
140 lis r0, PICR1_ADDRESS_MAP@h
141 ori r0, r0, PICR1_ADDRESS_MAP@l
148 * Do the init for the SIO.
152 addi r3, r13, (MinitLogo-MessageBlock)
155 addi r3, r13, (Mspd01-MessageBlock)
158 * Memory cofiguration using SPD information stored on the SODIMMs
164 li r3, 0x0002 /* get RAM type from spd for bank0/1 */
167 cmpi 0, 0, r3, -1 /* error ? */
170 addi r3, r13, (Mfail-MessageBlock)
173 li r6, 0xe0 /* error codes in r6 and r7 */
175 b toggleError /* fail - loop forever */
178 mr r15, r3 /* save r3 */
180 addi r3, r13, (Mok-MessageBlock)
183 cmpli 0, 0, r15, 0x0001 /* FPM ? */
185 cmpli 0, 0, r15, 0x0002 /* EDO ? */
187 cmpli 0, 0, r15, 0x0004 /* SDRAM ? */
190 li r6, 0xe0 /* error codes in r6 and r7 */
192 b toggleError /* fail - loop forever */
195 addi r3, r13, (MsdRam-MessageBlock)
198 * set the Memory Configuration Reg. 1
200 li r3, 0x001f /* get bank size from spd bank0/1 */
206 li r3, 0x0011 /* get number of internal banks */
207 /* from spd for bank0/1 */
216 li r6, 0xe0 /* error codes in r6 and r7 */
218 b toggleError /* fail - loop forever */
221 li r20, 0x0005 /* 64-Mbit SDRAM 2 banks */
225 li r20, 0x0000 /* 64-Mbit SDRAM 4 banks */
229 li r20, 0x000f /* 16-Mbit SDRAM 2 banks */
232 li r3, 0x0102 /* get RAM type spd for bank2/3 */
235 cmpli 0, 0, r3, 0x0004
236 bne S2D64MB4B /* bank2/3 isn't present or no SDRAM */
238 li r3, 0x011f /* get bank size from spd bank2/3 */
244 * set the Memory Configuration Reg. 2
246 li r3, 0x0111 /* get number of internal banks */
247 /* from spd for bank2/3 */
256 li r6, 0xe0 /* error codes in r6 and r7 */
258 b toggleError /* fail - loop forever */
261 ori r20, r20, 0x0050 /* 64-Mbit SDRAM 2 banks */
265 ori r20, r20, 0x00f0 /* 16-Mbit SDRAM 2 banks */
268 * set the Memory Configuration Reg. 3
271 lis r21, 0x8630 /* BSTOPRE = 0x80, REFREC = 6, */
275 * set the Memory Configuration Reg. 4
277 lis r22, 0x2430 /* PRETOACT = 2, ACTOPRE = 4, */
278 /* WCBUF = 1, RCBUF = 1 */
279 ori r22, r22, 0x2220 /* SDMODE = 0x022, ACTORW = 2 */
282 * get the size of bank 0-3
284 li r3, 0x001f /* get bank size from spd bank0/1 */
287 rlwinm r16, r3, 2, 24, 29 /* calculate size in MByte */
290 li r3, 0x0005 /* get number of banks from spd */
294 cmpi 0, 0, r3, 2 /* 2 banks ? */
300 addi r3, r13, (Mspd23-MessageBlock)
303 li r3, 0x0102 /* get RAM type spd for bank2/3 */
306 cmpli 0, 0, r3, 0x0001 /* FPM ? */
307 bne noFPM23 /* handle as EDO */
308 addi r3, r13, (Mok-MessageBlock)
310 addi r3, r13, (MfpmRam-MessageBlock)
314 cmpli 0, 0, r3, 0x0002 /* EDO ? */
316 addi r3, r13, (Mok-MessageBlock)
318 addi r3, r13, (MedoRam-MessageBlock)
322 cmpli 0, 0, r3, 0x0004 /* SDRAM ? */
324 addi r3, r13, (Mok-MessageBlock)
326 addi r3, r13, (MsdRam-MessageBlock)
330 addi r3, r13, (Mna-MessageBlock)
332 b configRAMcommon /* bank2/3 isn't present or no SDRAM */
335 li r3, 0x011f /* get bank size from spd bank2/3 */
338 rlwinm r18, r3, 2, 24, 29 /* calculate size in MByte */
341 li r3, 0x0105 /* get number of banks from */
345 cmpi 0, 0, r3, 2 /* 2 banks ? */
354 addi r3, r13, (MfpmRam-MessageBlock)
358 * set the Memory Configuration Reg. 1
361 addi r3, r13, (MedoRam-MessageBlock)
364 lis r20, MCCR1_TYPE_EDO@h
367 li r3, 0x0003 /* get number of row bits from */
368 /* spd from bank0/1 */
370 ori r20, r20, (MCCR1_BK0_9BITS | MCCR1_BK1_9BITS)
371 cmpli 0, 0, r3, 0x0009 /* bank0 - 9 row bits */
374 ori r20, r20, (MCCR1_BK0_10BITS | MCCR1_BK1_10BITS)
375 cmpli 0, 0, r3, 0x000a /* bank0 - 10 row bits */
378 ori r20, r20, (MCCR1_BK0_11BITS | MCCR1_BK1_11BITS)
379 cmpli 0, 0, r3, 0x000b /* bank0 - 11 row bits */
382 ori r20, r20, (MCCR1_BK0_12BITS | MCCR1_BK1_12BITS)
383 cmpli 0, 0, r3, 0x000c /* bank0 - 12 row bits */
386 cmpli 0, 0, r3, 0x000d /* bank0 - 13 row bits */
389 li r6, 0xe0 /* error codes in r6 and r7 */
391 b toggleError /* fail - loop forever */
394 li r3, 0x0103 /* get number of row bits from */
395 /* spd for bank2/3 */
398 ori r20, r20, (MCCR1_BK2_9BITS | MCCR1_BK3_9BITS)
399 cmpli 0, 0, r3, 0x0009 /* bank0 - 9 row bits */
402 ori r20, r20, (MCCR1_BK2_10BITS | MCCR1_BK3_10BITS)
403 cmpli 0, 0, r3, 0x000a /* bank0 - 10 row bits */
406 ori r20, r20, (MCCR1_BK2_11BITS | MCCR1_BK3_11BITS)
407 cmpli 0, 0, r3, 0x000b /* bank0 - 11 row bits */
410 ori r20, r20, (MCCR1_BK2_12BITS | MCCR1_BK3_12BITS)
413 * set the Memory Configuration Reg. 3
416 lis r21, 0x000a /* CPX = 1, RAS6P = 4 */
417 ori r21, r21, 0x2293 /* CAS5 = 2, CP4 = 1, */
418 /* CAS3 = 2, RCD2 = 2, RP = 3 */
420 * set the Memory Configuration Reg. 4
422 lis r22, 0x0010 /* all SDRAM parameter 0, */
423 /* WCBUF flow through, */
424 /* RCBUF registered */
426 * get the size of bank 0-3
428 li r3, 0x0003 /* get row bits from spd bank0/1 */
431 li r16, 0 /* bank size is: */
432 /* (8*2^row*2^column)/0x100000 MB */
434 rlwnm r16, r16, r3, 0, 31
436 li r3, 0x0004 /* get column bits from spd bank0/1 */
439 rlwnm r16, r16, r3, 0, 31
441 li r3, 0x0005 /* get number of banks from */
442 /* spd for bank0/1 */
445 cmpi 0, 0, r3, 2 /* 2 banks ? */
451 addi r3, r13, (Mspd23-MessageBlock)
454 li r3, 0x0102 /* get RAM type spd for bank2/3 */
457 cmpli 0, 0, r3, 0x0001 /* FPM ? */
458 bne noFPM231 /* handle as EDO */
459 addi r3, r13, (Mok-MessageBlock)
461 addi r3, r13, (MfpmRam-MessageBlock)
465 cmpli 0, 0, r3, 0x0002 /* EDO ? */
467 addi r3, r13, (Mok-MessageBlock)
469 addi r3, r13, (MedoRam-MessageBlock)
473 cmpli 0, 0, r3, 0x0004 /* SDRAM ? */
475 addi r3, r13, (Mok-MessageBlock)
477 addi r3, r13, (MsdRam-MessageBlock)
481 addi r3, r13, (Mfail-MessageBlock)
483 b configRAMcommon /* bank2/3 isn't present or no SDRAM */
486 li r3, 0x0103 /* get row bits from spd for bank2/3 */
489 li r18, 0 /* bank size is: */
490 /* (8*2^row*2^column)/0x100000 MB */
492 rlwnm r18, r18, r3, 0, 31
494 li r3, 0x0104 /* get column bits from spd bank2/3 */
497 rlwnm r18, r18, r3, 0, 31
499 li r3, 0x0105 /* get number of banks from */
500 /* spd for bank2/3 */
503 cmpi 0, 0, r3, 2 /* 2 banks ? */
509 lis r1, MPC106_REG_ADDR@h
510 ori r1, r1, MPC106_REG_ADDR@l
511 lis r2, MPC106_REG_DATA@h
512 ori r2, r2, MPC106_REG_DATA@l
517 * If we are already running in RAM (debug mode), we should
518 * NOT reset the MEMGO flag. Otherwise we will stop all memory
522 lis r4, MCCR1_MEMGO@h
523 ori r4, r4, MCCR1_MEMGO@l
528 * set the Memory Configuration Reg. 1
530 lis r3, MPC106_REG@h /* start building new reg number */
531 ori r3, r3, MPC106_MCCR1 /* register number 0xf0 */
532 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
533 eieio /* make sure mem. access is complete */
534 stwbrx r20, r0, r2 /* write data to CONFIG_DATA */
536 * set the Memory Configuration Reg. 3
538 lis r3, MPC106_REG@h /* start building new reg number */
539 ori r3, r3, MPC106_MCCR3 /* register number 0xf8 */
540 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
541 eieio /* make sure mem. access is complete */
542 stwbrx r21, r0, r2 /* write data to CONFIG_DATA */
544 * set the Memory Configuration Reg. 4
546 lis r3, MPC106_REG@h /* start building new reg number */
547 ori r3, r3, MPC106_MCCR4 /* register number 0xfc */
548 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
549 eieio /* make sure mem. access is complete */
550 stwbrx r22, r0, r2 /* write data to CONFIG_DATA */
552 * set the memory boundary registers for bank 0-3
557 subi r21, r16, 1 /* calculate end address bank0 */
560 cmpi 0, 0, r17, 0 /* bank1 present ? */
563 rlwinm r3, r16, 8, 16, 23 /* calculate start address of bank1 */
565 add r16, r16, r17 /* add to total memory size */
566 subi r3, r16, 1 /* calculate end address of bank1 */
567 rlwinm r3, r3, 8, 16, 23
569 ori r22, r22, (MBER_BANK1) /* enable bank1 */
573 ori r23, r23, 0x0300 /* set bank1 start to unused area */
574 ori r24, r24, 0x0300 /* set bank1 end to unused area */
577 cmpi 0, 0, r18, 0 /* bank2 present ? */
580 andi. r3, r16, 0x00ff /* calculate start address of bank2 */
581 andi. r4, r16, 0x0300
582 rlwinm r3, r3, 16, 8, 15
584 rlwinm r3, r4, 8, 8, 15
586 add r16, r16, r18 /* add to total memory size */
587 subi r3, r16, 1 /* calculate end address of bank2 */
590 rlwinm r3, r3, 16, 8, 15
592 rlwinm r3, r4, 8, 8, 15
594 ori r22, r22, (MBER_BANK2) /* enable bank2 */
599 or r23, r23, r3 /* set bank2 start to unused area */
600 or r24, r24, r3 /* set bank2 end to unused area */
603 cmpi 0, 0, r19, 0 /* bank3 present ? */
606 andi. r3, r16, 0x00ff /* calculate start address of bank3 */
607 andi. r4, r16, 0x0300
608 rlwinm r3, r3, 24, 0, 7
610 rlwinm r3, r4, 16, 0, 7
612 add r16, r16, r19 /* add to total memory size */
613 subi r3, r16, 1 /* calculate end address of bank3 */
616 rlwinm r3, r3, 24, 0, 7
618 rlwinm r3, r4, 16, 0, 7
620 ori r22, r22, (MBER_BANK3) /* enable bank3 */
625 or r23, r23, r3 /* set bank3 start to unused area */
626 or r24, r24, r3 /* set bank3 end to unused area */
629 lis r3, MPC106_REG@h /* start building new reg number */
630 ori r3, r3, MPC106_MSAR1 /* register number 0x80 */
631 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
632 eieio /* make sure mem. access is complete */
633 stwbrx r20, r0, r2 /* write data to CONFIG_DATA */
635 lis r3, MPC106_REG@h /* start building new reg number */
636 ori r3, r3, MPC106_MEAR1 /* register number 0x90 */
637 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
638 eieio /* make sure mem. access is complete */
639 stwbrx r21, r0, r2 /* write data to CONFIG_DATA */
641 lis r3, MPC106_REG@h /* start building new reg number */
642 ori r3, r3, MPC106_EMSAR1 /* register number 0x88 */
643 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
644 eieio /* make sure mem. access is complete */
645 stwbrx r23, r0, r2 /* write data to CONFIG_DATA */
647 lis r3, MPC106_REG@h /* start building new reg number */
648 ori r3, r3, MPC106_EMEAR1 /* register number 0x98 */
649 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
650 eieio /* make sure mem. access is complete */
651 stwbrx r24, r0, r2 /* write data to CONFIG_DATA */
654 * set boundaries of unused banks to unused address space
657 ori r4, r4, 0x0303 /* bank 4-7 start and end adresses */
658 lis r3, MPC106_REG@h /* start building new reg number */
659 ori r3, r3, MPC106_EMSAR2 /* register number 0x8C */
660 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
661 eieio /* make sure mem. access is complete */
662 stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
664 lis r3, MPC106_REG@h /* start building new reg number */
665 ori r3, r3, MPC106_EMEAR2 /* register number 0x9C */
666 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
667 eieio /* make sure mem. access is complete */
668 stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
671 * set the Memory Configuration Reg. 2
673 lis r3, MPC106_REG@h /* start building new reg number */
674 ori r3, r3, MPC106_MCCR2 /* register number 0xf4 */
675 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
676 eieio /* make sure mem. access is complete */
678 li r3, 0x000c /* get refresh from spd for bank0/1 */
681 cmpi 0, 0, r3, -1 /* error ? */
684 li r6, 0xe0 /* error codes in r6 and r7 */
686 b toggleError /* fail - loop forever */
689 andi. r15, r3, 0x007f /* mask selfrefresh bit */
690 li r3, 0x010c /* get refresh from spd for bank2/3 */
693 cmpi 0, 0, r3, -1 /* error ? */
695 andi. r3, r3, 0x007f /* mask selfrefresh bit */
696 cmp 0, 0, r3, r15 /* find the lower */
703 li r4, 0x1010 /* refesh cycle 1028 clocks */
705 cmpli 0, 0, r3, 0x0000 /* 15.6 us ? */
708 li r4, 0x0808 /* refesh cycle 514 clocks */
710 cmpli 0, 0, r3, 0x0002 /* 7.8 us ? */
713 li r4, 0x2020 /* refesh cycle 2056 clocks */
715 cmpli 0, 0, r3, 0x0003 /* 31.3 us ? */
718 li r4, 0x4040 /* refesh cycle 4112 clocks */
720 cmpli 0, 0, r3, 0x0004 /* 62.5 us ? */
724 ori r4, r4, 0x8080 /* refesh cycle 8224 clocks */
726 cmpli 0, 0, r3, 0x0005 /* 125 us ? */
729 li r6, 0xe0 /* error codes in r6 and r7 */
731 b toggleError /* fail - loop forever */
734 stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
737 * DRAM BANKS SHOULD BE ENABLED
739 addi r3, r13, (Mactivate-MessageBlock)
743 addi r3, r13, (Mmbyte-MessageBlock)
746 lis r3, MPC106_REG@h /* start building new reg number */
747 ori r3, r3, MPC106_MBER /* register number 0xa0 */
748 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
749 eieio /* make sure mem. access is complete */
750 stb r22, 0(r2) /* write data to CONFIG_DATA */
751 li r8, 0x63 /* PGMAX = 99 */
752 stb r8, 3(r2) /* write data to CONFIG_DATA */
755 * DRAM SHOULD NOW BE CONFIGURED AND ENABLED
756 * MUST WAIT 200us BEFORE ACCESSING
764 lis r3, MPC106_REG@h /* start building new reg number */
765 ori r3, r3, MPC106_MCCR1 /* register number 0xf0 */
766 stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
767 eieio /* make sure mem. access is complete */
769 lwbrx r4, r0, r2 /* load r4 from CONFIG_DATA */
771 lis r0, MCCR1_MEMGO@h /* MEMGO=1 */
772 ori r0, r0, MCCR1_MEMGO@l
773 or r4, r4, r0 /* set the MEMGO bit */
774 stwbrx r4, r0, r2 /* write mdfd data to CONFIG_DATA */
782 addi r3, r13, (Mok-MessageBlock)
789 * Infinite loop called in case of an error during RAM initialisation.
790 * error codes in r6 and r7.
799 ble cr1, toggleError1
806 ble cr1, toggleError2
810 /******************************************************************************
811 * This function performs a basic initialisation of the superio chip
812 * to enable basic console output and SPD access during RAM initialisation.
814 * Upon completion, SIO resource registers are mapped as follows:
815 * Resource Enabled Address
816 * UART1 Yes 3F8-3FF COM1
817 * UART2 Yes 2F8-2FF COM2
820 .set SIO_LUNINDEX, 0x07 /* SIO LUN index register */
821 .set SIO_CNFG1, 0x21 /* SIO configuration #1 register */
822 .set SIO_PCSCI, 0x23 /* SIO PCS configuration index reg */
823 .set SIO_PCSCD, 0x24 /* SIO PCS configuration data reg */
824 .set SIO_ACTIVATE, 0x30 /* SIO activate register */
825 .set SIO_IOBASEHI, 0x60 /* SIO I/O port base address, 15:8 */
826 .set SIO_IOBASELO, 0x61 /* SIO I/O port base address, 7:0 */
827 .set SIO_LUNENABLE, 0x01 /* SIO LUN enable */
830 mfspr r7, 8 /* save link register */
835 * Get base addr of ISA I/O space
838 ori r6, r6, CFG_ISA_IO@l
841 * Set offset to base address for config registers.
843 #if defined(CFG_NS87308_BADDR_0x)
845 #elif defined(CFG_NS87308_BADDR_10)
847 #elif defined(CFG_NS87308_BADDR_11)
850 add r6, r6, r4 /* add offset to base */
851 or r3, r6, r6 /* make a copy */
856 addi r4, r0, SIO_LUNINDEX /* select PMC LUN */
859 addi r4, r0, SIO_IOBASEHI /* initialize PMC address to 0x460 */
862 addi r4, r0, SIO_IOBASELO
865 addi r4, r0, SIO_ACTIVATE /* enable PMC */
866 addi r5, r0, SIO_LUNENABLE
872 stb r9, 0(r8) /* select PMC2 register */
875 stb r9, 1(r8) /* SuperI/O clock src: 24MHz via X1 */
879 * map UART1 (LUN 6) or UART2 (LUN 5) to COM1 (0x3F8)
881 addi r4, r0, SIO_LUNINDEX /* select COM1 LUN */
885 addi r4, r0, SIO_IOBASEHI /* initialize COM1 address to 0x3F8 */
889 addi r4, r0, SIO_IOBASELO
893 addi r4, r0, SIO_ACTIVATE /* enable COM1 */
894 addi r5, r0, SIO_LUNENABLE
898 * Init COM1 for polled output
903 stb r9, 1(r8) /* int disabled */
906 stb r9, 4(r8) /* modem ctrl */
909 stb r9, 3(r8) /* link ctrl, bank select */
911 li r9, 115200/CONFIG_BAUDRATE
912 stb r9, 0(r8) /* baud rate (LSB)*/
915 stb r9, 1(r8) /* baud rate (MSB) */
918 stb r9, 3(r8) /* 8 data bits, 1 stop bit, */
922 stb r9, 4(r8) /* enable the receiver and transmitter */
926 lbz r9, 5(r8) /* transmit empty */
930 stb r9, 3(r8) /* send break, 8 data bits, */
931 /* 2 stop bits, no parity */
938 lwz r0, 5(r8) /* load from port for delay */
942 lbz r9, 5(r8) /* transmit empty */
946 stb r9, 3(r8) /* 8 data bits, 2 stop bits, */
953 addi r4, r0, SIO_LUNINDEX /* select GPIO LUN */
957 addi r4, r0, SIO_IOBASEHI /* initialize GPIO address to 0x220 */
961 addi r4, r0, SIO_IOBASELO
965 addi r4, r0, SIO_ACTIVATE /* enable GPIO */
966 addi r5, r0, SIO_LUNENABLE
972 * Get base addr of ISA I/O space
975 ori r3, r3, CFG_ISA_IO@l
977 addi r3, r3, 0x015C /* adjust to superI/O 87308 base */
978 or r6, r3, r3 /* make a copy */
982 addi r4, r0, SIO_PCSCI /* select PCSCIR */
985 addi r4, r0, SIO_PCSCD /* select PCSCDR */
988 addi r4, r0, SIO_PCSCI /* select PCSCIR */
991 addi r4, r0, SIO_PCSCD /* select PCSCDR */
994 addi r4, r0, SIO_PCSCI /* select PCSCIR */
997 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1003 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1006 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1009 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1012 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1015 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1018 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1024 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1027 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1030 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1033 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1036 addi r4, r0, SIO_PCSCI /* select PCSCIR */
1039 addi r4, r0, SIO_PCSCD /* select PCSCDR */
1043 mtspr 8, r7 /* restore link register */
1044 bclr 20, 0 /* return to caller */
1047 * this function writes a register to the SIO chip
1050 stb r4, 0(r3) /* write index register with register offset */
1053 stb r5, 1(r3) /* 1st write */
1056 stb r5, 1(r3) /* 2nd write */
1059 bclr 20, 0 /* return to caller */
1061 * this function reads a register from the SIO chip
1064 stb r4, 0(r3) /* write index register with register offset */
1067 lbz r3, 1(r3) /* retrieve specified reg offset contents */
1070 bclr 20, 0 /* return to caller */
1073 * Print a message to COM1 in polling mode
1074 * r10=COM1 port, r3=(char*)string
1078 lis r10, CFG_ISA_IO@h /* COM1 port */
1079 ori r10, r10, 0x03f8
1082 lbz r0, 5(r10) /* read link status */
1084 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1085 beq cr0, WaitChr /* wait till empty */
1086 lbzx r0, r0, r3 /* get char */
1087 stb r0, 0(r10) /* write to transmit reg */
1089 addi r3, r3, 1 /* next char */
1090 lbzx r0, r0, r3 /* get char */
1091 cmpwi cr1, r0, 0 /* end of string ? */
1096 * Print 8/4/2 digits hex value to COM1 in polling mode
1097 * r10=COM1 port, r3=val
1100 li r9, 4 /* shift reg for 2 digits */
1103 li r9, 12 /* shift reg for 4 digits */
1107 li r9, 28 /* shift reg for 8 digits */
1109 lis r10, CFG_ISA_IO@h /* COM1 port */
1110 ori r10, r10, 0x03f8
1112 lbz r0, 5(r10) /* read link status */
1114 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1125 stb r0, 0(r10) /* write to transmit reg */
1131 * Print 3 digits hdec value to COM1 in polling mode
1132 * r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch
1137 divwu r0, r3, r6 /* r0 = r3 / 10, r9 = r3 mod 10 */
1142 divwu r0, r3, r6 /* r0 = r3 / 10, r8 = r3 mod 10 */
1147 divwu r0, r3, r6 /* r0 = r3 / 10, r7 = r3 mod 10 */
1151 lis r10, CFG_ISA_IO@h /* COM1 port */
1152 ori r10, r10, 0x03f8
1160 addi r3, r7, 48 /* convert to ASCII */
1163 lbz r0, 0(r13) /* slow down dummy read */
1164 lbz r0, 5(r10) /* read link status */
1166 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1168 stb r3, 0(r10) /* x00 to transmit */
1174 addi r3, r8, 48 /* convert to ASCII */
1176 lbz r0, 0(r13) /* slow down dummy read */
1177 lbz r0, 5(r10) /* read link status */
1179 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1181 stb r3, 0(r10) /* x0 to transmit */
1184 addi r3, r9, 48 /* convert to ASCII */
1186 lbz r0, 0(r13) /* slow down dummy read */
1187 lbz r0, 5(r10) /* read link status */
1189 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1191 stb r3, 0(r10) /* x to transmit */
1195 * Print a char to COM1 in polling mode
1196 * r10=COM1 port, r3=char
1200 lis r10, CFG_ISA_IO@h /* COM1 port */
1201 ori r10, r10, 0x03f8
1204 lbz r0, 5(r10) /* read link status */
1206 andi. r0, r0, 0x40 /* mask transmitter empty bit */
1207 beq cr0, OutChr1 /* wait till empty */
1208 stb r3, 0(r10) /* write to transmit reg */
1212 * Input: r3 adr to read
1213 * Output: r3 val or -1 for error
1216 mfspr r26, 8 /* save link register */
1218 lis r30, CFG_ISA_IO@h
1219 ori r30, r30, 0x220 /* GPIO Port 1 */
1230 li r12, 0x20 /* set I2C data */
1231 li r4, 0x40 /* set I2C clock */
1232 li r6, 0x60 /* set I2C clock and data */
1237 bl spdStart /* access I2C bus as master */
1238 li r10, 0xa0 /* write to SPD */
1240 bl spdReadAck /* ACK returns in r10 */
1242 bne AckErr /* r10 must be 0, if ACK received */
1243 mr r10, r3 /* adr to read */
1249 li r10, 0xa1 /* read from SPD */
1254 bl spdReadByte /* return val in r10 */
1256 bl spdStop /* release I2C bus */
1258 mtspr 8, r26 /* restore link register */
1261 * ACK error occurred
1265 orc r3, r0, r0 /* return -1 */
1266 mtspr 8, r26 /* restore link register */
1270 * Routines to read from RAM spd.
1271 * r30 - GPIO Port1 address in all cases.
1272 * r4 - clock mask for SPD
1273 * r6 - port mask for SPD
1274 * r12 - data mask for SPD
1281 bclr 20, 0 /* return to caller */
1284 * establish START condition on I2C bus
1287 mfspr r27, 8 /* save link register */
1288 stb r6, 0(r30) /* set SDA and SCL */
1290 stb r6, 1(r30) /* switch GPIO to output */
1293 stb r4, 0(r30) /* reset SDA */
1296 stb r7, 0(r30) /* reset SCL */
1300 bclr 20, 0 /* return to caller */
1303 * establish STOP condition on I2C bus
1306 mfspr r27, 8 /* save link register */
1307 stb r7, 0(r30) /* reset SCL and SDA */
1309 stb r6, 1(r30) /* switch GPIO to output */
1312 stb r4, 0(r30) /* set SCL */
1315 stb r6, 0(r30) /* set SDA and SCL */
1318 stb r7, 1(r30) /* switch GPIO to input */
1321 bclr 20, 0 /* return to caller */
1325 stb r4, 1(r30) /* set GPIO for SCL output */
1330 stb r7, 0(r30) /* reset SDA and SCL */
1333 stb r4, 0(r30) /* set SCL */
1336 lbz r5, 0(r30) /* read from GPIO Port1 */
1337 rlwinm r10, r10, 1, 0, 31
1340 ori r10, r10, 0x01 /* append _1_ */
1342 stb r7, 0(r30) /* reset SCL */
1348 bclr 20, 0 /* return (r10) to caller */
1351 * spdWriteByte writes bits 24 - 31 of r10 to I2C.
1352 * r8 contains bit mask 0x80
1355 mfspr r27, 8 /* save link register */
1356 li r9, 0x08 /* write octet */
1359 stb r7, 0(r30) /* set SDA to _0_ */
1363 stb r12, 0(r30) /* set SDA to _1_ */
1366 stb r6, 1(r30) /* set GPIO to output */
1371 stb r7, 0(r30) /* set SDA to _0_ */
1375 stb r12, 0(r30) /* set SDA to _1_ */
1381 stb r4, 0(r30) /* set SDA to _0_ and SCL */
1385 stb r6, 0(r30) /* set SDA to _1_ and SCL */
1391 stb r7, 0(r30) /* set SDA to _0_ and reset SCL */
1395 stb r12, 0(r30) /* set SDA to _1_ and reset SCL */
1399 rlwinm r10, r10, 1, 0, 31 /* next bit */
1403 bclr 20, 0 /* return to caller */
1406 * Read ACK from SPD, return value in r10
1409 mfspr r27, 8 /* save link register */
1410 stb r4, 1(r30) /* set GPIO to output */
1412 stb r7, 0(r30) /* reset SDA and SCL */
1415 stb r4, 0(r30) /* set SCL */
1418 lbz r10, 0(r30) /* read GPIO Port 1 and mask SDA */
1421 stb r7, 0(r30) /* reset SDA and SCL */
1425 bclr 20, 0 /* return (r10) to caller */
1429 stb r12, 0(r30) /* set SCL */
1431 stb r6, 1(r30) /* set GPIO to output */
1434 stb r6, 0(r30) /* SDA and SCL */
1437 stb r12, 0(r30) /* reset SCL */
1441 bclr 20, 0 /* return to caller */
1444 mflr r3 /* return link reg */
1448 * Messages for console output
1453 .ascii "OK\015\012\000"
1455 .ascii "FAILED\015\012\000"
1457 .ascii "NA\015\012\000"
1459 .ascii "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
1460 .ascii "\015\012Initialising RAM\015\012\000"
1462 .ascii " Reading SPD of bank0/1 ..... \000"
1464 .ascii " Reading SPD of bank2/3 ..... \000"
1466 .ascii " RAM-Type: FPM \015\012\000"
1468 .ascii " RAM-Type: EDO \015\012\000"
1470 .ascii " RAM-Type: SDRAM \015\012\000"
1472 .ascii " Activating \000"
1474 .ascii " MB .......... \000"