summaryrefslogtreecommitdiff
path: root/drivers/mtd/nand/nand_device_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/nand_device_info.c')
-rw-r--r--drivers/mtd/nand/nand_device_info.c2413
1 files changed, 2413 insertions, 0 deletions
diff --git a/drivers/mtd/nand/nand_device_info.c b/drivers/mtd/nand/nand_device_info.c
new file mode 100644
index 000000000000..6a23810ebadb
--- /dev/null
+++ b/drivers/mtd/nand/nand_device_info.c
@@ -0,0 +1,2413 @@
+/*
+ * Copyright (C) 2009-2010 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 <asm/sizes.h>
+#include <linux/mtd/nand.h>
+
+#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,
+ },
+ {
+ .end_of_table = false,
+ .manufacturer_code = 0x2c,
+ .device_code = 0x48,
+ .cell_technology = NAND_DEVICE_CELL_TECH_SLC,
+ .chip_size_in_bytes = 2LL*SZ_1G,
+ .block_size_in_pages = 128,
+ /* TODO: The actual oob size for MT29F16G08ABACA is
+ 224 bytes. Use oob 218 bytes since MX53 NFC controller
+ mentions the spare area size must be less or equal 218
+ byte if ECC is enabled */
+ .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 = 20,
+ .gpmi_sample_delay_in_ns = 6,
+ .tREA_in_ns = 20,
+ .tRLOH_in_ns = 5,
+ .tRHOH_in_ns = 15,
+ "MT29F16G08ABACA(2GB)",
+ },
+ {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",
+ },
+ {
+ .end_of_table = false,
+ .manufacturer_code = 0xad,
+ .device_code = 0xd3,
+ .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 + 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,
+ "H27U8G8T2B",
+ },
+ {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 = 20,
+ .tRLOH_in_ns = 5,
+ .tRHOH_in_ns = 15,
+ "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}
+};
+
+static struct nand_device_info nand_device_info_table_type_16[] __initdata = {
+ {
+ .end_of_table = false,
+ .manufacturer_code = 0xec,
+ .device_code = 0xd7,
+ .is_ddr_ok = true,
+ .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 + 512,
+ .ecc_strength_in_bits = 24,
+ .ecc_size_in_bytes = 1024,
+ .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,
+ "K9LCGD88X1M(8GB, 1CE); K9HDGD8X5M(8GB, 2CE); K9PFGD8X7M(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 = 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 + 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,
+ "H27UAG8T2ATR (2GB, 1CE)",
+ },
+ {
+ .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}
+};
+
+/*
+ * BCH ECC24
+ */
+static struct nand_device_info nand_device_info_table_bch_ecc24[] __initdata = {
+ {
+ .end_of_table = false,
+ .manufacturer_code = 0x2c,
+ .device_code = 0x88,
+ .is_ddr_ok = true,
+ .cell_technology = NAND_DEVICE_CELL_TECH_MLC,
+ .chip_size_in_bytes = 8LL * SZ_1G,
+ .block_size_in_pages = 256,
+ .page_total_size_in_bytes = 8 * SZ_1K + 448,
+ .ecc_strength_in_bits = 24,
+ .ecc_size_in_bytes = 1024,
+ .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,
+ "MT29F64G08CBAAA(8GB, 2CE) ",
+ },
+ {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_[<manufacturer>_[<modifier>_]]<field>
+ *
+ * extract the given field from an ID byte array. Macros of the form:
+ *
+ * ID_[<manufacturer>_[<modifier>_]]<field>_<meaning>
+ *
+ * contain the value for the given field that has the given meaning.
+ *
+ * If the <manufacturer> appears, it means this macro represents a view of this
+ * field that is specific to the given manufacturer.
+ *
+ * If the <modifier> 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_ODD (0xd5)
+ #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 */
+ #define ID_MICRON_DEVICE_CODE_ECC24_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)
+
+#define ID_ONFI_NAND_BYTE3 (0x04)
+/* 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)
+
+#define ID_GET_TOGGLE_NAND(id) ((ID_GET_BYTE_6(id) >> 7) & 0x1)
+
+/* -------------------------------------------------------------------------- */
+
+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 : <None>\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)) {
+ if (ID_GET_TOGGLE_NAND(id))
+ table = nand_device_info_table_type_16;
+ else
+ /* 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_DEVICE_CODE(id) == ID_HYNIX_DEVICE_CODE_ECC12_ODD)) &&
+ 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));
+
+ }
+
+ if (ID_GET_DEVICE_CODE(id) == ID_MICRON_DEVICE_CODE_ECC24_8GB_PER_CE
+ && ID_GET_BYTE_3(id) == ID_ONFI_NAND_BYTE3) {
+ /* BCH ECC 24 */
+ table = nand_device_info_table_bch_ecc24;
+ } else
+ /*
+ * 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_type_16, "Type 16" },
+ {nand_device_info_table_bch_ecc12, "BCH ECC12"},
+ {nand_device_info_table_bch_ecc24, "BCH ECC24"},
+ {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);
+
+}