1
0
uboot-1.1.4-kirkwood/board/mv_feroceon/mv_dd/nBootstrap.S
2024-01-09 13:43:28 +01:00

459 lines
14 KiB
ArmAsm

#define MV_ASMLANGUAGE
#include "nBootstrap.h"
#include "ddr2/mvDramIfRegs.h"
#include "ddr2/mvDramIfConfig.h"
#include "xor/mvXorRegs.h"
#include "ctrlEnv/mvCtrlEnvSpec.h"
#define XOR_CHAN0 0 /* XOR channel 0 used for memory initialization */
#define XOR_UNIT0 0 /* XOR unit 0 used for memory initialization */
#define XOR_ADDR_DEC_WIN0 0 /* Enable DRAM access using XOR decode window 0 */
/* XOR Engine Address Decoding Register Map */
#define XOR_WINDOW_CTRL_REG(unit,chan) (XOR_UNIT_BASE(unit)+(0x240 + ((chan) * 4)))
#define XOR_BASE_ADDR_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x250 + ((winNum) * 4)))
#define XOR_SIZE_MASK_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x270 + ((winNum) * 4)))
#if !defined(MV_BOOTROM)
.globl nbootStart
nbootStart:
/*
* set the cpu to SVC32 mode, I and F disabled.
*/
mov r1, #0xd3
msr cpsr,r1
/*
* flush v4 I/D caches
*/
mcr p15, 0, r1, c7, c7, 0 /* invalidate v3/v4 cache */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r1, c1, c0, 0
bic r1, r1, #0x00000300 /* clear bits 9:8 (--V- --RS) */
bic r1, r1, #0x00000007 /* clear bits 2:0 (-CAM) */
orr r1, r1, #0x00001000 /* set bit 12 (I) I-Cache */
/* MUST BE PLACED AT END OF CACHE LINE!!!!!!!!!!!!!!! */
mcr p15, 0, r1, c1, c0, 0
/* Add nop commands for cache flush operations */
nop
nop
nop
nop
nop
nop
/* here. MUST BE IN THE SAME CACHE LINE */
mov r0, #0 /* We use r0 as always '0' */
#ifdef NAND_CTRL_88F528x
/* Load CPU controller base address 0xD0020000 */
mov r2, #0xd0000000
orr r2, r2, #0x20000
MV_REG_READ_ASM (r1, r2, 0x20120)
bic r1, r1, #MV_32BIT_LE(0x7F00)
orr r1, r1, #MV_32BIT_LE(0x8200)
bic r1, r1, #MV_32BIT_LE(0x007F)
orr r1, r1, #MV_32BIT_LE(0x001b)
MV_REG_WRITE_ASM(r1, r2, 0x20120)
/* Set CPU to Mbus-L DDR Interface Tick Driver and Tick Sample */
MV_REG_READ_ASM (r1, r2, 0x20100)
bic r1, r1, #MV_32BIT_LE(0xFF00)
orr r1, r1, #MV_32BIT_LE(CPU_2_MBUSL_DDR_CLK)
MV_REG_WRITE_ASM(r1, r2, 0x20100)
#endif /* NAND_CTRL_88F528x */
/* DRAM memory initialization */
/* Load SDRAM controller base address 0xd0001000 */
mov r2, #0xd0000000
orr r2, r2, #0x1000
/* Write to SDRAM coniguration register */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_CONFIG_REG_DV))
MV_REG_WRITE_ASM(r1, r2, SDRAM_CONFIG_REG)
/* Write Dunit control low register */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_DUNIT_CTRL_REG_DV))
MV_REG_WRITE_ASM(r1, r2, SDRAM_DUNIT_CTRL_REG);
/* Write SDRAM address control register */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_ADDR_CTRL_REG_DV))
MV_REG_WRITE_ASM(r1, r2, SDRAM_ADDR_CTRL_REG)
/* Write SDRAM timing Low register */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_TIMING_CTRL_LOW_REG_DVAL))
MV_REG_WRITE_ASM(r1, r2, SDRAM_TIMING_CTRL_LOW_REG)
/* Write SDRAM timing High register */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_TIMING_CTRL_HIGH_REG_DVAL))
MV_REG_WRITE_ASM(r1, r2, SDRAM_TIMING_CTRL_HIGH_REG)
/* Write DDR2 SDRAM timing Low register */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_DDR2_TIMING_LO_REG_DV))
MV_REG_WRITE_ASM(r1, r2, SDRAM_DDR2_TIMING_LO_REG)
/* Write DDR2 SDRAM timing High register */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_DDR2_TIMING_HI_REG_DV))
MV_REG_WRITE_ASM(r1, r2, SDRAM_DDR2_TIMING_HI_REG)
/* Write SDRAM mode register */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_MODE_REG_DV))
MV_REG_WRITE_ASM(r1, r2, SDRAM_MODE_REG)
/* Write SDRAM Extended mode register */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_EXTENDED_MODE_REG_DV))
MV_REG_WRITE_ASM(r1, r2, SDRAM_EXTENDED_MODE_REG)
/* Config DDR2 On Die Termination (ODT) registers */
GPR_LOAD(r1, MV_32BIT_LE(DDR2_SDRAM_ODT_CTRL_LOW_REG_DV))
MV_REG_WRITE_ASM(r1, r2, DDR2_SDRAM_ODT_CTRL_LOW_REG)
/* Write SDRAM DDR2 ODT control high register */
GPR_LOAD(r1, MV_32BIT_LE(DDR2_SDRAM_ODT_CTRL_HIGH_REG_DV))
MV_REG_WRITE_ASM(r1, r2, DDR2_SDRAM_ODT_CTRL_HIGH_REG)
/* Write SDRAM DDR2 Dunit ODT control register */
GPR_LOAD(r1, MV_32BIT_LE(DDR2_DUNIT_ODT_CTRL_REG_DV))
MV_REG_WRITE_ASM(r1, r2, DDR2_DUNIT_ODT_CONTROL_REG)
/*SDRAM_DUNIT_CTRL_HI_REG */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_DUNIT_CTRL_HI_REG_DV))
MV_REG_WRITE_ASM(r1, r2, SDRAM_DUNIT_CTRL_HI_REG)
/* DDR SDRAM Initialization Control Register. Init enable */
mov r1, #MV_32BIT_LE(DSICR_INIT_EN)
MV_REG_WRITE_ASM (r1, r2, DDR_SDRAM_INIT_CTRL_REG)
ddrInitLoop:
MV_REG_READ_ASM (r1, r2, DDR_SDRAM_INIT_CTRL_REG)
cmp r1, #0
bne ddrInitLoop
/* Continue in next NAND page */
/*****************************************************************************/
/* This code open NAND page 1 for read and relocates the CPU to read */
/* from that page. */
/*****************************************************************************/
/* r2 - is the page number */
/* r5 - nand flash base */
/* r6 - is cmd read */
/* r0 - 0 */
/* r9 - is cmd status */
/* r4 - next address to jump */
/* Load the NAND base address */
GPR_LOAD(r5, NAND_FLASH_BASE)
/* init */
mov r0, #0
mov r2, #0x1 /* start with page 1 */
mov r6, #CMD_READ
mov r9, #CMD_STATUS
orr r4, r5, #0x200
.align 5
b ncl
sop:
/* issue read command */
strb r6, [r5, #NAND_CMD_PORT]
/* issue address */
strb r0, [r5, #NAND_ADDR_PORT]
strb r2, [r5, #NAND_ADDR_PORT] /* page address */
strb r0, [r5, #NAND_ADDR_PORT]
/* Check status */
strb r9, [r5, #NAND_CMD_PORT]
b busy_loop
.align 5
ncl:
b ncl2
busy_loop:
ldrb r1, [r5]
tst r1, #STATUS_READY
beq busy_loop
/* back to read mode */
strb r6, [r5, #NAND_CMD_PORT]
mov pc, r4
.align 5
ncl2:
b sop
/* Next page must be in page offset - 512 bytes */
.align 9
page1:
/*****************************************************************************/
/* This code extract the booter from the rest of block 1 which is known to */
/* be error free (no need for ECC). This booter should copy the U-boot code */
/* to DRAM */
/*****************************************************************************/
/* DRAM init - Cont'd */
/* Load back SDRAM controller base address 0xd0001000 */
mov r2, #0xd0000000
orr r2, r2, #0x1000
/* Open SDRAM bank 0 size register */
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_SIZE_REG_DV))
MV_REG_WRITE_ASM(r1, r2, SDRAM_SIZE_REG(0,0))
#ifdef RD_MV78XX0_MASA_2DIMM
orr r1, #0x5
MV_REG_WRITE_ASM(r1, r2, SDRAM_SIZE_REG(0,1))
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_BASE1_REG_DV))
MV_REG_WRITE_ASM(r1, r2, SDRAM_BASE_ADDR_REG(0,1))
#else
MV_REG_WRITE_ASM(r0, r2, SDRAM_SIZE_REG(0,1))
#endif
/* Close SDRAM bank 2,3 */
MV_REG_WRITE_ASM(r0, r2, SDRAM_SIZE_REG(0,2))
MV_REG_WRITE_ASM(r0, r2, SDRAM_SIZE_REG(0,3))
/* Prepare the address where to find the nandBoot function pointer */
mov lr, #0x20000
orr lr, lr, #0x620
#if 1
/* Load xor controller base address 0xd0060000 */
mov r2, #0xd0000000
orr r2, r2, #0x60000
/* Disable all XOR address decode windows to avoid possible overlap */
MV_REG_WRITE_ASM (r0, r2, (XOR_WINDOW_CTRL_REG(XOR_UNIT0,XOR_CHAN0)))
/* Init first XOR_SIZE_MASK_REG */
MV_REG_WRITE_ASM (r1, r2, XOR_SIZE_MASK_REG(XOR_UNIT0,XOR_ADDR_DEC_WIN0))
/* Update destination & size */
MV_REG_WRITE_ASM(r0, r2, XOR_DST_PTR_REG(XOR_UNIT0,XOR_CHAN0))
mov r6, #0xe00
MV_REG_WRITE_ASM (r6, r2, XOR_BASE_ADDR_REG(XOR_UNIT0,XOR_ADDR_DEC_WIN0))
mov r6, #0xf0000
orr r6, r6, #0xf000
orr r6, r6, #0x1
MV_REG_WRITE_ASM (r6, r2, XOR_WINDOW_CTRL_REG(XOR_UNIT0,XOR_CHAN0))
/* Configure XOR engine for memory init function. */
MV_REG_READ_ASM (r6, r2, XOR_CONFIG_REG(XOR_UNIT0,XOR_CHAN0))
and r6, r6, #~0x7 /* Clear operation mode field */
orr r6, r6, #0x4 /* Set operation to memory init */
MV_REG_WRITE_ASM(r6, r2, XOR_CONFIG_REG(XOR_UNIT0,XOR_CHAN0))
/* Set initVal in the XOR Engine Initial Value Registers */
GPR_LOAD(r6, MV_32BIT_LE(0xfeedfeed))
MV_REG_WRITE_ASM(r6, r2, XOR_INIT_VAL_LOW_REG(XOR_UNIT0))
MV_REG_WRITE_ASM(r6, r2, XOR_INIT_VAL_HIGH_REG(XOR_UNIT0))
/* Set block size using DRAM bank size */
and r6, r1, #SCSR_SIZE_MASK
mov r1, r6, LSR #SCSR_SIZE_OFFS
add r1, r1, #1
mov r6, r5, LSL #SCSR_SIZE_OFFS
MV_REG_WRITE_ASM(r6, r2, XOR_BLOCK_SIZE_REG(XOR_UNIT0,XOR_CHAN0))
/* Clean interrupt cause*/
MV_REG_WRITE_ASM(r0, r2, XOR_CAUSE_REG(XOR_UNIT0))
/* Clean error interrupt cause*/
MV_REG_READ_ASM(r6, r2, XOR_ERROR_CAUSE_REG(XOR_UNIT0))
MV_REG_READ_ASM(r6, r2, XOR_ERROR_ADDR_REG(XOR_UNIT0))
/* Start transfer */
MV_REG_READ_ASM (r6, r2, XOR_ACTIVATION_REG(XOR_UNIT0,XOR_CHAN0))
orr r6, r6, #0x1 /* Preform start command */
MV_REG_WRITE_ASM(r6, r2, XOR_ACTIVATION_REG(XOR_UNIT0,XOR_CHAN0))
.align 5
b ncl32
sop1:
/* Wait for engine to finish */
waitForComplete:
MV_REG_READ_ASM(r6, r2, XOR_CAUSE_REG(XOR_UNIT0))
and r6, r6, #2
cmp r6, #0
beq waitForComplete
b cp_page_init
#else
/* Initialize UART 0 to 115200 bps */
GPR_LOAD(r2, 0xd0012000)
mov r1, #0x07
strb r1, [r2, #0x8]
mov r1, #0x83
strb r1, [r2, #0xC]
mov r1, #0x5A
strb r1, [r2, #0x0]
mov r1, #0x03
strb r1, [r2, #0xC]
mov r1, #'N'
strb r1, [r2]
mov r1, #'A'
strb r1, [r2]
mov r1, #'N'
strb r1, [r2]
mov r1, #'D'
strb r1, [r2]
mov r1, #' '
strb r1, [r2]
mov r1, #'b'
strb r1, [r2]
mov r1, #'o'
strb r1, [r2]
mov r1, #'o'
strb r1, [r2]
mov r1, #'t'
strb r1, [r2]
mov r1, #'s'
strb r1, [r2]
mov r1, #'t'
strb r1, [r2]
mov r1, #'r'
strb r1, [r2]
mov r1, #'a'
strb r1, [r2]
mov r1, #'p'
strb r1, [r2]
mov r1, #10
strb r1, [r2]
mov r1, #13
strb r1, [r2]
#endif
.align 5
ncl32:
b ncl33
cp_page_init:
/* init */
mov r2, #0x3 /* start with page 3 */
mov r3, #0x20000
orr r3, r3, #0x600
b cp_page_loop
.align 5
ncl33:
b ncl31
cp_page_loop:
mov r0, #0
mov r6, #CMD_READ
mov r9, #CMD_STATUS
mov r4, #PAGE_SIZE /* Byte counter */
b startRead
.align 5
ncl31:
b ncl3
startRead:
/* issue read command */
strb r6, [r5, #NAND_CMD_PORT]
/* issue address */
strb r0, [r5, #NAND_ADDR_PORT]
strb r2, [r5, #NAND_ADDR_PORT] /* page address */
strb r0, [r5, #NAND_ADDR_PORT]
/* Check status */
strb r9, [r5, #NAND_CMD_PORT]
b busy_loop1
.align 5
ncl3:
b ncl4
busy_loop1:
ldrb r1, [r5]
tst r1, #STATUS_READY
beq busy_loop1
/* back to read mode */
strb r6, [r5, #NAND_CMD_PORT]
/* now perform reading */
mov r0, r5
b copy_loop1
.align 5
ncl4:
b ncl5
copy_loop1:
sub r4, r4, #32 /* 8 dwords * 4 bytes */
ldmia r0!, {r6-r13}
stmia r3!, {r6-r13}
cmp r4, #0 /* check if we have read a full Page */
bne copy_loop1
b nextPage
.align 5
ncl5:
b ncl6
nextPage:
add r2, r2, #1 /* increment page number */
cmp r2, #BOOTER_PAGE_NUM
bne cp_page_loop
b stack_setup
.align 5
ncl6:
b sop1
/* Set up the stack */
stack_setup:
sub sp, lr, #40 /* leave 3 words for abort-stack */
/* jump to new code */
mov pc, lr
.align 9
/* This is known to be address (BOOTER_BASE + 2 * PAGE_SIZE) */
_nandBootPtr:
.word nand_boot
#else /* MV_BOOTROM */
.globl nbootStart
nbootStart:
/* Enable I-Cache */
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0x00001000 /* set bit 12 (I) I-Cache */
/* MUST BE PLACED AT END OF CACHE LINE!!!!!!!!!!!!!!! */
mcr p15, 0, r1, c1, c0, 0
/* Set up the stack */
mov r0, #BOOTER_BASE
sub sp, r0, #12 /* leave 3 words for abort-stack */
/* jump to new code */
ldr lr, =nand_boot
mov pc, lr
#endif /* !defined(MV_BOOTROM) */