From 5c2fffec7406f81988824933bf55a97bb66ff2f0 Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 15 Dec 2009 11:44:37 +0800 Subject: ENGR00119324 Put GPMI NAND flash scan scheme code to the common NAND directory 1.GPMI NAND flash scan scheme can overcome the shortcomings of MTD NAND community code. 2.Put it to the common NAND directory can benifit I.MX NAND driver besides GPMI NAND driver. 3.Fix the section mismatch build warnings on ALL platforms. 4.Fix the kbuild build errors of I.MX platforms. Signed-off-by:Jason Liu --- drivers/mtd/nand/Makefile | 6 +- drivers/mtd/nand/gpmi/Makefile | 1 - drivers/mtd/nand/gpmi/gpmi-base.c | 2 +- drivers/mtd/nand/gpmi/gpmi.h | 2 +- drivers/mtd/nand/gpmi/nand_device_info.c | 2297 ------------------------------ drivers/mtd/nand/gpmi/nand_device_info.h | 140 -- drivers/mtd/nand/mxc_nd2.c | 2 +- drivers/mtd/nand/nand_device_info.c | 2297 ++++++++++++++++++++++++++++++ drivers/mtd/nand/nand_device_info.h | 140 ++ 9 files changed, 2443 insertions(+), 2444 deletions(-) delete mode 100644 drivers/mtd/nand/gpmi/nand_device_info.c delete mode 100644 drivers/mtd/nand/gpmi/nand_device_info.h create mode 100644 drivers/mtd/nand/nand_device_info.c create mode 100644 drivers/mtd/nand/nand_device_info.h diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 5295ddb5c2bf..226015b9a0b0 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -39,9 +39,9 @@ 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 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_MXC_V2) += mxc_nd2.o nand_device_info.o +obj-$(CONFIG_MTD_NAND_MXC_V3) += mxc_nd2.o nand_device_info.o +obj-$(CONFIG_MTD_NAND_GPMI) += gpmi/ nand_device_info.o obj-$(CONFIG_MTD_NAND_GPMI_LBA) += lba/ obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o diff --git a/drivers/mtd/nand/gpmi/Makefile b/drivers/mtd/nand/gpmi/Makefile index 175327c330d5..4a4b50d294fa 100644 --- a/drivers/mtd/nand/gpmi/Makefile +++ b/drivers/mtd/nand/gpmi/Makefile @@ -4,4 +4,3 @@ gpmi-objs += gpmi-hamming-22-16.o gpmi-objs += gpmi-hamming-13-8.o gpmi-objs += gpmi-bch.o gpmi-objs += gpmi-ecc8.o -gpmi-objs += nand_device_info.o diff --git a/drivers/mtd/nand/gpmi/gpmi-base.c b/drivers/mtd/nand/gpmi/gpmi-base.c index 035d2e6dcd66..98acd9019b66 100644 --- a/drivers/mtd/nand/gpmi/gpmi-base.c +++ b/drivers/mtd/nand/gpmi/gpmi-base.c @@ -41,7 +41,7 @@ #include #include #include "gpmi.h" -#include "nand_device_info.h" +#include "../nand_device_info.h" /* Macro definitions for the i.MX23. Some will be different for other SoC's. */ diff --git a/drivers/mtd/nand/gpmi/gpmi.h b/drivers/mtd/nand/gpmi/gpmi.h index 5c0b6691c654..6d107bd87688 100644 --- a/drivers/mtd/nand/gpmi/gpmi.h +++ b/drivers/mtd/nand/gpmi/gpmi.h @@ -30,7 +30,7 @@ #include #include "gpmi-hamming-22-16.h" -#include "nand_device_info.h" +#include "../nand_device_info.h" #define GPMI_ECC4_WR \ (BM_GPMI_ECCCTRL_ENABLE_ECC | \ diff --git a/drivers/mtd/nand/gpmi/nand_device_info.c b/drivers/mtd/nand/gpmi/nand_device_info.c deleted file mode 100644 index ba3ed9e01bd1..000000000000 --- a/drivers/mtd/nand/gpmi/nand_device_info.c +++ /dev/null @@ -1,2297 +0,0 @@ -/* - * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include - -#include "nand_device_info.h" - -/* - * Type 2 - */ -static struct nand_device_info nand_device_info_table_type_2[] __initdata = -{ - { - .end_of_table = false, - .manufacturer_code = 0x20, - .device_code = 0xf1, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 128LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 30, - .data_hold_in_ns = 20, - .address_setup_in_ns = 25, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "NAND01GW3", - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xf1, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 128LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 30, - .address_setup_in_ns = 25, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xf1, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 128LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 30, - .data_hold_in_ns = 20, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xf1, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 128LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 35, - .data_hold_in_ns = 25, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9F1F08", - }, - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xf1, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 128LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 30, - .data_hold_in_ns = 20, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "TC58NVG0S3", - }, - { - .end_of_table = false, - .manufacturer_code = 0x45, - .device_code = 0xf1, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 128LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 32, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0x20, - .device_code = 0xda, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 256LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 30, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "NAND02GW3", - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xda, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 256LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 30, - .data_hold_in_ns = 25, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "HY27UF082G2M, HY27UG082G2M, HY27UG082G1M", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xda, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 256LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 10, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "MT29F2G08", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xda, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 256LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9F2G08U0M", - }, - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xda, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 256LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 30, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "TC58NVG1S3", - }, - { - .end_of_table = false, - .manufacturer_code = 0x45, - .device_code = 0xda, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 256LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 32, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0x20, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 30, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 30, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 10, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "HY27UH084G2M, HY27UG084G2M, HY27UH084G1M", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 10, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "MT29F4G08", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 25, - .data_hold_in_ns = 25, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 25, - .data_hold_in_ns = 25, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "TH58NVG2S3", - }, - { - .end_of_table = false, - .manufacturer_code = 0x45, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 32, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 30, - .data_hold_in_ns = 25, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "HY27UH088G2M", - }, - { - .end_of_table = false, - .manufacturer_code = 0x20, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 30, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "NAND08GW3BxANx", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 25, - .data_hold_in_ns = 15, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "MT29F8G08FABWG", - }, - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 32, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0x20, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 30, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 25, - .data_hold_in_ns = 30, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 32, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - {true} -}; - -/* - * Large MLC - */ -static struct nand_device_info nand_device_info_table_large_mlc[] __initdata = -{ - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xda, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 256LL*SZ_1M, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 30, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "TC58NVG1D4BFT00", - }, - { - .end_of_table = false, - .manufacturer_code = 0x45, - .device_code = 0xda, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 256LL*SZ_1M, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 30, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0x45, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 30, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 35, - .data_hold_in_ns = 30, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "TH58NVG3D4xFT00", - }, - { - .end_of_table = false, - .manufacturer_code = 0x45, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 35, - .data_hold_in_ns = 20, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 35, - .data_hold_in_ns = 15, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "TH58NVG4D4xFT00", - }, - { - .end_of_table = false, - .manufacturer_code = 0x45, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 35, - .data_hold_in_ns = 15, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 30, - .address_setup_in_ns = 0, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "TC58NVG2D4BFT00", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 25, - .data_hold_in_ns = 15, - .address_setup_in_ns = 25, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9G4G08U0M", - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 45, - .data_hold_in_ns = 25, - .address_setup_in_ns = 50, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "HY27UT084G2M, HY27UU088G5M", - }, - { - .end_of_table = false, - .manufacturer_code = 0x20, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 40, - .data_hold_in_ns = 20, - .address_setup_in_ns = 30, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "NAND04GW3C2AN1E", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 15, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9G8G08U0M, K9HAG08U1M", - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 60, - .data_hold_in_ns = 30, - .address_setup_in_ns = 50, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "HY27UV08AG5M", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 15, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "Intel JS29F08G08AAMiB1 and Micron MT29F8G08MAA; " - "Intel JS29F08G08CAMiB1 and Micron MT29F16G08QAA", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 15, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9LAG08U0M K9HBG08U1M K9GAG08U0M", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "Intel JS29F32G08FAMiB1 and Micron MT29F32G08TAA", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 20, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "MT29F4G08", - }, - { - .end_of_table = false, - .manufacturer_code = 0x89, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "JS29F08G08AAMiB2, JS29F08G08CAMiB2", - }, - { - .end_of_table = false, - .manufacturer_code = 0x89, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "JS29F32G08FAMiB2", - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "HY27UW08CGFM", - }, - {true} -}; - -/* - * Type 7 - */ -static struct nand_device_info nand_device_info_table_type_7[] __initdata = -{ - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 25, - .data_hold_in_ns = 15, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "MT29F8G08FABWG", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 10, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "MT29F4G08AAA", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xdc, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 512LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 12, - .address_setup_in_ns = 25, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9F4G08", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 25, - .data_hold_in_ns = 15, - .address_setup_in_ns = 35, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9K8G08UXM, K9NBG08U5A, K9WAG08U1A", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 12, - .address_setup_in_ns = 25, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9WAG08UXM", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xda, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 256LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9F2G08U0A", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xf1, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 128LL*SZ_1M, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 2*SZ_1K + 64, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 12, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9F1F08", - }, - {true} -}; - -/* - * Type 8 - */ -static struct nand_device_info nand_device_info_table_type_8[] __initdata = -{ - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 128, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9GAG08U0M", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 128, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 15, - .address_setup_in_ns = 25, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9LBG08U0M (32Gb), K9HCG08U1M (64Gb), K9MDG08U5M (128Gb)", - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 128, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 20, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 0, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "H27UAG, H27UBG", - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 128, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 23, - .data_hold_in_ns = 20, - .address_setup_in_ns = 25, - .gpmi_sample_delay_in_ns = 0, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "H27UCG", - }, - {true} -}; - -/* - * Type 9 - */ -static struct nand_device_info nand_device_info_table_type_9[] __initdata = -{ - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 8, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 15, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "TC58NVG3D1DTG00", - }, - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 8, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 15, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "TC58NVG4D1DTG00", - }, - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 8, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 15, - .address_setup_in_ns = 10, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "TH58NVG6D1DTG20", - }, - { - .end_of_table = false, - .manufacturer_code = 0x89, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 8, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 10, - .data_hold_in_ns = 10, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "JS29F16G08AAMC1, JS29F32G08CAMC1", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 8, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "MT29F16G08MAA, MT29F32G08QAA", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 8, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "MT29F64G08TAA (32Gb), MT29F32G08CBAAA (32Gb) MT29F64G08CFAAA (64Gb)", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xd9, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 8LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 8, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 10, - .data_hold_in_ns = 10, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "MT29F128G08CJAAA", - }, - { - .end_of_table = false, - .manufacturer_code = 0x89, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 8, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 10, - .data_hold_in_ns = 10, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "JSF64G08FAMC1", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 8, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 10, - .address_setup_in_ns = 25, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9LBG08U0D", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 8, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9GAG08U0D, K9LBG08U1D, K9HCG08U5D", - }, - {true} -}; - -/* - * Type 10 - */ -static struct nand_device_info nand_device_info_table_type_10[] __initdata = -{ - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd3, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 1LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 4*SZ_1K + 128, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd5, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 4*SZ_1K + 128, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 25, - .data_hold_in_ns = 15, - .address_setup_in_ns = 30, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - "K9NCG08U5M", - }, - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_SLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 64, - .page_total_size_in_bytes = 4*SZ_1K + 128, - .ecc_strength_in_bits = 4, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 15, - .address_setup_in_ns = 25, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = -1, - .tRLOH_in_ns = -1, - .tRHOH_in_ns = -1, - NULL, - }, - {true} -}; - -/* - * Type 11 - */ -static struct nand_device_info nand_device_info_table_type_11[] __initdata = -{ - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 8*SZ_1K + 376, - .ecc_strength_in_bits = 14, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 8, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = 20, - .tRLOH_in_ns = 5, - .tRHOH_in_ns = 25, - "TC58NVG5D2ELAM8 (4GB), TH58NVG6D2ELAM8 (8GB)", - }, - { - .end_of_table = false, - .manufacturer_code = 0x98, - .device_code = 0xde, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 8LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 8*SZ_1K + 376, - .ecc_strength_in_bits = 14, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 8, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = 20, - .tRLOH_in_ns = 5, - .tRHOH_in_ns = 25, - "TH58NVG7D2ELAM8", - }, - {true} -}; - -/* - * Type 15 - */ -static struct nand_device_info nand_device_info_table_type_15[] __initdata = -{ - { - .end_of_table = false, - .manufacturer_code = 0xec, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 8*SZ_1K + 436, - .ecc_strength_in_bits = 16, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 20, - .data_hold_in_ns = 10, - .address_setup_in_ns = 25, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = 25, - .tRLOH_in_ns = 5, - .tRHOH_in_ns = 15, - "K9GBG08U0M (4GB, 1CE); K9LCG08U1M (8GB, 2CE); K9HDG08U5M (16GB, 4CE)", - }, - {true} -}; - -/* - * BCH ECC12 - */ -static struct nand_device_info nand_device_info_table_bch_ecc12[] __initdata = -{ - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 224, - .ecc_strength_in_bits = 12, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = 20, - .tRLOH_in_ns = 5, - .tRHOH_in_ns = 15, - "H27UBG8T2M (4GB, 1CE), H27UCG8UDM (8GB, 2CE), H27UDG8VEM (16GB, 4CE)", - }, - { - .end_of_table = false, - .manufacturer_code = 0xad, - .device_code = 0xde, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 8LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 224, - .ecc_strength_in_bits = 12, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = 20, - .tRLOH_in_ns = 5, - .tRHOH_in_ns = 15, - "H27UEG8YEM (32GB, 4CE)", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xd7, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 12, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 10, - .data_hold_in_ns = 10, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = 16, - .tRLOH_in_ns = 5, - .tRHOH_in_ns = 15, - "MT29F32G08CBAAA (4GB, 1CE), MT29F64G08CFAAA (8GB, 2CE)", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0xd9, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 8LL*SZ_1G, - .block_size_in_pages = 128, - .page_total_size_in_bytes = 4*SZ_1K + 218, - .ecc_strength_in_bits = 12, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 10, - .data_hold_in_ns = 10, - .address_setup_in_ns = 15, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = 16, - .tRLOH_in_ns = 5, - .tRHOH_in_ns = 15, - "MT29F128G08CJAAA (16GB, 2CE)", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0x48, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 2LL*SZ_1G, - .block_size_in_pages = 256, - .page_total_size_in_bytes = 4*SZ_1K + 224, - .ecc_strength_in_bits = 12, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = 20, - .tRLOH_in_ns = 5, - .tRHOH_in_ns = 15, - "MT29F16G08CBABA (2GB, 1CE)", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0x68, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 4LL*SZ_1G, - .block_size_in_pages = 256, - .page_total_size_in_bytes = 4*SZ_1K + 224, - .ecc_strength_in_bits = 12, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = 20, - .tRLOH_in_ns = 5, - .tRHOH_in_ns = 15, - "MT29F32G08CBABA (4GB, 1CE); " - "MT29F64G08CEABA (8GB, 2CE); " - "MT29F64G08CFABA (8GB, 2CE)", - }, - { - .end_of_table = false, - .manufacturer_code = 0x2c, - .device_code = 0x88, - .cell_technology = NAND_DEVICE_CELL_TECH_MLC, - .chip_size_in_bytes = 8LL*SZ_1G, - .block_size_in_pages = 256, - .page_total_size_in_bytes = 4*SZ_1K + 224, - .ecc_strength_in_bits = 12, - .ecc_size_in_bytes = 512, - .data_setup_in_ns = 15, - .data_hold_in_ns = 10, - .address_setup_in_ns = 20, - .gpmi_sample_delay_in_ns = 6, - .tREA_in_ns = 20, - .tRLOH_in_ns = 5, - .tRHOH_in_ns = 15, - "MT29F128G08CJABA (16GB, 2CE); " - "MT29F128G08CKABA (16GB, 2CE); " - "MT29F256G08CUABA (32GB, 4CE)", - }, - {true} -}; - -/* - * The following macros make it convenient to extract information from an ID - * byte array. All these macros begin with the prefix "ID_". - * - * Macros of the form: - * - * ID_GET_[_[_]] - * - * extract the given field from an ID byte array. Macros of the form: - * - * ID_[_[_]]_ - * - * contain the value for the given field that has the given meaning. - * - * If the appears, it means this macro represents a view of this - * field that is specific to the given manufacturer. - * - * If the appears, it means this macro represents a view of this - * field that the given manufacturer applies only under specific conditions. - * - * Here is a simple example: - * - * ID_PAGE_SIZE_CODE_2K - * - * This macro has the value of the "Page Size" field that indicates the page - * size is 2K. - * - * A more complicated example: - * - * ID_SAMSUNG_6_BYTE_PAGE_SIZE_CODE_8K (0x2) - * - * This macro has the value of the "Page Size" field for Samsung parts that - * indicates the page size is 8K. However, this interpretation is only correct - * for devices that return 6 ID bytes. - */ - -/* Byte 1 ------------------------------------------------------------------- */ - -#define ID_GET_BYTE_1(id) ((id)[0]) - -#define ID_GET_MFR_CODE(id) ID_GET_BYTE_1(id) - -/* Byte 2 ------------------------------------------------------------------- */ - -#define ID_GET_BYTE_2(id) ((id)[1]) - -#define ID_GET_DEVICE_CODE(id) ID_GET_BYTE_2(id) - #define ID_SAMSUNG_DEVICE_CODE_1_GBIT (0xf1) - #define ID_SAMSUNG_DEVICE_CODE_2_GBIT (0xda) - #define ID_HYNIX_DEVICE_CODE_ECC12 (0xd7) - #define ID_HYNIX_DEVICE_CODE_ECC12_LARGE (0xde) - #define ID_MICRON_DEVICE_CODE_ECC12 (0xd7) /* ECC12 */ - #define ID_MICRON_DEVICE_CODE_ECC12_LARGE (0xd9) /* ECC12 8GB/CE */ - #define ID_MICRON_DEVICE_CODE_ECC12_2GB_PER_CE (0x48) /* L63B 2GB/CE */ - #define ID_MICRON_DEVICE_CODE_ECC12_4GB_PER_CE (0x68) /* L63B 4GB/CE */ - #define ID_MICRON_DEVICE_CODE_ECC12_8GB_PER_CE (0x88) /* L63B 8GB/CE */ - -/* Byte 3 ------------------------------------------------------------------- */ - -#define ID_GET_BYTE_3(id) ((id)[2]) - -#define ID_GET_DIE_COUNT_CODE(id) ((ID_GET_BYTE_3(id) >> 0) & 0x3) - -#define ID_GET_CELL_TYPE_CODE(id) ((ID_GET_BYTE_3(id) >> 2) & 0x3) - #define ID_CELL_TYPE_CODE_SLC (0x0) /* All others => MLC. */ - -#define ID_GET_SAMSUNG_SIMUL_PROG(id) ((ID_GET_BYTE_3(id) >> 4) & 0x3) - -#define ID_GET_MICRON_SIMUL_PROG(id) ((ID_GET_BYTE_3(id) >> 4) & 0x3) - -#define ID_GET_CACHE_PROGRAM(id) ((ID_GET_BYTE_3(id) >> 7) & 0x1) - -/* Byte 4 ------------------------------------------------------------------- */ - -#define ID_GET_BYTE_4(id) ((id)[3]) - #define ID_HYNIX_BYTE_4_ECC12_DEVICE (0x25) - -#define ID_GET_PAGE_SIZE_CODE(id) ((ID_GET_BYTE_4(id) >> 0) & 0x3) - #define ID_PAGE_SIZE_CODE_1K (0x0) - #define ID_PAGE_SIZE_CODE_2K (0x1) - #define ID_PAGE_SIZE_CODE_4K (0x2) - #define ID_PAGE_SIZE_CODE_8K (0x3) - #define ID_SAMSUNG_6_BYTE_PAGE_SIZE_CODE_8K (0x2) - -#define ID_GET_OOB_SIZE_CODE(id) ((ID_GET_BYTE_4(id) >> 2) & 0x1) - -#define ID_GET_BLOCK_SIZE_CODE(id) ((ID_GET_BYTE_4(id) >> 4) & 0x3) - -/* Byte 5 ------------------------------------------------------------------- */ - -#define ID_GET_BYTE_5(id) ((id)[4]) - #define ID_MICRON_BYTE_5_ECC12 (0x84) - -#define ID_GET_SAMSUNG_ECC_LEVEL_CODE(id) ((ID_GET_BYTE_5(id) >> 4) & 0x7) - #define ID_SAMSUNG_ECC_LEVEL_CODE_8 (0x03) - #define ID_SAMSUNG_ECC_LEVEL_CODE_24 (0x05) - -#define ID_GET_PLANE_COUNT_CODE(id) ((ID_GET_BYTE_5(id) >> 2) & 0x3) - -/* Byte 6 ------------------------------------------------------------------- */ - -#define ID_GET_BYTE_6(id) ((id)[5]) - #define ID_TOSHIBA_BYTE_6_PAGE_SIZE_CODE_8K (0x54) - #define ID_TOSHIBA_BYTE_6_PAGE_SIZE_CODE_4K (0x13) - -#define ID_GET_SAMSUNG_DEVICE_VERSION_CODE(id) ((ID_GET_BYTE_6(id)>>0) & 0x7) - #define ID_SAMSUNG_DEVICE_VERSION_CODE_40NM (0x01) - -/* -------------------------------------------------------------------------- */ - -void nand_device_print_info(struct nand_device_info *info) -{ - unsigned i; - const char *mfr_name; - const char *cell_technology_name; - uint64_t chip_size; - const char *chip_size_units; - unsigned page_data_size_in_bytes; - unsigned page_oob_size_in_bytes; - - /* Check for nonsense. */ - - if (!info) - return; - - /* Prepare the manufacturer name. */ - - mfr_name = "Unknown"; - - for (i = 0; nand_manuf_ids[i].id; i++) { - if (nand_manuf_ids[i].id == info->manufacturer_code) { - mfr_name = nand_manuf_ids[i].name; - break; - } - } - - /* Prepare the name of the cell technology. */ - - switch (info->cell_technology) { - case NAND_DEVICE_CELL_TECH_SLC: - cell_technology_name = "SLC"; - break; - case NAND_DEVICE_CELL_TECH_MLC: - cell_technology_name = "MLC"; - break; - default: - cell_technology_name = "Unknown"; - break; - } - - /* Prepare the chip size. */ - - if ((info->chip_size_in_bytes >= SZ_1G) && - !(info->chip_size_in_bytes % SZ_1G)) { - chip_size = info->chip_size_in_bytes / ((uint64_t) SZ_1G); - chip_size_units = "GiB"; - } else if ((info->chip_size_in_bytes >= SZ_1M) && - !(info->chip_size_in_bytes % SZ_1M)) { - chip_size = info->chip_size_in_bytes / ((uint64_t) SZ_1M); - chip_size_units = "MiB"; - } else { - chip_size = info->chip_size_in_bytes; - chip_size_units = "B"; - } - - /* Prepare the page geometry. */ - - page_data_size_in_bytes = (1<<(fls(info->page_total_size_in_bytes)-1)); - page_oob_size_in_bytes = info->page_total_size_in_bytes - - page_data_size_in_bytes; - - /* Print the information. */ - - printk(KERN_INFO "Manufacturer : %s (0x%02x)\n", mfr_name, - info->manufacturer_code); - printk(KERN_INFO "Device Code : 0x%02x\n", info->device_code); - printk(KERN_INFO "Cell Technology : %s\n", cell_technology_name); - printk(KERN_INFO "Chip Size : %llu %s\n", chip_size, - chip_size_units); - printk(KERN_INFO "Pages per Block : %u\n", - info->block_size_in_pages); - printk(KERN_INFO "Page Geometry : %u+%u\n", page_data_size_in_bytes, - page_oob_size_in_bytes); - printk(KERN_INFO "ECC Strength : %u bits\n", - info->ecc_strength_in_bits); - printk(KERN_INFO "ECC Size : %u B\n", info->ecc_size_in_bytes); - printk(KERN_INFO "Data Setup Time : %u ns\n", info->data_setup_in_ns); - printk(KERN_INFO "Data Hold Time : %u ns\n", info->data_hold_in_ns); - printk(KERN_INFO "Address Setup Time: %u ns\n", - info->address_setup_in_ns); - printk(KERN_INFO "GPMI Sample Delay : %u ns\n", - info->gpmi_sample_delay_in_ns); - if (info->tREA_in_ns >= 0) - printk(KERN_INFO "tREA : %u ns\n", - info->tREA_in_ns); - else - printk(KERN_INFO "tREA : Unknown\n"); - if (info->tREA_in_ns >= 0) - printk(KERN_INFO "tRLOH : %u ns\n", - info->tRLOH_in_ns); - else - printk(KERN_INFO "tRLOH : Unknown\n"); - if (info->tREA_in_ns >= 0) - printk(KERN_INFO "tRHOH : %u ns\n", - info->tRHOH_in_ns); - else - printk(KERN_INFO "tRHOH : Unknown\n"); - if (info->description) - printk(KERN_INFO "Description : %s\n", info->description); - else - printk(KERN_INFO "Description : \n"); - -} - -static struct nand_device_info *nand_device_info_search( - struct nand_device_info *table, uint8_t mfr_code, uint8_t device_code) -{ - - for (; !table->end_of_table; table++) { - if (table->manufacturer_code != mfr_code) - continue; - if (table->device_code != device_code) - continue; - return table; - } - - return 0; - -} - -static struct nand_device_info *nand_device_info_fn_toshiba(const uint8_t id[]) -{ - struct nand_device_info *table; - - /* Check for an SLC device. */ - - if (ID_GET_CELL_TYPE_CODE(id) == ID_CELL_TYPE_CODE_SLC) { - /* Type 2 */ - return nand_device_info_search(nand_device_info_table_type_2, - ID_GET_MFR_CODE(id), ID_GET_DEVICE_CODE(id)); - } - - /* - * Look for 8K page Toshiba MLC devices. - * - * The page size field in byte 4 can't be used because the field was - * redefined in the 8K parts so the value meaning "8K page" is the same - * as the value meaning "4K page" on the 4K page devices. - * - * The only identifiable difference between the 4K and 8K page Toshiba - * devices with a device code of 0xd7 is the undocumented 6th ID byte. - * The 4K device returns a value of 0x13 and the 8K a value of 0x54. - * Toshiba has verified that this is an acceptable method to distinguish - * the two device families. - */ - - if (ID_GET_BYTE_6(id) == ID_TOSHIBA_BYTE_6_PAGE_SIZE_CODE_8K) { - /* Type 11 */ - table = nand_device_info_table_type_11; - } else if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { - /* Type 9 */ - table = nand_device_info_table_type_9; - } else { - /* Large MLC */ - table = nand_device_info_table_large_mlc; - } - - return nand_device_info_search(table, ID_GET_MFR_CODE(id), - ID_GET_DEVICE_CODE(id)); - -} - -static struct nand_device_info *nand_device_info_fn_samsung(const uint8_t id[]) -{ - struct nand_device_info *table; - - /* Check for an MLC device. */ - - if (ID_GET_CELL_TYPE_CODE(id) != ID_CELL_TYPE_CODE_SLC) { - - /* Is this a Samsung 8K Page MLC device with 16 bit ECC? */ - if ((ID_GET_SAMSUNG_ECC_LEVEL_CODE(id) == - ID_SAMSUNG_ECC_LEVEL_CODE_24) && - (ID_GET_PAGE_SIZE_CODE(id) == - ID_SAMSUNG_6_BYTE_PAGE_SIZE_CODE_8K)) { - /* Type 15 */ - table = nand_device_info_table_type_15; - } - /* Is this a Samsung 42nm ECC8 device with a 6 byte ID? */ - else if ((ID_GET_SAMSUNG_ECC_LEVEL_CODE(id) == - ID_SAMSUNG_ECC_LEVEL_CODE_8) && - (ID_GET_SAMSUNG_DEVICE_VERSION_CODE(id) == - ID_SAMSUNG_DEVICE_VERSION_CODE_40NM)) { - /* Type 9 */ - table = nand_device_info_table_type_9; - } else if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { - /* Type 8 */ - table = nand_device_info_table_type_8; - } else { - /* Large MLC */ - table = nand_device_info_table_large_mlc; - } - - } else { - - /* Check the page size first. */ - if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { - /* Type 10 */ - table = nand_device_info_table_type_10; - } - /* Check the chip size. */ - else if (ID_GET_DEVICE_CODE(id) == - ID_SAMSUNG_DEVICE_CODE_1_GBIT) { - if (!ID_GET_CACHE_PROGRAM(id)) { - /* - * 128 MiB Samsung chips without cache program - * are Type 7. - * - * The K9F1G08U0B does not support multi-plane - * program, so the if statement below cannot be - * used to identify it. - */ - table = nand_device_info_table_type_7; - - } else { - /* Smaller sizes are Type 2 by default. */ - table = nand_device_info_table_type_2; - } - } else { - /* Check number of simultaneously programmed pages. */ - if (ID_GET_SAMSUNG_SIMUL_PROG(id) && - ID_GET_PLANE_COUNT_CODE(id)) { - /* Type 7 */ - table = nand_device_info_table_type_7; - } else { - /* Type 2 */ - table = nand_device_info_table_type_2; - } - - } - - } - - return nand_device_info_search(table, ID_GET_MFR_CODE(id), - ID_GET_DEVICE_CODE(id)); - -} - -static struct nand_device_info *nand_device_info_fn_stmicro(const uint8_t id[]) -{ - struct nand_device_info *table; - - /* Check for an SLC device. */ - - if (ID_GET_CELL_TYPE_CODE(id) == ID_CELL_TYPE_CODE_SLC) - /* Type 2 */ - table = nand_device_info_table_type_2; - else - /* Large MLC */ - table = nand_device_info_table_large_mlc; - - return nand_device_info_search(table, ID_GET_MFR_CODE(id), - ID_GET_DEVICE_CODE(id)); - -} - -static struct nand_device_info *nand_device_info_fn_hynix(const uint8_t id[]) -{ - struct nand_device_info *table; - - /* Check for an SLC device. */ - - if (ID_GET_CELL_TYPE_CODE(id) == ID_CELL_TYPE_CODE_SLC) { - /* Type 2 */ - return nand_device_info_search(nand_device_info_table_type_2, - ID_GET_MFR_CODE(id), ID_GET_DEVICE_CODE(id)); - } - - /* - * Check for ECC12 devices. - * - * We look at the 4th ID byte to distinguish some Hynix ECC12 devices - * from the similar ECC8 part. For example H27UBG8T2M (ECC12) 4th byte - * is 0x25, whereas H27UDG8WFM (ECC8) 4th byte is 0xB6. - */ - - if ((ID_GET_DEVICE_CODE(id) == ID_HYNIX_DEVICE_CODE_ECC12 && - ID_GET_BYTE_4(id) == ID_HYNIX_BYTE_4_ECC12_DEVICE) || - (ID_GET_DEVICE_CODE(id) == ID_HYNIX_DEVICE_CODE_ECC12_LARGE)) { - /* BCH ECC 12 */ - table = nand_device_info_table_bch_ecc12; - } else if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { - /* - * So far, all other Samsung and Hynix 4K page devices are - * Type 8. - */ - table = nand_device_info_table_type_8; - } else - /* Large MLC */ - table = nand_device_info_table_large_mlc; - - return nand_device_info_search(table, ID_GET_MFR_CODE(id), - ID_GET_DEVICE_CODE(id)); - -} - -static struct nand_device_info *nand_device_info_fn_micron(const uint8_t id[]) -{ - struct nand_device_info *table; - - /* Check for an SLC device. */ - - if (ID_GET_CELL_TYPE_CODE(id) == ID_CELL_TYPE_CODE_SLC) { - - /* Check number of simultaneously programmed pages. */ - - if (ID_GET_MICRON_SIMUL_PROG(id)) { - /* Type 7 */ - table = nand_device_info_table_type_7; - } else { - /* Zero simultaneously programmed pages means Type 2. */ - table = nand_device_info_table_type_2; - } - - return nand_device_info_search(table, ID_GET_MFR_CODE(id), - ID_GET_DEVICE_CODE(id)); - - } - - /* - * We look at the 5th ID byte to distinguish some Micron ECC12 NANDs - * from the similar ECC8 part. - * - * For example MT29F64G08CFAAA (ECC12) 5th byte is 0x84, whereas - * MT29F64G08TAA (ECC8) 5th byte is 0x78. - * - * We also have a special case for the Micron L63B family - * (256 page/block), which has unique device codes but no ID fields that - * can easily be used to distinguish the family. - */ - - if ((ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC12 && - ID_GET_BYTE_5(id) == ID_MICRON_BYTE_5_ECC12) || - (ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC12_LARGE) || - (ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC12_2GB_PER_CE) || - (ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC12_4GB_PER_CE) || - (ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC12_8GB_PER_CE)) { - /* BCH ECC 12 */ - table = nand_device_info_table_bch_ecc12; - } else if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { - /* Toshiba devices with 4K pages are Type 9. */ - table = nand_device_info_table_type_9; - } else { - /* Large MLC */ - table = nand_device_info_table_large_mlc; - } - - return nand_device_info_search(table, ID_GET_MFR_CODE(id), - ID_GET_DEVICE_CODE(id)); - -} - -static struct nand_device_info *nand_device_info_fn_sandisk(const uint8_t id[]) -{ - struct nand_device_info *table; - - if (ID_GET_CELL_TYPE_CODE(id) != ID_CELL_TYPE_CODE_SLC) { - /* Large MLC */ - table = nand_device_info_table_large_mlc; - } else { - /* Type 2 */ - table = nand_device_info_table_type_2; - } - - return nand_device_info_search(table, ID_GET_MFR_CODE(id), - ID_GET_DEVICE_CODE(id)); - -} - -static struct nand_device_info *nand_device_info_fn_intel(const uint8_t id[]) -{ - struct nand_device_info *table; - - /* Check for an SLC device. */ - - if (ID_GET_CELL_TYPE_CODE(id) == ID_CELL_TYPE_CODE_SLC) { - /* Type 2 */ - return nand_device_info_search(nand_device_info_table_type_2, - ID_GET_MFR_CODE(id), ID_GET_DEVICE_CODE(id)); - } - - if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { - /* Type 9 */ - table = nand_device_info_table_type_9; - } else { - /* Large MLC */ - table = nand_device_info_table_large_mlc; - } - - return nand_device_info_search(table, ID_GET_MFR_CODE(id), - ID_GET_DEVICE_CODE(id)); - -} - -/** - * struct nand_device_type_info - Information about a NAND Flash type. - * - * @name: A human-readable name for this type. - * @table: The device info table for this type. - */ - -struct nand_device_type_info { - struct nand_device_info *table; - const char *name; -}; - -/* - * A table that maps manufacturer IDs to device information tables. - */ - -static struct nand_device_type_info nand_device_type_directory[] __initdata = -{ - {nand_device_info_table_type_2, "Type 2" }, - {nand_device_info_table_large_mlc, "Large MLC"}, - {nand_device_info_table_type_7, "Type 7" }, - {nand_device_info_table_type_8, "Type 8" }, - {nand_device_info_table_type_9, "Type 9" }, - {nand_device_info_table_type_10, "Type 10" }, - {nand_device_info_table_type_11, "Type 11" }, - {nand_device_info_table_type_15, "Type 15" }, - {nand_device_info_table_bch_ecc12, "BCH ECC12"}, - {0, 0}, -}; - -/** - * struct nand_device_mfr_info - Information about a NAND Flash manufacturer. - * - * @id: The value of the first NAND Flash ID byte, which identifies the - * manufacturer. - * @fn: A pointer to a function to use for identifying devices from the - * given manufacturer. - */ - -struct nand_device_mfr_info { - uint8_t id; - struct nand_device_info *(*fn)(const uint8_t id[]); -}; - -/* - * A table that maps manufacturer IDs to device information tables. - */ - -static struct nand_device_mfr_info nand_device_mfr_directory[] __initdata = -{ - { - .id = NAND_MFR_TOSHIBA, - .fn = nand_device_info_fn_toshiba, - }, - { - .id = NAND_MFR_SAMSUNG, - .fn = nand_device_info_fn_samsung, - }, - { - .id = NAND_MFR_FUJITSU, - .fn = 0, - }, - { - .id = NAND_MFR_NATIONAL, - .fn = 0, - }, - { - .id = NAND_MFR_RENESAS, - .fn = 0, - }, - { - .id = NAND_MFR_STMICRO, - .fn = nand_device_info_fn_stmicro, - }, - { - .id = NAND_MFR_HYNIX, - .fn = nand_device_info_fn_hynix, - }, - { - .id = NAND_MFR_MICRON, - .fn = nand_device_info_fn_micron, - }, - { - .id = NAND_MFR_AMD, - .fn = 0, - }, - { - .id = NAND_MFR_SANDISK, - .fn = nand_device_info_fn_sandisk, - }, - { - .id = NAND_MFR_INTEL, - .fn = nand_device_info_fn_intel, - }, - {0, 0} -}; - -/** - * nand_device_info_test_table - Validate a device info table. - * - * This function runs tests on the given device info table to check that it - * meets the current assumptions. - */ - -static void __init nand_device_info_test_table( - struct nand_device_info *table, const char * name) -{ - unsigned i; - unsigned j; - uint8_t mfr_code; - uint8_t device_code; - - /* Loop over entries in this table. */ - - for (i = 0; !table[i].end_of_table; i++) { - - /* Get discriminating attributes of the current device. */ - - mfr_code = table[i].manufacturer_code; - device_code = table[i].device_code; - - /* Compare with the remaining devices in this table. */ - - for (j = i + 1; !table[j].end_of_table; j++) { - if ((mfr_code == table[j].manufacturer_code) && - (device_code == table[j].device_code)) - goto error; - } - - } - - return; - -error: - - printk(KERN_EMERG - "\n== NAND Flash device info table failed validity check ==\n"); - - printk(KERN_EMERG "\nDevice Info Table: %s\n", name); - printk(KERN_EMERG "\nTable Index %u\n", i); - nand_device_print_info(table + i); - printk(KERN_EMERG "\nTable Index %u\n", j); - nand_device_print_info(table + j); - printk(KERN_EMERG "\n"); - - BUG(); - -} - -/** - * nand_device_info_test_data - Test the NAND Flash device data. - */ - -static void __init nand_device_info_test_data(void) -{ - - unsigned i; - - for (i = 0; nand_device_type_directory[i].name; i++) { - nand_device_info_test_table( - nand_device_type_directory[i].table, - nand_device_type_directory[i].name); - } - -} - -struct nand_device_info * __init nand_device_get_info(const uint8_t id[]) -{ - unsigned i; - uint8_t mfr_id = ID_GET_MFR_CODE(id); - struct nand_device_info *(*fn)(const uint8_t id[]) = 0; - - /* Test the data. */ - - nand_device_info_test_data(); - - /* Look for information about this manufacturer. */ - - for (i = 0; nand_device_mfr_directory[i].id; i++) { - if (nand_device_mfr_directory[i].id == mfr_id) { - fn = nand_device_mfr_directory[i].fn; - break; - } - } - - if (!fn) - return 0; - - /* - * If control arrives here, we found both a table of device information, - * and a function we can use to identify the current device. Attempt to - * identify the device and return the result. - */ - - return fn(id); - -} diff --git a/drivers/mtd/nand/gpmi/nand_device_info.h b/drivers/mtd/nand/gpmi/nand_device_info.h deleted file mode 100644 index a5f56e913ec6..000000000000 --- a/drivers/mtd/nand/gpmi/nand_device_info.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ -#ifndef __DRIVERS_NAND_DEVICE_INFO_H -#define __DRIVERS_NAND_DEVICE_INFO_H - - /* - * The number of ID bytes to read from the NAND Flash device and hand over to - * the identification system. - */ - -#define NAND_DEVICE_ID_BYTE_COUNT (6) - - /* - * The number of ID bytes to read from the NAND Flash device and hand over to - * the identification system. - */ - -enum nand_device_cell_technology { - NAND_DEVICE_CELL_TECH_SLC = 0, - NAND_DEVICE_CELL_TECH_MLC = 1, -}; - -/** - * struct nand_device_info - Information about a single NAND Flash device. - * - * This structure contains all the *essential* information about a NAND Flash - * device, derived from the device's data sheet. For each manufacturer, we have - * an array of these structures. - * - * @end_of_table: If true, marks the end of a table of device - * information. - * @manufacturer_code: The manufacturer code (1st ID byte) reported by - * the device. - * @device_code: The device code (2nd ID byte) reported by the - * device. - * @cell_technology: The storage cell technology. - * @chip_size_in_bytes: The total size of the storage behind a single - * chip select, in bytes. Notice that this is *not* - * necessarily the total size of the storage in a - * *package*, which may contain several chips. - * @block_size_in_pages: The number of pages in a block. - * @page_total_size_in_bytes: The total size of a page, in bytes, including - * both the data and the OOB. - * @ecc_strength_in_bits: The strength of the ECC called for by the - * manufacturer, in number of correctable bits. - * @ecc_size_in_bytes: The size of the data block over which the - * manufacturer calls for the given ECC algorithm - * and strength. - * @data_setup_in_ns: The data setup time, in nanoseconds. Usually the - * maximum of tDS and tWP. A negative value - * indicates this characteristic isn't known. - * @data_hold_in_ns: The data hold time, in nanoseconds. Usually the - * maximum of tDH, tWH and tREH. A negative value - * indicates this characteristic isn't known. - * @address_setup_in_ns: The address setup time, in nanoseconds. Usually - * the maximum of tCLS, tCS and tALS. A negative - * value indicates this characteristic isn't known. - * @gpmi_sample_delay_in_ns: A GPMI-specific timing parameter. A negative - * value indicates this characteristic isn't known. - * @tREA_in_ns: tREA, in nanoseconds, from the data sheet. A - * negative value indicates this characteristic - * isn't known. - * @tRLOH_in_ns: tRLOH, in nanoseconds, from the data sheet. A - * negative value indicates this characteristic - * isn't known. - * @tRHOH_in_ns: tRHOH, in nanoseconds, from the data sheet. A - * negative value indicates this characteristic - * isn't known. - */ - -struct nand_device_info { - - /* End of table marker */ - - bool end_of_table; - - /* Manufacturer and Device codes */ - - uint8_t manufacturer_code; - uint8_t device_code; - - /* Technology */ - - enum nand_device_cell_technology cell_technology; - - /* Geometry */ - - uint64_t chip_size_in_bytes; - uint32_t block_size_in_pages; - uint16_t page_total_size_in_bytes; - - /* ECC */ - - uint8_t ecc_strength_in_bits; - uint16_t ecc_size_in_bytes; - - /* Timing */ - - int8_t data_setup_in_ns; - int8_t data_hold_in_ns; - int8_t address_setup_in_ns; - int8_t gpmi_sample_delay_in_ns; - int8_t tREA_in_ns; - int8_t tRLOH_in_ns; - int8_t tRHOH_in_ns; - - /* Description */ - - const char *description; - -}; - -/** - * nand_device_get_info - Get info about a device based on ID bytes. - * - * @id_bytes: An array of NAND_DEVICE_ID_BYTE_COUNT ID bytes retrieved from the - * NAND Flash device. - */ - -struct nand_device_info *nand_device_get_info(const uint8_t id_bytes[]); - -/** - * nand_device_print_info - Prints information about a NAND Flash device. - * - * @info A pointer to a NAND Flash device information structure. - */ - -void nand_device_print_info(struct nand_device_info *info); - -#endif diff --git a/drivers/mtd/nand/mxc_nd2.c b/drivers/mtd/nand/mxc_nd2.c index 17c6e806b55d..84eb9b29b100 100644 --- a/drivers/mtd/nand/mxc_nd2.c +++ b/drivers/mtd/nand/mxc_nd2.c @@ -26,7 +26,7 @@ #include #include #include "mxc_nd2.h" -#include "gpmi/nand_device_info.h" +#include "nand_device_info.h" #define DVR_VER "2.5" diff --git a/drivers/mtd/nand/nand_device_info.c b/drivers/mtd/nand/nand_device_info.c new file mode 100644 index 000000000000..ecd5b21189cc --- /dev/null +++ b/drivers/mtd/nand/nand_device_info.c @@ -0,0 +1,2297 @@ +/* + * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include + +#include "nand_device_info.h" + +/* + * Type 2 + */ +static struct nand_device_info nand_device_info_table_type_2[] __initdata = +{ + { + .end_of_table = false, + .manufacturer_code = 0x20, + .device_code = 0xf1, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 128LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 30, + .data_hold_in_ns = 20, + .address_setup_in_ns = 25, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "NAND01GW3", + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xf1, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 128LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 30, + .address_setup_in_ns = 25, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xf1, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 128LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 30, + .data_hold_in_ns = 20, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xf1, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 128LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 35, + .data_hold_in_ns = 25, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9F1F08", + }, + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xf1, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 128LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 30, + .data_hold_in_ns = 20, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "TC58NVG0S3", + }, + { + .end_of_table = false, + .manufacturer_code = 0x45, + .device_code = 0xf1, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 128LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 32, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0x20, + .device_code = 0xda, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 256LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 30, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "NAND02GW3", + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xda, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 256LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 30, + .data_hold_in_ns = 25, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "HY27UF082G2M, HY27UG082G2M, HY27UG082G1M", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xda, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 256LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 10, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "MT29F2G08", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xda, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 256LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9F2G08U0M", + }, + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xda, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 256LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 30, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "TC58NVG1S3", + }, + { + .end_of_table = false, + .manufacturer_code = 0x45, + .device_code = 0xda, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 256LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 32, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0x20, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 30, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 30, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 10, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "HY27UH084G2M, HY27UG084G2M, HY27UH084G1M", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 10, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "MT29F4G08", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 25, + .data_hold_in_ns = 25, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 25, + .data_hold_in_ns = 25, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "TH58NVG2S3", + }, + { + .end_of_table = false, + .manufacturer_code = 0x45, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 32, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 30, + .data_hold_in_ns = 25, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "HY27UH088G2M", + }, + { + .end_of_table = false, + .manufacturer_code = 0x20, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 30, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "NAND08GW3BxANx", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 25, + .data_hold_in_ns = 15, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "MT29F8G08FABWG", + }, + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 32, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0x20, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 30, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 25, + .data_hold_in_ns = 30, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 32, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + {true} +}; + +/* + * Large MLC + */ +static struct nand_device_info nand_device_info_table_large_mlc[] __initdata = +{ + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xda, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 256LL*SZ_1M, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 30, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "TC58NVG1D4BFT00", + }, + { + .end_of_table = false, + .manufacturer_code = 0x45, + .device_code = 0xda, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 256LL*SZ_1M, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 30, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0x45, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 30, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 35, + .data_hold_in_ns = 30, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "TH58NVG3D4xFT00", + }, + { + .end_of_table = false, + .manufacturer_code = 0x45, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 35, + .data_hold_in_ns = 20, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 35, + .data_hold_in_ns = 15, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "TH58NVG4D4xFT00", + }, + { + .end_of_table = false, + .manufacturer_code = 0x45, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 35, + .data_hold_in_ns = 15, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 30, + .address_setup_in_ns = 0, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "TC58NVG2D4BFT00", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 25, + .data_hold_in_ns = 15, + .address_setup_in_ns = 25, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9G4G08U0M", + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 45, + .data_hold_in_ns = 25, + .address_setup_in_ns = 50, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "HY27UT084G2M, HY27UU088G5M", + }, + { + .end_of_table = false, + .manufacturer_code = 0x20, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 40, + .data_hold_in_ns = 20, + .address_setup_in_ns = 30, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "NAND04GW3C2AN1E", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 15, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9G8G08U0M, K9HAG08U1M", + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 60, + .data_hold_in_ns = 30, + .address_setup_in_ns = 50, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "HY27UV08AG5M", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 15, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "Intel JS29F08G08AAMiB1 and Micron MT29F8G08MAA; " + "Intel JS29F08G08CAMiB1 and Micron MT29F16G08QAA", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 15, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9LAG08U0M K9HBG08U1M K9GAG08U0M", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "Intel JS29F32G08FAMiB1 and Micron MT29F32G08TAA", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 20, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "MT29F4G08", + }, + { + .end_of_table = false, + .manufacturer_code = 0x89, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "JS29F08G08AAMiB2, JS29F08G08CAMiB2", + }, + { + .end_of_table = false, + .manufacturer_code = 0x89, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "JS29F32G08FAMiB2", + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "HY27UW08CGFM", + }, + {true} +}; + +/* + * Type 7 + */ +static struct nand_device_info nand_device_info_table_type_7[] __initdata = +{ + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 25, + .data_hold_in_ns = 15, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "MT29F8G08FABWG", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 10, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "MT29F4G08AAA", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xdc, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 512LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 12, + .address_setup_in_ns = 25, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9F4G08", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 25, + .data_hold_in_ns = 15, + .address_setup_in_ns = 35, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9K8G08UXM, K9NBG08U5A, K9WAG08U1A", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 12, + .address_setup_in_ns = 25, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9WAG08UXM", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xda, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 256LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9F2G08U0A", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xf1, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 128LL*SZ_1M, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 2*SZ_1K + 64, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 12, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9F1F08", + }, + {true} +}; + +/* + * Type 8 + */ +static struct nand_device_info nand_device_info_table_type_8[] __initdata = +{ + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 128, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9GAG08U0M", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 128, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 15, + .address_setup_in_ns = 25, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9LBG08U0M (32Gb), K9HCG08U1M (64Gb), K9MDG08U5M (128Gb)", + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 128, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 20, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 0, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "H27UAG, H27UBG", + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 128, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 23, + .data_hold_in_ns = 20, + .address_setup_in_ns = 25, + .gpmi_sample_delay_in_ns = 0, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "H27UCG", + }, + {true} +}; + +/* + * Type 9 + */ +static struct nand_device_info nand_device_info_table_type_9[] __initdata = +{ + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 8, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 15, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "TC58NVG3D1DTG00", + }, + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 8, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 15, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "TC58NVG4D1DTG00", + }, + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 8, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 15, + .address_setup_in_ns = 10, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "TH58NVG6D1DTG20", + }, + { + .end_of_table = false, + .manufacturer_code = 0x89, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 8, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 10, + .data_hold_in_ns = 10, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "JS29F16G08AAMC1, JS29F32G08CAMC1", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 8, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "MT29F16G08MAA, MT29F32G08QAA", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 8, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "MT29F64G08TAA (32Gb), MT29F32G08CBAAA (32Gb) MT29F64G08CFAAA (64Gb)", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xd9, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 8LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 8, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 10, + .data_hold_in_ns = 10, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "MT29F128G08CJAAA", + }, + { + .end_of_table = false, + .manufacturer_code = 0x89, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 8, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 10, + .data_hold_in_ns = 10, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "JSF64G08FAMC1", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 8, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 10, + .address_setup_in_ns = 25, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9LBG08U0D", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 8, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9GAG08U0D, K9LBG08U1D, K9HCG08U5D", + }, + {true} +}; + +/* + * Type 10 + */ +static struct nand_device_info nand_device_info_table_type_10[] __initdata = +{ + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd3, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 1LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 4*SZ_1K + 128, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd5, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 4*SZ_1K + 128, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 25, + .data_hold_in_ns = 15, + .address_setup_in_ns = 30, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + "K9NCG08U5M", + }, + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_SLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 64, + .page_total_size_in_bytes = 4*SZ_1K + 128, + .ecc_strength_in_bits = 4, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 15, + .address_setup_in_ns = 25, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = -1, + .tRLOH_in_ns = -1, + .tRHOH_in_ns = -1, + NULL, + }, + {true} +}; + +/* + * Type 11 + */ +static struct nand_device_info nand_device_info_table_type_11[] __initdata = +{ + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 8*SZ_1K + 376, + .ecc_strength_in_bits = 14, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 8, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = 20, + .tRLOH_in_ns = 5, + .tRHOH_in_ns = 25, + "TC58NVG5D2ELAM8 (4GB), TH58NVG6D2ELAM8 (8GB)", + }, + { + .end_of_table = false, + .manufacturer_code = 0x98, + .device_code = 0xde, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 8LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 8*SZ_1K + 376, + .ecc_strength_in_bits = 14, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 8, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = 20, + .tRLOH_in_ns = 5, + .tRHOH_in_ns = 25, + "TH58NVG7D2ELAM8", + }, + {true} +}; + +/* + * Type 15 + */ +static struct nand_device_info nand_device_info_table_type_15[] __initdata = +{ + { + .end_of_table = false, + .manufacturer_code = 0xec, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 8*SZ_1K + 436, + .ecc_strength_in_bits = 16, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 20, + .data_hold_in_ns = 10, + .address_setup_in_ns = 25, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = 25, + .tRLOH_in_ns = 5, + .tRHOH_in_ns = 15, + "K9GBG08U0M (4GB, 1CE); K9LCG08U1M (8GB, 2CE); K9HDG08U5M (16GB, 4CE)", + }, + {true} +}; + +/* + * BCH ECC12 + */ +static struct nand_device_info nand_device_info_table_bch_ecc12[] __initdata = +{ + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 224, + .ecc_strength_in_bits = 12, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = 20, + .tRLOH_in_ns = 5, + .tRHOH_in_ns = 15, + "H27UBG8T2M (4GB, 1CE), H27UCG8UDM (8GB, 2CE), H27UDG8VEM (16GB, 4CE)", + }, + { + .end_of_table = false, + .manufacturer_code = 0xad, + .device_code = 0xde, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 8LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 224, + .ecc_strength_in_bits = 12, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = 20, + .tRLOH_in_ns = 5, + .tRHOH_in_ns = 15, + "H27UEG8YEM (32GB, 4CE)", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xd7, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 12, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 10, + .data_hold_in_ns = 10, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = 16, + .tRLOH_in_ns = 5, + .tRHOH_in_ns = 15, + "MT29F32G08CBAAA (4GB, 1CE), MT29F64G08CFAAA (8GB, 2CE)", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0xd9, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 8LL*SZ_1G, + .block_size_in_pages = 128, + .page_total_size_in_bytes = 4*SZ_1K + 218, + .ecc_strength_in_bits = 12, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 10, + .data_hold_in_ns = 10, + .address_setup_in_ns = 15, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = 16, + .tRLOH_in_ns = 5, + .tRHOH_in_ns = 15, + "MT29F128G08CJAAA (16GB, 2CE)", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0x48, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 2LL*SZ_1G, + .block_size_in_pages = 256, + .page_total_size_in_bytes = 4*SZ_1K + 224, + .ecc_strength_in_bits = 12, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = 20, + .tRLOH_in_ns = 5, + .tRHOH_in_ns = 15, + "MT29F16G08CBABA (2GB, 1CE)", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0x68, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 4LL*SZ_1G, + .block_size_in_pages = 256, + .page_total_size_in_bytes = 4*SZ_1K + 224, + .ecc_strength_in_bits = 12, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = 20, + .tRLOH_in_ns = 5, + .tRHOH_in_ns = 15, + "MT29F32G08CBABA (4GB, 1CE); " + "MT29F64G08CEABA (8GB, 2CE); " + "MT29F64G08CFABA (8GB, 2CE)", + }, + { + .end_of_table = false, + .manufacturer_code = 0x2c, + .device_code = 0x88, + .cell_technology = NAND_DEVICE_CELL_TECH_MLC, + .chip_size_in_bytes = 8LL*SZ_1G, + .block_size_in_pages = 256, + .page_total_size_in_bytes = 4*SZ_1K + 224, + .ecc_strength_in_bits = 12, + .ecc_size_in_bytes = 512, + .data_setup_in_ns = 15, + .data_hold_in_ns = 10, + .address_setup_in_ns = 20, + .gpmi_sample_delay_in_ns = 6, + .tREA_in_ns = 20, + .tRLOH_in_ns = 5, + .tRHOH_in_ns = 15, + "MT29F128G08CJABA (16GB, 2CE); " + "MT29F128G08CKABA (16GB, 2CE); " + "MT29F256G08CUABA (32GB, 4CE)", + }, + {true} +}; + +/* + * The following macros make it convenient to extract information from an ID + * byte array. All these macros begin with the prefix "ID_". + * + * Macros of the form: + * + * ID_GET_[_[_]] + * + * extract the given field from an ID byte array. Macros of the form: + * + * ID_[_[_]]_ + * + * contain the value for the given field that has the given meaning. + * + * If the appears, it means this macro represents a view of this + * field that is specific to the given manufacturer. + * + * If the appears, it means this macro represents a view of this + * field that the given manufacturer applies only under specific conditions. + * + * Here is a simple example: + * + * ID_PAGE_SIZE_CODE_2K + * + * This macro has the value of the "Page Size" field that indicates the page + * size is 2K. + * + * A more complicated example: + * + * ID_SAMSUNG_6_BYTE_PAGE_SIZE_CODE_8K (0x2) + * + * This macro has the value of the "Page Size" field for Samsung parts that + * indicates the page size is 8K. However, this interpretation is only correct + * for devices that return 6 ID bytes. + */ + +/* Byte 1 ------------------------------------------------------------------- */ + +#define ID_GET_BYTE_1(id) ((id)[0]) + +#define ID_GET_MFR_CODE(id) ID_GET_BYTE_1(id) + +/* Byte 2 ------------------------------------------------------------------- */ + +#define ID_GET_BYTE_2(id) ((id)[1]) + +#define ID_GET_DEVICE_CODE(id) ID_GET_BYTE_2(id) + #define ID_SAMSUNG_DEVICE_CODE_1_GBIT (0xf1) + #define ID_SAMSUNG_DEVICE_CODE_2_GBIT (0xda) + #define ID_HYNIX_DEVICE_CODE_ECC12 (0xd7) + #define ID_HYNIX_DEVICE_CODE_ECC12_LARGE (0xde) + #define ID_MICRON_DEVICE_CODE_ECC12 (0xd7) /* ECC12 */ + #define ID_MICRON_DEVICE_CODE_ECC12_LARGE (0xd9) /* ECC12 8GB/CE */ + #define ID_MICRON_DEVICE_CODE_ECC12_2GB_PER_CE (0x48) /* L63B 2GB/CE */ + #define ID_MICRON_DEVICE_CODE_ECC12_4GB_PER_CE (0x68) /* L63B 4GB/CE */ + #define ID_MICRON_DEVICE_CODE_ECC12_8GB_PER_CE (0x88) /* L63B 8GB/CE */ + +/* Byte 3 ------------------------------------------------------------------- */ + +#define ID_GET_BYTE_3(id) ((id)[2]) + +#define ID_GET_DIE_COUNT_CODE(id) ((ID_GET_BYTE_3(id) >> 0) & 0x3) + +#define ID_GET_CELL_TYPE_CODE(id) ((ID_GET_BYTE_3(id) >> 2) & 0x3) + #define ID_CELL_TYPE_CODE_SLC (0x0) /* All others => MLC. */ + +#define ID_GET_SAMSUNG_SIMUL_PROG(id) ((ID_GET_BYTE_3(id) >> 4) & 0x3) + +#define ID_GET_MICRON_SIMUL_PROG(id) ((ID_GET_BYTE_3(id) >> 4) & 0x3) + +#define ID_GET_CACHE_PROGRAM(id) ((ID_GET_BYTE_3(id) >> 7) & 0x1) + +/* Byte 4 ------------------------------------------------------------------- */ + +#define ID_GET_BYTE_4(id) ((id)[3]) + #define ID_HYNIX_BYTE_4_ECC12_DEVICE (0x25) + +#define ID_GET_PAGE_SIZE_CODE(id) ((ID_GET_BYTE_4(id) >> 0) & 0x3) + #define ID_PAGE_SIZE_CODE_1K (0x0) + #define ID_PAGE_SIZE_CODE_2K (0x1) + #define ID_PAGE_SIZE_CODE_4K (0x2) + #define ID_PAGE_SIZE_CODE_8K (0x3) + #define ID_SAMSUNG_6_BYTE_PAGE_SIZE_CODE_8K (0x2) + +#define ID_GET_OOB_SIZE_CODE(id) ((ID_GET_BYTE_4(id) >> 2) & 0x1) + +#define ID_GET_BLOCK_SIZE_CODE(id) ((ID_GET_BYTE_4(id) >> 4) & 0x3) + +/* Byte 5 ------------------------------------------------------------------- */ + +#define ID_GET_BYTE_5(id) ((id)[4]) + #define ID_MICRON_BYTE_5_ECC12 (0x84) + +#define ID_GET_SAMSUNG_ECC_LEVEL_CODE(id) ((ID_GET_BYTE_5(id) >> 4) & 0x7) + #define ID_SAMSUNG_ECC_LEVEL_CODE_8 (0x03) + #define ID_SAMSUNG_ECC_LEVEL_CODE_24 (0x05) + +#define ID_GET_PLANE_COUNT_CODE(id) ((ID_GET_BYTE_5(id) >> 2) & 0x3) + +/* Byte 6 ------------------------------------------------------------------- */ + +#define ID_GET_BYTE_6(id) ((id)[5]) + #define ID_TOSHIBA_BYTE_6_PAGE_SIZE_CODE_8K (0x54) + #define ID_TOSHIBA_BYTE_6_PAGE_SIZE_CODE_4K (0x13) + +#define ID_GET_SAMSUNG_DEVICE_VERSION_CODE(id) ((ID_GET_BYTE_6(id)>>0) & 0x7) + #define ID_SAMSUNG_DEVICE_VERSION_CODE_40NM (0x01) + +/* -------------------------------------------------------------------------- */ + +void nand_device_print_info(struct nand_device_info *info) +{ + unsigned i; + const char *mfr_name; + const char *cell_technology_name; + uint64_t chip_size; + const char *chip_size_units; + unsigned page_data_size_in_bytes; + unsigned page_oob_size_in_bytes; + + /* Check for nonsense. */ + + if (!info) + return; + + /* Prepare the manufacturer name. */ + + mfr_name = "Unknown"; + + for (i = 0; nand_manuf_ids[i].id; i++) { + if (nand_manuf_ids[i].id == info->manufacturer_code) { + mfr_name = nand_manuf_ids[i].name; + break; + } + } + + /* Prepare the name of the cell technology. */ + + switch (info->cell_technology) { + case NAND_DEVICE_CELL_TECH_SLC: + cell_technology_name = "SLC"; + break; + case NAND_DEVICE_CELL_TECH_MLC: + cell_technology_name = "MLC"; + break; + default: + cell_technology_name = "Unknown"; + break; + } + + /* Prepare the chip size. */ + + if ((info->chip_size_in_bytes >= SZ_1G) && + !(info->chip_size_in_bytes % SZ_1G)) { + chip_size = info->chip_size_in_bytes / ((uint64_t) SZ_1G); + chip_size_units = "GiB"; + } else if ((info->chip_size_in_bytes >= SZ_1M) && + !(info->chip_size_in_bytes % SZ_1M)) { + chip_size = info->chip_size_in_bytes / ((uint64_t) SZ_1M); + chip_size_units = "MiB"; + } else { + chip_size = info->chip_size_in_bytes; + chip_size_units = "B"; + } + + /* Prepare the page geometry. */ + + page_data_size_in_bytes = (1<<(fls(info->page_total_size_in_bytes)-1)); + page_oob_size_in_bytes = info->page_total_size_in_bytes - + page_data_size_in_bytes; + + /* Print the information. */ + + printk(KERN_INFO "Manufacturer : %s (0x%02x)\n", mfr_name, + info->manufacturer_code); + printk(KERN_INFO "Device Code : 0x%02x\n", info->device_code); + printk(KERN_INFO "Cell Technology : %s\n", cell_technology_name); + printk(KERN_INFO "Chip Size : %llu %s\n", chip_size, + chip_size_units); + printk(KERN_INFO "Pages per Block : %u\n", + info->block_size_in_pages); + printk(KERN_INFO "Page Geometry : %u+%u\n", page_data_size_in_bytes, + page_oob_size_in_bytes); + printk(KERN_INFO "ECC Strength : %u bits\n", + info->ecc_strength_in_bits); + printk(KERN_INFO "ECC Size : %u B\n", info->ecc_size_in_bytes); + printk(KERN_INFO "Data Setup Time : %u ns\n", info->data_setup_in_ns); + printk(KERN_INFO "Data Hold Time : %u ns\n", info->data_hold_in_ns); + printk(KERN_INFO "Address Setup Time: %u ns\n", + info->address_setup_in_ns); + printk(KERN_INFO "GPMI Sample Delay : %u ns\n", + info->gpmi_sample_delay_in_ns); + if (info->tREA_in_ns >= 0) + printk(KERN_INFO "tREA : %u ns\n", + info->tREA_in_ns); + else + printk(KERN_INFO "tREA : Unknown\n"); + if (info->tREA_in_ns >= 0) + printk(KERN_INFO "tRLOH : %u ns\n", + info->tRLOH_in_ns); + else + printk(KERN_INFO "tRLOH : Unknown\n"); + if (info->tREA_in_ns >= 0) + printk(KERN_INFO "tRHOH : %u ns\n", + info->tRHOH_in_ns); + else + printk(KERN_INFO "tRHOH : Unknown\n"); + if (info->description) + printk(KERN_INFO "Description : %s\n", info->description); + else + printk(KERN_INFO "Description : \n"); + +} + +static struct nand_device_info *nand_device_info_search( + struct nand_device_info *table, uint8_t mfr_code, uint8_t device_code) +{ + + for (; !table->end_of_table; table++) { + if (table->manufacturer_code != mfr_code) + continue; + if (table->device_code != device_code) + continue; + return table; + } + + return 0; + +} + +static struct nand_device_info * __init nand_device_info_fn_toshiba(const uint8_t id[]) +{ + struct nand_device_info *table; + + /* Check for an SLC device. */ + + if (ID_GET_CELL_TYPE_CODE(id) == ID_CELL_TYPE_CODE_SLC) { + /* Type 2 */ + return nand_device_info_search(nand_device_info_table_type_2, + ID_GET_MFR_CODE(id), ID_GET_DEVICE_CODE(id)); + } + + /* + * Look for 8K page Toshiba MLC devices. + * + * The page size field in byte 4 can't be used because the field was + * redefined in the 8K parts so the value meaning "8K page" is the same + * as the value meaning "4K page" on the 4K page devices. + * + * The only identifiable difference between the 4K and 8K page Toshiba + * devices with a device code of 0xd7 is the undocumented 6th ID byte. + * The 4K device returns a value of 0x13 and the 8K a value of 0x54. + * Toshiba has verified that this is an acceptable method to distinguish + * the two device families. + */ + + if (ID_GET_BYTE_6(id) == ID_TOSHIBA_BYTE_6_PAGE_SIZE_CODE_8K) { + /* Type 11 */ + table = nand_device_info_table_type_11; + } else if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { + /* Type 9 */ + table = nand_device_info_table_type_9; + } else { + /* Large MLC */ + table = nand_device_info_table_large_mlc; + } + + return nand_device_info_search(table, ID_GET_MFR_CODE(id), + ID_GET_DEVICE_CODE(id)); + +} + +static struct nand_device_info * __init nand_device_info_fn_samsung(const uint8_t id[]) +{ + struct nand_device_info *table; + + /* Check for an MLC device. */ + + if (ID_GET_CELL_TYPE_CODE(id) != ID_CELL_TYPE_CODE_SLC) { + + /* Is this a Samsung 8K Page MLC device with 16 bit ECC? */ + if ((ID_GET_SAMSUNG_ECC_LEVEL_CODE(id) == + ID_SAMSUNG_ECC_LEVEL_CODE_24) && + (ID_GET_PAGE_SIZE_CODE(id) == + ID_SAMSUNG_6_BYTE_PAGE_SIZE_CODE_8K)) { + /* Type 15 */ + table = nand_device_info_table_type_15; + } + /* Is this a Samsung 42nm ECC8 device with a 6 byte ID? */ + else if ((ID_GET_SAMSUNG_ECC_LEVEL_CODE(id) == + ID_SAMSUNG_ECC_LEVEL_CODE_8) && + (ID_GET_SAMSUNG_DEVICE_VERSION_CODE(id) == + ID_SAMSUNG_DEVICE_VERSION_CODE_40NM)) { + /* Type 9 */ + table = nand_device_info_table_type_9; + } else if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { + /* Type 8 */ + table = nand_device_info_table_type_8; + } else { + /* Large MLC */ + table = nand_device_info_table_large_mlc; + } + + } else { + + /* Check the page size first. */ + if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { + /* Type 10 */ + table = nand_device_info_table_type_10; + } + /* Check the chip size. */ + else if (ID_GET_DEVICE_CODE(id) == + ID_SAMSUNG_DEVICE_CODE_1_GBIT) { + if (!ID_GET_CACHE_PROGRAM(id)) { + /* + * 128 MiB Samsung chips without cache program + * are Type 7. + * + * The K9F1G08U0B does not support multi-plane + * program, so the if statement below cannot be + * used to identify it. + */ + table = nand_device_info_table_type_7; + + } else { + /* Smaller sizes are Type 2 by default. */ + table = nand_device_info_table_type_2; + } + } else { + /* Check number of simultaneously programmed pages. */ + if (ID_GET_SAMSUNG_SIMUL_PROG(id) && + ID_GET_PLANE_COUNT_CODE(id)) { + /* Type 7 */ + table = nand_device_info_table_type_7; + } else { + /* Type 2 */ + table = nand_device_info_table_type_2; + } + + } + + } + + return nand_device_info_search(table, ID_GET_MFR_CODE(id), + ID_GET_DEVICE_CODE(id)); + +} + +static struct nand_device_info * __init nand_device_info_fn_stmicro(const uint8_t id[]) +{ + struct nand_device_info *table; + + /* Check for an SLC device. */ + + if (ID_GET_CELL_TYPE_CODE(id) == ID_CELL_TYPE_CODE_SLC) + /* Type 2 */ + table = nand_device_info_table_type_2; + else + /* Large MLC */ + table = nand_device_info_table_large_mlc; + + return nand_device_info_search(table, ID_GET_MFR_CODE(id), + ID_GET_DEVICE_CODE(id)); + +} + +static struct nand_device_info * __init nand_device_info_fn_hynix(const uint8_t id[]) +{ + struct nand_device_info *table; + + /* Check for an SLC device. */ + + if (ID_GET_CELL_TYPE_CODE(id) == ID_CELL_TYPE_CODE_SLC) { + /* Type 2 */ + return nand_device_info_search(nand_device_info_table_type_2, + ID_GET_MFR_CODE(id), ID_GET_DEVICE_CODE(id)); + } + + /* + * Check for ECC12 devices. + * + * We look at the 4th ID byte to distinguish some Hynix ECC12 devices + * from the similar ECC8 part. For example H27UBG8T2M (ECC12) 4th byte + * is 0x25, whereas H27UDG8WFM (ECC8) 4th byte is 0xB6. + */ + + if ((ID_GET_DEVICE_CODE(id) == ID_HYNIX_DEVICE_CODE_ECC12 && + ID_GET_BYTE_4(id) == ID_HYNIX_BYTE_4_ECC12_DEVICE) || + (ID_GET_DEVICE_CODE(id) == ID_HYNIX_DEVICE_CODE_ECC12_LARGE)) { + /* BCH ECC 12 */ + table = nand_device_info_table_bch_ecc12; + } else if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { + /* + * So far, all other Samsung and Hynix 4K page devices are + * Type 8. + */ + table = nand_device_info_table_type_8; + } else + /* Large MLC */ + table = nand_device_info_table_large_mlc; + + return nand_device_info_search(table, ID_GET_MFR_CODE(id), + ID_GET_DEVICE_CODE(id)); + +} + +static struct nand_device_info * __init nand_device_info_fn_micron(const uint8_t id[]) +{ + struct nand_device_info *table; + + /* Check for an SLC device. */ + + if (ID_GET_CELL_TYPE_CODE(id) == ID_CELL_TYPE_CODE_SLC) { + + /* Check number of simultaneously programmed pages. */ + + if (ID_GET_MICRON_SIMUL_PROG(id)) { + /* Type 7 */ + table = nand_device_info_table_type_7; + } else { + /* Zero simultaneously programmed pages means Type 2. */ + table = nand_device_info_table_type_2; + } + + return nand_device_info_search(table, ID_GET_MFR_CODE(id), + ID_GET_DEVICE_CODE(id)); + + } + + /* + * We look at the 5th ID byte to distinguish some Micron ECC12 NANDs + * from the similar ECC8 part. + * + * For example MT29F64G08CFAAA (ECC12) 5th byte is 0x84, whereas + * MT29F64G08TAA (ECC8) 5th byte is 0x78. + * + * We also have a special case for the Micron L63B family + * (256 page/block), which has unique device codes but no ID fields that + * can easily be used to distinguish the family. + */ + + if ((ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC12 && + ID_GET_BYTE_5(id) == ID_MICRON_BYTE_5_ECC12) || + (ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC12_LARGE) || + (ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC12_2GB_PER_CE) || + (ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC12_4GB_PER_CE) || + (ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC12_8GB_PER_CE)) { + /* BCH ECC 12 */ + table = nand_device_info_table_bch_ecc12; + } else if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { + /* Toshiba devices with 4K pages are Type 9. */ + table = nand_device_info_table_type_9; + } else { + /* Large MLC */ + table = nand_device_info_table_large_mlc; + } + + return nand_device_info_search(table, ID_GET_MFR_CODE(id), + ID_GET_DEVICE_CODE(id)); + +} + +static struct nand_device_info * __init nand_device_info_fn_sandisk(const uint8_t id[]) +{ + struct nand_device_info *table; + + if (ID_GET_CELL_TYPE_CODE(id) != ID_CELL_TYPE_CODE_SLC) { + /* Large MLC */ + table = nand_device_info_table_large_mlc; + } else { + /* Type 2 */ + table = nand_device_info_table_type_2; + } + + return nand_device_info_search(table, ID_GET_MFR_CODE(id), + ID_GET_DEVICE_CODE(id)); + +} + +static struct nand_device_info * __init nand_device_info_fn_intel(const uint8_t id[]) +{ + struct nand_device_info *table; + + /* Check for an SLC device. */ + + if (ID_GET_CELL_TYPE_CODE(id) == ID_CELL_TYPE_CODE_SLC) { + /* Type 2 */ + return nand_device_info_search(nand_device_info_table_type_2, + ID_GET_MFR_CODE(id), ID_GET_DEVICE_CODE(id)); + } + + if (ID_GET_PAGE_SIZE_CODE(id) == ID_PAGE_SIZE_CODE_4K) { + /* Type 9 */ + table = nand_device_info_table_type_9; + } else { + /* Large MLC */ + table = nand_device_info_table_large_mlc; + } + + return nand_device_info_search(table, ID_GET_MFR_CODE(id), + ID_GET_DEVICE_CODE(id)); + +} + +/** + * struct nand_device_type_info - Information about a NAND Flash type. + * + * @name: A human-readable name for this type. + * @table: The device info table for this type. + */ + +struct nand_device_type_info { + struct nand_device_info *table; + const char *name; +}; + +/* + * A table that maps manufacturer IDs to device information tables. + */ + +static struct nand_device_type_info nand_device_type_directory[] __initdata = +{ + {nand_device_info_table_type_2, "Type 2" }, + {nand_device_info_table_large_mlc, "Large MLC"}, + {nand_device_info_table_type_7, "Type 7" }, + {nand_device_info_table_type_8, "Type 8" }, + {nand_device_info_table_type_9, "Type 9" }, + {nand_device_info_table_type_10, "Type 10" }, + {nand_device_info_table_type_11, "Type 11" }, + {nand_device_info_table_type_15, "Type 15" }, + {nand_device_info_table_bch_ecc12, "BCH ECC12"}, + {0, 0}, +}; + +/** + * struct nand_device_mfr_info - Information about a NAND Flash manufacturer. + * + * @id: The value of the first NAND Flash ID byte, which identifies the + * manufacturer. + * @fn: A pointer to a function to use for identifying devices from the + * given manufacturer. + */ + +struct nand_device_mfr_info { + uint8_t id; + struct nand_device_info *(*fn)(const uint8_t id[]); +}; + +/* + * A table that maps manufacturer IDs to device information tables. + */ + +static struct nand_device_mfr_info nand_device_mfr_directory[] __initdata = +{ + { + .id = NAND_MFR_TOSHIBA, + .fn = nand_device_info_fn_toshiba, + }, + { + .id = NAND_MFR_SAMSUNG, + .fn = nand_device_info_fn_samsung, + }, + { + .id = NAND_MFR_FUJITSU, + .fn = 0, + }, + { + .id = NAND_MFR_NATIONAL, + .fn = 0, + }, + { + .id = NAND_MFR_RENESAS, + .fn = 0, + }, + { + .id = NAND_MFR_STMICRO, + .fn = nand_device_info_fn_stmicro, + }, + { + .id = NAND_MFR_HYNIX, + .fn = nand_device_info_fn_hynix, + }, + { + .id = NAND_MFR_MICRON, + .fn = nand_device_info_fn_micron, + }, + { + .id = NAND_MFR_AMD, + .fn = 0, + }, + { + .id = NAND_MFR_SANDISK, + .fn = nand_device_info_fn_sandisk, + }, + { + .id = NAND_MFR_INTEL, + .fn = nand_device_info_fn_intel, + }, + {0, 0} +}; + +/** + * nand_device_info_test_table - Validate a device info table. + * + * This function runs tests on the given device info table to check that it + * meets the current assumptions. + */ + +static void __init nand_device_info_test_table( + struct nand_device_info *table, const char * name) +{ + unsigned i; + unsigned j; + uint8_t mfr_code; + uint8_t device_code; + + /* Loop over entries in this table. */ + + for (i = 0; !table[i].end_of_table; i++) { + + /* Get discriminating attributes of the current device. */ + + mfr_code = table[i].manufacturer_code; + device_code = table[i].device_code; + + /* Compare with the remaining devices in this table. */ + + for (j = i + 1; !table[j].end_of_table; j++) { + if ((mfr_code == table[j].manufacturer_code) && + (device_code == table[j].device_code)) + goto error; + } + + } + + return; + +error: + + printk(KERN_EMERG + "\n== NAND Flash device info table failed validity check ==\n"); + + printk(KERN_EMERG "\nDevice Info Table: %s\n", name); + printk(KERN_EMERG "\nTable Index %u\n", i); + nand_device_print_info(table + i); + printk(KERN_EMERG "\nTable Index %u\n", j); + nand_device_print_info(table + j); + printk(KERN_EMERG "\n"); + + BUG(); + +} + +/** + * nand_device_info_test_data - Test the NAND Flash device data. + */ + +static void __init nand_device_info_test_data(void) +{ + + unsigned i; + + for (i = 0; nand_device_type_directory[i].name; i++) { + nand_device_info_test_table( + nand_device_type_directory[i].table, + nand_device_type_directory[i].name); + } + +} + +struct nand_device_info * __init nand_device_get_info(const uint8_t id[]) +{ + unsigned i; + uint8_t mfr_id = ID_GET_MFR_CODE(id); + struct nand_device_info *(*fn)(const uint8_t id[]) = 0; + + /* Test the data. */ + + nand_device_info_test_data(); + + /* Look for information about this manufacturer. */ + + for (i = 0; nand_device_mfr_directory[i].id; i++) { + if (nand_device_mfr_directory[i].id == mfr_id) { + fn = nand_device_mfr_directory[i].fn; + break; + } + } + + if (!fn) + return 0; + + /* + * If control arrives here, we found both a table of device information, + * and a function we can use to identify the current device. Attempt to + * identify the device and return the result. + */ + + return fn(id); + +} diff --git a/drivers/mtd/nand/nand_device_info.h b/drivers/mtd/nand/nand_device_info.h new file mode 100644 index 000000000000..a5f56e913ec6 --- /dev/null +++ b/drivers/mtd/nand/nand_device_info.h @@ -0,0 +1,140 @@ +/* + * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __DRIVERS_NAND_DEVICE_INFO_H +#define __DRIVERS_NAND_DEVICE_INFO_H + + /* + * The number of ID bytes to read from the NAND Flash device and hand over to + * the identification system. + */ + +#define NAND_DEVICE_ID_BYTE_COUNT (6) + + /* + * The number of ID bytes to read from the NAND Flash device and hand over to + * the identification system. + */ + +enum nand_device_cell_technology { + NAND_DEVICE_CELL_TECH_SLC = 0, + NAND_DEVICE_CELL_TECH_MLC = 1, +}; + +/** + * struct nand_device_info - Information about a single NAND Flash device. + * + * This structure contains all the *essential* information about a NAND Flash + * device, derived from the device's data sheet. For each manufacturer, we have + * an array of these structures. + * + * @end_of_table: If true, marks the end of a table of device + * information. + * @manufacturer_code: The manufacturer code (1st ID byte) reported by + * the device. + * @device_code: The device code (2nd ID byte) reported by the + * device. + * @cell_technology: The storage cell technology. + * @chip_size_in_bytes: The total size of the storage behind a single + * chip select, in bytes. Notice that this is *not* + * necessarily the total size of the storage in a + * *package*, which may contain several chips. + * @block_size_in_pages: The number of pages in a block. + * @page_total_size_in_bytes: The total size of a page, in bytes, including + * both the data and the OOB. + * @ecc_strength_in_bits: The strength of the ECC called for by the + * manufacturer, in number of correctable bits. + * @ecc_size_in_bytes: The size of the data block over which the + * manufacturer calls for the given ECC algorithm + * and strength. + * @data_setup_in_ns: The data setup time, in nanoseconds. Usually the + * maximum of tDS and tWP. A negative value + * indicates this characteristic isn't known. + * @data_hold_in_ns: The data hold time, in nanoseconds. Usually the + * maximum of tDH, tWH and tREH. A negative value + * indicates this characteristic isn't known. + * @address_setup_in_ns: The address setup time, in nanoseconds. Usually + * the maximum of tCLS, tCS and tALS. A negative + * value indicates this characteristic isn't known. + * @gpmi_sample_delay_in_ns: A GPMI-specific timing parameter. A negative + * value indicates this characteristic isn't known. + * @tREA_in_ns: tREA, in nanoseconds, from the data sheet. A + * negative value indicates this characteristic + * isn't known. + * @tRLOH_in_ns: tRLOH, in nanoseconds, from the data sheet. A + * negative value indicates this characteristic + * isn't known. + * @tRHOH_in_ns: tRHOH, in nanoseconds, from the data sheet. A + * negative value indicates this characteristic + * isn't known. + */ + +struct nand_device_info { + + /* End of table marker */ + + bool end_of_table; + + /* Manufacturer and Device codes */ + + uint8_t manufacturer_code; + uint8_t device_code; + + /* Technology */ + + enum nand_device_cell_technology cell_technology; + + /* Geometry */ + + uint64_t chip_size_in_bytes; + uint32_t block_size_in_pages; + uint16_t page_total_size_in_bytes; + + /* ECC */ + + uint8_t ecc_strength_in_bits; + uint16_t ecc_size_in_bytes; + + /* Timing */ + + int8_t data_setup_in_ns; + int8_t data_hold_in_ns; + int8_t address_setup_in_ns; + int8_t gpmi_sample_delay_in_ns; + int8_t tREA_in_ns; + int8_t tRLOH_in_ns; + int8_t tRHOH_in_ns; + + /* Description */ + + const char *description; + +}; + +/** + * nand_device_get_info - Get info about a device based on ID bytes. + * + * @id_bytes: An array of NAND_DEVICE_ID_BYTE_COUNT ID bytes retrieved from the + * NAND Flash device. + */ + +struct nand_device_info *nand_device_get_info(const uint8_t id_bytes[]); + +/** + * nand_device_print_info - Prints information about a NAND Flash device. + * + * @info A pointer to a NAND Flash device information structure. + */ + +void nand_device_print_info(struct nand_device_info *info); + +#endif -- cgit v1.2.3