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