免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 740 | 回复: 0
打印 上一主题 下一主题

移植U-Boot.2008.10到友善之臂mini2440(五)【转】 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-05 00:25 |只看该作者 |倒序浏览

1.2.7 Nand Flash 驱动



首先,要说明一下 CFG_NAND_LEGACY 的使用。在u-boot的 drivers/mtd/下有两个目录,分别是nand和nand_legacy。在nand目录下的是nand的初始化函数和nand的操作读写函数,是使用linux的mtd构架。此目录下的文件,只有在定义了CFG_CMD_NAND宏和没有定义CFG_NAND_LEGACY宏的情况下才会被编译。在nand_leagcy目录下的文件也是是实现nand相关操作命令,如read,write等命令的功能,但不是使用linux的mtd构架。此目录下的文件,只有在定义了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
#define S3C2440_ADDR_NALE 0x0c
#define S3C2440_ADDR_NCLE 0x08

#endif
#endif
#define S3C2410_NFCONF_EN          (1
u-boot.2008.10自带的S3C2410的s3c2410_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

  #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
        NFCONF = cfg;
        //DEBUGN("cfg is %x\n",cfg);
        //DEBUGN("NFCONF is %lx\n",NFCONF);
        cfg = (1
        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)由于S3C2410和S3C2440的MPLL、UPLL计算公式不一样,所以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
    else if (pllreg == UPLL)
#endif
return((CONFIG_SYS_CLK_FREQ * m ) / (p

(3) 由于S3C2410和S3C2440的设置方法也不一样,所以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


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/107284/showart_2111618.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP