summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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)