Chinaunix首页 | 论坛 | 博客
  • 博客访问: 79495
  • 博文数量: 11
  • 博客积分: 1401
  • 博客等级: 上尉
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-12 16:16
文章分类
文章存档

2011年(1)

2009年(10)

我的朋友

分类: LINUX

2009-05-21 02:32:18


1.2.7 Nand Flash 驱动


 

首先要说明一下 CFG_NAND_LEGACY 的使用。在u-boot drivers/mtd/下有两个目录,分别是nandnand_legacy。在nand目录下的是nand的初始化函数和nand的操作读写函数,是使用linuxmtd构架。此目录下的文件,只有在定义了CFG_CMD_NAND宏和没有定义CFG_NAND_LEGACY宏的情况下才会被编译。在nand_leagcy目录下的文件也是是实现nand相关操作命令,如read,write等命令的功能,但不是使用linuxmtd构架。此目录下的文件,只有在定义了CFG_CMD_NAND和定义了CFG_NAND_LEGACY宏的情况下才会定义。此目录下的文件u-boot已不推荐使用。在本移植过程中采用不定义CFG_NAND_LEGACY的方式。

(1)修改/cpu/arm920t/s3c24x0/nand.c

先加入S3C2440 NAND flash控制器的地址定义,修改后如下:

#define __REGb(x)      (*(volatile unsigned char *)(x))

#define __REGi(x)      (*(volatile unsigned int *)(x))

 

#if defined(CONFIG_S3C2410)

 

 #define       NF_BASE        0x4e000000

 #define       NFCONF         __REGi(NF_BASE + 0x0)

 #define       NFCMD          __REGb(NF_BASE + 0x4)

 ……

 

 #define NFECC0        __REGb(NF_BASE + 0x14)

 #define NFECC1        __REGb(NF_BASE + 0x15)

 #define NFECC2        __REGb(NF_BASE + 0x16)

#else

 

#if defined(CONFIG_S3C2440)

 

#define NF_BASE        0x4e000000

#define NFCONF         __REGi(NF_BASE + 0x0)

#define NFCONT         __REGi(NF_BASE + 0x4)

#define NFCMD          __REGb(NF_BASE + 0x8)

#define NFADDR         __REGb(NF_BASE + 0xc)

#define NFDATA         __REGb(NF_BASE + 0x10)

#define NFMECCD0       __REGi(NF_BASE + 0x14)

#define NFMECCD1       __REGi(NF_BASE + 0x18)

#define NFSECCD         __REGi(NF_BASE + 0x1C)

#define NFSTAT         __REGb(NF_BASE + 0x20)

#define NFSTAT0        __REGi(NF_BASE + 0x24)

#define NFSTAT1        __REGi(NF_BASE + 0x28)

#define NFMECC0        __REGi(NF_BASE + 0x2C)

#define NFMECC1        __REGi(NF_BASE + 0x30)

#define NFSECC         __REGi(NF_BASE + 0x34)

#define NFSBLK         __REGi(NF_BASE + 0x38)

#define NFEBLK         __REGi(NF_BASE + 0x3c)

 

#define S3C2440_NFCONT_nCE     (1<<1)

#define S3C2440_ADDR_NALE 0x0c

#define S3C2440_ADDR_NCLE 0x08

 

#endif

#endif

#define S3C2410_NFCONF_EN          (1<<15)
#define S3C2410_NFCONF_512BYTE     (1<<14)


u-boot.2008.10自带的S3C2410s3c2410_hwcontrol函数有错在此函数中,把chip->IO_ADDR_W值改写了,导致在写数据时出现错误。解决方法是使用一全局变量代替 chip->IO_ADDR_W。在 s3c2410_hwcontrol 函数上一行定义这个全局变量,然后修改 s3c2410_hwcontrol 函数,让它支持 S3C2440,修改后如下:

 

#define S3C2410_ADDR_NCLE 8

 

ulong IO_ADDR_W = NF_BASE;

 static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)

 {

        struct nand_chip *chip = mtd->priv;

 

        DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);

 

#if defined(CONFIG_S3C2410)

        if (ctrl & NAND_CTRL_CHANGE) {

                //ulong IO_ADDR_W = NF_BASE;

               IO_ADDR_W = NF_BASE;

               if (!(ctrl & NAND_CLE))

                       IO_ADDR_W |= S3C2410_ADDR_NCLE;

               if (!(ctrl & NAND_ALE))

                       IO_ADDR_W |= S3C2410_ADDR_NALE;

 

                //chip->IO_ADDR_W = (void *)IO_ADDR_W;

 

               if (ctrl & NAND_NCE)

                       NFCONF &= ~S3C2410_NFCONF_nFCE;

……

 

        }

 

        if (cmd != NAND_CMD_NONE)

               //writeb(cmd, chip->IO_ADDR_W);

               writeb(cmd,(void *)IO_ADDR_W);

#endif

#if defined(CONFIG_S3C2440)

        if (ctrl & NAND_CTRL_CHANGE) {

               IO_ADDR_W = NF_BASE;

               if (!(ctrl & NAND_CLE)) //要写的是地址

                       {

                       IO_ADDR_W |= S3C2440_ADDR_NALE;}

               if (!(ctrl & NAND_ALE)) //要写的是命令

                       {

                       IO_ADDR_W |= S3C2440_ADDR_NCLE;}

 

               //chip->IO_ADDR_W = (void *)IO_ADDR_W;

 

               if (ctrl & NAND_NCE)  

                       {NFCONT &= ~S3C2440_NFCONT_nCE; //使能nand flash

                       //DEBUGN("NFCONT is 0x%x ",NFCONT);

                       //DEBUGN("nand Enable ");

                       }

               else

                       {NFCONT |= S3C2440_NFCONT_nCE;  //禁止nand flash

                       //DEBUGN("nand disable ");

                       }

        }

 

        if (cmd != NAND_CMD_NONE)

               writeb(cmd,(void *)IO_ADDR_W);

               //writeb(cmd, chip->IO_ADDR_W);

#endif

}

 

修改board_nand_init 函数如下:

 

        DEBUGN("board_nand_init()\n");

 

        clk_power->CLKCON |= (1 << 4);

 

  #if  defined(CONFIG_S3C2410)
           DEBUGN("CONFIG_S3C2410\n");

        /* initialize hardware */

        twrph0 = 3; twrph1 = 0; tacls = 0;

 

……

        nand->cmd_ctrl = s3c2410_hwcontrol;

 

        nand->dev_ready = s3c2410_dev_ready;

#else

#if defined(CONFIG_S3C2440)

        DEBUGN("CONFIG_S3C2440\n");

        twrph0 = 4; twrph1 = 2; tacls = 0;

        cfg = (tacls<<12)|(twrph0<<8)|(twrph1<<4);

        NFCONF = cfg;

        //DEBUGN("cfg is %x\n",cfg);

        //DEBUGN("NFCONF is %lx\n",NFCONF);

        cfg = (1<<6)|(1<<4)|(0<<1)|(1<<0);

        NFCONT = cfg;

        //DEBUGN("cfg is %lx\n",cfg);

        //DEBUGN("NFCONT is %x\n",NFCONT);

/* initialize nand_chip data structure */

        nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;

 

        /* read_buf and write_buf are default */

        /* read_byte and write_byte are default */

 

        /* hwcontrol always must be implemented */

        nand->cmd_ctrl = s3c2410_hwcontrol;

 

        nand->dev_ready = s3c2410_dev_ready;

#endif

#endif

 

 #ifdef CONFIG_S3C2410_NAND_HWECC


1.2.8 修改u-boot-2008.10/cpu/arm920t/s3c24x0/interrupts.c 文件


(1)在有S3C2410的宏定义开关里加入对S3C2440的支持:

#include

#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)

#include

#if defined(CONFIG_S3C2400)

#include

#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

#include

#endif

 

(2)加入对mini2440的支持:

 

#elif defined(CONFIG_SBC2410X) || \

       defined(CONFIG_SMDK2410) || \

      defined(CONFIG_VCMA9)    || \

      defined(CONFIG_mini2440)

 

        tbclk = CFG_HZ;

 #else

 #      error "tbclk not configured"


1.2.9 修改 cpu\arm920t\s3c24x0\speed.c 修改根据时钟寄存器来计算时钟的方法


(1)头文件对S3C2440的支持:

#include

#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)

#include

#if defined(CONFIG_S3C2400)

#include

#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

#include

#endif

 

(2)由于S3C2410S3C2440MPLLUPLL计算公式不一样,所以get_PLLCLK函数也需要修改:

 

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

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

     s = r & 0x3;

#if defined(CONFIG_S3C2440)

   if (pllreg == MPLL)

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

    else if (pllreg == UPLL)

#endif

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

 

(3) 由于S3C2410S3C2440的设置方法也不一样,所以get_HCLK函数也需要修改:

 

ulong get_HCLK(void)

 {

     S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();

#if defined(CONFIG_S3C2440)

    if (clk_power->CLKDIVN & 0x6)

               {

                if ((clk_power->CLKDIVN & 0x6)==2) return(get_FCLK()/2);

                if ((clk_power->CLKDIVN & 0x6)==6) return((clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 : get_FCLK()/3);

                if ((clk_power->CLKDIVN & 0x6)==4) return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4);

                return(get_FCLK());

                }

 

    else return(get_FCLK());

#else

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

#endif

 

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

}

 /* return PCLK frequency */

 


1.2.10 修改u-boot-2008.10/drivers/usb/usb_ohci.c ,添加对2440的支持


 

     defined(CONFIG_S3C2400) || \

     defined(CONFIG_S3C2410) || \

    defined(CONFIG_S3C2440) || \

     defined(CONFIG_S3C6400) || \

     defined(CONFIG_440EP) || \

     defined(CONFIG_PCI_OHCI) || \

     defined(CONFIG_MPC5200) || \

     defined(CFG_OHCI_USE_NPS)

# define OHCI_USE_NPS          /* force NoPowerSwitching mode */

 #endif

 


1.2.11 添加mini2440的机器ID


 

u-boot-2008.10/include/asm-arm/mach-types.h文件中添加(需要和内核的ID保持一致):

#define MACH_TYPE_IMX27IPCAM           1871

 #define MACH_TYPE_NEMOC                1872

 #define MACH_TYPE_GENEVA               1873

#define MACH_TYPE_mini2440                 782

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