Merge branch 'master' of git://git.denx.de/u-boot-blackfin
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index ea80555..84b6272 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -4,6 +4,10 @@
  * (c) 1999 Machine Vision Holdings, Inc.
  * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
  *
+ * Ported 'dynenv' to 'nand env.oob' command
+ * (C) 2010 Nanometrics, Inc.
+ * 'dynenv' -- Dynamic environment offset in NAND OOB
+ * (C) Copyright 2006-2007 OpenMoko, Inc.
  * Added 16-bit nand support
  * (C) 2004 Texas Instruments
  */
@@ -193,6 +197,90 @@
 }
 #endif
 
+#ifdef CONFIG_ENV_OFFSET_OOB
+unsigned long nand_env_oob_offset;
+
+int do_nand_env_oob(cmd_tbl_t *cmdtp, nand_info_t *nand,
+		    int argc, char * const argv[])
+{
+	int ret;
+	uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)];
+
+	char *cmd = argv[1];
+
+	if (!strcmp(cmd, "get")) {
+		ret = get_nand_env_oob(nand, &nand_env_oob_offset);
+		if (ret)
+			return 1;
+
+		printf("0x%08lx\n", nand_env_oob_offset);
+	} else if (!strcmp(cmd, "set")) {
+		ulong addr;
+		size_t dummy_size;
+		struct mtd_oob_ops ops;
+
+		if (argc < 3)
+			goto usage;
+
+		if (arg_off_size(argc - 2, argv + 2, nand, &addr,
+				 &dummy_size) < 0) {
+			printf("Offset or partition name expected\n");
+			return 1;
+		}
+
+		if (nand->oobavail < ENV_OFFSET_SIZE) {
+			printf("Insufficient available OOB bytes:\n"
+			       "%d OOB bytes available but %d required for "
+			       "env.oob support\n",
+			       nand->oobavail, ENV_OFFSET_SIZE);
+			return 1;
+		}
+
+		if ((addr & (nand->erasesize - 1)) != 0) {
+			printf("Environment offset must be block-aligned\n");
+			return 1;
+		}
+
+		ops.datbuf = NULL;
+		ops.mode = MTD_OOB_AUTO;
+		ops.ooboffs = 0;
+		ops.ooblen = ENV_OFFSET_SIZE;
+		ops.oobbuf = (void *) oob_buf;
+
+		oob_buf[0] = ENV_OOB_MARKER;
+		oob_buf[1] = addr / nand->erasesize;
+
+		ret = nand->write_oob(nand, ENV_OFFSET_SIZE, &ops);
+		if (ret) {
+			printf("Error writing OOB block 0\n");
+			return ret;
+		}
+
+		ret = get_nand_env_oob(nand, &nand_env_oob_offset);
+		if (ret) {
+			printf("Error reading env offset in OOB\n");
+			return ret;
+		}
+
+		if (addr != nand_env_oob_offset) {
+			printf("Verification of env offset in OOB failed: "
+			       "0x%08lx expected but got 0x%08lx\n",
+			       addr, nand_env_oob_offset);
+			return 1;
+		}
+	} else {
+		goto usage;
+	}
+
+	return ret;
+
+usage:
+	cmd_usage(cmdtp);
+	return 1;
+}
+
+#endif
+
 static void nand_print_info(int idx)
 {
 	nand_info_t *nand = &nand_info[idx];
@@ -272,9 +360,21 @@
 	    strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 &&
 	    strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 &&
 	    strcmp(cmd, "biterr") != 0 &&
-	    strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 )
+	    strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0
+#ifdef CONFIG_ENV_OFFSET_OOB
+	    && strcmp(cmd, "env.oob") != 0
+#endif
+	    )
 		goto usage;
 
+#ifdef CONFIG_ENV_OFFSET_OOB
+	/* this command operates only on the first nand device */
+	if (strcmp(cmd, "env.oob") == 0) {
+		return do_nand_env_oob(cmdtp, &nand_info[0],
+				       argc - 1, argv + 1);
+	}
+#endif
+
 	/* the following commands operate on the current device */
 	if (nand_curr_device < 0 || nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
 	    !nand_info[nand_curr_device].name) {
@@ -502,6 +602,13 @@
 	"    bring nand to lock state or display locked pages\n"
 	"nand unlock [offset] [size] - unlock section"
 #endif
+#ifdef CONFIG_ENV_OFFSET_OOB
+	"\n"
+	"nand env.oob - environment offset in OOB of block 0 of"
+	"    first device.\n"
+	"nand env.oob set off|partition - set enviromnent offset\n"
+	"nand env.oob get - get environment offset"
+#endif
 );
 
 static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
diff --git a/common/env_nand.c b/common/env_nand.c
index 50bc111..a5e1038 100644
--- a/common/env_nand.c
+++ b/common/env_nand.c
@@ -38,6 +38,7 @@
 #include <linux/stddef.h>
 #include <malloc.h>
 #include <nand.h>
+#include <asm/errno.h>
 
 #if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_NAND)
 #define CMD_SAVEENV
@@ -284,6 +285,38 @@
 	return 0;
 }
 
+#ifdef CONFIG_ENV_OFFSET_OOB
+int get_nand_env_oob(nand_info_t *nand, unsigned long *result)
+{
+	struct mtd_oob_ops ops;
+	uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)];
+	int ret;
+
+	ops.datbuf = NULL;
+	ops.mode = MTD_OOB_AUTO;
+	ops.ooboffs = 0;
+	ops.ooblen = ENV_OFFSET_SIZE;
+	ops.oobbuf = (void *) oob_buf;
+
+	ret = nand->read_oob(nand, ENV_OFFSET_SIZE, &ops);
+	if (ret) {
+		printf("error reading OOB block 0\n");
+		return ret;
+	}
+
+	if (oob_buf[0] == ENV_OOB_MARKER) {
+		*result = oob_buf[1] * nand->erasesize;
+	} else if (oob_buf[0] == ENV_OOB_MARKER_OLD) {
+		*result = oob_buf[1];
+	} else {
+		printf("No dynamic environment marker in OOB block 0\n");
+		return -ENOENT;
+	}
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_ENV_OFFSET_REDUND
 void env_relocate_spec (void)
 {
@@ -353,6 +386,17 @@
 #if !defined(ENV_IS_EMBEDDED)
 	int ret;
 
+#if defined(CONFIG_ENV_OFFSET_OOB)
+	ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset);
+	/* If unable to read environment offset from NAND OOB then fall through
+	 * to the normal environment reading code below
+	 */
+	if (!ret)
+		printf("Found Environment offset in OOB..\n");
+	else
+		return use_default();
+#endif
+
 	ret = readenv(CONFIG_ENV_OFFSET, (u_char *) env_ptr);
 	if (ret)
 		return use_default();
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 7171bdd..ed1c9c9 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2652,8 +2652,12 @@
 		}
 	}
 
-	if (!type)
+	if (!type) {
+		printk(KERN_INFO "%s: unknown NAND device: Manufacturer ID:"
+		       " 0x%02x, Chip ID: 0x%02x\n", __func__,
+		       *maf_id, dev_id);
 		return ERR_PTR(-ENODEV);
+	}
 
 	if (!mtd->name)
 		mtd->name = type->name;
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 077c305..25b22ec 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -83,6 +83,7 @@
 	/* 1 Gigabit */
 	{"NAND 128MiB 1,8V 8-bit",	0xA1, 0, 128, 0, LP_OPTIONS},
 	{"NAND 128MiB 3,3V 8-bit",	0xF1, 0, 128, 0, LP_OPTIONS},
+	{"NAND 128MiB 3,3V 8-bit",	0xD1, 0, 128, 0, LP_OPTIONS},
 	{"NAND 128MiB 1,8V 16-bit",	0xB1, 0, 128, 0, LP_OPTIONS16},
 	{"NAND 128MiB 3,3V 16-bit",	0xC1, 0, 128, 0, LP_OPTIONS16},
 
diff --git a/drivers/mtd/nand/nand_plat.c b/drivers/mtd/nand/nand_plat.c
index b35492b..37a0206 100644
--- a/drivers/mtd/nand/nand_plat.c
+++ b/drivers/mtd/nand/nand_plat.c
@@ -16,6 +16,10 @@
 
 #include <common.h>
 #include <asm/io.h>
+#ifdef NAND_PLAT_GPIO_DEV_READY
+# include <asm/gpio.h>
+# define NAND_PLAT_DEV_READY(chip) gpio_get_value(NAND_PLAT_GPIO_DEV_READY)
+#endif
 
 #include <nand.h>
 
@@ -43,7 +47,14 @@
 
 int board_nand_init(struct nand_chip *nand)
 {
+#ifdef NAND_PLAT_GPIO_DEV_READY
+	gpio_request(NAND_PLAT_GPIO_DEV_READY, "nand-plat");
+	gpio_direction_input(NAND_PLAT_GPIO_DEV_READY);
+#endif
+
+#ifdef NAND_PLAT_INIT
 	NAND_PLAT_INIT();
+#endif
 
 	nand->cmd_ctrl = plat_cmd_ctrl;
 	nand->dev_ready = plat_dev_ready;
diff --git a/include/configs/bf537-pnav.h b/include/configs/bf537-pnav.h
index 8daebc8..39bbb41 100644
--- a/include/configs/bf537-pnav.h
+++ b/include/configs/bf537-pnav.h
@@ -132,7 +132,6 @@
 
 #define BFIN_NAND_CLE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 2))
 #define BFIN_NAND_ALE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 1))
-#define BFIN_NAND_READY     PF12
 #define BFIN_NAND_WRITE(addr, cmd) \
 	do { \
 		bfin_write8(addr, cmd); \
@@ -141,13 +140,7 @@
 
 #define NAND_PLAT_WRITE_CMD(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_CLE(chip), cmd)
 #define NAND_PLAT_WRITE_ADR(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_ALE(chip), cmd)
-#define NAND_PLAT_DEV_READY(chip)      (bfin_read_PORTHIO() & BFIN_NAND_READY)
-#define NAND_PLAT_INIT() \
-	do { \
-		bfin_write_PORTH_FER(bfin_read_PORTH_FER() & ~BFIN_NAND_READY); \
-		bfin_write_PORTHIO_DIR(bfin_read_PORTHIO_DIR() & ~BFIN_NAND_READY); \
-		bfin_write_PORTHIO_INEN(bfin_read_PORTHIO_INEN() | BFIN_NAND_READY); \
-	} while (0)
+#define NAND_PLAT_GPIO_DEV_READY       GPIO_PF12
 
 
 /*
diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h
index 3592862..96704d7 100644
--- a/include/configs/bf537-stamp.h
+++ b/include/configs/bf537-stamp.h
@@ -155,7 +155,6 @@
 
 #define BFIN_NAND_CLE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 2))
 #define BFIN_NAND_ALE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 1))
-#define BFIN_NAND_READY     PF3
 #define BFIN_NAND_WRITE(addr, cmd) \
 	do { \
 		bfin_write8(addr, cmd); \
@@ -164,13 +163,7 @@
 
 #define NAND_PLAT_WRITE_CMD(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_CLE(chip), cmd)
 #define NAND_PLAT_WRITE_ADR(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_ALE(chip), cmd)
-#define NAND_PLAT_DEV_READY(chip)      (bfin_read_PORTFIO() & BFIN_NAND_READY)
-#define NAND_PLAT_INIT() \
-	do { \
-		bfin_write_PORTF_FER(bfin_read_PORTF_FER() & ~BFIN_NAND_READY); \
-		bfin_write_PORTFIO_DIR(bfin_read_PORTFIO_DIR() & ~BFIN_NAND_READY); \
-		bfin_write_PORTFIO_INEN(bfin_read_PORTFIO_INEN() | BFIN_NAND_READY); \
-	} while (0)
+#define NAND_PLAT_GPIO_DEV_READY       GPIO_PF3
 
 
 /*
diff --git a/include/configs/bf561-acvilon.h b/include/configs/bf561-acvilon.h
index 44854c7..0c0204f 100644
--- a/include/configs/bf561-acvilon.h
+++ b/include/configs/bf561-acvilon.h
@@ -144,7 +144,6 @@
 
 #define BFIN_NAND_CLE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 2))
 #define BFIN_NAND_ALE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 3))
-#define BFIN_NAND_READY     PF10
 #define BFIN_NAND_WRITE(addr, cmd) \
 	do { \
 		bfin_write8(addr, cmd); \
@@ -153,12 +152,7 @@
 
 #define NAND_PLAT_WRITE_CMD(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_CLE(chip), cmd)
 #define NAND_PLAT_WRITE_ADR(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_ALE(chip), cmd)
-#define NAND_PLAT_DEV_READY(chip)      (bfin_read_FIO0_FLAG_D() & BFIN_NAND_READY)
-#define NAND_PLAT_INIT() \
-	do { \
-		bfin_write_FIO0_DIR(bfin_read_FIO0_DIR() & ~BFIN_NAND_READY); \
-		bfin_write_FIO0_INEN(bfin_read_FIO0_INEN() | BFIN_NAND_READY); \
-	} while (0)
+#define NAND_PLAT_GPIO_DEV_READY       GPIO_PF10
 
 
 /*
diff --git a/include/configs/ip04.h b/include/configs/ip04.h
index 425a745..c024d78 100644
--- a/include/configs/ip04.h
+++ b/include/configs/ip04.h
@@ -116,7 +116,6 @@
 
 #define BFIN_NAND_CLE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 2))
 #define BFIN_NAND_ALE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 1))
-#define BFIN_NAND_READY     PF10
 #define BFIN_NAND_WRITE(addr, cmd) \
 	do { \
 		bfin_write8(addr, cmd); \
@@ -125,14 +124,7 @@
 
 #define NAND_PLAT_WRITE_CMD(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_CLE(chip), cmd)
 #define NAND_PLAT_WRITE_ADR(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_ALE(chip), cmd)
-#define NAND_PLAT_DEV_READY(chip)      (bfin_read_FIO_FLAG_D() & BFIN_NAND_READY)
-#define NAND_PLAT_INIT() \
-	do { \
-		bfin_write_FIO_DIR(bfin_read_FIO_DIR() & ~BFIN_NAND_READY); \
-		bfin_write_FIO_INEN(bfin_read_FIO_INEN() | BFIN_NAND_READY); \
-		bfin_write_FIO_EDGE(bfin_read_FIO_EDGE() & ~BFIN_NAND_READY); \
-		bfin_write_FIO_POLAR(bfin_read_FIO_POLAR() & ~BFIN_NAND_READY); \
-	} while (0)
+#define NAND_PLAT_GPIO_DEV_READY       GPIO_PF10
 
 
 /*
diff --git a/include/environment.h b/include/environment.h
index 203f731..fbccf6a 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -74,15 +74,24 @@
 #endif	/* CONFIG_ENV_IS_IN_FLASH */
 
 #if defined(CONFIG_ENV_IS_IN_NAND)
-# ifndef CONFIG_ENV_OFFSET
-#  error "Need to define CONFIG_ENV_OFFSET when using CONFIG_ENV_IS_IN_NAND"
-# endif
+# if defined(CONFIG_ENV_OFFSET_OOB)
+#  ifdef CONFIG_ENV_OFFSET_REDUND
+#   error "CONFIG_ENV_OFFSET_REDUND is not supported when CONFIG_ENV_OFFSET_OOB"
+#   error "is set"
+#  endif
+extern unsigned long nand_env_oob_offset;
+#  define CONFIG_ENV_OFFSET nand_env_oob_offset
+# else
+#  ifndef CONFIG_ENV_OFFSET
+#   error "Need to define CONFIG_ENV_OFFSET when using CONFIG_ENV_IS_IN_NAND"
+#  endif
+#  ifdef CONFIG_ENV_OFFSET_REDUND
+#   define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+#  endif
+# endif /* CONFIG_ENV_OFFSET_OOB */
 # ifndef CONFIG_ENV_SIZE
 #  error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_NAND"
 # endif
-# ifdef CONFIG_ENV_OFFSET_REDUND
-#  define CONFIG_SYS_REDUNDAND_ENVIRONMENT
-# endif
 #endif /* CONFIG_ENV_IS_IN_NAND */
 
 #if defined(CONFIG_ENV_IS_IN_MG_DISK)
diff --git a/include/nand.h b/include/nand.h
index 2a81597..8bdf419 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -130,3 +130,12 @@
 __attribute__((noreturn)) void nand_boot(void);
 
 #endif
+
+#ifdef CONFIG_ENV_OFFSET_OOB
+#define ENV_OOB_MARKER 0x30425645 /*"EVB0" in little-endian -- offset is stored
+				    as block number*/
+#define ENV_OOB_MARKER_OLD 0x30564e45 /*"ENV0" in little-endian -- offset is
+					stored as byte number */
+#define ENV_OFFSET_SIZE 8
+int get_nand_env_oob(nand_info_t *nand, unsigned long *result);
+#endif