| /* | |
| * (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 |