移植uboot(支持nand)

    复制S3C2410_nand.c为S3C2440_nand.c,修改drivers/mtd/nand/makefile编译S3C2440_nand.c而不编译S3C2410_nand.c
添加:COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
smdk2440.h中:
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
改为:
#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_S3C2440_NAND_HWECC

s3c2440_nand.c:
S3C2440_hwcontrol()中修改使能选中和取消选中

board_nand_init()函数中初始化:修改为

tacls  = 0;
twrph0 = 1;
twrph1 = 0;
cfg = ((tacls-1)<<12)|((twrph0-1)<<8)|((twrp1-1)<<4);
writel((1<<4)|(1<<1)|(1<<0),&nand_reg->nfcont);
修改:s3c2440_hwcontrol()和nand_select_chip()
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();

	debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);

	if (ctrl & NAND_CTRL_CHANGE) {
		ulong IO_ADDR_W = (ulong)nand;

		//if (!(ctrl & NAND_CLE))
		//	IO_ADDR_W |= S3C2440_ADDR_NCLE;
		//if (!(ctrl & NAND_ALE))
		//	IO_ADDR_W |= S3C2440_ADDR_NALE;
			
		//if (cmd != NAND_CMD_NONE)
		//	writeb(cmd, chip->IO_ADDR_W);
		/*前面我们指定的 chip->IO_ADDR_W = (void *)&nand_reg->nfdata; 显然将命令发送到数据寄存器
		是错误,我们看到在发送之前 chip->IO_ADDR_W = (void *)IO_ADDR_W; IO_ADDR_W 这个变量是根据 
		ctrl 来计算的,它有以下取值
	    	ctrl :!NAND_CLE ,             S3C2410_ADDR_NCLE == 8    ->地址
	    	ctrl :!NAND_ALE ,              S3C2410_ADDR_NALE == 4    -> 指令
	    	ctrl : (!NAND_CLE) | (!NAND_ALE)    -> 8 | 4 == 12   -> 数据
	    	*/
    
    		//修改IO_ADDR_W后再写
	    	if (!(ctrl & NAND_CLE))  
	    		IO_ADDR_W |= 12;
	   	if (!(ctrl & NAND_ALE))  
	   		IO_ADDR_W |= 8;          
		if ((!(ctrl & NAND_CLE)) && (!(ctrl & NAND_ALE)))
	   		IO_ADDR_W = IO_ADDR_W + 4;    //8|12 == 12 != 16 因此 + 4  
	   		 
	   	chip->IO_ADDR_W = (void *)IO_ADDR_W;
		//chip->IO_ADDR_W = (void *)IO_ADDR_W;
		/*
		if (ctrl & NAND_NCE)	//使能选中
			writel(readl(&nand->nfconf) & ~S3C2440_NFCONF_nFCE,
			       &nand->nfconf);
		else			//取消选中
			writel(readl(&nand->nfconf) | S3C2440_NFCONF_nFCE,
			       &nand->nfconf);
		*/
		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);
}
nand_base.c默认的选中芯片函数中没有代码实现选中芯片:
static void nand_select_chip(struct mtd_info *mtd, int chipnr)
{
	struct nand_chip *chip = mtd->priv;

	switch (chipnr) {
	case -1:
		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
		break;
	case 0:
		break;

	default:
		BUG();
	}
}
自定义芯片选中函数:
static void s3c2440_nand_select(struct mtd_info *mtd, int chipnr)
{
	struct s3c2440_nand *nand = s3c2440_get_base_nand();

	switch (chipnr) {
	case -1:
		nand->nfcont |= (1<<1);
		break;
	case 0:
		nand->nfcont &= ~(1<<1);
		break;

	default:
		BUG();
	}
}
    并把这个函数填充到nand->select_chip:
board_nand_init()中:
把  :nand->select_chip = NULL;
改为:nand->select_chip = s3c2440_nand_select;
  编译烧写启动,即可识别nand,支持nand启动。


猜你喜欢

转载自blog.csdn.net/qq_22863733/article/details/79075518