s5pv210 uboot-2012-10移植(六) 之支持NandFlash
s5pv210?uboot-2012-10移植(六)?之支持NandFlash?我的开发板上外接256M的K9F2G08U0A?FLASH芯片。uboot-2012-10本身不带s5pv210的nandflash操作,s5pv210的nandflash和s3c2410的寄存器差不多,所以,我就在s3c2410的nandFlash上进行修改了,因为我不懂nandflash的HW_EEC,所以我实现的是SOFT_EEC了。 1.修改include/configs/smdkv210.h?+88 ? /*#undef CONFIG_CMD_NAND*/ #define CONFIG_CMD_NAND #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE 0xB0E00000 #define CONFIG_NAND_S3C2410 ? 2.修改drivers/mtd/nand/s3c2410_nand.c?+207,屏蔽了s3c2410的nandflash初始化,添加了s5pv210nandflash总线的初始化和nandflash控制器的初始化,并添加s5pv210_select_chip函数,其他不变。? ? int board_nand_init(struct nand_chip *nand) { #if 0 u_int32_t cfg; u_int8_t tacls,twrph0,twrph1; struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); struct s3c2410_nand *nand_reg = s3c2410_get_base_nand(); debug("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 = S3C2410_NFCONF_EN; cfg |= S3C2410_NFCONF_TACLS(tacls - 1); cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); writel(cfg,&nand_reg->nfconf); #endif #define MP0_1CON (*(volatile unsigned int *)0xE02002E0) #define MP0_3CON (*(volatile unsigned int *)0xE0200320) #define NFCONF (*(volatile unsigned int *)0xB0E00000) #define NFCONT (*(volatile unsigned int *)0xB0E00004) #define NFCMMD (*(volatile unsigned char *)0xB0E00008) #define NFADDR (*(volatile unsigned char *)0xB0E0000C) #define NFDATA (*(volatile unsigned char *)0xB0E00010) #define NFSTAT (*(volatile unsigned int *)0xB0E00028) #define NFCONF_VAL ((7<<12)|(7<<8)|(7<<4)|(0<<3)|(0<<2)|(1<<1)) #define NFCONT_VAL ((1<<23)|(1<<22)|(1<<2)|(0<<1)|(1<<0)) unsigned int tmp; //tmp = MP0_1CON; //tmp &= ~((0xf<<8)|(0xf<<12)); //tmp |= (0x3<<8) | (0x3<<12); //MP0_1CON = tmp; tmp = MP0_1CON; tmp &= ~(0xf<<16); tmp |= (0x3<<16); MP0_1CON = tmp; tmp = MP0_3CON; //tmp &= ~((0xf<<0)|(0xf<<4)|(0xf<<8)|(0xf<<12)|(0xf<<16)|(0xf<<20)); //tmp |= (0x2<<0)|(0x2<<4)|(0x2<<8)|(0x2<<12)|(0x2<<16)|(0x2<<20); tmp &= ~((0xf<<0)|(0xf<<4)|(0xf<<8)|(0xf<<12)|(0xf<<16)); tmp |= (0x2<<0)|(0x2<<4)|(0x2<<8)|(0x2<<12)|(0x2<<16); MP0_3CON = tmp; NFCONF = NFCONF_VAL; NFCONT = NFCONT_VAL; /* initialize nand_chip data structure */ nand->IO_ADDR_R = (volatile unsigned char *)0xB0E00010; nand->IO_ADDR_W = (volatile unsigned char *)0xB0E00010; nand->select_chip = s5pv210_select_chip; /* 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 = s3c2410_hwcontrol; nand->dev_ready = s3c2410_dev_ready; #ifdef CONFIG_S3C2410_NAND_HWECC nand->ecc.hwctl = s3c2410_nand_enable_hwecc; nand->ecc.calculate = s3c2410_nand_calculate_ecc; nand->ecc.correct = s3c2410_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_S3C2410_NAND_BBT nand->options = NAND_USE_FLASH_BBT; #else nand->options = 0; #endif debug("end of nand_initn"); return 0; } ? 3.在drivers/mtd/nand/s3c2410_nand.c?添加s5pv210_select_chip函数? ? static void s5pv210_select_chip(struct mtd_info *mtd,int chipnr) { #define NFCONT (*(volatile unsigned int *)0xB0E00004) struct nand_chip *chip = mtd->priv; switch (chipnr) { case -1: //chip->cmd_ctrl(mtd,NAND_CMD_NONE,0 | NAND_CTRL_CHANGE); NFCONT |= (1<<1); break; case 0: NFCONT &= ~(1<<1); break; default: BUG(); } } ? 4.修改drivers/mtd/nand/s3c2410_nand.c?的s3c2410_hwcontrol函数? ? static void s3c2410_hwcontrol(struct mtd_info *mtd,int cmd,unsigned int ctrl) { #if 0 struct nand_chip *chip = mtd->priv; struct s3c2410_nand *nand = s3c2410_get_base_nand(); debug("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 |= S3C2410_ADDR_NCLE; if (!(ctrl & NAND_ALE)) IO_ADDR_W |= S3C2410_ADDR_NALE; chip->IO_ADDR_W = (void *)IO_ADDR_W; if (ctrl & NAND_NCE) writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE,&nand->nfconf); else writel(readl(&nand->nfconf) | S3C2410_NFCONF_nFCE,&nand->nfconf); } if (cmd != NAND_CMD_NONE) writeb(cmd,chip->IO_ADDR_W); #endif #define NFCMMD (*(volatile unsigned char *)0xB0E00008) #define NFADDR (*(volatile unsigned char *)0xB0E0000C) if (cmd != NAND_CMD_NONE) { if (ctrl & NAND_CLE) { NFCMMD = cmd; //printf ("cmd: %xn",cmd); //writeb(cmd,NFCMMD); } else if (ctrl & NAND_ALE) { //writeb(cmd,NFADDR); NFADDR = cmd; //printf ("addr: %xn",cmd); } } } ? 5.make,使用命令下载到sd卡里,上电,观察控制台,可以看到,识别出了256M的nandflash了,以后就可以对nandflash进行操作了。?? ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |