aboutsummaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorJason <r64343@freescale.com>2009-12-08 17:51:09 +0800
committerJason <r64343@freescale.com>2009-12-08 17:51:09 +0800
commit0f8f5b5cd3ac306d4145d6c191af44dea6c8a8c0 (patch)
tree99802228e69b8a33e215d785558d2bbaf45f4cce /drivers/mtd
parent225dcaeab2ee2a5fa46bfb17f93f42a046f11c58 (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>
Diffstat (limited to 'drivers/mtd')
-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 f18e71f4a1e..5295ddb5c2b 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 470f799bd41..3dd355f0a79 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 b89b9318f37..c0c086eb441 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)