diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/Makefile | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/mxc_nd2.c | 76 | ||||
-rw-r--r-- | drivers/mtd/nand/mxc_nd2.h | 21 |
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) |