Patchwork [U-Boot,6/7] omap4/5: Add support for booting with CH.

login
register
mail settings
Submitter SRICHARAN R
Date Oct. 19, 2011, 12:47 p.m.
Message ID <1319028444-11748-7-git-send-email-r.sricharan@ti.com>
Download mbox | patch
Permalink /patch/120618/
State Superseded
Headers show

Comments

SRICHARAN R - Oct. 19, 2011, 12:47 p.m.
Configuration header(CH) is 512 byte header attached to an OMAP
    boot image that will help ROM code to initialize clocks, SDRAM
    etc and copy U-Boot directly into SDRAM. CH can help us in
    by-passing SPL and directly boot U-boot, hence it's an alternative
    for SPL. However, we intend to support both CH and SPL for OMAP4/5.

    Initialization done through CH is limited and is not equivalent
    to that done by SPL. So U-Boot has to distinguish between the
    two cases and handle them accordingly. This patch takes care
    of doing this.

Signed-off-by: sricharan <r.sricharan@ti.com>
---
  Note: There are a few checkpatch warnings introduced
  from the mux data file because of the comment lines
  exceeding 80 characters. But the code looks better
  readable this way.

 arch/arm/cpu/armv7/omap-common/clocks-common.c |   58 +++++++++++++++++++----
 arch/arm/cpu/armv7/omap-common/hwinit-common.c |   17 ++++++-
 arch/arm/cpu/armv7/omap-common/lowlevel_init.S |   27 +++++++++--
 arch/arm/cpu/armv7/omap-common/spl.c           |    8 +++-
 arch/arm/cpu/armv7/omap4/clocks.c              |   44 +++++++++++++-----
 arch/arm/cpu/armv7/omap5/clocks.c              |   40 ++++++++++++----
 arch/arm/include/asm/arch-omap4/clocks.h       |    1 +
 arch/arm/include/asm/arch-omap4/omap.h         |   16 +++++++
 arch/arm/include/asm/arch-omap4/sys_proto.h    |   25 +++++++---
 arch/arm/include/asm/arch-omap5/clocks.h       |    1 +
 arch/arm/include/asm/arch-omap5/omap.h         |   16 +++++++
 arch/arm/include/asm/arch-omap5/sys_proto.h    |   18 ++++---
 arch/arm/include/asm/omap_common.h             |    2 +-
 board/ti/omap5_evm/mux_data.h                  |   16 +++---
 board/ti/sdp4430/sdp4430_mux_data.h            |   17 ++++---
 15 files changed, 231 insertions(+), 75 deletions(-)

Patch

diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c
index e97677d..9e2f3d6 100644
--- a/arch/arm/cpu/armv7/omap-common/clocks-common.c
+++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c
@@ -115,17 +115,46 @@  static inline void wait_for_lock(u32 *const base)
 	}
 }
 
+inline u32 check_for_lock(u32 *const base)
+{
+	struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+	u32 lock = readl(&dpll_regs->cm_idlest_dpll) & ST_DPLL_CLK_MASK;
+
+	return lock;
+}
+
 static void do_setup_dpll(u32 *const base, const struct dpll_params *params,
-				u8 lock)
+				u8 lock, char *dpll)
 {
-	u32 temp;
+	u32 temp, M, N;
 	struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
 
+	temp = readl(&dpll_regs->cm_clksel_dpll);
+
+	if (check_for_lock(base)) {
+		/*
+		 * The Dpll has already been locked by rom code using CH.
+		 * Check if M,N are matching with Ideal nominal opp values.
+		 * If matches, skip the rest otherwise relock.
+		 */
+		M = (temp & CM_CLKSEL_DPLL_M_MASK) >> CM_CLKSEL_DPLL_M_SHIFT;
+		N = (temp & CM_CLKSEL_DPLL_N_MASK) >> CM_CLKSEL_DPLL_N_SHIFT;
+		if ((M != (params->m)) || (N != (params->n))) {
+			debug("\n %s Dpll locked, but not for ideal M = %d,"
+				"N = %d values, current values are M = %d,"
+				"N= %d" , dpll, params->m, params->n,
+				M, N);
+		} else {
+			/* Dpll locked with ideal values for nominal opps. */
+			debug("\n %s Dpll already locked with ideal"
+						"nominal opp values", dpll);
+			return;
+		}
+	}
+
 	bypass_dpll(base);
 
 	/* Set M & N */
-	temp = readl(&dpll_regs->cm_clksel_dpll);
-
 	temp &= ~CM_CLKSEL_DPLL_M_MASK;
 	temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK;
 
@@ -216,7 +245,8 @@  void configure_mpu_dpll(void)
 	}
 
 	params = get_mpu_dpll_params();
-	do_setup_dpll(&prcm->cm_clkmode_dpll_mpu, params, DPLL_LOCK);
+
+	do_setup_dpll(&prcm->cm_clkmode_dpll_mpu, params, DPLL_LOCK, "mpu");
 	debug("MPU DPLL locked\n");
 }
 
@@ -235,7 +265,8 @@  static void setup_dplls(void)
 	 * Core DPLL will be locked after setting up EMIF
 	 * using the FREQ_UPDATE method(freq_update_core())
 	 */
-	do_setup_dpll(&prcm->cm_clkmode_dpll_core, params, DPLL_NO_LOCK);
+	do_setup_dpll(&prcm->cm_clkmode_dpll_core, params, DPLL_NO_LOCK,
+								"core");
 	/* Set the ratios for CORE_CLK, L3_CLK, L4_CLK */
 	temp = (CLKSEL_CORE_X2_DIV_1 << CLKSEL_CORE_SHIFT) |
 	    (CLKSEL_L3_CORE_DIV_2 << CLKSEL_L3_SHIFT) |
@@ -246,13 +277,14 @@  static void setup_dplls(void)
 	/* lock PER dpll */
 	params = get_per_dpll_params();
 	do_setup_dpll(&prcm->cm_clkmode_dpll_per,
-			params, DPLL_LOCK);
+			params, DPLL_LOCK, "per");
 	debug("PER DPLL locked\n");
 
 	/* MPU dpll */
 	configure_mpu_dpll();
 }
 
+#ifdef CONFIG_UBOOT_CLOCKS_ENABLE_ALL
 static void setup_non_essential_dplls(void)
 {
 	u32 sys_clk_khz, abe_ref_clk;
@@ -267,7 +299,7 @@  static void setup_non_essential_dplls(void)
 		CM_BYPCLK_DPLL_IVA_CLKSEL_MASK, DPLL_IVA_CLKSEL_CORE_X2_DIV_2);
 
 	params = get_iva_dpll_params();
-	do_setup_dpll(&prcm->cm_clkmode_dpll_iva, params, DPLL_LOCK);
+	do_setup_dpll(&prcm->cm_clkmode_dpll_iva, params, DPLL_LOCK, "iva");
 
 	/*
 	 * USB:
@@ -287,7 +319,7 @@  static void setup_non_essential_dplls(void)
 			sd_div << CM_CLKSEL_DPLL_DPLL_SD_DIV_SHIFT);
 
 	/* Now setup the dpll with the regular function */
-	do_setup_dpll(&prcm->cm_clkmode_dpll_usb, params, DPLL_LOCK);
+	do_setup_dpll(&prcm->cm_clkmode_dpll_usb, params, DPLL_LOCK, "usb");
 
 	/* Configure ABE dpll */
 	params = get_abe_dpll_params();
@@ -315,8 +347,9 @@  static void setup_non_essential_dplls(void)
 			CM_ABE_PLL_REF_CLKSEL_CLKSEL_MASK,
 			abe_ref_clk << CM_ABE_PLL_REF_CLKSEL_CLKSEL_SHIFT);
 	/* Lock the dpll */
-	do_setup_dpll(&prcm->cm_clkmode_dpll_abe, params, DPLL_LOCK);
+	do_setup_dpll(&prcm->cm_clkmode_dpll_abe, params, DPLL_LOCK, "abe");
 }
+#endif
 
 void do_scale_tps62361(u32 reg, u32 volt_mv)
 {
@@ -561,10 +594,15 @@  void prcm_init(void)
 		enable_basic_clocks();
 		scale_vcores();
 		setup_dplls();
+#ifdef CONFIG_UBOOT_CLOCKS_ENABLE_ALL
 		setup_non_essential_dplls();
 		enable_non_essential_clocks();
+#endif
 		break;
 	default:
 		break;
 	}
+
+	if (OMAP_INIT_CONTEXT_SPL == omap_hw_init_context())
+		enable_basic_uboot_clocks();
 }
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index b370d31..97c0093 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -34,6 +34,14 @@ 
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/*
+ * This is used to verify if the configuration header
+ * was executed by rom code prior to control of transfer
+ * to the bootloader. SPL is responsible for saving and
+ * passing the boot_params pointer to the u-boot.
+ */
+struct omap_boot_parameters boot_params __attribute__ ((section(".data")));
+
 #ifdef CONFIG_SPL_BUILD
 /*
  * We use static variables because global data is not ready yet.
@@ -41,12 +49,11 @@  DECLARE_GLOBAL_DATA_PTR;
  * We would not typically need to save these parameters in regular
  * U-Boot. This is needed only in SPL at the moment.
  */
-u32 omap_bootdevice = BOOT_DEVICE_MMC1;
 u32 omap_bootmode = MMCSD_MODE_FAT;
 
-u32 omap_boot_device(void)
+u8 omap_boot_device(void)
 {
-	return omap_bootdevice;
+	return boot_params.omap_bootdevice;
 }
 
 u32 omap_boot_mode(void)
@@ -71,12 +78,16 @@  void set_mux_conf_regs(void)
 		set_muxconf_regs_essential();
 		break;
 	case OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL:
+#ifdef CONFIG_UBOOT_ENABLE_PADS_ALL
 		set_muxconf_regs_non_essential();
+#endif
 		break;
 	case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR:
 	case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH:
 		set_muxconf_regs_essential();
+#ifdef CONFIG_UBOOT_ENABLE_PADS_ALL
 		set_muxconf_regs_non_essential();
+#endif
 		break;
 	}
 }
diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
index 6873298..a2b83dc 100644
--- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
@@ -27,7 +27,7 @@ 
  */
 
 #include <asm/arch/omap.h>
-#ifdef CONFIG_SPL_BUILD
+
 .global save_boot_params
 save_boot_params:
 	/*
@@ -43,21 +43,38 @@  save_boot_params:
 	cmp	r2, r0
 	blt	1f
 
+	/*
+	 * store the boot params passed from rom code or saved
+	 * and passed by SPL
+	 */
+	ldr	r1, =boot_params
+	str	r0, [r1]
+#ifdef CONFIG_SPL_BUILD
 	/* Store the boot device in omap_boot_device */
-	ldr     r2, [r0, #BOOT_DEVICE_OFFSET]	@ r1 <- value of boot device
+	ldrb	r2, [r0, #BOOT_DEVICE_OFFSET]	@ r1 <- value of boot device
 	and	r2, #BOOT_DEVICE_MASK
-	ldr	r3, =omap_bootdevice
-	str     r2, [r3]			@ omap_boot_device <- r1
+	ldr	r3, =boot_params
+	strb	r2, [r3, #BOOT_DEVICE_OFFSET]	@ omap_boot_device <- r1
 
+	/* boot mode is passed only for devices that can raw/fat mode */
+	cmp	r2, #2
+	blt	2f
+	cmp	r2, #7
+	bgt	2f
 	/* Store the boot mode (raw/FAT) in omap_boot_mode */
 	ldr	r2, [r0, #DEV_DESC_PTR_OFFSET]	@ get the device descriptor ptr
 	ldr	r2, [r2, #DEV_DATA_PTR_OFFSET]	@ get the pDeviceData ptr
 	ldr	r2, [r2, #BOOT_MODE_OFFSET]	@ get the boot mode
 	ldr	r3, =omap_bootmode
 	str	r2, [r3]
+#endif
+2:
+	ldrb	r2, [r0, #CH_FLAGS_OFFSET]
+	ldr	r3, =boot_params
+	strb	r2, [r3, #CH_FLAGS_OFFSET]
 1:
 	bx	lr
-#endif
+
 
 .globl lowlevel_init
 lowlevel_init:
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c
index c76fea6..8158b82 100644
--- a/arch/arm/cpu/armv7/omap-common/spl.c
+++ b/arch/arm/cpu/armv7/omap-common/spl.c
@@ -92,12 +92,16 @@  void spl_parse_image_header(const struct image_header *header)
 
 static void jump_to_image_no_args(void)
 {
-	typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn));
+	typedef void (*image_entry_noargs_t)(u32 *)__attribute__ ((noreturn));
 	image_entry_noargs_t image_entry =
 			(image_entry_noargs_t) spl_image.entry_point;
 
 	debug("image entry point: 0x%X\n", spl_image.entry_point);
-	image_entry();
+	/* Pass the saved boot_params from rom code */
+#if defined(CONFIG_VIRTIO) || defined(CONFIG_ZEBU)
+	image_entry = 0x80100000;
+#endif
+	image_entry((u32 *)&boot_params);
 }
 
 void jump_to_image_no_args(void) __attribute__ ((noreturn));
diff --git a/arch/arm/cpu/armv7/omap4/clocks.c b/arch/arm/cpu/armv7/omap4/clocks.c
index abef438..8477a8a 100644
--- a/arch/arm/cpu/armv7/omap4/clocks.c
+++ b/arch/arm/cpu/armv7/omap4/clocks.c
@@ -333,30 +333,22 @@  void enable_basic_clocks(void)
 	};
 
 	u32 *const clk_modules_hw_auto_essential[] = {
+		&prcm->cm_memif_emif_1_clkctrl,
+		&prcm->cm_memif_emif_2_clkctrl,
+		&prcm->cm_l4cfg_l4_cfg_clkctrl,
 		&prcm->cm_wkup_gpio1_clkctrl,
 		&prcm->cm_l4per_gpio2_clkctrl,
 		&prcm->cm_l4per_gpio3_clkctrl,
 		&prcm->cm_l4per_gpio4_clkctrl,
 		&prcm->cm_l4per_gpio5_clkctrl,
 		&prcm->cm_l4per_gpio6_clkctrl,
-		&prcm->cm_memif_emif_1_clkctrl,
-		&prcm->cm_memif_emif_2_clkctrl,
-		&prcm->cm_l3init_hsusbotg_clkctrl,
-		&prcm->cm_l3init_usbphy_clkctrl,
-		&prcm->cm_l4cfg_l4_cfg_clkctrl,
 		0
 	};
 
 	u32 *const clk_modules_explicit_en_essential[] = {
-		&prcm->cm_l4per_gptimer2_clkctrl,
 		&prcm->cm_l3init_hsmmc1_clkctrl,
 		&prcm->cm_l3init_hsmmc2_clkctrl,
-		&prcm->cm_l4per_mcspi1_clkctrl,
-		&prcm->cm_wkup_gptimer1_clkctrl,
-		&prcm->cm_l4per_i2c1_clkctrl,
-		&prcm->cm_l4per_i2c2_clkctrl,
-		&prcm->cm_l4per_i2c3_clkctrl,
-		&prcm->cm_l4per_i2c4_clkctrl,
+		&prcm->cm_l4per_gptimer2_clkctrl,
 		&prcm->cm_wkup_wdtimer2_clkctrl,
 		&prcm->cm_l4per_uart3_clkctrl,
 		0
@@ -386,6 +378,33 @@  void enable_basic_clocks(void)
 			 1);
 }
 
+void enable_basic_uboot_clocks(void)
+{
+	u32 *const clk_domains_essential[] = {
+		0
+	};
+
+	u32 *const clk_modules_hw_auto_essential[] = {
+		&prcm->cm_l3init_hsusbotg_clkctrl,
+		&prcm->cm_l3init_usbphy_clkctrl,
+		0
+	};
+
+	u32 *const clk_modules_explicit_en_essential[] = {
+		&prcm->cm_l4per_mcspi1_clkctrl,
+		&prcm->cm_l4per_i2c1_clkctrl,
+		&prcm->cm_l4per_i2c2_clkctrl,
+		&prcm->cm_l4per_i2c3_clkctrl,
+		&prcm->cm_l4per_i2c4_clkctrl,
+		0
+	};
+
+	do_enable_clocks(clk_domains_essential,
+			 clk_modules_hw_auto_essential,
+			 clk_modules_explicit_en_essential,
+			 1);
+}
+
 /*
  * Enable non-essential clock domains, modules and
  * do some additional special settings needed
@@ -421,6 +440,7 @@  void enable_non_essential_clocks(void)
 	};
 
 	u32 *const clk_modules_explicit_en_non_essential[] = {
+		&prcm->cm_wkup_gptimer1_clkctrl,
 		&prcm->cm1_abe_aess_clkctrl,
 		&prcm->cm1_abe_pdm_clkctrl,
 		&prcm->cm1_abe_dmic_clkctrl,
diff --git a/arch/arm/cpu/armv7/omap5/clocks.c b/arch/arm/cpu/armv7/omap5/clocks.c
index 28d3bcd..57062aa 100644
--- a/arch/arm/cpu/armv7/omap5/clocks.c
+++ b/arch/arm/cpu/armv7/omap5/clocks.c
@@ -273,30 +273,25 @@  void enable_basic_clocks(void)
 	};
 
 	u32 *const clk_modules_hw_auto_essential[] = {
+		&prcm->cm_memif_emif_1_clkctrl,
+		&prcm->cm_memif_emif_2_clkctrl,
+		&prcm->cm_l4cfg_l4_cfg_clkctrl,
 		&prcm->cm_wkup_gpio1_clkctrl,
 		&prcm->cm_l4per_gpio2_clkctrl,
 		&prcm->cm_l4per_gpio3_clkctrl,
 		&prcm->cm_l4per_gpio4_clkctrl,
 		&prcm->cm_l4per_gpio5_clkctrl,
 		&prcm->cm_l4per_gpio6_clkctrl,
-		&prcm->cm_memif_emif_1_clkctrl,
-		&prcm->cm_memif_emif_2_clkctrl,
-		&prcm->cm_l4cfg_l4_cfg_clkctrl,
 		0
 	};
 
 	u32 *const clk_modules_explicit_en_essential[] = {
-		&prcm->cm_l4per_gptimer2_clkctrl,
 		&prcm->cm_l3init_hsmmc1_clkctrl,
 		&prcm->cm_l3init_hsmmc2_clkctrl,
-		&prcm->cm_l4per_mcspi1_clkctrl,
-		&prcm->cm_wkup_gptimer1_clkctrl,
-		&prcm->cm_l4per_i2c1_clkctrl,
-		&prcm->cm_l4per_i2c2_clkctrl,
-		&prcm->cm_l4per_i2c3_clkctrl,
-		&prcm->cm_l4per_i2c4_clkctrl,
+		&prcm->cm_l4per_gptimer2_clkctrl,
 		&prcm->cm_wkup_wdtimer2_clkctrl,
 		&prcm->cm_l4per_uart3_clkctrl,
+		&prcm->cm_l4per_i2c1_clkctrl,
 		0
 	};
 
@@ -320,6 +315,30 @@  void enable_basic_clocks(void)
 			 1);
 }
 
+void enable_basic_uboot_clocks(void)
+{
+	u32 *const clk_domains_essential[] = {
+		0
+	};
+
+	u32 *const clk_modules_hw_auto_essential[] = {
+		0
+	};
+
+	u32 *const clk_modules_explicit_en_essential[] = {
+		&prcm->cm_l4per_mcspi1_clkctrl,
+		&prcm->cm_l4per_i2c2_clkctrl,
+		&prcm->cm_l4per_i2c3_clkctrl,
+		&prcm->cm_l4per_i2c4_clkctrl,
+		0
+	};
+
+	do_enable_clocks(clk_domains_essential,
+			 clk_modules_hw_auto_essential,
+			 clk_modules_explicit_en_essential,
+			 1);
+}
+
 /*
  * Enable non-essential clock domains, modules and
  * do some additional special settings needed
@@ -355,6 +374,7 @@  void enable_non_essential_clocks(void)
 	};
 
 	u32 *const clk_modules_explicit_en_non_essential[] = {
+		&prcm->cm_wkup_gptimer1_clkctrl,
 		&prcm->cm1_abe_aess_clkctrl,
 		&prcm->cm1_abe_pdm_clkctrl,
 		&prcm->cm1_abe_dmic_clkctrl,
diff --git a/arch/arm/include/asm/arch-omap4/clocks.h b/arch/arm/include/asm/arch-omap4/clocks.h
index ba52574..c2a9b46 100644
--- a/arch/arm/include/asm/arch-omap4/clocks.h
+++ b/arch/arm/include/asm/arch-omap4/clocks.h
@@ -698,6 +698,7 @@  void setup_sri2c(void);
 void setup_post_dividers(u32 *const base, const struct dpll_params *params);
 u32 get_sys_clk_index(void);
 void enable_basic_clocks(void);
+void enable_basic_uboot_clocks(void);
 void enable_non_essential_clocks(void);
 void do_enable_clocks(u32 *const *clk_domains,
 		      u32 *const *clk_modules_hw_auto,
diff --git a/arch/arm/include/asm/arch-omap4/omap.h b/arch/arm/include/asm/arch-omap4/omap.h
index 0ade896..e994257 100644
--- a/arch/arm/include/asm/arch-omap4/omap.h
+++ b/arch/arm/include/asm/arch-omap4/omap.h
@@ -191,5 +191,21 @@  struct control_lpddr2io_regs {
 #define DEV_DESC_PTR_OFFSET	0x4
 #define DEV_DATA_PTR_OFFSET	0x18
 #define BOOT_MODE_OFFSET	0x8
+#define RESET_REASON_OFFSET	0x9
+#define CH_FLAGS_OFFSET		0xA
 
+#define CH_FLAGS_CHSETTINGS	(0x1 << 0)
+#define CH_FLAGS_CHRAM		(0x1 << 1)
+#define CH_FLAGS_CHFLASH	(0x1 << 2)
+#define CH_FLAGS_CHMMCSD	(0x1 << 3)
+
+#ifndef __ASSEMBLY__
+struct omap_boot_parameters {
+	char *boot_message;
+	unsigned int mem_boot_descriptor;
+	unsigned char omap_bootdevice;
+	unsigned char reset_reason;
+	unsigned char ch_flags;
+};
+#endif
 #endif
diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h
index a6ac79f..d80bfcb 100644
--- a/arch/arm/include/asm/arch-omap4/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap4/sys_proto.h
@@ -56,6 +56,13 @@  u32 omap_sdram_size(void);
 u32 cortex_rev(void);
 void init_omap_revision(void);
 void do_io_settings(void);
+/*
+ * This is used to verify if the configuration header
+ * was executed by Romcode prior to control of transfer
+ * to the bootloader. SPL is responsible for saving and
+ * passing this to the u-boot.
+ */
+extern struct omap_boot_parameters boot_params;
 
 static inline u32 running_from_sdram(void)
 {
@@ -68,15 +75,17 @@  static inline u32 running_from_sdram(void)
 static inline u8 uboot_loaded_by_spl(void)
 {
 	/*
-	 * Configuration Header is not supported yet, so u-boot init running
-	 * from SDRAM implies that it was loaded by SPL. When this situation
-	 * changes one of these approaches could be taken:
-	 * i.  Pass a magic from SPL to U-Boot and U-Boot save it at a known
-	 *     location.
-	 * ii. Check the OPP. CH can support only 50% OPP while SPL initializes
-	 *     the DPLLs at 100% OPP.
+	 * u-boot can be running from sdram either because of configuration
+	 * Header or by SPL. If because of CH, then the romcode sets the
+	 * CHSETTINGS executed bit to true in the boot parameter structure that
+	 * it passes to the bootloader.This parameter is stored in the ch_flags
+	 * variable by both SPL and u-boot.Check out for CHSETTINGS, which is a
+	 * mandatory section if CH is present.
 	 */
-	return running_from_sdram();
+	if ((boot_params.ch_flags) & (CH_FLAGS_CHSETTINGS))
+		return 0;
+	else
+		return running_from_sdram();
 }
 /*
  * The basic hardware init of OMAP(s_init()) can happen in 4
diff --git a/arch/arm/include/asm/arch-omap5/clocks.h b/arch/arm/include/asm/arch-omap5/clocks.h
index edcc9e9..fa99f65 100644
--- a/arch/arm/include/asm/arch-omap5/clocks.h
+++ b/arch/arm/include/asm/arch-omap5/clocks.h
@@ -708,6 +708,7 @@  void setup_post_dividers(u32 *const base, const struct dpll_params *params);
 u32 get_sys_clk_index(void);
 void enable_basic_clocks(void);
 void enable_non_essential_clocks(void);
+void enable_basic_uboot_clocks(void);
 void do_enable_clocks(u32 *const *clk_domains,
 		      u32 *const *clk_modules_hw_auto,
 		      u32 *const *clk_modules_explicit_en,
diff --git a/arch/arm/include/asm/arch-omap5/omap.h b/arch/arm/include/asm/arch-omap5/omap.h
index d272276..5447931 100644
--- a/arch/arm/include/asm/arch-omap5/omap.h
+++ b/arch/arm/include/asm/arch-omap5/omap.h
@@ -198,5 +198,21 @@  struct control_lpddr2io_regs {
 #define DEV_DESC_PTR_OFFSET	0x4
 #define DEV_DATA_PTR_OFFSET	0x18
 #define BOOT_MODE_OFFSET	0x8
+#define RESET_REASON_OFFSET     0x9
+#define CH_FLAGS_OFFSET         0xA
 
+#define CH_FLAGS_CHSETTINGS	(0x1 << 0)
+#define	CH_FLAGS_CHRAM		(0x1 << 1)
+#define CH_FLAGS_CHFLASH	(0x1 << 2)
+#define CH_FLAGS_CHMMCSD	(0x1 << 3)
+
+#ifndef __ASSEMBLY__
+struct omap_boot_parameters {
+	char *boot_message;
+	unsigned int mem_boot_descriptor;
+	unsigned char omap_bootdevice;
+	unsigned char reset_reason;
+	unsigned char ch_flags;
+};
+#endif /* __ASSEMBLY__ */
 #endif
diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h
index 3945924..47f1596 100644
--- a/arch/arm/include/asm/arch-omap5/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap5/sys_proto.h
@@ -76,15 +76,17 @@  static inline u32 running_from_sdram(void)
 static inline u8 uboot_loaded_by_spl(void)
 {
 	/*
-	 * Configuration Header is not supported yet, so u-boot init running
-	 * from SDRAM implies that it was loaded by SPL. When this situation
-	 * changes one of these approaches could be taken:
-	 * i.  Pass a magic from SPL to U-Boot and U-Boot save it at a known
-	 *     location.
-	 * ii. Check the OPP. CH can support only 50% OPP while SPL initializes
-	 *     the DPLLs at 100% OPP.
+	 * u-boot can be running from sdram either because of configuration
+	 * Header or by SPL. If because of CH, then the romcode sets the
+	 * CHSETTINGS executed bit to true in the boot parameter structure that
+	 * it passes to the bootloader.This parameter is stored in the ch_flags
+	 * variable by both SPL and u-boot.Check out for CHSETTINGS, which is a
+	 * mandatory section if CH is present.
 	 */
-	return running_from_sdram();
+	if ((boot_params.ch_flags) & (CH_FLAGS_CHSETTINGS))
+		return 0;
+	else
+		return running_from_sdram();
 }
 /*
  * The basic hardware init of OMAP(s_init()) can happen in 4
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index 5f39040..2d7dbfb 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -80,7 +80,7 @@  struct spl_image_info {
 
 extern struct spl_image_info spl_image;
 
-u32 omap_boot_device(void);
+u8 omap_boot_device(void);
 u32 omap_boot_mode(void);
 
 /* SPL common function s*/
diff --git a/board/ti/omap5_evm/mux_data.h b/board/ti/omap5_evm/mux_data.h
index f033451..18f4729 100644
--- a/board/ti/omap5_evm/mux_data.h
+++ b/board/ti/omap5_evm/mux_data.h
@@ -50,14 +50,6 @@  const struct pad_conf_entry core_padconf_array_essential[] = {
 {SDMMC1_DAT5, (PTU | IEN | OFF_EN | OFF_PD | OFF_IN | M0)}, /* sdmmc1_dat5 */
 {SDMMC1_DAT6, (PTU | IEN | OFF_EN | OFF_PD | OFF_IN | M0)}, /* sdmmc1_dat6 */
 {SDMMC1_DAT7, (PTU | IEN | OFF_EN | OFF_PD | OFF_IN | M0)}, /* sdmmc1_dat7 */
-{I2C1_SCL, (PTU | IEN | M0)},				/* i2c1_scl */
-{I2C1_SDA, (PTU | IEN | M0)},				/* i2c1_sda */
-{I2C2_SCL, (PTU | IEN | M0)},				/* i2c2_scl */
-{I2C2_SDA, (PTU | IEN | M0)},				/* i2c2_sda */
-{I2C3_SCL, (PTU | IEN | M0)},				/* i2c3_scl */
-{I2C3_SDA, (PTU | IEN | M0)},				/* i2c3_sda */
-{I2C4_SCL, (PTU | IEN | M0)},				/* i2c4_scl */
-{I2C4_SDA, (PTU | IEN | M0)},				/* i2c4_sda */
 {UART3_CTS_RCTX, (PTU | IEN | M0)},			/* uart3_tx */
 {UART3_RTS_SD, (M0)},					/* uart3_rts_sd */
 {UART3_RX_IRRX, (IEN | M0)},				/* uart3_rx */
@@ -245,6 +237,14 @@  const struct pad_conf_entry core_padconf_array_non_essential[] = {
 	{DPM_EMU17, (IEN | M5)},					/* dispc2_data2 */
 	{DPM_EMU18, (IEN | M5)},					/* dispc2_data1 */
 	{DPM_EMU19, (IEN | M5)},					/* dispc2_data0 */
+	{I2C1_SCL, (PTU | IEN | M0)},				/* i2c1_scl */
+	{I2C1_SDA, (PTU | IEN | M0)},				/* i2c1_sda */
+	{I2C2_SCL, (PTU | IEN | M0)},				/* i2c2_scl */
+	{I2C2_SDA, (PTU | IEN | M0)},				/* i2c2_sda */
+	{I2C3_SCL, (PTU | IEN | M0)},				/* i2c3_scl */
+	{I2C3_SDA, (PTU | IEN | M0)},				/* i2c3_sda */
+	{I2C4_SCL, (PTU | IEN | M0)},				/* i2c4_scl */
+	{I2C4_SDA, (PTU | IEN | M0)}				/* i2c4_sda */
 };
 
 const struct pad_conf_entry wkup_padconf_array_non_essential[] = {
diff --git a/board/ti/sdp4430/sdp4430_mux_data.h b/board/ti/sdp4430/sdp4430_mux_data.h
index 7010b0b..5b5b0c4 100644
--- a/board/ti/sdp4430/sdp4430_mux_data.h
+++ b/board/ti/sdp4430/sdp4430_mux_data.h
@@ -50,14 +50,6 @@  const struct pad_conf_entry core_padconf_array_essential[] = {
 {SDMMC1_DAT5, (PTU | IEN | OFF_EN | OFF_PD | OFF_IN | M0)}, /* sdmmc1_dat5 */
 {SDMMC1_DAT6, (PTU | IEN | OFF_EN | OFF_PD | OFF_IN | M0)}, /* sdmmc1_dat6 */
 {SDMMC1_DAT7, (PTU | IEN | OFF_EN | OFF_PD | OFF_IN | M0)}, /* sdmmc1_dat7 */
-{I2C1_SCL, (PTU | IEN | M0)},				/* i2c1_scl */
-{I2C1_SDA, (PTU | IEN | M0)},				/* i2c1_sda */
-{I2C2_SCL, (PTU | IEN | M0)},				/* i2c2_scl */
-{I2C2_SDA, (PTU | IEN | M0)},				/* i2c2_sda */
-{I2C3_SCL, (PTU | IEN | M0)},				/* i2c3_scl */
-{I2C3_SDA, (PTU | IEN | M0)},				/* i2c3_sda */
-{I2C4_SCL, (PTU | IEN | M0)},				/* i2c4_scl */
-{I2C4_SDA, (PTU | IEN | M0)},				/* i2c4_sda */
 {UART3_CTS_RCTX, (PTU | IEN | M0)},			/* uart3_tx */
 {UART3_RTS_SD, (M0)},					/* uart3_rts_sd */
 {UART3_RX_IRRX, (IEN | M0)},				/* uart3_rx */
@@ -245,6 +237,15 @@  const struct pad_conf_entry core_padconf_array_non_essential[] = {
 	{DPM_EMU17, (IEN | M5)},					/* dispc2_data2 */
 	{DPM_EMU18, (IEN | M5)},					/* dispc2_data1 */
 	{DPM_EMU19, (IEN | M5)},					/* dispc2_data0 */
+	{I2C1_SCL, (PTU | IEN | M0)},					/* i2c1_scl */
+	{I2C1_SDA, (PTU | IEN | M0)},					/* i2c1_sda */
+	{I2C2_SCL, (PTU | IEN | M0)},					/* i2c2_scl */
+	{I2C2_SDA, (PTU | IEN | M0)},					/* i2c2_sda */
+	{I2C3_SCL, (PTU | IEN | M0)},					/* i2c3_scl */
+	{I2C3_SDA, (PTU | IEN | M0)},					/* i2c3_sda */
+	{I2C4_SCL, (PTU | IEN | M0)},					/* i2c4_scl */
+	{I2C4_SDA, (PTU | IEN | M0)}					/* i2c4_sda */
+
 };
 
 const struct pad_conf_entry wkup_padconf_array_non_essential[] = {