Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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(&param,&using_way);
	if(using_way==1)		//use old way
	{
		tran_old_burnway(&param);
	}
#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;
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}