<一>支持NAND Flash
1. 首先在配置文件 include/config/fl2440.h 的宏 CONFIG_COMMANDS 中增加 CFG_CMD_NAND,
#define CONFIG_COMMANDS
(CONFIG_CMD_DFL |
CFG_CMD_CACHE |
CFG_CMD_NAND |
2.在配置文件 include/configs/fl2440.h 中增加如下3个宏
#define CFG_NAND_BASE 0 //无实际意义:基地址,在board_nand_init中重新定义
#define CFG_MAX_NAND_DEVICE 1 //NAND Flash设备数目为1
#define NAND_MAX_CHIPS 1 //每个NAND设备由1个NADN芯片组成
3.在 include/s3c24x0.h 文件中增加s3c2440_NAND 数据结构
typedef struct {
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCONT;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG32 NFDATA;
S3C24X0_REG32 NFMECCD0;
S3C24X0_REG32 NFMECCD1;
S3C24X0_REG32 NFSECCD;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFESTAT0;
S3C24X0_REG32 NFESTAT1;
S3C24X0_REG32 NFMECC0;
S3C24X0_REG32 NFMECC1;
S3C24X0_REG32 NFSECC;
S3C24X0_REG32 NFSBLK;
S3C24X0_REG32 NFEBLK;
} S3C2440_NAND;
4.在 includ/s3c2410.h 文件中仿照 s3c2410_GetBase_NAND 函数定义 S3C2440_GetBase_NAND 函数
static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)
{
return (S3C2440_NAND * const)S3C2410_NAND_BASE;
5.在 cpu/arm920t/s3c24x0 下新建nand_flash.c文件,代码如下。
#include <common.h>
#include <common.h>
#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
#include <s3c2410.h>
#include <nand.h>
DECLARE_GLOBAL_DATA_PTR;
#define S3C2410_NFSTAT_READY (1<<0)
#define S3C2410_NFCONF_nFCE (1<<11)
#define S3C2440_NFSTAT_READY (1<<0)
#define S3C2440_NFCONT_nFCE (1<<1)
static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
{
S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();
if (chip == -1) {
s3c2410nand->NFCONF |= S3C2410_NFCONF_nFCE;
} else {
s3c2410nand->NFCONF &= ~S3C2410_NFCONF_nFCE;
}
}
static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();
struct nand_chip *chip = mtd->priv;
switch (cmd) {
case NAND_CTL_SETNCE:
case NAND_CTL_CLRNCE:
printf("%s: called for NCE
", __FUNCTION__);
break;
case NAND_CTL_SETCLE:
chip->IO_ADDR_W = (void *)&s3c2410nand->NFCMD;
break;
case NAND_CTL_SETALE:
chip->IO_ADDR_W = (void *)&s3c2410nand->NFADDR;
break;
}
}
static int s3c2410_nand_devready(struct mtd_info *mtd)
{
S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();
return (s3c2410nand->NFSTAT & S3C2410_NFSTAT_READY);
}
static void s3c2440_nand_select_chip(struct mtd_info *mtd, int chip)
{
S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();
if (chip == -1) {
s3c2440nand->NFCONT |= S3C2440_NFCONT_nFCE;
} else {
s3c2440nand->NFCONT &= ~S3C2440_NFCONT_nFCE;
}
}
static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();
struct nand_chip *chip = mtd->priv;
switch (cmd) {
case NAND_CTL_SETNCE:
case NAND_CTL_CLRNCE:
printf("%s: called for NCE
", __FUNCTION__);
break;
case NAND_CTL_SETCLE:
chip->IO_ADDR_W = (void *)&s3c2440nand->NFCMD;
break;
case NAND_CTL_SETALE:
chip->IO_ADDR_W = (void *)&s3c2440nand->NFADDR;
break;
default:
chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;
break;
}
}
static int s3c2440_nand_devready(struct mtd_info *mtd)
{
S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();
return (s3c2440nand->NFSTAT & S3C2440_NFSTAT_READY);
}
static void s3c24x0_nand_inithw(void)
{
S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();
S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
{
s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
}
else
{
s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
s3c2440nand->NFCONT = (1<<4)|(0<<1)|(1<<0);
}
}
void board_nand_init(struct nand_chip *chip)
{
S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();
S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();
s3c24x0_nand_inithw();
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410) {
chip->IO_ADDR_R = (void *)&s3c2410nand->NFDATA;
chip->IO_ADDR_W = (void *)&s3c2410nand->NFDATA;
chip->hwcontrol = s3c2410_nand_hwcontrol;
chip->dev_ready = s3c2410_nand_devready;
chip->select_chip = s3c2410_nand_select_chip;
chip->options = 0;
} else {
chip->IO_ADDR_R = (void *)&s3c2440nand->NFDATA;
chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;
chip->hwcontrol = s3c2440_nand_hwcontrol;
chip->dev_ready = s3c2440_nand_devready;
chip->select_chip = s3c2440_nand_select_chip;
chip->options = 0;
}
chip->eccmode = NAND_ECC_SOFT;
}
#endif
6.修改cpu/arm920t/s3c24x0/Makefile:
COBJS = 加上一项nand_flash.o
7.修改 cpu/arm920t/s3c24x0/Makefile文件如下
COBJS = i2c.o interrupts.o serial.o speed.o
usb_ohci.o nand_flash.o
<二>现在就可以编译了,如果出现错误
文件格式错误: failed to merge target specific data of file /usr/local/arm/3.3.2/lib/gcc-lib/arm-linux/3.3.2/libgcc.a(_clz.oS)
修改 cpu/arm920t/config.mk 文件如下(不使用软浮点进行编译,即用硬浮点进行编译)
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8
# -msoft-float
可以使用新编译的U-Boot.bin烧入NAND Flash了。