summaryrefslogtreecommitdiff
path: root/board/eltec/bab7xx
diff options
context:
space:
mode:
authorwdenk <wdenk>2002-11-03 00:24:07 +0000
committerwdenk <wdenk>2002-11-03 00:24:07 +0000
commitc609719b8d1b2dca590e0ed499016d041203e403 (patch)
tree7ea1755d80903ff972f312a249eb856061d40e15 /board/eltec/bab7xx
parent5b1d713721c3ea02549940133f09236783dda1f9 (diff)
Initial revision
Diffstat (limited to 'board/eltec/bab7xx')
-rw-r--r--board/eltec/bab7xx/asm_init.S1487
-rw-r--r--board/eltec/bab7xx/el_srom.c292
-rw-r--r--board/eltec/bab7xx/u-boot.lds129
3 files changed, 1908 insertions, 0 deletions
diff --git a/board/eltec/bab7xx/asm_init.S b/board/eltec/bab7xx/asm_init.S
new file mode 100644
index 0000000000..d739b81753
--- /dev/null
+++ b/board/eltec/bab7xx/asm_init.S
@@ -0,0 +1,1487 @@
+/*
+ * (C) Copyright 2001 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * ELTEC BAB PPC 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 <mpc75x.h>
+#include <mpc106.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+/*
+ * This following contains the entry code for the initialization code
+ * for the MPC 106, a PCI Bridge/Memory Controller.
+ * Register usage:
+ * r0 = ramtest scratch register, toggleError loop counter
+ * r1 = 0xfec0 0cf8 CONFIG_ADDRESS
+ * r2 = 0xfee0 0cfc CONFIG_DATA
+ * r3 = scratch register, subroutine argument and return value, ramtest size
+ * r4 = scratch register, spdRead clock mask, OutHex loop count
+ * r5 = ramtest scratch register
+ * r6 = toggleError 1st value, spdRead port mask
+ * r7 = toggleError 2nd value, ramtest scratch register,
+ * spdRead scratch register (0x00)
+ * r8 = ramtest scratch register, spdRead scratch register (0x80)
+ * r9 = ramtest scratch register, toggleError loop end, OutHex digit
+ * r10 = ramtest scratch register, spdWriteByte parameter,
+ * spdReadByte return value, printf pointer to COM1
+ * r11 = startType
+ * r12 = ramtest scratch register, spdRead data mask
+ * r13 = pointer to message block
+ * r14 = pointer to GOT
+ * r15 = scratch register, SPD save
+ * r16 = bank0 size, total memory size
+ * r17 = bank1 size
+ * r18 = bank2 size
+ * r19 = bank3 size
+ * r20 = MCCR1, MSAR1
+ * r21 = MCCR3, MEAR1
+ * r22 = MCCR4, MBER
+ * r23 = EMSAR1
+ * r24 = EMEAR1
+ * r25 = save link register 1st level
+ * r26 = save link register 2nd level
+ * r27 = save link register 3rd level
+ * r30 = pointer to GPIO for spdRead
+ */
+
+
+.globl board_asm_init
+board_asm_init:
+/*
+ * setup pointer to message block
+ */
+ mflr r25 /* save away link register */
+ bl get_lnk_reg /* r3=addr of next instruction */
+ subi r4, r3, 8 /* r4=board_asm_init addr */
+ addi r13, 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
+
+ lis r1, 0xfec0
+ ori r1, r1, 0x0cf8
+ lis r2, 0xfee0
+ ori r2, r2, 0xcfc
+
+#ifdef CFG_ADDRESS_MAP_A
+/*
+ * Switch to address map A if necessary.
+ */
+ lis r3, MPC106_REG@h
+ ori r3, r3, PCI_PICR1
+ stwbrx r3, 0, r1
+ sync
+ lwbrx r4, 0, r2
+ sync
+ lis r0, PICR1_XIO_MODE@h
+ ori r0, r0, PICR1_XIO_MODE@l
+ andc r4, r4, r0
+ lis r0, PICR1_ADDRESS_MAP@h
+ ori r0, r0, PICR1_ADDRESS_MAP@l
+ or r4, r4, r0
+ stwbrx r4, 0, r2
+ sync
+#endif
+
+/*
+ * Do the init for the SIO.
+ */
+ bl .sioInit
+
+ addi r3, r13, (MinitLogo-MessageBlock)
+ bl Printf
+
+ addi r3, r13, (Mspd01-MessageBlock)
+ bl Printf
+/*
+ * Memory cofiguration using SPD information stored on the SODIMMs
+ */
+ li r17, 0
+ li r18, 0
+ li r19, 0
+
+ li r3, 0x0002 /* get RAM type from spd for bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, -1 /* error ? */
+ bne noSpdError
+
+ addi r3, r13, (Mfail-MessageBlock)
+ bl Printf
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x00
+ b toggleError /* fail - loop forever */
+
+noSpdError:
+ mr r15, r3 /* save r3 */
+
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+
+ cmpli 0, 0, r15, 0x0001 /* FPM ? */
+ beq configFPM
+ cmpli 0, 0, r15, 0x0002 /* EDO ? */
+ beq configEDO
+ cmpli 0, 0, r15, 0x0004 /* SDRAM ? */
+ beq configSDRAM
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x01
+ b toggleError /* fail - loop forever */
+
+configSDRAM:
+ addi r3, r13, (MsdRam-MessageBlock)
+ bl Printf
+/*
+ * set the Memory Configuration Reg. 1
+ */
+ li r3, 0x001f /* get bank size from spd bank0/1 */
+ bl spdRead
+
+ andi. r3, r3, 0x0038
+ beq SD16MB2B
+
+ li r3, 0x0011 /* get number of internal banks */
+ /* from spd for bank0/1 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x02
+ beq SD64MB2B
+
+ cmpli 0, 0, r3, 0x04
+ beq SD64MB4B
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x02
+ b toggleError /* fail - loop forever */
+
+SD64MB2B:
+ li r20, 0x0005 /* 64-Mbit SDRAM 2 banks */
+ b SDRow2nd
+
+SD64MB4B:
+ li r20, 0x0000 /* 64-Mbit SDRAM 4 banks */
+ b SDRow2nd
+
+SD16MB2B:
+ li r20, 0x000f /* 16-Mbit SDRAM 2 banks */
+
+SDRow2nd:
+ li r3, 0x0102 /* get RAM type spd for bank2/3 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x0004
+ bne S2D64MB4B /* bank2/3 isn't present or no SDRAM */
+
+ li r3, 0x011f /* get bank size from spd bank2/3 */
+ bl spdRead
+
+ andi. r3, r3, 0x0038
+ beq S2D16MB2B
+/*
+ * set the Memory Configuration Reg. 2
+ */
+ li r3, 0x0111 /* get number of internal banks */
+ /* from spd for bank2/3 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x02
+ beq S2D64MB2B
+
+ cmpli 0, 0, r3, 0x04
+ beq S2D64MB4B
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x03
+ b toggleError /* fail - loop forever */
+
+S2D64MB2B:
+ ori r20, r20, 0x0050 /* 64-Mbit SDRAM 2 banks */
+ b S2D64MB4B
+
+S2D16MB2B:
+ ori r20, r20, 0x00f0 /* 16-Mbit SDRAM 2 banks */
+
+/*
+ * set the Memory Configuration Reg. 3
+ */
+S2D64MB4B:
+ lis r21, 0x8630 /* BSTOPRE = 0x80, REFREC = 6, */
+ /* RDLAT = 3 */
+
+/*
+ * set the Memory Configuration Reg. 4
+ */
+ lis r22, 0x2430 /* PRETOACT = 2, ACTOPRE = 4, */
+ /* WCBUF = 1, RCBUF = 1 */
+ ori r22, r22, 0x2220 /* SDMODE = 0x022, ACTORW = 2 */
+
+/*
+ * get the size of bank 0-3
+ */
+ li r3, 0x001f /* get bank size from spd 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:
+ addi r3, r13, (Mspd23-MessageBlock)
+ bl Printf
+
+ li r3, 0x0102 /* get RAM type spd for bank2/3 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x0001 /* FPM ? */
+ bne noFPM23 /* handle as EDO */
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MfpmRam-MessageBlock)
+ bl Printf
+ b configRAMcommon
+noFPM23:
+ cmpli 0, 0, r3, 0x0002 /* EDO ? */
+ bne noEDO23
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MedoRam-MessageBlock)
+ bl Printf
+ b configRAMcommon
+noEDO23:
+ cmpli 0, 0, r3, 0x0004 /* SDRAM ? */
+ bne noSDRAM23
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MsdRam-MessageBlock)
+ bl Printf
+ b configSDRAM23
+noSDRAM23:
+ addi r3, r13, (Mna-MessageBlock)
+ bl Printf
+ b configRAMcommon /* bank2/3 isn't present or no SDRAM */
+
+configSDRAM23:
+ li r3, 0x011f /* get bank size from spd bank2/3 */
+ bl spdRead
+
+ rlwinm r18, r3, 2, 24, 29 /* calculate size in MByte */
+ /* (128 MB max.) */
+
+ li r3, 0x0105 /* get number of banks from */
+ /* spd bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, 2 /* 2 banks ? */
+ bne SDRAMnobank3
+
+ mr r19, r18
+
+SDRAMnobank3:
+ b configRAMcommon
+
+configFPM:
+ addi r3, r13, (MfpmRam-MessageBlock)
+ bl Printf
+ b configEDO0
+/*
+ * set the Memory Configuration Reg. 1
+ */
+configEDO:
+ addi r3, r13, (MedoRam-MessageBlock)
+ bl Printf
+configEDO0:
+ lis r20, MCCR1_TYPE_EDO@h
+
+getSpdRowBank01:
+ li r3, 0x0003 /* get number of row bits from */
+ /* spd from bank0/1 */
+ bl spdRead
+ ori r20, r20, (MCCR1_BK0_9BITS | MCCR1_BK1_9BITS)
+ cmpli 0, 0, r3, 0x0009 /* bank0 - 9 row bits */
+ beq getSpdRowBank23
+
+ ori r20, r20, (MCCR1_BK0_10BITS | MCCR1_BK1_10BITS)
+ cmpli 0, 0, r3, 0x000a /* bank0 - 10 row bits */
+ beq getSpdRowBank23
+
+ ori r20, r20, (MCCR1_BK0_11BITS | MCCR1_BK1_11BITS)
+ cmpli 0, 0, r3, 0x000b /* bank0 - 11 row bits */
+ beq getSpdRowBank23
+
+ ori r20, r20, (MCCR1_BK0_12BITS | MCCR1_BK1_12BITS)
+ cmpli 0, 0, r3, 0x000c /* bank0 - 12 row bits */
+ beq getSpdRowBank23
+
+ cmpli 0, 0, r3, 0x000d /* bank0 - 13 row bits */
+ beq getSpdRowBank23
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x10
+ b toggleError /* fail - loop forever */
+
+getSpdRowBank23:
+ li r3, 0x0103 /* get number of row bits from */
+ /* spd for bank2/3 */
+ bl spdRead
+
+ ori r20, r20, (MCCR1_BK2_9BITS | MCCR1_BK3_9BITS)
+ cmpli 0, 0, r3, 0x0009 /* bank0 - 9 row bits */
+ beq writeRowBits
+
+ ori r20, r20, (MCCR1_BK2_10BITS | MCCR1_BK3_10BITS)
+ cmpli 0, 0, r3, 0x000a /* bank0 - 10 row bits */
+ beq writeRowBits
+
+ ori r20, r20, (MCCR1_BK2_11BITS | MCCR1_BK3_11BITS)
+ cmpli 0, 0, r3, 0x000b /* bank0 - 11 row bits */
+ beq writeRowBits
+
+ ori r20, r20, (MCCR1_BK2_12BITS | MCCR1_BK3_12BITS)
+
+/*
+ * set the Memory Configuration Reg. 3
+ */
+writeRowBits:
+ lis r21, 0x000a /* CPX = 1, RAS6P = 4 */
+ ori r21, r21, 0x2293 /* CAS5 = 2, CP4 = 1, */
+ /* CAS3 = 2, RCD2 = 2, RP = 3 */
+/*
+ * set the Memory Configuration Reg. 4
+ */
+ lis r22, 0x0010 /* all SDRAM parameter 0, */
+ /* WCBUF flow through, */
+ /* RCBUF registered */
+/*
+ * get the size of bank 0-3
+ */
+ li r3, 0x0003 /* get row bits from spd bank0/1 */
+ bl spdRead
+
+ li r16, 0 /* bank size is: */
+ /* (8*2^row*2^column)/0x100000 MB */
+ ori r16, r16, 0x8000
+ rlwnm r16, r16, r3, 0, 31
+
+ li r3, 0x0004 /* get column bits from spd bank0/1 */
+ bl spdRead
+
+ rlwnm r16, r16, r3, 0, 31
+
+ li r3, 0x0005 /* get number of banks from */
+ /* spd for bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, 2 /* 2 banks ? */
+ bne EDOnobank1
+
+ mr r17, r16
+
+EDOnobank1:
+ addi r3, r13, (Mspd23-MessageBlock)
+ bl Printf
+
+ li r3, 0x0102 /* get RAM type spd for bank2/3 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x0001 /* FPM ? */
+ bne noFPM231 /* handle as EDO */
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MfpmRam-MessageBlock)
+ bl Printf
+ b EDObank2
+noFPM231:
+ cmpli 0, 0, r3, 0x0002 /* EDO ? */
+ bne noEDO231
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MedoRam-MessageBlock)
+ bl Printf
+ b EDObank2
+noEDO231:
+ cmpli 0, 0, r3, 0x0004 /* SDRAM ? */
+ bne noSDRAM231
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MsdRam-MessageBlock)
+ bl Printf
+ b configRAMcommon
+noSDRAM231:
+ addi r3, r13, (Mfail-MessageBlock)
+ bl Printf
+ b configRAMcommon /* bank2/3 isn't present or no SDRAM */
+
+EDObank2:
+ li r3, 0x0103 /* get row bits from spd for bank2/3 */
+ bl spdRead
+
+ li r18, 0 /* bank size is: */
+ /* (8*2^row*2^column)/0x100000 MB */
+ ori r18, r18, 0x8000
+ rlwnm r18, r18, r3, 0, 31
+
+ li r3, 0x0104 /* get column bits from spd bank2/3 */
+ bl spdRead
+
+ rlwnm r18, r18, r3, 0, 31
+
+ li r3, 0x0105 /* get number of banks from */
+ /* spd for bank2/3 */
+ bl spdRead
+
+ cmpi 0, 0, r3, 2 /* 2 banks ? */
+ bne configRAMcommon
+
+ mr r19, r18
+
+configRAMcommon:
+ 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
+
+ li r0, 0
+
+/*
+ * If we are already running in RAM (debug mode), we should
+ * NOT reset the MEMGO flag. Otherwise we will stop all memory
+ * accesses.
+ */
+#ifdef IN_RAM
+ lis r4, MCCR1_MEMGO@h
+ ori r4, r4, MCCR1_MEMGO@l
+ or r20, r20, r4
+#endif
+
+/*
+ * set the Memory Configuration Reg. 1
+ */
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MCCR1 /* register number 0xf0 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r20, r0, r2 /* write data to CONFIG_DATA */
+/*
+ * set the Memory Configuration Reg. 3
+ */
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MCCR3 /* register number 0xf8 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r21, r0, r2 /* write data to CONFIG_DATA */
+/*
+ * set the Memory Configuration Reg. 4
+ */
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MCCR4 /* register number 0xfc */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r22, r0, r2 /* write data to CONFIG_DATA */
+/*
+ * set the memory boundary registers for bank 0-3
+ */
+ li r20, 0
+ li r23, 0
+ li r24, 0
+ subi r21, r16, 1 /* calculate end address bank0 */
+ li r22, (MBER_BANK0)
+
+ cmpi 0, 0, r17, 0 /* bank1 present ? */
+ beq nobank1
+
+ rlwinm r3, r16, 8, 16, 23 /* calculate start address of bank1 */
+ or r20, r20, r3
+ add r16, r16, r17 /* add to total memory size */
+ subi r3, r16, 1 /* calculate end address of bank1 */
+ rlwinm r3, r3, 8, 16, 23
+ or r21, r21, r3
+ ori r22, r22, (MBER_BANK1) /* enable bank1 */
+ b bank2
+
+nobank1:
+ ori r23, r23, 0x0300 /* set bank1 start to unused area */
+ ori r24, r24, 0x0300 /* set bank1 end to unused area */
+
+bank2:
+ cmpi 0, 0, r18, 0 /* bank2 present ? */
+ beq nobank2
+
+ andi. r3, r16, 0x00ff /* calculate start address of bank2 */
+ andi. r4, r16, 0x0300
+ rlwinm r3, r3, 16, 8, 15
+ or r20, r20, r3
+ rlwinm r3, r4, 8, 8, 15
+ or r23, r23, r3
+ add r16, r16, r18 /* add to total memory size */
+ subi r3, r16, 1 /* calculate end address of bank2 */
+ andi. r4, r3, 0x0300
+ andi. r3, r3, 0x00ff
+ rlwinm r3, r3, 16, 8, 15
+ or r21, r21, r3
+ rlwinm r3, r4, 8, 8, 15
+ or r24, r24, r3
+ ori r22, r22, (MBER_BANK2) /* enable bank2 */
+ b bank3
+
+nobank2:
+ lis r3, 0x0003
+ or r23, r23, r3 /* set bank2 start to unused area */
+ or r24, r24, r3 /* set bank2 end to unused area */
+
+bank3:
+ cmpi 0, 0, r19, 0 /* bank3 present ? */
+ beq nobank3
+
+ andi. r3, r16, 0x00ff /* calculate start address of bank3 */
+ andi. r4, r16, 0x0300
+ rlwinm r3, r3, 24, 0, 7
+ or r20, r20, r3
+ rlwinm r3, r4, 16, 0, 7
+ or r23, r23, r3
+ add r16, r16, r19 /* add to total memory size */
+ subi r3, r16, 1 /* calculate end address of bank3 */
+ andi. r4, r3, 0x0300
+ andi. r3, r3, 0x00ff
+ rlwinm r3, r3, 24, 0, 7
+ or r21, r21, r3
+ rlwinm r3, r4, 16, 0, 7
+ or r24, r24, r3
+ ori r22, r22, (MBER_BANK3) /* enable bank3 */
+ b writebound
+
+nobank3:
+ lis r3, 0x0300
+ or r23, r23, r3 /* set bank3 start to unused area */
+ or r24, r24, r3 /* set bank3 end to unused area */
+
+writebound:
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MSAR1 /* register number 0x80 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r20, r0, r2 /* write data to CONFIG_DATA */
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MEAR1 /* register number 0x90 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r21, r0, r2 /* write data to CONFIG_DATA */
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_EMSAR1 /* register number 0x88 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r23, r0, r2 /* write data to CONFIG_DATA */
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_EMEAR1 /* register number 0x98 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r24, r0, r2 /* write data to CONFIG_DATA */
+
+/*
+ * set boundaries of unused banks to unused address space
+ */
+ lis r4, 0x0303
+ ori r4, r4, 0x0303 /* bank 4-7 start and end adresses */
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_EMSAR2 /* register number 0x8C */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_EMEAR2 /* register number 0x9C */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
+
+/*
+ * set the Memory Configuration Reg. 2
+ */
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MCCR2 /* register number 0xf4 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+
+ li r3, 0x000c /* get refresh from spd for bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, -1 /* error ? */
+ bne common1
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x20
+ b toggleError /* fail - loop forever */
+
+common1:
+ andi. r15, r3, 0x007f /* mask selfrefresh bit */
+ li r3, 0x010c /* get refresh from spd for bank2/3 */
+ bl spdRead
+
+ cmpi 0, 0, r3, -1 /* error ? */
+ beq common2
+ andi. r3, r3, 0x007f /* mask selfrefresh bit */
+ cmp 0, 0, r3, r15 /* find the lower */
+ blt common3
+
+common2:
+ mr r3, r15
+
+common3:
+ li r4, 0x1010 /* refesh cycle 1028 clocks */
+ /* left shifted 2 */
+ cmpli 0, 0, r3, 0x0000 /* 15.6 us ? */
+ beq writeRefresh
+
+ li r4, 0x0808 /* refesh cycle 514 clocks */
+ /* left shifted 2 */
+ cmpli 0, 0, r3, 0x0002 /* 7.8 us ? */
+ beq writeRefresh
+
+ li r4, 0x2020 /* refesh cycle 2056 clocks */
+ /* left shifted 2 */
+ cmpli 0, 0, r3, 0x0003 /* 31.3 us ? */
+ beq writeRefresh
+
+ li r4, 0x4040 /* refesh cycle 4112 clocks */
+ /* left shifted 2 */
+ cmpli 0, 0, r3, 0x0004 /* 62.5 us ? */
+ beq writeRefresh
+
+ li r4, 0
+ ori r4, r4, 0x8080 /* refesh cycle 8224 clocks */
+ /* left shifted 2 */
+ cmpli 0, 0, r3, 0x0005 /* 125 us ? */
+ beq writeRefresh
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x21
+ b toggleError /* fail - loop forever */
+
+writeRefresh:
+ stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
+
+/*
+ * DRAM BANKS SHOULD BE ENABLED
+ */
+ addi r3, r13, (Mactivate-MessageBlock)
+ bl Printf
+ mr r3, r16
+ bl OutDec
+ addi r3, r13, (Mmbyte-MessageBlock)
+ bl Printf
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MBER /* register number 0xa0 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stb r22, 0(r2) /* write data to CONFIG_DATA */
+ li r8, 0x63 /* PGMAX = 99 */
+ stb r8, 3(r2) /* write data to CONFIG_DATA */
+
+/*
+ * DRAM SHOULD NOW BE CONFIGURED AND ENABLED
+ * MUST WAIT 200us BEFORE ACCESSING
+ */
+ li r0, 0x7800
+ mtctr r0
+
+wait200us:
+ bdnz wait200us
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MCCR1 /* register number 0xf0 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+
+ lwbrx r4, r0, r2 /* load r4 from CONFIG_DATA */
+
+ lis r0, MCCR1_MEMGO@h /* MEMGO=1 */
+ ori r0, r0, MCCR1_MEMGO@l
+ or r4, r4, r0 /* set the MEMGO bit */
+ stwbrx r4, r0, r2 /* write mdfd data to CONFIG_DATA */
+
+ li r0, 0x7000
+ mtctr r0
+
+wait8ref:
+ bdnz wait8ref
+
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+
+ mtlr r25
+ blr
+
+/*
+ * Infinite loop called in case of an error during RAM initialisation.
+ * error codes in r6 and r7.
+ */
+toggleError:
+ li r0, 0
+ lis r9, 127
+ ori r9, r9, 65535
+toggleError1:
+ addic r0, r0, 1
+ cmpw cr1, r0, r9
+ ble cr1, toggleError1
+ li r0, 0
+ lis r9, 127
+ ori r9, r9, 65535
+toggleError2:
+ addic r0, r0, 1
+ cmpw cr1, r0, r9
+ ble cr1, toggleError2
+ b toggleError
+
+
+/******************************************************************************
+ * This function performs a basic initialisation of the superio chip
+ * to enable basic console output and SPD access during RAM initialisation.
+ *
+ * Upon completion, SIO resource registers are mapped as follows:
+ * Resource Enabled Address
+ * UART1 Yes 3F8-3FF COM1
+ * UART2 Yes 2F8-2FF COM2
+ * GPIO Yes 220-227
+ */
+.set SIO_LUNINDEX, 0x07 /* SIO LUN index register */
+.set SIO_CNFG1, 0x21 /* SIO configuration #1 register */
+.set SIO_PCSCI, 0x23 /* SIO PCS configuration index reg */
+.set SIO_PCSCD, 0x24 /* SIO PCS configuration data reg */
+.set SIO_ACTIVATE, 0x30 /* SIO activate register */
+.set SIO_IOBASEHI, 0x60 /* SIO I/O port base address, 15:8 */
+.set SIO_IOBASELO, 0x61 /* SIO I/O port base address, 7:0 */
+.set SIO_LUNENABLE, 0x01 /* SIO LUN enable */
+
+.sioInit:
+ mfspr r7, 8 /* save link register */
+
+.sioInit_87308:
+
+/*
+ * Get base addr of ISA I/O space
+ */
+ lis r6, CFG_ISA_IO@h
+ ori r6, r6, CFG_ISA_IO@l
+
+/*
+ * Set offset to base address for config registers.
+ */
+#if defined(CFG_NS87308_BADDR_0x)
+ addi r4, r0, 0x0279
+#elif defined(CFG_NS87308_BADDR_10)
+ addi r4, r0, 0x015C
+#elif defined(CFG_NS87308_BADDR_11)
+ addi r4, r0, 0x002E
+#endif
+ add r6, r6, r4 /* add offset to base */
+ or r3, r6, r6 /* make a copy */
+
+/*
+ * PMC (LUN 8)
+ */
+ addi r4, r0, SIO_LUNINDEX /* select PMC LUN */
+ addi r5, r0, 0x8
+ bl .sio_bw
+ addi r4, r0, SIO_IOBASEHI /* initialize PMC address to 0x460 */
+ addi r5, r0, 0x04
+ bl .sio_bw
+ addi r4, r0, SIO_IOBASELO
+ addi r5, r0, 0x60
+ bl .sio_bw
+ addi r4, r0, SIO_ACTIVATE /* enable PMC */
+ addi r5, r0, SIO_LUNENABLE
+ bl .sio_bw
+
+ lis r8, CFG_ISA_IO@h
+ ori r8, r8, 0x0460
+ li r9, 0x03
+ stb r9, 0(r8) /* select PMC2 register */
+ eieio
+ li r9, 0x00
+ stb r9, 1(r8) /* SuperI/O clock src: 24MHz via X1 */
+ eieio
+
+/*
+ * map UART1 (LUN 6) or UART2 (LUN 5) to COM1 (0x3F8)
+ */
+ addi r4, r0, SIO_LUNINDEX /* select COM1 LUN */
+ addi r5, r0, 0x6
+ bl .sio_bw
+
+ addi r4, r0, SIO_IOBASEHI /* initialize COM1 address to 0x3F8 */
+ addi r5, r0, 0x03
+ bl .sio_bw
+
+ addi r4, r0, SIO_IOBASELO
+ addi r5, r0, 0xF8
+ bl .sio_bw
+
+ addi r4, r0, SIO_ACTIVATE /* enable COM1 */
+ addi r5, r0, SIO_LUNENABLE
+ bl .sio_bw
+
+/*
+ * Init COM1 for polled output
+ */
+ lis r8, CFG_ISA_IO@h
+ ori r8, r8, 0x03f8
+ 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, bank select */
+ eieio
+ li r9, 115200/CONFIG_BAUDRATE
+ stb r9, 0(r8) /* baud rate (LSB)*/
+ eieio
+ rotrwi r9, r9, 8
+ stb r9, 1(r8) /* baud rate (MSB) */
+ eieio
+ li r9, 0x03
+ stb r9, 3(r8) /* 8 data bits, 1 stop bit, */
+ /* no parity */
+ eieio
+ li r9, 0x0b
+ stb r9, 4(r8) /* enable the receiver and transmitter */
+ 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 bits, 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 bits, */
+ /* no parity */
+ eieio
+
+/*
+ * GPIO (LUN 7)
+ */
+ addi r4, r0, SIO_LUNINDEX /* select GPIO LUN */
+ addi r5, r0, 0x7
+ bl .sio_bw
+
+ addi r4, r0, SIO_IOBASEHI /* initialize GPIO address to 0x220 */
+ addi r5, r0, 0x02
+ bl .sio_bw
+
+ addi r4, r0, SIO_IOBASELO
+ addi r5, r0, 0x20
+ bl .sio_bw
+
+ addi r4, r0, SIO_ACTIVATE /* enable GPIO */
+ addi r5, r0, SIO_LUNENABLE
+ bl .sio_bw
+
+.sioInit_done:
+
+/*
+ * Get base addr of ISA I/O space
+ */
+ lis r3, CFG_ISA_IO@h
+ ori r3, r3, CFG_ISA_IO@l
+
+ addi r3, r3, 0x015C /* adjust to superI/O 87308 base */
+ or r6, r3, r3 /* make a copy */
+/*
+ * CS0
+ */
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x00
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x00
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x01
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x76
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x02
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x40
+ bl .sio_bw
+/*
+ * CS1
+ */
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x05
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x00
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x05
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x70
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x06
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x1C
+ bl .sio_bw
+/*
+ * CS2
+ */
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x08
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x00
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x09
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x71
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x0A
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x1C
+ bl .sio_bw
+
+ mtspr 8, r7 /* restore link register */
+ bclr 20, 0 /* return to caller */
+
+/*
+ * this function writes a register to the SIO chip
+ */
+.sio_bw:
+ stb r4, 0(r3) /* write index register with register offset */
+ eieio
+ sync
+ stb r5, 1(r3) /* 1st write */
+ eieio
+ sync
+ stb r5, 1(r3) /* 2nd write */
+ eieio
+ sync
+ bclr 20, 0 /* return to caller */
+/*
+ * this function reads a register from the SIO chip
+ */
+.sio_br:
+ stb r4, 0(r3) /* write index register with register offset */
+ eieio
+ sync
+ lbz r3, 1(r3) /* retrieve specified reg offset contents */
+ eieio
+ sync
+ bclr 20, 0 /* return to caller */
+
+/*
+ * Print a message to COM1 in polling mode
+ * r10=COM1 port, r3=(char*)string
+ */
+.globl Printf
+Printf:
+ lis r10, CFG_ISA_IO@h /* COM1 port */
+ ori r10, r10, 0x03f8
+
+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 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
+ .globl OutHex
+OutHex:
+ li r9, 28 /* shift reg for 8 digits */
+OHstart:
+ lis r10, CFG_ISA_IO@h /* COM1 port */
+ ori r10, r10, 0x03f8
+OutDig:
+ 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
+ */
+.globl OutDec
+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_ISA_IO@h /* COM1 port */
+ ori r10, r10, 0x03f8
+
+ or. r7, r7, r7
+ bne noblank1
+ li r3, 0x20
+ b OutDec4
+
+noblank1:
+ addi r3, r7, 48 /* convert to ASCII */
+
+OutDec4:
+ lbz r0, 0(r13) /* 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(r13) /* 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(r13) /* 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
+/*
+ * Print a char to COM1 in polling mode
+ * r10=COM1 port, r3=char
+ */
+.globl OutChr
+OutChr:
+ lis r10, CFG_ISA_IO@h /* COM1 port */
+ ori r10, r10, 0x03f8
+
+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
+/*
+ * Input: r3 adr to read
+ * Output: r3 val or -1 for error
+ */
+spdRead:
+ mfspr r26, 8 /* save link register */
+
+ lis r30, CFG_ISA_IO@h
+ ori r30, r30, 0x220 /* GPIO Port 1 */
+ li r7, 0x00
+ li r8, 0x100
+ and. r5, r3, r8
+ beq spdbank0
+ li r12, 0x08
+ li r4, 0x10
+ li r6, 0x18
+ b spdRead1
+
+spdbank0:
+ li r12, 0x20 /* set I2C data */
+ li r4, 0x40 /* set I2C clock */
+ li r6, 0x60 /* set I2C clock and data */
+
+spdRead1:
+ li r8, 0x80
+
+ bl spdStart /* access I2C bus as master */
+ li r10, 0xa0 /* write to SPD */
+ bl spdWriteByte
+ bl spdReadAck /* ACK returns in r10 */
+ cmpw cr0, r10, r7
+ bne AckErr /* r10 must be 0, if ACK received */
+ mr r10, r3 /* adr to read */
+ bl spdWriteByte
+ bl spdReadAck
+ cmpw cr0, r10, r7
+ bne AckErr
+ bl spdStart
+ li r10, 0xa1 /* read from SPD */
+ bl spdWriteByte
+ bl spdReadAck
+ cmpw cr0, r10, r7
+ bne AckErr
+ bl spdReadByte /* return val in r10 */
+ bl spdWriteAck
+ bl spdStop /* release I2C bus */
+ mr r3, r10
+ mtspr 8, r26 /* restore link register */
+ blr
+/*
+ * ACK error occurred
+ */
+AckErr:
+ bl spdStop
+ orc r3, r0, r0 /* return -1 */
+ mtspr 8, r26 /* restore link register */
+ blr
+
+/*
+ * Routines to read from RAM spd.
+ * r30 - GPIO Port1 address in all cases.
+ * r4 - clock mask for SPD
+ * r6 - port mask for SPD
+ * r12 - data mask for SPD
+ */
+waitSpd:
+ li r0, 0x1000
+ mtctr r0
+wSpd:
+ bdnz wSpd
+ bclr 20, 0 /* return to caller */
+
+/*
+ * establish START condition on I2C bus
+ */
+spdStart:
+ mfspr r27, 8 /* save link register */
+ stb r6, 0(r30) /* set SDA and SCL */
+ eieio
+ stb r6, 1(r30) /* switch GPIO to output */
+ eieio
+ bl waitSpd
+ stb r4, 0(r30) /* reset SDA */
+ eieio
+ bl waitSpd
+ stb r7, 0(r30) /* reset SCL */
+ eieio
+ bl waitSpd
+ mtspr 8, r27
+ bclr 20, 0 /* return to caller */
+
+/*
+ * establish STOP condition on I2C bus
+ */
+spdStop:
+ mfspr r27, 8 /* save link register */
+ stb r7, 0(r30) /* reset SCL and SDA */
+ eieio
+ stb r6, 1(r30) /* switch GPIO to output */
+ eieio
+ bl waitSpd
+ stb r4, 0(r30) /* set SCL */
+ eieio
+ bl waitSpd
+ stb r6, 0(r30) /* set SDA and SCL */
+ eieio
+ bl waitSpd
+ stb r7, 1(r30) /* switch GPIO to input */
+ eieio
+ mtspr 8, r27
+ bclr 20, 0 /* return to caller */
+
+spdReadByte:
+ mfspr r27, 8
+ stb r4, 1(r30) /* set GPIO for SCL output */
+ eieio
+ li r9, 0x08
+ li r10, 0x00
+loopRB:
+ stb r7, 0(r30) /* reset SDA and SCL */
+ eieio
+ bl waitSpd
+ stb r4, 0(r30) /* set SCL */
+ eieio
+ bl waitSpd
+ lbz r5, 0(r30) /* read from GPIO Port1 */
+ rlwinm r10, r10, 1, 0, 31
+ and. r5, r5, r12
+ beq clearBit
+ ori r10, r10, 0x01 /* append _1_ */
+clearBit:
+ stb r7, 0(r30) /* reset SCL */
+ eieio
+ bl waitSpd
+ addic. r9, r9, -1
+ bne loopRB
+ mtspr 8, r27
+ bclr 20, 0 /* return (r10) to caller */
+
+/*
+ * spdWriteByte writes bits 24 - 31 of r10 to I2C.
+ * r8 contains bit mask 0x80
+ */
+spdWriteByte:
+ mfspr r27, 8 /* save link register */
+ li r9, 0x08 /* write octet */
+ and. r5, r10, r8
+ bne sWB1
+ stb r7, 0(r30) /* set SDA to _0_ */
+ eieio
+ b sWB2
+sWB1:
+ stb r12, 0(r30) /* set SDA to _1_ */
+ eieio
+sWB2:
+ stb r6, 1(r30) /* set GPIO to output */
+ eieio
+loopWB:
+ and. r5, r10, r8
+ bne sWB3
+ stb r7, 0(r30) /* set SDA to _0_ */
+ eieio
+ b sWB4
+sWB3:
+ stb r12, 0(r30) /* set SDA to _1_ */
+ eieio
+sWB4:
+ bl waitSpd
+ and. r5, r10, r8
+ bne sWB5
+ stb r4, 0(r30) /* set SDA to _0_ and SCL */
+ eieio
+ b sWB6
+sWB5:
+ stb r6, 0(r30) /* set SDA to _1_ and SCL */
+ eieio
+sWB6:
+ bl waitSpd
+ and. r5, r10, r8
+ bne sWB7
+ stb r7, 0(r30) /* set SDA to _0_ and reset SCL */
+ eieio
+ b sWB8
+sWB7:
+ stb r12, 0(r30) /* set SDA to _1_ and reset SCL */
+ eieio
+sWB8:
+ bl waitSpd
+ rlwinm r10, r10, 1, 0, 31 /* next bit */
+ addic. r9, r9, -1
+ bne loopWB
+ mtspr 8, r27
+ bclr 20, 0 /* return to caller */
+
+/*
+ * Read ACK from SPD, return value in r10
+ */
+spdReadAck:
+ mfspr r27, 8 /* save link register */
+ stb r4, 1(r30) /* set GPIO to output */
+ eieio
+ stb r7, 0(r30) /* reset SDA and SCL */
+ eieio
+ bl waitSpd
+ stb r4, 0(r30) /* set SCL */
+ eieio
+ bl waitSpd
+ lbz r10, 0(r30) /* read GPIO Port 1 and mask SDA */
+ and r10, r10, r12
+ bl waitSpd
+ stb r7, 0(r30) /* reset SDA and SCL */
+ eieio
+ bl waitSpd
+ mtspr 8, r27
+ bclr 20, 0 /* return (r10) to caller */
+
+spdWriteAck:
+ mfspr r27, 8
+ stb r12, 0(r30) /* set SCL */
+ eieio
+ stb r6, 1(r30) /* set GPIO to output */
+ eieio
+ bl waitSpd
+ stb r6, 0(r30) /* SDA and SCL */
+ eieio
+ bl waitSpd
+ stb r12, 0(r30) /* reset SCL */
+ eieio
+ bl waitSpd
+ mtspr 8, r27
+ bclr 20, 0 /* return to caller */
+
+get_lnk_reg:
+ mflr r3 /* return link reg */
+ blr
+
+/*
+ * Messages for console output
+ */
+.globl MessageBlock
+MessageBlock:
+Mok:
+ .ascii "OK\015\012\000"
+Mfail:
+ .ascii "FAILED\015\012\000"
+Mna:
+ .ascii "NA\015\012\000"
+MinitLogo:
+ .ascii "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
+ .ascii "\015\012Initialising RAM\015\012\000"
+Mspd01:
+ .ascii " Reading SPD of bank0/1 ..... \000"
+Mspd23:
+ .ascii " Reading SPD of bank2/3 ..... \000"
+MfpmRam:
+ .ascii " RAM-Type: FPM \015\012\000"
+MedoRam:
+ .ascii " RAM-Type: EDO \015\012\000"
+MsdRam:
+ .ascii " RAM-Type: SDRAM \015\012\000"
+Mactivate:
+ .ascii " Activating \000"
+Mmbyte:
+ .ascii " MB .......... \000"
+ .align 4
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/board/eltec/bab7xx/el_srom.c b/board/eltec/bab7xx/el_srom.c
new file mode 100644
index 0000000000..56abdc7c26
--- /dev/null
+++ b/board/eltec/bab7xx/el_srom.c
@@ -0,0 +1,292 @@
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * 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 <common.h>
+#include "srom.h"
+
+/*----------------------------------------------------------------------------*/
+/*
+ * START sequence
+ * _ _________
+ * SCLK _> \____
+ * _ ____
+ * SDIO _> \_________
+ * : : :
+ */
+static void eepStart (void)
+{
+ out8(I2C_BUS_DAT, 0x60); /* SCLK = high SDIO = high */
+ out8(I2C_BUS_DIR, 0x60); /* set output direction for SCLK/SDIO */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = low */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = low */
+ udelay(10);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * STOP sequence
+ * _______
+ * SCLK _____/
+ * _ ___
+ * SDIO _>_______/
+ * : : :
+ */
+static void eepStop (void)
+{
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = low */
+ out8(I2C_BUS_DIR, 0x60); /* set output direction for SCLK/SDIO */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = low */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x60); /* SCLK = high SDIO = high */
+ udelay(10);
+ out8(I2C_BUS_DIR, 0x00); /* reset to input direction */
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Read one byte from EEPROM
+ * ___ ___ ___ ___ ___ ___ ___ ___
+ * SCLK ___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \
+ * _________________________________________________________________
+ * SDIO > ^ ^ ^ ^ ^ ^ ^ ^
+ * : : : : : : : : : : : : : : : : :
+ */
+static unsigned char eepReadByte (void)
+{
+ register unsigned char buf = 0x00;
+ register int i;
+
+ out8(I2C_BUS_DIR, 0x40);
+
+ for (i = 0; i < 8; i++)
+ {
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = high */
+ udelay(15);
+ buf <<= 1;
+ buf = (in8(I2C_BUS_DAT) & 0x20) ? (buf | 0x01) : (buf & 0xFE);
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
+ udelay(10);
+ }
+ return(buf);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Write one byte to EEPROM
+ * ___ ___ ___ ___ ___ ___ ___ ___
+ * SCLK __/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \__
+ * _______ _______ _______ _______ _______ _______ _______ ________
+ * SDIO X_______X_______X_______X_______X_______X_______X_______X________
+ * : 7 : 6 : 5 : 4 : 3 : 2 : 1 : 0
+ */
+static void eepWriteByte (register unsigned char buf)
+{
+ register int i;
+
+ (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = data */
+ out8(I2C_BUS_DIR, 0x60);
+
+ for (i = 7; i >= 0; i--)
+ {
+ (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low SDIO=data */
+ udelay(10);
+ (buf & 0x80) ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK=high SDIO=data */
+ udelay(15);
+ (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low SDIO=data */
+ udelay(10);
+ buf <<= 1;
+ }
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Read data acknowledge of EEPROM
+ * _______
+ * SCLK ____/ \___
+ * _______________
+ * SDIO >
+ * : : ^ :
+ */
+static int eepReadAck (void)
+{
+ int retval;
+
+ out8(I2C_BUS_DIR, 0x40);
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = high */
+ udelay(10);
+ retval = (in8(I2C_BUS_DAT) & 0x20) ? ERROR : 0;
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
+ udelay(10);
+
+ return(retval);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Write data acknowledge to EEPROM
+ * _______
+ * SCLK ____/ \___
+ *
+ * SDIO >_______________
+ * : : :
+ */
+static void eepWriteAck (unsigned char ack)
+{
+ ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = ack */
+ out8(I2C_BUS_DIR, 0x60);
+ udelay(10);
+ ack ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = ack */
+ udelay(15);
+ ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = ack */
+ udelay(10);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Read bytes from EEPROM
+ */
+int el_srom_load (addr, buf, cnt, device, block)
+unsigned char addr;
+unsigned char *buf;
+int cnt;
+unsigned char device;
+unsigned char block;
+{
+ register int i;
+
+ for (i=0;i<cnt;i++)
+ {
+ eepStart();
+ eepWriteByte(0xA0 | device | block);
+ if (eepReadAck() == ERROR)
+ {
+ eepStop();
+ return(ERROR);
+ }
+ eepWriteByte(addr++);
+ if (eepReadAck() == ERROR)
+ {
+ eepStop();
+ return(ERROR);
+ }
+ eepStart();
+
+ eepWriteByte(0xA1 | device | block);
+ if (eepReadAck() == ERROR)
+ {
+ eepStop();
+ return(ERROR);
+ }
+
+ *buf++ = eepReadByte();
+ eepWriteAck(1);
+ eepStop();
+
+ if ((addr == 0) && (i != (cnt-1))) /* is it the same block ? */
+ {
+ if (block == FIRST_BLOCK)
+ block = SECOND_BLOCK;
+ else
+ return(ERROR);
+ }
+ }
+ return(cnt);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *
+ * Write bytes to EEPROM
+ *
+ */
+int el_srom_store (addr, buf, cnt, device, block)
+unsigned char addr, *buf, device, block;
+int cnt;
+{
+ register int i, retVal;
+
+ for (i=0;i<cnt;i++)
+ {
+ retVal = ERROR;
+ do
+ {
+ eepStart();
+ eepWriteByte(0xA0 | device | block);
+ if ((retVal = eepReadAck()) == ERROR)
+ eepStop();
+ } while (retVal == ERROR);
+
+ eepWriteByte(addr++);
+ if (eepReadAck() == ERROR) return(ERROR);
+
+ if ((addr == 0) && (i != (cnt-1))) /* is it the same block ? */
+ {
+ if (block == FIRST_BLOCK)
+ block = SECOND_BLOCK;
+ else
+ return(ERROR);
+ }
+
+ eepWriteByte(*buf++);
+ if (eepReadAck() == ERROR)
+ return(ERROR);
+
+ eepStop();
+ }
+ return(cnt);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * calculate checksum for ELTEC revision srom
+ */
+unsigned long el_srom_checksum (ptr, size)
+register unsigned char *ptr;
+unsigned long size;
+{
+ u_long f, accu = 0;
+ u_int i;
+ u_char byte;
+
+ for (; size; size--)
+ {
+ byte = *ptr++;
+ for (i = 8; i; i--)
+ {
+ f = ((byte & 1) ^ (accu & 1)) ? 0x84083001 : 0;
+ accu >>= 1; accu ^= f;
+ byte >>= 1;
+ }
+ }
+ return(accu);
+}
+
+/*----------------------------------------------------------------------------*/
diff --git a/board/eltec/bab7xx/u-boot.lds b/board/eltec/bab7xx/u-boot.lds
new file mode 100644
index 0000000000..7b10c0d2aa
--- /dev/null
+++ b/board/eltec/bab7xx/u-boot.lds
@@ -0,0 +1,129 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * u-boot.lds - linker script for U-Boot on the Galileo Eval Board.
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/74xx_7xx/start.o (.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/* . = env_offset; */
+/* common/environment.o(.text) */
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}