void board_nand_init(void) { struct mtd_info *mtd = nand_to_mtd(&lpc32xx_chip); int ret; /* Set all BOARDSPECIFIC (actually core-specific) fields */ lpc32xx_chip.IO_ADDR_R = &lpc32xx_nand_mlc_registers->buff; lpc32xx_chip.IO_ADDR_W = &lpc32xx_nand_mlc_registers->buff; lpc32xx_chip.cmd_ctrl = lpc32xx_cmd_ctrl; /* do not set init_size: nand_base.c will read sizes from chip */ lpc32xx_chip.dev_ready = lpc32xx_dev_ready; /* do not set setup_read_retry: this is NAND-chip-specific */ /* do not set chip_delay: we have dev_ready defined. */ lpc32xx_chip.options |= NAND_NO_SUBPAGE_WRITE; /* Set needed ECC fields */ lpc32xx_chip.ecc.mode = NAND_ECC_HW; lpc32xx_chip.ecc.layout = &lpc32xx_largepage_ecclayout; lpc32xx_chip.ecc.size = 512; lpc32xx_chip.ecc.bytes = 10; lpc32xx_chip.ecc.strength = 4; lpc32xx_chip.ecc.read_page = lpc32xx_read_page_hwecc; lpc32xx_chip.ecc.read_page_raw = lpc32xx_read_page_raw; lpc32xx_chip.ecc.write_page = lpc32xx_write_page_hwecc; lpc32xx_chip.ecc.write_page_raw = lpc32xx_write_page_raw; lpc32xx_chip.ecc.read_oob = lpc32xx_read_oob; lpc32xx_chip.ecc.write_oob = lpc32xx_write_oob; lpc32xx_chip.waitfunc = lpc32xx_waitfunc; lpc32xx_chip.read_byte = lpc32xx_read_byte; /* FIXME: NEEDED? */ /* BBT options: read from last two pages */ lpc32xx_chip.bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_LASTBLOCK | NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | NAND_BBT_WRITE; /* Initialize NAND interface */ lpc32xx_nand_init(); /* identify chip */ ret = nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_CHIPS, NULL); if (ret) { error("nand_scan_ident returned %i", ret); return; } /* finish scanning the chip */ ret = nand_scan_tail(mtd); if (ret) { error("nand_scan_tail returned %i", ret); return; } /* chip is good, register it */ ret = nand_register(0, mtd); if (ret) error("nand_register returned %i", ret); }
int jz_sfc_nand_init(int sfc_quad_mode,struct nand_param_from_burner *param) { u8 idcode[IDCODE_LEN + 1]; struct nand_chip *chip; struct mtd_info *mtd; struct jz_spi_support_from_burner *spi_flash; mtd = &nand_info[0]; int using_way; sfc_for_nand_init(sfc_quad_mode); #ifndef CONFIG_BURNER char *buffer=get_chip_param_from_nand(¶m,&using_way); if(using_way==1) //use old way { tran_old_burnway(¶m); } #endif read_sfcnand_id(idcode,2); spi_flash = sfc_nandflash_probe(idcode,param); chip = malloc(sizeof(struct nand_chip)); if (!chip) return -ENOMEM; memset(chip,0,sizeof(struct nand_chip)); mtd->size = spi_flash->size; mtd->flags |= MTD_CAP_NANDFLASH; mtd->erasesize = spi_flash->block_size; mtd->writesize = spi_flash->page_size; mtd->oobsize = spi_flash->oobsize; column_cmdaddr_bits = spi_flash->column_cmdaddr_bits; chip->select_chip = NULL; chip->badblockbits = 8; chip->scan_bbt = nand_default_bbt; chip->block_bad = jz_sfcnand_block_bad_check; chip->block_markbad = jz_sfcnand_block_markbad; chip->ecc.layout= &gd5f_ecc_layout_128; // for erase ops chip->bbt_erase_shift = chip->phys_erase_shift = ffs(mtd->erasesize) - 1; if (!(chip->options & NAND_OWN_BUFFERS)) chip->buffers = memalign(ARCH_DMA_MINALIGN,sizeof(*chip->buffers)); /* Set the bad block position */ if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16)) chip->badblockpos = NAND_LARGE_BADBLOCK_POS; else chip->badblockpos = NAND_SMALL_BADBLOCK_POS; mtd->priv = chip; jz_sfcnand_ext_init(); mtd_sfcnand_init(mtd); nand_register(0); return 0; }
static void nand_init_chip(int i) { struct mtd_info *mtd = &nand_info[i]; struct nand_chip *nand = &nand_chip[i]; ulong base_addr = base_address[i]; int maxchips = CONFIG_SYS_NAND_MAX_CHIPS; if (maxchips < 1) maxchips = 1; mtd->priv = nand; nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr; if (board_nand_init(nand)) return; if (nand_scan(mtd, maxchips)) return; nand_register(i); }
static int arasan_nand_init(struct nand_chip *nand_chip, int devnum) { struct arasan_nand_info *xnand; struct mtd_info *mtd; u8 maf_id, dev_id; int err = -1; u8 get_feature[4]; u8 set_feature[4] = {0x08, 0x00, 0x00, 0x00}; int ondie_ecc_enabled = 0; u32 timeout = ARASAN_NAND_POLL_TIMEOUT; u32 i; xnand = calloc(1, sizeof(struct arasan_nand_info)); if (!xnand) { printf("%s: failed to allocate\n", __func__); return -1; } xnand->nand_base = (void *)ARASAN_NAND_BASEADDR; mtd = &nand_info[0]; nand_chip->priv = xnand; mtd->priv = nand_chip; /* Set address of NAND IO lines */ nand_chip->IO_ADDR_R = (void *)&arasan_nand_base->buf_dataport; nand_chip->IO_ADDR_W = (void *)&arasan_nand_base->buf_dataport; /* Set the driver entry points for MTD */ nand_chip->cmdfunc = arasan_nand_cmd_function; nand_chip->select_chip = arasan_nand_select_chip; nand_chip->read_byte = arasan_nand_read_byte; /* Buffer read/write routines */ nand_chip->read_buf = arasan_nand_read_buf; nand_chip->write_buf = arasan_nand_write_buf; nand_chip->bbt_options = NAND_BBT_USE_FLASH; writel(0x0, &arasan_nand_base->cmd_reg); writel(0x0, &arasan_nand_base->pgm_reg); /* first scan to find the device and get the page size */ if (nand_scan_ident(mtd, 1, NULL)) { printf("%s: nand_scan_ident failed\n", __func__); goto fail; } mtd->size = nand_chip->chipsize; /* Send the command for reading device ID */ nand_chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); nand_chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); /* Read manufacturer and device IDs */ maf_id = nand_chip->read_byte(mtd); dev_id = nand_chip->read_byte(mtd); if ((maf_id == 0x2c) && ((dev_id == 0xf1) || (dev_id == 0xa1) || (dev_id == 0xb1) || (dev_id == 0xaa) || (dev_id == 0xba) || (dev_id == 0xda) || (dev_id == 0xca) || (dev_id == 0xac) || (dev_id == 0xbc) || (dev_id == 0xdc) || (dev_id == 0xcc) || (dev_id == 0xa3) || (dev_id == 0xb3) || (dev_id == 0xd3) || (dev_id == 0xc3))) { nand_chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, ONDIE_ECC_FEATURE_ADDR, -1); for (i = 0; i < 4; i++) writeb(set_feature[i], nand_chip->IO_ADDR_W); while (!(readl(&arasan_nand_base->intsts_reg) & ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) { timeout--; } if (!timeout) { puts("ERROR:arasan_nand_init timedout:Xfer CMPLT\n"); goto fail; } writel(readl(&arasan_nand_base->intsts_enr) | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK, &arasan_nand_base->intsts_enr); writel(readl(&arasan_nand_base->intsts_reg) | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK, &arasan_nand_base->intsts_reg); nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, ONDIE_ECC_FEATURE_ADDR, -1); for (i = 0; i < 4; i++) get_feature[i] = nand_chip->read_byte(mtd); if (get_feature[0] & 0x08) { debug("%s: OnDie ECC flash\n", __func__); ondie_ecc_enabled = 1; } else { printf("%s: Unable to detect OnDie ECC\n", __func__); } } if (!ondie_ecc_enabled) { nand_chip->ecc.mode = NAND_ECC_HW; nand_chip->ecc.strength = 1; nand_chip->ecc.hwctl = NULL; nand_chip->ecc.read_page = arasan_nand_read_page_hwecc; nand_chip->ecc.write_page = arasan_nand_write_page_hwecc; nand_chip->ecc.read_oob = arasan_nand_read_oob; nand_chip->ecc.write_oob = arasan_nand_write_oob; } arasan_nand_ecc_init(mtd); if (nand_scan_tail(mtd)) { printf("%s: nand_scan_tailfailed\n", __func__); goto fail; } if (nand_register(devnum)) { printf("Nand Register Fail\n"); goto fail; } return 0; fail: kfree(xnand); return err; }
int denali_init(struct denali_nand_info *denali) { struct mtd_info *mtd = nand_to_mtd(&denali->nand); int ret; denali_hw_init(denali); mtd->name = "denali-nand"; mtd->owner = THIS_MODULE; /* register the driver with the NAND core subsystem */ denali->nand.select_chip = denali_select_chip; denali->nand.cmdfunc = denali_cmdfunc; denali->nand.read_byte = denali_read_byte; denali->nand.read_buf = denali_read_buf; denali->nand.waitfunc = denali_waitfunc; /* * scan for NAND devices attached to the controller * this is the first stage in a two step process to register * with the nand subsystem */ if (nand_scan_ident(mtd, denali->max_banks, NULL)) { ret = -ENXIO; goto fail; } #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT /* check whether flash got BBT table (located at end of flash). As we * use NAND_BBT_NO_OOB, the BBT page will start with * bbt_pattern. We will have mirror pattern too */ denali->nand.bbt_options |= NAND_BBT_USE_FLASH; /* * We are using main + spare with ECC support. As BBT need ECC support, * we need to ensure BBT code don't write to OOB for the BBT pattern. * All BBT info will be stored into data area with ECC support. */ denali->nand.bbt_options |= NAND_BBT_NO_OOB; #endif denali->nand.ecc.mode = NAND_ECC_HW; denali->nand.ecc.size = CONFIG_NAND_DENALI_ECC_SIZE; /* no subpage writes on denali */ denali->nand.options |= NAND_NO_SUBPAGE_WRITE; /* * Tell driver the ecc strength. This register may be already set * correctly. So we read this value out. */ denali->nand.ecc.strength = readl(denali->flash_reg + ECC_CORRECTION); switch (denali->nand.ecc.size) { case 512: denali->nand.ecc.bytes = (denali->nand.ecc.strength * 13 + 15) / 16 * 2; break; case 1024: denali->nand.ecc.bytes = (denali->nand.ecc.strength * 14 + 15) / 16 * 2; break; default: pr_err("Unsupported ECC size\n"); ret = -EINVAL; goto fail; } nand_oob.eccbytes = denali->nand.ecc.bytes; denali->nand.ecc.layout = &nand_oob; writel(mtd->erasesize / mtd->writesize, denali->flash_reg + PAGES_PER_BLOCK); writel(denali->nand.options & NAND_BUSWIDTH_16 ? 1 : 0, denali->flash_reg + DEVICE_WIDTH); writel(mtd->writesize, denali->flash_reg + DEVICE_MAIN_AREA_SIZE); writel(mtd->oobsize, denali->flash_reg + DEVICE_SPARE_AREA_SIZE); if (readl(denali->flash_reg + DEVICES_CONNECTED) == 0) writel(1, denali->flash_reg + DEVICES_CONNECTED); /* override the default operations */ denali->nand.ecc.read_page = denali_read_page; denali->nand.ecc.read_page_raw = denali_read_page_raw; denali->nand.ecc.write_page = denali_write_page; denali->nand.ecc.write_page_raw = denali_write_page_raw; denali->nand.ecc.read_oob = denali_read_oob; denali->nand.ecc.write_oob = denali_write_oob; if (nand_scan_tail(mtd)) { ret = -ENXIO; goto fail; } ret = nand_register(0, mtd); fail: return ret; }