U-Boot-2011.03移植nandflash到mini2440

发布时间:2024-06-24  

u-boot2011.03支持s3c2440,寄存器在arch/arm/includer/asm/目录下s3c24x0_cpu.h中定义。

代码中包含了s3c2410读写nandflash函数,因此在s3c2410基础上进行修改

U-Boot源代码下载地址 http://www.linuxidc.com/Linux/2011-07/38897.htm

建一个s3c2440_nand.c文件

cd   drivers/mtd/nand/
cp     s3c2410_nand.c   s3c2440_nand.c
代码如下
寄存器操作说明:
readl函数原型
#define   readl(addr)       (*(volatile unsigned int*)(addr))
writeb函数原型
#define   writel(b,addr)          ((*(volatile unsigned int *) (addr)) = (b))
 
 
#include
#include
#include
#include
 
#define S3C2440_NFCONT_EN          (1<<0)
#define S3C2440_NFCONT_nFCE        (0<<1)
#define S3C2440_NFCONT_INITECC      (1<<4)
#define S3C2440_NFCONF_TACLS(x)    ((x)<<12)
#define S3C2440_NFCONF_TWRPH0(x)   ((x)<<8)
#define S3C2440_NFCONF_TWRPH1(x)   ((x)<<4)
 
#define S3C2440_ADDR_NALE 0x0c
#define S3C2440_ADDR_NCLE 0x08
 
#ifdef CONFIG_NAND_SPL
 
/* in the early stage of NAND flash booting, printf() is not available */
#define printf(fmt, args...)
 
static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
{
         int i;
         struct nand_chip *this = mtd->priv;
 
         for (i = 0; i < len; i++)
                   buf[i] = readb(this->IO_ADDR_R);
}
#endif
 
static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
         struct nand_chip *chip = mtd->priv;
         struct s3c2440_nand *nand = s3c2440_get_base_nand();
 
         debugX(1, "hwcontrol(): 0x%02x 0x%02xn", cmd, ctrl);
 
         if (ctrl & NAND_CTRL_CHANGE) {
                   ulong IO_ADDR_W = (ulong)nand;
 
                   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)
                            writel(readl(&nand->nfcont) & (~(1<<1)),
                                   &nand->nfcont);
                   else
                            writel(readl(&nand->nfcont) | (1<<1),
                                   &nand->nfcont);
         }
 
         if (cmd != NAND_CMD_NONE)
                   writeb(cmd, chip->IO_ADDR_W);
}
 
static int s3c2440_dev_ready(struct mtd_info *mtd)
{
         struct s3c2440_nand *nand = s3c2440_get_base_nand();
         debugX(1, "dev_readyn");
         return readl(&nand->nfstat) & 0x01;
}
 
#ifdef CONFIG_S3C2440_NAND_HWECC
void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
         struct s3c2440_nand *nand = s3c2440_get_base_nand();
         debugX(1, "s3c2440_nand_enable_hwecc(%p, %d)n", mtd, mode);
         writel(readl(&nand->nfconf) | S3C2440_NFCONF_INITECC, &nand->nfconf);
}
 
static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
{
         struct s3c2440_nand *nand = s3c2440_get_base_nand();
         ecc_code[0] = readb(&nand->nfecc);
         ecc_code[1] = readb(&nand->nfecc + 1);
         ecc_code[2] = readb(&nand->nfecc + 2);
         debugX(1, "s3c2440_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02xn",
                mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
 
         return 0;
}
 
static int s3c2440_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
{
         if (read_ecc[0] == calc_ecc[0] &&
             read_ecc[1] == calc_ecc[1] &&
             read_ecc[2] == calc_ecc[2])
                   return 0;
 
         printf("s3c2440_nand_correct_data: not implementedn");
         return -1;
}
#endif
int board_nand_init(struct nand_chip *nand)
{
         u_int32_t cfg;
         u_int8_t tacls, twrph0, twrph1;
         struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
         struct s3c2440_nand *nand_reg = s3c2440_get_base_nand();
         debugX(1, "board_nand_init()n");
         writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon);
         /* initialize hardware */
#if defined(CONFIG_S3C24XX_CUSTOM_NAND_TIMING)
         tacls  = CONFIG_S3C24XX_TACLS;
         twrph0 = CONFIG_S3C24XX_TWRPH0;
         twrph1 =  CONFIG_S3C24XX_TWRPH1;
#else
         tacls = 4;
         twrph0 = 8;
         twrph1 = 8;
#endif
         cfg = S3C2440_NFCONF_TACLS(tacls - 1);
         cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
         cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
         writel(cfg, &nand_reg->nfconf);
 
         cfg = S3C2440_NFCONT_EN;
         cfg |= S3C2440_NFCONT_nFCE;
         cfg |= S3C2440_NFCONT_INITECC;
         writel(cfg, &nand_reg->nfcont);
         /* initialize nand_chip data structure */
         nand->IO_ADDR_R = (void *)&nand_reg->nfdata;
         nand->IO_ADDR_W = (void *)&nand_reg->nfdata;
 
         nand->select_chip = NULL;
 
         /* read_buf and write_buf are default */
         /* read_byte and write_byte are default */
#ifdef CONFIG_NAND_SPL
         nand->read_buf = nand_read_buf;
#endif
 
         /* hwcontrol always must be implemented */
         nand->cmd_ctrl = s3c2440_hwcontrol;
         nand->dev_ready = s3c2440_dev_ready;
 
#ifdef CONFIG_S3C2440_NAND_HWECC
         nand->ecc.hwctl = s3c2440_nand_enable_hwecc;
         nand->ecc.calculate = s3c2440_nand_calculate_ecc;
         nand->ecc.correct = s3c2440_nand_correct_data;
         nand->ecc.mode = NAND_ECC_HW;
         nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
         nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
#else
         nand->ecc.mode = NAND_ECC_SOFT;
#endif
#ifdef CONFIG_S3C2440_NAND_BBT
         nand->options = NAND_USE_FLASH_BBT;
#else
         nand->options = 0;
#endif
         debugX(1, "end of nand_initn");
         return 0;
}
再在include/configs/mini2440.h中添加
#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE    0x4E000000
#define CONFIG_MTD_DEVICE
#define CONFIG_CMD_NAND
 
 
编译好后使用supervivi   的d命令下载到sdram的0x33f80000地指出执行
U-Boot 2011.03 (Nov 29 2011 - 09:21:34)
DRAM:  64 MiB
Flash:   2 MiB
NAND:  256 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
mini2440 # nand info
Device 0: nand0, sector size 128 KiB
mini2440 #
mini2440已经能够很好的支持nand flash

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>