今天12月13日是南京大屠杀遇难同胞遇难75周年,向南京大屠杀遇难者哀悼。勿忘国耻!
我的开发板上外接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
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_init\n"); return 0; }
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(); } }
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%02x\n", 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: %x\n", cmd); //writeb(cmd, NFCMMD); } else if (ctrl & NAND_ALE) { //writeb(cmd, NFADDR); NFADDR = cmd; //printf ("addr: %x\n", cmd); } } }