Patchwork [3/5] mtd/nand/denali.c: enabled multi connected NAND feature

login
register
mail settings
Submitter Dong, Chuanxiao
Date July 12, 2010, 9:04 a.m.
Message ID <5D8008F58939784290FAB48F549751981D09B718B5@shsmsx502.ccr.corp.intel.com>
Download mbox | patch
Permalink /patch/58602/
State New
Headers show

Comments

Dong, Chuanxiao - July 12, 2010, 9:04 a.m.
From e82af5ab049d25233709f998464f7813f4fc2ca1 Mon Sep 17 00:00:00 2001
From: Chuanxiao Dong <chuanxiao.dong@intel.com>
Date: Mon, 21 Jun 2010 18:34:30 +0800
Subject: [PATCH 3/5] [MTD/denali] enabled multi connected NAND feature

Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.com>
---
 drivers/mtd/nand/denali.c |   28 +++++++++++++++++++++++++---
 drivers/mtd/nand/denali.h |    2 ++
 2 files changed, 27 insertions(+), 3 deletions(-)

Patch

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index fbdd9f0..57818eb 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1415,8 +1415,9 @@  static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
 				   sector number * sector size + offset in
 				   sector
 				 */
-				int offset = err_sector * ECC_SECTOR_SIZE +
-								err_byte;
+				int offset = (err_sector * ECC_SECTOR_SIZE +
+						err_byte) * denali->devnum +
+						err_device;
 				if (offset < denali->mtd.writesize) {
 					/* correct the ECC error */
 					buf[offset] ^= err_correction_value;
@@ -2032,6 +2033,27 @@  static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 		goto failed_nand;
 	}
 
+	/* support for multi nand
+	 * MTD known nothing about multi nand,
+	 * so we should tell it the real pagesize
+	 * and anything necessery,
+	 * Some NAND chip has a spectial OOB size, so here do
+	 * a recheck */
+	denali->mtd.oobsize = ioread32(denali->flash_reg +
+						DEVICE_SPARE_AREA_SIZE);
+	denali->devnum = ioread32(denali->flash_reg + DEVICES_CONNECTED);
+	denali->nand.chipsize <<= (denali->devnum - 1);
+	denali->nand.page_shift += (denali->devnum - 1);
+	denali->nand.pagemask = (denali->nand.chipsize >>
+						denali->nand.page_shift) - 1;
+	denali->nand.bbt_erase_shift += (denali->devnum - 1);
+	denali->nand.phys_erase_shift = denali->nand.bbt_erase_shift;
+	denali->nand.chip_shift += (denali->devnum - 1);
+	denali->mtd.writesize <<= (denali->devnum - 1);
+	denali->mtd.oobsize <<= (denali->devnum - 1);
+	denali->mtd.erasesize <<= (denali->devnum - 1);
+	denali->mtd.size = denali->nand.numchips * denali->nand.chipsize;
+
 	/* second stage of the NAND scan
 	 * this stage requires information regarding ECC and
 	 * bad block management. */
@@ -2060,7 +2082,7 @@  static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	denali->nand.ecc.hwctl = denali_ecc_hwctl;
 
 	/* override the default read operations */
-	denali->nand.ecc.size = denali->mtd.writesize;
+	denali->nand.ecc.size = denali->mtd.writesize * denali->devnum;
 	denali->nand.ecc.read_page = denali_read_page;
 	denali->nand.ecc.read_page_raw = denali_read_page_raw;
 	denali->nand.ecc.write_page = denali_write_page;
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index fc6be39..2bee4cb 100644
--- a/drivers/mtd/nand/denali.h
+++ b/drivers/mtd/nand/denali.h
@@ -802,6 +802,8 @@  struct denali_nand_info {
 	uint32_t irq_status;
 	int irq_debug_array[32];
 	int idx;
+
+	uint32_t devnum;	/* represent how many nands connected */
 };
 
 #endif /*_LLD_NAND_*/