Merge branch 'master' of git://git.denx.de/u-boot-blackfin
diff --git a/board/freescale/mpc8360erdk/nand.c b/board/freescale/mpc8360erdk/nand.c
index 8e22e13..9ffffb4 100644
--- a/board/freescale/mpc8360erdk/nand.c
+++ b/board/freescale/mpc8360erdk/nand.c
@@ -57,7 +57,7 @@
 		eieio();
 }
 
-static int dev_ready(void)
+static int dev_ready(int chip_nr)
 {
 	if (in_be32(&im->qepio.ioport[4].pdat) & 0x00002000) {
 		debug("nand ready\n");
@@ -76,7 +76,7 @@
 	.upm_cmd_offset = 8,
 	.upm_addr_offset = 16,
 	.dev_ready = dev_ready,
-	.wait_pattern = 1,
+	.wait_flags = FSL_UPM_WAIT_RUN_PATTERN,
 	.chip_delay = 50,
 };
 
diff --git a/board/tqc/tqm85xx/nand.c b/board/tqc/tqm85xx/nand.c
index 8133fdc..3da689a 100644
--- a/board/tqc/tqm85xx/nand.c
+++ b/board/tqc/tqm85xx/nand.c
@@ -385,7 +385,7 @@
 			MxMR_OP_WARR | (addr & MxMR_MAD_MSK));
 
 	/* dummy access to perform write */
-	out_8 ((void __iomem *)CONFIG_SYS_NAND0_BASE, 0);
+	out_8 ((void __iomem *)CONFIG_SYS_NAND_BASE, 0);
 
 	clrbits_be32(&lbc->mbmr, MxMR_OP_WARR);
 }
@@ -446,7 +446,10 @@
 	.width = 8,
 	.upm_cmd_offset = 0x08,
 	.upm_addr_offset = 0x10,
+	.upm_mar_chip_offset = CONFIG_SYS_NAND_CS_DIST,
+	.chip_offset = CONFIG_SYS_NAND_CS_DIST,
 	.chip_delay = NAND_BIG_DELAY_US,
+	.wait_flags = FSL_UPM_WAIT_RUN_PATTERN | FSL_UPM_WAIT_WRITE_BUFFER,
 };
 
 void board_nand_select_device (struct nand_chip *nand, int chip)
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 04b3200..e142d76 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -205,6 +205,17 @@
 }
 #endif
 
+static void nand_print_info(int idx)
+{
+	nand_info_t *nand = &nand_info[idx];
+	struct nand_chip *chip = nand->priv;
+	printf("Device %d: ", idx);
+	if (chip->numchips > 1)
+		printf("%dx ", chip->numchips);
+	printf("%s, sector size %u KiB\n",
+	       nand->name, nand->erasesize >> 10);
+}
+
 int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
 	int i, dev, ret = 0;
@@ -233,9 +244,7 @@
 		putc('\n');
 		for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) {
 			if (nand_info[i].name)
-				printf("Device %d: %s, sector size %u KiB\n",
-				       i, nand_info[i].name,
-				       nand_info[i].erasesize >> 10);
+				nand_print_info(i);
 		}
 		return 0;
 	}
@@ -243,12 +252,12 @@
 	if (strcmp(cmd, "device") == 0) {
 
 		if (argc < 3) {
+			putc('\n');
 			if ((nand_curr_device < 0) ||
 			    (nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE))
-				puts("\nno devices available\n");
+				puts("no devices available\n");
 			else
-				printf("\nDevice %d: %s\n", nand_curr_device,
-				       nand_info[nand_curr_device].name);
+				nand_print_info(nand_curr_device);
 			return 0;
 		}
 		dev = (int)simple_strtoul(argv[2], NULL, 10);
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index 1a1d8c4..7cb99cb 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -31,26 +31,59 @@
 		eieio();
 }
 
-static void fsl_upm_run_pattern(struct fsl_upm *upm, int width, u32 cmd)
+static void fsl_upm_run_pattern(struct fsl_upm *upm, int width,
+				void __iomem *io_addr, u32 mar)
 {
-	out_be32(upm->mar, cmd << (32 - width));
+	out_be32(upm->mar, mar);
 	switch (width) {
 	case 8:
-		out_8(upm->io_addr, 0x0);
+		out_8(io_addr, 0x0);
 		break;
 	case 16:
-		out_be16(upm->io_addr, 0x0);
+		out_be16(io_addr, 0x0);
 		break;
 	case 32:
-		out_be32(upm->io_addr, 0x0);
+		out_be32(io_addr, 0x0);
 		break;
 	}
 }
 
+static void fun_wait(struct fsl_upm_nand *fun)
+{
+	if (fun->dev_ready) {
+		while (!fun->dev_ready(fun->chip_nr))
+			debug("unexpected busy state\n");
+	} else {
+		/*
+		 * If the R/B pin is not connected, like on the TQM8548,
+		 * a short delay is necessary.
+		 */
+		udelay(1);
+	}
+}
+
+#if CONFIG_SYS_NAND_MAX_CHIPS > 1
+static void fun_select_chip(struct mtd_info *mtd, int chip_nr)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct fsl_upm_nand *fun = chip->priv;
+
+	if (chip_nr >= 0) {
+		fun->chip_nr = chip_nr;
+		chip->IO_ADDR_R = chip->IO_ADDR_W =
+			fun->upm.io_addr + fun->chip_offset * chip_nr;
+	} else if (chip_nr == -1) {
+		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
+	}
+}
+#endif
+
 static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
 	struct nand_chip *chip = mtd->priv;
 	struct fsl_upm_nand *fun = chip->priv;
+	void __iomem *io_addr;
+	u32 mar;
 
 	if (!(ctrl & fun->last_ctrl)) {
 		fsl_upm_end_pattern(&fun->upm);
@@ -68,18 +101,25 @@
 			fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset);
 	}
 
-	fsl_upm_run_pattern(&fun->upm, fun->width, cmd);
+	mar = cmd << (32 - fun->width);
+	io_addr = fun->upm.io_addr;
+#if CONFIG_SYS_NAND_MAX_CHIPS > 1
+	if (fun->chip_nr > 0) {
+		io_addr += fun->chip_offset * fun->chip_nr;
+		if (fun->upm_mar_chip_offset)
+			mar |= fun->upm_mar_chip_offset * fun->chip_nr;
+	}
+#endif
+	fsl_upm_run_pattern(&fun->upm, fun->width, io_addr, mar);
 
 	/*
-	 * Some boards/chips needs this. At least on MPC8360E-RDK we
-	 * need it. Probably weird chip, because I don't see any need
-	 * for this on MPC8555E + Samsung K9F1G08U0A. Usually here are
-	 * 0-2 unexpected busy states per block read.
+	 * Some boards/chips needs this. At least the MPC8360E-RDK and
+	 * TQM8548 need it. Probably weird chip, because I don't see
+	 * any need for this on MPC8555E + Samsung K9F1G08U0A. Usually
+	 * here are 0-2 unexpected busy states per block read.
 	 */
-	if (fun->wait_pattern) {
-		while (!fun->dev_ready())
-			debug("unexpected busy state\n");
-	}
+	if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN)
+		fun_wait(fun);
 }
 
 static u8 nand_read_byte(struct mtd_info *mtd)
@@ -93,9 +133,16 @@
 {
 	int i;
 	struct nand_chip *chip = mtd->priv;
+	struct fsl_upm_nand *fun = chip->priv;
 
-	for (i = 0; i < len; i++)
+	for (i = 0; i < len; i++) {
 		out_8(chip->IO_ADDR_W, buf[i]);
+		if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE)
+			fun_wait(fun);
+	}
+
+	if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER)
+		fun_wait(fun);
 }
 
 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
@@ -125,7 +172,7 @@
 	struct nand_chip *chip = mtd->priv;
 	struct fsl_upm_nand *fun = chip->priv;
 
-	return fun->dev_ready();
+	return fun->dev_ready(fun->chip_nr);
 }
 
 int fsl_upm_nand_init(struct nand_chip *chip, struct fsl_upm_nand *fun)
@@ -139,6 +186,9 @@
 	chip->chip_delay = fun->chip_delay;
 	chip->ecc.mode = NAND_ECC_SOFT;
 	chip->cmd_ctrl = fun_cmd_ctrl;
+#if CONFIG_SYS_NAND_MAX_CHIPS > 1
+	chip->select_chip = fun_select_chip;
+#endif
 	chip->read_byte = nand_read_byte;
 	chip->read_buf = nand_read_buf;
 	chip->write_buf = nand_write_buf;
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
index 70b605f..9d83794 100644
--- a/drivers/mtd/nand/nand.c
+++ b/drivers/mtd/nand/nand.c
@@ -41,11 +41,15 @@
 static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
 			   ulong base_addr)
 {
+	int maxchips = CONFIG_SYS_NAND_MAX_CHIPS;
+
+	if (maxchips < 1)
+		maxchips = 1;
 	mtd->priv = nand;
 
 	nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;
 	if (board_nand_init(nand) == 0) {
-		if (nand_scan(mtd, 1) == 0) {
+		if (nand_scan(mtd, maxchips) == 0) {
 			if (!mtd->name)
 				mtd->name = (char *)default_nand_name;
 			else
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index d33fee2..e6ac859 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2652,8 +2652,10 @@
 		    type->id != chip->read_byte(mtd))
 			break;
 	}
+#ifdef DEBUG
 	if (i > 1)
 		printk(KERN_INFO "%d NAND chips detected\n", i);
+#endif
 
 	/* Store the number of chips and calc total size for mtd */
 	chip->numchips = i;
diff --git a/include/configs/TQM85xx.h b/include/configs/TQM85xx.h
index 72db26c..2ef24cd 100644
--- a/include/configs/TQM85xx.h
+++ b/include/configs/TQM85xx.h
@@ -371,35 +371,17 @@
 #define	CONFIG_SYS_NAND_CS_DIST	0x200
 
 #define CONFIG_SYS_NAND_SIZE		0x8000
-#define CONFIG_SYS_NAND0_BASE		(CONFIG_SYS_CCSRBAR + 0x03010000)
-#define CONFIG_SYS_NAND1_BASE		(CONFIG_SYS_NAND0_BASE + CONFIG_SYS_NAND_CS_DIST)
-#define CONFIG_SYS_NAND2_BASE		(CONFIG_SYS_NAND1_BASE + CONFIG_SYS_NAND_CS_DIST)
-#define CONFIG_SYS_NAND3_BASE		(CONFIG_SYS_NAND2_BASE + CONFIG_SYS_NAND_CS_DIST)
+#define CONFIG_SYS_NAND_BASE		(CONFIG_SYS_CCSRBAR + 0x03010000)
 
-#define CONFIG_SYS_MAX_NAND_DEVICE     2	/* Max number of NAND devices	*/
-
-#if (CONFIG_SYS_MAX_NAND_DEVICE == 1)
-#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND0_BASE }
-#elif (CONFIG_SYS_MAX_NAND_DEVICE == 2)
-#define	CONFIG_SYS_NAND_QUIET_TEST	1
-#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND0_BASE, \
-			     CONFIG_SYS_NAND1_BASE, \
-}
-#elif (CONFIG_SYS_MAX_NAND_DEVICE == 4)
-#define	CONFIG_SYS_NAND_QUIET_TEST	1
-#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND0_BASE, \
-			     CONFIG_SYS_NAND1_BASE, \
-			     CONFIG_SYS_NAND2_BASE, \
-			     CONFIG_SYS_NAND3_BASE, \
-}
-#endif
+#define CONFIG_SYS_MAX_NAND_DEVICE	1	/* Max number of NAND devices	*/
+#define CONFIG_SYS_NAND_MAX_CHIPS	2	/* Number of chips per device	*/
 
 /* CS3 for NAND Flash */
-#define CONFIG_SYS_BR3_PRELIM		((CONFIG_SYS_NAND0_BASE & BR_BA) | BR_PS_8 | \
-				 BR_MS_UPMB | BR_V)
+#define CONFIG_SYS_BR3_PRELIM		((CONFIG_SYS_NAND_BASE & BR_BA) | \
+					 BR_PS_8 | BR_MS_UPMB | BR_V)
 #define CONFIG_SYS_OR3_PRELIM		(P2SZ_TO_AM(CONFIG_SYS_NAND_SIZE) | OR_UPM_BI)
 
-#define NAND_BIG_DELAY_US       25	/* max tR for Samsung devices	*/
+#define NAND_BIG_DELAY_US		25	/* max tR for Samsung devices	*/
 
 #endif /* CONFIG_NAND */
 
diff --git a/include/linux/mtd/fsl_upm.h b/include/linux/mtd/fsl_upm.h
index 638a4e4..5d7156f 100644
--- a/include/linux/mtd/fsl_upm.h
+++ b/include/linux/mtd/fsl_upm.h
@@ -15,6 +15,10 @@
 
 #include <linux/mtd/nand.h>
 
+#define FSL_UPM_WAIT_RUN_PATTERN  0x1
+#define FSL_UPM_WAIT_WRITE_BYTE   0x2
+#define FSL_UPM_WAIT_WRITE_BUFFER 0x4
+
 struct fsl_upm {
 	void __iomem *mdr;
 	void __iomem *mxmr;
@@ -28,9 +32,12 @@
 	int width;
 	int upm_cmd_offset;
 	int upm_addr_offset;
-	int wait_pattern;
-	int (*dev_ready)(void);
+	int upm_mar_chip_offset;
+	int wait_flags;
+	int (*dev_ready)(int chip_nr);
 	int chip_delay;
+	int chip_offset;
+	int chip_nr;
 
 	/* no need to fill */
 	int last_ctrl;
diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c
index aff62d2..86428cc 100644
--- a/onenand_ipl/onenand_boot.c
+++ b/onenand_ipl/onenand_boot.c
@@ -28,46 +28,16 @@
 
 #include "onenand_ipl.h"
 
-#ifdef CONFIG_SYS_PRINTF
-int print_info(void)
-{
-	printf(XLOADER_VERSION);
-
-	return 0;
-}
-#endif
-
 typedef int (init_fnc_t)(void);
 
-init_fnc_t *init_sequence[] = {
-	board_init,		/* basic board dependent setup */
-#ifdef CONFIG_SYS_PRINTF
-	serial_init,		/* serial communications setup */
-	print_info,
-#endif
-	NULL,
-};
-
 void start_oneboot(void)
 {
-	init_fnc_t **init_fnc_ptr;
 	uchar *buf;
 
-	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
-		if ((*init_fnc_ptr)() != 0)
-			hang();
-	}
-
 	buf = (uchar *) CONFIG_SYS_LOAD_ADDR;
 
-	if (!onenand_read_block0(buf))
-		buf += ONENAND_BLOCK_SIZE;
+	onenand_read_block0(buf);
 
-	if (buf == (uchar *)CONFIG_SYS_LOAD_ADDR)
-		hang();
-
-	/* go run U-Boot and never return */
-	printf("Starting OS Bootloader...\n");
 	((init_fnc_t *)CONFIG_SYS_LOAD_ADDR)();
 
 	/* should never come here */
@@ -75,7 +45,5 @@
 
 void hang(void)
 {
-	/* if board_hang() returns, hange here */
-	printf("X-Loader hangs\n");
-	for (;;);
+       for (;;);
 }
diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h
index 3387998..57e54f5 100644
--- a/onenand_ipl/onenand_ipl.h
+++ b/onenand_ipl/onenand_ipl.h
@@ -23,12 +23,6 @@
 
 #include <linux/mtd/onenand_regs.h>
 
-#define ONENAND_BLOCK_SIZE              2048
-
-#ifndef CONFIG_SYS_PRINTF
-#define printf(format, args...)
-#endif
-
 #define onenand_readw(a)        readw(a)
 #define onenand_writew(v, a)    writew(v, a)