TX6 Release 2013-04-22
authorLothar Waßmann <LW@KARO-electronics.de>
Mon, 22 Apr 2013 10:39:49 +0000 (12:39 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Mon, 22 Apr 2013 10:39:49 +0000 (12:39 +0200)
156 files changed:
1  2 
.gitignore
Makefile
arch/arm/config.mk
arch/arm/cpu/arm926ejs/mxs/mxs.c
arch/arm/cpu/arm926ejs/mxs/spl_boot.c
arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
arch/arm/cpu/arm926ejs/mxs/timer.c
arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd
arch/arm/cpu/armv7/am33xx/Makefile
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock.c
arch/arm/cpu/armv7/am33xx/elm.c
arch/arm/cpu/armv7/am33xx/sys_info.c
arch/arm/cpu/armv7/cache_v7.c
arch/arm/cpu/armv7/cpu.c
arch/arm/cpu/armv7/mx5/clock.c
arch/arm/cpu/armv7/mx5/lowlevel_init.S
arch/arm/cpu/armv7/mx5/soc.c
arch/arm/cpu/armv7/mx6/clock.c
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/cpu/armv7/omap-common/boot-common.c
arch/arm/cpu/armv7/omap-common/lowlevel_init.S
arch/arm/cpu/armv7/omap-common/timer.c
arch/arm/cpu/armv7/start.S
arch/arm/dts/mx6q.dtsi
arch/arm/imx-common/cpu.c
arch/arm/imx-common/iomux-v3.c
arch/arm/imx-common/timer.c
arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/arch-am33xx/gpio.h
arch/arm/include/asm/arch-am33xx/hardware.h
arch/arm/include/asm/arch-am33xx/mmc_host_def.h
arch/arm/include/asm/arch-exynos/system.h
arch/arm/include/asm/arch-mx5/clock.h
arch/arm/include/asm/arch-mx5/crm_regs.h
arch/arm/include/asm/arch-mx5/imx-regs.h
arch/arm/include/asm/arch-mx5/iomux-mx51.h
arch/arm/include/asm/arch-mx5/iomux-mx53.h
arch/arm/include/asm/arch-mx5/mx5x_pins.h
arch/arm/include/asm/arch-mx5/sys_proto.h
arch/arm/include/asm/arch-mx6/clock.h
arch/arm/include/asm/arch-mx6/crm_regs.h
arch/arm/include/asm/arch-mx6/dma.h
arch/arm/include/asm/arch-mx6/imx-regs.h
arch/arm/include/asm/arch-mx6/iomux-mx6.h
arch/arm/include/asm/arch-mx6/iomux-v3.h
arch/arm/include/asm/arch-mx6/mx6x_pins.h
arch/arm/include/asm/arch-mx6/regs-apbh.h
arch/arm/include/asm/arch-mx6/regs-bch.h
arch/arm/include/asm/arch-mx6/regs-gpmi.h
arch/arm/include/asm/arch-mx6/regs-ocotp.h
arch/arm/include/asm/arch-mx6/sys_proto.h
arch/arm/include/asm/arch-mxs/mxsfb.h
arch/arm/include/asm/arch-mxs/regs-apbh.h
arch/arm/include/asm/arch-mxs/regs-bch.h
arch/arm/include/asm/arch-mxs/regs-gpmi.h
arch/arm/include/asm/arch-mxs/regs-lcdif.h
arch/arm/include/asm/arch-mxs/sys_proto.h
arch/arm/include/asm/global_data.h
arch/arm/include/asm/imx-common/iomux-v3.h
arch/arm/include/asm/system.h
arch/arm/lib/board.c
arch/arm/lib/cache-cp15.c
board/denx/m28evk/spl_boot.c
board/karo/dts/tx6q.dts
board/karo/tx28/flash.c
board/karo/tx28/spl_boot.c
board/karo/tx28/tx28.c
board/karo/tx48/config.mk
board/karo/tx48/spl.c
board/karo/tx48/tx48.c
board/karo/tx48/u-boot.lds
board/karo/tx51/tx51.c
board/karo/tx51/u-boot.lds
board/karo/tx53/lowlevel_init.S
board/karo/tx53/tx53.c
board/karo/tx53/u-boot.lds
board/karo/tx6q/Makefile
board/karo/tx6q/config.mk
board/karo/tx6q/dcd.c
board/karo/tx6q/flash.c
board/karo/tx6q/lowlevel_init.S
board/karo/tx6q/lowlevel_init.S.borked
board/karo/tx6q/lowlevel_init.S.ok
board/karo/tx6q/lowlevel_init.S.rotten
board/karo/tx6q/mmdc_regs.h
board/karo/tx6q/spl_boot.c
board/karo/tx6q/tx6q.c
board/karo/tx6q/u-boot.bd
board/karo/tx6q/u-boot.lds
board/ti/am335x/board.c
boards.cfg
common/Makefile
common/cmd_bootce.c
common/cmd_fdt.c
common/cmd_nand.c
common/cmd_sata.c
common/env_nand.c
common/fdt_support.c
common/lcd.c
common/main.c
common/spl/spl_nand.c
common/spl/spl_ymodem.c
common/xyzModem.c
config.mk
disk/part.c
drivers/dma/apbh_dma.c
drivers/gpio/Makefile
drivers/gpio/am33xx_gpio.c
drivers/gpio/mxc_gpio.c
drivers/misc/Makefile
drivers/misc/imx_iim.c
drivers/mmc/fsl_esdhc.c
drivers/mmc/mmc.c
drivers/mmc/mxsmmc.c
drivers/mmc/omap_hsmmc.c
drivers/mtd/nand/Makefile
drivers/mtd/nand/am33xx_nand.c
drivers/mtd/nand/mxs_nand.c
drivers/mtd/nand/nand_base.c
drivers/net/Makefile
drivers/net/cpsw.c
drivers/net/fec_mxc.c
drivers/net/fec_mxc.h
drivers/net/phy/phy.c
drivers/video/Makefile
drivers/video/da8xx-fb.c
drivers/video/ipu_common.c
drivers/video/ipu_disp.c
drivers/video/ipu_regs.h
drivers/video/mxc_ipuv3_fb.c
drivers/video/mxsfb.c
drivers/watchdog/imx_watchdog.c
dts/Makefile
include/ahci.h
include/asm-generic/gpio.h
include/configs/tx25.h
include/configs/tx28.h
include/configs/tx48.h
include/configs/tx51.h
include/configs/tx53.h
include/configs/tx6q.h
include/fsl_esdhc.h
include/ipu.h
include/ipu_pixfmt.h
include/lcd.h
include/nand.h
include/net.h
include/netdev.h
include/wince.h
net/Makefile
net/bootp.c
net/bootp.h
net/net.c

diff --cc .gitignore
Simple merge
diff --cc Makefile
+++ b/Makefile
@@@ -93,7 -113,7 +111,7 @@@ export CHECKSR
  ifneq ($(BUILD_DIR),)
  saved-output := $(BUILD_DIR)
  
--# Attempt to create a output directory.
++# Attempt to create an output directory.
  $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
  
  # Verify if it was successful.
@@@ -446,15 -508,49 +509,50 @@@ $(obj)u-boot.ais:       $(obj)spl/u-boo
                $(OBJCOPY) ${OBJCFLAGS} -I binary \
                        --pad-to=$(CONFIG_SPL_MAX_SIZE) -O binary \
                        $(obj)spl/u-boot-spl.ais $(obj)spl/u-boot-spl-pad.ais
-               cat $(obj)spl/u-boot-spl-pad.ais $(obj)u-boot.bin > \
+               cat $(obj)spl/u-boot-spl-pad.ais $(obj)u-boot.img > \
                        $(obj)u-boot.ais
-               rm $(obj)spl/u-boot-spl{,-pad}.ais
  
- $(obj)u-boot.bd:       $(TOPDIR)/board/$(BOARDDIR)/u-boot.bd
-               sed "s:@@BUILD_DIR@@:$(obj):g" $< > $@
+ # Specify the target for use in elftosb call
+ ELFTOSB_TARGET-$(CONFIG_MX28) = imx28
 -$(obj)u-boot.sb:       $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin
 -              elftosb -zf $(ELFTOSB_TARGET-y) -c $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot-$(ELFTOSB_TARGET-y).bd \
++$(obj)u-boot.sb:       $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin elftosb
++              cd $(OBJTREE); \
++              $(TOPDIR)/$(SUBDIR_TOOLS)/elftosb/bld/linux/elftosb -zdf $(ELFTOSB_TARGET-y) -c $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot-$(ELFTOSB_TARGET-y).bd \
+                       -o $(obj)u-boot.sb
+ # On x600 (SPEAr600) U-Boot is appended to U-Boot SPL.
+ # Both images are created using mkimage (crc etc), so that the ROM
+ # bootloader can check its integrity. Padding needs to be done to the
+ # SPL image (with mkimage header) and not the binary. Otherwise the resulting image
+ # which is loaded/copied by the ROM bootloader to SRAM doesn't fit.
+ # The resulting image containing both U-Boot images is called u-boot.spr
+ $(obj)u-boot.spr:     $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
+               $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
+               -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) -n XLOADER \
+               -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.img
+               tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_SPL_PAD_TO) \
+                       of=$(obj)spl/u-boot-spl-pad.img 2>/dev/null
+               dd if=$(obj)spl/u-boot-spl.img of=$(obj)spl/u-boot-spl-pad.img \
+                       conv=notrunc 2>/dev/null
+               cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@
+ ifeq ($(SOC),tegra20)
+ ifeq ($(CONFIG_OF_SEPARATE),y)
+ nodtb=dtb
+ dtbfile=$(obj)u-boot.dtb
+ else
+ nodtb=nodtb
+ dtbfile=
+ endif
+ $(obj)u-boot-$(nodtb)-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin $(dtbfile)
+               $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_TEXT_BASE) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin
+               cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin $(dtbfile) > $@
+               rm $(obj)spl/u-boot-spl-pad.bin
+ endif
  
- $(obj)u-boot.sb:       $(obj)u-boot.bd elftosb $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin
-               $(TOPDIR)/tools/elftosb/bld/linux/elftosb -zdf imx28 -c $< -o $@
+ $(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
+               cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@
  
  ifeq ($(CONFIG_SANDBOX),y)
  GEN_UBOOT = \
Simple merge
index 0000000,6ce8019..d314144
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,344 +1,375 @@@
 -      while (--timeout) {
 -              if ((readl(&reg->reg) & mask) == mask)
 -                      break;
+ /*
+  * Freescale i.MX28 common code
+  *
+  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+  * on behalf of DENX Software Engineering GmbH
+  *
+  * Based on code from LTIB:
+  * Copyright (C) 2010 Freescale Semiconductor, Inc.
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  */
+ #include <common.h>
+ #include <asm/errno.h>
+ #include <asm/io.h>
+ #include <asm/arch/clock.h>
+ #include <asm/arch/dma.h>
+ #include <asm/arch/gpio.h>
+ #include <asm/arch/iomux.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/arch/sys_proto.h>
+ DECLARE_GLOBAL_DATA_PTR;
+ /* 1 second delay should be plenty of time for block reset. */
+ #define       RESET_MAX_TIMEOUT       1000000
+ #define       MXS_BLOCK_SFTRST        (1 << 31)
+ #define       MXS_BLOCK_CLKGATE       (1 << 30)
+ /* Lowlevel init isn't used on i.MX28, so just have a dummy here */
+ inline void lowlevel_init(void) {}
+ void reset_cpu(ulong ignored) __attribute__((noreturn));
+ void reset_cpu(ulong ignored)
+ {
+       struct mxs_rtc_regs *rtc_regs =
+               (struct mxs_rtc_regs *)MXS_RTC_BASE;
+       struct mxs_lcdif_regs *lcdif_regs =
+               (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
+       /*
+        * Shut down the LCD controller as it interferes with BootROM boot mode
+        * pads sampling.
+        */
+       writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr);
+       /* Wait 1 uS before doing the actual watchdog reset */
+       writel(1, &rtc_regs->hw_rtc_watchdog);
+       writel(RTC_CTRL_WATCHDOGEN, &rtc_regs->hw_rtc_ctrl_set);
+       /* Endless loop, reset will exit from here */
+       for (;;)
+               ;
+ }
+ void enable_caches(void)
+ {
+ #ifndef CONFIG_SYS_ICACHE_OFF
+       icache_enable();
+ #endif
+ #ifndef CONFIG_SYS_DCACHE_OFF
+       dcache_enable();
+ #endif
+ }
++#define       MX28_HW_DIGCTL_MICROSECONDS     (void *)0x8001c0c0
++
+ int mxs_wait_mask_set(struct mxs_register_32 *reg, uint32_t mask, unsigned
+                                                               int timeout)
+ {
 -      while (--timeout) {
 -              if ((readl(&reg->reg) & mask) == 0)
 -                      break;
++      uint32_t start = readl(MX28_HW_DIGCTL_MICROSECONDS);
++
++      /* Wait for at least one microsecond for the bit mask to be set */
++      while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1 || --timeout) {
++              if ((readl(&reg->reg) & mask) == mask) {
++                      while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1)
++                              ;
++                      return 0;
++              }
+               udelay(1);
+       }
+       return !timeout;
+ }
+ int mxs_wait_mask_clr(struct mxs_register_32 *reg, uint32_t mask, unsigned
+                                                               int timeout)
+ {
 -      if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
++      uint32_t start = readl(MX28_HW_DIGCTL_MICROSECONDS);
++
++      /* Wait for at least one microsecond for the bit mask to be cleared */
++      while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1 || --timeout) {
++              if ((readl(&reg->reg) & mask) == 0) {
++                      while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1)
++                              ;
++                      return 0;
++              }
+               udelay(1);
+       }
+       return !timeout;
+ }
+ int mxs_reset_block(struct mxs_register_32 *reg)
+ {
+       /* Clear SFTRST */
+       writel(MXS_BLOCK_SFTRST, &reg->reg_clr);
 -      if (mxs_wait_mask_set(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
++      if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) {
++              printf("TIMEOUT waiting for SFTRST[%p] to clear: %08x\n",
++                      reg, readl(&reg->reg));
+               return 1;
++      }
+       /* Clear CLKGATE */
+       writel(MXS_BLOCK_CLKGATE, &reg->reg_clr);
+       /* Set SFTRST */
+       writel(MXS_BLOCK_SFTRST, &reg->reg_set);
+       /* Wait for CLKGATE being set */
 -      if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
++      if (mxs_wait_mask_set(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) {
++              printf("TIMEOUT waiting for CLKGATE[%p] to set: %08x\n",
++                      reg, readl(&reg->reg));
+               return 1;
++      }
+       /* Clear SFTRST */
+       writel(MXS_BLOCK_SFTRST, &reg->reg_clr);
 -      if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
++      if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) {
++              printf("TIMEOUT waiting for SFTRST[%p] to clear: %08x\n",
++                      reg, readl(&reg->reg));
+               return 1;
++      }
+       /* Clear CLKGATE */
+       writel(MXS_BLOCK_CLKGATE, &reg->reg_clr);
 -      /* Enable pad output */
 -      setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
 -
++      if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) {
++              printf("TIMEOUT waiting for CLKGATE[%p] to clear: %08x\n",
++                      reg, readl(&reg->reg));
+               return 1;
++      }
+       return 0;
+ }
+ void mx28_fixup_vt(uint32_t start_addr)
+ {
+       uint32_t *vt = (uint32_t *)0x20;
+       int i;
+       for (i = 0; i < 8; i++)
+               vt[i] = start_addr + (4 * i);
+ }
+ #ifdef        CONFIG_ARCH_MISC_INIT
+ int arch_misc_init(void)
+ {
+       mx28_fixup_vt(gd->relocaddr);
+       return 0;
+ }
+ #endif
++#ifdef        CONFIG_ARCH_CPU_INIT
+ int arch_cpu_init(void)
+ {
+       struct mxs_clkctrl_regs *clkctrl_regs =
+               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+       extern uint32_t _start;
+       mx28_fixup_vt((uint32_t)&_start);
+       /*
+        * Enable NAND clock
+        */
+       /* Clear bypass bit */
+       writel(CLKCTRL_CLKSEQ_BYPASS_GPMI,
+               &clkctrl_regs->hw_clkctrl_clkseq_set);
+       /* Set GPMI clock to ref_gpmi / 12 */
+       clrsetbits_le32(&clkctrl_regs->hw_clkctrl_gpmi,
+               CLKCTRL_GPMI_CLKGATE | CLKCTRL_GPMI_DIV_MASK, 1);
+       udelay(1000);
+       /*
+        * Configure GPIO unit
+        */
+       mxs_gpio_init();
+ #ifdef        CONFIG_APBH_DMA
+       /* Start APBH DMA */
+       mxs_dma_init();
+ #endif
+       return 0;
+ }
++#endif
+ #if defined(CONFIG_DISPLAY_CPUINFO)
+ static const char *get_cpu_type(void)
+ {
+       struct mxs_digctl_regs *digctl_regs =
+               (struct mxs_digctl_regs *)MXS_DIGCTL_BASE;
+       switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) {
+       case HW_DIGCTL_CHIPID_MX28:
+               return "28";
+       default:
+               return "??";
+       }
+ }
+ static const char *get_cpu_rev(void)
+ {
+       struct mxs_digctl_regs *digctl_regs =
+               (struct mxs_digctl_regs *)MXS_DIGCTL_BASE;
+       uint8_t rev = readl(&digctl_regs->hw_digctl_chipid) & 0x000000FF;
+       switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) {
+       case HW_DIGCTL_CHIPID_MX28:
+               switch (rev) {
+               case 0x1:
+                       return "1.2";
+               default:
+                       return "??";
+               }
+       default:
+               return "??";
+       }
+ }
+ int print_cpuinfo(void)
+ {
+       struct mxs_spl_data *data = (struct mxs_spl_data *)
+               ((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf);
+       printf("CPU:   Freescale i.MX%s rev%s at %d MHz\n",
+               get_cpu_type(),
+               get_cpu_rev(),
+               mxc_get_clock(MXC_ARM_CLK) / 1000000);
+       printf("BOOT:  %s\n", mxs_boot_modes[data->boot_mode_idx].mode);
+       return 0;
+ }
+ #endif
+ int do_mx28_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ {
+       printf("CPU:   %3d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
+       printf("BUS:   %3d MHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000000);
+       printf("EMI:   %3d MHz\n", mxc_get_clock(MXC_EMI_CLK));
+       printf("GPMI:  %3d MHz\n", mxc_get_clock(MXC_GPMI_CLK) / 1000000);
+       return 0;
+ }
+ /*
+  * Initializes on-chip ethernet controllers.
+  */
+ #if defined(CONFIG_MX28) && defined(CONFIG_CMD_NET)
+ int cpu_eth_init(bd_t *bis)
+ {
+       struct mxs_clkctrl_regs *clkctrl_regs =
+               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+       /* Turn on ENET clocks */
+       clrbits_le32(&clkctrl_regs->hw_clkctrl_enet,
+               CLKCTRL_ENET_SLEEP | CLKCTRL_ENET_DISABLE);
+       /* Set up ENET PLL for 50 MHz */
+       /* Power on ENET PLL */
+       writel(CLKCTRL_PLL2CTRL0_POWER,
+               &clkctrl_regs->hw_clkctrl_pll2ctrl0_set);
+       udelay(10);
++      /*
++       * Enable pad output; must be done BEFORE enabling PLL
++       * according to i.MX28 Ref. Manual Rev. 1, 2010 p. 883
++       */
++      setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
++
+       /* Gate on ENET PLL */
+       writel(CLKCTRL_PLL2CTRL0_CLKGATE,
+               &clkctrl_regs->hw_clkctrl_pll2ctrl0_clr);
+       return 0;
+ }
+ #endif
+ static void __mx28_adjust_mac(int dev_id, unsigned char *mac)
+ {
+       mac[0] = 0x00;
+       mac[1] = 0x04; /* Use FSL vendor MAC address by default */
+       if (dev_id == 1) /* Let MAC1 be MAC0 + 1 by default */
+               mac[5] += 1;
+ }
+ void mx28_adjust_mac(int dev_id, unsigned char *mac)
+       __attribute__((weak, alias("__mx28_adjust_mac")));
+ #ifdef        CONFIG_MX28_FEC_MAC_IN_OCOTP
+ #define       MXS_OCOTP_MAX_TIMEOUT   1000000
+ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+ {
+       struct mxs_ocotp_regs *ocotp_regs =
+               (struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
+       uint32_t data;
+       memset(mac, 0, 6);
+       writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_set);
+       if (mxs_wait_mask_clr(&ocotp_regs->hw_ocotp_ctrl_reg, OCOTP_CTRL_BUSY,
+                               MXS_OCOTP_MAX_TIMEOUT)) {
+               printf("MXS FEC: Can't get MAC from OCOTP\n");
+               return;
+       }
+       data = readl(&ocotp_regs->hw_ocotp_cust0);
+       mac[2] = (data >> 24) & 0xff;
+       mac[3] = (data >> 16) & 0xff;
+       mac[4] = (data >> 8) & 0xff;
+       mac[5] = data & 0xff;
+       mx28_adjust_mac(dev_id, mac);
+ }
+ #else
+ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+ {
+       memset(mac, 0, 6);
+ }
+ #endif
+ int mxs_dram_init(void)
+ {
+       struct mxs_spl_data *data = (struct mxs_spl_data *)
+               ((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf);
+       if (data->mem_dram_size == 0) {
+               printf("MXS:\n"
+                       "Error, the RAM size passed up from SPL is 0!\n");
+               hang();
+       }
+       gd->ram_size = data->mem_dram_size;
+       return 0;
+ }
+ U_BOOT_CMD(
+       clocks, CONFIG_SYS_MAXARGS, 1, do_mx28_showclocks,
+       "display clocks",
+       ""
+ );
index 0000000,1b8502e..57da57d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,132 +1,139 @@@
 -      uint32_t st = readl(&digctl_regs->hw_digctl_microseconds);
 -      st += delay;
 -      while (st > readl(&digctl_regs->hw_digctl_microseconds))
 -              ;
+ /*
+  * Freescale i.MX28 Boot setup
+  *
+  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+  * on behalf of DENX Software Engineering GmbH
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  */
+ #include <common.h>
+ #include <config.h>
+ #include <asm/io.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/arch/sys_proto.h>
+ #include <asm/gpio.h>
+ #include "mxs_init.h"
+ /*
+  * This delay function is intended to be used only in early stage of boot, where
+  * clock are not set up yet. The timer used here is reset on every boot and
+  * takes a few seconds to roll. The boot doesn't take that long, so to keep the
+  * code simple, it doesn't take rolling into consideration.
+  */
++/*
++ * There's nothing to be taken into consideration for the rollover.
++ * Two's complement arithmetic used correctly does all the magic automagically.
++ */
+ void early_delay(int delay)
+ {
+       struct mxs_digctl_regs *digctl_regs =
+               (struct mxs_digctl_regs *)MXS_DIGCTL_BASE;
++      u32 start = readl(&digctl_regs->hw_digctl_microseconds);
 -/* Support aparatus */
++      while (readl(&digctl_regs->hw_digctl_microseconds) - start < delay);
+ }
+ #define       MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
+ static const iomux_cfg_t iomux_boot[] = {
+       MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD,
+       MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD,
+       MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD,
+       MX28_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD,
+       MX28_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD,
+       MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD,
+ };
+ static uint8_t mxs_get_bootmode_index(void)
+ {
+       uint8_t bootmode = 0;
+       int i;
+       uint8_t masked;
+       /* Setup IOMUX of bootmode pads to GPIO */
+       mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot));
+       /* Setup bootmode pins as GPIO input */
+       gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0);
+       gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1);
+       gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2);
+       gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3);
+       gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4);
+       gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5);
+       /* Read bootmode pads */
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0;
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1;
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2;
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3;
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4) ? 1 : 0) << 4;
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5;
+       for (i = 0; i < ARRAY_SIZE(mxs_boot_modes); i++) {
+               masked = bootmode & mxs_boot_modes[i].boot_mask;
+               if (masked == mxs_boot_modes[i].boot_pads)
+                       break;
+       }
+       return i;
+ }
+ void mxs_common_spl_init(const iomux_cfg_t *iomux_setup,
+                       const unsigned int iomux_size)
+ {
+       struct mxs_spl_data *data = (struct mxs_spl_data *)
+               ((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf);
+       uint8_t bootmode = mxs_get_bootmode_index();
+       mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
+       mxs_power_init();
+       mxs_mem_init();
+       data->mem_dram_size = mxs_mem_get_size();
+       data->boot_mode_idx = bootmode;
+       mxs_power_wait_pswitch();
+ }
++/* Support apparatus */
+ inline void board_init_f(unsigned long bootflag)
+ {
+       for (;;)
+               ;
+ }
+ inline void board_init_r(gd_t *id, ulong dest_addr)
+ {
+       for (;;)
+               ;
+ }
++#ifndef CONFIG_SPL_SERIAL_SUPPORT
++void serial_putc(const char c) {}
++void serial_puts(const char *s) {}
++#endif
+ void hang(void) __attribute__ ((noreturn));
+ void hang(void)
+ {
++      serial_puts("ERROR: please reset the target\n");
+       for (;;)
+               ;
+ }
index 0000000,401c513..fa2dd97
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,243 +1,232 @@@
 -      early_delay(11000);
+ /*
+  * Freescale i.MX28 RAM init
+  *
+  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+  * on behalf of DENX Software Engineering GmbH
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  */
+ #include <common.h>
+ #include <config.h>
+ #include <asm/io.h>
+ #include <asm/arch/imx-regs.h>
+ #include "mxs_init.h"
+ static uint32_t dram_vals[] = {
+ /*
+  * i.MX28 DDR2 at 200MHz
+  */
+ #if defined(CONFIG_MX28)
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000100, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00010101, 0x01010101,
+       0x000f0f01, 0x0f02020a, 0x00000000, 0x00010101,
+       0x00000100, 0x00000100, 0x00000000, 0x00000002,
+       0x01010000, 0x05060302, 0x06005003, 0x0a0000c8,
+       0x02009c40, 0x0000030c, 0x0036a609, 0x031a0612,
+       0x02030202, 0x00c8001c, 0x00000000, 0x00000000,
+       0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+       0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+       0x00000003, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000612, 0x01000F02,
+       0x06120612, 0x00000200, 0x00020007, 0xf5014b27,
+       0xf5014b27, 0xf5014b27, 0xf5014b27, 0x07000300,
+       0x07000300, 0x07000300, 0x07000300, 0x00000006,
+       0x00000000, 0x00000000, 0x01000000, 0x01020408,
+       0x08040201, 0x000f1133, 0x00000000, 0x00001f04,
+       0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
+       0x00001f04, 0x00001f04, 0x00001f04, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00010000, 0x00020304,
+       0x00000004, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x01010000,
+       0x01000000, 0x03030000, 0x00010303, 0x01020202,
+       0x00000000, 0x02040303, 0x21002103, 0x00061200,
+       0x06120612, 0x04320432, 0x04320432, 0x00040004,
+       0x00040004, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00010001
+ #else
+ #error Unsupported memory initialization
+ #endif
+ };
+ void __mxs_adjust_memory_params(uint32_t *dram_vals)
+ {
+ }
+ void mxs_adjust_memory_params(uint32_t *dram_vals)
+       __attribute__((weak, alias("__mxs_adjust_memory_params")));
+ static void initialize_dram_values(void)
+ {
+       int i;
+       mxs_adjust_memory_params(dram_vals);
+       for (i = 0; i < ARRAY_SIZE(dram_vals); i++)
+               writel(dram_vals[i], MXS_DRAM_BASE + (4 * i));
+ }
+ static void mxs_mem_init_clock(void)
+ {
+       struct mxs_clkctrl_regs *clkctrl_regs =
+               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+       /* Gate EMI clock */
+       writeb(CLKCTRL_FRAC_CLKGATE,
+               &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_EMI]);
+       /* Set fractional divider for ref_emi to 480 * 18 / 21 = 411MHz */
+       writeb(CLKCTRL_FRAC_CLKGATE | (21 & CLKCTRL_FRAC_FRAC_MASK),
+               &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]);
+       /* Ungate EMI clock */
+       writeb(CLKCTRL_FRAC_CLKGATE,
+               &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_EMI]);
 -
 -      early_delay(10000);
+       /* Set EMI clock divider for EMI clock to 411 / 2 = 205MHz */
+       writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) |
+               (1 << CLKCTRL_EMI_DIV_XTAL_OFFSET),
+               &clkctrl_regs->hw_clkctrl_emi);
++      while (readl(&clkctrl_regs->hw_clkctrl_emi) & CLKCTRL_EMI_BUSY_REF_EMI)
++              ;
+       /* Unbypass EMI */
+       writel(CLKCTRL_CLKSEQ_BYPASS_EMI,
+               &clkctrl_regs->hw_clkctrl_clkseq_clr);
 -      writel(CLKCTRL_HBUS_DIV_MASK, &clkctrl_regs->hw_clkctrl_hbus_set);
 -      writel(((~3) << CLKCTRL_HBUS_DIV_OFFSET) & CLKCTRL_HBUS_DIV_MASK,
 -              &clkctrl_regs->hw_clkctrl_hbus_clr);
 -
 -      early_delay(10000);
+ }
+ static void mxs_mem_setup_cpu_and_hbus(void)
+ {
+       struct mxs_clkctrl_regs *clkctrl_regs =
+               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+       /* Set fractional divider for ref_cpu to 480 * 18 / 19 = 454MHz
+        * and ungate CPU clock */
+       writeb(19 & CLKCTRL_FRAC_FRAC_MASK,
+               (uint8_t *)&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]);
+       /* Set CPU bypass */
+       writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
+               &clkctrl_regs->hw_clkctrl_clkseq_set);
+       /* HBUS = 151MHz */
 -                      CLKCTRL_CPU_DIV_CPU_MASK, 1);
++      clrsetbits_le32(&clkctrl_regs->hw_clkctrl_hbus,
++                      CLKCTRL_HBUS_DIV_MASK,
++                      3 << CLKCTRL_HBUS_DIV_OFFSET);
++      while (readl(&clkctrl_regs->hw_clkctrl_hbus) & CLKCTRL_HBUS_ASM_BUSY)
++              ;
+       /* CPU clock divider = 1 */
+       clrsetbits_le32(&clkctrl_regs->hw_clkctrl_cpu,
 -
 -      early_delay(15000);
++                      CLKCTRL_CPU_DIV_CPU_MASK,
++                      1 << CLKCTRL_CPU_DIV_CPU_OFFSET);
++      while (readl(&clkctrl_regs->hw_clkctrl_cpu) & CLKCTRL_CPU_BUSY_REF_CPU)
++              ;
+       /* Disable CPU bypass */
+       writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
+               &clkctrl_regs->hw_clkctrl_clkseq_clr);
 -static void mxs_mem_setup_vdda(void)
+ }
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
 -      writel((0xc << POWER_VDDACTRL_TRG_OFFSET) |
 -              (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) |
 -              POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW,
 -              &power_regs->hw_power_vddactrl);
++static void __attribute__((naked)) data_abort_memdetect_handler(void)
+ {
 -      /* The following is "subs pc, r14, #4", used as return from DABT. */
 -      const uint32_t data_abort_memdetect_handler = 0xe25ef004;
++      asm volatile("subs pc, r14, #4");
+ }
+ uint32_t mxs_mem_get_size(void)
+ {
+       uint32_t sz, da;
+       uint32_t *vt = (uint32_t *)0x20;
 -      vt[4] = data_abort_memdetect_handler;
+       /* Replace the DABT handler. */
+       da = vt[4];
 -      early_delay(11000);
++      vt[4] = (uint32_t)data_abort_memdetect_handler;
+       sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
+       /* Restore the old DABT handler. */
+       vt[4] = da;
+       return sz;
+ }
+ void mxs_mem_init(void)
+ {
+       struct mxs_clkctrl_regs *clkctrl_regs =
+               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+       struct mxs_pinctrl_regs *pinctrl_regs =
+               (struct mxs_pinctrl_regs *)MXS_PINCTRL_BASE;
+       /* Set DDR2 mode */
+       writel(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2,
+               &pinctrl_regs->hw_pinctrl_emi_ds_ctrl_set);
+       /* Power up PLL0 */
+       writel(CLKCTRL_PLL0CTRL0_POWER,
+               &clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
 -      mxs_mem_setup_vdda();
 -
++      /* enabling the PLL requires a 10µs delay before use as clk source */
++      early_delay(11);
+       mxs_mem_init_clock();
 -      early_delay(10000);
 -
+       /*
+        * Configure the DRAM registers
+        */
+       /* Clear START bit from DRAM_CTL16 */
+       clrbits_le32(MXS_DRAM_BASE + 0x40, 1);
+       initialize_dram_values();
+       /* Clear SREFRESH bit from DRAM_CTL17 */
+       clrbits_le32(MXS_DRAM_BASE + 0x44, 1);
+       /* Set START bit in DRAM_CTL16 */
+       setbits_le32(MXS_DRAM_BASE + 0x40, 1);
+       /* Wait for bit 20 (DRAM init complete) in DRAM_CTL58 */
+       while (!(readl(MXS_DRAM_BASE + 0xe8) & (1 << 20)))
+               ;
+       mxs_mem_setup_cpu_and_hbus();
+ }
index 0000000,be44c22..362df4c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,921 +1,1036 @@@
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
+ /*
+  * Freescale i.MX28 Boot PMIC init
+  *
+  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+  * on behalf of DENX Software Engineering GmbH
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  */
+ #include <common.h>
+ #include <config.h>
+ #include <asm/io.h>
+ #include <asm/arch/imx-regs.h>
+ #include "mxs_init.h"
++#ifdef CONFIG_SYS_SPL_VDDD_VAL
++#define VDDD_VAL      CONFIG_SYS_SPL_VDDD_VAL
++#else
++#define VDDD_VAL      1350
++#endif
++#ifdef CONFIG_SYS_SPL_VDDIO_VAL
++#define VDDIO_VAL     CONFIG_SYS_SPL_VDDIO_VAL
++#else
++#define VDDIO_VAL     3300
++#endif
++#ifdef CONFIG_SYS_SPL_VDDA_VAL
++#define VDDA_VAL      CONFIG_SYS_SPL_VDDA_VAL
++#else
++#define VDDA_VAL      1800
++#endif
++#ifdef CONFIG_SYS_SPL_VDDMEM_VAL
++#define VDDMEM_VAL    CONFIG_SYS_SPL_VDDMEM_VAL
++#else
++#define VDDMEM_VAL    1500
++#endif
++
++#ifdef CONFIG_SYS_SPL_VDDD_BO_VAL
++#define VDDD_BO_VAL   CONFIG_SYS_SPL_VDDD_BO_VAL
++#else
++#define VDDD_BO_VAL   150
++#endif
++#ifdef CONFIG_SYS_SPL_VDDIO_BO_VAL
++#define VDDIO_BO_VAL  CONFIG_SYS_SPL_VDDIO_BO_VAL
++#else
++#define VDDIO_BO_VAL  150
++#endif
++#ifdef CONFIG_SYS_SPL_VDDA_BO_VAL
++#define VDDA_BO_VAL   CONFIG_SYS_SPL_VDDA_BO_VAL
++#else
++#define VDDA_BO_VAL   175
++#endif
++#ifdef CONFIG_SYS_SPL_VDDMEM_BO_VAL
++#define VDDMEM_BO_VAL CONFIG_SYS_SPL_VDDMEM_BO_VAL
++#else
++#define VDDMEM_BO_VAL 25
++#endif
++
++#ifdef CONFIG_SYS_SPL_BATT_BO_LEVEL
++#if CONFIG_SYS_SPL_BATT_BO_LEVEL < 2400 || CONFIG_SYS_SPL_BATT_BO_LEVEL > 3640
++#error CONFIG_SYS_SPL_BATT_BO_LEVEL out of range
++#endif
++#define BATT_BO_VAL   (((CONFIG_SYS_SPL_BATT_BO_LEVEL) - 2400) / 40)
++#else
++/* Brownout default at 3V */
++#define BATT_BO_VAL   ((3000 - 2400) / 40)
++#endif
++
++#ifdef CONFIG_SYS_SPL_FIXED_BATT_SUPPLY
++static const int fixed_batt_supply = 1;
++#else
++static const int fixed_batt_supply;
++#endif
++
++static struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
++
+ static void mxs_power_clock2xtal(void)
+ {
+       struct mxs_clkctrl_regs *clkctrl_regs =
+               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+       /* Set XTAL as CPU reference clock */
+       writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
+               &clkctrl_regs->hw_clkctrl_clkseq_set);
+ }
+ static void mxs_power_clock2pll(void)
+ {
+       struct mxs_clkctrl_regs *clkctrl_regs =
+               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+       setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
+                       CLKCTRL_PLL0CTRL0_POWER);
+       early_delay(100);
+       setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
+                       CLKCTRL_CLKSEQ_BYPASS_CPU);
+ }
+ static void mxs_power_clear_auto_restart(void)
+ {
+       struct mxs_rtc_regs *rtc_regs =
+               (struct mxs_rtc_regs *)MXS_RTC_BASE;
+       writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
+       while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
+               ;
+       writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
+       while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
+               ;
+       /*
+        * Due to the hardware design bug of mx28 EVK-A
+        * we need to set the AUTO_RESTART bit.
+        */
+       if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
+               return;
+       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
+               ;
+       setbits_le32(&rtc_regs->hw_rtc_persistent0,
+                       RTC_PERSISTENT0_AUTO_RESTART);
+       writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
+       writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
+       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
+               ;
+       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
+               ;
+ }
+ static void mxs_power_set_linreg(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+       /* Set linear regulator 25mV below switching converter */
+       clrsetbits_le32(&power_regs->hw_power_vdddctrl,
+                       POWER_VDDDCTRL_LINREG_OFFSET_MASK,
+                       POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
+       clrsetbits_le32(&power_regs->hw_power_vddactrl,
+                       POWER_VDDACTRL_LINREG_OFFSET_MASK,
+                       POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
+       clrsetbits_le32(&power_regs->hw_power_vddioctrl,
+                       POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
+                       POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
+ }
+ static int mxs_get_batt_volt(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+       uint32_t volt = readl(&power_regs->hw_power_battmonitor);
++
+       volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
+       volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
+       volt *= 8;
+       return volt;
+ }
+ static int mxs_is_batt_ready(void)
+ {
+       return (mxs_get_batt_volt() >= 3600);
+ }
+ static int mxs_is_batt_good(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
+       uint32_t volt = mxs_get_batt_volt();
+       if ((volt >= 2400) && (volt <= 4300))
+               return 1;
+       clrsetbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+               0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+       writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+               &power_regs->hw_power_5vctrl_clr);
+       clrsetbits_le32(&power_regs->hw_power_charge,
+               POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
+               POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
+       writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
+       writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+               &power_regs->hw_power_5vctrl_clr);
+       early_delay(500000);
+       volt = mxs_get_batt_volt();
+       if (volt >= 3500)
+               return 0;
+       if (volt >= 2400)
+               return 1;
+       writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
+               &power_regs->hw_power_charge_clr);
+       writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
+       return 0;
+ }
+ static void mxs_power_setup_5v_detect(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
+       /* Start 5V detection */
+       clrsetbits_le32(&power_regs->hw_power_5vctrl,
+                       POWER_5VCTRL_VBUSVALID_TRSH_MASK,
+                       POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
+                       POWER_5VCTRL_PWRUP_VBUS_CMPS);
+ }
+ static void mxs_src_power_init(void)
+ {
 -      setbits_le32(&power_regs->hw_power_battmonitor,
+       /* Improve efficieny and reduce transient ripple */
+       writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
+               POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
+       clrsetbits_le32(&power_regs->hw_power_dclimits,
+                       POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
+                       0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
 -      /* 5V to battery handoff ... FIXME */
 -      setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
 -      early_delay(30);
 -      clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
++      if (!fixed_batt_supply) {
++              /* FIXME: This requires the LRADC to be set up! */
++              setbits_le32(&power_regs->hw_power_battmonitor,
+                       POWER_BATTMONITOR_EN_BATADJ);
++      } else {
++              clrbits_le32(&power_regs->hw_power_battmonitor,
++                      POWER_BATTMONITOR_EN_BATADJ);
++      }
+       /* Increase the RCSCALE level for quick DCDC response to dynamic load */
+       clrsetbits_le32(&power_regs->hw_power_loopctrl,
+                       POWER_LOOPCTRL_EN_RCSCALE_MASK,
+                       POWER_LOOPCTRL_RCSCALE_THRESH |
+                       POWER_LOOPCTRL_EN_RCSCALE_8X);
+       clrsetbits_le32(&power_regs->hw_power_minpwr,
+                       POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
++      if (!fixed_batt_supply) {
++              /* 5V to battery handoff ... FIXME */
++              setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
++              early_delay(30);
++              clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
++      }
+ }
+ static void mxs_power_init_4p2_params(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+       /* Setup 4P2 parameters */
+       clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
+               POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
+               POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET));
+       clrsetbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_HEADROOM_ADJ_MASK,
+               0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
+       clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
+               POWER_DCDC4P2_DROPOUT_CTRL_MASK,
+               POWER_DCDC4P2_DROPOUT_CTRL_100MV |
+               POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL);
+       clrsetbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+               0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+ }
+ static void mxs_enable_4p2_dcdc_input(int xfer)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+       uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
+       uint32_t prev_5v_brnout, prev_5v_droop;
+       prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
+                               POWER_5VCTRL_PWDN_5VBRNOUT;
+       prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
+                               POWER_CTRL_ENIRQ_VDD5V_DROOP;
+       clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
+       writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
+               &power_regs->hw_power_reset);
+       clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
+       if (xfer && (readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_ENABLE_DCDC)) {
+               return;
+       }
+       /*
+        * Recording orignal values that will be modified temporarlily
+        * to handle a chip bug. See chip errata for CQ ENGR00115837
+        */
+       tmp = readl(&power_regs->hw_power_5vctrl);
+       vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
+       vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT;
+       pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
+       /*
+        * Disable mechanisms that get erroneously tripped by when setting
+        * the DCDC4P2 EN_DCDC
+        */
+       clrbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_VBUSVALID_5VDETECT |
+               POWER_5VCTRL_VBUSVALID_TRSH_MASK);
+       writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set);
+       if (xfer) {
+               setbits_le32(&power_regs->hw_power_5vctrl,
+                               POWER_5VCTRL_DCDC_XFER);
+               early_delay(20);
+               clrbits_le32(&power_regs->hw_power_5vctrl,
+                               POWER_5VCTRL_DCDC_XFER);
+               setbits_le32(&power_regs->hw_power_5vctrl,
+                               POWER_5VCTRL_ENABLE_DCDC);
+       } else {
+               setbits_le32(&power_regs->hw_power_dcdc4p2,
+                               POWER_DCDC4P2_ENABLE_DCDC);
+       }
+       early_delay(25);
+       clrsetbits_le32(&power_regs->hw_power_5vctrl,
+                       POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh);
+       if (vbus_5vdetect)
+               writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set);
+       if (!pwd_bo)
+               clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
+       while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ)
+               writel(POWER_CTRL_VBUS_VALID_IRQ,
+                       &power_regs->hw_power_ctrl_clr);
+       if (prev_5v_brnout) {
+               writel(POWER_5VCTRL_PWDN_5VBRNOUT,
+                       &power_regs->hw_power_5vctrl_set);
+               writel(POWER_RESET_UNLOCK_KEY,
+                       &power_regs->hw_power_reset);
+       } else {
+               writel(POWER_5VCTRL_PWDN_5VBRNOUT,
+                       &power_regs->hw_power_5vctrl_clr);
+               writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
+                       &power_regs->hw_power_reset);
+       }
+       while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ)
+               writel(POWER_CTRL_VDD5V_DROOP_IRQ,
+                       &power_regs->hw_power_ctrl_clr);
+       if (prev_5v_droop)
+               clrbits_le32(&power_regs->hw_power_ctrl,
+                               POWER_CTRL_ENIRQ_VDD5V_DROOP);
+       else
+               setbits_le32(&power_regs->hw_power_ctrl,
+                               POWER_CTRL_ENIRQ_VDD5V_DROOP);
+ }
+ static void mxs_power_init_4p2_regulator(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
+       uint32_t tmp, tmp2;
+       setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
+       writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
+       writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+               &power_regs->hw_power_5vctrl_clr);
+       clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK);
+       /* Power up the 4p2 rail and logic/control */
+       writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+               &power_regs->hw_power_5vctrl_clr);
+       /*
+        * Start charging up the 4p2 capacitor. We ramp of this charge
+        * gradually to avoid large inrush current from the 5V cable which can
+        * cause transients/problems
+        */
+       mxs_enable_4p2_dcdc_input(0);
+       if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
+               /*
+                * If we arrived here, we were unable to recover from mx23 chip
+                * errata 5837. 4P2 is disabled and sufficient battery power is
+                * not present. Exiting to not enable DCDC power during 5V
+                * connected state.
+                */
+               clrbits_le32(&power_regs->hw_power_dcdc4p2,
+                       POWER_DCDC4P2_ENABLE_DCDC);
+               writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+                       &power_regs->hw_power_5vctrl_set);
+               hang();
+       }
+       /*
+        * Here we set the 4p2 brownout level to something very close to 4.2V.
+        * We then check the brownout status. If the brownout status is false,
+        * the voltage is already close to the target voltage of 4.2V so we
+        * can go ahead and set the 4P2 current limit to our max target limit.
+        * If the brownout status is true, we need to ramp us the current limit
+        * so that we don't cause large inrush current issues. We step up the
+        * current limit until the brownout status is false or until we've
+        * reached our maximum defined 4p2 current limit.
+        */
+       clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
+                       POWER_DCDC4P2_BO_MASK,
+                       22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */
+       if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) {
+               setbits_le32(&power_regs->hw_power_5vctrl,
+                       0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+       } else {
+               tmp = (readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >>
+                       POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
+               while (tmp < 0x3f) {
+                       if (!(readl(&power_regs->hw_power_sts) &
+                                       POWER_STS_DCDC_4P2_BO)) {
+                               tmp = readl(&power_regs->hw_power_5vctrl);
+                               tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
+                               early_delay(100);
+                               writel(tmp, &power_regs->hw_power_5vctrl);
+                               break;
+                       } else {
+                               tmp++;
+                               tmp2 = readl(&power_regs->hw_power_5vctrl);
+                               tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
+                               tmp2 |= tmp <<
+                                       POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
+                               writel(tmp2, &power_regs->hw_power_5vctrl);
+                               early_delay(100);
+                       }
+               }
+       }
+       clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
+       writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
+ }
+ static void mxs_power_init_dcdc_4p2_source(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+       if (!(readl(&power_regs->hw_power_dcdc4p2) &
+               POWER_DCDC4P2_ENABLE_DCDC)) {
+               hang();
+       }
+       mxs_enable_4p2_dcdc_input(1);
+       if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
+               clrbits_le32(&power_regs->hw_power_dcdc4p2,
+                       POWER_DCDC4P2_ENABLE_DCDC);
+               writel(POWER_5VCTRL_ENABLE_DCDC,
+                       &power_regs->hw_power_5vctrl_clr);
+               writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+                       &power_regs->hw_power_5vctrl_set);
+       }
+ }
+ static void mxs_power_enable_4p2(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
+       uint32_t vdddctrl, vddactrl, vddioctrl;
+       uint32_t tmp;
+       vdddctrl = readl(&power_regs->hw_power_vdddctrl);
+       vddactrl = readl(&power_regs->hw_power_vddactrl);
+       vddioctrl = readl(&power_regs->hw_power_vddioctrl);
+       setbits_le32(&power_regs->hw_power_vdddctrl,
+               POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
+               POWER_VDDDCTRL_PWDN_BRNOUT);
+       setbits_le32(&power_regs->hw_power_vddactrl,
+               POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
+               POWER_VDDACTRL_PWDN_BRNOUT);
+       setbits_le32(&power_regs->hw_power_vddioctrl,
+               POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT);
+       mxs_power_init_4p2_params();
+       mxs_power_init_4p2_regulator();
+       /* Shutdown battery (none present) */
+       if (!mxs_is_batt_ready()) {
+               clrbits_le32(&power_regs->hw_power_dcdc4p2,
+                               POWER_DCDC4P2_BO_MASK);
+               writel(POWER_CTRL_DCDC4P2_BO_IRQ,
+                               &power_regs->hw_power_ctrl_clr);
+               writel(POWER_CTRL_ENIRQ_DCDC4P2_BO,
+                               &power_regs->hw_power_ctrl_clr);
+       }
+       mxs_power_init_dcdc_4p2_source();
+       writel(vdddctrl, &power_regs->hw_power_vdddctrl);
+       early_delay(20);
+       writel(vddactrl, &power_regs->hw_power_vddactrl);
+       early_delay(20);
+       writel(vddioctrl, &power_regs->hw_power_vddioctrl);
+       /*
+        * Check if FET is enabled on either powerout and if so,
+        * disable load.
+        */
+       tmp = 0;
+       tmp |= !(readl(&power_regs->hw_power_vdddctrl) &
+                       POWER_VDDDCTRL_DISABLE_FET);
+       tmp |= !(readl(&power_regs->hw_power_vddactrl) &
+                       POWER_VDDACTRL_DISABLE_FET);
+       tmp |= !(readl(&power_regs->hw_power_vddioctrl) &
+                       POWER_VDDIOCTRL_DISABLE_FET);
+       if (tmp)
+               writel(POWER_CHARGE_ENABLE_LOAD,
+                       &power_regs->hw_power_charge_clr);
+ }
+ static void mxs_boot_valid_5v(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+       /*
+        * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
+        * disconnect event. FIXME
+        */
+       writel(POWER_5VCTRL_VBUSVALID_5VDETECT,
+               &power_regs->hw_power_5vctrl_set);
+       /* Configure polarity to check for 5V disconnection. */
+       writel(POWER_CTRL_POLARITY_VBUSVALID |
+               POWER_CTRL_POLARITY_VDD5V_GT_VDDIO,
+               &power_regs->hw_power_ctrl_clr);
+       writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ,
+               &power_regs->hw_power_ctrl_clr);
+       mxs_power_enable_4p2();
+ }
+ static void mxs_powerdown(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
+       writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
+       writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
+               &power_regs->hw_power_reset);
+ }
+ static void mxs_batt_boot(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+       clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
+       clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
+       clrbits_le32(&power_regs->hw_power_dcdc4p2,
+                       POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
+       writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
+       /* 5V to battery handoff. */
+       setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+       early_delay(30);
+       clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+       writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
+       clrsetbits_le32(&power_regs->hw_power_minpwr,
+                       POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
+       mxs_power_set_linreg();
+       clrbits_le32(&power_regs->hw_power_vdddctrl,
+               POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
+       clrbits_le32(&power_regs->hw_power_vddactrl,
+               POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
+       clrbits_le32(&power_regs->hw_power_vddioctrl,
+               POWER_VDDIOCTRL_DISABLE_FET);
+       setbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
+       setbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_ENABLE_DCDC);
+       clrsetbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+               0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+ }
+ static void mxs_handle_5v_conflict(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
+       uint32_t tmp;
+       setbits_le32(&power_regs->hw_power_vddioctrl,
+                       POWER_VDDIOCTRL_BO_OFFSET_MASK);
+       for (;;) {
+               tmp = readl(&power_regs->hw_power_sts);
+               if (tmp & POWER_STS_VDDIO_BO) {
+                       /*
+                        * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes
+                        * unreliable
+                        */
+                       mxs_powerdown();
+                       break;
+               }
+               if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
+                       mxs_boot_valid_5v();
+                       break;
+               } else {
+                       mxs_powerdown();
+                       break;
+               }
+               if (tmp & POWER_STS_PSWITCH_MASK) {
+                       mxs_batt_boot();
+                       break;
+               }
+       }
+ }
+ static void mxs_5v_boot(void)
+ {
 -static void mxs_init_batt_bo(void)
+       /*
+        * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
+        * but their implementation always returns 1 so we omit it here.
+        */
+       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+               mxs_boot_valid_5v();
+               return;
+       }
+       early_delay(1000);
+       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+               mxs_boot_valid_5v();
+               return;
+       }
+       mxs_handle_5v_conflict();
+ }
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
++static void mxs_fixed_batt_boot(void)
+ {
 -      /* Brownout at 3V */
++      writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
++
++      setbits_le32(&power_regs->hw_power_5vctrl,
++              POWER_5VCTRL_PWDN_5VBRNOUT |
++              POWER_5VCTRL_ENABLE_DCDC |
++              POWER_5VCTRL_ILIMIT_EQ_ZERO |
++              POWER_5VCTRL_PWDN_5VBRNOUT |
++              POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
++
++      writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
++
++      clrbits_le32(&power_regs->hw_power_vdddctrl,
++              POWER_VDDDCTRL_DISABLE_FET |
++              POWER_VDDDCTRL_ENABLE_LINREG |
++              POWER_VDDDCTRL_DISABLE_STEPPING);
++
++      clrbits_le32(&power_regs->hw_power_vddactrl,
++              POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
++              POWER_VDDACTRL_DISABLE_STEPPING);
++
++      clrbits_le32(&power_regs->hw_power_vddioctrl,
++              POWER_VDDIOCTRL_DISABLE_FET |
++              POWER_VDDIOCTRL_DISABLE_STEPPING);
 -              15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
++      /* Stop 5V detection */
++      writel(POWER_5VCTRL_PWRUP_VBUS_CMPS,
++              &power_regs->hw_power_5vctrl_clr);
++}
++
++static void mxs_init_batt_bo(void)
++{
+       clrsetbits_le32(&power_regs->hw_power_battmonitor,
+               POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
++              BATT_BO_VAL << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
+       writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
+       writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
+ }
+ static void mxs_switch_vddd_to_dcdc_source(void)
+ {
 -      int batt_ready, batt_good;
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+       clrsetbits_le32(&power_regs->hw_power_vdddctrl,
+               POWER_VDDDCTRL_LINREG_OFFSET_MASK,
+               POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
+       clrbits_le32(&power_regs->hw_power_vdddctrl,
+               POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
+               POWER_VDDDCTRL_DISABLE_STEPPING);
+ }
+ static void mxs_power_configure_power_source(void)
+ {
 -      if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
 -              batt_ready = mxs_is_batt_ready();
 -              if (batt_ready) {
 -                      /* 5V source detected, good battery detected. */
 -                      mxs_batt_boot();
 -              } else {
 -                      batt_good = mxs_is_batt_good();
 -                      if (!batt_good) {
 -                              /* 5V source detected, bad battery detected. */
 -                              writel(LRADC_CONVERSION_AUTOMATIC,
 -                                      &lradc_regs->hw_lradc_conversion_clr);
 -                              clrbits_le32(&power_regs->hw_power_battmonitor,
 -                                      POWER_BATTMONITOR_BATT_VAL_MASK);
+       struct mxs_lradc_regs *lradc_regs =
+               (struct mxs_lradc_regs *)MXS_LRADC_BASE;
+       mxs_src_power_init();
 -                      mxs_5v_boot();
++      if (!fixed_batt_supply) {
++              if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
++                      if (mxs_is_batt_ready()) {
++                              /* 5V source detected, good battery detected. */
++                              mxs_batt_boot();
++                      } else {
++                              if (!mxs_is_batt_good()) {
++                                      /* 5V source detected, bad battery detected. */
++                                      writel(LRADC_CONVERSION_AUTOMATIC,
++                                              &lradc_regs->hw_lradc_conversion_clr);
++                                      clrbits_le32(&power_regs->hw_power_battmonitor,
++                                              POWER_BATTMONITOR_BATT_VAL_MASK);
++                              }
++                              mxs_5v_boot();
+                       }
 -              /* 5V not detected, booting from battery. */
 -              mxs_batt_boot();
++              } else {
++                      /* 5V not detected, booting from battery. */
++                      mxs_batt_boot();
+               }
+       } else {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
++              mxs_fixed_batt_boot();
+       }
+       mxs_power_clock2pll();
+       mxs_init_batt_bo();
+       mxs_switch_vddd_to_dcdc_source();
+ }
+ static void mxs_enable_output_rail_protection(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+       writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
+               POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
+       setbits_le32(&power_regs->hw_power_vdddctrl,
+                       POWER_VDDDCTRL_PWDN_BRNOUT);
+       setbits_le32(&power_regs->hw_power_vddactrl,
+                       POWER_VDDACTRL_PWDN_BRNOUT);
+       setbits_le32(&power_regs->hw_power_vddioctrl,
+                       POWER_VDDIOCTRL_PWDN_BRNOUT);
+ }
+ static int mxs_get_vddio_power_source_off(void)
+ {
 -      if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+       uint32_t tmp;
 -
++      if ((readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) &&
++              !(readl(&power_regs->hw_power_5vctrl) &
++                      POWER_5VCTRL_ILIMIT_EQ_ZERO)) {
++
+               tmp = readl(&power_regs->hw_power_vddioctrl);
+               if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
+                       if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
+                               POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
+                               return 1;
+                       }
+               }
+               if (!(readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_ENABLE_DCDC)) {
+                       if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
+                               POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
+                               return 1;
+                       }
+               }
+       }
+       return 0;
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+ }
+ static int mxs_get_vddd_power_source_off(void)
+ {
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
+       uint32_t tmp;
+       tmp = readl(&power_regs->hw_power_vdddctrl);
+       if (tmp & POWER_VDDDCTRL_DISABLE_FET) {
+               if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
+                       POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
+                       return 1;
+               }
+       }
+       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+               if (!(readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_ENABLE_DCDC)) {
+                       return 1;
+               }
+       }
+       if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) {
+               if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
+                       POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) {
+                       return 1;
+               }
+       }
+       return 0;
+ }
++static int mxs_get_vdda_power_source_off(void)
++{
++      uint32_t tmp;
++
++      tmp = readl(&power_regs->hw_power_vddactrl);
++      if (tmp & POWER_VDDACTRL_DISABLE_FET) {
++              if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
++                      POWER_VDDACTRL_LINREG_OFFSET_0STEPS) {
++                      return 1;
++              }
++      }
++
++      if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
++              if (!(readl(&power_regs->hw_power_5vctrl) &
++                      POWER_5VCTRL_ENABLE_DCDC)) {
++                      return 1;
++              }
++      }
++
++      if (!(tmp & POWER_VDDACTRL_ENABLE_LINREG)) {
++              if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
++                      POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW) {
++                      return 1;
++              }
++      }
++
++      return 0;
++}
++
+ struct mxs_vddx_cfg {
+       uint32_t                *reg;
+       uint8_t                 step_mV;
+       uint16_t                lowest_mV;
++      uint16_t                highest_mV;
+       int                     (*powered_by_linreg)(void);
+       uint32_t                trg_mask;
+       uint32_t                bo_irq;
+       uint32_t                bo_enirq;
+       uint32_t                bo_offset_mask;
+       uint32_t                bo_offset_offset;
+ };
+ static const struct mxs_vddx_cfg mxs_vddio_cfg = {
+       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
+                                       hw_power_vddioctrl),
+       .step_mV                = 50,
+       .lowest_mV              = 2800,
++      .highest_mV             = 3600,
+       .powered_by_linreg      = mxs_get_vddio_power_source_off,
+       .trg_mask               = POWER_VDDIOCTRL_TRG_MASK,
+       .bo_irq                 = POWER_CTRL_VDDIO_BO_IRQ,
+       .bo_enirq               = POWER_CTRL_ENIRQ_VDDIO_BO,
+       .bo_offset_mask         = POWER_VDDIOCTRL_BO_OFFSET_MASK,
+       .bo_offset_offset       = POWER_VDDIOCTRL_BO_OFFSET_OFFSET,
+ };
+ static const struct mxs_vddx_cfg mxs_vddd_cfg = {
+       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
+                                       hw_power_vdddctrl),
+       .step_mV                = 25,
+       .lowest_mV              = 800,
++      .highest_mV             = 1575,
+       .powered_by_linreg      = mxs_get_vddd_power_source_off,
+       .trg_mask               = POWER_VDDDCTRL_TRG_MASK,
+       .bo_irq                 = POWER_CTRL_VDDD_BO_IRQ,
+       .bo_enirq               = POWER_CTRL_ENIRQ_VDDD_BO,
+       .bo_offset_mask         = POWER_VDDDCTRL_BO_OFFSET_MASK,
+       .bo_offset_offset       = POWER_VDDDCTRL_BO_OFFSET_OFFSET,
+ };
++static const struct mxs_vddx_cfg mxs_vdda_cfg = {
++      .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
++                                      hw_power_vddactrl),
++      .step_mV                = 50,
++      .lowest_mV              = 2800,
++      .highest_mV             = 3600,
++      .powered_by_linreg      = mxs_get_vdda_power_source_off,
++      .trg_mask               = POWER_VDDACTRL_TRG_MASK,
++      .bo_irq                 = POWER_CTRL_VDDA_BO_IRQ,
++      .bo_enirq               = POWER_CTRL_ENIRQ_VDDA_BO,
++      .bo_offset_mask         = POWER_VDDACTRL_BO_OFFSET_MASK,
++      .bo_offset_offset       = POWER_VDDACTRL_BO_OFFSET_OFFSET,
++};
++
++static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
++      .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
++                                      hw_power_vddmemctrl),
++      .step_mV                = 25,
++      .lowest_mV              = 1100,
++      .highest_mV             = 1750,
++      .bo_offset_mask         = POWER_VDDMEMCTRL_BO_OFFSET_MASK,
++      .bo_offset_offset       = POWER_VDDMEMCTRL_BO_OFFSET_OFFSET,
++};
++
+ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
+                               uint32_t new_target, uint32_t new_brownout)
+ {
 -      uint32_t powered_by_linreg = 0;
 -      int adjust_up, tmp;
+       uint32_t cur_target, diff, bo_int = 0;
 -      powered_by_linreg = cfg->powered_by_linreg();
++      int powered_by_linreg = 0;
++      int adjust_up;
++
++      if (new_target < cfg->lowest_mV)
++              new_target = cfg->lowest_mV;
++      if (new_target > cfg->highest_mV)
++              new_target = cfg->highest_mV;
+       new_brownout = DIV_ROUND(new_target - new_brownout, cfg->step_mV);
+       cur_target = readl(cfg->reg);
+       cur_target &= cfg->trg_mask;
+       cur_target *= cfg->step_mV;
+       cur_target += cfg->lowest_mV;
+       adjust_up = new_target > cur_target;
 -                              POWER_STS_VDD5V_GT_VDDIO))
++      if (cfg->powered_by_linreg)
++              powered_by_linreg = cfg->powered_by_linreg();
+       if (adjust_up) {
+               if (powered_by_linreg) {
+                       bo_int = readl(cfg->reg);
+                       clrbits_le32(cfg->reg, cfg->bo_enirq);
+               }
+               setbits_le32(cfg->reg, cfg->bo_offset_mask);
+       }
+       do {
+               if (abs(new_target - cur_target) > 100) {
+                       if (adjust_up)
+                               diff = cur_target + 100;
+                       else
+                               diff = cur_target - 100;
+               } else {
+                       diff = new_target;
+               }
+               diff -= cfg->lowest_mV;
+               diff /= cfg->step_mV;
+               clrsetbits_le32(cfg->reg, cfg->trg_mask, diff);
+               if (powered_by_linreg ||
+                       (readl(&power_regs->hw_power_sts) &
 -              else {
 -                      for (;;) {
 -                              tmp = readl(&power_regs->hw_power_sts);
 -                              if (tmp & POWER_STS_DC_OK)
 -                                      break;
++                              POWER_STS_VDD5V_GT_VDDIO)) {
+                       early_delay(500);
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
++              } else {
++                      while (!(readl(&power_regs->hw_power_sts) &
++                                      POWER_STS_DC_OK)) {
++
+                       }
+               }
+               cur_target = readl(cfg->reg);
+               cur_target &= cfg->trg_mask;
+               cur_target *= cfg->step_mV;
+               cur_target += cfg->lowest_mV;
+       } while (new_target > cur_target);
+       if (adjust_up && powered_by_linreg) {
+               writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
+               if (bo_int & cfg->bo_enirq)
+                       setbits_le32(cfg->reg, cfg->bo_enirq);
+       }
+       clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
+                       new_brownout << cfg->bo_offset_offset);
+ }
+ static void mxs_setup_batt_detect(void)
+ {
+       mxs_lradc_init();
+       mxs_lradc_enable_batt_measurement();
+       early_delay(10);
+ }
+ void mxs_power_init(void)
+ {
 -      mxs_power_setup_5v_detect();
+       mxs_power_clock2xtal();
+       mxs_power_clear_auto_restart();
+       mxs_power_set_linreg();
 -      mxs_setup_batt_detect();
 -      mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
 -      mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000);
 -
++      if (!fixed_batt_supply) {
++              mxs_power_setup_5v_detect();
++              mxs_setup_batt_detect();
++      }
+       mxs_power_configure_power_source();
+       mxs_enable_output_rail_protection();
 -
 -      writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
 -
 -      early_delay(1000);
++      mxs_power_set_vddx(&mxs_vddio_cfg, VDDIO_VAL, VDDIO_BO_VAL);
++      mxs_power_set_vddx(&mxs_vddd_cfg, VDDD_VAL, VDDD_BO_VAL);
++      mxs_power_set_vddx(&mxs_vdda_cfg, VDDA_VAL, VDDA_BO_VAL);
++#if VDDMEM_VAL > 0
++      mxs_power_set_vddx(&mxs_vddmem_cfg, VDDMEM_VAL, VDDMEM_BO_VAL);
++
++      setbits_le32(&power_regs->hw_power_vddmemctrl,
++              POWER_VDDMEMCTRL_ENABLE_LINREG);
++      early_delay(500);
++      clrbits_le32(&power_regs->hw_power_vddmemctrl,
++              POWER_VDDMEMCTRL_ENABLE_ILIMIT);
++#else
++      clrbits_le32(&power_regs->hw_power_vddmemctrl,
++              POWER_VDDMEMCTRL_ENABLE_LINREG);
++#endif
+       writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
+               POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
+               POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
+               POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
 -      struct mxs_power_regs *power_regs =
 -              (struct mxs_power_regs *)MXS_POWER_BASE;
 -
++      if (!fixed_batt_supply)
++              writel(POWER_5VCTRL_PWDN_5VBRNOUT,
++                      &power_regs->hw_power_5vctrl_set);
+ }
+ #ifdef        CONFIG_SPL_MX28_PSWITCH_WAIT
+ void mxs_power_wait_pswitch(void)
+ {
+       while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
+               ;
+ }
+ #endif
index 0000000,3738411..f2dfc8a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,156 +1,165 @@@
 -#define timestamp (gd->arch.tbl)
 -#define lastdec (gd->arch.lastinc)
+ /*
+  * Freescale i.MX28 timer driver
+  *
+  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+  * on behalf of DENX Software Engineering GmbH
+  *
+  * Based on code from LTIB:
+  * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  */
+ #include <common.h>
+ #include <asm/io.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/arch/sys_proto.h>
+ /* Maximum fixed count */
+ #define TIMER_LOAD_VAL        0xffffffff
+ DECLARE_GLOBAL_DATA_PTR;
 -#define       MX28_INCREMENTER_HZ             1000
++/* Enable this to verify that the code can correctly
++ * handle the timer rollover
++ */
++/* #define DEBUG_TIMER_WRAP */
++
++#ifdef DEBUG_TIMER_WRAP
++/*
++ * Let the timer wrap 15 seconds after start to catch misbehaving
++ * timer related code early
++ */
++#define TIMER_START           (-time_to_tick(15 * CONFIG_SYS_HZ))
++#else
++#define TIMER_START           0UL
++#endif
+ /*
+  * This driver uses 1kHz clock source.
+  */
 -      return tick / (MX28_INCREMENTER_HZ / CONFIG_SYS_HZ);
++#define       MXS_INCREMENTER_HZ              1000
+ static inline unsigned long tick_to_time(unsigned long tick)
+ {
 -      return time * (MX28_INCREMENTER_HZ / CONFIG_SYS_HZ);
 -}
 -
 -/* Calculate how many ticks happen in "us" microseconds */
 -static inline unsigned long us_to_tick(unsigned long us)
 -{
 -      return (us * MX28_INCREMENTER_HZ) / 1000000;
++      return tick / (MXS_INCREMENTER_HZ / CONFIG_SYS_HZ);
+ }
+ static inline unsigned long time_to_tick(unsigned long time)
+ {
 -      /* Set fixed_count to maximal value */
++      return time * (MXS_INCREMENTER_HZ / CONFIG_SYS_HZ);
+ }
+ int timer_init(void)
+ {
+       struct mxs_timrot_regs *timrot_regs =
+               (struct mxs_timrot_regs *)MXS_TIMROT_BASE;
+       /* Reset Timers and Rotary Encoder module */
+       mxs_reset_block(&timrot_regs->hw_timrot_rotctrl_reg);
+       /* Set fixed_count to 0 */
+       writel(0, &timrot_regs->hw_timrot_fixed_count0);
+       /* Set UPDATE bit and 1Khz frequency */
+       writel(TIMROT_TIMCTRLn_UPDATE | TIMROT_TIMCTRLn_RELOAD |
+               TIMROT_TIMCTRLn_SELECT_1KHZ_XTAL,
+               &timrot_regs->hw_timrot_timctrl0);
 -
++#ifndef DEBUG_TIMER_WRAP
++      /* Set fixed_count to maximum value */
+       writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
 -
 -      /* Current tick value */
 -      uint32_t now = readl(&timrot_regs->hw_timrot_running_count0);
 -
 -      if (lastdec >= now) {
 -              /*
 -               * normal mode (non roll)
 -               * move stamp forward with absolut diff ticks
 -               */
 -              timestamp += (lastdec - now);
 -      } else {
 -              /* we have rollover of decrementer */
 -              timestamp += (TIMER_LOAD_VAL - now) + lastdec;
 -
 -      }
 -      lastdec = now;
 -
 -      return timestamp;
++#else
++      /* Set fixed_count so that the counter will wrap after 20 seconds */
++      writel(20 * MXS_INCREMENTER_HZ,
++              &timrot_regs->hw_timrot_fixed_count0);
++      gd->arch.lastinc = TIMER_LOAD_VAL - 20 * MXS_INCREMENTER_HZ;
++#endif
++#ifdef DEBUG_TIMER_WRAP
++      /* Make the usec counter roll over 30 seconds after startup */
++      writel(-30000000, MXS_HW_DIGCTL_MICROSECONDS);
++#endif
++      writel(TIMROT_TIMCTRLn_UPDATE,
++              &timrot_regs->hw_timrot_timctrl0_clr);
++#ifdef DEBUG_TIMER_WRAP
++      /* Set fixed_count to maximal value for subsequent loads */
++      writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
++#endif
++      gd->arch.timer_rate_hz = MXS_INCREMENTER_HZ;
++      gd->arch.tbl = TIMER_START;
++      gd->arch.tbu = 0;
+       return 0;
+ }
++/* Note: This function works correctly for TIMER_LOAD_VAL == 0xffffffff!
++ * The rollover is handled automagically due to the properties of
++ * two's complement arithmetic.
++ * For any other value of TIMER_LOAD_VAL the calculations would have
++ * to be done modulus(TIMER_LOAD_VAL + 1).
++ */
+ unsigned long long get_ticks(void)
+ {
+       struct mxs_timrot_regs *timrot_regs =
+               (struct mxs_timrot_regs *)MXS_TIMROT_BASE;
 -      return get_timer_masked() - base;
++      /* The timer is counting down, so subtract the register value from
++       * the counter period length to get an incrementing timestamp
++       */
++      unsigned long now = -readl(&timrot_regs->hw_timrot_running_count0);
++      ulong inc = now - gd->arch.lastinc;
++
++      gd->arch.tbl += inc;
++      gd->arch.lastinc = now;
++      /* Since the get_timer() function only uses a 32bit value
++       * it doesn't make sense to return a real 64 bit value here.
++       */
++      return gd->arch.tbl;
+ }
+ ulong get_timer_masked(void)
+ {
+       return tick_to_time(get_ticks());
+ }
+ ulong get_timer(ulong base)
+ {
 -#define       MX28_HW_DIGCTL_MICROSECONDS     0x8001c0c0
++      /* NOTE: time_to_tick(base) is required to correctly handle rollover! */
++      return tick_to_time(get_ticks() - time_to_tick(base));
+ }
+ /* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
 -      uint32_t old, new, incr;
 -      uint32_t counter = 0;
 -
 -      old = readl(MX28_HW_DIGCTL_MICROSECONDS);
 -
 -      while (counter < usec) {
 -              new = readl(MX28_HW_DIGCTL_MICROSECONDS);
 -
 -              /* Check if the timer wrapped. */
 -              if (new < old) {
 -                      incr = 0xffffffff - old;
 -                      incr += new;
 -              } else {
 -                      incr = new - old;
 -              }
 -
 -              /*
 -               * Check if we are close to the maximum time and the counter
 -               * would wrap if incremented. If that's the case, break out
 -               * from the loop as the requested delay time passed.
++#define       MXS_HW_DIGCTL_MICROSECONDS      0x8001c0c0
+ void __udelay(unsigned long usec)
+ {
 -              if (counter + incr < counter)
 -                      break;
 -
 -              counter += incr;
 -              old = new;
 -      }
++      uint32_t start = readl(MXS_HW_DIGCTL_MICROSECONDS);
++
++      while (readl(MXS_HW_DIGCTL_MICROSECONDS) - start <= usec)
++              /* use '<=' to guarantee a delay of _at least_
++               * the given number of microseconds.
++               * No need for fancy rollover checks
++               * Two's complement arithmetic applied correctly
++               * does everything that's needed  automagically!
+                */
 -      return MX28_INCREMENTER_HZ;
++              ;
+ }
+ ulong get_tbclk(void)
+ {
++      return gd->arch.timer_rate_hz;
+ }
index 0000000,c60615a..d336393
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,14 +1,14 @@@
 -      u_boot_spl="spl/u-boot-spl.bin";
 -      u_boot="u-boot.bin";
+ sources {
 -      load u_boot_spl > 0x0000;
 -      load ivt (entry = 0x0014) > 0x8000;
++      u_boot_spl="spl/u-boot-spl";
++      u_boot="u-boot";
+ }
+ section (0) {
 -      load u_boot > 0x40000100;
 -      load ivt (entry = 0x40000100) > 0x8000;
++      load u_boot_spl;
++      load ivt (entry = u_boot_spl:reset) > 0x8000;
+       hab call 0x8000;
++      load u_boot;
++      load ivt (entry = u_boot:reset) > 0x8000;
+       hab call 0x8000;
+ }
@@@ -18,12 -18,12 +18,13 @@@ LIB        = $(obj)lib$(SOC).
  
  COBJS += clock.o
  COBJS += sys_info.o
- COBJS-$(CONFIG_SYS_SDRAM_DDR3)        += ddr3.o
- COBJS-$(CONFIG_SYS_SDRAM_DDR2)        += ddr2.o
  COBJS += mem.o
+ COBJS += ddr.o
  COBJS += emif4.o
  COBJS += board.o
+ COBJS += mux.o
+ COBJS-$(CONFIG_NAND_OMAP_GPMC)        += elm.o
 +COBJS-$(CONFIG_NAND_AM33XX) += elm.o
  
  SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
  OBJS  := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
  #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/common_def.h>
+ #include <asm/arch/sys_proto.h>
  #include <asm/io.h>
- #include <asm/omap_common.h>
+ #include <asm/emif.h>
+ #include <asm/gpio.h>
+ #include <i2c.h>
+ #include <miiphy.h>
 -#include <cpsw.h>
++//#include <cpsw.h>
+ #include <asm/errno.h>
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/gadget.h>
+ #include <linux/usb/musb.h>
+ #include <asm/omap_musb.h>
  
  DECLARE_GLOBAL_DATA_PTR;
  
- /* UART Defines */
- #ifdef CONFIG_SPL_BUILD
- #define UART_RESET            (0x1 << 1)
- #define UART_CLK_RUNNING_MASK 0x1
- #define UART_SMART_IDLE_EN    (0x1 << 0x3)
- #endif
+ static const struct gpio_bank gpio_bank_am33xx[4] = {
+       { (void *)AM33XX_GPIO0_BASE, METHOD_GPIO_24XX },
+       { (void *)AM33XX_GPIO1_BASE, METHOD_GPIO_24XX },
+       { (void *)AM33XX_GPIO2_BASE, METHOD_GPIO_24XX },
+       { (void *)AM33XX_GPIO3_BASE, METHOD_GPIO_24XX },
+ };
  
- void reset_cpu(unsigned long ignored)
- {
-       /* clear RESET flags */
-       writel(~0, PRM_RSTST);
-       writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL);
- }
+ const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
  
- /*
-  * early system init of muxing and clocks.
-  */
- void s_init(void)
 +#ifdef CONFIG_HW_WATCHDOG
 +void hw_watchdog_reset(void)
 +{
 +      struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
 +      static int trg __attribute__((section(".data")));
 +
 +      switch (trg) {
 +      case 0:
 +      case 1:
 +              if (readl(&wdtimer->wdtwwps) & (1 << 4))
 +                      return;
 +              writel(trg ? 0x5555 : 0xaaaa, &wdtimer->wdtwspr);
 +              break;
 +      case 2:
 +              if (readl(&wdtimer->wdtwwps) & (1 << 2))
 +                      return;
 +              /* 10 sec timeout */
 +              writel(-32768 * 10, &wdtimer->wdtwldr);
 +
 +              if (readl(&wdtimer->wdtwwps) & (1 << 0))
 +                      return;
 +              /* prescaler = 1 */
 +              writel(0, &wdtimer->wdtwclr);
 +              break;
 +
 +      case 3:
 +      case 4:
 +              /* enable watchdog */
 +              if (readl(&wdtimer->wdtwwps) & (1 << 4))
 +                      return;
 +              writel((trg & 1) ? 0xBBBB : 0x4444, &wdtimer->wdtwspr);
 +              break;
 +
 +      default:
 +              /* retrigger watchdog */
 +              if (readl(&wdtimer->wdtwwps) & (1 << 3))
 +                      return;
 +
 +              writel(trg, &wdtimer->wdtwtgr);
 +              trg ^= 0x2;
 +              return;
 +      }
 +      trg++;
 +}
 +#endif
 +
+ #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
+ int cpu_mmc_init(bd_t *bis)
  {
- #ifdef CONFIG_SPL_BUILD
- #ifndef CONFIG_HW_WATCHDOG
-       struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
-       /* WDT1 is already running when the bootloader gets control
-        * Disable it to avoid "random" resets
-        */
-       writel(0xAAAA, &wdtimer->wdtwspr);
-       while (readl(&wdtimer->wdtwwps) != 0x0)
-               ;
-       writel(0x5555, &wdtimer->wdtwspr);
-       while (readl(&wdtimer->wdtwwps) != 0x0)
-               ;
- #endif
-       /* Setup the PLLs and the clocks for the peripherals */
-       pll_init();
-       /* UART softreset */
-       u32 regVal;
-       struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
+       int ret;
  
-       enable_uart0_pin_mux();
-       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);
+       ret = omap_mmc_init(0, 0, 0);
+       if (ret)
+               return ret;
  
-       /* Initialize the Timer */
-       timer_init();
+       return omap_mmc_init(1, 0, 0);
+ }
+ #endif
  
-       preloader_console_init();
+ void setup_clocks_for_console(void)
+ {
+       /* Not yet implemented */
+       return;
+ }
  
-       config_ddr();
+ /* AM33XX has two MUSB controllers which can be host or gadget */
+ #if (defined(CONFIG_MUSB_GADGET) || defined(CONFIG_MUSB_HOST)) && \
+       (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1))
+ static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
  
-       /* Enable MMC0 */
-       enable_mmc0_pin_mux();
- #endif
- }
+ /* 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)
  
- #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
- int board_mmc_init(bd_t *bis)
+ static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr)
  {
-       int ret = 0;
- #ifdef CONFIG_OMAP_MMC_DEV_0
-       ret = omap_mmc_init(0, 0, 0);
-       if (ret)
-               printf("Error %d while initializing MMC dev 0\n", ret);
- #endif
- #ifdef CONFIG_OMAP_MMC_DEV_1
-       ret = omap_mmc_init(1, 0, 0);
-       if (ret)
-               printf("Error %d while initializing MMC dev 1\n", ret);
- #endif
-       return ret;
+       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);
+       }
  }
- #endif
  
- #ifndef CONFIG_SYS_DCACHE_OFF
- void enable_caches(void)
+ 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)
  {
-       /* Enable D-cache. I-cache is already enabled in start.S */
-       dcache_enable();
+       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
  
- static u32 cortex_rev(void)
+ #ifdef CONFIG_AM335X_USB1
+ static void am33xx_otg1_set_phy_power(u8 on)
  {
-       unsigned int rev;
-       /* Read Main ID Register (MIDR) */
-       asm ("mrc p15, 0, %0, c0, c0, 0" : "=r" (rev));
-       return rev;
+       am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1);
  }
  
- void omap_rev_string(void)
- {
-       u32 omap_rev = cortex_rev();
-       u32 omap_variant = (omap_rev & 0xFFFF0000) >> 16;
-       u32 major_rev = (omap_rev & 0x00000F00) >> 8;
-       u32 minor_rev = (omap_rev & 0x000000F0) >> 4;
+ 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
  
-       printf("OMAP%x ES%x.%x\n", omap_variant, major_rev,
-               minor_rev);
+ int arch_misc_init(void)
+ {
+ #ifdef CONFIG_AM335X_USB0
+       musb_register(&otg0_plat, &otg0_board_data,
+               (void *)AM335X_USB0_OTG_BASE);
+ #endif
+ #ifdef CONFIG_AM335X_USB1
+       musb_register(&otg1_plat, &otg1_board_data,
+               (void *)AM335X_USB1_OTG_BASE);
+ #endif
+       return 0;
  }
  #define CLK_DIV_MASK          0x1f
  #define CLK_DIV2_MASK         0x7f
  #define CLK_SEL_SHIFT         0x8
 +#define CLK_MODE_MASK         0x7
  #define CLK_MODE_SEL          0x7
 -#define CLK_MODE_MASK         0xfffffff8
 -#define CLK_DIV_SEL           0xFFFFFFE0
 -#define CPGMAC0_IDLE          0x30000
 -#define DPLL_CLKDCOLDO_GATE_CTRL        0x300
++#define DPLL_CLKDCOLDO_GATE_CTRL 0x300
 +
  
  const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
  const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
  const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
+ const struct cm_rtc *cmrtc = (struct cm_rtc *)CM_RTC;
  
 +#ifdef CONFIG_SPL_BUILD
 +#define enable_clk(reg, val) __enable_clk(#reg, &reg, val)
 +
 +static void __enable_clk(const char *name, const void *reg, u32 mask)
 +{
 +      unsigned long timeout = 10000000;
 +
 +      writel(mask, reg);
 +      while (readl(reg) != mask)
 +              /* poor man's timeout, since timers not initialized */
 +              if (timeout-- == 0)
 +                      /* no error message, since console not yet available */
 +                      break;
 +}
 +
  static void enable_interface_clocks(void)
  {
        /* Enable all the Interconnect Modules */
 -      writel(PRCM_MOD_EN, &cmper->l3clkctrl);
 -      while (readl(&cmper->l3clkctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      writel(PRCM_MOD_EN, &cmper->l4lsclkctrl);
 -      while (readl(&cmper->l4lsclkctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      writel(PRCM_MOD_EN, &cmper->l4fwclkctrl);
 -      while (readl(&cmper->l4fwclkctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      writel(PRCM_MOD_EN, &cmwkup->wkl4wkclkctrl);
 -      while (readl(&cmwkup->wkl4wkclkctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      writel(PRCM_MOD_EN, &cmper->l3instrclkctrl);
 -      while (readl(&cmper->l3instrclkctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      writel(PRCM_MOD_EN, &cmper->l4hsclkctrl);
 -      while (readl(&cmper->l4hsclkctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      writel(PRCM_MOD_EN, &cmwkup->wkgpio0clkctrl);
 -      while (readl(&cmwkup->wkgpio0clkctrl) != PRCM_MOD_EN)
 -              ;
 +      enable_clk(cmper->l3clkctrl, PRCM_MOD_EN);
 +      enable_clk(cmper->l4lsclkctrl, PRCM_MOD_EN);
 +      enable_clk(cmper->l4fwclkctrl, PRCM_MOD_EN);
 +      enable_clk(cmwkup->wkl4wkclkctrl, PRCM_MOD_EN);
 +      enable_clk(cmper->l3instrclkctrl, PRCM_MOD_EN);
 +      enable_clk(cmper->l4hsclkctrl, PRCM_MOD_EN);
 +#ifdef CONFIG_HW_WATCHDOG
 +      enable_clk(cmwkup->wdtimer1ctrl, PRCM_MOD_EN);
 +#endif
 +      /* GPIO0 */
-       enable_clk(cmwkup->gpio0clkctrl, PRCM_MOD_EN);
++      enable_clk(cmwkup->wkgpio0clkctrl, PRCM_MOD_EN);
  }
  
  /*
@@@ -100,52 -111,105 +103,64 @@@ static void enable_per_clocks(void
        /* Select the Master osc 24 MHZ as Timer2 clock source */
        writel(0x1, &cmdpll->clktimer2clk);
  
 +#ifdef CONFIG_SYS_NS16550_COM1
        /* UART0 */
 -      writel(PRCM_MOD_EN, &cmwkup->wkup_uart0ctrl);
 -      while (readl(&cmwkup->wkup_uart0ctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      /* UART1 */
 -#ifdef CONFIG_SERIAL2
 -      writel(PRCM_MOD_EN, &cmper->uart1clkctrl);
 -      while (readl(&cmper->uart1clkctrl) != PRCM_MOD_EN)
 -              ;
 -#endif /* CONFIG_SERIAL2 */
 -
 -      /* UART2 */
 -#ifdef CONFIG_SERIAL3
 -      writel(PRCM_MOD_EN, &cmper->uart2clkctrl);
 -      while (readl(&cmper->uart2clkctrl) != PRCM_MOD_EN)
 -              ;
 -#endif /* CONFIG_SERIAL3 */
 -
 -      /* UART3 */
 -#ifdef CONFIG_SERIAL4
 -      writel(PRCM_MOD_EN, &cmper->uart3clkctrl);
 -      while (readl(&cmper->uart3clkctrl) != PRCM_MOD_EN)
 -              ;
 -#endif /* CONFIG_SERIAL4 */
 -
 -      /* UART4 */
 -#ifdef CONFIG_SERIAL5
 -      writel(PRCM_MOD_EN, &cmper->uart4clkctrl);
 -      while (readl(&cmper->uart4clkctrl) != PRCM_MOD_EN)
 -              ;
 -#endif /* CONFIG_SERIAL5 */
 -
 -      /* UART5 */
 -#ifdef CONFIG_SERIAL6
 -      writel(PRCM_MOD_EN, &cmper->uart5clkctrl);
 -      while (readl(&cmper->uart5clkctrl) != PRCM_MOD_EN)
 -              ;
 -#endif /* CONFIG_SERIAL6 */
 -
 +      enable_clk(cmwkup->wkup_uart0ctrl, PRCM_MOD_EN);
 +#endif
 +#ifdef CONFIG_SYS_NS16550_COM2
 +      enable_clk(cmper->uart1clkctrl, PRCM_MOD_EN);
 +#endif
 +#ifdef CONFIG_SYS_NS16550_COM3
 +      enable_clk(cmper->uart2clkctrl, PRCM_MOD_EN);
 +#endif
 +#ifdef CONFIG_SYS_NS16550_COM4
 +      enable_clk(cmper->uart3clkctrl, PRCM_MOD_EN);
 +#endif
 +#ifdef CONFIG_SYS_NS16550_COM5
 +      enable_clk(cmper->uart4clkctrl, PRCM_MOD_EN);
 +#endif
 +#ifdef CONFIG_SYS_NS16550_COM6
 +      enable_clk(cmper->uart5clkctrl, PRCM_MOD_EN);
 +#endif
        /* GPMC */
 -      writel(PRCM_MOD_EN, &cmper->gpmcclkctrl);
 -      while (readl(&cmper->gpmcclkctrl) != PRCM_MOD_EN)
 -              ;
 +      enable_clk(cmper->gpmcclkctrl, PRCM_MOD_EN);
  
        /* ELM */
 -      writel(PRCM_MOD_EN, &cmper->elmclkctrl);
 -      while (readl(&cmper->elmclkctrl) != PRCM_MOD_EN)
 -              ;
 +      enable_clk(cmper->elmclkctrl, PRCM_MOD_EN);
  
 -      /* MMC0*/
 -      writel(PRCM_MOD_EN, &cmper->mmc0clkctrl);
 -      while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN)
 -              ;
 +      /* Ethernet */
-       enable_clk(cmper->cpswclkctrl, PRCM_MOD_EN);
++      enable_clk(cmper->cpswclkstctrl, PRCM_MOD_EN);
 +      enable_clk(cmper->cpgmac0clkctrl, PRCM_MOD_EN);
 +
 +      /* MMC */
 +#ifndef CONFIG_OMAP_MMC_DEV_0
 +      enable_clk(cmper->mmc0clkctrl, PRCM_MOD_EN);
 +#endif
 +#ifdef CONFIG_OMAP_MMC_DEV_1
 +      enable_clk(cmper->mmc1clkctrl, PRCM_MOD_EN);
 +#endif
 +      /* LCD */
-       enable_clk(cmper->lcdcclkctrl, PRCM_MOD_EN);
++      enable_clk(cmper->lcdclkctrl, PRCM_MOD_EN);
  
        /* i2c0 */
 -      writel(PRCM_MOD_EN, &cmwkup->wkup_i2c0ctrl);
 -      while (readl(&cmwkup->wkup_i2c0ctrl) != PRCM_MOD_EN)
 -              ;
 +      enable_clk(cmwkup->wkup_i2c0ctrl, PRCM_MOD_EN);
  
 -      /* gpio1 module */
 -      writel(PRCM_MOD_EN, &cmper->gpio1clkctrl);
 -      while (readl(&cmper->gpio1clkctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      /* gpio2 module */
 -      writel(PRCM_MOD_EN, &cmper->gpio2clkctrl);
 -      while (readl(&cmper->gpio2clkctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      /* gpio3 module */
 -      writel(PRCM_MOD_EN, &cmper->gpio3clkctrl);
 -      while (readl(&cmper->gpio3clkctrl) != PRCM_MOD_EN)
 -              ;
 +      /* GPIO1-3 */
 +      enable_clk(cmper->gpio1clkctrl, PRCM_MOD_EN);
 +      enable_clk(cmper->gpio2clkctrl, PRCM_MOD_EN);
 +      enable_clk(cmper->gpio3clkctrl, PRCM_MOD_EN);
+       /* i2c1 */
 -      writel(PRCM_MOD_EN, &cmper->i2c1clkctrl);
 -      while (readl(&cmper->i2c1clkctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      /* Ethernet */
 -      writel(PRCM_MOD_EN, &cmper->cpgmac0clkctrl);
 -      while ((readl(&cmper->cpgmac0clkctrl) & CPGMAC0_IDLE) != PRCM_FUNCTL)
 -              ;
++      enable_clk(cmper->i2c1clkctrl, PRCM_MOD_EN);
+       /* spi0 */
 -      writel(PRCM_MOD_EN, &cmper->spi0clkctrl);
 -      while (readl(&cmper->spi0clkctrl) != PRCM_MOD_EN)
 -              ;
++      enable_clk(cmper->spi0clkctrl, PRCM_MOD_EN);
 -      /* RTC */
 -      writel(PRCM_MOD_EN, &cmrtc->rtcclkctrl);
 -      while (readl(&cmrtc->rtcclkctrl) != PRCM_MOD_EN)
 -              ;
++      /* rtc */
++      enable_clk(cmrtc->rtcclkctrl, PRCM_MOD_EN);
 -      /* MUSB */
 -      writel(PRCM_MOD_EN, &cmper->usb0clkctrl);
 -      while (readl(&cmper->usb0clkctrl) != PRCM_MOD_EN)
 -              ;
++      /* usb0 */
++      enable_clk(cmper->usb0clkctrl, PRCM_MOD_EN);
  }
  
  static void mpu_pll_config(void)
@@@ -245,39 -306,11 +260,41 @@@ static void per_pll_config(void
  
        while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK)
                ;
+       writel(DPLL_CLKDCOLDO_GATE_CTRL, &cmwkup->clkdcoldodpllper);
  }
  
- static void ddr_pll_config(void)
 +static void disp_pll_config(void)
 +{
 +      u32 clkmode, clksel, div_m2;
 +
 +      clkmode = readl(&cmwkup->clkmoddplldisp);
 +      clksel = readl(&cmwkup->clkseldplldisp);
 +      div_m2 = readl(&cmwkup->divm2dplldisp);
 +
 +      /* Set the PLL to bypass Mode */
 +      writel(PLL_BYPASS_MODE, &cmwkup->clkmoddplldisp);
 +
 +      while (!(readl(&cmwkup->idlestdplldisp) & ST_MN_BYPASS))
 +              ;
 +
 +      clksel &= ~CLK_SEL_MASK;
 +      clksel |= (DISPPLL_M << CLK_SEL_SHIFT) | DISPPLL_N;
 +      writel(clksel, &cmwkup->clkseldplldisp);
 +
 +      div_m2 &= ~CLK_DIV2_MASK;
 +      div_m2 |= DISPPLL_M2;
 +      writel(div_m2, &cmwkup->divm2dplldisp);
 +
 +      clkmode &= ~CLK_MODE_MASK;
 +      clkmode |= CLK_MODE_SEL;
 +      writel(clkmode, &cmwkup->clkmoddplldisp);
 +
 +      while (!(readl(&cmwkup->idlestdplldisp) & ST_DPLL_CLK))
 +              ;
 +}
 +
+ void ddr_pll_config(unsigned int ddrpll_m)
  {
        u32 clkmode, clksel, div_m2;
  
        writel(clkmode, &cmwkup->clkmoddpllddr);
  
        /* Wait till bypass mode is enabled */
 -      while ((readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS)
 -                              != ST_MN_BYPASS)
 +      while (!(readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS))
                ;
  
 -      clksel = clksel & (~CLK_SEL_MASK);
 -      clksel = clksel | ((ddrpll_m << CLK_SEL_SHIFT) | DDRPLL_N);
 +      clksel &= ~CLK_SEL_MASK;
-       clksel |= (DDRPLL_M << CLK_SEL_SHIFT) | DDRPLL_N;
++      clksel |= (ddrpll_m << CLK_SEL_SHIFT) | DDRPLL_N;
        writel(clksel, &cmwkup->clkseldpllddr);
  
 -      div_m2 = div_m2 & CLK_DIV_SEL;
 -      div_m2 = div_m2 | DDRPLL_M2;
 +      div_m2 &= ~CLK_DIV_MASK;
 +      div_m2 |= DDRPLL_M2;
        writel(div_m2, &cmwkup->divm2dpllddr);
  
 -      clkmode = (clkmode & CLK_MODE_MASK) | CLK_MODE_SEL;
 +      clkmode &= ~CLK_MODE_MASK;
 +      clkmode |= CLK_MODE_SEL;
        writel(clkmode, &cmwkup->clkmoddpllddr);
  
        /* Wait till dpll is locked */
@@@ -335,8 -362,6 +347,7 @@@ void pll_init(
        mpu_pll_config();
        core_pll_config();
        per_pll_config();
-       ddr_pll_config();
 +      disp_pll_config();
  
        /* Enable the required interconnect clocks */
        enable_interface_clocks();
Simple merge
@@@ -85,24 -85,7 +85,24 @@@ u32 get_sysboot_value(void
        return mode;
  }
  
- u32 get_sysboot_freq(void)
+ #ifdef CONFIG_DISPLAY_CPUINFO
 +#define SYSBOOT_FREQ_SHIFT    22
 +#define SYSBOOT_FREQ_MASK     (3 << SYSBOOT_FREQ_SHIFT)
 +
 +static unsigned long bootfreqs[] = {
 +      19200000,
 +      24000000,
 +      25000000,
 +      26000000,
 +};
 +
- #ifdef CONFIG_DISPLAY_CPUINFO
++static u32 get_sysboot_freq(void)
 +{
 +      int mode;
 +      mode = readl(&cstat->statusreg) & SYSBOOT_FREQ_MASK;
 +      return bootfreqs[mode >> SYSBOOT_FREQ_SHIFT];
 +}
 +
  /**
   * Print CPU information
   */
Simple merge
Simple merge
@@@ -84,64 -89,76 +89,133 @@@ struct pll_param 
  
  struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
  
- void set_usboh3_clk(void)
++int clk_enable(struct clk *clk)
 +{
-       unsigned int reg;
++      int ret = 0;
++
++      if (!clk)
++              return 0;
++      if (clk->usecount++ == 0) {
++              ret = clk->enable(clk);
++              if (ret)
++                      clk->usecount--;
++      }
++      return ret;
++}
 +
-       reg = readl(&mxc_ccm->cscmr1) &
-                ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK;
-       reg |= 1 << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET;
-       writel(reg, &mxc_ccm->cscmr1);
++void clk_disable(struct clk *clk)
++{
++      if (!clk)
++              return;
 +
-       reg = readl(&mxc_ccm->cscdr1);
-       reg &= ~MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK;
-       reg &= ~MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK;
-       reg |= 4 << MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET;
-       reg |= 1 << MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET;
++      if (!(--clk->usecount)) {
++              if (clk->disable)
++                      clk->disable(clk);
++      }
++      if (clk->usecount < 0) {
++              printf("%s: clk %p underflow\n", __func__, clk);
++              hang();
++      }
++}
 +
-       writel(reg, &mxc_ccm->cscdr1);
+ void set_usboh3_clk(void)
+ {
+       clrsetbits_le32(&mxc_ccm->cscmr1,
+                       MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK,
+                       MXC_CCM_CSCMR1_USBOH3_CLK_SEL(1));
+       clrsetbits_le32(&mxc_ccm->cscdr1,
+                       MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK |
+                       MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK,
+                       MXC_CCM_CSCDR1_USBOH3_CLK_PRED(4) |
+                       MXC_CCM_CSCDR1_USBOH3_CLK_PODF(1));
  }
  
  void enable_usboh3_clk(unsigned char enable)
  {
-       unsigned int reg;
+       unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
  
-       reg = readl(&mxc_ccm->CCGR2);
-       if (enable)
-               reg |= 1 << MXC_CCM_CCGR2_CG14_OFFSET;
-       else
-               reg &= ~(1 << MXC_CCM_CCGR2_CG14_OFFSET);
-       writel(reg, &mxc_ccm->CCGR2);
+       clrsetbits_le32(&mxc_ccm->CCGR2,
+                       MXC_CCM_CCGR2_USBOH3_60M(MXC_CCM_CCGR_CG_MASK),
+                       MXC_CCM_CCGR2_USBOH3_60M(cg));
  }
  
- void set_usb_phy1_clk(void)
++void ipu_clk_enable(void)
 +{
-       unsigned int reg;
++      /* IPU root clock derived from AXI B */
++      clrsetbits_le32(&mxc_ccm->cbcmr, MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK,
++                      MXC_CCM_CBCMR_IPU_HSP_CLK_SEL(1));
 +
-       reg = readl(&mxc_ccm->cscmr1);
-       reg &= ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
-       writel(reg, &mxc_ccm->cscmr1);
++      setbits_le32(&mxc_ccm->CCGR5,
++              MXC_CCM_CCGR5_IPU(MXC_CCM_CCGR_CG_MASK));
++
++      /* Handshake with IPU when certain clock rates are changed. */
++      clrbits_le32(&mxc_ccm->ccdr, MXC_CCM_CCDR_IPU_HS_MASK);
++
++      /* Handshake with IPU when LPM is entered as its enabled. */
++      clrbits_le32(&mxc_ccm->clpcr, MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS);
 +}
 +
- void enable_usb_phy1_clk(unsigned char enable)
++void ipu_clk_disable(void)
++{
++      clrbits_le32(&mxc_ccm->CCGR5,
++              MXC_CCM_CCGR5_IPU(MXC_CCM_CCGR_CG_MASK));
++
++      /* Handshake with IPU when certain clock rates are changed. */
++      setbits_le32(&mxc_ccm->ccdr, MXC_CCM_CCDR_IPU_HS_MASK);
++
++      /* Handshake with IPU when LPM is entered as its enabled. */
++      setbits_le32(&mxc_ccm->clpcr, MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS);
++}
++
+ #ifdef CONFIG_I2C_MXC
+ /* i2c_num can be from 0, to 1 for i.MX51 and 2 for i.MX53 */
+ int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
  {
-       unsigned int reg;
+       u32 mask;
  
-       reg = readl(&mxc_ccm->CCGR4);
+ #if defined(CONFIG_MX51)
+       if (i2c_num > 1)
+ #elif defined(CONFIG_MX53)
+       if (i2c_num > 2)
+ #endif
+               return -EINVAL;
+       mask = MXC_CCM_CCGR_CG_MASK <<
+                       (MXC_CCM_CCGR1_I2C1_OFFSET + (i2c_num << 1));
        if (enable)
-               reg |= 1 << MXC_CCM_CCGR4_CG5_OFFSET;
+               setbits_le32(&mxc_ccm->CCGR1, mask);
        else
-               reg &= ~(1 << MXC_CCM_CCGR4_CG5_OFFSET);
-       writel(reg, &mxc_ccm->CCGR4);
+               clrbits_le32(&mxc_ccm->CCGR1, mask);
+       return 0;
+ }
+ #endif
+ void set_usb_phy_clk(void)
+ {
+       clrbits_le32(&mxc_ccm->cscmr1, MXC_CCM_CSCMR1_USB_PHY_CLK_SEL);
  }
  
- void set_usb_phy2_clk(void)
+ #if defined(CONFIG_MX51)
+ void enable_usb_phy1_clk(unsigned char enable)
  {
-       unsigned int reg;
+       unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
  
-       reg = readl(&mxc_ccm->cscmr1);
-       reg &= ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
-       writel(reg, &mxc_ccm->cscmr1);
+       clrsetbits_le32(&mxc_ccm->CCGR2,
+                       MXC_CCM_CCGR2_USB_PHY(MXC_CCM_CCGR_CG_MASK),
+                       MXC_CCM_CCGR2_USB_PHY(cg));
+ }
+ void enable_usb_phy2_clk(unsigned char enable)
+ {
+       /* i.MX51 has a single USB PHY clock, so do nothing here. */
+ }
+ #elif defined(CONFIG_MX53)
+ void enable_usb_phy1_clk(unsigned char enable)
+ {
+       unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
+       clrsetbits_le32(&mxc_ccm->CCGR4,
+                       MXC_CCM_CCGR4_USB_PHY1(MXC_CCM_CCGR_CG_MASK),
+                       MXC_CCM_CCGR4_USB_PHY1(cg));
  }
  
  void enable_usb_phy2_clk(unsigned char enable)
@@@ -633,17 -695,22 +747,19 @@@ static int config_pll_clk(enum pll_cloc
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
 -              writel(ccsr & ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL,
 -                              &mxc_ccm->ccsr);
 +              __raw_writel(ccsr & ~0x1, &mxc_ccm->ccsr);
                break;
+ #ifdef CONFIG_MX53
        case PLL4_CLOCK:
                /* Switch to pll4 bypass clock */
 -              writel(ccsr | MXC_CCM_CCSR_PLL4_SW_CLK_SEL,
 -                              &mxc_ccm->ccsr);
 +              __raw_writel(ccsr | 0x20, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
 -              writel(ccsr & ~MXC_CCM_CCSR_PLL4_SW_CLK_SEL,
 -                              &mxc_ccm->ccsr);
 +              __raw_writel(ccsr & ~0x20, &mxc_ccm->ccsr);
                break;
+ #endif
        default:
                return -EINVAL;
        }
@@@ -209,16 -206,9 +206,15 @@@ setup_pll_func
        setup_pll PLL1_BASE_ADDR, 864
        setup_pll_errata PLL1_BASE_ADDR, W_DP_MFN_800_DIT
  #else
 +#if !defined(CONFIG_SYS_CPU_CLK) || CONFIG_SYS_CPU_CLK == 800
        setup_pll PLL1_BASE_ADDR, 800
 +#elif CONFIG_SYS_CPU_CLK == 600
 +      setup_pll PLL1_BASE_ADDR, 600
 +#else
 +#error Unsupported CONFIG_SYS_CPU_CLK value
 +#endif
  #endif
  
- #if defined(CONFIG_MX51)
        setup_pll PLL3_BASE_ADDR, 665
  
        /* Switch peripheral to PLL 3 */
        setup_pll PLL2_BASE_ADDR, 665
  
        /* Switch peripheral to PLL2 */
 -      ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x19239145
        str r1, [r0, #CLKCTL_CBCDR]
-       ldr r1, =0x000020C0
-       orr r1,r1,#CONFIG_SYS_DDR_CLKSEL
-       str r1, [r0, #CLKCTL_CBCMR]
- #elif defined(CONFIG_TX53)
-       setup_pll PLL3_BASE_ADDR, 400
-       /* Switch peripheral to PLL 3 */
-       ldr r1, [r0, #CLKCTL_CBCMR]
-       bic r1, #(0x3 << 12)
-       orr r1, r1, #(1 << 12)
+       ldr r1, =0x000020C0 | CONFIG_SYS_DDR_CLKSEL
        str r1, [r0, #CLKCTL_CBCMR]
  
-       ldr r1, [r0, #CLKCTL_CBCDR]
-       orr r1, r1, #(1 << 25)
-       str r1, [r0, #CLKCTL_CBCDR]
- 1:
-       /* make sure change is effective */
-       ldr     r1, [r0, #CLKCTL_CDHIPR]
-       tst     r1, #0x7f
-       bne     1b
- #if CONFIG_SYS_SDRAM_CLK == 400
-       setup_pll PLL2_BASE_ADDR, 400
- #elif CONFIG_SYS_SDRAM_CLK == 333
-       setup_pll PLL2_BASE_ADDR, 333
- #else
- #error Unsupported CONFIG_SYS_SDRAM_CLK
- #endif
-       /* Switch peripheral to PLL2 */
-       ldr r0, =CCM_BASE_ADDR
-       ldr r1, [r0, #CLKCTL_CBCDR]
-       bic r1, #(1 << 25)
-       str r1, [r0, #CLKCTL_CBCDR]
-       ldr r1, [r0, #CLKCTL_CBCMR]
-       bic r1, #(3 << 12)
-       orr r1, #(2 << 12)
-       str r1, [r0, #CLKCTL_CBCMR]
-       /* make sure change is effective */
- 1:
-       ldr     r1, [r0, #CLKCTL_CDHIPR]
-       cmp     r1, #0x0
-       bne     1b
- #endif
        setup_pll PLL3_BASE_ADDR, 216
  
        /* Set the platform clock dividers */
        str r1, [r0, #CLKCTL_CSCMR1]
        ldr r1, =0x00C30321
        str r1, [r0, #CLKCTL_CSCDR1]
- #elif defined(CONFIG_MX53)
+       /* make sure divider effective */
+ 1:    ldr r1, [r0, #CLKCTL_CDHIPR]
+       cmp r1, #0x0
+       bne 1b
+       str r4, [r0, #CLKCTL_CCDR]
+       /* for cko - for ARM div by 8 */
+       mov r1, #0x000A0000
+       add r1, r1, #0x00000F0
+       str r1, [r0, #CLKCTL_CCOSR]
+ #else /* CONFIG_MX53 */
+       ldr r0, =CCM_BASE_ADDR
+       /* Gate of clocks to the peripherals first */
+       ldr r1, =0x3FFFFFFF
+       str r1, [r0, #CLKCTL_CCGR0]
+       str r4, [r0, #CLKCTL_CCGR1]
+       str r4, [r0, #CLKCTL_CCGR2]
+       str r4, [r0, #CLKCTL_CCGR3]
+       str r4, [r0, #CLKCTL_CCGR7]
+       ldr r1, =0x00030000
+       str r1, [r0, #CLKCTL_CCGR4]
+       ldr r1, =0x00FFF030
+       str r1, [r0, #CLKCTL_CCGR5]
+       ldr r1, =0x0F00030F
+       str r1, [r0, #CLKCTL_CCGR6]
+       /* Switch ARM to step clock */
+       mov r1, #0x4
+       str r1, [r0, #CLKCTL_CCSR]
+       setup_pll PLL1_BASE_ADDR, 800
+         setup_pll PLL3_BASE_ADDR, 400
+         /* Switch peripheral to PLL3 */
+         ldr r0, =CCM_BASE_ADDR
+         ldr r1, =0x00015154
+         str r1, [r0, #CLKCTL_CBCMR]
+         ldr r1, =0x02888945
+         orr r1, r1, #(1 << 16)
+         str r1, [r0, #CLKCTL_CBCDR]
+         /* make sure change is effective */
+ 1:      ldr r1, [r0, #CLKCTL_CDHIPR]
+         cmp r1, #0x0
+         bne 1b
+         setup_pll PLL2_BASE_ADDR, 400
        /* Switch peripheral to PLL2 */
 -      ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x00808145
        orr r1, r1, #(2 << 10)
        orr r1, r1, #(0 << 16)
  
        ldr r1, =0x00016154
        str r1, [r0, #CLKCTL_CBCMR]
-       /* Change uart clk parent to pll2*/
+       /*change uart clk parent to pll2*/
        ldr r1, [r0, #CLKCTL_CSCMR1]
 -      and r1, r1, #0xfcffffff
 -      orr r1, r1, #0x01000000
 +      bic r1, #(0x3 << 24)
 +      orr r1, r1, #(0x1 << 24)
        str r1, [r0, #CLKCTL_CSCMR1]
+       /* make sure change is effective */
+ 1:      ldr r1, [r0, #CLKCTL_CDHIPR]
+       cmp r1, #0x0
+       bne 1b
+         setup_pll PLL3_BASE_ADDR, 216
+       setup_pll PLL4_BASE_ADDR, 455
+       /* Set the platform clock dividers */
+       ldr r0, =ARM_BASE_ADDR
+       ldr r1, =0x00000124
+       str r1, [r0, #0x14]
+       ldr r0, =CCM_BASE_ADDR
+       mov r1, #0
+       str r1, [r0, #CLKCTL_CACRR]
+       /* Switch ARM back to PLL 1. */
+       mov r1, #0x0
+       str r1, [r0, #CLKCTL_CCSR]
+       /* make uart div=6 */
        ldr r1, [r0, #CLKCTL_CSCDR1]
 -      and r1, r1, #0xffffffc0
 +      bic r1, #(0x3f << 0)
        orr r1, r1, #0x0a
        str r1, [r0, #CLKCTL_CSCDR1]
- #endif
 +      /* make sure divider effective */
 +1:    ldr r1, [r0, #CLKCTL_CDHIPR]
 +      cmp r1, #0x0
 +      bne 1b
- #endif
-       mov r1, #0x0
-       str r1, [r0, #CLKCTL_CCDR]
  
-       /* for cko - for ARM div by 8 */
-       mov r1, #0x000A0000
-       add r1, r1, #0x00000F0
-       str r1, [r0, #CLKCTL_CCOSR]
+       /* Restore the default values in the Gate registers */
+       ldr r1, =0xFFFFFFFF
+       str r1, [r0, #CLKCTL_CCGR0]
+       str r1, [r0, #CLKCTL_CCGR1]
+       str r1, [r0, #CLKCTL_CCGR2]
+       str r1, [r0, #CLKCTL_CCGR3]
+       str r1, [r0, #CLKCTL_CCGR4]
+       str r1, [r0, #CLKCTL_CCGR5]
+       str r1, [r0, #CLKCTL_CCGR6]
+       str r1, [r0, #CLKCTL_CCGR7]
+         mov r1, #0x00000
+         str r1, [r0, #CLKCTL_CCDR]
+         /* for cko - for ARM div by 8 */
+         mov r1, #0x000A0000
+         add r1, r1, #0x00000F0
+         str r1, [r0, #CLKCTL_CCOSR]
+ #endif        /* CONFIG_MX53 */
  .endm
  
  .macro setup_wdog
@@@ -398,25 -420,27 +428,30 @@@ ENTRY(lowlevel_init
  ENDPROC(lowlevel_init)
  
  /* Board level setting value */
- W_DP_OP_864:              .word DP_OP_864
- W_DP_MFD_864:             .word DP_MFD_864
- W_DP_MFN_864:             .word DP_MFN_864
- W_DP_MFN_800_DIT:         .word DP_MFN_800_DIT
- W_DP_OP_800:              .word DP_OP_800
- W_DP_MFD_800:             .word DP_MFD_800
- W_DP_MFN_800:             .word DP_MFN_800
- W_DP_OP_665:              .word DP_OP_665
- W_DP_MFD_665:             .word DP_MFD_665
- W_DP_MFN_665:             .word DP_MFN_665
- W_DP_OP_600:              .word DP_OP_600
- W_DP_MFD_600:             .word DP_MFD_600
- W_DP_MFN_600:             .word DP_MFN_600
- W_DP_OP_400:              .word DP_OP_400
- W_DP_MFD_400:             .word DP_MFD_400
- W_DP_MFN_400:             .word DP_MFN_400
- W_DP_OP_333:              .word DP_OP_333
- W_DP_MFD_333:             .word DP_MFD_333
- W_DP_MFN_333:             .word DP_MFN_333
- W_DP_OP_216:              .word DP_OP_216
- W_DP_MFD_216:             .word DP_MFD_216
- W_DP_MFN_216:             .word DP_MFN_216
+ #if defined(CONFIG_MX51_PLL_ERRATA)
+ W_DP_864:             .word DP_OP_864
+                       .word DP_MFD_864
+                       .word DP_MFN_864
+ W_DP_MFN_800_DIT:     .word DP_MFN_800_DIT
+ #else
+ W_DP_800:             .word DP_OP_800
+                       .word DP_MFD_800
+                       .word DP_MFN_800
+ #endif
+ #if defined(CONFIG_MX51)
+ W_DP_665:             .word DP_OP_665
+                       .word DP_MFD_665
+                       .word DP_MFN_665
++W_DP_600:             .word DP_OP_600
++                      .word DP_MFD_600
++                      .word DP_MFN_600
+ #endif
+ W_DP_216:             .word DP_OP_216
+                       .word DP_MFD_216
+                       .word DP_MFN_216
+ W_DP_400:               .word DP_OP_400
+                       .word DP_MFD_400
+                       .word DP_MFN_400
+ W_DP_455:               .word DP_OP_455
+                       .word DP_MFD_455
+                       .word DP_MFN_455
@@@ -88,8 -72,16 +89,16 @@@ u32 get_cpu_rev(void
        return system_rev;
  }
  
+ #ifndef CONFIG_SYS_DCACHE_OFF
+ void enable_caches(void)
+ {
+       /* Enable D-cache. I-cache is already enabled in start.S */
+       dcache_enable();
+ }
+ #endif
  #if defined(CONFIG_FEC_MXC)
 -void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 +static void __imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
  {
        int i;
        struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
@@@ -19,6 -19,6 +19,7 @@@
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
   * MA 02111-1307 USA
   */
++//#define DEBUG
  
  #include <common.h>
  #include <asm/io.h>
  #include <asm/arch/sys_proto.h>
  
  enum pll_clocks {
--      PLL_SYS,        /* System PLL */
--      PLL_BUS,        /* System Bus PLL*/
--      PLL_USBOTG,     /* OTG USB PLL */
--      PLL_ENET,       /* ENET PLL */
++      PLL_ARM,        /* PLL1: ARM PLL */
++      PLL_BUS,        /* PLL2: System Bus PLL*/
++      PLL_USBOTG,     /* PLL3: OTG USB PLL */
++      PLL_AUDIO,      /* PLL4: Audio PLL */
++      PLL_VIDEO,      /* PLL5: Video PLL */
++      PLL_ENET,       /* PLL6: ENET PLL */
++      PLL_USB2,       /* PLL7: USB2 PLL */
++      PLL_MLB,        /* PLL8: MLB PLL */
  };
  
--struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
++struct mxc_ccm_reg *const imx_ccm = (void *)CCM_BASE_ADDR;
++struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
++
++int clk_enable(struct clk *clk)
++{
++      int ret = 0;
++
++      if (!clk)
++              return 0;
++      if (clk->usecount == 0) {
++debug("%s: Enabling %s clock\n", __func__, clk->name);
++              ret = clk->enable(clk);
++              if (ret)
++                      return ret;
++              clk->usecount++;
++      }
++      assert(clk->usecount > 0);
++      return ret;
++}
++
++void clk_disable(struct clk *clk)
++{
++      if (!clk)
++              return;
++
++      assert(clk->usecount > 0);
++      if (!(--clk->usecount)) {
++              if (clk->disable) {
++debug("%s: Disabling %s clock\n", __func__, clk->name);
++                      clk->disable(clk);
++              }
++      }
++}
  
  void enable_usboh3_clk(unsigned char enable)
  {
@@@ -55,30 -77,30 +114,64 @@@ static u32 decode_pll(enum pll_clocks p
        u32 div;
  
        switch (pll) {
--      case PLL_SYS:
--              div = __raw_readl(&imx_ccm->analog_pll_sys);
--              div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
--
--              return infreq * (div >> 1);
++      case PLL_ARM:
++              div = __raw_readl(&anatop->pll_arm);
++              if (div & BM_ANADIG_PLL_ARM_BYPASS)
++                      /* Assume the bypass clock is always derived from OSC */
++                      return infreq;
++              div &= BM_ANADIG_PLL_ARM_DIV_SELECT;
++
++              return infreq * div / 2;
        case PLL_BUS:
--              div = __raw_readl(&imx_ccm->analog_pll_528);
--              div &= BM_ANADIG_PLL_528_DIV_SELECT;
++              div = __raw_readl(&anatop->pll_528);
++              if (div & BM_ANADIG_PLL_SYS_BYPASS)
++                      return infreq;
++              div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
  
--              return infreq * (20 + (div << 1));
++              return infreq * (20 + div * 2);
        case PLL_USBOTG:
--              div = __raw_readl(&imx_ccm->analog_usb1_pll_480_ctrl);
++              div = __raw_readl(&anatop->usb1_pll_480_ctrl);
++              if (div & BM_ANADIG_USB1_PLL_480_CTRL_BYPASS)
++                      return infreq;
                div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
  
--              return infreq * (20 + (div << 1));
++              return infreq * (20 + div * 2);
++      case PLL_AUDIO:
++              div = __raw_readl(&anatop->pll_audio);
++              if (div & BM_ANADIG_PLL_AUDIO_BYPASS)
++                      return infreq;
++              div &= BM_ANADIG_PLL_AUDIO_DIV_SELECT;
++
++              return infreq * div;
++      case PLL_VIDEO:
++              div = __raw_readl(&anatop->pll_video);
++              if (div & BM_ANADIG_PLL_VIDEO_BYPASS)
++                      return infreq;
++              div &= BM_ANADIG_PLL_VIDEO_DIV_SELECT;
++
++              return infreq * div;
        case PLL_ENET:
--              div = __raw_readl(&imx_ccm->analog_pll_enet);
++              div = __raw_readl(&anatop->pll_enet);
++              if (div & BM_ANADIG_PLL_ENET_BYPASS)
++                      return infreq;
                div &= BM_ANADIG_PLL_ENET_DIV_SELECT;
  
--              return (div == 3 ? 125000000 : 25000000 * (div << 1));
--      default:
++              return (div == 3 ? 125000000 : 25000000 * div * 2);
++      case PLL_USB2:
++              div = __raw_readl(&anatop->usb2_pll_480_ctrl);
++              if (div & BM_ANADIG_USB2_PLL_480_CTRL_BYPASS)
++                      return infreq;
++              div &= BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT;
++
++              return infreq * (20 + div * 2);
++      case PLL_MLB:
++              div = __raw_readl(&anatop->pll_mlb);
++              if (div & BM_ANADIG_PLL_MLB_BYPASS)
++                      return infreq;
++              /* unknown external clock provided on MLB_CLK pin */
                return 0;
        }
--      /* NOTREACHED */
++      return 0;
  }
  
  static u32 get_mcu_main_clk(void)
        reg = __raw_readl(&imx_ccm->cacrr);
        reg &= MXC_CCM_CACRR_ARM_PODF_MASK;
        reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET;
-       freq = decode_pll(PLL_SYS, CONFIG_SYS_MX6_HCLK);
 -      freq = decode_pll(PLL_SYS, MXC_HCLK);
++      freq = decode_pll(PLL_ARM, MXC_HCLK);
  
        return freq / (reg + 1);
  }
@@@ -109,10 -131,10 +202,8 @@@ u32 get_periph_clk(void
                        break;
                case 1:
                case 2:
-                       freq = CONFIG_SYS_MX6_HCLK;
-                       break;
-               default:
+                       freq = MXC_HCLK;
                        break;
 -              default:
 -                      break;
                }
        } else {
                reg = __raw_readl(&imx_ccm->cbcmr);
                case 3:
                        freq = PLL2_PFD2_DIV_FREQ;
                        break;
--              default:
--                      break;
                }
        }
  
@@@ -230,6 -252,6 +319,33 @@@ static u32 get_emi_slow_clk(void
        return root_freq / (emi_slow_pof + 1);
  }
  
++static u32 get_nfc_clk(void)
++{
++      u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
++      u32 podf = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
++      u32 pred = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
++      int nfc_clk_sel = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK) >>
++              MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
++      u32 root_freq;
++
++      switch (nfc_clk_sel) {
++      case 0:
++              root_freq = PLL2_PFD0_FREQ;
++              break;
++      case 1:
++              root_freq = decode_pll(PLL_BUS, MXC_HCLK);
++              break;
++      case 2:
++              root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
++              break;
++      case 3:
++              root_freq = PLL2_PFD2_FREQ;
++              break;
++      }
++
++      return root_freq / (pred + 1) / (podf + 1);
++}
++
  static u32 get_mmdc_ch0_clk(void)
  {
        u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
@@@ -294,10 -316,10 +410,8 @@@ u32 imx_get_fecclk(void
  
  int enable_sata_clock(void)
  {
--      u32 reg = 0;
++      u32 reg;
        s32 timeout = 100000;
--      struct mxc_ccm_reg *const imx_ccm
--              = (struct mxc_ccm_reg *) CCM_BASE_ADDR;
  
        /* Enable sata clock */
        reg = readl(&imx_ccm->CCGR5); /* CCGR5 */
        writel(reg, &imx_ccm->CCGR5);
  
        /* Enable PLLs */
--      reg = readl(&imx_ccm->analog_pll_enet);
--      reg &= ~BM_ANADIG_PLL_SYS_POWERDOWN;
--      writel(reg, &imx_ccm->analog_pll_enet);
--      reg |= BM_ANADIG_PLL_SYS_ENABLE;
++      reg = readl(&anatop->pll_enet);
++      reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
++      writel(reg, &anatop->pll_enet);
++      reg |= BM_ANADIG_PLL_ENET_ENABLE;
        while (timeout--) {
--              if (readl(&imx_ccm->analog_pll_enet) & BM_ANADIG_PLL_SYS_LOCK)
++              if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
                        break;
        }
        if (timeout <= 0)
                return -EIO;
--      reg &= ~BM_ANADIG_PLL_SYS_BYPASS;
--      writel(reg, &imx_ccm->analog_pll_enet);
++      reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
++      writel(reg, &anatop->pll_enet);
        reg |= BM_ANADIG_PLL_ENET_ENABLE_SATA;
--      writel(reg, &imx_ccm->analog_pll_enet);
++      writel(reg, &anatop->pll_enet);
  
        return 0 ;
  }
  
++void ipu_clk_enable(void)
++{
++      u32 reg = readl(&imx_ccm->CCGR3);
++      reg |= MXC_CCM_CCGR3_CG0_MASK;
++      writel(reg, &imx_ccm->CCGR3);
++}
++
++void ipu_clk_disable(void)
++{
++      u32 reg = readl(&imx_ccm->CCGR3);
++      reg &= ~MXC_CCM_CCGR3_CG0_MASK;
++      writel(reg, &imx_ccm->CCGR3);
++}
++
++void ocotp_clk_enable(void)
++{
++      u32 reg = readl(&imx_ccm->CCGR2);
++      reg |= MXC_CCM_CCGR2_CG6_MASK;
++      writel(reg, &imx_ccm->CCGR2);
++}
++
++void ocotp_clk_disable(void)
++{
++      u32 reg = readl(&imx_ccm->CCGR2);
++      reg &= ~MXC_CCM_CCGR2_CG6_MASK;
++      writel(reg, &imx_ccm->CCGR2);
++}
++
  unsigned int mxc_get_clock(enum mxc_clock clk)
  {
        switch (clk) {
                return get_usdhc_clk(3);
        case MXC_SATA_CLK:
                return get_ahb_clk();
--      default:
--              break;
++      case MXC_NFC_CLK:
++              return get_nfc_clk();
        }
  
        return -1;
  }
  
++static inline int gcd(int m, int n)
++{
++      int t;
++      while (m > 0) {
++              if (n > m) {
++                      t = m;
++                      m = n;
++                      n = t;
++              } /* swap */
++              m -= n;
++      }
++      return n;
++}
++
++/* Config CPU clock */
++static int config_core_clk(u32 ref, u32 freq)
++{
++      int d;
++      int div = 0;
++      int mul = 0;
++      int min_err = ~0 >> 1;
++      u32 reg;
++
++      if (freq / ref > 108 || freq / ref * 8 < 54) {
++              return -EINVAL;
++      }
++
++      for (d = 1; d < 8; d++) {
++              int m = (freq + (ref - 1)) / ref;
++              unsigned long f;
++              int err;
++
++              if (m > 108 || m < 54)
++                      return -EINVAL;
++
++              f = ref * m / d;
++              while (f > freq) {
++                      if (--m < 54)
++                              return -EINVAL;
++                      f = ref * m / d;
++              }
++              err = freq - f;
++              if (err == 0)
++                      break;
++              if (err < 0)
++                      return -EINVAL;
++              if (err < min_err) {
++                      mul = m;
++                      div = d;
++              }
++      }
++      printf("Setting M=%3u D=%2u for %u.%03uMHz (actual: %u.%03uMHz)\n",
++              mul, div, freq / 1000000, freq / 1000 % 1000,
++              ref * mul / div / 1000000, ref * mul / div / 1000 % 1000);
++
++      reg = readl(&anatop->pll_arm);
++      printf("anadig_pll_arm=%08x -> %08x\n",
++              reg, (reg & ~0x7f) | mul);
++#if 0
++      writel(div - 1, &imx_ccm->caccr);
++      reg &= 0x7f;
++      writel(reg | mul, &anatop->pll_arm);
++#endif
++      return 0;
++}
++
  /*
-- * Dump some core clockes.
++ * This function assumes the expected core clock has to be changed by
++ * modifying the PLL. This is NOT true always but for most of the times,
++ * it is. So it assumes the PLL output freq is the same as the expected
++ * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN.
++ * In the latter case, it will try to increase the presc value until
++ * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to
++ * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based
++ * on the targeted PLL and reference input clock to the PLL. Lastly,
++ * it sets the register based on these values along with the dividers.
++ * Note 1) There is no value checking for the passed-in divider values
++ *         so the caller has to make sure those values are sensible.
++ *      2) Also adjust the NFC divider such that the NFC clock doesn't
++ *         exceed NFC_CLK_MAX.
++ *      3) IPU HSP clock is independent of AHB clock. Even it can go up to
++ *         177MHz for higher voltage, this function fixes the max to 133MHz.
++ *      4) This function should not have allowed diag_printf() calls since
++ *         the serial driver has been stoped. But leave then here to allow
++ *         easy debugging by NOT calling the cyg_hal_plf_serial_stop().
   */
++int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk)
++{
++      freq *= 1000000;
++
++      switch (clk) {
++      case MXC_ARM_CLK:
++              if (config_core_clk(ref, freq))
++                      return -EINVAL;
++              break;
++#if 0
++      case MXC_PER_CLK:
++              if (config_periph_clk(ref, freq))
++                      return -EINVAL;
++              break;
++      case MXC_DDR_CLK:
++              if (config_ddr_clk(freq))
++                      return -EINVAL;
++              break;
++      case MXC_NFC_CLK:
++              if (config_nfc_clk(freq))
++                      return -EINVAL;
++              break;
++#endif
++      default:
++              printf("Warning: Unsupported or invalid clock type: %d\n",
++                      clk);
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++/*
++ * Dump some core clocks.
++ */
++#define print_pll(pll)        printf("%-12s %4d.%03d MHz\n", #pll,            \
++                              decode_pll(pll, MXC_HCLK) / 1000000,    \
++                              decode_pll(pll, MXC_HCLK) / 1000 % 1000)
++
++#define MXC_IPG_PER_CLK       MXC_IPG_PERCLK
++#define print_clk(clk)        printf("%-12s %4d.%03d MHz\n", #clk,            \
++                              mxc_get_clock(MXC_##clk##_CLK) / 1000000, \
++                              mxc_get_clock(MXC_##clk##_CLK) / 1000 % 1000)
++
  int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  {
--      u32 freq;
-       freq = decode_pll(PLL_SYS, CONFIG_SYS_MX6_HCLK);
 -      freq = decode_pll(PLL_SYS, MXC_HCLK);
--      printf("PLL_SYS    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_BUS, CONFIG_SYS_MX6_HCLK);
 -      freq = decode_pll(PLL_BUS, MXC_HCLK);
--      printf("PLL_BUS    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_USBOTG, CONFIG_SYS_MX6_HCLK);
 -      freq = decode_pll(PLL_USBOTG, MXC_HCLK);
--      printf("PLL_OTG    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_ENET, CONFIG_SYS_MX6_HCLK);
 -      freq = decode_pll(PLL_ENET, MXC_HCLK);
--      printf("PLL_NET    %8d MHz\n", freq / 1000000);
++      print_pll(PLL_ARM);
++      print_pll(PLL_BUS);
++      print_pll(PLL_USBOTG);
++      print_pll(PLL_AUDIO);
++      print_pll(PLL_VIDEO);
++      print_pll(PLL_ENET);
++      print_pll(PLL_USB2);
  
        printf("\n");
--      printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
--      printf("UART       %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000);
 -#ifdef CONFIG_MXC_SPI
--      printf("CSPI       %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
 -#endif
--      printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
--      printf("AXI        %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000);
--      printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
--      printf("USDHC1     %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000);
--      printf("USDHC2     %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000);
--      printf("USDHC3     %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000);
--      printf("USDHC4     %8d kHz\n", mxc_get_clock(MXC_ESDHC4_CLK) / 1000);
--      printf("EMI SLOW   %8d kHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK) / 1000);
--      printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
++      print_clk(IPG);
++      print_clk(UART);
++      print_clk(CSPI);
++      print_clk(AHB);
++      print_clk(AXI);
++      print_clk(DDR);
++      print_clk(ESDHC);
++      print_clk(ESDHC2);
++      print_clk(ESDHC3);
++      print_clk(ESDHC4);
++      print_clk(EMI_SLOW);
++      print_clk(NFC);
++      print_clk(IPG_PER);
++      print_clk(ARM);
  
        return 0;
  }
  #include <asm/errno.h>
  #include <asm/io.h>
  #include <asm/arch/imx-regs.h>
++#include <asm/arch/crm_regs.h>
++#include <asm/arch/regs-ocotp.h>
  #include <asm/arch/clock.h>
++#include <asm/arch/dma.h>
  #include <asm/arch/sys_proto.h>
+ #include <asm/imx-common/boot_mode.h>
++#ifdef CONFIG_VIDEO_IPUV3
++#include <ipu.h>
++#endif
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#define TEMPERATURE_MIN                       -40
++#define TEMPERATURE_HOT                       80
++#define TEMPERATURE_MAX                       125
++#define REG_VALUE_TO_CEL(ratio, raw) ((raw_n40c - raw) * 100 / ratio - 40)
++
++#define __data        __attribute__((section(".data")))
+ struct scu_regs {
+       u32     ctrl;
+       u32     config;
+       u32     status;
+       u32     invalidate;
+       u32     fpga_rev;
+ };
++#ifdef CONFIG_HW_WATCHDOG
++#define wdog_base     ((void *)WDOG1_BASE_ADDR)
++#define WDOG_WCR      0x00
++#define WCR_WDE               (1 << 2)
++#define WDOG_WSR      0x02
++
++void hw_watchdog_reset(void)
++{
++      if (readw(wdog_base + WDOG_WCR) & WCR_WDE) {
++              static u16 toggle = 0xaaaa;
++              static int first = 1;
++
++              if (first) {
++                      printf("Watchdog active\n");
++                      first = 0;
++              }
++              writew(toggle, wdog_base + WDOG_WSR);
++              toggle ^= 0xffff;
++      }
++}
++#endif
 +
  u32 get_cpu_rev(void)
  {
        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
@@@ -85,7 -101,7 +138,7 @@@ void init_aips(void
   * Possible values are from 0.725V to 1.450V in steps of
   * 0.025V (25mV).
   */
--void set_vddsoc(u32 mv)
++static void set_vddsoc(u32 mv)
  {
        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
        u32 val, reg = readl(&anatop->reg_core);
        writel(reg, &anatop->reg_core);
  }
  
++static u32 __data thermal_calib;
++
++int read_cpu_temperature(void)
++{
++      unsigned int reg, tmp, i;
++      unsigned int raw_25c, raw_hot, hot_temp, raw_n40c, ratio;
++      int temperature;
++      struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
++      struct mx6_ocotp_regs *const ocotp_regs = (void *)OCOTP_BASE_ADDR;
++
++      if (!thermal_calib) {
++              ocotp_clk_enable();
++              writel(1, &ocotp_regs->hw_ocotp_read_ctrl);
++              thermal_calib = readl(&ocotp_regs->hw_ocotp_ana1);
++              writel(0, &ocotp_regs->hw_ocotp_read_ctrl);
++              ocotp_clk_disable();
++      }
++
++      if (thermal_calib == 0 || thermal_calib == 0xffffffff)
++              return TEMPERATURE_MIN;
++
++      /* Fuse data layout:
++       * [31:20] sensor value @ 25C
++       * [19:8] sensor value of hot
++       * [7:0] hot temperature value */
++      raw_25c = thermal_calib >> 20;
++      raw_hot = (thermal_calib & 0xfff00) >> 8;
++      hot_temp = thermal_calib & 0xff;
++
++      ratio = ((raw_25c - raw_hot) * 100) / (hot_temp - 25);
++      raw_n40c = raw_25c + (13 * ratio) / 20;
++
++      /* now we only using single measure, every time we measure
++      the temperature, we will power on/down the anadig module*/
++      writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_clr);
++      writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set);
++
++      /* write measure freq */
++      reg = readl(&anatop->tempsense1);
++      reg &= ~BM_ANADIG_TEMPSENSE1_MEASURE_FREQ;
++      reg |= 327;
++      writel(reg, &anatop->tempsense1);
++
++      writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_clr);
++      writel(BM_ANADIG_TEMPSENSE0_FINISHED, &anatop->tempsense0_clr);
++      writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_set);
++
++      tmp = 0;
++      /* read five times of temperature values to get average*/
++      for (i = 0; i < 5; i++) {
++              while ((readl(&anatop->tempsense0) &
++                              BM_ANADIG_TEMPSENSE0_FINISHED) == 0)
++                      udelay(10000);
++              reg = readl(&anatop->tempsense0);
++              tmp += (reg & BM_ANADIG_TEMPSENSE0_TEMP_VALUE) >>
++                      BP_ANADIG_TEMPSENSE0_TEMP_VALUE;
++              writel(BM_ANADIG_TEMPSENSE0_FINISHED,
++                      &anatop->tempsense0_clr);
++      }
++
++      tmp = tmp / 5;
++      if (tmp <= raw_n40c)
++              temperature = REG_VALUE_TO_CEL(ratio, tmp);
++      else
++              temperature = TEMPERATURE_MIN;
++
++      /* power down anatop thermal sensor */
++      writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_set);
++      writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_clr);
++
++      return temperature;
++}
++
++int check_cpu_temperature(int boot)
++{
++      static int __data max_temp;
++      int boot_limit = TEMPERATURE_HOT;
++      int tmp = read_cpu_temperature();
++
++debug("max_temp[%p]=%d diff=%d\n", &max_temp, max_temp, tmp - max_temp);
++
++      if (tmp < TEMPERATURE_MIN || tmp > TEMPERATURE_MAX) {
++              printf("Temperature:   can't get valid data!\n");
++              return tmp;
++      }
++
++      while (tmp >= boot_limit) {
++              if (boot) {
++                      printf("CPU is %d C, too hot to boot, waiting...\n",
++                              tmp);
++                      udelay(5000000);
++                      tmp = read_cpu_temperature();
++                      boot_limit = TEMPERATURE_HOT - 1;
++              } else {
++                      printf("CPU is %d C, too hot, resetting...\n",
++                              tmp);
++                      udelay(1000000);
++                      reset_cpu(0);
++              }
++      }
++
++      if (boot) {
++              printf("Temperature:   %d C, calibration data 0x%x\n",
++                      tmp, thermal_calib);
++      } else if (tmp > max_temp) {
++              if (tmp > TEMPERATURE_HOT - 5)
++                      printf("WARNING: CPU temperature %d C\n", tmp);
++              max_temp = tmp;
++      }
++      return tmp;
++}
++
  int arch_cpu_init(void)
  {
        init_aips();
  
        set_vddsoc(1200);       /* Set VDDSOC to 1.2V */
  
++#ifdef CONFIG_VIDEO_IPUV3
++      gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3H;
++#endif
++#ifdef  CONFIG_APBH_DMA
++      /* Timer is required for Initializing APBH DMA */
++      timer_init();
++      mxs_dma_init();
++#endif
        return 0;
  }
- #endif
  
  #ifndef CONFIG_SYS_DCACHE_OFF
  void enable_caches(void)
@@@ -133,13 -148,48 +305,144 @@@ void imx_get_mac_from_fuse(int dev_id, 
  
        u32 value = readl(&fuse->mac_addr_high);
        mac[0] = (value >> 8);
--      mac[1] = value ;
++      mac[1] = value;
  
        value = readl(&fuse->mac_addr_low);
--      mac[2] = value >> 24 ;
--      mac[3] = value >> 16 ;
--      mac[4] = value >> 8 ;
--      mac[5] = value ;
--
++      mac[2] = value >> 24;
++      mac[3] = value >> 16;
++      mac[4] = value >> 8;
++      mac[5] = value;
  }
  #endif
+ void boot_mode_apply(unsigned cfg_val)
+ {
+       unsigned reg;
+       struct src *psrc = (struct src *)SRC_BASE_ADDR;
+       writel(cfg_val, &psrc->gpr9);
+       reg = readl(&psrc->gpr10);
+       if (cfg_val)
+               reg |= 1 << 28;
+       else
+               reg &= ~(1 << 28);
+       writel(reg, &psrc->gpr10);
+ }
+ /*
+  * cfg_val will be used for
+  * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0]
+  * After reset, if GPR10[28] is 1, ROM will copy GPR9[25:0]
+  * to SBMR1, which will determine the boot device.
+  */
+ const struct boot_mode soc_boot_modes[] = {
+       {"normal",      MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)},
+       /* reserved value should start rom usb */
+       {"usb",         MAKE_CFGVAL(0x01, 0x00, 0x00, 0x00)},
+       {"sata",        MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
+       {"escpi1:0",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
+       {"escpi1:1",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
+       {"escpi1:2",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
+       {"escpi1:3",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
+       /* 4 bit bus width */
+       {"esdhc1",      MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
+       {"esdhc2",      MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
+       {"esdhc3",      MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
+       {"esdhc4",      MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
+       {NULL,          0},
+ };
++#define RESET_MAX_TIMEOUT             1000000
++#define MXS_BLOCK_SFTRST              (1 << 31)
++#define MXS_BLOCK_CLKGATE             (1 << 30)
++#include <div64.h>
++
++static const int scale = 1;
++
++int mxs_wait_mask_set(struct mx6_register_32 *mx6_reg, uint32_t mask, unsigned long timeout)
++{
++      unsigned long loops = 0;
++
++      timeout /= scale;
++      if (timeout == 0)
++              timeout++;
++
++      /* Wait for at least one microsecond for the bit mask to be set */
++      while ((readl(&mx6_reg->reg) & mask) != mask) {
++              if ((loops += scale) >= timeout) {
++                      printf("MASK %08x in %p not set after %lu ticks\n",
++                              mask, &mx6_reg->reg, loops * scale);
++                      return 1;
++              }
++              udelay(scale);
++      }
++      if (loops == 0)
++              udelay(1);
++
++      return 0;
++}
++
++int mxs_wait_mask_clr(struct mx6_register_32 *mx6_reg, uint32_t mask, unsigned long timeout)
++{
++      unsigned long loops = 0;
++
++      timeout /= scale;
++      if (timeout == 0)
++              timeout++;
++
++      /* Wait for at least one microsecond for the bit mask to be cleared */
++      while ((readl(&mx6_reg->reg) & mask) != 0) {
++              if ((loops += scale) >= timeout) {
++                      printf("MASK %08x in %p not cleared after %lu ticks\n",
++                              mask, &mx6_reg->reg, loops * scale);
++                      return 1;
++              }
++              udelay(scale);
++      }
++      if (loops == 0)
++              udelay(1);
++
++      return 0;
++}
++
++int mxs_reset_block(struct mx6_register_32 *mx6_reg)
++{
++      /* Clear SFTRST */
++      writel(MXS_BLOCK_SFTRST, &mx6_reg->reg_clr);
++
++      if (mxs_wait_mask_clr(mx6_reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) {
++              printf("TIMEOUT waiting for SFTRST[%p] to clear: %08x\n",
++                      &mx6_reg->reg, readl(&mx6_reg->reg));
++              return 1;
++      }
++
++      /* Clear CLKGATE */
++      writel(MXS_BLOCK_CLKGATE, &mx6_reg->reg_clr);
++
++      /* Set SFTRST */
++      writel(MXS_BLOCK_SFTRST, &mx6_reg->reg_set);
++
++      /* Wait for CLKGATE being set */
++      if (mxs_wait_mask_set(mx6_reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) {
++              printf("TIMEOUT waiting for CLKGATE[%p] to set: %08x\n",
++                      &mx6_reg->reg, readl(&mx6_reg->reg));
++              return 0;
++      }
++
++      /* Clear SFTRST */
++      writel(MXS_BLOCK_SFTRST, &mx6_reg->reg_clr);
++
++      if (mxs_wait_mask_clr(mx6_reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) {
++              printf("TIMEOUT waiting for SFTRST[%p] to clear: %08x\n",
++                      &mx6_reg->reg, readl(&mx6_reg->reg));
++              return 1;
++      }
++
++      /* Clear CLKGATE */
++      writel(MXS_BLOCK_CLKGATE, &mx6_reg->reg_clr);
++
++      if (mxs_wait_mask_clr(mx6_reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) {
++              printf("TIMEOUT waiting for CLKGATE[%p] to clear: %08x\n",
++                      &mx6_reg->reg, readl(&mx6_reg->reg));
++              return 1;
++      }
++
++      return 0;
++}
@@@ -35,14 -38,14 +38,14 @@@ struct omap_boot_parameters boot_param
   * We would not typically need to save these parameters in regular
   * U-Boot. This is needed only in SPL at the moment.
   */
 -u32 omap_bootmode = MMCSD_MODE_FAT;
 +u32 omap_bootmode __attribute__ ((section(".data"))) = MMCSD_MODE_UNDEFINED;
  
- u32 omap_boot_device(void)
+ u32 spl_boot_device(void)
  {
 -      return (u32) (boot_params.omap_bootdevice);
 +      return boot_params.omap_bootdevice;
  }
  
- u32 omap_boot_mode(void)
+ u32 spl_boot_mode(void)
  {
        return omap_bootmode;
  }
@@@ -52,17 -53,18 +53,17 @@@ ENTRY(save_boot_params
        ldr     r1, =boot_params
        str     r0, [r1]
  #ifdef CONFIG_SPL_BUILD
-       /* Store the boot device in omap_boot_device */
+       /* Store the boot device in spl_boot_device */
 -      ldrb    r2, [r0, #BOOT_DEVICE_OFFSET]   @ r1 <- value of boot device
 +      ldrb    r2, [r0, #BOOT_DEVICE_OFFSET]   @ r2 <- value of boot device
        and     r2, #BOOT_DEVICE_MASK
-       strb    r2, [r1, #BOOT_DEVICE_OFFSET]   @ omap_boot_device <- r2
 -      ldr     r3, =boot_params
 -      strb    r2, [r3, #BOOT_DEVICE_OFFSET]   @ spl_boot_device <- r1
++      strb    r2, [r1, #BOOT_DEVICE_OFFSET]   @ spl_boot_device <- r2
  
-       /* boot mode is passed only for devices that can do raw/fat mode */
-       cmp     r2, #2
+       /* boot mode is passed only for devices that can raw/fat mode */
+       cmp     r2, #BOOT_DEVICE_XIP
        blt     2f
-       cmp     r2, #7
+       cmp     r2, #BOOT_DEVICE_MMC2
        bgt     2f
-       /* Store the boot mode (raw/FAT) in omap_boot_mode */
+       /* Store the boot mode (raw/FAT) in omap_bootmode */
        ldr     r2, [r0, #DEV_DESC_PTR_OFFSET]  @ get the device descriptor ptr
        ldr     r2, [r2, #DEV_DATA_PTR_OFFSET]  @ get the pDeviceData ptr
        ldr     r2, [r2, #BOOT_MODE_OFFSET]     @ get the boot mode
@@@ -98,6 -83,6 +81,7 @@@ ENTRY(set_pl310_ctrl_reg
        PUSH    {r4-r11, lr}    @ save registers - ROM code may pollute
                                @ our registers
        LDR     r12, =0x102     @ Set PL310 control register - value in R0
++      smc     #0
        .word   0xe1600070      @ SMC #0 - hand assembled because -march=armv5
                                @ call ROM Code API to set control register
        POP     {r4-r11, pc}
@@@ -98,13 -52,14 +98,13 @@@ 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);
 -
 -      /* reset time, capture current incrementer value time */
 -      gd->arch.lastinc = readl(&timer_base->tcrr) /
 -                                      (TIMER_CLOCK / CONFIG_SYS_HZ);
 -      gd->arch.tbl = 0;       /* start "advancing" time stamp from 0 */
 -
 +      writel(TCLR_VAL, &timer_base->tclr);
 +#endif
 +#ifndef CONFIG_SPL_BUILD
-       gd->lastinc = -30 * TIMER_CLOCK;
-       gd->tbl = TIMER_START;
-       gd->timer_rate_hz = TIMER_CLOCK;
++      gd->arch.lastinc = -30 * TIMER_CLOCK;
++      gd->arch.tbl = TIMER_START;
++      gd->arch.timer_rate_hz = TIMER_CLOCK;
 +#endif
        return 0;
  }
  
@@@ -144,12 -109,7 +144,12 @@@ ulong get_timer_masked(void
   */
  unsigned long long get_ticks(void)
  {
 -      return get_timer(0);
 +      ulong now = readl(&timer_base->tcrr);
-       ulong inc = now - gd->lastinc;
++      ulong inc = now - gd->arch.lastinc;
 +
-       gd->tbl += inc;
-       gd->lastinc = now;
-       return gd->tbl;
++      gd->arch.tbl += inc;
++      gd->arch.lastinc = now;
++      return gd->arch.tbl;
  }
  
  /*
   */
  ulong get_tbclk(void)
  {
-       return gd->timer_rate_hz;
 -      return CONFIG_SYS_HZ;
++      return gd->arch.timer_rate_hz;
  }
@@@ -81,11 -81,7 +81,7 @@@ _end_vect
  
  .globl _TEXT_BASE
  _TEXT_BASE:
- #ifndef CONFIG_SPL_BUILD
--      .word   CONFIG_SYS_TEXT_BASE
- #else
-       .word   CONFIG_SPL_TEXT_BASE
- #endif
++      .word   _start
  
  /*
   * These are defined in the board-specific linker script.
@@@ -182,13 -172,10 +172,9 @@@ ENTRY(relocate_code
        mov     r5, r1  /* save addr of gd */
        mov     r6, r2  /* save addr of destination */
  
-       /* Set up the stack                                                 */
- stack_setup:
-       mov     sp, r4
        adr     r0, _start
 -      cmp     r0, r6
 -      moveq   r9, #0          /* no relocation. relocation offset(r9) = 0 */
 +      subs    r9, r6, r0
-       beq     clear_bss               /* skip relocation */
+       beq     relocate_done           /* skip relocation */
        mov     r1, r6                  /* r1 <- scratch for copy_loop */
        ldr     r3, _image_copy_end_ofs
        add     r2, r0, r3              /* r2 <- source end address         */
@@@ -211,8 -197,8 +196,11 @@@ copy_loop
        add     r2, r2, r0              /* r2 <- rel dyn start in FLASH */
        ldr     r3, _rel_dyn_end_ofs    /* r3 <- rel dyn end ofs */
        add     r3, r3, r0              /* r3 <- rel dyn end in FLASH */
++      mov     r4, r0
  fixloop:
        ldr     r0, [r2]                /* r0 <- location to fix up, IN FLASH! */
++      cmp     r0, r4
++      blo     skipfix
        add     r0, r0, r9              /* r0 <- location to fix up in RAM */
        ldr     r1, [r2, #4]
        and     r7, r1, #0xff
@@@ -235,6 -221,6 +223,7 @@@ fixrel
        add     r1, r1, r9
  fixnext:
        str     r1, [r0]
++skipfix:
        add     r2, r2, #8              /* each rel.dyn entry is 8 bytes */
        cmp     r2, r3
        blo     fixloop
index 0000000,0000000..e6d834f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,428 @@@
++
++/*
++ * Copyright 2013 Freescale Semiconductor, Inc.
++ *
++ * 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.
++ *
++ */
++
++/include/ "imx6qdl.dtsi"
++
++/ {
++      cpus {
++              #address-cells = <1>;
++              #size-cells = <1>;
++
++              cpu@0 {
++                      compatible = "arm,cortex-a9";
++                      reg = <0>;
++                      next-level-cache = <&L2>;
++                      operating-points = <
++                              /* kHz    uV */
++                              1200000 1275000
++                              996000  1250000
++                              792000  1150000
++                              396000  950000
++                      >;
++                      clock-latency = <61036>; /* two CLK32 periods */
++                      clocks = <&clks 104>, <&clks 6>, <&clks 16>,
++                               <&clks 17>, <&clks 170>;
++                      clock-names = "arm", "pll2_pfd2_396m", "step",
++                                    "pll1_sw", "pll1_sys";
++                      arm-supply = <&reg_arm>;
++                      pu-supply = <&reg_pu>;
++                      soc-supply = <&reg_soc>;
++              };
++
++              cpu@1 {
++                      compatible = "arm,cortex-a9";
++                      reg = <1>;
++                      next-level-cache = <&L2>;
++              };
++
++              cpu@2 {
++                      compatible = "arm,cortex-a9";
++                      reg = <2>;
++                      next-level-cache = <&L2>;
++              };
++
++              cpu@3 {
++                      compatible = "arm,cortex-a9";
++                      reg = <3>;
++                      next-level-cache = <&L2>;
++              };
++      };
++
++      soc {
++              aips-bus@02000000 { /* AIPS1 */
++                      spba-bus@02000000 {
++                              ecspi5: ecspi@02018000 {
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++                                      compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
++                                      reg = <0x02018000 0x4000>;
++                                      interrupts = <0 35 0x04>;
++                                      clocks = <&clks 116>, <&clks 116>;
++                                      clock-names = "ipg", "per";
++                                      status = "disabled";
++                              };
++                      };
++
++                      iomuxc: iomuxc@020e0000 {
++                              compatible = "fsl,imx6q-iomuxc";
++                              reg = <0x020e0000 0x4000>;
++
++                              /* shared pinctrl settings */
++                              audmux {
++                                      pinctrl_audmux_1: audmux-1 {
++                                              fsl,pins = <
++                                                      18   0x80000000 /* MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD */
++                                                      1586 0x80000000 /* MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC */
++                                                      11   0x80000000 /* MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD */
++                                                      3    0x80000000 /* MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS */
++                                              >;
++                                      };
++                              };
++
++                              ecspi1 {
++                                      pinctrl_ecspi1_1: ecspi1grp-1 {
++                                              fsl,pins = <
++                                                      101 0x100b1     /* MX6Q_PAD_EIM_D17__ECSPI1_MISO */
++                                                      109 0x100b1     /* MX6Q_PAD_EIM_D18__ECSPI1_MOSI */
++                                                      94  0x100b1     /* MX6Q_PAD_EIM_D16__ECSPI1_SCLK */
++                                              >;
++                                      };
++                              };
++
++                              enet {
++                                      pinctrl_enet_1: enetgrp-1 {
++                                              fsl,pins = <
++                                                      695 0x1b0b0     /* MX6Q_PAD_ENET_MDIO__ENET_MDIO */
++                                                      756 0x1b0b0     /* MX6Q_PAD_ENET_MDC__ENET_MDC */
++                                                      24  0x1b0b0     /* MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC */
++                                                      30  0x1b0b0     /* MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0 */
++                                                      34  0x1b0b0     /* MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1 */
++                                                      39  0x1b0b0     /* MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2 */
++                                                      44  0x1b0b0     /* MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3 */
++                                                      56  0x1b0b0     /* MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL */
++                                                      702 0x1b0b0     /* MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK */
++                                                      74  0x1b0b0     /* MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC */
++                                                      52  0x1b0b0     /* MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0 */
++                                                      61  0x1b0b0     /* MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1 */
++                                                      66  0x1b0b0     /* MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 */
++                                                      70  0x1b0b0     /* MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 */
++                                                      48  0x1b0b0     /* MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL */
++                                                      1033 0x4001b0a8 /* MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT*/
++                                              >;
++                                      };
++
++                                      pinctrl_enet_2: enetgrp-2 {
++                                              fsl,pins = <
++                                                      890 0x1b0b0     /* MX6Q_PAD_KEY_COL1__ENET_MDIO */
++                                                      909 0x1b0b0     /* MX6Q_PAD_KEY_COL2__ENET_MDC */
++                                                      24  0x1b0b0     /* MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC */
++                                                      30  0x1b0b0     /* MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0 */
++                                                      34  0x1b0b0     /* MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1 */
++                                                      39  0x1b0b0     /* MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2 */
++                                                      44  0x1b0b0     /* MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3 */
++                                                      56  0x1b0b0     /* MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL */
++                                                      702 0x1b0b0     /* MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK */
++                                                      74  0x1b0b0     /* MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC */
++                                                      52  0x1b0b0     /* MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0 */
++                                                      61  0x1b0b0     /* MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1 */
++                                                      66  0x1b0b0     /* MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 */
++                                                      70  0x1b0b0     /* MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 */
++                                                      48  0x1b0b0     /* MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL */
++                                              >;
++                                      };
++                              };
++
++                              gpmi-nand {
++                                      pinctrl_gpmi_nand_1: gpmi-nand-1 {
++                                              fsl,pins = <
++                                                      1328 0xb0b1     /* MX6Q_PAD_NANDF_CLE__RAWNAND_CLE */
++                                                      1336 0xb0b1     /* MX6Q_PAD_NANDF_ALE__RAWNAND_ALE */
++                                                      1344 0xb0b1     /* MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN */
++                                                      1352 0xb000     /* MX6Q_PAD_NANDF_RB0__RAWNAND_READY0 */
++                                                      1360 0xb0b1     /* MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N */
++                                                      1365 0xb0b1     /* MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N */
++                                                      1371 0xb0b1     /* MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N */
++                                                      1378 0xb0b1     /* MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N */
++                                                      1387 0xb0b1     /* MX6Q_PAD_SD4_CMD__RAWNAND_RDN */
++                                                      1393 0xb0b1     /* MX6Q_PAD_SD4_CLK__RAWNAND_WRN */
++                                                      1397 0xb0b1     /* MX6Q_PAD_NANDF_D0__RAWNAND_D0 */
++                                                      1405 0xb0b1     /* MX6Q_PAD_NANDF_D1__RAWNAND_D1 */
++                                                      1413 0xb0b1     /* MX6Q_PAD_NANDF_D2__RAWNAND_D2 */
++                                                      1421 0xb0b1     /* MX6Q_PAD_NANDF_D3__RAWNAND_D3 */
++                                                      1429 0xb0b1     /* MX6Q_PAD_NANDF_D4__RAWNAND_D4 */
++                                                      1437 0xb0b1     /* MX6Q_PAD_NANDF_D5__RAWNAND_D5 */
++                                                      1445 0xb0b1     /* MX6Q_PAD_NANDF_D6__RAWNAND_D6 */
++                                                      1453 0xb0b1     /* MX6Q_PAD_NANDF_D7__RAWNAND_D7 */
++                                                      1463 0x00b1     /* MX6Q_PAD_SD4_DAT0__RAWNAND_DQS */
++                                              >;
++                                      };
++                              };
++
++                              i2c1 {
++                                      pinctrl_i2c1_1: i2c1grp-1 {
++                                              fsl,pins = <
++                                                      137 0x4001b8b1  /* MX6Q_PAD_EIM_D21__I2C1_SCL */
++                                                      196 0x4001b8b1  /* MX6Q_PAD_EIM_D28__I2C1_SDA */
++                                              >;
++                                      };
++                              };
++
++                              uart1 {
++                                      pinctrl_uart1_1: uart1grp-1 {
++                                              fsl,pins = <
++                                                      1140 0x1b0b1    /* MX6Q_PAD_CSI0_DAT10__UART1_TXD */
++                                                      1148 0x1b0b1    /* MX6Q_PAD_CSI0_DAT11__UART1_RXD */
++                                              >;
++                                      };
++                                      pinctrl_uart1_2: uart1-grp-2 {
++                                              fsl,pins = <
++                                                      120  0x1b0b1    /* MX6Q_PAD_EIM_D19__UART1_CTS */
++                                                      128  0x1b0b1    /* MX6Q_PAD_EIM_D20__UART1_RTS */
++                                              >;
++                                      };
++
++                                      pinctrl_uart1_3: uart1grp-3 {
++                                              fsl,pins = <
++                                                      1242 0x1b0b1    /* MX6Q_PAD_SD3_DAT7__UART1_TXD */
++                                                      1250 0x1b0b1    /* MX6Q_PAD_SD3_DAT6__UART1_RXD */
++                                              >;
++                                      };
++                                      pinctrl_uart1_4: uart1-grp-4 {
++                                              fsl,pins = <
++                                                      1290 0x1b0b1    /* MX6Q_PAD_SD3_DAT0__UART1_CTS */
++                                                      1298 0x1b0b1    /* MX6Q_PAD_SD3_DAT1__UART1_RTS */
++                                              >;
++                                      };
++                              };
++
++                              uart2 {
++                                      pinctrl_uart2_1: uart2grp-1 {
++                                              fsl,pins = <
++                                                      183  0x1b0b1    /* MX6Q_PAD_EIM_D26__UART2_TXD */
++                                                      191  0x1b0b1    /* MX6Q_PAD_EIM_D27__UART2_RXD */
++                                              >;
++                                      };
++                                      pinctrl_uart2_2: uart2grp-2 {
++                                              fsl,pins = <
++                                                      199  0x1b0b1    /* MX6Q_PAD_EIM_D28__UART2_CTS */
++                                                      206  0x1b0b1    /* MX6Q_PAD_EIM_D29__UART2_RTS */
++                                              >;
++                                      };
++
++                                      pinctrl_uart2_3: uart2grp-3 {
++                                              fsl,pins = <
++                                                      1258 0x1b0b1    /* MX6Q_PAD_SD3_DAT5__UART2_TXD */
++                                                      1266 0x1b0b1    /* MX6Q_PAD_SD3_DAT6__UART2_RXD */
++                                              >;
++                                      };
++                                      pinctrl_uart2_4: uart2grp-4 {
++                                              fsl,pins = <
++                                                      1274 0x1b0b1    /* MX6Q_PAD_SD3_CMD__UART2_CTS */
++                                                      1282 0x1b0b1    /* MX6Q_PAD_SD3_CLK__UART2_RTS */
++                                              >;
++                                      };
++
++                                      pinctrl_uart2_5: uart2grp-5 {
++                                              fsl,pins = <
++                                                      1518 0x1b0b1    /* MX6Q_PAD_SD4_DAT7__UART2_TXD */
++                                                      1494 0x1b0b1    /* MX6Q_PAD_SD4_DAT4__UART2_RXD */
++                                              >;
++                                      };
++                                      pinctrl_uart2_6: uart2grp-6 {
++                                              fsl,pins = <
++                                                      1510 0x1b0b1    /* MX6Q_PAD_SD4_DAT6__UART2_CTS */
++                                                      1502 0x1b0b1    /* MX6Q_PAD_SD4_DAT5__UART2_RTS */
++                                              >;
++                                      };
++
++                                      pinctrl_uart2_7: uart2grp-7 {
++                                              fsl,pins = <
++                                                      1019 0x1b0b1    /* MX6Q_PAD_GPIO_7__UART2_TXD */
++                                                      1027 0x1b0b1    /* MX6Q_PAD_GPIO_8__UART2_RXD */
++                                              >;
++                                      };
++                              };
++
++                              uart3 {
++                                      pinctrl_uart3_1: uart3grp-1 {
++                                              fsl,pins = <
++                                                      165  0x1b0b1    /* MX6Q_PAD_EIM_D24__UART3_TXD */
++                                                      173  0x1b0b1    /* MX6Q_PAD_EIM_D25__UART3_RXD */
++                                              >;
++                                      };
++                                      pinctrl_uart3_2: uart3grp-2 {
++                                              fsl,pins = <
++                                                      149  0x1b0b1    /* MX6Q_PAD_EIM_D23__UART3_CTS */
++                                                      157  0x1b0b1    /* MX6Q_PAD_EIM_EB3__UART3_RTS */
++                                              >;
++                                      };
++
++                                      pinctrl_uart3_3: uart3grp-3 {
++                                              fsl,pins = <
++                                                      1388 0x1b0b1    /* MX6Q_PAD_SD4_CMD__UART3_TXD */
++                                                      1394 0x1b0b1    /* MX6Q_PAD_SD4_CLK__UART3_RXD */
++                                              >;
++                                      };
++                                      pinctrl_uart3_4: uart3grp-4 {
++                                              fsl,pins = <
++                                                      1313 0x1b0b1    /* MX6Q_PAD_SD3_DAT3__UART3_CTS */
++                                                      1321 0x1b0b1    /* MX6Q_PAD_SD3_RST__UART3_RTS */
++                                              >;
++                                      };
++
++                                      pinctrl_uart3_5: uart3grp-5 {
++                                              fsl,pins = <
++                                                      214  0x1b0b1    /* MX6Q_PAD_EIM_D30__UART3_CTS */
++                                                      222  0x1b0b1    /* MX6Q_PAD_EIM_D31__UART3_RTS */
++                                              >;
++                                      };
++                              };
++
++                              uart4 {
++                                      pinctrl_uart4_1: uart4grp-1 {
++                                              fsl,pins = <
++                                                      877  0x1b0b1    /* MX6Q_PAD_KEY_COL0__UART4_TXD */
++                                                      885  0x1b0b1    /* MX6Q_PAD_KEY_ROW0__UART4_RXD */
++                                              >;
++                                      };
++                              };
++
++                              usbotg {
++                                      pinctrl_usbotg_1: usbotggrp-1 {
++                                              fsl,pins = <
++                                                      1592 0x17059    /* MX6Q_PAD_GPIO_1__ANATOP_USBOTG_ID */
++                                              >;
++                                      };
++                              };
++
++                              usdhc1 {
++                                      pinctrl_usdhc1_1: usdhc1grp-1 {
++                                              fsl,pins = <
++                                                      1548 0x17059    /* MX6Q_PAD_SD1_CMD__USDHC1_CMD */
++                                                      1562 0x10059    /* MX6Q_PAD_SD1_CLK__USDHC1_CLK */
++                                                      1532 0x17059    /* MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 */
++                                                      1524 0x17059    /* MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 */
++                                                      1554 0x17059    /* MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 */
++                                                      1540 0x17059    /* MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 */
++                                                      1398 0x17059    /* MX6Q_PAD_NANDF_D0__USDHC1_DAT4 */
++                                                      1406 0x17059    /* MX6Q_PAD_NANDF_D1__USDHC1_DAT5 */
++                                                      1414 0x17059    /* MX6Q_PAD_NANDF_D2__USDHC1_DAT6 */
++                                                      1422 0x17059    /* MX6Q_PAD_NANDF_D3__USDHC1_DAT7 */
++                                              >;
++                                      };
++
++                                      pinctrl_usdhc1_2: usdhc1grp-2 {
++                                              fsl,pins = <
++                                                      1548 0x17059    /* MX6Q_PAD_SD1_CMD__USDHC1_CMD */
++                                                      1562 0x10059    /* MX6Q_PAD_SD1_CLK__USDHC1_CLK */
++                                                      1532 0x17059    /* MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 */
++                                                      1524 0x17059    /* MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 */
++                                                      1554 0x17059    /* MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 */
++                                                      1540 0x17059    /* MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 */
++                                              >;
++                                      };
++                              };
++
++                              usdhc2 {
++                                      pinctrl_usdhc2_1: usdhc2grp-1 {
++                                              fsl,pins = <
++                                                      1577 0x17059    /* MX6Q_PAD_SD2_CMD__USDHC2_CMD */
++                                                      1569 0x10059    /* MX6Q_PAD_SD2_CLK__USDHC2_CLK */
++                                                      16   0x17059    /* MX6Q_PAD_SD2_DAT0__USDHC2_DAT0 */
++                                                      0    0x17059    /* MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 */
++                                                      8    0x17059    /* MX6Q_PAD_SD2_DAT2__USDHC2_DAT2 */
++                                                      1583 0x17059    /* MX6Q_PAD_SD2_DAT3__USDHC2_DAT3 */
++                                                      1430 0x17059    /* MX6Q_PAD_NANDF_D4__USDHC2_DAT4 */
++                                                      1438 0x17059    /* MX6Q_PAD_NANDF_D5__USDHC2_DAT5 */
++                                                      1446 0x17059    /* MX6Q_PAD_NANDF_D6__USDHC2_DAT6 */
++                                                      1454 0x17059    /* MX6Q_PAD_NANDF_D7__USDHC2_DAT7 */
++                                              >;
++                                      };
++
++                                      pinctrl_usdhc2_2: usdhc2grp-2 {
++                                              fsl,pins = <
++                                                      1577 0x17059    /* MX6Q_PAD_SD2_CMD__USDHC2_CMD */
++                                                      1569 0x10059    /* MX6Q_PAD_SD2_CLK__USDHC2_CLK */
++                                                      16   0x17059    /* MX6Q_PAD_SD2_DAT0__USDHC2_DAT0 */
++                                                      0    0x17059    /* MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 */
++                                                      8    0x17059    /* MX6Q_PAD_SD2_DAT2__USDHC2_DAT2 */
++                                                      1583 0x17059    /* MX6Q_PAD_SD2_DAT3__USDHC2_DAT3 */
++                                              >;
++                                      };
++                              };
++
++                              usdhc3 {
++                                      pinctrl_usdhc3_1: usdhc3grp-1 {
++                                              fsl,pins = <
++                                                      1273 0x17059    /* MX6Q_PAD_SD3_CMD__USDHC3_CMD */
++                                                      1281 0x10059    /* MX6Q_PAD_SD3_CLK__USDHC3_CLK */
++                                                      1289 0x17059    /* MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 */
++                                                      1297 0x17059    /* MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 */
++                                                      1305 0x17059    /* MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 */
++                                                      1312 0x17059    /* MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 */
++                                                      1265 0x17059    /* MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 */
++                                                      1257 0x17059    /* MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 */
++                                                      1249 0x17059    /* MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 */
++                                                      1241 0x17059    /* MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 */
++                                              >;
++                                      };
++
++                                      pinctrl_usdhc3_2: usdhc3grp-2 {
++                                              fsl,pins = <
++                                                      1273 0x17059    /* MX6Q_PAD_SD3_CMD__USDHC3_CMD */
++                                                      1281 0x10059    /* MX6Q_PAD_SD3_CLK__USDHC3_CLK */
++                                                      1289 0x17059    /* MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 */
++                                                      1297 0x17059    /* MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 */
++                                                      1305 0x17059    /* MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 */
++                                                      1312 0x17059    /* MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 */
++                                              >;
++                                      };
++                              };
++
++                              usdhc4 {
++                                      pinctrl_usdhc4_1: usdhc4grp-1 {
++                                              fsl,pins = <
++                                                      1386 0x17059    /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */
++                                                      1392 0x10059    /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */
++                                                      1462 0x17059    /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */
++                                                      1470 0x17059    /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */
++                                                      1478 0x17059    /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */
++                                                      1486 0x17059    /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */
++                                                      1493 0x17059    /* MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 */
++                                                      1501 0x17059    /* MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 */
++                                                      1509 0x17059    /* MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 */
++                                                      1517 0x17059    /* MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 */
++                                              >;
++                                      };
++
++                                      pinctrl_usdhc4_2: usdhc4grp-2 {
++                                              fsl,pins = <
++                                                      1386 0x17059    /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */
++                                                      1392 0x10059    /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */
++                                                      1462 0x17059    /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */
++                                                      1470 0x17059    /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */
++                                                      1478 0x17059    /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */
++                                                      1486 0x17059    /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */
++                                              >;
++                                      };
++                              };
++                      };
++              };
++
++              ipu2: ipu@02800000 {
++                      #crtc-cells = <1>;
++                      compatible = "fsl,imx6q-ipu";
++                      reg = <0x02800000 0x400000>;
++                      interrupts = <0 8 0x4 0 7 0x4>;
++                      clocks = <&clks 133>, <&clks 134>, <&clks 137>;
++                      clock-names = "bus", "di0", "di1";
++              };
++      };
++};
index 0000000,a9b86c1..a02f2e7
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,196 +1,187 @@@
 -#include <ipu_pixfmt.h>
+ /*
+  * (C) Copyright 2007
+  * Sascha Hauer, Pengutronix
+  *
+  * (C) Copyright 2009 Freescale Semiconductor, Inc.
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  */
+ #include <common.h>
+ #include <asm/errno.h>
+ #include <asm/io.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/arch/clock.h>
+ #include <asm/arch/sys_proto.h>
+ #include <asm/arch/crm_regs.h>
 -#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
+ #ifdef CONFIG_FSL_ESDHC
+ #include <fsl_esdhc.h>
+ #endif
+ char *get_reset_cause(void)
+ {
+       u32 cause;
+       struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+       cause = readl(&src_regs->srsr);
+       writel(cause, &src_regs->srsr);
+       switch (cause) {
+       case 0x00001:
+       case 0x00011:
+               return "POR";
+       case 0x00004:
+               return "CSU";
+       case 0x00008:
+               return "IPP USER";
+       case 0x00010:
+               return "WDOG";
+       case 0x00020:
+               return "JTAG HIGH-Z";
+       case 0x00040:
+               return "JTAG SW";
+       case 0x10000:
+               return "WARM BOOT";
+       default:
+               return "unknown reset";
+       }
+ }
 -
 -#if defined(CONFIG_VIDEO_IPUV3)
 -void arch_preboot_os(void)
 -{
 -      /* disable video before launching O/S */
 -      ipuv3_fb_shutdown();
 -}
 -#endif
++#if defined(CONFIG_MX53) || defined(CONFIG_MX6Q)
+ #if defined(CONFIG_MX53)
+ #define MEMCTL_BASE   ESDCTL_BASE_ADDR;
+ #else
+ #define MEMCTL_BASE   MMDC_P0_BASE_ADDR;
+ #endif
+ static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9};
+ static const unsigned char bank_lookup[] = {3, 2};
+ struct esd_mmdc_regs {
+       uint32_t        ctl;
+       uint32_t        pdc;
+       uint32_t        otc;
+       uint32_t        cfg0;
+       uint32_t        cfg1;
+       uint32_t        cfg2;
+       uint32_t        misc;
+       uint32_t        scr;
+       uint32_t        ref;
+       uint32_t        rsvd1;
+       uint32_t        rsvd2;
+       uint32_t        rwd;
+       uint32_t        or;
+       uint32_t        mrr;
+       uint32_t        cfg3lp;
+       uint32_t        mr4;
+ };
+ #define ESD_MMDC_CTL_GET_ROW(mdctl)   ((ctl >> 24) & 7)
+ #define ESD_MMDC_CTL_GET_COLUMN(mdctl)        ((ctl >> 20) & 7)
+ #define ESD_MMDC_CTL_GET_WIDTH(mdctl) ((ctl >> 16) & 3)
+ #define ESD_MMDC_CTL_GET_CS1(mdctl)   ((ctl >> 30) & 1)
+ #define ESD_MMDC_MISC_GET_BANK(mdmisc)        ((misc >> 5) & 1)
+ unsigned imx_ddr_size(void)
+ {
+       struct esd_mmdc_regs *mem = (struct esd_mmdc_regs *)MEMCTL_BASE;
+       unsigned ctl = readl(&mem->ctl);
+       unsigned misc = readl(&mem->misc);
+       int bits = 11 + 0 + 0 + 1;      /* row + col + bank + width */
+       bits += ESD_MMDC_CTL_GET_ROW(ctl);
+       bits += col_lookup[ESD_MMDC_CTL_GET_COLUMN(ctl)];
+       bits += bank_lookup[ESD_MMDC_MISC_GET_BANK(misc)];
+       bits += ESD_MMDC_CTL_GET_WIDTH(ctl);
+       bits += ESD_MMDC_CTL_GET_CS1(ctl);
+       return 1 << bits;
+ }
+ #endif
+ #if defined(CONFIG_DISPLAY_CPUINFO)
+ const char *get_imx_type(u32 imxtype)
+ {
+       switch (imxtype) {
+       case MXC_CPU_MX6Q:
+               return "6Q";    /* Quad-core version of the mx6 */
+       case MXC_CPU_MX6DL:
+               return "6DL";   /* Dual Lite version of the mx6 */
+       case MXC_CPU_MX6SOLO:
+               return "6SOLO"; /* Solo version of the mx6 */
+       case MXC_CPU_MX6SL:
+               return "6SL";   /* Solo-Lite version of the mx6 */
+       case MXC_CPU_MX51:
+               return "51";
+       case MXC_CPU_MX53:
+               return "53";
+       default:
+               return "??";
+       }
+ }
+ int print_cpuinfo(void)
+ {
+       u32 cpurev;
+       cpurev = get_cpu_rev();
+       printf("CPU:   Freescale i.MX%s rev%d.%d at %d MHz\n",
+               get_imx_type((cpurev & 0xFF000) >> 12),
+               (cpurev & 0x000F0) >> 4,
+               (cpurev & 0x0000F) >> 0,
+               mxc_get_clock(MXC_ARM_CLK) / 1000000);
+       printf("Reset cause: %s\n", get_reset_cause());
+       return 0;
+ }
+ #endif
+ int cpu_eth_init(bd_t *bis)
+ {
+       int rc = -ENODEV;
+ #if defined(CONFIG_FEC_MXC)
+       rc = fecmxc_initialize(bis);
+ #endif
+       return rc;
+ }
+ #ifdef CONFIG_FSL_ESDHC
+ /*
+  * Initializes on-chip MMC controllers.
+  * to override, implement board_mmc_init()
+  */
+ int cpu_mmc_init(bd_t *bis)
+ {
+       return fsl_esdhc_mmc_init(bis);
+ }
+ #endif
+ u32 get_ahb_clk(void)
+ {
+       struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+       u32 reg, ahb_podf;
+       reg = __raw_readl(&imx_ccm->cbcdr);
+       reg &= MXC_CCM_CBCDR_AHB_PODF_MASK;
+       ahb_podf = reg >> MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+       return get_periph_clk() / (ahb_podf + 1);
+ }
index 0000000,08fad78..2831964
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,71 +1,86 @@@
 -      if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs)
+ /*
+  * Based on the iomux-v3.c from Linux kernel:
+  * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+  * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+  *                       <armlinux@phytec.de>
+  *
+  * Copyright (C) 2004-2011 Freescale Semiconductor, Inc.
+  *
+  * 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.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+  * MA 02110-1301, USA.
+  */
+ #include <common.h>
+ #include <asm/io.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/imx-common/iomux-v3.h>
+ static void *base = (void *)IOMUXC_BASE_ADDR;
+ /*
+  * configures a single pad in the iomuxer
+  */
+ int imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
+ {
+       u32 mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
+       u32 mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
+       u32 sel_input_ofs =
+               (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT;
+       u32 sel_input =
+               (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
+       u32 pad_ctrl_ofs =
+               (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
+       u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
+       if (mux_ctrl_ofs)
+               __raw_writel(mux_mode, base + mux_ctrl_ofs);
+       if (sel_input_ofs)
+               __raw_writel(sel_input, base + sel_input_ofs);
++      if ((pad & PAD_CTRL_VALID) && pad_ctrl_ofs)
+               __raw_writel(pad_ctrl, base + pad_ctrl_ofs);
+       return 0;
+ }
+ int imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
+                                    unsigned count)
+ {
+       iomux_v3_cfg_t const *p = pad_list;
+       int i;
+       int ret;
+       for (i = 0; i < count; i++) {
++#if 0
++              u32 mux_ctrl_ofs = (*p & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
++              u32 mux_mode = (*p & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
++              u32 sel_input_ofs =
++                      (*p & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT;
++              u32 sel_input =
++                      (*p & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
++              u32 pad_ctrl_ofs =
++                      (*p & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
++              u32 pad_ctrl = (*p & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
++
++              printf("PAD[%2d]=%016llx mux[%03x]=%02x pad[%03x]=%05x%c inp[%03x]=%d\n",
++                      i, *p, mux_ctrl_ofs, mux_mode, pad_ctrl_ofs, pad_ctrl,
++                      *p & PAD_CTRL_VALID ? ' ' : '!', sel_input_ofs, sel_input);
++#endif
+               ret = imx_iomux_v3_setup_pad(*p);
+               if (ret)
+                       return ret;
+               p++;
+       }
+       return 0;
+ }
index 0000000,ab37d64..b2ce8fe
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,149 +1,195 @@@
 -#define GPTCR_CLKSOURCE_32    (4 << 6)        /* Clock source */
+ /*
+  * (C) Copyright 2007
+  * Sascha Hauer, Pengutronix
+  *
+  * (C) Copyright 2009 Freescale Semiconductor, Inc.
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  */
+ #include <common.h>
+ #include <asm/io.h>
+ #include <div64.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/arch/clock.h>
++#define DEBUG_TIMER_WRAP
++
+ /* General purpose timers registers */
+ struct mxc_gpt {
+       unsigned int control;
+       unsigned int prescaler;
+       unsigned int status;
+       unsigned int nouse[6];
+       unsigned int counter;
+ };
+ static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR;
+ /* General purpose timers bitfields */
+ #define GPTCR_SWR             (1 << 15)       /* Software reset */
+ #define GPTCR_FRR             (1 << 9)        /* Freerun / restart */
 -#define timestamp (gd->arch.tbl)
 -#define lastinc (gd->arch.lastinc)
++#define GPTCR_CLKSOURCE_IPG   (1 << 6)        /* Clock source */
++#define GPTCR_CLKSOURCE_CKIH  (2 << 6)
++#define GPTCR_CLKSOURCE_32kHz (4 << 6)
++#ifdef CONFIG_MX6Q
++#define GPTCR_CLKSOURCE_OSC_DIV_8     (5 << 6)
++#define GPTCR_CLKSOURCE_OSC   (7 << 6)
++#else
++#define GPTCR_CLKSOURCE_OSC   (5 << 6)
++#endif
++#define GPTCR_CLKSOURCE_MASK  (7 << 6)
+ #define GPTCR_TEN             1               /* Timer enable */
++#if 1
++#define GPT_CLKSOURCE         GPTCR_CLKSOURCE_OSC
++#define GPT_REFCLK            24000000
++#define GPT_PRESCALER         24
++#else
++#define GPT_CLKSOURCE         GPTCR_CLKSOURCE_32kHz
++#define GPT_REFCLK            32768
++#define GPT_PRESCALER         1
++#endif
++#define GPT_CLK                       (GPT_REFCLK / GPT_PRESCALER)
++
++#ifdef DEBUG_TIMER_WRAP
++/*
++ * Let the timer wrap 30 seconds after start to catch misbehaving
++ * timer related code early
++ */
++#define TIMER_START           (-time_to_tick(30 * CONFIG_SYS_HZ))
++#else
++#define TIMER_START           0UL
++#endif
++
+ DECLARE_GLOBAL_DATA_PTR;
 -static inline unsigned long long tick_to_time(unsigned long long tick)
++static inline unsigned long tick_to_time(unsigned long tick)
++{
++      unsigned long long t = (unsigned long long)tick * CONFIG_SYS_HZ;
++      do_div(t, GPT_CLK);
++      return t;
++}
 -      tick *= CONFIG_SYS_HZ;
 -      do_div(tick, MXC_CLK32);
++static inline unsigned long time_to_tick(unsigned long time)
+ {
 -      return tick;
++      unsigned long long ticks = (unsigned long long)time;
 -static inline unsigned long long us_to_tick(unsigned long long usec)
++      ticks *= GPT_CLK;
++      do_div(ticks, CONFIG_SYS_HZ);
++      return ticks;
+ }
 -      usec = usec * MXC_CLK32 + 999999;
 -      do_div(usec, 1000000);
++static inline unsigned long us_to_tick(unsigned long usec)
+ {
 -      return usec;
++      unsigned long long ticks = (unsigned long long)usec;
 -      __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */
++      ticks *= GPT_CLK;
++      do_div(ticks, 1000 * CONFIG_SYS_HZ);
++      return ticks;
+ }
+ int timer_init(void)
+ {
+       int i;
+       ulong val;
+       /* setup GP Timer 1 */
+       __raw_writel(GPTCR_SWR, &cur_gpt->control);
+       /* We have no udelay by now */
+       for (i = 0; i < 100; i++)
+               __raw_writel(0, &cur_gpt->control);
 -      __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control);
++      __raw_writel(GPT_PRESCALER - 1, &cur_gpt->prescaler);
+       /* Freerun Mode, PERCLK1 input */
+       i = __raw_readl(&cur_gpt->control);
 -      lastinc = val / (MXC_CLK32 / CONFIG_SYS_HZ);
 -      timestamp = 0;
++      i &= ~GPTCR_CLKSOURCE_MASK;
++      __raw_writel(i | GPT_CLKSOURCE | GPTCR_TEN, &cur_gpt->control);
+       val = __raw_readl(&cur_gpt->counter);
 -      if (now >= lastinc) {
 -              /*
 -               * normal mode (non roll)
 -               * move stamp forward with absolut diff ticks
 -               */
 -              timestamp += (now - lastinc);
 -      } else {
 -              /* we have rollover of incrementer */
 -              timestamp += (0xFFFFFFFF - lastinc) + now;
 -      }
 -      lastinc = now;
 -      return timestamp;
++      gd->arch.lastinc = val;
++      gd->arch.tbu = 0;
++      gd->arch.tbl = TIMER_START;
++      gd->arch.timer_rate_hz = GPT_CLK;
+       return 0;
+ }
+ unsigned long long get_ticks(void)
+ {
+       ulong now = __raw_readl(&cur_gpt->counter); /* current tick value */
++      ulong inc = now - gd->arch.lastinc;
 -      return get_timer_masked() - base;
++      gd->arch.tbl += inc;
++      gd->arch.lastinc = now;
++      return gd->arch.tbl;
+ }
+ ulong get_timer_masked(void)
+ {
+       /*
+        * get_ticks() returns a long long (64 bit), it wraps in
+        * 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
+        * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
+        * 5 * 10^6 days - long enough.
+        */
++      /*
++       * LW: get_ticks() returns a long long with the top 32 bits always ZERO!
++       * Thus the calculation above is not true.
++       * A 64bit timer value would only make sense if it was
++       * consistently used throughout the code. Thus also the parameter
++       * to get_timer() and its return value would need to be 64bit wide!
++       */
+       return tick_to_time(get_ticks());
+ }
+ ulong get_timer(ulong base)
+ {
 -      unsigned long long tmp;
 -      ulong tmo;
++      return tick_to_time(get_ticks() - time_to_tick(base));
+ }
++#include <asm/gpio.h>
++
+ /* delay x useconds AND preserve advance timstamp value */
+ void __udelay(unsigned long usec)
+ {
 -      tmo = us_to_tick(usec);
 -      tmp = get_ticks() + tmo;        /* get current timestamp */
++      unsigned long start = __raw_readl(&cur_gpt->counter);
++      unsigned long ticks;
++
++      if (usec == 0)
++              return;
 -      while (get_ticks() < tmp)       /* loop till event */
 -               /*NOP*/;
++      ticks = us_to_tick(usec);
++      if (ticks == 0)
++              ticks++;
 -      return MXC_CLK32;
++      while (__raw_readl(&cur_gpt->counter) - start < ticks)
++              /* loop till event */;
+ }
+ /*
+  * 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 gd->arch.timer_rate_hz;
+ }
  #ifndef _CLOCKS_AM33XX_H_
  #define _CLOCKS_AM33XX_H_
  
- #define OSC   24
+ #define OSC   (V_OSCK/1000000)
  
- /* MAIN PLL */
 +#ifndef CONFIG_SYS_MPU_CLK
- /* default to 500 MHz */
- #define MPUPLL_M      500
+ /* MAIN PLL Fdll = 550 MHZ, */
+ #define MPUPLL_M      550
 -#define MPUPLL_N      (OSC-1)
 +#else
 +#define MPUPLL_M      CONFIG_SYS_MPU_CLK
 +#endif
- #define MPUPLL_N      23
++#define MPUPLL_N      (OSC - 1)
  #define MPUPLL_M2     1
  
  /* Core PLL Fdll = 1 GHZ, */
  #define COREPLL_M     1000
- #define COREPLL_N     23
 -#define COREPLL_N     (OSC-1)
++#define COREPLL_N     (OSC - 1)
  
  #define COREPLL_M4    10      /* CORE_CLKOUTM4 = 200 MHZ */
  #define COREPLL_M5    8       /* CORE_CLKOUTM5 = 250 MHZ */
   * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
   */
  #define PERPLL_M      960
- #define PERPLL_N      23
 -#define PERPLL_N      (OSC-1)
++#define PERPLL_N      (OSC - 1)
  #define PERPLL_M2     5
  
  /* DDR Freq is 266 MHZ for now */
  /* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
 +#ifndef CONFIG_SYS_DDR_CLK
  #define DDRPLL_M      266
 -#define DDRPLL_N      (OSC-1)
 +#else
 +#define DDRPLL_M      CONFIG_SYS_DDR_CLK
 +#endif
- #define DDRPLL_N      23
++#define DDRPLL_N      (OSC - 1)
  #define DDRPLL_M2     1
  
- #define DISPPLL_N     23
 +#define DISPPLL_M     200
++#define DISPPLL_N     (OSC - 1)
 +#define DISPPLL_M2    1
 +
  extern void pll_init(void);
  extern void enable_emif_clocks(void);
  
  #define DEVICE_ID                     0x44E10600
  
  /* This gives the status of the boot mode pins on the evm */
 -#define SYSBOOT_MASK                  (BIT(0) | BIT(1) | BIT(2)\
 -                                      | BIT(3) | BIT(4))
 +#define SYSBOOT_MASK                  (BIT(0) | BIT(1) | BIT(2) | \
 +                                              BIT(3) | BIT(4))
  
  /* Reset control */
 -#ifdef CONFIG_AM33XX
  #define PRM_RSTCTRL                   0x44E00F00
  #define PRM_RSTST                     0x44E00F08
 -#endif
  #define PRM_RSTCTRL_RESET             0x01
+ #define PRM_RSTST_WARM_RESET_MASK     0x232
  
  #ifndef __KERNEL_STRICT_NAMES
  #ifndef __ASSEMBLY__
@@@ -113,9 -167,10 +168,10 @@@ struct cm_perpll 
        unsigned int l3clkstctrl;       /* offset 0x0c */
        unsigned int resv1;
        unsigned int cpgmac0clkctrl;    /* offset 0x14 */
-       unsigned int lcdcclkctrl;       /* offset 0x18 */
+       unsigned int lcdclkctrl;        /* offset 0x18 */
 -      unsigned int usb0clkctrl;       /* offset 0x1C */
 +      unsigned int usb0clkctrl;       /* offset 0x1c */
-       unsigned int resv2[2];
+       unsigned int resv2;
+       unsigned int tptc0clkctrl;      /* offset 0x24 */
        unsigned int emifclkctrl;       /* offset 0x28 */
        unsigned int ocmcramclkctrl;    /* offset 0x2c */
        unsigned int gpmcclkctrl;       /* offset 0x30 */
@@@ -227,68 -303,44 +304,55 @@@ struct vtp_reg 
  struct ctrl_stat {
        unsigned int resv1[16];
        unsigned int statusreg;         /* ofset 0x40 */
+       unsigned int resv2[51];
+       unsigned int secure_emif_sdram_config;  /* offset 0x0110 */
  };
  
- struct gpmc_cs {
-       u32 config1;            /* 0x00 */
-       u32 config2;            /* 0x04 */
-       u32 config3;            /* 0x08 */
-       u32 config4;            /* 0x0C */
-       u32 config5;            /* 0x10 */
-       u32 config6;            /* 0x14 */
-       u32 config7;            /* 0x18 */
-       u32 nand_cmd;           /* 0x1C */
-       u32 nand_adr;           /* 0x20 */
-       u32 nand_dat;           /* 0x24 */
-       u8 res[8];              /* blow up to 0x30 byte */
- };
+ /* AM33XX GPIO registers */
+ #define OMAP_GPIO_REVISION            0x0000
+ #define OMAP_GPIO_SYSCONFIG           0x0010
+ #define OMAP_GPIO_SYSSTATUS           0x0114
+ #define OMAP_GPIO_IRQSTATUS1          0x002c
+ #define OMAP_GPIO_IRQSTATUS2          0x0030
+ #define OMAP_GPIO_CTRL                        0x0130
+ #define OMAP_GPIO_OE                  0x0134
+ #define OMAP_GPIO_DATAIN              0x0138
+ #define OMAP_GPIO_DATAOUT             0x013c
+ #define OMAP_GPIO_LEVELDETECT0                0x0140
+ #define OMAP_GPIO_LEVELDETECT1                0x0144
+ #define OMAP_GPIO_RISINGDETECT                0x0148
+ #define OMAP_GPIO_FALLINGDETECT               0x014c
+ #define OMAP_GPIO_DEBOUNCE_EN         0x0150
+ #define OMAP_GPIO_DEBOUNCE_VAL                0x0154
+ #define OMAP_GPIO_CLEARDATAOUT                0x0190
+ #define OMAP_GPIO_SETDATAOUT          0x0194
  
- struct bch_res_0_3 {
-       u32 bch_result_x[4];
- };
- struct gpmc {
-       u8 res1[0x10];
-       u32 sysconfig;          /* 0x10 */
-       u8 res2[0x4];
-       u32 irqstatus;          /* 0x18 */
-       u32 irqenable;          /* 0x1C */
-       u8 res3[0x20];
-       u32 timeout_control;    /* 0x40 */
-       u8 res4[0xC];
-       u32 config;             /* 0x50 */
-       u32 status;             /* 0x54 */
-       u8 res5[0x8];           /* 0x58 */
-       struct gpmc_cs cs[8];   /* 0x60, 0x90, .. */
-       u8 res6[0x14];          /* 0x1E0 */
-       u32 ecc_config;         /* 0x1F4 */
-       u32 ecc_control;        /* 0x1F8 */
-       u32 ecc_size_config;    /* 0x1FC */
-       u32 ecc1_result;        /* 0x200 */
-       u32 ecc2_result;        /* 0x204 */
-       u32 ecc3_result;        /* 0x208 */
-       u32 ecc4_result;        /* 0x20C */
-       u32 ecc5_result;        /* 0x210 */
-       u32 ecc6_result;        /* 0x214 */
-       u32 ecc7_result;        /* 0x218 */
-       u32 ecc8_result;        /* 0x21C */
-       u32 ecc9_result;        /* 0x220 */
-       u8 res7[12];            /* 0x224 */
-       u32 testmomde_ctrl;     /* 0x230 */
-       u8 res8[12];            /* 0x234 */
-       struct bch_res_0_3 bch_result_0_3[2];   /* 0x240 */
+ /* Control Device Register */
+ struct ctrl_dev {
+       unsigned int deviceid;          /* offset 0x00 */
+       unsigned int resv1[7];
+       unsigned int usb_ctrl0;         /* offset 0x20 */
+       unsigned int resv2;
+       unsigned int usb_ctrl1;         /* offset 0x28 */
+       unsigned int resv3;
+       unsigned int macid0l;           /* offset 0x30 */
+       unsigned int macid0h;           /* offset 0x34 */
+       unsigned int macid1l;           /* offset 0x38 */
+       unsigned int macid1h;           /* offset 0x3c */
+       unsigned int resv4[4];
+       unsigned int miisel;            /* offset 0x50 */
  };
 +
 +void init_timer(void);
 +
 +#define clk_get_rate(c,p)                                     \
 +      __clk_get_rate(readl(&(c)->clkseldpll##p),              \
 +              readl(&(c)->divm2dpll##p))
 +
 +unsigned long __clk_get_rate(u32 m_n, u32 div_m2);
 +
++unsigned long lcdc_clk_rate(void);
++
  #endif /* __ASSEMBLY__ */
  #endif /* __KERNEL_STRICT_NAMES */
  
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  *
   */
- #ifndef _GPIO_AM33XX_H
- #define _GPIO_AM33XX_H
+ #ifndef _GPIO_AM33xx_H
+ #define _GPIO_AM33xx_H
+ #include <asm/omap_gpio.h>
  
- #include <asm-generic/gpio.h>
+ #define AM33XX_GPIO0_BASE       0x44E07000
+ #define AM33XX_GPIO1_BASE       0x4804C000
+ #define AM33XX_GPIO2_BASE       0x481AC000
+ #define AM33XX_GPIO3_BASE       0x481AE000
  
- #endif /* _GPIO_AM33XX_H */
 +#define AM33XX_GPIO_NR(bank, pin)     (((bank) << 5) | (pin))
 +
+ #endif /* _GPIO_AM33xx_H */
  #ifndef __AM33XX_HARDWARE_H
  #define __AM33XX_HARDWARE_H
  
+ #include <asm/arch/omap.h>
  /* Module base addresses */
- #define SRAM0_START                   0x402F0400
 +#define LOW_LEVEL_SRAM_STACK          0x4030B7FC
  #define UART0_BASE                    0x44E09000
  
  /* DM Timer base addresses */
  #define DM_TIMER6_BASE                        0x48048000
  #define DM_TIMER7_BASE                        0x4804A000
  
--/* GPIO Base address */
- #define GPIO0_BASE                    0x44E07000
 -#define GPIO0_BASE                    0x48032000
--#define GPIO1_BASE                    0x4804C000
--#define GPIO2_BASE                    0x481AC000
- #define GPIO3_BASE                    0x481AE000
--
  /* BCH Error Location Module */
  #define ELM_BASE                      0x48080000
  
  /*
   * OMAP HSMMC register definitions
   */
 -#define OMAP_HSMMC1_BASE              0x48060100
 -#define OMAP_HSMMC2_BASE              0x481D8100
 +#define OMAP_HSMMC1_BASE              0x48060000
 +#define OMAP_HSMMC2_BASE              0x481D8000
 +#define OMAP_HSMMC3_BASE              0x47810000
  
  typedef struct hsmmc {
-       unsigned char res1[0x110];
 -      unsigned char res1[0x10];
 -      unsigned int sysconfig;         /* 0x10 */
 -      unsigned int sysstatus;         /* 0x14 */
 -      unsigned char res2[0x14];
 -      unsigned int con;               /* 0x2C */
 -      unsigned char res3[0xD4];
 -      unsigned int blk;               /* 0x104 */
 -      unsigned int arg;               /* 0x108 */
 -      unsigned int cmd;               /* 0x10C */
 -      unsigned int rsp10;             /* 0x110 */
 -      unsigned int rsp32;             /* 0x114 */
 -      unsigned int rsp54;             /* 0x118 */
 -      unsigned int rsp76;             /* 0x11C */
 -      unsigned int data;              /* 0x120 */
 -      unsigned int pstate;            /* 0x124 */
 -      unsigned int hctl;              /* 0x128 */
 -      unsigned int sysctl;            /* 0x12C */
 -      unsigned int stat;              /* 0x130 */
 -      unsigned int ie;                /* 0x134 */
 -      unsigned char res4[0x8];
 -      unsigned int capa;              /* 0x140 */
++      unsigned int res1[0x110 / 4];
 +      unsigned int sysconfig;         /* 0x110 */
 +      unsigned int sysstatus;         /* 0x114 */
-       unsigned char res2[0x14];
++      unsigned int res2[0x14 / 4];
 +      unsigned int con;               /* 0x12C */
-       unsigned char res3[0xD4];
++      unsigned int res3[0xD4 / 4];
 +      unsigned int blk;               /* 0x204 */
 +      unsigned int arg;               /* 0x208 */
 +      unsigned int cmd;               /* 0x20C */
 +      unsigned int rsp10;             /* 0x210 */
 +      unsigned int rsp32;             /* 0x214 */
 +      unsigned int rsp54;             /* 0x218 */
 +      unsigned int rsp76;             /* 0x21C */
 +      unsigned int data;              /* 0x220 */
 +      unsigned int pstate;            /* 0x224 */
 +      unsigned int hctl;              /* 0x228 */
 +      unsigned int sysctl;            /* 0x22C */
 +      unsigned int stat;              /* 0x230 */
 +      unsigned int ie;                /* 0x234 */
-       unsigned char res4[0x8];
++      unsigned int res4[2];
 +      unsigned int capa;              /* 0x240 */
  } hsmmc_t;
  
  /*
@@@ -78,7 -77,7 +78,7 @@@
  #define DDIR_READ                     (0x1 << 4)
  #define MSBS_SGLEBLK                  (0x0 << 5)
  #define MSBS_MULTIBLK                 (0x1 << 5)
--#define RSP_TYPE_OFFSET                       (16)
++#define RSP_TYPE_OFFSET                       16
  #define RSP_TYPE_MASK                 (0x3 << 16)
  #define RSP_TYPE_NORSP                        (0x0 << 16)
  #define RSP_TYPE_LGHT136              (0x1 << 16)
@@@ -24,7 -24,7 +24,7 @@@
  
  #ifndef __ASSEMBLY__
  struct exynos4_sysreg {
--      unsigned char   res1[0x210];
++      unsigned int    res1[0x210 / 4];
        unsigned int    display_ctrl;
        unsigned int    display_ctrl2;
        unsigned int    camera_control;
@@@ -33,7 -33,7 +33,7 @@@
  };
  
  struct exynos5_sysreg {
--      unsigned char   res1[0x214];
++      unsigned int    res1[0x214 / 4];
        unsigned int    disp1blk_cfg;
        unsigned int    disp2blk_cfg;
        unsigned int    hdcp_e_fuse;
@@@ -42,6 -42,7 +42,7 @@@
        unsigned int    reserved;
        unsigned int    ispblk_cfg;
        unsigned int    usb20phy_cfg;
 -      unsigned char   res2[0x29c];
++      unsigned int    res2[0x29c / 4];
        unsigned int    mipi_dphy;
        unsigned int    dptx_dphy;
        unsigned int    phyclk_sel;
@@@ -36,18 -54,19 +54,68 @@@ enum mxc_clock 
        MXC_DDR_CLK,
        MXC_NFC_CLK,
        MXC_PERIPH_CLK,
+       MXC_I2C_CLK,
  };
  
- unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref);
++
++struct clk {
++      const char *name;
++      int id;
++      /* Source clock this clk depends on */
++      struct clk *parent;
++      /* Secondary clock to enable/disable with this clock */
++      struct clk *secondary;
++      /* Current clock rate */
++      unsigned long rate;
++      /* Reference count of clock enable/disable */
++      __s8 usecount;
++      /* Register bit position for clock's enable/disable control. */
++      u8 enable_shift;
++      /* Register address for clock's enable/disable control. */
++      void *enable_reg;
++      u32 flags;
++      /*
++       * Function ptr to recalculate the clock's rate based on parent
++       * clock's rate
++       */
++      void (*recalc) (struct clk *);
++      /*
++       * Function ptr to set the clock to a new rate. The rate must match a
++       * supported rate returned from round_rate. Leave blank if clock is not
++      * programmable
++       */
++      int (*set_rate) (struct clk *, unsigned long);
++      /*
++       * Function ptr to round the requested clock rate to the nearest
++       * supported rate that is less than or equal to the requested rate.
++       */
++      unsigned long (*round_rate) (struct clk *, unsigned long);
++      /*
++       * Function ptr to enable the clock. Leave blank if clock can not
++       * be gated.
++       */
++      int (*enable) (struct clk *);
++      /*
++       * Function ptr to disable the clock. Leave blank if clock can not
++       * be gated.
++       */
++      void (*disable) (struct clk *);
++      /* Function ptr to set the parent clock of the clock. */
++      int (*set_parent) (struct clk *, struct clk *);
++};
 +
  u32 imx_get_uartclk(void);
  u32 imx_get_fecclk(void);
  unsigned int mxc_get_clock(enum mxc_clock clk);
--int mxc_set_clock(u32 ref, u32 freq, u32 clk_type);
- void set_usb_phy2_clk(void);
++int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk);
+ void set_usb_phy_clk(void);
+ void enable_usb_phy1_clk(unsigned char enable);
  void enable_usb_phy2_clk(unsigned char enable);
  void set_usboh3_clk(void);
  void enable_usboh3_clk(unsigned char enable);
  void mxc_set_sata_internal_clock(void);
+ int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
++void ipu_clk_enable(void);
++void ipu_clk_disable(void);
  
  #endif /* __ASM_ARCH_CLOCK_H */
@@@ -178,36 -283,328 +283,328 @@@ struct mxc_ccm_reg 
  /* Define the bits in register CSCDR1 */
  #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET   22
  #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK     (0x7 << 22)
+ #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED(v)               (((v) & 0x7) << 22)
+ #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_RD(r)    (((r) >> 22) & 0x7)
  #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET   19
  #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK     (0x7 << 19)
+ #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF(v)               (((v) & 0x7) << 19)
+ #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_RD(r)    (((r) >> 19) & 0x7)
  #define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET   16
  #define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK     (0x7 << 16)
+ #define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED(v)               (((v) & 0x7) << 16)
+ #define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_RD(r)    (((r) >> 16) & 0x7)
  #define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET            14
  #define MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK              (0x3 << 14)
+ #define MXC_CCM_CSCDR1_PGC_CLK_PODF(v)                        (((v) & 0x3) << 14)
+ #define MXC_CCM_CSCDR1_PGC_CLK_PODF_RD(r)             (((r) >> 14) & 0x3)
  #define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET   11
  #define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK     (0x7 << 11)
+ #define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF(v)               (((v) & 0x7) << 11)
+ #define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_RD(r)    (((r) >> 11) & 0x7)
  #define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET         8
  #define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK           (0x7 << 8)
+ #define MXC_CCM_CSCDR1_USBOH3_CLK_PRED(v)             (((v) & 0x7) << 8)
+ #define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_RD(r)          (((r) >> 8) & 0x7)
  #define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET         6
  #define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK           (0x3 << 6)
+ #define MXC_CCM_CSCDR1_USBOH3_CLK_PODF(v)             (((v) & 0x3) << 6)
+ #define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_RD(r)          (((r) >> 6) & 0x3)
  #define MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET           3
  #define MXC_CCM_CSCDR1_UART_CLK_PRED_MASK             (0x7 << 3)
+ #define MXC_CCM_CSCDR1_UART_CLK_PRED(v)                       (((v) & 0x7) << 3)
+ #define MXC_CCM_CSCDR1_UART_CLK_PRED_RD(r)            (((r) >> 3) & 0x7)
  #define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET           0
  #define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK             0x7
+ #define MXC_CCM_CSCDR1_UART_CLK_PODF(v)                       ((v) & 0x7)
+ #define MXC_CCM_CSCDR1_UART_CLK_PODF_RD(r)            ((r) & 0x7)
  
  /* Define the bits in register CCDR */
--#define MXC_CCM_CCDR_IPU_HS_MASK                      (0x1 << 17)
++#define MXC_CCM_CCDR_IPU_HS_MASK                      (0x1 << 21)
  
  /* Define the bits in register CCGRx */
  #define MXC_CCM_CCGR_CG_MASK                          0x3
+ #define MXC_CCM_CCGR_CG_OFF                           0x0
+ #define MXC_CCM_CCGR_CG_RUN_ON                                0x1
+ #define MXC_CCM_CCGR_CG_ON                            0x3
+ #define MXC_CCM_CCGR0_ARM_BUS_OFFSET                  0
+ #define MXC_CCM_CCGR0_ARM_BUS(v)                      (((v) & 0x3) << 0)
+ #define MXC_CCM_CCGR0_ARM_AXI_OFFSET                  2
+ #define MXC_CCM_CCGR0_ARM_AXI(v)                      (((v) & 0x3) << 2)
+ #define MXC_CCM_CCGR0_ARM_DEBUG_OFFSET                        4
+ #define MXC_CCM_CCGR0_ARM_DEBUG(v)                    (((v) & 0x3) << 4)
+ #define MXC_CCM_CCGR0_TZIC_OFFSET                     6
+ #define MXC_CCM_CCGR0_TZIC(v)                         (((v) & 0x3) << 6)
+ #define MXC_CCM_CCGR0_DAP_OFFSET                      8
+ #define MXC_CCM_CCGR0_DAP(v)                          (((v) & 0x3) << 8)
+ #define MXC_CCM_CCGR0_TPIU_OFFSET                     10
+ #define MXC_CCM_CCGR0_TPIU(v)                         (((v) & 0x3) << 10)
+ #define MXC_CCM_CCGR0_CTI2_OFFSET                     12
+ #define MXC_CCM_CCGR0_CTI2(v)                         (((v) & 0x3) << 12)
+ #define MXC_CCM_CCGR0_CTI3_OFFSET                     14
+ #define MXC_CCM_CCGR0_CTI3(v)                         (((v) & 0x3) << 14)
+ #define MXC_CCM_CCGR0_AHBMUX1_OFFSET                  16
+ #define MXC_CCM_CCGR0_AHBMUX1(v)                      (((v) & 0x3) << 16)
+ #define MXC_CCM_CCGR0_AHBMUX2_OFFSET                  18
+ #define MXC_CCM_CCGR0_AHBMUX2(v)                      (((v) & 0x3) << 18)
+ #define MXC_CCM_CCGR0_ROMCP_OFFSET                    20
+ #define MXC_CCM_CCGR0_ROMCP(v)                                (((v) & 0x3) << 20)
+ #define MXC_CCM_CCGR0_ROM_OFFSET                      22
+ #define MXC_CCM_CCGR0_ROM(v)                          (((v) & 0x3) << 22)
+ #define MXC_CCM_CCGR0_AIPS_TZ1_OFFSET                 24
+ #define MXC_CCM_CCGR0_AIPS_TZ1(v)                     (((v) & 0x3) << 24)
+ #define MXC_CCM_CCGR0_AIPS_TZ2_OFFSET                 26
+ #define MXC_CCM_CCGR0_AIPS_TZ2(v)                     (((v) & 0x3) << 26)
+ #define MXC_CCM_CCGR0_AHB_MAX_OFFSET                  28
+ #define MXC_CCM_CCGR0_AHB_MAX(v)                      (((v) & 0x3) << 28)
+ #define MXC_CCM_CCGR0_IIM_OFFSET                      30
+ #define MXC_CCM_CCGR0_IIM(v)                          (((v) & 0x3) << 30)
+ #define MXC_CCM_CCGR1_TMAX1_OFFSET                    0
+ #define MXC_CCM_CCGR1_TMAX1(v)                                (((v) & 0x3) << 0)
+ #define MXC_CCM_CCGR1_TMAX2_OFFSET                    2
+ #define MXC_CCM_CCGR1_TMAX2(v)                                (((v) & 0x3) << 2)
+ #define MXC_CCM_CCGR1_TMAX3_OFFSET                    4
+ #define MXC_CCM_CCGR1_TMAX3(v)                                (((v) & 0x3) << 4)
+ #define MXC_CCM_CCGR1_UART1_IPG_OFFSET                        6
+ #define MXC_CCM_CCGR1_UART1_IPG(v)                    (((v) & 0x3) << 6)
+ #define MXC_CCM_CCGR1_UART1_PER_OFFSET                        8
+ #define MXC_CCM_CCGR1_UART1_PER(v)                    (((v) & 0x3) << 8)
+ #define MXC_CCM_CCGR1_UART2_IPG_OFFSET                        10
+ #define MXC_CCM_CCGR1_UART2_IPG(v)                    (((v) & 0x3) << 10)
+ #define MXC_CCM_CCGR1_UART2_PER_OFFSET                        12
+ #define MXC_CCM_CCGR1_UART2_PER(v)                    (((v) & 0x3) << 12)
+ #define MXC_CCM_CCGR1_UART3_IPG_OFFSET                        14
+ #define MXC_CCM_CCGR1_UART3_IPG(v)                    (((v) & 0x3) << 14)
+ #define MXC_CCM_CCGR1_UART3_PER_OFFSET                        16
+ #define MXC_CCM_CCGR1_UART3_PER(v)                    (((v) & 0x3) << 16)
+ #define MXC_CCM_CCGR1_I2C1_OFFSET                     18
+ #define MXC_CCM_CCGR1_I2C1(v)                         (((v) & 0x3) << 18)
+ #define MXC_CCM_CCGR1_I2C2_OFFSET                     20
+ #define MXC_CCM_CCGR1_I2C2(v)                         (((v) & 0x3) << 20)
+ #if defined(CONFIG_MX51)
+ #define MXC_CCM_CCGR1_HSI2C_IPG_OFFSET                        22
+ #define MXC_CCM_CCGR1_HSI2C_IPG(v)                    (((v) & 0x3) << 22)
+ #define MXC_CCM_CCGR1_HSI2C_SERIAL_OFFSET             24
+ #define MXC_CCM_CCGR1_HSI2C_SERIAL(v)                 (((v) & 0x3) << 24)
+ #elif defined(CONFIG_MX53)
+ #define MXC_CCM_CCGR1_I2C3_OFFSET                     22
+ #define MXC_CCM_CCGR1_I2C3(v)                         (((v) & 0x3) << 22)
+ #endif
+ #define MXC_CCM_CCGR1_FIRI_IPG_OFFSET                 26
+ #define MXC_CCM_CCGR1_FIRI_IPG(v)                     (((v) & 0x3) << 26)
+ #define MXC_CCM_CCGR1_FIRI_SERIAL_OFFSET              28
+ #define MXC_CCM_CCGR1_FIRI_SERIAL(v)                  (((v) & 0x3) << 28)
+ #define MXC_CCM_CCGR1_SCC_OFFSET                      30
+ #define MXC_CCM_CCGR1_SCC(v)                          (((v) & 0x3) << 30)
+ #if defined(CONFIG_MX51)
+ #define MXC_CCM_CCGR2_USB_PHY_OFFSET                  0
+ #define MXC_CCM_CCGR2_USB_PHY(v)                      (((v) & 0x3) << 0)
+ #endif
+ #define MXC_CCM_CCGR2_EPIT1_IPG_OFFSET                        2
+ #define MXC_CCM_CCGR2_EPIT1_IPG(v)                    (((v) & 0x3) << 2)
+ #define MXC_CCM_CCGR2_EPIT1_HF_OFFSET                 4
+ #define MXC_CCM_CCGR2_EPIT1_HF(v)                     (((v) & 0x3) << 4)
+ #define MXC_CCM_CCGR2_EPIT2_IPG_OFFSET                        6
+ #define MXC_CCM_CCGR2_EPIT2_IPG(v)                    (((v) & 0x3) << 6)
+ #define MXC_CCM_CCGR2_EPIT2_HF_OFFSET                 8
+ #define MXC_CCM_CCGR2_EPIT2_HF(v)                     (((v) & 0x3) << 8)
+ #define MXC_CCM_CCGR2_PWM1_IPG_OFFSET                 10
+ #define MXC_CCM_CCGR2_PWM1_IPG(v)                     (((v) & 0x3) << 10)
+ #define MXC_CCM_CCGR2_PWM1_HF_OFFSET                  12
+ #define MXC_CCM_CCGR2_PWM1_HF(v)                      (((v) & 0x3) << 12)
+ #define MXC_CCM_CCGR2_PWM2_IPG_OFFSET                 14
+ #define MXC_CCM_CCGR2_PWM2_IPG(v)                     (((v) & 0x3) << 14)
+ #define MXC_CCM_CCGR2_PWM2_HF_OFFSET                  16
+ #define MXC_CCM_CCGR2_PWM2_HF(v)                      (((v) & 0x3) << 16)
+ #define MXC_CCM_CCGR2_GPT_IPG_OFFSET                  18
+ #define MXC_CCM_CCGR2_GPT_IPG(v)                      (((v) & 0x3) << 18)
+ #define MXC_CCM_CCGR2_GPT_HF_OFFSET                   20
+ #define MXC_CCM_CCGR2_GPT_HF(v)                               (((v) & 0x3) << 20)
+ #define MXC_CCM_CCGR2_OWIRE_OFFSET                    22
+ #define MXC_CCM_CCGR2_OWIRE(v)                                (((v) & 0x3) << 22)
+ #define MXC_CCM_CCGR2_FEC_OFFSET                      24
+ #define MXC_CCM_CCGR2_FEC(v)                          (((v) & 0x3) << 24)
+ #define MXC_CCM_CCGR2_USBOH3_IPG_AHB_OFFSET           26
+ #define MXC_CCM_CCGR2_USBOH3_IPG_AHB(v)                       (((v) & 0x3) << 26)
+ #define MXC_CCM_CCGR2_USBOH3_60M_OFFSET                       28
+ #define MXC_CCM_CCGR2_USBOH3_60M(v)                   (((v) & 0x3) << 28)
+ #define MXC_CCM_CCGR2_TVE_OFFSET                      30
+ #define MXC_CCM_CCGR2_TVE(v)                          (((v) & 0x3) << 30)
  
- #define MXC_CCM_CCGR4_CG5_OFFSET                      10
- #define MXC_CCM_CCGR4_CG6_OFFSET                      12
- #define MXC_CCM_CCGR5_CG5_OFFSET                      10
- #define MXC_CCM_CCGR2_CG14_OFFSET                     28
+ #define MXC_CCM_CCGR3_ESDHC1_IPG_OFFSET                       0
+ #define MXC_CCM_CCGR3_ESDHC1_IPG(v)                   (((v) & 0x3) << 0)
+ #define MXC_CCM_CCGR3_ESDHC1_PER_OFFSET                       2
+ #define MXC_CCM_CCGR3_ESDHC1_PER(v)                   (((v) & 0x3) << 2)
+ #define MXC_CCM_CCGR3_ESDHC2_IPG_OFFSET                       4
+ #define MXC_CCM_CCGR3_ESDHC2_IPG(v)                   (((v) & 0x3) << 4)
+ #define MXC_CCM_CCGR3_ESDHC2_PER_OFFSET                       6
+ #define MXC_CCM_CCGR3_ESDHC2_PER(v)                   (((v) & 0x3) << 6)
+ #define MXC_CCM_CCGR3_ESDHC3_IPG_OFFSET                       8
+ #define MXC_CCM_CCGR3_ESDHC3_IPG(v)                   (((v) & 0x3) << 8)
+ #define MXC_CCM_CCGR3_ESDHC3_PER_OFFSET                       10
+ #define MXC_CCM_CCGR3_ESDHC3_PER(v)                   (((v) & 0x3) << 10)
+ #define MXC_CCM_CCGR3_ESDHC4_IPG_OFFSET                       12
+ #define MXC_CCM_CCGR3_ESDHC4_IPG(v)                   (((v) & 0x3) << 12)
+ #define MXC_CCM_CCGR3_ESDHC4_PER_OFFSET                       14
+ #define MXC_CCM_CCGR3_ESDHC4_PER(v)                   (((v) & 0x3) << 14)
+ #define MXC_CCM_CCGR3_SSI1_IPG_OFFSET                 16
+ #define MXC_CCM_CCGR3_SSI1_IPG(v)                     (((v) & 0x3) << 16)
+ #define MXC_CCM_CCGR3_SSI1_SSI_OFFSET                 18
+ #define MXC_CCM_CCGR3_SSI1_SSI(v)                     (((v) & 0x3) << 18)
+ #define MXC_CCM_CCGR3_SSI2_IPG_OFFSET                 20
+ #define MXC_CCM_CCGR3_SSI2_IPG(v)                     (((v) & 0x3) << 20)
+ #define MXC_CCM_CCGR3_SSI2_SSI_OFFSET                 22
+ #define MXC_CCM_CCGR3_SSI2_SSI(v)                     (((v) & 0x3) << 22)
+ #define MXC_CCM_CCGR3_SSI3_IPG_OFFSET                 24
+ #define MXC_CCM_CCGR3_SSI3_IPG(v)                     (((v) & 0x3) << 24)
+ #define MXC_CCM_CCGR3_SSI3_SSI_OFFSET                 26
+ #define MXC_CCM_CCGR3_SSI3_SSI(v)                     (((v) & 0x3) << 26)
+ #define MXC_CCM_CCGR3_SSI_EXT1_OFFSET                 28
+ #define MXC_CCM_CCGR3_SSI_EXT1(v)                     (((v) & 0x3) << 28)
+ #define MXC_CCM_CCGR3_SSI_EXT2_OFFSET                 30
+ #define MXC_CCM_CCGR3_SSI_EXT2(v)                     (((v) & 0x3) << 30)
+ #define MXC_CCM_CCGR4_PATA_OFFSET                     0
+ #define MXC_CCM_CCGR4_PATA(v)                         (((v) & 0x3) << 0)
+ #if defined(CONFIG_MX51)
+ #define MXC_CCM_CCGR4_SIM_IPG_OFFSET                  2
+ #define MXC_CCM_CCGR4_SIM_IPG(v)                      (((v) & 0x3) << 2)
+ #define MXC_CCM_CCGR4_SIM_SERIAL_OFFSET                       4
+ #define MXC_CCM_CCGR4_SIM_SERIAL(v)                   (((v) & 0x3) << 4)
+ #elif defined(CONFIG_MX53)
+ #define MXC_CCM_CCGR4_SATA_OFFSET                     2
+ #define MXC_CCM_CCGR4_SATA(v)                         (((v) & 0x3) << 2)
+ #define MXC_CCM_CCGR4_CAN2_IPG_OFFSET                 6
+ #define MXC_CCM_CCGR4_CAN2_IPG(v)                     (((v) & 0x3) << 6)
+ #define MXC_CCM_CCGR4_CAN2_SERIAL_OFFSET              8
+ #define MXC_CCM_CCGR4_CAN2_SERIAL(v)                  (((v) & 0x3) << 8)
+ #define MXC_CCM_CCGR4_USB_PHY1_OFFSET                 10
+ #define MXC_CCM_CCGR4_USB_PHY1(v)                     (((v) & 0x3) << 10)
+ #define MXC_CCM_CCGR4_USB_PHY2_OFFSET                 12
+ #define MXC_CCM_CCGR4_USB_PHY2(v)                     (((v) & 0x3) << 12)
+ #endif
+ #define MXC_CCM_CCGR4_SAHARA_OFFSET                   14
+ #define MXC_CCM_CCGR4_SAHARA(v)                               (((v) & 0x3) << 14)
+ #define MXC_CCM_CCGR4_RTIC_OFFSET                     16
+ #define MXC_CCM_CCGR4_RTIC(v)                         (((v) & 0x3) << 16)
+ #define MXC_CCM_CCGR4_ECSPI1_IPG_OFFSET                       18
+ #define MXC_CCM_CCGR4_ECSPI1_IPG(v)                   (((v) & 0x3) << 18)
+ #define MXC_CCM_CCGR4_ECSPI1_PER_OFFSET                       20
+ #define MXC_CCM_CCGR4_ECSPI1_PER(v)                   (((v) & 0x3) << 20)
+ #define MXC_CCM_CCGR4_ECSPI2_IPG_OFFSET                       22
+ #define MXC_CCM_CCGR4_ECSPI2_IPG(v)                   (((v) & 0x3) << 22)
+ #define MXC_CCM_CCGR4_ECSPI2_PER_OFFSET                       24
+ #define MXC_CCM_CCGR4_ECSPI2_PER(v)                   (((v) & 0x3) << 24)
+ #define MXC_CCM_CCGR4_CSPI_IPG_OFFSET                 26
+ #define MXC_CCM_CCGR4_CSPI_IPG(v)                     (((v) & 0x3) << 26)
+ #define MXC_CCM_CCGR4_SRTC_OFFSET      &nb