FL2440开发板的U-boot-2010.09版本移植(二)片上系统SoC初始化移植

时间:2021-07-29 17:11:53

--------------------------------------------------------

在“<2012 10 02> FL2440开发板的U-boot-2010.09版本移植(一)”的文章里,只是初步建立了一块开发板(With S3C2440 SoC)的U-boot框架,并且能够被gcc编译成功。但现在这个框架还不能下载到开发板上运行,因为还需要修改一些SoC最必须的参数,它们包括:寄存器地址、中断、CPU频率&PLL、RAM控制器、一些头文件包含、以及底层串口信息打印输出。

经过本文的修改,U-boot就能在FL2440开发板上运行了。具体下载到开发板的方法还需要有Jlink的支持(Notebook Without 并口)。

--------------------------------------------------------

添加fl2440中S3C2440片上系统的支持。

一、汇编文件修改,这部分主要集中修改修改cpu/arm920t/start.S文件。

1、删除AT91RM9200使用的LED代码,117、118行,关闭LED代码。

[cpp]  view plain copy
  1. // bl coloured_LED_init  
  2. // bl red_LED_on  


2、修改编译条件支持s3c2440,修改寄存器地址定义,修改 CPU频率初始化设置

[plain]  view plain copy
  1. # if defined(CONFIG_S3C2400)  
  2. #  define pWTCON    0x15300000  
  3. #  define INTMSK    0x14400008  /* Interupt-Controller base addresses */  
  4. #  define CLKDIVN   0x14800014  /* clock divisor register */  
  5. #else  
  6. #  define pWTCON    0x53000000  
  7. #  define INTMSK    0x4A000008  /* Interupt-Controller base addresses */  
  8. #  define INTSUBMSK 0x4A00001C  
  9. #  define CLKDIVN   0x4C000014  /* clock divisor register */  
  10. # endif  
  11. 添加  
  12. #  define CLK_CTL_BASE  0x4C000000  
  13. #  define MDIV_405      0x7f<<12          
  14. #  define PSDIV_405     0x21            /*set s3c2440 MPLL 405MHZ*/  
  15. #  define MDIV_200      0xa1<<12  
  16. #  define PSDIV_200     0x31            /*set s3c2410 MPLL 200MHZ*/   

3、修改中断禁止部分

[plain]  view plain copy
  1. # if defined(CONFIG_S3C2410)  
  2.  //ldr r1, =0x3ff  
  3.  ldr r1, =0x7ff  /*uboot error*/  
  4.  ldr r0, =INTSUBMSK  
  5.  str r1, [r0]  
  6. # endif  
  7. 后添加  
  8. #if defined(CONFIG_S3C2440)  
  9.         ldr     r1, =0x7ff  
  10.         ldr     r0, =INTSUBMSK  
  11.         str     r1, [r0]  
  12.         /*INTSUBMSK 关闭中断 S3C2440有15位*/  
  13. # endif  

★★★★★★Important★★★★★★

yanghao提供的代码中        ldr     r1, =0x7ff   写成了        ldr     r1, =0x7fff

需要更正! 

★★★★★★Important★★★★★★


4、修改时钟设置(2440的主频为405MHz),紧接着上面一步,在其后添加和修改为:

[cpp]  view plain copy
  1. #if defined(CONFIG_S3C2440)  
  2.         /* FCLK:HCLK:PCLK = 1:4:8 */  
  3.         /* default FCLK is 405 MHz ! */  
  4.         ldr r0, =CLKDIVN  
  5.         mov r1, #5  
  6.         str r1, [r0]  
  7.   
  8.         mrc     p15, 0, r1, c1, c0, 0  
  9.         orr     r1, r1, #0xc0000000 //asynchronous  
  10.         mcr     p15, 0, r1, c1, c0, 0  
  11.         /*上面这段代码见s3c2440a手册p215,HDIVN != 0 叫做异步总线模式*/  
  12.   
  13.         /* cpu clock FCLK = 405MHZ 通常我们叫400MHZ,实际是405MHZ,见S3C2440手册(英文版)chapt7,P227要习惯用英文手册:-)*/  
  14.         /*根据表中的数据设置MDIV,PDIV,SDIV*/  
  15.         mov     r1, #CLK_CTL_BASE  
  16.         mov     r2, #MDIV_405  
  17.         add     r2, r2, #PSDIV_405  
  18.         str     r2, [r1, #0x04] //写入MPLLCON  
  19.      
  20. #else  
  21.     /* FCLK:HCLK:PCLK = 1:2:4 */  
  22.     /* default FCLK is 120 MHz ! */  
  23.         ldr r0, =CLKDIVN  
  24.         mov r1, #3  
  25.         str r1, [r0]  
  26.         mrc     p15, 0, r1, c1, c0, 0  
  27.         orr     r1, r1, #0xc0000000 //asynchronous  
  28.         mcr     p15, 0, r1, c1, c0, 0  
  29.      
  30.         /* cpu clock is 200MHZ*/  
  31.         mov     r1, #CLK_CTL_BASE  
  32.         mov     r2, #MDIV_200  
  33.         add     r2, r2, #PSDIV_200  
  34.         str     r2, [r1, #0x04] //MPLLCON  
  35. #endif  

5、修改SDRAM的REFRESH刷新周期,修改board/fl2440/lowlevel_init.S文件

[cpp]  view plain copy
  1. #define REFCNT   1259  
  2. /*在SDRAM手册上P3上有64ms refresh period (8K Cycle)*/  
  3. /*结合fl2440开发板 preiod =64ms/8129=7.8125us,取7.9的话REFCNT的值为 (2048+1-7.9us*100Mhz)=1259*/  
  4.   
  5.   
  6.   
  7. #define Trp   0x0 /* 2clk */  
  8. /*RAS precharge Time SDRAM数据手册P10 tRP(min)=20ns 或者18ns(由型号决定)我们知道我们的HCLK=405/4Mhz 故可设成2clk(20ns),有些移植手册设为4clk 再次充电时间设大点问题也不大吧 */  
  9.   
  10. #define Trc   0x3 /* 7clk */  
  11. /*SDRAM ROW cycle time: Trc=Tsrc+Trp SDRAM数据手册p10 tRC(min)=65ns 或者60ns(由型号决定) 设为7即为70ns */  
  12.   
  13.   
  14. #define Tchr   0x2 /* 3clk */  
  15. /*为找到Tchr相关定义,在SMRDATA:后面设置REFRESH寄存器时(Tchr<<16),而实际上该寄存器(11~17)位为保留位,这里设置并没有意义(可能这个值在其他ARM体系中有用吧,但至少在S3C2440中是无效的)*/  


二、补充对S3C2440的支持。

6、修改S3C2440在C语言中要使用的寄存器,修改include/asm/arch-s3c24x0/s3c24x0.h文件的第81、91、95、106、144、400行:
将“#ifdef CONFIG_S3C2410”改为 #if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
顺便在其中加入S3C2440的NAND FLASH 寄存器定义(第154行附近)和CAMDIVN定义(第124行附近):

[cpp]  view plain copy
  1.  /* CLOCK & POWER MANAGEMENT (see S3C2400 manual chapter 6) */  
  2. /*                          (see S3C2410 manual chapter 7) */  
  3. struct s3c24x0_clock_power {  
  4.        u32  LOCKTIME;  
  5.        u32  MPLLCON;  
  6.        u32  UPLLCON;  
  7.        u32  CLKCON;  
  8.        u32  CLKSLOW;  
  9.        u32  CLKDIVN;  
  10. #if defined (CONFIG_S3C2440)  
  11.        u32  CAMDIVN;  
  12. #endif  
  13. };  
  14.   
  15. #if defined(CONFIG_S3C2410)  
  16. /* NAND FLASH (see S3C2410 manual chapter 6) */  
  17. struct s3c2410_nand {  
  18.  u32 NFCONF;  
  19.  u32 NFCMD;  
  20.  u32 NFADDR;  
  21.  u32 NFDATA;  
  22.  u32 NFSTAT;  
  23.  u32 NFECC;  
  24. };  
  25. #endif  
  26.   
  27. #if defined(CONFIG_S3C2440)  
  28. /* NAND FLASH (see S3C2440 manual chapter 6) */  
  29. struct s3c2410_nand {  
  30.  u32  NFCONF;  
  31.         u32  NFCONT;  
  32.         u32  NFCMD;  
  33.         u32  NFADDR;  
  34.         u32  NFDATA;  
  35.         u32  NFMECCD0;  
  36.         u32  NFMECCD1;  
  37.         u32  NFSECCD;  
  38.         u32  NFSTAT;  
  39.         u32  NFESTAT0;  
  40.         u32  NFESTAT1;  
  41.         u32  NFMECC0;  
  42.         u32  NFMECC1;  
  43.         u32  NFSECC;  
  44.         u32  NFSBLK;  
  45.         u32  NFEBLK;  
  46. };  
  47. #endif  

 

7、include/asm/arch/s3c24x0_cpu.h,这个文件使添加对2440的支持的头文件的工作量少了很多。文件的第23行
#if defined(CONFIG_S3C2400)
    #include <s3c2400.h>
  #elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
  #include <s3c2410.h>

8、arch/arm/cpu/arm920t/s3c24x0/timer.c文件的在184行添加     
  defined(CONFIG_VCMA9)    || \
      defined(CONFIG_FL2440)

9、arch/arm/cpu/arm920t/s3c24x0/speed.c
由于S3C2410和S3C2440的MPLL、UPLL计算公式不一样,所以get_PLLCLK函数也需要修改,在66行添加

[cpp]  view plain copy
  1. #if defined(CONFIG_S3C2440)  
  2.         if(pllreg == MPLL)  
  3.         return (CONFIG_SYS_CLK_FREQ * m * 2) / (p << s);  
  4.         else if(pllreg == UPLL)  
  5. #endif  
  6.  return (CONFIG_SYS_CLK_FREQ * m) / (p << s);  


由于S3C2410和S3C2440的设置方法也不一样,所以get_HCLK函数也需要修改,80行/* return HCLK frequency */

[cpp]  view plain copy
  1. ulong get_HCLK(void)  
  2. {  
  3.  struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();  
  4.    
  5. #if defined(CONFIG_S3C2440)  
  6.         if (readl(&clk_power->CLKDIVN) & 0x6)  
  7.           {  
  8.            if ((readl(&clk_power->CLKDIVN) & 0x6)==2) return(get_FCLK()/2);  
  9.                 if ((readl(&clk_power->CLKDIVN) & 0x6)==6) return((readl(&clk_power->CAMDIVN) & 0x100) ? get_FCLK()/6 : get_FCLK()/3);  
  10.                       if ((readl(&clk_power->CLKDIVN) & 0x6)==4) return((readl(&clk_power->CAMDIVN) & 0x200) ? get_FCLK()/8 : get_FCLK()/4);  
  11.                        return(get_FCLK());  
  12.             }  
  13.   
  14.           else return(get_FCLK());  
  15. #else  
  16.          return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK();  
  17. #endif  
  18. }  


10、修改drivers/i2c/s3c24x0_i2c.c文件,其原来的位置/cpu/arm920t/s3c24x0/i2c.c

第60、79、131、140、166行:
将“#ifdef CONFIG_S3C2410”改为 #if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

11、串口相关修改,修改common/serial.c文件,71行将#elif defined(CONFIG_S3C2410) 改为#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440),160行    改为#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

修改include/serial.h 在49行添加
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

12、修改include/configs/fl2440.h文件中第38行,39行的

[cpp]  view plain copy
  1. #define CONFIG_S3C2410 1 /* specifically a SAMSUNG S3C2410 SoC */  
  2. #define CONFIG_SMDK2410 1 /* on a SAMSUNG SMDK2410 Board  */  
  3.   
  4. 为  
  5.   
  6. #define CONFIG_S3C2440 1 /* specifically a SAMSUNG S3C2440 SoC */  
  7. #define CONFIG_FL2440 1 /* on a SAMSUNG FL2440 Board  */  


然后我们再执行make,这时可以成功编译出来的u-boot.bin。

------------------------------------------------

如果跳过U-boot第一阶段的初始化,直接进行高层功能(这在裸板烧写Bootloader时会用到):

如果我们在include/configs/fl2440.h文件中添加

#define  CONFIG_SKIP_LOWLEVEL_INIT     1 //用来支持uboot在内存中直接运行

然后再编译出u-boot.bin,这时的镜像文件就可以通过J-Link下载到内存0x33f80000处运行。

  不懂U-boot基本架构的,移步 http://www.cnblogs.com/andrew-wang/archive/2012/11/04/2753972.html

  不懂裸板烧写bootloader的,移步 http://www.cnblogs.com/andrew-wang/archive/2012/12/03/2799237.html

本文source http://blog.csdn.net/yanghao23/article/details/7688019