u-boot-2016.11移植uboot-spl.bin
2016-11-28 08:10
246 查看
一、时钟初始化 1、修改clock.h cd arch/arm/mach-s5pv210/include/mach/ vim clock.h /* add by Sourcelink */ struct s5pv210_clock { unsigned int apll_lock; unsigned char res1[0x04]; unsigned int mpll_lock; unsigned char res2[0x04]; unsigned int epll_lock; unsigned char res3[0x0c]; unsigned int vpll_lock; unsigned char res4[0xdc]; unsigned int apll_con0; unsigned int apll_con1; unsigned int mpll_con; unsigned char res5[0x04]; unsigned int epll_con0; unsigned int epll_con1; unsigned char res6[0x08]; unsigned int vpll_con; unsigned char res7[0xdc]; unsigned int clk_src0; unsigned int clk_src1; unsigned int clk_src2; unsigned int clk_src3; unsigned int clk_src4; unsigned int clk_src5; unsigned int clk_src6; unsigned char res8[0x64]; unsigned int clk_src_mask0; unsigned int clk_src_mask1; unsigned char res9[0x78]; unsigned int clk_div0; unsigned int clk_div1; unsigned int clk_div2; unsigned int clk_div3; unsigned int clk_div4; unsigned int clk_div5; unsigned int clk_div6; unsigned int clk_div7; unsigned char res10[0x24]; unsigned int clk_gate_sclk; unsigned char res11[0x18]; unsigned int clk_gate_ip0; unsigned int clk_gate_ip1; unsigned int clk_gate_ip2; unsigned int clk_gate_ip3; unsigned int clk_gate_ip4; unsigned char res12[0x0c]; unsigned int clk_gate_block; unsigned int clk_gate_ip5; }; 2、增加clock初始化函数 cd board/samsung/smdkv210/ vim smdkv210.c void clock_init(void) { u32 val = 0; struct s5pv210_clock *const clock = (struct s5pv210_clock *)samsung_get_base_clock(); /* 1.设置PLL锁定值 */ writel(0xFFFF, &clock->apll_lock); writel(0xFFFF, &clock->mpll_lock); writel(0xFFFF, &clock->epll_lock); writel(0xFFFF, &clock->vpll_lock); /* 2.设置PLL的PMS值(使用芯片手册推荐的值),并使能PLL */ /* P M S EN */ writel((3 << 8) | (125 << 16) | (1 << 0) | (1 << 31), &clock->apll_con0); /* FOUT_APLL = 1000MHz */ writel((12 << 8) | (667 << 16) | (1 << 0) | (1 << 31), &clock->mpll_con); /* FOUT_MPLL = 667MHz */ writel((3 << 8) | (48 << 16) | (2 << 0) | (1 << 31), &clock->epll_con0); /* FOUT_EPLL = 96MHz */ writel((6 << 8) | (108 << 16) | (3 << 0) | (1 << 31), &clock->vpll_con); /* FOUT_VPLL = 54MHz */ /* 3.等待PLL锁定 */ while (!(readl(&clock->apll_con0) & (1 << 29))); while (!(readl(&clock->mpll_con) & (1 << 29))); while (!(readl(&clock->apll_con0) & (1 << 29))); while (!(readl(&clock->epll_con0) & (1 << 29))); while (!(readl(&clock->vpll_con) & (1 << 29))); /* ** 4.设置系统时钟源,选择PLL为时钟输出 */ /* MOUT_MSYS = SCLKAPLL = FOUT_APLL = 1000MHz ** MOUT_DSYS = SCLKMPLL = FOUT_MPLL = 667MHz ** MOUT_PSYS = SCLKMPLL = FOUT_MPLL = 667MHz ** ONENAND = HCLK_PSYS */ writel((1 << 0) | (1 << 4) | (1 << 8) | (1 << 12), &clock->clk_src0); /* 4.设置其他模块的时钟源 */ /* 6.设置系统时钟分频值 */ val = (0 << 0) | /* APLL_RATIO = 0, freq(ARMCLK) = MOUT_MSYS / (APLL_RATIO + 1) = 1000MHz */ (4 << 4) | /* A2M_RATIO = 4, freq(A2M) = SCLKAPLL / (A2M_RATIO + 1) = 200MHz */ (4 << 8) | /* HCLK_MSYS_RATIO = 4, freq(HCLK_MSYS) = ARMCLK / (HCLK_MSYS_RATIO + 1) = 200MHz */ (1 << 12) | /* PCLK_MSYS_RATIO = 1, freq(PCLK_MSYS) = HCLK_MSYS / (PCLK_MSYS_RATIO + 1) = 100MHz */ (3 << 16) | /* HCLK_DSYS_RATIO = 3, freq(HCLK_DSYS) = MOUT_DSYS / (HCLK_DSYS_RATIO + 1) = 166MHz */ (1 << 20) | /* PCLK_DSYS_RATIO = 1, freq(PCLK_DSYS) = HCLK_DSYS / (PCLK_DSYS_RATIO + 1) = 83MHz */ (4 << 24) | /* HCLK_PSYS_RATIO = 4, freq(HCLK_PSYS) = MOUT_PSYS / (HCLK_PSYS_RATIO + 1) = 133MHz */ (1 << 28); /* PCLK_PSYS_RATIO = 1, freq(PCLK_PSYS) = HCLK_PSYS / (PCLK_PSYS_RATIO + 1) = 66MHz */ writel(val, &clock->clk_div0); /* 7.设置其他模块的时钟分频值 */ } 二、ddr初始化 1、增加dmc寄存器 cd arch/arm/mach-s5pv210/include/mach/ vim dmc.h /* add by Sourcelink */ #ifndef __ASM_ARM_ARCH_DRAM_H_ #define __ASM_ARM_ARCH_DRAM_H_ #ifndef __ASSEMBLY__ struct s5pv210_dmc0 { unsigned int concontrol; unsigned int memcontrol; unsigned int memconfig0; unsigned int memconfig1; unsigned int directcmd; unsigned int prechconfig; unsigned int phycontrol0; unsigned int phycontrol1; unsigned char res1[0x08]; unsigned int pwrdnconfig; unsigned char res2[0x04]; unsigned int timingaref; unsigned int timingrow; unsigned int timingdata; unsigned int timingpower; unsigned int phystatus; unsigned int chip0status; unsigned int chip1status; unsigned int arefstatus; unsigned int mrstatus; unsigned int phytest0; unsigned int phytest1; }; struct s5pv210_dmc1 { unsigned int concontrol; unsigned int memcontrol; unsigned int memconfig0; unsigned int memconfig1; unsigned int directcmd; unsigned int prechconfig; unsigned int phycontrol0; unsigned int phycontrol1; unsigned char res1[0x08]; unsigned int pwrdnconfig; unsigned char res2[0x04]; unsigned int timingaref; unsigned int timingrow; unsigned int timingdata; unsigned int timingpower; unsigned int phystatus; unsigned int chip0status; unsigned int chip1status; unsigned int arefstatus; unsigned int mrstatus; unsigned int phytest0; unsigned int phytest1; }; #endif #endif 2、增加ddr初始化函数 cd board/samsung/smdkv210/ vim smdkv210.c void ddr_init(void) { struct s5pv210_dmc0 *const dmc0 = (struct s5pv210_dmc0 *)samsung_get_base_dmc0(); struct s5pv210_dmc1 *const dmc1 = (struct s5pv210_dmc1 *)samsung_get_base_dmc1(); /* DMC0 */ writel(0x00101000, &dmc0->phycontrol0); writel(0x00101002, &dmc0->phycontrol0); /* DLL on */ writel(0x00000086, &dmc0->phycontrol1); writel(0x00101003, &dmc0->phycontrol0); /* DLL start */ while ((readl(&dmc0->phystatus) & 0x7) != 0x7); /* wait DLL locked */ writel(0x0FFF2350, &dmc0->concontrol); /* Auto Refresh Counter should be off */ writel(0x00202430, &dmc0->memcontrol); /* Dynamic power down should be off */ writel(0x20E01323, &dmc0->memconfig0); writel(0xFF000000, &dmc0->prechconfig); writel(0xFFFF00FF, &dmc0->pwrdnconfig); writel(0x00000618, &dmc0->timingaref); /* 7.8us * 200MHz = 1560 = 0x618 */ writel(0x19233309, &dmc0->timingrow); writel(0x23240204, &dmc0->timingdata); writel(0x09C80232, &dmc0->timingpower); writel(0x07000000, &dmc0->directcmd); /* NOP */ writel(0x01000000, &dmc0->directcmd); /* PALL */ writel(0x00020000, &dmc0->directcmd); /* EMRS2 */ writel(0x00030000, &dmc0->directcmd); /* EMRS3 */ writel(0x00010400, &dmc0->directcmd); /* EMRS enable DLL */ writel(0x00000542, &dmc0->directcmd); /* DLL reset */ writel(0x01000000, &dmc0->directcmd); /* PALL */ writel(0x05000000, &dmc0->directcmd); /* auto refresh */ writel(0x05000000, &dmc0->directcmd); /* auto refresh */ writel(0x00000442, &dmc0->directcmd); /* DLL unreset */ writel(0x00010780, &dmc0->directcmd); /* OCD default */ writel(0x00010400, &dmc0->directcmd); /* OCD exit */ writel(0x0FF02030, &dmc0->concontrol); /* auto refresh on */ writel(0xFFFF00FF, &dmc0->pwrdnconfig); writel(0x00202400, &dmc0->memcontrol); /* DMC1 */ writel(0x00101000, &dmc1->phycontrol0); writel(0x00101002, &dmc1->phycontrol0); /* DLL on */ writel(0x00000086, &dmc1->phycontrol1); writel(0x00101003, &dmc1->phycontrol0); /* DLL start */ while ((readl(&dmc1->phystatus) & 0x7) != 0x7); /* wait DLL locked */ writel(0x0FFF2350, &dmc1->concontrol); /* Auto Refresh Counter should be off */ writel(0x00202430, &dmc1->memcontrol); /* Dynamic power down should be off */ writel(0x40E01323, &dmc1->memconfig0); writel(0xFF000000, &dmc1->prechconfig); writel(0xFFFF00FF, &dmc1->pwrdnconfig); writel(0x00000618, &dmc1->timingaref); /* 7.8us * 200MHz = 1560 = 0x618 */ writel(0x19233309, &dmc1->timingrow); writel(0x23240204, &dmc1->timingdata); writel(0x09C80232, &dmc1->timingpower); writel(0x07000000, &dmc1->directcmd); /* NOP */ writel(0x01000000, &dmc1->directcmd); /* PALL */ writel(0x00020000, &dmc1->directcmd); /* EMRS2 */ writel(0x00030000, &dmc1->directcmd); /* EMRS3 */ writel(0x00010400, &dmc1->directcmd); /* EMRS enable DLL */ writel(0x00000542, &dmc1->directcmd); /* DLL reset */ writel(0x01000000, &dmc1->directcmd); /* PALL */ writel(0x05000000, &dmc1->directcmd); /* auto refresh */ writel(0x05000000, &dmc1->directcmd); /* auto refresh */ writel(0x00000442, &dmc1->directcmd); /* DLL unreset */ writel(0x00010780, &dmc1->directcmd); /* OCD default */ writel(0x00010400, &dmc1->directcmd); /* OCD exit */ writel(0x0FF02030, &dmc1->concontrol); /* auto refresh on */ writel(0xFFFF00FF, &dmc1->pwrdnconfig); writel(0x00202400, &dmc1->memcontrol); } 三、初始化sd卡copy函数 void copy_bl2_to_ram(void) { /* ** ch: 通道 ** sb: 起始块 ** bs: 块大小 ** dst: 目的地 ** i: 是否初始化 */ #iefine CopySDMMCtoMem(ch, sb, bs, dst, i) \ (((unsigned char(*)(int, unsigned int, unsigned short, unsigned int*, unsigned char))\ (*((unsigned int *)0xD0037F98)))(ch, sb, bs, dst, i)) unsigned int V210_SDMMC_BASE = *(volatile unsigned int *)(0xD0037488); // V210_SDMMC_BASE unsigned char ch = 0; /* 参考S5PV210手册7.9.1 SD/MMC REGISTER MAP */ if (V210_SDMMC_BASE == 0xEB000000) // 通道0 ch = 0; else if (V210_SDMMC_BASE == 0xEB200000) // 通道2 ch = 2; CopySDMMCtoMem(ch, 32, 10, (unsigned int *)CONFIG_SYS_SDRAM_BASE, 0); } 四、更改base地址 在进行clock初始化和ddr初始化时用到了.h中的寄存器地址 struct s5pv210_clock *const clock = (struct s5pv210_clock *)samsung_get_base_clock(); 定义了这个结构体变量 需要修改cpu.h cd arch/arm/mach-s5pv210/include/mach/ vim cpu.h /* add by Sourcelink */ IS_SAMSUNG_TYPE(s5pv210, 0x56210) /* modif by Sourcelink */ #define SAMSUNG_BASE(device, base) \ static inline unsigned int samsung_get_base_##device(void) \ { \ if(cpu_is_s5pv210()) \ return S5PV210_##base; \ else if(cpu_is_s5pc100()) \ return S5PC100_##base; \ } 一开始这么写发现执行都是S5PC100的寄存器基地址,现在还没有发现原因。s5pv210的id函数在上一节有贴出来。希望知道的朋友告知。最后改成了如下: /* modif by Sourcelink */ #define SAMSUNG_BASE(device, base) \ static inline unsigned int samsung_get_base_##device(void) \ { \ return S5PV210_##base; \ } /* add by Sourcelink */ SAMSUNG_BASE(dmc0,DMC0_BASE) SAMSUNG_BASE(dmc1,DMC1_BASE) 五、添加宏CONFIG_SPL 编译 u-boot-spl.bin 时,spl/Makefile 会导出一个宏 CONFIG_SPL_BUILD,我们通过这个宏来控制代码是否被编译,下面列出修改后的框架 #ifdef CONFIG_SPL_BUILD 六、硬件初始化 cd board/samsung/smdkv210/ vim lowlevel_init.S /* modif by Sourcelink */ .globl lowlevel_init lowlevel_init: mov r9, lr #ifdef CONFIG_SPL_BUILD bl clock_init /* 时钟初始化 */ bl ddr_init /* DDR初始化 */ #endif mov pc, r9 /* 返回 */ 七、修改_main函数 cd arch/arm/lib vim crt0.S ENTRY(_main) /* * Set up initial C runtime environment and call board_init_f(0). */ /* modied by Sourcelink */ #if !defined(CONFIG_SPL_BUILD) ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ sub sp, sp, #GD_SIZE /* allocate one GD above SP */ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ mov r9, sp /* GD is above SP */ mov r0, #0 #endif /* modied by Sourcelink */ #ifdef CONFIG_SPL_BUILD bl copy_bl2_to_ram /* 拷贝BL2到DDR */ ldr pc, =CONFIG_SYS_SDRAM_BASE /* 跳转到DDR的起始地址执行BL2 */ #else bl board_init_f #endif 八、修改ddr基地址 vim include/configs/smdkv210.h /* DRAM Base */ #define CONFIG_SYS_SDRAM_BASE 0x20000000 /* modif by Sourcelink */ /* Text Base */ #define CONFIG_SYS_TEXT_BASE 0x20000000 九、增加宏 vim configs/smdkv210_defconfig # add by Sourcelink CONFIG_SPL=y 十、添加增加头信息的可执行文件 在做完前面九步后进行编译会提示mkexynosspl:Command not find 这是个可执行文件是在make时自动增加头信息用的 分析scripts/Makefile.spl vim scripts/Makefile.spl # modif by Sourcelink $(obj)/$(BOARD)-spl.bin: $(obj)/u-boot-spl.bin $(if $(wildcard $(objtree)/spl/board/samsung/$(BOARD)/tools/mk$(BOARD)spl),\ $(objtree)/spl/board/samsung/$(BOARD)/tools/mk$(BOARD)spl,\ $(objtree)/tools/mksource210spl) $(VAR_SIZE_PARAM) $< $@ endif 把自己编译好的可执行文件Source210 更改成mksource210spl 放到tools目录下 十一、编译和烧写 make smdkv210_defconfig make spl/u-boot-spl.bin 编译完成后把spl目录下的smdkv210-spl.bin 烧写到sd卡扇区1,再烧写一个其他可运行bin文件到sd卡扇区32
相关文章推荐
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——移植u-boot-spl.bin(时钟初始化)
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——移植u-boot-spl.bin(内存初始化)
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——移植u-boot-spl.bin(核心初始化)
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——移植u-boot-spl.bin(点亮led灯)
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——移植u-boot-spl.bin(内存初始化)
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——移植u-boot-spl.bin(点亮led灯)
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——移植u-boot-spl.bin(核心初始化)
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——移植u-boot-spl.bin(时钟初始化)
- u-boot-2016.09移植(8)-合并tq210-spl.bin与u-boot.bin
- u-boot-2016.11移植u-boot.bin
- u-boot-2016.09移植(3)-u-boot-spl.bin
- JZ2440平台移植uboot 2016.11(二)
- JZ2440平台移植uboot 2016.11(四)
- S3C2440移植 u-boot-2016.11
- JZ2440平台移植uboot 2016.11(十)
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本号)——移植u-boot.bin(打印串口控制台)
- u-boot-2015.04 在tq2440上的移植(使用spl引导u-boot)
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——SPL
- S3C2440移植 u-boot-2016.11
- U-boot移植步骤详解_附:bin文件和所需文件(代码+流程图+遇到的错误及解决办法)