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

上次的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卡插到開發板上,上電,就可以在控制檯上打印出

這裏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 */


                                                                                                                    



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章