s5pv210 uboot-2012-10移植(一) 之分析Alex Ling 的linaro-2011.10 for mini210好久好久前就买了s5pv210的开发板,一直都是东搞搞西搞搞,一点收获也没有,这次下决心来移植最新的uboot 到u-boot-2012.10上,并通过这个博客记录下来以防时间长给忘了,我的开发板是QT210的。s5pv210的启动分为BL0,BL1,BL2,BL0是出厂的时候就固化在IROM 里的,所以我们的uboot 就要实现BL1和BL2,BL1在uboot 里叫做u-boot-spl.bin ,BL2就是我们很熟悉的u-boot.bin 了。在移植之前,我们先看下Alex Ling 的linaro-2011.10 for mini210的UBOOT 是怎么实现的。这里主要还是分析SPL 部分,u-boot.bin 是如何生成的现在资料很多,也很复杂,我这个菜鸟也是一知半解的,所以就不分析了。
1.顶层的Makefile ,从中可以知道,我们要想生成u-boot-spl.bin 就必须配置COFNIG_SPL ,那么u-boot-spl.bin 依赖什么呢,我们继续 1.ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin
2.
3.all: $(ALL-y) 搜索发现,是进入到uboot 顶层目录的spl 目录下执行Makefile 的 1.$(obj)spl/u-boot-spl.bin: depend
2. $(MAKE) -C spl all
2.打开spl/Makefile 分析,一开始就给我们导出CONFIG_SPL_BUILD
1.CONFIG_SPL_BUILD := y
2.export CONFIG_SPL_BUILD
然后分析目标,因为我们的平台是三星的,所以,会有两个目标,一个是不带头信息的u-boot-spl.bin ,一个是$(obj)$(BOARD)-spl.bin 。
1.ALL-y += $(obj)u-boot-spl.bin
2.
3.ifdef CONFIG_SAMSUNG
4.ALL-y += $(obj)$(BOARD)-spl.bin
5.endif
6.
7.all: $(ALL-y)
搜索$(obj)$(BOARD)-spl.bin ,发现,他是通过一个工具生成带头信息的u-boot-spl.bin
Object 1
Object 2
Object 3
Object 4
Object 5Object 6Object 7Object 8Object 9Object 10Object 11Object 12Object 13
Object 14Object 15Object 16Object 17Object 18Object 19Object 20Object 21Object 22Object 23Object 24Object 25Object 26
Object 27
Object 28
Object 29Object 30Object 31Object 32Object 33Object 34Object 35Object 36Object 37Object 38Object 39Object 40Object 41Object 42Object 43Object 44
Object 45Object 46Object 47Object 48Object 49
Object 50Object 51Object 52Object 53Object 54
Object 55Object 56Object 57
1.ifdef CONFIG_SAMSUNG
2.$(obj)$(BOARD)-spl.bin: $(obj)u-boot-spl.bin
3.$(TOPDIR)/board/$(BOARDDIR)/tools/mk$(BOARD)spl.exe \
4.$(obj)u-boot-spl.bin $(obj)$(BOARD)-spl.bin
5.endif
好了,Makefile就分析到这里,知道了BL1是如何生成的了。下面里分析代码了。
首先分析arch/arm/cpu/armv7/start.S
1.reset:
2.bl save_boot_params
3./*
4.* set the cpu to SVC32 mode
5.*/
6.mrs r0, cpsr
7.bic r0, r0, #0x1f
8.orr r0, r0, #0xd3
9.msr cpsr,r0
10.
11./* the mask ROM code should have PLL and others stable */
12.#ifndef CONFIG_SKIP_LOWLEVEL_INIT
13.bl cpu_init_crit
14.#endif
15.
16./* Set stackpointer in internal RAM to call board_init_f */
17.call_board_init_f:
18.ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
19.bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
20.ldr r0,=0x00000000
21.bl board_init_f
其中,cpu_init_crit中主要做初始化了memory和串口,接下来就是调用C函数board_init_f了,在调用C函数之前得设置栈,board_init_f有两个,一个是在arch/arm/lib/board.c,一个在
board/samsung/mini210/mmc_boot.c那么道理是那个呢,看各个目录下的Makefile
1.arch/arm/lib/下的
1.ifndef CONFIG_SPL_BUILD
2....
3.COBJS-y += board.o
4....
5.endif
2.board/samsung/mini210/
1.ifdef CONFIG_SPL_BUILD
2.COBJS += mmc_boot.o
3.endif
得出,是board/samsung/mini210/mmc_boot.c了,打开
1.void board_init_f(unsigned long bootflag)
2.{
3.__attribute__((noreturn)) void (*uboot)(void);
4.copy_uboot_to_ram();
5.
6./* Jump to U-Boot image */
7.uboot = (void *)CONFIG_SYS_TEXT_BASE;
8.(*uboot)();
9./* Never returns Here */
10.}
得出,首先拷贝BL2完整的UBOOT到RAM里去,然后从ram里开始执行,然后就没有了。那么是如何拷贝的呢,这就得需要一个文档了S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf中
好了,看看copy_uboot_to_ram代码
1.typedef u32(*copy_sd_mmc_to_mem)
2.(u32 channel, u32 start_block, u16 block_size, u32 *trg, u32 init);
1.ch = *(volatile u32 *)(0xD0037488);
2.copy_sd_mmc_to_mem copy_bl2 =
3.(copy_sd_mmc_to_mem) (*(u32 *) (0xD0037F98));
1.u32 ret;
2.if (ch == 0xEB000000) {
3.ret = copy_bl2(0, MOVI_BL2_POS, MOVI_BL2_BLKCNT,
4.CONFIG_SYS_TEXT_BASE, 0);
5.} else if (ch == 0xEB200000) {
6.ret = copy_bl2(2, MOVI_BL2_POS, MOVI_BL2_BLKCNT,
7.CONFIG_SYS_TEXT_BASE, 0);
8.}
其中,MOVI_BL2_POS是1,MOVI_BL2_BLKCNT是49,CONFIG_SYS_TEXT_BASE是uboot在内存里的其实地址。
复制完成之后就会在内存里从u-boot.bin的start.S出开始重新执行了。
s5pv210 uboot-2012-10移植(二) 之能够启动进入控制台
这次我们将从官网下载的最新uboot-2012-10移植到s5pv210开发板上,让其进入控制台,效果如下:
首先,我暂时没采用内核的SPL,这个将在后面给补上,这里的BL1是我自己参考资料写的,我用的是QT210开发板,内存1G,对于不同的开发板,需要重新配置memory和修改uboot在内存里的地址,也就是CONFIG_SYS_TEXT_BASE。我的BL1代码在这里下载。
一、添加smdkv210单板
1.cp -a board/samsung/smdkc100 board/samsung/smdkv210
2.cp include/configs/smdkc100.h include/configs/smdkv210.h
3.vim boards.cfg,在270行添加
1.270 smdkv210 arm armv7 smdkv210 samsung s5pc1xx
4.make smdkv210_config可以生成u-boot.bin了
二、让u-boot.bin在内存里启动起来
1.分析我的BL1代码可以得知,只拷贝了u-boot.bin,并没有清楚bss,在ls arch/arm/cpu/armv7/start.S +126中添加
1.reset:
2.//by ZheGao clear bss
3.ldr r0, =__bss_start
4.ldr r1, =__bss_end__
5.mov r2, #0x0
6.1:
7.str r2, [r0], #4
8.cmp r0, r1
9.bne 1b
10.//end of clear bss
11.
12.bl save_boot_params
2.在BL0已经关了看门狗,在BL1里已经初始化了memory和串口,修改
board/samsung/smdkv210/lowlevel_init.S +39中给屏蔽
1..globl lowlevel_init
2.lowlevel_init:
3.mov r9, lr
4.#if 0
5./* r5 has always zero */
6.mov r5, #0
7.
8.ldr r8, =S5PC100_GPIO_BASE
9.
10./* Disable Watchdog */
11.ldr r0, =S5PC100_WATCHDOG_BASE @0xEA200000
12.orr r0, r0, #0x0
13.str r5, [r0]
14.
15./* setting SRAM */
16.ldr r0, =S5PC100_SROMC_BASE
17.ldr r1, =0x9
18.str r1, [r0]
19.
20./* S5PC100 has 3 groups of interrupt sources */
21.ldr r0, =S5PC100_VIC0_BASE @0xE4000000
22.ldr r1, =S5PC100_VIC1_BASE @0xE4000000
23.ldr r2, =S5PC100_VIC2_BASE @0xE4000000
24.
25./* Disable all interrupts (VIC0, VIC1 and VIC2) */
26.mvn r3, #0x0
27.str r3, [r0, #0x14] @INTENCLEAR
28.str r3, [r1, #0x14] @INTENCLEAR
29.str r3, [r2, #0x14] @INTENCLEAR
30.
31./* Set all interrupts as IRQ */
32.str r5, [r0, #0xc] @INTSELECT
33.str r5, [r1, #0xc] @INTSELECT
34.str r5, [r2, #0xc] @INTSELECT
35.
36./* Pending Interrupt Clear */
37.str r5, [r0, #0xf00] @INTADDRESS
38.str r5, [r1, #0xf00] @INTADDRESS
39.str r5, [r2, #0xf00] @INTADDRESS
40.
41./* for UART */
42.bl uart_asm_init
43.
44./* for TZPC */
45.bl tzpc_asm_init
46.
47.1:
48.#endif
49.mov lr, r9
50.mov pc, lr
3.修改第一步的sp指针,在include/configs/smdkv210.h +228修改
1.//#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000)
2.#define CONFIG_SYS_INIT_SP_ADDR (0x30000000)
4.修改board/samsung/smdkv210/smdkc100.c +80
1.int checkboard(void)
2.{
3.printf("Board:\tSMDKv210\n");
4.return 0;
5.}
5.修改include/configs/smdkv210.h +51
1.//#define CONFIG_SYS_SDRAM_BASE 0x30000000
2.#define CONFIG_SYS_SDRAM_BASE 0x20000000
6.修改include/configs/smdkv210.h +189
1.//#define PHYS_SDRAM_1_SIZE (128 << 20) /* 0x8000000, 128 MB Bank #1 */
2.#define PHYS_SDRAM_1_SIZE (0x40000000) /* 0x8000000, 128 MB Bank #1 */
7.修改board/samsung/smdkv210/config.mk +16
1.CONFIG_SYS_TEXT_BASE = 0x5ff00000
8.修改 arch/arm/config.mk +88
1.#LDFLAGS_u-boot += -pie
9.修改include/configs/smdkv210.h +216
1.//#define CONFIG_ENV_IS_IN_ONENAND 1
2.#define CONFIG_ENV_IS_NOWHERE
10.修改arch/arm/lib/board.c +384
1.//addr -= gd->mon_len;
2.addr = 0x5ff00000;
11.因为bl1已经复制程序到指定的地址就不需要重新定位代码了,但还是需要重新设置栈,所以修改了上面的第8步,修改arch/arm/cpu/armv7/start.S +192
1.ENTRY(relocate_code)
2.mov r4, r0 /* save addr_sp */
3.mov r5, r1 /* save addr of gd */
4.mov r6, r2 /* save addr of destination */
5.
6.#if 0
7.//debug
8.ldr r0, =0xE0200C00
9.ldr r1, =0x1111
10.str r1, [r0]
11.
12.ldr r0, =0xE0200C04
13.ldr r1, =(7)
14.str r1, [r0]
15.#endif
16.
17.mov sp, r4
18.mov r0, r5
19.mov r1, r6
20.
21.bl board_init_r
22.#if 0
23./* Set up the stack */
24.stack_setup:
25.mov sp, r4
26.
27.adr r0, _start
28.cmp r0, r6
29.moveq r9, #0 /* no relocation. relocation offset(r9) = 0 */
30.beq clear_bss /* skip relocation */
31.mov r1, r6 /* r1 <- scratch for copy_loop */
32.ldr r3, _image_copy_end_ofs
33.add r2, r0, r3 /* r2 <- source end address */
34.
35.copy_loop:
36.ldmia r0!, {r9-r10} /* copy from source address [r0] */
37.stmia r1!, {r9-r10} /* copy to target address [r1] */
38.cmp r0, r2 /* until source end address [r2] */
39.blo copy_loop
40.
41./*
42.* fix .rel.dyn relocations
43.*/
44.ldr r0, _TEXT_BASE /* r0 <- T ext base */
45.sub r9, r6, r0 /* r9 <- relocation offset */
46.ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
47.add r10, r10, r0 /* r10 <- sym table in FLASH */
48.ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
49.add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
50.ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
51.add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
52.fixloop:
53.ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
54.add r0, r0, r9 /* r0 <- location to fix up in RAM */
55.ldr r1, [r2, #4]
56.and r7, r1, #0xff
57.cmp r7, #23 /* relative fixup? */
58.beq fixrel
59.cmp r7, #2 /* absolute fixup? */
60.beq fixabs
61./* ignore unknown type of fixup */
62. b fixnext
63.fixabs:
64./* absolute fix: set location to (offset) symbol value */
65.mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
66.add r1, r10, r1 /* r1 <- address of symbol in table */
67.ldr r1, [r1, #4] /* r1 <- symbol value */
68.add r1, r1, r9 /* r1 <- relocated sym addr */
69. b fixnext
70.fixrel:
71./* relative fix: increase location by offset */
72.ldr r1, [r0]
73.add r1, r1, r9
74.fixnext:
75.str r1, [r0]
76.add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
77.cmp r2, r3
78.blo fixloop
79. b clear_bss
80._rel_dyn_start_ofs:
81..word __rel_dyn_start - _start
82._rel_dyn_end_ofs:
83..word __rel_dyn_end - _start
84._dynsym_start_ofs:
85..word __dynsym_start - _start
86.
87.clear_bss:
88.ldr r0, _bss_start_ofs
89.ldr r1, _bss_end_ofs
90.mov r4, r6 /* reloc addr */
91.add r0, r0, r4
92.add r1, r1, r4
93.mov r2, #0x00000000 /* clear */
94.
95.clbss_l:cmp r0, r1 /* clear loop... */
96.bhs clbss_e /* if reached end of bss, exit */
97.str r2, [r0]
98.add r0, r0, #4
99. b clbss_l
100.clbss_e:
101.
102./*
103.* We are done. Do not return, instead branch to second part of board 104.* initialization, now running from RAM.
105.*/
106.jump_2_ram:
107./*
108.* If I-cache is enabled invalidate it
109.*/
110.#ifndef CONFIG_SYS_ICACHE_OFF
111.mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
112.mcr p15, 0, r0, c7, c10, 4 @ DSB
113.mcr p15, 0, r0, c7, c5, 4 @ ISB
114.#endif
115./*
116.* Move vector table
117.*/
118.#if !defined(CONFIG_TEGRA20)
119./* Set vector address in CP15 VBAR register */
120.ldr r0, =_start
121.add r0, r0, r9
122.mcr p15, 0, r0, c12, c0, 0 @Set VBAR
123.#endif /* !T egra20 */
124.
125.ldr r0, _board_init_r_ofs
126.adr r1, _start
127.add lr, r0, r1
128.add lr, lr, r9
129./* setup parameters for board_init_r */
130.mov r0, r5 /* gd_t */
131.mov r1, r6 /* dest_addr */
132./* jump to it ... */
133.mov pc, lr
134.
135._board_init_r_ofs:
136..word board_init_r - _start
137.#endif
138.ENDPROC(relocate_code)
139.#endif
重新make一下,使用下面命令烧写到sd卡里,插入开发板启动即可,看看上面的启动信息,还有很多很多地方要完善~
1.dd iflag=dsync oflag=dsync if=blSD.bin of=/dev/sdb seek=1
2.dd iflag=dsync oflag=dsync if=u-boot.bin of=/dev/sdb seek=49
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添加
1./* SPL */
2.#define CONFIG_SPL
3.#define CONFIG_SPL_FRAMEWORK
2.因为SPL不需要BSS清零,所以修改arch/arm/cpu/armv7/start.S +128
1.#ifndef CONFIG_SPL_BUILD
2.//by ZheGao clear bss
3.ldr r0, =__bss_start
4.ldr r1, =__bss_end__
5.mov r2, #0x0
6.1:
7.str r2, [r0], #4
8.cmp r0, r1
9.bne 1b
10.//end of clear bss
11.
12.bl save_boot_params
13.#endif
3.因为BL1需要初始化memory,所以在lowlevel_init中添加,
board/samsung/smdkv210/lowlevel_init.S +43
1.#ifdef CONFIG_SPL_BUILD
2.bl mem_ctrl_asm_init
3.#endif
4.mem_ctrl_asm_init在同目录下的mem_setup.S文件中,修改
board/samsung/smdkv210/mem_setup.S 添加memory的配置
1.#define ELFIN_GPIO_BASE 0xE0200000
2.#define MP1_0DRV_SR_OFFSET 0x3CC
3.#define MP1_1DRV_SR_OFFSET 0x3EC
4.#define MP1_2DRV_SR_OFFSET 0x40C
5.#define MP1_3DRV_SR_OFFSET 0x42C
6.#define MP1_4DRV_SR_OFFSET 0x44C
7.#define MP1_5DRV_SR_OFFSET 0x46C
8.#define MP1_6DRV_SR_OFFSET 0x48C
9.#define MP1_7DRV_SR_OFFSET 0x4AC
10.#define MP1_8DRV_SR_OFFSET 0x4CC
11.#define MP2_0DRV_SR_OFFSET 0x4EC
12.#define MP2_1DRV_SR_OFFSET 0x50C
13.#define MP2_2DRV_SR_OFFSET 0x52C
14.#define MP2_3DRV_SR_OFFSET 0x54C
15.#define MP2_4DRV_SR_OFFSET 0x56C
16.#define MP2_5DRV_SR_OFFSET 0x58C
17.#define MP2_6DRV_SR_OFFSET 0x5AC
18.#define MP2_7DRV_SR_OFFSET 0x5CC
19.#define MP2_8DRV_SR_OFFSET 0x5EC
20.#define APB_DMC_0_BASE 0xF0000000
21.#define APB_DMC_1_BASE 0xF1400000
22.#define ASYNC_MSYS_DMC0_BASE 0xF1E00000
23.
24.#define DMC_CONCONTROL 0x00
25.#define DMC_MEMCONTROL 0x04
26.#define DMC_MEMCONFIG0 0x08
27.#define DMC_MEMCONFIG1 0x0C
28.#define DMC_DIRECTCMD 0x10
29.#define DMC_PRECHCONFIG 0x14
30.#define DMC_PHYCONTROL0 0x18
31.#define DMC_PHYCONTROL1 0x1C
32.#define DMC_RESERVED 0x20
33.#define DMC_PWRDNCONFIG 0x28
34.#define DMC_TIMINGAREF 0x30
35.#define DMC_TIMINGROW 0x34
36.#define DMC_TIMINGDATA 0x38
37.#define DMC_TIMINGPOWER 0x3C
38.#define DMC_PHYSTATUS 0x40
39.#define DMC_CHIP0STATUS 0x48
40.#define DMC_CHIP1STATUS 0x4C
41.#define DMC_AREFSTATUS 0x50
42.#define DMC_MRSTATUS 0x54
43.#define DMC_PHYTEST0 0x58
44.#define DMC_PHYTEST1 0x5C
45.#define DMC_QOSCONTROL0 0x60
46.#define DMC_QOSCONFIG0 0x64
47.#define DMC_QOSCONTROL1 0x68
48.#define DMC_QOSCONFIG1 0x6C
49.#define DMC_QOSCONTROL2 0x70
50.#define DMC_QOSCONFIG2 0x74
51.#define DMC_QOSCONTROL3 0x78
52.#define DMC_QOSCONFIG3 0x7C
53.#define DMC_QOSCONTROL4 0x80
54.#define DMC_QOSCONFIG4 0x84
55.#define DMC_QOSCONTROL5 0x88
56.#define DMC_QOSCONFIG5 0x8C
57.#define DMC_QOSCONTROL6 0x90
58.#define DMC_QOSCONFIG6 0x94
59.#define DMC_QOSCONTROL7 0x98
60.#define DMC_QOSCONFIG7 0x9C
61.#define DMC_QOSCONTROL8 0xA0
62.#define DMC_QOSCONFIG8 0xA4
63.#define DMC_QOSCONTROL9 0xA8
64.#define DMC_QOSCONFIG9 0xAC
65.#define DMC_QOSCONTROL10 0xB0
66.#define DMC_QOSCONFIG10 0xB4
67.#define DMC_QOSCONTROL11 0xB8
68.#define DMC_QOSCONFIG11 0xBC
69.#define DMC_QOSCONTROL12 0xC0
70.#define DMC_QOSCONFIG12 0xC4
71.#define DMC_QOSCONTROL13 0xC8
72.#define DMC_QOSCONFIG13 0xCC
73.#define DMC_QOSCONTROL14 0xD0
74.#define DMC_QOSCONFIG14 0xD4
75.#define DMC_QOSCONTROL15 0xD8
76.#define DMC_QOSCONFIG15 0xDC
77.
78.#define DMC0_MEMCONFIG_0 0x20E01323 // MemConfig0 256MB config, 8 banks,Mapping Met
hod[12:15]0:linear, 1:linterleaved, 2:Mixed
79.#define DMC0_MEMCONFIG_1 0x40F01323 // MemConfig1
80.#define DMC0_TIMINGA_REF 0x00000618 // TimingAref 7.8us*133MHz=1038(0x40E), 100MHz
=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)
81.#define DMC0_TIMING_ROW 0x28233287 // TimingRow for @200MHz
82.#define DMC0_TIMING_DATA 0x23240304 // TimingData CL=3
83.#define DMC0_TIMING_PWR 0x09C80232 // TimingPower
84.
85.#define DMC1_MEMCONTROL 0x00202400 // MemControl BL=4, 2 chip, DDR2 type, dynamic s
elf refresh, force precharge, dynamic power down off
86.#define DMC1_MEMCONFIG_0 0x40C01323 // MemConfig0 512MB config, 8 banks,Mapping Me
thod[12:15]0:linear, 1:linterleaved, 2:Mixed
87.#define DMC1_MEMCONFIG_1 0x00E01323 // MemConfig1
88.#define DMC1_TIMINGA_REF 0x00000618 // TimingAref 7.8us*133MHz=1038(0x40E), 100MHz
=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4
89.#define DMC1_TIMING_ROW 0x28233289 // TimingRow for @200MHz
90.#define DMC1_TIMING_DATA 0x23240304 // TimingData CL=3
91.#define DMC1_TIMING_PWR 0x08280232 // TimingPower
92.
93.
94..globl mem_ctrl_asm_init
95.mem_ctrl_asm_init:
96.#if 0
97.ldr r6, =S5PC100_DMC_BASE @ 0xE6000000
98.
99./* DLL parameter setting */
100.ldr r1, =0x50101000
101.str r1, [r6, #0x018] @ PHYCONTROL0
102.ldr r1, =0xf4
103.str r1, [r6, #0x01C] @ PHYCONTROL1
104.ldr r1, =0x0
105.str r1, [r6, #0x020] @ PHYCONTROL2
106.
107./* DLL on */
108.ldr r1, =0x50101002
109.str r1, [r6, #0x018] @ PHYCONTROL0
110.
111./* DLL start */
112.ldr r1, =0x50101003
113.str r1, [r6, #0x018] @ PHYCONTROL0
114.
115./* Force value locking for DLL off */
116.str r1, [r6, #0x018] @ PHYCONTROL0
117.
118./* DLL off */
119.ldr r1, =0x50101001
120.str r1, [r6, #0x018] @ PHYCONTROL0
121.
122./* auto refresh off */
123.ldr r1, =0xff001010
124.str r1, [r6, #0x000] @ CONCONTROL
125.
126./*
127.* Burst Length 4, 2 chips, 32-bit, LPDDR
128.* OFF: dynamic self refresh, force precharge, dynamic power down off 129.*/
130.ldr r1, =0x00212100
131.str r1, [r6, #0x004] @ MEMCONTROL
132.
133./*
134.* Note:
135.* If Bank0 has OneDRAM we place it at 0x2800'0000
136.* So finally Bank1 should address start at at 0x2000'0000
137.*/
138.mov r4, #0x0
139.
140.swap_memory:
141./*
142.* Bank0
143.* 0x30 -> 0x30000000
144.* 0xf8 -> 0x37FFFFFF
145.* [15:12] 0: Linear
146.* [11:8 ] 2: 9 bits
147.* [ 7:4 ] 2: 14 bits
148.* [ 3:0 ] 2: 4 banks
149.*/
150.ldr r1, =0x30f80222
151./* if r4 is 1, swap the bank */
152.cmp r4, #0x1
153.orreq r1, r1, #0x08000000
154.str r1, [r6, #0x008] @ MEMCONFIG0
155.
156./*
157.* Bank1
158.* 0x38 -> 0x38000000
159.* 0xf8 -> 0x3fFFFFFF
160.* [15:12] 0: Linear
161.* [11:8 ] 2: 9 bits
162.* [ 7:4 ] 2: 14 bits
163.* [ 3:0 ] 2: 4 banks
164.*/
165.ldr r1, =0x38f80222
166./* if r4 is 1, swap the bank */
167.cmp r4, #0x1
168.biceq r1, r1, #0x08000000
169.str r1, [r6, #0x00c] @ MEMCONFIG1
170.
171.ldr r1, =0x20000000
172.str r1, [r6, #0x014] @ PRECHCONFIG
173.
174./*
175.* FIXME: Please verify these values
176.* 7.8us * 166MHz %LE %LONG1294(0x50E) 177.* 7.8us * 133MHz %LE %LONG1038(0x40E), 178.* 7.8us * 100MHz %LE %LONG780(0x30C), 179.* 7.8us * 20MHz %LE %LONG156(0x9C), 180.* 7.8us * 10MHz %LE %LONG78(0x4E)
181.*/
182.ldr r1, =0x0000050e
183.str r1, [r6, #0x030] @ TIMINGAREF 184.
185./* 166 MHz */
186.ldr r1, =0x0c233287
187.str r1, [r6, #0x034] @ TIMINGROW 188.
189./* twtr=3 twr=2 trtp=3 cl=3 wl=3 rl=3 */ 190.ldr r1, =0x32330303
191.str r1, [r6, #0x038] @ TIMINGDATA 192.
193./* tfaw=4 sxsr=0x14 txp=0x14 tcke=3 tmrd=3 */ 194.ldr r1, =0x04141433
195.str r1, [r6, #0x03C] @ TIMINGPOWER 196.
197./* chip0 Deselect */
198.ldr r1, =0x07000000
199.str r1, [r6, #0x010] @ DIRECTCMD 200.
201./* chip0 PALL */
202.ldr r1, =0x01000000
203.str r1, [r6, #0x010] @ DIRECTCMD 204.
205./* chip0 REFA */
206.ldr r1, =0x05000000
207.str r1, [r6, #0x010] @ DIRECTCMD 208./* chip0 REFA */
209.str r1, [r6, #0x010] @ DIRECTCMD 210.
211./* chip0 MRS, CL%LE %LONG3, BL%LE %LONG4 */ 212.ldr r1, =0x00000032
213.str r1, [r6, #0x010] @ DIRECTCMD 214.
215./* chip1 Deselect */
216.ldr r1, =0x07100000
217.str r1, [r6, #0x010] @ DIRECTCMD 218.
219./* chip1 PALL */
220.ldr r1, =0x01100000
221.str r1, [r6, #0x010] @ DIRECTCMD 222.
223./* chip1 REFA */
224.ldr r1, =0x05100000
225.str r1, [r6, #0x010] @ DIRECTCMD
226./* chip1 REFA */
227.str r1, [r6, #0x010] @ DIRECTCMD 228.
229./* chip1 MRS, CL%LE %LONG3, BL%LE %LONG4 */ 230.ldr r1, =0x00100032
231.str r1, [r6, #0x010] @ DIRECTCMD 232.
233./* auto refresh on */
234.ldr r1, =0xff002030
235.str r1, [r6, #0x000] @ CONCONTROL 236.
237./* PwrdnConfig */
238.ldr r1, =0x00100002
239.str r1, [r6, #0x028] @ PWRDNCONFIG 240.
241./* BL%LE %LONG */
242.ldr r1, =0xff212100
243.str r1, [r6, #0x004] @ MEMCONTROL 244.
245.
246./* T ry to test memory area */
247.cmp r4, #0x1
248.beq 1f
249.
250.mov r4, #0x1
251.ldr r1, =0x37ffff00
252.str r4, [r1]
253.str r4, [r1, #0x4] @ dummy write 254.ldr r0, [r1]
255.cmp r0, r4
256.bne swap_memory
257.#endif
258.
259./* DMC0 Drive Strength (Setting 2X) */
260.
261.ldr r0, =ELFIN_GPIO_BASE
262.
263.ldr r1, =0x0000AAAA
264.str r1, [r0, #MP1_0DRV_SR_OFFSET]
265.
266.ldr r1, =0x0000AAAA
267.str r1, [r0, #MP1_1DRV_SR_OFFSET]
268.
269.ldr r1, =0x0000AAAA
270.str r1, [r0, #MP1_2DRV_SR_OFFSET]
271.
272.ldr r1, =0x0000AAAA
273.str r1, [r0, #MP1_3DRV_SR_OFFSET]
274.
275.ldr r1, =0x0000AAAA
276.str r1, [r0, #MP1_4DRV_SR_OFFSET]
277.
278.ldr r1, =0x0000AAAA
279.str r1, [r0, #MP1_5DRV_SR_OFFSET]
280.
281.ldr r1, =0x0000AAAA
282.str r1, [r0, #MP1_6DRV_SR_OFFSET]
283.
284.ldr r1, =0x0000AAAA
285.str r1, [r0, #MP1_7DRV_SR_OFFSET]
286.
287.ldr r1, =0x00002AAA
288.str r1, [r0, #MP1_8DRV_SR_OFFSET]
289.
290.
291./* DMC1 Drive Strength (Setting 2X) */
292.
293.ldr r0, =ELFIN_GPIO_BASE
294.
295.ldr r1, =0x0000AAAA
296.str r1, [r0, #MP2_0DRV_SR_OFFSET]
297.
298.ldr r1, =0x0000AAAA
299.str r1, [r0, #MP2_1DRV_SR_OFFSET]
300.
301.ldr r1, =0x0000AAAA
302.str r1, [r0, #MP2_2DRV_SR_OFFSET]
303.
304.ldr r1, =0x0000AAAA
305.str r1, [r0, #MP2_3DRV_SR_OFFSET]
306.
307.ldr r1, =0x0000AAAA
308.str r1, [r0, #MP2_4DRV_SR_OFFSET]
309.
310.ldr r1, =0x0000AAAA
311.str r1, [r0, #MP2_5DRV_SR_OFFSET]
312.
313.ldr r1, =0x0000AAAA
314.str r1, [r0, #MP2_6DRV_SR_OFFSET]
315.
316.ldr r1, =0x0000AAAA
317.str r1, [r0, #MP2_7DRV_SR_OFFSET]
318.
319.ldr r1, =0x00002AAA
320.str r1, [r0, #MP2_8DRV_SR_OFFSET]
321.
322./* DMC0 initialization at single T ype*/
323.ldr r0, =APB_DMC_0_BASE
324.
325.ldr r1, =0x00101000 @PhyControl0 DLL parameter setting, manual 0x00101000 326.str r1, [r0, #DMC_PHYCONTROL0]
327.
328.ldr r1, =0x00000086 @PhyControl1 DLL parameter setting, LPDDR/LPDDR2 Case 329.str r1, [r0, #DMC_PHYCONTROL1]
331.ldr r1, =0x00101002 @PhyControl0 DLL on
332.str r1, [r0, #DMC_PHYCONTROL0]
333.
334.ldr r1, =0x00101003 @PhyControl0 DLL start
335.str r1, [r0, #DMC_PHYCONTROL0]
336.
337.find_lock_val:
338.ldr r1, [r0, #DMC_PHYSTATUS] @Load Phystatus register value
339.and r2, r1, #0x7
340.cmp r2, #0x7 @Loop until DLL is locked
341.bne find_lock_val
342.
343.and r1, #0x3fc0
344.mov r2, r1, LSL #18
345.orr r2, r2, #0x100000
346.orr r2 ,r2, #0x1000
347.
348.orr r1, r2, #0x3 @Force Value locking
349.str r1, [r0, #DMC_PHYCONTROL0]
350.
351.#if 0 /* Memory margin test 10.01.05 */
352.orr r1, r2, #0x1 @DLL off
353.str r1, [r0, #DMC_PHYCONTROL0]
354.#endif
355./* setting DDR2 */
356.ldr r1, =0x0FFF2010 @ConControl auto refresh off
357.str r1, [r0, #DMC_CONCONTROL]
358.
359.ldr r1, =0x00212400 @MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, fo rce precharge, dynamic power down off
360.str r1, [r0, #DMC_MEMCONTROL]
361.
362.ldr r1, =DMC0_MEMCONFIG_0 @MemConfig0 256MB config, 8 banks,Mapping Method[ 12:15]0:linear, 1:linterleaved, 2:Mixed
363.str r1, [r0, #DMC_MEMCONFIG0]
364.
365.ldr r1, =DMC0_MEMCONFIG_1 @MemConfig1
366.str r1, [r0, #DMC_MEMCONFIG1]
367.
368.ldr r1, =0xFF000000 @PrechConfig
369.str r1, [r0, #DMC_PRECHCONFIG]
370.
371.ldr r1, =DMC0_TIMINGA_REF @TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780 (0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)
372.str r1, [r0, #DMC_TIMINGAREF]
373.
374.ldr r1, =DMC0_TIMING_ROW @TimingRow for @200MHz
375.str r1, [r0, #DMC_TIMINGROW]
376.
377.ldr r1, =DMC0_TIMING_DATA @TimingData CL=3
378.str r1, [r0, #DMC_TIMINGDATA]
380.ldr r1, =DMC0_TIMING_PWR @TimingPower
381.str r1, [r0, #DMC_TIMINGPOWER]
382.
383.ldr r1, =0x07000000 @DirectCmd chip0 Deselect
384.str r1, [r0, #DMC_DIRECTCMD]
385.
386.ldr r1, =0x01000000 @DirectCmd chip0 PALL
387.str r1, [r0, #DMC_DIRECTCMD]
388.
389.ldr r1, =0x00020000 @DirectCmd chip0 EMRS2
390.str r1, [r0, #DMC_DIRECTCMD]
391.
392.ldr r1, =0x00030000 @DirectCmd chip0 EMRS3
393.str r1, [r0, #DMC_DIRECTCMD]
394.
395.ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable) 396.str r1, [r0, #DMC_DIRECTCMD]
397.
398.ldr r1, =0x00000542 @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4 399.str r1, [r0, #DMC_DIRECTCMD]
400.
401.ldr r1, =0x01000000 @DirectCmd chip0 PALL
402.str r1, [r0, #DMC_DIRECTCMD]
403.
404.ldr r1, =0x05000000 @DirectCmd chip0 REFA
405.str r1, [r0, #DMC_DIRECTCMD]
406.
407.ldr r1, =0x05000000 @DirectCmd chip0 REFA
408.str r1, [r0, #DMC_DIRECTCMD]
409.
410.ldr r1, =0x00000442 @DirectCmd chip0 MRS (MEM DLL unreset)
411.str r1, [r0, #DMC_DIRECTCMD]
412.
413.ldr r1, =0x00010780 @DirectCmd chip0 EMRS1 (OCD default)
414.str r1, [r0, #DMC_DIRECTCMD]
415.
416.ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (OCD exit)
417.str r1, [r0, #DMC_DIRECTCMD]
418.
419.ldr r1, =0x07100000 @DirectCmd chip1 Deselect
420.str r1, [r0, #DMC_DIRECTCMD]
421.
422.ldr r1, =0x01100000 @DirectCmd chip1 PALL
423.str r1, [r0, #DMC_DIRECTCMD]
424.
425.ldr r1, =0x00120000 @DirectCmd chip1 EMRS2
426.str r1, [r0, #DMC_DIRECTCMD]
427.
428.ldr r1, =0x00130000 @DirectCmd chip1 EMRS3
429.str r1, [r0, #DMC_DIRECTCMD]
430.
431.ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (MEM DLL on, DQS# disable) 432.str r1, [r0, #DMC_DIRECTCMD]
433.
434.ldr r1, =0x00100542 @DirectCmd chip1 MRS (MEM DLL reset) CL=4, BL=4 435.str r1, [r0, #DMC_DIRECTCMD]
436.
437.ldr r1, =0x01100000 @DirectCmd chip1 PALL
438.str r1, [r0, #DMC_DIRECTCMD]
439.
440.ldr r1, =0x05100000 @DirectCmd chip1 REFA
441.str r1, [r0, #DMC_DIRECTCMD]
442.
443.ldr r1, =0x05100000 @DirectCmd chip1 REFA
444.str r1, [r0, #DMC_DIRECTCMD]
445.
446.ldr r1, =0x00100442 @DirectCmd chip1 MRS (MEM DLL unreset)
447.str r1, [r0, #DMC_DIRECTCMD]
448.
449.ldr r1, =0x00110780 @DirectCmd chip1 EMRS1 (OCD default)
450.str r1, [r0, #DMC_DIRECTCMD]
451.
452.ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (OCD exit)
453.str r1, [r0, #DMC_DIRECTCMD]
454.
455.ldr r1, =0x0FF02030 @ConControl auto refresh on
456.str r1, [r0, #DMC_CONCONTROL]
457.
458.ldr r1, =0xFFFF00FF @PwrdnConfig
459.str r1, [r0, #DMC_PWRDNCONFIG]
460.
461.ldr r1, =0x00202400 @MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, fo rce precharge, dynamic power down off
462.str r1, [r0, #DMC_MEMCONTROL]
463.
464./* DMC1 initialization */
465.ldr r0, =APB_DMC_1_BASE
466.
467.ldr r1, =0x00101000 @Phycontrol0 DLL parameter setting
468.str r1, [r0, #DMC_PHYCONTROL0]
469.
470.ldr r1, =0x00000086 @Phycontrol1 DLL parameter setting
471.str r1, [r0, #DMC_PHYCONTROL1]
472.
473.ldr r1, =0x00101002 @PhyControl0 DLL on
474.str r1, [r0, #DMC_PHYCONTROL0]
475.
476.ldr r1, =0x00101003 @PhyControl0 DLL start
477.str r1, [r0, #DMC_PHYCONTROL0]
478.find_lock_val1:
479.ldr r1, [r0, #DMC_PHYSTATUS] @Load Phystatus register value
480.and r2, r1, #0x7
481.cmp r2, #0x7 @Loop until DLL is locked
482.bne find_lock_val1
483.
484.and r1, #0x3fc0
485.mov r2, r1, LSL #18
486.orr r2, r2, #0x100000
487.orr r2, r2, #0x1000
488.
489.orr r1, r2, #0x3 @Force Value locking
490.str r1, [r0, #DMC_PHYCONTROL0]
491.
492.#if 0 /* Memory margin test 10.01.05 */
493.orr r1, r2, #0x1 @DLL off
494.str r1, [r0, #DMC_PHYCONTROL0]
495.#endif
496.
497./* settinf fot DDR2 */
498.ldr r0, =APB_DMC_1_BASE
499.
500.ldr r1, =0x0FFF2010 @auto refresh off
501.str r1, [r0, #DMC_CONCONTROL]
502.
503.ldr r1, =DMC1_MEMCONTROL @MemControl BL=4, 2 chip, DDR2 type, dynamic self re fresh, force precharge, dynamic power down off
504.str r1, [r0, #DMC_MEMCONTROL]
505.
506.ldr r1, =DMC1_MEMCONFIG_0 @MemConfig0 512MB config, 8 banks,Mapping Method[ 12:15]0:linear, 1:linterleaved, 2:Mixed
507.str r1, [r0, #DMC_MEMCONFIG0]
508.
509.ldr r1, =DMC1_MEMCONFIG_1 @MemConfig1
510.str r1, [r0, #DMC_MEMCONFIG1]
511.
512.ldr r1, =0xFF000000
513.str r1, [r0, #DMC_PRECHCONFIG]
514.
515.ldr r1, =DMC1_TIMINGA_REF @TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780 (0x30C), 20MHz=156(0x9C), 10MHz=78(0x4
516.str r1, [r0, #DMC_TIMINGAREF]
517.
518.ldr r1, =DMC1_TIMING_ROW @TimingRow for @200MHz
519.str r1, [r0, #DMC_TIMINGROW]
520.
521.ldr r1, =DMC1_TIMING_DATA @TimingData CL=3
522.str r1, [r0, #DMC_TIMINGDATA]
523.
524.ldr r1, =DMC1_TIMING_PWR @TimingPower
525.str r1, [r0, #DMC_TIMINGPOWER]
526.
527.
528.ldr r1, =0x07000000 @DirectCmd chip0 Deselect
529.str r1, [r0, #DMC_DIRECTCMD]
530.