在cpu/arm920t/s3c24x0/nand_flash.c中添加代码,是从Linux-2.6.13中/drivers/mtd/nand/s3c2410.c中移植过来的,代码如下 /* * Nand flash interface of s3c2410/s3c2440 * Changed from drivers/mtd/nand/s3c2410.c of kernel 2.6.13 */
#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)
/* select chip, for s3c2410 */ 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; } }
/* command and control functions, for s3c2410 * * Note, these all use tglx's method of changing the IO_ADDR_W field * to make the code simpler, and use the nand layer's code to issue the * command and address sequences via the proper IO ports. * */ 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\n", __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;
/* NAND_CTL_CLRCLE: */ /* NAND_CTL_CLRALE: */ default: chip->IO_ADDR_W = (void *)&s3c2410nand->NFDATA; break; } }
/* s3c2410_nand_devready() * * returns 0 if the nand is busy, 1 if it is ready */ static int s3c2410_nand_devready(struct mtd_info *mtd) { S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();
return (s3c2410nand->NFSTAT & S3C2410_NFSTAT_READY); }
/* select chip, for s3c2440 */ 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; } }
/* command and control functions */ 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\n", __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;
/* NAND_CTL_CLRCLE: */ /* NAND_CTL_CLRALE: */ default: chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA; break; } }
/* s3c2440_nand_devready() * * returns 0 if the nand is busy, 1 if it is ready */ static int s3c2440_nand_devready(struct mtd_info *mtd) { S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();
return (s3c2440nand->NFSTAT & S3C2440_NFSTAT_READY); }
/* * Nand flash hardware initialization: * Set the timing, enable NAND flash controller */ 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) { /* Enable NAND flash controller, Initialize ECC, enable chip select, Set flash memory timing */ s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); } else { /* Set flash memory timing */ s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4); /* Initialize ECC, enable chip select, NAND flash controller enable */ s3c2440nand->NFCONT = (1<<4)|(0<<1)|(1<<0); } }
/* * Called by drivers/nand/nand.c, initialize the interface of nand flash */ 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
修改cpu/arm920t/s3c24x0/Makefile: COBJS = 加上一项nand_flash.o
最后 make clean make all 编译成功后加载到0x33000000RAM 中运行会有NAND 信息,
Uboot中支持小页nand flash 大页nand flash驱动: 文件:uboot nand驱动.rar大小:64KB下载:下载
支持网卡DM9000 u-boot 自带网卡驱动,所以只要做些设置即可在driver下,有网卡驱动DM9000x.c 和 DM9000x.hDM9000接在BANK4,位宽16 在include/configs/TX2440.h中设置网卡基地址: 在56行处,屏蔽CS8900的定义加上: #define CONFIG_ETHADDR 10:23:45:67:89:AB #define CONFIG_DRIVER_DM9000 1 #define CONFIG_DM9000_BASE 0x20000300 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 4) #define CONFIG_DM9000_USE_16BIT
#define CONFIG_ETHADDR 10:23:45:67:89:AB #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 192.168.0.10 #define CONFIG_SERVERIP 192.168.0.6 driver/Makefile 里修改: COBJS = dm9000x.o make clean make 加载到内存中运行 加载到内存中运行 SMDK2410 # tftp 0x30000000 zImage dm9000 i/o: 0x20000300, id: 0x90000a46 MAC: 00:80:00:80:00:80 could not establish link TFTP from server 192.168.0.5; our IP address is 192.168.0.10 Filename 'zImage'. Load address: 0x30000000 Loading: ################################################################# done Bytes transferred = 1924480 (1d5d80 hex) 在蓝色出会出现十秒的停顿,然后报could not establish link 错误,不过不影响使用,这是因为在网卡驱动中drivers/net/dm9000.c,有一段程序试图连接网卡的MII接口,而实际上MII 接口并未使用,所以有十秒的等待时间,且报错,将此段程序注释掉即可。且发现网卡物理地址MAC 不对,这是因为在显示MAC 之前没有 获取envaddr 这个环境变量。 |
|