336 lines
11 KiB
ArmAsm
336 lines
11 KiB
ArmAsm
|
#define MV_ASMLANGUAGE
|
||
|
#include "mvDramIfRegs.h"
|
||
|
#include "mvDramIfConfig.h"
|
||
|
#include "nBootstrap.h"
|
||
|
|
||
|
|
||
|
/* #define NAND_DEBUG */
|
||
|
#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, #0x00002300 /* clear bits 13, 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
|
||
|
/* 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 */
|
||
|
|
||
|
/* lock I-Cache */
|
||
|
mrc p15, 0, r8, c9, c0, 1
|
||
|
orr r8, r8, #0xf
|
||
|
mcr p15, 0, r8, c9, c0, 1
|
||
|
|
||
|
/* Start load code into I-Cache */
|
||
|
mov r2, #0x500
|
||
|
mov r8, pc
|
||
|
.align 5
|
||
|
bic r8, #0x1f
|
||
|
add r8, r8, #32
|
||
|
load_loop:
|
||
|
mcr p15, 0, r8, c7, c13, 1
|
||
|
add r8, r8, #32 /* 8 dwords * 4 bytes */
|
||
|
sub r2, r2, #32 /* 8 dwords * 4 bytes */
|
||
|
cmp r2, #0 /* check if we have read a full Page */
|
||
|
bne load_loop
|
||
|
|
||
|
#ifdef NAND_DEBUG
|
||
|
/* GPP initialization */
|
||
|
mov r2, #0xd0000000
|
||
|
orr r2, r2, #0x10000
|
||
|
mov r1, #0xf0ffffff
|
||
|
MV_REG_WRITE_ASM(r1, r2, 0x104)
|
||
|
mov r1, #0x1000000
|
||
|
MV_REG_WRITE_ASM(r1, r2, 0x100)
|
||
|
#endif
|
||
|
|
||
|
/* DRAM memory initialization */
|
||
|
/* Load SDRAM controller base address 0xd0001000 */
|
||
|
mov r2, #0xd0000000
|
||
|
orr r2, r2, #0x1000
|
||
|
|
||
|
/* Write to SDRAM coniguration register */
|
||
|
#ifndef MV_88W8660
|
||
|
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_CONFIG_REG_DV))
|
||
|
#else
|
||
|
GPR_LOAD(r1, MV_32BIT_LE((SDRAM_CONFIG_REG_DV & ~(0x40))))
|
||
|
#endif /* MV_88W8660 */
|
||
|
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 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 registers pad calibration */
|
||
|
MV_REG_READ_ASM (r1, r2, SDRAM_CONFIG_REG)
|
||
|
tst r1, #SDRAM_DTYPE_DDR2
|
||
|
beq ddr1PadCal
|
||
|
|
||
|
/* 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)
|
||
|
|
||
|
mov r3, #MV_32BIT_LE(DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV)
|
||
|
mov r4, #MV_32BIT_LE(DDR2_DATA_PAD_STRENGTH_TYPICAL_DV)
|
||
|
b next
|
||
|
|
||
|
ddr1PadCal:
|
||
|
mov r3, #MV_32BIT_LE(DDR1_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV)
|
||
|
mov r4, #MV_32BIT_LE(DDR1_DATA_PAD_STRENGTH_TYPICAL_DV)
|
||
|
|
||
|
next:
|
||
|
/* Implement Guideline (GL# MEM-3) Drive Strength Value */
|
||
|
/* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0 */
|
||
|
/* DDR SDRAM Address/Control Pads Calibration */
|
||
|
MV_REG_READ_ASM (r1, r2, SDRAM_ADDR_CTRL_PADS_CAL_REG)
|
||
|
|
||
|
orr r5, r1, #MV_32BIT_LE(SDRAM_WR_EN) /* Make register writeable */
|
||
|
|
||
|
MV_REG_WRITE_ASM (r5, r2, SDRAM_ADDR_CTRL_PADS_CAL_REG)
|
||
|
|
||
|
orr r1, r3, r1 /* Set default value for DDR */
|
||
|
|
||
|
MV_REG_WRITE_ASM (r1, r2, SDRAM_ADDR_CTRL_PADS_CAL_REG)
|
||
|
|
||
|
|
||
|
/* DDR SDRAM Data Pads Calibration */
|
||
|
MV_REG_READ_ASM (r1, r2, SDRAM_DATA_PADS_CAL_REG)
|
||
|
|
||
|
orr r5, r1, #MV_32BIT_LE(SDRAM_WR_EN) /* Make register writeable */
|
||
|
|
||
|
MV_REG_WRITE_ASM (r5, r2, SDRAM_DATA_PADS_CAL_REG)
|
||
|
|
||
|
orr r1, r4, r1 /* Set default value for DDR */
|
||
|
|
||
|
MV_REG_WRITE_ASM (r1, r2, SDRAM_DATA_PADS_CAL_REG)
|
||
|
|
||
|
#ifndef MV_88W8660
|
||
|
/* Write Dunit FTDLL Configuration Register */
|
||
|
GPR_LOAD(r1, MV_32BIT_LE(SDRAM_FTDLL_CONFIG_REG_DV))
|
||
|
MV_REG_WRITE_ASM(r1, r2, SDRAM_FTDLL_CONFIG_REG)
|
||
|
#endif /* MV_88W8660 */
|
||
|
|
||
|
/* 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)
|
||
|
|
||
|
#ifdef NAND_DEBUG
|
||
|
/* GPP initialization */
|
||
|
mov r2, #0xd0000000
|
||
|
orr r2, r2, #0x10000
|
||
|
mov r1, #0x2000000
|
||
|
MV_REG_WRITE_ASM(r1, r2, 0x100)
|
||
|
#endif
|
||
|
|
||
|
ddrInitLoop:
|
||
|
MV_REG_READ_ASM (r1, r2, DDR_SDRAM_INIT_CTRL_REG)
|
||
|
cmp r1, #0
|
||
|
bne ddrInitLoop
|
||
|
|
||
|
/* 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))
|
||
|
|
||
|
/* Close SDRAM bank 1,2,3 */
|
||
|
MV_REG_WRITE_ASM(r0, r2, SDRAM_SIZE_REG(1))
|
||
|
MV_REG_WRITE_ASM(r0, r2, SDRAM_SIZE_REG(2))
|
||
|
MV_REG_WRITE_ASM(r0, r2, SDRAM_SIZE_REG(3))
|
||
|
|
||
|
/* Prepare the address where to find the nandBoot function pointer */
|
||
|
mov lr, #BOOTER_BASE
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
/* GPP initialization */
|
||
|
mov r2, #0xd0000000
|
||
|
orr r2, r2, #0x10000
|
||
|
mov r1, #0x2000000
|
||
|
MV_REG_WRITE_ASM(r1, r2, 0x100)
|
||
|
#endif
|
||
|
|
||
|
/* init */
|
||
|
mov r2, #0x1 /* start with page 1 */
|
||
|
mov r3, #BOOTER_BASE /* start of DRAM buffer */
|
||
|
GPR_LOAD(r5, NAND_FLASH_BASE)
|
||
|
|
||
|
cp_page_loop:
|
||
|
mov r0, #0
|
||
|
mov r6, #CMD_READ
|
||
|
mov r7, #CMD_START_READ
|
||
|
mov r9, #CMD_RESET
|
||
|
mov r4, #PAGE_SIZE /* Byte counter */
|
||
|
|
||
|
|
||
|
startRead:
|
||
|
/* issue reset command */
|
||
|
strb r9, [r5, #NAND_CMD_PORT]
|
||
|
|
||
|
mov r9, #0x1000000
|
||
|
loop_delay1:
|
||
|
sub r9, r9, #1
|
||
|
cmp r9, #0
|
||
|
bne loop_delay1
|
||
|
|
||
|
/* issue read command */
|
||
|
strb r6, [r5, #NAND_CMD_PORT]
|
||
|
|
||
|
/* issue address */
|
||
|
strb r0, [r5, #NAND_ADDR_PORT]
|
||
|
strb r0, [r5, #NAND_ADDR_PORT]
|
||
|
strb r2, [r5, #NAND_ADDR_PORT] /* page address */
|
||
|
strb r0, [r5, #NAND_ADDR_PORT]
|
||
|
strb r0, [r5, #NAND_ADDR_PORT]
|
||
|
strb r7, [r5, #NAND_CMD_PORT]
|
||
|
|
||
|
#ifdef NAND_DEBUG
|
||
|
/* GPP initialization */
|
||
|
mov r6, #0xd0000000
|
||
|
orr r6, r6, #0x10000
|
||
|
mov r1, #0x3000000
|
||
|
MV_REG_WRITE_ASM(r1, r6, 0x100)
|
||
|
#endif
|
||
|
/* Delay of at least 25uSec (NAND flash tR) */
|
||
|
mov r9, #0x1000000
|
||
|
loop_delay3:
|
||
|
sub r9, r9, #1
|
||
|
cmp r9, #0
|
||
|
bne loop_delay3
|
||
|
|
||
|
#ifdef NAND_DEBUG
|
||
|
/* GPP initialization */
|
||
|
mov r6, #0xd0000000
|
||
|
orr r6, r6, #0x10000
|
||
|
mov r1, #0x4000000
|
||
|
MV_REG_WRITE_ASM(r1, r6, 0x100)
|
||
|
#endif
|
||
|
|
||
|
/* now perform reading */
|
||
|
mov r0, r5
|
||
|
|
||
|
copy_loop1:
|
||
|
sub r4, r4, #16 /* 4 dwords * 4 bytes */
|
||
|
ldmia r0!, {r6-r9}
|
||
|
stmia r3!, {r6-r9}
|
||
|
|
||
|
cmp r4, #0 /* check if we have read a full Page */
|
||
|
bne copy_loop1
|
||
|
|
||
|
nextPage:
|
||
|
add r2, r2, #1 /* increment page number */
|
||
|
cmp r2, #BOOTER_PAGE_NUM
|
||
|
bne cp_page_loop
|
||
|
|
||
|
#ifdef NAND_DEBUG
|
||
|
/* GPP initialization */
|
||
|
mov r2, #0xd0000000
|
||
|
orr r2, r2, #0x10000
|
||
|
mov r1, #0x5000000
|
||
|
MV_REG_WRITE_ASM(r1, r2, 0x100)
|
||
|
#endif
|
||
|
|
||
|
/* Set up the stack */
|
||
|
stack_setup:
|
||
|
mov r0, #BOOTER_BASE
|
||
|
sub sp, r0, #12 /* leave 3 words for abort-stack */
|
||
|
/* jump to new code */
|
||
|
mov pc, lr
|
||
|
|
||
|
.align 10
|
||
|
/* 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, =nandBoot
|
||
|
mov pc, lr
|
||
|
#endif /* !defined(MV_BOOTROM) */
|