diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c
index 18dbdf7abe9686b6e5220b534b5c3aa13bdbf2bb..6a0bcca9f921187acdfa5e15deca275881110ad4 100644
--- a/arch/blackfin/cpu/cpu.c
+++ b/arch/blackfin/cpu/cpu.c
@@ -19,6 +19,7 @@
 
 #include "cpu.h"
 #include "serial.h"
+#include "initcode.h"
 
 ulong bfin_poweron_retx;
 
@@ -44,13 +45,16 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
 		extern char _sdata_l1[], _data_l1_lma[], _data_l1_len[];
 		memcpy(&_sdata_l1, &_data_l1_lma, (unsigned long)_data_l1_len);
 	}
-#if defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__)
-	/* The BF537 bootrom will reset the EBIU_AMGCTL register on us
-	 * after it has finished loading the LDR.  So configure it again.
+
+	/*
+	 * Make sure our async settings are committed.  Some bootroms
+	 * (like the BF537) will reset some registers on us after it
+	 * has finished loading the LDR.  Or if we're booting over
+	 * JTAG, the initcode never got a chance to run.  Or if we
+	 * aren't booting from parallel flash, the initcode skipped
+	 * this step completely.
 	 */
-	else
-		bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
-#endif
+	program_async_controller(NULL);
 
 	/* Save RETX so we can pass it while booting Linux */
 	bfin_poweron_retx = bootflag;
diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c
index 61dc5ab0eb55aefa40a55cd7d240ddbc0a0201aa..917b7f9b91ce0fd8e1e83ed217d773969e70018d 100644
--- a/arch/blackfin/cpu/initcode.c
+++ b/arch/blackfin/cpu/initcode.c
@@ -4,7 +4,7 @@
  * cannot make any function calls as it may be executed all by itself by
  * the Blackfin's bootrom in LDR format.
  *
- * Copyright (c) 2004-2008 Analog Devices Inc.
+ * Copyright (c) 2004-2011 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -107,6 +107,8 @@ static inline void serial_putc(char c)
 		continue;
 }
 
+#include "initcode.h"
+
 __attribute__((always_inline)) static inline void
 program_nmi_handler(void)
 {
@@ -172,21 +174,6 @@ program_nmi_handler(void)
 # define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9) | CONFIG_CLKIN_HALF)
 #endif
 
-#ifndef CONFIG_EBIU_RSTCTL_VAL
-# define CONFIG_EBIU_RSTCTL_VAL 0 /* only MDDRENABLE is useful */
-#endif
-#if ((CONFIG_EBIU_RSTCTL_VAL & 0xFFFFFFC4) != 0)
-# error invalid EBIU_RSTCTL value: must not set reserved bits
-#endif
-
-#ifndef CONFIG_EBIU_MBSCTL_VAL
-# define CONFIG_EBIU_MBSCTL_VAL 0
-#endif
-
-#if defined(CONFIG_EBIU_DDRQUE_VAL) && ((CONFIG_EBIU_DDRQUE_VAL & 0xFFFF8000) != 0)
-# error invalid EBIU_DDRQUE value: must not set reserved bits
-#endif
-
 /* Make sure our voltage value is sane so we don't blow up! */
 #ifndef CONFIG_VR_CTL_VAL
 # define BFIN_CCLK ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_CCLK_DIV)
@@ -642,34 +629,6 @@ check_hibernation(ADI_BOOT_DATA *bs, u16 vr_ctl, bool put_into_srfs)
 	serial_putc('e');
 }
 
-__attribute__((always_inline)) static inline void
-program_async_controller(ADI_BOOT_DATA *bs)
-{
-	serial_putc('a');
-
-	/* Program the async banks controller. */
-	bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL);
-	bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL);
-	bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
-
-	serial_putc('b');
-
-	/* Not all parts have these additional MMRs. */
-#ifdef EBIU_MBSCTL
-	bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL);
-#endif
-#ifdef EBIU_MODE
-# ifdef CONFIG_EBIU_MODE_VAL
-	bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL);
-# endif
-# ifdef CONFIG_EBIU_FCTL_VAL
-	bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTL_VAL);
-# endif
-#endif
-
-	serial_putc('c');
-}
-
 BOOTROM_CALLED_FUNC_ATTR
 void initcode(ADI_BOOT_DATA *bs)
 {
diff --git a/arch/blackfin/cpu/initcode.h b/arch/blackfin/cpu/initcode.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0aad6de0f787428f9bad0b07f7c6353dc004b54
--- /dev/null
+++ b/arch/blackfin/cpu/initcode.h
@@ -0,0 +1,71 @@
+/*
+ * Code for early processor initialization
+ *
+ * Copyright (c) 2004-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_INITCODE_H__
+#define __BFIN_INITCODE_H__
+
+#include <asm/mach-common/bits/bootrom.h>
+
+#ifndef BFIN_IN_INITCODE
+# define serial_putc(c)
+#endif
+
+#ifndef CONFIG_EBIU_RSTCTL_VAL
+# define CONFIG_EBIU_RSTCTL_VAL 0 /* only MDDRENABLE is useful */
+#endif
+#if ((CONFIG_EBIU_RSTCTL_VAL & 0xFFFFFFC4) != 0)
+# error invalid EBIU_RSTCTL value: must not set reserved bits
+#endif
+
+#ifndef CONFIG_EBIU_MBSCTL_VAL
+# define CONFIG_EBIU_MBSCTL_VAL 0
+#endif
+
+#if defined(CONFIG_EBIU_DDRQUE_VAL) && ((CONFIG_EBIU_DDRQUE_VAL & 0xFFFF8000) != 0)
+# error invalid EBIU_DDRQUE value: must not set reserved bits
+#endif
+
+__attribute__((always_inline)) static inline void
+program_async_controller(ADI_BOOT_DATA *bs)
+{
+#ifdef BFIN_IN_INITCODE
+	/*
+	 * We really only need to setup the async banks early if we're
+	 * booting out of it.  Otherwise, do it later on in cpu_init.
+	 */
+	if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS &&
+	    CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_PARA)
+		return;
+#endif
+
+	serial_putc('a');
+
+	/* Program the async banks controller. */
+	bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL);
+	bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL);
+	bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
+
+	serial_putc('b');
+
+	/* Not all parts have these additional MMRs. */
+#ifdef EBIU_MBSCTL
+	bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL);
+#endif
+#ifdef EBIU_MODE
+# ifdef CONFIG_EBIU_MODE_VAL
+	bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL);
+# endif
+# ifdef CONFIG_EBIU_FCTL_VAL
+	bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTL_VAL);
+# endif
+#endif
+
+	serial_putc('c');
+}
+
+#endif