nand_wait_ready(mtd);
}
+static void nand_ccs_delay(struct nand_chip *chip)
+{
+ /*
+ * The controller already takes care of waiting for tCCS when the RNDIN
+ * or RNDOUT command is sent, return directly.
+ */
+ if (!(chip->options & NAND_WAIT_TCCS))
+ return;
+
+ /*
+ * Wait tCCS_min if it is correctly defined, otherwise wait 500ns
+ * (which should be safe for all NANDs).
+ */
+ if (chip->data_interface && chip->data_interface->timings.sdr.tCCS_min)
+ ndelay(chip->data_interface->timings.sdr.tCCS_min / 1000);
+ else
+ ndelay(500);
+}
+
/**
* nand_command_lp - [DEFAULT] Send command to NAND large page device
* @mtd: MTD device structure
column >>= 1;
chip->cmd_ctrl(mtd, column, ctrl);
ctrl &= ~NAND_CTRL_CHANGE;
- chip->cmd_ctrl(mtd, column >> 8, ctrl);
+
+ /* Only output a single addr cycle for 8bits opcodes. */
+ if (!nand_opcode_8bits(command))
+ chip->cmd_ctrl(mtd, column >> 8, ctrl);
}
if (page_addr != -1) {
chip->cmd_ctrl(mtd, page_addr, ctrl);
case NAND_CMD_ERASE1:
case NAND_CMD_ERASE2:
case NAND_CMD_SEQIN:
- case NAND_CMD_RNDIN:
case NAND_CMD_STATUS:
return;
+ case NAND_CMD_RNDIN:
+ nand_ccs_delay(chip);
+ return;
+
case NAND_CMD_RESET:
if (chip->dev_ready)
break;
NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
chip->cmd_ctrl(mtd, NAND_CMD_NONE,
NAND_NCE | NAND_CTRL_CHANGE);
+
+ nand_ccs_delay(chip);
return;
case NAND_CMD_READ0:
if (ecc_step > 0)
chip->ecc.size = ecc_step;
+ if (of_property_read_bool(dn, "nand-ecc-maximize"))
+ chip->ecc.options |= NAND_ECC_MAXIMIZE;
+
return 0;
}
ecc->write_page_raw = nand_write_page_raw;
ecc->read_oob = nand_read_oob_std;
ecc->write_oob = nand_write_oob_std;
+
/*
* Board driver should supply ecc.size and ecc.strength
* values to select how many bits are correctable.
}
mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
+
+ }
+
+ /*
+ * We can only maximize ECC config when the default layout is
+ * used, otherwise we don't know how many bytes can really be
+ * used.
+ */
+ if (mtd->ooblayout == &nand_ooblayout_lp_ops &&
+ ecc->options & NAND_ECC_MAXIMIZE) {
+ int steps, bytes;
+
+ /* Always prefer 1k blocks over 512bytes ones */
+ ecc->size = 1024;
+ steps = mtd->writesize / ecc->size;
+
+ /* Reserve 2 bytes for the BBM */
+ bytes = (mtd->oobsize - 2) / steps;
+ ecc->strength = bytes * 8 / fls(8 * ecc->size);
}
/* See nand_bch_init() for details. */
EXPORT_SYMBOL(nand_scan);
/**
- * nand_release - [NAND Interface] Free resources held by the NAND device
- * @mtd: MTD device structure
+ * nand_cleanup - [NAND Interface] Free resources held by the NAND device
+ * @chip: NAND chip object
*/
-void nand_release(struct mtd_info *mtd)
+void nand_cleanup(struct nand_chip *chip)
{
- struct nand_chip *chip = mtd_to_nand(mtd);
-
if (chip->ecc.mode == NAND_ECC_SOFT &&
chip->ecc.algo == NAND_ECC_BCH)
nand_bch_free((struct nand_bch_control *)chip->ecc.priv);
- mtd_device_unregister(mtd);
-
nand_release_data_interface(chip);
/* Free bad block table memory */
& NAND_BBT_DYNAMICSTRUCT)
kfree(chip->badblock_pattern);
}
+EXPORT_SYMBOL_GPL(nand_cleanup);
+
+/**
+ * nand_release - [NAND Interface] Unregister the MTD device and free resources
+ * held by the NAND device
+ * @mtd: MTD device structure
+ */
+void nand_release(struct mtd_info *mtd)
+{
+ mtd_device_unregister(mtd);
+ nand_cleanup(mtd_to_nand(mtd));
+}
EXPORT_SYMBOL_GPL(nand_release);
MODULE_LICENSE("GPL");