Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753144AbcCGQTd (ORCPT ); Mon, 7 Mar 2016 11:19:33 -0500 Received: from down.free-electrons.com ([37.187.137.238]:45977 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752919AbcCGQSk (ORCPT ); Mon, 7 Mar 2016 11:18:40 -0500 From: Boris Brezillon To: David Woodhouse , Brian Norris , linux-mtd@lists.infradead.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Maxime Ripard , Chen-Yu Tsai , linux-sunxi@googlegroups.com, Boris Brezillon Subject: [PATCH 06/16] mtd: nand: sunxi: implement ->read_oob()/->write_oob() Date: Mon, 7 Mar 2016 17:18:23 +0100 Message-Id: <1457367513-26069-7-git-send-email-boris.brezillon@free-electrons.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1457367513-26069-1-git-send-email-boris.brezillon@free-electrons.com> References: <1457367513-26069-1-git-send-email-boris.brezillon@free-electrons.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2738 Lines: 86 Allwinner's ECC engine is capable of protecting a few bytes of the OOB area. Implement specific OOB functions to benefit from this capability. Also, when in raw mode, the randomizer is disabled, which means you'll only be able to retrieve randomized data, which is not really useful for most applications. Signed-off-by: Boris Brezillon --- drivers/mtd/nand/sunxi_nand.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 2914785..8977a5f 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -1074,6 +1074,40 @@ static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd, return 0; } +static int sunxi_nfc_hw_common_ecc_read_oob(struct mtd_info *mtd, + struct nand_chip *chip, + int page) +{ + chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); + + chip->pagebuf = -1; + + return chip->ecc.read_page(mtd, chip, chip->buffers->databuf, 1, page); +} + +static int sunxi_nfc_hw_common_ecc_write_oob(struct mtd_info *mtd, + struct nand_chip *chip, + int page) +{ + int ret, status; + + chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0, page); + + chip->pagebuf = -1; + + memset(chip->buffers->databuf, 0xff, mtd->writesize); + ret = chip->ecc.write_page(mtd, chip, chip->buffers->databuf, 1, page); + if (ret) + return ret; + + /* Send command to program the OOB data */ + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); + + status = chip->waitfunc(mtd, chip); + + return status & NAND_STATUS_FAIL ? -EIO : 0; +} + static const s32 tWB_lut[] = {6, 12, 16, 20}; static const s32 tRHW_lut[] = {4, 8, 12, 20}; @@ -1315,6 +1349,8 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd, layout->eccbytes = (ecc->bytes * nsectors); + ecc->read_oob = sunxi_nfc_hw_common_ecc_read_oob; + ecc->write_oob = sunxi_nfc_hw_common_ecc_write_oob; ecc->layout = layout; ecc->priv = data; @@ -1346,6 +1382,8 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd, ecc->read_page = sunxi_nfc_hw_ecc_read_page; ecc->write_page = sunxi_nfc_hw_ecc_write_page; + ecc->read_oob_raw = nand_read_oob_std; + ecc->write_oob_raw = nand_write_oob_std; layout = ecc->layout; nsectors = mtd->writesize / ecc->size; @@ -1400,6 +1438,8 @@ static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd, ecc->prepad = 4; ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page; ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page; + ecc->read_oob_raw = nand_read_oob_syndrome; + ecc->write_oob_raw = nand_write_oob_syndrome; layout = ecc->layout; nsectors = mtd->writesize / ecc->size; -- 2.1.4