
Support subpage writes using a custom implementation of write_subpage. The driver loads the page into SRAM buffer using NAND_CMD_READ0, when the framework requests the NAND_CMD_SEQIN command. Then, the buffer is updated by the custom write_subpage implementation. Upon write, the controller calculates the hardware ECC across the whole page before programming the page.
This method saves transferring the whole page over the bus to the NFC IP, which would happen when using NAND_NO_SUBPAGE_WRITE.
Signed-off-by: Stefan Agner stefan@agner.ch --- This implements the procedure as discussed on the ML: http://lists.denx.de/pipermail/u-boot/2015-March/209567.html http://lists.denx.de/pipermail/u-boot/2015-March/209671.html
The drivers mxc_nand and mpc5121_nfc implement a similar subpage write.
drivers/mtd/nand/vf610_nfc.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index a8af00e..d552bed 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c @@ -566,6 +566,19 @@ static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip, return 0; }
+static int vf610_nfc_write_subpage(struct mtd_info *mtd, struct nand_chip *chip, + uint32_t offset, uint32_t data_len, + const uint8_t *buf, int oob_required) +{ + struct vf610_nfc *nfc = mtd_to_nfc(mtd); + nfc->column = offset; + vf610_nfc_write_buf(mtd, buf, data_len); + if (oob_required) + vf610_nfc_write_buf(mtd, chip->oob_poi, mtd->oobsize); + + return 0; +} + struct vf610_nfc_config { int hardware_ecc; int width; @@ -608,9 +621,6 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr) vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_16BIT); }
- /* Disable subpage writes as we do not provide ecc->hwctl */ - chip->options |= NAND_NO_SUBPAGE_WRITE; - chip->dev_ready = vf610_nfc_dev_ready; chip->cmdfunc = vf610_nfc_command; chip->read_byte = vf610_nfc_read_byte; @@ -669,6 +679,7 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr) mtd->ecclayout = chip->ecc.layout; chip->ecc.read_page = vf610_nfc_read_page; chip->ecc.write_page = vf610_nfc_write_page; + chip->ecc.write_subpage = vf610_nfc_write_subpage; chip->ecc.mode = NAND_ECC_HW;
chip->ecc.size = PAGE_2K;