|  | /* | 
|  | * (C) Copyright 2001 ELTEC Elektronik AG | 
|  | * Frank Gottschling <fgottschling@eltec.de> | 
|  | * | 
|  | * ELTEC ELPPC RAM initialization | 
|  | * | 
|  | * See file CREDITS for list of people who contributed to this | 
|  | * project. | 
|  | * | 
|  | * This program is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU General Public License as | 
|  | * published by the Free Software Foundation; either version 2 of | 
|  | * the License, or (at your option) any later version. | 
|  | * | 
|  | * This program is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | * GNU General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU General Public License | 
|  | * along with this program; if not, write to the Free Software | 
|  | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 
|  | * MA 02111-1307 USA | 
|  | */ | 
|  |  | 
|  | #include <config.h> | 
|  | #include <asm/processor.h> | 
|  | #include <version.h> | 
|  | #include <mpc106.h> | 
|  |  | 
|  | #include <ppc_asm.tmpl> | 
|  | #include <ppc_defs.h> | 
|  |  | 
|  | .globl board_asm_init | 
|  | board_asm_init: | 
|  |  | 
|  | /* | 
|  | * setup pointer to message block | 
|  | */ | 
|  | mflr    r13                 /* save away link register */ | 
|  | bl      get_lnk_reg         /* r3=addr of next instruction */ | 
|  | subi    r4, r3, 8           /* r4=board_asm_init addr */ | 
|  | addi    r29, r4, (MessageBlock-board_asm_init) | 
|  |  | 
|  | /* | 
|  | * dcache_disable | 
|  | */ | 
|  | mfspr   r3, HID0 | 
|  | li      r4, HID0_DCE | 
|  | andc    r3, r3, r4 | 
|  | mr      r2, r3 | 
|  | ori     r3, r3, HID0_DCI | 
|  | sync | 
|  | mtspr   HID0, r3 | 
|  | mtspr   HID0, r2 | 
|  | isync | 
|  | sync | 
|  | /* | 
|  | * icache_disable | 
|  | */ | 
|  | mfspr   r3, HID0 | 
|  | li      r4, 0 | 
|  | ori     r4, r4, HID0_ICE | 
|  | andc    r3, r3, r4 | 
|  | sync | 
|  | mtspr   HID0, r3 | 
|  | /* | 
|  | * invalidate caches | 
|  | */ | 
|  | ori     r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE) | 
|  | or      r4, r4, r3 | 
|  | isync | 
|  | mtspr   HID0, r4 | 
|  | andc    r4, r4, r3 | 
|  | isync | 
|  | mtspr   HID0, r4 | 
|  | isync | 
|  | /* | 
|  | * icache_enable | 
|  | */ | 
|  | mfspr   r3, HID0 | 
|  | ori     r3, r3, (HID0_ICE | HID0_ICFI) | 
|  | sync | 
|  | mtspr   HID0, r3 | 
|  |  | 
|  |  | 
|  | /* | 
|  | * setup memory controller | 
|  | */ | 
|  | lis     r1, MPC106_REG_ADDR@h | 
|  | ori     r1, r1, MPC106_REG_ADDR@l | 
|  | lis     r2, MPC106_REG_DATA@h | 
|  | ori     r2, r2, MPC106_REG_DATA@l | 
|  |  | 
|  | /* Configure PICR1 */ | 
|  | lis     r3, MPC106_REG@h | 
|  | ori     r3, r3, PCI_PICR1 | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0xFF14 | 
|  | ori     r3, r3, 0x1CC8 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | /* Configure PICR2 */ | 
|  | lis     r3, MPC106_REG@h | 
|  | ori     r3, r3, PCI_PICR2 | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0x0000 | 
|  | ori     r3, r3, 0x0000 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | /* Configure EUMBAR */ | 
|  | lis     r3, MPC106_REG@h | 
|  | ori     r3, r3, 0x0078      /* offest of EUMBAR in PCI config space */ | 
|  | stwbrx  r3, 0, r1 | 
|  | lis     r3, MPC107_EUMB_ADDR@h | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | /* Configure Address Map B Option Reg */ | 
|  | lis     r3, MPC106_REG@h | 
|  | ori     r3, r3, 0x00e0      /* offest of AMBOR in PCI config space */ | 
|  | stwbrx  r3, 0, r1 | 
|  | lis     r3, 0 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | /* Configure I2C Controller */ | 
|  | lis     r14, MPC107_I2C_ADDR@h  /* base of I2C controller */ | 
|  | ori     r14, r14, MPC107_I2C_ADDR@l | 
|  | lis     r3, 0x2b10          /* I2C clock = 100MHz/1024 */ | 
|  | stw     r3, 4(r14) | 
|  | li      r3, 0               /* clear arbitration */ | 
|  | eieio | 
|  | stw     r3, 12(r14) | 
|  |  | 
|  | /* Configure MCCR1 */ | 
|  | lis     r3, MPC106_REG@h | 
|  | ori     r3, r3, MPC106_MCCR1 | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0x0660      /* don't set MEMGO now ! */ | 
|  | ori     r3, r3, 0x0000 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | /* Configure MCCR2 */ | 
|  | lis     r3, MPC106_REG@h | 
|  | ori     r3, r3, MPC106_MCCR2 | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0x0400 | 
|  | ori     r3, r3, 0x1800 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  |  | 
|  | /* Configure MCCR3 */ | 
|  | lis     r3, MPC106_REG@h | 
|  | ori     r3, r3, MPC106_MCCR3 | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0x0230 | 
|  | ori     r3, r3, 0x0000 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | /* Configure MCCR4 */ | 
|  | lis     r3, MPC106_REG@h | 
|  | ori     r3, r3, MPC106_MCCR4 | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0x2532 | 
|  | ori     r3, r3, 0x2220 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | /* | 
|  | * configure memory interface (MICRs) | 
|  | */ | 
|  | addis   r3, r0, 0x8000      /* ADDR_80 */ | 
|  | ori     r3, r3, 0x0080      /* SMEMADD1 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0xFFFF | 
|  | ori     r3, r3, 0x4000 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_84 */ | 
|  | ori     r3, r3, 0x0084      /* SMEMADD2 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0xFFFF | 
|  | ori     r3, r3, 0xFFFF | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_88 */ | 
|  | ori     r3, r3, 0x0088      /* EXTSMEM1 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0x0303 | 
|  | ori     r3, r3, 0x0000 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_8C */ | 
|  | ori     r3, r3, 0x008c      /* EXTSMEM2 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0x0303 | 
|  | ori     r3, r3, 0x0303 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_90 */ | 
|  | ori     r3, r3, 0x0090      /* EMEMADD1 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0xFFFF | 
|  | ori     r3, r3, 0x7F3F | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_94 */ | 
|  | ori     r3, r3, 0x0094      /* EMEMADD2 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0xFFFF | 
|  | ori     r3, r3, 0xFFFF | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_98 */ | 
|  | ori     r3, r3, 0x0098      /* EXTEMEM1 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0x0303 | 
|  | ori     r3, r3, 0x0000 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_9C */ | 
|  | ori     r3, r3, 0x009c      /* EXTEMEM2 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0x0303 | 
|  | ori     r3, r3, 0x0303 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_A0 */ | 
|  | ori     r3, r3, 0x00a0      /* MEMBNKEN */ | 
|  | stwbrx  r3, 0, r1 | 
|  | addis   r3, r0, 0x0000 | 
|  | ori     r3, r3, 0x0003 | 
|  | eieio | 
|  | stwbrx  r3, 0, r2 | 
|  |  | 
|  | /* | 
|  | * must wait at least 100us after HRESET to issue a MEMGO | 
|  | */ | 
|  | lis     r0, 1 | 
|  | mtctr   r0 | 
|  | memStartWait: | 
|  | bdnz    memStartWait | 
|  |  | 
|  | /* | 
|  | * enable RAM Operations through MCCR1 (MEMGO) | 
|  | */ | 
|  | lis     r3, 0x8000 | 
|  | ori     r3, r3, 0x00f0 | 
|  | stwbrx  r3, r0, r1 | 
|  | sync | 
|  | lwbrx   r3, 0, r2 | 
|  | lis     r0, 0x0008 | 
|  | or      r3, r0, r3 | 
|  | stwbrx  r3, 0, r2 | 
|  | sync | 
|  |  | 
|  | /* | 
|  | * set LEDs first time | 
|  | */ | 
|  | li      r3, 0x1 | 
|  | lis     r30, CFG_USR_LED_BASE@h | 
|  | stb     r3, 2(r30) | 
|  | sync | 
|  |  | 
|  | /* | 
|  | * init COM1 for polled output | 
|  | */ | 
|  | lis     r8, CFG_NS16550_COM1@h  /* COM1 base address*/ | 
|  | ori     r8, r8, CFG_NS16550_COM1@l | 
|  | li      r9, 0x00 | 
|  | stb     r9, 1(r8)           /* int disabled */ | 
|  | eieio | 
|  | li      r9, 0x00 | 
|  | stb     r9, 4(r8)           /* modem ctrl */ | 
|  | eieio | 
|  | li      r9, 0x80 | 
|  | stb     r9, 3(r8)           /* link ctrl */ | 
|  | eieio | 
|  | li      r9, (CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE) | 
|  | stb     r9, 0(r8)           /* baud rate (LSB)*/ | 
|  | eieio | 
|  | li      r9, ((CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE) >> 8) | 
|  | stb     r9, 1(r8)           /* baud rate (MSB) */ | 
|  | eieio | 
|  | li      r9, 0x07 | 
|  | stb     r9, 3(r8)           /* 8 data bits, 2 stop bit, no parity */ | 
|  | eieio | 
|  | li      r9, 0x0b | 
|  | stb     r9, 4(r8)           /* enable the receiver and transmitter (modem ctrl) */ | 
|  | eieio | 
|  | waitEmpty: | 
|  | lbz     r9, 5(r8)           /* transmit empty */ | 
|  | andi.   r9, r9, 0x40 | 
|  | beq     waitEmpty | 
|  | li      r9, 0x47 | 
|  | stb     r9, 3(r8)           /* send break, 8 data bits, 2 stop bit, no parity */ | 
|  | eieio | 
|  |  | 
|  | lis     r0, 0x0001 | 
|  | mtctr   r0 | 
|  | waitCOM1: | 
|  | lwz     r0, 5(r8)           /* load from port for delay */ | 
|  | bdnz    waitCOM1 | 
|  |  | 
|  | waitEmpty1: | 
|  | lbz     r9, 5(r8)           /* transmit empty */ | 
|  | andi.   r9, r9, 0x40 | 
|  | beq     waitEmpty1 | 
|  | li      r9, 0x07 | 
|  | stb     r9, 3(r8)           /* 8 data bits, 2 stop bit, no parity */ | 
|  | eieio | 
|  |  | 
|  | /* | 
|  | * intro message from message block | 
|  | */ | 
|  | addi    r3, r29, (MnewLine-MessageBlock) | 
|  | bl      Printf | 
|  | addi    r3, r29, (MinitLogo-MessageBlock) | 
|  | bl      Printf | 
|  |  | 
|  | /* | 
|  | * memory cofiguration using SPD information stored on the SODIMMs | 
|  | */ | 
|  | addi    r3, r29, (Mspd01-MessageBlock) | 
|  | bl      Printf | 
|  |  | 
|  | li      r17, 0 | 
|  |  | 
|  | li      r3, 0x0002          /* get RAM type from spd for bank0/1 */ | 
|  | bl      spdRead | 
|  |  | 
|  | cmpi    0, 0, r3, -1        /* error ? */ | 
|  | bne     noSpdError | 
|  |  | 
|  | addi    r3, r29, (Mfail-MessageBlock) | 
|  | bl      Printf | 
|  |  | 
|  | li      r6, 0xe             /* error codes in r6 and r7  */ | 
|  | li      r7, 0x0 | 
|  | b       toggleError         /* fail - loop forever */ | 
|  |  | 
|  | noSpdError: | 
|  | mr      r15, r3             /* save r3 */ | 
|  |  | 
|  | addi    r3, r29, (Mok-MessageBlock) | 
|  | bl      Printf | 
|  |  | 
|  | cmpli   0, 0, r15, 0x0004   /* SDRAM ? */ | 
|  | beq     isSDRAM | 
|  |  | 
|  | addi    r3, r29, (MramTyp-MessageBlock) | 
|  | bl      Printf | 
|  |  | 
|  | li      r6, 0xd             /* error codes in r6 and r7  */ | 
|  | li      r7, 0x0 | 
|  | b       toggleError         /* fail - loop forever */ | 
|  |  | 
|  | isSDRAM: | 
|  | li      r3, 0x0012          /* get supported CAS latencies from byte 18 */ | 
|  | bl      spdRead | 
|  | mr      r15, r3 | 
|  | li      r3, 0x09 | 
|  | andi.   r0, r15, 0x04 | 
|  | bne     maxCLis3 | 
|  | li      r3, 0x17 | 
|  | maxCLis3: | 
|  | andi.   r0, r15, 0x02 | 
|  | bne     CL2 | 
|  |  | 
|  | addi    r3, r29, (MramTyp-MessageBlock) | 
|  | bl      Printf | 
|  |  | 
|  | li      r6, 0xc             /* error codes in r6 and r7  */ | 
|  | li      r7, 0x0 | 
|  | b       toggleError         /* fail - loop forever */ | 
|  | CL2: | 
|  | bl      spdRead | 
|  | cmpli   0, 0, r3, 0xa1      /* cycle time must be 10ns max. */ | 
|  | blt     speedOk | 
|  |  | 
|  | addi    r3, r29, (MramTyp-MessageBlock) | 
|  | bl      Printf | 
|  |  | 
|  | li      r6, 0xb             /* error codes in r6 and r7  */ | 
|  | li      r7, 0x0 | 
|  | b       toggleError         /* fail - loop forever */ | 
|  | speedOk: | 
|  | lis     r20, 0x06e8         /* preset MCR1 value */ | 
|  |  | 
|  | li      r3, 0x0011          /* get number of internal banks from spd for bank0/1 */ | 
|  | bl      spdRead | 
|  |  | 
|  | cmpli   0, 0, r3, 0x02 | 
|  | beq     SD_2B | 
|  | cmpli   0, 0, r3, 0x04 | 
|  | beq     SD_4B | 
|  | memConfErr: | 
|  | addi    r3, r29, (MramConfErr-MessageBlock) | 
|  | bl      Printf | 
|  |  | 
|  | li      r6, 0xa             /* error codes in r6 and r7  */ | 
|  | li      r7, 0x0 | 
|  | b       toggleError         /* fail - loop forever */ | 
|  |  | 
|  | SD_2B: | 
|  | li      r3, 0x0003          /* get number of row bits from spd for bank0/1 */ | 
|  | bl      spdRead | 
|  | cmpli   0, 0, r3, 0x0b | 
|  | beq     row11x2 | 
|  | cmpli   0, 0, r3, 0x0c | 
|  | beq     row12x2or13x2 | 
|  | cmpli   0, 0, r3, 0x0d | 
|  | beq     row12x2or13x2 | 
|  | b       memConfErr | 
|  | SD_4B: | 
|  | li      r3, 0x0003          /* get number of row bits from spd for bank0/1 */ | 
|  | bl      spdRead | 
|  | cmpli   0, 0, r3, 0x0b | 
|  | beq     row11x4or12x4 | 
|  | cmpli   0, 0, r3, 0x0c | 
|  | beq     row11x4or12x4 | 
|  | cmpli   0, 0, r3, 0x0d | 
|  | beq     row13x4 | 
|  | b       memConfErr | 
|  | row12x2or13x2: | 
|  | ori     r20, r20, 0x05 | 
|  | b       row11x4or12x4 | 
|  | row13x4: | 
|  | ori     r20, r20, 0x0a | 
|  | b       row11x4or12x4 | 
|  | row11x2: | 
|  | ori     r20, r20, 0x0f | 
|  | row11x4or12x4: | 
|  | /* get the size of bank 0-1 */ | 
|  |  | 
|  | li      r3, 0x001f          /* get bank size from spd for bank0/1 */ | 
|  | bl      spdRead | 
|  |  | 
|  | rlwinm  r16, r3, 2, 24, 29  /* calculate size in MByte (128 MB max.) */ | 
|  |  | 
|  | li      r3, 0x0005          /* get number of banks from spd for bank0/1 */ | 
|  | bl      spdRead | 
|  |  | 
|  | cmpi    0, 0, r3, 2         /* 2 banks ? */ | 
|  | bne     SDRAMnobank1 | 
|  |  | 
|  | mr      r17, r16 | 
|  |  | 
|  | SDRAMnobank1: | 
|  | li      r3, 0x000c          /* get refresh from spd for bank0/1 */ | 
|  | bl      spdRead | 
|  | andi.   r3, r3, 0x007f      /* mask selfrefresh bit */ | 
|  | li      r4, 0x1800          /* refesh cycle 1536 clocks left shifted 2 */ | 
|  | cmpli   0, 0, r3, 0x0000    /* 15.6 us ? */ | 
|  | beq     writeRefresh | 
|  |  | 
|  | li      r4, 0x0c00          /* refesh cycle 768 clocks left shifted 2 */ | 
|  | cmpli   0, 0, r3, 0x0002    /* 7.8 us ? */ | 
|  | beq     writeRefresh | 
|  |  | 
|  | li      r4, 0x3000          /* refesh cycle 3072 clocks left shifted 2 */ | 
|  | cmpli   0, 0, r3, 0x0003    /* 31.3 us ? */ | 
|  | beq     writeRefresh | 
|  |  | 
|  | li      r4, 0x6000          /* refesh cycle 6144 clocks left shifted 2 */ | 
|  | cmpli   0, 0, r3, 0x0004    /* 62.5 us ? */ | 
|  | beq     writeRefresh | 
|  |  | 
|  | li      r4, 0 | 
|  | ori     r4, r4, 0xc000      /* refesh cycle 8224 clocks left shifted 2 */ | 
|  | cmpli   0, 0, r3, 0x0005    /* 125 us ? */ | 
|  | beq     writeRefresh | 
|  |  | 
|  | b       memConfErr | 
|  |  | 
|  | writeRefresh: | 
|  | lis     r21, 0x0400         /* preset MCCR2 value */ | 
|  | or      r21, r21, r4 | 
|  |  | 
|  | /* Overwrite MCCR1 */ | 
|  | lis     r3, MPC106_REG@h | 
|  | ori     r3, r3, MPC106_MCCR1 | 
|  | stwbrx  r3, 0, r1 | 
|  | eieio | 
|  | stwbrx  r20, 0, r2 | 
|  |  | 
|  | /* Overwrite MCCR2 */ | 
|  | lis     r3, MPC106_REG@h | 
|  | ori     r3, r3, MPC106_MCCR2 | 
|  | stwbrx  r3, 0, r1 | 
|  | eieio | 
|  | stwbrx  r21, 0, r2 | 
|  |  | 
|  | /* set the memory boundary registers for bank 0-3 */ | 
|  | li      r20, 0 | 
|  | lis     r23, 0x0303 | 
|  | lis     r24, 0x0303 | 
|  | subi    r21, r16, 1         /* calculate end address bank0 */ | 
|  | li      r22, 1 | 
|  |  | 
|  | cmpi    0, 0, r17, 0        /* bank1 present ? */ | 
|  | beq     nobank1 | 
|  |  | 
|  | andi.   r3, r16, 0x00ff     /* calculate start address of bank1 */ | 
|  | andi.   r4, r16, 0x0300 | 
|  | rlwinm  r3, r3, 8, 16, 23 | 
|  | or      r20, r20, r3 | 
|  | or      r23, r23, r4 | 
|  |  | 
|  | add     r16, r16, r17       /* add to total memory size */ | 
|  |  | 
|  | subi    r3, r16, 1          /* calculate end address of bank1 */ | 
|  | andi.   r4, r3, 0x0300 | 
|  | andi.   r3, r3, 0x00ff | 
|  | rlwinm  r3, r3, 8, 16, 23 | 
|  | or      r21, r21, r3 | 
|  | or      r24, r24, r4 | 
|  |  | 
|  | ori     r22, r22, 2         /* enable bank1 */ | 
|  | b       bankOk | 
|  | nobank1: | 
|  | ori     r23, r23, 0x0300    /* set bank1 start to unused area */ | 
|  | ori     r24, r24, 0x0300    /* set bank1 end to unused area */ | 
|  | bankOk: | 
|  | addi    r3, r29, (Mactivate-MessageBlock) | 
|  | bl      Printf | 
|  | mr      r3, r16 | 
|  | bl      OutDec | 
|  | addi    r3, r29, (Mact0123e-MessageBlock) | 
|  | bl      Printf | 
|  |  | 
|  | /* | 
|  | * overwrite MSAR1, MEAR1, EMSAR1, and EMEAR1 | 
|  | */ | 
|  | addis   r3, r0, 0x8000      /* ADDR_80 */ | 
|  | ori     r3, r3, 0x0080      /* MSAR1 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | eieio | 
|  | stwbrx  r20, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_88 */ | 
|  | ori     r3, r3, 0x0088      /* EMSAR1 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | eieio | 
|  | stwbrx  r23, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_90 */ | 
|  | ori     r3, r3, 0x0090      /* MEAR1 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | eieio | 
|  | stwbrx  r21, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_98 */ | 
|  | ori     r3, r3, 0x0098      /* EMEAR1 */ | 
|  | stwbrx  r3, 0, r1 | 
|  | eieio | 
|  | stwbrx  r24, 0, r2 | 
|  |  | 
|  | addis   r3, r0, 0x8000      /* ADDR_A0 */ | 
|  | ori     r3, r3, 0x00a0      /* MBER */ | 
|  | stwbrx  r3, 0, r1 | 
|  | eieio | 
|  | stwbrx  r22, 0, r2 | 
|  |  | 
|  | /* | 
|  | * delay to let SDRAM go through several initialization/refresh cycles | 
|  | */ | 
|  | lis     r3, 3 | 
|  | mtctr   r3 | 
|  | memStartWait_1: | 
|  | bdnz    memStartWait_1 | 
|  | eieio | 
|  |  | 
|  | /* | 
|  | * set LEDs end | 
|  | */ | 
|  | li      r3, 0xf | 
|  | lis     r30, CFG_USR_LED_BASE@h | 
|  | stb     r3, 2(r30) | 
|  | sync | 
|  |  | 
|  | mtlr    r13 | 
|  | blr                         /* EXIT board_asm_init ... */ | 
|  |  | 
|  | /*----------------------------------------------------------------------------*/ | 
|  | /* | 
|  | * print a message to COM1 in polling mode (r10=COM1 port, r3=(char*)string) | 
|  | */ | 
|  |  | 
|  | Printf: | 
|  | lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/ | 
|  | ori     r10, r10, CFG_NS16550_COM1@l | 
|  | WaitChr: | 
|  | lbz     r0, 5(r10)          /* read link status */ | 
|  | eieio | 
|  | andi.   r0, r0, 0x40        /* mask transmitter empty bit */ | 
|  | beq     cr0, WaitChr        /* wait till empty */ | 
|  | lbzx    r0, r0, r3          /* get char */ | 
|  | stb     r0, 0(r10)          /* write to transmit reg */ | 
|  | eieio | 
|  | addi    r3, r3, 1           /* next char */ | 
|  | lbzx    r0, r0, r3          /* get char */ | 
|  | cmpwi   cr1, r0, 0          /* end of string ? */ | 
|  | bne     cr1, WaitChr | 
|  | blr | 
|  |  | 
|  | /* | 
|  | * print a char to COM1 in polling mode (r10=COM1 port, r3=char) | 
|  | */ | 
|  | OutChr: | 
|  | lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/ | 
|  | ori     r10, r10, CFG_NS16550_COM1@l | 
|  | OutChr1: | 
|  | lbz     r0, 5(r10)          /* read link status */ | 
|  | eieio | 
|  | andi.   r0, r0, 0x40        /* mask transmitter empty bit */ | 
|  | beq     cr0, OutChr1        /* wait till empty */ | 
|  | stb     r3, 0(r10)          /* write to transmit reg */ | 
|  | eieio | 
|  | blr | 
|  |  | 
|  | /* | 
|  | * print 8/4/2 digits hex value to COM1 in polling mode (r10=COM1 port, r3=val) | 
|  | */ | 
|  | OutHex2: | 
|  | li      r9, 4               /* shift reg for 2 digits */ | 
|  | b       OHstart | 
|  | OutHex4: | 
|  | li      r9, 12              /* shift reg for 4 digits */ | 
|  | b       OHstart | 
|  | OutHex: | 
|  | li      r9, 28              /* shift reg for 8 digits */ | 
|  | OHstart: | 
|  | lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/ | 
|  | ori     r10, r10, CFG_NS16550_COM1@l | 
|  | OutDig: | 
|  | lbz     r0, 0(r29)          /* slow down dummy read */ | 
|  | lbz     r0, 5(r10)          /* read link status */ | 
|  | eieio | 
|  | andi.   r0, r0, 0x40        /* mask transmitter empty bit */ | 
|  | beq     cr0, OutDig | 
|  | sraw    r0, r3, r9 | 
|  | clrlwi  r0, r0, 28 | 
|  | cmpwi   cr1, r0, 9 | 
|  | ble     cr1, digIsNum | 
|  | addic   r0, r0, 55 | 
|  | b       nextDig | 
|  | digIsNum: | 
|  | addic   r0, r0, 48 | 
|  | nextDig: | 
|  | stb     r0, 0(r10)          /* write to transmit reg */ | 
|  | eieio | 
|  | addic.  r9, r9, -4 | 
|  | bge     OutDig | 
|  | blr | 
|  |  | 
|  | /* | 
|  | * print 3 digits hdec value to COM1 in polling mode | 
|  | * (r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch) | 
|  | */ | 
|  | OutDec: | 
|  | li      r6, 10 | 
|  | divwu   r0, r3, r6          /* r0 = r3 / 10, r9 = r3 mod 10 */ | 
|  | mullw   r10, r0, r6 | 
|  | subf    r9, r10, r3 | 
|  | mr      r3, r0 | 
|  | divwu   r0, r3, r6          /* r0 = r3 / 10, r8 = r3 mod 10 */ | 
|  | mullw   r10, r0, r6 | 
|  | subf    r8, r10, r3 | 
|  | mr      r3, r0 | 
|  | divwu   r0, r3, r6          /* r0 = r3 / 10, r7 = r3 mod 10 */ | 
|  | mullw   r10, r0, r6 | 
|  | subf    r7, r10, r3 | 
|  | lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/ | 
|  | ori     r10, r10, CFG_NS16550_COM1@l | 
|  | or.     r7, r7, r7 | 
|  | bne     noblank1 | 
|  | li      r3, 0x20 | 
|  | b       OutDec4 | 
|  | noblank1: | 
|  | addi    r3, r7, 48          /* convert to ASCII */ | 
|  | OutDec4: | 
|  | lbz     r0, 0(r29)          /* slow down dummy read */ | 
|  | lbz     r0, 5(r10)          /* read link status */ | 
|  | eieio | 
|  | andi.   r0, r0, 0x40        /* mask transmitter empty bit */ | 
|  | beq     cr0, OutDec4 | 
|  | stb     r3, 0(r10)          /* x00 to transmit */ | 
|  | eieio | 
|  | or.     r7, r7, r8 | 
|  | beq     OutDec5 | 
|  | addi    r3, r8, 48          /* convert to ASCII */ | 
|  | OutDec5: | 
|  | lbz     r0, 0(r29)          /* slow down dummy read */ | 
|  | lbz     r0, 5(r10)          /* read link status */ | 
|  | eieio | 
|  | andi.   r0, r0, 0x40        /* mask transmitter empty bit */ | 
|  | beq     cr0, OutDec5 | 
|  | stb     r3, 0(r10)          /* x0  to transmit */ | 
|  | eieio | 
|  | addi    r3, r9, 48          /* convert to ASCII */ | 
|  | OutDec6: | 
|  | lbz     r0, 0(r29)          /* slow down dummy read */ | 
|  | lbz     r0, 5(r10)          /* read link status */ | 
|  | eieio | 
|  | andi.   r0, r0, 0x40        /* mask transmitter empty bit */ | 
|  | beq     cr0, OutDec6 | 
|  | stb     r3, 0(r10)          /* x   to transmit */ | 
|  | eieio | 
|  | blr | 
|  |  | 
|  | /* | 
|  | * hang endless loop | 
|  | */ | 
|  | toggleError:                    /* fail type in r6, r7=0xff, toggle LEDs */ | 
|  | stb     r7, 2(r30)          /* r7 to LED */ | 
|  | li      r0, 0 | 
|  | lis     r9, 127 | 
|  | ori     r9, r9, 65535 | 
|  | toggleError1: | 
|  | addic   r0, r0, 1 | 
|  | cmpw    cr1, r0, r9 | 
|  | ble     cr1, toggleError1 | 
|  | stb     r6, 2(r30)          /* r6 to LED */ | 
|  | li      r0, 0 | 
|  | lis     r9, 127 | 
|  | ori     r9, r9, 65535 | 
|  | toggleError2: | 
|  | addic   r0, r0, 1 | 
|  | cmpw    cr1, r0, r9 | 
|  | ble     cr1, toggleError2 | 
|  | b       toggleError | 
|  |  | 
|  | /* | 
|  | * routines to read from ram spd | 
|  | */ | 
|  | spdWaitIdle: | 
|  | lis     r0, 0x1             /* timeout for about 100us */ | 
|  | mtctr   r0 | 
|  | iSpd: | 
|  | lbz     r10, 12(r14) | 
|  | andi.   r10, r10, 0x20      /* mask and test MBB */ | 
|  | beq     idle | 
|  | bdnz    iSpd | 
|  | orc.    r10, r0, r0         /* return -1 to caller */ | 
|  | idle: | 
|  | bclr    20, 0               /* return to caller */ | 
|  |  | 
|  | waitSpd: | 
|  | lis     r0, 0x10            /* timeout for about 1.5ms */ | 
|  | mtctr   r0 | 
|  | wSpd: | 
|  | lbz     r10, 12(r14) | 
|  | andi.   r10, r10, 0x82 | 
|  | cmpli   0, 0, r10, 0x82     /* test MCF and MIF set */ | 
|  | beq     wend | 
|  | bdnz    wSpd | 
|  | orc.    r10, r0, r0         /* return -1 to caller */ | 
|  | bclr    20, 0               /* return to caller */ | 
|  |  | 
|  | wend: | 
|  | li      r10, 0 | 
|  | stb     r10, 12(r14)        /* clear status */ | 
|  | bclr    20, 0               /* return to caller */ | 
|  |  | 
|  | /* | 
|  | * spdread | 
|  | * in:  r3 adr to read | 
|  | * out: r3 val or -1 for error | 
|  | * uses r10, assumes that r14 points to I2C controller | 
|  | */ | 
|  | spdRead: | 
|  | mfspr   r25, 8              /* save link register */ | 
|  |  | 
|  | bl      spdWaitIdle | 
|  | bne     spdErr | 
|  |  | 
|  | li      r10, 0x80           /* start with MEN */ | 
|  | stb     r10, 8(r14) | 
|  | eieio | 
|  |  | 
|  | li      r10, 0xb0           /* start as master */ | 
|  | stb     r10, 8(r14) | 
|  | eieio | 
|  |  | 
|  | li      r10, 0xa0           /* write device 0xA0 */ | 
|  | stb     r10, 16(r14) | 
|  | eieio | 
|  | bl      waitSpd | 
|  | bne     spdErr | 
|  |  | 
|  | lbz     r10, 12(r14)        /* test ACK */ | 
|  | andi.   r10, r10, 0x01 | 
|  | bne     gotNoAck | 
|  |  | 
|  | stb     r3, 16(r14)         /* data address */ | 
|  | eieio | 
|  | bl      waitSpd | 
|  | bne     spdErr | 
|  |  | 
|  |  | 
|  | li      r10, 0xb4           /* switch to read - restart */ | 
|  | stb     r10, 8(r14) | 
|  | eieio | 
|  |  | 
|  | li      r10, 0xa1           /* read device 0xA0 */ | 
|  | stb     r10, 16(r14) | 
|  | eieio | 
|  | bl      waitSpd | 
|  | bne     spdErr | 
|  |  | 
|  | li      r10, 0xa8           /* no ACK */ | 
|  | stb     r10, 8(r14) | 
|  | eieio | 
|  |  | 
|  | lbz     r10, 16(r14)        /* trigger read next byte */ | 
|  | eieio | 
|  | bl      waitSpd | 
|  | bne     spdErr | 
|  |  | 
|  | li      r10, 0x88           /* generate STOP condition */ | 
|  | stb     r10, 8(r14) | 
|  | eieio | 
|  |  | 
|  | lbz     r3, 16(r14)         /* return read byte */ | 
|  |  | 
|  | mtspr   8, r25              /* restore link register */ | 
|  | blr | 
|  |  | 
|  | gotNoAck: | 
|  | li      r10, 0x80           /* generate STOP condition */ | 
|  | stb     r10, 8(r14) | 
|  | eieio | 
|  | spdErr: | 
|  | orc     r3, r0, r0          /* return -1 */ | 
|  | mtspr   8, r25              /* restore link register */ | 
|  | blr | 
|  |  | 
|  | get_lnk_reg: | 
|  | mflr    r3                  /* return link reg */ | 
|  | blr | 
|  |  | 
|  | MessageBlock: | 
|  |  | 
|  | MinitLogo: | 
|  | .ascii  "\015\012*** ELTEC Elektronik, Mainz ***\015\012" | 
|  | .ascii  "\015\012Initialising RAM\015\012\000" | 
|  | Mspd01: | 
|  | .ascii  "       Reading SPD of SODIMM ...... \000" | 
|  | MramTyp: | 
|  | .ascii  "\015\012\SDRAM with CL=2 at 100 MHz required!\015\012\000" | 
|  | MramConfErr: | 
|  | .ascii  "\015\012\Unsupported SODIMM Configuration!\015\012\000" | 
|  | Mactivate: | 
|  | .ascii  "       Activating \000" | 
|  | Mact0123e: | 
|  | .ascii  " MByte.\015\012\000" | 
|  | Mok: | 
|  | .ascii  "OK \015\012\000" | 
|  | Mfail: | 
|  | .ascii  "FAILED \015\012\000" | 
|  | MnewLine: | 
|  | .ascii  "\015\012\000" | 
|  | .align 4 |