ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/uboot/board/Marvell/common/nand.c b/marvell/uboot/board/Marvell/common/nand.c
new file mode 100644
index 0000000..7cf5ba1
--- /dev/null
+++ b/marvell/uboot/board/Marvell/common/nand.c
@@ -0,0 +1,224 @@
+#include <nand.h>
+#include <spi_flash.h>
+#include <common.h>
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <asm/errno.h>
+#include <asm/string.h>
+#include <mtd/pxa3xx_bbm.h>
+#include <asm/arch/pxa3xx_nand.h>
+
+int nand_curr_device = -1;
+#ifdef CONFIG_CMD_NAND
+nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
+#endif
+#ifdef CONFIG_CMD_ONENAND
+extern struct mtd_info onenand_mtd;
+#endif
+
+#ifdef CONFIG_NAND_PXA
+
+#ifdef MEP_OTA_FLASH_ADDRESS
+void nand_lock_priv_block(void)
+{
+	int chip = nand_curr_device;
+
+	if (chip < 0)
+		return;
+
+	nand_info[chip].protect_enabled = 1;
+}
+
+void nand_unlock_priv_block(void)
+{
+	int chip = nand_curr_device;
+
+	if (chip < 0)
+		return;
+
+	nand_info[chip].protect_enabled = 0;
+}
+
+static void nand_init_proctect_block(nand_info_t *nand)
+{
+	nand->protect_enabled = 1;
+	nand->protect_start = MEP_OTA_FLASH_ADDRESS;
+	nand->protect_end = MEP_OTA_FLASH_ADDRESS + MEP_OTA_FLASH_LEN;
+}
+#endif
+
+void nand_init()
+{
+	struct pxa3xx_nand_platform_data pxa_nandinfo;
+	struct pxa3xx_nand *nand;
+	int chip;
+
+	pxa_nandinfo.mmio_base		= CONFIG_SYS_NAND_BASE;
+	pxa_nandinfo.enable_arbiter 	= 1;
+	pxa_nandinfo.RD_CNT_DEL		= 0;
+
+	nand = pxa3xx_nand_probe(&pxa_nandinfo);
+	if (!nand) {
+		printf("pxa3xx-nand probe failed!!\n");
+		return;
+	}
+
+	for (chip = 0; chip < CONFIG_SYS_MAX_NAND_DEVICE; chip ++) {
+		if (nand->mtd[chip]) {
+#ifdef MEP_OTA_FLASH_ADDRESS
+			nand_init_proctect_block(nand->mtd[chip]);
+#endif
+			memcpy(&(nand_info[chip]), nand->mtd[chip], sizeof(struct mtd_info));
+
+			if (nand_curr_device < 0)
+				nand_curr_device = chip;
+		}
+	}
+
+	if (nand_curr_device < 0)
+		printf("No NAND dev is found !!!\n\n");
+}
+#endif
+
+#ifdef CONFIG_SPI_COPYBACK_NAND
+#define BACK_NTIM_OF		0x1000
+#define BACK_OBM_OF		0x30000
+#define BACK_UBOOT_OF		0x40000
+#define BACK_ZIMAGE_OF		0x100000
+#define BURN_ZIMAGE_OF		0x400000
+#define MAX_NTIM_SIZE		0x1000
+#define MAX_OBM_SIZE		0xf000
+#define MAX_UBOOT_SIZE		0x30000
+#define MAX_ZIMAGE_SIZE		0x300000
+#define NTIM_HEADER_1		0x30102
+#define NTIM_HEADER_2		0x54494d48
+#define BBT_INIT_COMMAND	"bbt init nand new"
+int nand_update_callback(void)
+{
+	void *buf = (void *)0x500000;
+	size_t retlen;
+	int ret;
+	unsigned int header_1, header_2;
+	struct mtd_info *mtd;
+
+	if (nand_curr_device != 0)
+		return -1;
+
+	mtd = &nand_info[0];
+	mtd->read(mtd, 0, mtd->writesize, &retlen, buf);
+	header_1 = *(unsigned int*)buf;
+	header_2 = *((unsigned int*)buf + 1);
+	if (header_1 == NTIM_HEADER_1 && header_2 == NTIM_HEADER_2) {
+		return 1;
+	}
+	else {
+		extern int not_updating;
+		extern struct spi_flash *flash;
+		struct erase_info instr = {
+			.callback	= NULL,
+		};
+
+		printf("\n### begin to update nand from spi nor ###\n");
+		run_command("nand device 1", 0);
+		not_updating = 1;
+		run_command(BBT_INIT_COMMAND, 0);
+		run_command("nand device 0", 0);
+		not_updating = 0;
+		run_command(BBT_INIT_COMMAND, 0);
+		not_updating = 1;
+		instr.addr = mtd->erasesize;
+		instr.len = instr.addr * 3;
+		printf("\nerasing..");
+		ret = mtd->erase(mtd, &instr);
+		if (ret) {
+			printf("erase 1-3 block failed!!!\n");
+			goto UPDATE_FAILED;
+		}
+
+		instr.addr = BACK_ZIMAGE_OF;
+		instr.len = MAX_ZIMAGE_SIZE * 2;
+		ret = mtd->erase(mtd, &instr);
+		if (ret) {
+			printf("erase 0x100000-0x700000 failed!!!\n");
+			goto UPDATE_FAILED;
+		}
+
+		printf("spi read 1..");
+		ret = spi_flash_read(flash, BACK_NTIM_OF, MAX_NTIM_SIZE, buf);
+		if (ret) {
+			printf("read ntim failed\n");
+			goto UPDATE_FAILED;
+		}
+
+		printf("2..");
+		buf += MAX_NTIM_SIZE;
+		ret = spi_flash_read(flash, BACK_OBM_OF, MAX_OBM_SIZE, buf);
+		if (ret) {
+			printf("read obm failed\n");
+			goto UPDATE_FAILED;
+		}
+
+		printf("3..");
+		buf += MAX_OBM_SIZE;
+		ret = spi_flash_read(flash, BACK_UBOOT_OF, MAX_UBOOT_SIZE,
+				buf);
+		if (ret) {
+			printf("read uboot failed\n");
+			goto UPDATE_FAILED;
+		}
+
+		printf("4..");
+		buf += MAX_UBOOT_SIZE;
+		ret = spi_flash_read(flash, BACK_ZIMAGE_OF, MAX_ZIMAGE_SIZE,
+				buf);
+		if (ret) {
+			printf("read zImage failed\n");
+			goto UPDATE_FAILED;
+		}
+
+		printf("nand write 1..");
+		buf = (void *)0x500000;
+		ret = mtd->write(mtd, 0, MAX_NTIM_SIZE, &retlen, buf);
+		if (ret) {
+			printf("update ntim failed!!\n");
+			goto UPDATE_FAILED;
+		}
+
+		printf("2..");
+		buf += MAX_NTIM_SIZE;
+		ret = mtd->write(mtd, mtd->erasesize, MAX_OBM_SIZE, &retlen,
+				buf);
+		if (ret) {
+			printf("update obm failed!!\n");
+			goto UPDATE_FAILED;
+		}
+
+		printf("3..");
+		buf += MAX_OBM_SIZE;
+		ret = mtd->write(mtd, mtd->erasesize * 2, MAX_UBOOT_SIZE,
+				&retlen, buf);
+		if (ret) {
+			printf("update uboot failed!!\n");
+			goto UPDATE_FAILED;
+		}
+
+		printf("4..");
+		buf += MAX_UBOOT_SIZE;
+		ret = mtd->write(mtd, BURN_ZIMAGE_OF, MAX_ZIMAGE_SIZE,
+				&retlen, buf);
+		if (ret) {
+			printf("update zImage failed!!\n");
+			goto UPDATE_FAILED;
+		}
+
+		printf("update done!!\n");
+		return 0;
+UPDATE_FAILED:
+
+		printf("!!!update failed!!!\n");
+		return -1;
+	}
+}
+#endif