summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason <r64343@freescale.com>2009-12-08 17:51:09 +0800
committerJustin Waters <justin.waters@timesys.com>2010-03-25 14:01:37 -0400
commitbe62816bfbc56e39a3c0ae065b5f4f8ec35b0b5a (patch)
tree99802228e69b8a33e215d785558d2bbaf45f4cce
parent583c06a1dc3da6e040f5891f8673b9cae280d5e8 (diff)
ENGR00118830 Update NAND driver scan scheme to support new nand type
Update NAND scan scheme to support new nand type. With this patch Linux NAND driver can support new NAND flash on mx25/mx35 board while compatible with old NAND on old boards. Signed-off-by: Jason Liu <r64343@freescale.com>
-rw-r--r--drivers/mtd/nand/Makefile4
-rw-r--r--drivers/mtd/nand/mxc_nd2.c76
-rw-r--r--drivers/mtd/nand/mxc_nd2.h21
3 files changed, 79 insertions, 22 deletions
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index f18e71f4a1eb..5295ddb5c2bf 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -39,8 +39,8 @@ obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o
obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o
obj-$(CONFIG_MTD_NAND_IMX_NFC) += imx_nfc.o
obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o
-obj-$(CONFIG_MTD_NAND_MXC_V2) += mxc_nd2.o
-obj-$(CONFIG_MTD_NAND_MXC_V3) += mxc_nd2.o
+obj-$(CONFIG_MTD_NAND_MXC_V2) += mxc_nd2.o gpmi/nand_device_info.o
+obj-$(CONFIG_MTD_NAND_MXC_V3) += mxc_nd2.o gpmi/nand_device_info.o
obj-$(CONFIG_MTD_NAND_GPMI) += gpmi/
obj-$(CONFIG_MTD_NAND_GPMI_LBA) += lba/
obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o
diff --git a/drivers/mtd/nand/mxc_nd2.c b/drivers/mtd/nand/mxc_nd2.c
index 470f799bd41c..3dd355f0a79a 100644
--- a/drivers/mtd/nand/mxc_nd2.c
+++ b/drivers/mtd/nand/mxc_nd2.c
@@ -26,6 +26,7 @@
#include <asm/mach/flash.h>
#include <asm/io.h>
#include "mxc_nd2.h"
+#include "gpmi/nand_device_info.h"
#define DVR_VER "2.5"
@@ -1093,16 +1094,6 @@ static int mxc_nand_scan_bbt(struct mtd_info *mtd)
g_page_mask = this->pagemask;
- /* limit to 2G size due to Kernel
- * larger 4G space support,need fix
- * it later
- */
- if (mtd->size == 0) {
- mtd->size = 1 << 31;
- this->numchips = 1;
- this->chipsize = mtd->size;
- }
-
if (IS_2K_PAGE_NAND) {
NFC_SET_NFMS(1 << NFMS_NF_PG_SZ);
this->ecc.layout = &nand_hw_eccoob_2k;
@@ -1185,6 +1176,63 @@ static void mxc_free_buf(void)
kfree(oob_buf);
}
+int nand_scan_mid(struct mtd_info *mtd)
+{
+ int i;
+ uint8_t id_bytes[NAND_DEVICE_ID_BYTE_COUNT];
+ struct nand_chip *this = mtd->priv;
+ struct nand_device_info *dev_info;
+
+ if (!IS_LARGE_PAGE_NAND)
+ return 0;
+
+ /* Read ID bytes from the first NAND Flash chip. */
+ this->select_chip(mtd, 0);
+
+ this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
+
+ for (i = 0; i < NAND_DEVICE_ID_BYTE_COUNT; i++)
+ id_bytes[i] = this->read_byte(mtd);
+
+ /* Get information about this device, based on the ID bytes. */
+ dev_info = nand_device_get_info(id_bytes);
+
+ /* Check if we understand this device. */
+ if (!dev_info) {
+ printk(KERN_ERR "Unrecognized NAND Flash device.\n");
+ return !0;
+ }
+
+ /* Correct mtd setting */
+ this->chipsize = dev_info->chip_size_in_bytes;
+ mtd->size = dev_info->chip_size_in_bytes * this->numchips;
+ mtd->writesize = dev_info->page_total_size_in_bytes & ~0x3ff;
+ mtd->oobsize = dev_info->page_total_size_in_bytes & 0x3ff;
+ mtd->erasesize = dev_info->block_size_in_pages * mtd->writesize;
+
+ /* limit to 2G size due to Kernel
+ * larger 4G space support,need fix
+ * it later
+ */
+ if ((u32)mtd->size == 0) {
+ mtd->size = (u32)(1 << 31);
+ this->numchips = 1;
+ this->chipsize = mtd->size;
+ }
+
+ /* Calculate the address shift from the page size */
+ this->page_shift = ffs(mtd->writesize) - 1;
+ /* Convert chipsize to number of pages per chip -1. */
+ this->pagemask = (this->chipsize >> this->page_shift) - 1;
+
+ this->bbt_erase_shift = this->phys_erase_shift =
+ ffs(mtd->erasesize) - 1;
+ this->chip_shift = ffs(this->chipsize) - 1;
+
+ return 0;
+}
+
+
/*!
* This function is called during the driver binding process.
*
@@ -1284,7 +1332,9 @@ static int __init mxcnd_probe(struct platform_device *pdev)
this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
/* Scan to find existence of the device */
- if (nand_scan(mtd, NFC_GET_MAXCHIP_SP())) {
+ if (nand_scan_ident(mtd, NFC_GET_MAXCHIP_SP())
+ || nand_scan_mid(mtd)
+ || nand_scan_tail(mtd)) {
DEBUG(MTD_DEBUG_LEVEL0,
"MXC_ND2: Unable to find any NAND device.\n");
err = -ENXIO;
@@ -1363,8 +1413,6 @@ static int __exit mxcnd_remove(struct platform_device *pdev)
static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct mtd_info *info = platform_get_drvdata(pdev);
-
DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND2 : NAND suspend\n");
/* Disable the NFC clock */
@@ -1384,8 +1432,6 @@ static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state)
*/
static int mxcnd_resume(struct platform_device *pdev)
{
- struct mtd_info *info = platform_get_drvdata(pdev);
-
DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND2 : NAND resume\n");
/* Enable the NFC clock */
diff --git a/drivers/mtd/nand/mxc_nd2.h b/drivers/mtd/nand/mxc_nd2.h
index b89b9318f372..c0c086eb4414 100644
--- a/drivers/mtd/nand/mxc_nd2.h
+++ b/drivers/mtd/nand/mxc_nd2.h
@@ -562,11 +562,22 @@ do { \
} while (0)
#define GET_ECC_STATUS() __raw_readl(REG_NFC_ECC_STATUS_RESULT);
-#define NFC_SET_NFMS(v) \
-do { \
- (NFMS |= (v)); \
- if (((v) & (1 << NFMS_NF_PG_SZ))) { \
- NFC_SET_SPAS(GET_NAND_OOB_SIZE >> 1); \
+#define NFC_SET_NFMS(v) \
+do { \
+ if (((v) & (1 << NFMS_NF_PG_SZ))) { \
+ if (IS_2K_PAGE_NAND) { \
+ (NFMS |= 0x00000100); \
+ (NFMS &= ~0x00000200); \
+ NFC_SET_SPAS(NFC_SPAS_64); \
+ } else if (IS_4K_PAGE_NAND) { \
+ (NFMS &= ~0x00000100); \
+ (NFMS |= 0x00000200); \
+ GET_NAND_OOB_SIZE == 128 ? \
+ NFC_SET_SPAS(NFC_SPAS_128) : \
+ NFC_SET_SPAS(NFC_SPAS_218); \
+ } else { \
+ printk(KERN_ERR "Err for setting page/oob size"); \
+ } \
NFC_SET_ECC_MODE(GET_NAND_OOB_SIZE >> 1); \
} \
} while (0)