s5pv210 uboot-2012-10移植(三) 之支持SPL

时间:2022-06-14 08:11:06

上次的uboot的BL1是自己实现的,今天就来让uboot-2012-10支持SPL功能,但不是完全用的uboot本身的代码,也不知道这样是好还是坏。

1.分析顶层目录的Makefile可以知道,需要添加CONFIG_SPL配置,这在前面的已经说过了,跟踪start.S代码,得知编译需要arch/arm/lib/spl.c文件,查看arch/arm/lib/Makefile得知,需要添加CONFIG_SPL_FRAMEWORK配置,所以include/configs/smdkv210.h +70添加

/* SPL */
#define CONFIG_SPL
#define CONFIG_SPL_FRAMEWORK
2.因为SPL不需要BSS清零,所以修改arch/arm/cpu/armv7/start.S +128

#ifndef CONFIG_SPL_BUILD
//by ZheGao clear bss
ldr r0, =__bss_start
ldr r1, =__bss_end__
mov r2, #0x0
1:
str r2, [r0], #4
cmp r0, r1
bne 1b
//end of clear bss

bl save_boot_params
#endif

3.因为BL1需要初始化memory,所以在lowlevel_init中添加,board/samsung/smdkv210/lowlevel_init.S +43

#ifdef CONFIG_SPL_BUILD
bl mem_ctrl_asm_init
#endif

4.mem_ctrl_asm_init在同目录下的mem_setup.S文件中,修改board/samsung/smdkv210/mem_setup.S 添加memory的配置

#define ELFIN_GPIO_BASE			0xE0200000
#define MP1_0DRV_SR_OFFSET 0x3CC
#define MP1_1DRV_SR_OFFSET 0x3EC
#define MP1_2DRV_SR_OFFSET 0x40C
#define MP1_3DRV_SR_OFFSET 0x42C
#define MP1_4DRV_SR_OFFSET 0x44C
#define MP1_5DRV_SR_OFFSET 0x46C
#define MP1_6DRV_SR_OFFSET 0x48C
#define MP1_7DRV_SR_OFFSET 0x4AC
#define MP1_8DRV_SR_OFFSET 0x4CC
#define MP2_0DRV_SR_OFFSET 0x4EC
#define MP2_1DRV_SR_OFFSET 0x50C
#define MP2_2DRV_SR_OFFSET 0x52C
#define MP2_3DRV_SR_OFFSET 0x54C
#define MP2_4DRV_SR_OFFSET 0x56C
#define MP2_5DRV_SR_OFFSET 0x58C
#define MP2_6DRV_SR_OFFSET 0x5AC
#define MP2_7DRV_SR_OFFSET 0x5CC
#define MP2_8DRV_SR_OFFSET 0x5EC
#define APB_DMC_0_BASE 0xF0000000
#define APB_DMC_1_BASE 0xF1400000
#define ASYNC_MSYS_DMC0_BASE 0xF1E00000

#define DMC_CONCONTROL 0x00
#define DMC_MEMCONTROL 0x04
#define DMC_MEMCONFIG0 0x08
#define DMC_MEMCONFIG1 0x0C
#define DMC_DIRECTCMD 0x10
#define DMC_PRECHCONFIG 0x14
#define DMC_PHYCONTROL0 0x18
#define DMC_PHYCONTROL1 0x1C
#define DMC_RESERVED 0x20
#define DMC_PWRDNCONFIG 0x28
#define DMC_TIMINGAREF 0x30
#define DMC_TIMINGROW 0x34
#define DMC_TIMINGDATA 0x38
#define DMC_TIMINGPOWER 0x3C
#define DMC_PHYSTATUS 0x40
#define DMC_CHIP0STATUS 0x48
#define DMC_CHIP1STATUS 0x4C
#define DMC_AREFSTATUS 0x50
#define DMC_MRSTATUS 0x54
#define DMC_PHYTEST0 0x58
#define DMC_PHYTEST1 0x5C
#define DMC_QOSCONTROL0 0x60
#define DMC_QOSCONFIG0 0x64
#define DMC_QOSCONTROL1 0x68
#define DMC_QOSCONFIG1 0x6C
#define DMC_QOSCONTROL2 0x70
#define DMC_QOSCONFIG2 0x74
#define DMC_QOSCONTROL3 0x78
#define DMC_QOSCONFIG3 0x7C
#define DMC_QOSCONTROL4 0x80
#define DMC_QOSCONFIG4 0x84
#define DMC_QOSCONTROL5 0x88
#define DMC_QOSCONFIG5 0x8C
#define DMC_QOSCONTROL6 0x90
#define DMC_QOSCONFIG6 0x94
#define DMC_QOSCONTROL7 0x98
#define DMC_QOSCONFIG7 0x9C
#define DMC_QOSCONTROL8 0xA0
#define DMC_QOSCONFIG8 0xA4
#define DMC_QOSCONTROL9 0xA8
#define DMC_QOSCONFIG9 0xAC
#define DMC_QOSCONTROL10 0xB0
#define DMC_QOSCONFIG10 0xB4
#define DMC_QOSCONTROL11 0xB8
#define DMC_QOSCONFIG11 0xBC
#define DMC_QOSCONTROL12 0xC0
#define DMC_QOSCONFIG12 0xC4
#define DMC_QOSCONTROL13 0xC8
#define DMC_QOSCONFIG13 0xCC
#define DMC_QOSCONTROL14 0xD0
#define DMC_QOSCONFIG14 0xD4
#define DMC_QOSCONTROL15 0xD8
#define DMC_QOSCONFIG15 0xDC

#define DMC0_MEMCONFIG_0 0x20E01323 // MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC0_MEMCONFIG_1 0x40F01323 // MemConfig1
#define DMC0_TIMINGA_REF 0x00000618 // TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)
#define DMC0_TIMING_ROW 0x28233287 // TimingRow for @200MHz
#define DMC0_TIMING_DATA 0x23240304 // TimingData CL=3
#define DMC0_TIMING_PWR 0x09C80232 // TimingPower

#define DMC1_MEMCONTROL 0x00202400 // MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
#define DMC1_MEMCONFIG_0 0x40C01323 // MemConfig0 512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC1_MEMCONFIG_1 0x00E01323 // MemConfig1
#define DMC1_TIMINGA_REF 0x00000618 // TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4
#define DMC1_TIMING_ROW 0x28233289 // TimingRow for @200MHz
#define DMC1_TIMING_DATA 0x23240304 // TimingData CL=3
#define DMC1_TIMING_PWR 0x08280232 // TimingPower


.globl mem_ctrl_asm_init
mem_ctrl_asm_init:
#if 0
ldr r6, =S5PC100_DMC_BASE @ 0xE6000000

/* DLL parameter setting */
ldr r1, =0x50101000
str r1, [r6, #0x018] @ PHYCONTROL0
ldr r1, =0xf4
str r1, [r6, #0x01C] @ PHYCONTROL1
ldr r1, =0x0
str r1, [r6, #0x020] @ PHYCONTROL2

/* DLL on */
ldr r1, =0x50101002
str r1, [r6, #0x018] @ PHYCONTROL0

/* DLL start */
ldr r1, =0x50101003
str r1, [r6, #0x018] @ PHYCONTROL0

/* Force value locking for DLL off */
str r1, [r6, #0x018] @ PHYCONTROL0

/* DLL off */
ldr r1, =0x50101001
str r1, [r6, #0x018] @ PHYCONTROL0

/* auto refresh off */
ldr r1, =0xff001010
str r1, [r6, #0x000] @ CONCONTROL

/*
* Burst Length 4, 2 chips, 32-bit, LPDDR
* OFF: dynamic self refresh, force precharge, dynamic power down off
*/
ldr r1, =0x00212100
str r1, [r6, #0x004] @ MEMCONTROL

/*
* Note:
* If Bank0 has OneDRAM we place it at 0x2800'0000
* So finally Bank1 should address start at at 0x2000'0000
*/
mov r4, #0x0

swap_memory:
/*
* Bank0
* 0x30 -> 0x30000000
* 0xf8 -> 0x37FFFFFF
* [15:12] 0: Linear
* [11:8 ] 2: 9 bits
* [ 7:4 ] 2: 14 bits
* [ 3:0 ] 2: 4 banks
*/
ldr r1, =0x30f80222
/* if r4 is 1, swap the bank */
cmp r4, #0x1
orreq r1, r1, #0x08000000
str r1, [r6, #0x008] @ MEMCONFIG0

/*
* Bank1
* 0x38 -> 0x38000000
* 0xf8 -> 0x3fFFFFFF
* [15:12] 0: Linear
* [11:8 ] 2: 9 bits
* [ 7:4 ] 2: 14 bits
* [ 3:0 ] 2: 4 banks
*/
ldr r1, =0x38f80222
/* if r4 is 1, swap the bank */
cmp r4, #0x1
biceq r1, r1, #0x08000000
str r1, [r6, #0x00c] @ MEMCONFIG1

ldr r1, =0x20000000
str r1, [r6, #0x014] @ PRECHCONFIG

/*
* FIXME: Please verify these values
* 7.8us * 166MHz %LE %LONG1294(0x50E)
* 7.8us * 133MHz %LE %LONG1038(0x40E),
* 7.8us * 100MHz %LE %LONG780(0x30C),
* 7.8us * 20MHz %LE %LONG156(0x9C),
* 7.8us * 10MHz %LE %LONG78(0x4E)
*/
ldr r1, =0x0000050e
str r1, [r6, #0x030] @ TIMINGAREF

/* 166 MHz */
ldr r1, =0x0c233287
str r1, [r6, #0x034] @ TIMINGROW

/* twtr=3 twr=2 trtp=3 cl=3 wl=3 rl=3 */
ldr r1, =0x32330303
str r1, [r6, #0x038] @ TIMINGDATA

/* tfaw=4 sxsr=0x14 txp=0x14 tcke=3 tmrd=3 */
ldr r1, =0x04141433
str r1, [r6, #0x03C] @ TIMINGPOWER

/* chip0 Deselect */
ldr r1, =0x07000000
str r1, [r6, #0x010] @ DIRECTCMD

/* chip0 PALL */
ldr r1, =0x01000000
str r1, [r6, #0x010] @ DIRECTCMD

/* chip0 REFA */
ldr r1, =0x05000000
str r1, [r6, #0x010] @ DIRECTCMD
/* chip0 REFA */
str r1, [r6, #0x010] @ DIRECTCMD

/* chip0 MRS, CL%LE %LONG3, BL%LE %LONG4 */
ldr r1, =0x00000032
str r1, [r6, #0x010] @ DIRECTCMD

/* chip1 Deselect */
ldr r1, =0x07100000
str r1, [r6, #0x010] @ DIRECTCMD

/* chip1 PALL */
ldr r1, =0x01100000
str r1, [r6, #0x010] @ DIRECTCMD

/* chip1 REFA */
ldr r1, =0x05100000
str r1, [r6, #0x010] @ DIRECTCMD
/* chip1 REFA */
str r1, [r6, #0x010] @ DIRECTCMD

/* chip1 MRS, CL%LE %LONG3, BL%LE %LONG4 */
ldr r1, =0x00100032
str r1, [r6, #0x010] @ DIRECTCMD

/* auto refresh on */
ldr r1, =0xff002030
str r1, [r6, #0x000] @ CONCONTROL

/* PwrdnConfig */
ldr r1, =0x00100002
str r1, [r6, #0x028] @ PWRDNCONFIG

/* BL%LE %LONG */
ldr r1, =0xff212100
str r1, [r6, #0x004] @ MEMCONTROL


/* Try to test memory area */
cmp r4, #0x1
beq 1f

mov r4, #0x1
ldr r1, =0x37ffff00
str r4, [r1]
str r4, [r1, #0x4] @ dummy write
ldr r0, [r1]
cmp r0, r4
bne swap_memory
#endif

/* DMC0 Drive Strength (Setting 2X) */

ldr r0, =ELFIN_GPIO_BASE

ldr r1, =0x0000AAAA
str r1, [r0, #MP1_0DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP1_1DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP1_2DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP1_3DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP1_4DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP1_5DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP1_6DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP1_7DRV_SR_OFFSET]

ldr r1, =0x00002AAA
str r1, [r0, #MP1_8DRV_SR_OFFSET]


/* DMC1 Drive Strength (Setting 2X) */

ldr r0, =ELFIN_GPIO_BASE

ldr r1, =0x0000AAAA
str r1, [r0, #MP2_0DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP2_1DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP2_2DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP2_3DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP2_4DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP2_5DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP2_6DRV_SR_OFFSET]

ldr r1, =0x0000AAAA
str r1, [r0, #MP2_7DRV_SR_OFFSET]

ldr r1, =0x00002AAA
str r1, [r0, #MP2_8DRV_SR_OFFSET]

/* DMC0 initialization at single Type*/
ldr r0, =APB_DMC_0_BASE

ldr r1, =0x00101000 @PhyControl0 DLL parameter setting, manual 0x00101000
str r1, [r0, #DMC_PHYCONTROL0]

ldr r1, =0x00000086 @PhyControl1 DLL parameter setting, LPDDR/LPDDR2 Case
str r1, [r0, #DMC_PHYCONTROL1]

ldr r1, =0x00101002 @PhyControl0 DLL on
str r1, [r0, #DMC_PHYCONTROL0]

ldr r1, =0x00101003 @PhyControl0 DLL start
str r1, [r0, #DMC_PHYCONTROL0]

find_lock_val:
ldr r1, [r0, #DMC_PHYSTATUS] @Load Phystatus register value
and r2, r1, #0x7
cmp r2, #0x7 @Loop until DLL is locked
bne find_lock_val

and r1, #0x3fc0
mov r2, r1, LSL #18
orr r2, r2, #0x100000
orr r2 ,r2, #0x1000

orr r1, r2, #0x3 @Force Value locking
str r1, [r0, #DMC_PHYCONTROL0]

#if 0 /* Memory margin test 10.01.05 */
orr r1, r2, #0x1 @DLL off
str r1, [r0, #DMC_PHYCONTROL0]
#endif
/* setting DDR2 */
ldr r1, =0x0FFF2010 @ConControl auto refresh off
str r1, [r0, #DMC_CONCONTROL]

ldr r1, =0x00212400 @MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
str r1, [r0, #DMC_MEMCONTROL]

ldr r1, =DMC0_MEMCONFIG_0 @MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
str r1, [r0, #DMC_MEMCONFIG0]

ldr r1, =DMC0_MEMCONFIG_1 @MemConfig1
str r1, [r0, #DMC_MEMCONFIG1]

ldr r1, =0xFF000000 @PrechConfig
str r1, [r0, #DMC_PRECHCONFIG]

ldr r1, =DMC0_TIMINGA_REF @TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)
str r1, [r0, #DMC_TIMINGAREF]

ldr r1, =DMC0_TIMING_ROW @TimingRow for @200MHz
str r1, [r0, #DMC_TIMINGROW]

ldr r1, =DMC0_TIMING_DATA @TimingData CL=3
str r1, [r0, #DMC_TIMINGDATA]

ldr r1, =DMC0_TIMING_PWR @TimingPower
str r1, [r0, #DMC_TIMINGPOWER]

ldr r1, =0x07000000 @DirectCmd chip0 Deselect
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00020000 @DirectCmd chip0 EMRS2
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00030000 @DirectCmd chip0 EMRS3
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00000542 @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00000442 @DirectCmd chip0 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00010780 @DirectCmd chip0 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (OCD exit)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x07100000 @DirectCmd chip1 Deselect
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00120000 @DirectCmd chip1 EMRS2
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00130000 @DirectCmd chip1 EMRS3
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00100542 @DirectCmd chip1 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x05100000 @DirectCmd chip1 REFA
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x05100000 @DirectCmd chip1 REFA
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00100442 @DirectCmd chip1 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00110780 @DirectCmd chip1 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (OCD exit)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x0FF02030 @ConControl auto refresh on
str r1, [r0, #DMC_CONCONTROL]

ldr r1, =0xFFFF00FF @PwrdnConfig
str r1, [r0, #DMC_PWRDNCONFIG]

ldr r1, =0x00202400 @MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
str r1, [r0, #DMC_MEMCONTROL]

/* DMC1 initialization */
ldr r0, =APB_DMC_1_BASE

ldr r1, =0x00101000 @Phycontrol0 DLL parameter setting
str r1, [r0, #DMC_PHYCONTROL0]

ldr r1, =0x00000086 @Phycontrol1 DLL parameter setting
str r1, [r0, #DMC_PHYCONTROL1]

ldr r1, =0x00101002 @PhyControl0 DLL on
str r1, [r0, #DMC_PHYCONTROL0]

ldr r1, =0x00101003 @PhyControl0 DLL start
str r1, [r0, #DMC_PHYCONTROL0]
find_lock_val1:
ldr r1, [r0, #DMC_PHYSTATUS] @Load Phystatus register value
and r2, r1, #0x7
cmp r2, #0x7 @Loop until DLL is locked
bne find_lock_val1

and r1, #0x3fc0
mov r2, r1, LSL #18
orr r2, r2, #0x100000
orr r2, r2, #0x1000

orr r1, r2, #0x3 @Force Value locking
str r1, [r0, #DMC_PHYCONTROL0]

#if 0 /* Memory margin test 10.01.05 */
orr r1, r2, #0x1 @DLL off
str r1, [r0, #DMC_PHYCONTROL0]
#endif

/* settinf fot DDR2 */
ldr r0, =APB_DMC_1_BASE

ldr r1, =0x0FFF2010 @auto refresh off
str r1, [r0, #DMC_CONCONTROL]

ldr r1, =DMC1_MEMCONTROL @MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
str r1, [r0, #DMC_MEMCONTROL]

ldr r1, =DMC1_MEMCONFIG_0 @MemConfig0 512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
str r1, [r0, #DMC_MEMCONFIG0]

ldr r1, =DMC1_MEMCONFIG_1 @MemConfig1
str r1, [r0, #DMC_MEMCONFIG1]

ldr r1, =0xFF000000
str r1, [r0, #DMC_PRECHCONFIG]

ldr r1, =DMC1_TIMINGA_REF @TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4
str r1, [r0, #DMC_TIMINGAREF]

ldr r1, =DMC1_TIMING_ROW @TimingRow for @200MHz
str r1, [r0, #DMC_TIMINGROW]

ldr r1, =DMC1_TIMING_DATA @TimingData CL=3
str r1, [r0, #DMC_TIMINGDATA]

ldr r1, =DMC1_TIMING_PWR @TimingPower
str r1, [r0, #DMC_TIMINGPOWER]


ldr r1, =0x07000000 @DirectCmd chip0 Deselect
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00020000 @DirectCmd chip0 EMRS2
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00030000 @DirectCmd chip0 EMRS3
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00000542 @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00000442 @DirectCmd chip0 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00010780 @DirectCmd chip0 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (OCD exit)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x07100000 @DirectCmd chip1 Deselect
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00120000 @DirectCmd chip1 EMRS2
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00130000 @DirectCmd chip1 EMRS3
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00110440 @DirectCmd chip1 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00100542 @DirectCmd chip1 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x05100000 @DirectCmd chip1 REFA
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x05100000 @DirectCmd chip1 REFA
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00100442 @DirectCmd chip1 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00110780 @DirectCmd chip1 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (OCD exit)
str r1, [r0, #DMC_DIRECTCMD]

ldr r1, =0x0FF02030 @ConControl auto refresh on
str r1, [r0, #DMC_CONCONTROL]

ldr r1, =0xFFFF00FF @PwrdnConfig
str r1, [r0, #DMC_PWRDNCONFIG]

ldr r1, =DMC1_MEMCONTROL @MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
str r1, [r0, #DMC_MEMCONTROL]

mov pc, lr

5.修改board/samsung/smdkv210/Makefile 添加对mem_setup.S的选则编译,uboot里就不需要编译了,因为BL1已经初始化过了,在执行一次也没问题的

ifndef CONFIG_SPL_BUILD
SOBJS := lowlevel_init.o
endif

ifdef CONFIG_SPL_BUILD
SOBJS := lowlevel_init.o mem_setup.o
endif
6.修改arch/arm/lib/spl.c 的 board_init_f 函数

void __weak board_init_f(ulong dummy)
{
__attribute__((noreturn)) void (*uboot)(void);
#if 0
/* Set the stack pointer. */
asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK));

/* Clear the BSS. */
memset(__bss_start, 0, __bss_end__ - __bss_start);

/* Set global data pointer. */
gd = &gdata;

board_init_r(NULL, 0);
#endif

/*
// test
#define GPH0CON (*(volatile unsigned int *)0xE0200C00)
#define GPH0DAT (*(volatile unsigned int *)0xE0200C04)

GPH0CON = (1<<0) | (1<<4) | (1<<8) | (1<<12);
GPH0DAT = 10;
*/

uart_init();

copy_uboot_to_ram();

//printf ("jump to u-boot image\r\n");
/* Jump to U-Boot image */
uboot = (void *)CONFIG_SYS_TEXT_BASE;
(*uboot)();
}
7.在arch/arm/lib/spl.c 中添加串口的初始化和从sd卡拷贝uboot到ddr2内存里的函数

//UART
#define ULCON0 (*(volatile unsigned int *)0xE2900000)
#define UCON0 (*(volatile unsigned int *)0xE2900004)
#define UTRSTAT0 (*(volatile unsigned int *)0xE2900010)
#define UTXH0 (*(volatile unsigned char *)0xE2900020)
#define URXH0 (*(volatile unsigned char *)0xE2900024)
#define UBRDIV0 (*(volatile unsigned int *)0xE2900028)
#define UDIVSLOT0 (*(volatile unsigned int *)0xE290002C)
//GPA0
#define GPA0CON (*(volatile unsigned int *)0xE0200000)

typedef u32(*copy_sd_mmc_to_mem)
(u32 channel, u32 start_block, u16 block_size, u32 *trg, u32 init);


/* Pointer to as well as the global data structure for SPL */
DECLARE_GLOBAL_DATA_PTR;
gd_t gdata __attribute__ ((section(".data")));

void uart_init (void)
{
//配置GPA0_0 - GPA0_1管脚为串口0功能管脚
GPA0CON = (2<<0) | (2<<4);

/**
* 传送模式: 0:普通模式
* 校验位: 0无校验
* 停止位: 1
* 数据位: 8
*/
ULCON0 = (0<<6) | (0<<3) | (0<<2) | (3<<0);

/**
* 时钟选则: 0 = PCLK = 66M:
* 发送模式:01 = Interrupt request or polling mode
*/
UCON0 = (0<<10) | (1<<2) | (1<<0);

/**
* DIV_VAL = UBRDIVn + (num of 1's in UDIVSLOTn)/16
* DIV_VAL = (PCLK / (bps x 16)) - 1
* DIV_VAL = (66000000 / (115200 * 16)) - 1 = 34.8
* UBRDIV0 = 34
* (num of 1's in UDIVSLOTn)/16 = 0.8
* (num of 1's in UDIVSLOTn) = 12
* 查表得 UDIVSLOT0 = 0xDDDD
*/
UBRDIV0 = 34;
UDIVSLOT0 = 0xDDDD;
}

void copy_uboot_to_ram(void)
{
ulong ch;

ch = *(volatile u32 *)(0xD0037488);
copy_sd_mmc_to_mem copy_bl2 =
(copy_sd_mmc_to_mem) (*(u32 *) (0xD0037F98));

u32 ret;

//printf ("boot mmc chanel: %x\r\n", ch);
if (ch == 0xEB000000) {
ret = copy_bl2(0, 49, 1024, CONFIG_SYS_TEXT_BASE, 0);
}

if (ret == 0) {
//printf ("copy error\r\n");
while (1);
}
else
return;
}
8.arch/arm/include/asm/spl.h +27

//#include <asm/arch/spl.h>

9.分析spl/Makefile得知,在tools/下没有mk$(BOARD)spl这个工具,我暂时对这个工具不熟悉,就用自己的吧,我的工具是mkv210_image,用来制作BL1头信息的

ifdef CONFIG_SAMSUNG
$(obj)$(BOARD)-spl.bin: $(obj)u-boot-spl.bin
$(OBJTREE)/tools/mk$(BOARD)spl \
$(obj)u-boot-spl.bin $(obj)$(BOARD)-spl.bin
endif
10.修改spl/Makefile,然后拷贝mkv210_image.c到tools/下

ifdef CONFIG_SAMSUNG
$(obj)$(BOARD)-spl.bin: $(obj)u-boot-spl.bin
$(HOSTCC) $(TOPDIR)/tools/mkv210_image.c -o $(TOPDIR)/tools/mkv210_image
$(OBJTREE)/tools/mkv210_image \
$(obj)u-boot-spl.bin $(obj)$(BOARD)-spl.bin
endif
11.make,插入SD卡,使用下面的命令烧写SPL和uboot.bin到SD卡上

dd iflag=dsync oflag=dsync if=spl/smdkv210-spl.bin of=/dev/sdb seek=1
dd iflag=dsync oflag=dsync if=u-boot.bin of=/dev/sdb seek=49


12.把SD卡插到开发板上,上电,就可以在控制台上打印出

s5pv210 uboot-2012-10移植(三) 之支持SPL
这里UBOOT有个小BUG,在执行spl/Makefile的时候,include/configs/smdkv210.h中有下面这种带//注释代码的就不行,他会在spl/u-boot-spl.lds上生成出来,导致链接出错,解决方法就是把这种注释全给删了。或改成/* */这种方法
//#define PHYS_SDRAM_1_SIZE	(128 << 20)	/* 0x8000000, 128 MB Bank #1 */
#define PHYS_SDRAM_1_SIZE (0x40000000) /* 0x8000000, 128 MB Bank #1 */