u-boot/board/eltec/bab7xx/asm_init.S
Wolfgang Denk 700a0c648d Add common (with Linux) MTD partition scheme and "mtdparts" command
Old, obsolete and duplicated code was cleaned up and replace by the
new partitioning method. There are two possible approaches now:
* define a single, static partition
* use mtdparts command line option and dynamic partitioning
Default is static partitioning.
2005-08-08 01:03:24 +02:00

1476 lines
41 KiB
ArmAsm

/*
* (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 <asm/processor.h>
#include <74xx_7xx.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