From patchwork Mon May 25 09:06:17 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Barinov X-Patchwork-Id: 27603 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by bilbo.ozlabs.org (Postfix) with ESMTPS id B5B43B7063 for ; Mon, 25 May 2009 19:12:07 +1000 (EST) Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1M8W8f-0005bO-QR; Mon, 25 May 2009 09:06:33 +0000 Received: from mail-bw0-f160.google.com ([209.85.218.160]) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1M8W8W-0005bF-S6 for linux-mtd@lists.infradead.org; Mon, 25 May 2009 09:06:31 +0000 Received: by bwz4 with SMTP id 4so3422539bwz.18 for ; Mon, 25 May 2009 02:06:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer; bh=Fr1IzJhUSJYI/3jjZSGr/zBn+sEyO9jJOWRRbfHlNCY=; b=sfG1i7JqHPJc4U04zhwiJGQHGMJpjhXMDs44ckiHFsWjHVmygdtmk+cN+ct9ksMDUS ap6xarBn+XjbB/wWOoVh/Ndrz+UCE88mn7m6yGB0otd53nvEH0XfXeyDvsL69bgMa+Cq xG3wMGn4J9FkXXvtQX9TH8GDlCMSWaUwPJbds= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=jdt+o9G3nPVPBGbJrn+TvWgP/fdPeQJRdmo/ss4QLe94/Lm3OvSsYbBqEQSnP0Npu+ OCWJJaBGf8DW0ehPKXGjdtQ5CvWhlNM1TAlJDmfuyQXpbbisVY2+sV88zE5pi+U6u8R0 TA6BaN8k48zzzOTPkHPOHXFmAu5GSAFVpIfa0= Received: by 10.204.61.204 with SMTP id u12mr6706658bkh.149.1243242382746; Mon, 25 May 2009 02:06:22 -0700 (PDT) Received: from localhost.localdomain ([93.170.0.44]) by mx.google.com with ESMTPS id y15sm10798062fkd.23.2009.05.25.02.06.19 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 25 May 2009 02:06:21 -0700 (PDT) From: Vladimir Barinov To: linux-mtd@lists.infradead.org Subject: [PATCH] [MTD] MXC NAND support for 2k page size flashes Date: Mon, 25 May 2009 13:06:17 +0400 Message-Id: <1243242377-4470-1-git-send-email-vbarinov@embeddedalley.com> X-Mailer: git-send-email 1.6.0.6 X-Spam-Score: 0.0 (/) Cc: lilja.magnus@gmail.com, maramaopercheseimorto@gmail.com, s.hauer@pengutronix.de, lanconelli.claudio@eptar.com, linux-arm-kernel@lists.arm.linux.org.uk X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org - Add support for 2k page size flashes - Fix page address access for large pages - Detect oob layout at runtime - handle pagesize_2k variable - Fix oob16 layout: reserve location 5 of oob area since it's used for bbt Signed-off-by: Vladimir Barinov --- drivers/mtd/nand/mxc_nand.c | 60 ++++++++++++++++++++++++++++++++++++------ 1 files changed, 51 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index f3548d0..5ab8985 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -138,7 +138,14 @@ static struct nand_ecclayout nand_hw_eccoob_8 = { static struct nand_ecclayout nand_hw_eccoob_16 = { .eccbytes = 5, .eccpos = {6, 7, 8, 9, 10}, - .oobfree = {{0, 6}, {12, 4}, } + .oobfree = {{0, 5}, {11, 5}, } +}; + +static struct nand_ecclayout nand_hw_eccoob_64 = { + .eccbytes = 20, + .eccpos = {6, 7, 8, 9, 10, 22, 23, 24, 25, 26, + 38, 39, 40, 41, 42, 54, 55, 56, 57, 58}, + .oobfree = {{2, 4}, {11, 10}, {27, 10}, {43, 10}, {59, 5}, } }; #ifdef CONFIG_MTD_PARTITIONS @@ -795,9 +802,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, send_addr(host, (page_addr & 0xff), false); if (host->pagesize_2k) { - send_addr(host, (page_addr >> 8) & 0xFF, false); - if (mtd->size >= 0x40000000) + if (mtd->size >= 0x10000000) { + /* paddr_8 - paddr_15 */ + send_addr(host, (page_addr >> 8) & 0xff, false); send_addr(host, (page_addr >> 16) & 0xff, true); + } else + /* paddr_8 - paddr_15 */ + send_addr(host, (page_addr >> 8) & 0xff, true); } else { /* One more address cycle for higher density devices */ if (mtd->size >= 0x4000000) { @@ -919,7 +930,6 @@ static int __init mxcnd_probe(struct platform_device *pdev) this->ecc.mode = NAND_ECC_HW; this->ecc.size = 512; this->ecc.bytes = 3; - this->ecc.layout = &nand_hw_eccoob_8; tmp = readw(host->regs + NFC_CONFIG1); tmp |= NFC_ECC_EN; writew(tmp, host->regs + NFC_CONFIG1); @@ -953,12 +963,44 @@ static int __init mxcnd_probe(struct platform_device *pdev) this->ecc.layout = &nand_hw_eccoob_16; } - host->pagesize_2k = 0; + /* first scan to find the device and get the page size */ + if (nand_scan_ident(mtd, 1)) { + err = -ENXIO; + goto escan; + } - /* Scan to find existence of the device */ - if (nand_scan(mtd, 1)) { - DEBUG(MTD_DEBUG_LEVEL0, - "MXC_ND: Unable to find any NAND device.\n"); + host->pagesize_2k = (mtd->writesize == 2048) ? 1 : 0; + + if (this->ecc.mode == NAND_ECC_HW) { + switch (mtd->oobsize) { + case 8: + this->ecc.layout = &nand_hw_eccoob_8; + break; + case 16: + this->ecc.layout = &nand_hw_eccoob_16; + break; + case 64: + this->ecc.layout = &nand_hw_eccoob_64; + break; + default: + /* page size not handled by HW ECC */ + /* switching back to soft ECC */ + this->ecc.size = 512; + this->ecc.bytes = 3; + this->ecc.layout = &nand_hw_eccoob_8; + this->ecc.mode = NAND_ECC_SOFT; + this->ecc.calculate = NULL; + this->ecc.correct = NULL; + this->ecc.hwctl = NULL; + tmp = readw(host->regs + NFC_CONFIG1); + tmp &= ~NFC_ECC_EN; + writew(tmp, host->regs + NFC_CONFIG1); + break; + } + } + + /* second phase scan */ + if (nand_scan_tail(mtd)) { err = -ENXIO; goto escan; }