zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/boot/common/src/uboot/drivers/mtd/nand/nand.c b/boot/common/src/uboot/drivers/mtd/nand/nand.c
new file mode 100755
index 0000000..ec3f79a
--- /dev/null
+++ b/boot/common/src/uboot/drivers/mtd/nand/nand.c
@@ -0,0 +1,184 @@
+/*
+ * (C) Copyright 2005
+ * 2N Telekomunikace, a.s. <www.2n.cz>
+ * Ladislav Michl <michl@2n.cz>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <nand.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <part.h>
+
+#include <boot_mode.h>
+
+
+#ifndef CONFIG_SYS_NAND_BASE_LIST
+#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static __attribute__((unused)) char dev_name[CONFIG_SYS_MAX_NAND_DEVICE][8];
+
+int nand_curr_device = -1;
+nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
+
+struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];  //zhouqi
+static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] = CONFIG_SYS_NAND_BASE_LIST;
+
+static const char default_nand_name[] = "nand";
+struct flash_ops flash;
+
+
+/*******************************************************************************
+ * Function:    
+ * Description: 
+ * Parameters:
+ *	 Input:
+ *
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int board_nand_init(struct nand_chip *nand)
+{
+    int ret = 0;
+	int boot_flash_type = 0;
+
+	boot_flash_type = read_boot_flashtype();
+	
+	if(boot_flash_type== IF_TYPE_NAND)
+	{
+		printf("nand: ");
+		ret = board_nand_init_denali(nand);
+		return ret;
+	}
+	else if(boot_flash_type == IF_TYPE_SPI_NAND)
+	{
+		printf("spi-nand: ");
+
+		ret = board_nand_init_spifc(nand);
+		return ret;
+	}
+	else if(boot_flash_type == IF_TYPE_NOR)
+	{
+		printf("spi-nor: ");
+		ret = fsl_qspi_probe();
+		return ret;
+	}
+	else
+	{
+		printf("boot_flash_type err\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+struct mtd_info* get_mtd_info(void)
+{
+	if (-1 == nand_curr_device || nand_curr_device > CONFIG_SYS_MAX_NAND_DEVICE)
+	{
+		return NULL;
+	}
+
+	return &nand_info[nand_curr_device];
+}
+
+static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
+			   ulong base_addr)
+{
+	mtd->priv = nand;
+	nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;
+
+	if (board_nand_init(nand) == 0) 
+	{
+		if (!mtd->name)
+		{
+			mtd->name = (char *)default_nand_name;
+		}
+
+#ifdef CONFIG_MTD_DEVICE
+		/*
+		 * Add MTD device so that we can reference it later
+		 * via the mtdcore infrastructure (e.g. ubi).
+		 */
+		sprintf(dev_name[i], "nand%d", i);
+		mtd->name = dev_name[i++];
+		add_mtd_device(mtd);
+#endif
+	}
+	else 
+	{
+		mtd->name = NULL;
+		mtd->size = 0;
+	}
+}
+
+void set_flash_opt(void)
+{
+	nand_info_t *nand = &nand_info[nand_curr_device];
+
+	flash.read = nand_read_skip_bad;
+	flash.read_no_ecc = nand_read_page_with_no_ecc;
+	flash.read_with_ecc = nand_read_page_with_ecc;
+	flash.write = nand_write_skip_bad;
+	flash.page_size = nand->writesize;
+	flash.erase = nand_erase_opts;
+ }
+
+struct flash_ops *get_flash_ops(void)
+{
+	struct flash_ops *m = NULL;
+	m = &flash;
+	
+	return m;
+}
+extern int jffs2_lzma_init(void);
+
+void nand_init(void)
+{
+	int i;
+	unsigned int size = 0;
+	for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) 
+	{
+		nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);
+		size += nand_info[i].size / 1024;
+		if (nand_curr_device == -1)
+		{
+			nand_curr_device = i;
+		}
+	}
+	BOOT_PRINTF(UBOOT_NOTICE, "%u MiB.\n", (size / 1024));
+
+#ifdef CONFIG_SYS_NAND_SELECT_DEVICE
+	/*
+	 * Select the chip in the board/cpu specific driver
+	 */
+	board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device);
+#endif
+
+	set_flash_opt();
+	jffs2_lzma_init();
+}