Chinaunix首页 | 论坛 | 博客
  • 博客访问: 344907
  • 博文数量: 92
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 960
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-21 19:38
文章分类

全部博文(92)

文章存档

2010年(71)

2009年(21)

我的朋友

分类: 嵌入式

2010-04-06 11:49:56

U-boot 移植--NOR

http://blog.sina.com.cn/s/blog_446b43c10100cn5c.html

http://xgc94418297.blog.163.com/blog/static/112966040200952971543686/(同时支持了24102440

http://blog.mcuol.com/User/stoneboy/Article/35436_1.htm  (支持nand flash u-boot

 2410启动代码分析)

 

修改顶层Makefile

解压U-BOOT-1.1.6,进入U-BOOT目录,修改Makefile

smdk2410_config :       unconfig
        @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

加上

TX2440_config :    unconfig
        @$(MKCONFIG) $(@:_config=) arm arm920t TX2440 NULL s3c24x0

各项的意思如下:
arm: CPU
的架构
(ARCH)
arm920t: CPU
的类型(CPU),其对应于cpu/arm920t子目录。

TX2440:
开发板的型号(BOARD),对应于board/TX2440目录。
NULL:
开发者/或经销商(vender)
s3c24x0:
片上系统(SOC)

 

在第128行:

ifeq ($(ARCH),arm)

CROSS_COMPILE = arm-linux-

指定交叉编译器,我使用的是3.4.1,这里也可以写绝对路径

 

修改完Makefile后,在board目录下,新建自己的开发板目录TX2440,把smdk2410目录下的所有文件拷到TX2440,把smdk2410.c改为TX2440.c。修改该目录下的Makefile,把smdk2410.o改为TX2410.o

COBJS    := TX2440.o flash.o

 

board目录下所有文件夹全部删除,只留TX2440

 

创建修改 include/configs/TX2440.h

include/configs目录下创建板子的配置头文件,把smdk2410.h改名为TX2440.h 

测试能否编译成功:

执行make TX2440_config

成功后可出现 Configuring for TX2440 board.....

 

修改 board/TX2440/lowlevel_init.S  (这里我参考了TX2440开发板自带S3C2410_BIOS)

修改SDRAM配置,在board/TX2440/lowlevel_init.S中,检查

#define B6_BWSCON          (DW32) 位宽为32

B1_BWSCON 改为(DW16  B5_BWSCON 改为(DW8

 

根据HCLK设置SDRAM 的刷新参数,主要是REFCNT寄存器,开发板HCLK100M

 #define REFCNT    0x1113  改为  #define REFCNT  0x4f4

 

 

修改board/TX2440/TX2440.c

1. 增加对S3C2440的支持,2440的时钟计算公式、NAND操作和2410不太一样。

对于2440开发板,将FCLK设为400MHz,分频比为FCLKHCLKPCLK=148

2. GPIO的设置要具体板子具体分析

 

2410中:

PLL Control Register (MPLLCON and UPLLCON)

Mpll = (m * Fin) / (p * 2s)

m = (MDIV + 8), p = (PDIV + 2), s = SDIV

 

2440中:

Mpll = (2*m * Fin) / (p * 2^s)

 m = (MDIV + 8), p = (PDIV + 2), s = SDIV

 

 

修改board/TX2440/TX2440.c中的board_init函数

/* S3C2440: Mpll,Upll = (2*m * Fin) / (p * 2^s)

 * m = M (the value for divider M)+ 8, p = P (the value for divider P) + 2

 */

#define S3C2440_MPLL_400MHZ     ((0x7f<<12)|(0x02<<4)|(0x01))

#define S3C2440_UPLL_48MHZ      ((0x38<<12)|(0x02<<4)|(0x02))

#define S3C2440_CLKDIV          0x05    /* FCLK:HCLK:PCLK = 1:4:8 */

 

/* S3C2410: Mpll,Upll = (m * Fin) / (p * 2^s)

 * m = M (the value for divider M)+ 8, p = P (the value for divider P) + 2

 */

#define S3C2410_MPLL_200MHZ     ((0x5c<<12)|(0x04<<4)|(0x00))

#define S3C2410_UPLL_48MHZ      ((0x28<<12)|(0x01<<4)|(0x02))

#define S3C2410_CLKDIV          0x03    /* FCLK:HCLK:PCLK = 1:2:4 */

 

int board_init (void)

{

       S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();

       S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

 

       /* set up the I/O ports */

       gpio->GPACON = 0x007FFFFF;

       gpio->GPBCON = 0x00044555;

       gpio->GPBUP = 0x000007FF;

       gpio->GPCCON = 0xAAAAAAAA;

       gpio->GPCUP = 0x0000FFFF;

       gpio->GPDCON = 0xAAAAAAAA;

       gpio->GPDUP = 0x0000FFFF;

       gpio->GPECON = 0xAAAAAAAA;

       gpio->GPEUP = 0x0000FFFF;

       gpio->GPFCON = 0x000055AA;

       gpio->GPFUP = 0x000000FF;

       gpio->GPGCON = 0xFF95FFBA;

       gpio->GPGUP = 0x0000FFFF;

       gpio->GPHCON = 0x002AFAAA;

       gpio->GPHUP = 0x000007FF;

      

       /*support both of S3C2410 and S3C2440*/

       if ((gpio->GSTATUS1 == 0x32410000) || (gpio->GSTATUS1 == 0x32410002))

       {

              /*FCLK:HCLK:PCLK = 1:2:4*/

              clk_power->CLKDIVN = S3C2410_CLKDIV;

             

              /* change to asynchronous bus mod */

        __asm__(    "mrc    p15, 0, r1, c1, c0, 0\n"    /* read ctrl register   */ 

                    "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */ 

                    "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */ 

                    :::"r1"

                    );

                                  

        /* to reduce PLL lock time, adjust the LOCKTIME register */

        clk_power->LOCKTIME = 0xFFFFFF;

 

        /* configure MPLL */

        clk_power->MPLLCON = S3C2410_MPLL_200MHZ;

 

        /* some delay between MPLL and UPLL */

        delay (4000);

 

        /* configure UPLL */

        clk_power->UPLLCON = S3C2410_UPLL_48MHZ;

 

        /* some delay between MPLL and UPLL */

        delay (8000);

       

        /* arch number of SMDK2410-Board */

        gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

       }

       else

       {

              /* FCLK:HCLK:PCLK = 1:4:8 */

        clk_power->CLKDIVN = S3C2440_CLKDIV;

 

        /* change to asynchronous bus mod */

        __asm__(    "mrc    p15, 0, r1, c1, c0, 0\n"    /* read ctrl register   */ 

                    "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */ 

                    "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */ 

                    :::"r1"

                    );

 

        /* to reduce PLL lock time, adjust the LOCKTIME register */

        clk_power->LOCKTIME = 0xFFFFFF;

 

        /* configure MPLL */

        clk_power->MPLLCON = S3C2440_MPLL_400MHZ;

 

        /* some delay between MPLL and UPLL */

        delay (4000);

 

        /* configure UPLL */

        clk_power->UPLLCON = S3C2440_UPLL_48MHZ;

 

        /* some delay between MPLL and UPLL */

        delay (8000);

       

        /* arch number of SMDK2440-Board */

        gd->bd->bi_arch_number = MACH_TYPE_S3C2440;

       }

 

       /* adress of boot parameters */

       gd->bd->bi_boot_params = 0x30000100;

 

       icache_enable();

       dcache_enable();

 

       return 0;

}

 

修改cpu/arm920t/s3c24X0/speed.c

在程序开头增加一行DECLARE_GLOBAL_DATA_PTR;,这样才可以使用gd变量

修改get_PLLCLK函数:

static ulong get_PLLCLK(int pllreg)

{

    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();

    ulong r, m, p, s;

 

    if (pllreg == MPLL)

       r = clk_power->MPLLCON;

    else if (pllreg == UPLL)

       r = clk_power->UPLLCON;

    else

       hang();

 

    m = ((r & 0xFF000) >> 12) + 8;

    p = ((r & 0x003F0) >> 4) + 2;

    s = r & 0x3;

 

    /* support both of S3C2410 and S3C2440 */

    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)

              return((CONFIG_SYS_CLK_FREQ * m) / (p << s));

    else

        return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));   /* S3C2440 */

}

 

修改get_HCLK, get_PCLK:

/* for s3c2440 */

#define S3C2440_CLKDIVN_PDIVN        (1<<0)

#define S3C2440_CLKDIVN_HDIVN_MASK   (3<<1)

#define S3C2440_CLKDIVN_HDIVN_1      (0<<1)

#define S3C2440_CLKDIVN_HDIVN_2      (1<<1)

#define S3C2440_CLKDIVN_HDIVN_4_8    (2<<1)

#define S3C2440_CLKDIVN_HDIVN_3_6    (3<<1)

#define S3C2440_CLKDIVN_UCLK         (1<<3)

 

#define S3C2440_CAMDIVN_CAMCLK_MASK  (0xf<<0)

#define S3C2440_CAMDIVN_CAMCLK_SEL   (1<<4)

#define S3C2440_CAMDIVN_HCLK3_HALF   (1<<8)

#define S3C2440_CAMDIVN_HCLK4_HALF   (1<<9)

#define S3C2440_CAMDIVN_DVSEN        (1<<12)

 

/* return HCLK frequency */

ulong get_HCLK(void)

{

    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();

    unsigned long clkdiv;

    unsigned long camdiv;

    int hdiv = 1;

 

    /* support both of S3C2410 and S3C2440 */

    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)

    return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());

    else

    {

        clkdiv = clk_power->CLKDIVN;

        camdiv = clk_power->CAMDIVN;

 

        /* work out clock scalings */

 

        switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {

        case S3C2440_CLKDIVN_HDIVN_1:

            hdiv = 1;

            break;

 

        case S3C2440_CLKDIVN_HDIVN_2:

            hdiv = 2;

            break;

 

        case S3C2440_CLKDIVN_HDIVN_4_8:

            hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;

            break;

 

        case S3C2440_CLKDIVN_HDIVN_3_6:

            hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;

            break;

        }

 

        return get_FCLK() / hdiv;

    }

}

 

/* return PCLK frequency */

ulong get_PCLK(void)

{

    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();

    unsigned long clkdiv;

    unsigned long camdiv;

    int hdiv = 1;

 

    /* support both of S3C2410 and S3C2440 */

    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)

    return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());

    else

    {  

        clkdiv = clk_power->CLKDIVN;

        camdiv = clk_power->CAMDIVN;

 

        /* work out clock scalings */

 

        switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {

        case S3C2440_CLKDIVN_HDIVN_1:

            hdiv = 1;

            break;

 

        case S3C2440_CLKDIVN_HDIVN_2:

            hdiv = 2;

            break;

 

        case S3C2440_CLKDIVN_HDIVN_4_8:

            hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;

            break;

 

        case S3C2440_CLKDIVN_HDIVN_3_6:

            hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;

            break;

        }

 

        return get_FCLK() / hdiv / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);

    }       

}

 

重新执行make TX2440_config    make all 生成u-boot.bin,由于还没有增加NAND Flash的支持,所以可烧入NOR Flash中运行

make all时会出现错误:没有CAMDIVN

这个要在include/s3c24x0.h中定义, 129S3C24X0_CLOCK_POWER结构体中增加:S3C24X0_REG32     CAMDIVN;    /* for s3c2440*/

 

H-FLASHER烧入板中,重启一下,在SecureCRT中看到:

U-Boot 1.1.6 (Apr  6 2010 - 11:04:15)

 

DRAM:  64 MB

Flash: 512 kB

*** Warning - bad CRC, using default environment

 

In:    serial

Out:   serial

Err:   serial

SMDK2410 #     (这个符号可以在 include/configs/TX2440.h  #define CFG_PROMPT 修改)

 

阅读(909) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~