upstream u-boot with additional patches for our devices/boards:
https://lists.denx.de/pipermail/u-boot/2017-March/282789.html (AXP crashes) ;
Gbit ethernet patch for some LIME2 revisions ;
with SPI flash support
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
862 lines
22 KiB
862 lines
22 KiB
/*
|
|
* (C) Copyright 2001 ELTEC Elektronik AG
|
|
* Frank Gottschling <fgottschling@eltec.de>
|
|
*
|
|
* ELTEC ELPPC RAM initialization
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#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, CONFIG_SYS_USR_LED_BASE@h
|
|
stb r3, 2(r30)
|
|
sync
|
|
|
|
/*
|
|
* init COM1 for polled output
|
|
*/
|
|
lis r8, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
|
|
ori r8, r8, CONFIG_SYS_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, (CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE)
|
|
stb r9, 0(r8) /* baud rate (LSB)*/
|
|
eieio
|
|
li r9, ((CONFIG_SYS_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, CONFIG_SYS_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, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
|
|
ori r10, r10, CONFIG_SYS_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, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
|
|
ori r10, r10, CONFIG_SYS_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, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
|
|
ori r10, r10, CONFIG_SYS_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, CONFIG_SYS_NS16550_COM1@h /* COM1 base address*/
|
|
ori r10, r10, CONFIG_SYS_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
|
|
|