Lines Matching +full:spare +full:- +full:regs

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright 2004-2008 Freescale Semiconductor, Inc.
34 /* Addresses for NFC SPARE BUFFER areas */
110 void __iomem *regs; member
127 return in_be16(prv->regs + reg); in nfc_read()
136 out_be16(prv->regs + reg, val); in nfc_write()
207 wake_up(&prv->irq_waitq); in mpc5121_nfc_irq()
221 rv = wait_event_timeout(prv->irq_waitq, in mpc5121_nfc_done()
225 dev_warn(prv->dev, in mpc5121_nfc_done()
236 u32 pagemask = chip->pagemask; in mpc5121_nfc_addr_cycle()
238 if (column != -1) { in mpc5121_nfc_addr_cycle()
240 if (mtd->writesize > 512) in mpc5121_nfc_addr_cycle()
244 if (page != -1) { in mpc5121_nfc_addr_cycle()
276 dn = of_find_compatible_node(NULL, NULL, "fsl,mpc5121ads-cpld"); in ads5121_chipselect_init()
278 prv->csreg = of_iomap(dn, 0); in ads5121_chipselect_init()
280 if (!prv->csreg) in ads5121_chipselect_init()
281 return -ENOMEM; in ads5121_chipselect_init()
284 prv->csreg += 9; in ads5121_chipselect_init()
288 return -EINVAL; in ads5121_chipselect_init()
297 v = in_8(prv->csreg); in ads5121_select_chip()
304 mpc5121_nfc_select_chip(nand, -1); in ads5121_select_chip()
306 out_8(prv->csreg, v); in ads5121_select_chip()
326 prv->column = (column >= 0) ? column : 0; in mpc5121_nfc_command()
327 prv->spareonly = 0; in mpc5121_nfc_command()
334 * NFC does not support sub-page reads and writes, in mpc5121_nfc_command()
342 prv->column += 256; in mpc5121_nfc_command()
348 prv->spareonly = 1; in mpc5121_nfc_command()
373 if (mtd->writesize > 512) in mpc5121_nfc_command()
384 if (chip->options & NAND_BUSWIDTH_16) in mpc5121_nfc_command()
385 prv->column = 1; in mpc5121_nfc_command()
387 prv->column = 0; in mpc5121_nfc_command()
392 /* Copy data from/to NFC spare buffers. */
401 * NAND spare area is available through NFC spare buffers. in mpc5121_nfc_copy_spare()
402 * The NFC divides spare area into (page_size / 512) chunks. in mpc5121_nfc_copy_spare()
403 * Each chunk is placed into separate spare memory area, using in mpc5121_nfc_copy_spare()
406 * For NAND device in which the spare area is not divided fully in mpc5121_nfc_copy_spare()
407 * by the number of chunks, number of used bytes in each spare in mpc5121_nfc_copy_spare()
409 * and all remaining bytes are added to the last used spare area. in mpc5121_nfc_copy_spare()
415 /* Calculate number of valid bytes in each spare buffer */ in mpc5121_nfc_copy_spare()
416 sbsize = (mtd->oobsize / (mtd->writesize / 512)) & ~1; in mpc5121_nfc_copy_spare()
419 /* Calculate spare buffer number */ in mpc5121_nfc_copy_spare()
421 if (s > NFC_SPARE_BUFFERS - 1) in mpc5121_nfc_copy_spare()
422 s = NFC_SPARE_BUFFERS - 1; in mpc5121_nfc_copy_spare()
425 * Calculate offset to requested data block in selected spare in mpc5121_nfc_copy_spare()
428 o = offset - (s * sbsize); in mpc5121_nfc_copy_spare()
429 blksize = min(sbsize - o, size); in mpc5121_nfc_copy_spare()
432 memcpy_toio(prv->regs + NFC_SPARE_AREA(s) + o, in mpc5121_nfc_copy_spare()
436 prv->regs + NFC_SPARE_AREA(s) + o, blksize); in mpc5121_nfc_copy_spare()
440 size -= blksize; in mpc5121_nfc_copy_spare()
444 /* Copy data from/to NFC main and spare buffers */
450 uint c = prv->column; in mpc5121_nfc_buf_copy()
453 /* Handle spare area access */ in mpc5121_nfc_buf_copy()
454 if (prv->spareonly || c >= mtd->writesize) { in mpc5121_nfc_buf_copy()
455 /* Calculate offset from beginning of spare area */ in mpc5121_nfc_buf_copy()
456 if (c >= mtd->writesize) in mpc5121_nfc_buf_copy()
457 c -= mtd->writesize; in mpc5121_nfc_buf_copy()
459 prv->column += len; in mpc5121_nfc_buf_copy()
465 * Handle main area access - limit copy length to prevent in mpc5121_nfc_buf_copy()
466 * crossing main/spare boundary. in mpc5121_nfc_buf_copy()
468 l = min((uint)len, mtd->writesize - c); in mpc5121_nfc_buf_copy()
469 prv->column += l; in mpc5121_nfc_buf_copy()
472 memcpy_toio(prv->regs + NFC_MAIN_AREA(0) + c, buf, l); in mpc5121_nfc_buf_copy()
474 memcpy_fromio(buf, prv->regs + NFC_MAIN_AREA(0) + c, l); in mpc5121_nfc_buf_copy()
476 /* Handle crossing main/spare boundary */ in mpc5121_nfc_buf_copy()
479 len -= l; in mpc5121_nfc_buf_copy()
512 * size, spare size and bus width.
527 rmnode = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-reset"); in mpc5121_nfc_read_hw_config()
529 dev_err(prv->dev, "Missing 'fsl,mpc5121-reset' " in mpc5121_nfc_read_hw_config()
531 return -ENODEV; in mpc5121_nfc_read_hw_config()
536 dev_err(prv->dev, "Error mapping reset module node!\n"); in mpc5121_nfc_read_hw_config()
537 ret = -EBUSY; in mpc5121_nfc_read_hw_config()
541 rcwh = in_be32(&rm->rcwhr); in mpc5121_nfc_read_hw_config()
546 /* Bit 7: NFC Page/Spare size */ in mpc5121_nfc_read_hw_config()
576 mtd->writesize = rcw_pagesize; in mpc5121_nfc_read_hw_config()
577 mtd->oobsize = rcw_sparesize; in mpc5121_nfc_read_hw_config()
579 chip->options |= NAND_BUSWIDTH_16; in mpc5121_nfc_read_hw_config()
581 dev_notice(prv->dev, "Configured for " in mpc5121_nfc_read_hw_config()
582 "%u-bit NAND, page size %u " in mpc5121_nfc_read_hw_config()
583 "with %u spare.\n", in mpc5121_nfc_read_hw_config()
598 clk_disable_unprepare(prv->clk); in mpc5121_nfc_free()
600 if (prv->csreg) in mpc5121_nfc_free()
601 iounmap(prv->csreg); in mpc5121_nfc_free()
606 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && in mpc5121_nfc_attach_chip()
607 chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) in mpc5121_nfc_attach_chip()
608 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in mpc5121_nfc_attach_chip()
619 struct device_node *dn = op->dev.of_node; in mpc5121_nfc_probe()
621 struct device *dev = &op->dev; in mpc5121_nfc_probe()
639 return -ENXIO; in mpc5121_nfc_probe()
644 return -ENOMEM; in mpc5121_nfc_probe()
646 chip = &prv->chip; in mpc5121_nfc_probe()
649 nand_controller_init(&prv->controller); in mpc5121_nfc_probe()
650 prv->controller.ops = &mpc5121_nfc_ops; in mpc5121_nfc_probe()
651 chip->controller = &prv->controller; in mpc5121_nfc_probe()
653 mtd->dev.parent = dev; in mpc5121_nfc_probe()
656 prv->dev = dev; in mpc5121_nfc_probe()
665 prv->irq = irq_of_parse_and_map(dn, 0); in mpc5121_nfc_probe()
666 if (prv->irq == NO_IRQ) { in mpc5121_nfc_probe()
668 return -EINVAL; in mpc5121_nfc_probe()
680 return -EINVAL; in mpc5121_nfc_probe()
688 return -EBUSY; in mpc5121_nfc_probe()
691 prv->regs = devm_ioremap(dev, regs_paddr, regs_size); in mpc5121_nfc_probe()
692 if (!prv->regs) { in mpc5121_nfc_probe()
694 return -ENOMEM; in mpc5121_nfc_probe()
697 mtd->name = "MPC5121 NAND"; in mpc5121_nfc_probe()
698 chip->legacy.dev_ready = mpc5121_nfc_dev_ready; in mpc5121_nfc_probe()
699 chip->legacy.cmdfunc = mpc5121_nfc_command; in mpc5121_nfc_probe()
700 chip->legacy.read_byte = mpc5121_nfc_read_byte; in mpc5121_nfc_probe()
701 chip->legacy.read_buf = mpc5121_nfc_read_buf; in mpc5121_nfc_probe()
702 chip->legacy.write_buf = mpc5121_nfc_write_buf; in mpc5121_nfc_probe()
703 chip->legacy.select_chip = mpc5121_nfc_select_chip; in mpc5121_nfc_probe()
704 chip->legacy.set_features = nand_get_set_features_notsupp; in mpc5121_nfc_probe()
705 chip->legacy.get_features = nand_get_set_features_notsupp; in mpc5121_nfc_probe()
706 chip->bbt_options = NAND_BBT_USE_FLASH; in mpc5121_nfc_probe()
708 /* Support external chip-select logic on ADS5121 board */ in mpc5121_nfc_probe()
716 chip->legacy.select_chip = ads5121_select_chip; in mpc5121_nfc_probe()
731 prv->clk = clk; in mpc5121_nfc_probe()
738 retval = -EINVAL; in mpc5121_nfc_probe()
755 * - Big Endian transfers, in mpc5121_nfc_probe()
756 * - Interrupt after full page read/write. in mpc5121_nfc_probe()
761 /* Set spare area size */ in mpc5121_nfc_probe()
762 nfc_write(mtd, NFC_SPAS, mtd->oobsize >> 1); in mpc5121_nfc_probe()
764 init_waitqueue_head(&prv->irq_waitq); in mpc5121_nfc_probe()
765 retval = devm_request_irq(dev, prv->irq, &mpc5121_nfc_irq, 0, DRV_NAME, in mpc5121_nfc_probe()
774 * Set ->engine_type before registering the NAND devices in order to in mpc5121_nfc_probe()
777 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in mpc5121_nfc_probe()
787 switch (mtd->erasesize / mtd->writesize) { in mpc5121_nfc_probe()
806 retval = -ENXIO; in mpc5121_nfc_probe()
827 struct device *dev = &op->dev; in mpc5121_nfc_remove()
840 { .compatible = "fsl,mpc5121-nfc", },