Merge branch 'master' of git://git.denx.de/u-boot-blackfin
diff --git a/Makefile b/Makefile
index d26a004..9647bd2 100644
--- a/Makefile
+++ b/Makefile
@@ -317,7 +317,7 @@
 		$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
 
 $(obj)u-boot.ldr:	$(obj)u-boot
-		$(LDR) -T $(CONFIG_BFIN_CPU) -f -c $@ $< $(LDR_FLAGS)
+		$(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
 
 $(obj)u-boot.ldr.hex:	$(obj)u-boot.ldr
 		$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary
diff --git a/blackfin_config.mk b/blackfin_config.mk
index c8be75e..7bde449 100644
--- a/blackfin_config.mk
+++ b/blackfin_config.mk
@@ -33,7 +33,11 @@
 
 SYM_PREFIX = _
 
+LDR_FLAGS += --bmode $(subst BFIN_BOOT_,,$(CONFIG_BFIN_BOOT_MODE))
 LDR_FLAGS += --use-vmas
+ifneq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS)
+LDR_FLAGS += --initcode $(obj)cpu/$(CPU)/initcode.o
+endif
 ifneq (,$(findstring s,$(MAKEFLAGS)))
 LDR_FLAGS += --quiet
 endif
diff --git a/board/bf533-ezkit/Makefile b/board/bf533-ezkit/Makefile
index 6a45b7c..1260277 100644
--- a/board/bf533-ezkit/Makefile
+++ b/board/bf533-ezkit/Makefile
@@ -29,11 +29,11 @@
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o flash.o
+COBJS-y	:= $(BOARD).o flash.o
 
-SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(COBJS))
-SOBJS	:= $(addprefix $(obj),$(SOBJS))
+SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS-y))
+SOBJS	:= $(addprefix $(obj),$(SOBJS-y))
 
 $(LIB):	$(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds
 	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
diff --git a/board/bf533-ezkit/bf533-ezkit.c b/board/bf533-ezkit/bf533-ezkit.c
index 42c4b50..d5f0b7c 100644
--- a/board/bf533-ezkit/bf533-ezkit.c
+++ b/board/bf533-ezkit/bf533-ezkit.c
@@ -1,7 +1,7 @@
 /*
- * U-boot - ezkit533.c
+ * U-boot - main board file
  *
- * Copyright (c) 2005-2007 Analog Devices Inc.
+ * Copyright (c) 2005-2008 Analog Devices Inc.
  *
  * (C) Copyright 2000-2004
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -26,9 +26,8 @@
  */
 
 #include <common.h>
-#if defined(CONFIG_MISC_INIT_R)
 #include "psd4256.h"
-#endif
+#include "flash-defines.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -41,24 +40,11 @@
 
 phys_size_t initdram(int board_type)
 {
-#ifdef DEBUG
-	int brate;
-	char *tmp = getenv("baudrate");
-	brate = simple_strtoul(tmp, NULL, 16);
-	printf("Serial Port initialized with Baud rate = %x\n", brate);
-	printf("SDRAM attributes:\n");
-	printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles"
-	       "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n",
-	       3, 3, 6, 2, 3);
-	printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE);
-	printf("Bank size = %d MB\n", CONFIG_SYS_MAX_RAM_SIZE >> 20);
-#endif
 	gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
 	gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
-	return CONFIG_SYS_MAX_RAM_SIZE;
+	return gd->bd->bi_memsize;
 }
 
-#if defined(CONFIG_MISC_INIT_R)
 /* miscellaneous platform dependent initialisations */
 int misc_init_r(void)
 {
@@ -71,4 +57,3 @@
 
 	return 0;
 }
-#endif
diff --git a/board/bf533-ezkit/flash-defines.h b/board/bf533-ezkit/flash-defines.h
index 1a4aa5f..eb0af94 100644
--- a/board/bf533-ezkit/flash-defines.h
+++ b/board/bf533-ezkit/flash-defines.h
@@ -50,6 +50,7 @@
 #define FLASH_SIZE		0x220000
 #define FLASH_MAN_ST		2
 #define CONFIG_SYS_FLASH0_BASE		0x20000000
+#define CONFIG_SYS_FLASH1_BASE		0x20200000
 #define RESET_VAL		0xF0
 
 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
@@ -68,9 +69,6 @@
 void get_sector_number(long lOffset, int *pnSector);
 int GetSectorProtectionStatus(flash_info_t * info, int nSector);
 int GetOffset(int nBlock);
-int AFP_NumSectors = 40;
-long AFP_SectorSize1 = 0x10000;
-int AFP_SectorSize2 = 0x4000;
 
 #define WRITESEQ1		0x0AAA
 #define WRITESEQ2		0x0554
diff --git a/board/bf533-ezkit/flash.c b/board/bf533-ezkit/flash.c
index a861e16..ab808d8 100644
--- a/board/bf533-ezkit/flash.c
+++ b/board/bf533-ezkit/flash.c
@@ -29,6 +29,10 @@
 #include <asm/io.h>
 #include "flash-defines.h"
 
+int AFP_NumSectors = 40;
+long AFP_SectorSize1 = 0x10000;
+int AFP_SectorSize2 = 0x4000;
+
 void flash_reset(void)
 {
 	reset_flash();
@@ -123,7 +127,7 @@
 		printf("ST Microelectronics ");
 		break;
 	default:
-		printf("Unknown Vendor: (0x%08X) ", info->flash_id);
+		printf("Unknown Vendor: (0x%08lX) ", info->flash_id);
 		break;
 	}
 	for (i = 0; i < info->sector_count; ++i) {
@@ -211,7 +215,7 @@
 		read_flash(ulOffset, &d);
 		if (d != 0xffff) {
 			printf
-			    ("Flash not erased at offset 0x%x Please erase to reprogram \n",
+			    ("Flash not erased at offset 0x%lx Please erase to reprogram\n",
 			     ulOffset);
 			return FLASH_FAIL;
 		}
@@ -230,7 +234,7 @@
 		read_flash(ulOffset, &d);
 		if (d != 0xffff) {
 			printf
-			    ("Flash not erased at offset 0x%x Please erase to reprogram \n",
+			    ("Flash not erased at offset 0x%lx Please erase to reprogram\n",
 			     ulOffset);
 			return FLASH_FAIL;
 		}
diff --git a/board/bf533-stamp/Makefile b/board/bf533-stamp/Makefile
index 5ae0228..a03fe89 100644
--- a/board/bf533-stamp/Makefile
+++ b/board/bf533-stamp/Makefile
@@ -1,7 +1,7 @@
 #
 # U-boot - Makefile
 #
-# Copyright (c) 2005-2007 Analog Device Inc.
+# Copyright (c) 2005-2008 Analog Device Inc.
 #
 # (C) Copyright 2000-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -29,11 +29,13 @@
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o spi_flash.o
+COBJS-y	:= $(BOARD).o
+COBJS-$(CONFIG_CMD_EEPROM) += spi_flash.o
+COBJS-$(CONFIG_VIDEO) += video.o
 
-SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(COBJS))
-SOBJS	:= $(addprefix $(obj),$(SOBJS))
+SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS-y))
+SOBJS	:= $(addprefix $(obj),$(SOBJS-y))
 
 $(LIB):	$(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds
 	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
diff --git a/board/bf533-stamp/bf533-stamp.c b/board/bf533-stamp/bf533-stamp.c
index 0c6324b..44ebc93 100644
--- a/board/bf533-stamp/bf533-stamp.c
+++ b/board/bf533-stamp/bf533-stamp.c
@@ -49,43 +49,28 @@
 
 phys_size_t initdram(int board_type)
 {
-#ifdef DEBUG
-	printf("SDRAM attributes:\n");
-	printf
-	    ("  tRCD:%d Cycles; tRP:%d Cycles; tRAS:%d Cycles; tWR:%d Cycles; "
-	     "CAS Latency:%d cycles\n", (SDRAM_tRCD >> 15), (SDRAM_tRP >> 11),
-	     (SDRAM_tRAS >> 6), (SDRAM_tWR >> 19), (SDRAM_CL >> 2));
-	printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE);
-	printf("Bank size = %d MB\n", 128);
-#endif
 	gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
 	gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
-	return (gd->bd->bi_memsize);
+	return gd->bd->bi_memsize;
 }
 
+/* PF0 and PF1 are used to switch between the ethernet and flash:
+ *         PF0  PF1
+ *  flash:  0    0
+ *  ether:  1    0
+ */
 void swap_to(int device_id)
 {
-
-	if (device_id == ETHERNET) {
-		*pFIO_DIR = PF0;
-		SSYNC();
-		*pFIO_FLAG_S = PF0;
-		SSYNC();
-	} else if (device_id == FLASH) {
-		*pFIO_DIR = (PF4 | PF3 | PF2 | PF1 | PF0);
-		*pFIO_FLAG_S = (PF4 | PF3 | PF2);
-		*pFIO_MASKA_D = (PF8 | PF6 | PF5);
-		*pFIO_MASKB_D = (PF7);
-		*pFIO_POLAR = (PF8 | PF6 | PF5);
-		*pFIO_EDGE = (PF8 | PF7 | PF6 | PF5);
-		*pFIO_INEN = (PF8 | PF7 | PF6 | PF5);
-		*pFIO_FLAG_D = (PF4 | PF3 | PF2);
-		SSYNC();
-	} else {
-		printf("Unknown bank to switch\n");
-	}
-
-	return;
+	bfin_write_FIO_DIR(bfin_read_FIO_DIR() | PF1 | PF0);
+	SSYNC();
+	bfin_write_FIO_FLAG_C(PF1);
+	if (device_id == ETHERNET)
+		bfin_write_FIO_FLAG_S(PF0);
+	else if (device_id == FLASH)
+		bfin_write_FIO_FLAG_C(PF0);
+	else
+		printf("Unknown device to switch\n");
+	SSYNC();
 }
 
 #if defined(CONFIG_MISC_INIT_R)
@@ -113,9 +98,6 @@
 	if (cf_stat) {
 		printf("Booting from COMPACT flash\n");
 
-		/* Set cycle time for CF */
-		*(volatile unsigned long *)ambctl1 = CF_AMBCTL1VAL;
-
 		for (i = 0; i < 0x1000; i++)
 			asm("nop;");
 		for (i = 0; i < 0x1000; i++)
diff --git a/board/bf533-stamp/bf533-stamp.h b/board/bf533-stamp/bf533-stamp.h
index 3b0d620..ebd39c7 100644
--- a/board/bf533-stamp/bf533-stamp.h
+++ b/board/bf533-stamp/bf533-stamp.h
@@ -34,9 +34,6 @@
 extern volatile unsigned long *ambctl1;
 extern volatile unsigned long *amgctl;
 
-extern unsigned long pll_div_fact;
-extern void serial_setbrg(void);
-
 /* Definitions used in  Compact Flash Boot support */
 #define FIO_EDGE_CF_BITS	0x0000
 #define FIO_POLAR_CF_BITS	0x0000
diff --git a/board/bf533-stamp/video.c b/board/bf533-stamp/video.c
new file mode 100644
index 0000000..3c15eaa
--- /dev/null
+++ b/board/bf533-stamp/video.c
@@ -0,0 +1,167 @@
+/*
+ * BF533-STAMP splash driver
+ *
+ * Copyright (c) 2006-2008 Analog Devices Inc.
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
+ * (C) Copyright 2002
+ * Wolfgang Denk, wd@denx.de
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <stdarg.h>
+#include <common.h>
+#include <config.h>
+#include <malloc.h>
+#include <asm/blackfin.h>
+#include <asm/mach-common/bits/dma.h>
+#include <i2c.h>
+#include <linux/types.h>
+#include <devices.h>
+
+int gunzip(void *, int, unsigned char *, unsigned long *);
+
+#define DMA_SIZE16	2
+
+#include <asm/mach-common/bits/ppi.h>
+
+#define NTSC_FRAME_ADDR 0x06000000
+#include "video.h"
+
+/* NTSC OUTPUT SIZE  720 * 240 */
+#define VERTICAL	2
+#define HORIZONTAL	4
+
+int is_vblank_line(const int line)
+{
+	/*
+	 *  This array contains a single bit for each line in
+	 *  an NTSC frame.
+	 */
+	if ((line <= 18) || (line >= 264 && line <= 281) || (line == 528))
+		return true;
+
+	return false;
+}
+
+int NTSC_framebuffer_init(char *base_address)
+{
+	const int NTSC_frames = 1;
+	const int NTSC_lines = 525;
+	char *dest = base_address;
+	int frame_num, line_num;
+
+	for (frame_num = 0; frame_num < NTSC_frames; ++frame_num) {
+		for (line_num = 1; line_num <= NTSC_lines; ++line_num) {
+			unsigned int code;
+			int offset = 0;
+			int i;
+
+			if (is_vblank_line(line_num))
+				offset++;
+
+			if (line_num > 266 || line_num < 3)
+				offset += 2;
+
+			/* Output EAV code */
+			code = system_code_map[offset].eav;
+			write_dest_byte((char)(code >> 24) & 0xff);
+			write_dest_byte((char)(code >> 16) & 0xff);
+			write_dest_byte((char)(code >> 8) & 0xff);
+			write_dest_byte((char)(code) & 0xff);
+
+			/* Output horizontal blanking */
+			for (i = 0; i < 67 * 2; ++i) {
+				write_dest_byte(0x80);
+				write_dest_byte(0x10);
+			}
+
+			/* Output SAV */
+			code = system_code_map[offset].sav;
+			write_dest_byte((char)(code >> 24) & 0xff);
+			write_dest_byte((char)(code >> 16) & 0xff);
+			write_dest_byte((char)(code >> 8) & 0xff);
+			write_dest_byte((char)(code) & 0xff);
+
+			/* Output empty horizontal data */
+			for (i = 0; i < 360 * 2; ++i) {
+				write_dest_byte(0x80);
+				write_dest_byte(0x10);
+			}
+		}
+	}
+
+	return dest - base_address;
+}
+
+void fill_frame(char *Frame, int Value)
+{
+	int *OddPtr32;
+	int OddLine;
+	int *EvenPtr32;
+	int EvenLine;
+	int i;
+	int *data;
+	int m, n;
+
+	/* fill odd and even frames */
+	for (OddLine = 22, EvenLine = 285; OddLine < 263; OddLine++, EvenLine++) {
+		OddPtr32 = (int *)((Frame + (OddLine * 1716)) + 276);
+		EvenPtr32 = (int *)((Frame + (EvenLine * 1716)) + 276);
+		for (i = 0; i < 360; i++, OddPtr32++, EvenPtr32++) {
+			*OddPtr32 = Value;
+			*EvenPtr32 = Value;
+		}
+	}
+
+	for (m = 0; m < VERTICAL; m++) {
+		data = (int *)u_boot_logo.data;
+		for (OddLine = (22 + m), EvenLine = (285 + m);
+		     OddLine < (u_boot_logo.height * VERTICAL) + (22 + m);
+		     OddLine += VERTICAL, EvenLine += VERTICAL) {
+			OddPtr32 = (int *)((Frame + ((OddLine) * 1716)) + 276);
+			EvenPtr32 =
+			    (int *)((Frame + ((EvenLine) * 1716)) + 276);
+			for (i = 0; i < u_boot_logo.width / 2; i++) {
+				/* enlarge one pixel to m x n */
+				for (n = 0; n < HORIZONTAL; n++) {
+					*OddPtr32++ = *data;
+					*EvenPtr32++ = *data;
+				}
+				data++;
+			}
+		}
+	}
+}
+
+static void video_init(char *NTSCFrame)
+{
+	NTSC_framebuffer_init(NTSCFrame);
+	fill_frame(NTSCFrame, BLUE);
+
+	bfin_write_PPI_CONTROL(0x0082);
+	bfin_write_PPI_FRAME(0x020D);
+
+	bfin_write_DMA0_START_ADDR(NTSCFrame);
+	bfin_write_DMA0_X_COUNT(0x035A);
+	bfin_write_DMA0_X_MODIFY(0x0002);
+	bfin_write_DMA0_Y_COUNT(0x020D);
+	bfin_write_DMA0_Y_MODIFY(0x0002);
+	bfin_write_DMA0_CONFIG(0x1015);
+	bfin_write_PPI_CONTROL(0x0083);
+}
+
+int drv_video_init(void)
+{
+	device_t videodev;
+
+	video_init((void *)NTSC_FRAME_ADDR);
+
+	memset(&videodev, 0, sizeof(videodev));
+	strcpy(videodev.name, "video");
+	videodev.ext = DEV_EXT_VIDEO;
+	videodev.flags = DEV_FLAGS_SYSTEM;
+
+	return device_register(&videodev);
+}
diff --git a/board/bf533-stamp/video.h b/board/bf533-stamp/video.h
new file mode 100644
index 0000000..80837e2
--- /dev/null
+++ b/board/bf533-stamp/video.h
@@ -0,0 +1,25 @@
+#include <video_logo.h>
+#define write_dest_byte(val) {*dest++=val;}
+#define BLACK   (0x01800180)	/* black pixel pattern   */
+#define BLUE    (0x296E29F0)	/* blue pixel pattern    */
+#define RED     (0x51F0515A)	/* red pixel pattern     */
+#define MAGENTA (0x6ADE6ACA)	/* magenta pixel pattern */
+#define GREEN   (0x91229136)	/* green pixel pattern   */
+#define CYAN    (0xAA10AAA6)	/* cyan pixel pattern    */
+#define YELLOW  (0xD292D210)	/* yellow pixel pattern  */
+#define WHITE   (0xFE80FE80)	/* white pixel pattern   */
+
+#define true	1
+#define false	0
+
+typedef struct {
+	unsigned int sav;
+	unsigned int eav;
+} system_code_type;
+
+const system_code_type system_code_map[] = {
+	{ 0xFF000080, 0xFF00009D },
+	{ 0xFF0000AB, 0xFF0000B6 },
+	{ 0xFF0000C7, 0xFF0000DA },
+	{ 0xFF0000EC, 0xFF0000F1 },
+};
diff --git a/board/bf537-stamp/Makefile b/board/bf537-stamp/Makefile
index e5ef9af..cb38b96 100644
--- a/board/bf537-stamp/Makefile
+++ b/board/bf537-stamp/Makefile
@@ -29,11 +29,13 @@
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o post-memory.o spi_flash.o cmd_bf537led.o nand.o
+COBJS-y	:= $(BOARD).o post-memory.o cmd_bf537led.o
+COBJS-$(CONFIG_CMD_EEPROM) += spi_flash.o
+COBJS-$(CONFIG_CMD_NAND)   += nand.o
 
-SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(COBJS))
-SOBJS	:= $(addprefix $(obj),$(SOBJS))
+SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS-y))
+SOBJS	:= $(addprefix $(obj),$(SOBJS-y))
 
 $(LIB):	$(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds
 	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c
index 7303f1b..63992f6 100644
--- a/board/bf537-stamp/bf537-stamp.c
+++ b/board/bf537-stamp/bf537-stamp.c
@@ -100,21 +100,9 @@
 
 phys_size_t initdram(int board_type)
 {
-#ifdef DEBUG
-	int brate;
-	char *tmp = getenv("baudrate");
-	brate = simple_strtoul(tmp, NULL, 16);
-	printf("Serial Port initialized with Baud rate = %x\n", brate);
-	printf("SDRAM attributes:\n");
-	printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles"
-	       "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n",
-	       3, 3, 6, 2, 3);
-	printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE);
-	printf("Bank size = %d MB\n", CONFIG_SYS_MAX_RAM_SIZE >> 20);
-#endif
 	gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
 	gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
-	return CONFIG_SYS_MAX_RAM_SIZE;
+	return gd->bd->bi_memsize;
 }
 
 #if defined(CONFIG_MISC_INIT_R)
diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c
index 20a7d0e..181e83d 100644
--- a/board/bf537-stamp/nand.c
+++ b/board/bf537-stamp/nand.c
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2006 Aubrey.Li, aubrey.li@analog.com
+ * Copyright (c) 2006-2007 Analog Devices Inc.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -23,8 +23,6 @@
 #include <common.h>
 #include <asm/io.h>
 
-#if defined(CONFIG_CMD_NAND)
-
 #include <nand.h>
 
 #define CONCAT(a,b,c,d) a ## b ## c ## d
@@ -43,11 +41,11 @@
 	u32 IO_ADDR_W = (u32) this->IO_ADDR_W;
 
 	if (ctrl & NAND_CTRL_CHANGE) {
-		if( ctrl & NAND_CLE )
+		if (ctrl & NAND_CLE)
 			IO_ADDR_W = CONFIG_SYS_NAND_BASE + BFIN_NAND_CLE;
 		else
 			IO_ADDR_W = CONFIG_SYS_NAND_BASE;
-		if( ctrl & NAND_ALE )
+		if (ctrl & NAND_ALE)
 			IO_ADDR_W = CONFIG_SYS_NAND_BASE + BFIN_NAND_ALE;
 		else
 			IO_ADDR_W = CONFIG_SYS_NAND_BASE;
@@ -100,4 +98,3 @@
 
 	return 0;
 }
-#endif
diff --git a/board/bf537-stamp/post-memory.c b/board/bf537-stamp/post-memory.c
index 889aa5c..9626f4c 100644
--- a/board/bf537-stamp/post-memory.c
+++ b/board/bf537-stamp/post-memory.c
@@ -21,10 +21,10 @@
 void post_init_uart(int sclk);
 
 const int pll[CCLK_NUM][SCLK_NUM][2] = {
-	{{20, 4}, {20, 5}, {20, 10}},	/* CCLK = 500M */
-	{{16, 4}, {16, 5}, {16, 8}},	/* CCLK = 400M */
-	{{8, 2}, {8, 4}, {8, 5}},	/* CCLK = 200M */
-	{{4, 1}, {4, 2}, {4, 4}}	/* CCLK = 100M */
+	{ {20, 4}, {20, 5}, {20, 10} },	/* CCLK = 500M */
+	{ {16, 4}, {16, 5}, {16, 8} },	/* CCLK = 400M */
+	{ {8, 2}, {8, 4}, {8, 5} },	/* CCLK = 200M */
+	{ {4, 1}, {4, 2}, {4, 4} }	/* CCLK = 100M */
 };
 const char *const log[CCLK_NUM][SCLK_NUM] = {
 	{"CCLK-500MHz SCLK-125MHz:    Writing...\0",
@@ -119,7 +119,8 @@
 {
 
 	int i = 0;
-	for (i = 0; i < 0x80000; i++) ;
+	for (i = 0; i < 0x80000; i++)
+		;
 	i = 0;
 	while ((buff[i] != '\0') && (i != 100)) {
 		while (!(*pUART_LSR & 0x20)) ;
@@ -127,7 +128,8 @@
 		SSYNC();
 		i++;
 	}
-	for (i = 0; i < 0x80000; i++) ;
+	for (i = 0; i < 0x80000; i++)
+		;
 }
 
 /* Using sw10-PF5 as the hotkey */
@@ -150,9 +152,8 @@
 			value = 0;
 			goto key_pressed;
 		}
-		if (value != 0) {
+		if (value != 0)
 			goto key_pressed;
-		}
 		for (n = 0; n < KEY_DELAY; n++)
 			asm("nop");
 	}
@@ -164,9 +165,8 @@
 			value = 0;
 			goto key_pressed;
 		}
-		if (value != 0) {
+		if (value != 0)
 			goto key_pressed;
-		}
 		for (n = 0; n < KEY_DELAY; n++)
 			asm("nop");
 	}
@@ -178,9 +178,8 @@
 			value = 0;
 			goto key_pressed;
 		}
-		if (value != 0) {
+		if (value != 0)
 			goto key_pressed;
-		}
 		for (n = 0; n < KEY_DELAY; n++)
 			asm("nop");
 	}
diff --git a/board/bf537-stamp/spi_flash.c b/board/bf537-stamp/spi_flash.c
index 11a2803..99caa96 100644
--- a/board/bf537-stamp/spi_flash.c
+++ b/board/bf537-stamp/spi_flash.c
@@ -182,8 +182,8 @@
  *	BF533, BF561: SSEL2
  */
 #ifndef CONFIG_SPI_FLASH_SSEL
-# if defined(__ADSPBF531__) || defined(__ADSPBF532__) || \
-     defined(__ADSPBF533__) || defined(__ADSPBF561__)
+# if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
+     defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
 #  define CONFIG_SPI_FLASH_SSEL 2
 # else
 #  define CONFIG_SPI_FLASH_SSEL 1
@@ -797,8 +797,8 @@
 		ret = 1;
 	else
 		printf("SPI Device: %s 0x%02X (%s) 0x%02X 0x%02X\n"
-			"Parameters: num sectors = %i, sector size = %i, write size = %i\n"
-			"Flash Size: %i mbit (%i mbyte)\n"
+			"Parameters: num sectors = %lu, sector size = %lu, write size = %i\n"
+			"Flash Size: %lu mbit (%lu mbyte)\n"
 			"Status: 0x%02X\n",
 			flash.flash->name, flash.manufacturer_id, flash.manufacturer->name,
 			flash.device_id1, flash.device_id2, flash.num_sectors,
diff --git a/board/bf561-ezkit/Makefile b/board/bf561-ezkit/Makefile
index e7ee243..daebb74 100644
--- a/board/bf561-ezkit/Makefile
+++ b/board/bf561-ezkit/Makefile
@@ -29,11 +29,11 @@
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o
+COBJS-y	:= $(BOARD).o
 
-SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(COBJS))
-SOBJS	:= $(addprefix $(obj),$(SOBJS))
+SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS-y))
+SOBJS	:= $(addprefix $(obj),$(SOBJS-y))
 
 $(LIB):	$(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds
 	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
diff --git a/board/bf561-ezkit/bf561-ezkit.c b/board/bf561-ezkit/bf561-ezkit.c
index 7f8598c..5aede17 100644
--- a/board/bf561-ezkit/bf561-ezkit.c
+++ b/board/bf561-ezkit/bf561-ezkit.c
@@ -39,19 +39,7 @@
 
 phys_size_t initdram(int board_type)
 {
-#ifdef DEBUG
-	int brate;
-	char *tmp = getenv("baudrate");
-	brate = simple_strtoul(tmp, NULL, 16);
-	printf("Serial Port initialized with Baud rate = %x\n", brate);
-	printf("SDRAM attributes:\n");
-	printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles"
-	       "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n",
-	       3, 3, 6, 2, 3);
-	printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE);
-	printf("Bank size = %d MB\n", CONFIG_SYS_MAX_RAM_SIZE >> 20);
-#endif
 	gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
 	gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
-	return CONFIG_SYS_MAX_RAM_SIZE;
+	return gd->bd->bi_memsize;
 }
diff --git a/common/cmd_bootldr.c b/common/cmd_bootldr.c
index b525f0d..48d113f 100644
--- a/common/cmd_bootldr.c
+++ b/common/cmd_bootldr.c
@@ -16,6 +16,125 @@
 #include <asm/blackfin.h>
 #include <asm/mach-common/bits/bootrom.h>
 
+/* Simple sanity check on the specified address to make sure it contains
+ * an LDR image of some sort.
+ */
+static bool ldr_valid_signature(uint8_t *data)
+{
+#if defined(__ADSPBF561__)
+
+	/* BF56x has a 4 byte global header */
+	if (data[3] == 0xA0)
+		return true;
+
+#elif defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
+      defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) || \
+      defined(__ADSPBF538__) || defined(__ADSPBF539__)
+
+	/* all the BF53x should start at this address mask */
+	uint32_t addr;
+	memmove(&addr, data, sizeof(addr));
+	if ((addr & 0xFF0FFF0F) == 0xFF000000)
+		return true;
+#else
+
+	/* everything newer has a magic byte */
+	uint32_t count;
+	memmove(&count, data + 8, sizeof(count));
+	if (data[3] == 0xAD && count == 0)
+		return true;
+
+#endif
+
+	return false;
+}
+
+/* If the Blackfin is new enough, the Blackfin on-chip ROM supports loading
+ * LDRs from random memory addresses.  So whenever possible, use that.  In
+ * the older cases (BF53x/BF561), parse the LDR format ourselves.
+ */
+#define ZEROFILL  0x0001
+#define RESVECT   0x0002
+#define INIT      0x0008
+#define IGNORE    0x0010
+#define FINAL     0x8000
+static void ldr_load(uint8_t *base_addr)
+{
+#if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
+  /*defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) ||*/\
+    defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
+
+	uint32_t addr;
+	uint32_t count;
+	uint16_t flags;
+
+	/* the bf56x has a 4 byte global header ... but it is useless to
+	 * us when booting an LDR from a memory address, so skip it
+	 */
+# ifdef __ADSPBF561__
+	base_addr += 4;
+# endif
+
+	memmove(&flags, base_addr + 8, sizeof(flags));
+	bfin_write_EVT1(flags & RESVECT ? 0xFFA00000 : 0xFFA08000);
+
+	do {
+		/* block header may not be aligned */
+		memmove(&addr, base_addr, sizeof(addr));
+		memmove(&count, base_addr+4, sizeof(count));
+		memmove(&flags, base_addr+8, sizeof(flags));
+		base_addr += sizeof(addr) + sizeof(count) + sizeof(flags);
+
+		printf("loading to 0x%08x (0x%x bytes) flags: 0x%04x\n",
+			addr, count, flags);
+
+		if (!(flags & IGNORE)) {
+			if (flags & ZEROFILL)
+				memset((void *)addr, 0x00, count);
+			else
+				memcpy((void *)addr, base_addr, count);
+
+			if (flags & INIT) {
+				void (*init)(void) = (void *)addr;
+				init();
+			}
+		}
+
+		if (!(flags & ZEROFILL))
+			base_addr += count;
+	} while (!(flags & FINAL));
+
+#endif
+}
+
+/* For BF537, we use the _BOOTROM_BOOT_DXE_FLASH funky ROM function.
+ * For all other BF53x/BF56x, we just call the entry point.
+ * For everything else (newer), we use _BOOTROM_MEMBOOT ROM function.
+ */
+static void ldr_exec(void *addr)
+{
+#if defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__)
+
+	/* restore EVT1 to reset value as this is what the bootrom uses as
+	 * the default entry point when booting the final block of LDRs
+	 */
+	bfin_write_EVT1(L1_INST_SRAM);
+	__asm__("call (%0);" : : "a"(_BOOTROM_MEMBOOT), "q7"(addr) : "RETS", "memory");
+
+#elif defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
+      defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
+
+	void (*ldr_entry)(void) = (void *)bfin_read_EVT1();
+	ldr_entry();
+
+#else
+
+	int32_t (*BOOTROM_MEM)(void *, int32_t, int32_t, void *) = (void *)_BOOTROM_MEMBOOT;
+	BOOTROM_MEM(addr, 0, 0, NULL);
+
+#endif
+}
+
 /*
  * the bootldr command loads an address, checks to see if there
  *   is a Boot stream that the on-chip BOOTROM can understand,
@@ -23,11 +142,9 @@
  *   to also add booting from SPI, or TWI, but this function does
  *   not currently support that.
  */
-
 int do_bootldr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	void *addr;
-	uint32_t *data;
 
 	/* Get the address */
 	if (argc < 2)
@@ -36,22 +153,14 @@
 		addr = (void *)simple_strtoul(argv[1], NULL, 16);
 
 	/* Check if it is a LDR file */
-	data = addr;
-#if defined(__ADSPBF54x__) || defined(__ADSPBF52x__)
-	if ((*data & 0xFF000000) == 0xAD000000 && data[2] == 0x00000000) {
-#else
-	if (*data == 0xFF800060 || *data == 0xFF800040 || *data == 0xFF800020) {
-#endif
-		/* We want to boot from FLASH or SDRAM */
+	if (ldr_valid_signature(addr)) {
 		printf("## Booting ldr image at 0x%p ...\n", addr);
+		ldr_load(addr);
 
 		icache_disable();
 		dcache_disable();
 
-		__asm__(
-			"jump (%1);"
-			:
-			: "q7" (addr), "a" (_BOOTROM_MEMBOOT));
+		ldr_exec(addr);
 	} else
 		printf("## No ldr image at address 0x%p\n", addr);
 
diff --git a/common/cmd_cplbinfo.c b/common/cmd_cplbinfo.c
index 629e6a9..56e70d6 100644
--- a/common/cmd_cplbinfo.c
+++ b/common/cmd_cplbinfo.c
@@ -26,11 +26,11 @@
  */
 static void show_cplb_table(uint32_t *addr, uint32_t *data)
 {
-	size_t i;
+	int i;
 	printf("      Address     Data   Size  Valid  Locked\n");
 	for (i = 1; i <= 16; ++i) {
 		printf(" %2i 0x%p  0x%05X   %s     %c      %c\n",
-			i, *addr, *data,
+			i, (void *)*addr, *data,
 			cplb_page_size(*data),
 			(*data & CPLB_VALID ? 'Y' : 'N'),
 			(*data & CPLB_LOCK ? 'Y' : 'N'));
diff --git a/common/cmd_otp.c b/common/cmd_otp.c
index e27bb29..6523290 100644
--- a/common/cmd_otp.c
+++ b/common/cmd_otp.c
@@ -6,7 +6,7 @@
  * Licensed under the GPL-2 or later.
  */
 
-/* There are 512 128-bit "pages" (0x000 to 0x1FF).
+/* There are 512 128-bit "pages" (0x000 through 0x1FF).
  * The pages are accessable as 64-bit "halfpages" (an upper and lower half).
  * The pages are not part of the memory map.  There is an OTP controller which
  * handles scanning in/out of bits.  While access is done through OTP MMRs,
@@ -17,8 +17,6 @@
 #include <common.h>
 #include <command.h>
 
-#ifdef CONFIG_CMD_OTP
-
 #include <asm/blackfin.h>
 #include <asm/mach-common/bits/otp.h>
 
@@ -40,30 +38,87 @@
 
 #define lowup(x) ((x) % 2 ? "upper" : "lower")
 
-int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+static int check_voltage(void)
 {
-	bool force = false;
-	if (!strcmp(argv[1], "--force")) {
-		force = true;
-		argv[1] = argv[0];
-		argv++;
-		--argc;
+	/* Make sure voltage limits are within datasheet spec */
+	uint16_t vr_ctl = bfin_read_VR_CTL();
+
+#ifdef __ADSPBF54x__
+	/* 0.9V <= VDDINT <= 1.1V */
+	if ((vr_ctl & 0xc) && (vr_ctl & 0xc0) == 0xc0)
+		return 1;
+#else
+	/* for the parts w/out qualification yet */
+	(void)vr_ctl;
+#endif
+
+	return 0;
+}
+
+static void set_otp_timing(bool write)
+{
+	static uint32_t timing;
+	if (!timing) {
+		uint32_t tp1, tp2, tp3;
+		/* OTP_TP1 = 1000 / sclk_period (in nanoseconds)
+		 * OTP_TP1 = 1000 / (1 / get_sclk() * 10^9)
+		 * OTP_TP1 = (1000 * get_sclk()) / 10^9
+		 * OTP_TP1 = get_sclk() / 10^6
+		 */
+		tp1 = get_sclk() / 1000000;
+		/* OTP_TP2 = 400 / (2 * sclk_period)
+		 * OTP_TP2 = 400 / (2 * 1 / get_sclk() * 10^9)
+		 * OTP_TP2 = (400 * get_sclk()) / (2 * 10^9)
+		 * OTP_TP2 = (2 * get_sclk()) / 10^7
+		 */
+		tp2 = (2 * get_sclk() / 10000000) << 8;
+		/* OTP_TP3 = magic constant */
+		tp3 = (0x1401) << 15;
+		timing = tp1 | tp2 | tp3;
 	}
 
+	bfrom_OtpCommand(OTP_INIT, write ? timing : timing & ~(-1 << 15));
+}
+
+int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	uint32_t ret, base_flags;
+	bool prompt_user, force_read;
 	uint32_t (*otp_func)(uint32_t page, uint32_t flags, uint64_t *page_content);
-	if (!strcmp(argv[1], "read"))
-		otp_func = otp_read;
-	else if (!strcmp(argv[1], "write"))
-		otp_func = otp_write;
-	else {
+
+	if (argc < 4) {
  usage:
 		cmd_usage(cmdtp);
 		return 1;
 	}
 
+	prompt_user = false;
+	base_flags = 0;
+	if (!strcmp(argv[1], "read"))
+		otp_func = bfrom_OtpRead;
+	else if (!strcmp(argv[1], "dump")) {
+		otp_func = bfrom_OtpRead;
+		force_read = true;
+	} else if (!strcmp(argv[1], "write")) {
+		otp_func = bfrom_OtpWrite;
+		base_flags = OTP_CHECK_FOR_PREV_WRITE;
+		if (!strcmp(argv[2], "--force")) {
+			argv[2] = argv[1];
+			argv++;
+			--argc;
+		} else
+			prompt_user = false;
+	} else if (!strcmp(argv[1], "lock")) {
+		if (argc != 4)
+			goto usage;
+		otp_func = bfrom_OtpWrite;
+		base_flags = OTP_LOCK;
+	} else
+		goto usage;
+
 	uint64_t *addr = (uint64_t *)simple_strtoul(argv[2], NULL, 16);
 	uint32_t page = simple_strtoul(argv[3], NULL, 16);
-	uint32_t flags, ret;
+	uint32_t flags;
 	size_t i, count;
 	ulong half;
 
@@ -81,14 +136,21 @@
 	} else
 		half = 0;
 
+	/* "otp lock" has slightly different semantics */
+	if (base_flags & OTP_LOCK) {
+		count = page;
+		page = (uint32_t)addr;
+		addr = NULL;
+	}
+
 	/* do to the nature of OTP, make sure users are sure */
-	if (!force && otp_func == otp_write) {
+	if (prompt_user) {
 		printf(
 			"Writing one time programmable memory\n"
 			"Make sure your operating voltages and temperature are within spec\n"
 			"   source address:  0x%p\n"
-			"   OTP destination: %s page 0x%03X - %s page 0x%03X\n"
-			"   number to write: %ld halfpages\n"
+			"   OTP destination: %s page 0x%03X - %s page 0x%03lX\n"
+			"   number to write: %lu halfpages\n"
 			" type \"YES\" (no quotes) to confirm: ",
 			addr,
 			lowup(half), page,
@@ -111,30 +173,42 @@
 				}
 			}
 		}
-
-		/* Only supported in newer silicon ... enable writing */
-#if (0)
-		otp_command(OTP_INIT, ...);
-#else
-		*pOTP_TIMING = 0x32149485;
-#endif
 	}
 
-	printf("OTP memory %s: addr 0x%08lx  page 0x%03X  count %ld ... ",
+	printf("OTP memory %s: addr 0x%p  page 0x%03X  count %zu ... ",
 		argv[1], addr, page, count);
 
+	set_otp_timing(otp_func == bfrom_OtpWrite);
+	if (otp_func == bfrom_OtpWrite && check_voltage()) {
+		puts("ERROR: VDDINT voltage is out of spec for writing\n");
+		return -1;
+	}
+
+	/* Do the actual reading/writing stuff */
 	ret = 0;
 	for (i = half; i < count + half; ++i) {
-		flags = (i % 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF;
+		flags = base_flags | (i % 2 ? OTP_UPPER_HALF : OTP_LOWER_HALF);
+ try_again:
 		ret = otp_func(page, flags, addr);
-		if (ret & 0x1)
-			break;
-		else if (ret)
+		if (ret & OTP_MASTER_ERROR) {
+			if (force_read) {
+				if (flags & OTP_NO_ECC)
+					break;
+				else
+					flags |= OTP_NO_ECC;
+				puts("E");
+				goto try_again;
+			} else
+				break;
+		} else if (ret)
 			puts("W");
 		else
 			puts(".");
-		++addr;
-		if (i % 2)
+		if (!(base_flags & OTP_LOCK)) {
+			++addr;
+			if (i % 2)
+				++page;
+		} else
 			++page;
 	}
 	if (ret & 0x1)
@@ -143,21 +217,20 @@
 	else
 		puts(" done\n");
 
-	if (otp_func == otp_write)
-		/* Only supported in newer silicon ... disable writing */
-#if (0)
-		otp_command(OTP_INIT, ...);
-#else
-		*pOTP_TIMING = 0x1485;
-#endif
+	/* Make sure we disable writing */
+	set_otp_timing(false);
+	bfrom_OtpCommand(OTP_CLOSE, 0);
 
 	return ret;
 }
 
-U_BOOT_CMD(otp, 6, 0, do_otp,
-	"One-Time-Programmable sub-system",
+U_BOOT_CMD(otp, 7, 0, do_otp,
+	"One-Time-Programmable sub-system\n",
 	"read <addr> <page> [count] [half]\n"
+	" - read 'count' half-pages starting at 'page' (offset 'half') to 'addr'\n"
+	"otp dump <addr> <page> [count] [half]\n"
+	" - like 'otp read', but skip read errors\n"
 	"otp write [--force] <addr> <page> [count] [half]\n"
-	"    - read/write 'count' half-pages starting at page 'page' (offset 'half')\n");
-
-#endif
+	" - write 'count' half-pages starting at 'page' (offset 'half') from 'addr'\n"
+	"otp lock <page> <count>\n"
+	" - lock 'count' pages starting at 'page'\n");
diff --git a/common/devices.c b/common/devices.c
index ce3b7a0..38f1bbc 100644
--- a/common/devices.c
+++ b/common/devices.c
@@ -240,6 +240,9 @@
 #ifdef CONFIG_NETCONSOLE
 	drv_nc_init ();
 #endif
+#ifdef CONFIG_JTAG_CONSOLE
+	drv_jtag_console_init ();
+#endif
 
 	return (0);
 }
diff --git a/cpu/blackfin/Makefile b/cpu/blackfin/Makefile
index 8fed4b4..b4049ff 100644
--- a/cpu/blackfin/Makefile
+++ b/cpu/blackfin/Makefile
@@ -17,14 +17,15 @@
 CEXTRA   := initcode.o
 SEXTRA   := start.o
 SOBJS    := interrupt.o cache.o
-COBJS    := cpu.o traps.o interrupts.o reset.o serial.o i2c.o watchdog.o
+COBJS-y  := cpu.o traps.o interrupts.o reset.o serial.o watchdog.o
+COBJS-$(CONFIG_JTAG_CONSOLE) += jtag-console.o
 
 ifeq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS)
-COBJS    += initcode.o
+COBJS-y  += initcode.o
 endif
 
-SRCS     := $(SEXTRA:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS     := $(addprefix $(obj),$(COBJS) $(SOBJS))
+SRCS     := $(SEXTRA:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS     := $(addprefix $(obj),$(COBJS-y) $(SOBJS))
 EXTRA    := $(addprefix $(obj),$(EXTRA))
 CEXTRA   := $(addprefix $(obj),$(CEXTRA))
 SEXTRA   := $(addprefix $(obj),$(SEXTRA))
diff --git a/cpu/blackfin/cache.S b/cpu/blackfin/cache.S
index 51bdb30..9facadf 100644
--- a/cpu/blackfin/cache.S
+++ b/cpu/blackfin/cache.S
@@ -39,7 +39,7 @@
 	RTS;
 ENDPROC(_blackfin_dcache_flush_range)
 
-ENTRY(_blackfin_dcache_invalidate_range)
+ENTRY(_blackfin_dcache_flush_invalidate_range)
 	R2 = -32;
 	R2 = R0 & R2;
 	P0 = R2;
@@ -58,4 +58,4 @@
 	FLUSHINV[P0];
 	SSYNC;
 	RTS;
-ENDPROC(_blackfin_dcache_invalidate_range)
+ENDPROC(_blackfin_dcache_flush_invalidate_range)
diff --git a/cpu/blackfin/cpu.c b/cpu/blackfin/cpu.c
index 9efd88e..30c214b 100644
--- a/cpu/blackfin/cpu.c
+++ b/cpu/blackfin/cpu.c
@@ -14,11 +14,14 @@
 #include <asm/blackfin.h>
 #include <asm/cplb.h>
 #include <asm/mach-common/bits/core.h>
+#include <asm/mach-common/bits/ebiu.h>
 #include <asm/mach-common/bits/trace.h>
 
 #include "cpu.h"
 #include "serial.h"
 
+ulong bfin_poweron_retx;
+
 __attribute__ ((__noreturn__))
 void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
 {
@@ -48,6 +51,9 @@
 		bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
 #endif
 
+	/* Save RETX so we can pass it while booting Linux */
+	bfin_poweron_retx = bootflag;
+
 #ifdef CONFIG_DEBUG_DUMP
 	/* Turn on hardware trace buffer */
 	bfin_write_TBUFCTL(TBUFPWR | TBUFEN);
diff --git a/cpu/blackfin/i2c.c b/cpu/blackfin/i2c.c
deleted file mode 100644
index 2a3e223..0000000
--- a/cpu/blackfin/i2c.c
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * i2c.c - driver for Blackfin on-chip TWI/I2C
- *
- * Copyright (c) 2006-2008 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-
-#ifdef CONFIG_HARD_I2C
-
-#include <asm/blackfin.h>
-#include <i2c.h>
-#include <asm/io.h>
-#include <asm/mach-common/bits/twi.h>
-
-/* Two-Wire Interface		(0xFFC01400 - 0xFFC014FF) */
-#ifdef TWI0_CLKDIV
-#define bfin_read_TWI_CLKDIV()               bfin_read_TWI0_CLKDIV()
-#define bfin_write_TWI_CLKDIV(val)           bfin_write_TWI0_CLKDIV(val)
-#define bfin_read_TWI_CONTROL()              bfin_read_TWI0_CONTROL()
-#define bfin_write_TWI_CONTROL(val)          bfin_write_TWI0_CONTROL(val)
-#define bfin_read_TWI_SLAVE_CTL()            bfin_read_TWI0_SLAVE_CTL()
-#define bfin_write_TWI_SLAVE_CTL(val)        bfin_write_TWI0_SLAVE_CTL(val)
-#define bfin_read_TWI_SLAVE_STAT()           bfin_read_TWI0_SLAVE_STAT()
-#define bfin_write_TWI_SLAVE_STAT(val)       bfin_write_TWI0_SLAVE_STAT(val)
-#define bfin_read_TWI_SLAVE_ADDR()           bfin_read_TWI0_SLAVE_ADDR()
-#define bfin_write_TWI_SLAVE_ADDR(val)       bfin_write_TWI0_SLAVE_ADDR(val)
-#define bfin_read_TWI_MASTER_CTL()           bfin_read_TWI0_MASTER_CTL()
-#define bfin_write_TWI_MASTER_CTL(val)       bfin_write_TWI0_MASTER_CTL(val)
-#define bfin_read_TWI_MASTER_STAT()          bfin_read_TWI0_MASTER_STAT()
-#define bfin_write_TWI_MASTER_STAT(val)      bfin_write_TWI0_MASTER_STAT(val)
-#define bfin_read_TWI_MASTER_ADDR()          bfin_read_TWI0_MASTER_ADDR()
-#define bfin_write_TWI_MASTER_ADDR(val)      bfin_write_TWI0_MASTER_ADDR(val)
-#define bfin_read_TWI_INT_STAT()             bfin_read_TWI0_INT_STAT()
-#define bfin_write_TWI_INT_STAT(val)         bfin_write_TWI0_INT_STAT(val)
-#define bfin_read_TWI_INT_MASK()             bfin_read_TWI0_INT_MASK()
-#define bfin_write_TWI_INT_MASK(val)         bfin_write_TWI0_INT_MASK(val)
-#define bfin_read_TWI_FIFO_CTL()             bfin_read_TWI0_FIFO_CTL()
-#define bfin_write_TWI_FIFO_CTL(val)         bfin_write_TWI0_FIFO_CTL(val)
-#define bfin_read_TWI_FIFO_STAT()            bfin_read_TWI0_FIFO_STAT()
-#define bfin_write_TWI_FIFO_STAT(val)        bfin_write_TWI0_FIFO_STAT(val)
-#define bfin_read_TWI_XMT_DATA8()            bfin_read_TWI0_XMT_DATA8()
-#define bfin_write_TWI_XMT_DATA8(val)        bfin_write_TWI0_XMT_DATA8(val)
-#define bfin_read_TWI_XMT_DATA_16()          bfin_read_TWI0_XMT_DATA16()
-#define bfin_write_TWI_XMT_DATA16(val)       bfin_write_TWI0_XMT_DATA16(val)
-#define bfin_read_TWI_RCV_DATA8()            bfin_read_TWI0_RCV_DATA8()
-#define bfin_write_TWI_RCV_DATA8(val)        bfin_write_TWI0_RCV_DATA8(val)
-#define bfin_read_TWI_RCV_DATA16()           bfin_read_TWI0_RCV_DATA16()
-#define bfin_write_TWI_RCV_DATA16(val)       bfin_write_TWI0_RCV_DATA16(val)
-#endif
-
-#ifdef DEBUG_I2C
-#define PRINTD(fmt,args...)	do {	\
-	DECLARE_GLOBAL_DATA_PTR;	\
-	if (gd->have_console)		\
-		printf(fmt ,##args);	\
-	} while (0)
-#else
-#define PRINTD(fmt,args...)
-#endif
-
-#ifndef CONFIG_TWICLK_KHZ
-#define CONFIG_TWICLK_KHZ	50
-#endif
-
-/* All transfers are described by this data structure */
-struct i2c_msg {
-	u16 addr;		/* slave address */
-	u16 flags;
-#define I2C_M_STOP		0x2
-#define I2C_M_RD		0x1
-	u16 len;		/* msg length */
-	u8 *buf;		/* pointer to msg data */
-};
-
-/**
- * i2c_reset: - reset the host controller
- */
-static void i2c_reset(void)
-{
-	/* Disable TWI */
-	bfin_write_TWI_CONTROL(0);
-	SSYNC();
-
-	/* Set TWI internal clock as 10MHz */
-	bfin_write_TWI_CONTROL(((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
-
-	/* Set Twi interface clock as specified */
-	if (CONFIG_TWICLK_KHZ > 400)
-		bfin_write_TWI_CLKDIV(((5 * 1024 / 400) << 8) | ((5 * 1024 /
-						400) & 0xFF));
-	else
-		bfin_write_TWI_CLKDIV(((5 * 1024 /
-					CONFIG_TWICLK_KHZ) << 8) | ((5 * 1024 /
-						CONFIG_TWICLK_KHZ)
-						& 0xFF));
-
-	/* Enable TWI */
-	bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
-	SSYNC();
-}
-
-int wait_for_completion(struct i2c_msg *msg, int timeout_count)
-{
-	unsigned short twi_int_stat;
-	unsigned short mast_stat;
-	int i;
-
-	for (i = 0; i < timeout_count; i++) {
-		twi_int_stat = bfin_read_TWI_INT_STAT();
-		mast_stat = bfin_read_TWI_MASTER_STAT();
-
-		if (XMTSERV & twi_int_stat) {
-			/* Transmit next data */
-			if (msg->len > 0) {
-				bfin_write_TWI_XMT_DATA8(*(msg->buf++));
-				msg->len--;
-			} else if (msg->flags & I2C_M_STOP)
-				bfin_write_TWI_MASTER_CTL
-				    (bfin_read_TWI_MASTER_CTL() | STOP);
-			SSYNC();
-			/* Clear status */
-			bfin_write_TWI_INT_STAT(XMTSERV);
-			SSYNC();
-			i = 0;
-		}
-		if (RCVSERV & twi_int_stat) {
-			if (msg->len > 0) {
-				/* Receive next data */
-				*(msg->buf++) = bfin_read_TWI_RCV_DATA8();
-				msg->len--;
-			} else if (msg->flags & I2C_M_STOP) {
-				bfin_write_TWI_MASTER_CTL
-				    (bfin_read_TWI_MASTER_CTL() | STOP);
-				SSYNC();
-			}
-			/* Clear interrupt source */
-			bfin_write_TWI_INT_STAT(RCVSERV);
-			SSYNC();
-			i = 0;
-		}
-		if (MERR & twi_int_stat) {
-			bfin_write_TWI_INT_STAT(MERR);
-			bfin_write_TWI_INT_MASK(0);
-			bfin_write_TWI_MASTER_STAT(0x3e);
-			bfin_write_TWI_MASTER_CTL(0);
-			SSYNC();
-			/*
-			 * if both err and complete int stats are set,
-			 * return proper results.
-			 */
-			if (MCOMP & twi_int_stat) {
-				bfin_write_TWI_INT_STAT(MCOMP);
-				bfin_write_TWI_INT_MASK(0);
-				bfin_write_TWI_MASTER_CTL(0);
-				SSYNC();
-				/*
-				 * If it is a quick transfer,
-				 * only address bug no data, not an err.
-				 */
-				if (msg->len == 0 && mast_stat & BUFRDERR)
-					return 0;
-				/*
-				 * If address not acknowledged return -3,
-				 * else return 0.
-				 */
-				else if (!(mast_stat & ANAK))
-					return 0;
-				else
-					return -3;
-			}
-			return -1;
-		}
-		if (MCOMP & twi_int_stat) {
-			bfin_write_TWI_INT_STAT(MCOMP);
-			SSYNC();
-			bfin_write_TWI_INT_MASK(0);
-			bfin_write_TWI_MASTER_CTL(0);
-			SSYNC();
-			return 0;
-		}
-	}
-	if (msg->flags & I2C_M_RD)
-		return -4;
-	else
-		return -2;
-}
-
-/**
- * i2c_transfer: - Transfer one byte over the i2c bus
- *
- * This function can tranfer a byte over the i2c bus in both directions.
- * It is used by the public API functions.
- *
- * @return:	 0: transfer successful
- *		-1: transfer fail
- *		-2: transmit timeout
- *		-3: ACK missing
- *		-4: receive timeout
- *		-5: controller not ready
- */
-int i2c_transfer(struct i2c_msg *msg)
-{
-	int ret = 0;
-	int timeout_count = 10000;
-	int len = msg->len;
-
-	if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) {
-		ret = -5;
-		goto transfer_error;
-	}
-
-	while (bfin_read_TWI_MASTER_STAT() & BUSBUSY)
-		continue;
-
-	/* Set Transmit device address */
-	bfin_write_TWI_MASTER_ADDR(msg->addr);
-
-	/*
-	 * FIFO Initiation.
-	 * Data in FIFO should be discarded before start a new operation.
-	 */
-	bfin_write_TWI_FIFO_CTL(0x3);
-	SSYNC();
-	bfin_write_TWI_FIFO_CTL(0);
-	SSYNC();
-
-	if (!(msg->flags & I2C_M_RD)) {
-		/* Transmit first data */
-		if (msg->len > 0) {
-			PRINTD("1 in i2c_transfer: buf=%d, len=%d\n", *msg->buf,
-			       len);
-			bfin_write_TWI_XMT_DATA8(*(msg->buf++));
-			msg->len--;
-			SSYNC();
-		}
-	}
-
-	/* clear int stat */
-	bfin_write_TWI_INT_STAT(MERR | MCOMP | XMTSERV | RCVSERV);
-
-	/* Interrupt mask . Enable XMT, RCV interrupt */
-	bfin_write_TWI_INT_MASK(MCOMP | MERR |
-			((msg->flags & I2C_M_RD) ? RCVSERV : XMTSERV));
-	SSYNC();
-
-	if (len > 0 && len <= 255)
-		bfin_write_TWI_MASTER_CTL((len << 6));
-	else if (msg->len > 255) {
-		bfin_write_TWI_MASTER_CTL((0xff << 6));
-		msg->flags &= I2C_M_STOP;
-	} else
-		bfin_write_TWI_MASTER_CTL(0);
-
-	/* Master enable */
-	bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
-			((msg->flags & I2C_M_RD)
-			 ? MDIR : 0) | ((CONFIG_TWICLK_KHZ >
-					 100) ? FAST : 0));
-	SSYNC();
-
-	ret = wait_for_completion(msg, timeout_count);
-	PRINTD("3 in i2c_transfer: ret=%d\n", ret);
-
- transfer_error:
-	switch (ret) {
-	case 1:
-		PRINTD(("i2c_transfer: error: transfer fail\n"));
-		break;
-	case 2:
-		PRINTD(("i2c_transfer: error: transmit timeout\n"));
-		break;
-	case 3:
-		PRINTD(("i2c_transfer: error: ACK missing\n"));
-		break;
-	case 4:
-		PRINTD(("i2c_transfer: error: receive timeout\n"));
-		break;
-	case 5:
-		PRINTD(("i2c_transfer: error: controller not ready\n"));
-		i2c_reset();
-		break;
-	default:
-		break;
-	}
-	return ret;
-
-}
-
-/* ---------------------------------------------------------------------*/
-/* API Functions							*/
-/* ---------------------------------------------------------------------*/
-
-void i2c_init(int speed, int slaveaddr)
-{
-	i2c_reset();
-}
-
-/**
- * i2c_probe: - Test if a chip answers for a given i2c address
- *
- * @chip:	address of the chip which is searched for
- * @return:	0 if a chip was found, -1 otherwhise
- */
-
-int i2c_probe(uchar chip)
-{
-	struct i2c_msg msg;
-	u8 probebuf;
-
-	i2c_reset();
-
-	probebuf = 0;
-	msg.addr = chip;
-	msg.flags = 0;
-	msg.len = 1;
-	msg.buf = &probebuf;
-	if (i2c_transfer(&msg))
-		return -1;
-
-	msg.addr = chip;
-	msg.flags = I2C_M_RD;
-	msg.len = 1;
-	msg.buf = &probebuf;
-	if (i2c_transfer(&msg))
-		return -1;
-
-	return 0;
-}
-
-/**
- *   i2c_read: - Read multiple bytes from an i2c device
- *
- *   chip:    I2C chip address, range 0..127
- *   addr:    Memory (register) address within the chip
- *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
- *		memories, 0 for register type devices with only one
- *		register)
- *   buffer:  Where to read/write the data
- *   len:     How many bytes to read/write
- *
- *   Returns: 0 on success, not 0 on failure
- */
-
-int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3];	/* lowest...highest byte of data address */
-
-	PRINTD("i2c_read: chip=0x%x, addr=0x%x, alen=0x%x, len=0x%x\n", chip,
-			addr, alen, len);
-
-	if (alen > 0) {
-		addr_bytes[0] = (u8) ((addr >> 0) & 0x000000FF);
-		addr_bytes[1] = (u8) ((addr >> 8) & 0x000000FF);
-		addr_bytes[2] = (u8) ((addr >> 16) & 0x000000FF);
-		msg.addr = chip;
-		msg.flags = 0;
-		msg.len = alen;
-		msg.buf = addr_bytes;
-		if (i2c_transfer(&msg))
-			return -1;
-	}
-
-	/* start read sequence */
-	PRINTD(("i2c_read: start read sequence\n"));
-	msg.addr = chip;
-	msg.flags = I2C_M_RD;
-	msg.len = len;
-	msg.buf = buffer;
-	if (i2c_transfer(&msg))
-		return -1;
-
-	return 0;
-}
-
-/**
- *   i2c_write: -  Write multiple bytes to an i2c device
- *
- *   chip:    I2C chip address, range 0..127
- *   addr:    Memory (register) address within the chip
- *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
- *		memories, 0 for register type devices with only one
- *		register)
- *   buffer:  Where to read/write the data
- *   len:     How many bytes to read/write
- *
- *   Returns: 0 on success, not 0 on failure
- */
-
-int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3];	/* lowest...highest byte of data address */
-
-	PRINTD
-		("i2c_write: chip=0x%x, addr=0x%x, alen=0x%x, len=0x%x, buf0=0x%x\n",
-		 chip, addr, alen, len, buffer[0]);
-
-	/* chip address write */
-	if (alen > 0) {
-		addr_bytes[0] = (u8) ((addr >> 0) & 0x000000FF);
-		addr_bytes[1] = (u8) ((addr >> 8) & 0x000000FF);
-		addr_bytes[2] = (u8) ((addr >> 16) & 0x000000FF);
-		msg.addr = chip;
-		msg.flags = 0;
-		msg.len = alen;
-		msg.buf = addr_bytes;
-		if (i2c_transfer(&msg))
-			return -1;
-	}
-
-	/* start read sequence */
-	PRINTD(("i2c_write: start write sequence\n"));
-	msg.addr = chip;
-	msg.flags = 0;
-	msg.len = len;
-	msg.buf = buffer;
-	if (i2c_transfer(&msg))
-		return -1;
-
-	return 0;
-
-}
-
-#endif /* CONFIG_HARD_I2C */
diff --git a/cpu/blackfin/initcode.c b/cpu/blackfin/initcode.c
index ffc8420..e733dd2 100644
--- a/cpu/blackfin/initcode.c
+++ b/cpu/blackfin/initcode.c
@@ -158,7 +158,7 @@
 #endif
 
 #ifndef CONFIG_PLL_CTL_VAL
-# define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9))
+# define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9) | CONFIG_CLKIN_HALF)
 #endif
 
 #ifndef CONFIG_EBIU_RSTCTL_VAL
diff --git a/cpu/blackfin/jtag-console.c b/cpu/blackfin/jtag-console.c
new file mode 100644
index 0000000..44c0a83
--- /dev/null
+++ b/cpu/blackfin/jtag-console.c
@@ -0,0 +1,125 @@
+/*
+ * jtag-console.c - console driver over Blackfin JTAG
+ *
+ * Copyright (c) 2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <devices.h>
+#include <asm/blackfin.h>
+
+#ifndef CONFIG_JTAG_CONSOLE_TIMEOUT
+# define CONFIG_JTAG_CONSOLE_TIMEOUT 100
+#endif
+
+/* The Blackfin tends to be much much faster than the JTAG hardware. */
+static void jtag_write_emudat(uint32_t emudat)
+{
+	static bool overflowed = false;
+	ulong timeout = get_timer(0) + CONFIG_JTAG_CONSOLE_TIMEOUT;
+	while (bfin_read_DBGSTAT() & 0x1) {
+		if (overflowed)
+			return;
+		if (timeout < get_timer(0))
+			overflowed = true;
+	}
+	overflowed = false;
+	__asm__ __volatile__("emudat = %0;" : : "d"(emudat));
+}
+/* Transmit a buffer.  The format is:
+ * [32bit length][actual data]
+ */
+static void jtag_send(const char *c, uint32_t len)
+{
+	uint32_t i;
+
+	if (len == 0)
+		return;
+
+	/* First send the length */
+	jtag_write_emudat(len);
+
+	/* Then send the data */
+	for (i = 0; i < len; i += 4)
+		jtag_write_emudat((c[i] << 0) | (c[i+1] << 8) | (c[i+2] << 16) | (c[i+3] << 24));
+}
+static void jtag_putc(const char c)
+{
+	jtag_send(&c, 1);
+}
+static void jtag_puts(const char *s)
+{
+	jtag_send(s, strlen(s));
+}
+
+static int jtag_tstc(void)
+{
+	return (bfin_read_DBGSTAT() & 0x2);
+}
+
+/* Receive a buffer.  The format is:
+ * [32bit length][actual data]
+ */
+static size_t inbound_len;
+static int leftovers_len;
+static uint32_t leftovers;
+static int jtag_getc(void)
+{
+	int ret;
+	uint32_t emudat;
+
+	/* see if any data is left over */
+	if (leftovers_len) {
+		--leftovers_len;
+		ret = leftovers & 0xff;
+		leftovers >>= 8;
+		return ret;
+	}
+
+	/* wait for new data ! */
+	while (!jtag_tstc())
+		continue;
+	__asm__("%0 = emudat;" : "=d"(emudat));
+
+	if (inbound_len == 0) {
+		/* grab the length */
+		inbound_len = emudat;
+	} else {
+		/* store the bytes */
+		leftovers_len = min(4, inbound_len);
+		inbound_len -= leftovers_len;
+		leftovers = emudat;
+	}
+
+	return jtag_getc();
+}
+
+int drv_jtag_console_init(void)
+{
+	device_t dev;
+	int ret;
+
+	memset(&dev, 0x00, sizeof(dev));
+	strcpy(dev.name, "jtag");
+	dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+	dev.putc = jtag_putc;
+	dev.puts = jtag_puts;
+	dev.tstc = jtag_tstc;
+	dev.getc = jtag_getc;
+
+	ret = device_register(&dev);
+	return (ret == 0 ? 1 : ret);
+}
+
+#ifdef CONFIG_UART_CONSOLE_IS_JTAG
+/* Since the JTAG is always available (at power on), allow it to fake a UART */
+void serial_set_baud(uint32_t baud) {}
+void serial_setbrg(void)            {}
+int serial_init(void)               { return 0; }
+void serial_putc(const char c)      __attribute__((alias("jtag_putc")));
+void serial_puts(const char *s)     __attribute__((alias("jtag_puts")));
+int serial_tstc(void)               __attribute__((alias("jtag_tstc")));
+int serial_getc(void)               __attribute__((alias("jtag_getc")));
+#endif
diff --git a/cpu/blackfin/reset.c b/cpu/blackfin/reset.c
index d1e34b3..284cea5 100644
--- a/cpu/blackfin/reset.c
+++ b/cpu/blackfin/reset.c
@@ -29,26 +29,35 @@
 	 */
 	__builtin_bfin_ssync();
 
-	while (1) {
+	/* The bootrom checks to see how it was reset and will
+	 * automatically perform a software reset for us when
+	 * it starts executing after the core reset.
+	 */
+	if (ANOMALY_05000353 || ANOMALY_05000386) {
 		/* Initiate System software reset. */
 		bfin_write_SWRST(0x7);
 
 		/* Due to the way reset is handled in the hardware, we need
-		 * to delay for 7 SCLKS.  The only reliable way to do this is
-		 * to calculate the CCLK/SCLK ratio and multiply 7.  For now,
+		 * to delay for 10 SCLKS.  The only reliable way to do this is
+		 * to calculate the CCLK/SCLK ratio and multiply 10.  For now,
 		 * we'll assume worse case which is a 1:15 ratio.
 		 */
 		asm(
 			"LSETUP (1f, 1f) LC0 = %0\n"
 			"1: nop;"
 			:
-			: "a" (15 * 7)
+			: "a" (15 * 10)
 			: "LC0", "LB0", "LT0"
 		);
 
 		/* Clear System software reset */
 		bfin_write_SWRST(0);
 
+		/* The BF526 ROM will crash during reset */
+#if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__)
+		bfin_read_SWRST();
+#endif
+
 		/* Wait for the SWRST write to complete.  Cannot rely on SSYNC
 		 * though as the System state is all reset now.
 		 */
@@ -59,10 +68,11 @@
 			: "a" (15 * 1)
 			: "LC1", "LB1", "LT1"
 		);
+	}
 
+	while (1)
 		/* Issue core reset */
 		asm("raise 1");
-	}
 }
 
 /* We need to trampoline ourselves up into L1 since our linker
diff --git a/cpu/blackfin/serial.c b/cpu/blackfin/serial.c
index 0d6f377..42534bd 100644
--- a/cpu/blackfin/serial.c
+++ b/cpu/blackfin/serial.c
@@ -29,6 +29,8 @@
 #include <asm/blackfin.h>
 #include <asm/mach-common/bits/uart.h>
 
+#ifdef CONFIG_UART_CONSOLE
+
 #if defined(UART_LSR) && (CONFIG_UART_CONSOLE != 0)
 # error CONFIG_UART_CONSOLE must be 0 on parts with only one UART
 #endif
@@ -170,3 +172,5 @@
 	while (*s)
 		serial_putc(*s++);
 }
+
+#endif
diff --git a/cpu/blackfin/serial.h b/cpu/blackfin/serial.h
index ec40c26..f671096 100644
--- a/cpu/blackfin/serial.h
+++ b/cpu/blackfin/serial.h
@@ -14,6 +14,10 @@
 #include <asm/blackfin.h>
 #include <asm/mach-common/bits/uart.h>
 
+#ifndef CONFIG_UART_CONSOLE
+# define CONFIG_UART_CONSOLE 0
+#endif
+
 #ifdef CONFIG_DEBUG_EARLY_SERIAL
 # define BFIN_DEBUG_EARLY_SERIAL 1
 #else
@@ -95,7 +99,16 @@
 __attribute__((always_inline))
 static inline void serial_do_portmux(void)
 {
-#ifdef __ADSPBF52x__
+#if defined(__ADSPBF51x__)
+# define DO_MUX(port, mux_tx, mux_rx, tx, rx) \
+	bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~(PORT_x_MUX_##mux_tx##_MASK | PORT_x_MUX_##mux_rx##_MASK)) | PORT_x_MUX_##mux_tx##_FUNC_2 | PORT_x_MUX_##mux_rx##_FUNC_2); \
+	bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx);
+	switch (CONFIG_UART_CONSOLE) {
+	case 0: DO_MUX(G, 5, 5, 9, 10);  break;	/* Port G; mux 5; PG9 and PG10 */
+	case 1: DO_MUX(F, 2, 3, 14, 15); break;	/* Port H; mux 2/3; PH14 and PH15 */
+	}
+	SSYNC();
+#elif defined(__ADSPBF52x__)
 # define DO_MUX(port, mux, tx, rx) \
 	bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~PORT_x_MUX_##mux##_MASK) | PORT_x_MUX_##mux##_FUNC_3); \
 	bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx);
diff --git a/cpu/blackfin/start.S b/cpu/blackfin/start.S
index 9975a0c..6c8def4 100644
--- a/cpu/blackfin/start.S
+++ b/cpu/blackfin/start.S
@@ -125,8 +125,11 @@
 	 */
 	r6 = 1 (x);
 
-	/* Relocate from wherever are (FLASH/RAM/etc...) to the
-	 * hardcoded monitor location in the end of RAM.
+	/* Relocate from wherever we are (FLASH/RAM/etc...) to the hardcoded
+	 * monitor location in the end of RAM.  We know that memcpy() only
+	 * uses registers, so it is safe to call here.  Note that this only
+	 * copies to external memory ... we do not start executing out of
+	 * it yet (see "lower to 15" below).
 	 */
 	serial_early_puts("Relocate");
 	call _get_pc;
@@ -135,27 +138,16 @@
 	r2.h = .Loffset;
 	r3.l = _start;
 	r3.h = _start;
-	r1 = r2 - r3;
-
-	r0 = r0 - r1;
-
-	cc = r0 == r3;
+	r2 = r2 - r3;
+	r1 = r0 - r2;
+	cc = r1 == r3;
 	if cc jump .Lnorelocate;
-
 	r6 = 0 (x);
-	p1 = r0;
 
-	p2.l = LO(CONFIG_SYS_MONITOR_BASE);
-	p2.h = HI(CONFIG_SYS_MONITOR_BASE);
-
-	p3 = 0x04;
-	p4.l = LO(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN);
-	p4.h = HI(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN);
-.Lloop1:
-	r1 = [p1 ++ p3];
-	[p2 ++ p3] = r1;
-	cc=p2==p4;
-	if !cc jump .Lloop1;
+	r0 = r3;
+	r2.l = LO(CONFIG_SYS_MONITOR_LEN);
+	r2.h = HI(CONFIG_SYS_MONITOR_LEN);
+	call _memcpy_ASM;
 
 	/* Initialize BSS section ... we know that memset() does not
 	 * use the BSS, so it is safe to call here.  The bootrom LDR
@@ -173,9 +165,8 @@
 .Lnorelocate:
 
 	/* Setup the actual stack in external memory */
-	r0.h = HI(CONFIG_STACKBASE);
-	r0.l = LO(CONFIG_STACKBASE);
-	sp = r0;
+	sp.h = HI(CONFIG_STACKBASE);
+	sp.l = LO(CONFIG_STACKBASE);
 	fp = sp;
 
 	/* Now lower ourselves from the highest interrupt level to
@@ -183,7 +174,9 @@
 	 * setting the 15 handler to ".Lenable_nested", raising the 15
 	 * interrupt, and then returning from the highest interrupt
 	 * level to the dummy "jump" until the interrupt controller
-	 * services the pending 15 interrupt.
+	 * services the pending 15 interrupt.  If executing out of
+	 * flash, these steps also changes the code flow from flash
+	 * to external memory.
 	 */
 	serial_early_puts("Lower to 15");
 	r0 = r7;
diff --git a/cpu/blackfin/traps.c b/cpu/blackfin/traps.c
index d17c0a1..a2c6f1e 100644
--- a/cpu/blackfin/traps.c
+++ b/cpu/blackfin/traps.c
@@ -111,23 +111,12 @@
 		}
 		if (i == ARRAY_SIZE(bfin_memory_map)) {
 			printf("%cCPLB exception outside of memory map at 0x%p\n",
-				(data ? 'D' : 'I'), new_cplb_addr);
+				(data ? 'D' : 'I'), (void *)new_cplb_addr);
 			bfin_panic(regs);
 		} else
 			debug("CPLB addr %p matches map 0x%p - 0x%p\n", new_cplb_addr, bfin_memory_map[i].start, bfin_memory_map[i].end);
 		new_cplb_data = (data ? bfin_memory_map[i].data_flags : bfin_memory_map[i].inst_flags);
 
-		/* Turn the cache off */
-		SSYNC();
-		if (data) {
-			asm(" .align 8; ");
-			*pDMEM_CONTROL &= ~ENDCPLB;
-		} else {
-			asm(" .align 8; ");
-			*pIMEM_CONTROL &= ~ENICPLB;
-		}
-		SSYNC();
-
 		if (data) {
 			CPLB_ADDR_BASE = (uint32_t *)DCPLB_ADDR0;
 			CPLB_DATA_BASE = (uint32_t *)DCPLB_DATA0;
@@ -149,8 +138,17 @@
 
 		debug("evicting entry %i: 0x%p 0x%08X\n", i, *CPLB_ADDR, *CPLB_DATA);
 		last_evicted = i + 1;
+
+		/* need to turn off cplbs whenever we muck with the cplb table */
+#if ENDCPLB != ENICPLB
+# error cplb enable bit violates my sanity
+#endif
+		uint32_t mem_control = (data ? DMEM_CONTROL : IMEM_CONTROL);
+		bfin_write32(mem_control, bfin_read32(mem_control) & ~ENDCPLB);
 		*CPLB_ADDR = new_cplb_addr;
 		*CPLB_DATA = new_cplb_data;
+		bfin_write32(mem_control, bfin_read32(mem_control) | ENDCPLB);
+		SSYNC();
 
 		/* dump current table for debugging purposes */
 		CPLB_ADDR = CPLB_ADDR_BASE;
@@ -158,17 +156,6 @@
 		for (i = 0; i < 16; ++i)
 			debug("%2i 0x%p 0x%08X\n", i, *CPLB_ADDR++, *CPLB_DATA++);
 
-		/* Turn the cache back on */
-		SSYNC();
-		if (data) {
-			asm(" .align 8; ");
-			*pDMEM_CONTROL |= ENDCPLB;
-		} else {
-			asm(" .align 8; ");
-			*pIMEM_CONTROL |= ENICPLB;
-		}
-		SSYNC();
-
 		break;
 	}
 
@@ -220,20 +207,21 @@
 static void decode_address(char *buf, unsigned long address)
 {
 	unsigned long sym_addr;
+	void *paddr = (void *)address;
 	const char *sym = symbol_lookup(address, &sym_addr);
 
 	if (sym) {
-		sprintf(buf, "<0x%p> { %s + 0x%x }", address, sym, address - sym_addr);
+		sprintf(buf, "<0x%p> { %s + 0x%lx }", paddr, sym, address - sym_addr);
 		return;
 	}
 
 	if (!address)
-		sprintf(buf, "<0x%p> /* Maybe null pointer? */", address);
+		sprintf(buf, "<0x%p> /* Maybe null pointer? */", paddr);
 	else if (address >= CONFIG_SYS_MONITOR_BASE &&
 	         address < CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)
-		sprintf(buf, "<0x%p> /* somewhere in u-boot */", address);
+		sprintf(buf, "<0x%p> /* somewhere in u-boot */", paddr);
 	else
-		sprintf(buf, "<0x%p> /* unknown address */", address);
+		sprintf(buf, "<0x%p> /* unknown address */", paddr);
 }
 
 static char *strhwerrcause(uint16_t hwerrcause)
@@ -273,7 +261,7 @@
 void dump(struct pt_regs *fp)
 {
 	char buf[150];
-	size_t i;
+	int i;
 	uint16_t hwerrcause, excause;
 
 	if (!ENABLE_DUMP)
@@ -288,8 +276,8 @@
 	printf("SEQUENCER STATUS:\n");
 	printf(" SEQSTAT: %08lx  IPEND: %04lx  SYSCFG: %04lx\n",
 		fp->seqstat, fp->ipend, fp->syscfg);
-	printf("  HWERRCAUSE: 0x%lx: %s\n", hwerrcause, strhwerrcause(hwerrcause));
-	printf("  EXCAUSE   : 0x%lx: %s\n", excause, strexcause(excause));
+	printf("  HWERRCAUSE: 0x%x: %s\n", hwerrcause, strhwerrcause(hwerrcause));
+	printf("  EXCAUSE   : 0x%x: %s\n", excause, strexcause(excause));
 	for (i = 6; i <= 15; ++i) {
 		if (fp->ipend & (1 << i)) {
 			decode_address(buf, bfin_read32(EVT0 + 4*i));
@@ -323,7 +311,7 @@
 	printf(" P0 : %08lx    P1 : %08lx    P2 : %08lx    P3 : %08lx\n",
 		fp->p0, fp->p1, fp->p2, fp->p3);
 	printf(" P4 : %08lx    P5 : %08lx    FP : %08lx    SP : %08lx\n",
-		fp->p4, fp->p5, fp->fp, fp);
+		fp->p4, fp->p5, fp->fp, (unsigned long)fp);
 	printf(" LB0: %08lx    LT0: %08lx    LC0: %08lx\n",
 		fp->lb0, fp->lt0, fp->lc0);
 	printf(" LB1: %08lx    LT1: %08lx    LC1: %08lx\n",
@@ -349,7 +337,7 @@
 {
 	char buf[150];
 	unsigned long tflags;
-	size_t i = 0;
+	int i = 0;
 
 	if (!ENABLE_DUMP)
 		return;
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 6079c05..08cb91d 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -25,6 +25,7 @@
 
 LIB	:= $(obj)libi2c.a
 
+COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
diff --git a/drivers/i2c/bfin-twi_i2c.c b/drivers/i2c/bfin-twi_i2c.c
new file mode 100644
index 0000000..cfe55cd
--- /dev/null
+++ b/drivers/i2c/bfin-twi_i2c.c
@@ -0,0 +1,285 @@
+/*
+ * i2c.c - driver for Blackfin on-chip TWI/I2C
+ *
+ * Copyright (c) 2006-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+#include <asm/blackfin.h>
+#include <asm/mach-common/bits/twi.h>
+
+#ifdef DEBUG
+# define dmemset(s, c, n) memset(s, c, n)
+#else
+# define dmemset(s, c, n)
+#endif
+#define debugi(fmt, args...) \
+	debug( \
+		"MSTAT:0x%03x FSTAT:0x%x ISTAT:0x%02x\t" \
+		"%-20s:%-3i: " fmt "\n", \
+		bfin_read_TWI_MASTER_STAT(), bfin_read_TWI_FIFO_STAT(), bfin_read_TWI_INT_STAT(), \
+		__func__, __LINE__, ## args)
+
+#ifdef TWI0_CLKDIV
+#define bfin_write_TWI_CLKDIV(val)           bfin_write_TWI0_CLKDIV(val)
+#define bfin_write_TWI_CONTROL(val)          bfin_write_TWI0_CONTROL(val)
+#define bfin_read_TWI_CONTROL(val)           bfin_read_TWI0_CONTROL(val)
+#define bfin_write_TWI_MASTER_ADDR(val)      bfin_write_TWI0_MASTER_ADDR(val)
+#define bfin_write_TWI_XMT_DATA8(val)        bfin_write_TWI0_XMT_DATA8(val)
+#define bfin_read_TWI_RCV_DATA8()            bfin_read_TWI0_RCV_DATA8()
+#define bfin_read_TWI_INT_STAT()             bfin_read_TWI0_INT_STAT()
+#define bfin_write_TWI_INT_STAT(val)         bfin_write_TWI0_INT_STAT(val)
+#define bfin_read_TWI_MASTER_STAT()          bfin_read_TWI0_MASTER_STAT()
+#define bfin_write_TWI_MASTER_STAT(val)      bfin_write_TWI0_MASTER_STAT(val)
+#define bfin_read_TWI_MASTER_CTL()           bfin_read_TWI0_MASTER_CTL()
+#define bfin_write_TWI_MASTER_CTL(val)       bfin_write_TWI0_MASTER_CTL(val)
+#define bfin_write_TWI_INT_MASK(val)         bfin_write_TWI0_INT_MASK(val)
+#define bfin_write_TWI_FIFO_CTL(val)         bfin_write_TWI0_FIFO_CTL(val)
+#endif
+
+#ifdef CONFIG_TWICLK_KHZ
+# error do not define CONFIG_TWICLK_KHZ ... use CONFIG_SYS_I2C_SPEED
+#endif
+#if CONFIG_SYS_I2C_SPEED > 400000
+# error The Blackfin I2C hardware can only operate at 400KHz max
+#endif
+
+/* All transfers are described by this data structure */
+struct i2c_msg {
+	u8 flags;
+#define I2C_M_COMBO		0x4
+#define I2C_M_STOP		0x2
+#define I2C_M_READ		0x1
+	int len;		/* msg length */
+	u8 *buf;		/* pointer to msg data */
+	int alen;		/* addr length */
+	u8 *abuf;		/* addr buffer */
+};
+
+/**
+ * wait_for_completion - manage the actual i2c transfer
+ *	@msg: the i2c msg
+ */
+static int wait_for_completion(struct i2c_msg *msg)
+{
+	uint16_t int_stat;
+
+	while (!ctrlc()) {
+		int_stat = bfin_read_TWI_INT_STAT();
+
+		if (int_stat & XMTSERV) {
+			debugi("processing XMTSERV");
+			bfin_write_TWI_INT_STAT(XMTSERV);
+			SSYNC();
+			if (msg->alen) {
+				bfin_write_TWI_XMT_DATA8(*(msg->abuf++));
+				--msg->alen;
+			} else if (!(msg->flags & I2C_M_COMBO) && msg->len) {
+				bfin_write_TWI_XMT_DATA8(*(msg->buf++));
+				--msg->len;
+			} else {
+				bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() |
+					(msg->flags & I2C_M_COMBO ? RSTART | MDIR : STOP));
+				SSYNC();
+			}
+		}
+		if (int_stat & RCVSERV) {
+			debugi("processing RCVSERV");
+			bfin_write_TWI_INT_STAT(RCVSERV);
+			SSYNC();
+			if (msg->len) {
+				*(msg->buf++) = bfin_read_TWI_RCV_DATA8();
+				--msg->len;
+			} else if (msg->flags & I2C_M_STOP) {
+				bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | STOP);
+				SSYNC();
+			}
+		}
+		if (int_stat & MERR) {
+			debugi("processing MERR");
+			bfin_write_TWI_INT_STAT(MERR);
+			SSYNC();
+			break;
+		}
+		if (int_stat & MCOMP) {
+			debugi("processing MCOMP");
+			bfin_write_TWI_INT_STAT(MCOMP);
+			SSYNC();
+			if (msg->flags & I2C_M_COMBO && msg->len) {
+				bfin_write_TWI_MASTER_CTL((bfin_read_TWI_MASTER_CTL() & ~RSTART) |
+					(min(msg->len, 0xff) << 6) | MEN | MDIR);
+				SSYNC();
+			} else
+				break;
+		}
+	}
+
+	return msg->len;
+}
+
+/**
+ * i2c_transfer - setup an i2c transfer
+ *	@return: 0 if things worked, non-0 if things failed
+ *
+ *	Here we just get the i2c stuff all prepped and ready, and then tail off
+ *	into wait_for_completion() for all the bits to go.
+ */
+static int i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer, int len, u8 flags)
+{
+	uchar addr_buffer[] = {
+		(addr >>  0),
+		(addr >>  8),
+		(addr >> 16),
+	};
+	struct i2c_msg msg = {
+		.flags = flags | (len >= 0xff ? I2C_M_STOP : 0),
+		.buf   = buffer,
+		.len   = len,
+		.abuf  = addr_buffer,
+		.alen  = alen,
+	};
+	int ret;
+
+	dmemset(buffer, 0xff, len);
+	debugi("chip=0x%x addr=0x%02x alen=%i buf[0]=0x%02x len=%i flags=0x%02x[%s] ",
+		chip, addr, alen, buffer[0], len, flags, (flags & I2C_M_READ ? "rd" : "wr"));
+
+	/* wait for things to settle */
+	while (bfin_read_TWI_MASTER_STAT() & BUSBUSY)
+		if (ctrlc())
+			return 1;
+
+	/* Set Transmit device address */
+	bfin_write_TWI_MASTER_ADDR(chip);
+
+	/* Clear the FIFO before starting things */
+	bfin_write_TWI_FIFO_CTL(XMTFLUSH | RCVFLUSH);
+	SSYNC();
+	bfin_write_TWI_FIFO_CTL(0);
+	SSYNC();
+
+	/* prime the pump */
+	if (msg.alen) {
+		len = msg.alen;
+		debugi("first byte=0x%02x", *msg.abuf);
+		bfin_write_TWI_XMT_DATA8(*(msg.abuf++));
+		--msg.alen;
+	} else if (!(msg.flags & I2C_M_READ) && msg.len) {
+		debugi("first byte=0x%02x", *msg.buf);
+		bfin_write_TWI_XMT_DATA8(*(msg.buf++));
+		--msg.len;
+	}
+
+	/* clear int stat */
+	bfin_write_TWI_MASTER_STAT(-1);
+	bfin_write_TWI_INT_STAT(-1);
+	bfin_write_TWI_INT_MASK(0);
+	SSYNC();
+
+	/* Master enable */
+	bfin_write_TWI_MASTER_CTL(
+			(bfin_read_TWI_MASTER_CTL() & FAST) |
+			(min(len, 0xff) << 6) | MEN |
+			((msg.flags & I2C_M_READ) ? MDIR : 0)
+	);
+	SSYNC();
+	debugi("CTL=0x%04x", bfin_read_TWI_MASTER_CTL());
+
+	/* process the rest */
+	ret = wait_for_completion(&msg);
+	debugi("ret=%d", ret);
+
+	if (ret) {
+		bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() & ~MEN);
+		bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() & ~TWI_ENA);
+		SSYNC();
+		bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
+		SSYNC();
+	}
+
+	return ret;
+}
+
+/*
+ * i2c_init - initialize the i2c bus
+ *	@speed: bus speed (in HZ)
+ *	@slaveaddr: address of device in slave mode (0 - not slave)
+ *
+ *	Slave mode isn't actually implemented.  It'll stay that way until
+ *	we get a real request for it.
+ */
+void i2c_init(int speed, int slaveaddr)
+{
+	uint8_t prescale = ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F;
+
+	/* Set TWI internal clock as 10MHz */
+	bfin_write_TWI_CONTROL(prescale);
+
+	/* Set TWI interface clock as specified */
+	bfin_write_TWI_CLKDIV(
+		((5 * 1024 / (speed / 1000)) << 8) |
+		((5 * 1024 / (speed / 1000)) & 0xFF)
+	);
+
+	/* Don't turn it on */
+	bfin_write_TWI_MASTER_CTL(speed > 100000 ? FAST : 0);
+
+	/* But enable it */
+	bfin_write_TWI_CONTROL(TWI_ENA | prescale);
+	SSYNC();
+
+	debugi("CONTROL:0x%04x CLKDIV:0x%04x",
+		bfin_read_TWI_CONTROL(), bfin_read_TWI_CLKDIV());
+
+#if CONFIG_SYS_I2C_SLAVE
+# error I2C slave support not tested/supported
+	/* If they want us as a slave, do it */
+	if (slaveaddr) {
+		bfin_write_TWI_SLAVE_ADDR(slaveaddr);
+		bfin_write_TWI_SLAVE_CTL(SEN);
+	}
+#endif
+}
+
+/**
+ * i2c_probe - test if a chip exists at a given i2c address
+ *	@chip: i2c chip addr to search for
+ *	@return: 0 if found, non-0 if not found
+ */
+int i2c_probe(uchar chip)
+{
+	u8 byte;
+	return i2c_read(chip, 0, 0, &byte, 1);
+}
+
+/**
+ * i2c_read - read data from an i2c device
+ *	@chip: i2c chip addr
+ *	@addr: memory (register) address in the chip
+ *	@alen: byte size of address
+ *	@buffer: buffer to store data read from chip
+ *	@len: how many bytes to read
+ *	@return: 0 on success, non-0 on failure
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	return i2c_transfer(chip, addr, alen, buffer, len, (alen ? I2C_M_COMBO : I2C_M_READ));
+}
+
+/**
+ * i2c_write - write data to an i2c device
+ *	@chip: i2c chip addr
+ *	@addr: memory (register) address in the chip
+ *	@alen: byte size of address
+ *	@buffer: buffer to store data read from chip
+ *	@len: how many bytes to write
+ *	@return: 0 on success, non-0 on failure
+ */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	return i2c_transfer(chip, addr, alen, buffer, len, 0);
+}
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 504fd10..dddbb78 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -331,20 +331,43 @@
 	*pVR_CTL |= CLKBUFOE;
 	/* Set all the pins to peripheral mode */
 
-#ifndef CONFIG_BFIN_MAC_RMII
-	*pPORTH_FER = 0xFFFF;
-#ifdef __ADSPBF52x__
-	*pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2;
-#endif
+#ifdef CONFIG_BFIN_MAC_RMII
+	/* grab RMII pins */
+# if defined(__ADSPBF51x__)
+	*pPORTF_MUX = (*pPORTF_MUX & \
+		~(PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \
+		PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1;
+	*pPORTF_FER |= PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15;
+	*pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1;
+	*pPORTG_FER |= PG0 | PG1 | PG2;
+# elif defined(__ADSPBF52x__)
+	*pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2;
+	*pPORTG_FER |= PG14 | PG15;
+	*pPORTH_MUX = (*pPORTH_MUX & ~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK)) | \
+		PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2;
+	*pPORTH_FER |= PH0 | PH1 | PH2 | PH3 | PH4 | PH5 | PH6 | PH7 | PH8;
+# else
+	*pPORTH_FER |= PH0 | PH1 | PH4 | PH5 | PH6 | PH8 | PH9 | PH14 | PH15;
+# endif
 #else
-#if defined(__ADSPBF536__) || defined(__ADSPBF537__)
-	*pPORTH_FER = 0xC373;
+	/* grab MII & RMII pins */
+# if defined(__ADSPBF51x__)
+	*pPORTF_MUX = (*pPORTF_MUX & \
+		~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK | PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \
+		PORT_x_MUX_0_FUNC_1 | PORT_x_MUX_1_FUNC_1 | PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1;
+	*pPORTF_FER |= PF0 | PF1 | PF2 | PF3 | PF4 | PF5 | PF6 | PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15;
+	*pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1;
+	*pPORTG_FER |= PG0 | PG1 | PG2;
+# elif defined(__ADSPBF52x__)
+	*pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2;
+	*pPORTG_FER |= PG14 | PG15;
+	*pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2;
+	*pPORTH_FER = -1; /* all pins */
+# else
+	*pPORTH_FER = -1; /* all pins */
+# endif
 #endif
-#ifdef __ADSPBF52x__
-	*pPORTH_FER = 0x01FF;
-	*pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2;
-#endif
-#endif
+
 	/* MDC  = 2.5 MHz */
 	sysctl = SET_MDCDIV(24);
 	/* Odd word alignment for Receive Frame DMA word */
diff --git a/include/asm-blackfin/blackfin-config-post.h b/include/asm-blackfin/blackfin-config-post.h
index 0ab68ac..21abd72 100644
--- a/include/asm-blackfin/blackfin-config-post.h
+++ b/include/asm-blackfin/blackfin-config-post.h
@@ -1,7 +1,7 @@
 /*
  * blackfin-config-post.h - setup common defines for Blackfin boards based on config.h
  *
- * Copyright (c) 2007 Analog Devices Inc.
+ * Copyright (c) 2007-2008 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -9,11 +9,6 @@
 #ifndef __ASM_BLACKFIN_CONFIG_POST_H__
 #define __ASM_BLACKFIN_CONFIG_POST_H__
 
-/* Check to make sure everything fits in external RAM */
-#if ((CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) > CONFIG_SYS_MAX_RAM_SIZE)
-# error Memory Map does not fit into configuration
-#endif
-
 /* Sanity check CONFIG_BFIN_CPU */
 #ifndef CONFIG_BFIN_CPU
 # error CONFIG_BFIN_CPU: your board config needs to define this
@@ -65,8 +60,81 @@
 #endif
 
 /* Using L1 scratch pad makes sense for everyone by default. */
-#ifndef CMD_LINE_ADDR
-# define CMD_LINE_ADDR L1_SRAM_SCRATCH
+#ifndef CONFIG_LINUX_CMDLINE_ADDR
+# define CONFIG_LINUX_CMDLINE_ADDR L1_SRAM_SCRATCH
+#endif
+#ifndef CONFIG_LINUX_CMDLINE_SIZE
+# define CONFIG_LINUX_CMDLINE_SIZE L1_SRAM_SCRATCH_SIZE
+#endif
+
+/* Default/common Blackfin memory layout */
+#ifndef CONFIG_SYS_SDRAM_BASE
+# define CONFIG_SYS_SDRAM_BASE 0
+#endif
+#ifndef CONFIG_SYS_MAX_RAM_SIZE
+# define CONFIG_SYS_MAX_RAM_SIZE (CONFIG_MEM_SIZE * 1024 * 1024)
+#endif
+#ifndef CONFIG_SYS_MONITOR_BASE
+# define CONFIG_SYS_MONITOR_BASE (CONFIG_SYS_MAX_RAM_SIZE - CONFIG_SYS_MONITOR_LEN)
+#endif
+#ifndef CONFIG_SYS_MALLOC_BASE
+# define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN)
+#endif
+#ifndef CONFIG_SYS_GBL_DATA_SIZE
+# define CONFIG_SYS_GBL_DATA_SIZE (128)
+#endif
+#ifndef CONFIG_SYS_GBL_DATA_ADDR
+# define CONFIG_SYS_GBL_DATA_ADDR (CONFIG_SYS_MALLOC_BASE - CONFIG_SYS_GBL_DATA_SIZE)
+#endif
+#ifndef CONFIG_STACKBASE
+# define CONFIG_STACKBASE (CONFIG_SYS_GBL_DATA_ADDR - 4)
+#endif
+#ifndef CONFIG_SYS_MEMTEST_START
+# define CONFIG_SYS_MEMTEST_START 0
+#endif
+#ifndef CONFIG_SYS_MEMTEST_END
+# define CONFIG_SYS_MEMTEST_END (CONFIG_STACKBASE - 8192 + 4)
+#endif
+
+/* Check to make sure everything fits in external RAM */
+#if ((CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) > CONFIG_SYS_MAX_RAM_SIZE)
+# error Memory Map does not fit into configuration
+#endif
+
+/* Default/common Blackfin environment settings */
+#ifndef CONFIG_LOADADDR
+# define CONFIG_LOADADDR 0x1000000
+#endif
+#ifndef CONFIG_SYS_LOAD_ADDR
+# define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+#endif
+#ifndef CONFIG_SYS_BOOTM_LEN
+# define CONFIG_SYS_BOOTM_LEN 0x4000000
+#endif
+#ifndef CONFIG_SYS_PROMPT
+# define CONFIG_SYS_PROMPT "bfin> "
+#endif
+#ifndef CONFIG_SYS_CBSIZE
+# ifdef CONFIG_CMD_KGDB
+#  define CONFIG_SYS_CBSIZE 1024
+# else
+#  define CONFIG_SYS_CBSIZE 256
+# endif
+#endif
+#ifndef CONFIG_SYS_BARGSIZE
+# define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+#endif
+#ifndef CONFIG_SYS_PBSIZE
+# define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#endif
+#ifndef CONFIG_SYS_MAXARGS
+# define CONFIG_SYS_MAXARGS 16
+#endif
+#ifndef CONFIG_SYS_HZ
+# define CONFIG_SYS_HZ 1000
+#endif
+#ifndef CONFIG_SYS_BAUDRATE_TABLE
+# define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
 #endif
 
 #endif
diff --git a/include/asm-blackfin/blackfin_local.h b/include/asm-blackfin/blackfin_local.h
index 6f0e662..c9ee91a 100644
--- a/include/asm-blackfin/blackfin_local.h
+++ b/include/asm-blackfin/blackfin_local.h
@@ -58,7 +58,7 @@
 
 extern void blackfin_icache_flush_range(const void *, const void *);
 extern void blackfin_dcache_flush_range(const void *, const void *);
-extern void blackfin_dcache_invalidate_range(const void *, const void *);
+extern void blackfin_dcache_flush_invalidate_range(const void *, const void *);
 
 /* Use DMA to move data from on chip to external memory.  While this is
  * required for only L1 instruction (it is not directly readable by the
diff --git a/include/asm-blackfin/mach-common/bits/bootrom.h b/include/asm-blackfin/mach-common/bits/bootrom.h
index 6cdaa4f..fb97ff8 100644
--- a/include/asm-blackfin/mach-common/bits/bootrom.h
+++ b/include/asm-blackfin/mach-common/bits/bootrom.h
@@ -88,27 +88,42 @@
 #define _BOOTROM_REV                   0xEF000040
 #define _BOOTROM_SESR                  0xEF001000
 
+#define BOOTROM_FOLLOWS_C_ABI 1
+
 #define BOOTROM_CAPS_ADI_BOOT_STRUCTS 1
 
-/* Not available on initial BF54x or BF52x */
-#if (defined(__ADSPBF54x__) && __SILICON_REVISION__ < 1) || \
-    (defined(__ADSPBF52x__) && __SILICON_REVISION__ < 2)
-#define BOOTROM_CAPS_SYSCONTROL 0
-#else
-#define BOOTROM_CAPS_SYSCONTROL 1
 #endif
 
+#ifndef BOOTROM_FOLLOWS_C_ABI
+#define BOOTROM_FOLLOWS_C_ABI 0
 #endif
-
 #ifndef BOOTROM_CAPS_ADI_BOOT_STRUCTS
 #define BOOTROM_CAPS_ADI_BOOT_STRUCTS 0
 #endif
-#ifndef BOOTROM_CAPS_SYSCONTROL
-#define BOOTROM_CAPS_SYSCONTROL 0
-#endif
+
+/* Possible syscontrol action flags */
+#define SYSCTRL_READ        0x00000000    /* read registers */
+#define SYSCTRL_WRITE       0x00000001    /* write registers */
+#define SYSCTRL_SYSRESET    0x00000002    /* perform system reset */
+#define SYSCTRL_CORERESET   0x00000004    /* perform core reset */
+#define SYSCTRL_SOFTRESET   0x00000006    /* perform core and system reset */
+#define SYSCTRL_VRCTL       0x00000010    /* read/write VR_CTL register */
+#define SYSCTRL_EXTVOLTAGE  0x00000020    /* VDDINT supplied externally */
+#define SYSCTRL_INTVOLTAGE  0x00000000    /* VDDINT generated by on-chip regulator */
+#define SYSCTRL_OTPVOLTAGE  0x00000040    /* For Factory Purposes Only */
+#define SYSCTRL_PLLCTL      0x00000100    /* read/write PLL_CTL register */
+#define SYSCTRL_PLLDIV      0x00000200    /* read/write PLL_DIV register */
+#define SYSCTRL_LOCKCNT     0x00000400    /* read/write PLL_LOCKCNT register */
+#define SYSCTRL_PLLSTAT     0x00000800    /* read/write PLL_STAT register */
 
 #ifndef __ASSEMBLY__
 
+#if BOOTROM_FOLLOWS_C_ABI
+# define BOOTROM_CALLED_FUNC_ATTR
+#else
+# define BOOTROM_CALLED_FUNC_ATTR __attribute__((saveall))
+#endif
+
 /* Structures for the syscontrol() function */
 typedef struct ADI_SYSCTRL_VALUES {
 	uint16_t uwVrCtl;
@@ -121,25 +136,26 @@
 #ifndef _BOOTROM_SYSCONTROL
 #define _BOOTROM_SYSCONTROL 0
 #endif
-static uint32_t (* const syscontrol)(uint32_t action_flags, ADI_SYSCTRL_VALUES *power_settings, void *reserved) = (void *)_BOOTROM_SYSCONTROL;
+static uint32_t (* const bfrom_SysControl)(uint32_t action_flags, ADI_SYSCTRL_VALUES *power_settings, void *reserved) = (void *)_BOOTROM_SYSCONTROL;
 
-#endif /* __ASSEMBLY__ */
-
-/* Possible syscontrol action flags */
-#define SYSCTRL_READ        0x00000000    /* read registers */
-#define SYSCTRL_WRITE       0x00000001    /* write registers */
-#define SYSCTRL_SYSRESET    0x00000002    /* perform system reset */
-#define SYSCTRL_SOFTRESET   0x00000004    /* perform core and system reset */
-#define SYSCTRL_VRCTL       0x00000010    /* read/write VR_CTL register */
-#define SYSCTRL_EXTVOLTAGE  0x00000020    /* VDDINT supplied externally */
-#define SYSCTRL_INTVOLTAGE  0x00000000    /* VDDINT generated by on-chip regulator */
-#define SYSCTRL_OTPVOLTAGE  0x00000040    /* For Factory Purposes Only */
-#define SYSCTRL_PLLCTL      0x00000100    /* read/write PLL_CTL register */
-#define SYSCTRL_PLLDIV      0x00000200    /* read/write PLL_DIV register */
-#define SYSCTRL_LOCKCNT     0x00000400    /* read/write PLL_LOCKCNT register */
-#define SYSCTRL_PLLSTAT     0x00000800    /* read/write PLL_STAT register */
-
-#ifndef __ASSEMBLY__
+/* We need a dedicated function since we need to screw with the stack pointer
+ * when resetting.  The on-chip ROM will save/restore registers on the stack
+ * when doing a system reset, so the stack cannot be outside of the chip.
+ */
+__attribute__((__noreturn__))
+static inline void bfrom_SoftReset(void *new_stack)
+{
+	while (1)
+		__asm__ __volatile__(
+			"sp = %[stack];"
+			"jump (%[bfrom_syscontrol]);"
+			: : [bfrom_syscontrol] "p"(bfrom_SysControl),
+				"q0"(SYSCTRL_SOFTRESET),
+				"q1"(0),
+				"q2"(NULL),
+				[stack] "p"(new_stack)
+		);
+}
 
 /* Structures for working with LDRs and boot rom callbacks */
 typedef struct ADI_BOOT_HEADER {
diff --git a/include/asm-blackfin/mach-common/bits/ebiu.h b/include/asm-blackfin/mach-common/bits/ebiu.h
index ab530ad..af456fb 100644
--- a/include/asm-blackfin/mach-common/bits/ebiu.h
+++ b/include/asm-blackfin/mach-common/bits/ebiu.h
@@ -410,12 +410,31 @@
 
 /* EBIU_SDSTAT Masks */
 #define SDCI		0x0001		/* SDRAM controller is idle */
-#define SDSRA		0x0002		/* SDRAM SDRAM self refresh is active */
+#define SDSRA		0x0002		/* SDRAM self refresh is active */
 #define SDPUA		0x0004		/* SDRAM power up active */
 #define SDRS		0x0008		/* SDRAM is in reset state */
 #define SDEASE		0x0010		/* SDRAM EAB sticky error status - W1C */
 #define BGSTAT		0x0020		/* Bus granted */
 
+/* Only available on DDR based-parts */
+#else
+
+/* EBIU_ERRMST Masks */
+#define DEB0_ERROR	0x0001		/* DEB0 access on reserved memory */
+#define DEB1_ERROR	0x0002		/* DEB1 access on reserved memory */
+#define DEB2_ERROR	0x0004		/* DEB2 (USB) access on reserved memory */
+#define CORE_ERROR	0x0008		/* Core access on reserved memory */
+#define DEB0_MERROR	0x0010		/* DEB0 access on reserved memory and DEB0_ERROR is set */
+#define DEB1_MERROR	0x0020		/* DEB1 access on reserved memory and DEB1_ERROR is set */
+#define DEB2_MERROR	0x0040		/* DEB2 access on reserved memory and DEB2_ERROR is set */
+#define CORE_MERROR	0x0080		/* Core access on reserved memory and CORE_ERROR is set */
+
+/* EBIU_RSTCTL Masks */
+#define DDR_SRESET	0x0001		/* Reset Control to DDR Controller */
+#define SRREQ		0x0008		/* Self Refresh Request */
+#define SRACK		0x0010		/* Self Refresh Request Acknowledgement */
+#define MDDRENABLE	0x0020		/* Mobile DDR Enable */
+
 #endif /* EBIU_SDGCTL */
 
 #endif
diff --git a/include/asm-blackfin/mach-common/bits/otp.h b/include/asm-blackfin/mach-common/bits/otp.h
index d529a0a..4e3f1af 100644
--- a/include/asm-blackfin/mach-common/bits/otp.h
+++ b/include/asm-blackfin/mach-common/bits/otp.h
@@ -9,23 +9,22 @@
 
 #include "bootrom.h"
 
-static uint32_t (* const otp_command)(uint32_t command, uint32_t value) = (void *)_BOOTROM_OTP_COMMAND;
-static uint32_t (* const otp_read)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_READ;
-static uint32_t (* const otp_write)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_WRITE;
+static uint32_t (* const bfrom_OtpCommand)(uint32_t command, uint32_t value) = (void *)_BOOTROM_OTP_COMMAND;
+static uint32_t (* const bfrom_OtpRead)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_READ;
+static uint32_t (* const bfrom_OtpWrite)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_WRITE;
 
 #endif
 
 /* otp_command(): defines for "command" */
-#define OTP_INIT             0x00000001
-#define OTP_CLOSE            0x00000002
+#define OTP_INIT                 0x00000001
+#define OTP_CLOSE                0x00000002
 
 /* otp_{read,write}(): defines for "flags" */
-#define OTP_LOWER_HALF       0x00000000 /* select upper/lower 64-bit half (bit 0) */
-#define OTP_UPPER_HALF       0x00000001
-#define OTP_NO_ECC           0x00000010 /* do not use ECC */
-#define OTP_LOCK             0x00000020 /* sets page protection bit for page */
-#define OTP_ACCESS_READ      0x00001000
-#define OTP_ACCESS_READWRITE 0x00002000
+#define OTP_LOWER_HALF           0x00000000 /* select upper/lower 64-bit half (bit 0) */
+#define OTP_UPPER_HALF           0x00000001
+#define OTP_NO_ECC               0x00000010 /* do not use ECC */
+#define OTP_LOCK                 0x00000020 /* sets page protection bit for page */
+#define OTP_CHECK_FOR_PREV_WRITE 0x00000080
 
 /* Return values for all functions */
 #define OTP_SUCCESS          0x00000000
diff --git a/include/configs/bf533-ezkit.h b/include/configs/bf533-ezkit.h
index e871737..48c0252 100644
--- a/include/configs/bf533-ezkit.h
+++ b/include/configs/bf533-ezkit.h
@@ -198,7 +198,7 @@
 #define I2C_DELAY	udelay(5)	/* 1/4 I2C clock duration */
 
 #define CONFIG_SYS_I2C_SPEED		50000
-#define CONFIG_SYS_I2C_SLAVE		0xFE
+#define CONFIG_SYS_I2C_SLAVE		0
 
 #define CONFIG_SYS_BOOTM_LEN		0x4000000	/* Large Image Length, set to 64 Meg */
 
diff --git a/include/configs/bf533-stamp.h b/include/configs/bf533-stamp.h
index 5ad99a2..ee41c7e 100644
--- a/include/configs/bf533-stamp.h
+++ b/include/configs/bf533-stamp.h
@@ -300,7 +300,7 @@
 #define I2C_DELAY		udelay(5)	/* 1/4 I2C clock duration */
 
 #define CONFIG_SYS_I2C_SPEED		50000
-#define CONFIG_SYS_I2C_SLAVE		0xFE
+#define CONFIG_SYS_I2C_SLAVE		0
 #endif /* CONFIG_SOFT_I2C */
 
 /*
diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h
index ac5aaa5..27567fa 100644
--- a/include/configs/bf537-stamp.h
+++ b/include/configs/bf537-stamp.h
@@ -305,13 +305,11 @@
 
 /*
  * I2C settings
- * By default PF1 is used as SDA and PF0 as SCL on the Stamp board
  */
-/* #define CONFIG_SOFT_I2C	1*/	/* I2C bit-banged */
-#define CONFIG_HARD_I2C		1	/* I2C TWI */
-#if defined CONFIG_HARD_I2C
-#define CONFIG_TWICLK_KHZ	50
-#endif
+#define CONFIG_HARD_I2C		1
+#define CONFIG_BFIN_TWI_I2C	1
+#define CFG_I2C_SPEED		50000
+#define CFG_I2C_SLAVE		0
 
 #define CONFIG_EBIU_SDRRC_VAL  0x306
 #define CONFIG_EBIU_SDGCTL_VAL 0x91114d
@@ -321,39 +319,6 @@
 #define CONFIG_EBIU_AMBCTL0_VAL		0x7BB07BB0
 #define CONFIG_EBIU_AMBCTL1_VAL		0xFFC27BB0
 
-#if defined CONFIG_SOFT_I2C
-/*
- * Software (bit-bang) I2C driver configuration
- */
-#define PF_SCL			PF0
-#define PF_SDA			PF1
-
-#define I2C_INIT		(*pFIO_DIR |=  PF_SCL); asm("ssync;")
-#define I2C_ACTIVE		(*pFIO_DIR |=  PF_SDA); *pFIO_INEN &= ~PF_SDA; asm("ssync;")
-#define I2C_TRISTATE		(*pFIO_DIR &= ~PF_SDA); *pFIO_INEN |= PF_SDA; asm("ssync;")
-#define I2C_READ		((volatile)(*pFIO_FLAG_D & PF_SDA) != 0); asm("ssync;")
-#define I2C_SDA(bit)		if(bit) { \
-					*pFIO_FLAG_S = PF_SDA; \
-					asm("ssync;"); \
-					} \
-				else    { \
-					*pFIO_FLAG_C = PF_SDA; \
-					asm("ssync;"); \
-					}
-#define I2C_SCL(bit)		if(bit) { \
-					*pFIO_FLAG_S = PF_SCL; \
-					asm("ssync;"); \
-					} \
-				else    { \
-					*pFIO_FLAG_C = PF_SCL; \
-					asm("ssync;"); \
-					}
-#define I2C_DELAY		udelay(5)	/* 1/4 I2C clock duration */
-#endif
-
-#define CONFIG_SYS_I2C_SPEED		50000
-#define CONFIG_SYS_I2C_SLAVE		0xFE
-
 /* 0xFF, 0x7BB07BB0, 0x22547BB0 */
 /* #define AMGCTLVAL		(AMBEN_P0 | AMBEN_P1 | AMBEN_P2 | AMCKEN)
 #define AMBCTL0VAL		(B1WAT_7 | B1RAT_11 | B1HT_2 | B1ST_3 | B1TT_4 | ~B1RDYPOL | \
diff --git a/include/devices.h b/include/devices.h
index 20ddfc4..84c4514 100644
--- a/include/devices.h
+++ b/include/devices.h
@@ -116,5 +116,8 @@
 #ifdef CONFIG_NETCONSOLE
 int	drv_nc_init (void);
 #endif
+#ifdef CONFIG_JTAG_CONSOLE
+int drv_jtag_console_init (void);
+#endif
 
 #endif	/* _DEVICES_H_ */
diff --git a/include/status_led.h b/include/status_led.h
index 79be698..175972a 100644
--- a/include/status_led.h
+++ b/include/status_led.h
@@ -346,6 +346,9 @@
 #elif defined(CONFIG_NIOS2)
 /* XXX empty just to avoid the error */
 /************************************************************************/
+#elif defined(CONFIG_BLACKFIN)
+/* XXX empty just to avoid the error */
+/************************************************************************/
 #elif defined(CONFIG_V38B)
 
 # define STATUS_LED_BIT		0x0010			/* Timer7 GPIO */
diff --git a/lib_blackfin/Makefile b/lib_blackfin/Makefile
index 3f69770..fee0fda 100644
--- a/lib_blackfin/Makefile
+++ b/lib_blackfin/Makefile
@@ -37,7 +37,7 @@
 SOBJS-y	+= memset.o
 
 COBJS-y	+= board.o
-COBJS-y	+= bootm.o
+COBJS-y	+= boot.o
 COBJS-y	+= cache.o
 COBJS-y	+= muldi3.o
 COBJS-y	+= post.o
diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c
index ddf8144..01b71d4 100644
--- a/lib_blackfin/board.c
+++ b/lib_blackfin/board.c
@@ -13,10 +13,10 @@
 #include <command.h>
 #include <devices.h>
 #include <environment.h>
-#include <i2c.h>
 #include <malloc.h>
 #include <net.h>
 #include <timestamp.h>
+#include <status_led.h>
 #include <version.h>
 
 #include <asm/cplb.h>
@@ -279,9 +279,13 @@
 	dcache_enable();
 #endif
 
+#ifdef DEBUG
+	if (CONFIG_SYS_GBL_DATA_SIZE < sizeof(*gd))
+		hang();
+#endif
 	serial_early_puts("Init global data\n");
 	gd = (gd_t *) (CONFIG_SYS_GBL_DATA_ADDR);
-	memset((void *)gd, 0, sizeof(gd_t));
+	memset((void *)gd, 0, CONFIG_SYS_GBL_DATA_SIZE);
 
 	/* Board data initialization */
 	addr = (CONFIG_SYS_GBL_DATA_ADDR + sizeof(gd_t));
@@ -331,16 +335,6 @@
 	board_init_r((gd_t *) gd, 0x20000010);
 }
 
-#if defined(CONFIG_SOFT_I2C) || defined(CONFIG_HARD_I2C)
-static int init_func_i2c(void)
-{
-	puts("I2C:   ");
-	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-	puts("ready\n");
-	return (0);
-}
-#endif
-
 void board_init_r(gd_t * id, ulong dest_addr)
 {
 	extern void malloc_bin_reloc(void);
@@ -356,14 +350,14 @@
 #endif
 
 #if	!defined(CONFIG_SYS_NO_FLASH)
-	/* There are some other pointer constants we must deal with */
-	/* configure available FLASH banks */
+	/* Initialize the flash and protect u-boot by default */
 	extern flash_info_t flash_info[];
 	ulong size = flash_init();
 	puts("Flash: ");
 	print_size(size, "\n");
 	flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_FLASH_BASE,
-		      CONFIG_SYS_FLASH_BASE + 0x1ffff, &flash_info[0]);
+		CONFIG_SYS_FLASH_BASE + CONFIG_SYS_MONITOR_LEN - 1,
+		&flash_info[0]);
 	bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
 	bd->bi_flashsize = size;
 	bd->bi_flashoffset = 0;
@@ -420,6 +414,11 @@
 	/* Initialize the console (after the relocation and devices init) */
 	console_init_r();
 
+#ifdef CONFIG_STATUS_LED
+	status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
+	status_led_set(STATUS_LED_CRASH, STATUS_LED_OFF);
+#endif
+
 	/* Initialize from environment */
 	if ((s = getenv("loadaddr")) != NULL)
 		load_addr = simple_strtoul(s, NULL, 16);
@@ -442,10 +441,6 @@
 			bd->bi_enetaddr[3], bd->bi_enetaddr[4], bd->bi_enetaddr[5]);
 #endif
 
-#if defined(CONFIG_SOFT_I2C) || defined(CONFIG_HARD_I2C)
-	init_func_i2c();
-#endif
-
 	display_global_data();
 
 #if defined(CONFIG_POST)
@@ -460,6 +455,10 @@
 
 void hang(void)
 {
+#ifdef CONFIG_STATUS_LED
+	status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
+	status_led_set(STATUS_LED_CRASH, STATUS_LED_BLINKING);
+#endif
 	puts("### ERROR ### Please RESET the board ###\n");
 	while (1)
 		/* If a JTAG emulator is hooked up, we'll automatically trigger
diff --git a/lib_blackfin/bootm.c b/lib_blackfin/boot.c
similarity index 68%
rename from lib_blackfin/bootm.c
rename to lib_blackfin/boot.c
index 195eb9c..951d5b0 100644
--- a/lib_blackfin/bootm.c
+++ b/lib_blackfin/boot.c
@@ -1,5 +1,5 @@
 /*
- * U-boot - bootm.c - misc boot helper functions
+ * U-boot - boot.c - misc boot helper functions
  *
  * Copyright (c) 2005-2008 Analog Devices Inc.
  *
@@ -20,17 +20,19 @@
 
 static char *make_command_line(void)
 {
-	char *dest = (char *)CMD_LINE_ADDR;
+	char *dest = (char *)CONFIG_LINUX_CMDLINE_ADDR;
 	char *bootargs = getenv("bootargs");
 
 	if (bootargs == NULL)
 		return NULL;
 
-	strncpy(dest, bootargs, 0x1000);
-	dest[0xfff] = 0;
+	strncpy(dest, bootargs, CONFIG_LINUX_CMDLINE_SIZE);
+	dest[CONFIG_LINUX_CMDLINE_SIZE - 1] = 0;
 	return dest;
 }
 
+extern ulong bfin_poweron_retx;
+
 int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 {
 	int	(*appl) (char *cmdline);
@@ -45,11 +47,16 @@
 
 	appl = (int (*)(char *))images->ep;
 
-	printf("Starting Kernel at = %x\n", appl);
+	printf("Starting Kernel at = %p\n", appl);
 	cmdline = make_command_line();
 	icache_disable();
 	dcache_disable();
-	(*appl) (cmdline);
+	asm __volatile__(
+		"RETX = %[retx];"
+		"CALL (%0);"
+		:
+		: "p"(appl), "q0"(cmdline), [retx] "d"(bfin_poweron_retx)
+	);
 	/* does not return */
 
 	return 1;
diff --git a/lib_blackfin/string.c b/lib_blackfin/string.c
index 6887c93..36eecdf 100644
--- a/lib_blackfin/string.c
+++ b/lib_blackfin/string.c
@@ -1,7 +1,7 @@
 /*
  * U-boot - string.c Contains library routines.
  *
- * Copyright (c) 2005-2007 Analog Devices Inc.
+ * Copyright (c) 2005-2008 Analog Devices Inc.
  *
  * (C) Copyright 2000-2004
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -130,12 +130,22 @@
 # define bfin_write_MDMA_D0_IRQ_STATUS bfin_write_MDMA1_D0_IRQ_STATUS
 # define bfin_read_MDMA_D0_IRQ_STATUS  bfin_read_MDMA1_D0_IRQ_STATUS
 #endif
-static void *dma_memcpy(void *dst, const void *src, size_t count)
+/* This version misbehaves for count values of 0 and 2^16+.
+ * Perhaps we should detect that ?  Nowhere do we actually
+ * use dma memcpy for those types of lengths though ...
+ */
+void dma_memcpy_nocache(void *dst, const void *src, size_t count)
 {
-	if (dcache_status())
-		blackfin_dcache_flush_range(src, src + count);
+	/* Scratchpad cannot be a DMA source or destination */
+	if (((unsigned long)src >= L1_SRAM_SCRATCH &&
+	     (unsigned long)src < L1_SRAM_SCRATCH_END) ||
+	    ((unsigned long)dst >= L1_SRAM_SCRATCH &&
+	     (unsigned long)dst < L1_SRAM_SCRATCH_END))
+		hang();
 
-	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
+	bfin_write_MDMA_S0_CONFIG(0);
+	bfin_write_MDMA_D0_CONFIG(0);
+	bfin_write_MDMA_D0_IRQ_STATUS(DMA_RUN | DMA_DONE | DMA_ERR);
 
 	/* Copy sram functions from sdram to sram */
 	/* Setup destination start address */
@@ -154,20 +164,33 @@
 
 	/* Enable source DMA */
 	bfin_write_MDMA_S0_CONFIG(DMAEN);
-	SSYNC();
 
 	bfin_write_MDMA_D0_CONFIG(WNR | DMAEN);
+	SSYNC();
 
 	while (bfin_read_MDMA_D0_IRQ_STATUS() & DMA_RUN)
-		bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | DMA_DONE | DMA_ERR);
-	bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | DMA_DONE | DMA_ERR);
+		continue;
+
+	bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | DMA_RUN | DMA_DONE | DMA_ERR);
+	bfin_write_MDMA_D0_CONFIG(0);
+	bfin_write_MDMA_S0_CONFIG(0);
+}
+/* We should do a dcache invalidate on the destination after the dma, but since
+ * we lack such hardware capability, we'll flush/invalidate the destination
+ * before the dma and bank on the idea that u-boot is single threaded.
+ */
+void *dma_memcpy(void *dst, const void *src, size_t count)
+{
+	if (dcache_status()) {
+		blackfin_dcache_flush_range(src, src + count);
+		blackfin_dcache_flush_invalidate_range(dst, dst + count);
+	}
+
+	dma_memcpy_nocache(dst, src, count);
 
 	if (icache_status())
 		blackfin_icache_flush_range(dst, dst + count);
 
-	if (dcache_status())
-		blackfin_dcache_invalidate_range(dst, dst + count);
-
 	return dst;
 }