#include #if 0 #define DEBUGN printf #else #define DEBUGN(x, args ...) {} #endif #include #include #include
#define __REGb(x) (*(volatile unsigned char *)(x)) #define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000//Nand配置寄存器基地址 #define NFCONF __REGi(NF_BASE + 0x0)//偏移后还是得到配置寄存器基地址 #define NFCONT __REGi(NF_BASE + 0x4)//偏移后得到Nand控制寄存器基地址 #define NFCMD __REGb(NF_BASE + 0x8)//偏移后得到Nand指令寄存器基地址 #define NFADDR __REGb(NF_BASE + 0xc)//偏移后得到Nand地址寄存器基地址 #define NFDATA __REGb(NF_BASE + 0x10)//偏移后得到Nand数据寄存器基地址 #define NFMECCD0 __REGi(NF_BASE + 0x14)//偏移后得到Nand主数据区域ECC0寄存器基地址 #define NFMECCD1 __REGi(NF_BASE + 0x18)//偏移后得到Nand主数据区域ECC1寄存器基地址 #define NFSECCD __REGi(NF_BASE + 0x1C)//偏移后得到Nand空闲区域ECC寄存器基地址 #define NFSTAT __REGb(NF_BASE + 0x20)//偏移后得到Nand状态寄存器基地址 #define NFSTAT0 __REGi(NF_BASE + 0x24)//偏移后得到Nand ECC0状态寄存器基地址 #define NFSTAT1 __REGi(NF_BASE + 0x28)//偏移后得到Nand ECC1状态寄存器基地址 #define NFMECC0 __REGi(NF_BASE + 0x2C)//偏移后得到Nand主数据区域ECC0状态寄存器基地址 #define NFMECC1 __REGi(NF_BASE + 0x30)//偏移后得到Nand主数据区域ECC1状态寄存器基地址 #define NFSECC __REGi(NF_BASE + 0x34)//偏移后得到Nand空闲区域ECC状态寄存器基地址 #define NFSBLK __REGi(NF_BASE + 0x38)//偏移后得到Nand块开始地址 #define NFEBLK __REGi(NF_BASE + 0x3c)//偏移后得到Nand块结束地址
#define S3C2440_NFCONT_nCE (1<1) #define S3C2440_ADDR_NALE 0x0c #define S3C2440_ADDR_NCLE 0x08
ulong IO_ADDR_W = NF_BASE;
static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; DEBUGN("hwcontrol(): 0xx 0xx\n", cmd, ctrl); 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; if (ctrl & NAND_NCE) NFCONT &= ~S3C2440_NFCONT_nCE;//使能nand flash else NFCONT |= S3C2440_NFCONT_nCE;//禁止nand flash } if (cmd != NAND_CMD_NONE) writeb(cmd,(void *)IO_ADDR_W); }
static int s3c2440_dev_ready(struct mtd_info *mtd) { DEBUGN("dev_ready\n"); return (NFSTAT & 0x01); }
int board_nand_init(struct nand_chip *nand) { u_int32_t cfg; u_int8_t tacls, twrph0, twrph1; S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
DEBUGN("board_nand_init()\n");
clk_power->CLKCON |= (1 < 4);
twrph0 = 4; twrph1 = 2; tacls = 0;
cfg = (tacls<12)|(twrph0<8)|(twrph1<4); NFCONF = cfg;
cfg = (1<6)|(1<4)|(0<1)|(1<0); NFCONT = cfg;
nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;
nand->cmd_ctrl = s3c2440_hwcontrol;
nand->dev_ready = s3c2440_dev_ready;
return 0; } |