arm: Introduce arch/arm/mach-omap2 for OMAP2 derivative platforms

This moves what was in arch/arm/cpu/armv7/omap-common in to
arch/arm/mach-omap2 and moves
arch/arm/cpu/armv7/{am33xx,omap3,omap4,omap5} in to arch/arm/mach-omap2
as subdirectories.  All refernces to the former locations are updated to
the current locations.  For the logic to decide what our outputs are,
consolidate the tests into a single config.mk rather than including 4.

Signed-off-by: Tom Rini <trini@konsulko.com>
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
new file mode 100644
index 0000000..24bc485
--- /dev/null
+++ b/arch/arm/mach-omap2/Kconfig
@@ -0,0 +1,17 @@
+config TI_SECURE_DEVICE
+	bool "HS Device Type Support"
+	depends on OMAP54XX || AM43XX || AM33XX
+	help
+	  If a high secure (HS) device type is being used, this config
+	  must be set. This option impacts various aspects of the
+	  build system (to create signed boot images that can be
+	  authenticated) and the code. See the doc/README.ti-secure
+	  file for further details.
+
+source "arch/arm/mach-omap2/omap3/Kconfig"
+
+source "arch/arm/mach-omap2/omap4/Kconfig"
+
+source "arch/arm/mach-omap2/omap5/Kconfig"
+
+source "arch/arm/mach-omap2/am33xx/Kconfig"
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
new file mode 100644
index 0000000..e814eb0
--- /dev/null
+++ b/arch/arm/mach-omap2/Makefile
@@ -0,0 +1,45 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(if $(filter am33xx,$(SOC)),y) += am33xx/
+obj-$(CONFIG_OMAP34XX) += omap3/
+obj-$(CONFIG_OMAP44XX) += omap4/
+obj-$(CONFIG_OMAP54XX) += omap5/
+
+obj-y	+= reset.o
+ifeq ($(CONFIG_TIMER),)
+obj-y	+= timer.o
+else
+ifdef CONFIG_SPL_BUILD
+obj-y	+= timer.o
+endif
+endif
+obj-y	+= utils.o
+
+ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+obj-y	+= hwinit-common.o
+obj-y	+= clocks-common.o
+obj-y	+= emif-common.o
+obj-y	+= vc.o
+obj-y	+= abb.o
+endif
+
+ifneq ($(CONFIG_OMAP54XX),)
+obj-y	+= pipe3-phy.o
+obj-$(CONFIG_SCSI_AHCI_PLAT) += sata.o
+endif
+
+ifeq ($(CONFIG_SYS_DCACHE_OFF),)
+obj-y	+= omap-cache.o
+endif
+
+obj-y	+= boot-common.o
+obj-y	+= lowlevel_init.o
+
+obj-y	+= mem-common.o
+
+obj-$(CONFIG_TI_SECURE_DEVICE) += sec-common.o
diff --git a/arch/arm/mach-omap2/abb.c b/arch/arm/mach-omap2/abb.c
new file mode 100644
index 0000000..a0add66
--- /dev/null
+++ b/arch/arm/mach-omap2/abb.c
@@ -0,0 +1,121 @@
+/*
+ * Adaptive Body Bias programming sequence for OMAP family
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * Andrii Tseglytskyi <andrii.tseglytskyi@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/omap_common.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+
+__weak s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb)
+{
+	return -1;
+}
+
+static void abb_setup_timings(u32 setup)
+{
+	u32 sys_rate, sr2_cnt, clk_cycles;
+
+	/*
+	 * SR2_WTCNT_VALUE is the settling time for the ABB ldo after a
+	 * transition and must be programmed with the correct time at boot.
+	 * The value programmed into the register is the number of SYS_CLK
+	 * clock cycles that match a given wall time profiled for the ldo.
+	 * This value depends on:
+	 * settling time of ldo in micro-seconds (varies per OMAP family),
+	 * of clock cycles per SYS_CLK period (varies per OMAP family),
+	 * the SYS_CLK frequency in MHz (varies per board)
+	 * The formula is:
+	 *
+	 *		       ldo settling time (in micro-seconds)
+	 * SR2_WTCNT_VALUE = ------------------------------------------
+	 *		    (# system clock cycles) * (sys_clk period)
+	 *
+	 * Put another way:
+	 *
+	 * SR2_WTCNT_VALUE = settling time / (# SYS_CLK cycles / SYS_CLK rate))
+	 *
+	 * To avoid dividing by zero multiply both "# clock cycles" and
+	 * "settling time" by 10 such that the final result is the one we want.
+	 */
+
+	/* calculate SR2_WTCNT_VALUE */
+	sys_rate = DIV_ROUND_CLOSEST(V_OSCK, 1000000);
+	clk_cycles = DIV_ROUND_CLOSEST(OMAP_ABB_CLOCK_CYCLES * 10, sys_rate);
+	sr2_cnt = DIV_ROUND_CLOSEST(OMAP_ABB_SETTLING_TIME * 10, clk_cycles);
+
+	setbits_le32(setup,
+		     sr2_cnt << (ffs(OMAP_ABB_SETUP_SR2_WTCNT_VALUE_MASK) - 1));
+}
+
+void abb_setup(u32 fuse, u32 ldovbb, u32 setup, u32 control,
+	       u32 txdone, u32 txdone_mask, u32 opp)
+{
+	u32 abb_type_mask, opp_sel_mask;
+
+	/* sanity check */
+	if (!setup || !control || !txdone)
+		return;
+
+	/* setup ABB only in case of Fast or Slow OPP */
+	switch (opp) {
+	case OMAP_ABB_FAST_OPP:
+		abb_type_mask = OMAP_ABB_SETUP_ACTIVE_FBB_SEL_MASK;
+		opp_sel_mask = OMAP_ABB_CONTROL_FAST_OPP_SEL_MASK;
+		break;
+	case OMAP_ABB_SLOW_OPP:
+		abb_type_mask = OMAP_ABB_SETUP_ACTIVE_RBB_SEL_MASK;
+		opp_sel_mask = OMAP_ABB_CONTROL_SLOW_OPP_SEL_MASK;
+		break;
+	default:
+	       return;
+	}
+
+	/*
+	 * For some OMAP silicons additional setup for LDOVBB register is
+	 * required. This is determined by data retrieved from corresponding
+	 * OPP EFUSE register. Data, which is retrieved from EFUSE - is
+	 * ABB enable/disable flag and VSET value, which must be copied
+	 * to LDOVBB register. If function call fails - return quietly,
+	 * it means no ABB is required for such silicon.
+	 *
+	 * For silicons, which don't require LDOVBB setup "fuse" and
+	 * "ldovbb" offsets are not defined. ABB will be initialized in
+	 * the common way for them.
+	 */
+	if (fuse && ldovbb) {
+		if (abb_setup_ldovbb(fuse, ldovbb))
+			return;
+	}
+
+	/* clear ABB registers */
+	writel(0, setup);
+	writel(0, control);
+
+	/* configure timings, based on oscillator value */
+	abb_setup_timings(setup);
+
+	/* clear pending interrupts before setup */
+	setbits_le32(txdone, txdone_mask);
+
+	/* select ABB type */
+	setbits_le32(setup, abb_type_mask | OMAP_ABB_SETUP_SR2EN_MASK);
+
+	/* initiate ABB ldo change */
+	setbits_le32(control, opp_sel_mask | OMAP_ABB_CONTROL_OPP_CHANGE_MASK);
+
+	/* wait until transition complete */
+	if (!wait_on_value(txdone_mask, txdone_mask, (void *)txdone, LDELAY))
+		puts("Error: ABB txdone is not set\n");
+
+	/* clear ABB tranxdone */
+	setbits_le32(txdone, txdone_mask);
+}
diff --git a/arch/arm/mach-omap2/am33xx/Kconfig b/arch/arm/mach-omap2/am33xx/Kconfig
new file mode 100644
index 0000000..8fd32c2
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/Kconfig
@@ -0,0 +1,137 @@
+if AM33XX
+
+choice
+	prompt "AM33xx board select"
+	optional
+
+config TARGET_AM335X_EVM
+	bool "Support am335x_evm"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+	select TI_I2C_BOARD_DETECT
+	help
+	  This option specifies support for the AM335x
+	  GP and HS EVM development platforms. The AM335x
+	  GP EVM is a standalone test, development, and
+	  evaluation module system that enables developers
+	  to write software and develop hardware around
+	  an AM335x processor subsystem.
+
+config TARGET_AM335X_BALTOS
+	bool "Support am335x_baltos"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_AM335X_IGEP0033
+	bool "Support am335x_igep0033"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_AM335X_SHC
+	bool "Support am335x based shc board from bosch"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_AM335X_SL50
+	bool "Support am335x_sl50"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_BAV335X
+	bool "Support bav335x"
+	select DM
+	select DM_SERIAL
+	help
+	  The BAV335x OEM Network Processor integrates all the functions of an
+	  embedded network computer in a small, easy to use SODIMM module which
+	  incorporates the popular Texas Instruments Sitara 32bit ARM Coretex-A8
+	  processor, with fast DDR3 512MB SDRAM, 4GB of embedded MMC and a Gigabit
+	  ethernet with simple connection to external connectors.
+
+	  For more information, visit: http://birdland.com/oem
+
+config TARGET_CM_T335
+	bool "Support cm_t335"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_PCM051
+	bool "Support pcm051"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_PENGWYN
+	bool "Support pengwyn"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_PEPPER
+	bool "Support pepper"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+endchoice
+
+endif
+
+if AM43XX
+
+config SPL_EXT_SUPPORT
+	default y
+
+config SPL_GPIO_SUPPORT
+	default y
+
+config SPL_I2C_SUPPORT
+	default y
+
+config TARGET_AM43XX_EVM
+	bool "Support am43xx_evm"
+	select TI_I2C_BOARD_DETECT
+	help
+	  This option specifies support for the AM43xx
+	  GP and HS EVM development platforms.The AM437x
+	  GP EVM is a standalone test, development, and
+	  evaluation module system that enables developers
+	  to write software and develop hardware around
+	  an AM43xx processor subsystem.
+endif
+
+if AM43XX || AM33XX
+config ISW_ENTRY_ADDR
+	hex "Address in memory or XIP flash of bootloader entry point"
+	help
+	  After any reset, the boot ROM on the AM43XX SOC
+	  searches the boot media for a valid boot image.
+	  For non-XIP devices, the ROM then copies the
+	  image into internal memory.
+	  For all boot modes, after the ROM processes the
+	  boot image it eventually computes the entry
+	  point address depending on the device type
+	  (secure/non-secure), boot media (xip/non-xip) and
+	  image headers.
+	default 0x402F4000
+
+config PUB_ROM_DATA_SIZE
+	hex "Size in bytes of the L3 SRAM reserved by ROM to store data"
+	help
+	  During the device boot, the public ROM uses the top of
+	  the public L3 OCMC RAM to store r/w data like stack,
+	  heap, globals etc. When the ROM is copying the boot
+	  image from the boot media into memory, the image must
+	  not spill over into this area. This value can be used
+	  during compile time to determine the maximum size of a
+	  boot image. Once the ROM transfers control to the boot
+	  image, this area is no longer used, and can be reclaimed
+	  for run time use by the boot image.
+	default 0x8400
+endif
diff --git a/arch/arm/mach-omap2/am33xx/Makefile b/arch/arm/mach-omap2/am33xx/Makefile
new file mode 100644
index 0000000..6fda482
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/Makefile
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_AM33XX)	+= clock_am33xx.o
+obj-$(CONFIG_TI814X)	+= clock_ti814x.o
+obj-$(CONFIG_AM43XX)	+= clock_am43xx.o
+
+ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX),)
+obj-y	+= clock.o
+endif
+
+obj-$(CONFIG_TI816X)	+= clock_ti816x.o
+obj-y	+= sys_info.o
+obj-y	+= ddr.o
+obj-y	+= emif4.o
+obj-y	+= board.o
+obj-y	+= mux.o
+
+obj-$(CONFIG_CLOCK_SYNTHESIZER)	+= clk_synthesizer.o
diff --git a/arch/arm/mach-omap2/am33xx/board.c b/arch/arm/mach-omap2/am33xx/board.c
new file mode 100644
index 0000000..5ebeac0
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/board.c
@@ -0,0 +1,317 @@
+/*
+ * board.c
+ *
+ * Common board functions for AM33XX based boards
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <ns16550.h>
+#include <spl.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/emif.h>
+#include <asm/gpio.h>
+#include <i2c.h>
+#include <miiphy.h>
+#include <cpsw.h>
+#include <linux/errno.h>
+#include <linux/compiler.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/musb.h>
+#include <asm/omap_musb.h>
+#include <asm/davinci_rtc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if !CONFIG_IS_ENABLED(OF_CONTROL)
+static const struct ns16550_platdata am33xx_serial[] = {
+	{ .base = CONFIG_SYS_NS16550_COM1, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
+# ifdef CONFIG_SYS_NS16550_COM2
+	{ .base = CONFIG_SYS_NS16550_COM2, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
+#  ifdef CONFIG_SYS_NS16550_COM3
+	{ .base = CONFIG_SYS_NS16550_COM3, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
+	{ .base = CONFIG_SYS_NS16550_COM4, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
+	{ .base = CONFIG_SYS_NS16550_COM5, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
+	{ .base = CONFIG_SYS_NS16550_COM6, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
+#  endif
+# endif
+};
+
+U_BOOT_DEVICES(am33xx_uarts) = {
+	{ "ns16550_serial", &am33xx_serial[0] },
+#  ifdef CONFIG_SYS_NS16550_COM2
+	{ "ns16550_serial", &am33xx_serial[1] },
+#   ifdef CONFIG_SYS_NS16550_COM3
+	{ "ns16550_serial", &am33xx_serial[2] },
+	{ "ns16550_serial", &am33xx_serial[3] },
+	{ "ns16550_serial", &am33xx_serial[4] },
+	{ "ns16550_serial", &am33xx_serial[5] },
+#   endif
+#  endif
+};
+
+#ifdef CONFIG_DM_GPIO
+static const struct omap_gpio_platdata am33xx_gpio[] = {
+	{ 0, AM33XX_GPIO0_BASE },
+	{ 1, AM33XX_GPIO1_BASE },
+	{ 2, AM33XX_GPIO2_BASE },
+	{ 3, AM33XX_GPIO3_BASE },
+#ifdef CONFIG_AM43XX
+	{ 4, AM33XX_GPIO4_BASE },
+	{ 5, AM33XX_GPIO5_BASE },
+#endif
+};
+
+U_BOOT_DEVICES(am33xx_gpios) = {
+	{ "gpio_omap", &am33xx_gpio[0] },
+	{ "gpio_omap", &am33xx_gpio[1] },
+	{ "gpio_omap", &am33xx_gpio[2] },
+	{ "gpio_omap", &am33xx_gpio[3] },
+#ifdef CONFIG_AM43XX
+	{ "gpio_omap", &am33xx_gpio[4] },
+	{ "gpio_omap", &am33xx_gpio[5] },
+#endif
+};
+#endif
+#endif
+
+#ifndef CONFIG_DM_GPIO
+static const struct gpio_bank gpio_bank_am33xx[] = {
+	{ (void *)AM33XX_GPIO0_BASE },
+	{ (void *)AM33XX_GPIO1_BASE },
+	{ (void *)AM33XX_GPIO2_BASE },
+	{ (void *)AM33XX_GPIO3_BASE },
+#ifdef CONFIG_AM43XX
+	{ (void *)AM33XX_GPIO4_BASE },
+	{ (void *)AM33XX_GPIO5_BASE },
+#endif
+};
+
+const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
+#endif
+
+#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
+int cpu_mmc_init(bd_t *bis)
+{
+	int ret;
+
+	ret = omap_mmc_init(0, 0, 0, -1, -1);
+	if (ret)
+		return ret;
+
+	return omap_mmc_init(1, 0, 0, -1, -1);
+}
+#endif
+
+/* AM33XX has two MUSB controllers which can be host or gadget */
+#if (defined(CONFIG_USB_MUSB_GADGET) || defined(CONFIG_USB_MUSB_HOST)) && \
+	(defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1))
+static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+
+/* USB 2.0 PHY Control */
+#define CM_PHY_PWRDN			(1 << 0)
+#define CM_PHY_OTG_PWRDN		(1 << 1)
+#define OTGVDET_EN			(1 << 19)
+#define OTGSESSENDEN			(1 << 20)
+
+static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr)
+{
+	if (on) {
+		clrsetbits_le32(reg_addr, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN,
+				OTGVDET_EN | OTGSESSENDEN);
+	} else {
+		clrsetbits_le32(reg_addr, 0, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN);
+	}
+}
+
+static struct musb_hdrc_config musb_config = {
+	.multipoint     = 1,
+	.dyn_fifo       = 1,
+	.num_eps        = 16,
+	.ram_bits       = 12,
+};
+
+#ifdef CONFIG_AM335X_USB0
+static void am33xx_otg0_set_phy_power(u8 on)
+{
+	am33xx_usb_set_phy_power(on, &cdev->usb_ctrl0);
+}
+
+struct omap_musb_board_data otg0_board_data = {
+	.set_phy_power = am33xx_otg0_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data otg0_plat = {
+	.mode           = CONFIG_AM335X_USB0_MODE,
+	.config         = &musb_config,
+	.power          = 50,
+	.platform_ops	= &musb_dsps_ops,
+	.board_data	= &otg0_board_data,
+};
+#endif
+
+#ifdef CONFIG_AM335X_USB1
+static void am33xx_otg1_set_phy_power(u8 on)
+{
+	am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1);
+}
+
+struct omap_musb_board_data otg1_board_data = {
+	.set_phy_power = am33xx_otg1_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data otg1_plat = {
+	.mode           = CONFIG_AM335X_USB1_MODE,
+	.config         = &musb_config,
+	.power          = 50,
+	.platform_ops	= &musb_dsps_ops,
+	.board_data	= &otg1_board_data,
+};
+#endif
+#endif
+
+int arch_misc_init(void)
+{
+#ifdef CONFIG_AM335X_USB0
+	musb_register(&otg0_plat, &otg0_board_data,
+		(void *)USB0_OTG_BASE);
+#endif
+#ifdef CONFIG_AM335X_USB1
+	musb_register(&otg1_plat, &otg1_board_data,
+		(void *)USB1_OTG_BASE);
+#endif
+	return 0;
+}
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+/*
+ * In the case of non-SPL based booting we'll want to call these
+ * functions a tiny bit later as it will require gd to be set and cleared
+ * and that's not true in s_init in this case so we cannot do it there.
+ */
+int board_early_init_f(void)
+{
+	prcm_init();
+	set_mux_conf_regs();
+
+	return 0;
+}
+
+/*
+ * This function is the place to do per-board things such as ramp up the
+ * MPU clock frequency.
+ */
+__weak void am33xx_spl_board_init(void)
+{
+	do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);
+	do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
+}
+
+#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
+static void rtc32k_enable(void)
+{
+	struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
+
+	/*
+	 * Unlock the RTC's registers.  For more details please see the
+	 * RTC_SS section of the TRM.  In order to unlock we need to
+	 * write these specific values (keys) in this order.
+	 */
+	writel(RTC_KICK0R_WE, &rtc->kick0r);
+	writel(RTC_KICK1R_WE, &rtc->kick1r);
+
+	/* Enable the RTC 32K OSC by setting bits 3 and 6. */
+	writel((1 << 3) | (1 << 6), &rtc->osc);
+}
+#endif
+
+static void uart_soft_reset(void)
+{
+	struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
+	u32 regval;
+
+	regval = readl(&uart_base->uartsyscfg);
+	regval |= UART_RESET;
+	writel(regval, &uart_base->uartsyscfg);
+	while ((readl(&uart_base->uartsyssts) &
+		UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK)
+		;
+
+	/* Disable smart idle */
+	regval = readl(&uart_base->uartsyscfg);
+	regval |= UART_SMART_IDLE_EN;
+	writel(regval, &uart_base->uartsyscfg);
+}
+
+static void watchdog_disable(void)
+{
+	struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+
+	writel(0xAAAA, &wdtimer->wdtwspr);
+	while (readl(&wdtimer->wdtwwps) != 0x0)
+		;
+	writel(0x5555, &wdtimer->wdtwspr);
+	while (readl(&wdtimer->wdtwwps) != 0x0)
+		;
+}
+
+void s_init(void)
+{
+}
+
+void early_system_init(void)
+{
+	/*
+	 * The ROM will only have set up sufficient pinmux to allow for the
+	 * first 4KiB NOR to be read, we must finish doing what we know of
+	 * the NOR mux in this space in order to continue.
+	 */
+#ifdef CONFIG_NOR_BOOT
+	enable_norboot_pin_mux();
+#endif
+	watchdog_disable();
+	set_uart_mux_conf();
+	setup_early_clocks();
+	uart_soft_reset();
+#ifdef CONFIG_TI_I2C_BOARD_DETECT
+	do_board_detect();
+#endif
+#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
+	/* Enable RTC32K clock */
+	rtc32k_enable();
+#endif
+}
+
+#ifdef CONFIG_SPL_BUILD
+void board_init_f(ulong dummy)
+{
+	early_system_init();
+	board_early_init_f();
+	sdram_init();
+}
+#endif
+
+#endif
+
+int arch_cpu_init_dm(void)
+{
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+	early_system_init();
+#endif
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/am33xx/clk_synthesizer.c b/arch/arm/mach-omap2/am33xx/clk_synthesizer.c
new file mode 100644
index 0000000..316e677
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/clk_synthesizer.c
@@ -0,0 +1,104 @@
+/*
+ * clk-synthesizer.c
+ *
+ * Clock synthesizer apis
+ *
+ * Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+
+#include <common.h>
+#include <asm/arch/clk_synthesizer.h>
+#include <i2c.h>
+
+/**
+ * clk_synthesizer_reg_read - Read register from synthesizer.
+ * @addr:	addr within the i2c device
+ * buf:		Buffer to which value is to be read.
+ *
+ * For reading the register from this clock synthesizer, a command needs to
+ * be send along with enabling byte read more, and then read can happen.
+ * Returns 0 on success
+ */
+static int clk_synthesizer_reg_read(int addr, uint8_t *buf)
+{
+	int rc;
+
+	/* Enable Bye read */
+	addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
+
+	/* Send the command byte */
+	rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
+	if (rc)
+		printf("Failed to send command to clock synthesizer\n");
+
+	/* Read the Data */
+	return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
+}
+
+/**
+ * clk_synthesizer_reg_write - Write a value to register in synthesizer.
+ * @addr:	addr within the i2c device
+ * val:		Value to be written in the addr.
+ *
+ * Enable the byte read mode in the address and start the i2c transfer.
+ * Returns 0 on success
+ */
+static int clk_synthesizer_reg_write(int addr, uint8_t val)
+{
+	uint8_t cmd[2];
+	int rc = 0;
+
+	/* Enable byte write */
+	cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
+	cmd[1] = val;
+
+	rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
+	if (rc)
+		printf("Clock synthesizer reg write failed at addr = 0x%x\n",
+		       addr);
+	return rc;
+}
+
+/**
+ * setup_clock_syntherizer - Program the clock synthesizer to get the desired
+ *				frequency.
+ * @data: Data containing the desired output
+ *
+ * This is a PLL-based high performance synthesizer which gives 3 outputs
+ * as per the PLL_DIV and load capacitor programmed.
+ */
+int setup_clock_synthesizer(struct clk_synth *data)
+{
+	int rc;
+	uint8_t val;
+
+	rc =  i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
+	if (rc) {
+		printf("i2c probe failed at address 0x%x\n",
+		       CLK_SYNTHESIZER_I2C_ADDR);
+		return rc;
+	}
+
+	rc = clk_synthesizer_reg_read(CLK_SYNTHESIZER_ID_REG, &val);
+	if (val != data->id)
+		return rc;
+
+	/* Crystal Load capacitor selection */
+	rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_XCSEL, data->capacitor);
+	if (rc)
+		return rc;
+	rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_MUX_REG, data->mux);
+	if (rc)
+		return rc;
+	rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV2_REG, data->pdiv2);
+	if (rc)
+		return rc;
+	rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV3_REG, data->pdiv3);
+	if (rc)
+		return rc;
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/am33xx/clock.c b/arch/arm/mach-omap2/am33xx/clock.c
new file mode 100644
index 0000000..3d17698
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/clock.c
@@ -0,0 +1,246 @@
+/*
+ * clock.c
+ *
+ * Clock initialization for AM33XX boards.
+ * Derived from OMAP4 boards
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+
+static void setup_post_dividers(const struct dpll_regs *dpll_regs,
+			 const struct dpll_params *params)
+{
+	/* Setup post-dividers */
+	if (params->m2 >= 0)
+		writel(params->m2, dpll_regs->cm_div_m2_dpll);
+	if (params->m3 >= 0)
+		writel(params->m3, dpll_regs->cm_div_m3_dpll);
+	if (params->m4 >= 0)
+		writel(params->m4, dpll_regs->cm_div_m4_dpll);
+	if (params->m5 >= 0)
+		writel(params->m5, dpll_regs->cm_div_m5_dpll);
+	if (params->m6 >= 0)
+		writel(params->m6, dpll_regs->cm_div_m6_dpll);
+}
+
+static inline void do_lock_dpll(const struct dpll_regs *dpll_regs)
+{
+	clrsetbits_le32(dpll_regs->cm_clkmode_dpll,
+			CM_CLKMODE_DPLL_DPLL_EN_MASK,
+			DPLL_EN_LOCK << CM_CLKMODE_DPLL_EN_SHIFT);
+}
+
+static inline void wait_for_lock(const struct dpll_regs *dpll_regs)
+{
+	if (!wait_on_value(ST_DPLL_CLK_MASK, ST_DPLL_CLK_MASK,
+			   (void *)dpll_regs->cm_idlest_dpll, LDELAY)) {
+		printf("DPLL locking failed for 0x%x\n",
+		       dpll_regs->cm_clkmode_dpll);
+		hang();
+	}
+}
+
+static inline void do_bypass_dpll(const struct dpll_regs *dpll_regs)
+{
+	clrsetbits_le32(dpll_regs->cm_clkmode_dpll,
+			CM_CLKMODE_DPLL_DPLL_EN_MASK,
+			DPLL_EN_MN_BYPASS << CM_CLKMODE_DPLL_EN_SHIFT);
+}
+
+static inline void wait_for_bypass(const struct dpll_regs *dpll_regs)
+{
+	if (!wait_on_value(ST_DPLL_CLK_MASK, 0,
+			   (void *)dpll_regs->cm_idlest_dpll, LDELAY)) {
+		printf("Bypassing DPLL failed 0x%x\n",
+		       dpll_regs->cm_clkmode_dpll);
+	}
+}
+
+static void bypass_dpll(const struct dpll_regs *dpll_regs)
+{
+	do_bypass_dpll(dpll_regs);
+	wait_for_bypass(dpll_regs);
+}
+
+void do_setup_dpll(const struct dpll_regs *dpll_regs,
+		   const struct dpll_params *params)
+{
+	u32 temp;
+
+	if (!params)
+		return;
+
+	temp = readl(dpll_regs->cm_clksel_dpll);
+
+	bypass_dpll(dpll_regs);
+
+	/* Set M & N */
+	temp &= ~CM_CLKSEL_DPLL_M_MASK;
+	temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK;
+
+	temp &= ~CM_CLKSEL_DPLL_N_MASK;
+	temp |= (params->n << CM_CLKSEL_DPLL_N_SHIFT) & CM_CLKSEL_DPLL_N_MASK;
+
+	writel(temp, dpll_regs->cm_clksel_dpll);
+
+	setup_post_dividers(dpll_regs, params);
+
+	/* Wait till the DPLL locks */
+	do_lock_dpll(dpll_regs);
+	wait_for_lock(dpll_regs);
+}
+
+static void setup_dplls(void)
+{
+	const struct dpll_params *params;
+
+	params = get_dpll_core_params();
+	do_setup_dpll(&dpll_core_regs, params);
+
+	params = get_dpll_mpu_params();
+	do_setup_dpll(&dpll_mpu_regs, params);
+
+	params = get_dpll_per_params();
+	do_setup_dpll(&dpll_per_regs, params);
+	writel(0x300, &cmwkup->clkdcoldodpllper);
+
+	params = get_dpll_ddr_params();
+	do_setup_dpll(&dpll_ddr_regs, params);
+}
+
+static inline void wait_for_clk_enable(u32 *clkctrl_addr)
+{
+	u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED;
+	u32 bound = LDELAY;
+
+	while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) ||
+		(idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) {
+		clkctrl = readl(clkctrl_addr);
+		idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
+			 MODULE_CLKCTRL_IDLEST_SHIFT;
+		if (--bound == 0) {
+			printf("Clock enable failed for 0x%p idlest 0x%x\n",
+			       clkctrl_addr, clkctrl);
+			return;
+		}
+	}
+}
+
+static inline void enable_clock_module(u32 *const clkctrl_addr, u32 enable_mode,
+				       u32 wait_for_enable)
+{
+	clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK,
+			enable_mode << MODULE_CLKCTRL_MODULEMODE_SHIFT);
+	debug("Enable clock module - %p\n", clkctrl_addr);
+	if (wait_for_enable)
+		wait_for_clk_enable(clkctrl_addr);
+}
+
+static inline void wait_for_clk_disable(u32 *clkctrl_addr)
+{
+	u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_FULLY_FUNCTIONAL;
+	u32 bound = LDELAY;
+
+	while ((idlest != MODULE_CLKCTRL_IDLEST_DISABLED)) {
+		clkctrl = readl(clkctrl_addr);
+		idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
+			  MODULE_CLKCTRL_IDLEST_SHIFT;
+		if (--bound == 0) {
+			printf("Clock disable failed for 0x%p idlest 0x%x\n",
+			       clkctrl_addr, clkctrl);
+			 return;
+		}
+	}
+}
+static inline void disable_clock_module(u32 *const clkctrl_addr,
+					u32 wait_for_disable)
+{
+	clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_DISABLE <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+	debug("Disable clock module - %p\n", clkctrl_addr);
+	if (wait_for_disable)
+		wait_for_clk_disable(clkctrl_addr);
+}
+
+static inline void enable_clock_domain(u32 *const clkctrl_reg, u32 enable_mode)
+{
+	clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
+			enable_mode << CD_CLKCTRL_CLKTRCTRL_SHIFT);
+	debug("Enable clock domain - %p\n", clkctrl_reg);
+}
+
+static inline void disable_clock_domain(u32 *const clkctrl_reg)
+{
+	clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
+			CD_CLKCTRL_CLKTRCTRL_SW_SLEEP <<
+			CD_CLKCTRL_CLKTRCTRL_SHIFT);
+	debug("Disable clock domain - %p\n", clkctrl_reg);
+}
+
+void do_enable_clocks(u32 *const *clk_domains,
+		      u32 *const *clk_modules_explicit_en, u8 wait_for_enable)
+{
+	u32 i, max = 100;
+
+	/* Put the clock domains in SW_WKUP mode */
+	for (i = 0; (i < max) && clk_domains[i]; i++) {
+		enable_clock_domain(clk_domains[i],
+				    CD_CLKCTRL_CLKTRCTRL_SW_WKUP);
+	}
+
+	/* Clock modules that need to be put in SW_EXPLICIT_EN mode */
+	for (i = 0; (i < max) && clk_modules_explicit_en[i]; i++) {
+		enable_clock_module(clk_modules_explicit_en[i],
+				    MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN,
+				    wait_for_enable);
+	};
+}
+
+void do_disable_clocks(u32 *const *clk_domains,
+			u32 *const *clk_modules_disable,
+			u8 wait_for_disable)
+{
+	u32 i, max = 100;
+
+
+	/* Clock modules that need to be put in SW_DISABLE */
+	for (i = 0; (i < max) && clk_modules_disable[i]; i++)
+		disable_clock_module(clk_modules_disable[i],
+				     wait_for_disable);
+
+	/* Put the clock domains in SW_SLEEP mode */
+	for (i = 0; (i < max) && clk_domains[i]; i++)
+		disable_clock_domain(clk_domains[i]);
+}
+
+/*
+ * Before scaling up the clocks we need to have the PMIC scale up the
+ * voltages first.  This will be dependent on which PMIC is in use
+ * and in some cases we may not be scaling things up at all and thus not
+ * need to do anything here.
+ */
+__weak void scale_vcores(void)
+{
+}
+
+void setup_early_clocks(void)
+{
+	setup_clocks_for_console();
+	enable_basic_clocks();
+	timer_init();
+}
+
+void prcm_init(void)
+{
+	scale_vcores();
+	setup_dplls();
+}
diff --git a/arch/arm/mach-omap2/am33xx/clock_am33xx.c b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
new file mode 100644
index 0000000..7b841b2
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
@@ -0,0 +1,234 @@
+/*
+ * clock_am33xx.c
+ *
+ * clocks for AM33XX based boards
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+#define OSC	(V_OSCK/1000000)
+
+struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER;
+struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP;
+struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
+struct cm_rtc *const cmrtc = (struct cm_rtc *)CM_RTC;
+
+const struct dpll_regs dpll_mpu_regs = {
+	.cm_clkmode_dpll	= CM_WKUP + 0x88,
+	.cm_idlest_dpll		= CM_WKUP + 0x20,
+	.cm_clksel_dpll		= CM_WKUP + 0x2C,
+	.cm_div_m2_dpll		= CM_WKUP + 0xA8,
+};
+
+const struct dpll_regs dpll_core_regs = {
+	.cm_clkmode_dpll	= CM_WKUP + 0x90,
+	.cm_idlest_dpll		= CM_WKUP + 0x5C,
+	.cm_clksel_dpll		= CM_WKUP + 0x68,
+	.cm_div_m4_dpll		= CM_WKUP + 0x80,
+	.cm_div_m5_dpll		= CM_WKUP + 0x84,
+	.cm_div_m6_dpll		= CM_WKUP + 0xD8,
+};
+
+const struct dpll_regs dpll_per_regs = {
+	.cm_clkmode_dpll	= CM_WKUP + 0x8C,
+	.cm_idlest_dpll		= CM_WKUP + 0x70,
+	.cm_clksel_dpll		= CM_WKUP + 0x9C,
+	.cm_div_m2_dpll		= CM_WKUP + 0xAC,
+};
+
+const struct dpll_regs dpll_ddr_regs = {
+	.cm_clkmode_dpll	= CM_WKUP + 0x94,
+	.cm_idlest_dpll		= CM_WKUP + 0x34,
+	.cm_clksel_dpll		= CM_WKUP + 0x40,
+	.cm_div_m2_dpll		= CM_WKUP + 0xA0,
+};
+
+struct dpll_params dpll_mpu_opp100 = {
+		CONFIG_SYS_MPUCLK, OSC-1, 1, -1, -1, -1, -1};
+const struct dpll_params dpll_core_opp100 = {
+		1000, OSC-1, -1, -1, 10, 8, 4};
+const struct dpll_params dpll_mpu = {
+		MPUPLL_M_300, OSC-1, 1, -1, -1, -1, -1};
+const struct dpll_params dpll_core = {
+		50, OSC-1, -1, -1, 1, 1, 1};
+const struct dpll_params dpll_per = {
+		960, OSC-1, 5, -1, -1, -1, -1};
+
+const struct dpll_params *get_dpll_mpu_params(void)
+{
+	return &dpll_mpu;
+}
+
+const struct dpll_params *get_dpll_core_params(void)
+{
+	return &dpll_core;
+}
+
+const struct dpll_params *get_dpll_per_params(void)
+{
+	return &dpll_per;
+}
+
+void setup_clocks_for_console(void)
+{
+	clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
+			CD_CLKCTRL_CLKTRCTRL_SW_WKUP <<
+			CD_CLKCTRL_CLKTRCTRL_SHIFT);
+
+	clrsetbits_le32(&cmper->l4hsclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
+			CD_CLKCTRL_CLKTRCTRL_SW_WKUP <<
+			CD_CLKCTRL_CLKTRCTRL_SHIFT);
+
+	clrsetbits_le32(&cmwkup->wkup_uart0ctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+	clrsetbits_le32(&cmper->uart1clkctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+	clrsetbits_le32(&cmper->uart2clkctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+	clrsetbits_le32(&cmper->uart3clkctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+	clrsetbits_le32(&cmper->uart4clkctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+	clrsetbits_le32(&cmper->uart5clkctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+}
+
+void enable_basic_clocks(void)
+{
+	u32 *const clk_domains[] = {
+		&cmper->l3clkstctrl,
+		&cmper->l4fwclkstctrl,
+		&cmper->l3sclkstctrl,
+		&cmper->l4lsclkstctrl,
+		&cmwkup->wkclkstctrl,
+		&cmper->emiffwclkctrl,
+		&cmrtc->clkstctrl,
+		0
+	};
+
+	u32 *const clk_modules_explicit_en[] = {
+		&cmper->l3clkctrl,
+		&cmper->l4lsclkctrl,
+		&cmper->l4fwclkctrl,
+		&cmwkup->wkl4wkclkctrl,
+		&cmper->l3instrclkctrl,
+		&cmper->l4hsclkctrl,
+		&cmwkup->wkgpio0clkctrl,
+		&cmwkup->wkctrlclkctrl,
+		&cmper->timer2clkctrl,
+		&cmper->gpmcclkctrl,
+		&cmper->elmclkctrl,
+		&cmper->mmc0clkctrl,
+		&cmper->mmc1clkctrl,
+		&cmwkup->wkup_i2c0ctrl,
+		&cmper->gpio1clkctrl,
+		&cmper->gpio2clkctrl,
+		&cmper->gpio3clkctrl,
+		&cmper->i2c1clkctrl,
+		&cmper->cpgmac0clkctrl,
+		&cmper->spi0clkctrl,
+		&cmrtc->rtcclkctrl,
+		&cmper->usb0clkctrl,
+		&cmper->emiffwclkctrl,
+		&cmper->emifclkctrl,
+		0
+	};
+
+	do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
+
+	/* Select the Master osc 24 MHZ as Timer2 clock source */
+	writel(0x1, &cmdpll->clktimer2clk);
+}
+
+/*
+ * Enable Spread Spectrum for the MPU by calculating the required
+ * values and setting the registers accordingly.
+ * @param permille The spreading in permille (10th of a percent)
+ */
+void set_mpu_spreadspectrum(int permille)
+{
+	u32 multiplier_m;
+	u32 predivider_n;
+	u32 cm_clksel_dpll_mpu;
+	u32 cm_clkmode_dpll_mpu;
+	u32 ref_clock;
+	u32 pll_bandwidth;
+	u32 mod_freq_divider;
+	u32 exponent;
+	u32 mantissa;
+	u32 delta_m_step;
+
+	printf("Enabling Spread Spectrum of %d permille for MPU\n",
+	       permille);
+
+	/* Read PLL parameter m and n */
+	cm_clksel_dpll_mpu = readl(&cmwkup->clkseldpllmpu);
+	multiplier_m = (cm_clksel_dpll_mpu >> 8) & 0x3FF;
+	predivider_n = cm_clksel_dpll_mpu & 0x7F;
+
+	/*
+	 * Calculate reference clock (clock after pre-divider),
+	 * its max. PLL bandwidth,
+	 * and resulting mod_freq_divider
+	 */
+	ref_clock = V_OSCK / (predivider_n + 1);
+	pll_bandwidth = ref_clock / 70;
+	mod_freq_divider = ref_clock / (4 * pll_bandwidth);
+
+	/* Calculate Mantissa/Exponent */
+	exponent = 0;
+	mantissa = mod_freq_divider;
+	while ((mantissa > 127) && (exponent < 7)) {
+		exponent++;
+		mantissa /= 2;
+	}
+	if (mantissa > 127)
+		mantissa = 127;
+
+	mod_freq_divider = mantissa << exponent;
+
+	/*
+	 * Calculate Modulation steps
+	 * As we use Downspread only, the spread is twice the value of
+	 * permille, so Div2!
+	 * As it takes the value in percent, divide by ten!
+	 */
+	delta_m_step = ((u32)((multiplier_m * permille) / 10 / 2)) << 18;
+	delta_m_step /= 100;
+	delta_m_step /= mod_freq_divider;
+	if (delta_m_step > 0xFFFFF)
+		delta_m_step = 0xFFFFF;
+
+	/* Setup Spread Spectrum */
+	writel(delta_m_step, &cmwkup->sscdeltamstepdllmpu);
+	writel((exponent << 8) | mantissa, &cmwkup->sscmodfreqdivdpllmpu);
+	cm_clkmode_dpll_mpu = readl(&cmwkup->clkmoddpllmpu);
+	/* clear all SSC flags */
+	cm_clkmode_dpll_mpu &= ~(0xF << CM_CLKMODE_DPLL_SSC_EN_SHIFT);
+	/* enable SSC with Downspread only */
+	cm_clkmode_dpll_mpu |=  CM_CLKMODE_DPLL_SSC_EN_MASK |
+				CM_CLKMODE_DPLL_SSC_DOWNSPREAD_MASK;
+	writel(cm_clkmode_dpll_mpu, &cmwkup->clkmoddpllmpu);
+	while (!(readl(&cmwkup->clkmoddpllmpu) & 0x2000))
+		;
+}
diff --git a/arch/arm/mach-omap2/am33xx/clock_am43xx.c b/arch/arm/mach-omap2/am33xx/clock_am43xx.c
new file mode 100644
index 0000000..73ea955
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/clock_am43xx.c
@@ -0,0 +1,231 @@
+/*
+ * clock_am43xx.c
+ *
+ * clocks for AM43XX based boards
+ * Derived from AM33XX based boards
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+
+struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER;
+struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP;
+struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
+
+const struct dpll_regs dpll_mpu_regs = {
+	.cm_clkmode_dpll	= CM_WKUP + 0x560,
+	.cm_idlest_dpll		= CM_WKUP + 0x564,
+	.cm_clksel_dpll		= CM_WKUP + 0x56c,
+	.cm_div_m2_dpll		= CM_WKUP + 0x570,
+};
+
+const struct dpll_regs dpll_core_regs = {
+	.cm_clkmode_dpll	= CM_WKUP + 0x520,
+	.cm_idlest_dpll		= CM_WKUP + 0x524,
+	.cm_clksel_dpll		= CM_WKUP + 0x52C,
+	.cm_div_m4_dpll		= CM_WKUP + 0x538,
+	.cm_div_m5_dpll		= CM_WKUP + 0x53C,
+	.cm_div_m6_dpll		= CM_WKUP + 0x540,
+};
+
+const struct dpll_regs dpll_per_regs = {
+	.cm_clkmode_dpll	= CM_WKUP + 0x5E0,
+	.cm_idlest_dpll		= CM_WKUP + 0x5E4,
+	.cm_clksel_dpll		= CM_WKUP + 0x5EC,
+	.cm_div_m2_dpll		= CM_WKUP + 0x5F0,
+};
+
+const struct dpll_regs dpll_ddr_regs = {
+	.cm_clkmode_dpll	= CM_WKUP + 0x5A0,
+	.cm_idlest_dpll		= CM_WKUP + 0x5A4,
+	.cm_clksel_dpll		= CM_WKUP + 0x5AC,
+	.cm_div_m2_dpll		= CM_WKUP + 0x5B0,
+	.cm_div_m4_dpll		= CM_WKUP + 0x5B8,
+};
+
+void setup_clocks_for_console(void)
+{
+	u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED;
+
+	/* Do not add any spl_debug prints in this function */
+	clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
+			CD_CLKCTRL_CLKTRCTRL_SW_WKUP <<
+			CD_CLKCTRL_CLKTRCTRL_SHIFT);
+
+	/* Enable UART0 */
+	clrsetbits_le32(&cmwkup->wkup_uart0ctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+
+	while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) ||
+		(idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) {
+		clkctrl = readl(&cmwkup->wkup_uart0ctrl);
+		idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
+			 MODULE_CLKCTRL_IDLEST_SHIFT;
+	}
+}
+
+void enable_basic_clocks(void)
+{
+	u32 *const clk_domains[] = {
+		&cmper->l3clkstctrl,
+		&cmper->l3sclkstctrl,
+		&cmper->l4lsclkstctrl,
+		&cmwkup->wkclkstctrl,
+		&cmper->emifclkstctrl,
+		0
+	};
+
+	u32 *const clk_modules_explicit_en[] = {
+		&cmper->l3clkctrl,
+		&cmper->l4lsclkctrl,
+		&cmper->l4fwclkctrl,
+		&cmwkup->wkl4wkclkctrl,
+		&cmper->l3instrclkctrl,
+		&cmper->l4hsclkctrl,
+		&cmwkup->wkgpio0clkctrl,
+		&cmwkup->wkctrlclkctrl,
+		&cmper->timer2clkctrl,
+		&cmper->gpmcclkctrl,
+		&cmper->elmclkctrl,
+		&cmper->mmc0clkctrl,
+		&cmper->mmc1clkctrl,
+		&cmwkup->wkup_i2c0ctrl,
+		&cmper->gpio1clkctrl,
+		&cmper->gpio2clkctrl,
+		&cmper->gpio3clkctrl,
+		&cmper->gpio4clkctrl,
+		&cmper->gpio5clkctrl,
+		&cmper->i2c1clkctrl,
+		&cmper->cpgmac0clkctrl,
+		&cmper->emiffwclkctrl,
+		&cmper->emifclkctrl,
+		&cmper->otfaemifclkctrl,
+		&cmper->qspiclkctrl,
+		&cmper->spi0clkctrl,
+		0
+	};
+
+	do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
+
+	/* Select the Master osc clk as Timer2 clock source */
+	writel(0x1, &cmdpll->clktimer2clk);
+
+	/* For OPP100 the mac clock should be /5. */
+	writel(0x4, &cmdpll->clkselmacclk);
+}
+
+#ifdef CONFIG_TI_EDMA3
+void enable_edma3_clocks(void)
+{
+	u32 *const clk_domains_edma3[] = {
+		0
+	};
+
+	u32 *const clk_modules_explicit_en_edma3[] = {
+		&cmper->tpccclkctrl,
+		&cmper->tptc0clkctrl,
+		0
+	};
+
+	do_enable_clocks(clk_domains_edma3,
+			 clk_modules_explicit_en_edma3,
+			 1);
+}
+
+void disable_edma3_clocks(void)
+{
+	u32 *const clk_domains_edma3[] = {
+		0
+	};
+
+	u32 *const clk_modules_disable_edma3[] = {
+		&cmper->tpccclkctrl,
+		&cmper->tptc0clkctrl,
+		0
+	};
+
+	do_disable_clocks(clk_domains_edma3,
+			  clk_modules_disable_edma3,
+			  1);
+}
+#endif
+
+#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP)
+void enable_usb_clocks(int index)
+{
+	u32 *usbclkctrl = 0;
+	u32 *usbphyocp2scpclkctrl = 0;
+
+	if (index == 0) {
+		usbclkctrl = &cmper->usb0clkctrl;
+		usbphyocp2scpclkctrl = &cmper->usbphyocp2scp0clkctrl;
+		setbits_le32(&cmper->usb0clkctrl,
+			     USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
+		setbits_le32(&cmwkup->usbphy0clkctrl,
+			     USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
+	} else if (index == 1) {
+		usbclkctrl = &cmper->usb1clkctrl;
+		usbphyocp2scpclkctrl = &cmper->usbphyocp2scp1clkctrl;
+		setbits_le32(&cmper->usb1clkctrl,
+			     USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
+		setbits_le32(&cmwkup->usbphy1clkctrl,
+			     USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
+	}
+
+	u32 *const clk_domains_usb[] = {
+		0
+	};
+
+	u32 *const clk_modules_explicit_en_usb[] = {
+		usbclkctrl,
+		usbphyocp2scpclkctrl,
+		0
+	};
+
+	do_enable_clocks(clk_domains_usb, clk_modules_explicit_en_usb, 1);
+}
+
+void disable_usb_clocks(int index)
+{
+	u32 *usbclkctrl = 0;
+	u32 *usbphyocp2scpclkctrl = 0;
+
+	if (index == 0) {
+		usbclkctrl = &cmper->usb0clkctrl;
+		usbphyocp2scpclkctrl = &cmper->usbphyocp2scp0clkctrl;
+		clrbits_le32(&cmper->usb0clkctrl,
+			     USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
+		clrbits_le32(&cmwkup->usbphy0clkctrl,
+			     USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
+	} else if (index == 1) {
+		usbclkctrl = &cmper->usb1clkctrl;
+		usbphyocp2scpclkctrl = &cmper->usbphyocp2scp1clkctrl;
+		clrbits_le32(&cmper->usb1clkctrl,
+			     USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
+		clrbits_le32(&cmwkup->usbphy1clkctrl,
+			     USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
+	}
+
+	u32 *const clk_domains_usb[] = {
+		0
+	};
+
+	u32 *const clk_modules_disable_usb[] = {
+		usbclkctrl,
+		usbphyocp2scpclkctrl,
+		0
+	};
+
+	do_disable_clocks(clk_domains_usb, clk_modules_disable_usb, 1);
+}
+#endif
diff --git a/arch/arm/mach-omap2/am33xx/clock_ti814x.c b/arch/arm/mach-omap2/am33xx/clock_ti814x.c
new file mode 100644
index 0000000..50bd631
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/clock_ti814x.c
@@ -0,0 +1,410 @@
+/*
+ * clock_ti814x.c
+ *
+ * Clocks for TI814X based boards
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+/* PRCM */
+#define PRCM_MOD_EN		0x2
+
+/* CLK_SRC */
+#define OSC_SRC0		0
+#define OSC_SRC1		1
+
+#define L3_OSC_SRC		OSC_SRC0
+
+#define OSC_0_FREQ		20
+
+#define DCO_HS2_MIN		500
+#define DCO_HS2_MAX		1000
+#define DCO_HS1_MIN		1000
+#define DCO_HS1_MAX		2000
+
+#define SELFREQDCO_HS2		0x00000801
+#define SELFREQDCO_HS1		0x00001001
+
+#define MPU_N			0x1
+#define MPU_M			0x3C
+#define MPU_M2			1
+#define MPU_CLKCTRL		0x1
+
+#define L3_N			19
+#define L3_M			880
+#define L3_M2			4
+#define L3_CLKCTRL		0x801
+
+#define DDR_N			19
+#define DDR_M			666
+#define DDR_M2			2
+#define DDR_CLKCTRL		0x801
+
+/* ADPLLJ register values */
+#define ADPLLJ_CLKCTRL_HS2	0x00000801 /* HS2 mode, TINT2 = 1 */
+#define ADPLLJ_CLKCTRL_HS1	0x00001001 /* HS1 mode, TINT2 = 1 */
+#define ADPLLJ_CLKCTRL_CLKDCOLDOEN	(1 << 29)
+#define ADPLLJ_CLKCTRL_IDLE		(1 << 23)
+#define ADPLLJ_CLKCTRL_CLKOUTEN		(1 << 20)
+#define ADPLLJ_CLKCTRL_CLKOUTLDOEN	(1 << 19)
+#define ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ	(1 << 17)
+#define ADPLLJ_CLKCTRL_LPMODE		(1 << 12)
+#define ADPLLJ_CLKCTRL_DRIFTGUARDIAN	(1 << 11)
+#define ADPLLJ_CLKCTRL_REGM4XEN		(1 << 10)
+#define ADPLLJ_CLKCTRL_TINITZ		(1 << 0)
+#define ADPLLJ_CLKCTRL_CLKDCO		(ADPLLJ_CLKCTRL_CLKDCOLDOEN | \
+					 ADPLLJ_CLKCTRL_CLKOUTEN | \
+					 ADPLLJ_CLKCTRL_CLKOUTLDOEN | \
+					 ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ)
+
+#define ADPLLJ_STATUS_PHASELOCK		(1 << 10)
+#define ADPLLJ_STATUS_FREQLOCK		(1 << 9)
+#define ADPLLJ_STATUS_PHSFRQLOCK	(ADPLLJ_STATUS_PHASELOCK | \
+					 ADPLLJ_STATUS_FREQLOCK)
+#define ADPLLJ_STATUS_BYPASSACK		(1 << 8)
+#define ADPLLJ_STATUS_BYPASS		(1 << 0)
+#define ADPLLJ_STATUS_BYPASSANDACK	(ADPLLJ_STATUS_BYPASSACK | \
+					 ADPLLJ_STATUS_BYPASS)
+
+#define ADPLLJ_TENABLE_ENB		(1 << 0)
+#define ADPLLJ_TENABLEDIV_ENB		(1 << 0)
+
+#define ADPLLJ_M2NDIV_M2SHIFT		16
+
+#define MPU_PLL_BASE			(PLL_SUBSYS_BASE + 0x048)
+#define L3_PLL_BASE			(PLL_SUBSYS_BASE + 0x110)
+#define DDR_PLL_BASE			(PLL_SUBSYS_BASE + 0x290)
+
+struct ad_pll {
+	unsigned int pwrctrl;
+	unsigned int clkctrl;
+	unsigned int tenable;
+	unsigned int tenablediv;
+	unsigned int m2ndiv;
+	unsigned int mn2div;
+	unsigned int fracdiv;
+	unsigned int bwctrl;
+	unsigned int fracctrl;
+	unsigned int status;
+	unsigned int m3div;
+	unsigned int rampctrl;
+};
+
+#define OSC_SRC_CTRL			(PLL_SUBSYS_BASE + 0x2C0)
+
+#define ENET_CLKCTRL_CMPL		0x30000
+
+#define SATA_PLL_BASE			(CTRL_BASE + 0x0720)
+
+struct sata_pll {
+	unsigned int pllcfg0;
+	unsigned int pllcfg1;
+	unsigned int pllcfg2;
+	unsigned int pllcfg3;
+	unsigned int pllcfg4;
+	unsigned int pllstatus;
+	unsigned int rxstatus;
+	unsigned int txstatus;
+	unsigned int testcfg;
+};
+
+#define SEL_IN_FREQ		(0x1 << 31)
+#define DIGCLRZ			(0x1 << 30)
+#define ENDIGLDO		(0x1 << 4)
+#define APLL_CP_CURR		(0x1 << 3)
+#define ENBGSC_REF		(0x1 << 2)
+#define ENPLLLDO		(0x1 << 1)
+#define ENPLL			(0x1 << 0)
+
+#define SATA_PLLCFG0_1 (SEL_IN_FREQ | ENBGSC_REF)
+#define SATA_PLLCFG0_2 (SEL_IN_FREQ | ENDIGLDO | ENBGSC_REF)
+#define SATA_PLLCFG0_3 (SEL_IN_FREQ | ENDIGLDO | ENBGSC_REF | ENPLLLDO)
+#define SATA_PLLCFG0_4 (SEL_IN_FREQ | DIGCLRZ | ENDIGLDO | ENBGSC_REF | \
+			ENPLLLDO | ENPLL)
+
+#define PLL_LOCK		(0x1 << 0)
+
+#define ENSATAMODE		(0x1 << 31)
+#define PLLREFSEL		(0x1 << 30)
+#define MDIVINT			(0x4b << 18)
+#define EN_CLKAUX		(0x1 << 5)
+#define EN_CLK125M		(0x1 << 4)
+#define EN_CLK100M		(0x1 << 3)
+#define EN_CLK50M		(0x1 << 2)
+
+#define SATA_PLLCFG1 (ENSATAMODE |	\
+		      PLLREFSEL |	\
+		      MDIVINT |		\
+		      EN_CLKAUX |	\
+		      EN_CLK125M |	\
+		      EN_CLK100M |	\
+		      EN_CLK50M)
+
+#define DIGLDO_EN_CAPLESSMODE	(0x1 << 22)
+#define PLLDO_EN_LDO_STABLE	(0x1 << 11)
+#define PLLDO_EN_BUF_CUR	(0x1 << 7)
+#define PLLDO_EN_LP		(0x1 << 6)
+#define PLLDO_CTRL_TRIM_1_4V	(0x10 << 1)
+
+#define SATA_PLLCFG3 (DIGLDO_EN_CAPLESSMODE |	\
+		      PLLDO_EN_LDO_STABLE |	\
+		      PLLDO_EN_BUF_CUR |	\
+		      PLLDO_EN_LP |		\
+		      PLLDO_CTRL_TRIM_1_4V)
+
+const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE;
+const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE;
+const struct sata_pll *spll = (struct sata_pll *)SATA_PLL_BASE;
+
+/*
+ * Enable the peripheral clock for required peripherals
+ */
+static void enable_per_clocks(void)
+{
+	/* HSMMC1 */
+	writel(PRCM_MOD_EN, &cmalwon->mmchs1clkctrl);
+	while (readl(&cmalwon->mmchs1clkctrl) != PRCM_MOD_EN)
+		;
+
+	/* Ethernet */
+	writel(PRCM_MOD_EN, &cmalwon->ethclkstctrl);
+	writel(PRCM_MOD_EN, &cmalwon->ethernet0clkctrl);
+	while ((readl(&cmalwon->ethernet0clkctrl) & ENET_CLKCTRL_CMPL) != 0)
+		;
+	writel(PRCM_MOD_EN, &cmalwon->ethernet1clkctrl);
+	while ((readl(&cmalwon->ethernet1clkctrl) & ENET_CLKCTRL_CMPL) != 0)
+		;
+
+	/* RTC clocks */
+	writel(PRCM_MOD_EN, &cmalwon->rtcclkstctrl);
+	writel(PRCM_MOD_EN, &cmalwon->rtcclkctrl);
+	while (readl(&cmalwon->rtcclkctrl) != PRCM_MOD_EN)
+		;
+}
+
+/*
+ * select the HS1 or HS2 for DCO Freq
+ * return : CLKCTRL
+ */
+static u32 pll_dco_freq_sel(u32 clkout_dco)
+{
+	if (clkout_dco >= DCO_HS2_MIN && clkout_dco < DCO_HS2_MAX)
+		return SELFREQDCO_HS2;
+	else if (clkout_dco >= DCO_HS1_MIN && clkout_dco < DCO_HS1_MAX)
+		return SELFREQDCO_HS1;
+	else
+		return -1;
+}
+
+/*
+ * select the sigma delta config
+ * return: sigma delta val
+ */
+static u32 pll_sigma_delta_val(u32 clkout_dco)
+{
+	u32 sig_val = 0;
+
+	sig_val = (clkout_dco + 225) / 250;
+	sig_val = sig_val << 24;
+
+	return sig_val;
+}
+
+/*
+ * configure individual ADPLLJ
+ */
+static void pll_config(u32 base, u32 n, u32 m, u32 m2,
+		       u32 clkctrl_val, int adpllj)
+{
+	const struct ad_pll *adpll = (struct ad_pll *)base;
+	u32 m2nval, mn2val, read_clkctrl = 0, clkout_dco = 0;
+	u32 sig_val = 0, hs_mod = 0;
+
+	m2nval = (m2 << ADPLLJ_M2NDIV_M2SHIFT) | n;
+	mn2val = m;
+
+	/* calculate clkout_dco */
+	clkout_dco = ((OSC_0_FREQ / (n+1)) * m);
+
+	/* sigma delta & Hs mode selection skip for ADPLLS*/
+	if (adpllj) {
+		sig_val = pll_sigma_delta_val(clkout_dco);
+		hs_mod = pll_dco_freq_sel(clkout_dco);
+	}
+
+	/* by-pass pll */
+	read_clkctrl = readl(&adpll->clkctrl);
+	writel((read_clkctrl | ADPLLJ_CLKCTRL_IDLE), &adpll->clkctrl);
+	while ((readl(&adpll->status) & ADPLLJ_STATUS_BYPASSANDACK)
+		!= ADPLLJ_STATUS_BYPASSANDACK)
+		;
+
+	/* clear TINITZ */
+	read_clkctrl = readl(&adpll->clkctrl);
+	writel((read_clkctrl & ~ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl);
+
+	/*
+	 * ref_clk = 20/(n + 1);
+	 * clkout_dco = ref_clk * m;
+	 * clk_out = clkout_dco/m2;
+	*/
+	read_clkctrl = readl(&adpll->clkctrl) &
+			     ~(ADPLLJ_CLKCTRL_LPMODE |
+			     ADPLLJ_CLKCTRL_DRIFTGUARDIAN |
+			     ADPLLJ_CLKCTRL_REGM4XEN);
+	writel(m2nval, &adpll->m2ndiv);
+	writel(mn2val, &adpll->mn2div);
+
+	/* Skip for modena(ADPLLS) */
+	if (adpllj) {
+		writel(sig_val, &adpll->fracdiv);
+		writel((read_clkctrl | hs_mod), &adpll->clkctrl);
+	}
+
+	/* Load M2, N2 dividers of ADPLL */
+	writel(ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv);
+	writel(~ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv);
+
+	/* Load M, N dividers of ADPLL */
+	writel(ADPLLJ_TENABLE_ENB, &adpll->tenable);
+	writel(~ADPLLJ_TENABLE_ENB, &adpll->tenable);
+
+	/* Configure CLKDCOLDOEN,CLKOUTLDOEN,CLKOUT Enable BITS */
+	read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_CLKDCO;
+	if (adpllj)
+		writel((read_clkctrl | ADPLLJ_CLKCTRL_CLKDCO),
+						&adpll->clkctrl);
+
+	/* Enable TINTZ and disable IDLE(PLL in Active & Locked Mode */
+	read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_IDLE;
+	writel((read_clkctrl | ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl);
+
+	/* Wait for phase and freq lock */
+	while ((readl(&adpll->status) & ADPLLJ_STATUS_PHSFRQLOCK) !=
+	       ADPLLJ_STATUS_PHSFRQLOCK)
+		;
+}
+
+static void unlock_pll_control_mmr(void)
+{
+	/* TRM 2.10.1.4 and 3.2.7-3.2.11 */
+	writel(0x1EDA4C3D, 0x481C5040);
+	writel(0x2FF1AC2B, 0x48140060);
+	writel(0xF757FDC0, 0x48140064);
+	writel(0xE2BC3A6D, 0x48140068);
+	writel(0x1EBF131D, 0x4814006c);
+	writel(0x6F361E05, 0x48140070);
+}
+
+static void mpu_pll_config(void)
+{
+	pll_config(MPU_PLL_BASE, MPU_N, MPU_M, MPU_M2, MPU_CLKCTRL, 0);
+}
+
+static void l3_pll_config(void)
+{
+	u32 l3_osc_src, rd_osc_src = 0;
+
+	l3_osc_src = L3_OSC_SRC;
+	rd_osc_src = readl(OSC_SRC_CTRL);
+
+	if (OSC_SRC0 == l3_osc_src)
+		writel((rd_osc_src & 0xfffffffe)|0x0, OSC_SRC_CTRL);
+	else
+		writel((rd_osc_src & 0xfffffffe)|0x1, OSC_SRC_CTRL);
+
+	pll_config(L3_PLL_BASE, L3_N, L3_M, L3_M2, L3_CLKCTRL, 1);
+}
+
+void ddr_pll_config(unsigned int ddrpll_m)
+{
+	pll_config(DDR_PLL_BASE, DDR_N, DDR_M, DDR_M2, DDR_CLKCTRL, 1);
+}
+
+void sata_pll_config(void)
+{
+	/*
+	 * This sequence for configuring the SATA PLL
+	 * resident in the control module is documented
+	 * in TI8148 TRM section 21.3.1
+	 */
+	writel(SATA_PLLCFG1, &spll->pllcfg1);
+	udelay(50);
+
+	writel(SATA_PLLCFG3, &spll->pllcfg3);
+	udelay(50);
+
+	writel(SATA_PLLCFG0_1, &spll->pllcfg0);
+	udelay(50);
+
+	writel(SATA_PLLCFG0_2, &spll->pllcfg0);
+	udelay(50);
+
+	writel(SATA_PLLCFG0_3, &spll->pllcfg0);
+	udelay(50);
+
+	writel(SATA_PLLCFG0_4, &spll->pllcfg0);
+	udelay(50);
+
+	while (((readl(&spll->pllstatus) & PLL_LOCK) == 0))
+		;
+}
+
+void enable_dmm_clocks(void)
+{
+	writel(PRCM_MOD_EN, &cmdef->fwclkctrl);
+	writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl);
+	writel(PRCM_MOD_EN, &cmdef->emif0clkctrl);
+	while ((readl(&cmdef->emif0clkctrl)) != PRCM_MOD_EN)
+		;
+	writel(PRCM_MOD_EN, &cmdef->emif1clkctrl);
+	while ((readl(&cmdef->emif1clkctrl)) != PRCM_MOD_EN)
+		;
+	while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300)
+		;
+	writel(PRCM_MOD_EN, &cmdef->dmmclkctrl);
+	while ((readl(&cmdef->dmmclkctrl)) != PRCM_MOD_EN)
+		;
+	writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl);
+	while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100)
+		;
+}
+
+void setup_clocks_for_console(void)
+{
+	unlock_pll_control_mmr();
+	/* UART0 */
+	writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl);
+	while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN)
+		;
+}
+
+void setup_early_clocks(void)
+{
+	setup_clocks_for_console();
+}
+
+/*
+ * Configure the PLL/PRCM for necessary peripherals
+ */
+void prcm_init(void)
+{
+	/* Enable the control module */
+	writel(PRCM_MOD_EN, &cmalwon->controlclkctrl);
+
+	/* Configure PLLs */
+	mpu_pll_config();
+	l3_pll_config();
+	sata_pll_config();
+
+	/* Enable the required peripherals */
+	enable_per_clocks();
+}
diff --git a/arch/arm/mach-omap2/am33xx/clock_ti816x.c b/arch/arm/mach-omap2/am33xx/clock_ti816x.c
new file mode 100644
index 0000000..079ddd7
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/clock_ti816x.c
@@ -0,0 +1,450 @@
+/*
+ * clock_ti816x.c
+ *
+ * Clocks for TI816X based boards
+ *
+ * Copyright (C) 2013, Adeneo Embedded <www.adeneo-embedded.com>
+ * Antoine Tenart, <atenart@adeneo-embedded.com>
+ *
+ * Based on TI-PSP-04.00.02.14 :
+ *
+ * Copyright (C) 2009, Texas Instruments, Incorporated
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+#include <asm/emif.h>
+
+#define CM_PLL_BASE		(CTRL_BASE + 0x0400)
+
+/* Main PLL */
+#define MAIN_N			64
+#define MAIN_P			0x1
+#define MAIN_INTFREQ1		0x8
+#define MAIN_FRACFREQ1		0x800000
+#define MAIN_MDIV1		0x2
+#define MAIN_INTFREQ2		0xE
+#define MAIN_FRACFREQ2		0x0
+#define MAIN_MDIV2		0x1
+#define MAIN_INTFREQ3		0x8
+#define MAIN_FRACFREQ3		0xAAAAB0
+#define MAIN_MDIV3		0x3
+#define MAIN_INTFREQ4		0x9
+#define MAIN_FRACFREQ4		0x55554F
+#define MAIN_MDIV4		0x3
+#define MAIN_INTFREQ5		0x9
+#define MAIN_FRACFREQ5		0x374BC6
+#define MAIN_MDIV5		0xC
+#define MAIN_MDIV6		0x48
+#define MAIN_MDIV7		0x4
+
+/* DDR PLL */
+#if defined(CONFIG_TI816X_DDR_PLL_400) /* 400 MHz */
+#define DDR_N			59
+#define DDR_P			0x1
+#define DDR_MDIV1		0x4
+#define DDR_INTFREQ2		0x8
+#define DDR_FRACFREQ2		0xD99999
+#define DDR_MDIV2		0x1E
+#define DDR_INTFREQ3		0x8
+#define DDR_FRACFREQ3		0x0
+#define DDR_MDIV3		0x4
+#define DDR_INTFREQ4		0xE /* Expansion DDR clk */
+#define DDR_FRACFREQ4		0x0
+#define DDR_MDIV4		0x4
+#define DDR_INTFREQ5		0xE /* Expansion DDR clk */
+#define DDR_FRACFREQ5		0x0
+#define DDR_MDIV5		0x4
+#elif defined(CONFIG_TI816X_DDR_PLL_531) /* 531 MHz */
+#define DDR_N			59
+#define DDR_P			0x1
+#define DDR_MDIV1		0x3
+#define DDR_INTFREQ2		0x8
+#define DDR_FRACFREQ2		0xD99999
+#define DDR_MDIV2		0x1E
+#define DDR_INTFREQ3		0x8
+#define DDR_FRACFREQ3		0x0
+#define DDR_MDIV3		0x4
+#define DDR_INTFREQ4		0xE /* Expansion DDR clk */
+#define DDR_FRACFREQ4		0x0
+#define DDR_MDIV4		0x4
+#define DDR_INTFREQ5		0xE /* Expansion DDR clk */
+#define DDR_FRACFREQ5		0x0
+#define DDR_MDIV5		0x4
+#elif defined(CONFIG_TI816X_DDR_PLL_675) /* 675 MHz */
+#define DDR_N			50
+#define DDR_P			0x1
+#define DDR_MDIV1		0x2
+#define DDR_INTFREQ2		0x9
+#define DDR_FRACFREQ2		0x0
+#define DDR_MDIV2		0x19
+#define DDR_INTFREQ3		0x13
+#define DDR_FRACFREQ3		0x800000
+#define DDR_MDIV3		0x2
+#define DDR_INTFREQ4		0xE /* Expansion DDR clk */
+#define DDR_FRACFREQ4		0x0
+#define DDR_MDIV4		0x4
+#define DDR_INTFREQ5		0xE /* Expansion DDR clk */
+#define DDR_FRACFREQ5		0x0
+#define DDR_MDIV5		0x4
+#elif defined(CONFIG_TI816X_DDR_PLL_796) /* 796 MHz */
+#define DDR_N			59
+#define DDR_P			0x1
+#define DDR_MDIV1		0x2
+#define DDR_INTFREQ2		0x8
+#define DDR_FRACFREQ2		0xD99999
+#define DDR_MDIV2		0x1E
+#define DDR_INTFREQ3		0x8
+#define DDR_FRACFREQ3		0x0
+#define DDR_MDIV3		0x4
+#define DDR_INTFREQ4		0xE /* Expansion DDR clk */
+#define DDR_FRACFREQ4		0x0
+#define DDR_MDIV4		0x4
+#define DDR_INTFREQ5		0xE /* Expansion DDR clk */
+#define DDR_FRACFREQ5		0x0
+#define DDR_MDIV5		0x4
+#endif
+
+#define CONTROL_STATUS			(CTRL_BASE + 0x40)
+#define DDR_RCD				(CTRL_BASE + 0x070C)
+#define CM_TIMER1_CLKSEL		(PRCM_BASE + 0x390)
+#define DMM_PAT_BASE_ADDR		(DMM_BASE + 0x420)
+#define CM_ALWON_CUST_EFUSE_CLKCTRL	(PRCM_BASE + 0x1628)
+
+#define INTCPS_SYSCONFIG	0x48200010
+#define CM_SYSCLK10_CLKSEL	0x48180324
+
+struct cm_pll {
+	unsigned int mainpll_ctrl;	/* offset 0x400 */
+	unsigned int mainpll_pwd;
+	unsigned int mainpll_freq1;
+	unsigned int mainpll_div1;
+	unsigned int mainpll_freq2;
+	unsigned int mainpll_div2;
+	unsigned int mainpll_freq3;
+	unsigned int mainpll_div3;
+	unsigned int mainpll_freq4;
+	unsigned int mainpll_div4;
+	unsigned int mainpll_freq5;
+	unsigned int mainpll_div5;
+	unsigned int resv0[1];
+	unsigned int mainpll_div6;
+	unsigned int resv1[1];
+	unsigned int mainpll_div7;
+	unsigned int ddrpll_ctrl;	/* offset 0x440 */
+	unsigned int ddrpll_pwd;
+	unsigned int resv2[1];
+	unsigned int ddrpll_div1;
+	unsigned int ddrpll_freq2;
+	unsigned int ddrpll_div2;
+	unsigned int ddrpll_freq3;
+	unsigned int ddrpll_div3;
+	unsigned int ddrpll_freq4;
+	unsigned int ddrpll_div4;
+	unsigned int ddrpll_freq5;
+	unsigned int ddrpll_div5;
+	unsigned int videopll_ctrl;	/* offset 0x470 */
+	unsigned int videopll_pwd;
+	unsigned int videopll_freq1;
+	unsigned int videopll_div1;
+	unsigned int videopll_freq2;
+	unsigned int videopll_div2;
+	unsigned int videopll_freq3;
+	unsigned int videopll_div3;
+	unsigned int resv3[4];
+	unsigned int audiopll_ctrl;	/* offset 0x4A0 */
+	unsigned int audiopll_pwd;
+	unsigned int resv4[2];
+	unsigned int audiopll_freq2;
+	unsigned int audiopll_div2;
+	unsigned int audiopll_freq3;
+	unsigned int audiopll_div3;
+	unsigned int audiopll_freq4;
+	unsigned int audiopll_div4;
+	unsigned int audiopll_freq5;
+	unsigned int audiopll_div5;
+};
+
+const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE;
+const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE;
+const struct cm_pll *cmpll = (struct cm_pll *)CM_PLL_BASE;
+const struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+
+void enable_dmm_clocks(void)
+{
+	writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl);
+	writel(PRCM_MOD_EN, &cmdef->emif0clkctrl);
+	writel(PRCM_MOD_EN, &cmdef->emif1clkctrl);
+
+	/* Wait for clocks to be active */
+	while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300)
+		;
+	/* Wait for emif0 to be fully functional, including OCP */
+	while (((readl(&cmdef->emif0clkctrl) >> 17) & 0x3) != 0)
+		;
+	/* Wait for emif1 to be fully functional, including OCP */
+	while (((readl(&cmdef->emif1clkctrl) >> 17) & 0x3) != 0)
+		;
+
+	writel(PRCM_MOD_EN, &cmdef->dmmclkctrl);
+	/* Wait for dmm to be fully functional, including OCP */
+	while (((readl(&cmdef->dmmclkctrl) >> 17) & 0x3) != 0)
+		;
+
+	/* Enable Tiled Access */
+	writel(0x80000000, DMM_PAT_BASE_ADDR);
+}
+
+/* assume delay is aprox at least 1us */
+static void ddr_delay(int d)
+{
+	int i;
+
+	/*
+	 * read a control register.
+	 * this is a bit more delay and cannot be optimized by the compiler
+	 * assuming one read takes 200 cycles and A8 is runing 1 GHz
+	 * somewhat conservative setting
+	 */
+	for (i = 0; i < 50*d; i++)
+		readl(CONTROL_STATUS);
+}
+
+static void main_pll_init_ti816x(void)
+{
+	u32 main_pll_ctrl = 0;
+
+	/* Put the PLL in bypass mode by setting BIT2 in its ctrl reg */
+	main_pll_ctrl = readl(&cmpll->mainpll_ctrl);
+	main_pll_ctrl &= 0xFFFFFFFB;
+	main_pll_ctrl |= BIT(2);
+	writel(main_pll_ctrl, &cmpll->mainpll_ctrl);
+
+	/* Enable PLL by setting BIT3 in its ctrl reg */
+	main_pll_ctrl = readl(&cmpll->mainpll_ctrl);
+	main_pll_ctrl &= 0xFFFFFFF7;
+	main_pll_ctrl |= BIT(3);
+	writel(main_pll_ctrl, &cmpll->mainpll_ctrl);
+
+	/* Write the values of N,P in the CTRL reg  */
+	main_pll_ctrl = readl(&cmpll->mainpll_ctrl);
+	main_pll_ctrl &= 0xFF;
+	main_pll_ctrl |= (MAIN_N<<16 | MAIN_P<<8);
+	writel(main_pll_ctrl, &cmpll->mainpll_ctrl);
+
+	/* Power up clock1-7 */
+	writel(0x0, &cmpll->mainpll_pwd);
+
+	/* Program the freq and divider values for clock1-7 */
+	writel((1<<31 | 1<<28 | (MAIN_INTFREQ1<<24) | MAIN_FRACFREQ1),
+		&cmpll->mainpll_freq1);
+	writel(((1<<8) | MAIN_MDIV1), &cmpll->mainpll_div1);
+
+	writel((1<<31 | 1<<28 | (MAIN_INTFREQ2<<24) | MAIN_FRACFREQ2),
+		&cmpll->mainpll_freq2);
+	writel(((1<<8) | MAIN_MDIV2), &cmpll->mainpll_div2);
+
+	writel((1<<31 | 1<<28 | (MAIN_INTFREQ3<<24) | MAIN_FRACFREQ3),
+		&cmpll->mainpll_freq3);
+	writel(((1<<8) | MAIN_MDIV3), &cmpll->mainpll_div3);
+
+	writel((1<<31 | 1<<28 | (MAIN_INTFREQ4<<24) | MAIN_FRACFREQ4),
+		&cmpll->mainpll_freq4);
+	writel(((1<<8) | MAIN_MDIV4), &cmpll->mainpll_div4);
+
+	writel((1<<31 | 1<<28 | (MAIN_INTFREQ5<<24) | MAIN_FRACFREQ5),
+		&cmpll->mainpll_freq5);
+	writel(((1<<8) | MAIN_MDIV5), &cmpll->mainpll_div5);
+
+	writel((1<<8 | MAIN_MDIV6), &cmpll->mainpll_div6);
+
+	writel((1<<8 | MAIN_MDIV7), &cmpll->mainpll_div7);
+
+	/* Wait for PLL to lock */
+	while ((readl(&cmpll->mainpll_ctrl) & BIT(7)) != BIT(7))
+		;
+
+	/* Put the PLL in normal mode, disable bypass */
+	main_pll_ctrl = readl(&cmpll->mainpll_ctrl);
+	main_pll_ctrl &= 0xFFFFFFFB;
+	writel(main_pll_ctrl, &cmpll->mainpll_ctrl);
+}
+
+static void ddr_pll_bypass_ti816x(void)
+{
+	u32 ddr_pll_ctrl = 0;
+
+	/* Put the PLL in bypass mode by setting BIT2 in its ctrl reg */
+	ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl);
+	ddr_pll_ctrl &= 0xFFFFFFFB;
+	ddr_pll_ctrl |= BIT(2);
+	writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl);
+}
+
+static void ddr_pll_init_ti816x(void)
+{
+	u32 ddr_pll_ctrl = 0;
+	/* Enable PLL by setting BIT3 in its ctrl reg */
+	ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl);
+	ddr_pll_ctrl &= 0xFFFFFFF7;
+	ddr_pll_ctrl |= BIT(3);
+	writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl);
+
+	/* Write the values of N,P in the CTRL reg  */
+	ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl);
+	ddr_pll_ctrl &= 0xFF;
+	ddr_pll_ctrl |= (DDR_N<<16 | DDR_P<<8);
+	writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl);
+
+	ddr_delay(10);
+
+	/* Power up clock1-5 */
+	writel(0x0, &cmpll->ddrpll_pwd);
+
+	/* Program the freq and divider values for clock1-3 */
+	writel(((0<<8) | DDR_MDIV1), &cmpll->ddrpll_div1);
+	ddr_delay(1);
+	writel(((1<<8) | DDR_MDIV1), &cmpll->ddrpll_div1);
+	writel((1<<31 | 1<<28 | (DDR_INTFREQ2<<24) | DDR_FRACFREQ2),
+		&cmpll->ddrpll_freq2);
+	writel(((1<<8) | DDR_MDIV2), &cmpll->ddrpll_div2);
+	writel(((0<<8) | DDR_MDIV3), &cmpll->ddrpll_div3);
+	ddr_delay(1);
+	writel(((1<<8) | DDR_MDIV3), &cmpll->ddrpll_div3);
+	ddr_delay(1);
+	writel((0<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3),
+		&cmpll->ddrpll_freq3);
+	ddr_delay(1);
+	writel((1<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3),
+		&cmpll->ddrpll_freq3);
+
+	ddr_delay(5);
+
+	/* Wait for PLL to lock */
+	while ((readl(&cmpll->ddrpll_ctrl) & BIT(7)) != BIT(7))
+		;
+
+	/* Power up RCD */
+	writel(BIT(0), DDR_RCD);
+}
+
+static void peripheral_enable(void)
+{
+	/* Wake-up the l3_slow clock */
+	writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl);
+
+	/*
+	 * Note on Timers:
+	 * There are 8 timers(0-7) out of which timer 0 is a secure timer.
+	 * Timer 0 mux should not be changed
+	 *
+	 * To access the timer registers we need the to be
+	 * enabled which is what we do in the first step
+	 */
+
+	/* Enable timer1 */
+	writel(PRCM_MOD_EN, &cmalwon->timer1clkctrl);
+	/* Select timer1 clock to be CLKIN (27MHz) */
+	writel(BIT(1), CM_TIMER1_CLKSEL);
+
+	/* Wait for timer1 to be ON-ACTIVE */
+	while (((readl(&cmalwon->l3slowclkstctrl)
+					& (0x80000<<1))>>20) != 1)
+		;
+	/* Wait for timer1 to be enabled */
+	while (((readl(&cmalwon->timer1clkctrl) & 0x30000)>>16) != 0)
+		;
+	/* Active posted mode */
+	writel(PRCM_MOD_EN, (DM_TIMER1_BASE + 0x54));
+	while (readl(DM_TIMER1_BASE + 0x10) & BIT(0))
+		;
+	/* Start timer1  */
+	writel(BIT(0), (DM_TIMER1_BASE + 0x38));
+
+	/* eFuse */
+	writel(PRCM_MOD_EN, CM_ALWON_CUST_EFUSE_CLKCTRL);
+	while (readl(CM_ALWON_CUST_EFUSE_CLKCTRL) != PRCM_MOD_EN)
+		;
+
+	/* Enable gpio0 */
+	writel(PRCM_MOD_EN, &cmalwon->gpio0clkctrl);
+	while (readl(&cmalwon->gpio0clkctrl) != PRCM_MOD_EN)
+		;
+	writel((BIT(8)), &cmalwon->gpio0clkctrl);
+
+	/* Enable spi */
+	writel(PRCM_MOD_EN, &cmalwon->spiclkctrl);
+	while (readl(&cmalwon->spiclkctrl) != PRCM_MOD_EN)
+		;
+
+	/* Enable i2c0 */
+	writel(PRCM_MOD_EN, &cmalwon->i2c0clkctrl);
+	while (readl(&cmalwon->i2c0clkctrl) != PRCM_MOD_EN)
+		;
+
+	/* Enable ethernet0 */
+	writel(PRCM_MOD_EN, &cmalwon->ethclkstctrl);
+	writel(PRCM_MOD_EN, &cmalwon->ethernet0clkctrl);
+	writel(PRCM_MOD_EN, &cmalwon->ethernet1clkctrl);
+
+	/* Enable hsmmc */
+	writel(PRCM_MOD_EN, &cmalwon->sdioclkctrl);
+	while (readl(&cmalwon->sdioclkctrl) != PRCM_MOD_EN)
+		;
+}
+
+void setup_clocks_for_console(void)
+{
+	/* Fix ROM code bug - from TI-PSP-04.00.02.14 */
+	writel(0x0, CM_SYSCLK10_CLKSEL);
+
+	ddr_pll_bypass_ti816x();
+
+	/* Enable uart0-2 */
+	writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl);
+	while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN)
+		;
+	writel(PRCM_MOD_EN, &cmalwon->uart1clkctrl);
+	while (readl(&cmalwon->uart1clkctrl) != PRCM_MOD_EN)
+		;
+	writel(PRCM_MOD_EN, &cmalwon->uart2clkctrl);
+	while (readl(&cmalwon->uart2clkctrl) != PRCM_MOD_EN)
+		;
+	while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100)
+		;
+}
+
+void setup_early_clocks(void)
+{
+	setup_clocks_for_console();
+}
+
+void prcm_init(void)
+{
+	/* Enable the control */
+	writel(PRCM_MOD_EN, &cmalwon->controlclkctrl);
+
+	main_pll_init_ti816x();
+	ddr_pll_init_ti816x();
+
+	/*
+	 * With clk freqs setup to desired values,
+	 * enable the required peripherals
+	 */
+	peripheral_enable();
+}
diff --git a/arch/arm/mach-omap2/am33xx/ddr.c b/arch/arm/mach-omap2/am33xx/ddr.c
new file mode 100644
index 0000000..6acf30c
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/ddr.c
@@ -0,0 +1,377 @@
+/*
+ * DDR Configuration for AM33xx devices.
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/arch/cpu.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/emif.h>
+
+/**
+ * Base address for EMIF instances
+ */
+static struct emif_reg_struct *emif_reg[2] = {
+				(struct emif_reg_struct *)EMIF4_0_CFG_BASE,
+				(struct emif_reg_struct *)EMIF4_1_CFG_BASE};
+
+/**
+ * Base addresses for DDR PHY cmd/data regs
+ */
+static struct ddr_cmd_regs *ddr_cmd_reg[2] = {
+				(struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR,
+				(struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2};
+
+static struct ddr_data_regs *ddr_data_reg[2] = {
+				(struct ddr_data_regs *)DDR_PHY_DATA_ADDR,
+				(struct ddr_data_regs *)DDR_PHY_DATA_ADDR2};
+
+/**
+ * Base address for ddr io control instances
+ */
+static struct ddr_cmdtctrl *ioctrl_reg = {
+			(struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR};
+
+static inline u32 get_mr(int nr, u32 cs, u32 mr_addr)
+{
+	u32 mr;
+
+	mr_addr |= cs << EMIF_REG_CS_SHIFT;
+	writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg);
+
+	mr = readl(&emif_reg[nr]->emif_lpddr2_mode_reg_data);
+	debug("get_mr: EMIF1 cs %d mr %08x val 0x%x\n", cs, mr_addr, mr);
+	if (((mr & 0x0000ff00) >>  8) == (mr & 0xff) &&
+	    ((mr & 0x00ff0000) >> 16) == (mr & 0xff) &&
+	    ((mr & 0xff000000) >> 24) == (mr & 0xff))
+		return mr & 0xff;
+	else
+		return mr;
+}
+
+static inline void set_mr(int nr, u32 cs, u32 mr_addr, u32 mr_val)
+{
+	mr_addr |= cs << EMIF_REG_CS_SHIFT;
+	writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg);
+	writel(mr_val, &emif_reg[nr]->emif_lpddr2_mode_reg_data);
+}
+
+static void configure_mr(int nr, u32 cs)
+{
+	u32 mr_addr;
+
+	while (get_mr(nr, cs, LPDDR2_MR0) & LPDDR2_MR0_DAI_MASK)
+		;
+	set_mr(nr, cs, LPDDR2_MR10, 0x56);
+
+	set_mr(nr, cs, LPDDR2_MR1, 0x43);
+	set_mr(nr, cs, LPDDR2_MR2, 0x2);
+
+	mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK;
+	set_mr(nr, cs, mr_addr, 0x2);
+}
+
+/*
+ * Configure EMIF4D5 registers and MR registers For details about these magic
+ * values please see the EMIF registers section of the TRM.
+ */
+void config_sdram_emif4d5(const struct emif_regs *regs, int nr)
+{
+	writel(0xA0, &emif_reg[nr]->emif_pwr_mgmt_ctrl);
+	writel(0xA0, &emif_reg[nr]->emif_pwr_mgmt_ctrl_shdw);
+	writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
+
+	writel(regs->temp_alert_config, &emif_reg[nr]->emif_temp_alert_config);
+	writel(regs->emif_rd_wr_lvl_rmp_win,
+	       &emif_reg[nr]->emif_rd_wr_lvl_rmp_win);
+	writel(regs->emif_rd_wr_lvl_rmp_ctl,
+	       &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl);
+	writel(regs->emif_rd_wr_lvl_ctl, &emif_reg[nr]->emif_rd_wr_lvl_ctl);
+	writel(regs->emif_rd_wr_exec_thresh,
+	       &emif_reg[nr]->emif_rd_wr_exec_thresh);
+
+	/*
+	 * for most SOCs these registers won't need to be changed so only
+	 * write to these registers if someone explicitly has set the
+	 * register's value.
+	 */
+	if(regs->emif_cos_config) {
+		writel(regs->emif_prio_class_serv_map, &emif_reg[nr]->emif_prio_class_serv_map);
+		writel(regs->emif_connect_id_serv_1_map, &emif_reg[nr]->emif_connect_id_serv_1_map);
+		writel(regs->emif_connect_id_serv_2_map, &emif_reg[nr]->emif_connect_id_serv_2_map);
+		writel(regs->emif_cos_config, &emif_reg[nr]->emif_cos_config);
+	}
+
+	/*
+	 * Sequence to ensure that the PHY is in a known state prior to
+	 * startting hardware leveling.  Also acts as to latch some state from
+	 * the EMIF into the PHY.
+	 */
+	writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
+	writel(0x2411, &emif_reg[nr]->emif_iodft_tlgc);
+	writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
+
+	clrbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
+			EMIF_REG_INITREF_DIS_MASK);
+
+	writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
+	writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
+
+	/* Wait 1ms because of L3 timeout error */
+	udelay(1000);
+
+	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
+	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
+
+	/* Perform hardware leveling for DDR3 */
+	if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) {
+		writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) |
+		       0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
+		writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) |
+		       0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
+
+		writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl);
+
+		/* Enable read leveling */
+		writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl);
+
+		/*
+		 * Enable full read and write leveling.  Wait for read and write
+		 * leveling bit to clear RDWRLVLFULL_START bit 31
+		 */
+		while ((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000)
+		      != 0)
+			;
+
+		/* Check the timeout register to see if leveling is complete */
+		if ((readl(&emif_reg[nr]->emif_status) & 0x70) != 0)
+			puts("DDR3 H/W leveling incomplete with errors\n");
+
+	} else {
+		/* DDR2 */
+		configure_mr(nr, 0);
+		configure_mr(nr, 1);
+	}
+}
+
+/**
+ * Configure SDRAM
+ */
+void config_sdram(const struct emif_regs *regs, int nr)
+{
+	if (regs->zq_config) {
+		writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
+		writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
+		writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
+
+		/* Trigger initialization */
+		writel(0x00003100, &emif_reg[nr]->emif_sdram_ref_ctrl);
+		/* Wait 1ms because of L3 timeout error */
+		udelay(1000);
+
+		/* Write proper sdram_ref_cref_ctrl value */
+		writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
+		writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
+	}
+	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
+	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
+	writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
+}
+
+/**
+ * Set SDRAM timings
+ */
+void set_sdram_timings(const struct emif_regs *regs, int nr)
+{
+	writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1);
+	writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1_shdw);
+	writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2);
+	writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2_shdw);
+	writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3);
+	writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw);
+}
+
+/*
+ * Configure EXT PHY registers for software leveling
+ */
+static void ext_phy_settings_swlvl(const struct emif_regs *regs, int nr)
+{
+	u32 *ext_phy_ctrl_base = 0;
+	u32 *emif_ext_phy_ctrl_base = 0;
+	__maybe_unused const u32 *ext_phy_ctrl_const_regs;
+	u32 i = 0;
+	__maybe_unused u32 size;
+
+	ext_phy_ctrl_base = (u32 *)&(regs->emif_ddr_ext_phy_ctrl_1);
+	emif_ext_phy_ctrl_base =
+			(u32 *)&(emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
+
+	/* Configure external phy control timing registers */
+	for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) {
+		writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++);
+		/* Update shadow registers */
+		writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++);
+	}
+
+#ifdef CONFIG_AM43XX
+	/*
+	 * External phy 6-24 registers do not change with ddr frequency.
+	 * These only need to be set on DDR2 on AM43xx.
+	 */
+	emif_get_ext_phy_ctrl_const_regs(&ext_phy_ctrl_const_regs, &size);
+
+	if (!size)
+		return;
+
+	for (i = 0; i < size; i++) {
+		writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++);
+		/* Update shadow registers */
+		writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++);
+	}
+#endif
+}
+
+/*
+ * Configure EXT PHY registers for hardware leveling
+ */
+static void ext_phy_settings_hwlvl(const struct emif_regs *regs, int nr)
+{
+	/*
+	 * Enable hardware leveling on the EMIF.  For details about these
+	 * magic values please see the EMIF registers section of the TRM.
+	 */
+	writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
+	writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1_shdw);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_22);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_22_shdw);
+	writel(0x00600020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_23);
+	writel(0x00600020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_23_shdw);
+	writel(0x40010080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_24);
+	writel(0x40010080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_24_shdw);
+	writel(0x08102040, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_25);
+	writel(0x08102040, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_25_shdw);
+	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_26);
+	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_26_shdw);
+	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_27);
+	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_27_shdw);
+	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_28);
+	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_28_shdw);
+	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_29);
+	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_29_shdw);
+	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_30);
+	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_30_shdw);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_31);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_31_shdw);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_32);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_32_shdw);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_33);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_33_shdw);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_34);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_34_shdw);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_35);
+	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_35_shdw);
+	writel(0x000000FF, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
+	writel(0x000000FF, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
+
+	/*
+	 * Sequence to ensure that the PHY is again in a known state after
+	 * hardware leveling.
+	 */
+	writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
+	writel(0x2411, &emif_reg[nr]->emif_iodft_tlgc);
+	writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
+}
+
+/**
+ * Configure DDR PHY
+ */
+void config_ddr_phy(const struct emif_regs *regs, int nr)
+{
+	/*
+	 * Disable initialization and refreshes for now until we finish
+	 * programming EMIF regs and set time between rising edge of
+	 * DDR_RESET to rising edge of DDR_CKE to > 500us per memory spec.
+	 * We currently hardcode a value based on a max expected frequency
+	 * of 400MHz.
+	 */
+	writel(EMIF_REG_INITREF_DIS_MASK | 0x3100,
+		&emif_reg[nr]->emif_sdram_ref_ctrl);
+
+	writel(regs->emif_ddr_phy_ctlr_1,
+		&emif_reg[nr]->emif_ddr_phy_ctrl_1);
+	writel(regs->emif_ddr_phy_ctlr_1,
+		&emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw);
+
+	if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5) {
+		if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3)
+			ext_phy_settings_hwlvl(regs, nr);
+		else
+			ext_phy_settings_swlvl(regs, nr);
+	}
+}
+
+/**
+ * Configure DDR CMD control registers
+ */
+void config_cmd_ctrl(const struct cmd_control *cmd, int nr)
+{
+	if (!cmd)
+		return;
+
+	writel(cmd->cmd0csratio, &ddr_cmd_reg[nr]->cm0csratio);
+	writel(cmd->cmd0iclkout, &ddr_cmd_reg[nr]->cm0iclkout);
+
+	writel(cmd->cmd1csratio, &ddr_cmd_reg[nr]->cm1csratio);
+	writel(cmd->cmd1iclkout, &ddr_cmd_reg[nr]->cm1iclkout);
+
+	writel(cmd->cmd2csratio, &ddr_cmd_reg[nr]->cm2csratio);
+	writel(cmd->cmd2iclkout, &ddr_cmd_reg[nr]->cm2iclkout);
+}
+
+/**
+ * Configure DDR DATA registers
+ */
+void config_ddr_data(const struct ddr_data *data, int nr)
+{
+	int i;
+
+	if (!data)
+		return;
+
+	for (i = 0; i < DDR_DATA_REGS_NR; i++) {
+		writel(data->datardsratio0,
+			&(ddr_data_reg[nr]+i)->dt0rdsratio0);
+		writel(data->datawdsratio0,
+			&(ddr_data_reg[nr]+i)->dt0wdsratio0);
+		writel(data->datawiratio0,
+			&(ddr_data_reg[nr]+i)->dt0wiratio0);
+		writel(data->datagiratio0,
+			&(ddr_data_reg[nr]+i)->dt0giratio0);
+		writel(data->datafwsratio0,
+			&(ddr_data_reg[nr]+i)->dt0fwsratio0);
+		writel(data->datawrsratio0,
+			&(ddr_data_reg[nr]+i)->dt0wrsratio0);
+	}
+}
+
+void config_io_ctrl(const struct ctrl_ioregs *ioregs)
+{
+	if (!ioregs)
+		return;
+
+	writel(ioregs->cm0ioctl, &ioctrl_reg->cm0ioctl);
+	writel(ioregs->cm1ioctl, &ioctrl_reg->cm1ioctl);
+	writel(ioregs->cm2ioctl, &ioctrl_reg->cm2ioctl);
+	writel(ioregs->dt0ioctl, &ioctrl_reg->dt0ioctl);
+	writel(ioregs->dt1ioctl, &ioctrl_reg->dt1ioctl);
+#ifdef CONFIG_AM43XX
+	writel(ioregs->dt2ioctrl, &ioctrl_reg->dt2ioctrl);
+	writel(ioregs->dt3ioctrl, &ioctrl_reg->dt3ioctrl);
+	writel(ioregs->emif_sdram_config_ext,
+	       &ioctrl_reg->emif_sdram_config_ext);
+#endif
+}
diff --git a/arch/arm/mach-omap2/am33xx/emif4.c b/arch/arm/mach-omap2/am33xx/emif4.c
new file mode 100644
index 0000000..27fa3fb
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/emif4.c
@@ -0,0 +1,140 @@
+/*
+ * emif4.c
+ *
+ * AM33XX emif4 configuration file
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/emif.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+	sdram_init();
+#endif
+
+	/* dram_init must store complete ramsize in gd->ram_size */
+	gd->ram_size = get_ram_size(
+			(void *)CONFIG_SYS_SDRAM_BASE,
+			CONFIG_MAX_RAM_BANK_SIZE);
+	return 0;
+}
+
+void dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+	gd->bd->bi_dram[0].size = gd->ram_size;
+}
+
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+#ifdef CONFIG_TI81XX
+static struct dmm_lisa_map_regs *hw_lisa_map_regs =
+				(struct dmm_lisa_map_regs *)DMM_BASE;
+#endif
+#ifndef CONFIG_TI816X
+static struct vtp_reg *vtpreg[2] = {
+				(struct vtp_reg *)VTP0_CTRL_ADDR,
+				(struct vtp_reg *)VTP1_CTRL_ADDR};
+#endif
+#ifdef CONFIG_AM33XX
+static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
+#endif
+#ifdef CONFIG_AM43XX
+static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
+static struct cm_device_inst *cm_device =
+				(struct cm_device_inst *)CM_DEVICE_INST;
+#endif
+
+#ifdef CONFIG_TI81XX
+void config_dmm(const struct dmm_lisa_map_regs *regs)
+{
+	enable_dmm_clocks();
+
+	writel(0, &hw_lisa_map_regs->dmm_lisa_map_3);
+	writel(0, &hw_lisa_map_regs->dmm_lisa_map_2);
+	writel(0, &hw_lisa_map_regs->dmm_lisa_map_1);
+	writel(0, &hw_lisa_map_regs->dmm_lisa_map_0);
+
+	writel(regs->dmm_lisa_map_3, &hw_lisa_map_regs->dmm_lisa_map_3);
+	writel(regs->dmm_lisa_map_2, &hw_lisa_map_regs->dmm_lisa_map_2);
+	writel(regs->dmm_lisa_map_1, &hw_lisa_map_regs->dmm_lisa_map_1);
+	writel(regs->dmm_lisa_map_0, &hw_lisa_map_regs->dmm_lisa_map_0);
+}
+#endif
+
+#ifndef CONFIG_TI816X
+static void config_vtp(int nr)
+{
+	writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_ENABLE,
+			&vtpreg[nr]->vtp0ctrlreg);
+	writel(readl(&vtpreg[nr]->vtp0ctrlreg) & (~VTP_CTRL_START_EN),
+			&vtpreg[nr]->vtp0ctrlreg);
+	writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_START_EN,
+			&vtpreg[nr]->vtp0ctrlreg);
+
+	/* Poll for READY */
+	while ((readl(&vtpreg[nr]->vtp0ctrlreg) & VTP_CTRL_READY) !=
+			VTP_CTRL_READY)
+		;
+}
+#endif
+
+void __weak ddr_pll_config(unsigned int ddrpll_m)
+{
+}
+
+void config_ddr(unsigned int pll, const struct ctrl_ioregs *ioregs,
+		const struct ddr_data *data, const struct cmd_control *ctrl,
+		const struct emif_regs *regs, int nr)
+{
+	ddr_pll_config(pll);
+#ifndef CONFIG_TI816X
+	config_vtp(nr);
+#endif
+	config_cmd_ctrl(ctrl, nr);
+
+	config_ddr_data(data, nr);
+#ifdef CONFIG_AM33XX
+	config_io_ctrl(ioregs);
+
+	/* Set CKE to be controlled by EMIF/DDR PHY */
+	writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl);
+
+#endif
+#ifdef CONFIG_AM43XX
+	writel(readl(&cm_device->cm_dll_ctrl) & ~0x1, &cm_device->cm_dll_ctrl);
+	while ((readl(&cm_device->cm_dll_ctrl) & CM_DLL_READYST) == 0)
+		;
+
+	config_io_ctrl(ioregs);
+
+	/* Set CKE to be controlled by EMIF/DDR PHY */
+	writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl);
+
+	if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3)
+		/* Allow EMIF to control DDR_RESET */
+		writel(0x00000000, &ddrctrl->ddrioctrl);
+#endif
+
+	/* Program EMIF instance */
+	config_ddr_phy(regs, nr);
+	set_sdram_timings(regs, nr);
+	if (get_emif_rev(EMIF1_BASE) == EMIF_4D5)
+		config_sdram_emif4d5(regs, nr);
+	else
+		config_sdram(regs, nr);
+}
+#endif
diff --git a/arch/arm/mach-omap2/am33xx/mux.c b/arch/arm/mach-omap2/am33xx/mux.c
new file mode 100644
index 0000000..2ded472
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/mux.c
@@ -0,0 +1,33 @@
+/*
+ * mux.c
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+/*
+ * Configure the pin mux for the module
+ */
+void configure_module_pin_mux(struct module_pin_mux *mod_pin_mux)
+{
+	int i;
+
+	if (!mod_pin_mux)
+		return;
+
+	for (i = 0; mod_pin_mux[i].reg_offset != -1; i++)
+		MUX_CFG(mod_pin_mux[i].val, mod_pin_mux[i].reg_offset);
+}
diff --git a/arch/arm/mach-omap2/am33xx/sys_info.c b/arch/arm/mach-omap2/am33xx/sys_info.c
new file mode 100644
index 0000000..f0f72fa
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/sys_info.c
@@ -0,0 +1,176 @@
+/*
+ * sys_info.c
+ *
+ * System information functions
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * Derived from Beagle Board and 3430 SDP code by
+ *      Richard Woodruff <r-woodruff2@ti.com>
+ *      Syed Mohammed Khasim <khasim@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <power/tps65910.h>
+#include <linux/compiler.h>
+
+struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE;
+
+/**
+ * get_cpu_rev(void) - extract rev info
+ */
+u32 get_cpu_rev(void)
+{
+	u32 id;
+	u32 rev;
+
+	id = readl(DEVICE_ID);
+	rev = (id >> 28) & 0xff;
+
+	return rev;
+}
+
+/**
+ * get_cpu_type(void) - extract cpu info
+ */
+u32 get_cpu_type(void)
+{
+	u32 id = 0;
+	u32 partnum;
+
+	id = readl(DEVICE_ID);
+	partnum = (id >> 12) & 0xffff;
+
+	return partnum;
+}
+
+/**
+ * get_device_type(): tell if GP/HS/EMU/TST
+ */
+u32 get_device_type(void)
+{
+	int mode;
+	mode = readl(&cstat->statusreg) & (DEVICE_MASK);
+	return mode >>= 8;
+}
+
+/**
+ * get_sysboot_value(void) - return SYS_BOOT[4:0]
+ */
+u32 get_sysboot_value(void)
+{
+	return readl(&cstat->statusreg) & SYSBOOT_MASK;
+}
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+static char *cpu_revs[] = {
+		"1.0",
+		"2.0",
+		"2.1"};
+
+
+static char *dev_types[] = {
+		"TST",
+		"EMU",
+		"HS",
+		"GP"};
+
+/**
+ * Print CPU information
+ */
+int print_cpuinfo(void)
+{
+	char *cpu_s, *sec_s, *rev_s;
+
+	switch (get_cpu_type()) {
+	case AM335X:
+		cpu_s = "AM335X";
+		break;
+	case TI81XX:
+		cpu_s = "TI81XX";
+		break;
+	case AM437X:
+		cpu_s = "AM437X";
+		break;
+	default:
+		cpu_s = "Unknown CPU type";
+		break;
+	}
+
+	if (get_cpu_rev() < ARRAY_SIZE(cpu_revs))
+		rev_s = cpu_revs[get_cpu_rev()];
+	else
+		rev_s = "?";
+
+	if (get_device_type() < ARRAY_SIZE(dev_types))
+		sec_s = dev_types[get_device_type()];
+	else
+		sec_s = "?";
+
+	printf("CPU  : %s-%s rev %s\n", cpu_s, sec_s, rev_s);
+
+	return 0;
+}
+#endif	/* CONFIG_DISPLAY_CPUINFO */
+
+#ifdef CONFIG_AM33XX
+int am335x_get_efuse_mpu_max_freq(struct ctrl_dev *cdev)
+{
+	int sil_rev;
+
+	sil_rev = readl(&cdev->deviceid) >> 28;
+
+	if (sil_rev == 1)
+		/* PG 2.0, efuse may not be set. */
+		return MPUPLL_M_800;
+	else if (sil_rev >= 2) {
+		/* Check what the efuse says our max speed is. */
+		int efuse_arm_mpu_max_freq;
+		efuse_arm_mpu_max_freq = readl(&cdev->efuse_sma);
+		switch ((efuse_arm_mpu_max_freq & DEVICE_ID_MASK)) {
+		case AM335X_ZCZ_1000:
+			return MPUPLL_M_1000;
+		case AM335X_ZCZ_800:
+			return MPUPLL_M_800;
+		case AM335X_ZCZ_720:
+			return MPUPLL_M_720;
+		case AM335X_ZCZ_600:
+		case AM335X_ZCE_600:
+			return MPUPLL_M_600;
+		case AM335X_ZCZ_300:
+		case AM335X_ZCE_300:
+			return MPUPLL_M_300;
+		}
+	}
+
+	/* PG 1.0 or otherwise unknown, use the PG1.0 max */
+	return MPUPLL_M_720;
+}
+
+int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency)
+{
+	/* For PG2.1 and later, we have one set of values. */
+	if (sil_rev >= 2) {
+		switch (frequency) {
+		case MPUPLL_M_1000:
+			return TPS65910_OP_REG_SEL_1_3_2_5;
+		case MPUPLL_M_800:
+			return TPS65910_OP_REG_SEL_1_2_6;
+		case MPUPLL_M_720:
+			return TPS65910_OP_REG_SEL_1_2_0;
+		case MPUPLL_M_600:
+		case MPUPLL_M_300:
+			return TPS65910_OP_REG_SEL_1_1_3;
+		}
+	}
+
+	/* Default to PG1.0/PG2.0 values. */
+	return TPS65910_OP_REG_SEL_1_1_3;
+}
+#endif
diff --git a/arch/arm/mach-omap2/am33xx/u-boot-spl.lds b/arch/arm/mach-omap2/am33xx/u-boot-spl.lds
new file mode 100644
index 0000000..07cf267
--- /dev/null
+++ b/arch/arm/mach-omap2/am33xx/u-boot-spl.lds
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *	Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
+		LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+		LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	.text      :
+	{
+		__start = .;
+		*(.vectors)
+		arch/arm/cpu/armv7/start.o	(.text)
+		*(.text*)
+	} >.sram
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+	. = ALIGN(4);
+	.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+
+	.u_boot_list : {
+		KEEP(*(SORT(.u_boot_list*)));
+	} >.sram
+
+	. = ALIGN(4);
+	__image_copy_end = .;
+
+	.end :
+	{
+		*(.__end)
+	} >.sram
+
+	.bss :
+	{
+		. = ALIGN(4);
+		__bss_start = .;
+		*(.bss*)
+		. = ALIGN(4);
+		__bss_end = .;
+	} >.sdram
+}
diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c
new file mode 100644
index 0000000..385310b
--- /dev/null
+++ b/arch/arm/mach-omap2/boot-common.c
@@ -0,0 +1,252 @@
+/*
+ * boot-common.c
+ *
+ * Common bootmode functions for omap based boards
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <ahci.h>
+#include <spl.h>
+#include <asm/omap_common.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
+#include <watchdog.h>
+#include <scsi.h>
+#include <i2c.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+__weak u32 omap_sys_boot_device(void)
+{
+	return BOOT_DEVICE_NONE;
+}
+
+void save_omap_boot_params(void)
+{
+	u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
+	struct omap_boot_parameters *omap_boot_params;
+	int sys_boot_device = 0;
+	u32 boot_device;
+	u32 boot_mode;
+
+	if ((boot_params < NON_SECURE_SRAM_START) ||
+	    (boot_params > NON_SECURE_SRAM_END))
+		return;
+
+	omap_boot_params = (struct omap_boot_parameters *)boot_params;
+
+	boot_device = omap_boot_params->boot_device;
+	boot_mode = MMCSD_MODE_UNDEFINED;
+
+	/* Boot device */
+
+#ifdef BOOT_DEVICE_NAND_I2C
+	/*
+	 * Re-map NAND&I2C boot-device to the "normal" NAND boot-device.
+	 * Otherwise the SPL boot IF can't handle this device correctly.
+	 * Somehow booting with Hynix 4GBit NAND H27U4G8 on Siemens
+	 * Draco leads to this boot-device passed to SPL from the BootROM.
+	 */
+	if (boot_device == BOOT_DEVICE_NAND_I2C)
+		boot_device = BOOT_DEVICE_NAND;
+#endif
+#ifdef BOOT_DEVICE_QSPI_4
+	/*
+	 * We get different values for QSPI_1 and QSPI_4 being used, but
+	 * don't actually care about this difference.  Rather than
+	 * mangle the later code, if we're coming in as QSPI_4 just
+	 * change to the QSPI_1 value.
+	 */
+	if (boot_device == BOOT_DEVICE_QSPI_4)
+		boot_device = BOOT_DEVICE_SPI;
+#endif
+	/*
+	 * When booting from peripheral booting, the boot device is not usable
+	 * as-is (unless there is support for it), so the boot device is instead
+	 * figured out using the SYS_BOOT pins.
+	 */
+	switch (boot_device) {
+#if defined(BOOT_DEVICE_UART) && !defined(CONFIG_SPL_YMODEM_SUPPORT)
+		case BOOT_DEVICE_UART:
+			sys_boot_device = 1;
+			break;
+#endif
+#if defined(BOOT_DEVICE_USB) && !defined(CONFIG_SPL_USB_SUPPORT)
+		case BOOT_DEVICE_USB:
+			sys_boot_device = 1;
+			break;
+#endif
+#if defined(BOOT_DEVICE_USBETH) && !defined(CONFIG_SPL_USBETH_SUPPORT)
+		case BOOT_DEVICE_USBETH:
+			sys_boot_device = 1;
+			break;
+#endif
+#if defined(BOOT_DEVICE_CPGMAC) && !defined(CONFIG_SPL_ETH_SUPPORT)
+		case BOOT_DEVICE_CPGMAC:
+			sys_boot_device = 1;
+			break;
+#endif
+#if defined(BOOT_DEVICE_DFU) && !defined(CONFIG_SPL_DFU_SUPPORT)
+		case BOOT_DEVICE_DFU:
+			sys_boot_device = 1;
+			break;
+#endif
+	}
+
+	if (sys_boot_device) {
+		boot_device = omap_sys_boot_device();
+
+		/* MMC raw mode will fallback to FS mode. */
+		if ((boot_device >= MMC_BOOT_DEVICES_START) &&
+		    (boot_device <= MMC_BOOT_DEVICES_END))
+			boot_mode = MMCSD_MODE_RAW;
+	}
+
+	gd->arch.omap_boot_device = boot_device;
+
+	/* Boot mode */
+
+#ifdef CONFIG_OMAP34XX
+	if ((boot_device >= MMC_BOOT_DEVICES_START) &&
+	    (boot_device <= MMC_BOOT_DEVICES_END)) {
+		switch (boot_device) {
+		case BOOT_DEVICE_MMC1:
+			boot_mode = MMCSD_MODE_FS;
+			break;
+		case BOOT_DEVICE_MMC2:
+			boot_mode = MMCSD_MODE_RAW;
+			break;
+		}
+	}
+#else
+	/*
+	 * If the boot device was dynamically changed and doesn't match what
+	 * the bootrom initially booted, we cannot use the boot device
+	 * descriptor to figure out the boot mode.
+	 */
+	if ((boot_device == omap_boot_params->boot_device) &&
+	    (boot_device >= MMC_BOOT_DEVICES_START) &&
+	    (boot_device <= MMC_BOOT_DEVICES_END)) {
+		boot_params = omap_boot_params->boot_device_descriptor;
+		if ((boot_params < NON_SECURE_SRAM_START) ||
+		    (boot_params > NON_SECURE_SRAM_END))
+			return;
+
+		boot_params = *((u32 *)(boot_params + DEVICE_DATA_OFFSET));
+		if ((boot_params < NON_SECURE_SRAM_START) ||
+		    (boot_params > NON_SECURE_SRAM_END))
+			return;
+
+		boot_mode = *((u32 *)(boot_params + BOOT_MODE_OFFSET));
+
+		if (boot_mode != MMCSD_MODE_FS &&
+		    boot_mode != MMCSD_MODE_RAW)
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+			boot_mode = MMCSD_MODE_EMMCBOOT;
+#else
+			boot_mode = MMCSD_MODE_UNDEFINED;
+#endif
+	}
+#endif
+
+	gd->arch.omap_boot_mode = boot_mode;
+
+#if !defined(CONFIG_TI814X) && !defined(CONFIG_TI816X) && \
+    !defined(CONFIG_AM33XX) && !defined(CONFIG_AM43XX)
+
+	/* CH flags */
+
+	gd->arch.omap_ch_flags = omap_boot_params->ch_flags;
+#endif
+}
+
+#ifdef CONFIG_SPL_BUILD
+u32 spl_boot_device(void)
+{
+	return gd->arch.omap_boot_device;
+}
+
+u32 spl_boot_mode(const u32 boot_device)
+{
+	return gd->arch.omap_boot_mode;
+}
+
+void spl_board_init(void)
+{
+	/*
+	 * Save the boot parameters passed from romcode.
+	 * We cannot delay the saving further than this,
+	 * to prevent overwrites.
+	 */
+	save_omap_boot_params();
+
+	/* Prepare console output */
+	preloader_console_init();
+
+#if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
+	gpmc_init();
+#endif
+#ifdef CONFIG_SPL_I2C_SUPPORT
+	i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
+#endif
+#if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)
+	arch_misc_init();
+#endif
+#if defined(CONFIG_HW_WATCHDOG)
+	hw_watchdog_init();
+#endif
+#ifdef CONFIG_AM33XX
+	am33xx_spl_board_init();
+#endif
+}
+
+__weak int board_mmc_init(bd_t *bis)
+{
+	switch (spl_boot_device()) {
+	case BOOT_DEVICE_MMC1:
+		omap_mmc_init(0, 0, 0, -1, -1);
+		break;
+	case BOOT_DEVICE_MMC2:
+	case BOOT_DEVICE_MMC2_2:
+		omap_mmc_init(0, 0, 0, -1, -1);
+		omap_mmc_init(1, 0, 0, -1, -1);
+		break;
+	}
+	return 0;
+}
+
+void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+{
+	typedef void __noreturn (*image_entry_noargs_t)(u32 *);
+	image_entry_noargs_t image_entry =
+			(image_entry_noargs_t) spl_image->entry_point;
+
+	u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
+
+	debug("image entry point: 0x%X\n", spl_image->entry_point);
+	/* Pass the saved boot_params from rom code */
+	image_entry((u32 *)boot_params);
+}
+#endif
+
+#ifdef CONFIG_SCSI_AHCI_PLAT
+void arch_preboot_os(void)
+{
+	ahci_reset((void __iomem *)DWC_AHSATA_BASE);
+}
+#endif
+
+#if defined(CONFIG_USB_FUNCTION_FASTBOOT) && !defined(CONFIG_ENV_IS_NOWHERE)
+int fb_set_reboot_flag(void)
+{
+	printf("Setting reboot to fastboot flag ...\n");
+	setenv("dofastboot", "1");
+	saveenv();
+	return 0;
+}
+#endif
diff --git a/arch/arm/mach-omap2/clocks-common.c b/arch/arm/mach-omap2/clocks-common.c
new file mode 100644
index 0000000..9b97583
--- /dev/null
+++ b/arch/arm/mach-omap2/clocks-common.c
@@ -0,0 +1,892 @@
+/*
+ *
+ * Clock initialization for OMAP4
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.com>
+ *
+ * Based on previous work by:
+ *	Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *	Rajendra Nayak <rnayak@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <i2c.h>
+#include <asm/omap_common.h>
+#include <asm/gpio.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/utils.h>
+#include <asm/omap_gpio.h>
+#include <asm/emif.h>
+
+#ifndef CONFIG_SPL_BUILD
+/*
+ * printing to console doesn't work unless
+ * this code is executed from SPL
+ */
+#define printf(fmt, args...)
+#define puts(s)
+#endif
+
+const u32 sys_clk_array[8] = {
+	12000000,	       /* 12 MHz */
+	20000000,		/* 20 MHz */
+	16800000,	       /* 16.8 MHz */
+	19200000,	       /* 19.2 MHz */
+	26000000,	       /* 26 MHz */
+	27000000,	       /* 27 MHz */
+	38400000,	       /* 38.4 MHz */
+};
+
+static inline u32 __get_sys_clk_index(void)
+{
+	s8 ind;
+	/*
+	 * For ES1 the ROM code calibration of sys clock is not reliable
+	 * due to hw issue. So, use hard-coded value. If this value is not
+	 * correct for any board over-ride this function in board file
+	 * From ES2.0 onwards you will get this information from
+	 * CM_SYS_CLKSEL
+	 */
+	if (omap_revision() == OMAP4430_ES1_0)
+		ind = OMAP_SYS_CLK_IND_38_4_MHZ;
+	else {
+		/* SYS_CLKSEL - 1 to match the dpll param array indices */
+		ind = (readl((*prcm)->cm_sys_clksel) &
+			CM_SYS_CLKSEL_SYS_CLKSEL_MASK) - 1;
+	}
+	return ind;
+}
+
+u32 get_sys_clk_index(void)
+	__attribute__ ((weak, alias("__get_sys_clk_index")));
+
+u32 get_sys_clk_freq(void)
+{
+	u8 index = get_sys_clk_index();
+	return sys_clk_array[index];
+}
+
+void setup_post_dividers(u32 const base, const struct dpll_params *params)
+{
+	struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+
+	/* Setup post-dividers */
+	if (params->m2 >= 0)
+		writel(params->m2, &dpll_regs->cm_div_m2_dpll);
+	if (params->m3 >= 0)
+		writel(params->m3, &dpll_regs->cm_div_m3_dpll);
+	if (params->m4_h11 >= 0)
+		writel(params->m4_h11, &dpll_regs->cm_div_m4_h11_dpll);
+	if (params->m5_h12 >= 0)
+		writel(params->m5_h12, &dpll_regs->cm_div_m5_h12_dpll);
+	if (params->m6_h13 >= 0)
+		writel(params->m6_h13, &dpll_regs->cm_div_m6_h13_dpll);
+	if (params->m7_h14 >= 0)
+		writel(params->m7_h14, &dpll_regs->cm_div_m7_h14_dpll);
+	if (params->h21 >= 0)
+		writel(params->h21, &dpll_regs->cm_div_h21_dpll);
+	if (params->h22 >= 0)
+		writel(params->h22, &dpll_regs->cm_div_h22_dpll);
+	if (params->h23 >= 0)
+		writel(params->h23, &dpll_regs->cm_div_h23_dpll);
+	if (params->h24 >= 0)
+		writel(params->h24, &dpll_regs->cm_div_h24_dpll);
+}
+
+static inline void do_bypass_dpll(u32 const base)
+{
+	struct dpll_regs *dpll_regs = (struct dpll_regs *)base;
+
+	clrsetbits_le32(&dpll_regs->cm_clkmode_dpll,
+			CM_CLKMODE_DPLL_DPLL_EN_MASK,
+			DPLL_EN_FAST_RELOCK_BYPASS <<
+			CM_CLKMODE_DPLL_EN_SHIFT);
+}
+
+static inline void wait_for_bypass(u32 const base)
+{
+	struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+
+	if (!wait_on_value(ST_DPLL_CLK_MASK, 0, &dpll_regs->cm_idlest_dpll,
+				LDELAY)) {
+		printf("Bypassing DPLL failed %x\n", base);
+	}
+}
+
+static inline void do_lock_dpll(u32 const base)
+{
+	struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+
+	clrsetbits_le32(&dpll_regs->cm_clkmode_dpll,
+		      CM_CLKMODE_DPLL_DPLL_EN_MASK,
+		      DPLL_EN_LOCK << CM_CLKMODE_DPLL_EN_SHIFT);
+}
+
+static inline void wait_for_lock(u32 const base)
+{
+	struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+
+	if (!wait_on_value(ST_DPLL_CLK_MASK, ST_DPLL_CLK_MASK,
+		&dpll_regs->cm_idlest_dpll, LDELAY)) {
+		printf("DPLL locking failed for %x\n", base);
+		hang();
+	}
+}
+
+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;
+}
+
+const struct dpll_params *get_mpu_dpll_params(struct dplls const *dpll_data)
+{
+	u32 sysclk_ind = get_sys_clk_index();
+	return &dpll_data->mpu[sysclk_ind];
+}
+
+const struct dpll_params *get_core_dpll_params(struct dplls const *dpll_data)
+{
+	u32 sysclk_ind = get_sys_clk_index();
+	return &dpll_data->core[sysclk_ind];
+}
+
+const struct dpll_params *get_per_dpll_params(struct dplls const *dpll_data)
+{
+	u32 sysclk_ind = get_sys_clk_index();
+	return &dpll_data->per[sysclk_ind];
+}
+
+const struct dpll_params *get_iva_dpll_params(struct dplls const *dpll_data)
+{
+	u32 sysclk_ind = get_sys_clk_index();
+	return &dpll_data->iva[sysclk_ind];
+}
+
+const struct dpll_params *get_usb_dpll_params(struct dplls const *dpll_data)
+{
+	u32 sysclk_ind = get_sys_clk_index();
+	return &dpll_data->usb[sysclk_ind];
+}
+
+const struct dpll_params *get_abe_dpll_params(struct dplls const *dpll_data)
+{
+#ifdef CONFIG_SYS_OMAP_ABE_SYSCK
+	u32 sysclk_ind = get_sys_clk_index();
+	return &dpll_data->abe[sysclk_ind];
+#else
+	return dpll_data->abe;
+#endif
+}
+
+static const struct dpll_params *get_ddr_dpll_params
+			(struct dplls const *dpll_data)
+{
+	u32 sysclk_ind = get_sys_clk_index();
+
+	if (!dpll_data->ddr)
+		return NULL;
+	return &dpll_data->ddr[sysclk_ind];
+}
+
+#ifdef CONFIG_DRIVER_TI_CPSW
+static const struct dpll_params *get_gmac_dpll_params
+			(struct dplls const *dpll_data)
+{
+	u32 sysclk_ind = get_sys_clk_index();
+
+	if (!dpll_data->gmac)
+		return NULL;
+	return &dpll_data->gmac[sysclk_ind];
+}
+#endif
+
+static void do_setup_dpll(u32 const base, const struct dpll_params *params,
+				u8 lock, char *dpll)
+{
+	u32 temp, M, N;
+	struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+
+	if (!params)
+		return;
+
+	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);
+
+			bypass_dpll(base);
+			goto setup_post_dividers;
+		}
+	}
+
+	bypass_dpll(base);
+
+	/* Set M & N */
+	temp &= ~CM_CLKSEL_DPLL_M_MASK;
+	temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK;
+
+	temp &= ~CM_CLKSEL_DPLL_N_MASK;
+	temp |= (params->n << CM_CLKSEL_DPLL_N_SHIFT) & CM_CLKSEL_DPLL_N_MASK;
+
+	writel(temp, &dpll_regs->cm_clksel_dpll);
+
+setup_post_dividers:
+	setup_post_dividers(base, params);
+
+	/* Lock */
+	if (lock)
+		do_lock_dpll(base);
+
+	/* Wait till the DPLL locks */
+	if (lock)
+		wait_for_lock(base);
+}
+
+u32 omap_ddr_clk(void)
+{
+	u32 ddr_clk, sys_clk_khz, omap_rev, divider;
+	const struct dpll_params *core_dpll_params;
+
+	omap_rev = omap_revision();
+	sys_clk_khz = get_sys_clk_freq() / 1000;
+
+	core_dpll_params = get_core_dpll_params(*dplls_data);
+
+	debug("sys_clk %d\n ", sys_clk_khz * 1000);
+
+	/* Find Core DPLL locked frequency first */
+	ddr_clk = sys_clk_khz * 2 * core_dpll_params->m /
+			(core_dpll_params->n + 1);
+
+	if (omap_rev < OMAP5430_ES1_0) {
+		/*
+		 * DDR frequency is PHY_ROOT_CLK/2
+		 * PHY_ROOT_CLK = Fdpll/2/M2
+		 */
+		divider = 4;
+	} else {
+		/*
+		 * DDR frequency is PHY_ROOT_CLK
+		 * PHY_ROOT_CLK = Fdpll/2/M2
+		 */
+		divider = 2;
+	}
+
+	ddr_clk = ddr_clk / divider / core_dpll_params->m2;
+	ddr_clk *= 1000;	/* convert to Hz */
+	debug("ddr_clk %d\n ", ddr_clk);
+
+	return ddr_clk;
+}
+
+/*
+ * Lock MPU dpll
+ *
+ * Resulting MPU frequencies:
+ * 4430 ES1.0	: 600 MHz
+ * 4430 ES2.x	: 792 MHz (OPP Turbo)
+ * 4460		: 920 MHz (OPP Turbo) - DCC disabled
+ */
+void configure_mpu_dpll(void)
+{
+	const struct dpll_params *params;
+	struct dpll_regs *mpu_dpll_regs;
+	u32 omap_rev;
+	omap_rev = omap_revision();
+
+	/*
+	 * DCC and clock divider settings for 4460.
+	 * DCC is required, if more than a certain frequency is required.
+	 * For, 4460 > 1GHZ.
+	 *     5430 > 1.4GHZ.
+	 */
+	if ((omap_rev >= OMAP4460_ES1_0) && (omap_rev < OMAP5430_ES1_0)) {
+		mpu_dpll_regs =
+			(struct dpll_regs *)((*prcm)->cm_clkmode_dpll_mpu);
+		bypass_dpll((*prcm)->cm_clkmode_dpll_mpu);
+		clrbits_le32((*prcm)->cm_mpu_mpu_clkctrl,
+			MPU_CLKCTRL_CLKSEL_EMIF_DIV_MODE_MASK);
+		setbits_le32((*prcm)->cm_mpu_mpu_clkctrl,
+			MPU_CLKCTRL_CLKSEL_ABE_DIV_MODE_MASK);
+		clrbits_le32(&mpu_dpll_regs->cm_clksel_dpll,
+			CM_CLKSEL_DCC_EN_MASK);
+	}
+
+	params = get_mpu_dpll_params(*dplls_data);
+
+	do_setup_dpll((*prcm)->cm_clkmode_dpll_mpu, params, DPLL_LOCK, "mpu");
+	debug("MPU DPLL locked\n");
+}
+
+#if defined(CONFIG_USB_EHCI_OMAP) || defined(CONFIG_USB_XHCI_OMAP) || \
+	defined(CONFIG_USB_MUSB_OMAP2PLUS)
+static void setup_usb_dpll(void)
+{
+	const struct dpll_params *params;
+	u32 sys_clk_khz, sd_div, num, den;
+
+	sys_clk_khz = get_sys_clk_freq() / 1000;
+	/*
+	 * USB:
+	 * USB dpll is J-type. Need to set DPLL_SD_DIV for jitter correction
+	 * DPLL_SD_DIV = CEILING ([DPLL_MULT/(DPLL_DIV+1)]* CLKINP / 250)
+	 *      - where CLKINP is sys_clk in MHz
+	 * Use CLKINP in KHz and adjust the denominator accordingly so
+	 * that we have enough accuracy and at the same time no overflow
+	 */
+	params = get_usb_dpll_params(*dplls_data);
+	num = params->m * sys_clk_khz;
+	den = (params->n + 1) * 250 * 1000;
+	num += den - 1;
+	sd_div = num / den;
+	clrsetbits_le32((*prcm)->cm_clksel_dpll_usb,
+			CM_CLKSEL_DPLL_DPLL_SD_DIV_MASK,
+			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, "usb");
+}
+#endif
+
+static void setup_dplls(void)
+{
+	u32 temp;
+	const struct dpll_params *params;
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
+
+	debug("setup_dplls\n");
+
+	/* CORE dpll */
+	params = get_core_dpll_params(*dplls_data);	/* default - safest */
+	/*
+	 * Do not lock the core DPLL now. Just set it up.
+	 * Core DPLL will be locked after setting up EMIF
+	 * using the FREQ_UPDATE method(freq_update_core())
+	 */
+	if (emif_sdram_type(readl(&emif->emif_sdram_config)) ==
+	    EMIF_SDRAM_TYPE_LPDDR2)
+		do_setup_dpll((*prcm)->cm_clkmode_dpll_core, params,
+							DPLL_NO_LOCK, "core");
+	else
+		do_setup_dpll((*prcm)->cm_clkmode_dpll_core, params,
+							DPLL_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) |
+	    (CLKSEL_L4_L3_DIV_2 << CLKSEL_L4_SHIFT);
+	writel(temp, (*prcm)->cm_clksel_core);
+	debug("Core DPLL configured\n");
+
+	/* lock PER dpll */
+	params = get_per_dpll_params(*dplls_data);
+	do_setup_dpll((*prcm)->cm_clkmode_dpll_per,
+			params, DPLL_LOCK, "per");
+	debug("PER DPLL locked\n");
+
+	/* MPU dpll */
+	configure_mpu_dpll();
+
+#if defined(CONFIG_USB_EHCI_OMAP) || defined(CONFIG_USB_XHCI_OMAP) || \
+	defined(CONFIG_USB_MUSB_OMAP2PLUS)
+	setup_usb_dpll();
+#endif
+	params = get_ddr_dpll_params(*dplls_data);
+	do_setup_dpll((*prcm)->cm_clkmode_dpll_ddrphy,
+		      params, DPLL_LOCK, "ddr");
+
+#ifdef CONFIG_DRIVER_TI_CPSW
+	params = get_gmac_dpll_params(*dplls_data);
+	do_setup_dpll((*prcm)->cm_clkmode_dpll_gmac, params,
+		      DPLL_LOCK, "gmac");
+#endif
+}
+
+u32 get_offset_code(u32 volt_offset, struct pmic_data *pmic)
+{
+	u32 offset_code;
+
+	volt_offset -= pmic->base_offset;
+
+	offset_code = (volt_offset + pmic->step - 1) / pmic->step;
+
+	/*
+	 * Offset codes 1-6 all give the base voltage in Palmas
+	 * Offset code 0 switches OFF the SMPS
+	 */
+	return offset_code + pmic->start_code;
+}
+
+void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic)
+{
+	u32 offset_code;
+	u32 offset = volt_mv;
+	int ret = 0;
+
+	if (!volt_mv)
+		return;
+
+	pmic->pmic_bus_init();
+	/* See if we can first get the GPIO if needed */
+	if (pmic->gpio_en)
+		ret = gpio_request(pmic->gpio, "PMIC_GPIO");
+
+	if (ret < 0) {
+		printf("%s: gpio %d request failed %d\n", __func__,
+							pmic->gpio, ret);
+		return;
+	}
+
+	/* Pull the GPIO low to select SET0 register, while we program SET1 */
+	if (pmic->gpio_en)
+		gpio_direction_output(pmic->gpio, 0);
+
+	/* convert to uV for better accuracy in the calculations */
+	offset *= 1000;
+
+	offset_code = get_offset_code(offset, pmic);
+
+	debug("do_scale_vcore: volt - %d offset_code - 0x%x\n", volt_mv,
+		offset_code);
+
+	if (pmic->pmic_write(pmic->i2c_slave_addr, vcore_reg, offset_code))
+		printf("Scaling voltage failed for 0x%x\n", vcore_reg);
+	if (pmic->gpio_en)
+		gpio_direction_output(pmic->gpio, 1);
+}
+
+static u32 optimize_vcore_voltage(struct volts const *v)
+{
+	u32 val;
+	if (!v->value)
+		return 0;
+	if (!v->efuse.reg)
+		return v->value;
+
+	switch (v->efuse.reg_bits) {
+	case 16:
+		val = readw(v->efuse.reg);
+		break;
+	case 32:
+		val = readl(v->efuse.reg);
+		break;
+	default:
+		printf("Error: efuse 0x%08x bits=%d unknown\n",
+		       v->efuse.reg, v->efuse.reg_bits);
+		return v->value;
+	}
+
+	if (!val) {
+		printf("Error: efuse 0x%08x bits=%d val=0, using %d\n",
+		       v->efuse.reg, v->efuse.reg_bits, v->value);
+		return v->value;
+	}
+
+	debug("%s:efuse 0x%08x bits=%d Vnom=%d, using efuse value %d\n",
+	      __func__, v->efuse.reg, v->efuse.reg_bits, v->value, val);
+	return val;
+}
+
+#ifdef CONFIG_IODELAY_RECALIBRATION
+void __weak recalibrate_iodelay(void)
+{
+}
+#endif
+
+/*
+ * Setup the voltages for the main SoC core power domains.
+ * We start with the maximum voltages allowed here, as set in the corresponding
+ * vcores_data struct, and then scale (usually down) to the fused values that
+ * are retrieved from the SoC. The scaling happens only if the efuse.reg fields
+ * are initialised.
+ * Rail grouping is supported for the DRA7xx SoCs only, therefore the code is
+ * compiled conditionally. Note that the new code writes the scaled (or zeroed)
+ * values back to the vcores_data struct for eventual reuse. Zero values mean
+ * that the corresponding rails are not controlled separately, and are not sent
+ * to the PMIC.
+ */
+void scale_vcores(struct vcores_data const *vcores)
+{
+	int i;
+	struct volts *pv = (struct volts *)vcores;
+	struct volts *px;
+
+	for (i=0; i<(sizeof(struct vcores_data)/sizeof(struct volts)); i++) {
+		debug("%d -> ", pv->value);
+		if (pv->value) {
+			/* Handle non-empty members only */
+			pv->value = optimize_vcore_voltage(pv);
+     			px = (struct volts *)vcores;
+			while (px < pv) {
+				/*
+				 * Scan already handled non-empty members to see
+				 * if we have a group and find the max voltage,
+				 * which is set to the first occurance of the
+				 * particular SMPS; the other group voltages are
+				 * zeroed.
+				 */
+				if (px->value) {
+					if ((pv->pmic->i2c_slave_addr ==
+					     px->pmic->i2c_slave_addr) &&
+					    (pv->addr == px->addr)) {
+					    	/* Same PMIC, same SMPS */
+						if (pv->value > px->value)
+							px->value = pv->value;
+
+						pv->value = 0;
+					}
+		     		}
+				px++;
+			}
+		}
+	     	debug("%d\n", pv->value);
+		pv++;
+	}
+
+	debug("cor: %d\n", vcores->core.value);
+	do_scale_vcore(vcores->core.addr, vcores->core.value, vcores->core.pmic);
+	/*
+	 * IO delay recalibration should be done immediately after
+	 * adjusting AVS voltages for VDD_CORE_L.
+	 * Respective boards should call __recalibrate_iodelay()
+	 * with proper mux, virtual and manual mode configurations.
+	 */
+#ifdef CONFIG_IODELAY_RECALIBRATION
+	recalibrate_iodelay();
+#endif
+
+	debug("mpu: %d\n", vcores->mpu.value);
+	do_scale_vcore(vcores->mpu.addr, vcores->mpu.value, vcores->mpu.pmic);
+	/* Configure MPU ABB LDO after scale */
+	abb_setup(vcores->mpu.efuse.reg,
+		  (*ctrl)->control_wkup_ldovbb_mpu_voltage_ctrl,
+		  (*prcm)->prm_abbldo_mpu_setup,
+		  (*prcm)->prm_abbldo_mpu_ctrl,
+		  (*prcm)->prm_irqstatus_mpu_2,
+		  vcores->mpu.abb_tx_done_mask,
+		  OMAP_ABB_FAST_OPP);
+
+	debug("mm: %d\n", vcores->mm.value);
+	do_scale_vcore(vcores->mm.addr, vcores->mm.value, vcores->mm.pmic);
+	/* Configure MM ABB LDO after scale */
+	abb_setup(vcores->mm.efuse.reg,
+		  (*ctrl)->control_wkup_ldovbb_mm_voltage_ctrl,
+		  (*prcm)->prm_abbldo_mm_setup,
+		  (*prcm)->prm_abbldo_mm_ctrl,
+		  (*prcm)->prm_irqstatus_mpu,
+		  vcores->mm.abb_tx_done_mask,
+		  OMAP_ABB_FAST_OPP);
+
+	debug("gpu: %d\n", vcores->gpu.value);
+	do_scale_vcore(vcores->gpu.addr, vcores->gpu.value, vcores->gpu.pmic);
+	/* Configure GPU ABB LDO after scale */
+	abb_setup(vcores->gpu.efuse.reg,
+		  (*ctrl)->control_wkup_ldovbb_gpu_voltage_ctrl,
+		  (*prcm)->prm_abbldo_gpu_setup,
+		  (*prcm)->prm_abbldo_gpu_ctrl,
+		  (*prcm)->prm_irqstatus_mpu,
+		  vcores->gpu.abb_tx_done_mask,
+		  OMAP_ABB_FAST_OPP);
+	debug("eve: %d\n", vcores->eve.value);
+	do_scale_vcore(vcores->eve.addr, vcores->eve.value, vcores->eve.pmic);
+	/* Configure EVE ABB LDO after scale */
+	abb_setup(vcores->eve.efuse.reg,
+		  (*ctrl)->control_wkup_ldovbb_eve_voltage_ctrl,
+		  (*prcm)->prm_abbldo_eve_setup,
+		  (*prcm)->prm_abbldo_eve_ctrl,
+		  (*prcm)->prm_irqstatus_mpu,
+		  vcores->eve.abb_tx_done_mask,
+		  OMAP_ABB_FAST_OPP);
+	debug("iva: %d\n", vcores->iva.value);
+	do_scale_vcore(vcores->iva.addr, vcores->iva.value, vcores->iva.pmic);
+	/* Configure IVA ABB LDO after scale */
+	abb_setup(vcores->iva.efuse.reg,
+		  (*ctrl)->control_wkup_ldovbb_iva_voltage_ctrl,
+		  (*prcm)->prm_abbldo_iva_setup,
+		  (*prcm)->prm_abbldo_iva_ctrl,
+		  (*prcm)->prm_irqstatus_mpu,
+		  vcores->iva.abb_tx_done_mask,
+		  OMAP_ABB_FAST_OPP);
+}
+
+static inline void enable_clock_domain(u32 const clkctrl_reg, u32 enable_mode)
+{
+	clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
+			enable_mode << CD_CLKCTRL_CLKTRCTRL_SHIFT);
+	debug("Enable clock domain - %x\n", clkctrl_reg);
+}
+
+static inline void disable_clock_domain(u32 const clkctrl_reg)
+{
+	clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
+			CD_CLKCTRL_CLKTRCTRL_SW_SLEEP <<
+			CD_CLKCTRL_CLKTRCTRL_SHIFT);
+	debug("Disable clock domain - %x\n", clkctrl_reg);
+}
+
+static inline void wait_for_clk_enable(u32 clkctrl_addr)
+{
+	u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED;
+	u32 bound = LDELAY;
+
+	while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) ||
+		(idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) {
+
+		clkctrl = readl(clkctrl_addr);
+		idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
+			 MODULE_CLKCTRL_IDLEST_SHIFT;
+		if (--bound == 0) {
+			printf("Clock enable failed for 0x%x idlest 0x%x\n",
+				clkctrl_addr, clkctrl);
+			return;
+		}
+	}
+}
+
+static inline void enable_clock_module(u32 const clkctrl_addr, u32 enable_mode,
+				u32 wait_for_enable)
+{
+	clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK,
+			enable_mode << MODULE_CLKCTRL_MODULEMODE_SHIFT);
+	debug("Enable clock module - %x\n", clkctrl_addr);
+	if (wait_for_enable)
+		wait_for_clk_enable(clkctrl_addr);
+}
+
+static inline void wait_for_clk_disable(u32 clkctrl_addr)
+{
+	u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_FULLY_FUNCTIONAL;
+	u32 bound = LDELAY;
+
+	while ((idlest != MODULE_CLKCTRL_IDLEST_DISABLED)) {
+		clkctrl = readl(clkctrl_addr);
+		idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
+			 MODULE_CLKCTRL_IDLEST_SHIFT;
+		if (--bound == 0) {
+			printf("Clock disable failed for 0x%x idlest 0x%x\n",
+			       clkctrl_addr, clkctrl);
+			return;
+		}
+	}
+}
+
+static inline void disable_clock_module(u32 const clkctrl_addr,
+					u32 wait_for_disable)
+{
+	clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_DISABLE <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+	debug("Disable clock module - %x\n", clkctrl_addr);
+	if (wait_for_disable)
+		wait_for_clk_disable(clkctrl_addr);
+}
+
+void freq_update_core(void)
+{
+	u32 freq_config1 = 0;
+	const struct dpll_params *core_dpll_params;
+	u32 omap_rev = omap_revision();
+
+	core_dpll_params = get_core_dpll_params(*dplls_data);
+	/* Put EMIF clock domain in sw wakeup mode */
+	enable_clock_domain((*prcm)->cm_memif_clkstctrl,
+				CD_CLKCTRL_CLKTRCTRL_SW_WKUP);
+	wait_for_clk_enable((*prcm)->cm_memif_emif_1_clkctrl);
+	wait_for_clk_enable((*prcm)->cm_memif_emif_2_clkctrl);
+
+	freq_config1 = SHADOW_FREQ_CONFIG1_FREQ_UPDATE_MASK |
+	    SHADOW_FREQ_CONFIG1_DLL_RESET_MASK;
+
+	freq_config1 |= (DPLL_EN_LOCK << SHADOW_FREQ_CONFIG1_DPLL_EN_SHIFT) &
+				SHADOW_FREQ_CONFIG1_DPLL_EN_MASK;
+
+	freq_config1 |= (core_dpll_params->m2 <<
+			SHADOW_FREQ_CONFIG1_M2_DIV_SHIFT) &
+			SHADOW_FREQ_CONFIG1_M2_DIV_MASK;
+
+	writel(freq_config1, (*prcm)->cm_shadow_freq_config1);
+	if (!wait_on_value(SHADOW_FREQ_CONFIG1_FREQ_UPDATE_MASK, 0,
+			(u32 *) (*prcm)->cm_shadow_freq_config1, LDELAY)) {
+		puts("FREQ UPDATE procedure failed!!");
+		hang();
+	}
+
+	/*
+	 * Putting EMIF in HW_AUTO is seen to be causing issues with
+	 * EMIF clocks and the master DLL. Keep EMIF in SW_WKUP
+	 * in OMAP5430 ES1.0 silicon
+	 */
+	if (omap_rev != OMAP5430_ES1_0) {
+		/* Put EMIF clock domain back in hw auto mode */
+		enable_clock_domain((*prcm)->cm_memif_clkstctrl,
+					CD_CLKCTRL_CLKTRCTRL_HW_AUTO);
+		wait_for_clk_enable((*prcm)->cm_memif_emif_1_clkctrl);
+		wait_for_clk_enable((*prcm)->cm_memif_emif_2_clkctrl);
+	}
+}
+
+void bypass_dpll(u32 const base)
+{
+	do_bypass_dpll(base);
+	wait_for_bypass(base);
+}
+
+void lock_dpll(u32 const base)
+{
+	do_lock_dpll(base);
+	wait_for_lock(base);
+}
+
+static void setup_clocks_for_console(void)
+{
+	/* Do not add any spl_debug prints in this function */
+	clrsetbits_le32((*prcm)->cm_l4per_clkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
+			CD_CLKCTRL_CLKTRCTRL_SW_WKUP <<
+			CD_CLKCTRL_CLKTRCTRL_SHIFT);
+
+	/* Enable all UARTs - console will be on one of them */
+	clrsetbits_le32((*prcm)->cm_l4per_uart1_clkctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+
+	clrsetbits_le32((*prcm)->cm_l4per_uart2_clkctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+
+	clrsetbits_le32((*prcm)->cm_l4per_uart3_clkctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+
+	clrsetbits_le32((*prcm)->cm_l4per_uart4_clkctrl,
+			MODULE_CLKCTRL_MODULEMODE_MASK,
+			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+			MODULE_CLKCTRL_MODULEMODE_SHIFT);
+
+	clrsetbits_le32((*prcm)->cm_l4per_clkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
+			CD_CLKCTRL_CLKTRCTRL_HW_AUTO <<
+			CD_CLKCTRL_CLKTRCTRL_SHIFT);
+}
+
+void do_enable_clocks(u32 const *clk_domains,
+			    u32 const *clk_modules_hw_auto,
+			    u32 const *clk_modules_explicit_en,
+			    u8 wait_for_enable)
+{
+	u32 i, max = 100;
+
+	/* Put the clock domains in SW_WKUP mode */
+	for (i = 0; (i < max) && clk_domains[i]; i++) {
+		enable_clock_domain(clk_domains[i],
+				    CD_CLKCTRL_CLKTRCTRL_SW_WKUP);
+	}
+
+	/* Clock modules that need to be put in HW_AUTO */
+	for (i = 0; (i < max) && clk_modules_hw_auto[i]; i++) {
+		enable_clock_module(clk_modules_hw_auto[i],
+				    MODULE_CLKCTRL_MODULEMODE_HW_AUTO,
+				    wait_for_enable);
+	};
+
+	/* Clock modules that need to be put in SW_EXPLICIT_EN mode */
+	for (i = 0; (i < max) && clk_modules_explicit_en[i]; i++) {
+		enable_clock_module(clk_modules_explicit_en[i],
+				    MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN,
+				    wait_for_enable);
+	};
+
+	/* Put the clock domains in HW_AUTO mode now */
+	for (i = 0; (i < max) && clk_domains[i]; i++) {
+		enable_clock_domain(clk_domains[i],
+				    CD_CLKCTRL_CLKTRCTRL_HW_AUTO);
+	}
+}
+
+void do_disable_clocks(u32 const *clk_domains,
+			    u32 const *clk_modules_disable,
+			    u8 wait_for_disable)
+{
+	u32 i, max = 100;
+
+
+	/* Clock modules that need to be put in SW_DISABLE */
+	for (i = 0; (i < max) && clk_modules_disable[i]; i++)
+		disable_clock_module(clk_modules_disable[i],
+				     wait_for_disable);
+
+	/* Put the clock domains in SW_SLEEP mode */
+	for (i = 0; (i < max) && clk_domains[i]; i++)
+		disable_clock_domain(clk_domains[i]);
+}
+
+/**
+ * setup_early_clocks() - Setup early clocks needed for SoC
+ *
+ * Setup clocks for console, SPL basic initialization clocks and initialize
+ * the timer. This is invoked prior prcm_init.
+ */
+void setup_early_clocks(void)
+{
+	switch (omap_hw_init_context()) {
+	case OMAP_INIT_CONTEXT_SPL:
+	case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR:
+	case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH:
+		setup_clocks_for_console();
+		enable_basic_clocks();
+		timer_init();
+		/* Fall through */
+	}
+}
+
+void prcm_init(void)
+{
+	switch (omap_hw_init_context()) {
+	case OMAP_INIT_CONTEXT_SPL:
+	case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR:
+	case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH:
+		scale_vcores(*omap_vcores);
+		setup_dplls();
+		setup_warmreset_time();
+		break;
+	default:
+		break;
+	}
+
+	if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context())
+		enable_basic_uboot_clocks();
+}
+
+void gpi2c_init(void)
+{
+	static int gpi2c = 1;
+
+	if (gpi2c) {
+		i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED,
+			 CONFIG_SYS_OMAP24_I2C_SLAVE);
+		gpi2c = 0;
+	}
+}
diff --git a/arch/arm/mach-omap2/config.mk b/arch/arm/mach-omap2/config.mk
new file mode 100644
index 0000000..5368f6b
--- /dev/null
+++ b/arch/arm/mach-omap2/config.mk
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+#
+# SPDX-License-Identifier:      GPL-2.0+
+
+include  $(srctree)/arch/arm/mach-omap2/config_secure.mk
+
+ifdef CONFIG_SPL_BUILD
+ifeq ($(CONFIG_AM33XX)$(CONFIG_TI_SECURE_DEVICE),yy)
+#
+# For booting from SPI use
+# u-boot-spl_HS_SPI_X-LOADER to program flash
+#
+# On AM43XX:
+#
+# For booting spl from all other media use
+# u-boot-spl_HS_ISSW
+#
+# On AM33XX:
+#
+# For booting spl from NAND flash use
+# u-boot-spl_HS_X-LOADER
+#
+# For booting spl from SD/MMC/eMMC media use
+# u-boot-spl_HS_MLO
+#
+# For booting spl over UART, USB, or Ethernet use
+# u-boot-spl_HS_2ND
+#
+# Refer to README.ti-secure for more info
+#
+ALL-y += u-boot-spl_HS_ISSW
+ALL-y += u-boot-spl_HS_SPI_X-LOADER
+ALL-y += u-boot-spl_HS_X-LOADER
+ALL-y += u-boot-spl_HS_MLO
+ALL-y += u-boot-spl_HS_2ND
+else
+ifeq ($(CONFIG_OMAP54XX)$(CONFIG_TI_SECURE_DEVICE),yy)
+ALL-y += u-boot-spl_HS_MLO u-boot-spl_HS_X-LOADER
+else
+ALL-y += MLO
+ifeq ($(CONFIG_AM33XX),y)
+ALL-y += MLO.byteswap
+endif
+endif
+endif
+else
+ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
+ALL-$(CONFIG_QSPI_BOOT) += u-boot_HS_XIP_X-LOADER
+ALL-$(CONFIG_SPL_LOAD_FIT) += u-boot_HS.img
+endif
+ALL-y += u-boot.img
+endif
diff --git a/arch/arm/mach-omap2/config_secure.mk b/arch/arm/mach-omap2/config_secure.mk
new file mode 100644
index 0000000..1122439
--- /dev/null
+++ b/arch/arm/mach-omap2/config_secure.mk
@@ -0,0 +1,113 @@
+#
+# Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+quiet_cmd_mkomapsecimg = MKIMAGE $@
+ifneq ($(TI_SECURE_DEV_PKG),)
+ifneq ($(wildcard $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh),)
+ifneq ($(CONFIG_SPL_BUILD),)
+cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \
+	$(patsubst u-boot-spl_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \
+	$(if $(KBUILD_VERBOSE:1=), >/dev/null)
+else
+cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \
+	$(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \
+	$(if $(KBUILD_VERBOSE:1=), >/dev/null)
+endif
+else
+cmd_mkomapsecimg = echo "WARNING:" \
+	"$(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh not found." \
+	"$@ was NOT created!"
+endif
+else
+cmd_mkomapsecimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \
+	"variable must be defined for TI secure devices. $@ was NOT created!"
+endif
+
+ifdef CONFIG_SPL_LOAD_FIT
+quiet_cmd_omapsecureimg = SECURE  $@
+ifneq ($(TI_SECURE_DEV_PKG),)
+ifneq ($(wildcard $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh),)
+cmd_omapsecureimg = $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh \
+	$< $@ \
+	$(if $(KBUILD_VERBOSE:1=), >/dev/null)
+else
+cmd_omapsecureimg = echo "WARNING:" \
+	"$(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh not found." \
+	"$@ was NOT created!"; cp $< $@
+endif
+else
+cmd_omapsecureimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \
+	"variable must be defined for TI secure devices." \
+	"$@ was NOT created!"; cp $< $@
+endif
+endif
+
+
+# Standard X-LOADER target (QPSI, NOR flash)
+u-boot-spl_HS_X-LOADER: $(obj)/u-boot-spl.bin
+	$(call if_changed,mkomapsecimg)
+
+# For MLO targets (SD card boot) the final file name that is copied to the SD
+# card FAT partition must be MLO, so we make a copy of the output file to a new
+# file with that name
+u-boot-spl_HS_MLO: $(obj)/u-boot-spl.bin
+	$(call if_changed,mkomapsecimg)
+	@if [ -f $@ ]; then \
+		cp -f $@ MLO; \
+	fi
+
+# Standard 2ND target (certain peripheral boot modes)
+u-boot-spl_HS_2ND: $(obj)/u-boot-spl.bin
+	$(call if_changed,mkomapsecimg)
+
+# Standard ULO target (certain peripheral boot modes)
+u-boot-spl_HS_ULO: $(obj)/u-boot-spl.bin
+	$(call if_changed,mkomapsecimg)
+
+# Standard ISSW target (certain devices, various boot modes)
+u-boot-spl_HS_ISSW: $(obj)/u-boot-spl.bin
+	$(call if_changed,mkomapsecimg)
+
+# For SPI flash on AM335x and AM43xx, these require special byte swap handling
+# so we use the SPI_X-LOADER target instead of X-LOADER and let the
+# create-boot-image.sh script handle that
+u-boot-spl_HS_SPI_X-LOADER: $(obj)/u-boot-spl.bin
+	$(call if_changed,mkomapsecimg)
+
+# For supporting single stage XiP QSPI on AM43xx, the image is a full u-boot
+# file, not an SPL. In this case the mkomapsecimg command looks for a
+# u-boot-HS_* prefix
+u-boot_HS_XIP_X-LOADER: $(obj)/u-boot.bin
+	$(call if_changed,mkomapsecimg)
+
+# For supporting the SPL loading and interpreting of FIT images whose
+# components are pre-processed before being integrated into the FIT image in
+# order to secure them in some way
+ifdef CONFIG_SPL_LOAD_FIT
+
+MKIMAGEFLAGS_u-boot_HS.img = -f auto -A $(ARCH) -T firmware -C none -O u-boot \
+	-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
+	-n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" -E \
+	$(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST)))
+
+OF_LIST_TARGETS = $(patsubst %,arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST)))
+$(OF_LIST_TARGETS): dtbs
+
+%_HS.dtb: %.dtb
+	$(call if_changed,omapsecureimg)
+	$(Q)if [ -f $@ ]; then \
+		cp -f $@ $<; \
+	fi
+
+u-boot-nodtb_HS.bin: u-boot-nodtb.bin
+	$(call if_changed,omapsecureimg)
+
+u-boot_HS.img: u-boot-nodtb_HS.bin u-boot.img $(patsubst %.dtb,%_HS.dtb,$(OF_LIST_TARGETS))
+	$(call if_changed,mkimage)
+	$(Q)if [ -f $@ ]; then \
+		cp -f $@ u-boot.img; \
+	fi
+
+endif
diff --git a/arch/arm/mach-omap2/emif-common.c b/arch/arm/mach-omap2/emif-common.c
new file mode 100644
index 0000000..b26984e
--- /dev/null
+++ b/arch/arm/mach-omap2/emif-common.c
@@ -0,0 +1,1504 @@
+/*
+ * EMIF programming
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/emif.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/omap_common.h>
+#include <asm/omap_sec_common.h>
+#include <asm/utils.h>
+#include <linux/compiler.h>
+
+static int emif1_enabled = -1, emif2_enabled = -1;
+
+void set_lpmode_selfrefresh(u32 base)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+	u32 reg;
+
+	reg = readl(&emif->emif_pwr_mgmt_ctrl);
+	reg &= ~EMIF_REG_LP_MODE_MASK;
+	reg |= LP_MODE_SELF_REFRESH << EMIF_REG_LP_MODE_SHIFT;
+	reg &= ~EMIF_REG_SR_TIM_MASK;
+	writel(reg, &emif->emif_pwr_mgmt_ctrl);
+
+	/* dummy read for the new SR_TIM to be loaded */
+	readl(&emif->emif_pwr_mgmt_ctrl);
+}
+
+void force_emif_self_refresh()
+{
+	set_lpmode_selfrefresh(EMIF1_BASE);
+	if (!is_dra72x())
+		set_lpmode_selfrefresh(EMIF2_BASE);
+}
+
+inline u32 emif_num(u32 base)
+{
+	if (base == EMIF1_BASE)
+		return 1;
+	else if (base == EMIF2_BASE)
+		return 2;
+	else
+		return 0;
+}
+
+static inline u32 get_mr(u32 base, u32 cs, u32 mr_addr)
+{
+	u32 mr;
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	mr_addr |= cs << EMIF_REG_CS_SHIFT;
+	writel(mr_addr, &emif->emif_lpddr2_mode_reg_cfg);
+	if (omap_revision() == OMAP4430_ES2_0)
+		mr = readl(&emif->emif_lpddr2_mode_reg_data_es2);
+	else
+		mr = readl(&emif->emif_lpddr2_mode_reg_data);
+	debug("get_mr: EMIF%d cs %d mr %08x val 0x%x\n", emif_num(base),
+	      cs, mr_addr, mr);
+	if (((mr & 0x0000ff00) >>  8) == (mr & 0xff) &&
+	    ((mr & 0x00ff0000) >> 16) == (mr & 0xff) &&
+	    ((mr & 0xff000000) >> 24) == (mr & 0xff))
+		return mr & 0xff;
+	else
+		return mr;
+}
+
+static inline void set_mr(u32 base, u32 cs, u32 mr_addr, u32 mr_val)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	mr_addr |= cs << EMIF_REG_CS_SHIFT;
+	writel(mr_addr, &emif->emif_lpddr2_mode_reg_cfg);
+	writel(mr_val, &emif->emif_lpddr2_mode_reg_data);
+}
+
+void emif_reset_phy(u32 base)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+	u32 iodft;
+
+	iodft = readl(&emif->emif_iodft_tlgc);
+	iodft |= EMIF_REG_RESET_PHY_MASK;
+	writel(iodft, &emif->emif_iodft_tlgc);
+}
+
+static void do_lpddr2_init(u32 base, u32 cs)
+{
+	u32 mr_addr;
+	const struct lpddr2_mr_regs *mr_regs;
+
+	get_lpddr2_mr_regs(&mr_regs);
+	/* Wait till device auto initialization is complete */
+	while (get_mr(base, cs, LPDDR2_MR0) & LPDDR2_MR0_DAI_MASK)
+		;
+	set_mr(base, cs, LPDDR2_MR10, mr_regs->mr10);
+	/*
+	 * tZQINIT = 1 us
+	 * Enough loops assuming a maximum of 2GHz
+	 */
+
+	sdelay(2000);
+
+	set_mr(base, cs, LPDDR2_MR1, mr_regs->mr1);
+	set_mr(base, cs, LPDDR2_MR16, mr_regs->mr16);
+
+	/*
+	 * Enable refresh along with writing MR2
+	 * Encoding of RL in MR2 is (RL - 2)
+	 */
+	mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK;
+	set_mr(base, cs, mr_addr, mr_regs->mr2);
+
+	if (mr_regs->mr3 > 0)
+		set_mr(base, cs, LPDDR2_MR3, mr_regs->mr3);
+}
+
+static void lpddr2_init(u32 base, const struct emif_regs *regs)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	/* Not NVM */
+	clrbits_le32(&emif->emif_lpddr2_nvm_config, EMIF_REG_CS1NVMEN_MASK);
+
+	/*
+	 * Keep REG_INITREF_DIS = 1 to prevent re-initialization of SDRAM
+	 * when EMIF_SDRAM_CONFIG register is written
+	 */
+	setbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_MASK);
+
+	/*
+	 * Set the SDRAM_CONFIG and PHY_CTRL for the
+	 * un-locked frequency & default RL
+	 */
+	writel(regs->sdram_config_init, &emif->emif_sdram_config);
+	writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1);
+
+	do_ext_phy_settings(base, regs);
+
+	do_lpddr2_init(base, CS0);
+	if (regs->sdram_config & EMIF_REG_EBANK_MASK)
+		do_lpddr2_init(base, CS1);
+
+	writel(regs->sdram_config, &emif->emif_sdram_config);
+	writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1);
+
+	/* Enable refresh now */
+	clrbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_MASK);
+
+	}
+
+__weak void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
+{
+}
+
+void emif_update_timings(u32 base, const struct emif_regs *regs)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	if (!is_dra7xx())
+		writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl_shdw);
+	else
+		writel(regs->ref_ctrl_final, &emif->emif_sdram_ref_ctrl_shdw);
+
+	writel(regs->sdram_tim1, &emif->emif_sdram_tim_1_shdw);
+	writel(regs->sdram_tim2, &emif->emif_sdram_tim_2_shdw);
+	writel(regs->sdram_tim3, &emif->emif_sdram_tim_3_shdw);
+	if (omap_revision() == OMAP4430_ES1_0) {
+		/* ES1 bug EMIF should be in force idle during freq_update */
+		writel(0, &emif->emif_pwr_mgmt_ctrl);
+	} else {
+		writel(EMIF_PWR_MGMT_CTRL, &emif->emif_pwr_mgmt_ctrl);
+		writel(EMIF_PWR_MGMT_CTRL_SHDW, &emif->emif_pwr_mgmt_ctrl_shdw);
+	}
+	writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl_shdw);
+	writel(regs->zq_config, &emif->emif_zq_config);
+	writel(regs->temp_alert_config, &emif->emif_temp_alert_config);
+	writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw);
+
+	if ((omap_revision() >= OMAP5430_ES1_0) || is_dra7xx()) {
+		writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_5_LL_0,
+			&emif->emif_l3_config);
+	} else if (omap_revision() >= OMAP4460_ES1_0) {
+		writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_3_LL_0,
+			&emif->emif_l3_config);
+	} else {
+		writel(EMIF_L3_CONFIG_VAL_SYS_10_LL_0,
+			&emif->emif_l3_config);
+	}
+}
+
+#ifndef CONFIG_OMAP44XX
+static void omap5_ddr3_leveling(u32 base, const struct emif_regs *regs)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	/* keep sdram in self-refresh */
+	writel(((LP_MODE_SELF_REFRESH << EMIF_REG_LP_MODE_SHIFT)
+		& EMIF_REG_LP_MODE_MASK), &emif->emif_pwr_mgmt_ctrl);
+	__udelay(130);
+
+	/*
+	 * Set invert_clkout (if activated)--DDR_PHYCTRL_1
+	 * Invert clock adds an additional half cycle delay on the
+	 * command interface.  The additional half cycle, is usually
+	 * meant to enable leveling in the situation that DQS is later
+	 * than CK on the board.It also helps provide some additional
+	 * margin for leveling.
+	 */
+	writel(regs->emif_ddr_phy_ctlr_1,
+	       &emif->emif_ddr_phy_ctrl_1);
+
+	writel(regs->emif_ddr_phy_ctlr_1,
+	       &emif->emif_ddr_phy_ctrl_1_shdw);
+	__udelay(130);
+
+	writel(((LP_MODE_DISABLE << EMIF_REG_LP_MODE_SHIFT)
+	       & EMIF_REG_LP_MODE_MASK), &emif->emif_pwr_mgmt_ctrl);
+
+	/* Launch Full leveling */
+	writel(DDR3_FULL_LVL, &emif->emif_rd_wr_lvl_ctl);
+
+	/* Wait till full leveling is complete */
+	readl(&emif->emif_rd_wr_lvl_ctl);
+	      __udelay(130);
+
+	/* Read data eye leveling no of samples */
+	config_data_eye_leveling_samples(base);
+
+	/*
+	 * Launch 8 incremental WR_LVL- to compensate for
+	 * PHY limitation.
+	 */
+	writel(0x2 << EMIF_REG_WRLVLINC_INT_SHIFT,
+	       &emif->emif_rd_wr_lvl_ctl);
+
+	__udelay(130);
+
+	/* Launch Incremental leveling */
+	writel(DDR3_INC_LVL, &emif->emif_rd_wr_lvl_ctl);
+	       __udelay(130);
+}
+
+static void update_hwleveling_output(u32 base, const struct emif_regs *regs)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+	u32 *emif_ext_phy_ctrl_reg, *emif_phy_status;
+	u32 reg, i, phy;
+
+	emif_phy_status = (u32 *)&emif->emif_ddr_phy_status[7];
+	phy = readl(&emif->emif_ddr_phy_ctrl_1);
+
+	/* Update PHY_REG_RDDQS_RATIO */
+	emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_7;
+	if (!(phy & EMIF_DDR_PHY_CTRL_1_RDLVL_MASK_MASK))
+		for (i = 0; i < PHY_RDDQS_RATIO_REGS; i++) {
+			reg = readl(emif_phy_status++);
+			writel(reg, emif_ext_phy_ctrl_reg++);
+			writel(reg, emif_ext_phy_ctrl_reg++);
+		}
+
+	/* Update PHY_REG_FIFO_WE_SLAVE_RATIO */
+	emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_2;
+	emif_phy_status = (u32 *)&emif->emif_ddr_phy_status[12];
+	if (!(phy & EMIF_DDR_PHY_CTRL_1_RDLVLGATE_MASK_MASK))
+		for (i = 0; i < PHY_FIFO_WE_SLAVE_RATIO_REGS; i++) {
+			reg = readl(emif_phy_status++);
+			writel(reg, emif_ext_phy_ctrl_reg++);
+			writel(reg, emif_ext_phy_ctrl_reg++);
+		}
+
+	/* Update PHY_REG_WR_DQ/DQS_SLAVE_RATIO */
+	emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_12;
+	emif_phy_status = (u32 *)&emif->emif_ddr_phy_status[17];
+	if (!(phy & EMIF_DDR_PHY_CTRL_1_WRLVL_MASK_MASK))
+		for (i = 0; i < PHY_REG_WR_DQ_SLAVE_RATIO_REGS; i++) {
+			reg = readl(emif_phy_status++);
+			writel(reg, emif_ext_phy_ctrl_reg++);
+			writel(reg, emif_ext_phy_ctrl_reg++);
+		}
+
+	/* Disable Leveling */
+	writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1);
+	writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw);
+	writel(0x0, &emif->emif_rd_wr_lvl_rmp_ctl);
+}
+
+static void dra7_ddr3_leveling(u32 base, const struct emif_regs *regs)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	/* Clear Error Status */
+	clrsetbits_le32(&emif->emif_ddr_ext_phy_ctrl_36,
+			EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR,
+			EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR);
+
+	clrsetbits_le32(&emif->emif_ddr_ext_phy_ctrl_36_shdw,
+			EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR,
+			EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR);
+
+	/* Disable refreshed before leveling */
+	clrsetbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_MASK,
+			EMIF_REG_INITREF_DIS_MASK);
+
+	/* Start Full leveling */
+	writel(DDR3_FULL_LVL, &emif->emif_rd_wr_lvl_ctl);
+
+	__udelay(300);
+
+	/* Check for leveling timeout */
+	if (readl(&emif->emif_status) & EMIF_REG_LEVELING_TO_MASK) {
+		printf("Leveling timeout on EMIF%d\n", emif_num(base));
+		return;
+	}
+
+	/* Enable refreshes after leveling */
+	clrbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_MASK);
+
+	debug("HW leveling success\n");
+	/*
+	 * Update slave ratios in EXT_PHY_CTRLx registers
+	 * as per HW leveling output
+	 */
+	update_hwleveling_output(base, regs);
+}
+
+static void dra7_ddr3_init(u32 base, const struct emif_regs *regs)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	if (warm_reset()) {
+		emif_reset_phy(base);
+		writel(0x0, &emif->emif_pwr_mgmt_ctrl);
+	}
+	do_ext_phy_settings(base, regs);
+
+	writel(regs->ref_ctrl | EMIF_REG_INITREF_DIS_MASK,
+	       &emif->emif_sdram_ref_ctrl);
+	/* Update timing registers */
+	writel(regs->sdram_tim1, &emif->emif_sdram_tim_1);
+	writel(regs->sdram_tim2, &emif->emif_sdram_tim_2);
+	writel(regs->sdram_tim3, &emif->emif_sdram_tim_3);
+
+	writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_5_LL_0, &emif->emif_l3_config);
+	writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl);
+	writel(regs->zq_config, &emif->emif_zq_config);
+	writel(regs->temp_alert_config, &emif->emif_temp_alert_config);
+	writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl);
+	writel(regs->emif_rd_wr_lvl_ctl, &emif->emif_rd_wr_lvl_ctl);
+
+	writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1);
+	writel(regs->emif_rd_wr_exec_thresh, &emif->emif_rd_wr_exec_thresh);
+
+	writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl);
+
+	writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
+	writel(regs->sdram_config_init, &emif->emif_sdram_config);
+
+	__udelay(1000);
+
+	writel(regs->ref_ctrl_final, &emif->emif_sdram_ref_ctrl);
+
+	if (regs->emif_rd_wr_lvl_rmp_ctl & EMIF_REG_RDWRLVL_EN_MASK)
+		dra7_ddr3_leveling(base, regs);
+}
+
+static void omap5_ddr3_init(u32 base, const struct emif_regs *regs)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl);
+	writel(regs->sdram_config_init, &emif->emif_sdram_config);
+	/*
+	 * Set SDRAM_CONFIG and PHY control registers to locked frequency
+	 * and RL =7. As the default values of the Mode Registers are not
+	 * defined, contents of mode Registers must be fully initialized.
+	 * H/W takes care of this initialization
+	 */
+	writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1);
+
+	/* Update timing registers */
+	writel(regs->sdram_tim1, &emif->emif_sdram_tim_1);
+	writel(regs->sdram_tim2, &emif->emif_sdram_tim_2);
+	writel(regs->sdram_tim3, &emif->emif_sdram_tim_3);
+
+	writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl);
+
+	writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
+	writel(regs->sdram_config_init, &emif->emif_sdram_config);
+	do_ext_phy_settings(base, regs);
+
+	writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl);
+	omap5_ddr3_leveling(base, regs);
+}
+
+static void ddr3_init(u32 base, const struct emif_regs *regs)
+{
+	if (is_omap54xx())
+		omap5_ddr3_init(base, regs);
+	else
+		dra7_ddr3_init(base, regs);
+}
+#endif
+
+#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
+#define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg))
+
+/*
+ * Organization and refresh requirements for LPDDR2 devices of different
+ * types and densities. Derived from JESD209-2 section 2.4
+ */
+const struct lpddr2_addressing addressing_table[] = {
+	/* Banks tREFIx10     rowx32,rowx16      colx32,colx16	density */
+	{BANKS4, T_REFI_15_6, {ROW_12, ROW_12}, {COL_7, COL_8} },/*64M */
+	{BANKS4, T_REFI_15_6, {ROW_12, ROW_12}, {COL_8, COL_9} },/*128M */
+	{BANKS4, T_REFI_7_8, {ROW_13, ROW_13}, {COL_8, COL_9} },/*256M */
+	{BANKS4, T_REFI_7_8, {ROW_13, ROW_13}, {COL_9, COL_10} },/*512M */
+	{BANKS8, T_REFI_7_8, {ROW_13, ROW_13}, {COL_9, COL_10} },/*1GS4 */
+	{BANKS8, T_REFI_3_9, {ROW_14, ROW_14}, {COL_9, COL_10} },/*2GS4 */
+	{BANKS8, T_REFI_3_9, {ROW_14, ROW_14}, {COL_10, COL_11} },/*4G */
+	{BANKS8, T_REFI_3_9, {ROW_15, ROW_15}, {COL_10, COL_11} },/*8G */
+	{BANKS4, T_REFI_7_8, {ROW_14, ROW_14}, {COL_9, COL_10} },/*1GS2 */
+	{BANKS4, T_REFI_3_9, {ROW_15, ROW_15}, {COL_9, COL_10} },/*2GS2 */
+};
+
+static const u32 lpddr2_density_2_size_in_mbytes[] = {
+	8,			/* 64Mb */
+	16,			/* 128Mb */
+	32,			/* 256Mb */
+	64,			/* 512Mb */
+	128,			/* 1Gb   */
+	256,			/* 2Gb   */
+	512,			/* 4Gb   */
+	1024,			/* 8Gb   */
+	2048,			/* 16Gb  */
+	4096			/* 32Gb  */
+};
+
+/*
+ * Calculate the period of DDR clock from frequency value and set the
+ * denominator and numerator in global variables for easy access later
+ */
+static void set_ddr_clk_period(u32 freq)
+{
+	/*
+	 * period = 1/freq
+	 * period_in_ns = 10^9/freq
+	 */
+	*T_num = 1000000000;
+	*T_den = freq;
+	cancel_out(T_num, T_den, 200);
+
+}
+
+/*
+ * Convert time in nano seconds to number of cycles of DDR clock
+ */
+static inline u32 ns_2_cycles(u32 ns)
+{
+	return ((ns * (*T_den)) + (*T_num) - 1) / (*T_num);
+}
+
+/*
+ * ns_2_cycles with the difference that the time passed is 2 times the actual
+ * value(to avoid fractions). The cycles returned is for the original value of
+ * the timing parameter
+ */
+static inline u32 ns_x2_2_cycles(u32 ns)
+{
+	return ((ns * (*T_den)) + (*T_num) * 2 - 1) / ((*T_num) * 2);
+}
+
+/*
+ * Find addressing table index based on the device's type(S2 or S4) and
+ * density
+ */
+s8 addressing_table_index(u8 type, u8 density, u8 width)
+{
+	u8 index;
+	if ((density > LPDDR2_DENSITY_8Gb) || (width == LPDDR2_IO_WIDTH_8))
+		return -1;
+
+	/*
+	 * Look at the way ADDR_TABLE_INDEX* values have been defined
+	 * in emif.h compared to LPDDR2_DENSITY_* values
+	 * The table is layed out in the increasing order of density
+	 * (ignoring type). The exceptions 1GS2 and 2GS2 have been placed
+	 * at the end
+	 */
+	if ((type == LPDDR2_TYPE_S2) && (density == LPDDR2_DENSITY_1Gb))
+		index = ADDR_TABLE_INDEX1GS2;
+	else if ((type == LPDDR2_TYPE_S2) && (density == LPDDR2_DENSITY_2Gb))
+		index = ADDR_TABLE_INDEX2GS2;
+	else
+		index = density;
+
+	debug("emif: addressing table index %d\n", index);
+
+	return index;
+}
+
+/*
+ * Find the the right timing table from the array of timing
+ * tables of the device using DDR clock frequency
+ */
+static const struct lpddr2_ac_timings *get_timings_table(const struct
+			lpddr2_ac_timings const *const *device_timings,
+			u32 freq)
+{
+	u32 i, temp, freq_nearest;
+	const struct lpddr2_ac_timings *timings = 0;
+
+	emif_assert(freq <= MAX_LPDDR2_FREQ);
+	emif_assert(device_timings);
+
+	/*
+	 * Start with the maximum allowed frequency - that is always safe
+	 */
+	freq_nearest = MAX_LPDDR2_FREQ;
+	/*
+	 * Find the timings table that has the max frequency value:
+	 *   i.  Above or equal to the DDR frequency - safe
+	 *   ii. The lowest that satisfies condition (i) - optimal
+	 */
+	for (i = 0; (i < MAX_NUM_SPEEDBINS) && device_timings[i]; i++) {
+		temp = device_timings[i]->max_freq;
+		if ((temp >= freq) && (temp <= freq_nearest)) {
+			freq_nearest = temp;
+			timings = device_timings[i];
+		}
+	}
+	debug("emif: timings table: %d\n", freq_nearest);
+	return timings;
+}
+
+/*
+ * Finds the value of emif_sdram_config_reg
+ * All parameters are programmed based on the device on CS0.
+ * If there is a device on CS1, it will be same as that on CS0 or
+ * it will be NVM. We don't support NVM yet.
+ * If cs1_device pointer is NULL it is assumed that there is no device
+ * on CS1
+ */
+static u32 get_sdram_config_reg(const struct lpddr2_device_details *cs0_device,
+				const struct lpddr2_device_details *cs1_device,
+				const struct lpddr2_addressing *addressing,
+				u8 RL)
+{
+	u32 config_reg = 0;
+
+	config_reg |=  (cs0_device->type + 4) << EMIF_REG_SDRAM_TYPE_SHIFT;
+	config_reg |=  EMIF_INTERLEAVING_POLICY_MAX_INTERLEAVING <<
+			EMIF_REG_IBANK_POS_SHIFT;
+
+	config_reg |= cs0_device->io_width << EMIF_REG_NARROW_MODE_SHIFT;
+
+	config_reg |= RL << EMIF_REG_CL_SHIFT;
+
+	config_reg |= addressing->row_sz[cs0_device->io_width] <<
+			EMIF_REG_ROWSIZE_SHIFT;
+
+	config_reg |= addressing->num_banks << EMIF_REG_IBANK_SHIFT;
+
+	config_reg |= (cs1_device ? EBANK_CS1_EN : EBANK_CS1_DIS) <<
+			EMIF_REG_EBANK_SHIFT;
+
+	config_reg |= addressing->col_sz[cs0_device->io_width] <<
+			EMIF_REG_PAGESIZE_SHIFT;
+
+	return config_reg;
+}
+
+static u32 get_sdram_ref_ctrl(u32 freq,
+			      const struct lpddr2_addressing *addressing)
+{
+	u32 ref_ctrl = 0, val = 0, freq_khz;
+	freq_khz = freq / 1000;
+	/*
+	 * refresh rate to be set is 'tREFI * freq in MHz
+	 * division by 10000 to account for khz and x10 in t_REFI_us_x10
+	 */
+	val = addressing->t_REFI_us_x10 * freq_khz / 10000;
+	ref_ctrl |= val << EMIF_REG_REFRESH_RATE_SHIFT;
+
+	return ref_ctrl;
+}
+
+static u32 get_sdram_tim_1_reg(const struct lpddr2_ac_timings *timings,
+			       const struct lpddr2_min_tck *min_tck,
+			       const struct lpddr2_addressing *addressing)
+{
+	u32 tim1 = 0, val = 0;
+	val = max(min_tck->tWTR, ns_x2_2_cycles(timings->tWTRx2)) - 1;
+	tim1 |= val << EMIF_REG_T_WTR_SHIFT;
+
+	if (addressing->num_banks == BANKS8)
+		val = (timings->tFAW * (*T_den) + 4 * (*T_num) - 1) /
+							(4 * (*T_num)) - 1;
+	else
+		val = max(min_tck->tRRD, ns_2_cycles(timings->tRRD)) - 1;
+
+	tim1 |= val << EMIF_REG_T_RRD_SHIFT;
+
+	val = ns_2_cycles(timings->tRASmin + timings->tRPab) - 1;
+	tim1 |= val << EMIF_REG_T_RC_SHIFT;
+
+	val = max(min_tck->tRAS_MIN, ns_2_cycles(timings->tRASmin)) - 1;
+	tim1 |= val << EMIF_REG_T_RAS_SHIFT;
+
+	val = max(min_tck->tWR, ns_2_cycles(timings->tWR)) - 1;
+	tim1 |= val << EMIF_REG_T_WR_SHIFT;
+
+	val = max(min_tck->tRCD, ns_2_cycles(timings->tRCD)) - 1;
+	tim1 |= val << EMIF_REG_T_RCD_SHIFT;
+
+	val = max(min_tck->tRP_AB, ns_2_cycles(timings->tRPab)) - 1;
+	tim1 |= val << EMIF_REG_T_RP_SHIFT;
+
+	return tim1;
+}
+
+static u32 get_sdram_tim_2_reg(const struct lpddr2_ac_timings *timings,
+			       const struct lpddr2_min_tck *min_tck)
+{
+	u32 tim2 = 0, val = 0;
+	val = max(min_tck->tCKE, timings->tCKE) - 1;
+	tim2 |= val << EMIF_REG_T_CKE_SHIFT;
+
+	val = max(min_tck->tRTP, ns_x2_2_cycles(timings->tRTPx2)) - 1;
+	tim2 |= val << EMIF_REG_T_RTP_SHIFT;
+
+	/*
+	 * tXSRD = tRFCab + 10 ns. XSRD and XSNR should have the
+	 * same value
+	 */
+	val = ns_2_cycles(timings->tXSR) - 1;
+	tim2 |= val << EMIF_REG_T_XSRD_SHIFT;
+	tim2 |= val << EMIF_REG_T_XSNR_SHIFT;
+
+	val = max(min_tck->tXP, ns_x2_2_cycles(timings->tXPx2)) - 1;
+	tim2 |= val << EMIF_REG_T_XP_SHIFT;
+
+	return tim2;
+}
+
+static u32 get_sdram_tim_3_reg(const struct lpddr2_ac_timings *timings,
+			       const struct lpddr2_min_tck *min_tck,
+			       const struct lpddr2_addressing *addressing)
+{
+	u32 tim3 = 0, val = 0;
+	val = min(timings->tRASmax * 10 / addressing->t_REFI_us_x10 - 1, 0xF);
+	tim3 |= val << EMIF_REG_T_RAS_MAX_SHIFT;
+
+	val = ns_2_cycles(timings->tRFCab) - 1;
+	tim3 |= val << EMIF_REG_T_RFC_SHIFT;
+
+	val = ns_x2_2_cycles(timings->tDQSCKMAXx2) - 1;
+	tim3 |= val << EMIF_REG_T_TDQSCKMAX_SHIFT;
+
+	val = ns_2_cycles(timings->tZQCS) - 1;
+	tim3 |= val << EMIF_REG_ZQ_ZQCS_SHIFT;
+
+	val = max(min_tck->tCKESR, ns_2_cycles(timings->tCKESR)) - 1;
+	tim3 |= val << EMIF_REG_T_CKESR_SHIFT;
+
+	return tim3;
+}
+
+static u32 get_zq_config_reg(const struct lpddr2_device_details *cs1_device,
+			     const struct lpddr2_addressing *addressing,
+			     u8 volt_ramp)
+{
+	u32 zq = 0, val = 0;
+	if (volt_ramp)
+		val =
+		    EMIF_ZQCS_INTERVAL_DVFS_IN_US * 10 /
+		    addressing->t_REFI_us_x10;
+	else
+		val =
+		    EMIF_ZQCS_INTERVAL_NORMAL_IN_US * 10 /
+		    addressing->t_REFI_us_x10;
+	zq |= val << EMIF_REG_ZQ_REFINTERVAL_SHIFT;
+
+	zq |= (REG_ZQ_ZQCL_MULT - 1) << EMIF_REG_ZQ_ZQCL_MULT_SHIFT;
+
+	zq |= (REG_ZQ_ZQINIT_MULT - 1) << EMIF_REG_ZQ_ZQINIT_MULT_SHIFT;
+
+	zq |= REG_ZQ_SFEXITEN_ENABLE << EMIF_REG_ZQ_SFEXITEN_SHIFT;
+
+	/*
+	 * Assuming that two chipselects have a single calibration resistor
+	 * If there are indeed two calibration resistors, then this flag should
+	 * be enabled to take advantage of dual calibration feature.
+	 * This data should ideally come from board files. But considering
+	 * that none of the boards today have calibration resistors per CS,
+	 * it would be an unnecessary overhead.
+	 */
+	zq |= REG_ZQ_DUALCALEN_DISABLE << EMIF_REG_ZQ_DUALCALEN_SHIFT;
+
+	zq |= REG_ZQ_CS0EN_ENABLE << EMIF_REG_ZQ_CS0EN_SHIFT;
+
+	zq |= (cs1_device ? 1 : 0) << EMIF_REG_ZQ_CS1EN_SHIFT;
+
+	return zq;
+}
+
+static u32 get_temp_alert_config(const struct lpddr2_device_details *cs1_device,
+				 const struct lpddr2_addressing *addressing,
+				 u8 is_derated)
+{
+	u32 alert = 0, interval;
+	interval =
+	    TEMP_ALERT_POLL_INTERVAL_MS * 10000 / addressing->t_REFI_us_x10;
+	if (is_derated)
+		interval *= 4;
+	alert |= interval << EMIF_REG_TA_REFINTERVAL_SHIFT;
+
+	alert |= TEMP_ALERT_CONFIG_DEVCT_1 << EMIF_REG_TA_DEVCNT_SHIFT;
+
+	alert |= TEMP_ALERT_CONFIG_DEVWDT_32 << EMIF_REG_TA_DEVWDT_SHIFT;
+
+	alert |= 1 << EMIF_REG_TA_SFEXITEN_SHIFT;
+
+	alert |= 1 << EMIF_REG_TA_CS0EN_SHIFT;
+
+	alert |= (cs1_device ? 1 : 0) << EMIF_REG_TA_CS1EN_SHIFT;
+
+	return alert;
+}
+
+static u32 get_read_idle_ctrl_reg(u8 volt_ramp)
+{
+	u32 idle = 0, val = 0;
+	if (volt_ramp)
+		val = ns_2_cycles(READ_IDLE_INTERVAL_DVFS) / 64 - 1;
+	else
+		/*Maximum value in normal conditions - suggested by hw team */
+		val = 0x1FF;
+	idle |= val << EMIF_REG_READ_IDLE_INTERVAL_SHIFT;
+
+	idle |= EMIF_REG_READ_IDLE_LEN_VAL << EMIF_REG_READ_IDLE_LEN_SHIFT;
+
+	return idle;
+}
+
+static u32 get_ddr_phy_ctrl_1(u32 freq, u8 RL)
+{
+	u32 phy = 0, val = 0;
+
+	phy |= (RL + 2) << EMIF_REG_READ_LATENCY_SHIFT;
+
+	if (freq <= 100000000)
+		val = EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS;
+	else if (freq <= 200000000)
+		val = EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ;
+	else
+		val = EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ;
+	phy |= val << EMIF_REG_DLL_SLAVE_DLY_CTRL_SHIFT;
+
+	/* Other fields are constant magic values. Hardcode them together */
+	phy |= EMIF_DDR_PHY_CTRL_1_BASE_VAL <<
+		EMIF_EMIF_DDR_PHY_CTRL_1_BASE_VAL_SHIFT;
+
+	return phy;
+}
+
+static u32 get_emif_mem_size(u32 base)
+{
+	u32 size_mbytes = 0, temp;
+	struct emif_device_details dev_details;
+	struct lpddr2_device_details cs0_dev_details, cs1_dev_details;
+	u32 emif_nr = emif_num(base);
+
+	emif_reset_phy(base);
+	dev_details.cs0_device_details = emif_get_device_details(emif_nr, CS0,
+						&cs0_dev_details);
+	dev_details.cs1_device_details = emif_get_device_details(emif_nr, CS1,
+						&cs1_dev_details);
+	emif_reset_phy(base);
+
+	if (dev_details.cs0_device_details) {
+		temp = dev_details.cs0_device_details->density;
+		size_mbytes += lpddr2_density_2_size_in_mbytes[temp];
+	}
+
+	if (dev_details.cs1_device_details) {
+		temp = dev_details.cs1_device_details->density;
+		size_mbytes += lpddr2_density_2_size_in_mbytes[temp];
+	}
+	/* convert to bytes */
+	return size_mbytes << 20;
+}
+
+/* Gets the encoding corresponding to a given DMM section size */
+u32 get_dmm_section_size_map(u32 section_size)
+{
+	/*
+	 * Section size mapping:
+	 * 0x0: 16-MiB section
+	 * 0x1: 32-MiB section
+	 * 0x2: 64-MiB section
+	 * 0x3: 128-MiB section
+	 * 0x4: 256-MiB section
+	 * 0x5: 512-MiB section
+	 * 0x6: 1-GiB section
+	 * 0x7: 2-GiB section
+	 */
+	section_size >>= 24; /* divide by 16 MB */
+	return log_2_n_round_down(section_size);
+}
+
+static void emif_calculate_regs(
+		const struct emif_device_details *emif_dev_details,
+		u32 freq, struct emif_regs *regs)
+{
+	u32 temp, sys_freq;
+	const struct lpddr2_addressing *addressing;
+	const struct lpddr2_ac_timings *timings;
+	const struct lpddr2_min_tck *min_tck;
+	const struct lpddr2_device_details *cs0_dev_details =
+					emif_dev_details->cs0_device_details;
+	const struct lpddr2_device_details *cs1_dev_details =
+					emif_dev_details->cs1_device_details;
+	const struct lpddr2_device_timings *cs0_dev_timings =
+					emif_dev_details->cs0_device_timings;
+
+	emif_assert(emif_dev_details);
+	emif_assert(regs);
+	/*
+	 * You can not have a device on CS1 without one on CS0
+	 * So configuring EMIF without a device on CS0 doesn't
+	 * make sense
+	 */
+	emif_assert(cs0_dev_details);
+	emif_assert(cs0_dev_details->type != LPDDR2_TYPE_NVM);
+	/*
+	 * If there is a device on CS1 it should be same type as CS0
+	 * (or NVM. But NVM is not supported in this driver yet)
+	 */
+	emif_assert((cs1_dev_details == NULL) ||
+		    (cs1_dev_details->type == LPDDR2_TYPE_NVM) ||
+		    (cs0_dev_details->type == cs1_dev_details->type));
+	emif_assert(freq <= MAX_LPDDR2_FREQ);
+
+	set_ddr_clk_period(freq);
+
+	/*
+	 * The device on CS0 is used for all timing calculations
+	 * There is only one set of registers for timings per EMIF. So, if the
+	 * second CS(CS1) has a device, it should have the same timings as the
+	 * device on CS0
+	 */
+	timings = get_timings_table(cs0_dev_timings->ac_timings, freq);
+	emif_assert(timings);
+	min_tck = cs0_dev_timings->min_tck;
+
+	temp = addressing_table_index(cs0_dev_details->type,
+				      cs0_dev_details->density,
+				      cs0_dev_details->io_width);
+
+	emif_assert((temp >= 0));
+	addressing = &(addressing_table[temp]);
+	emif_assert(addressing);
+
+	sys_freq = get_sys_clk_freq();
+
+	regs->sdram_config_init = get_sdram_config_reg(cs0_dev_details,
+							cs1_dev_details,
+							addressing, RL_BOOT);
+
+	regs->sdram_config = get_sdram_config_reg(cs0_dev_details,
+						cs1_dev_details,
+						addressing, RL_FINAL);
+
+	regs->ref_ctrl = get_sdram_ref_ctrl(freq, addressing);
+
+	regs->sdram_tim1 = get_sdram_tim_1_reg(timings, min_tck, addressing);
+
+	regs->sdram_tim2 = get_sdram_tim_2_reg(timings, min_tck);
+
+	regs->sdram_tim3 = get_sdram_tim_3_reg(timings, min_tck, addressing);
+
+	regs->read_idle_ctrl = get_read_idle_ctrl_reg(LPDDR2_VOLTAGE_STABLE);
+
+	regs->temp_alert_config =
+	    get_temp_alert_config(cs1_dev_details, addressing, 0);
+
+	regs->zq_config = get_zq_config_reg(cs1_dev_details, addressing,
+					    LPDDR2_VOLTAGE_STABLE);
+
+	regs->emif_ddr_phy_ctlr_1_init =
+			get_ddr_phy_ctrl_1(sys_freq / 2, RL_BOOT);
+
+	regs->emif_ddr_phy_ctlr_1 =
+			get_ddr_phy_ctrl_1(freq, RL_FINAL);
+
+	regs->freq = freq;
+
+	print_timing_reg(regs->sdram_config_init);
+	print_timing_reg(regs->sdram_config);
+	print_timing_reg(regs->ref_ctrl);
+	print_timing_reg(regs->sdram_tim1);
+	print_timing_reg(regs->sdram_tim2);
+	print_timing_reg(regs->sdram_tim3);
+	print_timing_reg(regs->read_idle_ctrl);
+	print_timing_reg(regs->temp_alert_config);
+	print_timing_reg(regs->zq_config);
+	print_timing_reg(regs->emif_ddr_phy_ctlr_1);
+	print_timing_reg(regs->emif_ddr_phy_ctlr_1_init);
+}
+#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */
+
+#ifdef CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION
+const char *get_lpddr2_type(u8 type_id)
+{
+	switch (type_id) {
+	case LPDDR2_TYPE_S4:
+		return "LPDDR2-S4";
+	case LPDDR2_TYPE_S2:
+		return "LPDDR2-S2";
+	default:
+		return NULL;
+	}
+}
+
+const char *get_lpddr2_io_width(u8 width_id)
+{
+	switch (width_id) {
+	case LPDDR2_IO_WIDTH_8:
+		return "x8";
+	case LPDDR2_IO_WIDTH_16:
+		return "x16";
+	case LPDDR2_IO_WIDTH_32:
+		return "x32";
+	default:
+		return NULL;
+	}
+}
+
+const char *get_lpddr2_manufacturer(u32 manufacturer)
+{
+	switch (manufacturer) {
+	case LPDDR2_MANUFACTURER_SAMSUNG:
+		return "Samsung";
+	case LPDDR2_MANUFACTURER_QIMONDA:
+		return "Qimonda";
+	case LPDDR2_MANUFACTURER_ELPIDA:
+		return "Elpida";
+	case LPDDR2_MANUFACTURER_ETRON:
+		return "Etron";
+	case LPDDR2_MANUFACTURER_NANYA:
+		return "Nanya";
+	case LPDDR2_MANUFACTURER_HYNIX:
+		return "Hynix";
+	case LPDDR2_MANUFACTURER_MOSEL:
+		return "Mosel";
+	case LPDDR2_MANUFACTURER_WINBOND:
+		return "Winbond";
+	case LPDDR2_MANUFACTURER_ESMT:
+		return "ESMT";
+	case LPDDR2_MANUFACTURER_SPANSION:
+		return "Spansion";
+	case LPDDR2_MANUFACTURER_SST:
+		return "SST";
+	case LPDDR2_MANUFACTURER_ZMOS:
+		return "ZMOS";
+	case LPDDR2_MANUFACTURER_INTEL:
+		return "Intel";
+	case LPDDR2_MANUFACTURER_NUMONYX:
+		return "Numonyx";
+	case LPDDR2_MANUFACTURER_MICRON:
+		return "Micron";
+	default:
+		return NULL;
+	}
+}
+
+static void display_sdram_details(u32 emif_nr, u32 cs,
+				  struct lpddr2_device_details *device)
+{
+	const char *mfg_str;
+	const char *type_str;
+	char density_str[10];
+	u32 density;
+
+	debug("EMIF%d CS%d\t", emif_nr, cs);
+
+	if (!device) {
+		debug("None\n");
+		return;
+	}
+
+	mfg_str = get_lpddr2_manufacturer(device->manufacturer);
+	type_str = get_lpddr2_type(device->type);
+
+	density = lpddr2_density_2_size_in_mbytes[device->density];
+	if ((density / 1024 * 1024) == density) {
+		density /= 1024;
+		sprintf(density_str, "%d GB", density);
+	} else
+		sprintf(density_str, "%d MB", density);
+	if (mfg_str && type_str)
+		debug("%s\t\t%s\t%s\n", mfg_str, type_str, density_str);
+}
+
+static u8 is_lpddr2_sdram_present(u32 base, u32 cs,
+				  struct lpddr2_device_details *lpddr2_device)
+{
+	u32 mr = 0, temp;
+
+	mr = get_mr(base, cs, LPDDR2_MR0);
+	if (mr > 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	temp = (mr & LPDDR2_MR0_DI_MASK) >> LPDDR2_MR0_DI_SHIFT;
+	if (temp) {
+		/* Not SDRAM */
+		return 0;
+	}
+	temp = (mr & LPDDR2_MR0_DNVI_MASK) >> LPDDR2_MR0_DNVI_SHIFT;
+
+	if (temp) {
+		/* DNV supported - But DNV is only supported for NVM */
+		return 0;
+	}
+
+	mr = get_mr(base, cs, LPDDR2_MR4);
+	if (mr > 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	mr = get_mr(base, cs, LPDDR2_MR5);
+	if (mr > 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	if (!get_lpddr2_manufacturer(mr)) {
+		/* Manufacturer not identified */
+		return 0;
+	}
+	lpddr2_device->manufacturer = mr;
+
+	mr = get_mr(base, cs, LPDDR2_MR6);
+	if (mr >= 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	mr = get_mr(base, cs, LPDDR2_MR7);
+	if (mr >= 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	mr = get_mr(base, cs, LPDDR2_MR8);
+	if (mr >= 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	temp = (mr & MR8_TYPE_MASK) >> MR8_TYPE_SHIFT;
+	if (!get_lpddr2_type(temp)) {
+		/* Not SDRAM */
+		return 0;
+	}
+	lpddr2_device->type = temp;
+
+	temp = (mr & MR8_DENSITY_MASK) >> MR8_DENSITY_SHIFT;
+	if (temp > LPDDR2_DENSITY_32Gb) {
+		/* Density not supported */
+		return 0;
+	}
+	lpddr2_device->density = temp;
+
+	temp = (mr & MR8_IO_WIDTH_MASK) >> MR8_IO_WIDTH_SHIFT;
+	if (!get_lpddr2_io_width(temp)) {
+		/* IO width unsupported value */
+		return 0;
+	}
+	lpddr2_device->io_width = temp;
+
+	/*
+	 * If all the above tests pass we should
+	 * have a device on this chip-select
+	 */
+	return 1;
+}
+
+struct lpddr2_device_details *emif_get_device_details(u32 emif_nr, u8 cs,
+			struct lpddr2_device_details *lpddr2_dev_details)
+{
+	u32 phy;
+	u32 base = (emif_nr == 1) ? EMIF1_BASE : EMIF2_BASE;
+
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	if (!lpddr2_dev_details)
+		return NULL;
+
+	/* Do the minimum init for mode register accesses */
+	if (!(running_from_sdram() || warm_reset())) {
+		phy = get_ddr_phy_ctrl_1(get_sys_clk_freq() / 2, RL_BOOT);
+		writel(phy, &emif->emif_ddr_phy_ctrl_1);
+	}
+
+	if (!(is_lpddr2_sdram_present(base, cs, lpddr2_dev_details)))
+		return NULL;
+
+	display_sdram_details(emif_num(base), cs, lpddr2_dev_details);
+
+	return lpddr2_dev_details;
+}
+#endif /* CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION */
+
+static void do_sdram_init(u32 base)
+{
+	const struct emif_regs *regs;
+	u32 in_sdram, emif_nr;
+
+	debug(">>do_sdram_init() %x\n", base);
+
+	in_sdram = running_from_sdram();
+	emif_nr = (base == EMIF1_BASE) ? 1 : 2;
+
+#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
+	emif_get_reg_dump(emif_nr, &regs);
+	if (!regs) {
+		debug("EMIF: reg dump not provided\n");
+		return;
+	}
+#else
+	/*
+	 * The user has not provided the register values. We need to
+	 * calculate it based on the timings and the DDR frequency
+	 */
+	struct emif_device_details dev_details;
+	struct emif_regs calculated_regs;
+
+	/*
+	 * Get device details:
+	 * - Discovered if CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION is set
+	 * - Obtained from user otherwise
+	 */
+	struct lpddr2_device_details cs0_dev_details, cs1_dev_details;
+	emif_reset_phy(base);
+	dev_details.cs0_device_details = emif_get_device_details(emif_nr, CS0,
+						&cs0_dev_details);
+	dev_details.cs1_device_details = emif_get_device_details(emif_nr, CS1,
+						&cs1_dev_details);
+	emif_reset_phy(base);
+
+	/* Return if no devices on this EMIF */
+	if (!dev_details.cs0_device_details &&
+	    !dev_details.cs1_device_details) {
+		return;
+	}
+
+	/*
+	 * Get device timings:
+	 * - Default timings specified by JESD209-2 if
+	 *   CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS is set
+	 * - Obtained from user otherwise
+	 */
+	emif_get_device_timings(emif_nr, &dev_details.cs0_device_timings,
+				&dev_details.cs1_device_timings);
+
+	/* Calculate the register values */
+	emif_calculate_regs(&dev_details, omap_ddr_clk(), &calculated_regs);
+	regs = &calculated_regs;
+#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */
+
+	/*
+	 * Initializing the DDR device can not happen from SDRAM.
+	 * Changing the timing registers in EMIF can happen(going from one
+	 * OPP to another)
+	 */
+	if (!in_sdram && (!warm_reset() || is_dra7xx())) {
+		if (emif_sdram_type(regs->sdram_config) ==
+		    EMIF_SDRAM_TYPE_LPDDR2)
+			lpddr2_init(base, regs);
+#ifndef CONFIG_OMAP44XX
+		else
+			ddr3_init(base, regs);
+#endif
+	}
+#ifdef CONFIG_OMAP54X
+	if (warm_reset() && (emif_sdram_type(regs->sdram_config) ==
+	    EMIF_SDRAM_TYPE_DDR3) && !is_dra7xx()) {
+		set_lpmode_selfrefresh(base);
+		emif_reset_phy(base);
+		omap5_ddr3_leveling(base, regs);
+	}
+#endif
+
+	/* Write to the shadow registers */
+	emif_update_timings(base, regs);
+
+	debug("<<do_sdram_init() %x\n", base);
+}
+
+void emif_post_init_config(u32 base)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+	u32 omap_rev = omap_revision();
+
+	/* reset phy on ES2.0 */
+	if (omap_rev == OMAP4430_ES2_0)
+		emif_reset_phy(base);
+
+	/* Put EMIF back in smart idle on ES1.0 */
+	if (omap_rev == OMAP4430_ES1_0)
+		writel(0x80000000, &emif->emif_pwr_mgmt_ctrl);
+}
+
+void dmm_init(u32 base)
+{
+	const struct dmm_lisa_map_regs *lisa_map_regs;
+	u32 i, section, valid;
+
+#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
+	emif_get_dmm_regs(&lisa_map_regs);
+#else
+	u32 emif1_size, emif2_size, mapped_size, section_map = 0;
+	u32 section_cnt, sys_addr;
+	struct dmm_lisa_map_regs lis_map_regs_calculated = {0};
+
+	mapped_size = 0;
+	section_cnt = 3;
+	sys_addr = CONFIG_SYS_SDRAM_BASE;
+	emif1_size = get_emif_mem_size(EMIF1_BASE);
+	emif2_size = get_emif_mem_size(EMIF2_BASE);
+	debug("emif1_size 0x%x emif2_size 0x%x\n", emif1_size, emif2_size);
+
+	if (!emif1_size && !emif2_size)
+		return;
+
+	/* symmetric interleaved section */
+	if (emif1_size && emif2_size) {
+		mapped_size = min(emif1_size, emif2_size);
+		section_map = DMM_LISA_MAP_INTERLEAVED_BASE_VAL;
+		section_map |= 0 << EMIF_SDRC_ADDR_SHIFT;
+		/* only MSB */
+		section_map |= (sys_addr >> 24) <<
+				EMIF_SYS_ADDR_SHIFT;
+		section_map |= get_dmm_section_size_map(mapped_size * 2)
+				<< EMIF_SYS_SIZE_SHIFT;
+		lis_map_regs_calculated.dmm_lisa_map_3 = section_map;
+		emif1_size -= mapped_size;
+		emif2_size -= mapped_size;
+		sys_addr += (mapped_size * 2);
+		section_cnt--;
+	}
+
+	/*
+	 * Single EMIF section(we can have a maximum of 1 single EMIF
+	 * section- either EMIF1 or EMIF2 or none, but not both)
+	 */
+	if (emif1_size) {
+		section_map = DMM_LISA_MAP_EMIF1_ONLY_BASE_VAL;
+		section_map |= get_dmm_section_size_map(emif1_size)
+				<< EMIF_SYS_SIZE_SHIFT;
+		/* only MSB */
+		section_map |= (mapped_size >> 24) <<
+				EMIF_SDRC_ADDR_SHIFT;
+		/* only MSB */
+		section_map |= (sys_addr >> 24) << EMIF_SYS_ADDR_SHIFT;
+		section_cnt--;
+	}
+	if (emif2_size) {
+		section_map = DMM_LISA_MAP_EMIF2_ONLY_BASE_VAL;
+		section_map |= get_dmm_section_size_map(emif2_size) <<
+				EMIF_SYS_SIZE_SHIFT;
+		/* only MSB */
+		section_map |= mapped_size >> 24 << EMIF_SDRC_ADDR_SHIFT;
+		/* only MSB */
+		section_map |= sys_addr >> 24 << EMIF_SYS_ADDR_SHIFT;
+		section_cnt--;
+	}
+
+	if (section_cnt == 2) {
+		/* Only 1 section - either symmetric or single EMIF */
+		lis_map_regs_calculated.dmm_lisa_map_3 = section_map;
+		lis_map_regs_calculated.dmm_lisa_map_2 = 0;
+		lis_map_regs_calculated.dmm_lisa_map_1 = 0;
+	} else {
+		/* 2 sections - 1 symmetric, 1 single EMIF */
+		lis_map_regs_calculated.dmm_lisa_map_2 = section_map;
+		lis_map_regs_calculated.dmm_lisa_map_1 = 0;
+	}
+
+	/* TRAP for invalid TILER mappings in section 0 */
+	lis_map_regs_calculated.dmm_lisa_map_0 = DMM_LISA_MAP_0_INVAL_ADDR_TRAP;
+
+	if (omap_revision() >= OMAP4460_ES1_0)
+		lis_map_regs_calculated.is_ma_present = 1;
+
+	lisa_map_regs = &lis_map_regs_calculated;
+#endif
+	struct dmm_lisa_map_regs *hw_lisa_map_regs =
+	    (struct dmm_lisa_map_regs *)base;
+
+	writel(0, &hw_lisa_map_regs->dmm_lisa_map_3);
+	writel(0, &hw_lisa_map_regs->dmm_lisa_map_2);
+	writel(0, &hw_lisa_map_regs->dmm_lisa_map_1);
+	writel(0, &hw_lisa_map_regs->dmm_lisa_map_0);
+
+	writel(lisa_map_regs->dmm_lisa_map_3,
+		&hw_lisa_map_regs->dmm_lisa_map_3);
+	writel(lisa_map_regs->dmm_lisa_map_2,
+		&hw_lisa_map_regs->dmm_lisa_map_2);
+	writel(lisa_map_regs->dmm_lisa_map_1,
+		&hw_lisa_map_regs->dmm_lisa_map_1);
+	writel(lisa_map_regs->dmm_lisa_map_0,
+		&hw_lisa_map_regs->dmm_lisa_map_0);
+
+	if (lisa_map_regs->is_ma_present) {
+		hw_lisa_map_regs =
+		    (struct dmm_lisa_map_regs *)MA_BASE;
+
+		writel(lisa_map_regs->dmm_lisa_map_3,
+			&hw_lisa_map_regs->dmm_lisa_map_3);
+		writel(lisa_map_regs->dmm_lisa_map_2,
+			&hw_lisa_map_regs->dmm_lisa_map_2);
+		writel(lisa_map_regs->dmm_lisa_map_1,
+			&hw_lisa_map_regs->dmm_lisa_map_1);
+		writel(lisa_map_regs->dmm_lisa_map_0,
+			&hw_lisa_map_regs->dmm_lisa_map_0);
+
+		setbits_le32(MA_PRIORITY, MA_HIMEM_INTERLEAVE_UN_MASK);
+	}
+
+	/*
+	 * EMIF should be configured only when
+	 * memory is mapped on it. Using emif1_enabled
+	 * and emif2_enabled variables for this.
+	 */
+	emif1_enabled = 0;
+	emif2_enabled = 0;
+	for (i = 0; i < 4; i++) {
+		section	= __raw_readl(DMM_BASE + i*4);
+		valid = (section & EMIF_SDRC_MAP_MASK) >>
+			(EMIF_SDRC_MAP_SHIFT);
+		if (valid == 3) {
+			emif1_enabled = 1;
+			emif2_enabled = 1;
+			break;
+		}
+
+		if (valid == 1)
+			emif1_enabled = 1;
+
+		if (valid == 2)
+			emif2_enabled = 1;
+	}
+}
+
+static void do_bug0039_workaround(u32 base)
+{
+	u32 val, i, clkctrl;
+	struct emif_reg_struct *emif_base = (struct emif_reg_struct *)base;
+	const struct read_write_regs *bug_00339_regs;
+	u32 iterations;
+	u32 *phy_status_base = &emif_base->emif_ddr_phy_status[0];
+	u32 *phy_ctrl_base = &emif_base->emif_ddr_ext_phy_ctrl_1;
+
+	if (is_dra7xx())
+		phy_status_base++;
+
+	bug_00339_regs = get_bug_regs(&iterations);
+
+	/* Put EMIF in to idle */
+	clkctrl = __raw_readl((*prcm)->cm_memif_clkstctrl);
+	__raw_writel(0x0, (*prcm)->cm_memif_clkstctrl);
+
+	/* Copy the phy status registers in to phy ctrl shadow registers */
+	for (i = 0; i < iterations; i++) {
+		val = __raw_readl(phy_status_base +
+				  bug_00339_regs[i].read_reg - 1);
+
+		__raw_writel(val, phy_ctrl_base +
+			     ((bug_00339_regs[i].write_reg - 1) << 1));
+
+		__raw_writel(val, phy_ctrl_base +
+			     (bug_00339_regs[i].write_reg << 1) - 1);
+	}
+
+	/* Disable leveling */
+	writel(0x0, &emif_base->emif_rd_wr_lvl_rmp_ctl);
+
+	__raw_writel(clkctrl,  (*prcm)->cm_memif_clkstctrl);
+}
+
+/*
+ * SDRAM initialization:
+ * SDRAM initialization has two parts:
+ * 1. Configuring the SDRAM device
+ * 2. Update the AC timings related parameters in the EMIF module
+ * (1) should be done only once and should not be done while we are
+ * running from SDRAM.
+ * (2) can and should be done more than once if OPP changes.
+ * Particularly, this may be needed when we boot without SPL and
+ * and using Configuration Header(CH). ROM code supports only at 50% OPP
+ * at boot (low power boot). So u-boot has to switch to OPP100 and update
+ * the frequency. So,
+ * Doing (1) and (2) makes sense - first time initialization
+ * Doing (2) and not (1) makes sense - OPP change (when using CH)
+ * Doing (1) and not (2) doen't make sense
+ * See do_sdram_init() for the details
+ */
+void sdram_init(void)
+{
+	u32 in_sdram, size_prog, size_detect;
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
+	u32 sdram_type = emif_sdram_type(emif->emif_sdram_config);
+
+	debug(">>sdram_init()\n");
+
+	if (omap_hw_init_context() == OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL)
+		return;
+
+	in_sdram = running_from_sdram();
+	debug("in_sdram = %d\n", in_sdram);
+
+	if (!in_sdram) {
+		if ((sdram_type == EMIF_SDRAM_TYPE_LPDDR2) && !warm_reset())
+			bypass_dpll((*prcm)->cm_clkmode_dpll_core);
+		else if (sdram_type == EMIF_SDRAM_TYPE_DDR3)
+			writel(CM_DLL_CTRL_NO_OVERRIDE, (*prcm)->cm_dll_ctrl);
+	}
+
+	if (!in_sdram)
+		dmm_init(DMM_BASE);
+
+	if (emif1_enabled)
+		do_sdram_init(EMIF1_BASE);
+
+	if (emif2_enabled)
+		do_sdram_init(EMIF2_BASE);
+
+	if (!(in_sdram || warm_reset())) {
+		if (emif1_enabled)
+			emif_post_init_config(EMIF1_BASE);
+		if (emif2_enabled)
+			emif_post_init_config(EMIF2_BASE);
+	}
+
+	/* for the shadow registers to take effect */
+	if (sdram_type == EMIF_SDRAM_TYPE_LPDDR2)
+		freq_update_core();
+
+	/* Do some testing after the init */
+	if (!in_sdram) {
+		size_prog = omap_sdram_size();
+		size_prog = log_2_n_round_down(size_prog);
+		size_prog = (1 << size_prog);
+
+		size_detect = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
+						size_prog);
+		/* Compare with the size programmed */
+		if (size_detect != size_prog) {
+			printf("SDRAM: identified size not same as expected"
+				" size identified: %x expected: %x\n",
+				size_detect,
+				size_prog);
+		} else
+			debug("get_ram_size() successful");
+	}
+
+#if defined(CONFIG_TI_SECURE_DEVICE)
+	/*
+	 * On HS devices, do static EMIF firewall configuration
+	 * but only do it if not already running in SDRAM
+	 */
+	if (!in_sdram)
+		if (0 != secure_emif_reserve())
+			hang();
+
+	/* On HS devices, ensure static EMIF firewall APIs are locked */
+	if (0 != secure_emif_firewall_lock())
+		hang();
+#endif
+
+	if (sdram_type == EMIF_SDRAM_TYPE_DDR3 &&
+	    (!in_sdram && !warm_reset()) && (!is_dra7xx())) {
+		if (emif1_enabled)
+			do_bug0039_workaround(EMIF1_BASE);
+		if (emif2_enabled)
+			do_bug0039_workaround(EMIF2_BASE);
+	}
+
+	debug("<<sdram_init()\n");
+}
diff --git a/arch/arm/mach-omap2/hwinit-common.c b/arch/arm/mach-omap2/hwinit-common.c
new file mode 100644
index 0000000..f317293
--- /dev/null
+++ b/arch/arm/mach-omap2/hwinit-common.c
@@ -0,0 +1,296 @@
+/*
+ *
+ * Common functions for OMAP4/5 based boards
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *	Aneesh V	<aneesh@ti.com>
+ *	Steve Sakoman	<steve@sakoman.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <spl.h>
+#include <asm/arch/sys_proto.h>
+#include <linux/sizes.h>
+#include <asm/emif.h>
+#include <asm/omap_common.h>
+#include <linux/compiler.h>
+#include <asm/system.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void do_set_mux(u32 base, struct pad_conf_entry const *array, int size)
+{
+	int i;
+	struct pad_conf_entry *pad = (struct pad_conf_entry *) array;
+
+	for (i = 0; i < size; i++, pad++)
+		writew(pad->val, base + pad->offset);
+}
+
+static void set_mux_conf_regs(void)
+{
+	switch (omap_hw_init_context()) {
+	case OMAP_INIT_CONTEXT_SPL:
+		set_muxconf_regs();
+		break;
+	case OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL:
+		break;
+	case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR:
+	case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH:
+		set_muxconf_regs();
+		break;
+	}
+}
+
+u32 cortex_rev(void)
+{
+
+	unsigned int rev;
+
+	/* Read Main ID Register (MIDR) */
+	asm ("mrc p15, 0, %0, c0, c0, 0" : "=r" (rev));
+
+	return rev;
+}
+
+static void omap_rev_string(void)
+{
+	u32 omap_rev = omap_revision();
+	u32 soc_variant	= (omap_rev & 0xF0000000) >> 28;
+	u32 omap_variant = (omap_rev & 0xFFFF0000) >> 16;
+	u32 major_rev = (omap_rev & 0x00000F00) >> 8;
+	u32 minor_rev = (omap_rev & 0x000000F0) >> 4;
+
+	const char *sec_s;
+
+	switch (get_device_type()) {
+	case TST_DEVICE:
+		sec_s = "TST";
+		break;
+	case EMU_DEVICE:
+		sec_s = "EMU";
+		break;
+	case HS_DEVICE:
+		sec_s = "HS";
+		break;
+	case GP_DEVICE:
+		sec_s = "GP";
+		break;
+	default:
+		sec_s = "?";
+	}
+
+	if (soc_variant)
+		printf("OMAP");
+	else
+		printf("DRA");
+	printf("%x-%s ES%x.%x\n", omap_variant, sec_s, major_rev, minor_rev);
+}
+
+#ifdef CONFIG_SPL_BUILD
+void spl_display_print(void)
+{
+	omap_rev_string();
+}
+#endif
+
+void __weak srcomp_enable(void)
+{
+}
+
+/**
+ * do_board_detect() - Detect board description
+ *
+ * Function to detect board description. This is expected to be
+ * overridden in the SoC family board file where desired.
+ */
+void __weak do_board_detect(void)
+{
+}
+
+/**
+ * vcores_init() - Assign omap_vcores based on board
+ *
+ * Function to pick the vcores based on board. This is expected to be
+ * overridden in the SoC family board file where desired.
+ */
+void __weak vcores_init(void)
+{
+}
+
+void s_init(void)
+{
+}
+
+/**
+ * early_system_init - Does Early system initialization.
+ *
+ * Does early system init of watchdog, muxing,  andclocks
+ * Watchdog disable is done always. For the rest what gets done
+ * depends on the boot mode in which this function is executed when
+ *   1. SPL running from SRAM
+ *   2. U-Boot running from FLASH
+ *   3. U-Boot loaded to SDRAM by SPL
+ *   4. U-Boot loaded to SDRAM by ROM code using the
+ *	Configuration Header feature
+ * Please have a look at the respective functions to see what gets
+ * done in each of these cases
+ * This function is called with SRAM stack.
+ */
+void early_system_init(void)
+{
+	init_omap_revision();
+	hw_data_init();
+
+#ifdef CONFIG_SPL_BUILD
+	if (warm_reset())
+		force_emif_self_refresh();
+#endif
+	watchdog_init();
+	set_mux_conf_regs();
+#ifdef CONFIG_SPL_BUILD
+	srcomp_enable();
+	do_io_settings();
+#endif
+	setup_early_clocks();
+	do_board_detect();
+	vcores_init();
+	prcm_init();
+}
+
+#ifdef CONFIG_SPL_BUILD
+void board_init_f(ulong dummy)
+{
+	early_system_init();
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+	board_early_init_f();
+#endif
+	/* For regular u-boot sdram_init() is called from dram_init() */
+	sdram_init();
+}
+#endif
+
+int arch_cpu_init_dm(void)
+{
+	early_system_init();
+	return 0;
+}
+
+/*
+ * Routine: wait_for_command_complete
+ * Description: Wait for posting to finish on watchdog
+ */
+void wait_for_command_complete(struct watchdog *wd_base)
+{
+	int pending = 1;
+	do {
+		pending = readl(&wd_base->wwps);
+	} while (pending);
+}
+
+/*
+ * Routine: watchdog_init
+ * Description: Shut down watch dogs
+ */
+void watchdog_init(void)
+{
+	struct watchdog *wd2_base = (struct watchdog *)WDT2_BASE;
+
+	writel(WD_UNLOCK1, &wd2_base->wspr);
+	wait_for_command_complete(wd2_base);
+	writel(WD_UNLOCK2, &wd2_base->wspr);
+}
+
+
+/*
+ * This function finds the SDRAM size available in the system
+ * based on DMM section configurations
+ * This is needed because the size of memory installed may be
+ * different on different versions of the board
+ */
+u32 omap_sdram_size(void)
+{
+	u32 section, i, valid;
+	u64 sdram_start = 0, sdram_end = 0, addr,
+	    size, total_size = 0, trap_size = 0, trap_start = 0;
+
+	for (i = 0; i < 4; i++) {
+		section	= __raw_readl(DMM_BASE + i*4);
+		valid = (section & EMIF_SDRC_ADDRSPC_MASK) >>
+			(EMIF_SDRC_ADDRSPC_SHIFT);
+		addr = section & EMIF_SYS_ADDR_MASK;
+
+		/* See if the address is valid */
+		if ((addr >= TI_ARMV7_DRAM_ADDR_SPACE_START) &&
+		    (addr < TI_ARMV7_DRAM_ADDR_SPACE_END)) {
+			size = ((section & EMIF_SYS_SIZE_MASK) >>
+				   EMIF_SYS_SIZE_SHIFT);
+			size = 1 << size;
+			size *= SZ_16M;
+
+			if (valid != DMM_SDRC_ADDR_SPC_INVALID) {
+				if (!sdram_start || (addr < sdram_start))
+					sdram_start = addr;
+				if (!sdram_end || ((addr + size) > sdram_end))
+					sdram_end = addr + size;
+			} else {
+				trap_size = size;
+				trap_start = addr;
+			}
+		}
+	}
+
+	if ((trap_start >= sdram_start) && (trap_start < sdram_end))
+		total_size = (sdram_end - sdram_start) - (trap_size);
+	else
+		total_size = sdram_end - sdram_start;
+
+	return total_size;
+}
+
+
+/*
+ * Routine: dram_init
+ * Description: sets uboots idea of sdram size
+ */
+int dram_init(void)
+{
+	sdram_init();
+	gd->ram_size = omap_sdram_size();
+	return 0;
+}
+
+/*
+ * Print board information
+ */
+int checkboard(void)
+{
+	puts(sysinfo.board_string);
+	return 0;
+}
+
+/*
+ *  get_device_type(): tell if GP/HS/EMU/TST
+ */
+u32 get_device_type(void)
+{
+	return (readl((*ctrl)->control_status) &
+				      (DEVICE_TYPE_MASK)) >> DEVICE_TYPE_SHIFT;
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+/*
+ * Print CPU information
+ */
+int print_cpuinfo(void)
+{
+	puts("CPU  : ");
+	omap_rev_string();
+
+	return 0;
+}
+#endif
diff --git a/arch/arm/mach-omap2/lowlevel_init.S b/arch/arm/mach-omap2/lowlevel_init.S
new file mode 100644
index 0000000..8ce12c8
--- /dev/null
+++ b/arch/arm/mach-omap2/lowlevel_init.S
@@ -0,0 +1,90 @@
+/*
+ * Board specific setup info
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *	Aneesh V	<aneesh@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <asm/arch/omap.h>
+#include <asm/omap_common.h>
+#include <asm/arch/spl.h>
+#include <linux/linkage.h>
+
+.arch_extension sec
+
+#ifdef CONFIG_SPL
+ENTRY(save_boot_params)
+	ldr	r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS
+	str	r0, [r1]
+	b	save_boot_params_ret
+ENDPROC(save_boot_params)
+
+#if !defined(CONFIG_TI_SECURE_DEVICE) && defined(CONFIG_ARMV7_LPAE)
+ENTRY(switch_to_hypervisor)
+
+/*
+ * Switch to hypervisor mode
+ */
+	adr	r0, save_sp
+	str	sp, [r0]
+	adr	r1, restore_from_hyp
+	ldr	r0, =0x102
+	b	omap_smc1
+restore_from_hyp:
+	adr	r0, save_sp
+	ldr	sp, [r0]
+	MRC p15, 4, R0, c1, c0, 0
+	ldr     r1, =0X1004	@Set cache enable bits for hypervisor mode
+	orr     r0, r0, r1
+	MCR p15, 4, R0, c1, c0, 0
+	b	switch_to_hypervisor_ret
+save_sp:
+	.word	0x0
+ENDPROC(switch_to_hypervisor)
+#endif
+#endif
+
+ENTRY(omap_smc1)
+	push	{r4-r12, lr}	@ save registers - ROM code may pollute
+				@ our registers
+	mov	r12, r0		@ Service
+	mov	r0, r1		@ Argument
+
+	dsb
+	dmb
+	smc	0		@ SMC #0 to enter monitor mode
+				@ call ROM Code API for the service requested
+	pop	{r4-r12, pc}
+ENDPROC(omap_smc1)
+
+ENTRY(omap_smc_sec)
+	push	{r4-r12, lr}	@ save registers - ROM code may pollute
+				@ our registers
+	mov	r6, #0xFF	@ Indicate new Task call
+	mov	r12, #0x00	@ Secure Service ID in R12
+
+	dsb
+	dmb
+	smc	0		@ SMC #0 to enter monitor mode
+
+	b	omap_smc_sec_end @ exit at end of the service execution
+	nop
+
+	@ In case of IRQ happening in Secure, then ARM will branch here.
+	@ At that moment, IRQ will be pending and ARM will jump to Non Secure
+	@ IRQ handler
+	mov	r12, #0xFE
+
+	dsb
+	dmb
+	smc	0		@ SMC #0 to enter monitor mode
+
+omap_smc_sec_end:
+	pop	{r4-r12, pc}
+ENDPROC(omap_smc_sec)
diff --git a/arch/arm/mach-omap2/mem-common.c b/arch/arm/mach-omap2/mem-common.c
new file mode 100644
index 0000000..d72e82e
--- /dev/null
+++ b/arch/arm/mach-omap2/mem-common.c
@@ -0,0 +1,174 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *     Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * Initial Code from:
+ *     Manikandan Pillai <mani.pillai@ti.com>
+ *     Richard Woodruff <r-woodruff2@ti.com>
+ *     Syed Mohammed Khasim <khasim@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/sys_proto.h>
+#include <command.h>
+#include <linux/mtd/omap_gpmc.h>
+#include <jffs2/load_kernel.h>
+
+const struct gpmc *gpmc_cfg = (struct gpmc *)GPMC_BASE;
+
+#if defined(CONFIG_NOR)
+char gpmc_cs0_flash = MTD_DEV_TYPE_NOR;
+#elif defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+char gpmc_cs0_flash = MTD_DEV_TYPE_NAND;
+#elif defined(CONFIG_CMD_ONENAND)
+char gpmc_cs0_flash = MTD_DEV_TYPE_ONENAND;
+#else
+char gpmc_cs0_flash = -1;
+#endif
+
+#if defined(CONFIG_OMAP34XX)
+/********************************************************
+ *  mem_ok() - test used to see if timings are correct
+ *             for a part. Helps in guessing which part
+ *             we are currently using.
+ *******************************************************/
+u32 mem_ok(u32 cs)
+{
+	u32 val1, val2, addr;
+	u32 pattern = 0x12345678;
+
+	addr = OMAP34XX_SDRC_CS0 + get_sdr_cs_offset(cs);
+
+	writel(0x0, addr + 0x400);	/* clear pos A */
+	writel(pattern, addr);		/* pattern to pos B */
+	writel(0x0, addr + 4);		/* remove pattern off the bus */
+	val1 = readl(addr + 0x400);	/* get pos A value */
+	val2 = readl(addr);		/* get val2 */
+	writel(0x0, addr + 0x400);	/* clear pos A */
+
+	if ((val1 != 0) || (val2 != pattern))	/* see if pos A val changed */
+		return 0;
+	else
+		return 1;
+}
+#endif
+
+void enable_gpmc_cs_config(const u32 *gpmc_config, const struct gpmc_cs *cs,
+				u32 base, u32 size)
+{
+	writel(0, &cs->config7);
+	sdelay(1000);
+	/* Delay for settling */
+	writel(gpmc_config[0], &cs->config1);
+	writel(gpmc_config[1], &cs->config2);
+	writel(gpmc_config[2], &cs->config3);
+	writel(gpmc_config[3], &cs->config4);
+	writel(gpmc_config[4], &cs->config5);
+	writel(gpmc_config[5], &cs->config6);
+	/* Enable the config */
+	writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) |
+		(1 << 6)), &cs->config7);
+	sdelay(2000);
+}
+
+void set_gpmc_cs0(int flash_type)
+{
+	const u32 *gpmc_regs;
+	u32 base, size;
+#if defined(CONFIG_NOR)
+	const u32 gpmc_regs_nor[GPMC_MAX_REG] = {
+		STNOR_GPMC_CONFIG1,
+		STNOR_GPMC_CONFIG2,
+		STNOR_GPMC_CONFIG3,
+		STNOR_GPMC_CONFIG4,
+		STNOR_GPMC_CONFIG5,
+		STNOR_GPMC_CONFIG6,
+		STNOR_GPMC_CONFIG7
+	};
+#endif
+#if defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+	const u32 gpmc_regs_nand[GPMC_MAX_REG] = {
+		M_NAND_GPMC_CONFIG1,
+		M_NAND_GPMC_CONFIG2,
+		M_NAND_GPMC_CONFIG3,
+		M_NAND_GPMC_CONFIG4,
+		M_NAND_GPMC_CONFIG5,
+		M_NAND_GPMC_CONFIG6,
+		0
+	};
+#endif
+#if defined(CONFIG_CMD_ONENAND)
+	const u32 gpmc_regs_onenand[GPMC_MAX_REG] = {
+		ONENAND_GPMC_CONFIG1,
+		ONENAND_GPMC_CONFIG2,
+		ONENAND_GPMC_CONFIG3,
+		ONENAND_GPMC_CONFIG4,
+		ONENAND_GPMC_CONFIG5,
+		ONENAND_GPMC_CONFIG6,
+		0
+	};
+#endif
+
+	switch (flash_type) {
+#if defined(CONFIG_NOR)
+	case MTD_DEV_TYPE_NOR:
+		gpmc_regs = gpmc_regs_nor;
+		base = CONFIG_SYS_FLASH_BASE;
+		size = (CONFIG_SYS_FLASH_SIZE > 0x08000000) ? GPMC_SIZE_256M :
+		      ((CONFIG_SYS_FLASH_SIZE > 0x04000000) ? GPMC_SIZE_128M :
+		      ((CONFIG_SYS_FLASH_SIZE > 0x02000000) ? GPMC_SIZE_64M  :
+		      ((CONFIG_SYS_FLASH_SIZE > 0x01000000) ? GPMC_SIZE_32M  :
+		                                              GPMC_SIZE_16M)));
+		break;
+#endif
+#if defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+	case MTD_DEV_TYPE_NAND:
+		gpmc_regs = gpmc_regs_nand;
+		base = CONFIG_SYS_NAND_BASE;
+		size = GPMC_SIZE_16M;
+		break;
+#endif
+#if defined(CONFIG_CMD_ONENAND)
+	case MTD_DEV_TYPE_ONENAND:
+		gpmc_regs = gpmc_regs_onenand;
+		base = CONFIG_SYS_ONENAND_BASE;
+		size = GPMC_SIZE_128M;
+		break;
+#endif
+	default:
+		/* disable the GPMC0 config set by ROM code */
+		writel(0, &gpmc_cfg->cs[0].config7);
+		sdelay(1000);
+		return;
+	}
+
+	/* enable chip-select specific configurations */
+	enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
+}
+
+/*****************************************************
+ * gpmc_init(): init gpmc bus
+ * Init GPMC for x16, MuxMode (SDRAM in x32).
+ * This code can only be executed from SRAM or SDRAM.
+ *****************************************************/
+void gpmc_init(void)
+{
+	/* global settings */
+	writel(0x00000008, &gpmc_cfg->sysconfig);
+	writel(0x00000000, &gpmc_cfg->irqstatus);
+	writel(0x00000000, &gpmc_cfg->irqenable);
+	/* disable timeout, set a safe reset value */
+	writel(0x00001ff0, &gpmc_cfg->timeout_control);
+	writel(gpmc_cs0_flash == MTD_DEV_TYPE_NOR ?
+		0x00000200 : 0x00000012, &gpmc_cfg->config);
+
+	set_gpmc_cs0(gpmc_cs0_flash);
+}
diff --git a/arch/arm/mach-omap2/omap-cache.c b/arch/arm/mach-omap2/omap-cache.c
new file mode 100644
index 0000000..b37163a
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-cache.c
@@ -0,0 +1,77 @@
+/*
+ *
+ * Common functions for OMAP4/5 based boards
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *	Aneesh V	<aneesh@ti.com>
+ *	Steve Sakoman	<steve@sakoman.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/cache.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Without LPAE short descriptors are used
+ * Set C - Cache Bit3
+ * Set B - Buffer Bit2
+ * The last 2 bits set to 0b10
+ * Do Not set XN bit4
+ * So value is 0xe
+ *
+ * With LPAE cache configuration happens via MAIR0 register
+ * AttrIndx value is 0x3 for picking byte3 for MAIR0 which has 0xFF.
+ * 0xFF maps to Cache writeback with Read and Write Allocate set
+ * The bits[1:0] should have the value 0b01 for the first level
+ * descriptor.
+ * So the value is 0xd
+ */
+
+#ifdef CONFIG_ARMV7_LPAE
+#define ARMV7_DCACHE_POLICY	DCACHE_WRITEALLOC
+#else
+#define ARMV7_DCACHE_POLICY	DCACHE_WRITEBACK & ~TTB_SECT_XN_MASK
+#endif
+
+#define ARMV7_DOMAIN_CLIENT	1
+#define ARMV7_DOMAIN_MASK	(0x3 << 0)
+
+void enable_caches(void)
+{
+	/* Enable D-cache. I-cache is already enabled in start.S */
+	dcache_enable();
+}
+
+void dram_bank_mmu_setup(int bank)
+{
+	bd_t *bd = gd->bd;
+	int	i;
+
+	u32 start = bd->bi_dram[bank].start >> MMU_SECTION_SHIFT;
+	u32 size = bd->bi_dram[bank].size >> MMU_SECTION_SHIFT;
+	u32 end = start + size;
+
+	debug("%s: bank: %d\n", __func__, bank);
+	for (i = start; i < end; i++)
+		set_section_dcache(i, ARMV7_DCACHE_POLICY);
+}
+
+void arm_init_domains(void)
+{
+	u32 reg;
+
+	reg = get_dacr();
+	/*
+	* Set DOMAIN to client access so that all permissions
+	* set in pagetables are validated by the mmu.
+	*/
+	reg &= ~ARMV7_DOMAIN_MASK;
+	reg |= ARMV7_DOMAIN_CLIENT;
+	set_dacr(reg);
+}
diff --git a/arch/arm/mach-omap2/omap3/Kconfig b/arch/arm/mach-omap2/omap3/Kconfig
new file mode 100644
index 0000000..7d884a2
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/Kconfig
@@ -0,0 +1,154 @@
+if OMAP34XX
+
+config SPL_EXT_SUPPORT
+	default y
+
+config SPL_FAT_SUPPORT
+	default y
+
+config SPL_GPIO_SUPPORT
+	default y
+
+config SPL_I2C_SUPPORT
+	default y
+
+config SPL_LIBCOMMON_SUPPORT
+	default y
+
+config SPL_LIBDISK_SUPPORT
+	default y
+
+config SPL_LIBGENERIC_SUPPORT
+	default y
+
+config SPL_MMC_SUPPORT
+	default y
+
+config SPL_NAND_SUPPORT
+	default y
+
+config SPL_POWER_SUPPORT
+	default y
+
+config SPL_SERIAL_SUPPORT
+	default y
+
+choice
+	prompt "OMAP3 board select"
+	optional
+
+config TARGET_AM3517_EVM
+	bool "AM3517 EVM"
+
+config TARGET_MT_VENTOUX
+	bool "TeeJet Mt.Ventoux"
+
+config TARGET_OMAP3_BEAGLE
+	bool "TI OMAP3 BeagleBoard"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_CM_T35
+	bool "CompuLab CM-T3530 and CM-T3730 boards"
+
+config TARGET_CM_T3517
+	bool "CompuLab CM-T3517 boards"
+
+config TARGET_DEVKIT8000
+	bool "TimLL OMAP3 Devkit8000"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_OMAP3_EVM
+	bool "TI OMAP3 EVM"
+
+config TARGET_OMAP3_IGEP00X0
+	bool "IGEP"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_OMAP3_OVERO
+	bool "OMAP35xx Gumstix Overo"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_OMAP3_ZOOM1
+	bool "TI Zoom1"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_AM3517_CRANE
+	bool "am3517_crane"
+
+config TARGET_OMAP3_PANDORA
+	bool "OMAP3 Pandora"
+
+config TARGET_ECO5PK
+	bool "ECO5PK"
+
+config TARGET_TRICORDER
+	bool "Tricorder"
+
+config TARGET_MCX
+	bool "MCX"
+
+config TARGET_OMAP3_LOGIC
+	bool "OMAP3 Logic"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_NOKIA_RX51
+	bool "Nokia RX51"
+
+config TARGET_TAO3530
+	bool "TAO3530"
+
+config TARGET_TWISTER
+	bool "Twister"
+
+config TARGET_OMAP3_CAIRO
+	bool "QUIPOS CAIRO"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+config TARGET_SNIPER
+	bool "LG Optimus Black"
+	select DM
+	select DM_SERIAL
+	select DM_GPIO
+
+endchoice
+
+config SYS_SOC
+	default "omap3"
+
+source "board/logicpd/am3517evm/Kconfig"
+source "board/teejet/mt_ventoux/Kconfig"
+source "board/ti/beagle/Kconfig"
+source "board/compulab/cm_t35/Kconfig"
+source "board/compulab/cm_t3517/Kconfig"
+source "board/timll/devkit8000/Kconfig"
+source "board/ti/evm/Kconfig"
+source "board/isee/igep00x0/Kconfig"
+source "board/overo/Kconfig"
+source "board/logicpd/zoom1/Kconfig"
+source "board/ti/am3517crane/Kconfig"
+source "board/pandora/Kconfig"
+source "board/8dtech/eco5pk/Kconfig"
+source "board/corscience/tricorder/Kconfig"
+source "board/htkw/mcx/Kconfig"
+source "board/logicpd/omap3som/Kconfig"
+source "board/nokia/rx51/Kconfig"
+source "board/technexion/tao3530/Kconfig"
+source "board/technexion/twister/Kconfig"
+source "board/quipos/cairo/Kconfig"
+source "board/lg/sniper/Kconfig"
+
+endif
diff --git a/arch/arm/mach-omap2/omap3/Makefile b/arch/arm/mach-omap2/omap3/Makefile
new file mode 100644
index 0000000..b2fce96
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/Makefile
@@ -0,0 +1,21 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	:= lowlevel_init.o
+
+obj-y	+= board.o
+obj-y	+= boot.o
+obj-y	+= clock.o
+obj-y	+= sys_info.o
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SPL_OMAP3_ID_NAND)	+= spl_id_nand.o
+endif
+
+obj-$(CONFIG_DRIVER_TI_EMAC)	+= emac.o
+obj-$(CONFIG_EMIF4)	+= emif4.o
+obj-$(CONFIG_SDRC)	+= sdrc.o
+obj-$(CONFIG_USB_MUSB_AM35X)	+= am35x_musb.o
diff --git a/arch/arm/mach-omap2/omap3/am35x_musb.c b/arch/arm/mach-omap2/omap3/am35x_musb.c
new file mode 100644
index 0000000..74dd105
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/am35x_musb.c
@@ -0,0 +1,61 @@
+/*
+ * This file configures the internal USB PHY in AM35X.
+ *
+ * Copyright (C) 2012 Ilya Yanok <ilya.yanok@gmail.com>
+ *
+ * Based on omap_phy_internal.c code from Linux by
+ * Hema HK <hemahk@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/am35x_def.h>
+
+void am35x_musb_reset(void)
+{
+	/* Reset the musb interface */
+	clrsetbits_le32(&am35x_scm_general_regs->ip_sw_reset,
+			0, USBOTGSS_SW_RST);
+	clrsetbits_le32(&am35x_scm_general_regs->ip_sw_reset,
+			USBOTGSS_SW_RST, 0);
+}
+
+void am35x_musb_phy_power(u8 on)
+{
+	unsigned long start = get_timer(0);
+
+	if (on) {
+		/*
+		 * Start the on-chip PHY and its PLL.
+		 */
+		clrsetbits_le32(&am35x_scm_general_regs->devconf2,
+				CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN,
+				CONF2_PHY_PLLON);
+
+		debug("Waiting for PHY clock good...\n");
+		while (!(readl(&am35x_scm_general_regs->devconf2)
+				& CONF2_PHYCLKGD)) {
+
+			if (get_timer(start) > CONFIG_SYS_HZ / 10) {
+				printf("musb PHY clock good timed out\n");
+				break;
+			}
+		}
+	} else {
+		/*
+		 * Power down the on-chip PHY.
+		 */
+		clrsetbits_le32(&am35x_scm_general_regs->devconf2,
+				CONF2_PHY_PLLON,
+				CONF2_PHYPWRDN | CONF2_OTGPWRDN);
+	}
+}
+
+void am35x_musb_clear_irq(void)
+{
+	clrsetbits_le32(&am35x_scm_general_regs->lvl_intr_clr,
+			0, USBOTGSS_INT_CLR);
+	readl(&am35x_scm_general_regs->lvl_intr_clr);
+}
diff --git a/arch/arm/mach-omap2/omap3/board.c b/arch/arm/mach-omap2/omap3/board.c
new file mode 100644
index 0000000..5f55977
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/board.c
@@ -0,0 +1,434 @@
+/*
+ *
+ * Common board functions for OMAP3 based boards.
+ *
+ * (C) Copyright 2004-2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *      Sunil Kumar <sunilsaini05@gmail.com>
+ *      Shashi Ranjan <shashiranjanmca05@gmail.com>
+ *
+ * Derived from Beagle Board and 3430 SDP code by
+ *      Richard Woodruff <r-woodruff2@ti.com>
+ *      Syed Mohammed Khasim <khasim@ti.com>
+ *
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <dm.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/mem.h>
+#include <asm/cache.h>
+#include <asm/armv7.h>
+#include <asm/gpio.h>
+#include <asm/omap_common.h>
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Declarations */
+extern omap3_sysinfo sysinfo;
+#ifndef CONFIG_SYS_L2CACHE_OFF
+static void omap3_invalidate_l2_cache_secure(void);
+#endif
+
+#ifdef CONFIG_DM_GPIO
+static const struct omap_gpio_platdata omap34xx_gpio[] = {
+	{ 0, OMAP34XX_GPIO1_BASE },
+	{ 1, OMAP34XX_GPIO2_BASE },
+	{ 2, OMAP34XX_GPIO3_BASE },
+	{ 3, OMAP34XX_GPIO4_BASE },
+	{ 4, OMAP34XX_GPIO5_BASE },
+	{ 5, OMAP34XX_GPIO6_BASE },
+};
+
+U_BOOT_DEVICES(am33xx_gpios) = {
+	{ "gpio_omap", &omap34xx_gpio[0] },
+	{ "gpio_omap", &omap34xx_gpio[1] },
+	{ "gpio_omap", &omap34xx_gpio[2] },
+	{ "gpio_omap", &omap34xx_gpio[3] },
+	{ "gpio_omap", &omap34xx_gpio[4] },
+	{ "gpio_omap", &omap34xx_gpio[5] },
+};
+
+#else
+
+static const struct gpio_bank gpio_bank_34xx[6] = {
+	{ (void *)OMAP34XX_GPIO1_BASE },
+	{ (void *)OMAP34XX_GPIO2_BASE },
+	{ (void *)OMAP34XX_GPIO3_BASE },
+	{ (void *)OMAP34XX_GPIO4_BASE },
+	{ (void *)OMAP34XX_GPIO5_BASE },
+	{ (void *)OMAP34XX_GPIO6_BASE },
+};
+
+const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx;
+
+#endif
+
+/******************************************************************************
+ * Routine: secure_unlock
+ * Description: Setup security registers for access
+ *              (GP Device only)
+ *****************************************************************************/
+void secure_unlock_mem(void)
+{
+	struct pm *pm_rt_ape_base = (struct pm *)PM_RT_APE_BASE_ADDR_ARM;
+	struct pm *pm_gpmc_base = (struct pm *)PM_GPMC_BASE_ADDR_ARM;
+	struct pm *pm_ocm_ram_base = (struct pm *)PM_OCM_RAM_BASE_ADDR_ARM;
+	struct pm *pm_iva2_base = (struct pm *)PM_IVA2_BASE_ADDR_ARM;
+	struct sms *sms_base = (struct sms *)OMAP34XX_SMS_BASE;
+
+	/* Protection Module Register Target APE (PM_RT) */
+	writel(UNLOCK_1, &pm_rt_ape_base->req_info_permission_1);
+	writel(UNLOCK_1, &pm_rt_ape_base->read_permission_0);
+	writel(UNLOCK_1, &pm_rt_ape_base->wirte_permission_0);
+	writel(UNLOCK_2, &pm_rt_ape_base->addr_match_1);
+
+	writel(UNLOCK_3, &pm_gpmc_base->req_info_permission_0);
+	writel(UNLOCK_3, &pm_gpmc_base->read_permission_0);
+	writel(UNLOCK_3, &pm_gpmc_base->wirte_permission_0);
+
+	writel(UNLOCK_3, &pm_ocm_ram_base->req_info_permission_0);
+	writel(UNLOCK_3, &pm_ocm_ram_base->read_permission_0);
+	writel(UNLOCK_3, &pm_ocm_ram_base->wirte_permission_0);
+	writel(UNLOCK_2, &pm_ocm_ram_base->addr_match_2);
+
+	/* IVA Changes */
+	writel(UNLOCK_3, &pm_iva2_base->req_info_permission_0);
+	writel(UNLOCK_3, &pm_iva2_base->read_permission_0);
+	writel(UNLOCK_3, &pm_iva2_base->wirte_permission_0);
+
+	/* SDRC region 0 public */
+	writel(UNLOCK_1, &sms_base->rg_att0);
+}
+
+/******************************************************************************
+ * Routine: secureworld_exit()
+ * Description: If chip is EMU and boot type is external
+ *		configure secure registers and exit secure world
+ *              general use.
+ *****************************************************************************/
+void secureworld_exit(void)
+{
+	unsigned long i;
+
+	/* configure non-secure access control register */
+	__asm__ __volatile__("mrc p15, 0, %0, c1, c1, 2":"=r"(i));
+	/* enabling co-processor CP10 and CP11 accesses in NS world */
+	__asm__ __volatile__("orr %0, %0, #0xC00":"=r"(i));
+	/*
+	 * allow allocation of locked TLBs and L2 lines in NS world
+	 * allow use of PLE registers in NS world also
+	 */
+	__asm__ __volatile__("orr %0, %0, #0x70000":"=r"(i));
+	__asm__ __volatile__("mcr p15, 0, %0, c1, c1, 2":"=r"(i));
+
+	/* Enable ASA in ACR register */
+	__asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
+	__asm__ __volatile__("orr %0, %0, #0x10":"=r"(i));
+	__asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
+
+	/* Exiting secure world */
+	__asm__ __volatile__("mrc p15, 0, %0, c1, c1, 0":"=r"(i));
+	__asm__ __volatile__("orr %0, %0, #0x31":"=r"(i));
+	__asm__ __volatile__("mcr p15, 0, %0, c1, c1, 0":"=r"(i));
+}
+
+/******************************************************************************
+ * Routine: try_unlock_sram()
+ * Description: If chip is GP/EMU(special) type, unlock the SRAM for
+ *              general use.
+ *****************************************************************************/
+void try_unlock_memory(void)
+{
+	int mode;
+	int in_sdram = is_running_in_sdram();
+
+	/*
+	 * if GP device unlock device SRAM for general use
+	 * secure code breaks for Secure/Emulation device - HS/E/T
+	 */
+	mode = get_device_type();
+	if (mode == GP_DEVICE)
+		secure_unlock_mem();
+
+	/*
+	 * If device is EMU and boot is XIP external booting
+	 * Unlock firewalls and disable L2 and put chip
+	 * out of secure world
+	 *
+	 * Assuming memories are unlocked by the demon who put us in SDRAM
+	 */
+	if ((mode <= EMU_DEVICE) && (get_boot_type() == 0x1F)
+	    && (!in_sdram)) {
+		secure_unlock_mem();
+		secureworld_exit();
+	}
+
+	return;
+}
+
+/******************************************************************************
+ * Routine: s_init
+ * Description: Does early system init of muxing and clocks.
+ *              - Called path is with SRAM stack.
+ *****************************************************************************/
+void s_init(void)
+{
+	watchdog_init();
+
+	try_unlock_memory();
+
+#ifndef CONFIG_SYS_L2CACHE_OFF
+	/* Invalidate L2-cache from secure mode */
+	omap3_invalidate_l2_cache_secure();
+#endif
+
+	set_muxconf_regs();
+	sdelay(100);
+
+	prcm_init();
+
+	per_clocks_enable();
+
+#ifdef CONFIG_USB_EHCI_OMAP
+	ehci_clocks_enable();
+#endif
+}
+
+#ifdef CONFIG_SPL_BUILD
+void board_init_f(ulong dummy)
+{
+	mem_init();
+}
+#endif
+
+/*
+ * Routine: misc_init_r
+ * Description: A basic misc_init_r that just displays the die ID
+ */
+int __weak misc_init_r(void)
+{
+	omap_die_id_display();
+
+	return 0;
+}
+
+/******************************************************************************
+ * Routine: wait_for_command_complete
+ * Description: Wait for posting to finish on watchdog
+ *****************************************************************************/
+static void wait_for_command_complete(struct watchdog *wd_base)
+{
+	int pending = 1;
+	do {
+		pending = readl(&wd_base->wwps);
+	} while (pending);
+}
+
+/******************************************************************************
+ * Routine: watchdog_init
+ * Description: Shut down watch dogs
+ *****************************************************************************/
+void watchdog_init(void)
+{
+	struct watchdog *wd2_base = (struct watchdog *)WD2_BASE;
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+
+	/*
+	 * There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is
+	 * either taken care of by ROM (HS/EMU) or not accessible (GP).
+	 * We need to take care of WD2-MPU or take a PRCM reset. WD3
+	 * should not be running and does not generate a PRCM reset.
+	 */
+
+	setbits_le32(&prcm_base->fclken_wkup, 0x20);
+	setbits_le32(&prcm_base->iclken_wkup, 0x20);
+	wait_on_value(ST_WDT2, 0x20, &prcm_base->idlest_wkup, 5);
+
+	writel(WD_UNLOCK1, &wd2_base->wspr);
+	wait_for_command_complete(wd2_base);
+	writel(WD_UNLOCK2, &wd2_base->wspr);
+}
+
+/******************************************************************************
+ * Dummy function to handle errors for EABI incompatibility
+ *****************************************************************************/
+void abort(void)
+{
+}
+
+#if defined(CONFIG_NAND_OMAP_GPMC) & !defined(CONFIG_SPL_BUILD)
+/******************************************************************************
+ * OMAP3 specific command to switch between NAND HW and SW ecc
+ *****************************************************************************/
+static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+{
+	if (argc < 2 || argc > 3)
+		goto usage;
+
+	if (strncmp(argv[1], "hw", 2) == 0) {
+		if (argc == 2) {
+			omap_nand_switch_ecc(1, 1);
+		} else {
+			if (strncmp(argv[2], "hamming", 7) == 0)
+				omap_nand_switch_ecc(1, 1);
+			else if (strncmp(argv[2], "bch8", 4) == 0)
+				omap_nand_switch_ecc(1, 8);
+			else if (strncmp(argv[2], "bch16", 5) == 0)
+				omap_nand_switch_ecc(1, 16);
+			else
+				goto usage;
+		}
+	} else if (strncmp(argv[1], "sw", 2) == 0) {
+		if (argc == 2) {
+			omap_nand_switch_ecc(0, 1);
+		} else {
+			if (strncmp(argv[2], "hamming", 7) == 0)
+				omap_nand_switch_ecc(0, 1);
+			else if (strncmp(argv[2], "bch8", 4) == 0)
+				omap_nand_switch_ecc(0, 8);
+			else
+				goto usage;
+		}
+	} else {
+		goto usage;
+	}
+
+	return 0;
+
+usage:
+	printf ("Usage: nandecc %s\n", cmdtp->usage);
+	return 1;
+}
+
+U_BOOT_CMD(
+	nandecc, 3, 1,	do_switch_ecc,
+	"switch OMAP3 NAND ECC calculation algorithm",
+	"hw [hamming|bch8|bch16] - Switch between NAND hardware 1-bit hamming"
+	" and 8-bit/16-bit BCH\n"
+	"                           ecc calculation (second parameter may"
+	" be omitted).\n"
+	"nandecc sw               - Switch to NAND software ecc algorithm."
+);
+
+#endif /* CONFIG_NAND_OMAP_GPMC & !CONFIG_SPL_BUILD */
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+/**
+ * Print board information
+ */
+int checkboard (void)
+{
+	char *mem_s ;
+
+	if (is_mem_sdr())
+		mem_s = "mSDR";
+	else
+		mem_s = "LPDDR";
+
+	printf("%s + %s/%s\n", sysinfo.board_string, mem_s,
+			sysinfo.nand_string);
+
+	return 0;
+}
+#endif	/* CONFIG_DISPLAY_BOARDINFO */
+
+static void omap3_emu_romcode_call(u32 service_id, u32 *parameters)
+{
+	u32 i, num_params = *parameters;
+	u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA;
+
+	/*
+	 * copy the parameters to an un-cached area to avoid coherency
+	 * issues
+	 */
+	for (i = 0; i < num_params; i++) {
+		__raw_writel(*parameters, sram_scratch_space);
+		parameters++;
+		sram_scratch_space++;
+	}
+
+	/* Now make the PPA call */
+	do_omap3_emu_romcode_call(service_id, OMAP3_PUBLIC_SRAM_SCRATCH_AREA);
+}
+
+void __weak omap3_set_aux_cr_secure(u32 acr)
+{
+	struct emu_hal_params emu_romcode_params;
+
+	emu_romcode_params.num_params = 1;
+	emu_romcode_params.param1 = acr;
+	omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR,
+			       (u32 *)&emu_romcode_params);
+}
+
+void v7_arch_cp15_set_acr(u32 acr, u32 cpu_midr, u32 cpu_rev_comb,
+			  u32 cpu_variant, u32 cpu_rev)
+{
+	/* Write ACR - affects secure banked bits */
+	if (get_device_type() == GP_DEVICE)
+		omap_smc1(OMAP3_GP_ROMCODE_API_WRITE_ACR, acr);
+	else
+		omap3_set_aux_cr_secure(acr);
+
+	/* Write ACR - affects non-secure banked bits - some erratas need it */
+	asm volatile ("mcr p15, 0, %0, c1, c0, 1" : : "r" (acr));
+}
+
+
+#ifndef CONFIG_SYS_L2CACHE_OFF
+static void omap3_update_aux_cr(u32 set_bits, u32 clear_bits)
+{
+	u32 acr;
+
+	/* Read ACR */
+	asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
+	acr &= ~clear_bits;
+	acr |= set_bits;
+	v7_arch_cp15_set_acr(acr, 0, 0, 0, 0);
+
+}
+
+/* Invalidate the entire L2 cache from secure mode */
+static void omap3_invalidate_l2_cache_secure(void)
+{
+	if (get_device_type() == GP_DEVICE) {
+		omap_smc1(OMAP3_GP_ROMCODE_API_L2_INVAL, 0);
+	} else {
+		struct emu_hal_params emu_romcode_params;
+		emu_romcode_params.num_params = 1;
+		emu_romcode_params.param1 = 0;
+		omap3_emu_romcode_call(OMAP3_EMU_HAL_API_L2_INVAL,
+				       (u32 *)&emu_romcode_params);
+	}
+}
+
+void v7_outer_cache_enable(void)
+{
+
+	/*
+	 * Set L2EN
+	 * On some revisions L2EN bit is banked on some revisions it's not
+	 * No harm in setting both banked bits(in fact this is required
+	 * by an erratum)
+	 */
+	omap3_update_aux_cr(0x2, 0);
+}
+
+void omap3_outer_cache_disable(void)
+{
+	/*
+	 * Clear L2EN
+	 * On some revisions L2EN bit is banked on some revisions it's not
+	 * No harm in clearing both banked bits(in fact this is required
+	 * by an erratum)
+	 */
+	omap3_update_aux_cr(0, 0x2);
+}
+#endif /* !CONFIG_SYS_L2CACHE_OFF */
diff --git a/arch/arm/mach-omap2/omap3/boot.c b/arch/arm/mach-omap2/omap3/boot.c
new file mode 100644
index 0000000..64b242b
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/boot.c
@@ -0,0 +1,104 @@
+/*
+ * OMAP3 boot
+ *
+ * Copyright (C) 2015 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <spl.h>
+
+static u32 boot_devices[] = {
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_XIPWAIT,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_XIPWAIT,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_XIPWAIT,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_XIPWAIT,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_XIPWAIT,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_MMC2_2,
+};
+
+u32 omap_sys_boot_device(void)
+{
+	struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE;
+	u32 sys_boot;
+
+	/* Grab the first 5 bits of the status register for SYS_BOOT. */
+	sys_boot = readl(&ctrl_base->status) & ((1 << 5) - 1);
+
+	if (sys_boot >= (sizeof(boot_devices) / sizeof(u32)))
+		return BOOT_DEVICE_NONE;
+
+	return boot_devices[sys_boot];
+}
+
+int omap_reboot_mode(char *mode, unsigned int length)
+{
+	u32 reboot_mode;
+	char c;
+
+	if (length < 2)
+		return -1;
+
+	reboot_mode = readl((u32 *)(OMAP34XX_SCRATCHPAD +
+		OMAP_REBOOT_REASON_OFFSET));
+
+	c = (reboot_mode >> 24) & 0xff;
+	if (c != 'B')
+		return -1;
+
+	c = (reboot_mode >> 16) & 0xff;
+	if (c != 'M')
+		return -1;
+
+	c = reboot_mode & 0xff;
+
+	mode[0] = c;
+	mode[1] = '\0';
+
+	return 0;
+}
+
+int omap_reboot_mode_clear(void)
+{
+	writel(0, (u32 *)(OMAP34XX_SCRATCHPAD + OMAP_REBOOT_REASON_OFFSET));
+
+	return 0;
+}
+
+int omap_reboot_mode_store(char *mode)
+{
+	u32 reboot_mode;
+
+	reboot_mode = 'B' << 24 | 'M' << 16 | mode[0];
+
+	writel(reboot_mode, (u32 *)(OMAP34XX_SCRATCHPAD +
+		OMAP_REBOOT_REASON_OFFSET));
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/omap3/clock.c b/arch/arm/mach-omap2/omap3/clock.c
new file mode 100644
index 0000000..006969e
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/clock.c
@@ -0,0 +1,799 @@
+/*
+ * (C) Copyright 2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *      Manikandan Pillai <mani.pillai@ti.com>
+ *
+ * Derived from Beagle Board and OMAP3 SDP code by
+ *      Richard Woodruff <r-woodruff2@ti.com>
+ *      Syed Mohammed Khasim <khasim@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/clocks_omap3.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/sys_proto.h>
+#include <environment.h>
+#include <command.h>
+
+/******************************************************************************
+ * get_sys_clk_speed() - determine reference oscillator speed
+ *                       based on known 32kHz clock and gptimer.
+ *****************************************************************************/
+u32 get_osc_clk_speed(void)
+{
+	u32 start, cstart, cend, cdiff, cdiv, val;
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	struct prm *prm_base = (struct prm *)PRM_BASE;
+	struct gptimer *gpt1_base = (struct gptimer *)OMAP34XX_GPT1;
+	struct s32ktimer *s32k_base = (struct s32ktimer *)SYNC_32KTIMER_BASE;
+
+	val = readl(&prm_base->clksrc_ctrl);
+
+	if (val & SYSCLKDIV_2)
+		cdiv = 2;
+	else
+		cdiv = 1;
+
+	/* enable timer2 */
+	val = readl(&prcm_base->clksel_wkup) | CLKSEL_GPT1;
+
+	/* select sys_clk for GPT1 */
+	writel(val, &prcm_base->clksel_wkup);
+
+	/* Enable I and F Clocks for GPT1 */
+	val = readl(&prcm_base->iclken_wkup) | EN_GPT1 | EN_32KSYNC;
+	writel(val, &prcm_base->iclken_wkup);
+
+	val = readl(&prcm_base->fclken_wkup) | EN_GPT1;
+	writel(val, &prcm_base->fclken_wkup);
+
+	writel(0, &gpt1_base->tldr);		/* start counting at 0 */
+	writel(GPT_EN, &gpt1_base->tclr);	/* enable clock */
+
+	/* enable 32kHz source, determine sys_clk via gauging */
+
+	/* start time in 20 cycles */
+	start = 20 + readl(&s32k_base->s32k_cr);
+
+	/* dead loop till start time */
+	while (readl(&s32k_base->s32k_cr) < start);
+
+	/* get start sys_clk count */
+	cstart = readl(&gpt1_base->tcrr);
+
+	/* wait for 40 cycles */
+	while (readl(&s32k_base->s32k_cr) < (start + 20)) ;
+	cend = readl(&gpt1_base->tcrr);		/* get end sys_clk count */
+	cdiff = cend - cstart;			/* get elapsed ticks */
+	cdiff *= cdiv;
+
+	/* based on number of ticks assign speed */
+	if (cdiff > 19000)
+		return S38_4M;
+	else if (cdiff > 15200)
+		return S26M;
+	else if (cdiff > 13000)
+		return S24M;
+	else if (cdiff > 9000)
+		return S19_2M;
+	else if (cdiff > 7600)
+		return S13M;
+	else
+		return S12M;
+}
+
+/******************************************************************************
+ * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on
+ *                       input oscillator clock frequency.
+ *****************************************************************************/
+void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
+{
+	switch(osc_clk) {
+	case S38_4M:
+		*sys_clkin_sel = 4;
+		break;
+	case S26M:
+		*sys_clkin_sel = 3;
+		break;
+	case S19_2M:
+		*sys_clkin_sel = 2;
+		break;
+	case S13M:
+		*sys_clkin_sel = 1;
+		break;
+	case S12M:
+	default:
+		*sys_clkin_sel = 0;
+	}
+}
+
+/*
+ * OMAP34XX/35XX specific functions
+ */
+
+static void dpll3_init_34xx(u32 sil_index, u32 clk_index)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	dpll_param *ptr = (dpll_param *) get_core_dpll_param();
+	void (*f_lock_pll) (u32, u32, u32, u32);
+	int xip_safe, p0, p1, p2, p3;
+
+	xip_safe = is_running_in_sram();
+
+	/* Moving to the right sysclk and ES rev base */
+	ptr = ptr + (3 * clk_index) + sil_index;
+
+	if (xip_safe) {
+		/*
+		 * CORE DPLL
+		 */
+		clrsetbits_le32(&prcm_base->clken_pll,
+				0x00000007, PLL_FAST_RELOCK_BYPASS);
+		wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
+				LDELAY);
+
+		/*
+		 * For OMAP3 ES1.0 Errata 1.50, default value directly doesn't
+		 * work. write another value and then default value.
+		 */
+
+		/* CM_CLKSEL1_EMU[DIV_DPLL3] */
+		clrsetbits_le32(&prcm_base->clksel1_emu,
+				0x001F0000, (CORE_M3X2 + 1) << 16) ;
+		clrsetbits_le32(&prcm_base->clksel1_emu,
+				0x001F0000, CORE_M3X2 << 16);
+
+		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+		clrsetbits_le32(&prcm_base->clksel1_pll,
+				0xF8000000, ptr->m2 << 27);
+
+		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+		clrsetbits_le32(&prcm_base->clksel1_pll,
+				0x07FF0000, ptr->m << 16);
+
+		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+		clrsetbits_le32(&prcm_base->clksel1_pll,
+				0x00007F00, ptr->n << 8);
+
+		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+		clrbits_le32(&prcm_base->clksel1_pll, 0x00000040);
+
+		/* SSI */
+		clrsetbits_le32(&prcm_base->clksel_core,
+				0x00000F00, CORE_SSI_DIV << 8);
+		/* FSUSB */
+		clrsetbits_le32(&prcm_base->clksel_core,
+				0x00000030, CORE_FUSB_DIV << 4);
+		/* L4 */
+		clrsetbits_le32(&prcm_base->clksel_core,
+				0x0000000C, CORE_L4_DIV << 2);
+		/* L3 */
+		clrsetbits_le32(&prcm_base->clksel_core,
+				0x00000003, CORE_L3_DIV);
+		/* GFX */
+		clrsetbits_le32(&prcm_base->clksel_gfx,
+				0x00000007, GFX_DIV);
+		/* RESET MGR */
+		clrsetbits_le32(&prcm_base->clksel_wkup,
+				0x00000006, WKUP_RSM << 1);
+		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+		clrsetbits_le32(&prcm_base->clken_pll,
+				0x000000F0, ptr->fsel << 4);
+		/* LOCK MODE */
+		clrsetbits_le32(&prcm_base->clken_pll,
+				0x00000007, PLL_LOCK);
+
+		wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
+				LDELAY);
+	} else if (is_running_in_flash()) {
+		/*
+		 * if running from flash, jump to small relocated code
+		 * area in SRAM.
+		 */
+		f_lock_pll = (void *) (SRAM_CLK_CODE);
+
+		p0 = readl(&prcm_base->clken_pll);
+		clrsetbits_le32(&p0, 0x00000007, PLL_FAST_RELOCK_BYPASS);
+		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+		clrsetbits_le32(&p0, 0x000000F0, ptr->fsel << 4);
+
+		p1 = readl(&prcm_base->clksel1_pll);
+		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+		clrsetbits_le32(&p1, 0xF8000000, ptr->m2 << 27);
+		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+		clrsetbits_le32(&p1, 0x07FF0000, ptr->m << 16);
+		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+		clrsetbits_le32(&p1, 0x00007F00, ptr->n << 8);
+		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+		clrbits_le32(&p1, 0x00000040);
+
+		p2 = readl(&prcm_base->clksel_core);
+		/* SSI */
+		clrsetbits_le32(&p2, 0x00000F00, CORE_SSI_DIV << 8);
+		/* FSUSB */
+		clrsetbits_le32(&p2, 0x00000030, CORE_FUSB_DIV << 4);
+		/* L4 */
+		clrsetbits_le32(&p2, 0x0000000C, CORE_L4_DIV << 2);
+		/* L3 */
+		clrsetbits_le32(&p2, 0x00000003, CORE_L3_DIV);
+
+		p3 = (u32)&prcm_base->idlest_ckgen;
+
+		(*f_lock_pll) (p0, p1, p2, p3);
+	}
+}
+
+static void dpll4_init_34xx(u32 sil_index, u32 clk_index)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	dpll_param *ptr = (dpll_param *) get_per_dpll_param();
+
+	/* Moving it to the right sysclk base */
+	ptr = ptr + clk_index;
+
+	/* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
+	clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_STOP << 16);
+	wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
+
+	/*
+	 * Errata 1.50 Workaround for OMAP3 ES1.0 only
+	 * If using default divisors, write default divisor + 1
+	 * and then the actual divisor value
+	 */
+	/* M6 */
+	clrsetbits_le32(&prcm_base->clksel1_emu,
+			0x1F000000, (PER_M6X2 + 1) << 24);
+	clrsetbits_le32(&prcm_base->clksel1_emu,
+			0x1F000000, PER_M6X2 << 24);
+	/* M5 */
+	clrsetbits_le32(&prcm_base->clksel_cam, 0x0000001F, (PER_M5X2 + 1));
+	clrsetbits_le32(&prcm_base->clksel_cam, 0x0000001F, PER_M5X2);
+	/* M4 */
+	clrsetbits_le32(&prcm_base->clksel_dss, 0x0000001F, (PER_M4X2 + 1));
+	clrsetbits_le32(&prcm_base->clksel_dss, 0x0000001F, PER_M4X2);
+	/* M3 */
+	clrsetbits_le32(&prcm_base->clksel_dss,
+			0x00001F00, (PER_M3X2 + 1) << 8);
+	clrsetbits_le32(&prcm_base->clksel_dss,
+			0x00001F00, PER_M3X2 << 8);
+	/* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
+	clrsetbits_le32(&prcm_base->clksel3_pll, 0x0000001F, (ptr->m2 + 1));
+	clrsetbits_le32(&prcm_base->clksel3_pll, 0x0000001F, ptr->m2);
+	/* Workaround end */
+
+	/* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */
+	clrsetbits_le32(&prcm_base->clksel2_pll,
+			0x0007FF00, ptr->m << 8);
+
+	/* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
+	clrsetbits_le32(&prcm_base->clksel2_pll, 0x0000007F, ptr->n);
+
+	/* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */
+	clrsetbits_le32(&prcm_base->clken_pll, 0x00F00000, ptr->fsel << 20);
+
+	/* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
+	clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_LOCK << 16);
+	wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
+}
+
+static void dpll5_init_34xx(u32 sil_index, u32 clk_index)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	dpll_param *ptr = (dpll_param *) get_per2_dpll_param();
+
+	/* Moving it to the right sysclk base */
+	ptr = ptr + clk_index;
+
+	/* PER2 DPLL (DPLL5) */
+	clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_STOP);
+	wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY);
+	/* set M2 (usbtll_fck) */
+	clrsetbits_le32(&prcm_base->clksel5_pll, 0x0000001F, ptr->m2);
+	/* set m (11-bit multiplier) */
+	clrsetbits_le32(&prcm_base->clksel4_pll, 0x0007FF00, ptr->m << 8);
+	/* set n (7-bit divider)*/
+	clrsetbits_le32(&prcm_base->clksel4_pll, 0x0000007F, ptr->n);
+	/* FREQSEL */
+	clrsetbits_le32(&prcm_base->clken_pll, 0x000000F0, ptr->fsel << 4);
+	/* lock mode */
+	clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_LOCK);
+	wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY);
+}
+
+static void mpu_init_34xx(u32 sil_index, u32 clk_index)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	dpll_param *ptr = (dpll_param *) get_mpu_dpll_param();
+
+	/* Moving to the right sysclk and ES rev base */
+	ptr = ptr + (3 * clk_index) + sil_index;
+
+	/* MPU DPLL (unlocked already) */
+
+	/* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
+	clrsetbits_le32(&prcm_base->clksel2_pll_mpu,
+			0x0000001F, ptr->m2);
+
+	/* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
+	clrsetbits_le32(&prcm_base->clksel1_pll_mpu,
+			0x0007FF00, ptr->m << 8);
+
+	/* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
+	clrsetbits_le32(&prcm_base->clksel1_pll_mpu,
+			0x0000007F, ptr->n);
+
+	/* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */
+	clrsetbits_le32(&prcm_base->clken_pll_mpu,
+			0x000000F0, ptr->fsel << 4);
+}
+
+static void iva_init_34xx(u32 sil_index, u32 clk_index)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	dpll_param *ptr = (dpll_param *) get_iva_dpll_param();
+
+	/* Moving to the right sysclk and ES rev base */
+	ptr = ptr + (3 * clk_index) + sil_index;
+
+	/* IVA DPLL */
+	/* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
+	clrsetbits_le32(&prcm_base->clken_pll_iva2,
+			0x00000007, PLL_STOP);
+	wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
+
+	/* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
+	clrsetbits_le32(&prcm_base->clksel2_pll_iva2,
+			0x0000001F, ptr->m2);
+
+	/* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
+	clrsetbits_le32(&prcm_base->clksel1_pll_iva2,
+			0x0007FF00, ptr->m << 8);
+
+	/* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
+	clrsetbits_le32(&prcm_base->clksel1_pll_iva2,
+			0x0000007F, ptr->n);
+
+	/* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */
+	clrsetbits_le32(&prcm_base->clken_pll_iva2,
+			0x000000F0, ptr->fsel << 4);
+
+	/* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
+	clrsetbits_le32(&prcm_base->clken_pll_iva2,
+			0x00000007, PLL_LOCK);
+
+	wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
+}
+
+/*
+ * OMAP3630 specific functions
+ */
+
+static void dpll3_init_36xx(u32 sil_index, u32 clk_index)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	dpll_param *ptr = (dpll_param *) get_36x_core_dpll_param();
+	void (*f_lock_pll) (u32, u32, u32, u32);
+	int xip_safe, p0, p1, p2, p3;
+
+	xip_safe = is_running_in_sram();
+
+	/* Moving it to the right sysclk base */
+	ptr += clk_index;
+
+	if (xip_safe) {
+		/* CORE DPLL */
+
+		/* Select relock bypass: CM_CLKEN_PLL[0:2] */
+		clrsetbits_le32(&prcm_base->clken_pll,
+				0x00000007, PLL_FAST_RELOCK_BYPASS);
+		wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
+				LDELAY);
+
+		/* CM_CLKSEL1_EMU[DIV_DPLL3] */
+		clrsetbits_le32(&prcm_base->clksel1_emu,
+				0x001F0000, CORE_M3X2 << 16);
+
+		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+		clrsetbits_le32(&prcm_base->clksel1_pll,
+				0xF8000000, ptr->m2 << 27);
+
+		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+		clrsetbits_le32(&prcm_base->clksel1_pll,
+				0x07FF0000, ptr->m << 16);
+
+		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+		clrsetbits_le32(&prcm_base->clksel1_pll,
+				0x00007F00, ptr->n << 8);
+
+		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+		clrbits_le32(&prcm_base->clksel1_pll, 0x00000040);
+
+		/* SSI */
+		clrsetbits_le32(&prcm_base->clksel_core,
+				0x00000F00, CORE_SSI_DIV << 8);
+		/* FSUSB */
+		clrsetbits_le32(&prcm_base->clksel_core,
+				0x00000030, CORE_FUSB_DIV << 4);
+		/* L4 */
+		clrsetbits_le32(&prcm_base->clksel_core,
+				0x0000000C, CORE_L4_DIV << 2);
+		/* L3 */
+		clrsetbits_le32(&prcm_base->clksel_core,
+				0x00000003, CORE_L3_DIV);
+		/* GFX */
+		clrsetbits_le32(&prcm_base->clksel_gfx,
+				0x00000007, GFX_DIV_36X);
+		/* RESET MGR */
+		clrsetbits_le32(&prcm_base->clksel_wkup,
+				0x00000006, WKUP_RSM << 1);
+		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+		clrsetbits_le32(&prcm_base->clken_pll,
+				0x000000F0, ptr->fsel << 4);
+		/* LOCK MODE */
+		clrsetbits_le32(&prcm_base->clken_pll,
+				0x00000007, PLL_LOCK);
+
+		wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
+				LDELAY);
+	} else if (is_running_in_flash()) {
+		/*
+		 * if running from flash, jump to small relocated code
+		 * area in SRAM.
+		 */
+		f_lock_pll = (void *) (SRAM_CLK_CODE);
+
+		p0 = readl(&prcm_base->clken_pll);
+		clrsetbits_le32(&p0, 0x00000007, PLL_FAST_RELOCK_BYPASS);
+		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+		clrsetbits_le32(&p0, 0x000000F0, ptr->fsel << 4);
+
+		p1 = readl(&prcm_base->clksel1_pll);
+		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+		clrsetbits_le32(&p1, 0xF8000000, ptr->m2 << 27);
+		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+		clrsetbits_le32(&p1, 0x07FF0000, ptr->m << 16);
+		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+		clrsetbits_le32(&p1, 0x00007F00, ptr->n << 8);
+		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+		clrbits_le32(&p1, 0x00000040);
+
+		p2 = readl(&prcm_base->clksel_core);
+		/* SSI */
+		clrsetbits_le32(&p2, 0x00000F00, CORE_SSI_DIV << 8);
+		/* FSUSB */
+		clrsetbits_le32(&p2, 0x00000030, CORE_FUSB_DIV << 4);
+		/* L4 */
+		clrsetbits_le32(&p2, 0x0000000C, CORE_L4_DIV << 2);
+		/* L3 */
+		clrsetbits_le32(&p2, 0x00000003, CORE_L3_DIV);
+
+		p3 = (u32)&prcm_base->idlest_ckgen;
+
+		(*f_lock_pll) (p0, p1, p2, p3);
+	}
+}
+
+static void dpll4_init_36xx(u32 sil_index, u32 clk_index)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	struct dpll_per_36x_param *ptr;
+
+	ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param();
+
+	/* Moving it to the right sysclk base */
+	ptr += clk_index;
+
+	/* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
+	clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_STOP << 16);
+	wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
+
+	/* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */
+	clrsetbits_le32(&prcm_base->clksel1_emu, 0x3F000000, ptr->m6 << 24);
+
+	/* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */
+	clrsetbits_le32(&prcm_base->clksel_cam, 0x0000003F, ptr->m5);
+
+	/* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */
+	clrsetbits_le32(&prcm_base->clksel_dss, 0x0000003F, ptr->m4);
+
+	/* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */
+	clrsetbits_le32(&prcm_base->clksel_dss, 0x00003F00, ptr->m3 << 8);
+
+	/* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
+	clrsetbits_le32(&prcm_base->clksel3_pll, 0x0000001F, ptr->m2);
+
+	/* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */
+	clrsetbits_le32(&prcm_base->clksel2_pll, 0x000FFF00, ptr->m << 8);
+
+	/* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
+	clrsetbits_le32(&prcm_base->clksel2_pll, 0x0000007F, ptr->n);
+
+	/* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */
+	clrsetbits_le32(&prcm_base->clksel_core, 0x00003000, ptr->m2div << 12);
+
+	/* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
+	clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_LOCK << 16);
+	wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
+}
+
+static void dpll5_init_36xx(u32 sil_index, u32 clk_index)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	dpll_param *ptr = (dpll_param *) get_36x_per2_dpll_param();
+
+	/* Moving it to the right sysclk base */
+	ptr = ptr + clk_index;
+
+	/* PER2 DPLL (DPLL5) */
+	clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_STOP);
+	wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY);
+	/* set M2 (usbtll_fck) */
+	clrsetbits_le32(&prcm_base->clksel5_pll, 0x0000001F, ptr->m2);
+	/* set m (11-bit multiplier) */
+	clrsetbits_le32(&prcm_base->clksel4_pll, 0x0007FF00, ptr->m << 8);
+	/* set n (7-bit divider)*/
+	clrsetbits_le32(&prcm_base->clksel4_pll, 0x0000007F, ptr->n);
+	/* lock mode */
+	clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_LOCK);
+	wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY);
+}
+
+static void mpu_init_36xx(u32 sil_index, u32 clk_index)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	dpll_param *ptr = (dpll_param *) get_36x_mpu_dpll_param();
+
+	/* Moving to the right sysclk */
+	ptr += clk_index;
+
+	/* MPU DPLL (unlocked already */
+
+	/* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
+	clrsetbits_le32(&prcm_base->clksel2_pll_mpu, 0x0000001F, ptr->m2);
+
+	/* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
+	clrsetbits_le32(&prcm_base->clksel1_pll_mpu, 0x0007FF00, ptr->m << 8);
+
+	/* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
+	clrsetbits_le32(&prcm_base->clksel1_pll_mpu, 0x0000007F, ptr->n);
+}
+
+static void iva_init_36xx(u32 sil_index, u32 clk_index)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+	dpll_param *ptr = (dpll_param *)get_36x_iva_dpll_param();
+
+	/* Moving to the right sysclk */
+	ptr += clk_index;
+
+	/* IVA DPLL */
+	/* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
+	clrsetbits_le32(&prcm_base->clken_pll_iva2, 0x00000007, PLL_STOP);
+	wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
+
+	/* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
+	clrsetbits_le32(&prcm_base->clksel2_pll_iva2, 0x0000001F, ptr->m2);
+
+	/* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
+	clrsetbits_le32(&prcm_base->clksel1_pll_iva2, 0x0007FF00, ptr->m << 8);
+
+	/* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
+	clrsetbits_le32(&prcm_base->clksel1_pll_iva2, 0x0000007F, ptr->n);
+
+	/* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
+	clrsetbits_le32(&prcm_base->clken_pll_iva2, 0x00000007, PLL_LOCK);
+
+	wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
+}
+
+/******************************************************************************
+ * prcm_init() - inits clocks for PRCM as defined in clocks.h
+ *               called from SRAM, or Flash (using temp SRAM stack).
+ *****************************************************************************/
+void prcm_init(void)
+{
+	u32 osc_clk = 0, sys_clkin_sel;
+	u32 clk_index, sil_index = 0;
+	struct prm *prm_base = (struct prm *)PRM_BASE;
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+
+	/*
+	 * Gauge the input clock speed and find out the sys_clkin_sel
+	 * value corresponding to the input clock.
+	 */
+	osc_clk = get_osc_clk_speed();
+	get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
+
+	/* set input crystal speed */
+	clrsetbits_le32(&prm_base->clksel, 0x00000007, sys_clkin_sel);
+
+	/* If the input clock is greater than 19.2M always divide/2 */
+	if (sys_clkin_sel > 2) {
+		/* input clock divider */
+		clrsetbits_le32(&prm_base->clksrc_ctrl, 0x000000C0, 2 << 6);
+		clk_index = sys_clkin_sel / 2;
+	} else {
+		/* input clock divider */
+		clrsetbits_le32(&prm_base->clksrc_ctrl, 0x000000C0, 1 << 6);
+		clk_index = sys_clkin_sel;
+	}
+
+	if (get_cpu_family() == CPU_OMAP36XX) {
+		/*
+		 * In warm reset conditions on OMAP36xx/AM/DM37xx
+		 * the rom code incorrectly sets the DPLL4 clock
+		 * input divider to /6.5. Section 3.5.3.3.3.2.1 of
+		 * the AM/DM37x TRM explains that the /6.5 divider
+		 * is used only when the input clock is 13MHz.
+		 *
+		 * If the part is in this cpu family *and* the input
+		 * clock *is not* 13 MHz, then reset the DPLL4 clock
+		 * input divider to /1 as it should never set to /6.5
+		 * in this case.
+		 */
+		if (sys_clkin_sel != 1) {	/* 13 MHz */
+			/* Bit 8: DPLL4_CLKINP_DIV */
+			clrbits_le32(&prm_base->clksrc_ctrl, 0x00000100);
+		}
+
+		/* Unlock MPU DPLL (slows things down, and needed later) */
+		clrsetbits_le32(&prcm_base->clken_pll_mpu,
+				0x00000007, PLL_LOW_POWER_BYPASS);
+		wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
+				LDELAY);
+
+		dpll3_init_36xx(0, clk_index);
+		dpll4_init_36xx(0, clk_index);
+		dpll5_init_36xx(0, clk_index);
+		iva_init_36xx(0, clk_index);
+		mpu_init_36xx(0, clk_index);
+
+		/* Lock MPU DPLL to set frequency */
+		clrsetbits_le32(&prcm_base->clken_pll_mpu,
+				0x00000007, PLL_LOCK);
+		wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
+				LDELAY);
+	} else {
+		/*
+		 * The DPLL tables are defined according to sysclk value and
+		 * silicon revision. The clk_index value will be used to get
+		 * the values for that input sysclk from the DPLL param table
+		 * and sil_index will get the values for that SysClk for the
+		 * appropriate silicon rev.
+		 */
+		if (((get_cpu_family() == CPU_OMAP34XX)
+				&& (get_cpu_rev() >= CPU_3XX_ES20)) ||
+			(get_cpu_family() == CPU_AM35XX))
+			sil_index = 1;
+
+		/* Unlock MPU DPLL (slows things down, and needed later) */
+		clrsetbits_le32(&prcm_base->clken_pll_mpu,
+				0x00000007, PLL_LOW_POWER_BYPASS);
+		wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
+				LDELAY);
+
+		dpll3_init_34xx(sil_index, clk_index);
+		dpll4_init_34xx(sil_index, clk_index);
+		dpll5_init_34xx(sil_index, clk_index);
+		if (get_cpu_family() != CPU_AM35XX)
+			iva_init_34xx(sil_index, clk_index);
+
+		mpu_init_34xx(sil_index, clk_index);
+
+		/* Lock MPU DPLL to set frequency */
+		clrsetbits_le32(&prcm_base->clken_pll_mpu,
+				0x00000007, PLL_LOCK);
+		wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
+				LDELAY);
+	}
+
+	/* Set up GPTimers to sys_clk source only */
+	setbits_le32(&prcm_base->clksel_per, 0x000000FF);
+	setbits_le32(&prcm_base->clksel_wkup, 1);
+
+	sdelay(5000);
+}
+
+/*
+ * Enable usb ehci uhh, tll clocks
+ */
+void ehci_clocks_enable(void)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+
+	/* Enable USBHOST_L3_ICLK (USBHOST_MICLK) */
+	setbits_le32(&prcm_base->iclken_usbhost, 1);
+	/*
+	 * Enable USBHOST_48M_FCLK (USBHOST_FCLK1)
+	 * and USBHOST_120M_FCLK (USBHOST_FCLK2)
+	 */
+	setbits_le32(&prcm_base->fclken_usbhost, 0x00000003);
+	/* Enable USBTTL_ICLK */
+	setbits_le32(&prcm_base->iclken3_core, 0x00000004);
+	/* Enable USBTTL_FCLK */
+	setbits_le32(&prcm_base->fclken3_core, 0x00000004);
+}
+
+/******************************************************************************
+ * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...)
+ *****************************************************************************/
+void per_clocks_enable(void)
+{
+	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+
+	/* Enable GP2 timer. */
+	setbits_le32(&prcm_base->clksel_per, 0x01);	/* GPT2 = sys clk */
+	setbits_le32(&prcm_base->iclken_per, 0x08);	/* ICKen GPT2 */
+	setbits_le32(&prcm_base->fclken_per, 0x08);	/* FCKen GPT2 */
+
+	/* Enable GP9 timer. */
+	setbits_le32(&prcm_base->clksel_per, 0x80);	/* GPT9 = 32kHz clk */
+	setbits_le32(&prcm_base->iclken_per, 0x400);	/* ICKen GPT9 */
+	setbits_le32(&prcm_base->fclken_per, 0x400);	/* FCKen GPT9 */
+
+#ifdef CONFIG_SYS_NS16550
+	/* Enable UART1 clocks */
+	setbits_le32(&prcm_base->fclken1_core, 0x00002000);
+	setbits_le32(&prcm_base->iclken1_core, 0x00002000);
+
+	/* Enable UART2 clocks */
+	setbits_le32(&prcm_base->fclken1_core, 0x00004000);
+	setbits_le32(&prcm_base->iclken1_core, 0x00004000);
+
+	/* UART 3 Clocks */
+	setbits_le32(&prcm_base->fclken_per, 0x00000800);
+	setbits_le32(&prcm_base->iclken_per, 0x00000800);
+#endif
+
+#ifdef CONFIG_OMAP3_GPIO_2
+	setbits_le32(&prcm_base->fclken_per, 0x00002000);
+	setbits_le32(&prcm_base->iclken_per, 0x00002000);
+#endif
+#ifdef CONFIG_OMAP3_GPIO_3
+	setbits_le32(&prcm_base->fclken_per, 0x00004000);
+	setbits_le32(&prcm_base->iclken_per, 0x00004000);
+#endif
+#ifdef CONFIG_OMAP3_GPIO_4
+	setbits_le32(&prcm_base->fclken_per, 0x00008000);
+	setbits_le32(&prcm_base->iclken_per, 0x00008000);
+#endif
+#ifdef CONFIG_OMAP3_GPIO_5
+	setbits_le32(&prcm_base->fclken_per, 0x00010000);
+	setbits_le32(&prcm_base->iclken_per, 0x00010000);
+#endif
+#ifdef CONFIG_OMAP3_GPIO_6
+	setbits_le32(&prcm_base->fclken_per, 0x00020000);
+	setbits_le32(&prcm_base->iclken_per, 0x00020000);
+#endif
+
+#ifdef CONFIG_SYS_I2C_OMAP34XX
+	/* Turn on all 3 I2C clocks */
+	setbits_le32(&prcm_base->fclken1_core, 0x00038000);
+	setbits_le32(&prcm_base->iclken1_core, 0x00038000); /* I2C1,2,3 = on */
+#endif
+	/* Enable the ICLK for 32K Sync Timer as its used in udelay */
+	setbits_le32(&prcm_base->iclken_wkup, 0x00000004);
+
+	if (get_cpu_family() != CPU_AM35XX)
+		out_le32(&prcm_base->fclken_iva2, FCK_IVA2_ON);
+
+	out_le32(&prcm_base->fclken1_core, FCK_CORE1_ON);
+	out_le32(&prcm_base->iclken1_core, ICK_CORE1_ON);
+	out_le32(&prcm_base->iclken2_core, ICK_CORE2_ON);
+	out_le32(&prcm_base->fclken_wkup, FCK_WKUP_ON);
+	out_le32(&prcm_base->iclken_wkup, ICK_WKUP_ON);
+	out_le32(&prcm_base->fclken_dss, FCK_DSS_ON);
+	out_le32(&prcm_base->iclken_dss, ICK_DSS_ON);
+	if (get_cpu_family() != CPU_AM35XX) {
+		out_le32(&prcm_base->fclken_cam, FCK_CAM_ON);
+		out_le32(&prcm_base->iclken_cam, ICK_CAM_ON);
+	}
+
+	sdelay(1000);
+}
diff --git a/arch/arm/mach-omap2/omap3/emac.c b/arch/arm/mach-omap2/omap3/emac.c
new file mode 100644
index 0000000..37f4b8b
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/emac.c
@@ -0,0 +1,29 @@
+/*
+ *
+ * DaVinci EMAC initialization.
+ *
+ * (C) Copyright 2011, Ilya Yanok, Emcraft Systems
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <asm/arch/am35x_def.h>
+
+/*
+ * Initializes on-chip ethernet controllers.
+ * to override, implement board_eth_init()
+ */
+int cpu_eth_init(bd_t *bis)
+{
+	u32 reset;
+
+	/* ensure that the module is out of reset */
+	reset = readl(&am35x_scm_general_regs->ip_sw_reset);
+	reset &= ~CPGMACSS_SW_RST;
+	writel(reset, &am35x_scm_general_regs->ip_sw_reset);
+
+	return davinci_emac_initialize();
+}
diff --git a/arch/arm/mach-omap2/omap3/emif4.c b/arch/arm/mach-omap2/omap3/emif4.c
new file mode 100644
index 0000000..a2aadc9
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/emif4.c
@@ -0,0 +1,165 @@
+/*
+ * Author :
+ *     Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+ * Based on mem.c and sdrc.c
+ *
+ * Copyright (C) 2010
+ * Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/emif4.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+extern omap3_sysinfo sysinfo;
+
+static emif4_t *emif4_base = (emif4_t *)OMAP34XX_SDRC_BASE;
+
+/*
+ * is_mem_sdr -
+ *  - Return 1 if mem type in use is SDR
+ */
+u32 is_mem_sdr(void)
+{
+	return 0;
+}
+
+/*
+ * get_sdr_cs_size -
+ *  - Get size of chip select 0/1
+ */
+u32 get_sdr_cs_size(u32 cs)
+{
+	u32 size = 0;
+
+	/* TODO: Calculate the size based on EMIF4 configuration */
+	if (cs == CS0)
+		size = CONFIG_SYS_CS0_SIZE;
+
+	return size;
+}
+
+/*
+ * get_sdr_cs_offset -
+ *  - Get offset of cs from cs0 start
+ */
+u32 get_sdr_cs_offset(u32 cs)
+{
+	u32 offset = 0;
+
+	return offset;
+}
+
+/*
+ * do_emif4_init -
+ *  - Init the emif4 module for DDR access
+ *  - Early init routines, called from flash or SRAM.
+ */
+static void do_emif4_init(void)
+{
+	unsigned int regval;
+	/* Set the DDR PHY parameters in PHY ctrl registers */
+	regval = (EMIF4_DDR1_READ_LAT | EMIF4_DDR1_PWRDN_DIS |
+		EMIF4_DDR1_EXT_STRB_DIS);
+	writel(regval, &emif4_base->ddr_phyctrl1);
+	writel(regval, &emif4_base->ddr_phyctrl1_shdw);
+	writel(0, &emif4_base->ddr_phyctrl2);
+
+	/* Reset the DDR PHY and wait till completed */
+	regval = readl(&emif4_base->sdram_iodft_tlgc);
+	regval |= (1<<10);
+	writel(regval, &emif4_base->sdram_iodft_tlgc);
+	/*Wait till that bit clears*/
+	while ((readl(&emif4_base->sdram_iodft_tlgc) & (1<<10)) == 0x1);
+	/*Re-verify the DDR PHY status*/
+	while ((readl(&emif4_base->sdram_sts) & (1<<2)) == 0x0);
+
+	regval |= (1<<0);
+	writel(regval, &emif4_base->sdram_iodft_tlgc);
+	/* Set SDR timing registers */
+	regval = (EMIF4_TIM1_T_WTR | EMIF4_TIM1_T_RRD |
+		EMIF4_TIM1_T_RC | EMIF4_TIM1_T_RAS |
+		EMIF4_TIM1_T_WR | EMIF4_TIM1_T_RCD |
+		EMIF4_TIM1_T_RP);
+	writel(regval, &emif4_base->sdram_time1);
+	writel(regval, &emif4_base->sdram_time1_shdw);
+
+	regval = (EMIF4_TIM2_T_CKE | EMIF4_TIM2_T_RTP |
+		EMIF4_TIM2_T_XSRD | EMIF4_TIM2_T_XSNR |
+		EMIF4_TIM2_T_ODT | EMIF4_TIM2_T_XP);
+	writel(regval, &emif4_base->sdram_time2);
+	writel(regval, &emif4_base->sdram_time2_shdw);
+
+	regval = (EMIF4_TIM3_T_RAS_MAX | EMIF4_TIM3_T_RFC);
+	writel(regval, &emif4_base->sdram_time3);
+	writel(regval, &emif4_base->sdram_time3_shdw);
+
+	/* Set the PWR control register */
+	regval = (EMIF4_PWR_PM_TIM | EMIF4_PWR_LP_MODE |
+		EMIF4_PWR_DPD_DIS | EMIF4_PWR_IDLE_MODE);
+	writel(regval, &emif4_base->sdram_pwr_mgmt);
+	writel(regval, &emif4_base->sdram_pwr_mgmt_shdw);
+
+	/* Set the DDR refresh rate control register */
+	regval = (EMIF4_REFRESH_RATE | EMIF4_INITREF_DIS);
+	writel(regval, &emif4_base->sdram_refresh_ctrl);
+	writel(regval, &emif4_base->sdram_refresh_ctrl_shdw);
+
+	/* set the SDRAM configuration register */
+	regval = (EMIF4_CFG_PGSIZE | EMIF4_CFG_EBANK |
+		EMIF4_CFG_IBANK | EMIF4_CFG_ROWSIZE |
+		EMIF4_CFG_CL | EMIF4_CFG_NARROW_MD |
+		EMIF4_CFG_SDR_DRV | EMIF4_CFG_DDR_DIS_DLL |
+		EMIF4_CFG_DDR2_DDQS | EMIF4_CFG_DDR_TERM |
+		EMIF4_CFG_IBANK_POS | EMIF4_CFG_SDRAM_TYP);
+	writel(regval, &emif4_base->sdram_config);
+}
+
+/*
+ * dram_init -
+ *  - Sets uboots idea of sdram size
+ */
+int dram_init(void)
+{
+	unsigned int size0 = 0, size1 = 0;
+
+	size0 = get_sdr_cs_size(CS0);
+	/*
+	 * If a second bank of DDR is attached to CS1 this is
+	 * where it can be started.  Early init code will init
+	 * memory on CS0.
+	 */
+	if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED))
+		size1 = get_sdr_cs_size(CS1);
+
+	gd->ram_size = size0 + size1;
+	return 0;
+}
+
+void dram_init_banksize (void)
+{
+	unsigned int size0 = 0, size1 = 0;
+
+	size0 = get_sdr_cs_size(CS0);
+	size1 = get_sdr_cs_size(CS1);
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = size0;
+	gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1);
+	gd->bd->bi_dram[1].size = size1;
+}
+
+/*
+ * mem_init() -
+ *  - Initialize memory subsystem
+ */
+void mem_init(void)
+{
+	do_emif4_init();
+}
diff --git a/arch/arm/mach-omap2/omap3/lowlevel_init.S b/arch/arm/mach-omap2/omap3/lowlevel_init.S
new file mode 100644
index 0000000..1e58772
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/lowlevel_init.S
@@ -0,0 +1,476 @@
+/*
+ * Board specific setup info
+ *
+ * (C) Copyright 2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Initial Code by:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Syed Mohammed Khasim <khasim@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/clocks_omap3.h>
+#include <linux/linkage.h>
+
+/*
+ * Funtion for making PPA HAL API calls in secure devices
+ * Input:
+ *	R0 - Service ID
+ *	R1 - paramer list
+ */
+ENTRY(do_omap3_emu_romcode_call)
+	PUSH {r4-r12, lr} @ Save all registers from ROM code!
+	MOV r12, r0	@ Copy the Secure Service ID in R12
+	MOV r3, r1	@ Copy the pointer to va_list in R3
+	MOV r1, #0	@ Process ID - 0
+	MOV r2, #OMAP3_EMU_HAL_START_HAL_CRITICAL	@ Copy the pointer
+							@ to va_list in R3
+	MOV r6, #0xFF	@ Indicate new Task call
+	mcr     p15, 0, r0, c7, c10, 4	@ DSB
+	mcr     p15, 0, r0, c7, c10, 5	@ DMB
+	.word	0xe1600071	@ SMC #1 to call PPA service - hand assembled
+				@ because we use -march=armv5
+	POP {r4-r12, pc}
+ENDPROC(do_omap3_emu_romcode_call)
+
+#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_NAND_BOOT)
+/**************************************************************************
+ * cpy_clk_code: relocates clock code into SRAM where its safer to execute
+ * R1 = SRAM destination address.
+ *************************************************************************/
+ENTRY(cpy_clk_code)
+	/* Copy DPLL code into SRAM */
+	adr	r0, go_to_speed		/* copy from start of go_to_speed... */
+	adr	r2, lowlevel_init	/* ... up to start of low_level_init */
+next2:
+	ldmia	r0!, {r3 - r10}		/* copy from source address [r0] */
+	stmia	r1!, {r3 - r10}		/* copy to   target address [r1] */
+	cmp	r0, r2			/* until source end address [r2] */
+	blo	next2
+	mov	pc, lr			/* back to caller */
+ENDPROC(cpy_clk_code)
+
+/* ***************************************************************************
+ *  go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed
+ *               -executed from SRAM.
+ *  R0 = CM_CLKEN_PLL-bypass value
+ *  R1 = CM_CLKSEL1_PLL-m, n, and divider values
+ *  R2 = CM_CLKSEL_CORE-divider values
+ *  R3 = CM_IDLEST_CKGEN - addr dpll lock wait
+ *
+ *  Note: If core unlocks/relocks and SDRAM is running fast already it gets
+ *        confused.  A reset of the controller gets it back.  Taking away its
+ *        L3 when its not in self refresh seems bad for it.  Normally, this
+ *	  code runs from flash before SDR is init so that should be ok.
+ ****************************************************************************/
+ENTRY(go_to_speed)
+	stmfd sp!, {r4 - r6}
+
+	/* move into fast relock bypass */
+	ldr	r4, pll_ctl_add
+	str	r0, [r4]
+wait1:
+	ldr	r5, [r3]		/* get status */
+	and	r5, r5, #0x1		/* isolate core status */
+	cmp	r5, #0x1		/* still locked? */
+	beq	wait1			/* if lock, loop */
+
+	/* set new dpll dividers _after_ in bypass */
+	ldr	r5, pll_div_add1
+	str	r1, [r5]		/* set m, n, m2 */
+	ldr	r5, pll_div_add2
+	str	r2, [r5]		/* set l3/l4/.. dividers*/
+	ldr	r5, pll_div_add3	/* wkup */
+	ldr	r2, pll_div_val3	/* rsm val */
+	str	r2, [r5]
+	ldr	r5, pll_div_add4	/* gfx */
+	ldr	r2, pll_div_val4
+	str	r2, [r5]
+	ldr	r5, pll_div_add5	/* emu */
+	ldr	r2, pll_div_val5
+	str	r2, [r5]
+
+	/* now prepare GPMC (flash) for new dpll speed */
+	/* flash needs to be stable when we jump back to it */
+	ldr	r5, flash_cfg3_addr
+	ldr	r2, flash_cfg3_val
+	str	r2, [r5]
+	ldr	r5, flash_cfg4_addr
+	ldr	r2, flash_cfg4_val
+	str	r2, [r5]
+	ldr	r5, flash_cfg5_addr
+	ldr	r2, flash_cfg5_val
+	str	r2, [r5]
+	ldr	r5, flash_cfg1_addr
+	ldr	r2, [r5]
+	orr	r2, r2, #0x3		/* up gpmc divider */
+	str	r2, [r5]
+
+	/* lock DPLL3 and wait a bit */
+	orr	r0, r0, #0x7	/* set up for lock mode */
+	str	r0, [r4]	/* lock */
+	nop			/* ARM slow at this point working at sys_clk */
+	nop
+	nop
+	nop
+wait2:
+	ldr	r5, [r3]	/* get status */
+	and	r5, r5, #0x1	/* isolate core status */
+	cmp	r5, #0x1	/* still locked? */
+	bne	wait2		/* if lock, loop */
+	nop
+	nop
+	nop
+	nop
+	ldmfd	sp!, {r4 - r6}
+	mov	pc, lr		/* back to caller, locked */
+ENDPROC(go_to_speed)
+
+_go_to_speed: .word go_to_speed
+
+/* these constants need to be close for PIC code */
+/* The Nor has to be in the Flash Base CS0 for this condition to happen */
+flash_cfg1_addr:
+	.word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG1)
+flash_cfg3_addr:
+	.word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG3)
+flash_cfg3_val:
+	.word STNOR_GPMC_CONFIG3
+flash_cfg4_addr:
+	.word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG4)
+flash_cfg4_val:
+	.word STNOR_GPMC_CONFIG4
+flash_cfg5_val:
+	.word STNOR_GPMC_CONFIG5
+flash_cfg5_addr:
+	.word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG5)
+pll_ctl_add:
+	.word CM_CLKEN_PLL
+pll_div_add1:
+	.word CM_CLKSEL1_PLL
+pll_div_add2:
+	.word CM_CLKSEL_CORE
+pll_div_add3:
+	.word CM_CLKSEL_WKUP
+pll_div_val3:
+	.word (WKUP_RSM << 1)
+pll_div_add4:
+	.word CM_CLKSEL_GFX
+pll_div_val4:
+	.word (GFX_DIV << 0)
+pll_div_add5:
+	.word CM_CLKSEL1_EMU
+pll_div_val5:
+	.word CLSEL1_EMU_VAL
+
+#endif
+
+ENTRY(lowlevel_init)
+	ldr	sp, SRAM_STACK
+	str	ip, [sp]	/* stash ip register */
+	mov	ip, lr		/* save link reg across call */
+#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT)
+/*
+ * No need to copy/exec the clock code - DPLL adjust already done
+ * in NAND/oneNAND Boot.
+ */
+	ldr	r1, =SRAM_CLK_CODE
+	bl	cpy_clk_code
+#endif /* NAND Boot */
+	mov	lr, ip		/* restore link reg */
+	ldr	ip, [sp]	/* restore save ip */
+	/* tail-call s_init to setup pll, mux, memory */
+	b	s_init
+
+ENDPROC(lowlevel_init)
+
+	/* the literal pools origin */
+	.ltorg
+
+REG_CONTROL_STATUS:
+	.word CONTROL_STATUS
+SRAM_STACK:
+	.word LOW_LEVEL_SRAM_STACK
+
+/* DPLL(1-4) PARAM TABLES */
+
+/*
+ * Each of the tables has M, N, FREQSEL, M2 values defined for nominal
+ * OPP (1.2V). The fields are defined according to dpll_param struct (clock.c).
+ * The values are defined for all possible sysclk and for ES1 and ES2.
+ */
+
+mpu_dpll_param:
+/* 12MHz */
+/* ES1 */
+.word MPU_M_12_ES1, MPU_N_12_ES1, MPU_FSEL_12_ES1, MPU_M2_12_ES1
+/* ES2 */
+.word MPU_M_12_ES2, MPU_N_12_ES2, MPU_FSEL_12_ES2, MPU_M2_ES2
+/* 3410 */
+.word MPU_M_12, MPU_N_12, MPU_FSEL_12, MPU_M2_12
+
+/* 13MHz */
+/* ES1 */
+.word MPU_M_13_ES1, MPU_N_13_ES1, MPU_FSEL_13_ES1, MPU_M2_13_ES1
+/* ES2 */
+.word MPU_M_13_ES2, MPU_N_13_ES2, MPU_FSEL_13_ES2, MPU_M2_13_ES2
+/* 3410 */
+.word MPU_M_13, MPU_N_13, MPU_FSEL_13, MPU_M2_13
+
+/* 19.2MHz */
+/* ES1 */
+.word MPU_M_19P2_ES1, MPU_N_19P2_ES1, MPU_FSEL_19P2_ES1, MPU_M2_19P2_ES1
+/* ES2 */
+.word MPU_M_19P2_ES2, MPU_N_19P2_ES2, MPU_FSEL_19P2_ES2, MPU_M2_19P2_ES2
+/* 3410 */
+.word MPU_M_19P2, MPU_N_19P2, MPU_FSEL_19P2, MPU_M2_19P2
+
+/* 26MHz */
+/* ES1 */
+.word MPU_M_26_ES1, MPU_N_26_ES1, MPU_FSEL_26_ES1, MPU_M2_26_ES1
+/* ES2 */
+.word MPU_M_26_ES2, MPU_N_26_ES2, MPU_FSEL_26_ES2, MPU_M2_26_ES2
+/* 3410 */
+.word MPU_M_26, MPU_N_26, MPU_FSEL_26, MPU_M2_26
+
+/* 38.4MHz */
+/* ES1 */
+.word MPU_M_38P4_ES1, MPU_N_38P4_ES1, MPU_FSEL_38P4_ES1, MPU_M2_38P4_ES1
+/* ES2 */
+.word MPU_M_38P4_ES2, MPU_N_38P4_ES2, MPU_FSEL_38P4_ES2, MPU_M2_38P4_ES2
+/* 3410 */
+.word MPU_M_38P4, MPU_N_38P4, MPU_FSEL_38P4, MPU_M2_38P4
+
+
+.globl get_mpu_dpll_param
+get_mpu_dpll_param:
+	adr	r0, mpu_dpll_param
+	mov	pc, lr
+
+iva_dpll_param:
+/* 12MHz */
+/* ES1 */
+.word IVA_M_12_ES1, IVA_N_12_ES1, IVA_FSEL_12_ES1, IVA_M2_12_ES1
+/* ES2 */
+.word IVA_M_12_ES2, IVA_N_12_ES2, IVA_FSEL_12_ES2, IVA_M2_12_ES2
+/* 3410 */
+.word IVA_M_12, IVA_N_12, IVA_FSEL_12, IVA_M2_12
+
+/* 13MHz */
+/* ES1 */
+.word IVA_M_13_ES1, IVA_N_13_ES1, IVA_FSEL_13_ES1, IVA_M2_13_ES1
+/* ES2 */
+.word IVA_M_13_ES2, IVA_N_13_ES2,  IVA_FSEL_13_ES2, IVA_M2_13_ES2
+/* 3410 */
+.word IVA_M_13, IVA_N_13, IVA_FSEL_13, IVA_M2_13
+
+/* 19.2MHz */
+/* ES1 */
+.word IVA_M_19P2_ES1, IVA_N_19P2_ES1, IVA_FSEL_19P2_ES1, IVA_M2_19P2_ES1
+/* ES2 */
+.word IVA_M_19P2_ES2, IVA_N_19P2_ES2, IVA_FSEL_19P2_ES2, IVA_M2_19P2_ES2
+/* 3410 */
+.word IVA_M_19P2, IVA_N_19P2, IVA_FSEL_19P2, IVA_M2_19P2
+
+/* 26MHz */
+/* ES1 */
+.word IVA_M_26_ES1, IVA_N_26_ES1, IVA_FSEL_26_ES1, IVA_M2_26_ES1
+/* ES2 */
+.word IVA_M_26_ES2, IVA_N_26_ES2, IVA_FSEL_26_ES2, IVA_M2_26_ES2
+/* 3410 */
+.word IVA_M_26, IVA_N_26, IVA_FSEL_26, IVA_M2_26
+
+/* 38.4MHz */
+/* ES1 */
+.word IVA_M_38P4_ES1, IVA_N_38P4_ES1, IVA_FSEL_38P4_ES1, IVA_M2_38P4_ES1
+/* ES2 */
+.word IVA_M_38P4_ES2, IVA_N_38P4_ES2, IVA_FSEL_38P4_ES2, IVA_M2_38P4_ES2
+/* 3410 */
+.word IVA_M_38P4, IVA_N_38P4, IVA_FSEL_38P4, IVA_M2_38P4
+
+
+.globl get_iva_dpll_param
+get_iva_dpll_param:
+	adr	r0, iva_dpll_param
+	mov	pc, lr
+
+/* Core DPLL targets for L3 at 166 & L133 */
+core_dpll_param:
+/* 12MHz */
+/* ES1 */
+.word CORE_M_12_ES1, CORE_N_12_ES1, CORE_FSL_12_ES1, CORE_M2_12_ES1
+/* ES2 */
+.word CORE_M_12, CORE_N_12, CORE_FSEL_12, CORE_M2_12
+/* 3410 */
+.word CORE_M_12, CORE_N_12, CORE_FSEL_12, CORE_M2_12
+
+/* 13MHz */
+/* ES1 */
+.word CORE_M_13_ES1, CORE_N_13_ES1, CORE_FSL_13_ES1, CORE_M2_13_ES1
+/* ES2 */
+.word CORE_M_13, CORE_N_13, CORE_FSEL_13, CORE_M2_13
+/* 3410 */
+.word CORE_M_13, CORE_N_13, CORE_FSEL_13, CORE_M2_13
+
+/* 19.2MHz */
+/* ES1 */
+.word CORE_M_19P2_ES1, CORE_N_19P2_ES1, CORE_FSL_19P2_ES1, CORE_M2_19P2_ES1
+/* ES2 */
+.word CORE_M_19P2, CORE_N_19P2, CORE_FSEL_19P2, CORE_M2_19P2
+/* 3410 */
+.word CORE_M_19P2, CORE_N_19P2, CORE_FSEL_19P2, CORE_M2_19P2
+
+/* 26MHz */
+/* ES1 */
+.word CORE_M_26_ES1, CORE_N_26_ES1, CORE_FSL_26_ES1, CORE_M2_26_ES1
+/* ES2 */
+.word CORE_M_26, CORE_N_26, CORE_FSEL_26, CORE_M2_26
+/* 3410 */
+.word CORE_M_26, CORE_N_26, CORE_FSEL_26, CORE_M2_26
+
+/* 38.4MHz */
+/* ES1 */
+.word CORE_M_38P4_ES1, CORE_N_38P4_ES1, CORE_FSL_38P4_ES1, CORE_M2_38P4_ES1
+/* ES2 */
+.word CORE_M_38P4, CORE_N_38P4, CORE_FSEL_38P4, CORE_M2_38P4
+/* 3410 */
+.word CORE_M_38P4, CORE_N_38P4, CORE_FSEL_38P4, CORE_M2_38P4
+
+.globl get_core_dpll_param
+get_core_dpll_param:
+	adr	r0, core_dpll_param
+	mov	pc, lr
+
+/* PER DPLL values are same for both ES1 and ES2 */
+per_dpll_param:
+/* 12MHz */
+.word PER_M_12, PER_N_12, PER_FSEL_12, PER_M2_12
+
+/* 13MHz */
+.word PER_M_13, PER_N_13, PER_FSEL_13, PER_M2_13
+
+/* 19.2MHz */
+.word PER_M_19P2, PER_N_19P2, PER_FSEL_19P2, PER_M2_19P2
+
+/* 26MHz */
+.word PER_M_26, PER_N_26, PER_FSEL_26, PER_M2_26
+
+/* 38.4MHz */
+.word PER_M_38P4, PER_N_38P4, PER_FSEL_38P4, PER_M2_38P4
+
+.globl get_per_dpll_param
+get_per_dpll_param:
+	adr	r0, per_dpll_param
+	mov	pc, lr
+
+/* PER2 DPLL values */
+per2_dpll_param:
+/* 12MHz */
+.word PER2_M_12, PER2_N_12, PER2_FSEL_12, PER2_M2_12
+
+/* 13MHz */
+.word PER2_M_13, PER2_N_13, PER2_FSEL_13, PER2_M2_13
+
+/* 19.2MHz */
+.word PER2_M_19P2, PER2_N_19P2, PER2_FSEL_19P2, PER2_M2_19P2
+
+/* 26MHz */
+.word PER2_M_26, PER2_N_26, PER2_FSEL_26, PER2_M2_26
+
+/* 38.4MHz */
+.word PER2_M_38P4, PER2_N_38P4, PER2_FSEL_38P4, PER2_M2_38P4
+
+.globl get_per2_dpll_param
+get_per2_dpll_param:
+	adr	r0, per2_dpll_param
+	mov	pc, lr
+
+/*
+ * Tables for 36XX/37XX devices
+ *
+ */
+mpu_36x_dpll_param:
+/* 12MHz */
+.word 50, 0, 0, 1
+/* 13MHz */
+.word 600, 12, 0, 1
+/* 19.2MHz */
+.word 125, 3, 0, 1
+/* 26MHz */
+.word 300, 12, 0, 1
+/* 38.4MHz */
+.word 125, 7, 0, 1
+
+iva_36x_dpll_param:
+/* 12MHz */
+.word 130, 2, 0, 1
+/* 13MHz */
+.word 20, 0, 0, 1
+/* 19.2MHz */
+.word 325, 11, 0, 1
+/* 26MHz */
+.word 10, 0, 0, 1
+/* 38.4MHz */
+.word 325, 23, 0, 1
+
+core_36x_dpll_param:
+/* 12MHz */
+.word 100, 2, 0, 1
+/* 13MHz */
+.word 400, 12, 0, 1
+/* 19.2MHz */
+.word 375, 17, 0, 1
+/* 26MHz */
+.word 200, 12, 0, 1
+/* 38.4MHz */
+.word 375, 35, 0, 1
+
+per_36x_dpll_param:
+/*    SYSCLK    M       N      M2      M3      M4     M5      M6      m2DIV */
+.word 12000,    360,    4,     9,      16,     5,     4,      3,      1
+.word 13000,    864,   12,     9,      16,     9,     4,      3,      1
+.word 19200,    360,    7,     9,      16,     5,     4,      3,      1
+.word 26000,    432,   12,     9,      16,     9,     4,      3,      1
+.word 38400,    360,   15,     9,      16,     5,     4,      3,      1
+
+per2_36x_dpll_param:
+/* 12MHz */
+.word PER2_36XX_M_12, PER2_36XX_N_12, 0, PER2_36XX_M2_12
+/* 13MHz */
+.word PER2_36XX_M_13, PER2_36XX_N_13, 0, PER2_36XX_M2_13
+/* 19.2MHz */
+.word PER2_36XX_M_19P2, PER2_36XX_N_19P2, 0, PER2_36XX_M2_19P2
+/* 26MHz */
+.word PER2_36XX_M_26, PER2_36XX_N_26, 0, PER2_36XX_M2_26
+/* 38.4MHz */
+.word PER2_36XX_M_38P4, PER2_36XX_N_38P4, 0, PER2_36XX_M2_38P4
+
+
+ENTRY(get_36x_mpu_dpll_param)
+	adr	r0, mpu_36x_dpll_param
+	mov	pc, lr
+ENDPROC(get_36x_mpu_dpll_param)
+
+ENTRY(get_36x_iva_dpll_param)
+	adr	r0, iva_36x_dpll_param
+	mov	pc, lr
+ENDPROC(get_36x_iva_dpll_param)
+
+ENTRY(get_36x_core_dpll_param)
+	adr	r0, core_36x_dpll_param
+	mov	pc, lr
+ENDPROC(get_36x_core_dpll_param)
+
+ENTRY(get_36x_per_dpll_param)
+	adr	r0, per_36x_dpll_param
+	mov	pc, lr
+ENDPROC(get_36x_per_dpll_param)
+
+ENTRY(get_36x_per2_dpll_param)
+	adr	r0, per2_36x_dpll_param
+	mov	pc, lr
+ENDPROC(get_36x_per2_dpll_param)
diff --git a/arch/arm/mach-omap2/omap3/sdrc.c b/arch/arm/mach-omap2/omap3/sdrc.c
new file mode 100644
index 0000000..4f15ac9
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/sdrc.c
@@ -0,0 +1,241 @@
+/*
+ * Functions related to OMAP3 SDRC.
+ *
+ * This file has been created after exctracting and consolidating
+ * the SDRC related content from mem.c and board.c, also created
+ * generic init function (mem_init).
+ *
+ * Copyright (C) 2004-2010
+ * Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
+ *
+ * Author :
+ *     Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+ * Original implementation by (mem.c, board.c) :
+ *      Sunil Kumar <sunilsaini05@gmail.com>
+ *      Shashi Ranjan <shashiranjanmca05@gmail.com>
+ *      Manikandan Pillai <mani.pillai@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+extern omap3_sysinfo sysinfo;
+
+static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE;
+
+/*
+ * is_mem_sdr -
+ *  - Return 1 if mem type in use is SDR
+ */
+u32 is_mem_sdr(void)
+{
+	if (readl(&sdrc_base->cs[CS0].mr) == SDRC_MR_0_SDR)
+		return 1;
+	return 0;
+}
+
+/*
+ * make_cs1_contiguous -
+ * - When we have CS1 populated we want to have it mapped after cs0 to allow
+ *   command line mem=xyz use all memory with out discontinuous support
+ *   compiled in.  We could do it in the ATAG, but there really is two banks...
+ */
+void make_cs1_contiguous(void)
+{
+	u32 size, a_add_low, a_add_high;
+
+	size = get_sdr_cs_size(CS0);
+	size >>= 25;	/* divide by 32 MiB to find size to offset CS1 */
+	a_add_high = (size & 3) << 8;	/* set up low field */
+	a_add_low = (size & 0x3C) >> 2;	/* set up high field */
+	writel((a_add_high | a_add_low), &sdrc_base->cs_cfg);
+
+}
+
+
+/*
+ * get_sdr_cs_size -
+ *  - Get size of chip select 0/1
+ */
+u32 get_sdr_cs_size(u32 cs)
+{
+	u32 size;
+
+	/* get ram size field */
+	size = readl(&sdrc_base->cs[cs].mcfg) >> 8;
+	size &= 0x3FF;		/* remove unwanted bits */
+	size <<= 21;		/* multiply by 2 MiB to find size in MB */
+	return size;
+}
+
+/*
+ * get_sdr_cs_offset -
+ *  - Get offset of cs from cs0 start
+ */
+u32 get_sdr_cs_offset(u32 cs)
+{
+	u32 offset;
+
+	if (!cs)
+		return 0;
+
+	offset = readl(&sdrc_base->cs_cfg);
+	offset = (offset & 15) << 27 | (offset & 0x300) << 17;
+
+	return offset;
+}
+
+/*
+ * write_sdrc_timings -
+ *  - Takes CS and associated timings and initalize SDRAM
+ *  - Test CS to make sure it's OK for use
+ */
+static void write_sdrc_timings(u32 cs, struct sdrc_actim *sdrc_actim_base,
+			struct board_sdrc_timings *timings)
+{
+	/* Setup timings we got from the board. */
+	writel(timings->mcfg, &sdrc_base->cs[cs].mcfg);
+	writel(timings->ctrla, &sdrc_actim_base->ctrla);
+	writel(timings->ctrlb, &sdrc_actim_base->ctrlb);
+	writel(timings->rfr_ctrl, &sdrc_base->cs[cs].rfr_ctrl);
+	writel(CMD_NOP, &sdrc_base->cs[cs].manual);
+	writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual);
+	writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
+	writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
+	writel(timings->mr, &sdrc_base->cs[cs].mr);
+
+	/*
+	 * Test ram in this bank
+	 * Disable if bad or not present
+	 */
+	if (!mem_ok(cs))
+		writel(0, &sdrc_base->cs[cs].mcfg);
+}
+
+/*
+ * do_sdrc_init -
+ *  - Code called once in C-Stack only context for CS0 and with early being
+ *    true and a possible 2nd time depending on memory configuration from
+ *    stack+global context.
+ */
+void do_sdrc_init(u32 cs, u32 early)
+{
+	struct sdrc_actim *sdrc_actim_base0, *sdrc_actim_base1;
+	struct board_sdrc_timings timings;
+
+	sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE;
+	sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE;
+
+	/* set some default timings */
+	timings.sharing = SDRC_SHARING;
+
+	/*
+	 * When called in the early context this may be SPL and we will
+	 * need to set all of the timings.  This ends up being board
+	 * specific so we call a helper function to take care of this
+	 * for us.  Otherwise, to be safe, we need to copy the settings
+	 * from the first bank to the second.  We will setup CS0,
+	 * then set cs_cfg to the appropriate value then try and
+	 * setup CS1.
+	 */
+#ifdef CONFIG_SPL_BUILD
+	/* set/modify board-specific timings */
+	get_board_mem_timings(&timings);
+#endif
+	if (early) {
+		/* reset sdrc controller */
+		writel(SOFTRESET, &sdrc_base->sysconfig);
+		wait_on_value(RESETDONE, RESETDONE, &sdrc_base->status,
+				12000000);
+		writel(0, &sdrc_base->sysconfig);
+
+		/* setup sdrc to ball mux */
+		writel(timings.sharing, &sdrc_base->sharing);
+
+		/* Disable Power Down of CKE because of 1 CKE on combo part */
+		writel(WAKEUPPROC | SRFRONRESET | PAGEPOLICY_HIGH,
+				&sdrc_base->power);
+
+		writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl);
+		sdelay(0x20000);
+#ifdef CONFIG_SPL_BUILD
+		write_sdrc_timings(CS0, sdrc_actim_base0, &timings);
+		make_cs1_contiguous();
+		write_sdrc_timings(CS1, sdrc_actim_base1, &timings);
+#endif
+
+	}
+
+	/*
+	 * If we aren't using SPL we have been loaded by some
+	 * other means which may not have correctly initialized
+	 * both CS0 and CS1 (such as some older versions of x-loader)
+	 * so we may be asked now to setup CS1.
+	 */
+	if (cs == CS1) {
+		timings.mcfg = readl(&sdrc_base->cs[CS0].mcfg),
+		timings.rfr_ctrl = readl(&sdrc_base->cs[CS0].rfr_ctrl);
+		timings.ctrla = readl(&sdrc_actim_base0->ctrla);
+		timings.ctrlb = readl(&sdrc_actim_base0->ctrlb);
+		timings.mr = readl(&sdrc_base->cs[CS0].mr);
+		write_sdrc_timings(cs, sdrc_actim_base1, &timings);
+	}
+}
+
+/*
+ * dram_init -
+ *  - Sets uboots idea of sdram size
+ */
+int dram_init(void)
+{
+	unsigned int size0 = 0, size1 = 0;
+
+	size0 = get_sdr_cs_size(CS0);
+	/*
+	 * We always need to have cs_cfg point at where the second
+	 * bank would be, if present.  Failure to do so can lead to
+	 * strange situations where memory isn't detected and
+	 * configured correctly.  CS0 will already have been setup
+	 * at this point.
+	 */
+	make_cs1_contiguous();
+	do_sdrc_init(CS1, NOT_EARLY);
+	size1 = get_sdr_cs_size(CS1);
+
+	gd->ram_size = size0 + size1;
+
+	return 0;
+}
+
+void dram_init_banksize (void)
+{
+	unsigned int size0 = 0, size1 = 0;
+
+	size0 = get_sdr_cs_size(CS0);
+	size1 = get_sdr_cs_size(CS1);
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = size0;
+	gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1);
+	gd->bd->bi_dram[1].size = size1;
+}
+
+/*
+ * mem_init -
+ *  - Init the sdrc chip,
+ *  - Selects CS0 and CS1,
+ */
+void mem_init(void)
+{
+	/* only init up first bank here */
+	do_sdrc_init(CS0, EARLY_INIT);
+}
diff --git a/arch/arm/mach-omap2/omap3/spl_id_nand.c b/arch/arm/mach-omap2/omap3/spl_id_nand.c
new file mode 100644
index 0000000..0e2f0a2
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/spl_id_nand.c
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2011
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *     Tom Rini <trini@ti.com>
+ *
+ * Initial Code from:
+ *     Richard Woodruff <r-woodruff2@ti.com>
+ *     Jian Zhang <jzhang@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <jffs2/load_kernel.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/omap_gpmc.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/mem.h>
+
+/*
+ * Many boards will want to know the results of the NAND_CMD_READID command
+ * in order to decide what to do about DDR initialization.  This function
+ * allows us to do that very early and to pass those results back to the
+ * board so it can make whatever decisions need to be made.
+ */
+int identify_nand_chip(int *mfr, int *id)
+{
+	int loops = 1000;
+
+	/* Make sure that we have setup GPMC for NAND correctly. */
+	set_gpmc_cs0(MTD_DEV_TYPE_NAND);
+
+	sdelay(2000);
+
+	/* Issue a RESET and then READID */
+	writeb(NAND_CMD_RESET, &gpmc_cfg->cs[0].nand_cmd);
+	writeb(NAND_CMD_STATUS, &gpmc_cfg->cs[0].nand_cmd);
+	while ((readl(&gpmc_cfg->cs[0].nand_dat) & NAND_STATUS_READY)
+	                                        != NAND_STATUS_READY) {
+		sdelay(100);
+		if (--loops == 0)
+			return 1;
+	}
+	writeb(NAND_CMD_READID, &gpmc_cfg->cs[0].nand_cmd);
+
+	/* Set the address to read to 0x0 */
+	writeb(0x0, &gpmc_cfg->cs[0].nand_adr);
+
+	/* Read off the manufacturer and device id. */
+	*mfr = readb(&gpmc_cfg->cs[0].nand_dat);
+	*id = readb(&gpmc_cfg->cs[0].nand_dat);
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/omap3/sys_info.c b/arch/arm/mach-omap2/omap3/sys_info.c
new file mode 100644
index 0000000..6818fab
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3/sys_info.c
@@ -0,0 +1,343 @@
+/*
+ * (C) Copyright 2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *      Manikandan Pillai <mani.pillai@ti.com>
+ *
+ * Derived from Beagle Board and 3430 SDP code by
+ *      Richard Woodruff <r-woodruff2@ti.com>
+ *      Syed Mohammed Khasim <khasim@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/mem.h>	/* get mem tables */
+#include <asm/arch/sys_proto.h>
+#include <asm/bootm.h>
+
+#include <i2c.h>
+#include <linux/compiler.h>
+
+extern omap3_sysinfo sysinfo;
+static struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE;
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+static char *rev_s[CPU_3XX_MAX_REV] = {
+				"1.0",
+				"2.0",
+				"2.1",
+				"3.0",
+				"3.1",
+				"UNKNOWN",
+				"UNKNOWN",
+				"3.1.2"};
+
+/* this is the revision table for 37xx CPUs */
+static char *rev_s_37xx[CPU_37XX_MAX_REV] = {
+				"1.0",
+				"1.1",
+				"1.2"};
+#endif /* CONFIG_DISPLAY_CPUINFO */
+
+void omap_die_id(unsigned int *die_id)
+{
+	struct ctrl_id *id_base = (struct ctrl_id *)OMAP34XX_ID_L4_IO_BASE;
+
+	die_id[0] = readl(&id_base->die_id_0);
+	die_id[1] = readl(&id_base->die_id_1);
+	die_id[2] = readl(&id_base->die_id_2);
+	die_id[3] = readl(&id_base->die_id_3);
+}
+
+/******************************************
+ * get_cpu_type(void) - extract cpu info
+ ******************************************/
+u32 get_cpu_type(void)
+{
+	return readl(&ctrl_base->ctrl_omap_stat);
+}
+
+/******************************************
+ * get_cpu_id(void) - extract cpu id
+ * returns 0 for ES1.0, cpuid otherwise
+ ******************************************/
+u32 get_cpu_id(void)
+{
+	struct ctrl_id *id_base;
+	u32 cpuid = 0;
+
+	/*
+	 * On ES1.0 the IDCODE register is not exposed on L4
+	 * so using CPU ID to differentiate between ES1.0 and > ES1.0.
+	 */
+	__asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(cpuid));
+	if ((cpuid & 0xf) == 0x0) {
+		return 0;
+	} else {
+		/* Decode the IDs on > ES1.0 */
+		id_base = (struct ctrl_id *) OMAP34XX_ID_L4_IO_BASE;
+
+		cpuid = readl(&id_base->idcode);
+	}
+
+	return cpuid;
+}
+
+/******************************************
+ * get_cpu_family(void) - extract cpu info
+ ******************************************/
+u32 get_cpu_family(void)
+{
+	u16 hawkeye;
+	u32 cpu_family;
+	u32 cpuid = get_cpu_id();
+
+	if (cpuid == 0)
+		return CPU_OMAP34XX;
+
+	hawkeye = (cpuid >> HAWKEYE_SHIFT) & 0xffff;
+	switch (hawkeye) {
+	case HAWKEYE_OMAP34XX:
+		cpu_family = CPU_OMAP34XX;
+		break;
+	case HAWKEYE_AM35XX:
+		cpu_family = CPU_AM35XX;
+		break;
+	case HAWKEYE_OMAP36XX:
+		cpu_family = CPU_OMAP36XX;
+		break;
+	default:
+		cpu_family = CPU_OMAP34XX;
+	}
+
+	return cpu_family;
+}
+
+/******************************************
+ * get_cpu_rev(void) - extract version info
+ ******************************************/
+u32 get_cpu_rev(void)
+{
+	u32 cpuid = get_cpu_id();
+
+	if (cpuid == 0)
+		return CPU_3XX_ES10;
+	else
+		return (cpuid >> CPU_3XX_ID_SHIFT) & 0xf;
+}
+
+/*****************************************************************
+ * get_sku_id(void) - read sku_id to get info on max clock rate
+ *****************************************************************/
+u32 get_sku_id(void)
+{
+	struct ctrl_id *id_base = (struct ctrl_id *)OMAP34XX_ID_L4_IO_BASE;
+	return readl(&id_base->sku_id) & SKUID_CLK_MASK;
+}
+
+/***************************************************************************
+ *  get_gpmc0_base() - Return current address hardware will be
+ *     fetching from. The below effectively gives what is correct, its a bit
+ *   mis-leading compared to the TRM.  For the most general case the mask
+ *   needs to be also taken into account this does work in practice.
+ *   - for u-boot we currently map:
+ *       -- 0 to nothing,
+ *       -- 4 to flash
+ *       -- 8 to enent
+ *       -- c to wifi
+ ****************************************************************************/
+u32 get_gpmc0_base(void)
+{
+	u32 b;
+
+	b = readl(&gpmc_cfg->cs[0].config7);
+	b &= 0x1F;		/* keep base [5:0] */
+	b = b << 24;		/* ret 0x0b000000 */
+	return b;
+}
+
+/*******************************************************************
+ * get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand)
+ *******************************************************************/
+u32 get_gpmc0_width(void)
+{
+	return WIDTH_16BIT;
+}
+
+/*************************************************************************
+ * get_board_rev() - setup to pass kernel board revision information
+ * returns:(bit[0-3] sub version, higher bit[7-4] is higher version)
+ *************************************************************************/
+#ifdef CONFIG_REVISION_TAG
+u32 __weak get_board_rev(void)
+{
+	return 0x20;
+}
+#endif
+
+/********************************************************
+ *  get_base(); get upper addr of current execution
+ *******************************************************/
+static u32 get_base(void)
+{
+	u32 val;
+
+	__asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory");
+	val &= 0xF0000000;
+	val >>= 28;
+	return val;
+}
+
+/********************************************************
+ *  is_running_in_flash() - tell if currently running in
+ *  FLASH.
+ *******************************************************/
+u32 is_running_in_flash(void)
+{
+	if (get_base() < 4)
+		return 1;	/* in FLASH */
+
+	return 0;		/* running in SRAM or SDRAM */
+}
+
+/********************************************************
+ *  is_running_in_sram() - tell if currently running in
+ *  SRAM.
+ *******************************************************/
+u32 is_running_in_sram(void)
+{
+	if (get_base() == 4)
+		return 1;	/* in SRAM */
+
+	return 0;		/* running in FLASH or SDRAM */
+}
+
+/********************************************************
+ *  is_running_in_sdram() - tell if currently running in
+ *  SDRAM.
+ *******************************************************/
+u32 is_running_in_sdram(void)
+{
+	if (get_base() > 4)
+		return 1;	/* in SDRAM */
+
+	return 0;		/* running in SRAM or FLASH */
+}
+
+/***************************************************************
+ *  get_boot_type() - Is this an XIP type device or a stream one
+ *  bits 4-0 specify type. Bit 5 says mem/perif
+ ***************************************************************/
+u32 get_boot_type(void)
+{
+	return (readl(&ctrl_base->status) & SYSBOOT_MASK);
+}
+
+/*************************************************************
+ *  get_device_type(): tell if GP/HS/EMU/TST
+ *************************************************************/
+u32 get_device_type(void)
+{
+	return ((readl(&ctrl_base->status) & (DEVICE_MASK)) >> 8);
+}
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+/**
+ * Print CPU information
+ */
+int print_cpuinfo (void)
+{
+	char *cpu_family_s, *cpu_s, *sec_s, *max_clk;
+
+	switch (get_cpu_family()) {
+	case CPU_OMAP34XX:
+		cpu_family_s = "OMAP";
+		switch (get_cpu_type()) {
+		case OMAP3503:
+			cpu_s = "3503";
+			break;
+		case OMAP3515:
+			cpu_s = "3515";
+			break;
+		case OMAP3525:
+			cpu_s = "3525";
+			break;
+		case OMAP3530:
+			cpu_s = "3530";
+			break;
+		default:
+			cpu_s = "35XX";
+			break;
+		}
+		if ((get_cpu_rev() >= CPU_3XX_ES31) &&
+		    (get_sku_id() == SKUID_CLK_720MHZ))
+			max_clk = "720 MHz";
+		else
+			max_clk = "600 MHz";
+
+		break;
+	case CPU_AM35XX:
+		cpu_family_s = "AM";
+		switch (get_cpu_type()) {
+		case AM3505:
+			cpu_s = "3505";
+			break;
+		case AM3517:
+			cpu_s = "3517";
+			break;
+		default:
+			cpu_s = "35XX";
+			break;
+		}
+		max_clk = "600 Mhz";
+		break;
+	case CPU_OMAP36XX:
+		cpu_family_s = "OMAP";
+		switch (get_cpu_type()) {
+		case OMAP3730:
+			cpu_s = "3630/3730";
+			break;
+		default:
+			cpu_s = "36XX/37XX";
+			break;
+		}
+		max_clk = "1 Ghz";
+		break;
+	default:
+		cpu_family_s = "OMAP";
+		cpu_s = "35XX";
+		max_clk = "600 Mhz";
+	}
+
+	switch (get_device_type()) {
+	case TST_DEVICE:
+		sec_s = "TST";
+		break;
+	case EMU_DEVICE:
+		sec_s = "EMU";
+		break;
+	case HS_DEVICE:
+		sec_s = "HS";
+		break;
+	case GP_DEVICE:
+		sec_s = "GP";
+		break;
+	default:
+		sec_s = "?";
+	}
+
+	if (CPU_OMAP36XX == get_cpu_family())
+		printf("%s%s-%s ES%s, CPU-OPP2, L3-200MHz, Max CPU Clock %s\n",
+		       cpu_family_s, cpu_s, sec_s,
+		       rev_s_37xx[get_cpu_rev()], max_clk);
+	else
+		printf("%s%s-%s ES%s, CPU-OPP2, L3-165MHz, Max CPU Clock %s\n",
+			cpu_family_s, cpu_s, sec_s,
+			rev_s[get_cpu_rev()], max_clk);
+
+	return 0;
+}
+#endif	/* CONFIG_DISPLAY_CPUINFO */
diff --git a/arch/arm/mach-omap2/omap4/Kconfig b/arch/arm/mach-omap2/omap4/Kconfig
new file mode 100644
index 0000000..2091dd7
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4/Kconfig
@@ -0,0 +1,65 @@
+if OMAP44XX
+
+config SPL_EXT_SUPPORT
+	default y
+
+config SPL_FAT_SUPPORT
+	default y
+
+config SPL_GPIO_SUPPORT
+	default y
+
+config SPL_I2C_SUPPORT
+	default y
+
+config SPL_LIBCOMMON_SUPPORT
+	default y
+
+config SPL_LIBDISK_SUPPORT
+	default y
+
+config SPL_LIBGENERIC_SUPPORT
+	default y
+
+config SPL_MMC_SUPPORT
+	default y
+
+config SPL_NAND_SUPPORT
+	default y
+
+config SPL_POWER_SUPPORT
+	default y
+
+config SPL_SERIAL_SUPPORT
+	default y
+
+config SPL_DISPLAY_PRINT
+	default y
+
+choice
+	prompt "OMAP4 board select"
+	optional
+
+config TARGET_DUOVERO
+	bool "OMAP4430 Gumstix Duovero"
+
+config TARGET_OMAP4_PANDA
+	bool "TI OMAP4 PandaBoard"
+
+config TARGET_OMAP4_SDP4430
+	bool "TI OMAP4 SDP4430"
+
+config TARGET_KC1
+	bool "Amazon Kindle Fire (first generation)"
+
+endchoice
+
+config SYS_SOC
+	default "omap4"
+
+source "board/gumstix/duovero/Kconfig"
+source "board/ti/panda/Kconfig"
+source "board/ti/sdp4430/Kconfig"
+source "board/amazon/kc1/Kconfig"
+
+endif
diff --git a/arch/arm/mach-omap2/omap4/Makefile b/arch/arm/mach-omap2/omap4/Makefile
new file mode 100644
index 0000000..564f1f6
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4/Makefile
@@ -0,0 +1,13 @@
+#
+# (C) Copyright 2000-2010
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	+= boot.o
+obj-y	+= sdram_elpida.o
+obj-y	+= hwinit.o
+obj-y	+= emif.o
+obj-y	+= prcm-regs.o
+obj-y	+= hw_data.o
diff --git a/arch/arm/mach-omap2/omap4/boot.c b/arch/arm/mach-omap2/omap4/boot.c
new file mode 100644
index 0000000..7f5791e
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4/boot.c
@@ -0,0 +1,105 @@
+/*
+ * OMAP4 boot
+ *
+ * Copyright (C) 2015 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/omap_common.h>
+#include <asm/arch/sys_proto.h>
+#include <spl.h>
+
+static u32 boot_devices[] = {
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_XIPWAIT,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_XIPWAIT,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_XIPWAIT,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_XIPWAIT,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_MMC2_2,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_MMC2_2,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_MMC2_2,
+	BOOT_DEVICE_MMC2_2,
+	BOOT_DEVICE_NONE,
+	BOOT_DEVICE_XIPWAIT,
+};
+
+u32 omap_sys_boot_device(void)
+{
+	u32 sys_boot;
+
+	/* Grab the first 5 bits of the status register for SYS_BOOT. */
+	sys_boot = readl((u32 *) (*ctrl)->control_status) & ((1 << 5) - 1);
+
+	if (sys_boot >= (sizeof(boot_devices) / sizeof(u32)))
+		return BOOT_DEVICE_NONE;
+
+	return boot_devices[sys_boot];
+}
+
+int omap_reboot_mode(char *mode, unsigned int length)
+{
+	unsigned int limit;
+	unsigned int i;
+
+	if (length < 2)
+		return -1;
+
+	if (!warm_reset())
+		return -1;
+
+	limit = (length < OMAP_REBOOT_REASON_SIZE) ? length :
+		OMAP_REBOOT_REASON_SIZE;
+
+	for (i = 0; i < (limit - 1); i++)
+		mode[i] = readb((u8 *)(OMAP44XX_SAR_RAM_BASE +
+			OMAP_REBOOT_REASON_OFFSET + i));
+
+	mode[i] = '\0';
+
+	return 0;
+}
+
+int omap_reboot_mode_clear(void)
+{
+	writeb(0, (u8 *)(OMAP44XX_SAR_RAM_BASE + OMAP_REBOOT_REASON_OFFSET));
+
+	return 0;
+}
+
+int omap_reboot_mode_store(char *mode)
+{
+	unsigned int i;
+
+	for (i = 0; i < (OMAP_REBOOT_REASON_SIZE - 1) && mode[i] != '\0'; i++)
+		writeb(mode[i], (u8 *)(OMAP44XX_SAR_RAM_BASE +
+			OMAP_REBOOT_REASON_OFFSET + i));
+
+	writeb('\0', (u8 *)(OMAP44XX_SAR_RAM_BASE +
+		OMAP_REBOOT_REASON_OFFSET + i));
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/omap4/emif.c b/arch/arm/mach-omap2/omap4/emif.c
new file mode 100644
index 0000000..403c3c6
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4/emif.c
@@ -0,0 +1,112 @@
+/*
+ * EMIF programming
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/emif.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/utils.h>
+
+#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
+u32 *const T_num = (u32 *)OMAP_SRAM_SCRATCH_EMIF_T_NUM;
+u32 *const T_den = (u32 *)OMAP_SRAM_SCRATCH_EMIF_T_DEN;
+#endif
+
+#ifdef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
+/* Base AC Timing values specified by JESD209-2 for 400MHz operation */
+static const struct lpddr2_ac_timings timings_jedec_400_mhz = {
+	.max_freq = 400000000,
+	.RL = 6,
+	.tRPab = 21,
+	.tRCD = 18,
+	.tWR = 15,
+	.tRASmin = 42,
+	.tRRD = 10,
+	.tWTRx2 = 15,
+	.tXSR = 140,
+	.tXPx2 = 15,
+	.tRFCab = 130,
+	.tRTPx2 = 15,
+	.tCKE = 3,
+	.tCKESR = 15,
+	.tZQCS = 90,
+	.tZQCL = 360,
+	.tZQINIT = 1000,
+	.tDQSCKMAXx2 = 11,
+	.tRASmax = 70,
+	.tFAW = 50
+};
+
+/* Base AC Timing values specified by JESD209-2 for 200 MHz operation */
+static const struct lpddr2_ac_timings timings_jedec_200_mhz = {
+	.max_freq = 200000000,
+	.RL = 3,
+	.tRPab = 21,
+	.tRCD = 18,
+	.tWR = 15,
+	.tRASmin = 42,
+	.tRRD = 10,
+	.tWTRx2 = 20,
+	.tXSR = 140,
+	.tXPx2 = 15,
+	.tRFCab = 130,
+	.tRTPx2 = 15,
+	.tCKE = 3,
+	.tCKESR = 15,
+	.tZQCS = 90,
+	.tZQCL = 360,
+	.tZQINIT = 1000,
+	.tDQSCKMAXx2 = 11,
+	.tRASmax = 70,
+	.tFAW = 50
+};
+
+/*
+ * Min tCK values specified by JESD209-2
+ * Min tCK specifies the minimum duration of some AC timing parameters in terms
+ * of the number of cycles. If the calculated number of cycles based on the
+ * absolute time value is less than the min tCK value, min tCK value should
+ * be used instead. This typically happens at low frequencies.
+ */
+static const struct lpddr2_min_tck min_tck_jedec = {
+	.tRL = 3,
+	.tRP_AB = 3,
+	.tRCD = 3,
+	.tWR = 3,
+	.tRAS_MIN = 3,
+	.tRRD = 2,
+	.tWTR = 2,
+	.tXP = 2,
+	.tRTP = 2,
+	.tCKE = 3,
+	.tCKESR = 3,
+	.tFAW = 8
+};
+
+static const struct lpddr2_ac_timings const*
+			jedec_ac_timings[MAX_NUM_SPEEDBINS] = {
+	&timings_jedec_200_mhz,
+	&timings_jedec_400_mhz
+};
+
+const struct lpddr2_device_timings jedec_default_timings = {
+	.ac_timings = jedec_ac_timings,
+	.min_tck = &min_tck_jedec
+};
+
+void emif_get_device_timings(u32 emif_nr,
+		const struct lpddr2_device_timings **cs0_device_timings,
+		const struct lpddr2_device_timings **cs1_device_timings)
+{
+	/* Assume Identical devices on EMIF1 & EMIF2 */
+	*cs0_device_timings = &jedec_default_timings;
+	*cs1_device_timings = &jedec_default_timings;
+}
+#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */
diff --git a/arch/arm/mach-omap2/omap4/hw_data.c b/arch/arm/mach-omap2/omap4/hw_data.c
new file mode 100644
index 0000000..02c06c1
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4/hw_data.c
@@ -0,0 +1,460 @@
+/*
+ *
+ * HW data initialization for OMAP4
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * Sricharan R <r.sricharan@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/omap_common.h>
+#include <asm/arch/clock.h>
+#include <asm/omap_gpio.h>
+#include <asm/io.h>
+
+struct prcm_regs const **prcm =
+			(struct prcm_regs const **) OMAP_SRAM_SCRATCH_PRCM_PTR;
+struct dplls const **dplls_data =
+			(struct dplls const **) OMAP_SRAM_SCRATCH_DPLLS_PTR;
+struct vcores_data const **omap_vcores =
+		(struct vcores_data const **) OMAP_SRAM_SCRATCH_VCORES_PTR;
+struct omap_sys_ctrl_regs const **ctrl =
+	(struct omap_sys_ctrl_regs const **)OMAP_SRAM_SCRATCH_SYS_CTRL;
+
+/*
+ * The M & N values in the following tables are created using the
+ * following tool:
+ * tools/omap/clocks_get_m_n.c
+ * Please use this tool for creating the table for any new frequency.
+ */
+
+/*
+ * dpll locked at 1400 MHz MPU clk at 700 MHz(OPP100) - DCC OFF
+ * OMAP4460 OPP_NOM frequency
+ */
+static const struct dpll_params mpu_dpll_params_1400mhz[NUM_SYS_CLKS] = {
+	{175, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{700, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{125, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{401, 10, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{350, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{700, 26, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{638, 34, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}	/* 38.4 MHz */
+};
+
+/*
+ * dpll locked at 1600 MHz - MPU clk at 800 MHz(OPP Turbo 4430)
+ * OMAP4430 OPP_TURBO frequency
+ * OMAP4470 OPP_NOM frequency
+ */
+static const struct dpll_params mpu_dpll_params_1600mhz[NUM_SYS_CLKS] = {
+	{200, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{800, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{619, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{125, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{400, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{800, 26, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{125, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}		/* 38.4 MHz */
+};
+
+/*
+ * dpll locked at 1200 MHz - MPU clk at 600 MHz
+ * OMAP4430 OPP_NOM frequency
+ */
+static const struct dpll_params mpu_dpll_params_1200mhz[NUM_SYS_CLKS] = {
+	{50, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 12 MHz   */
+	{600, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{250, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{125, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{300, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{200, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{125, 7, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}		/* 38.4 MHz */
+};
+
+/* OMAP4460 OPP_NOM frequency */
+/* OMAP4470 OPP_NOM (Low Power) frequency */
+static const struct dpll_params core_dpll_params_1600mhz[NUM_SYS_CLKS] = {
+	{200, 2, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 12 MHz   */
+	{800, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 13 MHz   */
+	{619, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 16.8 MHz */
+	{125, 2, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 19.2 MHz */
+	{400, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 26 MHz   */
+	{800, 26, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 27 MHz   */
+	{125, 5, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}	/* 38.4 MHz */
+};
+
+/* OMAP4430 ES1 OPP_NOM frequency */
+static const struct dpll_params core_dpll_params_es1_1524mhz[NUM_SYS_CLKS] = {
+	{127, 1, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 12 MHz   */
+	{762, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 13 MHz   */
+	{635, 13, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 16.8 MHz */
+	{635, 15, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 19.2 MHz */
+	{381, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 26 MHz   */
+	{254, 8, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 27 MHz   */
+	{496, 24, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}	/* 38.4 MHz */
+};
+
+/* OMAP4430 ES2.X OPP_NOM frequency */
+static const struct dpll_params
+		core_dpll_params_es2_1600mhz_ddr200mhz[NUM_SYS_CLKS] = {
+	{200, 2, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 12 MHz   */
+	{800, 12, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 13 MHz   */
+	{619, 12, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 16.8 MHz */
+	{125, 2, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 19.2 MHz */
+	{400, 12, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 26 MHz   */
+	{800, 26, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1},	/* 27 MHz   */
+	{125, 5, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1}	/* 38.4 MHz */
+};
+
+static const struct dpll_params per_dpll_params_1536mhz[NUM_SYS_CLKS] = {
+	{64, 0, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1},	/* 12 MHz   */
+	{768, 12, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1},	/* 13 MHz   */
+	{320, 6, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1},	/* 16.8 MHz */
+	{40, 0, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1},	/* 19.2 MHz */
+	{384, 12, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1},	/* 26 MHz   */
+	{256, 8, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1},	/* 27 MHz   */
+	{20, 0, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1}	/* 38.4 MHz */
+};
+
+static const struct dpll_params iva_dpll_params_1862mhz[NUM_SYS_CLKS] = {
+	{931, 11, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{931, 12, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{665, 11, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{727, 14, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{931, 25, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{931, 26, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{291, 11, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1}		/* 38.4 MHz */
+};
+
+/* ABE M & N values with sys_clk as source */
+static const struct dpll_params
+		abe_dpll_params_sysclk_196608khz[NUM_SYS_CLKS] = {
+	{49, 5, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{68, 8, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{35, 5, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{46, 8, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{34, 8, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{29, 7, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{64, 24, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}	/* 38.4 MHz */
+};
+
+/* ABE M & N values with 32K clock as source */
+static const struct dpll_params abe_dpll_params_32k_196608khz = {
+	750, 0, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+static const struct dpll_params usb_dpll_params_1920mhz[NUM_SYS_CLKS] = {
+	{80, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 12 MHz   */
+	{960, 12, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{400, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{50, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 19.2 MHz */
+	{480, 12, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{320, 8, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{25, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}		/* 38.4 MHz */
+};
+
+struct dplls omap4430_dplls_es1 = {
+	.mpu = mpu_dpll_params_1200mhz,
+	.core = core_dpll_params_es1_1524mhz,
+	.per = per_dpll_params_1536mhz,
+	.iva = iva_dpll_params_1862mhz,
+#ifdef CONFIG_SYS_OMAP_ABE_SYSCK
+	.abe = abe_dpll_params_sysclk_196608khz,
+#else
+	.abe = &abe_dpll_params_32k_196608khz,
+#endif
+	.usb = usb_dpll_params_1920mhz,
+	.ddr = NULL
+};
+
+struct dplls omap4430_dplls_es20 = {
+	.mpu = mpu_dpll_params_1200mhz,
+	.core = core_dpll_params_es2_1600mhz_ddr200mhz,
+	.per = per_dpll_params_1536mhz,
+	.iva = iva_dpll_params_1862mhz,
+#ifdef CONFIG_SYS_OMAP_ABE_SYSCK
+	.abe = abe_dpll_params_sysclk_196608khz,
+#else
+	.abe = &abe_dpll_params_32k_196608khz,
+#endif
+	.usb = usb_dpll_params_1920mhz,
+	.ddr = NULL
+};
+
+struct dplls omap4430_dplls = {
+	.mpu = mpu_dpll_params_1200mhz,
+	.core = core_dpll_params_1600mhz,
+	.per = per_dpll_params_1536mhz,
+	.iva = iva_dpll_params_1862mhz,
+#ifdef CONFIG_SYS_OMAP_ABE_SYSCK
+	.abe = abe_dpll_params_sysclk_196608khz,
+#else
+	.abe = &abe_dpll_params_32k_196608khz,
+#endif
+	.usb = usb_dpll_params_1920mhz,
+	.ddr = NULL
+};
+
+struct dplls omap4460_dplls = {
+	.mpu = mpu_dpll_params_1400mhz,
+	.core = core_dpll_params_1600mhz,
+	.per = per_dpll_params_1536mhz,
+	.iva = iva_dpll_params_1862mhz,
+#ifdef CONFIG_SYS_OMAP_ABE_SYSCK
+	.abe = abe_dpll_params_sysclk_196608khz,
+#else
+	.abe = &abe_dpll_params_32k_196608khz,
+#endif
+	.usb = usb_dpll_params_1920mhz,
+	.ddr = NULL
+};
+
+struct dplls omap4470_dplls = {
+	.mpu = mpu_dpll_params_1600mhz,
+	.core = core_dpll_params_1600mhz,
+	.per = per_dpll_params_1536mhz,
+	.iva = iva_dpll_params_1862mhz,
+#ifdef CONFIG_SYS_OMAP_ABE_SYSCK
+	.abe = abe_dpll_params_sysclk_196608khz,
+#else
+	.abe = &abe_dpll_params_32k_196608khz,
+#endif
+	.usb = usb_dpll_params_1920mhz,
+	.ddr = NULL
+};
+
+struct pmic_data twl6030_4430es1 = {
+	.base_offset = PHOENIX_SMPS_BASE_VOLT_STD_MODE_UV,
+	.step = 12660, /* 12.66 mV represented in uV */
+	/* The code starts at 1 not 0 */
+	.start_code = 1,
+	.i2c_slave_addr	= SMPS_I2C_SLAVE_ADDR,
+	.pmic_bus_init	= sri2c_init,
+	.pmic_write	= omap_vc_bypass_send_value,
+};
+
+/* twl6030 struct is used for TWL6030 and TWL6032 PMIC */
+struct pmic_data twl6030 = {
+	.base_offset = PHOENIX_SMPS_BASE_VOLT_STD_MODE_WITH_OFFSET_UV,
+	.step = 12660, /* 12.66 mV represented in uV */
+	/* The code starts at 1 not 0 */
+	.start_code = 1,
+	.i2c_slave_addr	= SMPS_I2C_SLAVE_ADDR,
+	.pmic_bus_init	= sri2c_init,
+	.pmic_write	= omap_vc_bypass_send_value,
+};
+
+struct pmic_data tps62361 = {
+	.base_offset = TPS62361_BASE_VOLT_MV,
+	.step = 10000, /* 10 mV represented in uV */
+	.start_code = 0,
+	.gpio = TPS62361_VSEL0_GPIO,
+	.gpio_en = 1,
+	.i2c_slave_addr	= SMPS_I2C_SLAVE_ADDR,
+	.pmic_bus_init	= sri2c_init,
+	.pmic_write	= omap_vc_bypass_send_value,
+};
+
+struct vcores_data omap4430_volts_es1 = {
+	.mpu.value = 1325,
+	.mpu.addr = SMPS_REG_ADDR_VCORE1,
+	.mpu.pmic = &twl6030_4430es1,
+
+	.core.value = 1200,
+	.core.addr = SMPS_REG_ADDR_VCORE3,
+	.core.pmic = &twl6030_4430es1,
+
+	.mm.value = 1200,
+	.mm.addr = SMPS_REG_ADDR_VCORE2,
+	.mm.pmic = &twl6030_4430es1,
+};
+
+struct vcores_data omap4430_volts = {
+	.mpu.value = 1325,
+	.mpu.addr = SMPS_REG_ADDR_VCORE1,
+	.mpu.pmic = &twl6030,
+
+	.core.value = 1200,
+	.core.addr = SMPS_REG_ADDR_VCORE3,
+	.core.pmic = &twl6030,
+
+	.mm.value = 1200,
+	.mm.addr = SMPS_REG_ADDR_VCORE2,
+	.mm.pmic = &twl6030,
+};
+
+struct vcores_data omap4460_volts = {
+	.mpu.value = 1203,
+	.mpu.addr = TPS62361_REG_ADDR_SET1,
+	.mpu.pmic = &tps62361,
+
+	.core.value = 1200,
+	.core.addr = SMPS_REG_ADDR_VCORE1,
+	.core.pmic = &twl6030,
+
+	.mm.value = 1200,
+	.mm.addr = SMPS_REG_ADDR_VCORE2,
+	.mm.pmic = &twl6030,
+};
+
+/*
+ * Take closest integer part of the mV value corresponding to a TWL6032 SMPS
+ * voltage selection code. Aligned with OMAP4470 ES1.0 OCA V.0.7.
+ */
+struct vcores_data omap4470_volts = {
+	.mpu.value = 1202,
+	.mpu.addr = SMPS_REG_ADDR_SMPS1,
+	.mpu.pmic = &twl6030,
+
+	.core.value = 1126,
+	.core.addr = SMPS_REG_ADDR_SMPS2,
+	.core.pmic = &twl6030,
+
+	.mm.value = 1139,
+	.mm.addr = SMPS_REG_ADDR_SMPS5,
+	.mm.pmic = &twl6030,
+};
+
+/*
+ * Enable essential clock domains, modules and
+ * do some additional special settings needed
+ */
+void enable_basic_clocks(void)
+{
+	u32 const clk_domains_essential[] = {
+		(*prcm)->cm_l4per_clkstctrl,
+		(*prcm)->cm_l3init_clkstctrl,
+		(*prcm)->cm_memif_clkstctrl,
+		(*prcm)->cm_l4cfg_clkstctrl,
+		0
+	};
+
+	u32 const clk_modules_hw_auto_essential[] = {
+		(*prcm)->cm_l3_gpmc_clkctrl,
+		(*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,
+		0
+	};
+
+	u32 const clk_modules_explicit_en_essential[] = {
+		(*prcm)->cm_wkup_gptimer1_clkctrl,
+		(*prcm)->cm_l3init_hsmmc1_clkctrl,
+		(*prcm)->cm_l3init_hsmmc2_clkctrl,
+		(*prcm)->cm_l4per_gptimer2_clkctrl,
+		(*prcm)->cm_wkup_wdtimer2_clkctrl,
+		(*prcm)->cm_l4per_uart3_clkctrl,
+		(*prcm)->cm_l4per_i2c1_clkctrl,
+		(*prcm)->cm_l4per_i2c2_clkctrl,
+		(*prcm)->cm_l4per_i2c3_clkctrl,
+		(*prcm)->cm_l4per_i2c4_clkctrl,
+		0
+	};
+
+	/* Enable optional additional functional clock for GPIO4 */
+	setbits_le32((*prcm)->cm_l4per_gpio4_clkctrl,
+			GPIO4_CLKCTRL_OPTFCLKEN_MASK);
+
+	/* Enable 96 MHz clock for MMC1 & MMC2 */
+	setbits_le32((*prcm)->cm_l3init_hsmmc1_clkctrl,
+			HSMMC_CLKCTRL_CLKSEL_MASK);
+	setbits_le32((*prcm)->cm_l3init_hsmmc2_clkctrl,
+			HSMMC_CLKCTRL_CLKSEL_MASK);
+
+	/* Select 32KHz clock as the source of GPTIMER1 */
+	setbits_le32((*prcm)->cm_wkup_gptimer1_clkctrl,
+			GPTIMER1_CLKCTRL_CLKSEL_MASK);
+
+	/* Enable optional 48M functional clock for USB PHY */
+	setbits_le32((*prcm)->cm_l3init_usbphy_clkctrl,
+			USBPHY_CLKCTRL_OPTFCLKEN_PHY_48M_MASK);
+
+	/* Enable 32 KHz clock for USB PHY */
+	setbits_le32((*prcm)->cm_coreaon_usb_phy1_core_clkctrl,
+			USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K);
+
+	do_enable_clocks(clk_domains_essential,
+			 clk_modules_hw_auto_essential,
+			 clk_modules_explicit_en_essential,
+			 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,
+		(*prcm)->cm_clksel_usb_60mhz,
+		(*prcm)->cm_l3init_hsusbtll_clkctrl,
+		0
+	};
+
+	u32 const clk_modules_explicit_en_essential[] = {
+		(*prcm)->cm_l4per_mcspi1_clkctrl,
+		(*prcm)->cm_l3init_hsusbhost_clkctrl,
+		0
+	};
+
+	do_enable_clocks(clk_domains_essential,
+			 clk_modules_hw_auto_essential,
+			 clk_modules_explicit_en_essential,
+			 1);
+}
+
+void hw_data_init(void)
+{
+	u32 omap_rev = omap_revision();
+
+	(*prcm) = &omap4_prcm;
+
+	switch (omap_rev) {
+
+	case OMAP4430_ES1_0:
+	*dplls_data = &omap4430_dplls_es1;
+	*omap_vcores = &omap4430_volts_es1;
+	break;
+
+	case OMAP4430_ES2_0:
+	*dplls_data = &omap4430_dplls_es20;
+	*omap_vcores = &omap4430_volts;
+	break;
+
+	case OMAP4430_ES2_1:
+	case OMAP4430_ES2_2:
+	case OMAP4430_ES2_3:
+	*dplls_data = &omap4430_dplls;
+	*omap_vcores = &omap4430_volts;
+	break;
+
+	case OMAP4460_ES1_0:
+	case OMAP4460_ES1_1:
+	*dplls_data = &omap4460_dplls;
+	*omap_vcores = &omap4460_volts;
+	break;
+
+	case OMAP4470_ES1_0:
+	*dplls_data = &omap4470_dplls;
+	*omap_vcores = &omap4470_volts;
+	break;
+
+	default:
+		printf("\n INVALID OMAP REVISION ");
+	}
+
+	*ctrl = &omap4_ctrl;
+}
diff --git a/arch/arm/mach-omap2/omap4/hwinit.c b/arch/arm/mach-omap2/omap4/hwinit.c
new file mode 100644
index 0000000..7c6638c
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4/hwinit.c
@@ -0,0 +1,177 @@
+/*
+ *
+ * Common functions for OMAP4 based boards
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *	Aneesh V	<aneesh@ti.com>
+ *	Steve Sakoman	<steve@sakoman.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/armv7.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/sys_proto.h>
+#include <linux/sizes.h>
+#include <asm/emif.h>
+#include <asm/arch/gpio.h>
+#include <asm/omap_common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 *const omap_si_rev = (u32 *)OMAP_SRAM_SCRATCH_OMAP_REV;
+
+static const struct gpio_bank gpio_bank_44xx[6] = {
+	{ (void *)OMAP44XX_GPIO1_BASE },
+	{ (void *)OMAP44XX_GPIO2_BASE },
+	{ (void *)OMAP44XX_GPIO3_BASE },
+	{ (void *)OMAP44XX_GPIO4_BASE },
+	{ (void *)OMAP44XX_GPIO5_BASE },
+	{ (void *)OMAP44XX_GPIO6_BASE },
+};
+
+const struct gpio_bank *const omap_gpio_bank = gpio_bank_44xx;
+
+#ifdef CONFIG_SPL_BUILD
+/*
+ * Some tuning of IOs for optimal power and performance
+ */
+void do_io_settings(void)
+{
+	u32 lpddr2io;
+
+	u32 omap4_rev = omap_revision();
+
+	if (omap4_rev == OMAP4430_ES1_0)
+		lpddr2io = CONTROL_LPDDR2IO_SLEW_125PS_DRV8_PULL_DOWN;
+	else if (omap4_rev == OMAP4430_ES2_0)
+		lpddr2io = CONTROL_LPDDR2IO_SLEW_325PS_DRV8_GATE_KEEPER;
+	else
+		lpddr2io = CONTROL_LPDDR2IO_SLEW_315PS_DRV12_PULL_DOWN;
+
+	/* EMIF1 */
+	writel(lpddr2io, (*ctrl)->control_lpddr2io1_0);
+	writel(lpddr2io, (*ctrl)->control_lpddr2io1_1);
+	/* No pull for GR10 as per hw team's recommendation */
+	writel(lpddr2io & ~LPDDR2IO_GR10_WD_MASK,
+		(*ctrl)->control_lpddr2io1_2);
+	writel(CONTROL_LPDDR2IO_3_VAL, (*ctrl)->control_lpddr2io1_3);
+
+	/* EMIF2 */
+	writel(lpddr2io, (*ctrl)->control_lpddr2io2_0);
+	writel(lpddr2io, (*ctrl)->control_lpddr2io2_1);
+	/* No pull for GR10 as per hw team's recommendation */
+	writel(lpddr2io & ~LPDDR2IO_GR10_WD_MASK,
+		(*ctrl)->control_lpddr2io2_2);
+	writel(CONTROL_LPDDR2IO_3_VAL, (*ctrl)->control_lpddr2io2_3);
+
+	/*
+	 * Some of these settings (TRIM values) come from eFuse and are
+	 * in turn programmed in the eFuse at manufacturing time after
+	 * calibration of the device. Do the software over-ride only if
+	 * the device is not correctly trimmed
+	 */
+	if (!(readl((*ctrl)->control_std_fuse_opp_bgap) & 0xFFFF)) {
+
+		writel(LDOSRAM_VOLT_CTRL_OVERRIDE,
+			(*ctrl)->control_ldosram_iva_voltage_ctrl);
+
+		writel(LDOSRAM_VOLT_CTRL_OVERRIDE,
+			(*ctrl)->control_ldosram_mpu_voltage_ctrl);
+
+		writel(LDOSRAM_VOLT_CTRL_OVERRIDE,
+			(*ctrl)->control_ldosram_core_voltage_ctrl);
+	}
+
+	/*
+	 * Over-ride the register
+	 *	i. unconditionally for all 4430
+	 *	ii. only if un-trimmed for 4460
+	 */
+	if (!readl((*ctrl)->control_efuse_1))
+		writel(CONTROL_EFUSE_1_OVERRIDE, (*ctrl)->control_efuse_1);
+
+	if ((omap4_rev < OMAP4460_ES1_0) || !readl((*ctrl)->control_efuse_2))
+		writel(CONTROL_EFUSE_2_OVERRIDE, (*ctrl)->control_efuse_2);
+}
+#endif /* CONFIG_SPL_BUILD */
+
+/* dummy fuction for omap4 */
+void config_data_eye_leveling_samples(u32 emif_base)
+{
+}
+
+void init_omap_revision(void)
+{
+	/*
+	 * For some of the ES2/ES1 boards ID_CODE is not reliable:
+	 * Also, ES1 and ES2 have different ARM revisions
+	 * So use ARM revision for identification
+	 */
+	unsigned int arm_rev = cortex_rev();
+
+	switch (arm_rev) {
+	case MIDR_CORTEX_A9_R0P1:
+		*omap_si_rev = OMAP4430_ES1_0;
+		break;
+	case MIDR_CORTEX_A9_R1P2:
+		switch (readl(CONTROL_ID_CODE)) {
+		case OMAP4_CONTROL_ID_CODE_ES2_0:
+			*omap_si_rev = OMAP4430_ES2_0;
+			break;
+		case OMAP4_CONTROL_ID_CODE_ES2_1:
+			*omap_si_rev = OMAP4430_ES2_1;
+			break;
+		case OMAP4_CONTROL_ID_CODE_ES2_2:
+			*omap_si_rev = OMAP4430_ES2_2;
+			break;
+		default:
+			*omap_si_rev = OMAP4430_ES2_0;
+			break;
+		}
+		break;
+	case MIDR_CORTEX_A9_R1P3:
+		*omap_si_rev = OMAP4430_ES2_3;
+		break;
+	case MIDR_CORTEX_A9_R2P10:
+		switch (readl(CONTROL_ID_CODE)) {
+		case OMAP4470_CONTROL_ID_CODE_ES1_0:
+			*omap_si_rev = OMAP4470_ES1_0;
+			break;
+		case OMAP4460_CONTROL_ID_CODE_ES1_1:
+			*omap_si_rev = OMAP4460_ES1_1;
+			break;
+		case OMAP4460_CONTROL_ID_CODE_ES1_0:
+		default:
+			*omap_si_rev = OMAP4460_ES1_0;
+			break;
+		}
+		break;
+	default:
+		*omap_si_rev = OMAP4430_SILICON_ID_INVALID;
+		break;
+	}
+}
+
+void omap_die_id(unsigned int *die_id)
+{
+	die_id[0] = readl((*ctrl)->control_std_fuse_die_id_0);
+	die_id[1] = readl((*ctrl)->control_std_fuse_die_id_1);
+	die_id[2] = readl((*ctrl)->control_std_fuse_die_id_2);
+	die_id[3] = readl((*ctrl)->control_std_fuse_die_id_3);
+}
+
+#ifndef CONFIG_SYS_L2CACHE_OFF
+void v7_outer_cache_enable(void)
+{
+	omap_smc1(OMAP4_SERVICE_PL310_CONTROL_REG_SET, 1);
+}
+
+void v7_outer_cache_disable(void)
+{
+	omap_smc1(OMAP4_SERVICE_PL310_CONTROL_REG_SET, 0);
+}
+#endif /* !CONFIG_SYS_L2CACHE_OFF */
diff --git a/arch/arm/mach-omap2/omap4/prcm-regs.c b/arch/arm/mach-omap2/omap4/prcm-regs.c
new file mode 100644
index 0000000..2f0e1e8
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4/prcm-regs.c
@@ -0,0 +1,307 @@
+/*
+ *
+ * HW regs data for OMAP4
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * Sricharan R <r.sricharan@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/omap_common.h>
+
+struct prcm_regs const omap4_prcm = {
+	/* cm1.ckgen */
+	.cm_clksel_core  = 0x4a004100,
+	.cm_clksel_abe = 0x4a004108,
+	.cm_dll_ctrl = 0x4a004110,
+	.cm_clkmode_dpll_core = 0x4a004120,
+	.cm_idlest_dpll_core = 0x4a004124,
+	.cm_autoidle_dpll_core = 0x4a004128,
+	.cm_clksel_dpll_core = 0x4a00412c,
+	.cm_div_m2_dpll_core = 0x4a004130,
+	.cm_div_m3_dpll_core = 0x4a004134,
+	.cm_div_m4_dpll_core = 0x4a004138,
+	.cm_div_m5_dpll_core = 0x4a00413c,
+	.cm_div_m6_dpll_core = 0x4a004140,
+	.cm_div_m7_dpll_core = 0x4a004144,
+	.cm_ssc_deltamstep_dpll_core = 0x4a004148,
+	.cm_ssc_modfreqdiv_dpll_core = 0x4a00414c,
+	.cm_emu_override_dpll_core = 0x4a004150,
+	.cm_clkmode_dpll_mpu = 0x4a004160,
+	.cm_idlest_dpll_mpu = 0x4a004164,
+	.cm_autoidle_dpll_mpu = 0x4a004168,
+	.cm_clksel_dpll_mpu = 0x4a00416c,
+	.cm_div_m2_dpll_mpu = 0x4a004170,
+	.cm_ssc_deltamstep_dpll_mpu = 0x4a004188,
+	.cm_ssc_modfreqdiv_dpll_mpu = 0x4a00418c,
+	.cm_bypclk_dpll_mpu = 0x4a00419c,
+	.cm_clkmode_dpll_iva = 0x4a0041a0,
+	.cm_idlest_dpll_iva = 0x4a0041a4,
+	.cm_autoidle_dpll_iva = 0x4a0041a8,
+	.cm_clksel_dpll_iva = 0x4a0041ac,
+	.cm_div_m4_dpll_iva = 0x4a0041b8,
+	.cm_div_m5_dpll_iva = 0x4a0041bc,
+	.cm_ssc_deltamstep_dpll_iva = 0x4a0041c8,
+	.cm_ssc_modfreqdiv_dpll_iva = 0x4a0041cc,
+	.cm_bypclk_dpll_iva = 0x4a0041dc,
+	.cm_clkmode_dpll_abe = 0x4a0041e0,
+	.cm_idlest_dpll_abe = 0x4a0041e4,
+	.cm_autoidle_dpll_abe = 0x4a0041e8,
+	.cm_clksel_dpll_abe = 0x4a0041ec,
+	.cm_div_m2_dpll_abe = 0x4a0041f0,
+	.cm_div_m3_dpll_abe = 0x4a0041f4,
+	.cm_ssc_deltamstep_dpll_abe = 0x4a004208,
+	.cm_ssc_modfreqdiv_dpll_abe = 0x4a00420c,
+	.cm_clkmode_dpll_ddrphy = 0x4a004220,
+	.cm_idlest_dpll_ddrphy = 0x4a004224,
+	.cm_autoidle_dpll_ddrphy = 0x4a004228,
+	.cm_clksel_dpll_ddrphy = 0x4a00422c,
+	.cm_div_m2_dpll_ddrphy = 0x4a004230,
+	.cm_div_m4_dpll_ddrphy = 0x4a004238,
+	.cm_div_m5_dpll_ddrphy = 0x4a00423c,
+	.cm_div_m6_dpll_ddrphy = 0x4a004240,
+	.cm_ssc_deltamstep_dpll_ddrphy = 0x4a004248,
+	.cm_shadow_freq_config1 = 0x4a004260,
+	.cm_mpu_mpu_clkctrl = 0x4a004320,
+
+	/* cm1.dsp */
+	.cm_dsp_clkstctrl = 0x4a004400,
+	.cm_dsp_dsp_clkctrl = 0x4a004420,
+
+	/* cm1.abe */
+	.cm1_abe_clkstctrl = 0x4a004500,
+	.cm1_abe_l4abe_clkctrl = 0x4a004520,
+	.cm1_abe_aess_clkctrl = 0x4a004528,
+	.cm1_abe_pdm_clkctrl = 0x4a004530,
+	.cm1_abe_dmic_clkctrl = 0x4a004538,
+	.cm1_abe_mcasp_clkctrl = 0x4a004540,
+	.cm1_abe_mcbsp1_clkctrl = 0x4a004548,
+	.cm1_abe_mcbsp2_clkctrl = 0x4a004550,
+	.cm1_abe_mcbsp3_clkctrl = 0x4a004558,
+	.cm1_abe_slimbus_clkctrl = 0x4a004560,
+	.cm1_abe_timer5_clkctrl = 0x4a004568,
+	.cm1_abe_timer6_clkctrl = 0x4a004570,
+	.cm1_abe_timer7_clkctrl = 0x4a004578,
+	.cm1_abe_timer8_clkctrl = 0x4a004580,
+	.cm1_abe_wdt3_clkctrl = 0x4a004588,
+
+	/* cm2.ckgen */
+	.cm_clksel_mpu_m3_iss_root = 0x4a008100,
+	.cm_clksel_usb_60mhz = 0x4a008104,
+	.cm_scale_fclk = 0x4a008108,
+	.cm_core_dvfs_perf1 = 0x4a008110,
+	.cm_core_dvfs_perf2 = 0x4a008114,
+	.cm_core_dvfs_perf3 = 0x4a008118,
+	.cm_core_dvfs_perf4 = 0x4a00811c,
+	.cm_core_dvfs_current = 0x4a008124,
+	.cm_iva_dvfs_perf_tesla = 0x4a008128,
+	.cm_iva_dvfs_perf_ivahd = 0x4a00812c,
+	.cm_iva_dvfs_perf_abe = 0x4a008130,
+	.cm_iva_dvfs_current = 0x4a008138,
+	.cm_clkmode_dpll_per = 0x4a008140,
+	.cm_idlest_dpll_per = 0x4a008144,
+	.cm_autoidle_dpll_per = 0x4a008148,
+	.cm_clksel_dpll_per = 0x4a00814c,
+	.cm_div_m2_dpll_per = 0x4a008150,
+	.cm_div_m3_dpll_per = 0x4a008154,
+	.cm_div_m4_dpll_per = 0x4a008158,
+	.cm_div_m5_dpll_per = 0x4a00815c,
+	.cm_div_m6_dpll_per = 0x4a008160,
+	.cm_div_m7_dpll_per = 0x4a008164,
+	.cm_ssc_deltamstep_dpll_per = 0x4a008168,
+	.cm_ssc_modfreqdiv_dpll_per = 0x4a00816c,
+	.cm_emu_override_dpll_per = 0x4a008170,
+	.cm_clkmode_dpll_usb = 0x4a008180,
+	.cm_idlest_dpll_usb = 0x4a008184,
+	.cm_autoidle_dpll_usb = 0x4a008188,
+	.cm_clksel_dpll_usb = 0x4a00818c,
+	.cm_div_m2_dpll_usb = 0x4a008190,
+	.cm_ssc_deltamstep_dpll_usb = 0x4a0081a8,
+	.cm_ssc_modfreqdiv_dpll_usb = 0x4a0081ac,
+	.cm_clkdcoldo_dpll_usb = 0x4a0081b4,
+	.cm_clkmode_dpll_unipro = 0x4a0081c0,
+	.cm_idlest_dpll_unipro = 0x4a0081c4,
+	.cm_autoidle_dpll_unipro = 0x4a0081c8,
+	.cm_clksel_dpll_unipro = 0x4a0081cc,
+	.cm_div_m2_dpll_unipro = 0x4a0081d0,
+	.cm_ssc_deltamstep_dpll_unipro = 0x4a0081e8,
+	.cm_ssc_modfreqdiv_dpll_unipro = 0x4a0081ec,
+	.cm_coreaon_usb_phy1_core_clkctrl = 0x4a008640,
+
+	/* cm2.core */
+	.cm_l3_1_clkstctrl = 0x4a008700,
+	.cm_l3_1_dynamicdep = 0x4a008708,
+	.cm_l3_1_l3_1_clkctrl = 0x4a008720,
+	.cm_l3_2_clkstctrl = 0x4a008800,
+	.cm_l3_2_dynamicdep = 0x4a008808,
+	.cm_l3_2_l3_2_clkctrl = 0x4a008820,
+	.cm_l3_gpmc_clkctrl = 0x4a008828,
+	.cm_l3_2_ocmc_ram_clkctrl = 0x4a008830,
+	.cm_mpu_m3_clkstctrl = 0x4a008900,
+	.cm_mpu_m3_staticdep = 0x4a008904,
+	.cm_mpu_m3_dynamicdep = 0x4a008908,
+	.cm_mpu_m3_mpu_m3_clkctrl = 0x4a008920,
+	.cm_sdma_clkstctrl = 0x4a008a00,
+	.cm_sdma_staticdep = 0x4a008a04,
+	.cm_sdma_dynamicdep = 0x4a008a08,
+	.cm_sdma_sdma_clkctrl = 0x4a008a20,
+	.cm_memif_clkstctrl = 0x4a008b00,
+	.cm_memif_dmm_clkctrl = 0x4a008b20,
+	.cm_memif_emif_fw_clkctrl = 0x4a008b28,
+	.cm_memif_emif_1_clkctrl = 0x4a008b30,
+	.cm_memif_emif_2_clkctrl = 0x4a008b38,
+	.cm_memif_dll_clkctrl = 0x4a008b40,
+	.cm_memif_emif_h1_clkctrl = 0x4a008b50,
+	.cm_memif_emif_h2_clkctrl = 0x4a008b58,
+	.cm_memif_dll_h_clkctrl = 0x4a008b60,
+	.cm_c2c_clkstctrl = 0x4a008c00,
+	.cm_c2c_staticdep = 0x4a008c04,
+	.cm_c2c_dynamicdep = 0x4a008c08,
+	.cm_c2c_sad2d_clkctrl = 0x4a008c20,
+	.cm_c2c_modem_icr_clkctrl = 0x4a008c28,
+	.cm_c2c_sad2d_fw_clkctrl = 0x4a008c30,
+	.cm_l4cfg_clkstctrl = 0x4a008d00,
+	.cm_l4cfg_dynamicdep = 0x4a008d08,
+	.cm_l4cfg_l4_cfg_clkctrl = 0x4a008d20,
+	.cm_l4cfg_hw_sem_clkctrl = 0x4a008d28,
+	.cm_l4cfg_mailbox_clkctrl = 0x4a008d30,
+	.cm_l4cfg_sar_rom_clkctrl = 0x4a008d38,
+	.cm_l3instr_clkstctrl = 0x4a008e00,
+	.cm_l3instr_l3_3_clkctrl = 0x4a008e20,
+	.cm_l3instr_l3_instr_clkctrl = 0x4a008e28,
+	.cm_l3instr_intrconn_wp1_clkct = 0x4a008e40,
+	.cm_ivahd_clkstctrl = 0x4a008f00,
+
+	/* cm2.ivahd */
+	.cm_ivahd_ivahd_clkctrl = 0x4a008f20,
+	.cm_ivahd_sl2_clkctrl = 0x4a008f28,
+
+	/* cm2.cam */
+	.cm_cam_clkstctrl = 0x4a009000,
+	.cm_cam_iss_clkctrl = 0x4a009020,
+	.cm_cam_fdif_clkctrl = 0x4a009028,
+
+	/* cm2.dss */
+	.cm_dss_clkstctrl = 0x4a009100,
+	.cm_dss_dss_clkctrl = 0x4a009120,
+
+	/* cm2.sgx */
+	.cm_sgx_clkstctrl = 0x4a009200,
+	.cm_sgx_sgx_clkctrl = 0x4a009220,
+
+	/* cm2.l3init */
+	.cm_l3init_clkstctrl = 0x4a009300,
+	.cm_l3init_hsmmc1_clkctrl = 0x4a009328,
+	.cm_l3init_hsmmc2_clkctrl = 0x4a009330,
+	.cm_l3init_hsi_clkctrl = 0x4a009338,
+	.cm_l3init_hsusbhost_clkctrl = 0x4a009358,
+	.cm_l3init_hsusbotg_clkctrl = 0x4a009360,
+	.cm_l3init_hsusbtll_clkctrl = 0x4a009368,
+	.cm_l3init_p1500_clkctrl = 0x4a009378,
+	.cm_l3init_fsusb_clkctrl = 0x4a0093d0,
+	.cm_l3init_usbphy_clkctrl = 0x4a0093e0,
+
+	/* cm2.l4per */
+	.cm_l4per_clkstctrl = 0x4a009400,
+	.cm_l4per_dynamicdep = 0x4a009408,
+	.cm_l4per_adc_clkctrl = 0x4a009420,
+	.cm_l4per_gptimer10_clkctrl = 0x4a009428,
+	.cm_l4per_gptimer11_clkctrl = 0x4a009430,
+	.cm_l4per_gptimer2_clkctrl = 0x4a009438,
+	.cm_l4per_gptimer3_clkctrl = 0x4a009440,
+	.cm_l4per_gptimer4_clkctrl = 0x4a009448,
+	.cm_l4per_gptimer9_clkctrl = 0x4a009450,
+	.cm_l4per_elm_clkctrl = 0x4a009458,
+	.cm_l4per_gpio2_clkctrl = 0x4a009460,
+	.cm_l4per_gpio3_clkctrl = 0x4a009468,
+	.cm_l4per_gpio4_clkctrl = 0x4a009470,
+	.cm_l4per_gpio5_clkctrl = 0x4a009478,
+	.cm_l4per_gpio6_clkctrl = 0x4a009480,
+	.cm_l4per_hdq1w_clkctrl = 0x4a009488,
+	.cm_l4per_hecc1_clkctrl = 0x4a009490,
+	.cm_l4per_hecc2_clkctrl = 0x4a009498,
+	.cm_l4per_i2c1_clkctrl = 0x4a0094a0,
+	.cm_l4per_i2c2_clkctrl = 0x4a0094a8,
+	.cm_l4per_i2c3_clkctrl = 0x4a0094b0,
+	.cm_l4per_i2c4_clkctrl = 0x4a0094b8,
+	.cm_l4per_l4per_clkctrl = 0x4a0094c0,
+	.cm_l4per_mcasp2_clkctrl = 0x4a0094d0,
+	.cm_l4per_mcasp3_clkctrl = 0x4a0094d8,
+	.cm_l4per_mcbsp4_clkctrl = 0x4a0094e0,
+	.cm_l4per_mgate_clkctrl = 0x4a0094e8,
+	.cm_l4per_mcspi1_clkctrl = 0x4a0094f0,
+	.cm_l4per_mcspi2_clkctrl = 0x4a0094f8,
+	.cm_l4per_mcspi3_clkctrl = 0x4a009500,
+	.cm_l4per_mcspi4_clkctrl = 0x4a009508,
+	.cm_l4per_mmcsd3_clkctrl = 0x4a009520,
+	.cm_l4per_mmcsd4_clkctrl = 0x4a009528,
+	.cm_l4per_msprohg_clkctrl = 0x4a009530,
+	.cm_l4per_slimbus2_clkctrl = 0x4a009538,
+	.cm_l4per_uart1_clkctrl = 0x4a009540,
+	.cm_l4per_uart2_clkctrl = 0x4a009548,
+	.cm_l4per_uart3_clkctrl = 0x4a009550,
+	.cm_l4per_uart4_clkctrl = 0x4a009558,
+	.cm_l4per_mmcsd5_clkctrl = 0x4a009560,
+	.cm_l4per_i2c5_clkctrl = 0x4a009568,
+	.cm_l4sec_clkstctrl = 0x4a009580,
+	.cm_l4sec_staticdep = 0x4a009584,
+	.cm_l4sec_dynamicdep = 0x4a009588,
+	.cm_l4sec_aes1_clkctrl = 0x4a0095a0,
+	.cm_l4sec_aes2_clkctrl = 0x4a0095a8,
+	.cm_l4sec_des3des_clkctrl = 0x4a0095b0,
+	.cm_l4sec_pkaeip29_clkctrl = 0x4a0095b8,
+	.cm_l4sec_rng_clkctrl = 0x4a0095c0,
+	.cm_l4sec_sha2md51_clkctrl = 0x4a0095c8,
+	.cm_l4sec_cryptodma_clkctrl = 0x4a0095d8,
+
+	/* l4 wkup regs */
+	.cm_abe_pll_ref_clksel = 0x4a30610c,
+	.cm_sys_clksel = 0x4a306110,
+	.cm_wkup_clkstctrl = 0x4a307800,
+	.cm_wkup_l4wkup_clkctrl = 0x4a307820,
+	.cm_wkup_wdtimer1_clkctrl = 0x4a307828,
+	.cm_wkup_wdtimer2_clkctrl = 0x4a307830,
+	.cm_wkup_gpio1_clkctrl = 0x4a307838,
+	.cm_wkup_gptimer1_clkctrl = 0x4a307840,
+	.cm_wkup_gptimer12_clkctrl = 0x4a307848,
+	.cm_wkup_synctimer_clkctrl = 0x4a307850,
+	.cm_wkup_usim_clkctrl = 0x4a307858,
+	.cm_wkup_sarram_clkctrl = 0x4a307860,
+	.cm_wkup_keyboard_clkctrl = 0x4a307878,
+	.cm_wkup_rtc_clkctrl = 0x4a307880,
+	.cm_wkup_bandgap_clkctrl = 0x4a307888,
+	.prm_vc_val_bypass = 0x4a307ba0,
+	.prm_vc_cfg_channel = 0x4a307ba4,
+	.prm_vc_cfg_i2c_mode = 0x4a307ba8,
+	.prm_vc_cfg_i2c_clk = 0x4a307bac,
+};
+
+struct omap_sys_ctrl_regs const omap4_ctrl = {
+	.control_status				= 0x4A0022C4,
+	.control_std_fuse_die_id_0		= 0x4A002200,
+	.control_std_fuse_die_id_1		= 0x4A002208,
+	.control_std_fuse_die_id_2		= 0x4A00220C,
+	.control_std_fuse_die_id_3		= 0x4A002210,
+	.control_std_fuse_opp_bgap		= 0x4a002260,
+	.control_status				= 0x4a0022c4,
+	.control_ldosram_iva_voltage_ctrl	= 0x4A002320,
+	.control_ldosram_mpu_voltage_ctrl	= 0x4A002324,
+	.control_ldosram_core_voltage_ctrl	= 0x4A002328,
+	.control_usbotghs_ctrl			= 0x4A00233C,
+	.control_padconf_core_base		= 0x4A100000,
+	.control_pbiaslite			= 0x4A100600,
+	.control_lpddr2io1_0			= 0x4A100638,
+	.control_lpddr2io1_1			= 0x4A10063C,
+	.control_lpddr2io1_2			= 0x4A100640,
+	.control_lpddr2io1_3			= 0x4A100644,
+	.control_lpddr2io2_0			= 0x4A100648,
+	.control_lpddr2io2_1			= 0x4A10064C,
+	.control_lpddr2io2_2			= 0x4A100650,
+	.control_lpddr2io2_3			= 0x4A100654,
+	.control_efuse_1			= 0x4A100700,
+	.control_efuse_2			= 0x4A100704,
+	.control_padconf_wkup_base		= 0x4A31E000,
+};
diff --git a/arch/arm/mach-omap2/omap4/sdram_elpida.c b/arch/arm/mach-omap2/omap4/sdram_elpida.c
new file mode 100644
index 0000000..78b4f09
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4/sdram_elpida.c
@@ -0,0 +1,324 @@
+/*
+ * Timing and Organization details of the Elpida parts used in OMAP4
+ * SDPs and Panda
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/emif.h>
+#include <asm/arch/sys_proto.h>
+
+/*
+ * This file provides details of the LPDDR2 SDRAM parts used on OMAP4430
+ * SDP and Panda. Since the parts used and geometry are identical for
+ * SDP and Panda for a given OMAP4 revision, this information is kept
+ * here instead of being in board directory. However the key functions
+ * exported are weakly linked so that they can be over-ridden in the board
+ * directory if there is a OMAP4 board in the future that uses a different
+ * memory device or geometry.
+ *
+ * For any new board with different memory devices over-ride one or more
+ * of the following functions as per the CONFIG flags you intend to enable:
+ * - emif_get_reg_dump()
+ * - emif_get_dmm_regs()
+ * - emif_get_device_details()
+ * - emif_get_device_timings()
+ */
+
+#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
+
+const struct emif_regs emif_regs_elpida_200_mhz_2cs = {
+	.sdram_config_init		= 0x80000eb9,
+	.sdram_config			= 0x80001ab9,
+	.ref_ctrl			= 0x0000030c,
+	.sdram_tim1			= 0x08648311,
+	.sdram_tim2			= 0x101b06ca,
+	.sdram_tim3			= 0x0048a19f,
+	.read_idle_ctrl			= 0x000501ff,
+	.zq_config			= 0x500b3214,
+	.temp_alert_config		= 0xd8016893,
+	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
+	.emif_ddr_phy_ctlr_1		= 0x049ff808
+};
+
+const struct emif_regs emif_regs_elpida_380_mhz_1cs = {
+	.sdram_config_init		= 0x80000eb1,
+	.sdram_config			= 0x80001ab1,
+	.ref_ctrl			= 0x000005cd,
+	.sdram_tim1			= 0x10cb0622,
+	.sdram_tim2			= 0x20350d52,
+	.sdram_tim3			= 0x00b1431f,
+	.read_idle_ctrl			= 0x000501ff,
+	.zq_config			= 0x500b3214,
+	.temp_alert_config		= 0x58016893,
+	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
+	.emif_ddr_phy_ctlr_1		= 0x049ff418
+};
+
+const struct emif_regs emif_regs_elpida_400_mhz_1cs = {
+	.sdram_config_init		= 0x80800eb2,
+	.sdram_config			= 0x80801ab2,
+	.ref_ctrl			= 0x00000618,
+	.sdram_tim1			= 0x10eb0662,
+	.sdram_tim2			= 0x20370dd2,
+	.sdram_tim3			= 0x00b1c33f,
+	.read_idle_ctrl			= 0x000501ff,
+	.zq_config			= 0x500b3215,
+	.temp_alert_config		= 0x58016893,
+	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
+	.emif_ddr_phy_ctlr_1		= 0x049ff418
+};
+
+const struct emif_regs emif_regs_elpida_400_mhz_2cs = {
+	.sdram_config_init		= 0x80000eb9,
+	.sdram_config			= 0x80001ab9,
+	.ref_ctrl			= 0x00000618,
+	.sdram_tim1			= 0x10eb0662,
+	.sdram_tim2			= 0x20370dd2,
+	.sdram_tim3			= 0x00b1c33f,
+	.read_idle_ctrl			= 0x000501ff,
+	.zq_config			= 0xd00b3214,
+	.temp_alert_config		= 0xd8016893,
+	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
+	.emif_ddr_phy_ctlr_1		= 0x049ff418
+};
+
+const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = {
+	.dmm_lisa_map_0 = 0xFF020100,
+	.dmm_lisa_map_1 = 0,
+	.dmm_lisa_map_2 = 0,
+	.dmm_lisa_map_3 = 0x80540300,
+	.is_ma_present	= 0x0
+};
+
+const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2 = {
+	.dmm_lisa_map_0 = 0xFF020100,
+	.dmm_lisa_map_1 = 0,
+	.dmm_lisa_map_2 = 0,
+	.dmm_lisa_map_3 = 0x80640300,
+	.is_ma_present	= 0x0
+};
+
+const struct dmm_lisa_map_regs ma_lisa_map_2G_x_2_x_2 = {
+	.dmm_lisa_map_0 = 0xFF020100,
+	.dmm_lisa_map_1 = 0,
+	.dmm_lisa_map_2 = 0,
+	.dmm_lisa_map_3 = 0x80640300,
+	.is_ma_present	= 0x1
+};
+
+static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs)
+{
+	u32 omap4_rev = omap_revision();
+
+	/* Same devices and geometry on both EMIFs */
+	if (omap4_rev == OMAP4430_ES1_0)
+		*regs = &emif_regs_elpida_380_mhz_1cs;
+	else if (omap4_rev == OMAP4430_ES2_0)
+		*regs = &emif_regs_elpida_200_mhz_2cs;
+	else if (omap4_rev < OMAP4470_ES1_0)
+		*regs = &emif_regs_elpida_400_mhz_2cs;
+	else
+		*regs = &emif_regs_elpida_400_mhz_1cs;
+}
+void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs)
+	__attribute__((weak, alias("emif_get_reg_dump_sdp")));
+
+static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs
+						**dmm_lisa_regs)
+{
+	u32 omap_rev = omap_revision();
+
+	if (omap_rev == OMAP4430_ES1_0)
+		*dmm_lisa_regs = &lisa_map_2G_x_1_x_2;
+	else if (omap_rev < OMAP4460_ES1_0)
+		*dmm_lisa_regs = &lisa_map_2G_x_2_x_2;
+	else
+		*dmm_lisa_regs = &ma_lisa_map_2G_x_2_x_2;
+}
+
+void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs)
+	__attribute__((weak, alias("emif_get_dmm_regs_sdp")));
+
+#else
+
+const struct lpddr2_device_details elpida_2G_S4_details = {
+	.type		= LPDDR2_TYPE_S4,
+	.density	= LPDDR2_DENSITY_2Gb,
+	.io_width	= LPDDR2_IO_WIDTH_32,
+	.manufacturer	= LPDDR2_MANUFACTURER_ELPIDA
+};
+
+const struct lpddr2_device_details elpida_4G_S4_details = {
+	.type		= LPDDR2_TYPE_S4,
+	.density	= LPDDR2_DENSITY_4Gb,
+	.io_width	= LPDDR2_IO_WIDTH_32,
+	.manufacturer	= LPDDR2_MANUFACTURER_ELPIDA
+};
+
+struct lpddr2_device_details *emif_get_device_details_sdp(u32 emif_nr, u8 cs,
+			struct lpddr2_device_details *lpddr2_dev_details)
+{
+	u32 omap_rev = omap_revision();
+
+	/* EMIF1 & EMIF2 have identical configuration */
+	if (((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0))
+		&& (cs == CS1)) {
+		/* Nothing connected on CS1 for 4430/4470 ES1.0 */
+		return NULL;
+	} else if (omap_rev < OMAP4470_ES1_0) {
+		/* In all other 4430/4460 cases Elpida 2G device */
+		*lpddr2_dev_details = elpida_2G_S4_details;
+	} else {
+		/* 4470: 4G device */
+		*lpddr2_dev_details = elpida_4G_S4_details;
+	}
+	return lpddr2_dev_details;
+}
+
+struct lpddr2_device_details *emif_get_device_details(u32 emif_nr, u8 cs,
+			struct lpddr2_device_details *lpddr2_dev_details)
+	__attribute__((weak, alias("emif_get_device_details_sdp")));
+
+#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */
+
+#ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
+static const struct lpddr2_ac_timings timings_elpida_400_mhz = {
+	.max_freq	= 400000000,
+	.RL		= 6,
+	.tRPab		= 21,
+	.tRCD		= 18,
+	.tWR		= 15,
+	.tRASmin	= 42,
+	.tRRD		= 10,
+	.tWTRx2		= 15,
+	.tXSR		= 140,
+	.tXPx2		= 15,
+	.tRFCab		= 130,
+	.tRTPx2		= 15,
+	.tCKE		= 3,
+	.tCKESR		= 15,
+	.tZQCS		= 90,
+	.tZQCL		= 360,
+	.tZQINIT	= 1000,
+	.tDQSCKMAXx2	= 11,
+	.tRASmax	= 70,
+	.tFAW		= 50
+};
+
+static const struct lpddr2_ac_timings timings_elpida_333_mhz = {
+	.max_freq	= 333000000,
+	.RL		= 5,
+	.tRPab		= 21,
+	.tRCD		= 18,
+	.tWR		= 15,
+	.tRASmin	= 42,
+	.tRRD		= 10,
+	.tWTRx2		= 15,
+	.tXSR		= 140,
+	.tXPx2		= 15,
+	.tRFCab		= 130,
+	.tRTPx2		= 15,
+	.tCKE		= 3,
+	.tCKESR		= 15,
+	.tZQCS		= 90,
+	.tZQCL		= 360,
+	.tZQINIT	= 1000,
+	.tDQSCKMAXx2	= 11,
+	.tRASmax	= 70,
+	.tFAW		= 50
+};
+
+static const struct lpddr2_ac_timings timings_elpida_200_mhz = {
+	.max_freq	= 200000000,
+	.RL		= 3,
+	.tRPab		= 21,
+	.tRCD		= 18,
+	.tWR		= 15,
+	.tRASmin	= 42,
+	.tRRD		= 10,
+	.tWTRx2		= 20,
+	.tXSR		= 140,
+	.tXPx2		= 15,
+	.tRFCab		= 130,
+	.tRTPx2		= 15,
+	.tCKE		= 3,
+	.tCKESR		= 15,
+	.tZQCS		= 90,
+	.tZQCL		= 360,
+	.tZQINIT	= 1000,
+	.tDQSCKMAXx2	= 11,
+	.tRASmax	= 70,
+	.tFAW		= 50
+};
+
+static const struct lpddr2_min_tck min_tck_elpida = {
+	.tRL		= 3,
+	.tRP_AB		= 3,
+	.tRCD		= 3,
+	.tWR		= 3,
+	.tRAS_MIN	= 3,
+	.tRRD		= 2,
+	.tWTR		= 2,
+	.tXP		= 2,
+	.tRTP		= 2,
+	.tCKE		= 3,
+	.tCKESR		= 3,
+	.tFAW		= 8
+};
+
+static const struct lpddr2_ac_timings *elpida_ac_timings[MAX_NUM_SPEEDBINS] = {
+		&timings_elpida_200_mhz,
+		&timings_elpida_333_mhz,
+		&timings_elpida_400_mhz
+};
+
+const struct lpddr2_device_timings elpida_2G_S4_timings = {
+	.ac_timings	= elpida_ac_timings,
+	.min_tck	= &min_tck_elpida,
+};
+
+void emif_get_device_timings_sdp(u32 emif_nr,
+		const struct lpddr2_device_timings **cs0_device_timings,
+		const struct lpddr2_device_timings **cs1_device_timings)
+{
+	u32 omap_rev = omap_revision();
+
+	/* Identical devices on EMIF1 & EMIF2 */
+	*cs0_device_timings = &elpida_2G_S4_timings;
+
+	if ((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0))
+		*cs1_device_timings = NULL;
+	else
+		*cs1_device_timings = &elpida_2G_S4_timings;
+}
+
+void emif_get_device_timings(u32 emif_nr,
+		const struct lpddr2_device_timings **cs0_device_timings,
+		const struct lpddr2_device_timings **cs1_device_timings)
+	__attribute__((weak, alias("emif_get_device_timings_sdp")));
+
+#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */
+
+const struct lpddr2_mr_regs mr_regs = {
+	.mr1	= MR1_BL_8_BT_SEQ_WRAP_EN_NWR_3,
+	.mr2	= 0x4,
+	.mr3	= -1,
+	.mr10	= MR10_ZQ_ZQINIT,
+	.mr16	= MR16_REF_FULL_ARRAY
+};
+
+void get_lpddr2_mr_regs(const struct lpddr2_mr_regs **regs)
+{
+	*regs = &mr_regs;
+}
+
+__weak const struct read_write_regs *get_bug_regs(u32 *iterations)
+{
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/omap5/Kconfig b/arch/arm/mach-omap2/omap5/Kconfig
new file mode 100644
index 0000000..22259dc
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/Kconfig
@@ -0,0 +1,94 @@
+if OMAP54XX
+
+config SPL_EXT_SUPPORT
+	default y
+
+config SPL_FAT_SUPPORT
+	default y
+
+config SPL_GPIO_SUPPORT
+	default y
+
+config SPL_I2C_SUPPORT
+	default y
+
+config SPL_LIBCOMMON_SUPPORT
+	default y
+
+config SPL_LIBDISK_SUPPORT
+	default y
+
+config SPL_LIBGENERIC_SUPPORT
+	default y
+
+config SPL_MMC_SUPPORT
+	default y
+
+config SPL_NAND_SUPPORT
+	default y
+
+config SPL_POWER_SUPPORT
+	default y
+
+config SPL_SERIAL_SUPPORT
+	default y
+
+config SPL_DISPLAY_PRINT
+	default y
+
+choice
+	prompt "OMAP5 board select"
+	optional
+
+config TARGET_CM_T54
+	bool "CompuLab CM-T54"
+
+config TARGET_OMAP5_UEVM
+	bool "TI OMAP5 uEVM board"
+
+config TARGET_DRA7XX_EVM
+	bool "TI DRA7XX"
+	select TI_I2C_BOARD_DETECT
+	select PHYS_64BIT
+
+config TARGET_AM57XX_EVM
+	bool "AM57XX"
+	select TI_I2C_BOARD_DETECT
+
+endchoice
+
+config SYS_SOC
+	default "omap5"
+
+config TI_SECURE_EMIF_REGION_START
+	hex "Reserved EMIF region start address"
+	depends on TI_SECURE_DEVICE
+	default 0x0
+	help
+	  Reserved EMIF region start address. Set to "0" to auto-select
+	  to be at the end of the external memory region.
+
+config TI_SECURE_EMIF_TOTAL_REGION_SIZE
+	hex "Reserved EMIF region size"
+	depends on TI_SECURE_DEVICE
+	default 0x0
+	help
+	  Total reserved EMIF region size. Default is 0, which means no reserved EMIF
+	  region on secure devices.
+
+config TI_SECURE_EMIF_PROTECTED_REGION_SIZE
+	hex "Size of protected region within reserved EMIF region"
+	depends on TI_SECURE_DEVICE
+	default 0x0
+	help
+	  This config option is used to specify the size of the portion of the total
+	  reserved EMIF region set aside for secure OS needs that will  be protected
+	  using hardware memory firewalls. This value must be smaller than the
+	  TI_SECURE_EMIF_TOTAL_REGION_SIZE value.
+
+source "board/compulab/cm_t54/Kconfig"
+source "board/ti/omap5_uevm/Kconfig"
+source "board/ti/dra7xx/Kconfig"
+source "board/ti/am57xx/Kconfig"
+
+endif
diff --git a/arch/arm/mach-omap2/omap5/Makefile b/arch/arm/mach-omap2/omap5/Makefile
new file mode 100644
index 0000000..0212df7
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/Makefile
@@ -0,0 +1,17 @@
+#
+# (C) Copyright 2000-2010
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	+= boot.o
+obj-y	+= hwinit.o
+obj-y	+= emif.o
+obj-y	+= sdram.o
+obj-y	+= prcm-regs.o
+obj-y	+= hw_data.o
+obj-y	+= abb.o
+obj-y	+= fdt.o
+obj-$(CONFIG_IODELAY_RECALIBRATION) += dra7xx_iodelay.o
+obj-$(CONFIG_TI_SECURE_DEVICE) += sec-fxns.o
diff --git a/arch/arm/mach-omap2/omap5/abb.c b/arch/arm/mach-omap2/omap5/abb.c
new file mode 100644
index 0000000..3bf8897
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/abb.c
@@ -0,0 +1,57 @@
+/*
+ * Adaptive Body Bias programming sequence for OMAP5 family
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * Andrii Tseglytskyi <andrii.tseglytskyi@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/omap_common.h>
+#include <asm/io.h>
+
+/*
+ * Setup LDOVBB for OMAP5.
+ * On OMAP5+ some ABB settings are fused. They are handled
+ * in the following way:
+ *
+ * 1. corresponding EFUSE register contains ABB enable bit
+ *    and VSET value
+ * 2. If ABB enable bit is set to 1, than ABB should be
+ *    enabled, otherwise ABB should be disabled
+ * 3. If ABB is enabled, than VSET value should be copied
+ *    to corresponding MUX control register
+ */
+s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb)
+{
+	u32 vset;
+	u32 fuse_enable_mask = OMAP5_ABB_FUSE_ENABLE_MASK;
+	u32 fuse_vset_mask = OMAP5_ABB_FUSE_VSET_MASK;
+
+	if (!is_omap54xx()) {
+		/* DRA7 */
+		fuse_enable_mask = DRA7_ABB_FUSE_ENABLE_MASK;
+		fuse_vset_mask = DRA7_ABB_FUSE_VSET_MASK;
+	}
+	/*
+	 * ABB parameters must be properly fused
+	 * otherwise ABB should be disabled
+	 */
+	vset = readl(fuse);
+	if (!(vset & fuse_enable_mask))
+		return -1;
+
+	/* prepare VSET value for LDOVBB mux register */
+	vset &= fuse_vset_mask;
+	vset >>= ffs(fuse_vset_mask) - 1;
+	vset <<= ffs(OMAP5_ABB_LDOVBBMPU_VSET_OUT_MASK) - 1;
+	vset |= OMAP5_ABB_LDOVBBMPU_MUX_CTRL_MASK;
+
+	/* setup LDOVBB using fused value */
+	clrsetbits_le32(ldovbb,  OMAP5_ABB_LDOVBBMPU_VSET_OUT_MASK, vset);
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/omap5/boot.c b/arch/arm/mach-omap2/omap5/boot.c
new file mode 100644
index 0000000..583becc
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/boot.c
@@ -0,0 +1,46 @@
+/*
+ * OMAP5 boot
+ *
+ * Copyright (C) 2015 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/omap_common.h>
+#include <spl.h>
+
+static u32 boot_devices[] = {
+#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_SATA,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_SPI,
+	BOOT_DEVICE_SPI,
+#else
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_SATA,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_XIPWAIT,
+#endif
+};
+
+u32 omap_sys_boot_device(void)
+{
+	u32 sys_boot;
+
+	/* Grab the first 4 bits of the status register for SYS_BOOT. */
+	sys_boot = readl((u32 *) (*ctrl)->control_status) & ((1 << 4) - 1);
+
+	if (sys_boot >= (sizeof(boot_devices) / sizeof(u32)))
+		return BOOT_DEVICE_NONE;
+
+	return boot_devices[sys_boot];
+}
diff --git a/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c b/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c
new file mode 100644
index 0000000..8798730
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c
@@ -0,0 +1,274 @@
+/*
+ * (C) Copyright 2015
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * Lokesh Vutla <lokeshvutla@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/utils.h>
+#include <asm/arch/dra7xx_iodelay.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/mux_dra7xx.h>
+#include <asm/omap_common.h>
+
+static int isolate_io(u32 isolate)
+{
+	if (isolate) {
+		clrsetbits_le32((*ctrl)->control_pbias, SDCARD_PWRDNZ,
+				SDCARD_PWRDNZ);
+		clrsetbits_le32((*ctrl)->control_pbias, SDCARD_BIAS_PWRDNZ,
+				SDCARD_BIAS_PWRDNZ);
+	}
+
+	/* Override control on ISOCLKIN signal to IO pad ring. */
+	clrsetbits_le32((*prcm)->prm_io_pmctrl, PMCTRL_ISOCLK_OVERRIDE_MASK,
+			PMCTRL_ISOCLK_OVERRIDE_CTRL);
+	if (!wait_on_value(PMCTRL_ISOCLK_STATUS_MASK, PMCTRL_ISOCLK_STATUS_MASK,
+			   (u32 *)(*prcm)->prm_io_pmctrl, LDELAY))
+		return ERR_DEISOLATE_IO << isolate;
+
+	/* Isolate/Deisolate IO */
+	clrsetbits_le32((*ctrl)->ctrl_core_sma_sw_0, CTRL_ISOLATE_MASK,
+			isolate << CTRL_ISOLATE_SHIFT);
+	/* Dummy read to add delay t > 10ns */
+	readl((*ctrl)->ctrl_core_sma_sw_0);
+
+	/* Return control on ISOCLKIN to hardware */
+	clrsetbits_le32((*prcm)->prm_io_pmctrl, PMCTRL_ISOCLK_OVERRIDE_MASK,
+			PMCTRL_ISOCLK_NOT_OVERRIDE_CTRL);
+	if (!wait_on_value(PMCTRL_ISOCLK_STATUS_MASK,
+			   0 << PMCTRL_ISOCLK_STATUS_SHIFT,
+			   (u32 *)(*prcm)->prm_io_pmctrl, LDELAY))
+		return ERR_DEISOLATE_IO << isolate;
+
+	return 0;
+}
+
+static int calibrate_iodelay(u32 base)
+{
+	u32 reg;
+
+	/* Configure REFCLK period */
+	reg = readl(base + CFG_REG_2_OFFSET);
+	reg &= ~CFG_REG_REFCLK_PERIOD_MASK;
+	reg |= CFG_REG_REFCLK_PERIOD;
+	writel(reg, base + CFG_REG_2_OFFSET);
+
+	/* Initiate Calibration */
+	clrsetbits_le32(base + CFG_REG_0_OFFSET, CFG_REG_CALIB_STRT_MASK,
+			CFG_REG_CALIB_STRT << CFG_REG_CALIB_STRT_SHIFT);
+	if (!wait_on_value(CFG_REG_CALIB_STRT_MASK, CFG_REG_CALIB_END,
+			   (u32 *)(base + CFG_REG_0_OFFSET), LDELAY))
+		return ERR_CALIBRATE_IODELAY;
+
+	return 0;
+}
+
+static int update_delay_mechanism(u32 base)
+{
+	/* Initiate the reload of calibrated values. */
+	clrsetbits_le32(base + CFG_REG_0_OFFSET, CFG_REG_ROM_READ_MASK,
+			CFG_REG_ROM_READ_START);
+	if (!wait_on_value(CFG_REG_ROM_READ_MASK, CFG_REG_ROM_READ_END,
+			   (u32 *)(base + CFG_REG_0_OFFSET), LDELAY))
+		return ERR_UPDATE_DELAY;
+
+	return 0;
+}
+
+static u32 calculate_delay(u32 base, u16 offset, u16 den)
+{
+	u16 refclk_period, dly_cnt, ref_cnt;
+	u32 reg, q, r;
+
+	refclk_period = readl(base + CFG_REG_2_OFFSET) &
+			      CFG_REG_REFCLK_PERIOD_MASK;
+
+	reg = readl(base + offset);
+	dly_cnt = (reg & CFG_REG_DLY_CNT_MASK) >> CFG_REG_DLY_CNT_SHIFT;
+	ref_cnt = (reg & CFG_REG_REF_CNT_MASK) >> CFG_REG_REF_CNT_SHIFT;
+
+	if (!dly_cnt || !den)
+		return 0;
+
+	/*
+	 * To avoid overflow and integer truncation, delay value
+	 * is calculated as quotient + remainder.
+	 */
+	q = 5 * ((ref_cnt * refclk_period) / (dly_cnt * den));
+	r = (10 * ((ref_cnt * refclk_period) % (dly_cnt * den))) /
+		(2 * dly_cnt * den);
+
+	return q + r;
+}
+
+static u32 get_cfg_reg(u16 a_delay, u16 g_delay, u32 cpde, u32 fpde)
+{
+	u32 g_delay_coarse, g_delay_fine;
+	u32 a_delay_coarse, a_delay_fine;
+	u32 c_elements, f_elements;
+	u32 total_delay, reg = 0;
+
+	g_delay_coarse = g_delay / 920;
+	g_delay_fine = ((g_delay % 920) * 10) / 60;
+
+	a_delay_coarse = a_delay / cpde;
+	a_delay_fine = ((a_delay % cpde) * 10) / fpde;
+
+	c_elements = g_delay_coarse + a_delay_coarse;
+	f_elements = (g_delay_fine + a_delay_fine) / 10;
+
+	if (f_elements > 22) {
+		total_delay = c_elements * cpde + f_elements * fpde;
+
+		c_elements = total_delay / cpde;
+		f_elements = (total_delay % cpde) / fpde;
+	}
+
+	reg = (c_elements << CFG_X_COARSE_DLY_SHIFT) & CFG_X_COARSE_DLY_MASK;
+	reg |= (f_elements << CFG_X_FINE_DLY_SHIFT) & CFG_X_FINE_DLY_MASK;
+	reg |= CFG_X_SIGNATURE << CFG_X_SIGNATURE_SHIFT;
+	reg |= CFG_X_LOCK << CFG_X_LOCK_SHIFT;
+
+	return reg;
+}
+
+int do_set_iodelay(u32 base, struct iodelay_cfg_entry const *array,
+		   int niodelays)
+{
+	struct iodelay_cfg_entry *iodelay = (struct iodelay_cfg_entry *)array;
+	u32 reg, cpde, fpde, i;
+
+	if (!niodelays)
+		return 0;
+
+	cpde = calculate_delay((*ctrl)->iodelay_config_base, CFG_REG_3_OFFSET,
+			       88);
+	if (!cpde)
+		return ERR_CPDE;
+
+	fpde = calculate_delay((*ctrl)->iodelay_config_base, CFG_REG_4_OFFSET,
+			       264);
+	if (!fpde)
+		return ERR_FPDE;
+
+	for (i = 0; i < niodelays; i++, iodelay++) {
+		reg = get_cfg_reg(iodelay->a_delay, iodelay->g_delay, cpde,
+				  fpde);
+		writel(reg, base + iodelay->offset);
+	}
+
+	return 0;
+}
+
+int __recalibrate_iodelay_start(void)
+{
+	int ret = 0;
+
+	/* IO recalibration should be done only from SRAM */
+	if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) {
+		puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n");
+		return -1;
+	}
+
+	/* unlock IODELAY CONFIG registers */
+	writel(CFG_IODELAY_UNLOCK_KEY, (*ctrl)->iodelay_config_base +
+	       CFG_REG_8_OFFSET);
+
+	ret = calibrate_iodelay((*ctrl)->iodelay_config_base);
+	if (ret)
+		goto err;
+
+	ret = isolate_io(ISOLATE_IO);
+	if (ret)
+		goto err;
+
+	ret = update_delay_mechanism((*ctrl)->iodelay_config_base);
+
+err:
+	return ret;
+}
+
+void __recalibrate_iodelay_end(int ret)
+{
+
+	/* IO recalibration should be done only from SRAM */
+	if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) {
+		puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n");
+		return;
+	}
+
+	if (!ret)
+		ret = isolate_io(DEISOLATE_IO);
+
+	/* lock IODELAY CONFIG registers */
+	writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base +
+	       CFG_REG_8_OFFSET);
+
+	/*
+	 * UART cannot be used during IO recalibration sequence as IOs are in
+	 * isolation. So error handling and debug prints are done after
+	 * complete IO delay recalibration sequence
+	 */
+	switch (ret) {
+	case ERR_CALIBRATE_IODELAY:
+		puts("IODELAY: IO delay calibration sequence failed\n");
+		break;
+	case ERR_ISOLATE_IO:
+		puts("IODELAY: Isolation of Device IOs failed\n");
+		break;
+	case ERR_UPDATE_DELAY:
+		puts("IODELAY: Delay mechanism update with new calibrated values failed\n");
+		break;
+	case ERR_DEISOLATE_IO:
+		puts("IODELAY: De-isolation of Device IOs failed\n");
+		break;
+	case ERR_CPDE:
+		puts("IODELAY: CPDE calculation failed\n");
+		break;
+	case ERR_FPDE:
+		puts("IODELAY: FPDE calculation failed\n");
+		break;
+	case -1:
+		puts("IODELAY: Wrong Context call?\n");
+		break;
+	default:
+		debug("IODELAY: IO delay recalibration successfully completed\n");
+	}
+
+	return;
+}
+
+void __recalibrate_iodelay(struct pad_conf_entry const *pad, int npads,
+			   struct iodelay_cfg_entry const *iodelay,
+			   int niodelays)
+{
+	int ret = 0;
+
+	/* IO recalibration should be done only from SRAM */
+	if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) {
+		puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n");
+		return;
+	}
+
+	ret = __recalibrate_iodelay_start();
+	if (ret)
+		goto err;
+
+	/* Configure Mux settings */
+	do_set_mux32((*ctrl)->control_padconf_core_base, pad, npads);
+
+	/* Configure Manual IO timing modes */
+	ret = do_set_iodelay((*ctrl)->iodelay_config_base, iodelay, niodelays);
+	if (ret)
+		goto err;
+
+err:
+	__recalibrate_iodelay_end(ret);
+
+}
diff --git a/arch/arm/mach-omap2/omap5/emif.c b/arch/arm/mach-omap2/omap5/emif.c
new file mode 100644
index 0000000..b1203a3
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/emif.c
@@ -0,0 +1,88 @@
+/*
+ * EMIF programming
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.com> for OMAP4
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/emif.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/utils.h>
+
+#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
+#define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg))
+static u32 *const T_num = (u32 *)OMAP_SRAM_SCRATCH_EMIF_T_NUM;
+static u32 *const T_den = (u32 *)OMAP_SRAM_SCRATCH_EMIF_T_DEN;
+#endif
+
+#ifdef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
+/* Base AC Timing values specified by JESD209-2 for 532MHz operation */
+static const struct lpddr2_ac_timings timings_jedec_532_mhz = {
+	.max_freq = 532000000,
+	.RL = 8,
+	.tRPab = 21,
+	.tRCD = 18,
+	.tWR = 15,
+	.tRASmin = 42,
+	.tRRD = 10,
+	.tWTRx2 = 15,
+	.tXSR = 140,
+	.tXPx2 = 15,
+	.tRFCab = 130,
+	.tRTPx2 = 15,
+	.tCKE = 3,
+	.tCKESR = 15,
+	.tZQCS = 90,
+	.tZQCL = 360,
+	.tZQINIT = 1000,
+	.tDQSCKMAXx2 = 11,
+	.tRASmax = 70,
+	.tFAW = 50
+};
+
+/*
+ * Min tCK values specified by JESD209-2
+ * Min tCK specifies the minimum duration of some AC timing parameters in terms
+ * of the number of cycles. If the calculated number of cycles based on the
+ * absolute time value is less than the min tCK value, min tCK value should
+ * be used instead. This typically happens at low frequencies.
+ */
+static const struct lpddr2_min_tck min_tck_jedec = {
+	.tRL = 3,
+	.tRP_AB = 3,
+	.tRCD = 3,
+	.tWR = 3,
+	.tRAS_MIN = 3,
+	.tRRD = 2,
+	.tWTR = 2,
+	.tXP = 2,
+	.tRTP = 2,
+	.tCKE = 3,
+	.tCKESR = 3,
+	.tFAW = 8
+};
+
+static const struct lpddr2_ac_timings const*
+			jedec_ac_timings[MAX_NUM_SPEEDBINS] = {
+	&timings_jedec_532_mhz
+};
+
+static const struct lpddr2_device_timings jedec_default_timings = {
+	.ac_timings = jedec_ac_timings,
+	.min_tck = &min_tck_jedec
+};
+
+void emif_get_device_timings(u32 emif_nr,
+		const struct lpddr2_device_timings **cs0_device_timings,
+		const struct lpddr2_device_timings **cs1_device_timings)
+{
+	/* Assume Identical devices on EMIF1 & EMIF2 */
+	*cs0_device_timings = &jedec_default_timings;
+	*cs1_device_timings = NULL;
+}
+#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */
diff --git a/arch/arm/mach-omap2/omap5/fdt.c b/arch/arm/mach-omap2/omap5/fdt.c
new file mode 100644
index 0000000..da8d59b
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/fdt.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2016 Texas Instruments, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <malloc.h>
+
+#include <asm/omap_common.h>
+#include <asm/arch-omap5/sys_proto.h>
+
+#ifdef CONFIG_TI_SECURE_DEVICE
+
+/* Give zero values if not already defined */
+#ifndef TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ
+#define TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ (0)
+#endif
+#ifndef CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ
+#define CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ (0)
+#endif
+
+static u32 hs_irq_skip[] = {
+	8,	/* Secure violation reporting interrupt */
+	15,	/* One interrupt for SDMA by secure world */
+	118	/* One interrupt for Crypto DMA by secure world */
+};
+
+static int ft_hs_fixup_crossbar(void *fdt, bd_t *bd)
+{
+	const char *path;
+	int offs;
+	int ret;
+	int len, i, old_cnt, new_cnt;
+	u32 *temp;
+	const u32 *p_data;
+
+	/*
+	 * Increase the size of the fdt
+	 * so we have some breathing room
+	 */
+	ret = fdt_increase_size(fdt, 512);
+	if (ret < 0) {
+		printf("Could not increase size of device tree: %s\n",
+		       fdt_strerror(ret));
+		return ret;
+	}
+
+	/* Reserve IRQs that are used/needed by secure world */
+	path = "/ocp/crossbar";
+	offs = fdt_path_offset(fdt, path);
+	if (offs < 0) {
+		debug("Node %s not found.\n", path);
+		return 0;
+	}
+
+	/* Get current entries */
+	p_data = fdt_getprop(fdt, offs, "ti,irqs-skip", &len);
+	if (p_data)
+		old_cnt = len / sizeof(u32);
+	else
+		old_cnt = 0;
+
+	new_cnt = sizeof(hs_irq_skip) /
+				sizeof(hs_irq_skip[0]);
+
+	/* Create new/updated skip list for HS parts */
+	temp = malloc(sizeof(u32) * (old_cnt + new_cnt));
+	for (i = 0; i < new_cnt; i++)
+		temp[i] = cpu_to_fdt32(hs_irq_skip[i]);
+	for (i = 0; i < old_cnt; i++)
+		temp[i + new_cnt] = p_data[i];
+
+	/* Blow away old data and set new data */
+	fdt_delprop(fdt, offs, "ti,irqs-skip");
+	ret = fdt_setprop(fdt, offs, "ti,irqs-skip",
+			  temp,
+			  (old_cnt + new_cnt) * sizeof(u32));
+	free(temp);
+
+	/* Check if the update worked */
+	if (ret < 0) {
+		printf("Could not add ti,irqs-skip property to node %s: %s\n",
+		       path, fdt_strerror(ret));
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ft_hs_disable_rng(void *fdt, bd_t *bd)
+{
+	const char *path;
+	int offs;
+	int ret;
+
+	/* Make HW RNG reserved for secure world use */
+	path = "/ocp/rng";
+	offs = fdt_path_offset(fdt, path);
+	if (offs < 0) {
+		debug("Node %s not found.\n", path);
+		return 0;
+	}
+	ret = fdt_setprop_string(fdt, offs,
+				 "status", "disabled");
+	if (ret < 0) {
+		printf("Could not add status property to node %s: %s\n",
+		       path, fdt_strerror(ret));
+		return ret;
+	}
+	return 0;
+}
+
+#if ((TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ != 0) || \
+    (CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ != 0))
+static int ft_hs_fixup_sram(void *fdt, bd_t *bd)
+{
+	const char *path;
+	int offs;
+	int ret;
+	u32 temp[2];
+
+	/*
+	 * Update SRAM reservations on secure devices. The OCMC RAM
+	 * is always reserved for secure use from the start of that
+	 * memory region
+	 */
+	path = "/ocp/ocmcram@40300000/sram-hs";
+	offs = fdt_path_offset(fdt, path);
+	if (offs < 0) {
+		debug("Node %s not found.\n", path);
+		return 0;
+	}
+
+	/* relative start offset */
+	temp[0] = cpu_to_fdt32(0);
+	/* reservation size */
+	temp[1] = cpu_to_fdt32(max(TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ,
+				   CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ));
+	fdt_delprop(fdt, offs, "reg");
+	ret = fdt_setprop(fdt, offs, "reg", temp, 2 * sizeof(u32));
+	if (ret < 0) {
+		printf("Could not add reg property to node %s: %s\n",
+		       path, fdt_strerror(ret));
+		return ret;
+	}
+
+	return 0;
+}
+#else
+static int ft_hs_fixup_sram(void *fdt, bd_t *bd) { return 0; }
+#endif
+
+#if (CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE != 0)
+static int ft_hs_fixup_dram(void *fdt, bd_t *bd)
+{
+	const char *path, *subpath;
+	int offs;
+	u32 sec_mem_start = CONFIG_TI_SECURE_EMIF_REGION_START;
+	u32 sec_mem_size = CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE;
+	fdt64_t temp[2];
+
+	/* If start address is zero, place at end of DRAM */
+	if (0 == sec_mem_start)
+		sec_mem_start =
+			(CONFIG_SYS_SDRAM_BASE +
+			(omap_sdram_size() - sec_mem_size));
+
+	/* Delete any original secure_reserved node */
+	path = "/reserved-memory/secure_reserved";
+	offs = fdt_path_offset(fdt, path);
+	if (offs >= 0)
+		fdt_del_node(fdt, offs);
+
+	/* Add new secure_reserved node */
+	path = "/reserved-memory";
+	offs = fdt_path_offset(fdt, path);
+	if (offs < 0) {
+		debug("Node %s not found\n", path);
+		path = "/";
+		subpath = "reserved-memory";
+		fdt_path_offset(fdt, path);
+		offs = fdt_add_subnode(fdt, offs, subpath);
+		if (offs < 0) {
+			printf("Could not create %s%s node.\n", path, subpath);
+			return 1;
+		}
+		path = "/reserved-memory";
+		offs = fdt_path_offset(fdt, path);
+	}
+
+	subpath = "secure_reserved";
+	offs = fdt_add_subnode(fdt, offs, subpath);
+	if (offs < 0) {
+		printf("Could not create %s%s node.\n", path, subpath);
+		return 1;
+	}
+
+	temp[0] = cpu_to_fdt64(((u64)sec_mem_start));
+	temp[1] = cpu_to_fdt64(((u64)sec_mem_size));
+	fdt_setprop_string(fdt, offs, "compatible",
+			   "ti,dra7-secure-memory");
+	fdt_setprop_string(fdt, offs, "status", "okay");
+	fdt_setprop(fdt, offs, "no-map", NULL, 0);
+	fdt_setprop(fdt, offs, "reg", temp, sizeof(temp));
+
+	return 0;
+}
+#else
+static int ft_hs_fixup_dram(void *fdt, bd_t *bd) { return 0; }
+#endif
+
+static void ft_hs_fixups(void *fdt, bd_t *bd)
+{
+	/* Check we are running on an HS/EMU device type */
+	if (GP_DEVICE != get_device_type()) {
+		if ((ft_hs_fixup_crossbar(fdt, bd) == 0) &&
+		    (ft_hs_disable_rng(fdt, bd) == 0) &&
+		    (ft_hs_fixup_sram(fdt, bd) == 0) &&
+		    (ft_hs_fixup_dram(fdt, bd) == 0))
+			return;
+	} else {
+		printf("ERROR: Incorrect device type (GP) detected!");
+	}
+	/* Fixup failed or wrong device type */
+	hang();
+}
+#else
+static void ft_hs_fixups(void *fdt, bd_t *bd)
+{
+}
+#endif /* #ifdef CONFIG_TI_SECURE_DEVICE */
+
+/*
+ * Place for general cpu/SoC FDT fixups. Board specific
+ * fixups should remain in the board files which is where
+ * this function should be called from.
+ */
+void ft_cpu_setup(void *fdt, bd_t *bd)
+{
+	ft_hs_fixups(fdt, bd);
+}
diff --git a/arch/arm/mach-omap2/omap5/hw_data.c b/arch/arm/mach-omap2/omap5/hw_data.c
new file mode 100644
index 0000000..fc99135
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/hw_data.c
@@ -0,0 +1,776 @@
+/*
+ *
+ * HW data initialization for OMAP5
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * Sricharan R <r.sricharan@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <palmas.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/omap_common.h>
+#include <asm/arch/clock.h>
+#include <asm/omap_gpio.h>
+#include <asm/io.h>
+#include <asm/emif.h>
+
+struct prcm_regs const **prcm =
+			(struct prcm_regs const **) OMAP_SRAM_SCRATCH_PRCM_PTR;
+struct dplls const **dplls_data =
+			(struct dplls const **) OMAP_SRAM_SCRATCH_DPLLS_PTR;
+struct vcores_data const **omap_vcores =
+		(struct vcores_data const **) OMAP_SRAM_SCRATCH_VCORES_PTR;
+struct omap_sys_ctrl_regs const **ctrl =
+	(struct omap_sys_ctrl_regs const **)OMAP_SRAM_SCRATCH_SYS_CTRL;
+
+/* OPP HIGH FREQUENCY for ES2.0 */
+static const struct dpll_params mpu_dpll_params_1_5ghz[NUM_SYS_CLKS] = {
+	{125, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{625, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{625, 7, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{750, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{625, 15, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}	/* 38.4 MHz */
+};
+
+/* OPP NOM FREQUENCY for ES1.0 */
+static const struct dpll_params mpu_dpll_params_800mhz[NUM_SYS_CLKS] = {
+	{200, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{1000, 20, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{375, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{400, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{375, 17, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}	/* 38.4 MHz */
+};
+
+/* OPP LOW FREQUENCY for ES1.0 */
+static const struct dpll_params mpu_dpll_params_400mhz[NUM_SYS_CLKS] = {
+	{200, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{1000, 20, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{375, 8, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{400, 12, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{375, 17, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}	/* 38.4 MHz */
+};
+
+/* OPP LOW FREQUENCY for ES2.0 */
+static const struct dpll_params mpu_dpll_params_499mhz[NUM_SYS_CLKS] = {
+	{499, 11, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{297, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{493, 18, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{499, 25, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{493, 37, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}	/* 38.4 MHz */
+};
+
+/* OPP NOM FREQUENCY for OMAP5 ES2.0, and DRA7 ES1.0 */
+static const struct dpll_params mpu_dpll_params_1ghz[NUM_SYS_CLKS] = {
+	{250, 2, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 12 MHz   */
+	{500, 9, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 20 MHz   */
+	{119, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 16.8 MHz */
+	{625, 11, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{500, 12, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{625, 23, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 38.4 MHz */
+};
+
+static const struct dpll_params
+			core_dpll_params_2128mhz_ddr532[NUM_SYS_CLKS] = {
+	{266, 2, 2, 5, 8, 4, 62, 5, -1, 5, 7, -1},		/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{443, 6, 2, 5, 8, 4, 62, 5, -1, 5, 7, -1},		/* 16.8 MHz */
+	{277, 4, 2, 5, 8, 4, 62, 5, -1, 5, 7, -1},		/* 19.2 MHz */
+	{368, 8, 2, 5, 8, 4, 62, 5, -1, 5, 7, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{277, 9, 2, 5, 8, 4, 62, 5, -1, 5, 7, -1}		/* 38.4 MHz */
+};
+
+static const struct dpll_params
+			core_dpll_params_2128mhz_ddr532_es2[NUM_SYS_CLKS] = {
+	{266, 2, 2, 5, 8, 4, 62, 63, 6, 5, 7, 6},		/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{443, 6, 2, 5, 8, 4, 62, 63, 6, 5, 7, 6},		/* 16.8 MHz */
+	{277, 4, 2, 5, 8, 4, 62, 63, 6, 5, 7, 6},		/* 19.2 MHz */
+	{368, 8, 2, 5, 8, 4, 62, 63, 6, 5, 7, 6},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{277, 9, 2, 5, 8, 4, 62, 63, 6, 5, 7, 6}		/* 38.4 MHz */
+};
+
+static const struct dpll_params
+		core_dpll_params_2128mhz_dra7xx[NUM_SYS_CLKS] = {
+	{266, 2, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6},		/* 12 MHz   */
+	{266, 4, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6},		/* 20 MHz   */
+	{443, 6, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6},		/* 16.8 MHz */
+	{277, 4, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6},		/* 19.2 MHz */
+	{368, 8, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{277, 9, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6},		/* 38.4 MHz */
+};
+
+static const struct dpll_params
+			core_dpll_params_2128mhz_ddr266[NUM_SYS_CLKS] = {
+	{266, 2, 4, 8, 8, 8, 62, 10, -1, 10, 14, -1},		/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{443, 6, 4, 8, 8, 8, 62, 10, -1, 10, 14, -1},		/* 16.8 MHz */
+	{277, 4, 4, 8, 8, 8, 62, 10, -1, 10, 14, -1},		/* 19.2 MHz */
+	{368, 8, 4, 8, 8, 8, 62, 10, -1, 10, 14, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{277, 9, 4, 8, 8, 8, 62, 10, -1, 10, 14, -1}		/* 38.4 MHz */
+};
+
+static const struct dpll_params
+			core_dpll_params_2128mhz_ddr266_es2[NUM_SYS_CLKS] = {
+	{266, 2, 4, 8, 8, 8, 62, 5, 12, 10, 14, 12},		/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{443, 6, 4, 8, 8, 8, 62, 5, 12, 10, 14, 12},		/* 16.8 MHz */
+	{277, 4, 4, 8, 8, 8, 62, 5, 12, 10, 14, 12},		/* 19.2 MHz */
+	{368, 8, 4, 8, 8, 8, 62, 5, 12, 10, 14, 12},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{277, 9, 4, 8, 8, 8, 62, 5, 12, 10, 14, 12}		/* 38.4 MHz */
+};
+
+static const struct dpll_params per_dpll_params_768mhz[NUM_SYS_CLKS] = {
+	{32, 0, 4, 3, 6, 4, -1, 2, -1, -1, -1, -1},		/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{160, 6, 4, 3, 6, 4, -1, 2, -1, -1, -1, -1},		/* 16.8 MHz */
+	{20, 0, 4, 3, 6, 4, -1, 2, -1, -1, -1, -1},		/* 19.2 MHz */
+	{192, 12, 4, 3, 6, 4, -1, 2, -1, -1, -1, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{10, 0, 4, 3, 6, 4, -1, 2, -1, -1, -1, -1}		/* 38.4 MHz */
+};
+
+static const struct dpll_params per_dpll_params_768mhz_es2[NUM_SYS_CLKS] = {
+	{32, 0, 4, 3, 3, 4, -1, 2, -1, -1, -1, -1},		/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{160, 6, 4, 3, 3, 4, -1, 2, -1, -1, -1, -1},		/* 16.8 MHz */
+	{20, 0, 4, 3, 3, 4, -1, 2, -1, -1, -1, -1},		/* 19.2 MHz */
+	{192, 12, 4, 3, 3, 4, -1, 2, -1, -1, -1, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{10, 0, 4, 3, 3, 4, -1, 2, -1, -1, -1, -1}		/* 38.4 MHz */
+};
+
+static const struct dpll_params per_dpll_params_768mhz_dra7xx[NUM_SYS_CLKS] = {
+	{32, 0, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1},		/* 12 MHz   */
+	{96, 4, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1},		/* 20 MHz   */
+	{160, 6, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1},		/* 16.8 MHz */
+	{20, 0, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1},		/* 19.2 MHz */
+	{192, 12, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{10, 0, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1},		/* 38.4 MHz */
+};
+
+static const struct dpll_params iva_dpll_params_2330mhz[NUM_SYS_CLKS] = {
+	{1165, 11, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{208, 2, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1},		/* 16.8 MHz */
+	{182, 2, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1},		/* 19.2 MHz */
+	{224, 4, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{91, 2, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1}		/* 38.4 MHz */
+};
+
+static const struct dpll_params iva_dpll_params_2330mhz_dra7xx[NUM_SYS_CLKS] = {
+	{1165, 11, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{233, 3, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 20 MHz */
+	{208, 2, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 16.8 MHz */
+	{182, 2, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 19.2 MHz */
+	{224, 4, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{91, 2, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 38.4 MHz */
+};
+
+/* ABE M & N values with sys_clk as source */
+static const struct dpll_params
+		abe_dpll_params_sysclk_196608khz[NUM_SYS_CLKS] = {
+	{49, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{35, 5, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 16.8 MHz */
+	{46, 8, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 19.2 MHz */
+	{34, 8, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{64, 24, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}		/* 38.4 MHz */
+};
+
+/* ABE M & N values with 32K clock as source */
+static const struct dpll_params abe_dpll_params_32k_196608khz = {
+	750, 0, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+/* ABE M & N values with sysclk2(22.5792 MHz) as input */
+static const struct dpll_params
+		abe_dpll_params_sysclk2_361267khz[NUM_SYS_CLKS] = {
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{16, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1},		/* 20 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 38.4 MHz */
+};
+
+static const struct dpll_params usb_dpll_params_1920mhz[NUM_SYS_CLKS] = {
+	{400, 4, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{480, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 20 MHz   */
+	{400, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{400, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{480, 12, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{400, 15, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 38.4 MHz */
+};
+
+static const struct dpll_params ddr_dpll_params_2664mhz[NUM_SYS_CLKS] = {
+	{111, 0, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 12 MHz   */
+	{333, 4, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 20 MHz   */
+	{555, 6, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 16.8 MHz */
+	{555, 7, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 19.2 MHz */
+	{666, 12, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{555, 15, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 38.4 MHz */
+};
+
+static const struct dpll_params ddr_dpll_params_2128mhz[NUM_SYS_CLKS] = {
+	{266, 2, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 12 MHz   */
+	{266, 4, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 20 MHz   */
+	{190, 2, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 16.8 MHz */
+	{665, 11, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 19.2 MHz */
+	{532, 12, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{665, 23, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1},		/* 38.4 MHz */
+};
+
+static const struct dpll_params gmac_dpll_params_2000mhz[NUM_SYS_CLKS] = {
+	{250, 2, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1},		/* 12 MHz   */
+	{250, 4, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1},		/* 20 MHz   */
+	{119, 1, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1},		/* 16.8 MHz */
+	{625, 11, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{500, 12, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{625, 23, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1},	/* 38.4 MHz */
+};
+
+struct dplls omap5_dplls_es1 = {
+	.mpu = mpu_dpll_params_800mhz,
+	.core = core_dpll_params_2128mhz_ddr532,
+	.per = per_dpll_params_768mhz,
+	.iva = iva_dpll_params_2330mhz,
+#ifdef CONFIG_SYS_OMAP_ABE_SYSCK
+	.abe = abe_dpll_params_sysclk_196608khz,
+#else
+	.abe = &abe_dpll_params_32k_196608khz,
+#endif
+	.usb = usb_dpll_params_1920mhz,
+	.ddr = NULL
+};
+
+struct dplls omap5_dplls_es2 = {
+	.mpu = mpu_dpll_params_1ghz,
+	.core = core_dpll_params_2128mhz_ddr532_es2,
+	.per = per_dpll_params_768mhz_es2,
+	.iva = iva_dpll_params_2330mhz,
+#ifdef CONFIG_SYS_OMAP_ABE_SYSCK
+	.abe = abe_dpll_params_sysclk_196608khz,
+#else
+	.abe = &abe_dpll_params_32k_196608khz,
+#endif
+	.usb = usb_dpll_params_1920mhz,
+	.ddr = NULL
+};
+
+struct dplls dra7xx_dplls = {
+	.mpu = mpu_dpll_params_1ghz,
+	.core = core_dpll_params_2128mhz_dra7xx,
+	.per = per_dpll_params_768mhz_dra7xx,
+	.abe = abe_dpll_params_sysclk2_361267khz,
+	.iva = iva_dpll_params_2330mhz_dra7xx,
+	.usb = usb_dpll_params_1920mhz,
+	.ddr = ddr_dpll_params_2128mhz,
+	.gmac = gmac_dpll_params_2000mhz,
+};
+
+struct dplls dra72x_dplls = {
+	.mpu = mpu_dpll_params_1ghz,
+	.core = core_dpll_params_2128mhz_dra7xx,
+	.per = per_dpll_params_768mhz_dra7xx,
+	.abe = abe_dpll_params_sysclk2_361267khz,
+	.iva = iva_dpll_params_2330mhz_dra7xx,
+	.usb = usb_dpll_params_1920mhz,
+	.ddr =	ddr_dpll_params_2664mhz,
+	.gmac = gmac_dpll_params_2000mhz,
+};
+
+struct pmic_data palmas = {
+	.base_offset = PALMAS_SMPS_BASE_VOLT_UV,
+	.step = 10000, /* 10 mV represented in uV */
+	/*
+	 * Offset codes 1-6 all give the base voltage in Palmas
+	 * Offset code 0 switches OFF the SMPS
+	 */
+	.start_code = 6,
+	.i2c_slave_addr	= SMPS_I2C_SLAVE_ADDR,
+	.pmic_bus_init	= sri2c_init,
+	.pmic_write	= omap_vc_bypass_send_value,
+	.gpio_en = 0,
+};
+
+/* The TPS659038 and TPS65917 are software-compatible, use common struct */
+struct pmic_data tps659038 = {
+	.base_offset = PALMAS_SMPS_BASE_VOLT_UV,
+	.step = 10000, /* 10 mV represented in uV */
+	/*
+	 * Offset codes 1-6 all give the base voltage in Palmas
+	 * Offset code 0 switches OFF the SMPS
+	 */
+	.start_code = 6,
+	.i2c_slave_addr	= TPS659038_I2C_SLAVE_ADDR,
+	.pmic_bus_init	= gpi2c_init,
+	.pmic_write	= palmas_i2c_write_u8,
+	.gpio_en = 0,
+};
+
+struct vcores_data omap5430_volts = {
+	.mpu.value = VDD_MPU,
+	.mpu.addr = SMPS_REG_ADDR_12_MPU,
+	.mpu.pmic = &palmas,
+
+	.core.value = VDD_CORE,
+	.core.addr = SMPS_REG_ADDR_8_CORE,
+	.core.pmic = &palmas,
+
+	.mm.value = VDD_MM,
+	.mm.addr = SMPS_REG_ADDR_45_IVA,
+	.mm.pmic = &palmas,
+};
+
+struct vcores_data omap5430_volts_es2 = {
+	.mpu.value = VDD_MPU_ES2,
+	.mpu.addr = SMPS_REG_ADDR_12_MPU,
+	.mpu.pmic = &palmas,
+	.mpu.abb_tx_done_mask = OMAP_ABB_MPU_TXDONE_MASK,
+
+	.core.value = VDD_CORE_ES2,
+	.core.addr = SMPS_REG_ADDR_8_CORE,
+	.core.pmic = &palmas,
+
+	.mm.value = VDD_MM_ES2,
+	.mm.addr = SMPS_REG_ADDR_45_IVA,
+	.mm.pmic = &palmas,
+	.mm.abb_tx_done_mask = OMAP_ABB_MM_TXDONE_MASK,
+};
+
+/*
+ * Enable essential clock domains, modules and
+ * do some additional special settings needed
+ */
+void enable_basic_clocks(void)
+{
+	u32 const clk_domains_essential[] = {
+		(*prcm)->cm_l4per_clkstctrl,
+		(*prcm)->cm_l3init_clkstctrl,
+		(*prcm)->cm_memif_clkstctrl,
+		(*prcm)->cm_l4cfg_clkstctrl,
+#ifdef CONFIG_DRIVER_TI_CPSW
+		(*prcm)->cm_gmac_clkstctrl,
+#endif
+		0
+	};
+
+	u32 const clk_modules_hw_auto_essential[] = {
+		(*prcm)->cm_l3_gpmc_clkctrl,
+		(*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_l4per_gpio7_clkctrl,
+		(*prcm)->cm_l4per_gpio8_clkctrl,
+		0
+	};
+
+	u32 const clk_modules_explicit_en_essential[] = {
+		(*prcm)->cm_wkup_gptimer1_clkctrl,
+		(*prcm)->cm_l3init_hsmmc1_clkctrl,
+		(*prcm)->cm_l3init_hsmmc2_clkctrl,
+		(*prcm)->cm_l4per_gptimer2_clkctrl,
+		(*prcm)->cm_wkup_wdtimer2_clkctrl,
+		(*prcm)->cm_l4per_uart3_clkctrl,
+		(*prcm)->cm_l4per_i2c1_clkctrl,
+#ifdef CONFIG_DRIVER_TI_CPSW
+		(*prcm)->cm_gmac_gmac_clkctrl,
+#endif
+
+#ifdef CONFIG_TI_QSPI
+		(*prcm)->cm_l4per_qspi_clkctrl,
+#endif
+		0
+	};
+
+	/* Enable optional additional functional clock for GPIO4 */
+	setbits_le32((*prcm)->cm_l4per_gpio4_clkctrl,
+			GPIO4_CLKCTRL_OPTFCLKEN_MASK);
+
+	/* Enable 96 MHz clock for MMC1 & MMC2 */
+	setbits_le32((*prcm)->cm_l3init_hsmmc1_clkctrl,
+			HSMMC_CLKCTRL_CLKSEL_MASK);
+	setbits_le32((*prcm)->cm_l3init_hsmmc2_clkctrl,
+			HSMMC_CLKCTRL_CLKSEL_MASK);
+
+	/* Set the correct clock dividers for mmc */
+	setbits_le32((*prcm)->cm_l3init_hsmmc1_clkctrl,
+			HSMMC_CLKCTRL_CLKSEL_DIV_MASK);
+	setbits_le32((*prcm)->cm_l3init_hsmmc2_clkctrl,
+			HSMMC_CLKCTRL_CLKSEL_DIV_MASK);
+
+	/* Select 32KHz clock as the source of GPTIMER1 */
+	setbits_le32((*prcm)->cm_wkup_gptimer1_clkctrl,
+			GPTIMER1_CLKCTRL_CLKSEL_MASK);
+
+	do_enable_clocks(clk_domains_essential,
+			 clk_modules_hw_auto_essential,
+			 clk_modules_explicit_en_essential,
+			 1);
+
+#ifdef CONFIG_TI_QSPI
+	setbits_le32((*prcm)->cm_l4per_qspi_clkctrl, (1<<24));
+#endif
+
+	/* Enable SCRM OPT clocks for PER and CORE dpll */
+	setbits_le32((*prcm)->cm_wkupaon_scrm_clkctrl,
+			OPTFCLKEN_SCRM_PER_MASK);
+	setbits_le32((*prcm)->cm_wkupaon_scrm_clkctrl,
+			OPTFCLKEN_SCRM_CORE_MASK);
+}
+
+void enable_basic_uboot_clocks(void)
+{
+	u32 const clk_domains_essential[] = {
+#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)
+		(*prcm)->cm_ipu_clkstctrl,
+#endif
+		0
+	};
+
+	u32 const clk_modules_hw_auto_essential[] = {
+		(*prcm)->cm_l3init_hsusbtll_clkctrl,
+		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,
+#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)
+		(*prcm)->cm_ipu_i2c5_clkctrl,
+#else
+		(*prcm)->cm_l4per_i2c5_clkctrl,
+#endif
+		(*prcm)->cm_l3init_hsusbhost_clkctrl,
+		(*prcm)->cm_l3init_fsusb_clkctrl,
+		0
+	};
+	do_enable_clocks(clk_domains_essential,
+			 clk_modules_hw_auto_essential,
+			 clk_modules_explicit_en_essential,
+			 1);
+}
+
+#ifdef CONFIG_TI_EDMA3
+void enable_edma3_clocks(void)
+{
+	u32 const clk_domains_edma3[] = {
+		0
+	};
+
+	u32 const clk_modules_hw_auto_edma3[] = {
+		(*prcm)->cm_l3main1_tptc1_clkctrl,
+		(*prcm)->cm_l3main1_tptc2_clkctrl,
+		0
+	};
+
+	u32 const clk_modules_explicit_en_edma3[] = {
+		0
+	};
+
+	do_enable_clocks(clk_domains_edma3,
+			 clk_modules_hw_auto_edma3,
+			 clk_modules_explicit_en_edma3,
+			 1);
+}
+
+void disable_edma3_clocks(void)
+{
+	u32 const clk_domains_edma3[] = {
+		0
+	};
+
+	u32 const clk_modules_disable_edma3[] = {
+		(*prcm)->cm_l3main1_tptc1_clkctrl,
+		(*prcm)->cm_l3main1_tptc2_clkctrl,
+		0
+	};
+
+	do_disable_clocks(clk_domains_edma3,
+			  clk_modules_disable_edma3,
+			  1);
+}
+#endif
+
+#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP)
+void enable_usb_clocks(int index)
+{
+	u32 cm_l3init_usb_otg_ss_clkctrl = 0;
+
+	if (index == 0) {
+		cm_l3init_usb_otg_ss_clkctrl =
+			(*prcm)->cm_l3init_usb_otg_ss1_clkctrl;
+		/* Enable 960 MHz clock for dwc3 */
+		setbits_le32((*prcm)->cm_l3init_usb_otg_ss1_clkctrl,
+			     OPTFCLKEN_REFCLK960M);
+
+		/* Enable 32 KHz clock for USB_PHY1 */
+		setbits_le32((*prcm)->cm_coreaon_usb_phy1_core_clkctrl,
+			     USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K);
+
+		/* Enable 32 KHz clock for USB_PHY3 */
+		if (is_dra7xx())
+			setbits_le32((*prcm)->cm_coreaon_usb_phy3_core_clkctrl,
+				     USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K);
+	} else if (index == 1) {
+		cm_l3init_usb_otg_ss_clkctrl =
+			(*prcm)->cm_l3init_usb_otg_ss2_clkctrl;
+		/* Enable 960 MHz clock for dwc3 */
+		setbits_le32((*prcm)->cm_l3init_usb_otg_ss2_clkctrl,
+			     OPTFCLKEN_REFCLK960M);
+
+		/* Enable 32 KHz clock for dwc3 */
+		setbits_le32((*prcm)->cm_coreaon_usb_phy2_core_clkctrl,
+			     USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K);
+
+		/* Enable 60 MHz clock for USB2PHY2 */
+		setbits_le32((*prcm)->cm_coreaon_l3init_60m_gfclk_clkctrl,
+			     L3INIT_CLKCTRL_OPTFCLKEN_60M_GFCLK);
+	}
+
+	u32 const clk_domains_usb[] = {
+		0
+	};
+
+	u32 const clk_modules_hw_auto_usb[] = {
+		(*prcm)->cm_l3init_ocp2scp1_clkctrl,
+		cm_l3init_usb_otg_ss_clkctrl,
+		0
+	};
+
+	u32 const clk_modules_explicit_en_usb[] = {
+		0
+	};
+
+	do_enable_clocks(clk_domains_usb,
+			 clk_modules_hw_auto_usb,
+			 clk_modules_explicit_en_usb,
+			 1);
+}
+
+void disable_usb_clocks(int index)
+{
+	u32 cm_l3init_usb_otg_ss_clkctrl = 0;
+
+	if (index == 0) {
+		cm_l3init_usb_otg_ss_clkctrl =
+			(*prcm)->cm_l3init_usb_otg_ss1_clkctrl;
+		/* Disable 960 MHz clock for dwc3 */
+		clrbits_le32((*prcm)->cm_l3init_usb_otg_ss1_clkctrl,
+			     OPTFCLKEN_REFCLK960M);
+
+		/* Disable 32 KHz clock for USB_PHY1 */
+		clrbits_le32((*prcm)->cm_coreaon_usb_phy1_core_clkctrl,
+			     USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K);
+
+		/* Disable 32 KHz clock for USB_PHY3 */
+		if (is_dra7xx())
+			clrbits_le32((*prcm)->cm_coreaon_usb_phy3_core_clkctrl,
+				     USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K);
+	} else if (index == 1) {
+		cm_l3init_usb_otg_ss_clkctrl =
+			(*prcm)->cm_l3init_usb_otg_ss2_clkctrl;
+		/* Disable 960 MHz clock for dwc3 */
+		clrbits_le32((*prcm)->cm_l3init_usb_otg_ss2_clkctrl,
+			     OPTFCLKEN_REFCLK960M);
+
+		/* Disable 32 KHz clock for dwc3 */
+		clrbits_le32((*prcm)->cm_coreaon_usb_phy2_core_clkctrl,
+			     USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K);
+
+		/* Disable 60 MHz clock for USB2PHY2 */
+		clrbits_le32((*prcm)->cm_coreaon_l3init_60m_gfclk_clkctrl,
+			     L3INIT_CLKCTRL_OPTFCLKEN_60M_GFCLK);
+	}
+
+	u32 const clk_domains_usb[] = {
+		0
+	};
+
+	u32 const clk_modules_disable[] = {
+		(*prcm)->cm_l3init_ocp2scp1_clkctrl,
+		cm_l3init_usb_otg_ss_clkctrl,
+		0
+	};
+
+	do_disable_clocks(clk_domains_usb,
+			  clk_modules_disable,
+			  1);
+}
+#endif
+
+const struct ctrl_ioregs ioregs_omap5430 = {
+	.ctrl_ddrch = DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN,
+	.ctrl_lpddr2ch = DDR_IO_I_34OHM_SR_FASTEST_WD_CK_CKE_NCS_CA_PULL_DOWN,
+	.ctrl_ddrio_0 = DDR_IO_0_DDR2_DQ_INT_EN_ALL_DDR3_CA_DIS_ALL,
+	.ctrl_ddrio_1 = DDR_IO_1_DQ_OUT_EN_ALL_DQ_INT_EN_ALL,
+	.ctrl_ddrio_2 = DDR_IO_2_CA_OUT_EN_ALL_CA_INT_EN_ALL,
+};
+
+const struct ctrl_ioregs ioregs_omap5432_es1 = {
+	.ctrl_ddrch = DDR_IO_I_40OHM_SR_FAST_WD_DQ_NO_PULL_DQS_NO_PULL,
+	.ctrl_lpddr2ch = 0x0,
+	.ctrl_ddr3ch = DDR_IO_I_40OHM_SR_SLOWEST_WD_DQ_NO_PULL_DQS_NO_PULL,
+	.ctrl_ddrio_0 = DDR_IO_0_VREF_CELLS_DDR3_VALUE,
+	.ctrl_ddrio_1 = DDR_IO_1_VREF_CELLS_DDR3_VALUE,
+	.ctrl_ddrio_2 = DDR_IO_2_VREF_CELLS_DDR3_VALUE,
+	.ctrl_emif_sdram_config_ext = SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES,
+	.ctrl_emif_sdram_config_ext_final = SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES,
+};
+
+const struct ctrl_ioregs ioregs_omap5432_es2 = {
+	.ctrl_ddrch = DDR_IO_I_40OHM_SR_FAST_WD_DQ_NO_PULL_DQS_NO_PULL_ES2,
+	.ctrl_lpddr2ch = 0x0,
+	.ctrl_ddr3ch = DDR_IO_I_40OHM_SR_SLOWEST_WD_DQ_NO_PULL_DQS_NO_PULL_ES2,
+	.ctrl_ddrio_0 = DDR_IO_0_VREF_CELLS_DDR3_VALUE_ES2,
+	.ctrl_ddrio_1 = DDR_IO_1_VREF_CELLS_DDR3_VALUE_ES2,
+	.ctrl_ddrio_2 = DDR_IO_2_VREF_CELLS_DDR3_VALUE_ES2,
+	.ctrl_emif_sdram_config_ext = SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES,
+	.ctrl_emif_sdram_config_ext_final = SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES,
+};
+
+const struct ctrl_ioregs ioregs_dra7xx_es1 = {
+	.ctrl_ddrch = 0x40404040,
+	.ctrl_lpddr2ch = 0x40404040,
+	.ctrl_ddr3ch = 0x80808080,
+	.ctrl_ddrio_0 = 0x00094A40,
+	.ctrl_ddrio_1 = 0x04A52000,
+	.ctrl_ddrio_2 = 0x84210000,
+	.ctrl_emif_sdram_config_ext = 0x0001C1A7,
+	.ctrl_emif_sdram_config_ext_final = 0x0001C1A7,
+	.ctrl_ddr_ctrl_ext_0 = 0xA2000000,
+};
+
+const struct ctrl_ioregs ioregs_dra72x_es1 = {
+	.ctrl_ddrch = 0x40404040,
+	.ctrl_lpddr2ch = 0x40404040,
+	.ctrl_ddr3ch = 0x60606080,
+	.ctrl_ddrio_0 = 0x00094A40,
+	.ctrl_ddrio_1 = 0x04A52000,
+	.ctrl_ddrio_2 = 0x84210000,
+	.ctrl_emif_sdram_config_ext = 0x0001C1A7,
+	.ctrl_emif_sdram_config_ext_final = 0x0001C1A7,
+	.ctrl_ddr_ctrl_ext_0 = 0xA2000000,
+};
+
+const struct ctrl_ioregs ioregs_dra72x_es2 = {
+	.ctrl_ddrch = 0x40404040,
+	.ctrl_lpddr2ch = 0x40404040,
+	.ctrl_ddr3ch = 0x60606060,
+	.ctrl_ddrio_0 = 0x00094A40,
+	.ctrl_ddrio_1 = 0x00000000,
+	.ctrl_ddrio_2 = 0x00000000,
+	.ctrl_emif_sdram_config_ext = 0x0001C1A7,
+	.ctrl_emif_sdram_config_ext_final = 0x0001C1A7,
+	.ctrl_ddr_ctrl_ext_0 = 0xA2000000,
+};
+
+void __weak hw_data_init(void)
+{
+	u32 omap_rev = omap_revision();
+
+	switch (omap_rev) {
+
+	case OMAP5430_ES1_0:
+	case OMAP5432_ES1_0:
+	*prcm = &omap5_es1_prcm;
+	*dplls_data = &omap5_dplls_es1;
+	*omap_vcores = &omap5430_volts;
+	*ctrl = &omap5_ctrl;
+	break;
+
+	case OMAP5430_ES2_0:
+	case OMAP5432_ES2_0:
+	*prcm = &omap5_es2_prcm;
+	*dplls_data = &omap5_dplls_es2;
+	*omap_vcores = &omap5430_volts_es2;
+	*ctrl = &omap5_ctrl;
+	break;
+
+	case DRA752_ES1_0:
+	case DRA752_ES1_1:
+	case DRA752_ES2_0:
+	*prcm = &dra7xx_prcm;
+	*dplls_data = &dra7xx_dplls;
+	*ctrl = &dra7xx_ctrl;
+	break;
+
+	case DRA722_ES1_0:
+	case DRA722_ES2_0:
+	*prcm = &dra7xx_prcm;
+	*dplls_data = &dra72x_dplls;
+	*ctrl = &dra7xx_ctrl;
+	break;
+
+	default:
+		printf("\n INVALID OMAP REVISION ");
+	}
+}
+
+void get_ioregs(const struct ctrl_ioregs **regs)
+{
+	u32 omap_rev = omap_revision();
+
+	switch (omap_rev) {
+	case OMAP5430_ES1_0:
+	case OMAP5430_ES2_0:
+		*regs = &ioregs_omap5430;
+		break;
+	case OMAP5432_ES1_0:
+		*regs = &ioregs_omap5432_es1;
+		break;
+	case OMAP5432_ES2_0:
+		*regs = &ioregs_omap5432_es2;
+		break;
+	case DRA752_ES1_0:
+	case DRA752_ES1_1:
+	case DRA752_ES2_0:
+		*regs = &ioregs_dra7xx_es1;
+		break;
+	case DRA722_ES1_0:
+		*regs = &ioregs_dra72x_es1;
+		break;
+	case DRA722_ES2_0:
+		*regs = &ioregs_dra72x_es2;
+		break;
+
+	default:
+		printf("\n INVALID OMAP REVISION ");
+	}
+}
diff --git a/arch/arm/mach-omap2/omap5/hwinit.c b/arch/arm/mach-omap2/omap5/hwinit.c
new file mode 100644
index 0000000..e3ac8bb
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/hwinit.c
@@ -0,0 +1,453 @@
+/*
+ *
+ * Functions for omap5 based boards.
+ *
+ * (C) Copyright 2011
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *	Aneesh V	<aneesh@ti.com>
+ *	Steve Sakoman	<steve@sakoman.com>
+ *	Sricharan	<r.sricharan@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/armv7.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/clock.h>
+#include <linux/sizes.h>
+#include <asm/utils.h>
+#include <asm/arch/gpio.h>
+#include <asm/emif.h>
+#include <asm/omap_common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 *const omap_si_rev = (u32 *)OMAP_SRAM_SCRATCH_OMAP_REV;
+
+#ifndef CONFIG_DM_GPIO
+static struct gpio_bank gpio_bank_54xx[8] = {
+	{ (void *)OMAP54XX_GPIO1_BASE },
+	{ (void *)OMAP54XX_GPIO2_BASE },
+	{ (void *)OMAP54XX_GPIO3_BASE },
+	{ (void *)OMAP54XX_GPIO4_BASE },
+	{ (void *)OMAP54XX_GPIO5_BASE },
+	{ (void *)OMAP54XX_GPIO6_BASE },
+	{ (void *)OMAP54XX_GPIO7_BASE },
+	{ (void *)OMAP54XX_GPIO8_BASE },
+};
+
+const struct gpio_bank *const omap_gpio_bank = gpio_bank_54xx;
+#endif
+
+void do_set_mux32(u32 base, struct pad_conf_entry const *array, int size)
+{
+	int i;
+	struct pad_conf_entry *pad = (struct pad_conf_entry *)array;
+
+	for (i = 0; i < size; i++, pad++)
+		writel(pad->val, base + pad->offset);
+}
+
+#ifdef CONFIG_SPL_BUILD
+/* LPDDR2 specific IO settings */
+static void io_settings_lpddr2(void)
+{
+	const struct ctrl_ioregs *ioregs;
+
+	get_ioregs(&ioregs);
+	writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch1_0);
+	writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch1_1);
+	writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch2_0);
+	writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch2_1);
+	writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_0);
+	writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_1);
+	writel(ioregs->ctrl_ddrio_0, (*ctrl)->control_ddrio_0);
+	writel(ioregs->ctrl_ddrio_1, (*ctrl)->control_ddrio_1);
+	writel(ioregs->ctrl_ddrio_2, (*ctrl)->control_ddrio_2);
+}
+
+/* DDR3 specific IO settings */
+static void io_settings_ddr3(void)
+{
+	u32 io_settings = 0;
+	const struct ctrl_ioregs *ioregs;
+
+	get_ioregs(&ioregs);
+	writel(ioregs->ctrl_ddr3ch, (*ctrl)->control_ddr3ch1_0);
+	writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch1_0);
+	writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch1_1);
+
+	writel(ioregs->ctrl_ddr3ch, (*ctrl)->control_ddr3ch2_0);
+	writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch2_0);
+	writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch2_1);
+
+	writel(ioregs->ctrl_ddrio_0, (*ctrl)->control_ddrio_0);
+	writel(ioregs->ctrl_ddrio_1, (*ctrl)->control_ddrio_1);
+
+	if (!is_dra7xx()) {
+		writel(ioregs->ctrl_ddrio_2, (*ctrl)->control_ddrio_2);
+		writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_1);
+	}
+
+	/* omap5432 does not use lpddr2 */
+	writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_0);
+
+	writel(ioregs->ctrl_emif_sdram_config_ext,
+	       (*ctrl)->control_emif1_sdram_config_ext);
+	if (!is_dra72x())
+		writel(ioregs->ctrl_emif_sdram_config_ext,
+		       (*ctrl)->control_emif2_sdram_config_ext);
+
+	if (is_omap54xx()) {
+		/* Disable DLL select */
+		io_settings = (readl((*ctrl)->control_port_emif1_sdram_config)
+							& 0xFFEFFFFF);
+		writel(io_settings,
+			(*ctrl)->control_port_emif1_sdram_config);
+
+		io_settings = (readl((*ctrl)->control_port_emif2_sdram_config)
+							& 0xFFEFFFFF);
+		writel(io_settings,
+			(*ctrl)->control_port_emif2_sdram_config);
+	} else {
+		writel(ioregs->ctrl_ddr_ctrl_ext_0,
+				(*ctrl)->control_ddr_control_ext_0);
+	}
+}
+
+/*
+ * Some tuning of IOs for optimal power and performance
+ */
+void do_io_settings(void)
+{
+	u32 io_settings = 0, mask = 0;
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
+
+	/* Impedance settings EMMC, C2C 1,2, hsi2 */
+	mask = (ds_mask << 2) | (ds_mask << 8) |
+		(ds_mask << 16) | (ds_mask << 18);
+	io_settings = readl((*ctrl)->control_smart1io_padconf_0) &
+				(~mask);
+	io_settings |= (ds_60_ohm << 8) | (ds_45_ohm << 16) |
+			(ds_45_ohm << 18) | (ds_60_ohm << 2);
+	writel(io_settings, (*ctrl)->control_smart1io_padconf_0);
+
+	/* Impedance settings Mcspi2 */
+	mask = (ds_mask << 30);
+	io_settings = readl((*ctrl)->control_smart1io_padconf_1) &
+			(~mask);
+	io_settings |= (ds_60_ohm << 30);
+	writel(io_settings, (*ctrl)->control_smart1io_padconf_1);
+
+	/* Impedance settings C2C 3,4 */
+	mask = (ds_mask << 14) | (ds_mask << 16);
+	io_settings = readl((*ctrl)->control_smart1io_padconf_2) &
+			(~mask);
+	io_settings |= (ds_45_ohm << 14) | (ds_45_ohm << 16);
+	writel(io_settings, (*ctrl)->control_smart1io_padconf_2);
+
+	/* Slew rate settings EMMC, C2C 1,2 */
+	mask = (sc_mask << 8) | (sc_mask << 16) | (sc_mask << 18);
+	io_settings = readl((*ctrl)->control_smart2io_padconf_0) &
+			(~mask);
+	io_settings |= (sc_fast << 8) | (sc_na << 16) | (sc_na << 18);
+	writel(io_settings, (*ctrl)->control_smart2io_padconf_0);
+
+	/* Slew rate settings hsi2, Mcspi2 */
+	mask = (sc_mask << 24) | (sc_mask << 28);
+	io_settings = readl((*ctrl)->control_smart2io_padconf_1) &
+			(~mask);
+	io_settings |= (sc_fast << 28) | (sc_fast << 24);
+	writel(io_settings, (*ctrl)->control_smart2io_padconf_1);
+
+	/* Slew rate settings C2C 3,4 */
+	mask = (sc_mask << 16) | (sc_mask << 18);
+	io_settings = readl((*ctrl)->control_smart2io_padconf_2) &
+			(~mask);
+	io_settings |= (sc_na << 16) | (sc_na << 18);
+	writel(io_settings, (*ctrl)->control_smart2io_padconf_2);
+
+	/* impedance and slew rate settings for usb */
+	mask = (usb_i_mask << 29) | (usb_i_mask << 26) | (usb_i_mask << 23) |
+		(usb_i_mask << 20) | (usb_i_mask << 17) | (usb_i_mask << 14);
+	io_settings = readl((*ctrl)->control_smart3io_padconf_1) &
+			(~mask);
+	io_settings |= (ds_60_ohm << 29) | (ds_60_ohm << 26) |
+		       (ds_60_ohm << 23) | (sc_fast << 20) |
+		       (sc_fast << 17) | (sc_fast << 14);
+	writel(io_settings, (*ctrl)->control_smart3io_padconf_1);
+
+	if (emif_sdram_type(emif->emif_sdram_config) == EMIF_SDRAM_TYPE_LPDDR2)
+		io_settings_lpddr2();
+	else
+		io_settings_ddr3();
+}
+
+static const struct srcomp_params srcomp_parameters[NUM_SYS_CLKS] = {
+	{0x45, 0x1},	/* 12 MHz   */
+	{-1, -1},	/* 13 MHz   */
+	{0x63, 0x2},	/* 16.8 MHz */
+	{0x57, 0x2},	/* 19.2 MHz */
+	{0x20, 0x1},	/* 26 MHz   */
+	{-1, -1},	/* 27 MHz   */
+	{0x41, 0x3}	/* 38.4 MHz */
+};
+
+void srcomp_enable(void)
+{
+	u32 srcomp_value, mul_factor, div_factor, clk_val, i;
+	u32 sysclk_ind	= get_sys_clk_index();
+	u32 omap_rev	= omap_revision();
+
+	if (!is_omap54xx())
+		return;
+
+	mul_factor = srcomp_parameters[sysclk_ind].multiply_factor;
+	div_factor = srcomp_parameters[sysclk_ind].divide_factor;
+
+	for (i = 0; i < 4; i++) {
+		srcomp_value = readl((*ctrl)->control_srcomp_north_side + i*4);
+		srcomp_value &=
+			~(MULTIPLY_FACTOR_XS_MASK | DIVIDE_FACTOR_XS_MASK);
+		srcomp_value |= (mul_factor << MULTIPLY_FACTOR_XS_SHIFT) |
+			(div_factor << DIVIDE_FACTOR_XS_SHIFT);
+		writel(srcomp_value, (*ctrl)->control_srcomp_north_side + i*4);
+	}
+
+	if ((omap_rev == OMAP5430_ES1_0) || (omap_rev == OMAP5432_ES1_0)) {
+		clk_val = readl((*prcm)->cm_coreaon_io_srcomp_clkctrl);
+		clk_val |= OPTFCLKEN_SRCOMP_FCLK_MASK;
+		writel(clk_val, (*prcm)->cm_coreaon_io_srcomp_clkctrl);
+
+		for (i = 0; i < 4; i++) {
+			srcomp_value =
+				readl((*ctrl)->control_srcomp_north_side + i*4);
+			srcomp_value &= ~PWRDWN_XS_MASK;
+			writel(srcomp_value,
+			       (*ctrl)->control_srcomp_north_side + i*4);
+
+			while (((readl((*ctrl)->control_srcomp_north_side + i*4)
+				& SRCODE_READ_XS_MASK) >>
+				SRCODE_READ_XS_SHIFT) == 0)
+				;
+
+			srcomp_value =
+				readl((*ctrl)->control_srcomp_north_side + i*4);
+			srcomp_value &= ~OVERRIDE_XS_MASK;
+			writel(srcomp_value,
+			       (*ctrl)->control_srcomp_north_side + i*4);
+		}
+	} else {
+		srcomp_value = readl((*ctrl)->control_srcomp_east_side_wkup);
+		srcomp_value &= ~(MULTIPLY_FACTOR_XS_MASK |
+				  DIVIDE_FACTOR_XS_MASK);
+		srcomp_value |= (mul_factor << MULTIPLY_FACTOR_XS_SHIFT) |
+				(div_factor << DIVIDE_FACTOR_XS_SHIFT);
+		writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup);
+
+		for (i = 0; i < 4; i++) {
+			srcomp_value =
+				readl((*ctrl)->control_srcomp_north_side + i*4);
+			srcomp_value |= SRCODE_OVERRIDE_SEL_XS_MASK;
+			writel(srcomp_value,
+			       (*ctrl)->control_srcomp_north_side + i*4);
+
+			srcomp_value =
+				readl((*ctrl)->control_srcomp_north_side + i*4);
+			srcomp_value &= ~OVERRIDE_XS_MASK;
+			writel(srcomp_value,
+			       (*ctrl)->control_srcomp_north_side + i*4);
+		}
+
+		srcomp_value =
+			readl((*ctrl)->control_srcomp_east_side_wkup);
+		srcomp_value |= SRCODE_OVERRIDE_SEL_XS_MASK;
+		writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup);
+
+		srcomp_value =
+			readl((*ctrl)->control_srcomp_east_side_wkup);
+		srcomp_value &= ~OVERRIDE_XS_MASK;
+		writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup);
+
+		clk_val = readl((*prcm)->cm_coreaon_io_srcomp_clkctrl);
+		clk_val |= OPTFCLKEN_SRCOMP_FCLK_MASK;
+		writel(clk_val, (*prcm)->cm_coreaon_io_srcomp_clkctrl);
+
+		clk_val = readl((*prcm)->cm_wkupaon_io_srcomp_clkctrl);
+		clk_val |= OPTFCLKEN_SRCOMP_FCLK_MASK;
+		writel(clk_val, (*prcm)->cm_wkupaon_io_srcomp_clkctrl);
+
+		for (i = 0; i < 4; i++) {
+			while (((readl((*ctrl)->control_srcomp_north_side + i*4)
+				& SRCODE_READ_XS_MASK) >>
+				SRCODE_READ_XS_SHIFT) == 0)
+				;
+
+			srcomp_value =
+				readl((*ctrl)->control_srcomp_north_side + i*4);
+			srcomp_value &= ~SRCODE_OVERRIDE_SEL_XS_MASK;
+			writel(srcomp_value,
+			       (*ctrl)->control_srcomp_north_side + i*4);
+		}
+
+		while (((readl((*ctrl)->control_srcomp_east_side_wkup) &
+			SRCODE_READ_XS_MASK) >> SRCODE_READ_XS_SHIFT) == 0)
+			;
+
+		srcomp_value =
+			readl((*ctrl)->control_srcomp_east_side_wkup);
+		srcomp_value &= ~SRCODE_OVERRIDE_SEL_XS_MASK;
+		writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup);
+	}
+}
+#endif
+
+void config_data_eye_leveling_samples(u32 emif_base)
+{
+	const struct ctrl_ioregs *ioregs;
+
+	get_ioregs(&ioregs);
+
+	/*EMIF_SDRAM_CONFIG_EXT-Read data eye leveling no of samples =4*/
+	if (emif_base == EMIF1_BASE)
+		writel(ioregs->ctrl_emif_sdram_config_ext_final,
+		       (*ctrl)->control_emif1_sdram_config_ext);
+	else if (emif_base == EMIF2_BASE)
+		writel(ioregs->ctrl_emif_sdram_config_ext_final,
+		       (*ctrl)->control_emif2_sdram_config_ext);
+}
+
+void init_cpu_configuration(void)
+{
+	u32 l2actlr;
+
+	asm volatile("mrc p15, 1, %0, c15, c0, 0" : "=r"(l2actlr));
+	/*
+	 * L2ACTLR: Ensure to enable the following:
+	 * 3: Disable clean/evict push to external
+	 * 4: Disable WriteUnique and WriteLineUnique transactions from master
+	 * 8: Disable DVM/CMO message broadcast
+	 */
+	l2actlr |= 0x118;
+	omap_smc1(OMAP5_SERVICE_L2ACTLR_SET, l2actlr);
+}
+
+void init_omap_revision(void)
+{
+	/*
+	 * For some of the ES2/ES1 boards ID_CODE is not reliable:
+	 * Also, ES1 and ES2 have different ARM revisions
+	 * So use ARM revision for identification
+	 */
+	unsigned int rev = cortex_rev();
+
+	switch (readl(CONTROL_ID_CODE)) {
+	case OMAP5430_CONTROL_ID_CODE_ES1_0:
+		*omap_si_rev = OMAP5430_ES1_0;
+		if (rev == MIDR_CORTEX_A15_R2P2)
+			*omap_si_rev = OMAP5430_ES2_0;
+		break;
+	case OMAP5432_CONTROL_ID_CODE_ES1_0:
+		*omap_si_rev = OMAP5432_ES1_0;
+		if (rev == MIDR_CORTEX_A15_R2P2)
+			*omap_si_rev = OMAP5432_ES2_0;
+		break;
+	case OMAP5430_CONTROL_ID_CODE_ES2_0:
+		*omap_si_rev = OMAP5430_ES2_0;
+		break;
+	case OMAP5432_CONTROL_ID_CODE_ES2_0:
+		*omap_si_rev = OMAP5432_ES2_0;
+		break;
+	case DRA752_CONTROL_ID_CODE_ES1_0:
+		*omap_si_rev = DRA752_ES1_0;
+		break;
+	case DRA752_CONTROL_ID_CODE_ES1_1:
+		*omap_si_rev = DRA752_ES1_1;
+		break;
+	case DRA752_CONTROL_ID_CODE_ES2_0:
+		*omap_si_rev = DRA752_ES2_0;
+		break;
+	case DRA722_CONTROL_ID_CODE_ES1_0:
+		*omap_si_rev = DRA722_ES1_0;
+		break;
+	case DRA722_CONTROL_ID_CODE_ES2_0:
+		*omap_si_rev = DRA722_ES2_0;
+		break;
+	default:
+		*omap_si_rev = OMAP5430_SILICON_ID_INVALID;
+	}
+	init_cpu_configuration();
+}
+
+void omap_die_id(unsigned int *die_id)
+{
+	die_id[0] = readl((*ctrl)->control_std_fuse_die_id_0);
+	die_id[1] = readl((*ctrl)->control_std_fuse_die_id_1);
+	die_id[2] = readl((*ctrl)->control_std_fuse_die_id_2);
+	die_id[3] = readl((*ctrl)->control_std_fuse_die_id_3);
+}
+
+void reset_cpu(ulong ignored)
+{
+	u32 omap_rev = omap_revision();
+
+	/*
+	 * WARM reset is not functional in case of OMAP5430 ES1.0 soc.
+	 * So use cold reset in case instead.
+	 */
+	if (omap_rev == OMAP5430_ES1_0)
+		writel(PRM_RSTCTRL_RESET << 0x1, (*prcm)->prm_rstctrl);
+	else
+		writel(PRM_RSTCTRL_RESET, (*prcm)->prm_rstctrl);
+}
+
+u32 warm_reset(void)
+{
+	return readl((*prcm)->prm_rstst) & PRM_RSTST_WARM_RESET_MASK;
+}
+
+void setup_warmreset_time(void)
+{
+	u32 rst_time, rst_val;
+
+#ifndef CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC
+	rst_time = CONFIG_DEFAULT_OMAP_RESET_TIME_MAX_USEC;
+#else
+	rst_time = CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC;
+#endif
+	rst_time = usec_to_32k(rst_time) << RSTTIME1_SHIFT;
+
+	if (rst_time > RSTTIME1_MASK)
+		rst_time = RSTTIME1_MASK;
+
+	rst_val = readl((*prcm)->prm_rsttime) & ~RSTTIME1_MASK;
+	rst_val |= rst_time;
+	writel(rst_val, (*prcm)->prm_rsttime);
+}
+
+void v7_arch_cp15_set_l2aux_ctrl(u32 l2auxctrl, u32 cpu_midr,
+				 u32 cpu_rev_comb, u32 cpu_variant,
+				 u32 cpu_rev)
+{
+	omap_smc1(OMAP5_SERVICE_L2ACTLR_SET, l2auxctrl);
+}
+
+void v7_arch_cp15_set_acr(u32 acr, u32 cpu_midr, u32 cpu_rev_comb,
+			  u32 cpu_variant, u32 cpu_rev)
+{
+
+#ifdef CONFIG_ARM_ERRATA_801819
+	/*
+	 * DRA72x processors are uniprocessors and DONOT have
+	 * ACP (Accelerator Coherency Port) hooked to ACE (AXI Coherency
+	 * Extensions) Hence the erratum workaround is not applicable for
+	 * DRA72x processors.
+	 */
+	if (is_dra72x())
+		acr &= ~((0x3 << 23) | (0x3 << 25));
+#endif
+	omap_smc1(OMAP5_SERVICE_ACR_SET, acr);
+}
diff --git a/arch/arm/mach-omap2/omap5/prcm-regs.c b/arch/arm/mach-omap2/omap5/prcm-regs.c
new file mode 100644
index 0000000..b5f1d70
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/prcm-regs.c
@@ -0,0 +1,1024 @@
+/*
+ *
+ * HW regs data for OMAP5 Soc
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * Sricharan R <r.sricharan@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/omap_common.h>
+#include <asm/io.h>
+
+struct prcm_regs const omap5_es1_prcm = {
+	/* cm1.ckgen */
+	.cm_clksel_core = 0x4a004100,
+	.cm_clksel_abe = 0x4a004108,
+	.cm_dll_ctrl = 0x4a004110,
+	.cm_clkmode_dpll_core = 0x4a004120,
+	.cm_idlest_dpll_core = 0x4a004124,
+	.cm_autoidle_dpll_core = 0x4a004128,
+	.cm_clksel_dpll_core = 0x4a00412c,
+	.cm_div_m2_dpll_core = 0x4a004130,
+	.cm_div_m3_dpll_core = 0x4a004134,
+	.cm_div_h11_dpll_core = 0x4a004138,
+	.cm_div_h12_dpll_core = 0x4a00413c,
+	.cm_div_h13_dpll_core = 0x4a004140,
+	.cm_div_h14_dpll_core = 0x4a004144,
+	.cm_ssc_deltamstep_dpll_core = 0x4a004148,
+	.cm_ssc_modfreqdiv_dpll_core = 0x4a00414c,
+	.cm_emu_override_dpll_core = 0x4a004150,
+	.cm_div_h22_dpllcore = 0x4a004154,
+	.cm_div_h23_dpll_core = 0x4a004158,
+	.cm_clkmode_dpll_mpu = 0x4a004160,
+	.cm_idlest_dpll_mpu = 0x4a004164,
+	.cm_autoidle_dpll_mpu = 0x4a004168,
+	.cm_clksel_dpll_mpu = 0x4a00416c,
+	.cm_div_m2_dpll_mpu = 0x4a004170,
+	.cm_ssc_deltamstep_dpll_mpu = 0x4a004188,
+	.cm_ssc_modfreqdiv_dpll_mpu = 0x4a00418c,
+	.cm_bypclk_dpll_mpu = 0x4a00419c,
+	.cm_clkmode_dpll_iva = 0x4a0041a0,
+	.cm_idlest_dpll_iva = 0x4a0041a4,
+	.cm_autoidle_dpll_iva = 0x4a0041a8,
+	.cm_clksel_dpll_iva = 0x4a0041ac,
+	.cm_div_h11_dpll_iva = 0x4a0041b8,
+	.cm_div_h12_dpll_iva = 0x4a0041bc,
+	.cm_ssc_deltamstep_dpll_iva = 0x4a0041c8,
+	.cm_ssc_modfreqdiv_dpll_iva = 0x4a0041cc,
+	.cm_bypclk_dpll_iva = 0x4a0041dc,
+	.cm_clkmode_dpll_abe = 0x4a0041e0,
+	.cm_idlest_dpll_abe = 0x4a0041e4,
+	.cm_autoidle_dpll_abe = 0x4a0041e8,
+	.cm_clksel_dpll_abe = 0x4a0041ec,
+	.cm_div_m2_dpll_abe = 0x4a0041f0,
+	.cm_div_m3_dpll_abe = 0x4a0041f4,
+	.cm_ssc_deltamstep_dpll_abe = 0x4a004208,
+	.cm_ssc_modfreqdiv_dpll_abe = 0x4a00420c,
+	.cm_clkmode_dpll_ddrphy = 0x4a004220,
+	.cm_idlest_dpll_ddrphy = 0x4a004224,
+	.cm_autoidle_dpll_ddrphy = 0x4a004228,
+	.cm_clksel_dpll_ddrphy = 0x4a00422c,
+	.cm_div_m2_dpll_ddrphy = 0x4a004230,
+	.cm_div_h11_dpll_ddrphy = 0x4a004238,
+	.cm_div_h12_dpll_ddrphy = 0x4a00423c,
+	.cm_div_h13_dpll_ddrphy = 0x4a004240,
+	.cm_ssc_deltamstep_dpll_ddrphy = 0x4a004248,
+	.cm_shadow_freq_config1 = 0x4a004260,
+	.cm_mpu_mpu_clkctrl = 0x4a004320,
+
+	/* cm1.dsp */
+	.cm_dsp_clkstctrl = 0x4a004400,
+	.cm_dsp_dsp_clkctrl = 0x4a004420,
+
+	/* cm1.abe */
+	.cm1_abe_clkstctrl = 0x4a004500,
+	.cm1_abe_l4abe_clkctrl = 0x4a004520,
+	.cm1_abe_aess_clkctrl = 0x4a004528,
+	.cm1_abe_pdm_clkctrl = 0x4a004530,
+	.cm1_abe_dmic_clkctrl = 0x4a004538,
+	.cm1_abe_mcasp_clkctrl = 0x4a004540,
+	.cm1_abe_mcbsp1_clkctrl = 0x4a004548,
+	.cm1_abe_mcbsp2_clkctrl = 0x4a004550,
+	.cm1_abe_mcbsp3_clkctrl = 0x4a004558,
+	.cm1_abe_slimbus_clkctrl = 0x4a004560,
+	.cm1_abe_timer5_clkctrl = 0x4a004568,
+	.cm1_abe_timer6_clkctrl = 0x4a004570,
+	.cm1_abe_timer7_clkctrl = 0x4a004578,
+	.cm1_abe_timer8_clkctrl = 0x4a004580,
+	.cm1_abe_wdt3_clkctrl = 0x4a004588,
+
+	/* cm2.ckgen */
+	.cm_clksel_mpu_m3_iss_root = 0x4a008100,
+	.cm_clksel_usb_60mhz = 0x4a008104,
+	.cm_scale_fclk = 0x4a008108,
+	.cm_core_dvfs_perf1 = 0x4a008110,
+	.cm_core_dvfs_perf2 = 0x4a008114,
+	.cm_core_dvfs_perf3 = 0x4a008118,
+	.cm_core_dvfs_perf4 = 0x4a00811c,
+	.cm_core_dvfs_current = 0x4a008124,
+	.cm_iva_dvfs_perf_tesla = 0x4a008128,
+	.cm_iva_dvfs_perf_ivahd = 0x4a00812c,
+	.cm_iva_dvfs_perf_abe = 0x4a008130,
+	.cm_iva_dvfs_current = 0x4a008138,
+	.cm_clkmode_dpll_per = 0x4a008140,
+	.cm_idlest_dpll_per = 0x4a008144,
+	.cm_autoidle_dpll_per = 0x4a008148,
+	.cm_clksel_dpll_per = 0x4a00814c,
+	.cm_div_m2_dpll_per = 0x4a008150,
+	.cm_div_m3_dpll_per = 0x4a008154,
+	.cm_div_h11_dpll_per = 0x4a008158,
+	.cm_div_h12_dpll_per = 0x4a00815c,
+	.cm_div_h14_dpll_per = 0x4a008164,
+	.cm_ssc_deltamstep_dpll_per = 0x4a008168,
+	.cm_ssc_modfreqdiv_dpll_per = 0x4a00816c,
+	.cm_emu_override_dpll_per = 0x4a008170,
+	.cm_clkmode_dpll_usb = 0x4a008180,
+	.cm_idlest_dpll_usb = 0x4a008184,
+	.cm_autoidle_dpll_usb = 0x4a008188,
+	.cm_clksel_dpll_usb = 0x4a00818c,
+	.cm_div_m2_dpll_usb = 0x4a008190,
+	.cm_ssc_deltamstep_dpll_usb = 0x4a0081a8,
+	.cm_ssc_modfreqdiv_dpll_usb = 0x4a0081ac,
+	.cm_clkdcoldo_dpll_usb = 0x4a0081b4,
+	.cm_clkmode_dpll_unipro = 0x4a0081c0,
+	.cm_idlest_dpll_unipro = 0x4a0081c4,
+	.cm_autoidle_dpll_unipro = 0x4a0081c8,
+	.cm_clksel_dpll_unipro = 0x4a0081cc,
+	.cm_div_m2_dpll_unipro = 0x4a0081d0,
+	.cm_ssc_deltamstep_dpll_unipro = 0x4a0081e8,
+	.cm_ssc_modfreqdiv_dpll_unipro = 0x4a0081ec,
+
+	/* cm2.core */
+	.cm_coreaon_bandgap_clkctrl = 0x4a008648,
+	.cm_coreaon_io_srcomp_clkctrl = 0x4a008650,
+	.cm_l3_1_clkstctrl = 0x4a008700,
+	.cm_l3_1_dynamicdep = 0x4a008708,
+	.cm_l3_1_l3_1_clkctrl = 0x4a008720,
+	.cm_l3_2_clkstctrl = 0x4a008800,
+	.cm_l3_2_dynamicdep = 0x4a008808,
+	.cm_l3_2_l3_2_clkctrl = 0x4a008820,
+	.cm_l3_gpmc_clkctrl = 0x4a008828,
+	.cm_l3_2_ocmc_ram_clkctrl = 0x4a008830,
+	.cm_mpu_m3_clkstctrl = 0x4a008900,
+	.cm_mpu_m3_staticdep = 0x4a008904,
+	.cm_mpu_m3_dynamicdep = 0x4a008908,
+	.cm_mpu_m3_mpu_m3_clkctrl = 0x4a008920,
+	.cm_sdma_clkstctrl = 0x4a008a00,
+	.cm_sdma_staticdep = 0x4a008a04,
+	.cm_sdma_dynamicdep = 0x4a008a08,
+	.cm_sdma_sdma_clkctrl = 0x4a008a20,
+	.cm_memif_clkstctrl = 0x4a008b00,
+	.cm_memif_dmm_clkctrl = 0x4a008b20,
+	.cm_memif_emif_fw_clkctrl = 0x4a008b28,
+	.cm_memif_emif_1_clkctrl = 0x4a008b30,
+	.cm_memif_emif_2_clkctrl = 0x4a008b38,
+	.cm_memif_dll_clkctrl = 0x4a008b40,
+	.cm_memif_emif_h1_clkctrl = 0x4a008b50,
+	.cm_memif_emif_h2_clkctrl = 0x4a008b58,
+	.cm_memif_dll_h_clkctrl = 0x4a008b60,
+	.cm_c2c_clkstctrl = 0x4a008c00,
+	.cm_c2c_staticdep = 0x4a008c04,
+	.cm_c2c_dynamicdep = 0x4a008c08,
+	.cm_c2c_sad2d_clkctrl = 0x4a008c20,
+	.cm_c2c_modem_icr_clkctrl = 0x4a008c28,
+	.cm_c2c_sad2d_fw_clkctrl = 0x4a008c30,
+	.cm_l4cfg_clkstctrl = 0x4a008d00,
+	.cm_l4cfg_dynamicdep = 0x4a008d08,
+	.cm_l4cfg_l4_cfg_clkctrl = 0x4a008d20,
+	.cm_l4cfg_hw_sem_clkctrl = 0x4a008d28,
+	.cm_l4cfg_mailbox_clkctrl = 0x4a008d30,
+	.cm_l4cfg_sar_rom_clkctrl = 0x4a008d38,
+	.cm_l3instr_clkstctrl = 0x4a008e00,
+	.cm_l3instr_l3_3_clkctrl = 0x4a008e20,
+	.cm_l3instr_l3_instr_clkctrl = 0x4a008e28,
+	.cm_l3instr_intrconn_wp1_clkctrl = 0x4a008e40,
+
+	/* cm2.ivahd */
+	.cm_ivahd_clkstctrl = 0x4a008f00,
+	.cm_ivahd_ivahd_clkctrl = 0x4a008f20,
+	.cm_ivahd_sl2_clkctrl = 0x4a008f28,
+
+	/* cm2.cam */
+	.cm_cam_clkstctrl = 0x4a009000,
+	.cm_cam_iss_clkctrl = 0x4a009020,
+	.cm_cam_fdif_clkctrl = 0x4a009028,
+
+	/* cm2.dss */
+	.cm_dss_clkstctrl = 0x4a009100,
+	.cm_dss_dss_clkctrl = 0x4a009120,
+
+	/* cm2.sgx */
+	.cm_sgx_clkstctrl = 0x4a009200,
+	.cm_sgx_sgx_clkctrl = 0x4a009220,
+
+	/* cm2.l3init */
+	.cm_l3init_clkstctrl = 0x4a009300,
+	.cm_l3init_hsmmc1_clkctrl = 0x4a009328,
+	.cm_l3init_hsmmc2_clkctrl = 0x4a009330,
+	.cm_l3init_hsi_clkctrl = 0x4a009338,
+	.cm_l3init_hsusbhost_clkctrl = 0x4a009358,
+	.cm_l3init_hsusbotg_clkctrl = 0x4a009360,
+	.cm_l3init_hsusbtll_clkctrl = 0x4a009368,
+	.cm_l3init_p1500_clkctrl = 0x4a009378,
+	.cm_l3init_sata_clkctrl = 0x4a009388,
+	.cm_l3init_fsusb_clkctrl = 0x4a0093d0,
+	.cm_l3init_ocp2scp1_clkctrl = 0x4a0093e0,
+	.cm_l3init_ocp2scp3_clkctrl = 0x4a0093e8,
+
+	/* cm2.l4per */
+	.cm_l4per_clkstctrl = 0x4a009400,
+	.cm_l4per_dynamicdep = 0x4a009408,
+	.cm_l4per_adc_clkctrl = 0x4a009420,
+	.cm_l4per_gptimer10_clkctrl = 0x4a009428,
+	.cm_l4per_gptimer11_clkctrl = 0x4a009430,
+	.cm_l4per_gptimer2_clkctrl = 0x4a009438,
+	.cm_l4per_gptimer3_clkctrl = 0x4a009440,
+	.cm_l4per_gptimer4_clkctrl = 0x4a009448,
+	.cm_l4per_gptimer9_clkctrl = 0x4a009450,
+	.cm_l4per_elm_clkctrl = 0x4a009458,
+	.cm_l4per_gpio2_clkctrl = 0x4a009460,
+	.cm_l4per_gpio3_clkctrl = 0x4a009468,
+	.cm_l4per_gpio4_clkctrl = 0x4a009470,
+	.cm_l4per_gpio5_clkctrl = 0x4a009478,
+	.cm_l4per_gpio6_clkctrl = 0x4a009480,
+	.cm_l4per_hdq1w_clkctrl = 0x4a009488,
+	.cm_l4per_hecc1_clkctrl = 0x4a009490,
+	.cm_l4per_hecc2_clkctrl = 0x4a009498,
+	.cm_l4per_i2c1_clkctrl = 0x4a0094a0,
+	.cm_l4per_i2c2_clkctrl = 0x4a0094a8,
+	.cm_l4per_i2c3_clkctrl = 0x4a0094b0,
+	.cm_l4per_i2c4_clkctrl = 0x4a0094b8,
+	.cm_l4per_l4per_clkctrl = 0x4a0094c0,
+	.cm_l4per_mcasp2_clkctrl = 0x4a0094d0,
+	.cm_l4per_mcasp3_clkctrl = 0x4a0094d8,
+	.cm_l4per_mgate_clkctrl = 0x4a0094e8,
+	.cm_l4per_mcspi1_clkctrl = 0x4a0094f0,
+	.cm_l4per_mcspi2_clkctrl = 0x4a0094f8,
+	.cm_l4per_mcspi3_clkctrl = 0x4a009500,
+	.cm_l4per_mcspi4_clkctrl = 0x4a009508,
+	.cm_l4per_gpio7_clkctrl = 0x4a009510,
+	.cm_l4per_gpio8_clkctrl = 0x4a009518,
+	.cm_l4per_mmcsd3_clkctrl = 0x4a009520,
+	.cm_l4per_mmcsd4_clkctrl = 0x4a009528,
+	.cm_l4per_msprohg_clkctrl = 0x4a009530,
+	.cm_l4per_slimbus2_clkctrl = 0x4a009538,
+	.cm_l4per_uart1_clkctrl = 0x4a009540,
+	.cm_l4per_uart2_clkctrl = 0x4a009548,
+	.cm_l4per_uart3_clkctrl = 0x4a009550,
+	.cm_l4per_uart4_clkctrl = 0x4a009558,
+	.cm_l4per_mmcsd5_clkctrl = 0x4a009560,
+	.cm_l4per_i2c5_clkctrl = 0x4a009568,
+	.cm_l4per_uart5_clkctrl = 0x4a009570,
+	.cm_l4per_uart6_clkctrl = 0x4a009578,
+	.cm_l4sec_clkstctrl = 0x4a009580,
+	.cm_l4sec_staticdep = 0x4a009584,
+	.cm_l4sec_dynamicdep = 0x4a009588,
+	.cm_l4sec_aes1_clkctrl = 0x4a0095a0,
+	.cm_l4sec_aes2_clkctrl = 0x4a0095a8,
+	.cm_l4sec_des3des_clkctrl = 0x4a0095b0,
+	.cm_l4sec_pkaeip29_clkctrl = 0x4a0095b8,
+	.cm_l4sec_rng_clkctrl = 0x4a0095c0,
+	.cm_l4sec_sha2md51_clkctrl = 0x4a0095c8,
+	.cm_l4sec_cryptodma_clkctrl = 0x4a0095d8,
+
+	/* l4 wkup regs */
+	.cm_abe_pll_ref_clksel = 0x4ae0610c,
+	.cm_sys_clksel = 0x4ae06110,
+	.cm_wkup_clkstctrl = 0x4ae07800,
+	.cm_wkup_l4wkup_clkctrl = 0x4ae07820,
+	.cm_wkup_wdtimer1_clkctrl = 0x4ae07828,
+	.cm_wkup_wdtimer2_clkctrl = 0x4ae07830,
+	.cm_wkup_gpio1_clkctrl = 0x4ae07838,
+	.cm_wkup_gptimer1_clkctrl = 0x4ae07840,
+	.cm_wkup_gptimer12_clkctrl = 0x4ae07848,
+	.cm_wkup_synctimer_clkctrl = 0x4ae07850,
+	.cm_wkup_usim_clkctrl = 0x4ae07858,
+	.cm_wkup_sarram_clkctrl = 0x4ae07860,
+	.cm_wkup_keyboard_clkctrl = 0x4ae07878,
+	.cm_wkup_rtc_clkctrl = 0x4ae07880,
+	.cm_wkup_bandgap_clkctrl = 0x4ae07888,
+	.cm_wkupaon_scrm_clkctrl = 0x4ae07890,
+	.cm_wkupaon_io_srcomp_clkctrl = 0x4ae07898,
+	.prm_rstctrl = 0x4ae07b00,
+	.prm_rstst = 0x4ae07b04,
+	.prm_rsttime = 0x4ae07b08,
+	.prm_vc_val_bypass = 0x4ae07ba0,
+	.prm_vc_cfg_i2c_mode = 0x4ae07bb4,
+	.prm_vc_cfg_i2c_clk = 0x4ae07bb8,
+
+	/* SCRM stuff, used by some boards */
+	.scrm_auxclk0 = 0x4ae0a310,
+	.scrm_auxclk1 = 0x4ae0a314,
+};
+
+struct omap_sys_ctrl_regs const omap5_ctrl = {
+	.control_status				= 0x4A002134,
+	.control_std_fuse_die_id_0		= 0x4A002200,
+	.control_std_fuse_die_id_1		= 0x4A002208,
+	.control_std_fuse_die_id_2		= 0x4A00220C,
+	.control_std_fuse_die_id_3		= 0x4A002210,
+	.control_phy_power_usb 			= 0x4A002370,
+	.control_phy_power_sata			= 0x4A002374,
+	.control_padconf_core_base		= 0x4A002800,
+	.control_paconf_global			= 0x4A002DA0,
+	.control_paconf_mode			= 0x4A002DA4,
+	.control_smart1io_padconf_0		= 0x4A002DA8,
+	.control_smart1io_padconf_1		= 0x4A002DAC,
+	.control_smart1io_padconf_2		= 0x4A002DB0,
+	.control_smart2io_padconf_0		= 0x4A002DB4,
+	.control_smart2io_padconf_1		= 0x4A002DB8,
+	.control_smart2io_padconf_2		= 0x4A002DBC,
+	.control_smart3io_padconf_0		= 0x4A002DC0,
+	.control_smart3io_padconf_1		= 0x4A002DC4,
+	.control_pbias				= 0x4A002E00,
+	.control_i2c_0				= 0x4A002E04,
+	.control_camera_rx			= 0x4A002E08,
+	.control_hdmi_tx_phy			= 0x4A002E0C,
+	.control_uniportm			= 0x4A002E10,
+	.control_dsiphy				= 0x4A002E14,
+	.control_mcbsplp			= 0x4A002E18,
+	.control_usb2phycore			= 0x4A002E1C,
+	.control_hdmi_1				= 0x4A002E20,
+	.control_hsi				= 0x4A002E24,
+	.control_ddr3ch1_0			= 0x4A002E30,
+	.control_ddr3ch2_0			= 0x4A002E34,
+	.control_ddrch1_0			= 0x4A002E38,
+	.control_ddrch1_1			= 0x4A002E3C,
+	.control_ddrch2_0			= 0x4A002E40,
+	.control_ddrch2_1			= 0x4A002E44,
+	.control_lpddr2ch1_0			= 0x4A002E48,
+	.control_lpddr2ch1_1			= 0x4A002E4C,
+	.control_ddrio_0			= 0x4A002E50,
+	.control_ddrio_1			= 0x4A002E54,
+	.control_ddrio_2			= 0x4A002E58,
+	.control_hyst_1				= 0x4A002E5C,
+	.control_usbb_hsic_control		= 0x4A002E60,
+	.control_c2c				= 0x4A002E64,
+	.control_core_control_spare_rw		= 0x4A002E68,
+	.control_core_control_spare_r		= 0x4A002E6C,
+	.control_core_control_spare_r_c0	= 0x4A002E70,
+	.control_srcomp_north_side		= 0x4A002E74,
+	.control_srcomp_south_side		= 0x4A002E78,
+	.control_srcomp_east_side		= 0x4A002E7C,
+	.control_srcomp_west_side		= 0x4A002E80,
+	.control_srcomp_code_latch		= 0x4A002E84,
+	.control_port_emif1_sdram_config	= 0x4AE0C110,
+	.control_port_emif1_lpddr2_nvm_config	= 0x4AE0C114,
+	.control_port_emif2_sdram_config	= 0x4AE0C118,
+	.control_emif1_sdram_config_ext		= 0x4AE0C144,
+	.control_emif2_sdram_config_ext		= 0x4AE0C148,
+	.control_wkup_ldovbb_mpu_voltage_ctrl	= 0x4AE0C318,
+	.control_wkup_ldovbb_mm_voltage_ctrl	= 0x4AE0C314,
+	.control_padconf_wkup_base		= 0x4AE0C800,
+	.control_smart1nopmio_padconf_0		= 0x4AE0CDA0,
+	.control_smart1nopmio_padconf_1		= 0x4AE0CDA4,
+	.control_padconf_mode			= 0x4AE0CDA8,
+	.control_xtal_oscillator		= 0x4AE0CDAC,
+	.control_i2c_2				= 0x4AE0CDB0,
+	.control_ckobuffer			= 0x4AE0CDB4,
+	.control_wkup_control_spare_rw		= 0x4AE0CDB8,
+	.control_wkup_control_spare_r		= 0x4AE0CDBC,
+	.control_wkup_control_spare_r_c0	= 0x4AE0CDC0,
+	.control_srcomp_east_side_wkup		= 0x4AE0CDC4,
+	.control_efuse_1			= 0x4AE0CDC8,
+	.control_efuse_2			= 0x4AE0CDCC,
+	.control_efuse_3			= 0x4AE0CDD0,
+	.control_efuse_4			= 0x4AE0CDD4,
+	.control_efuse_5			= 0x4AE0CDD8,
+	.control_efuse_6			= 0x4AE0CDDC,
+	.control_efuse_7			= 0x4AE0CDE0,
+	.control_efuse_8			= 0x4AE0CDE4,
+	.control_efuse_9			= 0x4AE0CDE8,
+	.control_efuse_10			= 0x4AE0CDEC,
+	.control_efuse_11			= 0x4AE0CDF0,
+	.control_efuse_12			= 0x4AE0CDF4,
+	.control_efuse_13			= 0x4AE0CDF8,
+};
+
+struct omap_sys_ctrl_regs const dra7xx_ctrl = {
+	.control_status				= 0x4A002134,
+	.control_phy_power_usb			= 0x4A002370,
+	.control_phy_power_sata			= 0x4A002374,
+	.ctrl_core_sma_sw_0			= 0x4A0023FC,
+	.ctrl_core_sma_sw_1			= 0x4A002534,
+	.control_core_mac_id_0_lo		= 0x4A002514,
+	.control_core_mac_id_0_hi		= 0x4A002518,
+	.control_core_mac_id_1_lo		= 0x4A00251C,
+	.control_core_mac_id_1_hi		= 0x4A002520,
+	.control_core_mmr_lock1			= 0x4A002540,
+	.control_core_mmr_lock2			= 0x4A002544,
+	.control_core_mmr_lock3			= 0x4A002548,
+	.control_core_mmr_lock4			= 0x4A00254C,
+	.control_core_mmr_lock5			= 0x4A002550,
+	.control_core_control_io1		= 0x4A002554,
+	.control_core_control_io2		= 0x4A002558,
+	.control_paconf_global			= 0x4A002DA0,
+	.control_paconf_mode			= 0x4A002DA4,
+	.control_smart1io_padconf_0		= 0x4A002DA8,
+	.control_smart1io_padconf_1		= 0x4A002DAC,
+	.control_smart1io_padconf_2		= 0x4A002DB0,
+	.control_smart2io_padconf_0		= 0x4A002DB4,
+	.control_smart2io_padconf_1		= 0x4A002DB8,
+	.control_smart2io_padconf_2		= 0x4A002DBC,
+	.control_smart3io_padconf_0		= 0x4A002DC0,
+	.control_smart3io_padconf_1		= 0x4A002DC4,
+	.control_pbias				= 0x4A002E00,
+	.control_i2c_0				= 0x4A002E04,
+	.control_camera_rx			= 0x4A002E08,
+	.control_hdmi_tx_phy			= 0x4A002E0C,
+	.control_uniportm			= 0x4A002E10,
+	.control_dsiphy				= 0x4A002E14,
+	.control_mcbsplp			= 0x4A002E18,
+	.control_usb2phycore			= 0x4A002E1C,
+	.control_hdmi_1				= 0x4A002E20,
+	.control_hsi				= 0x4A002E24,
+	.control_ddr3ch1_0			= 0x4A002E30,
+	.control_ddr3ch2_0			= 0x4A002E34,
+	.control_ddrch1_0			= 0x4A002E38,
+	.control_ddrch1_1			= 0x4A002E3C,
+	.control_ddrch2_0			= 0x4A002E40,
+	.control_ddrch2_1			= 0x4A002E44,
+	.control_lpddr2ch1_0			= 0x4A002E48,
+	.control_lpddr2ch1_1			= 0x4A002E4C,
+	.control_ddrio_0			= 0x4A002E50,
+	.control_ddrio_1			= 0x4A002E54,
+	.control_ddrio_2			= 0x4A002E58,
+	.control_hyst_1				= 0x4A002E5C,
+	.control_usbb_hsic_control		= 0x4A002E60,
+	.control_c2c				= 0x4A002E64,
+	.control_core_control_spare_rw		= 0x4A002E68,
+	.control_core_control_spare_r		= 0x4A002E6C,
+	.control_core_control_spare_r_c0	= 0x4A002E70,
+	.control_srcomp_north_side		= 0x4A002E74,
+	.control_srcomp_south_side		= 0x4A002E78,
+	.control_srcomp_east_side		= 0x4A002E7C,
+	.control_srcomp_west_side		= 0x4A002E80,
+	.control_srcomp_code_latch		= 0x4A002E84,
+	.control_ddr_control_ext_0		= 0x4A002E88,
+	.control_padconf_core_base		= 0x4A003400,
+	.control_port_emif1_sdram_config	= 0x4AE0C110,
+	.control_port_emif1_lpddr2_nvm_config	= 0x4AE0C114,
+	.control_port_emif2_sdram_config	= 0x4AE0C118,
+	.control_emif1_sdram_config_ext		= 0x4AE0C144,
+	.control_emif2_sdram_config_ext		= 0x4AE0C148,
+	.control_wkup_ldovbb_mpu_voltage_ctrl	= 0x4AE0C158,
+	.control_wkup_ldovbb_iva_voltage_ctrl	= 0x4A002470,
+	.control_wkup_ldovbb_eve_voltage_ctrl	= 0x4A00246C,
+	.control_wkup_ldovbb_gpu_voltage_ctrl	= 0x4AE0C154,
+	.control_std_fuse_die_id_0		= 0x4AE0C200,
+	.control_std_fuse_die_id_1		= 0x4AE0C208,
+	.control_std_fuse_die_id_2		= 0x4AE0C20C,
+	.control_std_fuse_die_id_3		= 0x4AE0C210,
+	.control_padconf_mode			= 0x4AE0C5A0,
+	.control_xtal_oscillator		= 0x4AE0C5A4,
+	.control_i2c_2				= 0x4AE0C5A8,
+	.control_ckobuffer			= 0x4AE0C5AC,
+	.control_wkup_control_spare_rw		= 0x4AE0C5B0,
+	.control_wkup_control_spare_r		= 0x4AE0C5B4,
+	.control_wkup_control_spare_r_c0	= 0x4AE0C5B8,
+	.control_srcomp_east_side_wkup		= 0x4AE0C5BC,
+	.control_efuse_1			= 0x4AE0C5C8,
+	.control_efuse_2			= 0x4AE0C5CC,
+	.control_efuse_3			= 0x4AE0C5D0,
+	.control_efuse_4			= 0x4AE0C5D4,
+	.control_efuse_13			= 0x4AE0C5F0,
+	.iodelay_config_base			= 0x4844A000,
+};
+
+struct prcm_regs const omap5_es2_prcm = {
+	/* cm1.ckgen */
+	.cm_clksel_core = 0x4a004100,
+	.cm_clksel_abe = 0x4a004108,
+	.cm_dll_ctrl = 0x4a004110,
+	.cm_clkmode_dpll_core = 0x4a004120,
+	.cm_idlest_dpll_core = 0x4a004124,
+	.cm_autoidle_dpll_core = 0x4a004128,
+	.cm_clksel_dpll_core = 0x4a00412c,
+	.cm_div_m2_dpll_core = 0x4a004130,
+	.cm_div_m3_dpll_core = 0x4a004134,
+	.cm_div_h11_dpll_core = 0x4a004138,
+	.cm_div_h12_dpll_core = 0x4a00413c,
+	.cm_div_h13_dpll_core = 0x4a004140,
+	.cm_div_h14_dpll_core = 0x4a004144,
+	.cm_ssc_deltamstep_dpll_core = 0x4a004148,
+	.cm_ssc_modfreqdiv_dpll_core = 0x4a00414c,
+	.cm_div_h21_dpll_core = 0x4a004150,
+	.cm_div_h22_dpllcore = 0x4a004154,
+	.cm_div_h23_dpll_core = 0x4a004158,
+	.cm_div_h24_dpll_core = 0x4a00415c,
+	.cm_clkmode_dpll_mpu = 0x4a004160,
+	.cm_idlest_dpll_mpu = 0x4a004164,
+	.cm_autoidle_dpll_mpu = 0x4a004168,
+	.cm_clksel_dpll_mpu = 0x4a00416c,
+	.cm_div_m2_dpll_mpu = 0x4a004170,
+	.cm_ssc_deltamstep_dpll_mpu = 0x4a004188,
+	.cm_ssc_modfreqdiv_dpll_mpu = 0x4a00418c,
+	.cm_bypclk_dpll_mpu = 0x4a00419c,
+	.cm_clkmode_dpll_iva = 0x4a0041a0,
+	.cm_idlest_dpll_iva = 0x4a0041a4,
+	.cm_autoidle_dpll_iva = 0x4a0041a8,
+	.cm_clksel_dpll_iva = 0x4a0041ac,
+	.cm_div_h11_dpll_iva = 0x4a0041b8,
+	.cm_div_h12_dpll_iva = 0x4a0041bc,
+	.cm_ssc_deltamstep_dpll_iva = 0x4a0041c8,
+	.cm_ssc_modfreqdiv_dpll_iva = 0x4a0041cc,
+	.cm_bypclk_dpll_iva = 0x4a0041dc,
+	.cm_clkmode_dpll_abe = 0x4a0041e0,
+	.cm_idlest_dpll_abe = 0x4a0041e4,
+	.cm_autoidle_dpll_abe = 0x4a0041e8,
+	.cm_clksel_dpll_abe = 0x4a0041ec,
+	.cm_div_m2_dpll_abe = 0x4a0041f0,
+	.cm_div_m3_dpll_abe = 0x4a0041f4,
+	.cm_ssc_deltamstep_dpll_abe = 0x4a004208,
+	.cm_ssc_modfreqdiv_dpll_abe = 0x4a00420c,
+	.cm_clkmode_dpll_ddrphy = 0x4a004220,
+	.cm_idlest_dpll_ddrphy = 0x4a004224,
+	.cm_autoidle_dpll_ddrphy = 0x4a004228,
+	.cm_clksel_dpll_ddrphy = 0x4a00422c,
+	.cm_div_m2_dpll_ddrphy = 0x4a004230,
+	.cm_div_h11_dpll_ddrphy = 0x4a004238,
+	.cm_div_h12_dpll_ddrphy = 0x4a00423c,
+	.cm_div_h13_dpll_ddrphy = 0x4a004240,
+	.cm_ssc_deltamstep_dpll_ddrphy = 0x4a004248,
+	.cm_shadow_freq_config1 = 0x4a004260,
+	.cm_mpu_mpu_clkctrl = 0x4a004320,
+
+	/* cm1.dsp */
+	.cm_dsp_clkstctrl = 0x4a004400,
+	.cm_dsp_dsp_clkctrl = 0x4a004420,
+
+	/* cm1.abe */
+	.cm1_abe_clkstctrl = 0x4a004500,
+	.cm1_abe_l4abe_clkctrl = 0x4a004520,
+	.cm1_abe_aess_clkctrl = 0x4a004528,
+	.cm1_abe_pdm_clkctrl = 0x4a004530,
+	.cm1_abe_dmic_clkctrl = 0x4a004538,
+	.cm1_abe_mcasp_clkctrl = 0x4a004540,
+	.cm1_abe_mcbsp1_clkctrl = 0x4a004548,
+	.cm1_abe_mcbsp2_clkctrl = 0x4a004550,
+	.cm1_abe_mcbsp3_clkctrl = 0x4a004558,
+	.cm1_abe_slimbus_clkctrl = 0x4a004560,
+	.cm1_abe_timer5_clkctrl = 0x4a004568,
+	.cm1_abe_timer6_clkctrl = 0x4a004570,
+	.cm1_abe_timer7_clkctrl = 0x4a004578,
+	.cm1_abe_timer8_clkctrl = 0x4a004580,
+	.cm1_abe_wdt3_clkctrl = 0x4a004588,
+
+	/* cm2.ckgen */
+	.cm_clksel_mpu_m3_iss_root = 0x4a008100,
+	.cm_clksel_usb_60mhz = 0x4a008104,
+	.cm_scale_fclk = 0x4a008108,
+	.cm_core_dvfs_perf1 = 0x4a008110,
+	.cm_core_dvfs_perf2 = 0x4a008114,
+	.cm_core_dvfs_perf3 = 0x4a008118,
+	.cm_core_dvfs_perf4 = 0x4a00811c,
+	.cm_core_dvfs_current = 0x4a008124,
+	.cm_iva_dvfs_perf_tesla = 0x4a008128,
+	.cm_iva_dvfs_perf_ivahd = 0x4a00812c,
+	.cm_iva_dvfs_perf_abe = 0x4a008130,
+	.cm_iva_dvfs_current = 0x4a008138,
+	.cm_clkmode_dpll_per = 0x4a008140,
+	.cm_idlest_dpll_per = 0x4a008144,
+	.cm_autoidle_dpll_per = 0x4a008148,
+	.cm_clksel_dpll_per = 0x4a00814c,
+	.cm_div_m2_dpll_per = 0x4a008150,
+	.cm_div_m3_dpll_per = 0x4a008154,
+	.cm_div_h11_dpll_per = 0x4a008158,
+	.cm_div_h12_dpll_per = 0x4a00815c,
+	.cm_div_h13_dpll_per = 0x4a008160,
+	.cm_div_h14_dpll_per = 0x4a008164,
+	.cm_ssc_deltamstep_dpll_per = 0x4a008168,
+	.cm_ssc_modfreqdiv_dpll_per = 0x4a00816c,
+	.cm_emu_override_dpll_per = 0x4a008170,
+	.cm_clkmode_dpll_usb = 0x4a008180,
+	.cm_idlest_dpll_usb = 0x4a008184,
+	.cm_autoidle_dpll_usb = 0x4a008188,
+	.cm_clksel_dpll_usb = 0x4a00818c,
+	.cm_div_m2_dpll_usb = 0x4a008190,
+	.cm_ssc_deltamstep_dpll_usb = 0x4a0081a8,
+	.cm_ssc_modfreqdiv_dpll_usb = 0x4a0081ac,
+	.cm_clkdcoldo_dpll_usb = 0x4a0081b4,
+	.cm_clkmode_dpll_unipro = 0x4a0081c0,
+	.cm_idlest_dpll_unipro = 0x4a0081c4,
+	.cm_autoidle_dpll_unipro = 0x4a0081c8,
+	.cm_clksel_dpll_unipro = 0x4a0081cc,
+	.cm_div_m2_dpll_unipro = 0x4a0081d0,
+	.cm_ssc_deltamstep_dpll_unipro = 0x4a0081e8,
+	.cm_ssc_modfreqdiv_dpll_unipro = 0x4a0081ec,
+	.cm_coreaon_usb_phy1_core_clkctrl = 0x4A008640,
+	.cm_coreaon_bandgap_clkctrl = 0x4a008648,
+	.cm_coreaon_io_srcomp_clkctrl = 0x4a008650,
+
+	/* cm2.core */
+	.cm_l3_1_clkstctrl = 0x4a008700,
+	.cm_l3_1_dynamicdep = 0x4a008708,
+	.cm_l3_1_l3_1_clkctrl = 0x4a008720,
+	.cm_l3_2_clkstctrl = 0x4a008800,
+	.cm_l3_2_dynamicdep = 0x4a008808,
+	.cm_l3_2_l3_2_clkctrl = 0x4a008820,
+	.cm_l3_gpmc_clkctrl = 0x4a008828,
+	.cm_l3_2_ocmc_ram_clkctrl = 0x4a008830,
+	.cm_mpu_m3_clkstctrl = 0x4a008900,
+	.cm_mpu_m3_staticdep = 0x4a008904,
+	.cm_mpu_m3_dynamicdep = 0x4a008908,
+	.cm_mpu_m3_mpu_m3_clkctrl = 0x4a008920,
+	.cm_sdma_clkstctrl = 0x4a008a00,
+	.cm_sdma_staticdep = 0x4a008a04,
+	.cm_sdma_dynamicdep = 0x4a008a08,
+	.cm_sdma_sdma_clkctrl = 0x4a008a20,
+	.cm_memif_clkstctrl = 0x4a008b00,
+	.cm_memif_dmm_clkctrl = 0x4a008b20,
+	.cm_memif_emif_fw_clkctrl = 0x4a008b28,
+	.cm_memif_emif_1_clkctrl = 0x4a008b30,
+	.cm_memif_emif_2_clkctrl = 0x4a008b38,
+	.cm_memif_dll_clkctrl = 0x4a008b40,
+	.cm_memif_emif_h1_clkctrl = 0x4a008b50,
+	.cm_memif_emif_h2_clkctrl = 0x4a008b58,
+	.cm_memif_dll_h_clkctrl = 0x4a008b60,
+	.cm_c2c_clkstctrl = 0x4a008c00,
+	.cm_c2c_staticdep = 0x4a008c04,
+	.cm_c2c_dynamicdep = 0x4a008c08,
+	.cm_c2c_sad2d_clkctrl = 0x4a008c20,
+	.cm_c2c_modem_icr_clkctrl = 0x4a008c28,
+	.cm_c2c_sad2d_fw_clkctrl = 0x4a008c30,
+	.cm_l4cfg_clkstctrl = 0x4a008d00,
+	.cm_l4cfg_dynamicdep = 0x4a008d08,
+	.cm_l4cfg_l4_cfg_clkctrl = 0x4a008d20,
+	.cm_l4cfg_hw_sem_clkctrl = 0x4a008d28,
+	.cm_l4cfg_mailbox_clkctrl = 0x4a008d30,
+	.cm_l4cfg_sar_rom_clkctrl = 0x4a008d38,
+	.cm_l3instr_clkstctrl = 0x4a008e00,
+	.cm_l3instr_l3_3_clkctrl = 0x4a008e20,
+	.cm_l3instr_l3_instr_clkctrl = 0x4a008e28,
+	.cm_l3instr_intrconn_wp1_clkctrl = 0x4a008e40,
+	.cm_l4per_clkstctrl = 0x4a009000,
+	.cm_l4per_dynamicdep = 0x4a009008,
+	.cm_l4per_adc_clkctrl = 0x4a009020,
+	.cm_l4per_gptimer10_clkctrl = 0x4a009028,
+	.cm_l4per_gptimer11_clkctrl = 0x4a009030,
+	.cm_l4per_gptimer2_clkctrl = 0x4a009038,
+	.cm_l4per_gptimer3_clkctrl = 0x4a009040,
+	.cm_l4per_gptimer4_clkctrl = 0x4a009048,
+	.cm_l4per_gptimer9_clkctrl = 0x4a009050,
+	.cm_l4per_elm_clkctrl = 0x4a009058,
+	.cm_l4per_gpio2_clkctrl = 0x4a009060,
+	.cm_l4per_gpio3_clkctrl = 0x4a009068,
+	.cm_l4per_gpio4_clkctrl = 0x4a009070,
+	.cm_l4per_gpio5_clkctrl = 0x4a009078,
+	.cm_l4per_gpio6_clkctrl = 0x4a009080,
+	.cm_l4per_hdq1w_clkctrl = 0x4a009088,
+	.cm_l4per_hecc1_clkctrl = 0x4a009090,
+	.cm_l4per_hecc2_clkctrl = 0x4a009098,
+	.cm_l4per_i2c1_clkctrl = 0x4a0090a0,
+	.cm_l4per_i2c2_clkctrl = 0x4a0090a8,
+	.cm_l4per_i2c3_clkctrl = 0x4a0090b0,
+	.cm_l4per_i2c4_clkctrl = 0x4a0090b8,
+	.cm_l4per_l4per_clkctrl = 0x4a0090c0,
+	.cm_l4per_mcasp2_clkctrl = 0x4a0090d0,
+	.cm_l4per_mcasp3_clkctrl = 0x4a0090d8,
+	.cm_l4per_mgate_clkctrl = 0x4a0090e8,
+	.cm_l4per_mcspi1_clkctrl = 0x4a0090f0,
+	.cm_l4per_mcspi2_clkctrl = 0x4a0090f8,
+	.cm_l4per_mcspi3_clkctrl = 0x4a009100,
+	.cm_l4per_mcspi4_clkctrl = 0x4a009108,
+	.cm_l4per_gpio7_clkctrl = 0x4a009110,
+	.cm_l4per_gpio8_clkctrl = 0x4a009118,
+	.cm_l4per_mmcsd3_clkctrl = 0x4a009120,
+	.cm_l4per_mmcsd4_clkctrl = 0x4a009128,
+	.cm_l4per_msprohg_clkctrl = 0x4a009130,
+	.cm_l4per_slimbus2_clkctrl = 0x4a009138,
+	.cm_l4per_uart1_clkctrl = 0x4a009140,
+	.cm_l4per_uart2_clkctrl = 0x4a009148,
+	.cm_l4per_uart3_clkctrl = 0x4a009150,
+	.cm_l4per_uart4_clkctrl = 0x4a009158,
+	.cm_l4per_mmcsd5_clkctrl = 0x4a009160,
+	.cm_l4per_i2c5_clkctrl = 0x4a009168,
+	.cm_l4per_uart5_clkctrl = 0x4a009170,
+	.cm_l4per_uart6_clkctrl = 0x4a009178,
+	.cm_l4sec_clkstctrl = 0x4a009180,
+	.cm_l4sec_staticdep = 0x4a009184,
+	.cm_l4sec_dynamicdep = 0x4a009188,
+	.cm_l4sec_aes1_clkctrl = 0x4a0091a0,
+	.cm_l4sec_aes2_clkctrl = 0x4a0091a8,
+	.cm_l4sec_des3des_clkctrl = 0x4a0091b0,
+	.cm_l4sec_pkaeip29_clkctrl = 0x4a0091b8,
+	.cm_l4sec_rng_clkctrl = 0x4a0091c0,
+	.cm_l4sec_sha2md51_clkctrl = 0x4a0091c8,
+	.cm_l4sec_cryptodma_clkctrl = 0x4a0091d8,
+
+	/* cm2.ivahd */
+	.cm_ivahd_clkstctrl = 0x4a009200,
+	.cm_ivahd_ivahd_clkctrl = 0x4a009220,
+	.cm_ivahd_sl2_clkctrl = 0x4a009228,
+
+	/* cm2.cam */
+	.cm_cam_clkstctrl = 0x4a009300,
+	.cm_cam_iss_clkctrl = 0x4a009320,
+	.cm_cam_fdif_clkctrl = 0x4a009328,
+
+	/* cm2.dss */
+	.cm_dss_clkstctrl = 0x4a009400,
+	.cm_dss_dss_clkctrl = 0x4a009420,
+
+	/* cm2.sgx */
+	.cm_sgx_clkstctrl = 0x4a009500,
+	.cm_sgx_sgx_clkctrl = 0x4a009520,
+
+	/* cm2.l3init */
+	.cm_l3init_clkstctrl = 0x4a009600,
+
+	/* cm2.l3init */
+	.cm_l3init_hsmmc1_clkctrl = 0x4a009628,
+	.cm_l3init_hsmmc2_clkctrl = 0x4a009630,
+	.cm_l3init_hsi_clkctrl = 0x4a009638,
+	.cm_l3init_hsusbhost_clkctrl = 0x4a009658,
+	.cm_l3init_hsusbotg_clkctrl = 0x4a009660,
+	.cm_l3init_hsusbtll_clkctrl = 0x4a009668,
+	.cm_l3init_p1500_clkctrl = 0x4a009678,
+	.cm_l3init_sata_clkctrl = 0x4a009688,
+	.cm_l3init_fsusb_clkctrl = 0x4a0096d0,
+	.cm_l3init_ocp2scp1_clkctrl = 0x4a0096e0,
+	.cm_l3init_ocp2scp3_clkctrl = 0x4a0096e8,
+	.cm_l3init_usb_otg_ss1_clkctrl = 0x4a0096f0,
+
+	/* prm irqstatus regs */
+	.prm_irqstatus_mpu = 0x4ae06010,
+	.prm_irqstatus_mpu_2 = 0x4ae06014,
+
+	/* l4 wkup regs */
+	.cm_abe_pll_ref_clksel = 0x4ae0610c,
+	.cm_sys_clksel = 0x4ae06110,
+	.cm_wkup_clkstctrl = 0x4ae07900,
+	.cm_wkup_l4wkup_clkctrl = 0x4ae07920,
+	.cm_wkup_wdtimer1_clkctrl = 0x4ae07928,
+	.cm_wkup_wdtimer2_clkctrl = 0x4ae07930,
+	.cm_wkup_gpio1_clkctrl = 0x4ae07938,
+	.cm_wkup_gptimer1_clkctrl = 0x4ae07940,
+	.cm_wkup_gptimer12_clkctrl = 0x4ae07948,
+	.cm_wkup_synctimer_clkctrl = 0x4ae07950,
+	.cm_wkup_usim_clkctrl = 0x4ae07958,
+	.cm_wkup_sarram_clkctrl = 0x4ae07960,
+	.cm_wkup_keyboard_clkctrl = 0x4ae07978,
+	.cm_wkup_rtc_clkctrl = 0x4ae07980,
+	.cm_wkup_bandgap_clkctrl = 0x4ae07988,
+	.cm_wkupaon_scrm_clkctrl = 0x4ae07990,
+	.cm_wkupaon_io_srcomp_clkctrl = 0x4ae07998,
+	.prm_rstctrl = 0x4ae07c00,
+	.prm_rstst = 0x4ae07c04,
+	.prm_rsttime = 0x4ae07c08,
+	.prm_vc_val_bypass = 0x4ae07ca0,
+	.prm_vc_cfg_i2c_mode = 0x4ae07cb4,
+	.prm_vc_cfg_i2c_clk = 0x4ae07cb8,
+
+	.prm_abbldo_mpu_setup = 0x4ae07cdc,
+	.prm_abbldo_mpu_ctrl = 0x4ae07ce0,
+	.prm_abbldo_mm_setup = 0x4ae07ce4,
+	.prm_abbldo_mm_ctrl = 0x4ae07ce8,
+
+	/* SCRM stuff, used by some boards */
+	.scrm_auxclk0 = 0x4ae0a310,
+	.scrm_auxclk1 = 0x4ae0a314,
+};
+
+struct prcm_regs const dra7xx_prcm = {
+	/* cm1.ckgen */
+	.cm_clksel_core				= 0x4a005100,
+	.cm_clksel_abe				= 0x4a005108,
+	.cm_dll_ctrl				= 0x4a005110,
+	.cm_clkmode_dpll_core			= 0x4a005120,
+	.cm_idlest_dpll_core			= 0x4a005124,
+	.cm_autoidle_dpll_core			= 0x4a005128,
+	.cm_clksel_dpll_core			= 0x4a00512c,
+	.cm_div_m2_dpll_core			= 0x4a005130,
+	.cm_div_m3_dpll_core			= 0x4a005134,
+	.cm_div_h11_dpll_core			= 0x4a005138,
+	.cm_div_h12_dpll_core			= 0x4a00513c,
+	.cm_div_h13_dpll_core			= 0x4a005140,
+	.cm_div_h14_dpll_core			= 0x4a005144,
+	.cm_ssc_deltamstep_dpll_core		= 0x4a005148,
+	.cm_ssc_modfreqdiv_dpll_core		= 0x4a00514c,
+	.cm_div_h21_dpll_core			= 0x4a005150,
+	.cm_div_h22_dpllcore			= 0x4a005154,
+	.cm_div_h23_dpll_core			= 0x4a005158,
+	.cm_div_h24_dpll_core			= 0x4a00515c,
+	.cm_clkmode_dpll_mpu			= 0x4a005160,
+	.cm_idlest_dpll_mpu			= 0x4a005164,
+	.cm_autoidle_dpll_mpu			= 0x4a005168,
+	.cm_clksel_dpll_mpu			= 0x4a00516c,
+	.cm_div_m2_dpll_mpu			= 0x4a005170,
+	.cm_ssc_deltamstep_dpll_mpu		= 0x4a005188,
+	.cm_ssc_modfreqdiv_dpll_mpu		= 0x4a00518c,
+	.cm_bypclk_dpll_mpu			= 0x4a00519c,
+	.cm_clkmode_dpll_iva			= 0x4a0051a0,
+	.cm_idlest_dpll_iva			= 0x4a0051a4,
+	.cm_autoidle_dpll_iva			= 0x4a0051a8,
+	.cm_clksel_dpll_iva			= 0x4a0051ac,
+	.cm_ssc_deltamstep_dpll_iva		= 0x4a0051c8,
+	.cm_ssc_modfreqdiv_dpll_iva		= 0x4a0051cc,
+	.cm_bypclk_dpll_iva			= 0x4a0051dc,
+	.cm_clkmode_dpll_abe			= 0x4a0051e0,
+	.cm_idlest_dpll_abe			= 0x4a0051e4,
+	.cm_autoidle_dpll_abe			= 0x4a0051e8,
+	.cm_clksel_dpll_abe			= 0x4a0051ec,
+	.cm_div_m2_dpll_abe			= 0x4a0051f0,
+	.cm_div_m3_dpll_abe			= 0x4a0051f4,
+	.cm_ssc_deltamstep_dpll_abe		= 0x4a005208,
+	.cm_ssc_modfreqdiv_dpll_abe		= 0x4a00520c,
+	.cm_clkmode_dpll_ddrphy			= 0x4a005210,
+	.cm_idlest_dpll_ddrphy			= 0x4a005214,
+	.cm_autoidle_dpll_ddrphy		= 0x4a005218,
+	.cm_clksel_dpll_ddrphy			= 0x4a00521c,
+	.cm_div_m2_dpll_ddrphy			= 0x4a005220,
+	.cm_div_h11_dpll_ddrphy			= 0x4a005228,
+	.cm_ssc_deltamstep_dpll_ddrphy		= 0x4a00522c,
+	.cm_clkmode_dpll_dsp			= 0x4a005234,
+	.cm_shadow_freq_config1			= 0x4a005260,
+	.cm_clkmode_dpll_gmac			= 0x4a0052a8,
+	.cm_coreaon_usb_phy1_core_clkctrl	= 0x4a008640,
+	.cm_coreaon_usb_phy2_core_clkctrl	= 0x4a008688,
+	.cm_coreaon_usb_phy3_core_clkctrl	= 0x4a008698,
+	.cm_coreaon_l3init_60m_gfclk_clkctrl	= 0x4a0086c0,
+
+	/* cm1.mpu */
+	.cm_mpu_mpu_clkctrl			= 0x4a005320,
+
+	/* cm1.dsp */
+	.cm_dsp_clkstctrl			= 0x4a005400,
+	.cm_dsp_dsp_clkctrl			= 0x4a005420,
+
+	/* cm IPU */
+	.cm_ipu_clkstctrl			= 0x4a005540,
+	.cm_ipu_i2c5_clkctrl			= 0x4a005578,
+
+	/* prm irqstatus regs */
+	.prm_irqstatus_mpu			= 0x4ae06010,
+	.prm_irqstatus_mpu_2			= 0x4ae06014,
+
+	/* cm2.ckgen */
+	.cm_clksel_usb_60mhz			= 0x4a008104,
+	.cm_clkmode_dpll_per			= 0x4a008140,
+	.cm_idlest_dpll_per			= 0x4a008144,
+	.cm_autoidle_dpll_per			= 0x4a008148,
+	.cm_clksel_dpll_per			= 0x4a00814c,
+	.cm_div_m2_dpll_per			= 0x4a008150,
+	.cm_div_m3_dpll_per			= 0x4a008154,
+	.cm_div_h11_dpll_per			= 0x4a008158,
+	.cm_div_h12_dpll_per			= 0x4a00815c,
+	.cm_div_h13_dpll_per			= 0x4a008160,
+	.cm_div_h14_dpll_per			= 0x4a008164,
+	.cm_ssc_deltamstep_dpll_per		= 0x4a008168,
+	.cm_ssc_modfreqdiv_dpll_per		= 0x4a00816c,
+	.cm_clkmode_dpll_usb			= 0x4a008180,
+	.cm_idlest_dpll_usb			= 0x4a008184,
+	.cm_autoidle_dpll_usb			= 0x4a008188,
+	.cm_clksel_dpll_usb			= 0x4a00818c,
+	.cm_div_m2_dpll_usb			= 0x4a008190,
+	.cm_ssc_deltamstep_dpll_usb		= 0x4a0081a8,
+	.cm_ssc_modfreqdiv_dpll_usb		= 0x4a0081ac,
+	.cm_clkdcoldo_dpll_usb			= 0x4a0081b4,
+	.cm_clkmode_dpll_pcie_ref		= 0x4a008200,
+	.cm_clkmode_apll_pcie			= 0x4a00821c,
+	.cm_idlest_apll_pcie			= 0x4a008220,
+	.cm_div_m2_apll_pcie			= 0x4a008224,
+	.cm_clkvcoldo_apll_pcie			= 0x4a008228,
+
+	/* cm2.core */
+	.cm_l3_1_clkstctrl			= 0x4a008700,
+	.cm_l3_1_dynamicdep			= 0x4a008708,
+	.cm_l3_1_l3_1_clkctrl			= 0x4a008720,
+	.cm_l3_gpmc_clkctrl			= 0x4a008728,
+	.cm_mpu_m3_clkstctrl			= 0x4a008900,
+	.cm_mpu_m3_staticdep			= 0x4a008904,
+	.cm_mpu_m3_dynamicdep			= 0x4a008908,
+	.cm_mpu_m3_mpu_m3_clkctrl		= 0x4a008920,
+	.cm_sdma_clkstctrl			= 0x4a008a00,
+	.cm_sdma_staticdep			= 0x4a008a04,
+	.cm_sdma_dynamicdep			= 0x4a008a08,
+	.cm_sdma_sdma_clkctrl			= 0x4a008a20,
+	.cm_memif_clkstctrl			= 0x4a008b00,
+	.cm_memif_dmm_clkctrl			= 0x4a008b20,
+	.cm_memif_emif_fw_clkctrl		= 0x4a008b28,
+	.cm_memif_emif_1_clkctrl		= 0x4a008b30,
+	.cm_memif_emif_2_clkctrl		= 0x4a008b38,
+	.cm_memif_dll_clkctrl			= 0x4a008b40,
+	.cm_l4cfg_clkstctrl			= 0x4a008d00,
+	.cm_l4cfg_dynamicdep			= 0x4a008d08,
+	.cm_l4cfg_l4_cfg_clkctrl		= 0x4a008d20,
+	.cm_l4cfg_hw_sem_clkctrl		= 0x4a008d28,
+	.cm_l4cfg_mailbox_clkctrl		= 0x4a008d30,
+	.cm_l4cfg_sar_rom_clkctrl		= 0x4a008d38,
+	.cm_l3instr_clkstctrl			= 0x4a008e00,
+	.cm_l3instr_l3_3_clkctrl		= 0x4a008e20,
+	.cm_l3instr_l3_instr_clkctrl		= 0x4a008e28,
+	.cm_l3instr_intrconn_wp1_clkctrl	= 0x4a008e40,
+
+	/* cm2.ivahd */
+	.cm_ivahd_clkstctrl			= 0x4a008f00,
+	.cm_ivahd_ivahd_clkctrl			= 0x4a008f20,
+	.cm_ivahd_sl2_clkctrl			= 0x4a008f28,
+
+	/* cm2.cam */
+	.cm_cam_clkstctrl			= 0x4a009000,
+	.cm_cam_vip1_clkctrl			= 0x4a009020,
+	.cm_cam_vip2_clkctrl			= 0x4a009028,
+	.cm_cam_vip3_clkctrl			= 0x4a009030,
+	.cm_cam_lvdsrx_clkctrl			= 0x4a009038,
+	.cm_cam_csi1_clkctrl			= 0x4a009040,
+	.cm_cam_csi2_clkctrl			= 0x4a009048,
+
+	/* cm2.dss */
+	.cm_dss_clkstctrl			= 0x4a009100,
+	.cm_dss_dss_clkctrl			= 0x4a009120,
+
+	/* cm2.sgx */
+	.cm_sgx_clkstctrl			= 0x4a009200,
+	.cm_sgx_sgx_clkctrl			= 0x4a009220,
+
+	/* cm2.l3init */
+	.cm_l3init_clkstctrl			= 0x4a009300,
+
+	/* cm2.l3init */
+	.cm_l3init_hsmmc1_clkctrl		= 0x4a009328,
+	.cm_l3init_hsmmc2_clkctrl		= 0x4a009330,
+	.cm_l3init_hsusbhost_clkctrl		= 0x4a009340,
+	.cm_l3init_hsusbotg_clkctrl		= 0x4a009348,
+	.cm_l3init_hsusbtll_clkctrl		= 0x4a009350,
+	.cm_l3init_sata_clkctrl			= 0x4a009388,
+	.cm_gmac_clkstctrl			= 0x4a0093c0,
+	.cm_gmac_gmac_clkctrl			= 0x4a0093d0,
+	.cm_l3init_ocp2scp1_clkctrl		= 0x4a0093e0,
+	.cm_l3init_ocp2scp3_clkctrl		= 0x4a0093e8,
+	.cm_l3init_usb_otg_ss1_clkctrl		= 0x4a0093f0,
+	.cm_l3init_usb_otg_ss2_clkctrl		= 0x4a009340,
+
+	/* cm2.l4per */
+	.cm_l4per_clkstctrl			= 0x4a009700,
+	.cm_l4per_dynamicdep			= 0x4a009708,
+	.cm_l4per_gptimer10_clkctrl		= 0x4a009728,
+	.cm_l4per_gptimer11_clkctrl		= 0x4a009730,
+	.cm_l4per_gptimer2_clkctrl		= 0x4a009738,
+	.cm_l4per_gptimer3_clkctrl		= 0x4a009740,
+	.cm_l4per_gptimer4_clkctrl		= 0x4a009748,
+	.cm_l4per_gptimer9_clkctrl		= 0x4a009750,
+	.cm_l4per_elm_clkctrl			= 0x4a009758,
+	.cm_l4per_gpio2_clkctrl			= 0x4a009760,
+	.cm_l4per_gpio3_clkctrl			= 0x4a009768,
+	.cm_l4per_gpio4_clkctrl			= 0x4a009770,
+	.cm_l4per_gpio5_clkctrl			= 0x4a009778,
+	.cm_l4per_gpio6_clkctrl			= 0x4a009780,
+	.cm_l4per_hdq1w_clkctrl			= 0x4a009788,
+	.cm_l4per_i2c1_clkctrl			= 0x4a0097a0,
+	.cm_l4per_i2c2_clkctrl			= 0x4a0097a8,
+	.cm_l4per_i2c3_clkctrl			= 0x4a0097b0,
+	.cm_l4per_i2c4_clkctrl			= 0x4a0097b8,
+	.cm_l4per_l4per_clkctrl			= 0x4a0097c0,
+	.cm_l4per_mcspi1_clkctrl		= 0x4a0097f0,
+	.cm_l4per_mcspi2_clkctrl		= 0x4a0097f8,
+	.cm_l4per_mcspi3_clkctrl		= 0x4a009800,
+	.cm_l4per_mcspi4_clkctrl		= 0x4a009808,
+	.cm_l4per_gpio7_clkctrl			= 0x4a009810,
+	.cm_l4per_gpio8_clkctrl			= 0x4a009818,
+	.cm_l4per_mmcsd3_clkctrl		= 0x4a009820,
+	.cm_l4per_mmcsd4_clkctrl		= 0x4a009828,
+	.cm_l4per_qspi_clkctrl			= 0x4a009838,
+	.cm_l4per_uart1_clkctrl			= 0x4a009840,
+	.cm_l4per_uart2_clkctrl			= 0x4a009848,
+	.cm_l4per_uart3_clkctrl			= 0x4a009850,
+	.cm_l4per_uart4_clkctrl			= 0x4a009858,
+	.cm_l4per_uart5_clkctrl			= 0x4a009870,
+	.cm_l4sec_clkstctrl			= 0x4a009880,
+	.cm_l4sec_staticdep			= 0x4a009884,
+	.cm_l4sec_dynamicdep			= 0x4a009888,
+	.cm_l4sec_aes1_clkctrl			= 0x4a0098a0,
+	.cm_l4sec_aes2_clkctrl			= 0x4a0098a8,
+	.cm_l4sec_des3des_clkctrl		= 0x4a0098b0,
+	.cm_l4sec_rng_clkctrl			= 0x4a0098c0,
+	.cm_l4sec_sha2md51_clkctrl		= 0x4a0098c8,
+	.cm_l4sec_cryptodma_clkctrl		= 0x4a0098d8,
+
+	/* l4 wkup regs */
+	.cm_abe_pll_ref_clksel			= 0x4ae0610c,
+	.cm_sys_clksel				= 0x4ae06110,
+	.cm_abe_pll_sys_clksel			= 0x4ae06118,
+	.cm_wkup_clkstctrl			= 0x4ae07800,
+	.cm_wkup_l4wkup_clkctrl			= 0x4ae07820,
+	.cm_wkup_wdtimer1_clkctrl		= 0x4ae07828,
+	.cm_wkup_wdtimer2_clkctrl		= 0x4ae07830,
+	.cm_wkup_gpio1_clkctrl			= 0x4ae07838,
+	.cm_wkup_gptimer1_clkctrl		= 0x4ae07840,
+	.cm_wkup_gptimer12_clkctrl		= 0x4ae07848,
+	.cm_wkup_sarram_clkctrl			= 0x4ae07860,
+	.cm_wkup_keyboard_clkctrl		= 0x4ae07878,
+	.cm_wkupaon_scrm_clkctrl		= 0x4ae07890,
+	.prm_rstctrl				= 0x4ae07d00,
+	.prm_rstst				= 0x4ae07d04,
+	.prm_rsttime				= 0x4ae07d08,
+	.prm_io_pmctrl				= 0x4ae07d20,
+	.prm_vc_val_bypass			= 0x4ae07da0,
+	.prm_vc_cfg_i2c_mode			= 0x4ae07db4,
+	.prm_vc_cfg_i2c_clk			= 0x4ae07db8,
+
+	.prm_abbldo_mpu_setup			= 0x4AE07DDC,
+	.prm_abbldo_mpu_ctrl			= 0x4AE07DE0,
+	.prm_abbldo_iva_setup			= 0x4AE07E34,
+	.prm_abbldo_iva_ctrl			= 0x4AE07E24,
+	.prm_abbldo_eve_setup			= 0x4AE07E30,
+	.prm_abbldo_eve_ctrl			= 0x4AE07E20,
+	.prm_abbldo_gpu_setup			= 0x4AE07DE4,
+	.prm_abbldo_gpu_ctrl			= 0x4AE07DE8,
+
+	/*l3main1 edma*/
+	.cm_l3main1_tptc1_clkctrl               = 0x4a008778,
+	.cm_l3main1_tptc2_clkctrl               = 0x4a008780,
+};
+
+void clrset_spare_register(u8 spare_type, u32 clear_bits, u32 set_bits)
+{
+	u32 reg = spare_type ? (*ctrl)->ctrl_core_sma_sw_1 :
+		(*ctrl)->ctrl_core_sma_sw_0;
+	clrsetbits_le32(reg, clear_bits, set_bits);
+}
diff --git a/arch/arm/mach-omap2/omap5/sdram.c b/arch/arm/mach-omap2/omap5/sdram.c
new file mode 100644
index 0000000..7712923d
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/sdram.c
@@ -0,0 +1,742 @@
+/*
+ * Timing and Organization details of the ddr device parts used in OMAP5
+ * EVM
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.com>
+ * Sricharan R <r.sricharan@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/emif.h>
+#include <asm/arch/sys_proto.h>
+
+/*
+ * This file provides details of the LPDDR2 SDRAM parts used on OMAP5
+ * EVM. Since the parts used and geometry are identical for
+ * evm for a given OMAP5 revision, this information is kept
+ * here instead of being in board directory. However the key functions
+ * exported are weakly linked so that they can be over-ridden in the board
+ * directory if there is a OMAP5 board in the future that uses a different
+ * memory device or geometry.
+ *
+ * For any new board with different memory devices over-ride one or more
+ * of the following functions as per the CONFIG flags you intend to enable:
+ * - emif_get_reg_dump()
+ * - emif_get_dmm_regs()
+ * - emif_get_device_details()
+ * - emif_get_device_timings()
+ */
+
+#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
+const struct emif_regs emif_regs_532_mhz_2cs = {
+	.sdram_config_init		= 0x80800EBA,
+	.sdram_config			= 0x808022BA,
+	.ref_ctrl			= 0x0000081A,
+	.sdram_tim1			= 0x772F6873,
+	.sdram_tim2			= 0x304a129a,
+	.sdram_tim3			= 0x02f7e45f,
+	.read_idle_ctrl			= 0x00050000,
+	.zq_config			= 0x000b3215,
+	.temp_alert_config		= 0x08000a05,
+	.emif_ddr_phy_ctlr_1_init	= 0x0E28420d,
+	.emif_ddr_phy_ctlr_1		= 0x0E28420d,
+	.emif_ddr_ext_phy_ctrl_1	= 0x04020080,
+	.emif_ddr_ext_phy_ctrl_2	= 0x28C518A3,
+	.emif_ddr_ext_phy_ctrl_3	= 0x518A3146,
+	.emif_ddr_ext_phy_ctrl_4	= 0x0014628C,
+	.emif_ddr_ext_phy_ctrl_5	= 0x04010040
+};
+
+const struct emif_regs emif_regs_532_mhz_2cs_es2 = {
+	.sdram_config_init		= 0x80800EBA,
+	.sdram_config			= 0x808022BA,
+	.ref_ctrl			= 0x0000081A,
+	.sdram_tim1			= 0x772F6873,
+	.sdram_tim2			= 0x304a129a,
+	.sdram_tim3			= 0x02f7e45f,
+	.read_idle_ctrl			= 0x00050000,
+	.zq_config			= 0x100b3215,
+	.temp_alert_config		= 0x08000a05,
+	.emif_ddr_phy_ctlr_1_init	= 0x0E30400d,
+	.emif_ddr_phy_ctlr_1		= 0x0E30400d,
+	.emif_ddr_ext_phy_ctrl_1	= 0x04020080,
+	.emif_ddr_ext_phy_ctrl_2	= 0x28C518A3,
+	.emif_ddr_ext_phy_ctrl_3	= 0x518A3146,
+	.emif_ddr_ext_phy_ctrl_4	= 0x0014628C,
+	.emif_ddr_ext_phy_ctrl_5	= 0xC330CC33,
+};
+
+const struct emif_regs emif_regs_266_mhz_2cs = {
+	.sdram_config_init		= 0x80800EBA,
+	.sdram_config			= 0x808022BA,
+	.ref_ctrl			= 0x0000040D,
+	.sdram_tim1			= 0x2A86B419,
+	.sdram_tim2			= 0x1025094A,
+	.sdram_tim3			= 0x026BA22F,
+	.read_idle_ctrl			= 0x00050000,
+	.zq_config			= 0x000b3215,
+	.temp_alert_config		= 0x08000a05,
+	.emif_ddr_phy_ctlr_1_init	= 0x0E28420d,
+	.emif_ddr_phy_ctlr_1		= 0x0E28420d,
+	.emif_ddr_ext_phy_ctrl_1	= 0x04020080,
+	.emif_ddr_ext_phy_ctrl_2	= 0x0A414829,
+	.emif_ddr_ext_phy_ctrl_3	= 0x14829052,
+	.emif_ddr_ext_phy_ctrl_4	= 0x000520A4,
+	.emif_ddr_ext_phy_ctrl_5	= 0x04010040
+};
+
+const struct emif_regs emif_regs_ddr3_532_mhz_1cs = {
+	.sdram_config_init		= 0x61851B32,
+	.sdram_config			= 0x61851B32,
+	.sdram_config2			= 0x0,
+	.ref_ctrl			= 0x00001035,
+	.sdram_tim1			= 0xCCCF36B3,
+	.sdram_tim2			= 0x308F7FDA,
+	.sdram_tim3			= 0x027F88A8,
+	.read_idle_ctrl			= 0x00050000,
+	.zq_config			= 0x0007190B,
+	.temp_alert_config		= 0x00000000,
+	.emif_ddr_phy_ctlr_1_init	= 0x0020420A,
+	.emif_ddr_phy_ctlr_1		= 0x0024420A,
+	.emif_ddr_ext_phy_ctrl_1	= 0x04040100,
+	.emif_ddr_ext_phy_ctrl_2	= 0x00000000,
+	.emif_ddr_ext_phy_ctrl_3	= 0x00000000,
+	.emif_ddr_ext_phy_ctrl_4	= 0x00000000,
+	.emif_ddr_ext_phy_ctrl_5	= 0x04010040,
+	.emif_rd_wr_lvl_rmp_win		= 0x00000000,
+	.emif_rd_wr_lvl_rmp_ctl		= 0x80000000,
+	.emif_rd_wr_lvl_ctl		= 0x00000000,
+	.emif_rd_wr_exec_thresh		= 0x00000305
+};
+
+const struct emif_regs emif_regs_ddr3_532_mhz_1cs_es2 = {
+	.sdram_config_init              = 0x61851B32,
+	.sdram_config                   = 0x61851B32,
+	.sdram_config2			= 0x0,
+	.ref_ctrl                       = 0x00001035,
+	.sdram_tim1                     = 0xCCCF36B3,
+	.sdram_tim2                     = 0x308F7FDA,
+	.sdram_tim3                     = 0x027F88A8,
+	.read_idle_ctrl                 = 0x00050000,
+	.zq_config                      = 0x1007190B,
+	.temp_alert_config              = 0x00000000,
+	.emif_ddr_phy_ctlr_1_init       = 0x0030400A,
+	.emif_ddr_phy_ctlr_1            = 0x0034400A,
+	.emif_ddr_ext_phy_ctrl_1        = 0x04040100,
+	.emif_ddr_ext_phy_ctrl_2        = 0x00000000,
+	.emif_ddr_ext_phy_ctrl_3        = 0x00000000,
+	.emif_ddr_ext_phy_ctrl_4        = 0x00000000,
+	.emif_ddr_ext_phy_ctrl_5        = 0x4350D435,
+	.emif_rd_wr_lvl_rmp_win         = 0x00000000,
+	.emif_rd_wr_lvl_rmp_ctl         = 0x80000000,
+	.emif_rd_wr_lvl_ctl             = 0x00000000,
+	.emif_rd_wr_exec_thresh         = 0x40000305
+};
+
+const struct dmm_lisa_map_regs lisa_map_4G_x_2_x_2 = {
+	.dmm_lisa_map_0 = 0x0,
+	.dmm_lisa_map_1 = 0x0,
+	.dmm_lisa_map_2 = 0x80740300,
+	.dmm_lisa_map_3 = 0xFF020100,
+	.is_ma_present	= 0x1
+};
+
+static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs)
+{
+	switch (omap_revision()) {
+	case OMAP5430_ES1_0:
+		*regs = &emif_regs_532_mhz_2cs;
+		break;
+	case OMAP5432_ES1_0:
+		*regs = &emif_regs_ddr3_532_mhz_1cs;
+		break;
+	case OMAP5430_ES2_0:
+		*regs = &emif_regs_532_mhz_2cs_es2;
+		break;
+	case OMAP5432_ES2_0:
+	default:
+		*regs = &emif_regs_ddr3_532_mhz_1cs_es2;
+		break;
+	}
+}
+
+void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs)
+	__attribute__((weak, alias("emif_get_reg_dump_sdp")));
+
+static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs
+						**dmm_lisa_regs)
+{
+	switch (omap_revision()) {
+	case OMAP5430_ES1_0:
+	case OMAP5430_ES2_0:
+	case OMAP5432_ES1_0:
+	case OMAP5432_ES2_0:
+	default:
+		*dmm_lisa_regs = &lisa_map_4G_x_2_x_2;
+		break;
+	}
+
+}
+
+void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs)
+	__attribute__((weak, alias("emif_get_dmm_regs_sdp")));
+#else
+
+static const struct lpddr2_device_details dev_4G_S4_details = {
+	.type		= LPDDR2_TYPE_S4,
+	.density	= LPDDR2_DENSITY_4Gb,
+	.io_width	= LPDDR2_IO_WIDTH_32,
+	.manufacturer	= LPDDR2_MANUFACTURER_SAMSUNG
+};
+
+static void emif_get_device_details_sdp(u32 emif_nr,
+		struct lpddr2_device_details *cs0_device_details,
+		struct lpddr2_device_details *cs1_device_details)
+{
+	/* EMIF1 & EMIF2 have identical configuration */
+	*cs0_device_details = dev_4G_S4_details;
+	*cs1_device_details = dev_4G_S4_details;
+}
+
+void emif_get_device_details(u32 emif_nr,
+		struct lpddr2_device_details *cs0_device_details,
+		struct lpddr2_device_details *cs1_device_details)
+	__attribute__((weak, alias("emif_get_device_details_sdp")));
+
+#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */
+
+const u32 ext_phy_ctrl_const_base[] = {
+	0x01004010,
+	0x00001004,
+	0x04010040,
+	0x01004010,
+	0x00001004,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x80080080,
+	0x00800800,
+	0x08102040,
+	0x00000001,
+	0x540A8150,
+	0xA81502a0,
+	0x002A0540,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000077,
+	0x0
+};
+
+const u32 ddr3_ext_phy_ctrl_const_base_es1[] = {
+	0x01004010,
+	0x00001004,
+	0x04010040,
+	0x01004010,
+	0x00001004,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x80080080,
+	0x00800800,
+	0x08102040,
+	0x00000002,
+	0x0,
+	0x0,
+	0x0,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000057,
+	0x0
+};
+
+const u32 ddr3_ext_phy_ctrl_const_base_es2[] = {
+	0x50D4350D,
+	0x00000D43,
+	0x04010040,
+	0x01004010,
+	0x00001004,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x80080080,
+	0x00800800,
+	0x08102040,
+	0x00000002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000057,
+	0x0
+};
+
+/* Ext phy ctrl 1-35 regs */
+const u32
+dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = {
+	0x10040100,
+	0x00910091,
+	0x00950095,
+	0x009B009B,
+	0x009E009E,
+	0x00980098,
+	0x00340034,
+	0x00350035,
+	0x00340034,
+	0x00310031,
+	0x00340034,
+	0x007F007F,
+	0x007F007F,
+	0x007F007F,
+	0x007F007F,
+	0x007F007F,
+	0x00480048,
+	0x004A004A,
+	0x00520052,
+	0x00550055,
+	0x00500050,
+	0x00000000,
+	0x00600020,
+	0x40011080,
+	0x08102040,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0
+};
+
+/* Ext phy ctrl 1-35 regs */
+const u32
+dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[] = {
+	0x10040100,
+	0x00910091,
+	0x00950095,
+	0x009B009B,
+	0x009E009E,
+	0x00980098,
+	0x00330033,
+	0x00330033,
+	0x002F002F,
+	0x00320032,
+	0x00310031,
+	0x007F007F,
+	0x007F007F,
+	0x007F007F,
+	0x007F007F,
+	0x007F007F,
+	0x00520052,
+	0x00520052,
+	0x00470047,
+	0x00490049,
+	0x00500050,
+	0x00000000,
+	0x00600020,
+	0x40011080,
+	0x08102040,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0
+};
+
+/* Ext phy ctrl 1-35 regs */
+const u32
+dra_ddr3_ext_phy_ctrl_const_base_666MHz[] = {
+	0x10040100,
+	0x00A400A4,
+	0x00A900A9,
+	0x00B000B0,
+	0x00B000B0,
+	0x00A400A4,
+	0x00390039,
+	0x00320032,
+	0x00320032,
+	0x00320032,
+	0x00440044,
+	0x00550055,
+	0x00550055,
+	0x00550055,
+	0x00550055,
+	0x007F007F,
+	0x004D004D,
+	0x00430043,
+	0x00560056,
+	0x00540054,
+	0x00600060,
+	0x0,
+	0x00600020,
+	0x40010080,
+	0x08102040,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0
+};
+
+const u32 dra_ddr3_ext_phy_ctrl_const_base_666MHz_es2[] = {
+	0x04040100,
+	0x006B009F,
+	0x006B00A2,
+	0x006B00A8,
+	0x006B00A8,
+	0x006B00B2,
+	0x002F002F,
+	0x002F002F,
+	0x002F002F,
+	0x002F002F,
+	0x002F002F,
+	0x00600073,
+	0x00600071,
+	0x0060007C,
+	0x0060007E,
+	0x00600084,
+	0x00400053,
+	0x00400051,
+	0x0040005C,
+	0x0040005E,
+	0x00400064,
+	0x00800080,
+	0x00800080,
+	0x40010080,
+	0x08102040,
+	0x005B008F,
+	0x005B0092,
+	0x005B0098,
+	0x005B0098,
+	0x005B00A2,
+	0x00300043,
+	0x00300041,
+	0x0030004C,
+	0x0030004E,
+	0x00300054,
+	0x00000077
+};
+
+const struct lpddr2_mr_regs mr_regs = {
+	.mr1	= MR1_BL_8_BT_SEQ_WRAP_EN_NWR_8,
+	.mr2	= 0x6,
+	.mr3	= 0x1,
+	.mr10	= MR10_ZQ_ZQINIT,
+	.mr16	= MR16_REF_FULL_ARRAY
+};
+
+void __weak emif_get_ext_phy_ctrl_const_regs(u32 emif_nr,
+					     const u32 **regs,
+					     u32 *size)
+{
+	switch (omap_revision()) {
+	case OMAP5430_ES1_0:
+	case OMAP5430_ES2_0:
+		*regs = ext_phy_ctrl_const_base;
+		*size = ARRAY_SIZE(ext_phy_ctrl_const_base);
+		break;
+	case OMAP5432_ES1_0:
+		*regs = ddr3_ext_phy_ctrl_const_base_es1;
+		*size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es1);
+		break;
+	case OMAP5432_ES2_0:
+		*regs = ddr3_ext_phy_ctrl_const_base_es2;
+		*size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es2);
+		break;
+	case DRA752_ES1_0:
+	case DRA752_ES1_1:
+	case DRA752_ES2_0:
+		if (emif_nr == 1) {
+			*regs = dra_ddr3_ext_phy_ctrl_const_base_es1_emif1;
+			*size =
+			ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_es1_emif1);
+		} else {
+			*regs = dra_ddr3_ext_phy_ctrl_const_base_es1_emif2;
+			*size =
+			ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_es1_emif2);
+		}
+		break;
+	case DRA722_ES1_0:
+		*regs = dra_ddr3_ext_phy_ctrl_const_base_666MHz;
+		*size = ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_666MHz);
+		break;
+	case DRA722_ES2_0:
+		*regs = dra_ddr3_ext_phy_ctrl_const_base_666MHz_es2;
+		*size = ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_666MHz_es2);
+		break;
+	default:
+		*regs = ddr3_ext_phy_ctrl_const_base_es2;
+		*size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es2);
+
+	}
+}
+
+void get_lpddr2_mr_regs(const struct lpddr2_mr_regs **regs)
+{
+	*regs = &mr_regs;
+}
+
+static void do_ext_phy_settings_omap5(u32 base, const struct emif_regs *regs)
+{
+	u32 *ext_phy_ctrl_base = 0;
+	u32 *emif_ext_phy_ctrl_base = 0;
+	u32 emif_nr;
+	const u32 *ext_phy_ctrl_const_regs;
+	u32 i = 0;
+	u32 size;
+
+	emif_nr = (base == EMIF1_BASE) ? 1 : 2;
+
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1);
+	emif_ext_phy_ctrl_base = (u32 *) &(emif->emif_ddr_ext_phy_ctrl_1);
+
+	/* Configure external phy control timing registers */
+	for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) {
+		writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++);
+		/* Update shadow registers */
+		writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++);
+	}
+
+	/*
+	 * external phy 6-24 registers do not change with
+	 * ddr frequency
+	 */
+	emif_get_ext_phy_ctrl_const_regs(emif_nr,
+					 &ext_phy_ctrl_const_regs, &size);
+
+	for (i = 0; i < size; i++) {
+		writel(ext_phy_ctrl_const_regs[i],
+		       emif_ext_phy_ctrl_base++);
+		/* Update shadow registers */
+		writel(ext_phy_ctrl_const_regs[i],
+		       emif_ext_phy_ctrl_base++);
+	}
+}
+
+static void do_ext_phy_settings_dra7(u32 base, const struct emif_regs *regs)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+	u32 *emif_ext_phy_ctrl_base = 0;
+	u32 emif_nr;
+	const u32 *ext_phy_ctrl_const_regs;
+	u32 i, hw_leveling, size, phy;
+
+	emif_nr = (base == EMIF1_BASE) ? 1 : 2;
+
+	hw_leveling = regs->emif_rd_wr_lvl_rmp_ctl >> EMIF_REG_RDWRLVL_EN_SHIFT;
+	phy = regs->emif_ddr_phy_ctlr_1_init;
+
+	emif_ext_phy_ctrl_base = (u32 *)&(emif->emif_ddr_ext_phy_ctrl_1);
+
+	emif_get_ext_phy_ctrl_const_regs(emif_nr,
+					 &ext_phy_ctrl_const_regs, &size);
+
+	writel(ext_phy_ctrl_const_regs[0], &emif_ext_phy_ctrl_base[0]);
+	writel(ext_phy_ctrl_const_regs[0], &emif_ext_phy_ctrl_base[1]);
+
+	/*
+	 * Copy the predefined PHY register values
+	 * if leveling is disabled.
+	 */
+	if (phy & EMIF_DDR_PHY_CTRL_1_RDLVLGATE_MASK_MASK)
+		for (i = 1; i < 6; i++) {
+			writel(ext_phy_ctrl_const_regs[i],
+			       &emif_ext_phy_ctrl_base[i * 2]);
+			writel(ext_phy_ctrl_const_regs[i],
+			       &emif_ext_phy_ctrl_base[i * 2 + 1]);
+		}
+
+	if (phy & EMIF_DDR_PHY_CTRL_1_RDLVL_MASK_MASK)
+		for (i = 6; i < 11; i++) {
+			writel(ext_phy_ctrl_const_regs[i],
+			       &emif_ext_phy_ctrl_base[i * 2]);
+			writel(ext_phy_ctrl_const_regs[i],
+			       &emif_ext_phy_ctrl_base[i * 2 + 1]);
+		}
+
+	if (phy & EMIF_DDR_PHY_CTRL_1_WRLVL_MASK_MASK)
+		for (i = 11; i < 25; i++) {
+			writel(ext_phy_ctrl_const_regs[i],
+			       &emif_ext_phy_ctrl_base[i * 2]);
+			writel(ext_phy_ctrl_const_regs[i],
+			       &emif_ext_phy_ctrl_base[i * 2 + 1]);
+		}
+
+	if (hw_leveling) {
+		/*
+		 * Write the init value for HW levling to occur
+		 */
+		for (i = 21; i < 35; i++) {
+			writel(ext_phy_ctrl_const_regs[i],
+			       &emif_ext_phy_ctrl_base[i * 2]);
+			writel(ext_phy_ctrl_const_regs[i],
+			       &emif_ext_phy_ctrl_base[i * 2 + 1]);
+		}
+	}
+}
+
+void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
+{
+	if (is_omap54xx())
+		do_ext_phy_settings_omap5(base, regs);
+	else
+		do_ext_phy_settings_dra7(base, regs);
+}
+
+#ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
+static const struct lpddr2_ac_timings timings_jedec_532_mhz = {
+	.max_freq	= 532000000,
+	.RL		= 8,
+	.tRPab		= 21,
+	.tRCD		= 18,
+	.tWR		= 15,
+	.tRASmin	= 42,
+	.tRRD		= 10,
+	.tWTRx2		= 15,
+	.tXSR		= 140,
+	.tXPx2		= 15,
+	.tRFCab		= 130,
+	.tRTPx2		= 15,
+	.tCKE		= 3,
+	.tCKESR		= 15,
+	.tZQCS		= 90,
+	.tZQCL		= 360,
+	.tZQINIT	= 1000,
+	.tDQSCKMAXx2	= 11,
+	.tRASmax	= 70,
+	.tFAW		= 50
+};
+
+static const struct lpddr2_min_tck min_tck = {
+	.tRL		= 3,
+	.tRP_AB		= 3,
+	.tRCD		= 3,
+	.tWR		= 3,
+	.tRAS_MIN	= 3,
+	.tRRD		= 2,
+	.tWTR		= 2,
+	.tXP		= 2,
+	.tRTP		= 2,
+	.tCKE		= 3,
+	.tCKESR		= 3,
+	.tFAW		= 8
+};
+
+static const struct lpddr2_ac_timings *ac_timings[MAX_NUM_SPEEDBINS] = {
+	&timings_jedec_532_mhz
+};
+
+static const struct lpddr2_device_timings dev_4G_S4_timings = {
+	.ac_timings	= ac_timings,
+	.min_tck	= &min_tck,
+};
+
+/*
+ * List of status registers to be controlled back to control registers
+ * after initial leveling
+ * readreg, writereg
+ */
+const struct read_write_regs omap5_bug_00339_regs[] = {
+	{ 8,  5 },
+	{ 9,  6 },
+	{ 10, 7 },
+	{ 14, 8 },
+	{ 15, 9 },
+	{ 16, 10 },
+	{ 11, 2 },
+	{ 12, 3 },
+	{ 13, 4 },
+	{ 17, 11 },
+	{ 18, 12 },
+	{ 19, 13 },
+};
+
+const struct read_write_regs dra_bug_00339_regs[] = {
+	{ 7,  7 },
+	{ 8,  8 },
+	{ 9,  9 },
+	{ 10, 10 },
+	{ 11, 11 },
+	{ 12, 2 },
+	{ 13, 3 },
+	{ 14, 4 },
+	{ 15, 5 },
+	{ 16, 6 },
+	{ 17, 12 },
+	{ 18, 13 },
+	{ 19, 14 },
+	{ 20, 15 },
+	{ 21, 16 },
+	{ 22, 17 },
+	{ 23, 18 },
+	{ 24, 19 },
+	{ 25, 20 },
+	{ 26, 21}
+};
+
+const struct read_write_regs *get_bug_regs(u32 *iterations)
+{
+	const struct read_write_regs *bug_00339_regs_ptr = NULL;
+
+	switch (omap_revision()) {
+	case OMAP5430_ES1_0:
+	case OMAP5430_ES2_0:
+	case OMAP5432_ES1_0:
+	case OMAP5432_ES2_0:
+		bug_00339_regs_ptr = omap5_bug_00339_regs;
+		*iterations = sizeof(omap5_bug_00339_regs)/
+			     sizeof(omap5_bug_00339_regs[0]);
+		break;
+	case DRA752_ES1_0:
+	case DRA752_ES1_1:
+	case DRA752_ES2_0:
+	case DRA722_ES1_0:
+	case DRA722_ES2_0:
+		bug_00339_regs_ptr = dra_bug_00339_regs;
+		*iterations = sizeof(dra_bug_00339_regs)/
+			     sizeof(dra_bug_00339_regs[0]);
+		break;
+	default:
+		printf("\n Error: UnKnown SOC");
+	}
+
+	return bug_00339_regs_ptr;
+}
+
+void emif_get_device_timings_sdp(u32 emif_nr,
+		const struct lpddr2_device_timings **cs0_device_timings,
+		const struct lpddr2_device_timings **cs1_device_timings)
+{
+	/* Identical devices on EMIF1 & EMIF2 */
+	*cs0_device_timings = &dev_4G_S4_timings;
+	*cs1_device_timings = &dev_4G_S4_timings;
+}
+
+void emif_get_device_timings(u32 emif_nr,
+		const struct lpddr2_device_timings **cs0_device_timings,
+		const struct lpddr2_device_timings **cs1_device_timings)
+	__attribute__((weak, alias("emif_get_device_timings_sdp")));
+
+#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */
diff --git a/arch/arm/mach-omap2/omap5/sec-fxns.c b/arch/arm/mach-omap2/omap5/sec-fxns.c
new file mode 100644
index 0000000..33d4ea4
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/sec-fxns.c
@@ -0,0 +1,126 @@
+/*
+ *
+ * Security related functions for OMAP5 class devices
+ *
+ * (C) Copyright 2016
+ * Texas Instruments, <www.ti.com>
+ *
+ * Daniel Allred <d-allred@ti.com>
+ * Harinarayan Bhatta <harinarayan@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <stdarg.h>
+
+#include <asm/arch/sys_proto.h>
+#include <asm/omap_common.h>
+#include <asm/omap_sec_common.h>
+#include <asm/spl.h>
+#include <spl.h>
+
+/* Index for signature PPA-based TI HAL APIs */
+#define PPA_HAL_SERVICES_START_INDEX        (0x200)
+#define PPA_SERV_HAL_SETUP_SEC_RESVD_REGION (PPA_HAL_SERVICES_START_INDEX + 25)
+#define PPA_SERV_HAL_SETUP_EMIF_FW_REGION   (PPA_HAL_SERVICES_START_INDEX + 26)
+#define PPA_SERV_HAL_LOCK_EMIF_FW           (PPA_HAL_SERVICES_START_INDEX + 27)
+
+static u32 get_sec_mem_start(void)
+{
+	u32 sec_mem_start = CONFIG_TI_SECURE_EMIF_REGION_START;
+	u32 sec_mem_size = CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE;
+	/*
+	 * Total reserved region is all contiguous with protected
+	 * region coming first, followed by the non-secure region.
+	 * If 0x0 start address is given, we simply put the reserved
+	 * region at the end of the external DRAM.
+	 */
+	if (sec_mem_start == 0)
+		sec_mem_start =
+			(CONFIG_SYS_SDRAM_BASE +
+			(omap_sdram_size() - sec_mem_size));
+	return sec_mem_start;
+}
+
+int secure_emif_firewall_setup(uint8_t region_num, uint32_t start_addr,
+			       uint32_t size, uint32_t access_perm,
+			       uint32_t initiator_perm)
+{
+	int result = 1;
+
+	/*
+	 * Call PPA HAL API to do any other general firewall
+	 * configuration for regions 1-6 of the EMIF firewall.
+	 */
+	debug("%s: regionNum = %x, startAddr = %x, size = %x", __func__,
+	      region_num, start_addr, size);
+
+	result = secure_rom_call(
+			PPA_SERV_HAL_SETUP_EMIF_FW_REGION, 0, 0, 4,
+			(start_addr & 0xFFFFFFF0) | (region_num & 0x0F),
+			size, access_perm, initiator_perm);
+
+	if (result != 0) {
+		puts("Secure EMIF Firewall Setup failed!\n");
+		debug("Return Value = %x\n", result);
+	}
+
+	return result;
+}
+
+#if	(CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE <  \
+	CONFIG_TI_SECURE_EMIF_PROTECTED_REGION_SIZE)
+#error	"TI Secure EMIF: Protected size cannot be larger than total size."
+#endif
+int secure_emif_reserve(void)
+{
+	int result = 1;
+	u32 sec_mem_start = get_sec_mem_start();
+	u32 sec_prot_size = CONFIG_TI_SECURE_EMIF_PROTECTED_REGION_SIZE;
+
+	/* If there is no protected region, there is no reservation to make */
+	if (sec_prot_size == 0)
+		return 0;
+
+	/*
+	 * Call PPA HAL API to reserve a chunk of EMIF SDRAM
+	 * for secure world use. This region should be carved out
+	 * from use by any public code. EMIF firewall region 7
+	 * will be used to protect this block of memory.
+	 */
+	result = secure_rom_call(
+			PPA_SERV_HAL_SETUP_SEC_RESVD_REGION,
+			0, 0, 2, sec_mem_start, sec_prot_size);
+
+	if (result != 0) {
+		puts("SDRAM Firewall: Secure memory reservation failed!\n");
+		debug("Return Value = %x\n", result);
+	}
+
+	return result;
+}
+
+int secure_emif_firewall_lock(void)
+{
+	int result = 1;
+
+	/*
+	 * Call PPA HAL API to lock the EMIF firewall configurations.
+	 * After this API is called, none of the PPA HAL APIs for
+	 * configuring the EMIF firewalls will be usable again (that
+	 * is, calls to those APIs will return failure and have no
+	 * effect).
+	 */
+
+	result = secure_rom_call(
+			PPA_SERV_HAL_LOCK_EMIF_FW,
+			0, 0, 0);
+
+	if (result != 0) {
+		puts("Secure EMIF Firewall Lock failed!\n");
+		debug("Return Value = %x\n", result);
+	}
+
+	return result;
+}
diff --git a/arch/arm/mach-omap2/pipe3-phy.c b/arch/arm/mach-omap2/pipe3-phy.c
new file mode 100644
index 0000000..e02e3ec
--- /dev/null
+++ b/arch/arm/mach-omap2/pipe3-phy.c
@@ -0,0 +1,231 @@
+/*
+ * TI PIPE3 PHY
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <sata.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include "pipe3-phy.h"
+
+/* PLLCTRL Registers */
+#define PLL_STATUS              0x00000004
+#define PLL_GO                  0x00000008
+#define PLL_CONFIGURATION1      0x0000000C
+#define PLL_CONFIGURATION2      0x00000010
+#define PLL_CONFIGURATION3      0x00000014
+#define PLL_CONFIGURATION4      0x00000020
+
+#define PLL_REGM_MASK           0x001FFE00
+#define PLL_REGM_SHIFT          9
+#define PLL_REGM_F_MASK         0x0003FFFF
+#define PLL_REGM_F_SHIFT        0
+#define PLL_REGN_MASK           0x000001FE
+#define PLL_REGN_SHIFT          1
+#define PLL_SELFREQDCO_MASK     0x0000000E
+#define PLL_SELFREQDCO_SHIFT    1
+#define PLL_SD_MASK             0x0003FC00
+#define PLL_SD_SHIFT            10
+#define SET_PLL_GO              0x1
+#define PLL_TICOPWDN            BIT(16)
+#define PLL_LDOPWDN             BIT(15)
+#define PLL_LOCK                0x2
+#define PLL_IDLE                0x1
+
+/* PHY POWER CONTROL Register */
+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK         0x003FC000
+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT        0xE
+
+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK        0xFFC00000
+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT       0x16
+
+#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON       0x3
+#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF      0x0
+
+
+#define PLL_IDLE_TIME   100     /* in milliseconds */
+#define PLL_LOCK_TIME   100     /* in milliseconds */
+
+static inline u32 omap_pipe3_readl(void __iomem *addr, unsigned offset)
+{
+	return __raw_readl(addr + offset);
+}
+
+static inline void omap_pipe3_writel(void __iomem *addr, unsigned offset,
+		u32 data)
+{
+	__raw_writel(data, addr + offset);
+}
+
+static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(struct omap_pipe3
+									*pipe3)
+{
+	u32 rate;
+	struct pipe3_dpll_map *dpll_map = pipe3->dpll_map;
+
+	rate = get_sys_clk_freq();
+
+	for (; dpll_map->rate; dpll_map++) {
+		if (rate == dpll_map->rate)
+			return &dpll_map->params;
+	}
+
+	printf("%s: No DPLL configuration for %u Hz SYS CLK\n",
+	       __func__, rate);
+	return NULL;
+}
+
+
+static int omap_pipe3_wait_lock(struct omap_pipe3 *phy)
+{
+	u32 val;
+	int timeout = PLL_LOCK_TIME;
+
+	do {
+		mdelay(1);
+		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
+		if (val & PLL_LOCK)
+			break;
+	} while (--timeout);
+
+	if (!(val & PLL_LOCK)) {
+		printf("%s: DPLL failed to lock\n", __func__);
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static int omap_pipe3_dpll_program(struct omap_pipe3 *phy)
+{
+	u32                     val;
+	struct pipe3_dpll_params *dpll_params;
+
+	dpll_params = omap_pipe3_get_dpll_params(phy);
+	if (!dpll_params) {
+		printf("%s: Invalid DPLL parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
+	val &= ~PLL_REGN_MASK;
+	val |= dpll_params->n << PLL_REGN_SHIFT;
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
+
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
+	val &= ~PLL_SELFREQDCO_MASK;
+	val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
+
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
+	val &= ~PLL_REGM_MASK;
+	val |= dpll_params->m << PLL_REGM_SHIFT;
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
+
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
+	val &= ~PLL_REGM_F_MASK;
+	val |= dpll_params->mf << PLL_REGM_F_SHIFT;
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
+
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
+	val &= ~PLL_SD_MASK;
+	val |= dpll_params->sd << PLL_SD_SHIFT;
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
+
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
+
+	return omap_pipe3_wait_lock(phy);
+}
+
+static void omap_control_phy_power(struct omap_pipe3 *phy, int on)
+{
+	u32 val, rate;
+
+	val = readl(phy->power_reg);
+
+	rate = get_sys_clk_freq();
+	rate = rate/1000000;
+
+	if (on) {
+		val &= ~(OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK |
+				OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK);
+		val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON <<
+			OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT;
+		val |= rate <<
+			OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT;
+	} else {
+		val &= ~OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK;
+		val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF <<
+			OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT;
+	}
+
+	writel(val, phy->power_reg);
+}
+
+int phy_pipe3_power_on(struct omap_pipe3 *phy)
+{
+	int ret;
+	u32 val;
+
+	/* Program the DPLL only if not locked */
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
+	if (!(val & PLL_LOCK)) {
+		ret = omap_pipe3_dpll_program(phy);
+		if (ret)
+			return ret;
+	} else {
+		/* else just bring it out of IDLE mode */
+		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
+		if (val & PLL_IDLE) {
+			val &= ~PLL_IDLE;
+			omap_pipe3_writel(phy->pll_ctrl_base,
+					  PLL_CONFIGURATION2, val);
+			ret = omap_pipe3_wait_lock(phy);
+			if (ret)
+				return ret;
+		}
+	}
+
+	/* Power up the PHY */
+	omap_control_phy_power(phy, 1);
+
+	return 0;
+}
+
+int phy_pipe3_power_off(struct omap_pipe3 *phy)
+{
+	u32 val;
+	int timeout = PLL_IDLE_TIME;
+
+	/* Power down the PHY */
+	omap_control_phy_power(phy, 0);
+
+	/* Put DPLL in IDLE mode */
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
+	val |= PLL_IDLE;
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
+
+	/* wait for LDO and Oscillator to power down */
+	do {
+		mdelay(1);
+		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
+		if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN))
+			break;
+	} while (--timeout);
+
+	if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) {
+		printf("%s: Failed to power down DPLL: PLL_STATUS 0x%x\n",
+		       __func__, val);
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
diff --git a/arch/arm/mach-omap2/pipe3-phy.h b/arch/arm/mach-omap2/pipe3-phy.h
new file mode 100644
index 0000000..441f49a
--- /dev/null
+++ b/arch/arm/mach-omap2/pipe3-phy.h
@@ -0,0 +1,36 @@
+/*
+ * TI PIPE3 PHY
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __OMAP_PIPE3_PHY_H
+#define __OMAP_PIPE3_PHY_H
+
+struct pipe3_dpll_params {
+	u16     m;
+	u8      n;
+	u8      freq:3;
+	u8      sd;
+	u32     mf;
+};
+
+struct pipe3_dpll_map {
+	unsigned long rate;
+	struct pipe3_dpll_params params;
+};
+
+struct omap_pipe3 {
+	void __iomem            *pll_ctrl_base;
+	void __iomem		*power_reg;
+	struct pipe3_dpll_map   *dpll_map;
+};
+
+
+int phy_pipe3_power_on(struct omap_pipe3 *phy);
+int phy_pipe3_power_off(struct omap_pipe3 *pipe3);
+
+#endif /* __OMAP_PIPE3_PHY_H */
diff --git a/arch/arm/mach-omap2/reset.c b/arch/arm/mach-omap2/reset.c
new file mode 100644
index 0000000..91ad031
--- /dev/null
+++ b/arch/arm/mach-omap2/reset.c
@@ -0,0 +1,29 @@
+/*
+ *
+ * Common layer for reset related functionality of OMAP based socs.
+ *
+ * (C) Copyright 2012
+ * Texas Instruments, <www.ti.com>
+ *
+ * Sricharan R <r.sricharan@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <config.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <linux/compiler.h>
+
+void __weak reset_cpu(unsigned long ignored)
+{
+	writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL);
+}
+
+u32 __weak warm_reset(void)
+{
+	return (readl(PRM_RSTST) & PRM_RSTST_WARM_RESET_MASK);
+}
+
+void __weak setup_warmreset_time(void)
+{
+}
diff --git a/arch/arm/mach-omap2/sata.c b/arch/arm/mach-omap2/sata.c
new file mode 100644
index 0000000..2c2d1bc
--- /dev/null
+++ b/arch/arm/mach-omap2/sata.c
@@ -0,0 +1,93 @@
+/*
+ * TI SATA platform driver
+ *
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <ahci.h>
+#include <scsi.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sata.h>
+#include <sata.h>
+#include <asm/io.h>
+#include "pipe3-phy.h"
+
+static struct pipe3_dpll_map dpll_map_sata[] = {
+	{12000000, {1000, 7, 4, 6, 0} },        /* 12 MHz */
+	{16800000, {714, 7, 4, 6, 0} },         /* 16.8 MHz */
+	{19200000, {625, 7, 4, 6, 0} },         /* 19.2 MHz */
+	{20000000, {600, 7, 4, 6, 0} },         /* 20 MHz */
+	{26000000, {461, 7, 4, 6, 0} },         /* 26 MHz */
+	{38400000, {312, 7, 4, 6, 0} },         /* 38.4 MHz */
+	{ },                                    /* Terminator */
+};
+
+struct omap_pipe3 sata_phy = {
+	.pll_ctrl_base = (void __iomem *)TI_SATA_PLLCTRL_BASE,
+	/* .power_reg is updated at runtime */
+	.dpll_map = dpll_map_sata,
+};
+
+int init_sata(int dev)
+{
+	int ret;
+	u32 val;
+
+	u32 const clk_domains_sata[] = {
+		0
+	};
+
+	u32 const clk_modules_hw_auto_sata[] = {
+		(*prcm)->cm_l3init_ocp2scp3_clkctrl,
+		0
+	};
+
+	u32 const clk_modules_explicit_en_sata[] = {
+		(*prcm)->cm_l3init_sata_clkctrl,
+		0
+	};
+
+	do_enable_clocks(clk_domains_sata,
+			 clk_modules_hw_auto_sata,
+			 clk_modules_explicit_en_sata,
+			 0);
+
+	/* Enable optional functional clock for SATA */
+	setbits_le32((*prcm)->cm_l3init_sata_clkctrl,
+		     SATA_CLKCTRL_OPTFCLKEN_MASK);
+
+	sata_phy.power_reg = (void __iomem *)(*ctrl)->control_phy_power_sata;
+
+	/* Power up the PHY */
+	phy_pipe3_power_on(&sata_phy);
+
+	/* Enable SATA module, No Idle, No Standby */
+	val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO;
+	writel(val, TI_SATA_WRAPPER_BASE + TI_SATA_SYSCONFIG);
+
+	ret = ahci_init((void __iomem *)DWC_AHSATA_BASE);
+
+	return ret;
+}
+
+int reset_sata(int dev)
+{
+	return 0;
+}
+
+/* On OMAP platforms SATA provides the SCSI subsystem */
+void scsi_init(void)
+{
+	init_sata(0);
+	scsi_scan(1);
+}
+
+void scsi_bus_reset(void)
+{
+	ahci_reset((void __iomem *)DWC_AHSATA_BASE);
+	ahci_init((void __iomem *)DWC_AHSATA_BASE);
+}
diff --git a/arch/arm/mach-omap2/sec-common.c b/arch/arm/mach-omap2/sec-common.c
new file mode 100644
index 0000000..246a239
--- /dev/null
+++ b/arch/arm/mach-omap2/sec-common.c
@@ -0,0 +1,139 @@
+/*
+ *
+ * Common security related functions for OMAP devices
+ *
+ * (C) Copyright 2016
+ * Texas Instruments, <www.ti.com>
+ *
+ * Daniel Allred <d-allred@ti.com>
+ * Andreas Dannenberg <dannenberg@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <stdarg.h>
+
+#include <asm/arch/sys_proto.h>
+#include <asm/omap_common.h>
+#include <asm/omap_sec_common.h>
+#include <asm/spl.h>
+#include <spl.h>
+
+/* Index for signature verify ROM API */
+#define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX	(0x0000000E)
+
+static uint32_t secure_rom_call_args[5] __aligned(ARCH_DMA_MINALIGN);
+
+u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...)
+{
+	int i;
+	u32 num_args;
+	va_list ap;
+
+	va_start(ap, flag);
+
+	num_args = va_arg(ap, u32);
+
+	if (num_args > 4)
+		return 1;
+
+	/* Copy args to aligned args structure */
+	for (i = 0; i < num_args; i++)
+		secure_rom_call_args[i + 1] = va_arg(ap, u32);
+
+	secure_rom_call_args[0] = num_args;
+
+	va_end(ap);
+
+	/* if data cache is enabled, flush the aligned args structure */
+	flush_dcache_range(
+		(unsigned int)&secure_rom_call_args[0],
+		(unsigned int)&secure_rom_call_args[0] +
+		roundup(sizeof(secure_rom_call_args), ARCH_DMA_MINALIGN));
+
+	return omap_smc_sec(service, proc_id, flag, secure_rom_call_args);
+}
+
+static u32 find_sig_start(char *image, size_t size)
+{
+	char *image_end = image + size;
+	char *sig_start_magic = "CERT_";
+	int magic_str_len = strlen(sig_start_magic);
+	char *ch;
+
+	while (--image_end > image) {
+		if (*image_end == '_') {
+			ch = image_end - magic_str_len + 1;
+			if (!strncmp(ch, sig_start_magic, magic_str_len))
+				return (u32)ch;
+		}
+	}
+	return 0;
+}
+
+int secure_boot_verify_image(void **image, size_t *size)
+{
+	int result = 1;
+	u32 cert_addr, sig_addr;
+	size_t cert_size;
+
+	/* Perform cache writeback on input buffer */
+	flush_dcache_range(
+		(u32)*image,
+		(u32)*image + roundup(*size, ARCH_DMA_MINALIGN));
+
+	cert_addr = (uint32_t)*image;
+	sig_addr = find_sig_start((char *)*image, *size);
+
+	if (sig_addr == 0) {
+		printf("No signature found in image!\n");
+		result = 1;
+		goto auth_exit;
+	}
+
+	*size = sig_addr - cert_addr;	/* Subtract out the signature size */
+	cert_size = *size;
+
+	/* Check if image load address is 32-bit aligned */
+	if (!IS_ALIGNED(cert_addr, 4)) {
+		printf("Image is not 4-byte aligned!\n");
+		result = 1;
+		goto auth_exit;
+	}
+
+	/* Image size also should be multiple of 4 */
+	if (!IS_ALIGNED(cert_size, 4)) {
+		printf("Image size is not 4-byte aligned!\n");
+		result = 1;
+		goto auth_exit;
+	}
+
+	/* Call ROM HAL API to verify certificate signature */
+	debug("%s: load_addr = %x, size = %x, sig_addr = %x\n", __func__,
+	      cert_addr, cert_size, sig_addr);
+
+	result = secure_rom_call(
+		API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX, 0, 0,
+		4, cert_addr, cert_size, sig_addr, 0xFFFFFFFF);
+auth_exit:
+	if (result != 0) {
+		printf("Authentication failed!\n");
+		printf("Return Value = %08X\n", result);
+		hang();
+	}
+
+	/*
+	 * Output notification of successful authentication as well the name of
+	 * the signing certificate used to re-assure the user that the secure
+	 * code is being processed as expected. However suppress any such log
+	 * output in case of building for SPL and booting via YMODEM. This is
+	 * done to avoid disturbing the YMODEM serial protocol transactions.
+	 */
+	if (!(IS_ENABLED(CONFIG_SPL_BUILD) &&
+	      IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) &&
+	      spl_boot_device() == BOOT_DEVICE_UART))
+		printf("Authentication passed: %s\n", (char *)sig_addr);
+
+	return result;
+}
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
new file mode 100644
index 0000000..49e3a97
--- /dev/null
+++ b/arch/arm/mach-omap2/timer.c
@@ -0,0 +1,103 @@
+/*
+ * (C) Copyright 2008
+ * Texas Instruments
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Syed Moahmmed Khasim <khasim@ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE;
+
+/*
+ * Nothing really to do with interrupts, just starts up a counter.
+ */
+
+#define TIMER_CLOCK		(V_SCLK / (2 << CONFIG_SYS_PTV))
+#define TIMER_OVERFLOW_VAL	0xffffffff
+#define TIMER_LOAD_VAL		0
+
+int timer_init(void)
+{
+	/* start the counter ticking up, reload value on overflow */
+	writel(TIMER_LOAD_VAL, &timer_base->tldr);
+	/* enable timer */
+	writel((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST,
+		&timer_base->tclr);
+
+	return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+/* delay x useconds */
+void __udelay(unsigned long usec)
+{
+	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
+	unsigned long now, last = readl(&timer_base->tcrr);
+
+	while (tmo > 0) {
+		now = readl(&timer_base->tcrr);
+		if (last > now) /* count up timer overflow */
+			tmo -= TIMER_OVERFLOW_VAL - last + now + 1;
+		else
+			tmo -= now - last;
+		last = now;
+	}
+}
+
+ulong get_timer_masked(void)
+{
+	/* current tick value */
+	ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
+
+	if (now >= gd->arch.lastinc) {	/* normal mode (non roll) */
+		/* move stamp fordward with absoulte diff ticks */
+		gd->arch.tbl += (now - gd->arch.lastinc);
+	} else {	/* we have rollover of incrementer */
+		gd->arch.tbl += ((TIMER_OVERFLOW_VAL / (TIMER_CLOCK /
+				CONFIG_SYS_HZ)) - gd->arch.lastinc) + now;
+	}
+	gd->arch.lastinc = now;
+	return gd->arch.tbl;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	return CONFIG_SYS_HZ;
+}
diff --git a/arch/arm/mach-omap2/u-boot-spl.lds b/arch/arm/mach-omap2/u-boot-spl.lds
new file mode 100644
index 0000000..8fec715
--- /dev/null
+++ b/arch/arm/mach-omap2/u-boot-spl.lds
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *	Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
+		LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+		LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	.text      :
+	{
+		__start = .;
+		*(.vectors)
+		arch/arm/cpu/armv7/start.o	(.text*)
+		*(.text*)
+	} >.sram
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+	. = ALIGN(4);
+	.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+
+	. = ALIGN(4);
+	.u_boot_list : {
+		KEEP(*(SORT(.u_boot_list*)));
+	} >.sram
+
+	. = ALIGN(4);
+	__image_copy_end = .;
+
+	.end :
+	{
+		*(.__end)
+	}
+
+	.bss :
+	{
+		. = ALIGN(4);
+		__bss_start = .;
+		*(.bss*)
+		. = ALIGN(4);
+		__bss_end = .;
+	} >.sdram
+}
diff --git a/arch/arm/mach-omap2/utils.c b/arch/arm/mach-omap2/utils.c
new file mode 100644
index 0000000..2d03ebf
--- /dev/null
+++ b/arch/arm/mach-omap2/utils.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2011 Linaro Limited
+ * Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+static void do_cancel_out(u32 *num, u32 *den, u32 factor)
+{
+	while (1) {
+		if (((*num)/factor*factor == (*num)) &&
+		   ((*den)/factor*factor == (*den))) {
+			(*num) /= factor;
+			(*den) /= factor;
+		} else
+			break;
+	}
+}
+
+/*
+ * Cancel out the denominator and numerator of a fraction
+ * to get smaller numerator and denominator.
+ */
+void cancel_out(u32 *num, u32 *den, u32 den_limit)
+{
+	do_cancel_out(num, den, 2);
+	do_cancel_out(num, den, 3);
+	do_cancel_out(num, den, 5);
+	do_cancel_out(num, den, 7);
+	do_cancel_out(num, den, 11);
+	do_cancel_out(num, den, 13);
+	do_cancel_out(num, den, 17);
+	while ((*den) > den_limit) {
+		*num /= 2;
+		/*
+		 * Round up the denominator so that the final fraction
+		 * (num/den) is always <= the desired value
+		 */
+		*den = (*den + 1) / 2;
+	}
+}
+
+__weak void omap_die_id(unsigned int *die_id)
+{
+	die_id[0] = die_id[1] = die_id[2] = die_id[3] = 0;
+}
+
+void omap_die_id_serial(void)
+{
+	unsigned int die_id[4] = { 0 };
+	char serial_string[17] = { 0 };
+
+	omap_die_id((unsigned int *)&die_id);
+
+	if (!getenv("serial#")) {
+		snprintf(serial_string, sizeof(serial_string),
+			"%08x%08x", die_id[0], die_id[3]);
+
+		setenv("serial#", serial_string);
+	}
+}
+
+void omap_die_id_get_board_serial(struct tag_serialnr *serialnr)
+{
+	char *serial_string;
+	unsigned long long serial;
+
+	serial_string = getenv("serial#");
+
+	if (serial_string) {
+		serial = simple_strtoull(serial_string, NULL, 16);
+
+		serialnr->high = (unsigned int) (serial >> 32);
+		serialnr->low = (unsigned int) (serial & 0xffffffff);
+	} else {
+		serialnr->high = 0;
+		serialnr->low = 0;
+	}
+}
+
+void omap_die_id_usbethaddr(void)
+{
+	unsigned int die_id[4] = { 0 };
+	unsigned char mac[6] = { 0 };
+
+	omap_die_id((unsigned int *)&die_id);
+
+	if (!getenv("usbethaddr")) {
+		/*
+		 * Create a fake MAC address from the processor ID code.
+		 * First byte is 0x02 to signify locally administered.
+		 */
+		mac[0] = 0x02;
+		mac[1] = die_id[3] & 0xff;
+		mac[2] = die_id[2] & 0xff;
+		mac[3] = die_id[1] & 0xff;
+		mac[4] = die_id[0] & 0xff;
+		mac[5] = (die_id[0] >> 8) & 0xff;
+
+		eth_setenv_enetaddr("usbethaddr", mac);
+	}
+}
+
+void omap_die_id_display(void)
+{
+	unsigned int die_id[4] = { 0 };
+
+	omap_die_id(die_id);
+
+	printf("OMAP die ID: %08x%08x%08x%08x\n", die_id[3], die_id[2],
+		die_id[1], die_id[0]);
+}
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
new file mode 100644
index 0000000..a68f1d1
--- /dev/null
+++ b/arch/arm/mach-omap2/vc.c
@@ -0,0 +1,151 @@
+/*
+ * Voltage Controller implementation for OMAP
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *	Nishanth Menon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/omap_common.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/clock.h>
+
+/*
+ * Define Master code if there are multiple masters on the I2C_SR bus.
+ * Normally not required
+ */
+#ifndef CONFIG_OMAP_VC_I2C_HS_MCODE
+#define CONFIG_OMAP_VC_I2C_HS_MCODE 0x0
+#endif
+
+/* Register defines and masks for VC IP Block */
+/* PRM_VC_CFG_I2C_MODE */
+#define PRM_VC_CFG_I2C_MODE_DFILTEREN_BIT	(0x1 << 6)
+#define PRM_VC_CFG_I2C_MODE_SRMODEEN_BIT	(0x1 << 4)
+#define PRM_VC_CFG_I2C_MODE_HSMODEEN_BIT	(0x1 << 3)
+#define PRM_VC_CFG_I2C_MODE_HSMCODE_SHIFT	0x0
+#define PRM_VC_CFG_I2C_MODE_HSMCODE_MASK	0x3
+
+/* PRM_VC_CFG_I2C_CLK */
+#define PRM_VC_CFG_I2C_CLK_HSCLL_SHIFT		24
+#define PRM_VC_CFG_I2C_CLK_HSCLL_MASK		0xFF
+#define PRM_VC_CFG_I2C_CLK_HSCLH_SHIFT		16
+#define PRM_VC_CFG_I2C_CLK_HSCLH_MASK		0xFF
+#define PRM_VC_CFG_I2C_CLK_SCLH_SHIFT		0
+#define PRM_VC_CFG_I2C_CLK_SCLH_MASK		0xFF
+#define PRM_VC_CFG_I2C_CLK_SCLL_SHIFT		8
+#define PRM_VC_CFG_I2C_CLK_SCLL_MASK		(0xFF << 8)
+
+/* PRM_VC_VAL_BYPASS */
+#define PRM_VC_VAL_BYPASS_VALID_BIT		(0x1 << 24)
+#define PRM_VC_VAL_BYPASS_SLAVEADDR_SHIFT	0
+#define PRM_VC_VAL_BYPASS_SLAVEADDR_MASK	0x7F
+#define PRM_VC_VAL_BYPASS_REGADDR_SHIFT		8
+#define PRM_VC_VAL_BYPASS_REGADDR_MASK		0xFF
+#define PRM_VC_VAL_BYPASS_DATA_SHIFT		16
+#define PRM_VC_VAL_BYPASS_DATA_MASK		0xFF
+
+/**
+ * omap_vc_init() - Initialization for Voltage controller
+ * @speed_khz: I2C buspeed in KHz
+ */
+static void omap_vc_init(u16 speed_khz)
+{
+	u32 val;
+	u32 sys_clk_khz, cycles_hi, cycles_low;
+
+	sys_clk_khz = get_sys_clk_freq() / 1000;
+
+	if (speed_khz > 400) {
+		puts("higher speed requested - throttle to 400Khz\n");
+		speed_khz = 400;
+	}
+
+	/*
+	 * Setup the dedicated I2C controller for Voltage Control
+	 * I2C clk - high period 40% low period 60%
+	 */
+	speed_khz /= 10;
+	cycles_hi = sys_clk_khz * 4 / speed_khz;
+	cycles_low = sys_clk_khz * 6 / speed_khz;
+	/* values to be set in register - less by 5 & 7 respectively */
+	cycles_hi -= 5;
+	cycles_low -= 7;
+	val = (cycles_hi << PRM_VC_CFG_I2C_CLK_SCLH_SHIFT) |
+	       (cycles_low << PRM_VC_CFG_I2C_CLK_SCLL_SHIFT);
+	writel(val, (*prcm)->prm_vc_cfg_i2c_clk);
+
+	val = CONFIG_OMAP_VC_I2C_HS_MCODE <<
+		PRM_VC_CFG_I2C_MODE_HSMCODE_SHIFT;
+	/* No HS mode for now */
+	val &= ~PRM_VC_CFG_I2C_MODE_HSMODEEN_BIT;
+	writel(val, (*prcm)->prm_vc_cfg_i2c_mode);
+}
+
+/**
+ * omap_vc_bypass_send_value() - Send a data using VC Bypass command
+ * @sa:		7 bit I2C slave address of the PMIC
+ * @reg_addr:	I2C register address(8 bit) address in PMIC
+ * @reg_data:	what 8 bit data to write
+ */
+int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data)
+{
+	/*
+	 * Unfortunately we need to loop here instead of a defined time
+	 * use arbitary large value
+	 */
+	u32 timeout = 0xFFFF;
+	u32 reg_val;
+
+	sa &= PRM_VC_VAL_BYPASS_SLAVEADDR_MASK;
+	reg_addr &= PRM_VC_VAL_BYPASS_REGADDR_MASK;
+	reg_data &= PRM_VC_VAL_BYPASS_DATA_MASK;
+
+	/* program VC to send data */
+	reg_val = sa << PRM_VC_VAL_BYPASS_SLAVEADDR_SHIFT |
+	    reg_addr << PRM_VC_VAL_BYPASS_REGADDR_SHIFT |
+	    reg_data << PRM_VC_VAL_BYPASS_DATA_SHIFT;
+	writel(reg_val, (*prcm)->prm_vc_val_bypass);
+
+	/* Signal VC to send data */
+	writel(reg_val | PRM_VC_VAL_BYPASS_VALID_BIT,
+				(*prcm)->prm_vc_val_bypass);
+
+	/* Wait on VC to complete transmission */
+	do {
+		reg_val = readl((*prcm)->prm_vc_val_bypass) &
+				PRM_VC_VAL_BYPASS_VALID_BIT;
+		if (!reg_val)
+			break;
+
+		sdelay(100);
+	} while (--timeout);
+
+	/* Optional: cleanup PRM_IRQSTATUS_Ax */
+	/* In case we can do something about it in future.. */
+	if (!timeout)
+		return -1;
+
+	/* All good.. */
+	return 0;
+}
+
+void sri2c_init(void)
+{
+	static int sri2c = 1;
+
+	if (sri2c) {
+		omap_vc_init(PRM_VC_I2C_CHANNEL_FREQ_KHZ);
+		sri2c = 0;
+	}
+	return;
+}