U-Boot-2011.03 transplant nandflash to mini2440

Publisher:TranquilDreamerLatest update time:2024-06-24 Source: elecfansKeywords:U-Boot Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

u-boot2011.03 supports s3c2440, and the registers are defined in s3c24x0_cpu.h in the arch/arm/includer/asm/ directory.

The code contains the s3c2410 read and write nandflash functions, so it is modified based on s3c2410

U-Boot source code download address http://www.linuxidc.com/Linux/2011-07/38897.htm

Create a s3c2440_nand.c file

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;
}
Then add in 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


After compiling, use supervivi's d command to download to sdram 0x33f80000 and point to execute
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 already supports nand flash very well


Keywords:U-Boot Reference address:U-Boot-2011.03 transplant nandflash to mini2440

Previous article:mini2440 drives ds18b20
Next article:QT_MPlayer ported to mini2440

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号