Bläddra i källkod

Merge branch 'master' of git://git.denx.de/u-boot-arm

* 'master' of git://git.denx.de/u-boot-arm: (167 commits)
  OMAP4/5: Change omap4_sdp, omap4_panda, omap5_evm maintainer
  ARM: omap3: Add CONFIG_SPL_BOARD_INIT for CONFIG_SPL_MMC_SUPPORT
  ARM: omap3: Set SPL stack size to 8KB, image to 54KB.
  arm, omap3: fix warm reset serial output on OMAP36xx/AM/DM37xx
  OMAP4: Set fdt_high for OMAP4 devices to enable booting with Device Tree
  omap4: do not enable auxiliary cores
  omap4: do not enable fs-usb module
  omap4: panda: disable uart2 pads during boot
  igep00x0: change mpurate from 500 to auto
  igep00x0: enable the use of a plain text file
  tegra2: trivially enable 13 mhz crystal frequency
  tegra: Enable keyboard for Seaboard
  tegra: Switch on console mux and use environment for console
  tegra: Add tegra keyboard driver
  tegra: fdt: Add keyboard definitions for Seaboard
  tegra: fdt: Add keyboard controller definition
  tegra: Add keyboard support to funcmux
  input: Add support for keyboard matrix decoding from an fdt
  input: Add generic keyboard input handler
  input: Add linux/input.h for key code support
  fdt: Add fdtdec functions to read byte array
  tegra: Enable LP0 on Seaboard
  tegra: fdt: Add EMC data for Tegra2 Seaboard
  tegra: i2c: Add function to find DVC bus
  fdt: tegra: Add EMC node to device tree
  tegra: Add EMC settings for Seaboard
  tegra: Turn off power detect in board init
  tegra: Set up warmboot code on Nvidia boards
  tegra: Setup PMC scratch info from ap20 setup
  tegra: Add warmboot implementation
  tegra: Set up PMU for Nvidia boards
  tegra: Add PMU to manage power supplies
  tegra: Add EMC support for optimal memory timings
  tegra: Add header file for APB_MISC register
  tegra: Add tegra_get_chip_type() to detect SKU
  tegra: Add flow, gp_padctl, fuse, sdram headers
  tegra: Add crypto library for warmboot code
  tegra: Add functions to access low-level Osc/PLL details
  tegra: Move ap20.h header into arch location
  Add AES crypto library
  i2c: Add TPS6586X driver
  Add abs() macro to return absolute value
  fdt: Add function to return next compatible subnode
  fdt: Add function to locate an array in the device tree
  i.MX28: Avoid redefining serial_put[cs]()
  i.MX28: Check if WP detection is implemented at all
  i.MX28: Add battery boot components to SPL
  i.MX28: Reorder battery status functions in SPL
  i.MX28: Add LRADC init to i.MX28 SPL
  i.MX28: Add LRADC register definitions
  i.MX28: Shut down the LCD controller before reset
  i.MX28: Add LCDIF register definitions
  i.MX28: Implement boot pads sampling and reporting
  i.MX28: Improve passing of data from SPL to U-Boot
  M28EVK: Add SD update command
  M28EVK: Implement support for new board V2.0
  FEC: Abstract out register setup
  MX5: PAD_CTL_DRV_VOT_LOW and PAD_CTL_DRV_VOT_HIGH exchanged
  i.MX28: Add delay after CPU bypass is cleared
  spi: mxs: Allow other chip selects to work
  spi: mxs: Introduce spi_cs_is_valid()
  mx53loco: Remove unneeded gpio_set_value()
  mx53loco: Add CONFIG_REVISION_TAG
  mx53loco: Turn on VUSB regulator
  mx53loco: Add mc34708 support and set mx53 frequency at 1GHz
  pmic: dialog: Avoid name conflicts
  imx: Add u-boot.imx as target for ARM9 i.MX SOCs
  i.MX2: Include asm/types.h in arch-mx25/imx-regs.h
  imx: usb: There is no such register
  i.MX25: usb: Set PORTSCx register
  imx: nand: Support flash based BBT
  i.MX25: This architecture has a GPIO4 too
  i.MX25: esdhc: Add mxc_get_clock infrastructure
  i.MX6: mx6q_sabrelite: add SATA bindings
  i.MX6: add enable_sata_clock()
  i.MX6: Add ANATOP regulator init
  mx28evk: add NAND support
  USB: ehci-mx6: Fix broken IO access
  M28: Scan only first 512 MB of DRAM to avoid memory wraparound
  Revert "i.MX28: Enable additional DRAM address bits"
  M28: Enable FDT support
  mx53loco: Add support for 1GHz operation for DA9053-based boards
  mx53loco: Allow to print CPU information at a later stage
  mx5: Add clock config interface
  imx-common: Factor out get_ahb_clk()
  i.MX6Q: mx6qsabrelite: Add keypress support to alter boot flow
  mx31pdk: Allow booting a zImage kernel
  mx6qarm2: Allow booting a zImage kernel
  mx6qsabrelite: Allow booting a zImage kernel
  mx28evk: Allow booting a zImage kernel
  m28evk: Allow to booting a dt kernel
  mx28evk: Allow to booting a dt kernel
  mx6qsabrelite: No need to set the direction for GPIO3_23 again
  pmic: Add support for the Dialog DA9053 PMIC
  MX53: mx53loco: Add SATA support
  MX53: Add support to ESG ima3 board
  SATA: add driver for MX5 / MX6 SOCs
  MX53: add function to set SATA clock to internal
  SATA: check for return value from sata functions
  MX5: Add definitions for SATA controller
  NET: fec_mxc.c: Add a way to disable auto negotiation
  Define UART4 and UART5 base addresses
  EXYNOS: Change bits per pixel value proper for u-boot.
  EXYNOS: support TRATS board display function
  LCD: support S6E8AX0 amoled driver based on EXYNOS MIPI DSI
  EXYNOS: support EXYNOS MIPI DSI interface driver.
  EXYNOS: support EXYNOS framebuffer and FIMD display drivers.
  LCD: add data structure for EXYNOS display driver
  EXYNOS: add LCD and MIPI DSI clock interface.
  EXYNOS: definitions of system resgister and power management registers.
  SMDK5250: fix compiler warning
  misc:pmic:samsung Convert TRATS target to use MAX8997 instead of MAX8998
  misc:pmic:max8997 MAX8997 support for PMIC driver
  TRATS: modify the trats's configuration
  ARM: Exynos4: ADC: Universal_C210: Enable LDO4 power line for ADC measurement
  EXYNOS: Rename exynos5_tzpc structure to exynos_tzpc
  arm: ea20: Change macro from BOARD_LATE_INIT to CONFIG_BOARD_LATE_INIT
  arm: cam_enc_4xx: Change macro from BOARD_LATE_INIT to CONFIG_BOARD_LATE_INIT
  cm-t35: add I2C multi-bus support
  include/configs: Remove CONFIG_SYS_64BIT_STRTOUL
  include/configs: Remove CONFIG_SYS_64BIT_VSPRINTF
  omap3: Introduce weak misc_init_r
  omap730p2: Remove empty misc_init_r
  omap5912osk: Remove empty misc_init_r
  omap4+: Remove CONFIG_ARCH_CPU_INIT
  omap4: Remove CONFIG_SYS_MMC_SET_DEV
  OMAP3: pandora: drop console kernel argument
  OMAP3: pandora: revise GPIO configuration
  ...
Wolfgang Denk 13 år sedan
förälder
incheckning
ee3a55fdf0
100 ändrade filer med 6318 tillägg och 418 borttagningar
  1. 18 6
      MAINTAINERS
  2. 7 0
      Makefile
  3. 8 0
      README
  4. 20 7
      arch/arm/config.mk
  5. 6 0
      arch/arm/cpu/arm926ejs/config.mk
  6. 45 0
      arch/arm/cpu/arm926ejs/lpc32xx/Makefile
  7. 117 0
      arch/arm/cpu/arm926ejs/lpc32xx/clk.c
  8. 70 0
      arch/arm/cpu/arm926ejs/lpc32xx/cpu.c
  9. 52 0
      arch/arm/cpu/arm926ejs/lpc32xx/devices.c
  10. 95 0
      arch/arm/cpu/arm926ejs/lpc32xx/timer.c
  11. 27 0
      arch/arm/cpu/arm926ejs/mx25/generic.c
  12. 1 1
      arch/arm/cpu/arm926ejs/mx28/Makefile
  13. 17 12
      arch/arm/cpu/arm926ejs/mx28/mx28.c
  14. 4 0
      arch/arm/cpu/arm926ejs/mx28/mx28_init.h
  15. 57 0
      arch/arm/cpu/arm926ejs/mx28/spl_boot.c
  16. 86 0
      arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c
  17. 6 8
      arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c
  18. 155 69
      arch/arm/cpu/arm926ejs/mx28/spl_power_init.c
  19. 1 1
      arch/arm/cpu/armv7/am33xx/board.c
  20. 5 2
      arch/arm/cpu/armv7/config.mk
  21. 1 1
      arch/arm/cpu/armv7/exynos/Makefile
  22. 184 0
      arch/arm/cpu/armv7/exynos/clock.c
  23. 54 0
      arch/arm/cpu/armv7/exynos/power.c
  24. 48 0
      arch/arm/cpu/armv7/exynos/system.c
  25. 14 1
      arch/arm/cpu/armv7/imx-common/cpu.c
  26. 472 21
      arch/arm/cpu/armv7/mx5/clock.c
  27. 3 2
      arch/arm/cpu/armv7/mx5/lowlevel_init.S
  28. 35 15
      arch/arm/cpu/armv7/mx6/clock.c
  29. 3 2
      arch/arm/cpu/armv7/mx6/lowlevel_init.S
  30. 30 0
      arch/arm/cpu/armv7/mx6/soc.c
  31. 1 0
      arch/arm/cpu/armv7/omap-common/Makefile
  32. 42 57
      arch/arm/cpu/armv7/omap-common/clocks-common.c
  33. 39 2
      arch/arm/cpu/armv7/omap-common/emif-common.c
  34. 5 11
      arch/arm/cpu/armv7/omap-common/hwinit-common.c
  35. 7 7
      arch/arm/cpu/armv7/omap-common/lowlevel_init.S
  36. 14 16
      arch/arm/cpu/armv7/omap-common/reset.c
  37. 1 0
      arch/arm/cpu/armv7/omap-common/spl.c
  38. 3 2
      arch/arm/cpu/armv7/omap-common/spl_mmc.c
  39. 138 0
      arch/arm/cpu/armv7/omap-common/vc.c
  40. 12 0
      arch/arm/cpu/armv7/omap3/board.c
  41. 16 0
      arch/arm/cpu/armv7/omap3/clock.c
  42. 21 20
      arch/arm/cpu/armv7/omap3/lowlevel_init.S
  43. 50 35
      arch/arm/cpu/armv7/omap4/clocks.c
  44. 12 12
      arch/arm/cpu/armv7/omap4/hwinit.c
  45. 4 0
      arch/arm/cpu/armv7/omap4/sdram_elpida.c
  46. 1 1
      arch/arm/cpu/armv7/omap5/Makefile
  47. 97 46
      arch/arm/cpu/armv7/omap5/clocks.c
  48. 101 3
      arch/arm/cpu/armv7/omap5/hwinit.c
  49. 72 29
      arch/arm/cpu/armv7/omap5/sdram.c
  50. 6 4
      arch/arm/cpu/armv7/s5pc1xx/cache.S
  51. 3 2
      arch/arm/cpu/armv7/s5pc1xx/reset.S
  52. 7 6
      arch/arm/cpu/armv7/start.S
  53. 4 0
      arch/arm/cpu/armv7/tegra2/Makefile
  54. 43 1
      arch/arm/cpu/armv7/tegra2/ap20.c
  55. 2 2
      arch/arm/cpu/armv7/tegra2/board.c
  56. 36 1
      arch/arm/cpu/armv7/tegra2/clock.c
  57. 230 0
      arch/arm/cpu/armv7/tegra2/crypto.c
  58. 36 0
      arch/arm/cpu/armv7/tegra2/crypto.h
  59. 286 0
      arch/arm/cpu/armv7/tegra2/emc.c
  60. 16 0
      arch/arm/cpu/armv7/tegra2/funcmux.c
  61. 3 2
      arch/arm/cpu/armv7/tegra2/lowlevel_init.S
  62. 70 0
      arch/arm/cpu/armv7/tegra2/pmu.c
  63. 386 0
      arch/arm/cpu/armv7/tegra2/warmboot.c
  64. 250 0
      arch/arm/cpu/armv7/tegra2/warmboot_avp.c
  65. 81 0
      arch/arm/cpu/armv7/tegra2/warmboot_avp.h
  66. 5 4
      arch/arm/cpu/armv7/u8500/lowlevel.S
  67. 11 0
      arch/arm/dts/tegra20.dtsi
  68. 1 1
      arch/arm/include/asm/arch-am33xx/mmc_host_def.h
  69. 3 0
      arch/arm/include/asm/arch-exynos/clk.h
  70. 5 0
      arch/arm/include/asm/arch-exynos/cpu.h
  71. 181 0
      arch/arm/include/asm/arch-exynos/dsim.h
  72. 446 0
      arch/arm/include/asm/arch-exynos/fb.h
  73. 380 0
      arch/arm/include/asm/arch-exynos/mipi_dsim.h
  74. 6 0
      arch/arm/include/asm/arch-exynos/power.h
  75. 53 0
      arch/arm/include/asm/arch-exynos/system.h
  76. 1 1
      arch/arm/include/asm/arch-exynos/tzpc.h
  77. 170 0
      arch/arm/include/asm/arch-lpc32xx/clk.h
  78. 76 0
      arch/arm/include/asm/arch-lpc32xx/config.h
  79. 64 0
      arch/arm/include/asm/arch-lpc32xx/cpu.h
  80. 92 0
      arch/arm/include/asm/arch-lpc32xx/emc.h
  81. 25 0
      arch/arm/include/asm/arch-lpc32xx/sys_proto.h
  82. 74 0
      arch/arm/include/asm/arch-lpc32xx/timer.h
  83. 114 0
      arch/arm/include/asm/arch-lpc32xx/uart.h
  84. 51 0
      arch/arm/include/asm/arch-lpc32xx/wdt.h
  85. 23 0
      arch/arm/include/asm/arch-mx25/clock.h
  86. 3 0
      arch/arm/include/asm/arch-mx25/imx-regs.h
  87. 2 0
      arch/arm/include/asm/arch-mx28/imx-regs.h
  88. 212 0
      arch/arm/include/asm/arch-mx28/regs-lcdif.h
  89. 400 0
      arch/arm/include/asm/arch-mx28/regs-lradc.h
  90. 30 0
      arch/arm/include/asm/arch-mx28/sys_proto.h
  91. 6 1
      arch/arm/include/asm/arch-mx5/clock.h
  92. 6 0
      arch/arm/include/asm/arch-mx5/crm_regs.h
  93. 11 0
      arch/arm/include/asm/arch-mx5/imx-regs.h
  94. 2 2
      arch/arm/include/asm/arch-mx5/iomux.h
  95. 3 0
      arch/arm/include/asm/arch-mx5/sys_proto.h
  96. 1 0
      arch/arm/include/asm/arch-mx6/clock.h
  97. 1 1
      arch/arm/include/asm/arch-mx6/crm_regs.h
  98. 9 0
      arch/arm/include/asm/arch-mx6/imx-regs.h
  99. 111 0
      arch/arm/include/asm/arch-mx6/iomux-v3.h
  100. 4 1
      arch/arm/include/asm/arch-mx6/sys_proto.h

+ 18 - 6
MAINTAINERS

@@ -777,6 +777,10 @@ Linus Walleij <linus.walleij@linaro.org>
 	integratorap	various
 	integratorcp	various
 
+Luka Perkov <uboot@lukaperkov.net>
+
+	ib62x0		ARM926EJS
+
 Dave Peverley <dpeverley@mpc-data.co.uk>
 
 	omap730p2	ARM926EJS
@@ -788,6 +792,16 @@ Stelian Pop <stelian@popies.net>
 	at91sam9263ek	ARM926EJS (AT91SAM9263 SoC)
 	at91sam9rlek	ARM926EJS (AT91SAM9RL SoC)
 
+Dave Purdy <david.c.purdy@gmail.com>
+
+	pogo_e02	ARM926EJS (Kirkwood SoC)
+
+Sricharan R <r.sricharan@ti.com>
+
+	omap4_panda	ARM ARMV7 (OMAP4xx SoC)
+	omap4_sdp4430	ARM ARMV7 (OMAP4xx SoC)
+	omap5_evm	ARM ARMV7 (OMAP5xx Soc)
+
 Thierry Reding <thierry.reding@avionic-design.de>
 
 	plutux		Tegra2 (ARM7 & A9 Dual Core)
@@ -860,12 +874,6 @@ Greg Ungerer <greg.ungerer@opengear.com>
 	cm4116		ks8695p
 	cm4148		ks8695p
 
-Aneesh V <aneesh@ti.com>
-
-	omap4_panda	ARM ARMV7 (OMAP4xx SoC)
-	omap4_sdp4430	ARM ARMV7 (OMAP4xx SoC)
-	omap5_evm	ARM ARMV7 (OMAP5xx Soc)
-
 Marek Vasut <marek.vasut@gmail.com>
 
 	balloon3	xscale/pxa
@@ -932,6 +940,10 @@ Sughosh Ganu <urwithsughosh@gmail.com>
 
 	hawkboard	ARM926EJS (OMAP-L138)
 
+Vladimir Zapolskiy <vz@mleia.com>
+
+	devkit3250	lpc32xx
+
 -------------------------------------------------------------------------
 
 Unknown / orphaned boards:

+ 7 - 0
Makefile

@@ -556,6 +556,13 @@ SYSTEM_MAP = \
 $(obj)System.map:	$(obj)u-boot
 		@$(call SYSTEM_MAP,$<) > $(obj)System.map
 
+checkthumb:
+	@if test $(call cc-version) -lt 0404; then \
+		echo -n '*** Your GCC does not produce working '; \
+		echo 'binaries in THUMB mode.'; \
+		echo '*** Your board is configured for THUMB mode.'; \
+		false; \
+	fi
 #
 # Auto-generate the autoconf.mk file (which is included by all makefiles)
 #

+ 8 - 0
README

@@ -432,6 +432,14 @@ The following options need to be configured:
 		Select high exception vectors of the ARM core, e.g., do not
 		clear the V bit of the c1 register of CP15.
 
+		CONFIG_SYS_THUMB_BUILD
+
+		Use this flag to build U-Boot using the Thumb instruction
+		set for ARM architectures. Thumb instruction set provides
+		better code density. For ARM architectures that support
+		Thumb2 this flag will result in Thumb2 code generated by
+		GCC.
+
 - Linux Kernel Interface:
 		CONFIG_CLOCKS_IN_MHZ
 

+ 20 - 7
arch/arm/config.mk

@@ -33,25 +33,38 @@ endif
 
 PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
 
-# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
-PF_CPPFLAGS_ARM := $(call cc-option,-marm,)
+# Choose between ARM/Thumb instruction sets
+ifeq ($(CONFIG_SYS_THUMB_BUILD),y)
+PF_CPPFLAGS_ARM := $(call cc-option, -mthumb -mthumb-interwork,\
+			$(call cc-option,-marm,)\
+			$(call cc-option,-mno-thumb-interwork,)\
+		)
+else
+PF_CPPFLAGS_ARM := $(call cc-option,-marm,) \
+		$(call cc-option,-mno-thumb-interwork,)
+endif
+
+# Only test once
+ifneq ($(CONFIG_SPL_BUILD),y)
+ALL-$(CONFIG_SYS_THUMB_BUILD)	+= checkthumb
+endif
 
 # Try if EABI is supported, else fall back to old API,
 # i. e. for example:
 # - with ELDK 4.2 (EABI supported), use:
-#	-mabi=aapcs-linux -mno-thumb-interwork
+#	-mabi=aapcs-linux
 # - with ELDK 4.1 (gcc 4.x, no EABI), use:
-#	-mabi=apcs-gnu -mno-thumb-interwork
+#	-mabi=apcs-gnu
 # - with ELDK 3.1 (gcc 3.x), use:
-#	-mapcs-32 -mno-thumb-interwork
+#	-mapcs-32
 PF_CPPFLAGS_ABI := $(call cc-option,\
-			-mabi=aapcs-linux -mno-thumb-interwork,\
+			-mabi=aapcs-linux,\
 			$(call cc-option,\
 				-mapcs-32,\
 				$(call cc-option,\
 					-mabi=apcs-gnu,\
 				)\
-			) $(call cc-option,-mno-thumb-interwork,)\
+			)\
 		)
 PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARM) $(PF_CPPFLAGS_ABI)
 

+ 6 - 0
arch/arm/cpu/arm926ejs/config.mk

@@ -31,3 +31,9 @@ PLATFORM_CPPFLAGS += -march=armv5te
 # =========================================================================
 PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
 PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
+
+ifneq ($(CONFIG_IMX_CONFIG),)
+
+ALL-y	+= $(obj)u-boot.imx
+
+endif

+ 45 - 0
arch/arm/cpu/arm926ejs/lpc32xx/Makefile

@@ -0,0 +1,45 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB     = $(obj)lib$(SOC).o
+
+COBJS   = cpu.o clk.o devices.o timer.o
+
+SRCS    := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS    := $(addprefix $(obj),$(COBJS) $(SOBJS))
+
+all:    $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 117 - 0
arch/arm/cpu/arm926ejs/lpc32xx/clk.c

@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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 <div64.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clk.h>
+#include <asm/io.h>
+
+static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE;
+
+unsigned int get_sys_clk_rate(void)
+{
+	if (readl(&clk->sysclk_ctrl) & CLK_SYSCLK_PLL397)
+		return RTC_CLK_FREQUENCY * 397;
+	else
+		return OSC_CLK_FREQUENCY;
+}
+
+unsigned int get_hclk_pll_rate(void)
+{
+	unsigned long long fin, fref, fcco, fout;
+	u32 val, m_div, n_div, p_div;
+
+	/*
+	 * Valid frequency ranges:
+	 *     1 * 10^6 <=  Fin <=  20 * 10^6
+	 *     1 * 10^6 <= Fref <=  27 * 10^6
+	 *   156 * 10^6 <= Fcco <= 320 * 10^6
+	 */
+
+	fref = fin = get_sys_clk_rate();
+	if (fin > 20000000ULL || fin < 1000000ULL)
+		return 0;
+
+	val = readl(&clk->hclkpll_ctrl);
+	m_div = ((val & CLK_HCLK_PLL_FEEDBACK_DIV_MASK) >> 1) + 1;
+	n_div = ((val & CLK_HCLK_PLL_PREDIV_MASK) >> 9) + 1;
+	if (val & CLK_HCLK_PLL_DIRECT)
+		p_div = 0;
+	else
+		p_div = ((val & CLK_HCLK_PLL_POSTDIV_MASK) >> 11) + 1;
+	p_div = 1 << p_div;
+
+	if (val & CLK_HCLK_PLL_BYPASS) {
+		do_div(fin, p_div);
+		return fin;
+	}
+
+	do_div(fref, n_div);
+	if (fref > 27000000ULL || fref < 1000000ULL)
+		return 0;
+
+	fout = fref * m_div;
+	if (val & CLK_HCLK_PLL_FEEDBACK) {
+		fcco = fout;
+		do_div(fout, p_div);
+	} else
+		fcco = fout * p_div;
+
+	if (fcco > 320000000ULL || fcco < 156000000ULL)
+		return 0;
+
+	return fout;
+}
+
+unsigned int get_hclk_clk_div(void)
+{
+	u32 val;
+
+	val = readl(&clk->hclkdiv_ctrl) & CLK_HCLK_ARM_PLL_DIV_MASK;
+
+	return 1 << val;
+}
+
+unsigned int get_hclk_clk_rate(void)
+{
+	return get_hclk_pll_rate() / get_hclk_clk_div();
+}
+
+unsigned int get_periph_clk_div(void)
+{
+	u32 val;
+
+	val = readl(&clk->hclkdiv_ctrl) & CLK_HCLK_PERIPH_DIV_MASK;
+
+	return (val >> 2) + 1;
+}
+
+unsigned int get_periph_clk_rate(void)
+{
+	if (!(readl(&clk->pwr_ctrl) & CLK_PWR_NORMAL_RUN))
+		return get_sys_clk_rate();
+
+	return get_hclk_pll_rate() / get_periph_clk_div();
+}
+
+int get_serial_clock(void)
+{
+	return get_periph_clk_rate();
+}

+ 70 - 0
arch/arm/cpu/arm926ejs/lpc32xx/cpu.c

@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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/arch/cpu.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/wdt.h>
+#include <asm/io.h>
+
+static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE;
+static struct wdt_regs  *wdt = (struct wdt_regs *)WDT_BASE;
+
+void reset_cpu(ulong addr)
+{
+	/* Enable watchdog clock */
+	setbits_le32(&clk->timclk_ctrl, CLK_TIMCLK_WATCHDOG);
+
+	/* Reset pulse length is 13005 peripheral clock frames */
+	writel(13000, &wdt->pulse);
+
+	/* Force WDOG_RESET2 and RESOUT_N signal active */
+	writel(WDTIM_MCTRL_RESFRC2 | WDTIM_MCTRL_RESFRC1 | WDTIM_MCTRL_M_RES2,
+	       &wdt->mctrl);
+
+	while (1)
+		/* NOP */;
+}
+
+#if defined(CONFIG_ARCH_CPU_INIT)
+int arch_cpu_init(void)
+{
+	/*
+	 * It might be necessary to flush data cache, if U-boot is loaded
+	 * from kickstart bootloader, e.g. from S1L loader
+	 */
+	flush_dcache_all();
+
+	return 0;
+}
+#else
+#error "You have to select CONFIG_ARCH_CPU_INIT"
+#endif
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+	printf("CPU:   NXP LPC32XX\n");
+	printf("CPU clock:        %uMHz\n", get_hclk_pll_rate() / 1000000);
+	printf("AHB bus clock:    %uMHz\n", get_hclk_clk_rate() / 1000000);
+	printf("Peripheral clock: %uMHz\n", get_periph_clk_rate() / 1000000);
+
+	return 0;
+}
+#endif

+ 52 - 0
arch/arm/cpu/arm926ejs/lpc32xx/devices.c

@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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/arch/cpu.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/uart.h>
+#include <asm/io.h>
+
+static struct clk_pm_regs    *clk  = (struct clk_pm_regs *)CLK_PM_BASE;
+static struct uart_ctrl_regs *ctrl = (struct uart_ctrl_regs *)UART_CTRL_BASE;
+
+void lpc32xx_uart_init(unsigned int uart_id)
+{
+	if (uart_id < 1 || uart_id > 7)
+		return;
+
+	/* Disable loopback mode, if it is set by S1L bootloader */
+	clrbits_le32(&ctrl->loop,
+		     UART_LOOPBACK(CONFIG_SYS_LPC32XX_UART));
+
+	if (uart_id < 3 || uart_id > 6)
+		return;
+
+	/* Enable UART system clock */
+	setbits_le32(&clk->uartclk_ctrl, CLK_UART(uart_id));
+
+	/* Set UART into autoclock mode */
+	clrsetbits_le32(&ctrl->clkmode,
+			UART_CLKMODE_MASK(uart_id),
+			UART_CLKMODE_AUTO(uart_id));
+
+	/* Bypass pre-divider of UART clock */
+	writel(CLK_UART_X_DIV(1) | CLK_UART_Y_DIV(1),
+	       &clk->u3clk + (uart_id - 3));
+}

+ 95 - 0
arch/arm/cpu/arm926ejs/lpc32xx/timer.c

@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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/arch/cpu.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/timer.h>
+#include <asm/io.h>
+
+static struct timer_regs  *timer0 = (struct timer_regs *)TIMER0_BASE;
+static struct timer_regs  *timer1 = (struct timer_regs *)TIMER1_BASE;
+static struct clk_pm_regs *clk    = (struct clk_pm_regs *)CLK_PM_BASE;
+
+static void lpc32xx_timer_clock(u32 bit, int enable)
+{
+	if (enable)
+		setbits_le32(&clk->timclk_ctrl1, bit);
+	else
+		clrbits_le32(&clk->timclk_ctrl1, bit);
+}
+
+static void lpc32xx_timer_reset(struct timer_regs *timer, u32 freq)
+{
+	writel(TIMER_TCR_COUNTER_RESET,   &timer->tcr);
+	writel(TIMER_TCR_COUNTER_DISABLE, &timer->tcr);
+	writel(0, &timer->tc);
+	writel(0, &timer->pr);
+
+	/* Count mode is every rising PCLK edge */
+	writel(TIMER_CTCR_MODE_TIMER, &timer->ctcr);
+
+	/* Set prescale counter value */
+	writel((get_periph_clk_rate() / freq) - 1, &timer->pr);
+}
+
+static void lpc32xx_timer_count(struct timer_regs *timer, int enable)
+{
+	if (enable)
+		writel(TIMER_TCR_COUNTER_ENABLE,  &timer->tcr);
+	else
+		writel(TIMER_TCR_COUNTER_DISABLE, &timer->tcr);
+}
+
+int timer_init(void)
+{
+	lpc32xx_timer_clock(CLK_TIMCLK_TIMER0, 1);
+	lpc32xx_timer_reset(timer0, CONFIG_SYS_HZ);
+	lpc32xx_timer_count(timer0, 1);
+
+	return 0;
+}
+
+ulong get_timer(ulong base)
+{
+	return readl(&timer0->tc) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+	lpc32xx_timer_clock(CLK_TIMCLK_TIMER1, 1);
+	lpc32xx_timer_reset(timer1, CONFIG_SYS_HZ * 1000);
+	lpc32xx_timer_count(timer1, 1);
+
+	while (readl(&timer1->tc) < usec)
+		/* NOP */;
+
+	lpc32xx_timer_count(timer1, 0);
+	lpc32xx_timer_clock(CLK_TIMCLK_TIMER1, 0);
+}
+
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+ulong get_tbclk(void)
+{
+	return CONFIG_SYS_HZ;
+}

+ 27 - 0
arch/arm/cpu/arm926ejs/mx25/generic.c

@@ -28,10 +28,15 @@
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/imx25-pinmux.h>
+#include <asm/arch/clock.h>
 #ifdef CONFIG_MXC_MMC
 #include <asm/arch/mxcmmc.h>
 #endif
 
+#ifdef CONFIG_FSL_ESDHC
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
 /*
  *  get the system pll clock in Hz
  *
@@ -105,6 +110,20 @@ ulong imx_get_perclk(int clk)
 	return lldiv(fref, div);
 }
 
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+	if (clk >= MXC_CLK_NUM)
+		return -1;
+	switch (clk) {
+	case MXC_ARM_CLK:
+		return imx_get_armclk();
+	case MXC_FEC_CLK:
+		return imx_get_ahbclk();
+	default:
+		return imx_get_perclk(clk);
+	}
+}
+
 u32 get_cpu_rev(void)
 {
 	u32 srev;
@@ -182,6 +201,14 @@ int cpu_eth_init(bd_t *bis)
 #endif
 }
 
+int get_clocks(void)
+{
+#ifdef CONFIG_FSL_ESDHC
+	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+#endif
+	return 0;
+}
+
 /*
  * Initializes on-chip MMC controllers.
  * to override, implement board_mmc_init()

+ 1 - 1
arch/arm/cpu/arm926ejs/mx28/Makefile

@@ -28,7 +28,7 @@ LIB	= $(obj)lib$(SOC).o
 COBJS	= clock.o mx28.o iomux.o timer.o
 
 ifdef	CONFIG_SPL_BUILD
-COBJS	+= spl_boot.o spl_mem_init.o spl_power_init.o
+COBJS	+= spl_boot.o spl_lradc_init.o spl_mem_init.o spl_power_init.o
 endif
 
 SRCS	:= $(START:.o=.S) $(COBJS:.o=.c)

+ 17 - 12
arch/arm/cpu/arm926ejs/mx28/mx28.c

@@ -51,9 +51,16 @@ void reset_cpu(ulong ignored) __attribute__((noreturn));
 
 void reset_cpu(ulong ignored)
 {
-
 	struct mx28_rtc_regs *rtc_regs =
 		(struct mx28_rtc_regs *)MXS_RTC_BASE;
+	struct mx28_lcdif_regs *lcdif_regs =
+		(struct mx28_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);
@@ -185,8 +192,12 @@ int arch_cpu_init(void)
 #if defined(CONFIG_DISPLAY_CPUINFO)
 int print_cpuinfo(void)
 {
+	struct mx28_spl_data *data = (struct mx28_spl_data *)
+		((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
+
 	printf("Freescale i.MX28 family at %d MHz\n",
 			mxc_get_clock(MXC_ARM_CLK) / 1000000);
+	printf("BOOT:  %s\n", mx28_boot_modes[data->boot_mode_idx].mode);
 	return 0;
 }
 #endif
@@ -279,22 +290,16 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 
 int mx28_dram_init(void)
 {
-	struct mx28_digctl_regs *digctl_regs =
-		(struct mx28_digctl_regs *)MXS_DIGCTL_BASE;
-	uint32_t sz[2];
-
-	sz[0] = readl(&digctl_regs->hw_digctl_scratch0);
-	sz[1] = readl(&digctl_regs->hw_digctl_scratch1);
+	struct mx28_spl_data *data = (struct mx28_spl_data *)
+		((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
 
-	if (sz[0] != sz[1]) {
+	if (data->mem_dram_size == 0) {
 		printf("MX28:\n"
-			"Error, the RAM size in HW_DIGCTRL_SCRATCH0 and\n"
-			"HW_DIGCTRL_SCRATCH1 is not the same. Please\n"
-			"verify these two registers contain valid RAM size!\n");
+			"Error, the RAM size passed up from SPL is 0!\n");
 		hang();
 	}
 
-	gd->ram_size = sz[0];
+	gd->ram_size = data->mem_dram_size;
 	return 0;
 }
 

+ 4 - 0
arch/arm/cpu/arm926ejs/mx28/mx28_init.h

@@ -37,5 +37,9 @@ static inline void mx28_power_wait_pswitch(void) { }
 #endif
 
 void mx28_mem_init(void);
+uint32_t mx28_mem_get_size(void);
+
+void mx28_lradc_init(void);
+void mx28_lradc_enable_batt_measurement(void);
 
 #endif	/* __M28_INIT_H__ */

+ 57 - 0
arch/arm/cpu/arm926ejs/mx28/spl_boot.c

@@ -28,6 +28,8 @@
 #include <asm/io.h>
 #include <asm/arch/iomux-mx28.h>
 #include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
 
 #include "mx28_init.h"
 
@@ -46,12 +48,65 @@ void early_delay(int delay)
 		;
 }
 
+#define	MUX_CONFIG_BOOTMODE_PAD	(MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
+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,
+};
+
+uint8_t mx28_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(mx28_boot_modes); i++) {
+		masked = bootmode & mx28_boot_modes[i].boot_mask;
+		if (masked == mx28_boot_modes[i].boot_pads)
+			break;
+	}
+
+	return i;
+}
+
 void mx28_common_spl_init(const iomux_cfg_t *iomux_setup,
 			const unsigned int iomux_size)
 {
+	struct mx28_spl_data *data = (struct mx28_spl_data *)
+		((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
+	uint8_t bootmode = mx28_get_bootmode_index();
+
 	mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
 	mx28_power_init();
+
 	mx28_mem_init();
+	data->mem_dram_size = mx28_mem_get_size();
+
+	data->boot_mode_idx = bootmode;
+
 	mx28_power_wait_pswitch();
 }
 
@@ -68,8 +123,10 @@ inline void board_init_r(gd_t *id, ulong dest_addr)
 		;
 }
 
+#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)
 {

+ 86 - 0
arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c

@@ -0,0 +1,86 @@
+/*
+ * Freescale i.MX28 Battery measurement 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 "mx28_init.h"
+
+void mx28_lradc_init(void)
+{
+	struct mx28_lradc_regs *regs = (struct mx28_lradc_regs *)MXS_LRADC_BASE;
+
+	writel(LRADC_CTRL0_SFTRST, &regs->hw_lradc_ctrl0_clr);
+	writel(LRADC_CTRL0_CLKGATE, &regs->hw_lradc_ctrl0_clr);
+	writel(LRADC_CTRL0_ONCHIP_GROUNDREF, &regs->hw_lradc_ctrl0_clr);
+
+	clrsetbits_le32(&regs->hw_lradc_ctrl3,
+			LRADC_CTRL3_CYCLE_TIME_MASK,
+			LRADC_CTRL3_CYCLE_TIME_6MHZ);
+
+	clrsetbits_le32(&regs->hw_lradc_ctrl4,
+			LRADC_CTRL4_LRADC7SELECT_MASK |
+			LRADC_CTRL4_LRADC6SELECT_MASK,
+			LRADC_CTRL4_LRADC7SELECT_CHANNEL7 |
+			LRADC_CTRL4_LRADC6SELECT_CHANNEL10);
+}
+
+void mx28_lradc_enable_batt_measurement(void)
+{
+	struct mx28_lradc_regs *regs = (struct mx28_lradc_regs *)MXS_LRADC_BASE;
+
+	/* Check if the channel is present at all. */
+	if (!(readl(&regs->hw_lradc_status) & LRADC_STATUS_CHANNEL7_PRESENT))
+		return;
+
+	writel(LRADC_CTRL1_LRADC7_IRQ_EN, &regs->hw_lradc_ctrl1_clr);
+	writel(LRADC_CTRL1_LRADC7_IRQ, &regs->hw_lradc_ctrl1_clr);
+
+	clrsetbits_le32(&regs->hw_lradc_conversion,
+			LRADC_CONVERSION_SCALE_FACTOR_MASK,
+			LRADC_CONVERSION_SCALE_FACTOR_LI_ION);
+	writel(LRADC_CONVERSION_AUTOMATIC, &regs->hw_lradc_conversion_set);
+
+	/* Configure the channel. */
+	writel((1 << 7) << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
+		&regs->hw_lradc_ctrl2_clr);
+	writel(0xffffffff, &regs->hw_lradc_ch7_clr);
+	clrbits_le32(&regs->hw_lradc_ch7, LRADC_CH_NUM_SAMPLES_MASK);
+	writel(LRADC_CH_ACCUMULATE, &regs->hw_lradc_ch7_clr);
+
+	/* Schedule the channel. */
+	writel(1 << 7, &regs->hw_lradc_ctrl0_set);
+
+	/* Start the channel sampling. */
+	writel(((1 << 7) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) |
+		((1 << 3) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) |
+		100, &regs->hw_lradc_delay3);
+
+	writel(0xffffffff, &regs->hw_lradc_ch7_clr);
+
+	writel(LRADC_DELAY_KICK, &regs->hw_lradc_delay3_set);
+}

+ 6 - 8
arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c

@@ -39,7 +39,7 @@ uint32_t dram_vals[] = {
 	0x00000000, 0x00000100, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00010101, 0x01010101,
-	0x000f0f01, 0x0f02010a, 0x00000000, 0x00010101,
+	0x000f0f01, 0x0f02020a, 0x00000000, 0x00010101,
 	0x00000100, 0x00000100, 0x00000000, 0x00000002,
 	0x01010000, 0x05060302, 0x06005003, 0x0a0000c8,
 	0x02009c40, 0x0000030c, 0x0036a609, 0x031a0612,
@@ -149,6 +149,8 @@ void mx28_mem_setup_cpu_and_hbus(void)
 	/* Disable CPU bypass */
 	writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
 		&clkctrl_regs->hw_clkctrl_clkseq_clr);
+
+	early_delay(15000);
 }
 
 void mx28_mem_setup_vdda(void)
@@ -173,10 +175,8 @@ void mx28_mem_setup_vddd(void)
 		&power_regs->hw_power_vdddctrl);
 }
 
-void mx28_mem_get_size(void)
+uint32_t mx28_mem_get_size(void)
 {
-	struct mx28_digctl_regs *digctl_regs =
-		(struct mx28_digctl_regs *)MXS_DIGCTL_BASE;
 	uint32_t sz, da;
 	uint32_t *vt = (uint32_t *)0x20;
 	/* The following is "subs pc, r14, #4", used as return from DABT. */
@@ -187,11 +187,11 @@ void mx28_mem_get_size(void)
 	vt[4] = data_abort_memdetect_handler;
 
 	sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
-	writel(sz, &digctl_regs->hw_digctl_scratch0);
-	writel(sz, &digctl_regs->hw_digctl_scratch1);
 
 	/* Restore the old DABT handler. */
 	vt[4] = da;
+
+	return sz;
 }
 
 void mx28_mem_init(void)
@@ -239,6 +239,4 @@ void mx28_mem_init(void)
 	early_delay(10000);
 
 	mx28_mem_setup_cpu_and_hbus();
-
-	mx28_mem_get_size();
 }

+ 155 - 69
arch/arm/cpu/arm926ejs/mx28/spl_power_init.c

@@ -45,11 +45,11 @@ void mx28_power_clock2pll(void)
 	struct mx28_clkctrl_regs *clkctrl_regs =
 		(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
 
-	writel(CLKCTRL_PLL0CTRL0_POWER,
-		&clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
+	setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
+			CLKCTRL_PLL0CTRL0_POWER);
 	early_delay(100);
-	writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
-		&clkctrl_regs->hw_clkctrl_clkseq_clr);
+	setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
+			CLKCTRL_CLKSEQ_BYPASS_CPU);
 }
 
 void mx28_power_clear_auto_restart(void)
@@ -104,6 +104,62 @@ void mx28_power_set_linreg(void)
 			POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
 }
 
+int mx28_get_batt_volt(void)
+{
+	struct mx28_power_regs *power_regs =
+		(struct mx28_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;
+}
+
+int mx28_is_batt_ready(void)
+{
+	return (mx28_get_batt_volt() >= 3600);
+}
+
+int mx28_is_batt_good(void)
+{
+	struct mx28_power_regs *power_regs =
+		(struct mx28_power_regs *)MXS_POWER_BASE;
+	uint32_t volt = mx28_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 = mx28_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;
+}
+
 void mx28_power_setup_5v_detect(void)
 {
 	struct mx28_power_regs *power_regs =
@@ -399,9 +455,14 @@ void mx28_power_enable_4p2(void)
 	mx28_power_init_4p2_regulator();
 
 	/* Shutdown battery (none present) */
-	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);
+	if (!mx28_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);
+	}
 
 	mx28_power_init_dcdc_4p2_source();
 
@@ -459,6 +520,50 @@ void mx28_powerdown(void)
 		&power_regs->hw_power_reset);
 }
 
+void mx28_batt_boot(void)
+{
+	struct mx28_power_regs *power_regs =
+		(struct mx28_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);
+
+	mx28_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);
+}
+
 void mx28_handle_5v_conflict(void)
 {
 	struct mx28_power_regs *power_regs =
@@ -483,23 +588,12 @@ void mx28_handle_5v_conflict(void)
 			mx28_powerdown();
 			break;
 		}
-	}
-}
 
-int mx28_get_batt_volt(void)
-{
-	struct mx28_power_regs *power_regs =
-		(struct mx28_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;
-}
-
-int mx28_is_batt_ready(void)
-{
-	return (mx28_get_batt_volt() >= 3600);
+		if (tmp & POWER_STS_PSWITCH_MASK) {
+			mx28_batt_boot();
+			break;
+		}
+	}
 }
 
 void mx28_5v_boot(void)
@@ -553,62 +647,44 @@ void mx28_switch_vddd_to_dcdc_source(void)
 		POWER_VDDDCTRL_DISABLE_STEPPING);
 }
 
-int mx28_is_batt_good(void)
+void mx28_power_configure_power_source(void)
 {
+	int batt_ready, batt_good;
 	struct mx28_power_regs *power_regs =
 		(struct mx28_power_regs *)MXS_POWER_BASE;
-	uint32_t volt;
-
-	volt = readl(&power_regs->hw_power_battmonitor);
-	volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
-	volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
-	volt *= 8;
+	struct mx28_lradc_regs *lradc_regs =
+		(struct mx28_lradc_regs *)MXS_LRADC_BASE;
 
-	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 = readl(&power_regs->hw_power_battmonitor);
-	volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
-	volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
-	volt *= 8;
-
-	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);
+	mx28_src_power_init();
 
-	return 0;
-}
+	batt_ready = mx28_is_batt_ready();
 
-void mx28_power_configure_power_source(void)
-{
-	mx28_src_power_init();
+	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+		batt_good = mx28_is_batt_good();
+		if (batt_ready) {
+			/* 5V source detected, good battery detected. */
+			mx28_batt_boot();
+		} else {
+			if (batt_good) {
+				/* 5V source detected, low battery detceted. */
+			} else {
+				/* 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);
+			}
+			mx28_5v_boot();
+		}
+	} else {
+		/* 5V not detected, booting from battery. */
+		mx28_batt_boot();
+	}
 
-	mx28_5v_boot();
 	mx28_power_clock2pll();
 
 	mx28_init_batt_bo();
+
 	mx28_switch_vddd_to_dcdc_source();
 }
 
@@ -883,6 +959,13 @@ void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout)
 			new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
 }
 
+void mx28_setup_batt_detect(void)
+{
+	mx28_lradc_init();
+	mx28_lradc_enable_batt_measurement();
+	early_delay(10);
+}
+
 void mx28_power_init(void)
 {
 	struct mx28_power_regs *power_regs =
@@ -892,6 +975,9 @@ void mx28_power_init(void)
 	mx28_power_clear_auto_restart();
 	mx28_power_set_linreg();
 	mx28_power_setup_5v_detect();
+
+	mx28_setup_batt_detect();
+
 	mx28_power_configure_power_source();
 	mx28_enable_output_rail_protection();
 

+ 1 - 1
arch/arm/cpu/armv7/am33xx/board.c

@@ -105,7 +105,7 @@ void init_timer(void)
 #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-	return omap_mmc_init(0);
+	return omap_mmc_init(0, 0, 0);
 }
 #endif
 

+ 5 - 2
arch/arm/cpu/armv7/config.mk

@@ -22,8 +22,11 @@
 #
 PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
 
-# Make ARMv5 to allow more compilers to work, even though its v7a.
-PLATFORM_CPPFLAGS += -march=armv5
+# If armv7-a is not supported by GCC fall-back to armv5, which is
+# supported by more tool-chains
+PF_CPPFLAGS_ARMV7 := $(call cc-option, -march=armv7-a, -march=armv5)
+PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARMV7)
+
 # =========================================================================
 #
 # Supply options according to compiler version

+ 1 - 1
arch/arm/cpu/armv7/exynos/Makefile

@@ -22,7 +22,7 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(SOC).o
 
-COBJS	+= clock.o soc.o
+COBJS	+= clock.o power.o soc.o system.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))

+ 184 - 0
arch/arm/cpu/armv7/exynos/clock.c

@@ -414,6 +414,170 @@ static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
 	writel(val, addr);
 }
 
+/* get_lcd_clk: return lcd clock frequency */
+static unsigned long exynos4_get_lcd_clk(void)
+{
+	struct exynos4_clock *clk =
+		(struct exynos4_clock *)samsung_get_base_clock();
+	unsigned long pclk, sclk;
+	unsigned int sel;
+	unsigned int ratio;
+
+	/*
+	 * CLK_SRC_LCD0
+	 * FIMD0_SEL [3:0]
+	 */
+	sel = readl(&clk->src_lcd0);
+	sel = sel & 0xf;
+
+	/*
+	 * 0x6: SCLK_MPLL
+	 * 0x7: SCLK_EPLL
+	 * 0x8: SCLK_VPLL
+	 */
+	if (sel == 0x6)
+		sclk = get_pll_clk(MPLL);
+	else if (sel == 0x7)
+		sclk = get_pll_clk(EPLL);
+	else if (sel == 0x8)
+		sclk = get_pll_clk(VPLL);
+	else
+		return 0;
+
+	/*
+	 * CLK_DIV_LCD0
+	 * FIMD0_RATIO [3:0]
+	 */
+	ratio = readl(&clk->div_lcd0);
+	ratio = ratio & 0xf;
+
+	pclk = sclk / (ratio + 1);
+
+	return pclk;
+}
+
+void exynos4_set_lcd_clk(void)
+{
+	struct exynos4_clock *clk =
+	    (struct exynos4_clock *)samsung_get_base_clock();
+	unsigned int cfg = 0;
+
+	/*
+	 * CLK_GATE_BLOCK
+	 * CLK_CAM	[0]
+	 * CLK_TV	[1]
+	 * CLK_MFC	[2]
+	 * CLK_G3D	[3]
+	 * CLK_LCD0	[4]
+	 * CLK_LCD1	[5]
+	 * CLK_GPS	[7]
+	 */
+	cfg = readl(&clk->gate_block);
+	cfg |= 1 << 4;
+	writel(cfg, &clk->gate_block);
+
+	/*
+	 * CLK_SRC_LCD0
+	 * FIMD0_SEL		[3:0]
+	 * MDNIE0_SEL		[7:4]
+	 * MDNIE_PWM0_SEL	[8:11]
+	 * MIPI0_SEL		[12:15]
+	 * set lcd0 src clock 0x6: SCLK_MPLL
+	 */
+	cfg = readl(&clk->src_lcd0);
+	cfg &= ~(0xf);
+	cfg |= 0x6;
+	writel(cfg, &clk->src_lcd0);
+
+	/*
+	 * CLK_GATE_IP_LCD0
+	 * CLK_FIMD0		[0]
+	 * CLK_MIE0		[1]
+	 * CLK_MDNIE0		[2]
+	 * CLK_DSIM0		[3]
+	 * CLK_SMMUFIMD0	[4]
+	 * CLK_PPMULCD0		[5]
+	 * Gating all clocks for FIMD0
+	 */
+	cfg = readl(&clk->gate_ip_lcd0);
+	cfg |= 1 << 0;
+	writel(cfg, &clk->gate_ip_lcd0);
+
+	/*
+	 * CLK_DIV_LCD0
+	 * FIMD0_RATIO		[3:0]
+	 * MDNIE0_RATIO		[7:4]
+	 * MDNIE_PWM0_RATIO	[11:8]
+	 * MDNIE_PWM_PRE_RATIO	[15:12]
+	 * MIPI0_RATIO		[19:16]
+	 * MIPI0_PRE_RATIO	[23:20]
+	 * set fimd ratio
+	 */
+	cfg &= ~(0xf);
+	cfg |= 0x1;
+	writel(cfg, &clk->div_lcd0);
+}
+
+void exynos4_set_mipi_clk(void)
+{
+	struct exynos4_clock *clk =
+	    (struct exynos4_clock *)samsung_get_base_clock();
+	unsigned int cfg = 0;
+
+	/*
+	 * CLK_SRC_LCD0
+	 * FIMD0_SEL		[3:0]
+	 * MDNIE0_SEL		[7:4]
+	 * MDNIE_PWM0_SEL	[8:11]
+	 * MIPI0_SEL		[12:15]
+	 * set mipi0 src clock 0x6: SCLK_MPLL
+	 */
+	cfg = readl(&clk->src_lcd0);
+	cfg &= ~(0xf << 12);
+	cfg |= (0x6 << 12);
+	writel(cfg, &clk->src_lcd0);
+
+	/*
+	 * CLK_SRC_MASK_LCD0
+	 * FIMD0_MASK		[0]
+	 * MDNIE0_MASK		[4]
+	 * MDNIE_PWM0_MASK	[8]
+	 * MIPI0_MASK		[12]
+	 * set src mask mipi0 0x1: Unmask
+	 */
+	cfg = readl(&clk->src_mask_lcd0);
+	cfg |= (0x1 << 12);
+	writel(cfg, &clk->src_mask_lcd0);
+
+	/*
+	 * CLK_GATE_IP_LCD0
+	 * CLK_FIMD0		[0]
+	 * CLK_MIE0		[1]
+	 * CLK_MDNIE0		[2]
+	 * CLK_DSIM0		[3]
+	 * CLK_SMMUFIMD0	[4]
+	 * CLK_PPMULCD0		[5]
+	 * Gating all clocks for MIPI0
+	 */
+	cfg = readl(&clk->gate_ip_lcd0);
+	cfg |= 1 << 3;
+	writel(cfg, &clk->gate_ip_lcd0);
+
+	/*
+	 * CLK_DIV_LCD0
+	 * FIMD0_RATIO		[3:0]
+	 * MDNIE0_RATIO		[7:4]
+	 * MDNIE_PWM0_RATIO	[11:8]
+	 * MDNIE_PWM_PRE_RATIO	[15:12]
+	 * MIPI0_RATIO		[19:16]
+	 * MIPI0_PRE_RATIO	[23:20]
+	 * set mipi ratio
+	 */
+	cfg &= ~(0xf << 16);
+	cfg |= (0x1 << 16);
+	writel(cfg, &clk->div_lcd0);
+}
+
 unsigned long get_pll_clk(int pllreg)
 {
 	if (cpu_is_exynos5())
@@ -453,3 +617,23 @@ void set_mmc_clk(int dev_index, unsigned int div)
 	else
 		exynos4_set_mmc_clk(dev_index, div);
 }
+
+unsigned long get_lcd_clk(void)
+{
+	if (cpu_is_exynos4())
+		return exynos4_get_lcd_clk();
+	else
+		return 0;
+}
+
+void set_lcd_clk(void)
+{
+	if (cpu_is_exynos4())
+		exynos4_set_lcd_clk();
+}
+
+void set_mipi_clk(void)
+{
+	if (cpu_is_exynos4())
+		exynos4_set_mipi_clk();
+}

+ 54 - 0
arch/arm/cpu/armv7/exynos/power.c

@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * 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/power.h>
+
+static void exynos4_mipi_phy_control(unsigned int dev_index,
+					unsigned int enable)
+{
+	struct exynos4_power *pmu =
+	    (struct exynos4_power *)samsung_get_base_power();
+	unsigned int addr, cfg = 0;
+
+	if (dev_index == 0)
+		addr = (unsigned int)&pmu->mipi_phy0_control;
+	else
+		addr = (unsigned int)&pmu->mipi_phy1_control;
+
+
+	cfg = readl(addr);
+	if (enable)
+		cfg |= (EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE);
+	else
+		cfg &= ~(EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE);
+
+	writel(cfg, addr);
+}
+
+void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable)
+{
+	if (cpu_is_exynos4())
+		exynos4_mipi_phy_control(dev_index, enable);
+}

+ 48 - 0
arch/arm/cpu/armv7/exynos/system.c

@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * 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/system.h>
+
+static void exynos4_set_system_display(void)
+{
+	struct exynos4_sysreg *sysreg =
+	    (struct exynos4_sysreg *)samsung_get_base_sysreg();
+	unsigned int cfg = 0;
+
+	/*
+	 * system register path set
+	 * 0: MIE/MDNIE
+	 * 1: FIMD Bypass
+	 */
+	cfg = readl(&sysreg->display_ctrl);
+	cfg |= (1 << 1);
+	writel(cfg, &sysreg->display_ctrl);
+}
+
+void set_system_display_ctrl(void)
+{
+	if (cpu_is_exynos4())
+		exynos4_set_system_display();
+}

+ 14 - 1
arch/arm/cpu/armv7/imx-common/cpu.c

@@ -29,12 +29,13 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/arch/crm_regs.h>
 
 #ifdef CONFIG_FSL_ESDHC
 #include <fsl_esdhc.h>
 #endif
 
-static char *get_reset_cause(void)
+char *get_reset_cause(void)
 {
 	u32 cause;
 	struct src *src_regs = (struct src *)SRC_BASE_ADDR;
@@ -127,3 +128,15 @@ void reset_cpu(ulong addr)
 {
 	__raw_writew(4, WDOG1_BASE_ADDR);
 }
+
+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);
+}

+ 472 - 21
arch/arm/cpu/armv7/mx5/clock.c

@@ -30,6 +30,7 @@
 #include <asm/arch/crm_regs.h>
 #include <asm/arch/clock.h>
 #include <div64.h>
+#include <asm/arch/sys_proto.h>
 
 enum pll_clocks {
 	PLL1_CLOCK = 0,
@@ -48,6 +49,42 @@ struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = {
 #endif
 };
 
+#define AHB_CLK_ROOT    133333333
+#define SZ_DEC_1M       1000000
+#define PLL_PD_MAX      16      /* Actual pd+1 */
+#define PLL_MFI_MAX     15
+#define PLL_MFI_MIN     5
+#define ARM_DIV_MAX     8
+#define IPG_DIV_MAX     4
+#define AHB_DIV_MAX     8
+#define EMI_DIV_MAX     8
+#define NFC_DIV_MAX     8
+
+#define MX5_CBCMR	0x00015154
+#define MX5_CBCDR	0x02888945
+
+struct fixed_pll_mfd {
+	u32 ref_clk_hz;
+	u32 mfd;
+};
+
+const struct fixed_pll_mfd fixed_mfd[] = {
+	{CONFIG_SYS_MX5_HCLK, 24 * 16},
+};
+
+struct pll_param {
+	u32 pd;
+	u32 mfi;
+	u32 mfn;
+	u32 mfd;
+};
+
+#define PLL_FREQ_MAX(ref_clk)  (4 * (ref_clk) * PLL_MFI_MAX)
+#define PLL_FREQ_MIN(ref_clk) \
+		((2 * (ref_clk) * (PLL_MFI_MIN - 1)) / PLL_PD_MAX)
+#define MAX_DDR_CLK     420000000
+#define NFC_CLK_MAX     34000000
+
 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
 
 void set_usboh3_clk(void)
@@ -192,7 +229,7 @@ u32 get_mcu_main_clk(void)
 /*
  * Get the rate of peripheral's root clock.
  */
-static u32 get_periph_clk(void)
+u32 get_periph_clk(void)
 {
 	u32 reg;
 
@@ -212,22 +249,6 @@ static u32 get_periph_clk(void)
 	/* NOTREACHED */
 }
 
-/*
- * Get the rate of ahb clock.
- */
-static u32 get_ahb_clk(void)
-{
-	uint32_t freq, div, reg;
-
-	freq = get_periph_clk();
-
-	reg = __raw_readl(&mxc_ccm->cbcdr);
-	div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
-			MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
-
-	return freq / div;
-}
-
 /*
  * Get the rate of ipg clock.
  */
@@ -306,7 +327,7 @@ static u32 get_uart_clk(void)
 /*
  * This function returns the low power audio clock.
  */
-u32 get_lp_apm(void)
+static u32 get_lp_apm(void)
 {
 	u32 ret_val = 0;
 	u32 ccsr = __raw_readl(&mxc_ccm->ccsr);
@@ -322,7 +343,7 @@ u32 get_lp_apm(void)
 /*
  * get cspi clock rate.
  */
-u32 imx_get_cspiclk(void)
+static u32 imx_get_cspiclk(void)
 {
 	u32 ret_val = 0, pdf, pre_pdf, clk_sel;
 	u32 cscmr1 = __raw_readl(&mxc_ccm->cscmr1);
@@ -359,8 +380,77 @@ u32 imx_get_cspiclk(void)
 	return ret_val;
 }
 
+static u32 get_axi_a_clk(void)
+{
+	u32 cbcdr =  __raw_readl(&mxc_ccm->cbcdr);
+	u32 pdf = (cbcdr & MXC_CCM_CBCDR_AXI_A_PODF_MASK) \
+			>> MXC_CCM_CBCDR_AXI_A_PODF_OFFSET;
+
+	return  get_periph_clk() / (pdf + 1);
+}
+
+static u32 get_axi_b_clk(void)
+{
+	u32 cbcdr =  __raw_readl(&mxc_ccm->cbcdr);
+	u32 pdf = (cbcdr & MXC_CCM_CBCDR_AXI_B_PODF_MASK) \
+			>> MXC_CCM_CBCDR_AXI_B_PODF_OFFSET;
+
+	return  get_periph_clk() / (pdf + 1);
+}
+
+static u32 get_emi_slow_clk(void)
+{
+	u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr);
+	u32 emi_clk_sel = cbcdr & MXC_CCM_CBCDR_EMI_CLK_SEL;
+	u32 pdf = (cbcdr & MXC_CCM_CBCDR_EMI_PODF_MASK) \
+			>> MXC_CCM_CBCDR_EMI_PODF_OFFSET;
+
+	if (emi_clk_sel)
+		return  get_ahb_clk() / (pdf + 1);
+
+	return  get_periph_clk() / (pdf + 1);
+}
+
+static u32 get_ddr_clk(void)
+{
+	u32 ret_val = 0;
+	u32 cbcmr = __raw_readl(&mxc_ccm->cbcmr);
+	u32 ddr_clk_sel = (cbcmr & MXC_CCM_CBCMR_DDR_CLK_SEL_MASK) \
+				>> MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET;
+#ifdef CONFIG_MX51
+	u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr);
+	if (cbcdr & MXC_CCM_CBCDR_DDR_HIFREQ_SEL) {
+		u32 ddr_clk_podf = (cbcdr & MXC_CCM_CBCDR_DDR_PODF_MASK) >> \
+					MXC_CCM_CBCDR_DDR_PODF_OFFSET;
+
+		ret_val = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK);
+		ret_val /= ddr_clk_podf + 1;
+
+		return ret_val;
+	}
+#endif
+	switch (ddr_clk_sel) {
+	case 0:
+		ret_val = get_axi_a_clk();
+		break;
+	case 1:
+		ret_val = get_axi_b_clk();
+		break;
+	case 2:
+		ret_val = get_emi_slow_clk();
+		break;
+	case 3:
+		ret_val = get_ahb_clk();
+		break;
+	default:
+		break;
+	}
+
+	return ret_val;
+}
+
 /*
- * The API of get mxc clockes.
+ * The API of get mxc clocks.
  */
 unsigned int mxc_get_clock(enum mxc_clock clk)
 {
@@ -380,10 +470,14 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
 	case MXC_FEC_CLK:
 		return decode_pll(mxc_plls[PLL1_CLOCK],
 				    CONFIG_SYS_MX5_HCLK);
+	case MXC_SATA_CLK:
+		return get_ahb_clk();
+	case MXC_DDR_CLK:
+		return get_ddr_clk();
 	default:
 		break;
 	}
-	return -1;
+	return -EINVAL;
 }
 
 u32 imx_get_uartclk(void)
@@ -397,6 +491,362 @@ u32 imx_get_fecclk(void)
 	return mxc_get_clock(MXC_IPG_CLK);
 }
 
+static 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;
+}
+
+/*
+ * This is to calculate various parameters based on reference clock and
+ * targeted clock based on the equation:
+ *      t_clk = 2*ref_freq*(mfi + mfn/(mfd+1))/(pd+1)
+ * This calculation is based on a fixed MFD value for simplicity.
+ */
+static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
+{
+	u64 pd, mfi = 1, mfn, mfd, t1;
+	u32 n_target = target;
+	u32 n_ref = ref, i;
+
+	/*
+	 * Make sure targeted freq is in the valid range.
+	 * Otherwise the following calculation might be wrong!!!
+	 */
+	if (n_target < PLL_FREQ_MIN(ref) ||
+		n_target > PLL_FREQ_MAX(ref)) {
+		printf("Targeted peripheral clock should be"
+			"within [%d - %d]\n",
+			PLL_FREQ_MIN(ref) / SZ_DEC_1M,
+			PLL_FREQ_MAX(ref) / SZ_DEC_1M);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(fixed_mfd); i++) {
+		if (fixed_mfd[i].ref_clk_hz == ref) {
+			mfd = fixed_mfd[i].mfd;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(fixed_mfd))
+		return -EINVAL;
+
+	/* Use n_target and n_ref to avoid overflow */
+	for (pd = 1; pd <= PLL_PD_MAX; pd++) {
+		t1 = n_target * pd;
+		do_div(t1, (4 * n_ref));
+		mfi = t1;
+		if (mfi > PLL_MFI_MAX)
+			return -EINVAL;
+		else if (mfi < 5)
+			continue;
+		break;
+	}
+	/*
+	 * Now got pd and mfi already
+	 *
+	 * mfn = (((n_target * pd) / 4 - n_ref * mfi) * mfd) / n_ref;
+	 */
+	t1 = n_target * pd;
+	do_div(t1, 4);
+	t1 -= n_ref * mfi;
+	t1 *= mfd;
+	do_div(t1, n_ref);
+	mfn = t1;
+	debug("ref=%d, target=%d, pd=%d," "mfi=%d,mfn=%d, mfd=%d\n",
+		ref, n_target, (u32)pd, (u32)mfi, (u32)mfn, (u32)mfd);
+	i = 1;
+	if (mfn != 0)
+		i = gcd(mfd, mfn);
+	pll->pd = (u32)pd;
+	pll->mfi = (u32)mfi;
+	do_div(mfn, i);
+	pll->mfn = (u32)mfn;
+	do_div(mfd, i);
+	pll->mfd = (u32)mfd;
+
+	return 0;
+}
+
+#define calc_div(tgt_clk, src_clk, limit) ({		\
+		u32 v = 0;				\
+		if (((src_clk) % (tgt_clk)) <= 100)	\
+			v = (src_clk) / (tgt_clk);	\
+		else					\
+			v = ((src_clk) / (tgt_clk)) + 1;\
+		if (v > limit)				\
+			v = limit;			\
+		(v - 1);				\
+	})
+
+#define CHANGE_PLL_SETTINGS(pll, pd, fi, fn, fd) \
+	{	\
+		__raw_writel(0x1232, &pll->ctrl);		\
+		__raw_writel(0x2, &pll->config);		\
+		__raw_writel((((pd) - 1) << 0) | ((fi) << 4),	\
+			&pll->op);				\
+		__raw_writel(fn, &(pll->mfn));			\
+		__raw_writel((fd) - 1, &pll->mfd);		\
+		__raw_writel((((pd) - 1) << 0) | ((fi) << 4),	\
+			&pll->hfs_op);				\
+		__raw_writel(fn, &pll->hfs_mfn);		\
+		__raw_writel((fd) - 1, &pll->hfs_mfd);		\
+		__raw_writel(0x1232, &pll->ctrl);		\
+		while (!__raw_readl(&pll->ctrl) & 0x1)		\
+			;\
+	}
+
+static int config_pll_clk(enum pll_clocks index, struct pll_param *pll_param)
+{
+	u32 ccsr = __raw_readl(&mxc_ccm->ccsr);
+	struct mxc_pll_reg *pll = mxc_plls[index];
+
+	switch (index) {
+	case PLL1_CLOCK:
+		/* Switch ARM to PLL2 clock */
+		__raw_writel(ccsr | 0x4, &mxc_ccm->ccsr);
+		CHANGE_PLL_SETTINGS(pll, pll_param->pd,
+					pll_param->mfi, pll_param->mfn,
+					pll_param->mfd);
+		/* Switch back */
+		__raw_writel(ccsr & ~0x4, &mxc_ccm->ccsr);
+		break;
+	case PLL2_CLOCK:
+		/* Switch to pll2 bypass clock */
+		__raw_writel(ccsr | 0x2, &mxc_ccm->ccsr);
+		CHANGE_PLL_SETTINGS(pll, pll_param->pd,
+					pll_param->mfi, pll_param->mfn,
+					pll_param->mfd);
+		/* Switch back */
+		__raw_writel(ccsr & ~0x2, &mxc_ccm->ccsr);
+		break;
+	case PLL3_CLOCK:
+		/* Switch to pll3 bypass clock */
+		__raw_writel(ccsr | 0x1, &mxc_ccm->ccsr);
+		CHANGE_PLL_SETTINGS(pll, pll_param->pd,
+					pll_param->mfi, pll_param->mfn,
+					pll_param->mfd);
+		/* Switch back */
+		__raw_writel(ccsr & ~0x1, &mxc_ccm->ccsr);
+		break;
+	case PLL4_CLOCK:
+		/* Switch to pll4 bypass clock */
+		__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 */
+		__raw_writel(ccsr & ~0x20, &mxc_ccm->ccsr);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Config CPU clock */
+static int config_core_clk(u32 ref, u32 freq)
+{
+	int ret = 0;
+	struct pll_param pll_param;
+
+	memset(&pll_param, 0, sizeof(struct pll_param));
+
+	/* The case that periph uses PLL1 is not considered here */
+	ret = calc_pll_params(ref, freq, &pll_param);
+	if (ret != 0) {
+		printf("Error:Can't find pll parameters: %d\n", ret);
+		return ret;
+	}
+
+	return config_pll_clk(PLL1_CLOCK, &pll_param);
+}
+
+static int config_nfc_clk(u32 nfc_clk)
+{
+	u32 reg;
+	u32 parent_rate = get_emi_slow_clk();
+	u32 div = parent_rate / nfc_clk;
+
+	if (nfc_clk <= 0)
+		return -EINVAL;
+	if (div == 0)
+		div++;
+	if (parent_rate / div > NFC_CLK_MAX)
+		div++;
+	reg = __raw_readl(&mxc_ccm->cbcdr);
+	reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK;
+	reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET;
+	__raw_writel(reg, &mxc_ccm->cbcdr);
+	while (__raw_readl(&mxc_ccm->cdhipr) != 0)
+		;
+	return 0;
+}
+
+/* Config main_bus_clock for periphs */
+static int config_periph_clk(u32 ref, u32 freq)
+{
+	int ret = 0;
+	struct pll_param pll_param;
+
+	memset(&pll_param, 0, sizeof(struct pll_param));
+
+	if (__raw_readl(&mxc_ccm->cbcdr) & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
+		ret = calc_pll_params(ref, freq, &pll_param);
+		if (ret != 0) {
+			printf("Error:Can't find pll parameters: %d\n",
+				ret);
+			return ret;
+		}
+		switch ((__raw_readl(&mxc_ccm->cbcmr) & \
+			MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >> \
+			MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) {
+		case 0:
+			return config_pll_clk(PLL1_CLOCK, &pll_param);
+			break;
+		case 1:
+			return config_pll_clk(PLL3_CLOCK, &pll_param);
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int config_ddr_clk(u32 emi_clk)
+{
+	u32 clk_src;
+	s32 shift = 0, clk_sel, div = 1;
+	u32 cbcmr = __raw_readl(&mxc_ccm->cbcmr);
+	u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr);
+
+	if (emi_clk > MAX_DDR_CLK) {
+		printf("Warning:DDR clock should not exceed %d MHz\n",
+			MAX_DDR_CLK / SZ_DEC_1M);
+		emi_clk = MAX_DDR_CLK;
+	}
+
+	clk_src = get_periph_clk();
+	/* Find DDR clock input */
+	clk_sel = (cbcmr >> 10) & 0x3;
+	switch (clk_sel) {
+	case 0:
+		shift = 16;
+		break;
+	case 1:
+		shift = 19;
+		break;
+	case 2:
+		shift = 22;
+		break;
+	case 3:
+		shift = 10;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if ((clk_src % emi_clk) < 10000000)
+		div = clk_src / emi_clk;
+	else
+		div = (clk_src / emi_clk) + 1;
+	if (div > 8)
+		div = 8;
+
+	cbcdr = cbcdr & ~(0x7 << shift);
+	cbcdr |= ((div - 1) << shift);
+	__raw_writel(cbcdr, &mxc_ccm->cbcdr);
+	while (__raw_readl(&mxc_ccm->cdhipr) != 0)
+		;
+	__raw_writel(0x0, &mxc_ccm->ccdr);
+
+	return 0;
+}
+
+/*
+ * 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 *= SZ_DEC_1M;
+
+	switch (clk) {
+	case MXC_ARM_CLK:
+		if (config_core_clk(ref, freq))
+			return -EINVAL;
+		break;
+	case MXC_PERIPH_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;
+	default:
+		printf("Warning:Unsupported or invalid clock type\n");
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_MX53
+/*
+ * The clock for the external interface can be set to use internal clock
+ * if fuse bank 4, row 3, bit 2 is set.
+ * This is an undocumented feature and it was confirmed by Freescale's support:
+ * Fuses (but not pins) may be used to configure SATA clocks.
+ * Particularly the i.MX53 Fuse_Map contains the next information
+ * about configuring SATA clocks :  SATA_ALT_REF_CLK[1:0] (offset 0x180C)
+ * '00' - 100MHz (External)
+ * '01' - 50MHz (External)
+ * '10' - 120MHz, internal (USB PHY)
+ * '11' - Reserved
+*/
+void mxc_set_sata_internal_clock(void)
+{
+	u32 *tmp_base =
+		(u32 *)(IIM_BASE_ADDR + 0x180c);
+
+	set_usb_phy1_clk();
+
+	writel((readl(tmp_base) & (~0x7)) | 0x4, tmp_base);
+}
+#endif
+
 /*
  * Dump some core clockes.
  */
@@ -419,6 +869,7 @@ int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
 	printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
 	printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
+	printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
 
 	return 0;
 }

+ 3 - 2
arch/arm/cpu/armv7/mx5/lowlevel_init.S

@@ -22,6 +22,7 @@
 #include <config.h>
 #include <asm/arch/imx-regs.h>
 #include <generated/asm-offsets.h>
+#include <linux/linkage.h>
 
 /*
  * L2CC Cache setup/invalidation/disable
@@ -326,8 +327,7 @@
 
 .section ".text.init", "x"
 
-.globl lowlevel_init
-lowlevel_init:
+ENTRY(lowlevel_init)
 #if defined(CONFIG_MX51)
 	ldr r0, =GPIO1_BASE_ADDR
 	ldr r1, [r0, #0x0]
@@ -348,6 +348,7 @@ lowlevel_init:
 
 	/* r12 saved upper lr*/
 	mov pc,lr
+ENDPROC(lowlevel_init)
 
 /* Board level setting value */
 W_DP_OP_864:              .word DP_OP_864

+ 35 - 15
arch/arm/cpu/armv7/mx6/clock.c

@@ -24,8 +24,9 @@
 #include <asm/io.h>
 #include <asm/errno.h>
 #include <asm/arch/imx-regs.h>
-#include <asm/arch/ccm_regs.h>
+#include <asm/arch/crm_regs.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
 
 enum pll_clocks {
 	PLL_SYS,	/* System PLL */
@@ -34,7 +35,7 @@ enum pll_clocks {
 	PLL_ENET,	/* ENET PLL */
 };
 
-struct imx_ccm_reg *imx_ccm = (struct imx_ccm_reg *)CCM_BASE_ADDR;
+struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 
 void enable_usboh3_clk(unsigned char enable)
 {
@@ -92,7 +93,7 @@ static u32 get_mcu_main_clk(void)
 	return freq / (reg + 1);
 }
 
-static u32 get_periph_clk(void)
+u32 get_periph_clk(void)
 {
 	u32 reg, freq = 0;
 
@@ -139,18 +140,6 @@ static u32 get_periph_clk(void)
 	return freq;
 }
 
-
-static u32 get_ahb_clk(void)
-{
-	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);
-}
-
 static u32 get_ipg_clk(void)
 {
 	u32 reg, ipg_podf;
@@ -303,6 +292,37 @@ u32 imx_get_fecclk(void)
 	return decode_pll(PLL_ENET, CONFIG_SYS_MX6_HCLK);
 }
 
+int enable_sata_clock(void)
+{
+	u32 reg = 0;
+	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 */
+	reg |= MXC_CCM_CCGR5_CG2_MASK;
+	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;
+	while (timeout--) {
+		if (readl(&imx_ccm->analog_pll_enet) & BM_ANADIG_PLL_SYS_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_ENABLE_SATA;
+	writel(reg, &imx_ccm->analog_pll_enet);
+
+	return 0 ;
+}
+
 unsigned int mxc_get_clock(enum mxc_clock clk)
 {
 	switch (clk) {

+ 3 - 2
arch/arm/cpu/armv7/mx6/lowlevel_init.S

@@ -18,7 +18,8 @@
  */
 .section ".text.init", "x"
 
-.globl lowlevel_init
-lowlevel_init:
+#include <linux/linkage.h>
 
+ENTRY(lowlevel_init)
 	mov pc, lr
+ENDPROC(lowlevel_init)

+ 30 - 0
arch/arm/cpu/armv7/mx6/soc.c

@@ -77,10 +77,40 @@ void init_aips(void)
 	writel(0x00000000, &aips2->opacr4);
 }
 
+/*
+ * Set the VDDSOC
+ *
+ * Mask out the REG_CORE[22:18] bits (REG2_TRIG) and set
+ * them to the specified millivolt level.
+ * Possible values are from 0.725V to 1.450V in steps of
+ * 0.025V (25mV).
+ */
+void set_vddsoc(u32 mv)
+{
+	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+	u32 val, reg = readl(&anatop->reg_core);
+
+	if (mv < 725)
+		val = 0x00;	/* Power gated off */
+	else if (mv > 1450)
+		val = 0x1F;	/* Power FET switched full on. No regulation */
+	else
+		val = (mv - 700) / 25;
+
+	/*
+	 * Mask out the REG_CORE[22:18] bits (REG2_TRIG)
+	 * and set them to the calculated value (0.7V + val * 0.25V)
+	 */
+	reg = (reg & ~(0x1F << 18)) | (val << 18);
+	writel(reg, &anatop->reg_core);
+}
+
 int arch_cpu_init(void)
 {
 	init_aips();
 
+	set_vddsoc(1200);	/* Set VDDSOC to 1.2V */
+
 	return 0;
 }
 #endif

+ 1 - 0
arch/arm/cpu/armv7/omap-common/Makefile

@@ -37,6 +37,7 @@ ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
 COBJS	+= hwinit-common.o
 COBJS	+= clocks-common.o
 COBJS	+= emif-common.o
+COBJS	+= vc.o
 endif
 
 ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)

+ 42 - 57
arch/arm/cpu/armv7/omap-common/clocks-common.c

@@ -245,6 +245,11 @@ void configure_mpu_dpll(void)
 			CM_CLKSEL_DCC_EN_MASK);
 	}
 
+	setbits_le32(&prcm->cm_mpu_mpu_clkctrl,
+		MPU_CLKCTRL_CLKSEL_EMIF_DIV_MODE_MASK);
+	setbits_le32(&prcm->cm_mpu_mpu_clkctrl,
+		MPU_CLKCTRL_CLKSEL_ABE_DIV_MODE_MASK);
+
 	params = get_mpu_dpll_params();
 
 	do_setup_dpll(&prcm->cm_clkmode_dpll_mpu, params, DPLL_LOCK, "mpu");
@@ -360,56 +365,51 @@ static void setup_non_essential_dplls(void)
 }
 #endif
 
-void do_scale_tps62361(u32 reg, u32 volt_mv)
+void do_scale_tps62361(int gpio, u32 reg, u32 volt_mv)
 {
-	u32 temp, step;
+	u32 step;
+	int ret = 0;
+
+	/* See if we can first get the GPIO if needed */
+	if (gpio >= 0)
+		ret = gpio_request(gpio, "TPS62361_VSEL0_GPIO");
+	if (ret < 0) {
+		printf("%s: gpio %d request failed %d\n", __func__, gpio, ret);
+		gpio = -1;
+	}
+
+	/* Pull the GPIO low to select SET0 register, while we program SET1 */
+	if (gpio >= 0)
+		gpio_direction_output(gpio, 0);
 
 	step = volt_mv - TPS62361_BASE_VOLT_MV;
 	step /= 10;
 
-	temp = TPS62361_I2C_SLAVE_ADDR |
-	    (reg << PRM_VC_VAL_BYPASS_REGADDR_SHIFT) |
-	    (step << PRM_VC_VAL_BYPASS_DATA_SHIFT) |
-	    PRM_VC_VAL_BYPASS_VALID_BIT;
 	debug("do_scale_tps62361: volt - %d step - 0x%x\n", volt_mv, step);
-
-	writel(temp, &prcm->prm_vc_val_bypass);
-	if (!wait_on_value(PRM_VC_VAL_BYPASS_VALID_BIT, 0,
-				&prcm->prm_vc_val_bypass, LDELAY)) {
+	if (omap_vc_bypass_send_value(TPS62361_I2C_SLAVE_ADDR, reg, step))
 		puts("Scaling voltage failed for vdd_mpu from TPS\n");
-	}
+
+	/* Pull the GPIO high to select SET1 register */
+	if (gpio >= 0)
+		gpio_direction_output(gpio, 1);
 }
 
 void do_scale_vcore(u32 vcore_reg, u32 volt_mv)
 {
-	u32 temp, offset_code;
-	u32 step = 12660; /* 12.66 mV represented in uV */
+	u32 offset_code;
 	u32 offset = volt_mv;
 
 	/* convert to uV for better accuracy in the calculations */
 	offset *= 1000;
 
-	if (omap_revision() == OMAP4430_ES1_0)
-		offset -= PHOENIX_SMPS_BASE_VOLT_STD_MODE_UV;
-	else
-		offset -= PHOENIX_SMPS_BASE_VOLT_STD_MODE_WITH_OFFSET_UV;
-
-	offset_code = (offset + step - 1) / step;
-	/* The code starts at 1 not 0 */
-	offset_code++;
+	offset_code = get_offset_code(offset);
 
 	debug("do_scale_vcore: volt - %d offset_code - 0x%x\n", volt_mv,
 		offset_code);
 
-	temp = SMPS_I2C_SLAVE_ADDR |
-	    (vcore_reg << PRM_VC_VAL_BYPASS_REGADDR_SHIFT) |
-	    (offset_code << PRM_VC_VAL_BYPASS_DATA_SHIFT) |
-	    PRM_VC_VAL_BYPASS_VALID_BIT;
-	writel(temp, &prcm->prm_vc_val_bypass);
-	if (!wait_on_value(PRM_VC_VAL_BYPASS_VALID_BIT, 0,
-				&prcm->prm_vc_val_bypass, LDELAY)) {
+	if (omap_vc_bypass_send_value(SMPS_I2C_SLAVE_ADDR,
+				vcore_reg, offset_code))
 		printf("Scaling voltage failed for 0x%x\n", vcore_reg);
-	}
 }
 
 static inline void enable_clock_domain(u32 *const clkctrl_reg, u32 enable_mode)
@@ -452,6 +452,7 @@ void freq_update_core(void)
 {
 	u32 freq_config1 = 0;
 	const struct dpll_params *core_dpll_params;
+	u32 omap_rev = omap_revision();
 
 	core_dpll_params = get_core_dpll_params();
 	/* Put EMIF clock domain in sw wakeup mode */
@@ -477,11 +478,18 @@ void freq_update_core(void)
 		hang();
 	}
 
-	/* Put EMIF clock domain back in hw auto mode */
-	enable_clock_domain(&prcm->cm_memif_clkstctrl,
-				CD_CLKCTRL_CLKTRCTRL_HW_AUTO);
-	wait_for_clk_enable(&prcm->cm_memif_emif_1_clkctrl);
-	wait_for_clk_enable(&prcm->cm_memif_emif_2_clkctrl);
+	/*
+	 * Putting EMIF in HW_AUTO is seen to be causing issues with
+	 * EMIF clocks and the master DLL. Put EMIF in SW_WKUP
+	 * in OMAP5430 ES1.0 silicon
+	 */
+	if (omap_rev != OMAP5430_ES1_0) {
+		/* Put EMIF clock domain back in hw auto mode */
+		enable_clock_domain(&prcm->cm_memif_clkstctrl,
+					CD_CLKCTRL_CLKTRCTRL_HW_AUTO);
+		wait_for_clk_enable(&prcm->cm_memif_emif_1_clkctrl);
+		wait_for_clk_enable(&prcm->cm_memif_emif_2_clkctrl);
+	}
 }
 
 void bypass_dpll(u32 *const base)
@@ -529,29 +537,6 @@ void setup_clocks_for_console(void)
 			CD_CLKCTRL_CLKTRCTRL_SHIFT);
 }
 
-void setup_sri2c(void)
-{
-	u32 sys_clk_khz, cycles_hi, cycles_low, temp;
-
-	sys_clk_khz = get_sys_clk_freq() / 1000;
-
-	/*
-	 * Setup the dedicated I2C controller for Voltage Control
-	 * I2C clk - high period 40% low period 60%
-	 */
-	cycles_hi = sys_clk_khz * 4 / PRM_VC_I2C_CHANNEL_FREQ_KHZ / 10;
-	cycles_low = sys_clk_khz * 6 / PRM_VC_I2C_CHANNEL_FREQ_KHZ / 10;
-	/* values to be set in register - less by 5 & 7 respectively */
-	cycles_hi -= 5;
-	cycles_low -= 7;
-	temp = (cycles_hi << PRM_VC_CFG_I2C_CLK_SCLH_SHIFT) |
-	       (cycles_low << PRM_VC_CFG_I2C_CLK_SCLL_SHIFT);
-	writel(temp, &prcm->prm_vc_cfg_i2c_clk);
-
-	/* Disable high speed mode and all advanced features */
-	writel(0x0, &prcm->prm_vc_cfg_i2c_mode);
-}
-
 void do_enable_clocks(u32 *const *clk_domains,
 			    u32 *const *clk_modules_hw_auto,
 			    u32 *const *clk_modules_explicit_en,

+ 39 - 2
arch/arm/cpu/armv7/omap-common/emif-common.c

@@ -90,20 +90,33 @@ static void do_lpddr2_init(u32 base, u32 cs)
 	 * tZQINIT = 1 us
 	 * Enough loops assuming a maximum of 2GHz
 	 */
+
 	sdelay(2000);
-	set_mr(base, cs, LPDDR2_MR1, MR1_BL_8_BT_SEQ_WRAP_EN_NWR_3);
+
+	if (omap_revision() >= OMAP5430_ES1_0)
+		set_mr(base, cs, LPDDR2_MR1, MR1_BL_8_BT_SEQ_WRAP_EN_NWR_8);
+	else
+		set_mr(base, cs, LPDDR2_MR1, MR1_BL_8_BT_SEQ_WRAP_EN_NWR_3);
+
 	set_mr(base, cs, LPDDR2_MR16, MR16_REF_FULL_ARRAY);
+
 	/*
 	 * Enable refresh along with writing MR2
 	 * Encoding of RL in MR2 is (RL - 2)
 	 */
 	mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK;
 	set_mr(base, cs, mr_addr, RL_FINAL - 2);
+
+	if (omap_revision() >= OMAP5430_ES1_0)
+		set_mr(base, cs, LPDDR2_MR3, 0x1);
 }
 
 static void lpddr2_init(u32 base, const struct emif_regs *regs)
 {
 	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+	u32 *ext_phy_ctrl_base = 0;
+	u32 *emif_ext_phy_ctrl_base = 0;
+	u32 i = 0;
 
 	/* Not NVM */
 	clrbits_le32(&emif->emif_lpddr2_nvm_config, EMIF_REG_CS1NVMEN_MASK);
@@ -119,7 +132,31 @@ static void lpddr2_init(u32 base, const struct emif_regs *regs)
 	 * un-locked frequency & default RL
 	 */
 	writel(regs->sdram_config_init, &emif->emif_sdram_config);
-	writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1);
+	writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1);
+
+	ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1);
+	emif_ext_phy_ctrl_base = (u32 *) &(emif->emif_ddr_ext_phy_ctrl_1);
+
+	if (omap_revision() >= OMAP5430_ES1_0) {
+		/* Configure external phy control timing registers */
+		for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) {
+			writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++);
+			/* Update shadow registers */
+			writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++);
+		}
+
+		/*
+		 * external phy 6-24 registers do not change with
+		 * ddr frequency
+		 */
+		for (i = 0; i < EMIF_EXT_PHY_CTRL_CONST_REG; i++) {
+			writel(ext_phy_ctrl_const_base[i],
+						emif_ext_phy_ctrl_base++);
+			/* Update shadow registers */
+			writel(ext_phy_ctrl_const_base[i],
+						emif_ext_phy_ctrl_base++);
+		}
+	}
 
 	do_lpddr2_init(base, CS0);
 	if (regs->sdram_config & EMIF_REG_EBANK_MASK)

+ 5 - 11
arch/arm/cpu/armv7/omap-common/hwinit-common.c

@@ -202,22 +202,16 @@ int checkboard(void)
 	return 0;
 }
 
-/*
-* This function is called by start_armboot. You can reliably use static
-* data. Any boot-time function that require static data should be
-* called from here
-*/
-int arch_cpu_init(void)
-{
-	return 0;
-}
-
 /*
  *  get_device_type(): tell if GP/HS/EMU/TST
  */
 u32 get_device_type(void)
 {
-	return 0;
+	struct omap_sys_ctrl_regs *ctrl =
+		      (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE;
+
+	return (readl(&ctrl->control_status) &
+				      (DEVICE_TYPE_MASK)) >> DEVICE_TYPE_SHIFT;
 }
 
 /*

+ 7 - 7
arch/arm/cpu/armv7/omap-common/lowlevel_init.S

@@ -27,9 +27,9 @@
  */
 
 #include <asm/arch/omap.h>
+#include <linux/linkage.h>
 
-.global save_boot_params
-save_boot_params:
+ENTRY(save_boot_params)
 	/*
 	 * See if the rom code passed pointer is valid:
 	 * It is not valid if it is not in non-secure SRAM
@@ -76,10 +76,9 @@ save_boot_params:
 	strb	r2, [r3, #CH_FLAGS_OFFSET]
 1:
 	bx	lr
+ENDPROC(save_boot_params)
 
-
-.globl lowlevel_init
-lowlevel_init:
+ENTRY(lowlevel_init)
 	/*
 	 * Setup a temporary stack
 	 */
@@ -95,12 +94,13 @@ lowlevel_init:
 	 */
 	bl	s_init
 	pop	{ip, pc}
+ENDPROC(lowlevel_init)
 
-.globl set_pl310_ctrl_reg
-set_pl310_ctrl_reg:
+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
 	.word	0xe1600070	@ SMC #0 - hand assembled because -march=armv5
 				@ call ROM Code API to set control register
 	POP	{r4-r11, pc}
+ENDPROC(set_pl310_ctrl_reg)

+ 14 - 16
arch/arm/cpu/armv7/omap-common/reset.S → arch/arm/cpu/armv7/omap-common/reset.c

@@ -1,6 +1,11 @@
 /*
- * Copyright (c) 2009 Samsung Electronics.
- * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * Common layer for reset related functionality of OMAP based socs.
+ *
+ * (C) Copyright 2012
+ * Texas Instruments, <www.ti.com>
+ *
+ * Sricharan R <r.sricharan@ti.com>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -20,19 +25,12 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
  */
-
 #include <config.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <linux/compiler.h>
 
-.global reset_cpu
-reset_cpu:
-	ldr	r1, rstctl			@ get addr for global reset
-						@ reg
-	ldr	r3, rstbit			@ sw reset bit
-	str	r3, [r1]			@ force reset
-	mov	r0, r0
-_loop_forever:
-	b	_loop_forever
-rstctl:
-	.word	PRM_RSTCTRL
-rstbit:
-	.word	PRM_RSTCTRL_RESET
+void __weak reset_cpu(unsigned long ignored)
+{
+	writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL);
+}

+ 1 - 0
arch/arm/cpu/armv7/omap-common/spl.c

@@ -162,6 +162,7 @@ void board_init_r(gd_t *id, ulong dummy)
 #ifdef CONFIG_SPL_MMC_SUPPORT
 	case BOOT_DEVICE_MMC1:
 	case BOOT_DEVICE_MMC2:
+	case BOOT_DEVICE_MMC2_2:
 		spl_mmc_load_image();
 		break;
 #endif

+ 3 - 2
arch/arm/cpu/armv7/omap-common/spl_mmc.c

@@ -39,10 +39,11 @@ int board_mmc_init(bd_t *bis)
 {
 	switch (omap_boot_device()) {
 	case BOOT_DEVICE_MMC1:
-		omap_mmc_init(0);
+		omap_mmc_init(0, 0, 0);
 		break;
 	case BOOT_DEVICE_MMC2:
-		omap_mmc_init(1);
+	case BOOT_DEVICE_MMC2_2:
+		omap_mmc_init(1, 0, 0);
 		break;
 	}
 	return 0;

+ 138 - 0
arch/arm/cpu/armv7/omap-common/vc.c

@@ -0,0 +1,138 @@
+/*
+ * Voltage Controller implementation for OMAP
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *	Nishanth Menon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/omap_common.h>
+#include <asm/arch/sys_proto.h>
+
+/*
+ * Define Master code if there are multiple masters on the I2C_SR bus.
+ * Normally not required
+ */
+#ifndef CONFIG_OMAP_VC_I2C_HS_MCODE
+#define CONFIG_OMAP_VC_I2C_HS_MCODE 0x0
+#endif
+
+/* Register defines and masks for VC IP Block */
+/* PRM_VC_CFG_I2C_MODE */
+#define PRM_VC_CFG_I2C_MODE_DFILTEREN_BIT	(0x1 << 6)
+#define PRM_VC_CFG_I2C_MODE_SRMODEEN_BIT	(0x1 << 4)
+#define PRM_VC_CFG_I2C_MODE_HSMODEEN_BIT	(0x1 << 3)
+#define PRM_VC_CFG_I2C_MODE_HSMCODE_SHIFT	0x0
+#define PRM_VC_CFG_I2C_MODE_HSMCODE_MASK	0x3
+
+/* PRM_VC_CFG_I2C_CLK */
+#define PRM_VC_CFG_I2C_CLK_HSCLL_SHIFT		24
+#define PRM_VC_CFG_I2C_CLK_HSCLL_MASK		0xFF
+#define PRM_VC_CFG_I2C_CLK_HSCLH_SHIFT		16
+#define PRM_VC_CFG_I2C_CLK_HSCLH_MASK		0xFF
+#define PRM_VC_CFG_I2C_CLK_SCLH_SHIFT		0
+#define PRM_VC_CFG_I2C_CLK_SCLH_MASK		0xFF
+#define PRM_VC_CFG_I2C_CLK_SCLL_SHIFT		8
+#define PRM_VC_CFG_I2C_CLK_SCLL_MASK		(0xFF << 8)
+
+/* PRM_VC_VAL_BYPASS */
+#define PRM_VC_VAL_BYPASS_VALID_BIT		(0x1 << 24)
+#define PRM_VC_VAL_BYPASS_SLAVEADDR_SHIFT	0
+#define PRM_VC_VAL_BYPASS_SLAVEADDR_MASK	0x7F
+#define PRM_VC_VAL_BYPASS_REGADDR_SHIFT		8
+#define PRM_VC_VAL_BYPASS_REGADDR_MASK		0xFF
+#define PRM_VC_VAL_BYPASS_DATA_SHIFT		16
+#define PRM_VC_VAL_BYPASS_DATA_MASK		0xFF
+
+/**
+ * omap_vc_init() - Initialization for Voltage controller
+ * @speed_khz: I2C buspeed in KHz
+ */
+void omap_vc_init(u16 speed_khz)
+{
+	u32 val;
+	u32 sys_clk_khz, cycles_hi, cycles_low;
+
+	sys_clk_khz = get_sys_clk_freq() / 1000;
+
+	if (speed_khz > 400) {
+		puts("higher speed requested - throttle to 400Khz\n");
+		speed_khz = 400;
+	}
+
+	/*
+	 * Setup the dedicated I2C controller for Voltage Control
+	 * I2C clk - high period 40% low period 60%
+	 */
+	speed_khz /= 10;
+	cycles_hi = sys_clk_khz * 4 / speed_khz;
+	cycles_low = sys_clk_khz * 6 / speed_khz;
+	/* values to be set in register - less by 5 & 7 respectively */
+	cycles_hi -= 5;
+	cycles_low -= 7;
+	val = (cycles_hi << PRM_VC_CFG_I2C_CLK_SCLH_SHIFT) |
+	       (cycles_low << PRM_VC_CFG_I2C_CLK_SCLL_SHIFT);
+	writel(val, &prcm->prm_vc_cfg_i2c_clk);
+
+	val = CONFIG_OMAP_VC_I2C_HS_MCODE <<
+		PRM_VC_CFG_I2C_MODE_HSMCODE_SHIFT;
+	/* No HS mode for now */
+	val &= ~PRM_VC_CFG_I2C_MODE_HSMODEEN_BIT;
+	writel(val, &prcm->prm_vc_cfg_i2c_mode);
+}
+
+/**
+ * omap_vc_bypass_send_value() - Send a data using VC Bypass command
+ * @sa:		7 bit I2C slave address of the PMIC
+ * @reg_addr:	I2C register address(8 bit) address in PMIC
+ * @reg_data:	what 8 bit data to write
+ */
+int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data)
+{
+	/*
+	 * Unfortunately we need to loop here instead of a defined time
+	 * use arbitary large value
+	 */
+	u32 timeout = 0xFFFF;
+	u32 reg_val;
+
+	sa &= PRM_VC_VAL_BYPASS_SLAVEADDR_MASK;
+	reg_addr &= PRM_VC_VAL_BYPASS_REGADDR_MASK;
+	reg_data &= PRM_VC_VAL_BYPASS_DATA_MASK;
+
+	/* program VC to send data */
+	reg_val = sa << PRM_VC_VAL_BYPASS_SLAVEADDR_SHIFT |
+	    reg_addr << PRM_VC_VAL_BYPASS_REGADDR_SHIFT |
+	    reg_data << PRM_VC_VAL_BYPASS_DATA_SHIFT;
+	writel(reg_val, &prcm->prm_vc_val_bypass);
+
+	/* Signal VC to send data */
+	writel(reg_val | PRM_VC_VAL_BYPASS_VALID_BIT, &prcm->prm_vc_val_bypass);
+
+	/* Wait on VC to complete transmission */
+	do {
+		reg_val = readl(&prcm->prm_vc_val_bypass) &
+				PRM_VC_VAL_BYPASS_VALID_BIT;
+		if (!reg_val)
+			break;
+
+		sdelay(100);
+	} while (--timeout);
+
+	/* Optional: cleanup PRM_IRQSTATUS_Ax */
+	/* In case we can do something about it in future.. */
+	if (!timeout)
+		return -1;
+
+	/* All good.. */
+	return 0;
+}

+ 12 - 0
arch/arm/cpu/armv7/omap3/board.c

@@ -41,6 +41,7 @@
 #include <asm/arch/gpio.h>
 #include <asm/omap_common.h>
 #include <i2c.h>
+#include <linux/compiler.h>
 
 /* Declarations */
 extern omap3_sysinfo sysinfo;
@@ -244,6 +245,17 @@ void s_init(void)
 		mem_init();
 }
 
+/*
+ * Routine: misc_init_r
+ * Description: A basic misc_init_r that just displays the die ID
+ */
+int __weak misc_init_r(void)
+{
+	dieid_num_r();
+
+	return 0;
+}
+
 /******************************************************************************
  * Routine: wait_for_command_complete
  * Description: Wait for posting to finish on watchdog

+ 16 - 0
arch/arm/cpu/armv7/omap3/clock.c

@@ -572,6 +572,22 @@ void prcm_init(void)
 	}
 
 	if (get_cpu_family() == CPU_OMAP36XX) {
+		/*
+		 * In warm reset conditions on OMAP36xx/AM/DM37xx
+		 * the rom code incorrectly sets the DPLL4 clock
+		 * input divider to /6.5. Section 3.5.3.3.3.2.1 of
+		 * the AM/DM37x TRM explains that the /6.5 divider
+		 * is used only when the input clock is 13MHz.
+		 *
+		 * If the part is in this cpu family *and* the input
+		 * clock *is not* 13 MHz, then reset the DPLL4 clock
+		 * input divider to /1 as it should never set to /6.5
+		 * in this case.
+		 */
+		if (sys_clkin_sel != 1) /* 13 MHz */
+			/* Bit 8: DPLL4_CLKINP_DIV */
+			sr32(&prm_base->clksrc_ctrl, 8, 1, 0);
+
 		/* Unlock MPU DPLL (slows things down, and needed later) */
 		sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
 		wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,

+ 21 - 20
arch/arm/cpu/armv7/omap3/lowlevel_init.S

@@ -31,22 +31,22 @@
 #include <version.h>
 #include <asm/arch/mem.h>
 #include <asm/arch/clocks_omap3.h>
+#include <linux/linkage.h>
 
 _TEXT_BASE:
 	.word	CONFIG_SYS_TEXT_BASE	/* sdram load addr from config.mk */
 
 #ifdef CONFIG_SPL_BUILD
-.global save_boot_params
-save_boot_params:
+ENTRY(save_boot_params)
 	ldr	r4, =omap3_boot_device
 	ldr	r5, [r0, #0x4]
 	and	r5, r5, #0xff
 	str	r5, [r4]
 	bx	lr
+ENDPROC(save_boot_params)
 #endif
 
-.global omap3_gp_romcode_call
-omap3_gp_romcode_call:
+ENTRY(omap3_gp_romcode_call)
 	PUSH {r4-r12, lr} @ Save all registers from ROM code!
 	MOV r12, r0	@ Copy the Service ID in R12
 	MOV r0, r1	@ Copy parameter to R0
@@ -55,6 +55,7 @@ omap3_gp_romcode_call:
 	.word	0xe1600070	@ SMC #0 to enter monitor - hand assembled
 				@ because we use -march=armv5
 	POP {r4-r12, pc}
+ENDPROC(omap3_gp_romcode_call)
 
 /*
  * Funtion for making PPA HAL API calls in secure devices
@@ -62,8 +63,7 @@ omap3_gp_romcode_call:
  *	R0 - Service ID
  *	R1 - paramer list
  */
-.global do_omap3_emu_romcode_call
-do_omap3_emu_romcode_call:
+ENTRY(do_omap3_emu_romcode_call)
 	PUSH {r4-r12, lr} @ Save all registers from ROM code!
 	MOV r12, r0	@ Copy the Secure Service ID in R12
 	MOV r3, r1	@ Copy the pointer to va_list in R3
@@ -76,14 +76,14 @@ do_omap3_emu_romcode_call:
 	.word	0xe1600071	@ SMC #1 to call PPA service - hand assembled
 				@ because we use -march=armv5
 	POP {r4-r12, pc}
+ENDPROC(do_omap3_emu_romcode_call)
 
 #if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_NAND_BOOT)
 /**************************************************************************
  * cpy_clk_code: relocates clock code into SRAM where its safer to execute
  * R1 = SRAM destination address.
  *************************************************************************/
-.global cpy_clk_code
- cpy_clk_code:
+ENTRY(cpy_clk_code)
 	/* Copy DPLL code into SRAM */
 	adr	r0, go_to_speed		/* get addr of clock setting code */
 	mov	r2, #384		/* r2 size to copy (div by 32 bytes) */
@@ -95,6 +95,7 @@ next2:
 	cmp	r0, r2			/* until source end address [r2] */
 	bne	next2
 	mov	pc, lr			/* back to caller */
+ENDPROC(cpy_clk_code)
 
 /* ***************************************************************************
  *  go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed
@@ -109,8 +110,7 @@ next2:
  *        L3 when its not in self refresh seems bad for it.  Normally, this
  *	  code runs from flash before SDR is init so that should be ok.
  ****************************************************************************/
-.global go_to_speed
- go_to_speed:
+ENTRY(go_to_speed)
 	stmfd sp!, {r4 - r6}
 
 	/* move into fast relock bypass */
@@ -171,6 +171,7 @@ wait2:
 	nop
 	ldmfd	sp!, {r4 - r6}
 	mov	pc, lr		/* back to caller, locked */
+ENDPROC(go_to_speed)
 
 _go_to_speed: .word go_to_speed
 
@@ -211,8 +212,7 @@ pll_div_val5:
 
 #endif
 
-.globl lowlevel_init
-lowlevel_init:
+ENTRY(lowlevel_init)
 	ldr	sp, SRAM_STACK
 	str	ip, [sp]	/* stash old link register */
 	mov	ip, lr		/* save link reg across call */
@@ -230,6 +230,7 @@ lowlevel_init:
 
 	/* back to arch calling code */
 	mov	pc, lr
+ENDPROC(lowlevel_init)
 
 	/* the literal pools origin */
 	.ltorg
@@ -480,22 +481,22 @@ per_36x_dpll_param:
 .word 26000,    432,   12,     9,      16,     9,     4,      3,      1
 .word 38400,    360,   15,     9,      16,     5,     4,      3,      1
 
-.globl get_36x_mpu_dpll_param
-get_36x_mpu_dpll_param:
+ENTRY(get_36x_mpu_dpll_param)
 	adr	r0, mpu_36x_dpll_param
 	mov	pc, lr
+ENDPROC(get_36x_mpu_dpll_param)
 
-.globl get_36x_iva_dpll_param
-get_36x_iva_dpll_param:
+ENTRY(get_36x_iva_dpll_param)
 	adr	r0, iva_36x_dpll_param
 	mov	pc, lr
+ENDPROC(get_36x_iva_dpll_param)
 
-.globl get_36x_core_dpll_param
-get_36x_core_dpll_param:
+ENTRY(get_36x_core_dpll_param)
 	adr	r0, core_36x_dpll_param
 	mov	pc, lr
+ENDPROC(get_36x_core_dpll_param)
 
-.globl get_36x_per_dpll_param
-get_36x_per_dpll_param:
+ENTRY(get_36x_per_dpll_param)
 	adr	r0, per_36x_dpll_param
 	mov	pc, lr
+ENDPROC(get_36x_per_dpll_param)

+ 50 - 35
arch/arm/cpu/armv7/omap4/clocks.c

@@ -46,8 +46,6 @@
 #define puts(s)
 #endif
 
-#define abs(x) (((x) < 0) ? ((x)*-1) : (x))
-
 struct omap4_prcm_regs *const prcm = (struct omap4_prcm_regs *)0x4A004100;
 
 const u32 sys_clk_array[8] = {
@@ -275,47 +273,70 @@ void scale_vcores(void)
 {
 	u32 volt, omap_rev;
 
-	setup_sri2c();
+	omap_vc_init(PRM_VC_I2C_CHANNEL_FREQ_KHZ);
 
 	omap_rev = omap_revision();
-	/* TPS - supplies vdd_mpu on 4460 */
-	if (omap_rev >= OMAP4460_ES1_0) {
-		volt = 1203;
-		do_scale_tps62361(TPS62361_REG_ADDR_SET1, volt);
-	}
 
 	/*
-	 * VCORE 1
-	 *
-	 * 4430 : supplies vdd_mpu
-	 * Setting a high voltage for Nitro mode as smart reflex is not enabled.
-	 * We use the maximum possible value in the AVS range because the next
-	 * higher voltage in the discrete range (code >= 0b111010) is way too
-	 * high
-	 *
-	 * 4460 : supplies vdd_core
+	 * Scale Voltage rails:
+	 * 1. VDD_CORE
+	 * 3. VDD_MPU
+	 * 3. VDD_IVA
 	 */
 	if (omap_rev < OMAP4460_ES1_0) {
+		/*
+		 * OMAP4430:
+		 * VDD_CORE = TWL6030 VCORE3
+		 * VDD_MPU = TWL6030 VCORE1
+		 * VDD_IVA = TWL6030 VCORE2
+		 */
+		volt = 1200;
+		do_scale_vcore(SMPS_REG_ADDR_VCORE3, volt);
+
+		/*
+		 * note on VDD_MPU:
+		 * Setting a high voltage for Nitro mode as smart reflex is not
+		 * enabled. We use the maximum possible value in the AVS range
+		 * because the next higher voltage in the discrete range
+		 * (code >= 0b111010) is way too high.
+		 */
 		volt = 1325;
 		do_scale_vcore(SMPS_REG_ADDR_VCORE1, volt);
+		volt = 1200;
+		do_scale_vcore(SMPS_REG_ADDR_VCORE2, volt);
+
 	} else {
+		/*
+		 * OMAP4460:
+		 * VDD_CORE = TWL6030 VCORE1
+		 * VDD_MPU = TPS62361
+		 * VDD_IVA = TWL6030 VCORE2
+		 */
 		volt = 1200;
 		do_scale_vcore(SMPS_REG_ADDR_VCORE1, volt);
+		/* TPS62361 */
+		volt = 1203;
+		do_scale_tps62361(TPS62361_VSEL0_GPIO,
+				  TPS62361_REG_ADDR_SET1, volt);
+		/* VCORE 2 - supplies vdd_iva */
+		volt = 1200;
+		do_scale_vcore(SMPS_REG_ADDR_VCORE2, volt);
 	}
+}
 
-	/* VCORE 2 - supplies vdd_iva */
-	volt = 1200;
-	do_scale_vcore(SMPS_REG_ADDR_VCORE2, volt);
+u32 get_offset_code(u32 offset)
+{
+	u32 offset_code, step = 12660; /* 12.66 mV represented in uV */
 
-	/*
-	 * VCORE 3
-	 * 4430 : supplies vdd_core
-	 * 4460 : not connected
-	 */
-	if (omap_rev < OMAP4460_ES1_0) {
-		volt = 1200;
-		do_scale_vcore(SMPS_REG_ADDR_VCORE3, volt);
-	}
+	if (omap_revision() == OMAP4430_ES1_0)
+		offset -= PHOENIX_SMPS_BASE_VOLT_STD_MODE_UV;
+	else
+		offset -= PHOENIX_SMPS_BASE_VOLT_STD_MODE_WITH_OFFSET_UV;
+
+	offset_code = (offset + step - 1) / step;
+
+	/* The code starts at 1 not 0 */
+	return ++offset_code;
 }
 
 /*
@@ -355,7 +376,6 @@ void enable_basic_clocks(void)
 		&prcm->cm_l4per_gptimer2_clkctrl,
 		&prcm->cm_wkup_wdtimer2_clkctrl,
 		&prcm->cm_l4per_uart3_clkctrl,
-		&prcm->cm_l3init_fsusb_clkctrl,
 		&prcm->cm_l3init_hsusbhost_clkctrl,
 		0
 	};
@@ -432,10 +452,6 @@ void enable_non_essential_clocks(void)
 	};
 
 	u32 *const clk_modules_hw_auto_non_essential[] = {
-		&prcm->cm_mpu_m3_mpu_m3_clkctrl,
-		&prcm->cm_ivahd_ivahd_clkctrl,
-		&prcm->cm_ivahd_sl2_clkctrl,
-		&prcm->cm_dsp_dsp_clkctrl,
 		&prcm->cm_l3_2_gpmc_clkctrl,
 		&prcm->cm_l3instr_l3_3_clkctrl,
 		&prcm->cm_l3instr_l3_instr_clkctrl,
@@ -482,7 +498,6 @@ void enable_non_essential_clocks(void)
 		&prcm->cm_dss_dss_clkctrl,
 		&prcm->cm_sgx_sgx_clkctrl,
 		&prcm->cm_l3init_hsusbhost_clkctrl,
-		&prcm->cm_l3init_fsusb_clkctrl,
 		0
 	};
 

+ 12 - 12
arch/arm/cpu/armv7/omap4/hwinit.c

@@ -37,7 +37,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-u32 *const omap4_revision = (u32 *)OMAP4_SRAM_SCRATCH_OMAP4_REV;
+u32 *const omap_si_rev = (u32 *)OMAP4_SRAM_SCRATCH_OMAP4_REV;
 
 static const struct gpio_bank gpio_bank_44xx[6] = {
 	{ (void *)OMAP44XX_GPIO1_BASE, METHOD_GPIO_24XX },
@@ -59,8 +59,8 @@ void do_io_settings(void)
 	u32 lpddr2io;
 	struct control_lpddr2io_regs *lpddr2io_regs =
 		(struct control_lpddr2io_regs *)LPDDR2_IO_REGS_BASE;
-	struct omap4_sys_ctrl_regs *const ctrl =
-		(struct omap4_sys_ctrl_regs *)SYSCTRL_GENERAL_CORE_BASE;
+	struct omap_sys_ctrl_regs *const ctrl =
+		(struct omap_sys_ctrl_regs *)SYSCTRL_GENERAL_CORE_BASE;
 
 	u32 omap4_rev = omap_revision();
 
@@ -129,40 +129,40 @@ void init_omap_revision(void)
 
 	switch (arm_rev) {
 	case MIDR_CORTEX_A9_R0P1:
-		*omap4_revision = OMAP4430_ES1_0;
+		*omap_si_rev = OMAP4430_ES1_0;
 		break;
 	case MIDR_CORTEX_A9_R1P2:
 		switch (readl(CONTROL_ID_CODE)) {
 		case OMAP4_CONTROL_ID_CODE_ES2_0:
-			*omap4_revision = OMAP4430_ES2_0;
+			*omap_si_rev = OMAP4430_ES2_0;
 			break;
 		case OMAP4_CONTROL_ID_CODE_ES2_1:
-			*omap4_revision = OMAP4430_ES2_1;
+			*omap_si_rev = OMAP4430_ES2_1;
 			break;
 		case OMAP4_CONTROL_ID_CODE_ES2_2:
-			*omap4_revision = OMAP4430_ES2_2;
+			*omap_si_rev = OMAP4430_ES2_2;
 			break;
 		default:
-			*omap4_revision = OMAP4430_ES2_0;
+			*omap_si_rev = OMAP4430_ES2_0;
 			break;
 		}
 		break;
 	case MIDR_CORTEX_A9_R1P3:
-		*omap4_revision = OMAP4430_ES2_3;
+		*omap_si_rev = OMAP4430_ES2_3;
 		break;
 	case MIDR_CORTEX_A9_R2P10:
 		switch (readl(CONTROL_ID_CODE)) {
 		case OMAP4460_CONTROL_ID_CODE_ES1_1:
-			*omap4_revision = OMAP4460_ES1_1;
+			*omap_si_rev = OMAP4460_ES1_1;
 			break;
 		case OMAP4460_CONTROL_ID_CODE_ES1_0:
 		default:
-			*omap4_revision = OMAP4460_ES1_0;
+			*omap_si_rev = OMAP4460_ES1_0;
 			break;
 		}
 		break;
 	default:
-		*omap4_revision = OMAP4430_SILICON_ID_INVALID;
+		*omap_si_rev = OMAP4430_SILICON_ID_INVALID;
 		break;
 	}
 }

+ 4 - 0
arch/arm/cpu/armv7/omap4/sdram_elpida.c

@@ -89,6 +89,10 @@ const struct emif_regs emif_regs_elpida_400_mhz_2cs = {
 	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
 	.emif_ddr_phy_ctlr_1		= 0x049ff418
 };
+
+/* Dummy registers for OMAP44xx */
+const u32 ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG];
+
 const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = {
 	.dmm_lisa_map_0 = 0xFF020100,
 	.dmm_lisa_map_1 = 0,

+ 1 - 1
arch/arm/cpu/armv7/omap5/Makefile

@@ -28,7 +28,7 @@ LIB	=  $(obj)lib$(SOC).o
 COBJS	+= hwinit.o
 COBJS	+= clocks.o
 COBJS	+= emif.o
-COBJS	+= sdram_elpida.o
+COBJS	+= sdram.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))

+ 97 - 46
arch/arm/cpu/armv7/omap5/clocks.c

@@ -88,6 +88,26 @@ static const struct dpll_params mpu_dpll_params_1100mhz[NUM_SYS_CLKS] = {
 	{1375, 47, 1, -1, -1, -1, -1, -1, -1, -1}	/* 38.4 MHz */
 };
 
+static const struct dpll_params mpu_dpll_params_800mhz[NUM_SYS_CLKS] = {
+	{200, 2, 1, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{1000, 20, 1, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{375, 8, 1, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{400, 12, 1, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{375, 17, 1, -1, -1, -1, -1, -1, -1, -1}		/* 38.4 MHz */
+};
+
+static const struct dpll_params mpu_dpll_params_400mhz[NUM_SYS_CLKS] = {
+	{200, 2, 2, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{1000, 20, 2, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{375, 8, 2, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{400, 12, 2, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{375, 17, 2, -1, -1, -1, -1, -1, -1, -1}		/* 38.4 MHz */
+};
+
 static const struct dpll_params mpu_dpll_params_550mhz[NUM_SYS_CLKS] = {
 	{275, 2, 2, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
 	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
@@ -100,24 +120,24 @@ static const struct dpll_params mpu_dpll_params_550mhz[NUM_SYS_CLKS] = {
 
 static const struct dpll_params
 			core_dpll_params_2128mhz_ddr532[NUM_SYS_CLKS] = {
-	{266, 2, 1, 5, 8, 4, 62, 5, 5, 7},		/* 12 MHz   */
+	{266, 2, 2, 5, 8, 4, 62, 5, 5, 7},		/* 12 MHz   */
 	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
-	{570, 8, 1, 5, 8, 4, 62, 5, 5, 7},		/* 16.8 MHz */
-	{665, 11, 1, 5, 8, 4, 62, 5, 5, 7},		/* 19.2 MHz */
-	{532, 12, 1, 5, 8, 4, 62, 5, 5, 7},		/* 26 MHz   */
+	{570, 8, 2, 5, 8, 4, 62, 5, 5, 7},		/* 16.8 MHz */
+	{665, 11, 2, 5, 8, 4, 62, 5, 5, 7},		/* 19.2 MHz */
+	{532, 12, 2, 5, 8, 4, 62, 5, 5, 7},		/* 26 MHz   */
 	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
-	{665, 23, 1, 5, 8, 4, 62, 5, 5, 7}		/* 38.4 MHz */
+	{665, 23, 2, 5, 8, 4, 62, 5, 5, 7}		/* 38.4 MHz */
 };
 
 static const struct dpll_params
 			core_dpll_params_2128mhz_ddr266[NUM_SYS_CLKS] = {
-	{266, 2, 2, 5, 8, 4, 62, 5, 5, 7},		/* 12 MHz   */
+	{266, 2, 4, 5, 8, 8, 62, 10, 10, 14},		/* 12 MHz   */
 	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
-	{570, 8, 2, 5, 8, 4, 62, 5, 5, 7},		/* 16.8 MHz */
-	{665, 11, 2, 5, 8, 4, 62, 5, 5, 7},		/* 19.2 MHz */
-	{532, 12, 2, 5, 8, 4, 62, 5, 5, 7},		/* 26 MHz   */
+	{570, 8, 4, 5, 8, 8, 62, 10, 10, 14},		/* 16.8 MHz */
+	{665, 11, 4, 5, 8, 8, 62, 10, 10, 14},		/* 19.2 MHz */
+	{532, 12, 4, 8, 8, 8, 62, 10, 10, 14},		/* 26 MHz   */
 	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
-	{665, 23, 2, 5, 8, 4, 62, 5, 5, 7}		/* 38.4 MHz */
+	{665, 23, 4, 8, 8, 8, 62, 10, 10, 14}		/* 38.4 MHz */
 };
 
 static const struct dpll_params per_dpll_params_768mhz[NUM_SYS_CLKS] = {
@@ -131,40 +151,40 @@ static const struct dpll_params per_dpll_params_768mhz[NUM_SYS_CLKS] = {
 };
 
 static const struct dpll_params iva_dpll_params_2330mhz[NUM_SYS_CLKS] = {
-	{931, 11, -1, -1, 4, 7, -1, -1},	/* 12 MHz   */
-	{931, 12, -1, -1, 4, 7, -1, -1},	/* 13 MHz   */
-	{665, 11, -1, -1, 4, 7, -1, -1},	/* 16.8 MHz */
-	{727, 14, -1, -1, 4, 7, -1, -1},	/* 19.2 MHz */
-	{931, 25, -1, -1, 4, 7, -1, -1},	/* 26 MHz   */
-	{931, 26, -1, -1, 4, 7, -1, -1},	/* 27 MHz   */
-	{412, 16, -1, -1, 4, 7, -1, -1}		/* 38.4 MHz */
+	{1165, 11, -1, -1, 5, 6, -1, -1, -1, -1},	/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{2011, 28, -1, -1, 5, 6, -1, -1, -1, -1},	/* 16.8 MHz */
+	{1881, 30, -1, -1, 5, 6, -1, -1, -1, -1},	/* 19.2 MHz */
+	{1165, 25, -1, -1, 5, 6, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{1972, 64, -1, -1, 5, 6, -1, -1, -1, -1}	/* 38.4 MHz */
 };
 
 /* ABE M & N values with sys_clk as source */
 static const struct dpll_params
 		abe_dpll_params_sysclk_196608khz[NUM_SYS_CLKS] = {
-	{49, 5, 1, 1, -1, -1, -1, -1},	/* 12 MHz   */
-	{68, 8, 1, 1, -1, -1, -1, -1},	/* 13 MHz   */
-	{35, 5, 1, 1, -1, -1, -1, -1},	/* 16.8 MHz */
-	{46, 8, 1, 1, -1, -1, -1, -1},	/* 19.2 MHz */
-	{34, 8, 1, 1, -1, -1, -1, -1},	/* 26 MHz   */
-	{29, 7, 1, 1, -1, -1, -1, -1},	/* 27 MHz   */
-	{64, 24, 1, 1, -1, -1, -1, -1}	/* 38.4 MHz */
+	{49, 5, 1, -1, -1, -1, -1, -1, -1, -1},		/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{35, 5, 1, 1, -1, -1, -1, -1, -1, -1},		/* 16.8 MHz */
+	{46, 8, 1, 1, -1, -1, -1, -1, -1, -1},		/* 19.2 MHz */
+	{34, 8, 1, 1, -1, -1, -1, -1, -1, -1},		/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{64, 24, 1, 1, -1, -1, -1, -1, -1, -1}		/* 38.4 MHz */
 };
 
 /* ABE M & N values with 32K clock as source */
 static const struct dpll_params abe_dpll_params_32k_196608khz = {
-	750, 0, 1, 1, -1, -1, -1, -1
+	750, 0, 1, 1, -1, -1, -1, -1, -1, -1
 };
 
 static const struct dpll_params usb_dpll_params_1920mhz[NUM_SYS_CLKS] = {
-	{80, 0, 2, -1, -1, -1, -1, -1},		/* 12 MHz   */
-	{960, 12, 2, -1, -1, -1, -1, -1},	/* 13 MHz   */
-	{400, 6, 2, -1, -1, -1, -1, -1},	/* 16.8 MHz */
-	{50, 0, 2, -1, -1, -1, -1, -1},		/* 19.2 MHz */
-	{480, 12, 2, -1, -1, -1, -1, -1},	/* 26 MHz   */
-	{320, 8, 2, -1, -1, -1, -1, -1},	/* 27 MHz   */
-	{25, 0, 2, -1, -1, -1, -1, -1}		/* 38.4 MHz */
+	{400, 4, 2, -1, -1, -1, -1, -1, -1, -1},	/* 12 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 13 MHz   */
+	{400, 6, 2, -1, -1, -1, -1, -1, -1, -1},	/* 16.8 MHz */
+	{400, 7, 2, -1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+	{480, 12, 2, -1, -1, -1, -1, -1, -1, -1},	/* 26 MHz   */
+	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},	/* 27 MHz   */
+	{400, 15, 2, -1, -1, -1, -1, -1, -1, -1}	/* 38.4 MHz */
 };
 
 void setup_post_dividers(u32 *const base, const struct dpll_params *params)
@@ -193,7 +213,7 @@ void setup_post_dividers(u32 *const base, const struct dpll_params *params)
 const struct dpll_params *get_mpu_dpll_params(void)
 {
 	u32 sysclk_ind = get_sys_clk_index();
-	return &mpu_dpll_params_1100mhz[sysclk_ind];
+	return &mpu_dpll_params_800mhz[sysclk_ind];
 }
 
 const struct dpll_params *get_core_dpll_params(void)
@@ -201,8 +221,7 @@ const struct dpll_params *get_core_dpll_params(void)
 	u32 sysclk_ind = get_sys_clk_index();
 
 	/* Configuring the DDR to be at 532mhz */
-	return &core_dpll_params_2128mhz_ddr266[sysclk_ind];
-
+	return &core_dpll_params_2128mhz_ddr532[sysclk_ind];
 }
 
 const struct dpll_params *get_per_dpll_params(void)
@@ -243,19 +262,33 @@ void scale_vcores(void)
 {
 	u32 volt;
 
-	setup_sri2c();
+	omap_vc_init(PRM_VC_I2C_CHANNEL_FREQ_KHZ);
+
+	/* Palmas settings */
+	volt = VDD_CORE;
+	do_scale_vcore(SMPS_REG_ADDR_8_CORE, volt);
 
-	/* Enable 1.22V from TPS for vdd_mpu */
-	volt = 1220;
-	do_scale_tps62361(TPS62361_REG_ADDR_SET1, volt);
+	volt = VDD_MPU;
+	do_scale_vcore(SMPS_REG_ADDR_12_MPU, volt);
 
-	/* VCORE 1 - for vdd_core */
-	volt = 1000;
-	do_scale_vcore(SMPS_REG_ADDR_VCORE1, volt);
+	volt = VDD_MM;
+	do_scale_vcore(SMPS_REG_ADDR_45_IVA, volt);
 
-	/* VCORE 2 - for vdd_MM */
-	volt = 1125;
-	do_scale_vcore(SMPS_REG_ADDR_VCORE2, volt);
+}
+
+u32 get_offset_code(u32 volt_offset)
+{
+	u32 offset_code, step = 10000; /* 10 mV represented in uV */
+
+	volt_offset -= PALMAS_SMPS_BASE_VOLT_UV;
+
+	offset_code = (volt_offset + step - 1) / step;
+
+	/*
+	 * Offset codes 1-6 all give the base voltage in Palmas
+	 * Offset code 0 switches OFF the SMPS
+	 */
+	return offset_code + 6;
 }
 
 /*
@@ -306,6 +339,12 @@ void enable_basic_clocks(void)
 	setbits_le32(&prcm->cm_l3init_hsmmc2_clkctrl,
 			HSMMC_CLKCTRL_CLKSEL_MASK);
 
+	/* Set the correct clock dividers for mmc */
+	setbits_le32(&prcm->cm_l3init_hsmmc1_clkctrl,
+			HSMMC_CLKCTRL_CLKSEL_DIV_MASK);
+	setbits_le32(&prcm->cm_l3init_hsmmc2_clkctrl,
+			HSMMC_CLKCTRL_CLKSEL_DIV_MASK);
+
 	/* Select 32KHz clock as the source of GPTIMER1 */
 	setbits_le32(&prcm->cm_wkup_gptimer1_clkctrl,
 			GPTIMER1_CLKCTRL_CLKSEL_MASK);
@@ -314,6 +353,18 @@ void enable_basic_clocks(void)
 			 clk_modules_hw_auto_essential,
 			 clk_modules_explicit_en_essential,
 			 1);
+
+	/* Select 384Mhz for GPU as its the POR for ES1.0 */
+	setbits_le32(&prcm->cm_sgx_sgx_clkctrl,
+			CLKSEL_GPU_HYD_GCLK_MASK);
+	setbits_le32(&prcm->cm_sgx_sgx_clkctrl,
+			CLKSEL_GPU_CORE_GCLK_MASK);
+
+	/* Enable SCRM OPT clocks for PER and CORE dpll */
+	setbits_le32(&prcm->cm_wkupaon_scrm_clkctrl,
+			OPTFCLKEN_SCRM_PER_MASK);
+	setbits_le32(&prcm->cm_wkupaon_scrm_clkctrl,
+			OPTFCLKEN_SCRM_CORE_MASK);
 }
 
 void enable_basic_uboot_clocks(void)
@@ -371,6 +422,7 @@ void enable_non_essential_clocks(void)
 		&prcm->cm_l3instr_intrconn_wp1_clkctrl,
 		&prcm->cm_l3init_hsi_clkctrl,
 		&prcm->cm_l3init_hsusbtll_clkctrl,
+		&prcm->cm_l4per_hdq1w_clkctrl,
 		0
 	};
 
@@ -393,7 +445,6 @@ void enable_non_essential_clocks(void)
 		&prcm->cm_l4per_gptimer11_clkctrl,
 		&prcm->cm_l4per_gptimer3_clkctrl,
 		&prcm->cm_l4per_gptimer4_clkctrl,
-		&prcm->cm_l4per_hdq1w_clkctrl,
 		&prcm->cm_l4per_mcspi2_clkctrl,
 		&prcm->cm_l4per_mcspi3_clkctrl,
 		&prcm->cm_l4per_mcspi4_clkctrl,

+ 101 - 3
arch/arm/cpu/armv7/omap5/hwinit.c

@@ -38,7 +38,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-u32 *const omap5_revision = (u32 *)OMAP5_SRAM_SCRATCH_OMAP5_REV;
+u32 *const omap_si_rev = (u32 *)OMAP5_SRAM_SCRATCH_OMAP5_REV;
 
 static struct gpio_bank gpio_bank_54xx[6] = {
 	{ (void *)OMAP54XX_GPIO1_BASE, METHOD_GPIO_24XX },
@@ -57,6 +57,89 @@ const struct gpio_bank *const omap_gpio_bank = gpio_bank_54xx;
  */
 void do_io_settings(void)
 {
+	u32 io_settings = 0, mask = 0;
+	struct omap_sys_ctrl_regs *ioregs_base =
+		      (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE;
+
+	/* Impedance settings EMMC, C2C 1,2, hsi2 */
+	mask = (ds_mask << 2) | (ds_mask << 8) |
+		(ds_mask << 16) | (ds_mask << 18);
+	io_settings = readl(&(ioregs_base->control_smart1io_padconf_0)) &
+				(~mask);
+	io_settings |= (ds_60_ohm << 8) | (ds_45_ohm << 16) |
+			(ds_45_ohm << 18) | (ds_60_ohm << 2);
+	writel(io_settings, &(ioregs_base->control_smart1io_padconf_0));
+
+	/* Impedance settings Mcspi2 */
+	mask = (ds_mask << 30);
+	io_settings = readl(&(ioregs_base->control_smart1io_padconf_1)) &
+			(~mask);
+	io_settings |= (ds_60_ohm << 30);
+	writel(io_settings, &(ioregs_base->control_smart1io_padconf_1));
+
+	/* Impedance settings C2C 3,4 */
+	mask = (ds_mask << 14) | (ds_mask << 16);
+	io_settings = readl(&(ioregs_base->control_smart1io_padconf_2)) &
+			(~mask);
+	io_settings |= (ds_45_ohm << 14) | (ds_45_ohm << 16);
+	writel(io_settings, &(ioregs_base->control_smart1io_padconf_2));
+
+	/* Slew rate settings EMMC, C2C 1,2 */
+	mask = (sc_mask << 8) | (sc_mask << 16) | (sc_mask << 18);
+	io_settings = readl(&(ioregs_base->control_smart2io_padconf_0)) &
+			(~mask);
+	io_settings |= (sc_fast << 8) | (sc_na << 16) | (sc_na << 18);
+	writel(io_settings, &(ioregs_base->control_smart2io_padconf_0));
+
+	/* Slew rate settings hsi2, Mcspi2 */
+	mask = (sc_mask << 24) | (sc_mask << 28);
+	io_settings = readl(&(ioregs_base->control_smart2io_padconf_1)) &
+			(~mask);
+	io_settings |= (sc_fast << 28) | (sc_fast << 24);
+	writel(io_settings, &(ioregs_base->control_smart2io_padconf_1));
+
+	/* Slew rate settings C2C 3,4 */
+	mask = (sc_mask << 16) | (sc_mask << 18);
+	io_settings = readl(&(ioregs_base->control_smart2io_padconf_2)) &
+			(~mask);
+	io_settings |= (sc_na << 16) | (sc_na << 18);
+	writel(io_settings, &(ioregs_base->control_smart2io_padconf_2));
+
+	/* impedance and slew rate settings for usb */
+	mask = (usb_i_mask << 29) | (usb_i_mask << 26) | (usb_i_mask << 23) |
+		(usb_i_mask << 20) | (usb_i_mask << 17) | (usb_i_mask << 14);
+	io_settings = readl(&(ioregs_base->control_smart3io_padconf_1)) &
+			(~mask);
+	io_settings |= (ds_60_ohm << 29) | (ds_60_ohm << 26) |
+		       (ds_60_ohm << 23) | (sc_fast << 20) |
+		       (sc_fast << 17) | (sc_fast << 14);
+	writel(io_settings, &(ioregs_base->control_smart3io_padconf_1));
+
+	/* LPDDR2 io settings */
+	writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN,
+					&(ioregs_base->control_ddrch1_0));
+	writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN,
+					&(ioregs_base->control_ddrch1_1));
+	writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN,
+					&(ioregs_base->control_ddrch2_0));
+	writel(DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN,
+					&(ioregs_base->control_ddrch2_1));
+	writel(DDR_IO_I_34OHM_SR_FASTEST_WD_CK_CKE_NCS_CA_PULL_DOWN,
+					&(ioregs_base->control_lpddr2ch1_0));
+	writel(DDR_IO_I_34OHM_SR_FASTEST_WD_CK_CKE_NCS_CA_PULL_DOWN,
+					&(ioregs_base->control_lpddr2ch1_1));
+	writel(DDR_IO_0_DDR2_DQ_INT_EN_ALL_DDR3_CA_DIS_ALL,
+					&(ioregs_base->control_ddrio_0));
+	writel(DDR_IO_1_DQ_OUT_EN_ALL_DQ_INT_EN_ALL,
+					&(ioregs_base->control_ddrio_1));
+	writel(DDR_IO_2_CA_OUT_EN_ALL_CA_INT_EN_ALL,
+					&(ioregs_base->control_ddrio_2));
+
+	/* Efuse settings */
+	writel(EFUSE_1, &(ioregs_base->control_efuse_1));
+	writel(EFUSE_2, &(ioregs_base->control_efuse_2));
+	writel(EFUSE_3, &(ioregs_base->control_efuse_3));
+	writel(EFUSE_4, &(ioregs_base->control_efuse_4));
 }
 #endif
 
@@ -71,8 +154,23 @@ void init_omap_revision(void)
 
 	switch (rev) {
 	case MIDR_CORTEX_A15_R0P0:
-		*omap5_revision = OMAP5430_ES1_0;
+		*omap_si_rev = OMAP5430_ES1_0;
+		break;
 	default:
-		*omap5_revision = OMAP5430_SILICON_ID_INVALID;
+		*omap_si_rev = OMAP5430_SILICON_ID_INVALID;
 	}
 }
+
+void reset_cpu(ulong ignored)
+{
+	u32 omap_rev = omap_revision();
+
+	/*
+	 * WARM reset is not functional in case of OMAP5430 ES1.0 soc.
+	 * So use cold reset in case instead.
+	 */
+	if (omap_rev == OMAP5430_ES1_0)
+		writel(PRM_RSTCTRL_RESET << 0x1, PRM_RSTCTRL);
+	else
+		writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL);
+}

+ 72 - 29
arch/arm/cpu/armv7/omap5/sdram_elpida.c → arch/arm/cpu/armv7/omap5/sdram.c

@@ -1,5 +1,5 @@
 /*
- * Timing and Organization details of the Elpida parts used in OMAP5
+ * Timing and Organization details of the ddr device parts used in OMAP5
  * EVM
  *
  * (C) Copyright 2010
@@ -48,31 +48,76 @@
  */
 
 #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
-
-const struct emif_regs emif_regs_elpida_532_mhz_1cs = {
-	.sdram_config_init		= 0x80801aB2,
-	.sdram_config			= 0x808022B2,
+const struct emif_regs emif_regs_532_mhz_2cs = {
+	.sdram_config_init		= 0x80800EBA,
+	.sdram_config			= 0x808022BA,
 	.ref_ctrl			= 0x0000081A,
 	.sdram_tim1			= 0x772F6873,
-	.sdram_tim2			= 0x304A129A,
-	.sdram_tim3			= 0x02F7E45F,
+	.sdram_tim2			= 0x304a129a,
+	.sdram_tim3			= 0x02f7e45f,
+	.read_idle_ctrl			= 0x00050000,
+	.zq_config			= 0x000b3215,
+	.temp_alert_config		= 0x08000a05,
+	.emif_ddr_phy_ctlr_1_init	= 0x0E28420d,
+	.emif_ddr_phy_ctlr_1		= 0x0E28420d,
+	.emif_ddr_ext_phy_ctrl_1	= 0x04020080,
+	.emif_ddr_ext_phy_ctrl_2	= 0x28C518A3,
+	.emif_ddr_ext_phy_ctrl_3	= 0x518A3146,
+	.emif_ddr_ext_phy_ctrl_4	= 0x0014628C,
+	.emif_ddr_ext_phy_ctrl_5	= 0x04010040
+};
+
+const struct emif_regs emif_regs_266_mhz_2cs = {
+	.sdram_config_init		= 0x80800EBA,
+	.sdram_config			= 0x808022BA,
+	.ref_ctrl			= 0x0000040D,
+	.sdram_tim1			= 0x2A86B419,
+	.sdram_tim2			= 0x1025094A,
+	.sdram_tim3			= 0x026BA22F,
 	.read_idle_ctrl			= 0x00050000,
-	.zq_config			= 0x000B3215,
-	.temp_alert_config		= 0x08000A05,
-	.emif_ddr_phy_ctlr_1_init	= 0x0E38200D,
-	.emif_ddr_phy_ctlr_1		= 0x0E38200D
+	.zq_config			= 0x000b3215,
+	.temp_alert_config		= 0x08000a05,
+	.emif_ddr_phy_ctlr_1_init	= 0x0E28420d,
+	.emif_ddr_phy_ctlr_1		= 0x0E28420d,
+	.emif_ddr_ext_phy_ctrl_1	= 0x04020080,
+	.emif_ddr_ext_phy_ctrl_2	= 0x0A414829,
+	.emif_ddr_ext_phy_ctrl_3	= 0x14829052,
+	.emif_ddr_ext_phy_ctrl_4	= 0x000520A4,
+	.emif_ddr_ext_phy_ctrl_5	= 0x04010040
 };
 
-const struct dmm_lisa_map_regs lisa_map_4G_x_1_x_2 = {
-	.dmm_lisa_map_0 = 0xFF020100,
+const struct dmm_lisa_map_regs lisa_map_4G_x_2_x_2 = {
+	.dmm_lisa_map_0 = 0x0,
 	.dmm_lisa_map_1 = 0,
 	.dmm_lisa_map_2 = 0,
-	.dmm_lisa_map_3 = 0x80640300
+	.dmm_lisa_map_3 = 0x80740300
+};
+
+const u32 ext_phy_ctrl_const_base[EMIF_EXT_PHY_CTRL_CONST_REG] = {
+	0x01004010,
+	0x00001004,
+	0x04010040,
+	0x01004010,
+	0x00001004,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x80080080,
+	0x00800800,
+	0x08102040,
+	0x00000001,
+	0x540A8150,
+	0xA81502a0,
+	0x002A0540,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000077
 };
 
 static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs)
 {
-	*regs = &emif_regs_elpida_532_mhz_1cs;
+	*regs = &emif_regs_532_mhz_2cs;
 }
 void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs)
 	__attribute__((weak, alias("emif_get_reg_dump_sdp")));
@@ -80,7 +125,7 @@ void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs)
 static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs
 						**dmm_lisa_regs)
 {
-	*dmm_lisa_regs = &lisa_map_4G_x_1_x_2;
+	*dmm_lisa_regs = &lisa_map_4G_x_2_x_2;
 }
 
 void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs)
@@ -88,11 +133,11 @@ void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs)
 
 #else
 
-static const struct lpddr2_device_details elpida_4G_S4_details = {
+static const struct lpddr2_device_details dev_4G_S4_details = {
 	.type		= LPDDR2_TYPE_S4,
 	.density	= LPDDR2_DENSITY_4Gb,
 	.io_width	= LPDDR2_IO_WIDTH_32,
-	.manufacturer	= LPDDR2_MANUFACTURER_ELPIDA
+	.manufacturer	= LPDDR2_MANUFACTURER_SAMSUNG
 };
 
 static void emif_get_device_details_sdp(u32 emif_nr,
@@ -100,10 +145,8 @@ static void emif_get_device_details_sdp(u32 emif_nr,
 		struct lpddr2_device_details *cs1_device_details)
 {
 	/* EMIF1 & EMIF2 have identical configuration */
-	*cs0_device_details = elpida_4G_S4_details;
-
-	/* Nothing is conected on cs1 */
-	cs1_device_details = NULL;
+	*cs0_device_details = dev_4G_S4_details;
+	*cs1_device_details = dev_4G_S4_details;
 }
 
 void emif_get_device_details(u32 emif_nr,
@@ -137,7 +180,7 @@ static const struct lpddr2_ac_timings timings_jedec_532_mhz = {
 	.tFAW		= 50
 };
 
-static const struct lpddr2_min_tck min_tck_elpida = {
+static const struct lpddr2_min_tck min_tck = {
 	.tRL		= 3,
 	.tRP_AB		= 3,
 	.tRCD		= 3,
@@ -152,13 +195,13 @@ static const struct lpddr2_min_tck min_tck_elpida = {
 	.tFAW		= 8
 };
 
-static const struct lpddr2_ac_timings *elpida_ac_timings[MAX_NUM_SPEEDBINS] = {
+static const struct lpddr2_ac_timings *ac_timings[MAX_NUM_SPEEDBINS] = {
 	&timings_jedec_532_mhz
 };
 
-static const struct lpddr2_device_timings elpida_4G_S4_timings = {
-	.ac_timings	= elpida_ac_timings,
-	.min_tck	= &min_tck_elpida,
+static const struct lpddr2_device_timings dev_4G_S4_timings = {
+	.ac_timings	= ac_timings,
+	.min_tck	= &min_tck,
 };
 
 void emif_get_device_timings_sdp(u32 emif_nr,
@@ -166,8 +209,8 @@ void emif_get_device_timings_sdp(u32 emif_nr,
 		const struct lpddr2_device_timings **cs1_device_timings)
 {
 	/* Identical devices on EMIF1 & EMIF2 */
-	*cs0_device_timings = &elpida_4G_S4_timings;
-	*cs1_device_timings = NULL;
+	*cs0_device_timings = &dev_4G_S4_timings;
+	*cs1_device_timings = &dev_4G_S4_timings;
 }
 
 void emif_get_device_timings(u32 emif_nr,

+ 6 - 4
arch/arm/cpu/armv7/s5pc1xx/cache.S

@@ -25,20 +25,22 @@
 
 .align 5
 
+#include <linux/linkage.h>
+
 #ifndef CONFIG_SYS_L2CACHE_OFF
-.global v7_outer_cache_enable
-v7_outer_cache_enable:
+ENTRY(v7_outer_cache_enable)
 	push	{r0, r1, r2, lr}
 	mrc	15, 0, r3, cr1, cr0, 1
 	orr	r3, r3, #2
 	mcr	15, 0, r3, cr1, cr0, 1
 	pop	{r1, r2, r3, pc}
+ENDPROC(v7_outer_cache_enable)
 
-.global v7_outer_cache_disable
-v7_outer_cache_disable:
+ENTRY(v7_outer_cache_disable)
 	push	{r0, r1, r2, lr}
 	mrc	15, 0, r3, cr1, cr0, 1
 	bic	r3, r3, #2
 	mcr	15, 0, r3, cr1, cr0, 1
 	pop	{r1, r2, r3, pc}
+ENDPROC(v7_outer_cache_disable)
 #endif

+ 3 - 2
arch/arm/cpu/armv7/s5pc1xx/reset.S

@@ -22,12 +22,12 @@
  */
 
 #include <asm/arch/cpu.h>
+#include <linux/linkage.h>
 
 #define S5PC100_SWRESET			0xE0200000
 #define S5PC110_SWRESET			0xE0102000
 
-.globl reset_cpu
-reset_cpu:
+ENTRY(reset_cpu)
 	ldr	r1, =S5PC100_PRO_ID
 	ldr	r2, [r1]
 	ldr	r4, =0x00010000
@@ -45,3 +45,4 @@ reset_cpu:
 	str	r2, [r1]
 _loop_forever:
 	b	_loop_forever
+ENDPROC(reset_cpu)

+ 7 - 6
arch/arm/cpu/armv7/start.S

@@ -33,6 +33,7 @@
 #include <config.h>
 #include <version.h>
 #include <asm/system.h>
+#include <linux/linkage.h>
 
 .globl _start
 _start: b	reset
@@ -172,8 +173,7 @@ call_board_init_f:
  * after relocating the monitor code.
  *
  */
-	.globl	relocate_code
-relocate_code:
+ENTRY(relocate_code)
 	mov	r4, r0	/* save addr_sp */
 	mov	r5, r1	/* save addr of gd */
 	mov	r6, r2	/* save addr of destination */
@@ -289,6 +289,7 @@ jump_2_ram:
 
 _board_init_r_ofs:
 	.word board_init_r - _start
+ENDPROC(relocate_code)
 
 /*************************************************************************
  *
@@ -298,8 +299,7 @@ _board_init_r_ofs:
  * CONFIG_SYS_ICACHE_OFF is defined.
  *
  *************************************************************************/
-.globl cpu_init_cp15
-cpu_init_cp15:
+ENTRY(cpu_init_cp15)
 	/*
 	 * Invalidate L1 I/D
 	 */
@@ -325,7 +325,7 @@ cpu_init_cp15:
 #endif
 	mcr	p15, 0, r0, c1, c0, 0
 	mov	pc, lr			@ back to my caller
-
+ENDPROC(cpu_init_cp15)
 
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
 /*************************************************************************
@@ -336,7 +336,7 @@ cpu_init_cp15:
  * setup memory timing
  *
  *************************************************************************/
-cpu_init_crit:
+ENTRY(cpu_init_crit)
 	/*
 	 * Jump to board specific initialization...
 	 * The Mask ROM will have already initialized
@@ -347,6 +347,7 @@ cpu_init_crit:
 	bl	lowlevel_init		@ go setup pll,mux,memory
 	mov	lr, ip			@ restore link
 	mov	pc, lr			@ back to my caller
+ENDPROC(cpu_init_crit)
 #endif
 
 #ifndef CONFIG_SPL_BUILD

+ 4 - 0
arch/arm/cpu/armv7/tegra2/Makefile

@@ -27,6 +27,7 @@
 # flags for any startup files it might use.
 CFLAGS_arch/arm/cpu/armv7/tegra2/ap20.o += -march=armv4t
 CFLAGS_arch/arm/cpu/armv7/tegra2/clock.o += -march=armv4t
+CFLAGS_arch/arm/cpu/armv7/tegra2/warmboot_avp.o += -march=armv4t
 
 include $(TOPDIR)/config.mk
 
@@ -34,7 +35,10 @@ LIB	=  $(obj)lib$(SOC).o
 
 SOBJS	:= lowlevel_init.o
 COBJS-y	:= ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o
+COBJS-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o
+COBJS-$(CONFIG_TEGRA_PMU) += pmu.o
 COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o
+COBJS-$(CONFIG_TEGRA2_LP0) += crypto.o warmboot.o warmboot_avp.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)

+ 43 - 1
arch/arm/cpu/armv7/tegra2/ap20.c

@@ -21,16 +21,53 @@
 * MA 02111-1307 USA
 */
 
-#include "ap20.h"
 #include <asm/io.h>
 #include <asm/arch/tegra2.h>
+#include <asm/arch/ap20.h>
 #include <asm/arch/clk_rst.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/fuse.h>
+#include <asm/arch/gp_padctrl.h>
 #include <asm/arch/pmc.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/scu.h>
+#include <asm/arch/warmboot.h>
 #include <common.h>
 
+int tegra_get_chip_type(void)
+{
+	struct apb_misc_gp_ctlr *gp;
+	struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE;
+	uint tegra_sku_id, rev;
+
+	/*
+	 * This is undocumented, Chip ID is bits 15:8 of the register
+	 * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for
+	 * Tegra30
+	 */
+	gp = (struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
+	rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;
+
+	tegra_sku_id = readl(&fuse->sku_info) & 0xff;
+
+	switch (rev) {
+	case CHIPID_TEGRA2:
+		switch (tegra_sku_id) {
+		case SKU_ID_T20:
+			return TEGRA_SOC_T20;
+		case SKU_ID_T25SE:
+		case SKU_ID_AP25:
+		case SKU_ID_T25:
+		case SKU_ID_AP25E:
+		case SKU_ID_T25E:
+			return TEGRA_SOC_T25;
+		}
+		break;
+	}
+	/* unknown sku id */
+	return TEGRA_SOC_UNKNOWN;
+}
+
 /* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */
 static int ap20_cpu_is_cortexa9(void)
 {
@@ -286,6 +323,11 @@ void init_pmc_scratch(void)
 
 	/* ODMDATA is for kernel use to determine RAM size, LP config, etc. */
 	writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20);
+
+#ifdef CONFIG_TEGRA2_LP0
+	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
+	warmboot_save_sdram_params();
+#endif
 }
 
 void tegra2_start(void)

+ 2 - 2
arch/arm/cpu/armv7/tegra2/board.c

@@ -23,12 +23,12 @@
 
 #include <common.h>
 #include <asm/io.h>
-#include "ap20.h"
+#include <asm/arch/ap20.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/funcmux.h>
+#include <asm/arch/pmc.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/tegra2.h>
-#include <asm/arch/pmc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 

+ 36 - 1
arch/arm/cpu/armv7/tegra2/clock.c

@@ -410,6 +410,16 @@ enum clock_osc_freq clock_get_osc_freq(void)
 	return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
 }
 
+int clock_get_osc_bypass(void)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 reg;
+
+	reg = readl(&clkrst->crc_osc_ctrl);
+	return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT;
+}
+
 /* Returns a pointer to the registers of the given pll */
 static struct clk_pll *get_pll(enum clock_id clkid)
 {
@@ -420,6 +430,28 @@ static struct clk_pll *get_pll(enum clock_id clkid)
 	return &clkrst->crc_pll[clkid];
 }
 
+int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
+		u32 *divp, u32 *cpcon, u32 *lfcon)
+{
+	struct clk_pll *pll = get_pll(clkid);
+	u32 data;
+
+	assert(clkid != CLOCK_ID_USB);
+
+	/* Safety check, adds to code size but is small */
+	if (!clock_id_isvalid(clkid) || clkid == CLOCK_ID_USB)
+		return -1;
+	data = readl(&pll->pll_base);
+	*divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
+	*divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT;
+	*divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
+	data = readl(&pll->pll_misc);
+	*cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT;
+	*lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT;
+
+	return 0;
+}
+
 unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
 		u32 divp, u32 cpcon, u32 lfcon)
 {
@@ -1027,7 +1059,10 @@ void clock_early_init(void)
 		clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8);
 		break;
 
-	case CLOCK_OSC_FREQ_13_0:
+	case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
+		clock_set_rate(CLOCK_ID_PERIPH, 432, 13, 1, 8);
+		clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
+		break;
 	case CLOCK_OSC_FREQ_19_2:
 	default:
 		/*

+ 230 - 0
arch/arm/cpu/armv7/tegra2/crypto.c

@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2010 - 2011 NVIDIA Corporation <www.nvidia.com>
+ *
+ * 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 "crypto.h"
+#include "aes.h"
+
+static u8 zero_key[16];
+
+#define AES_CMAC_CONST_RB 0x87  /* from RFC 4493, Figure 2.2 */
+
+enum security_op {
+	SECURITY_SIGN		= 1 << 0,	/* Sign the data */
+	SECURITY_ENCRYPT	= 1 << 1,	/* Encrypt the data */
+};
+
+static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
+{
+	u32 i;
+
+	debug("%s [%d] @0x%08x", name, num_bytes, (u32)data);
+	for (i = 0; i < num_bytes; i++) {
+		if (i % 16 == 0)
+			debug(" = ");
+		debug("%02x", data[i]);
+		if ((i+1) % 16 != 0)
+			debug(" ");
+	}
+	debug("\n");
+}
+
+/**
+ * Apply chain data to the destination using EOR
+ *
+ * Each array is of length AES_AES_KEY_LENGTH.
+ *
+ * \param cbc_chain_data	Chain data
+ * \param src			Source data
+ * \param dst			Destination data, which is modified here
+ */
+static void apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		*dst++ = *src++ ^ *cbc_chain_data++;
+}
+
+/**
+ * Encrypt some data with AES.
+ *
+ * \param key_schedule		Expanded key to use
+ * \param src			Source data to encrypt
+ * \param dst			Destination buffer
+ * \param num_aes_blocks	Number of AES blocks to encrypt
+ */
+static void encrypt_object(u8 *key_schedule, u8 *src, u8 *dst,
+			   u32 num_aes_blocks)
+{
+	u8 tmp_data[AES_KEY_LENGTH];
+	u8 *cbc_chain_data;
+	u32 i;
+
+	cbc_chain_data = zero_key;	/* Convenient array of 0's for IV */
+
+	for (i = 0; i < num_aes_blocks; i++) {
+		debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
+		debug_print_vector("AES Src", AES_KEY_LENGTH, src);
+
+		/* Apply the chain data */
+		apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
+		debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
+
+		/* encrypt the AES block */
+		aes_encrypt(tmp_data, key_schedule, dst);
+		debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
+
+		/* Update pointers for next loop. */
+		cbc_chain_data = dst;
+		src += AES_KEY_LENGTH;
+		dst += AES_KEY_LENGTH;
+	}
+}
+
+/**
+ * Shift a vector left by one bit
+ *
+ * \param in	Input vector
+ * \param out	Output vector
+ * \param size	Length of vector in bytes
+ */
+static void left_shift_vector(u8 *in, u8 *out, int size)
+{
+	int carry = 0;
+	int i;
+
+	for (i = size - 1; i >= 0; i--) {
+		out[i] = (in[i] << 1) | carry;
+		carry = in[i] >> 7;	/* get most significant bit */
+	}
+}
+
+/**
+ * Sign a block of data, putting the result into dst.
+ *
+ * \param key			Input AES key, length AES_KEY_LENGTH
+ * \param key_schedule		Expanded key to use
+ * \param src			Source data of length 'num_aes_blocks' blocks
+ * \param dst			Destination buffer, length AES_KEY_LENGTH
+ * \param num_aes_blocks	Number of AES blocks to encrypt
+ */
+static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst,
+			u32 num_aes_blocks)
+{
+	u8 tmp_data[AES_KEY_LENGTH];
+	u8 left[AES_KEY_LENGTH];
+	u8 k1[AES_KEY_LENGTH];
+	u8 *cbc_chain_data;
+	unsigned i;
+
+	cbc_chain_data = zero_key;	/* Convenient array of 0's for IV */
+
+	/* compute K1 constant needed by AES-CMAC calculation */
+	for (i = 0; i < AES_KEY_LENGTH; i++)
+		tmp_data[i] = 0;
+
+	encrypt_object(key_schedule, tmp_data, left, 1);
+	debug_print_vector("AES(key, nonce)", AES_KEY_LENGTH, left);
+
+	left_shift_vector(left, k1, sizeof(left));
+	debug_print_vector("L", AES_KEY_LENGTH, left);
+
+	if ((left[0] >> 7) != 0) /* get MSB of L */
+		k1[AES_KEY_LENGTH-1] ^= AES_CMAC_CONST_RB;
+	debug_print_vector("K1", AES_KEY_LENGTH, k1);
+
+	/* compute the AES-CMAC value */
+	for (i = 0; i < num_aes_blocks; i++) {
+		/* Apply the chain data */
+		apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
+
+		/* for the final block, XOR K1 into the IV */
+		if (i == num_aes_blocks - 1)
+			apply_cbc_chain_data(tmp_data, k1, tmp_data);
+
+		/* encrypt the AES block */
+		aes_encrypt(tmp_data, key_schedule, dst);
+
+		debug("sign_obj: block %d of %d\n", i, num_aes_blocks);
+		debug_print_vector("AES-CMAC Src", AES_KEY_LENGTH, src);
+		debug_print_vector("AES-CMAC Xor", AES_KEY_LENGTH, tmp_data);
+		debug_print_vector("AES-CMAC Dst", AES_KEY_LENGTH, dst);
+
+		/* Update pointers for next loop. */
+		cbc_chain_data = dst;
+		src += AES_KEY_LENGTH;
+	}
+
+	debug_print_vector("AES-CMAC Hash", AES_KEY_LENGTH, dst);
+}
+
+/**
+ * Encrypt and sign a block of data (depending on security mode).
+ *
+ * \param key		Input AES key, length AES_KEY_LENGTH
+ * \param oper		Security operations mask to perform (enum security_op)
+ * \param src		Source data
+ * \param length	Size of source data
+ * \param sig_dst	Destination address for signature, AES_KEY_LENGTH bytes
+ */
+static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src,
+			    u32 length, u8 *sig_dst)
+{
+	u32 num_aes_blocks;
+	u8 key_schedule[AES_EXPAND_KEY_LENGTH];
+
+	debug("encrypt_and_sign: length = %d\n", length);
+	debug_print_vector("AES key", AES_KEY_LENGTH, key);
+
+	/*
+	 * The only need for a key is for signing/checksum purposes, so
+	 * if not encrypting, expand a key of 0s.
+	 */
+	aes_expand_key(oper & SECURITY_ENCRYPT ? key : zero_key, key_schedule);
+
+	num_aes_blocks = (length + AES_KEY_LENGTH - 1) / AES_KEY_LENGTH;
+
+	if (oper & SECURITY_ENCRYPT) {
+		/* Perform this in place, resulting in src being encrypted. */
+		debug("encrypt_and_sign: begin encryption\n");
+		encrypt_object(key_schedule, src, src, num_aes_blocks);
+		debug("encrypt_and_sign: end encryption\n");
+	}
+
+	if (oper & SECURITY_SIGN) {
+		/* encrypt the data, overwriting the result in signature. */
+		debug("encrypt_and_sign: begin signing\n");
+		sign_object(key, key_schedule, src, sig_dst, num_aes_blocks);
+		debug("encrypt_and_sign: end signing\n");
+	}
+
+	return 0;
+}
+
+int sign_data_block(u8 *source, unsigned length, u8 *signature)
+{
+	return encrypt_and_sign(zero_key, SECURITY_SIGN, source,
+				length, signature);
+}

+ 36 - 0
arch/arm/cpu/armv7/tegra2/crypto.h

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2010 - 2011 NVIDIA Corporation <www.nvidia.com>
+ *
+ * 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
+ */
+
+#ifndef _CRYPTO_H_
+#define _CRYPTO_H_
+
+/**
+ * Sign a block of data
+ *
+ * \param source	Source data
+ * \param length	Size of source data
+ * \param signature	Destination address for signature, AES_KEY_LENGTH bytes
+ */
+int sign_data_block(u8 *source, unsigned length, u8 *signature);
+
+#endif /* #ifndef _CRYPTO_H_ */

+ 286 - 0
arch/arm/cpu/armv7/tegra2/emc.c

@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * 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 <fdtdec.h>
+#include <asm/io.h>
+#include <asm/arch/ap20.h>
+#include <asm/arch/apb_misc.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/emc.h>
+#include <asm/arch/tegra2.h>
+
+/*
+ * The EMC registers have shadow registers.  When the EMC clock is updated
+ * in the clock controller, the shadow registers are copied to the active
+ * registers, allowing glitchless memory bus frequency changes.
+ * This function updates the shadow registers for a new clock frequency,
+ * and relies on the clock lock on the emc clock to avoid races between
+ * multiple frequency changes
+ */
+
+/*
+ * This table defines the ordering of the registers provided to
+ * tegra_set_mmc()
+ * TODO: Convert to fdt version once available
+ */
+static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
+	0x2c,	/* RC */
+	0x30,	/* RFC */
+	0x34,	/* RAS */
+	0x38,	/* RP */
+	0x3c,	/* R2W */
+	0x40,	/* W2R */
+	0x44,	/* R2P */
+	0x48,	/* W2P */
+	0x4c,	/* RD_RCD */
+	0x50,	/* WR_RCD */
+	0x54,	/* RRD */
+	0x58,	/* REXT */
+	0x5c,	/* WDV */
+	0x60,	/* QUSE */
+	0x64,	/* QRST */
+	0x68,	/* QSAFE */
+	0x6c,	/* RDV */
+	0x70,	/* REFRESH */
+	0x74,	/* BURST_REFRESH_NUM */
+	0x78,	/* PDEX2WR */
+	0x7c,	/* PDEX2RD */
+	0x80,	/* PCHG2PDEN */
+	0x84,	/* ACT2PDEN */
+	0x88,	/* AR2PDEN */
+	0x8c,	/* RW2PDEN */
+	0x90,	/* TXSR */
+	0x94,	/* TCKE */
+	0x98,	/* TFAW */
+	0x9c,	/* TRPAB */
+	0xa0,	/* TCLKSTABLE */
+	0xa4,	/* TCLKSTOP */
+	0xa8,	/* TREFBW */
+	0xac,	/* QUSE_EXTRA */
+	0x114,	/* FBIO_CFG6 */
+	0xb0,	/* ODT_WRITE */
+	0xb4,	/* ODT_READ */
+	0x104,	/* FBIO_CFG5 */
+	0x2bc,	/* CFG_DIG_DLL */
+	0x2c0,	/* DLL_XFORM_DQS */
+	0x2c4,	/* DLL_XFORM_QUSE */
+	0x2e0,	/* ZCAL_REF_CNT */
+	0x2e4,	/* ZCAL_WAIT_CNT */
+	0x2a8,	/* AUTO_CAL_INTERVAL */
+	0x2d0,	/* CFG_CLKTRIM_0 */
+	0x2d4,	/* CFG_CLKTRIM_1 */
+	0x2d8,	/* CFG_CLKTRIM_2 */
+};
+
+struct emc_ctlr *emc_get_controller(const void *blob)
+{
+	fdt_addr_t addr;
+	int node;
+
+	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC);
+	if (node > 0) {
+		addr = fdtdec_get_addr(blob, node, "reg");
+		if (addr != FDT_ADDR_T_NONE)
+			return (struct emc_ctlr *)addr;
+	}
+	return NULL;
+}
+
+/* Error codes we use */
+enum {
+	ERR_NO_EMC_NODE = -10,
+	ERR_NO_EMC_REG,
+	ERR_NO_FREQ,
+	ERR_FREQ_NOT_FOUND,
+	ERR_BAD_REGS,
+	ERR_NO_RAM_CODE,
+	ERR_RAM_CODE_NOT_FOUND,
+};
+
+/**
+ * Find EMC tables for the given ram code.
+ *
+ * The tegra EMC binding has two options, one using the ram code and one not.
+ * We detect which is in use by looking for the nvidia,use-ram-code property.
+ * If this is not present, then the EMC tables are directly below 'node',
+ * otherwise we select the correct emc-tables subnode based on the 'ram_code'
+ * value.
+ *
+ * @param blob		Device tree blob
+ * @param node		EMC node (nvidia,tegra20-emc compatible string)
+ * @param ram_code	RAM code to select (0-3, or -1 if unknown)
+ * @return 0 if ok, otherwise a -ve ERR_ code (see enum above)
+ */
+static int find_emc_tables(const void *blob, int node, int ram_code)
+{
+	int need_ram_code;
+	int depth;
+	int offset;
+
+	/* If we are using RAM codes, scan through the tables for our code */
+	need_ram_code = fdtdec_get_bool(blob, node, "nvidia,use-ram-code");
+	if (!need_ram_code)
+		return node;
+	if (ram_code == -1) {
+		debug("%s: RAM code required but not supplied\n", __func__);
+		return ERR_NO_RAM_CODE;
+	}
+
+	offset = node;
+	depth = 0;
+	do {
+		/*
+		 * Sadly there is no compatible string so we cannot use
+		 * fdtdec_next_compatible_subnode().
+		 */
+		offset = fdt_next_node(blob, offset, &depth);
+		if (depth <= 0)
+			break;
+
+		/* Make sure this is a direct subnode */
+		if (depth != 1)
+			continue;
+		if (strcmp("emc-tables", fdt_get_name(blob, offset, NULL)))
+			continue;
+
+		if (fdtdec_get_int(blob, offset, "nvidia,ram-code", -1)
+				== ram_code)
+			return offset;
+	} while (1);
+
+	debug("%s: Could not find tables for RAM code %d\n", __func__,
+	      ram_code);
+	return ERR_RAM_CODE_NOT_FOUND;
+}
+
+/**
+ * Decode the EMC node of the device tree, returning a pointer to the emc
+ * controller and the table to be used for the given rate.
+ *
+ * @param blob	Device tree blob
+ * @param rate	Clock speed of memory controller in Hz (=2x memory bus rate)
+ * @param emcp	Returns address of EMC controller registers
+ * @param tablep Returns pointer to table to program into EMC. There are
+ *		TEGRA_EMC_NUM_REGS entries, destined for offsets as per the
+ *		emc_reg_addr array.
+ * @return 0 if ok, otherwise a -ve error code which will allow someone to
+ * figure out roughly what went wrong by looking at this code.
+ */
+static int decode_emc(const void *blob, unsigned rate, struct emc_ctlr **emcp,
+		      const u32 **tablep)
+{
+	struct apb_misc_pp_ctlr *pp =
+		(struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE;
+	int ram_code;
+	int depth;
+	int node;
+
+	ram_code = (readl(&pp->strapping_opt_a) & RAM_CODE_MASK)
+			>> RAM_CODE_SHIFT;
+	/*
+	 * The EMC clock rate is twice the bus rate, and the bus rate is
+	 * measured in kHz
+	 */
+	rate = rate / 2 / 1000;
+
+	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC);
+	if (node < 0) {
+		debug("%s: No EMC node found in FDT\n", __func__);
+		return ERR_NO_EMC_NODE;
+	}
+	*emcp = (struct emc_ctlr *)fdtdec_get_addr(blob, node, "reg");
+	if (*emcp == (struct emc_ctlr *)FDT_ADDR_T_NONE) {
+		debug("%s: No EMC node reg property\n", __func__);
+		return ERR_NO_EMC_REG;
+	}
+
+	/* Work out the parent node which contains our EMC tables */
+	node = find_emc_tables(blob, node, ram_code & 3);
+	if (node < 0)
+		return node;
+
+	depth = 0;
+	for (;;) {
+		int node_rate;
+
+		node = fdtdec_next_compatible_subnode(blob, node,
+				COMPAT_NVIDIA_TEGRA20_EMC_TABLE, &depth);
+		if (node < 0)
+			break;
+		node_rate = fdtdec_get_int(blob, node, "clock-frequency", -1);
+		if (node_rate == -1) {
+			debug("%s: Missing clock-frequency\n", __func__);
+			return ERR_NO_FREQ; /* we expect this property */
+		}
+
+		if (node_rate == rate)
+			break;
+	}
+	if (node < 0) {
+		debug("%s: No node found for clock frequency %d\n", __func__,
+		      rate);
+		return ERR_FREQ_NOT_FOUND;
+	}
+
+	*tablep = fdtdec_locate_array(blob, node, "nvidia,emc-registers",
+				      TEGRA_EMC_NUM_REGS);
+	if (!*tablep) {
+		debug("%s: node '%s' array missing / wrong size\n", __func__,
+		      fdt_get_name(blob, node, NULL));
+		return ERR_BAD_REGS;
+	}
+
+	/* All seems well */
+	return 0;
+}
+
+int tegra_set_emc(const void *blob, unsigned rate)
+{
+	struct emc_ctlr *emc;
+	const u32 *table;
+	int err, i;
+
+	err = decode_emc(blob, rate, &emc, &table);
+	if (err) {
+		debug("Warning: no valid EMC (%d), memory timings unset\n",
+		       err);
+		return err;
+	}
+
+	debug("%s: Table found, setting EMC values as follows:\n", __func__);
+	for (i = 0; i < TEGRA_EMC_NUM_REGS; i++) {
+		u32 value = fdt32_to_cpu(table[i]);
+		u32 addr = (uintptr_t)emc + emc_reg_addr[i];
+
+		debug("   %#x: %#x\n", addr, value);
+		writel(value, addr);
+	}
+
+	/* trigger emc with new settings */
+	clock_adjust_periph_pll_div(PERIPH_ID_EMC, CLOCK_ID_MEMORY,
+				clock_get_rate(CLOCK_ID_MEMORY), NULL);
+	debug("EMC clock set to %lu\n",
+	      clock_get_periph_rate(PERIPH_ID_EMC, CLOCK_ID_MEMORY));
+
+	return 0;
+}

+ 16 - 0
arch/arm/cpu/armv7/tegra2/funcmux.c

@@ -169,6 +169,22 @@ int funcmux_select(enum periph_id id, int config)
 		}
 		break;
 
+	case PERIPH_ID_KBC:
+		if (config == FUNCMUX_DEFAULT) {
+			enum pmux_pingrp grp[] = {PINGRP_KBCA, PINGRP_KBCB,
+				PINGRP_KBCC, PINGRP_KBCD, PINGRP_KBCE,
+				PINGRP_KBCF};
+			int i;
+
+			for (i = 0; i < ARRAY_SIZE(grp); i++) {
+				pinmux_tristate_disable(grp[i]);
+				pinmux_set_func(grp[i], PMUX_FUNC_KBC);
+				pinmux_set_pullupdown(grp[i], PMUX_PULL_UP);
+			}
+
+			break;
+		}
+
 	default:
 		debug("%s: invalid periph_id %d", __func__, id);
 		return -1;

+ 3 - 2
arch/arm/cpu/armv7/tegra2/lowlevel_init.S

@@ -25,10 +25,10 @@
 
 #include <config.h>
 #include <version.h>
+#include <linux/linkage.h>
 
 	.align	5
-.global reset_cpu
-reset_cpu:
+ENTRY(reset_cpu)
 	ldr	r1, rstctl			@ get addr for global reset
 						@ reg
 	ldr	r3, [r1]
@@ -39,3 +39,4 @@ _loop_forever:
 	b	_loop_forever
 rstctl:
 	.word	PRM_RSTCTRL
+ENDPROC(reset_cpu)

+ 70 - 0
arch/arm/cpu/armv7/tegra2/pmu.c

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2010,2011 NVIDIA Corporation <www.nvidia.com>
+ *
+ * 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 <tps6586x.h>
+#include <asm/io.h>
+#include <asm/arch/ap20.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/tegra_i2c.h>
+#include <asm/arch/sys_proto.h>
+
+#define VDD_CORE_NOMINAL_T25	0x17	/* 1.3v */
+#define VDD_CPU_NOMINAL_T25	0x10	/* 1.125v */
+
+#define VDD_CORE_NOMINAL_T20	0x16	/* 1.275v */
+#define VDD_CPU_NOMINAL_T20	0x0f	/* 1.1v */
+
+#define VDD_RELATION		0x02	/*  50mv */
+#define VDD_TRANSITION_STEP	0x06	/* 150mv */
+#define VDD_TRANSITION_RATE	0x06	/* 3.52mv/us */
+
+int pmu_set_nominal(void)
+{
+	int core, cpu, bus;
+
+	/* by default, the table has been filled with T25 settings */
+	switch (tegra_get_chip_type()) {
+	case TEGRA_SOC_T20:
+		core = VDD_CORE_NOMINAL_T20;
+		cpu = VDD_CPU_NOMINAL_T20;
+		break;
+	case TEGRA_SOC_T25:
+		core = VDD_CORE_NOMINAL_T25;
+		cpu = VDD_CPU_NOMINAL_T25;
+		break;
+	default:
+		debug("%s: Unknown chip type\n", __func__);
+		return -1;
+	}
+
+	bus = tegra_i2c_get_dvc_bus_num();
+	if (bus == -1) {
+		debug("%s: Cannot find DVC I2C bus\n", __func__);
+		return -1;
+	}
+	tps6586x_init(bus);
+	tps6586x_set_pwm_mode(TPS6586X_PWM_SM1);
+	return tps6586x_adjust_sm0_sm1(core, cpu, VDD_TRANSITION_STEP,
+				VDD_TRANSITION_RATE, VDD_RELATION);
+}

+ 386 - 0
arch/arm/cpu/armv7/tegra2/warmboot.c

@@ -0,0 +1,386 @@
+/*
+ * (C) Copyright 2010 - 2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * 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/errno.h>
+#include <asm/arch/ap20.h>
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/pmc.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/fuse.h>
+#include <asm/arch/emc.h>
+#include <asm/arch/gp_padctrl.h>
+#include <asm/arch/warmboot.h>
+#include <asm/arch/sdram_param.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_TEGRA_CLOCK_SCALING
+#error "You must enable CONFIG_TEGRA_CLOCK_SCALING to use CONFIG_TEGRA2_LP0"
+#endif
+
+/*
+ * This is the place in SRAM where the SDRAM parameters are stored. There
+ * are 4 blocks, one for each RAM code
+ */
+#define SDRAM_PARAMS_BASE	(AP20_BASE_PA_SRAM + 0x188)
+
+/* TODO: If we later add support for the Misc GP controller, refactor this */
+union xm2cfga_reg {
+	struct {
+		u32 reserved0:2;
+		u32 hsm_en:1;
+		u32 reserved1:2;
+		u32 preemp_en:1;
+		u32 vref_en:1;
+		u32 reserved2:5;
+		u32 cal_drvdn:5;
+		u32 reserved3:3;
+		u32 cal_drvup:5;
+		u32 reserved4:3;
+		u32 cal_drvdn_slwr:2;
+		u32 cal_drvup_slwf:2;
+	};
+	u32 word;
+};
+
+union xm2cfgd_reg {
+	struct {
+		u32 reserved0:2;
+		u32 hsm_en:1;
+		u32 schmt_en:1;
+		u32 lpmd:2;
+		u32 vref_en:1;
+		u32 reserved1:5;
+		u32 cal_drvdn:5;
+		u32 reserved2:3;
+		u32 cal_drvup:5;
+		u32 reserved3:3;
+		u32 cal_drvdn_slwr:2;
+		u32 cal_drvup_slwf:2;
+	};
+	u32 word;
+};
+
+/*
+ * TODO: This register is not documented in the TRM yet. We could move this
+ * into the EMC and give it a proper interface, but not while it is
+ * undocumented.
+ */
+union fbio_spare_reg {
+	struct {
+		u32 reserved:24;
+		u32 cfg_wb0:8;
+	};
+	u32 word;
+};
+
+/* We pack the resume information into these unions for later */
+union scratch2_reg {
+	struct {
+		u32 pllm_base_divm:5;
+		u32 pllm_base_divn:10;
+		u32 pllm_base_divp:3;
+		u32 pllm_misc_lfcon:4;
+		u32 pllm_misc_cpcon:4;
+		u32 gp_xm2cfga_padctrl_preemp:1;
+		u32 gp_xm2cfgd_padctrl_schmt:1;
+		u32 osc_ctrl_xobp:1;
+		u32 memory_type:3;
+	};
+	u32 word;
+};
+
+union scratch4_reg {
+	struct {
+		u32 emc_clock_divider:8;
+		u32 pllm_stable_time:8;
+		u32 pllx_stable_time:8;
+		u32 emc_fbio_spare_cfg_wb0:8;
+	};
+	u32 word;
+};
+
+union scratch24_reg {
+	struct {
+		u32 emc_auto_cal_wait:8;
+		u32 emc_pin_program_wait:8;
+		u32 warmboot_wait:8;
+		u32 reserved:8;
+	};
+	u32 word;
+};
+
+int warmboot_save_sdram_params(void)
+{
+	u32 ram_code;
+	struct sdram_params sdram;
+	struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
+	struct apb_misc_gp_ctlr *gp =
+			(struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
+	struct emc_ctlr *emc = emc_get_controller(gd->fdt_blob);
+	union scratch2_reg scratch2;
+	union scratch4_reg scratch4;
+	union scratch24_reg scratch24;
+	union xm2cfga_reg xm2cfga;
+	union xm2cfgd_reg xm2cfgd;
+	union fbio_spare_reg fbio_spare;
+
+	/* get ram code that is used as index to array sdram_params in BCT */
+	ram_code = (readl(&pmt->pmt_strap_opt_a) >>
+			STRAP_OPT_A_RAM_CODE_SHIFT) & 3;
+	memcpy(&sdram,
+	       (char *)((struct sdram_params *)SDRAM_PARAMS_BASE + ram_code),
+	       sizeof(sdram));
+
+	xm2cfga.word = readl(&gp->xm2cfga);
+	xm2cfgd.word = readl(&gp->xm2cfgd);
+
+	scratch2.word = 0;
+	scratch2.osc_ctrl_xobp = clock_get_osc_bypass();
+
+	/* Get the memory PLL settings */
+	{
+		u32 divm, divn, divp, cpcon, lfcon;
+
+		if (clock_ll_read_pll(CLOCK_ID_MEMORY, &divm, &divn, &divp,
+					&cpcon, &lfcon))
+			return -1;
+		scratch2.pllm_base_divm = divm;
+		scratch2.pllm_base_divn = divn;
+		scratch2.pllm_base_divp = divp;
+		scratch2.pllm_misc_cpcon = cpcon;
+		scratch2.pllm_misc_lfcon = lfcon;
+	}
+
+	scratch2.gp_xm2cfga_padctrl_preemp = xm2cfga.preemp_en;
+	scratch2.gp_xm2cfgd_padctrl_schmt = xm2cfgd.schmt_en;
+	scratch2.memory_type = sdram.memory_type;
+	writel(scratch2.word, &pmc->pmc_scratch2);
+
+	/* collect data from various sources for pmc_scratch4 */
+	fbio_spare.word = readl(&emc->fbio_spare);
+	scratch4.word = 0;
+	scratch4.emc_fbio_spare_cfg_wb0 = fbio_spare.cfg_wb0;
+	scratch4.emc_clock_divider = sdram.emc_clock_divider;
+	scratch4.pllm_stable_time = -1;
+	scratch4.pllx_stable_time = -1;
+	writel(scratch4.word, &pmc->pmc_scratch4);
+
+	/* collect various data from sdram for pmc_scratch24 */
+	scratch24.word = 0;
+	scratch24.emc_pin_program_wait = sdram.emc_pin_program_wait;
+	scratch24.emc_auto_cal_wait = sdram.emc_auto_cal_wait;
+	scratch24.warmboot_wait = sdram.warm_boot_wait;
+	writel(scratch24.word, &pmc->pmc_scratch24);
+
+	return 0;
+}
+
+static u32 get_major_version(void)
+{
+	u32 major_id;
+	struct apb_misc_gp_ctlr *gp =
+		(struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
+
+	major_id = (readl(&gp->hidrev) & HIDREV_MAJORPREV_MASK) >>
+			HIDREV_MAJORPREV_SHIFT;
+	return major_id;
+}
+
+static int is_production_mode_fuse_set(struct fuse_regs *fuse)
+{
+	return readl(&fuse->production_mode);
+}
+
+static int is_odm_production_mode_fuse_set(struct fuse_regs *fuse)
+{
+	return readl(&fuse->security_mode);
+}
+
+static int is_failure_analysis_mode(struct fuse_regs *fuse)
+{
+	return readl(&fuse->fa);
+}
+
+static int ap20_is_odm_production_mode(void)
+{
+	struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE;
+
+	if (!is_failure_analysis_mode(fuse) &&
+	    is_odm_production_mode_fuse_set(fuse))
+		return 1;
+	else
+		return 0;
+}
+
+static int ap20_is_production_mode(void)
+{
+	struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE;
+
+	if (get_major_version() == 0)
+		return 1;
+
+	if (!is_failure_analysis_mode(fuse) &&
+	    is_production_mode_fuse_set(fuse) &&
+	    !is_odm_production_mode_fuse_set(fuse))
+		return 1;
+	else
+		return 0;
+}
+
+static enum fuse_operating_mode fuse_get_operation_mode(void)
+{
+	u32 chip_id;
+	struct apb_misc_gp_ctlr *gp =
+		(struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
+
+	chip_id = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >>
+			HIDREV_CHIPID_SHIFT;
+	if (chip_id == CHIPID_TEGRA2) {
+		if (ap20_is_odm_production_mode()) {
+			printf("!! odm_production_mode is not supported !!\n");
+			return MODE_UNDEFINED;
+		} else
+			if (ap20_is_production_mode())
+				return MODE_PRODUCTION;
+			else
+				return MODE_UNDEFINED;
+	}
+	return MODE_UNDEFINED;
+}
+
+static void determine_crypto_options(int *is_encrypted, int *is_signed,
+				     int *use_zero_key)
+{
+	switch (fuse_get_operation_mode()) {
+	case MODE_PRODUCTION:
+		*is_encrypted = 0;
+		*is_signed = 1;
+		*use_zero_key = 1;
+		break;
+	case MODE_UNDEFINED:
+	default:
+		*is_encrypted = 0;
+		*is_signed = 0;
+		*use_zero_key  = 0;
+		break;
+	}
+}
+
+static int sign_wb_code(u32 start, u32 length, int use_zero_key)
+{
+	int err;
+	u8 *source;		/* Pointer to source */
+	u8 *hash;
+
+	/* Calculate AES block parameters. */
+	source = (u8 *)(start + offsetof(struct wb_header, random_aes_block));
+	length -= offsetof(struct wb_header, random_aes_block);
+	hash = (u8 *)(start + offsetof(struct wb_header, hash));
+	err = sign_data_block(source, length, hash);
+
+	return err;
+}
+
+int warmboot_prepare_code(u32 seg_address, u32 seg_length)
+{
+	int err = 0;
+	u32 length;			/* length of the signed/encrypt code */
+	struct wb_header *dst_header;	/* Pointer to dest WB header */
+	int is_encrypted;		/* Segment is encrypted */
+	int is_signed;			/* Segment is signed */
+	int use_zero_key;		/* Use key of all zeros */
+
+	/* Determine crypto options. */
+	determine_crypto_options(&is_encrypted, &is_signed, &use_zero_key);
+
+	/* Get the actual code limits. */
+	length = roundup(((u32)wb_end - (u32)wb_start), 16);
+
+	/*
+	 * The region specified by seg_address must be in SDRAM and must be
+	 * nonzero in length.
+	 */
+	if (seg_length == 0 || seg_address < NV_PA_SDRAM_BASE ||
+		seg_address + seg_length >= NV_PA_SDRAM_BASE + gd->ram_size) {
+		err = -EFAULT;
+		goto fail;
+	}
+
+	/* Things must be 16-byte aligned. */
+	if ((seg_length & 0xF) || (seg_address & 0xF)) {
+		err = -EINVAL;
+		goto fail;
+	}
+
+	/* Will the code fit? (destination includes wb_header + wb code) */
+	if (seg_length < (length + sizeof(struct wb_header))) {
+		err = -EINVAL;
+		goto fail;
+	}
+
+	dst_header = (struct wb_header *)seg_address;
+	memset((char *)dst_header, 0, sizeof(struct wb_header));
+
+	/* Populate the random_aes_block as requested. */
+	{
+		u32 *aes_block = (u32 *)&(dst_header->random_aes_block);
+		u32 *end = (u32 *)(((u32)aes_block) +
+				   sizeof(dst_header->random_aes_block));
+
+		do {
+			*aes_block++ = 0;
+		} while (aes_block < end);
+	}
+
+	/* Populate the header. */
+	dst_header->length_insecure = length + sizeof(struct wb_header);
+	dst_header->length_secure = length + sizeof(struct wb_header);
+	dst_header->destination = AP20_WB_RUN_ADDRESS;
+	dst_header->entry_point = AP20_WB_RUN_ADDRESS;
+	dst_header->code_length = length;
+
+	if (is_encrypted) {
+		printf("!!!! Encryption is not supported !!!!\n");
+		dst_header->length_insecure = 0;
+		err = -EACCES;
+		goto fail;
+	} else
+		/* copy the wb code directly following dst_header. */
+		memcpy((char *)(dst_header+1), (char *)wb_start, length);
+
+	if (is_signed)
+		err = sign_wb_code(seg_address, dst_header->length_insecure,
+				   use_zero_key);
+
+fail:
+	if (err)
+		printf("Warning: warmboot code copy failed (error=%d)\n", err);
+
+	return err;
+}

+ 250 - 0
arch/arm/cpu/armv7/tegra2/warmboot_avp.c

@@ -0,0 +1,250 @@
+/*
+ * (C) Copyright 2010 - 2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * 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/ap20.h>
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/flow.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/pmc.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/warmboot.h>
+#include "warmboot_avp.h"
+
+#define DEBUG_RESET_CORESIGHT
+
+void wb_start(void)
+{
+	struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
+	struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	union osc_ctrl_reg osc_ctrl;
+	union pllx_base_reg pllx_base;
+	union pllx_misc_reg pllx_misc;
+	union scratch3_reg scratch3;
+	u32 reg;
+
+	/* enable JTAG & TBE */
+	writel(CONFIG_CTL_TBE | CONFIG_CTL_JTAG, &pmt->pmt_cfg_ctl);
+
+	/* Are we running where we're supposed to be? */
+	asm volatile (
+		"adr	%0, wb_start;"	/* reg: wb_start address */
+		: "=r"(reg)		/* output */
+					/* no input, no clobber list */
+	);
+
+	if (reg != AP20_WB_RUN_ADDRESS)
+		goto do_reset;
+
+	/* Are we running with AVP? */
+	if (readl(NV_PA_PG_UP_BASE + PG_UP_TAG_0) != PG_UP_TAG_AVP)
+		goto do_reset;
+
+#ifdef DEBUG_RESET_CORESIGHT
+	/* Assert CoreSight reset */
+	reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]);
+	reg |= SWR_CSITE_RST;
+	writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]);
+#endif
+
+	/* TODO: Set the drive strength - maybe make this a board parameter? */
+	osc_ctrl.word = readl(&clkrst->crc_osc_ctrl);
+	osc_ctrl.xofs = 4;
+	osc_ctrl.xoe = 1;
+	writel(osc_ctrl.word, &clkrst->crc_osc_ctrl);
+
+	/* Power up the CPU complex if necessary */
+	if (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU)) {
+		reg = PWRGATE_TOGGLE_PARTID_CPU | PWRGATE_TOGGLE_START;
+		writel(reg, &pmc->pmc_pwrgate_toggle);
+		while (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU))
+			;
+	}
+
+	/* Remove the I/O clamps from the CPU power partition. */
+	reg = readl(&pmc->pmc_remove_clamping);
+	reg |= CPU_CLMP;
+	writel(reg, &pmc->pmc_remove_clamping);
+
+	reg = EVENT_ZERO_VAL_20 | EVENT_MSEC | EVENT_MODE_STOP;
+	writel(reg, &flow->halt_cop_events);
+
+	/* Assert CPU complex reset */
+	reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]);
+	reg |= CPU_RST;
+	writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]);
+
+	/* Hold both CPUs in reset */
+	reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_CPURESET1 | CPU_CMPLX_DERESET0 |
+	      CPU_CMPLX_DERESET1 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DBGRESET1;
+	writel(reg, &clkrst->crc_cpu_cmplx_set);
+
+	/* Halt CPU1 at the flow controller for uni-processor configurations */
+	writel(EVENT_MODE_STOP, &flow->halt_cpu1_events);
+
+	/*
+	 * Set the CPU reset vector. SCRATCH41 contains the physical
+	 * address of the CPU-side restoration code.
+	 */
+	reg = readl(&pmc->pmc_scratch41);
+	writel(reg, EXCEP_VECTOR_CPU_RESET_VECTOR);
+
+	/* Select CPU complex clock source */
+	writel(CCLK_PLLP_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
+
+	/* Start the CPU0 clock and stop the CPU1 clock */
+	reg = CPU_CMPLX_CPU_BRIDGE_CLKDIV_4 | CPU_CMPLX_CPU0_CLK_STP_RUN |
+	      CPU_CMPLX_CPU1_CLK_STP_STOP;
+	writel(reg, &clkrst->crc_clk_cpu_cmplx);
+
+	/* Enable the CPU complex clock */
+	reg = readl(&clkrst->crc_clk_out_enb[TEGRA_DEV_L]);
+	reg |= CLK_ENB_CPU;
+	writel(reg, &clkrst->crc_clk_out_enb[TEGRA_DEV_L]);
+
+	/* Make sure the resets were held for at least 2 microseconds */
+	reg = readl(TIMER_USEC_CNTR);
+	while (readl(TIMER_USEC_CNTR) <= (reg + 2))
+		;
+
+#ifdef DEBUG_RESET_CORESIGHT
+	/*
+	 * De-assert CoreSight reset.
+	 * NOTE: We're leaving the CoreSight clock on the oscillator for
+	 *	now. It will be restored to its original clock source
+	 *	when the CPU-side restoration code runs.
+	 */
+	reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]);
+	reg &= ~SWR_CSITE_RST;
+	writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]);
+#endif
+
+	/* Unlock the CPU CoreSight interfaces */
+	reg = 0xC5ACCE55;
+	writel(reg, CSITE_CPU_DBG0_LAR);
+	writel(reg, CSITE_CPU_DBG1_LAR);
+
+	/*
+	 * Sample the microsecond timestamp again. This is the time we must
+	 * use when returning from LP0 for PLL stabilization delays.
+	 */
+	reg = readl(TIMER_USEC_CNTR);
+	writel(reg, &pmc->pmc_scratch1);
+
+	pllx_base.word = 0;
+	pllx_misc.word = 0;
+	scratch3.word = readl(&pmc->pmc_scratch3);
+
+	/* Get the OSC. For 19.2 MHz, use 19 to make the calculations easier */
+	reg = (readl(TIMER_USEC_CFG) & USEC_CFG_DIVISOR_MASK) + 1;
+
+	/*
+	 * According to the TRM, for 19.2MHz OSC, the USEC_DIVISOR is 0x5f, and
+	 * USEC_DIVIDEND is 0x04. So, if USEC_DIVISOR > 26, OSC is 19.2 MHz.
+	 *
+	 * reg is used to calculate the pllx freq, which is used to determine if
+	 * to set dccon or not.
+	 */
+	if (reg > 26)
+		reg = 19;
+
+	/* PLLX_BASE.PLLX_DIVM */
+	if (scratch3.pllx_base_divm == reg)
+		reg = 0;
+	else
+		reg = 1;
+
+	/* PLLX_BASE.PLLX_DIVN */
+	pllx_base.divn = scratch3.pllx_base_divn;
+	reg = scratch3.pllx_base_divn << reg;
+
+	/* PLLX_BASE.PLLX_DIVP */
+	pllx_base.divp = scratch3.pllx_base_divp;
+	reg = reg >> scratch3.pllx_base_divp;
+
+	pllx_base.bypass = 1;
+
+	/* PLLX_MISC_DCCON must be set for pllx frequency > 600 MHz. */
+	if (reg > 600)
+		pllx_misc.dccon = 1;
+
+	/* PLLX_MISC_LFCON */
+	pllx_misc.lfcon = scratch3.pllx_misc_lfcon;
+
+	/* PLLX_MISC_CPCON */
+	pllx_misc.cpcon = scratch3.pllx_misc_cpcon;
+
+	writel(pllx_misc.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_misc);
+	writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
+
+	pllx_base.enable = 1;
+	writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
+	pllx_base.bypass = 0;
+	writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
+
+	writel(0, flow->halt_cpu_events);
+
+	reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DERESET0;
+	writel(reg, &clkrst->crc_cpu_cmplx_clr);
+
+	reg = PLLM_OUT1_RSTN_RESET_DISABLE | PLLM_OUT1_CLKEN_ENABLE |
+	      PLLM_OUT1_RATIO_VAL_8;
+	writel(reg, &clkrst->crc_pll[CLOCK_ID_MEMORY].pll_out);
+
+	reg = SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 | SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 |
+	      SCLK_SWAKE_RUN_SRC_PLLM_OUT1 | SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 |
+	      SCLK_SYS_STATE_IDLE;
+	writel(reg, &clkrst->crc_sclk_brst_pol);
+
+	/* avp_resume: no return after the write */
+	reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]);
+	reg &= ~CPU_RST;
+	writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]);
+
+	/* avp_halt: */
+avp_halt:
+	reg = EVENT_MODE_STOP | EVENT_JTAG;
+	writel(reg, flow->halt_cop_events);
+	goto avp_halt;
+
+do_reset:
+	/*
+	 * Execution comes here if something goes wrong. The chip is reset and
+	 * a cold boot is performed.
+	 */
+	writel(SWR_TRIG_SYS_RST, &clkrst->crc_rst_dev[TEGRA_DEV_L]);
+	goto do_reset;
+}
+
+/*
+ * wb_end() is a dummy function, and must be directly following wb_start(),
+ * and is used to calculate the size of wb_start().
+ */
+void wb_end(void)
+{
+}

+ 81 - 0
arch/arm/cpu/armv7/tegra2/warmboot_avp.h

@@ -0,0 +1,81 @@
+/*
+ * (C) Copyright 2010, 2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * 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
+ */
+
+#ifndef _WARMBOOT_AVP_H_
+#define _WARMBOOT_AVP_H_
+
+#define TEGRA_DEV_L			0
+#define TEGRA_DEV_H			1
+#define TEGRA_DEV_U			2
+
+#define SIMPLE_PLLX			(CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE)
+#define SIMPLE_PLLE			(CLOCK_ID_EPCI - CLOCK_ID_FIRST_SIMPLE)
+
+#define TIMER_USEC_CNTR			(NV_PA_TMRUS_BASE + 0)
+#define TIMER_USEC_CFG			(NV_PA_TMRUS_BASE + 4)
+
+#define USEC_CFG_DIVISOR_MASK		0xffff
+
+#define CONFIG_CTL_TBE			(1 << 7)
+#define CONFIG_CTL_JTAG			(1 << 6)
+
+#define CPU_RST				(1 << 0)
+#define CLK_ENB_CPU			(1 << 0)
+#define SWR_TRIG_SYS_RST		(1 << 2)
+#define SWR_CSITE_RST			(1 << 9)
+
+#define PWRGATE_STATUS_CPU		(1 << 0)
+#define PWRGATE_TOGGLE_PARTID_CPU	(0 << 0)
+#define PWRGATE_TOGGLE_START		(1 << 8)
+
+#define CPU_CMPLX_CPU_BRIDGE_CLKDIV_4	(3 << 0)
+#define CPU_CMPLX_CPU0_CLK_STP_STOP	(1 << 8)
+#define CPU_CMPLX_CPU0_CLK_STP_RUN	(0 << 8)
+#define CPU_CMPLX_CPU1_CLK_STP_STOP	(1 << 9)
+#define CPU_CMPLX_CPU1_CLK_STP_RUN	(0 << 9)
+
+#define CPU_CMPLX_CPURESET0		(1 << 0)
+#define CPU_CMPLX_CPURESET1		(1 << 1)
+#define CPU_CMPLX_DERESET0		(1 << 4)
+#define CPU_CMPLX_DERESET1		(1 << 5)
+#define CPU_CMPLX_DBGRESET0		(1 << 12)
+#define CPU_CMPLX_DBGRESET1		(1 << 13)
+
+#define PLLM_OUT1_RSTN_RESET_DISABLE	(1 << 0)
+#define PLLM_OUT1_CLKEN_ENABLE		(1 << 1)
+#define PLLM_OUT1_RATIO_VAL_8		(8 << 8)
+
+#define SCLK_SYS_STATE_IDLE		(1 << 28)
+#define SCLK_SWAKE_FIQ_SRC_PLLM_OUT1	(7 << 12)
+#define SCLK_SWAKE_IRQ_SRC_PLLM_OUT1	(7 << 8)
+#define SCLK_SWAKE_RUN_SRC_PLLM_OUT1	(7 << 4)
+#define SCLK_SWAKE_IDLE_SRC_PLLM_OUT1	(7 << 0)
+
+#define EVENT_ZERO_VAL_20		(20 << 0)
+#define EVENT_MSEC			(1 << 24)
+#define EVENT_JTAG			(1 << 28)
+#define EVENT_MODE_STOP			(2 << 29)
+
+#define CCLK_PLLP_BURST_POLICY		0x20004444
+
+#endif

+ 5 - 4
arch/arm/cpu/armv7/u8500/lowlevel.S

@@ -20,16 +20,17 @@
  */
 
 #include <config.h>
+#include <linux/linkage.h>
 
-.globl lowlevel_init
-lowlevel_init:
+ENTRY(lowlevel_init)
 	mov	pc, lr
+ENDPROC(lowlevel_init)
 
 	.align	5
-.globl reset_cpu
-reset_cpu:
+ENTRY(reset_cpu)
 	ldr r0, =CFG_PRCMU_BASE
 	ldr r1, =0x1
 	str r1, [r0, #0x228]
 _loop_forever:
 	b	_loop_forever
+ENDPROC(reset_cpu)

+ 11 - 0
arch/arm/dts/tegra20.dtsi

@@ -193,4 +193,15 @@
 		clocks = <&tegra_car 59>;	/* PERIPH_ID_USB3 */
 	};
 
+	emc@7000f400 {
+		#address-cells = < 1 >;
+		#size-cells = < 0 >;
+		compatible = "nvidia,tegra20-emc";
+		reg = <0x7000f400 0x200>;
+	};
+
+	kbc@7000e200 {
+		compatible = "nvidia,tegra20-kbc";
+		reg = <0x7000e200 0x0078>;
+	};
 };

+ 1 - 1
arch/arm/include/asm/arch-am33xx/mmc_host_def.h

@@ -159,6 +159,6 @@ typedef struct hsmmc {
 #define mmc_reg_out(addr, mask, val)\
 	writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))
 
-int omap_mmc_init(int dev_index);
+int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max);
 
 #endif /* MMC_HOST_DEF_H */

+ 3 - 0
arch/arm/include/asm/arch-exynos/clk.h

@@ -33,5 +33,8 @@ unsigned long get_arm_clk(void);
 unsigned long get_pwm_clk(void);
 unsigned long get_uart_clk(int dev_index);
 void set_mmc_clk(int dev_index, unsigned int div);
+unsigned long get_lcd_clk(void);
+void set_lcd_clk(void);
+void set_mipi_clk(void);
 
 #endif

+ 5 - 0
arch/arm/include/asm/arch-exynos/cpu.h

@@ -29,6 +29,7 @@
 /* EXYNOS4 */
 #define EXYNOS4_GPIO_PART3_BASE		0x03860000
 #define EXYNOS4_PRO_ID			0x10000000
+#define EXYNOS4_SYSREG_BASE		0x10010000
 #define EXYNOS4_POWER_BASE		0x10020000
 #define EXYNOS4_SWRESET			0x10020400
 #define EXYNOS4_CLOCK_BASE		0x10030000
@@ -40,6 +41,7 @@
 #define EXYNOS4_GPIO_PART2_BASE		0x11000000
 #define EXYNOS4_GPIO_PART1_BASE		0x11400000
 #define EXYNOS4_FIMD_BASE		0x11C00000
+#define EXYNOS4_MIPI_DSIM_BASE		0x11C80000
 #define EXYNOS4_USBOTG_BASE		0x12480000
 #define EXYNOS4_MMC_BASE		0x12510000
 #define EXYNOS4_SROMC_BASE		0x12570000
@@ -65,6 +67,7 @@
 #define EXYNOS5_GPIO_PART3_BASE		0x10D10000
 #define EXYNOS5_DMC_CTRL_BASE		0x10DD0000
 #define EXYNOS5_GPIO_PART1_BASE		0x11400000
+#define EXYNOS5_MIPI_DSIM_BASE		0x11D00000
 #define EXYNOS5_MMC_BASE		0x12200000
 #define EXYNOS5_SROMC_BASE		0x12250000
 #define EXYNOS5_USBOTG_BASE		0x12480000
@@ -127,7 +130,9 @@ static inline unsigned int samsung_get_base_##device(void)	\
 
 SAMSUNG_BASE(adc, ADC_BASE)
 SAMSUNG_BASE(clock, CLOCK_BASE)
+SAMSUNG_BASE(sysreg, SYSREG_BASE)
 SAMSUNG_BASE(fimd, FIMD_BASE)
+SAMSUNG_BASE(mipi_dsim, MIPI_DSIM_BASE)
 SAMSUNG_BASE(gpio_part1, GPIO_PART1_BASE)
 SAMSUNG_BASE(gpio_part2, GPIO_PART2_BASE)
 SAMSUNG_BASE(gpio_part3, GPIO_PART3_BASE)

+ 181 - 0
arch/arm/include/asm/arch-exynos/dsim.h

@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Author: Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; 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
+ */
+
+#ifndef __ASM_ARM_ARCH_DSIM_H_
+#define __ASM_ARM_ARCH_DSIM_H_
+
+#ifndef __ASSEMBLY__
+
+struct exynos_mipi_dsim {
+	unsigned int	status;
+	unsigned int	swrst;
+	unsigned int	clkctrl;
+	unsigned int	timeout;
+	unsigned int	config;
+	unsigned int	escmode;
+	unsigned int	mdresol;
+	unsigned int	mvporch;
+	unsigned int	mhporch;
+	unsigned int	msync;
+	unsigned int	sdresol;
+	unsigned int	intsrc;
+	unsigned int	intmsk;
+	unsigned int	pkthdr;
+	unsigned int	payload;
+	unsigned int	rxfifo;
+	unsigned int	fifothld;
+	unsigned int	fifoctrl;
+	unsigned int	memacchr;
+	unsigned int	pllctrl;
+	unsigned int	plltmr;
+	unsigned int	phyacchr;
+	unsigned int	phyacchr1;
+};
+
+#endif	/* __ASSEMBLY__ */
+
+/*
+ * Bit Definitions
+ */
+/* DSIM_STATUS */
+#define DSIM_STOP_STATE_DAT(x)	(((x) & 0xf) << 0)
+#define DSIM_STOP_STATE_CLK	(1 << 8)
+#define DSIM_TX_READY_HS_CLK	(1 << 10)
+#define DSIM_PLL_STABLE		(1 << 31)
+
+/* DSIM_SWRST */
+#define DSIM_FUNCRST		(1 << 16)
+#define DSIM_SWRST		(1 << 0)
+
+/* EXYNOS_DSIM_TIMEOUT */
+#define DSIM_LPDR_TOUT_SHIFT	(0)
+#define DSIM_BTA_TOUT_SHIFT	(16)
+
+/* EXYNOS_DSIM_CLKCTRL */
+#define DSIM_LANE_ESC_CLKEN_SHIFT	(19)
+#define DSIM_BYTE_CLKEN_SHIFT		(24)
+#define DSIM_BYTE_CLK_SRC_SHIFT		(25)
+#define DSIM_PLL_BYPASS_SHIFT		(27)
+#define DSIM_ESC_CLKEN_SHIFT		(28)
+#define DSIM_TX_REQUEST_HSCLK_SHIFT	(31)
+#define DSIM_LANE_ESC_CLKEN(x)		(((x) & 0x1f) << \
+						DSIM_LANE_ESC_CLKEN_SHIFT)
+#define DSIM_BYTE_CLK_ENABLE		(1 << DSIM_BYTE_CLKEN_SHIFT)
+#define DSIM_BYTE_CLK_DISABLE		(0 << DSIM_BYTE_CLKEN_SHIFT)
+#define DSIM_PLL_BYPASS_EXTERNAL	(1 << DSIM_PLL_BYPASS_SHIFT)
+#define DSIM_ESC_CLKEN_ENABLE		(1 << DSIM_ESC_CLKEN_SHIFT)
+#define DSIM_ESC_CLKEN_DISABLE		(0 << DSIM_ESC_CLKEN_SHIFT)
+
+/* EXYNOS_DSIM_CONFIG */
+#define DSIM_NUM_OF_DATALANE_SHIFT	(5)
+#define DSIM_SUBPIX_SHIFT		(8)
+#define DSIM_MAINPIX_SHIFT		(12)
+#define DSIM_SUBVC_SHIFT		(16)
+#define DSIM_MAINVC_SHIFT		(18)
+#define DSIM_HSA_MODE_SHIFT		(20)
+#define DSIM_HBP_MODE_SHIFT		(21)
+#define DSIM_HFP_MODE_SHIFT		(22)
+#define DSIM_HSE_MODE_SHIFT		(23)
+#define DSIM_AUTO_MODE_SHIFT		(24)
+#define DSIM_VIDEO_MODE_SHIFT		(25)
+#define DSIM_BURST_MODE_SHIFT		(26)
+#define DSIM_EOT_PACKET_SHIFT		(28)
+#define DSIM_AUTO_FLUSH_SHIFT		(29)
+#define DSIM_LANE_ENx(x)		(((x) & 0x1f) << 0)
+
+#define DSIM_NUM_OF_DATA_LANE(x)	((x) << DSIM_NUM_OF_DATALANE_SHIFT)
+
+/* EXYNOS_DSIM_ESCMODE */
+#define DSIM_TX_LPDT_SHIFT		(6)
+#define DSIM_CMD_LPDT_SHIFT		(7)
+#define DSIM_TX_LPDT_LP			(1 << DSIM_TX_LPDT_SHIFT)
+#define DSIM_CMD_LPDT_LP		(1 << DSIM_CMD_LPDT_SHIFT)
+#define DSIM_STOP_STATE_CNT_SHIFT	(21)
+#define DSIM_FORCE_STOP_STATE_SHIFT	(20)
+
+/* EXYNOS_DSIM_MDRESOL */
+#define DSIM_MAIN_STAND_BY		(1 << 31)
+#define DSIM_MAIN_VRESOL(x)		(((x) & 0x7ff) << 16)
+#define DSIM_MAIN_HRESOL(x)		(((x) & 0X7ff) << 0)
+
+/* EXYNOS_DSIM_MVPORCH */
+#define DSIM_CMD_ALLOW_SHIFT		(28)
+#define DSIM_STABLE_VFP_SHIFT		(16)
+#define DSIM_MAIN_VBP_SHIFT		(0)
+#define DSIM_CMD_ALLOW_MASK		(0xf << DSIM_CMD_ALLOW_SHIFT)
+#define DSIM_STABLE_VFP_MASK		(0x7ff << DSIM_STABLE_VFP_SHIFT)
+#define DSIM_MAIN_VBP_MASK		(0x7ff << DSIM_MAIN_VBP_SHIFT)
+
+/* EXYNOS_DSIM_MHPORCH */
+#define DSIM_MAIN_HFP_SHIFT		(16)
+#define DSIM_MAIN_HBP_SHIFT		(0)
+#define DSIM_MAIN_HFP_MASK		((0xffff) << DSIM_MAIN_HFP_SHIFT)
+#define DSIM_MAIN_HBP_MASK		((0xffff) << DSIM_MAIN_HBP_SHIFT)
+
+/* EXYNOS_DSIM_MSYNC */
+#define DSIM_MAIN_VSA_SHIFT		(22)
+#define DSIM_MAIN_HSA_SHIFT		(0)
+#define DSIM_MAIN_VSA_MASK		((0x3ff) << DSIM_MAIN_VSA_SHIFT)
+#define DSIM_MAIN_HSA_MASK		((0xffff) << DSIM_MAIN_HSA_SHIFT)
+
+/* EXYNOS_DSIM_SDRESOL */
+#define DSIM_SUB_STANDY_SHIFT		(31)
+#define DSIM_SUB_VRESOL_SHIFT		(16)
+#define DSIM_SUB_HRESOL_SHIFT		(0)
+#define DSIM_SUB_STANDY_MASK		((0x1) << DSIM_SUB_STANDY_SHIFT)
+#define DSIM_SUB_VRESOL_MASK		((0x7ff) << DSIM_SUB_VRESOL_SHIFT)
+#define DSIM_SUB_HRESOL_MASK		((0x7ff) << DSIM_SUB_HRESOL_SHIFT)
+
+/* EXYNOS_DSIM_INTSRC */
+#define INTSRC_FRAME_DONE		(1 << 24)
+#define INTSRC_PLL_STABLE		(1 << 31)
+#define INTSRC_SWRST_RELEASE		(1 << 30)
+
+/* EXYNOS_DSIM_INTMSK */
+#define INTMSK_FRAME_DONE		(1 << 24)
+
+/* EXYNOS_DSIM_FIFOCTRL */
+#define SFR_HEADER_EMPTY		(1 << 22)
+
+/* EXYNOS_DSIM_PKTHDR */
+#define DSIM_PKTHDR_DI(x)		(((x) & 0x3f) << 0)
+#define DSIM_PKTHDR_DAT0(x)		((x) << 8)
+#define DSIM_PKTHDR_DAT1(x)		((x) << 16)
+
+/* EXYNOS_DSIM_PHYACCHR */
+#define DSIM_AFC_CTL(x)			(((x) & 0x7) << 5)
+#define DSIM_AFC_CTL_SHIFT		(5)
+#define DSIM_AFC_EN			(1 << 14)
+
+/* EXYNOS_DSIM_PHYACCHR1 */
+#define DSIM_DPDN_SWAP_DATA_SHIFT	(0)
+
+/* EXYNOS_DSIM_PLLCTRL */
+#define DSIM_SCALER_SHIFT		(1)
+#define DSIM_MAIN_SHIFT			(4)
+#define DSIM_PREDIV_SHIFT		(13)
+#define DSIM_PRECTRL_SHIFT		(20)
+#define DSIM_PLL_EN_SHIFT		(23)
+#define DSIM_FREQ_BAND_SHIFT		(24)
+#define DSIM_ZEROCTRL_SHIFT		(28)
+
+#endif

+ 446 - 0
arch/arm/include/asm/arch-exynos/fb.h

@@ -0,0 +1,446 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; 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
+ * aint with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARM_ARCH_FB_H_
+#define __ASM_ARM_ARCH_FB_H_
+
+#ifndef __ASSEMBLY__
+struct exynos4_fb {
+	unsigned int vidcon0;
+	unsigned int vidcon1;
+	unsigned int vidcon2;
+	unsigned int vidcon3;
+	unsigned int vidtcon0;
+	unsigned int vidtcon1;
+	unsigned int vidtcon2;
+	unsigned int vidtcon3;
+	unsigned int wincon0;
+	unsigned int wincon1;
+	unsigned int wincon2;
+	unsigned int wincon3;
+	unsigned int wincon4;
+
+	unsigned int winshmap;
+	unsigned int res1;
+
+	unsigned int winchmap2;
+	unsigned int vidosd0a;
+	unsigned int vidosd0b;
+	unsigned int vidosd0c;
+	unsigned int res2;
+
+	unsigned int vidosd1a;
+	unsigned int vidosd1b;
+	unsigned int vidosd1c;
+	unsigned int vidosd1d;
+
+	unsigned int vidosd2a;
+	unsigned int vidosd2b;
+	unsigned int vidosd2c;
+	unsigned int vidosd2d;
+
+	unsigned int vidosd3a;
+	unsigned int vidosd3b;
+	unsigned int vidosd3c;
+	unsigned int res3;
+
+	unsigned int vidosd4a;
+	unsigned int vidosd4b;
+	unsigned int vidosd4c;
+	unsigned int res4[5];
+
+	unsigned int vidw00add0b0;
+	unsigned int vidw00add0b1;
+	unsigned int vidw01add0b0;
+	unsigned int vidw01add0b1;
+
+	unsigned int vidw02add0b0;
+	unsigned int vidw02add0b1;
+	unsigned int vidw03add0b0;
+	unsigned int vidw03add0b1;
+	unsigned int vidw04add0b0;
+	unsigned int vidw04add0b1;
+	unsigned int res5[2];
+
+	unsigned int vidw00add1b0;
+	unsigned int vidw00add1b1;
+	unsigned int vidw01add1b0;
+	unsigned int vidw01add1b1;
+
+	unsigned int vidw02add1b0;
+	unsigned int vidw02add1b1;
+	unsigned int vidw03add1b0;
+	unsigned int vidw03add1b1;
+
+	unsigned int vidw04add1b0;
+	unsigned int vidw04add1b1;
+	unsigned int res7[2];
+
+	unsigned int vidw00add2;
+	unsigned int vidw01add2;
+	unsigned int vidw02add2;
+	unsigned int vidw03add2;
+	unsigned int vidw04add2;
+	unsigned int res8[7];
+
+	unsigned int vidintcon0;
+	unsigned int vidintcon1;
+	unsigned int res9[1];
+
+	unsigned int w1keycon0;
+	unsigned int w1keycon1;
+	unsigned int w2keycon0;
+	unsigned int w2keycon1;
+	unsigned int w3keycon0;
+	unsigned int w3keycon1;
+	unsigned int w4keycon0;
+	unsigned int w4keycon1;
+
+	unsigned int w1keyalpha;
+	unsigned int w2keyalpha;
+	unsigned int w3keyalpha;
+	unsigned int w4keyalpha;
+
+	unsigned int dithmode;
+	unsigned int res10[2];
+
+	unsigned int win0map;
+	unsigned int win1map;
+	unsigned int win2map;
+	unsigned int win3map;
+	unsigned int win4map;
+	unsigned int res11[1];
+
+	unsigned int wpalcon_h;
+	unsigned int wpalcon_l;
+
+	unsigned int trigcon;
+	unsigned int res12[2];
+
+	unsigned int i80ifcona0;
+	unsigned int i80ifcona1;
+	unsigned int i80ifconb0;
+	unsigned int i80ifconb1;
+
+	unsigned int colorgaincon;
+	unsigned int res13[2];
+
+	unsigned int ldi_cmdcon0;
+	unsigned int ldi_cmdcon1;
+	unsigned int res14[1];
+
+	/* To be updated */
+
+	unsigned char res15[156];
+	unsigned int dualrgb;
+};
+#endif
+
+/*
+ *  Register offsets
+*/
+#define EXYNOS_WINCON(x)				(x * 0x04)
+#define EXYNOS_VIDOSD(x)				(x * 0x10)
+#define EXYNOS_BUFFER_OFFSET(x)				(x * 0x08)
+#define EXYNOS_BUFFER_SIZE(x)				(x * 0x04)
+
+/*
+ * Bit Definitions
+*/
+
+/* VIDCON0 */
+#define EXYNOS_VIDCON0_DSI_DISABLE			(0 << 30)
+#define EXYNOS_VIDCON0_DSI_ENABLE			(1 << 30)
+#define EXYNOS_VIDCON0_SCAN_PROGRESSIVE			(0 << 29)
+#define EXYNOS_VIDCON0_SCAN_INTERLACE			(1 << 29)
+#define EXYNOS_VIDCON0_SCAN_MASK			(1 << 29)
+#define EXYNOS_VIDCON0_VIDOUT_RGB			(0 << 26)
+#define EXYNOS_VIDCON0_VIDOUT_ITU			(1 << 26)
+#define EXYNOS_VIDCON0_VIDOUT_I80LDI0			(2 << 26)
+#define EXYNOS_VIDCON0_VIDOUT_I80LDI1			(3 << 26)
+#define EXYNOS_VIDCON0_VIDOUT_WB_RGB			(4 << 26)
+#define EXYNOS_VIDCON0_VIDOUT_WB_I80LDI0		(6 << 26)
+#define EXYNOS_VIDCON0_VIDOUT_WB_I80LDI1		(7 << 26)
+#define EXYNOS_VIDCON0_VIDOUT_MASK			(7 << 26)
+#define EXYNOS_VIDCON0_PNRMODE_RGB_P			(0 << 17)
+#define EXYNOS_VIDCON0_PNRMODE_BGR_P			(1 << 17)
+#define EXYNOS_VIDCON0_PNRMODE_RGB_S			(2 << 17)
+#define EXYNOS_VIDCON0_PNRMODE_BGR_S			(3 << 17)
+#define EXYNOS_VIDCON0_PNRMODE_MASK			(3 << 17)
+#define EXYNOS_VIDCON0_PNRMODE_SHIFT			(17)
+#define EXYNOS_VIDCON0_CLKVALUP_ALWAYS			(0 << 16)
+#define EXYNOS_VIDCON0_CLKVALUP_START_FRAME		(1 << 16)
+#define EXYNOS_VIDCON0_CLKVALUP_MASK			(1 << 16)
+#define EXYNOS_VIDCON0_CLKVAL_F(x)			(((x) & 0xff) << 6)
+#define EXYNOS_VIDCON0_VCLKEN_NORMAL			(0 << 5)
+#define EXYNOS_VIDCON0_VCLKEN_FREERUN			(1 << 5)
+#define EXYNOS_VIDCON0_VCLKEN_MASK			(1 << 5)
+#define EXYNOS_VIDCON0_CLKDIR_DIRECTED			(0 << 4)
+#define EXYNOS_VIDCON0_CLKDIR_DIVIDED			(1 << 4)
+#define EXYNOS_VIDCON0_CLKDIR_MASK			(1 << 4)
+#define EXYNOS_VIDCON0_CLKSEL_HCLK			(0 << 2)
+#define EXYNOS_VIDCON0_CLKSEL_SCLK			(1 << 2)
+#define EXYNOS_VIDCON0_CLKSEL_MASK			(1 << 2)
+#define EXYNOS_VIDCON0_ENVID_ENABLE			(1 << 1)
+#define EXYNOS_VIDCON0_ENVID_DISABLE			(0 << 1)
+#define EXYNOS_VIDCON0_ENVID_F_ENABLE			(1 << 0)
+#define EXYNOS_VIDCON0_ENVID_F_DISABLE			(0 << 0)
+
+/* VIDCON1 */
+#define EXYNOS_VIDCON1_IVCLK_FALLING_EDGE		(0 << 7)
+#define EXYNOS_VIDCON1_IVCLK_RISING_EDGE		(1 << 7)
+#define EXYNOS_VIDCON1_IHSYNC_NORMAL			(0 << 6)
+#define EXYNOS_VIDCON1_IHSYNC_INVERT			(1 << 6)
+#define EXYNOS_VIDCON1_IVSYNC_NORMAL			(0 << 5)
+#define EXYNOS_VIDCON1_IVSYNC_INVERT			(1 << 5)
+#define EXYNOS_VIDCON1_IVDEN_NORMAL			(0 << 4)
+#define EXYNOS_VIDCON1_IVDEN_INVERT			(1 << 4)
+
+/* VIDCON2 */
+#define EXYNOS_VIDCON2_EN601_DISABLE			(0 << 23)
+#define EXYNOS_VIDCON2_EN601_ENABLE			(1 << 23)
+#define EXYNOS_VIDCON2_EN601_MASK			(1 << 23)
+#define EXYNOS_VIDCON2_WB_DISABLE			(0 << 15)
+#define EXYNOS_VIDCON2_WB_ENABLE			(1 << 15)
+#define EXYNOS_VIDCON2_WB_MASK				(1 << 15)
+#define EXYNOS_VIDCON2_TVFORMATSEL_HW			(0 << 14)
+#define EXYNOS_VIDCON2_TVFORMATSEL_SW			(1 << 14)
+#define EXYNOS_VIDCON2_TVFORMATSEL_MASK			(1 << 14)
+#define EXYNOS_VIDCON2_TVFORMATSEL_YUV422		(1 << 12)
+#define EXYNOS_VIDCON2_TVFORMATSEL_YUV444		(2 << 12)
+#define EXYNOS_VIDCON2_TVFORMATSEL_YUV_MASK		(3 << 12)
+#define EXYNOS_VIDCON2_ORGYUV_YCBCR			(0 << 8)
+#define EXYNOS_VIDCON2_ORGYUV_CBCRY			(1 << 8)
+#define EXYNOS_VIDCON2_ORGYUV_MASK			(1 << 8)
+#define EXYNOS_VIDCON2_YUVORD_CBCR			(0 << 7)
+#define EXYNOS_VIDCON2_YUVORD_CRCB			(1 << 7)
+#define EXYNOS_VIDCON2_YUVORD_MASK			(1 << 7)
+
+/* PRTCON */
+#define EXYNOS_PRTCON_UPDATABLE				(0 << 11)
+#define EXYNOS_PRTCON_PROTECT				(1 << 11)
+
+/* VIDTCON0 */
+#define EXYNOS_VIDTCON0_VBPDE(x)			(((x) & 0xff) << 24)
+#define EXYNOS_VIDTCON0_VBPD(x)				(((x) & 0xff) << 16)
+#define EXYNOS_VIDTCON0_VFPD(x)				(((x) & 0xff) << 8)
+#define EXYNOS_VIDTCON0_VSPW(x)				(((x) & 0xff) << 0)
+
+/* VIDTCON1 */
+#define EXYNOS_VIDTCON1_VFPDE(x)			(((x) & 0xff) << 24)
+#define EXYNOS_VIDTCON1_HBPD(x)				(((x) & 0xff) << 16)
+#define EXYNOS_VIDTCON1_HFPD(x)				(((x) & 0xff) << 8)
+#define EXYNOS_VIDTCON1_HSPW(x)				(((x) & 0xff) << 0)
+
+/* VIDTCON2 */
+#define EXYNOS_VIDTCON2_LINEVAL(x)			(((x) & 0x7ff) << 11)
+#define EXYNOS_VIDTCON2_HOZVAL(x)			(((x) & 0x7ff) << 0)
+
+/* Window 0~4 Control - WINCONx */
+#define EXYNOS_WINCON_DATAPATH_DMA			(0 << 22)
+#define EXYNOS_WINCON_DATAPATH_LOCAL			(1 << 22)
+#define EXYNOS_WINCON_DATAPATH_MASK			(1 << 22)
+#define EXYNOS_WINCON_BUFSEL_0				(0 << 20)
+#define EXYNOS_WINCON_BUFSEL_1				(1 << 20)
+#define EXYNOS_WINCON_BUFSEL_MASK			(1 << 20)
+#define EXYNOS_WINCON_BUFSEL_SHIFT			(20)
+#define EXYNOS_WINCON_BUFAUTO_DISABLE			(0 << 19)
+#define EXYNOS_WINCON_BUFAUTO_ENABLE			(1 << 19)
+#define EXYNOS_WINCON_BUFAUTO_MASK			(1 << 19)
+#define EXYNOS_WINCON_BITSWP_DISABLE			(0 << 18)
+#define EXYNOS_WINCON_BITSWP_ENABLE			(1 << 18)
+#define EXYNOS_WINCON_BITSWP_SHIFT			(18)
+#define EXYNOS_WINCON_BYTESWP_DISABLE			(0 << 17)
+#define EXYNOS_WINCON_BYTESWP_ENABLE			(1 << 17)
+#define EXYNOS_WINCON_BYTESWP_SHIFT			(17)
+#define EXYNOS_WINCON_HAWSWP_DISABLE			(0 << 16)
+#define EXYNOS_WINCON_HAWSWP_ENABLE			(1 << 16)
+#define EXYNOS_WINCON_HAWSWP_SHIFT			(16)
+#define EXYNOS_WINCON_WSWP_DISABLE			(0 << 15)
+#define EXYNOS_WINCON_WSWP_ENABLE			(1 << 15)
+#define EXYNOS_WINCON_WSWP_SHIFT			(15)
+#define EXYNOS_WINCON_INRGB_RGB				(0 << 13)
+#define EXYNOS_WINCON_INRGB_YUV				(1 << 13)
+#define EXYNOS_WINCON_INRGB_MASK			(1 << 13)
+#define EXYNOS_WINCON_BURSTLEN_16WORD			(0 << 9)
+#define EXYNOS_WINCON_BURSTLEN_8WORD			(1 << 9)
+#define EXYNOS_WINCON_BURSTLEN_4WORD			(2 << 9)
+#define EXYNOS_WINCON_BURSTLEN_MASK			(3 << 9)
+#define EXYNOS_WINCON_ALPHA_MULTI_DISABLE		(0 << 7)
+#define EXYNOS_WINCON_ALPHA_MULTI_ENABLE		(1 << 7)
+#define EXYNOS_WINCON_BLD_PLANE				(0 << 6)
+#define EXYNOS_WINCON_BLD_PIXEL				(1 << 6)
+#define EXYNOS_WINCON_BLD_MASK				(1 << 6)
+#define EXYNOS_WINCON_BPPMODE_1BPP			(0 << 2)
+#define EXYNOS_WINCON_BPPMODE_2BPP			(1 << 2)
+#define EXYNOS_WINCON_BPPMODE_4BPP			(2 << 2)
+#define EXYNOS_WINCON_BPPMODE_8BPP_PAL			(3 << 2)
+#define EXYNOS_WINCON_BPPMODE_8BPP			(4 << 2)
+#define EXYNOS_WINCON_BPPMODE_16BPP_565			(5 << 2)
+#define EXYNOS_WINCON_BPPMODE_16BPP_A555		(6 << 2)
+#define EXYNOS_WINCON_BPPMODE_18BPP_666			(8 << 2)
+#define EXYNOS_WINCON_BPPMODE_18BPP_A665		(9 << 2)
+#define EXYNOS_WINCON_BPPMODE_24BPP_888			(0xb << 2)
+#define EXYNOS_WINCON_BPPMODE_24BPP_A887		(0xc << 2)
+#define EXYNOS_WINCON_BPPMODE_32BPP			(0xd << 2)
+#define EXYNOS_WINCON_BPPMODE_16BPP_A444		(0xe << 2)
+#define EXYNOS_WINCON_BPPMODE_15BPP_555			(0xf << 2)
+#define EXYNOS_WINCON_BPPMODE_MASK			(0xf << 2)
+#define EXYNOS_WINCON_BPPMODE_SHIFT			(2)
+#define EXYNOS_WINCON_ALPHA0_SEL			(0 << 1)
+#define EXYNOS_WINCON_ALPHA1_SEL			(1 << 1)
+#define EXYNOS_WINCON_ALPHA_SEL_MASK			(1 << 1)
+#define EXYNOS_WINCON_ENWIN_DISABLE			(0 << 0)
+#define EXYNOS_WINCON_ENWIN_ENABLE			(1 << 0)
+
+/* WINCON1 special */
+#define EXYNOS_WINCON1_VP_DISABLE			(0 << 24)
+#define EXYNOS_WINCON1_VP_ENABLE			(1 << 24)
+#define EXYNOS_WINCON1_LOCALSEL_FIMC1			(0 << 23)
+#define EXYNOS_WINCON1_LOCALSEL_VP			(1 << 23)
+#define EXYNOS_WINCON1_LOCALSEL_MASK			(1 << 23)
+
+/* WINSHMAP */
+#define EXYNOS_WINSHMAP_PROTECT(x)			(((x) & 0x1f) << 10)
+#define EXYNOS_WINSHMAP_CH_ENABLE(x)			(1 << (x))
+#define EXYNOS_WINSHMAP_CH_DISABLE(x)			(1 << (x))
+#define EXYNOS_WINSHMAP_LOCAL_ENABLE(x)			(0x20 << (x))
+#define EXYNOS_WINSHMAP_LOCAL_DISABLE(x)		(0x20 << (x))
+
+/* VIDOSDxA, VIDOSDxB */
+#define EXYNOS_VIDOSD_LEFT_X(x)				(((x) & 0x7ff) << 11)
+#define EXYNOS_VIDOSD_TOP_Y(x)				(((x) & 0x7ff) << 0)
+#define EXYNOS_VIDOSD_RIGHT_X(x)			(((x) & 0x7ff) << 11)
+#define EXYNOS_VIDOSD_BOTTOM_Y(x)			(((x) & 0x7ff) << 0)
+
+/* VIDOSD0C, VIDOSDxD */
+#define EXYNOS_VIDOSD_SIZE(x)				(((x) & 0xffffff) << 0)
+
+/* VIDOSDxC (1~4) */
+#define EXYNOS_VIDOSD_ALPHA0_R(x)			(((x) & 0xf) << 20)
+#define EXYNOS_VIDOSD_ALPHA0_G(x)			(((x) & 0xf) << 16)
+#define EXYNOS_VIDOSD_ALPHA0_B(x)			(((x) & 0xf) << 12)
+#define EXYNOS_VIDOSD_ALPHA1_R(x)			(((x) & 0xf) << 8)
+#define EXYNOS_VIDOSD_ALPHA1_G(x)			(((x) & 0xf) << 4)
+#define EXYNOS_VIDOSD_ALPHA1_B(x)			(((x) & 0xf) << 0)
+#define EXYNOS_VIDOSD_ALPHA0_SHIFT			(12)
+#define EXYNOS_VIDOSD_ALPHA1_SHIFT			(0)
+
+/* Start Address */
+#define EXYNOS_VIDADDR_START_VBANK(x)			(((x) & 0xff) << 24)
+#define EXYNOS_VIDADDR_START_VBASEU(x)			(((x) & 0xffffff) << 0)
+
+/* End Address */
+#define EXYNOS_VIDADDR_END_VBASEL(x)			(((x) & 0xffffff) << 0)
+
+/* Buffer Size */
+#define EXYNOS_VIDADDR_OFFSIZE(x)			(((x) & 0x1fff) << 13)
+#define EXYNOS_VIDADDR_PAGEWIDTH(x)			(((x) & 0x1fff) << 0)
+
+/* WIN Color Map */
+#define EXYNOS_WINMAP_COLOR(x)				((x) & 0xffffff)
+
+/* VIDINTCON0 */
+#define EXYNOS_VIDINTCON0_SYSMAINCON_DISABLE		(0 << 19)
+#define EXYNOS_VIDINTCON0_SYSMAINCON_ENABLE		(1 << 19)
+#define EXYNOS_VIDINTCON0_SYSSUBCON_DISABLE		(0 << 18)
+#define EXYNOS_VIDINTCON0_SYSSUBCON_ENABLE		(1 << 18)
+#define EXYNOS_VIDINTCON0_SYSIFDONE_DISABLE		(0 << 17)
+#define EXYNOS_VIDINTCON0_SYSIFDONE_ENABLE		(1 << 17)
+#define EXYNOS_VIDINTCON0_FRAMESEL0_BACK		(0 << 15)
+#define EXYNOS_VIDINTCON0_FRAMESEL0_VSYNC		(1 << 15)
+#define EXYNOS_VIDINTCON0_FRAMESEL0_ACTIVE		(2 << 15)
+#define EXYNOS_VIDINTCON0_FRAMESEL0_FRONT		(3 << 15)
+#define EXYNOS_VIDINTCON0_FRAMESEL0_MASK		(3 << 15)
+#define EXYNOS_VIDINTCON0_FRAMESEL1_NONE		(0 << 13)
+#define EXYNOS_VIDINTCON0_FRAMESEL1_BACK		(1 << 13)
+#define EXYNOS_VIDINTCON0_FRAMESEL1_VSYNC		(2 << 13)
+#define EXYNOS_VIDINTCON0_FRAMESEL1_FRONT		(3 << 13)
+#define EXYNOS_VIDINTCON0_INTFRMEN_DISABLE		(0 << 12)
+#define EXYNOS_VIDINTCON0_INTFRMEN_ENABLE		(1 << 12)
+#define EXYNOS_VIDINTCON0_FIFOSEL_WIN4			(1 << 11)
+#define EXYNOS_VIDINTCON0_FIFOSEL_WIN3			(1 << 10)
+#define EXYNOS_VIDINTCON0_FIFOSEL_WIN2			(1 << 9)
+#define EXYNOS_VIDINTCON0_FIFOSEL_WIN1			(1 << 6)
+#define EXYNOS_VIDINTCON0_FIFOSEL_WIN0			(1 << 5)
+#define EXYNOS_VIDINTCON0_FIFOSEL_ALL			(0x73 << 5)
+#define EXYNOS_VIDINTCON0_FIFOSEL_MASK			(0x73 << 5)
+#define EXYNOS_VIDINTCON0_FIFOLEVEL_25			(0 << 2)
+#define EXYNOS_VIDINTCON0_FIFOLEVEL_50			(1 << 2)
+#define EXYNOS_VIDINTCON0_FIFOLEVEL_75			(2 << 2)
+#define EXYNOS_VIDINTCON0_FIFOLEVEL_EMPTY		(3 << 2)
+#define EXYNOS_VIDINTCON0_FIFOLEVEL_FULL		(4 << 2)
+#define EXYNOS_VIDINTCON0_FIFOLEVEL_MASK		(7 << 2)
+#define EXYNOS_VIDINTCON0_INTFIFO_DISABLE		(0 << 1)
+#define EXYNOS_VIDINTCON0_INTFIFO_ENABLE		(1 << 1)
+#define EXYNOS_VIDINTCON0_INT_DISABLE			(0 << 0)
+#define EXYNOS_VIDINTCON0_INT_ENABLE			(1 << 0)
+#define EXYNOS_VIDINTCON0_INT_MASK			(1 << 0)
+
+/* VIDINTCON1 */
+#define EXYNOS_VIDINTCON1_INTVPPEND			(1 << 5)
+#define EXYNOS_VIDINTCON1_INTI80PEND			(1 << 2)
+#define EXYNOS_VIDINTCON1_INTFRMPEND			(1 << 1)
+#define EXYNOS_VIDINTCON1_INTFIFOPEND			(1 << 0)
+
+/* WINMAP */
+#define EXYNOS_WINMAP_ENABLE				(1 << 24)
+
+/* WxKEYCON0 (1~4) */
+#define EXYNOS_KEYCON0_KEYBLEN_DISABLE			(0 << 26)
+#define EXYNOS_KEYCON0_KEYBLEN_ENABLE			(1 << 26)
+#define EXYNOS_KEYCON0_KEY_DISABLE			(0 << 25)
+#define EXYNOS_KEYCON0_KEY_ENABLE			(1 << 25)
+#define EXYNOS_KEYCON0_DIRCON_MATCH_FG			(0 << 24)
+#define EXYNOS_KEYCON0_DIRCON_MATCH_BG			(1 << 24)
+#define EXYNOS_KEYCON0_COMPKEY(x)			(((x) & 0xffffff) << 0)
+
+/* WxKEYCON1 (1~4) */
+#define EXYNOS_KEYCON1_COLVAL(x)			(((x) & 0xffffff) << 0)
+
+/* DUALRGB */
+#define EXYNOS_DUALRGB_BYPASS_SINGLE			(0x00 << 0)
+#define EXYNOS_DUALRGB_BYPASS_DUAL			(0x01 << 0)
+#define EXYNOS_DUALRGB_MIE_DUAL				(0x10 << 0)
+#define EXYNOS_DUALRGB_MIE_SINGLE			(0x11 << 0)
+#define EXYNOS_DUALRGB_LINESPLIT			(0x0 << 2)
+#define EXYNOS_DUALRGB_FRAMESPLIT			(0x1 << 2)
+#define EXYNOS_DUALRGB_SUB_CNT(x)			((x & 0xfff) << 4)
+#define EXYNOS_DUALRGB_VDEN_EN_DISABLE			(0x0 << 16)
+#define EXYNOS_DUALRGB_VDEN_EN_ENABLE			(0x1 << 16)
+#define EXYNOS_DUALRGB_MAIN_CNT(x)			((x & 0xfff) << 18)
+
+/* I80IFCONA0 and I80IFCONA1 */
+#define EXYNOS_LCD_CS_SETUP(x)				(((x) & 0xf) << 16)
+#define EXYNOS_LCD_WR_SETUP(x)				(((x) & 0xf) << 12)
+#define EXYNOS_LCD_WR_ACT(x)				(((x) & 0xf) << 8)
+#define EXYNOS_LCD_WR_HOLD(x)				(((x) & 0xf) << 4)
+#define EXYNOS_RSPOL_LOW				(0 << 2)
+#define EXYNOS_RSPOL_HIGH				(1 << 2)
+#define EXYNOS_I80IFEN_DISABLE				(0 << 0)
+#define EXYNOS_I80IFEN_ENABLE				(1 << 0)
+
+/* TRIGCON */
+#define EXYNOS_I80SOFT_TRIG_EN				(1 << 0)
+#define EXYNOS_I80START_TRIG				(1 << 1)
+#define EXYNOS_I80STATUS_TRIG_DONE			(1 << 2)
+
+#endif /* _REGS_FB_H */

+ 380 - 0
arch/arm/include/asm/arch-exynos/mipi_dsim.h

@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Author: Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; 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
+ */
+
+#ifndef _DSIM_H
+#define _DSIM_H
+
+#include <linux/list.h>
+#include <linux/fb.h>
+
+#define PANEL_NAME_SIZE		(32)
+
+enum mipi_dsim_interface_type {
+	DSIM_COMMAND,
+	DSIM_VIDEO
+};
+
+enum mipi_dsim_virtual_ch_no {
+	DSIM_VIRTUAL_CH_0,
+	DSIM_VIRTUAL_CH_1,
+	DSIM_VIRTUAL_CH_2,
+	DSIM_VIRTUAL_CH_3
+};
+
+enum mipi_dsim_burst_mode_type {
+	DSIM_NON_BURST_SYNC_EVENT,
+	DSIM_BURST_SYNC_EVENT,
+	DSIM_NON_BURST_SYNC_PULSE,
+	DSIM_BURST,
+	DSIM_NON_VIDEO_MODE
+};
+
+enum mipi_dsim_no_of_data_lane {
+	DSIM_DATA_LANE_1,
+	DSIM_DATA_LANE_2,
+	DSIM_DATA_LANE_3,
+	DSIM_DATA_LANE_4
+};
+
+enum mipi_dsim_byte_clk_src {
+	DSIM_PLL_OUT_DIV8,
+	DSIM_EXT_CLK_DIV8,
+	DSIM_EXT_CLK_BYPASS
+};
+
+enum mipi_dsim_pixel_format {
+	DSIM_CMD_3BPP,
+	DSIM_CMD_8BPP,
+	DSIM_CMD_12BPP,
+	DSIM_CMD_16BPP,
+	DSIM_VID_16BPP_565,
+	DSIM_VID_18BPP_666PACKED,
+	DSIM_18BPP_666LOOSELYPACKED,
+	DSIM_24BPP_888
+};
+
+/* MIPI DSI Processor-to-Peripheral transaction types */
+enum {
+	MIPI_DSI_V_SYNC_START				= 0x01,
+	MIPI_DSI_V_SYNC_END				= 0x11,
+	MIPI_DSI_H_SYNC_START				= 0x21,
+	MIPI_DSI_H_SYNC_END				= 0x31,
+
+	MIPI_DSI_COLOR_MODE_OFF				= 0x02,
+	MIPI_DSI_COLOR_MODE_ON				= 0x12,
+	MIPI_DSI_SHUTDOWN_PERIPHERAL			= 0x22,
+	MIPI_DSI_TURN_ON_PERIPHERAL			= 0x32,
+
+	MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM		= 0x03,
+	MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM		= 0x13,
+	MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM		= 0x23,
+
+	MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM		= 0x04,
+	MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM		= 0x14,
+	MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM		= 0x24,
+
+	MIPI_DSI_DCS_SHORT_WRITE			= 0x05,
+	MIPI_DSI_DCS_SHORT_WRITE_PARAM			= 0x15,
+
+	MIPI_DSI_DCS_READ				= 0x06,
+
+	MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE		= 0x37,
+
+	MIPI_DSI_END_OF_TRANSMISSION			= 0x08,
+
+	MIPI_DSI_NULL_PACKET				= 0x09,
+	MIPI_DSI_BLANKING_PACKET			= 0x19,
+	MIPI_DSI_GENERIC_LONG_WRITE			= 0x29,
+	MIPI_DSI_DCS_LONG_WRITE				= 0x39,
+
+	MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20	= 0x0c,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24		= 0x1c,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16		= 0x2c,
+
+	MIPI_DSI_PACKED_PIXEL_STREAM_30			= 0x0d,
+	MIPI_DSI_PACKED_PIXEL_STREAM_36			= 0x1d,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12		= 0x3d,
+
+	MIPI_DSI_PACKED_PIXEL_STREAM_16			= 0x0e,
+	MIPI_DSI_PACKED_PIXEL_STREAM_18			= 0x1e,
+	MIPI_DSI_PIXEL_STREAM_3BYTE_18			= 0x2e,
+	MIPI_DSI_PACKED_PIXEL_STREAM_24			= 0x3e,
+};
+
+/*
+ * struct mipi_dsim_config - interface for configuring mipi-dsi controller.
+ *
+ * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC pulse.
+ * @eot_disable: enable or disable EoT packet in HS mode.
+ * @auto_vertical_cnt: specifies auto vertical count mode.
+ *	in Video mode, the vertical line transition uses line counter
+ *	configured by VSA, VBP, and Vertical resolution.
+ *	If this bit is set to '1', the line counter does not use VSA and VBP
+ *	registers.(in command mode, this variable is ignored)
+ * @hse: set horizontal sync event mode.
+ *	In VSYNC pulse and Vporch area, MIPI DSI master transfers only HSYNC
+ *	start packet to MIPI DSI slave at MIPI DSI spec1.1r02.
+ *	this bit transfers HSYNC end packet in VSYNC pulse and Vporch area
+ *	(in mommand mode, this variable is ignored)
+ * @hfp: specifies HFP disable mode.
+ *	if this variable is set, DSI master ignores HFP area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @hbp: specifies HBP disable mode.
+ *	if this variable is set, DSI master ignores HBP area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @hsa: specifies HSA disable mode.
+ *	if this variable is set, DSI master ignores HSA area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @e_interface: specifies interface to be used.(CPU or RGB interface)
+ * @e_virtual_ch: specifies virtual channel number that main or
+ *	sub diaplsy uses.
+ * @e_pixel_format: specifies pixel stream format for main or sub display.
+ * @e_burst_mode: selects Burst mode in Video mode.
+ *	in Non-burst mode, RGB data area is filled with RGB data and NULL
+ *	packets, according to input bandwidth of RGB interface.
+ *	In Burst mode, RGB data area is filled with RGB data only.
+ * @e_no_data_lane: specifies data lane count to be used by Master.
+ * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8)
+ *	DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported.
+ * @pll_stable_time: specifies the PLL Timer for stability of the ganerated
+ *	clock(System clock cycle base)
+ *	if the timer value goes to 0x00000000, the clock stable bit of status
+ *	and interrupt register is set.
+ * @esc_clk: specifies escape clock frequency for getting the escape clock
+ *	prescaler value.
+ * @stop_holding_cnt: specifies the interval value between transmitting
+ *	read packet(or write "set_tear_on" command) and BTA request.
+ *	after transmitting read packet or write "set_tear_on" command,
+ *	BTA requests to D-PHY automatically. this counter value specifies
+ *	the interval between them.
+ * @bta_timeout: specifies the timer for BTA.
+ *	this register specifies time out from BTA request to change
+ *	the direction with respect to Tx escape clock.
+ * @rx_timeout: specifies the timer for LP Rx mode timeout.
+ *	this register specifies time out on how long RxValid deasserts,
+ *	after RxLpdt asserts with respect to Tx escape clock.
+ *	- RxValid specifies Rx data valid indicator.
+ *	- RxLpdt specifies an indicator that D-PHY is under RxLpdt mode.
+ *	- RxValid and RxLpdt specifies signal from D-PHY.
+ */
+struct mipi_dsim_config {
+	unsigned char			auto_flush;
+	unsigned char			eot_disable;
+
+	unsigned char			auto_vertical_cnt;
+	unsigned char			hse;
+	unsigned char			hfp;
+	unsigned char			hbp;
+	unsigned char			hsa;
+
+	enum mipi_dsim_interface_type	e_interface;
+	enum mipi_dsim_virtual_ch_no	e_virtual_ch;
+	enum mipi_dsim_pixel_format	e_pixel_format;
+	enum mipi_dsim_burst_mode_type	e_burst_mode;
+	enum mipi_dsim_no_of_data_lane	e_no_data_lane;
+	enum mipi_dsim_byte_clk_src	e_byte_clk;
+
+	/*
+	 * ===========================================
+	 * |    P    |    M    |    S    |    MHz    |
+	 * -------------------------------------------
+	 * |    3    |   100   |    3    |    100    |
+	 * |    3    |   100   |    2    |    200    |
+	 * |    3    |    63   |    1    |    252    |
+	 * |    4    |   100   |    1    |    300    |
+	 * |    4    |   110   |    1    |    330    |
+	 * |   12    |   350   |    1    |    350    |
+	 * |    3    |   100   |    1    |    400    |
+	 * |    4    |   150   |    1    |    450    |
+	 * |    6    |   118   |    1    |    472    |
+	 * |	3    |   120   |    1    |    480    |
+	 * |   12    |   250   |    0    |    500    |
+	 * |    4    |   100   |    0    |    600    |
+	 * |    3    |    81   |    0    |    648    |
+	 * |    3    |    88   |    0    |    704    |
+	 * |    3    |    90   |    0    |    720    |
+	 * |    3    |   100   |    0    |    800    |
+	 * |   12    |   425   |    0    |    850    |
+	 * |    4    |   150   |    0    |    900    |
+	 * |   12    |   475   |    0    |    950    |
+	 * |    6    |   250   |    0    |   1000    |
+	 * -------------------------------------------
+	 */
+
+	/*
+	 * pms could be calculated as the following.
+	 * M * 24 / P * 2 ^ S = MHz
+	 */
+	unsigned char			p;
+	unsigned short			m;
+	unsigned char			s;
+
+	unsigned int			pll_stable_time;
+	unsigned long			esc_clk;
+
+	unsigned short			stop_holding_cnt;
+	unsigned char			bta_timeout;
+	unsigned short			rx_timeout;
+};
+
+/*
+ * struct mipi_dsim_device - global interface for mipi-dsi driver.
+ *
+ * @dsim_config: infomation for configuring mipi-dsi controller.
+ * @master_ops: callbacks to mipi-dsi operations.
+ * @dsim_lcd_dev: pointer to activated ddi device.
+ *	(it would be registered by mipi-dsi driver.)
+ * @dsim_lcd_drv: pointer to activated_ddi driver.
+ *	(it would be registered by mipi-dsi driver.)
+ * @state: specifies status of MIPI-DSI controller.
+ *	the status could be RESET, INIT, STOP, HSCLKEN and ULPS.
+ * @data_lane: specifiec enabled data lane number.
+ *	this variable would be set by driver according to e_no_data_lane
+ *	automatically.
+ * @e_clk_src: select byte clock source.
+ * @pd: pointer to MIPI-DSI driver platform data.
+ */
+struct mipi_dsim_device {
+	struct mipi_dsim_config		*dsim_config;
+	struct mipi_dsim_master_ops	*master_ops;
+	struct mipi_dsim_lcd_device	*dsim_lcd_dev;
+	struct mipi_dsim_lcd_driver	*dsim_lcd_drv;
+
+	unsigned int			state;
+	unsigned int			data_lane;
+	enum mipi_dsim_byte_clk_src	e_clk_src;
+
+	struct exynos_platform_mipi_dsim	*pd;
+};
+
+/*
+ * struct exynos_platform_mipi_dsim - interface to platform data
+ *	for mipi-dsi driver.
+ *
+ * @lcd_panel_name: specifies lcd panel name registered to mipi-dsi driver.
+ *	lcd panel driver searched would be actived.
+ * @dsim_config: pointer of structure for configuring mipi-dsi controller.
+ * @lcd_panel_info: pointer for lcd panel specific structure.
+ *	this structure specifies width, height, timing and polarity and so on.
+ * @lcd_power: callback pointer for enabling or disabling lcd power.
+ * @mipi_power: callback pointer for enabling or disabling mipi power.
+ * @phy_enable: pointer to a callback controlling D-PHY enable/reset
+ */
+struct exynos_platform_mipi_dsim {
+	char				lcd_panel_name[PANEL_NAME_SIZE];
+
+	struct mipi_dsim_config		*dsim_config;
+	void				*lcd_panel_info;
+
+	int (*lcd_power)(void);
+	int (*mipi_power)(void);
+	void (*phy_enable)(unsigned int dev_index, unsigned int enable);
+};
+
+/*
+ * struct mipi_dsim_master_ops - callbacks to mipi-dsi operations.
+ *
+ * @cmd_write: transfer command to lcd panel at LP mode.
+ * @cmd_read: read command from rx register.
+ * @get_dsim_frame_done: get the status that all screen data have been
+ *	transferred to mipi-dsi.
+ * @clear_dsim_frame_done: clear frame done status.
+ * @get_fb_frame_done: get frame done status of display controller.
+ * @trigger: trigger display controller.
+ *	- this one would be used only in case of CPU mode.
+ */
+struct mipi_dsim_master_ops {
+	int (*cmd_write)(struct mipi_dsim_device *dsim, unsigned int data_id,
+		unsigned int data0, unsigned int data1);
+	int (*cmd_read)(struct mipi_dsim_device *dsim, unsigned int data_id,
+		unsigned int data0, unsigned int data1);
+	int (*get_dsim_frame_done)(struct mipi_dsim_device *dsim);
+	int (*clear_dsim_frame_done)(struct mipi_dsim_device *dsim);
+
+	int (*get_fb_frame_done)(void);
+	void (*trigger)(struct fb_info *info);
+};
+
+/*
+ * device structure for mipi-dsi based lcd panel.
+ *
+ * @name: name of the device to use with this device, or an
+ *	alias for that name.
+ * @id: id of device to be registered.
+ * @bus_id: bus id for identifing connected bus
+ *	and this bus id should be same as id of mipi_dsim_device.
+ * @master: pointer to mipi-dsi master device object.
+ * @platform_data: lcd panel specific platform data.
+ */
+struct mipi_dsim_lcd_device {
+	char			*name;
+	int			id;
+	int			bus_id;
+
+	struct mipi_dsim_device *master;
+	void			*platform_data;
+};
+
+/*
+ * driver structure for mipi-dsi based lcd panel.
+ *
+ * this structure should be registered by lcd panel driver.
+ * mipi-dsi driver seeks lcd panel registered through name field
+ * and calls these callback functions in appropriate time.
+ *
+ * @name: name of the driver to use with this device, or an
+ *	alias for that name.
+ * @id: id of driver to be registered.
+ *	this id would be used for finding device object registered.
+ * @mipi_panel_init: callback pointer for initializing lcd panel based on mipi
+ *	dsi interface.
+ * @mipi_display_on: callback pointer for lcd panel display on.
+ */
+struct mipi_dsim_lcd_driver {
+	char			*name;
+	int			id;
+
+	int	(*mipi_panel_init)(struct mipi_dsim_device *dsim_dev);
+	void	(*mipi_display_on)(struct mipi_dsim_device *dsim_dev);
+};
+
+int exynos_mipi_dsi_init(void);
+
+/*
+ * register mipi_dsim_lcd_driver object defined by lcd panel driver
+ * to mipi-dsi driver.
+ */
+int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver
+						*lcd_drv);
+
+/*
+ * register mipi_dsim_lcd_device to mipi-dsi master.
+ */
+int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device
+						*lcd_dev);
+
+void exynos_set_dsim_platform_data(struct exynos_platform_mipi_dsim *pd);
+
+/* panel driver init based on mipi dsi interface */
+void s6e8ax0_init(void);
+
+#endif /* _DSIM_H */

+ 6 - 0
arch/arm/include/asm/arch-exynos/power.h

@@ -227,4 +227,10 @@ struct exynos4_power {
 };
 #endif	/* __ASSEMBLY__ */
 
+void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable);
+
+#define EXYNOS_MIPI_PHY_ENABLE		(1 << 0)
+#define EXYNOS_MIPI_PHY_SRESETN		(1 << 1)
+#define EXYNOS_MIPI_PHY_MRESETN		(1 << 2)
+
 #endif

+ 53 - 0
arch/arm/include/asm/arch-exynos/system.h

@@ -0,0 +1,53 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; 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
+ *
+ */
+
+#ifndef __ASM_ARM_ARCH_SYSTEM_H_
+#define __ASM_ARM_ARCH_SYSTEM_H_
+
+#ifndef __ASSEMBLY__
+struct exynos4_sysreg {
+	unsigned char	res1[0x210];
+	unsigned int	display_ctrl;
+	unsigned int	display_ctrl2;
+	unsigned int	camera_control;
+	unsigned int	audio_endian;
+	unsigned int	jtag_con;
+};
+
+struct exynos5_sysreg {
+	unsigned char	res1[0x214];
+	unsigned int	disp1blk_cfg;
+	unsigned int	disp2blk_cfg;
+	unsigned int	hdcp_e_fuse;
+	unsigned int	gsclblk_cfg0;
+	unsigned int	gsclblk_cfg1;
+	unsigned int	reserved;
+	unsigned int	ispblk_cfg;
+	unsigned int	usb20phy_cfg;
+	unsigned int	mipi_dphy;
+	unsigned int	dptx_dphy;
+	unsigned int	phyclk_sel;
+};
+#endif
+
+void set_system_display_ctrl(void);
+
+#endif	/* _EXYNOS4_SYSTEM_H */

+ 1 - 1
arch/arm/include/asm/arch-exynos/tzpc.h

@@ -22,7 +22,7 @@
 #define __TZPC_H_
 
 #ifndef __ASSEMBLY__
-struct exynos5_tzpc {
+struct exynos_tzpc {
 	unsigned int r0size;
 	char res1[0x7FC];
 	unsigned int decprot0stat;

+ 170 - 0
arch/arm/include/asm/arch-lpc32xx/clk.h

@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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.
+ */
+
+#ifndef _LPC32XX_CLK_H
+#define _LPC32XX_CLK_H
+
+#include <asm/types.h>
+
+#define OSC_CLK_FREQUENCY	13000000
+#define RTC_CLK_FREQUENCY	32768
+
+/* Clocking and Power Control Registers */
+struct clk_pm_regs {
+	u32 reserved0[5];
+	u32 boot_map;		/* Boot Map Control Register		*/
+	u32 p0_intr_er;		/* Port 0/1 Start and Interrupt Enable	*/
+	u32 usbdiv_ctrl;	/* USB Clock Pre-Divide Register	*/
+	/* Internal Start Signal Sources Registers	*/
+	u32 start_er_int;	/* Start Enable Register		*/
+	u32 start_rsr_int;	/* Start Raw Status Register		*/
+	u32 start_sr_int;	/* Start Status Register		*/
+	u32 start_apr_int;	/* Start Activation Polarity Register	*/
+	/* Device Pin Start Signal Sources Registers	*/
+	u32 start_er_pin;	/* Start Enable Register		*/
+	u32 start_rsr_pin;	/* Start Raw Status Register		*/
+	u32 start_sr_pin;	/* Start Status Register		*/
+	u32 start_apr_pin;	/* Start Activation Polarity Register	*/
+	/* Clock Control Registers			*/
+	u32 hclkdiv_ctrl;	/* HCLK Divider Control Register	*/
+	u32 pwr_ctrl;		/* Power Control Register		*/
+	u32 pll397_ctrl;	/* PLL397 Control Register		*/
+	u32 osc_ctrl;		/* Main Oscillator Control Register	*/
+	u32 sysclk_ctrl;	/* SYSCLK Control Register		*/
+	u32 lcdclk_ctrl;	/* LCD Clock Control Register		*/
+	u32 hclkpll_ctrl;	/* HCLK PLL Control Register		*/
+	u32 reserved1;
+	u32 adclk_ctrl1;	/* ADC Clock Control1 Register		*/
+	u32 usb_ctrl;		/* USB Control Register			*/
+	u32 sdramclk_ctrl;	/* SDRAM Clock Control Register		*/
+	u32 ddr_lap_nom;	/* DDR Calibration Nominal Value	*/
+	u32 ddr_lap_count;	/* DDR Calibration Measured Value	*/
+	u32 ddr_cal_delay;	/* DDR Calibration Delay Value		*/
+	u32 ssp_ctrl;		/* SSP Control Register			*/
+	u32 i2s_ctrl;		/* I2S Clock Control Register		*/
+	u32 ms_ctrl;		/* Memory Card Control Register		*/
+	u32 reserved2[3];
+	u32 macclk_ctrl;	/* Ethernet MAC Clock Control Register	*/
+	u32 reserved3[4];
+	u32 test_clk;		/* Test Clock Selection Register	*/
+	u32 sw_int;		/* Software Interrupt Register		*/
+	u32 i2cclk_ctrl;	/* I2C Clock Control Register		*/
+	u32 keyclk_ctrl;	/* Keyboard Scan Clock Control Register	*/
+	u32 adclk_ctrl;		/* ADC Clock Control Register		*/
+	u32 pwmclk_ctrl;	/* PWM Clock Control Register		*/
+	u32 timclk_ctrl;	/* Watchdog and Highspeed Timer Control */
+	u32 timclk_ctrl1;	/* Motor and Timer Clock Control	*/
+	u32 spi_ctrl;		/* SPI Control Register			*/
+	u32 flashclk_ctrl;	/* NAND Flash Clock Control Register	*/
+	u32 reserved4;
+	u32 u3clk;		/* UART 3 Clock Control Register	*/
+	u32 u4clk;		/* UART 4 Clock Control Register	*/
+	u32 u5clk;		/* UART 5 Clock Control Register	*/
+	u32 u6clk;		/* UART 6 Clock Control Register	*/
+	u32 irdaclk;		/* IrDA Clock Control Register		*/
+	u32 uartclk_ctrl;	/* UART Clock Control Register		*/
+	u32 dmaclk_ctrl;	/* DMA Clock Control Register		*/
+	u32 autoclk_ctrl;	/* Autoclock Control Register		*/
+};
+
+/* HCLK Divider Control Register bits */
+#define CLK_HCLK_DDRAM_HALF		(0x2 << 7)
+#define CLK_HCLK_DDRAM_NOMINAL		(0x1 << 7)
+#define CLK_HCLK_DDRAM_STOPPED		(0x0 << 7)
+#define CLK_HCLK_PERIPH_DIV_MASK	(0x1F << 2)
+#define CLK_HCLK_PERIPH_DIV(n)		((((n) - 1) & 0x1F) << 2)
+#define CLK_HCLK_ARM_PLL_DIV_MASK	(0x3 << 0)
+#define CLK_HCLK_ARM_PLL_DIV_4		(0x2 << 0)
+#define CLK_HCLK_ARM_PLL_DIV_2		(0x1 << 0)
+#define CLK_HCLK_ARM_PLL_DIV_1		(0x0 << 0)
+
+/* Power Control Register bits */
+#define CLK_PWR_HCLK_RUN_PERIPH		(1 << 10)
+#define CLK_PWR_EMC_SREFREQ		(1 << 9)
+#define CLK_PWR_EMC_SREFREQ_UPDATE	(1 << 8)
+#define CLK_PWR_SDRAM_SREFREQ		(1 << 7)
+#define CLK_PWR_HIGHCORE_LEVEL		(1 << 5)
+#define CLK_PWR_SYSCLKEN_LEVEL		(1 << 4)
+#define CLK_PWR_SYSCLKEN_CTRL		(1 << 3)
+#define CLK_PWR_NORMAL_RUN		(1 << 2)
+#define CLK_PWR_HIGHCORE_CTRL		(1 << 1)
+#define CLK_PWR_STOP_MODE		(1 << 0)
+
+/* SYSCLK Control Register bits */
+#define CLK_SYSCLK_PLL397		(1 << 1)
+#define CLK_SYSCLK_MUX			(1 << 0)
+
+/* HCLK PLL Control Register bits */
+#define CLK_HCLK_PLL_OPERATING		(1 << 16)
+#define CLK_HCLK_PLL_BYPASS		(1 << 15)
+#define CLK_HCLK_PLL_DIRECT		(1 << 14)
+#define CLK_HCLK_PLL_FEEDBACK		(1 << 13)
+#define CLK_HCLK_PLL_POSTDIV_MASK	(0x3 << 11)
+#define CLK_HCLK_PLL_POSTDIV_16		(0x3 << 11)
+#define CLK_HCLK_PLL_POSTDIV_8		(0x2 << 11)
+#define CLK_HCLK_PLL_POSTDIV_4		(0x1 << 11)
+#define CLK_HCLK_PLL_POSTDIV_2		(0x0 << 11)
+#define CLK_HCLK_PLL_PREDIV_MASK	(0x3 << 9)
+#define CLK_HCLK_PLL_PREDIV_4		(0x3 << 9)
+#define CLK_HCLK_PLL_PREDIV_3		(0x2 << 9)
+#define CLK_HCLK_PLL_PREDIV_2		(0x1 << 9)
+#define CLK_HCLK_PLL_PREDIV_1		(0x0 << 9)
+#define CLK_HCLK_PLL_FEEDBACK_DIV_MASK	(0xFF << 1)
+#define CLK_HCLK_PLL_FEEDBACK_DIV(n)	((((n) - 1) & 0xFF) << 1)
+#define CLK_HCLK_PLL_LOCKED		(1 << 0)
+
+/* Ethernet MAC Clock Control Register bits	*/
+#define CLK_MAC_RMII			(0x3 << 3)
+#define CLK_MAC_MII			(0x1 << 3)
+#define CLK_MAC_MASTER			(1 << 2)
+#define CLK_MAC_SLAVE			(1 << 1)
+#define CLK_MAC_REG			(1 << 0)
+
+/* Timer Clock Control1 Register bits */
+#define CLK_TIMCLK_MOTOR		(1 << 6)
+#define CLK_TIMCLK_TIMER3		(1 << 5)
+#define CLK_TIMCLK_TIMER2		(1 << 4)
+#define CLK_TIMCLK_TIMER1		(1 << 3)
+#define CLK_TIMCLK_TIMER0		(1 << 2)
+#define CLK_TIMCLK_TIMER5		(1 << 1)
+#define CLK_TIMCLK_TIMER4		(1 << 0)
+
+/* Timer Clock Control Register bits */
+#define CLK_TIMCLK_HSTIMER		(1 << 1)
+#define CLK_TIMCLK_WATCHDOG		(1 << 0)
+
+/* UART Clock Control Register bits */
+#define CLK_UART(n)			(1 << ((n) - 3))
+
+/* UARTn Clock Select Registers bits */
+#define CLK_UART_HCLK			(1 << 16)
+#define CLK_UART_X_DIV(n)		(((n) & 0xFF) << 8)
+#define CLK_UART_Y_DIV(n)		(((n) & 0xFF) << 0)
+
+/* DMA Clock Control Register bits */
+#define CLK_DMA_ENABLE			(1 << 0)
+
+unsigned int get_sys_clk_rate(void);
+unsigned int get_hclk_pll_rate(void);
+unsigned int get_hclk_clk_div(void);
+unsigned int get_hclk_clk_rate(void);
+unsigned int get_periph_clk_div(void);
+unsigned int get_periph_clk_rate(void);
+
+#endif /* _LPC32XX_CLK_H */

+ 76 - 0
arch/arm/include/asm/arch-lpc32xx/config.h

@@ -0,0 +1,76 @@
+/*
+ * Common definitions for LPC32XX board configurations
+ *
+ * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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.
+ */
+
+#ifndef _LPC32XX_CONFIG_H
+#define _LPC32XX_CONFIG_H
+
+/* Basic CPU architecture */
+#define CONFIG_ARM926EJS
+#define CONFIG_ARCH_CPU_INIT
+
+#define CONFIG_NR_DRAM_BANKS_MAX	2
+
+/* 1KHz clock tick */
+#define CONFIG_SYS_HZ			1000
+
+/* UART configuration */
+#if (CONFIG_SYS_LPC32XX_UART >= 3) && (CONFIG_SYS_LPC32XX_UART <= 6)
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_CONS_INDEX		(CONFIG_SYS_LPC32XX_UART - 2)
+#elif	(CONFIG_SYS_LPC32XX_UART == 1) || (CONFIG_SYS_LPC32XX_UART == 2) || \
+	(CONFIG_SYS_LPC32XX_UART == 7)
+#define CONFIG_LPC32XX_HSUART
+#else
+#error "define CONFIG_SYS_LPC32XX_UART in the range from 1 to 7"
+#endif
+
+#if defined(CONFIG_SYS_NS16550_SERIAL)
+#define CONFIG_SYS_NS16550
+
+#define CONFIG_SYS_NS16550_REG_SIZE	-4
+#define CONFIG_SYS_NS16550_CLK		get_serial_clock()
+
+#define CONFIG_SYS_NS16550_COM1		UART3_BASE
+#define CONFIG_SYS_NS16550_COM2		UART4_BASE
+#define CONFIG_SYS_NS16550_COM3		UART5_BASE
+#define CONFIG_SYS_NS16550_COM4		UART6_BASE
+#endif
+
+#if defined(CONFIG_LPC32XX_HSUART)
+#if	CONFIG_SYS_LPC32XX_UART == 1
+#define HS_UART_BASE			HS_UART1_BASE
+#elif	CONFIG_SYS_LPC32XX_UART == 2
+#define HS_UART_BASE			HS_UART2_BASE
+#else	/* CONFIG_SYS_LPC32XX_UART == 7 */
+#define HS_UART_BASE			HS_UART7_BASE
+#endif
+#endif
+
+#define CONFIG_SYS_BAUDRATE_TABLE	\
+		{ 9600, 19200, 38400, 57600, 115200, 230400, 460800 }
+
+/* NOR Flash */
+#if defined(CONFIG_SYS_FLASH_CFI)
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_SYS_FLASH_PROTECTION
+#endif
+
+#endif /* _LPC32XX_CONFIG_H */

+ 64 - 0
arch/arm/include/asm/arch-lpc32xx/cpu.h

@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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.
+ */
+
+#ifndef _LPC32XX_CPU_H
+#define _LPC32XX_CPU_H
+
+/* LPC32XX Memory map */
+
+/* AHB physical base addresses */
+#define SLC_NAND_BASE	0x20020000	/* SLC NAND Flash registers base    */
+#define SSP0_BASE	0x20084000	/* SSP0 registers base              */
+#define SD_CARD_BASE	0x20098000	/* SD card interface registers base */
+#define MLC_NAND_BASE	0x200A8000	/* MLC NAND Flash registers base    */
+#define DMA_BASE	0x31000000	/* DMA controller registers base    */
+#define USB_BASE	0x31020000	/* USB registers base               */
+#define LCD_BASE	0x31040000	/* LCD registers base               */
+#define ETHERNET_BASE	0x31060000	/* Ethernet registers base          */
+#define EMC_BASE	0x31080000	/* EMC configuration registers base */
+
+/* FAB peripherals base addresses */
+#define CLK_PM_BASE	0x40004000	/* System control registers base    */
+#define HS_UART1_BASE	0x40014000	/* High speed UART 1 registers base */
+#define HS_UART2_BASE	0x40018000	/* High speed UART 2 registers base */
+#define HS_UART7_BASE	0x4001C000	/* High speed UART 7 registers base */
+#define RTC_BASE	0x40024000	/* RTC registers base               */
+#define GPIO_BASE	0x40028000	/* GPIO registers base              */
+#define WDT_BASE	0x4003C000	/* Watchdog timer registers base    */
+#define TIMER0_BASE	0x40044000	/* Timer0 registers base            */
+#define TIMER1_BASE	0x4004C000	/* Timer1 registers base            */
+#define UART_CTRL_BASE	0x40054000	/* UART control regsisters base     */
+
+/* APB peripherals base addresses */
+#define UART3_BASE	0x40080000	/* UART 3 registers base            */
+#define UART4_BASE	0x40088000	/* UART 4 registers base            */
+#define UART5_BASE	0x40090000	/* UART 5 registers base            */
+#define UART6_BASE	0x40098000	/* UART 6 registers base            */
+
+/* External SDRAM Memory Bank base addresses */
+#define EMC_DYCS0_BASE	0x80000000	/* SDRAM DYCS0 base address         */
+#define EMC_DYCS1_BASE	0xA0000000	/* SDRAM DYCS1 base address         */
+
+/* External Static Memory Bank base addresses */
+#define EMC_CS0_BASE	0xE0000000
+#define EMC_CS1_BASE	0xE1000000
+#define EMC_CS2_BASE	0xE2000000
+#define EMC_CS3_BASE	0xE3000000
+
+#endif /* _LPC32XX_CPU_H */

+ 92 - 0
arch/arm/include/asm/arch-lpc32xx/emc.h

@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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.
+ */
+
+#ifndef _LPC32XX_EMC_H
+#define _LPC32XX_EMC_H
+
+#include <asm/types.h>
+
+/* EMC Registers */
+struct emc_regs {
+	u32 ctrl;		/* Controls operation of the EMC             */
+	u32 status;		/* Provides EMC status information           */
+	u32 config;		/* Configures operation of the EMC           */
+	u32 reserved0[5];
+	u32 control;		/* Controls dyn memory operation             */
+	u32 refresh;		/* Configures dyn memory refresh operation   */
+	u32 read_config;	/* Configures the dyn memory read strategy   */
+	u32 reserved1;
+	u32 t_rp;		/* Precharge command period                  */
+	u32 t_ras;		/* Active to precharge command period        */
+	u32 t_srex;		/* Self-refresh exit time                    */
+	u32 reserved2[2];
+	u32 t_wr;		/* Write recovery time                       */
+	u32 t_rc;		/* Active to active command period           */
+	u32 t_rfc;		/* Auto-refresh period                       */
+	u32 t_xsr;		/* Exit self-refresh to active command time  */
+	u32 t_rrd;		/* Active bank A to active bank B latency    */
+	u32 t_mrd;		/* Load mode register to active command time */
+	u32 t_cdlr;		/* Last data in to read command time         */
+	u32 reserved3[8];
+	u32 extended_wait;	/* time for static memory rd/wr transfers    */
+	u32 reserved4[31];
+	u32 config0;		/* Configuration information for the SDRAM   */
+	u32 rascas0;		/* RAS and CAS latencies for the SDRAM       */
+	u32 reserved5[6];
+	u32 config1;		/* Configuration information for the SDRAM   */
+	u32 rascas1;		/* RAS and CAS latencies for the SDRAM       */
+	u32 reserved6[54];
+	struct emc_stat_t {
+		u32 config;	/* Static memory configuration               */
+		u32 waitwen;	/* Delay from chip select to write enable    */
+		u32 waitoen;	/* Delay to output enable                    */
+		u32 waitrd;	/* Delay to a read access                    */
+		u32 waitpage;	/* Delay for async page mode read            */
+		u32 waitwr;	/* Delay to a write access                   */
+		u32 waitturn;	/* Number of bus turnaround cycles           */
+		u32 reserved;
+	} stat[4];
+	u32 reserved7[96];
+	struct emc_ahb_t {
+		u32 control;	/* Control register for AHB                  */
+		u32 status;	/* Status register for AHB                   */
+		u32 timeout;	/* Timeout register for AHB                  */
+		u32 reserved[5];
+	} ahb[5];
+};
+
+/* Static Memory Configuration Register bits */
+#define EMC_STAT_CONFIG_WP		(1 << 20)
+#define EMC_STAT_CONFIG_EW		(1 << 8)
+#define EMC_STAT_CONFIG_PB		(1 << 7)
+#define EMC_STAT_CONFIG_PC		(1 << 6)
+#define EMC_STAT_CONFIG_PM		(1 << 3)
+#define EMC_STAT_CONFIG_32BIT		(2 << 0)
+#define EMC_STAT_CONFIG_16BIT		(1 << 0)
+#define EMC_STAT_CONFIG_8BIT		(0 << 0)
+
+/* Static Memory Delay Registers */
+#define EMC_STAT_WAITWEN(n)		(((n) - 1) & 0x0F)
+#define EMC_STAT_WAITOEN(n)		(((n) - 1) & 0x0F)
+#define EMC_STAT_WAITRD(n)		(((n) - 1) & 0x1F)
+#define EMC_STAT_WAITPAGE(n)		(((n) - 1) & 0x1F)
+#define EMC_STAT_WAITWR(n)		(((n) - 2) & 0x1F)
+#define EMC_STAT_WAITTURN(n)		(((n) - 1) & 0x0F)
+
+#endif /* _LPC32XX_EMC_H */

+ 25 - 0
arch/arm/include/asm/arch-lpc32xx/sys_proto.h

@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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.
+ */
+
+#ifndef _LPC32XX_SYS_PROTO_H
+#define _LPC32XX_SYS_PROTO_H
+
+void lpc32xx_uart_init(unsigned int uart_id);
+
+#endif /* _LPC32XX_SYS_PROTO_H */

+ 74 - 0
arch/arm/include/asm/arch-lpc32xx/timer.h

@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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.
+ */
+
+#ifndef _LPC32XX_TIMER_H
+#define _LPC32XX_TIMER_H
+
+#include <asm/types.h>
+
+/* Timer/Counter Registers */
+struct timer_regs {
+	u32 ir;			/* Interrupt Register		*/
+	u32 tcr;		/* Timer Control Register	*/
+	u32 tc;			/* Timer Counter		*/
+	u32 pr;			/* Prescale Register		*/
+	u32 pc;			/* Prescale Counter		*/
+	u32 mcr;		/* Match Control Register	*/
+	u32 mr[4];		/* Match Registers		*/
+	u32 ccr;		/* Capture Control Register	*/
+	u32 cr[4];		/* Capture Registers		*/
+	u32 emr;		/* External Match Register	*/
+	u32 reserved[12];
+	u32 ctcr;		/* Count Control Register	*/
+};
+
+/* Timer/Counter Interrupt Register bits */
+#define TIMER_IR_CR(n)			(1 << ((n) + 4))
+#define TIMER_IR_MR(n)			(1 << (n))
+
+/* Timer/Counter Timer Control Register bits */
+#define TIMER_TCR_COUNTER_RESET		(1 << 1)
+#define TIMER_TCR_COUNTER_ENABLE	(1 << 0)
+#define TIMER_TCR_COUNTER_DISABLE	(0 << 0)
+
+/* Timer/Counter Match Control Register bits */
+#define TIMER_MCR_STOP(n)		(1 << (3 * (n) + 2))
+#define TIMER_MCR_RESET(n)		(1 << (3 * (n) + 1))
+#define TIMER_MCR_INTERRUPT(n)		(1 << (3 * (n)))
+
+/* Timer/Counter Capture Control Register bits */
+#define TIMER_CCR_INTERRUPT(n)		(1 << (3 * (n) + 2))
+#define TIMER_CCR_FALLING_EDGE(n)	(1 << (3 * (n) + 1))
+#define TIMER_CCR_RISING_EDGE(n)	(1 << (3 * (n)))
+
+/* Timer/Counter External Match Register bits */
+#define TIMER_EMR_EMC_TOGGLE(n)		(0x3 << (2 * (n) + 4))
+#define TIMER_EMR_EMC_SET(n)		(0x2 << (2 * (n) + 4))
+#define TIMER_EMR_EMC_CLEAR(n)		(0x1 << (2 * (n) + 4))
+#define TIMER_EMR_EMC_NOTHING(n)	(0x0 << (2 * (n) + 4))
+#define TIMER_EMR_EM(n)			(1 << (n))
+
+/* Timer/Counter Count Control Register bits */
+#define TIMER_CTCR_INPUT(n)		((n) << 2)
+#define TIMER_CTCR_MODE_COUNTER_BOTH	(0x3 << 0)
+#define TIMER_CTCR_MODE_COUNTER_FALLING	(0x2 << 0)
+#define TIMER_CTCR_MODE_COUNTER_RISING	(0x1 << 0)
+#define TIMER_CTCR_MODE_TIMER		(0x0 << 0)
+
+#endif /* _LPC32XX_TIMER_H */

+ 114 - 0
arch/arm/include/asm/arch-lpc32xx/uart.h

@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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.
+ */
+
+#ifndef _LPC32XX_UART_H
+#define _LPC32XX_UART_H
+
+#include <asm/types.h>
+
+/* 14-clock UART Registers */
+struct hsuart_regs {
+	union {
+		u32 rx;		/* Receiver FIFO		*/
+		u32 tx;		/* Transmitter FIFO		*/
+	};
+	u32 level;		/* FIFO Level Register		*/
+	u32 iir;		/* Interrupt ID Register	*/
+	u32 ctrl;		/* Control Register		*/
+	u32 rate;		/* Rate Control Register	*/
+};
+
+/* 14-clock UART Receiver FIFO Register bits */
+#define HSUART_RX_BREAK			(1 << 10)
+#define HSUART_RX_ERROR			(1 << 9)
+#define HSUART_RX_EMPTY			(1 << 8)
+#define HSUART_RX_DATA			(0xff << 0)
+
+/* 14-clock UART Level Register bits */
+#define HSUART_LEVEL_TX			(0xff << 8)
+#define HSUART_LEVEL_RX			(0xff << 0)
+
+/* 14-clock UART Interrupt Identification Register bits */
+#define HSUART_IIR_TX_INT_SET		(1 << 6)
+#define HSUART_IIR_RX_OE		(1 << 5)
+#define HSUART_IIR_BRK			(1 << 4)
+#define HSUART_IIR_FE			(1 << 3)
+#define HSUART_IIR_RX_TIMEOUT		(1 << 2)
+#define HSUART_IIR_RX_TRIG		(1 << 1)
+#define HSUART_IIR_TX			(1 << 0)
+
+/* 14-clock UART Control Register bits */
+#define HSUART_CTRL_HRTS_INV		(1 << 21)
+#define HSUART_CTRL_HRTS_TRIG_48	(0x3 << 19)
+#define HSUART_CTRL_HRTS_TRIG_32	(0x2 << 19)
+#define HSUART_CTRL_HRTS_TRIG_16	(0x1 << 19)
+#define HSUART_CTRL_HRTS_TRIG_8		(0x0 << 19)
+#define HSUART_CTRL_HRTS_EN		(1 << 18)
+#define HSUART_CTRL_TMO_16		(0x3 << 16)
+#define HSUART_CTRL_TMO_8		(0x2 << 16)
+#define HSUART_CTRL_TMO_4		(0x1 << 16)
+#define HSUART_CTRL_TMO_DISABLED	(0x0 << 16)
+#define HSUART_CTRL_HCTS_INV		(1 << 15)
+#define HSUART_CTRL_HCTS_EN		(1 << 14)
+#define HSUART_CTRL_HSU_OFFSET(n)	((n) << 9)
+#define HSUART_CTRL_HSU_BREAK		(1 << 8)
+#define HSUART_CTRL_HSU_ERR_INT_EN	(1 << 7)
+#define HSUART_CTRL_HSU_RX_INT_EN	(1 << 6)
+#define HSUART_CTRL_HSU_TX_INT_EN	(1 << 5)
+#define HSUART_CTRL_HSU_RX_TRIG_48	(0x5 << 2)
+#define HSUART_CTRL_HSU_RX_TRIG_32	(0x4 << 2)
+#define HSUART_CTRL_HSU_RX_TRIG_16	(0x3 << 2)
+#define HSUART_CTRL_HSU_RX_TRIG_8	(0x2 << 2)
+#define HSUART_CTRL_HSU_RX_TRIG_4	(0x1 << 2)
+#define HSUART_CTRL_HSU_RX_TRIG_1	(0x0 << 2)
+#define HSUART_CTRL_HSU_TX_TRIG_16	(0x3 << 0)
+#define HSUART_CTRL_HSU_TX_TRIG_8	(0x2 << 0)
+#define HSUART_CTRL_HSU_TX_TRIG_4	(0x1 << 0)
+#define HSUART_CTRL_HSU_TX_TRIG_0	(0x0 << 0)
+
+/* UART Control Registers */
+struct uart_ctrl_regs {
+	u32 ctrl;		/* Control Register		*/
+	u32 clkmode;		/* Clock Mode Register		*/
+	u32 loop;		/* Loopback Control Register	*/
+};
+
+/* UART Control Register bits */
+#define UART_CTRL_UART3_MD_CTRL		(1 << 11)
+#define UART_CTRL_HDPX_INV		(1 << 10)
+#define UART_CTRL_HDPX_EN		(1 << 9)
+#define UART_CTRL_UART6_IRDA		(1 << 5)
+#define UART_CTRL_IR_TX6_INV		(1 << 4)
+#define UART_CTRL_IR_RX6_INV		(1 << 3)
+#define UART_CTRL_IR_RX_LENGTH		(1 << 2)
+#define UART_CTRL_IR_TX_LENGTH		(1 << 1)
+#define UART_CTRL_UART5_USB_MODE	(1 << 0)
+
+/* UART Clock Mode Register bits */
+#define UART_CLKMODE_STATX(n)		(1 << ((n) + 16))
+#define UART_CLKMODE_STAT		(1 << 14)
+#define UART_CLKMODE_MASK(n)		(0x3 << (2 * (n) - 2))
+#define UART_CLKMODE_AUTO(n)		(0x2 << (2 * (n) - 2))
+#define UART_CLKMODE_ON(n)		(0x1 << (2 * (n) - 2))
+#define UART_CLKMODE_OFF(n)		(0x0 << (2 * (n) - 2))
+
+/* UART Loopback Control Register bits */
+#define UART_LOOPBACK(n)		(1 << ((n) - 1))
+
+#endif /* _LPC32XX_UART_H */

+ 51 - 0
arch/arm/include/asm/arch-lpc32xx/wdt.h

@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; 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.
+ */
+
+#ifndef _LPC32XX_WDT_H
+#define _LPC32XX_WDT_H
+
+#include <asm/types.h>
+
+/* Watchdog Timer Registers */
+struct wdt_regs {
+	u32 isr;		/* Interrupt Status Register		*/
+	u32 ctrl;		/* Control Register			*/
+	u32 counter;		/* Counter Value Register		*/
+	u32 mctrl;		/* Match Control Register		*/
+	u32 match0;		/* Match 0 Register			*/
+	u32 emr;		/* External Match Control Register	*/
+	u32 pulse;		/* Reset Pulse Length Register		*/
+	u32 res;		/* Reset Source Register		*/
+};
+
+/* Watchdog Timer Control Register bits */
+#define WDTIM_CTRL_PAUSE_EN		(1 << 2)
+#define WDTIM_CTRL_RESET_COUNT		(1 << 1)
+#define WDTIM_CTRL_COUNT_ENAB		(1 << 0)
+
+/* Watchdog Timer Match Control Register bits */
+#define WDTIM_MCTRL_RESFRC2		(1 << 6)
+#define WDTIM_MCTRL_RESFRC1		(1 << 5)
+#define WDTIM_MCTRL_M_RES2		(1 << 4)
+#define WDTIM_MCTRL_M_RES1		(1 << 3)
+#define WDTIM_MCTRL_STOP_COUNT0		(1 << 2)
+#define WDTIM_MCTRL_RESET_COUNT0	(1 << 1)
+#define WDTIM_MCTRL_MR0_INT		(1 << 0)
+
+#endif /* _LPC32XX_WDT_H */

+ 23 - 0
arch/arm/include/asm/arch-mx25/clock.h

@@ -26,11 +26,34 @@
 #ifndef __ASM_ARCH_CLOCK_H
 #define __ASM_ARCH_CLOCK_H
 
+enum mxc_clock {
+	MXC_CSI_CLK,
+	MXC_EPIT_CLK,
+	MXC_ESAI_CLK,
+	MXC_ESDHC1_CLK,
+	MXC_ESDHC2_CLK,
+	MXC_GPT_CLK,
+	MXC_I2C_CLK,
+	MXC_LCDC_CLK,
+	MXC_NFC_CLK,
+	MXC_OWIRE_CLK,
+	MXC_PWM_CLK,
+	MXC_SIM1_CLK,
+	MXC_SIM2_CLK,
+	MXC_SSI1_CLK,
+	MXC_SSI2_CLK,
+	MXC_UART_CLK,
+	MXC_ARM_CLK,
+	MXC_FEC_CLK,
+	MXC_CLK_NUM
+};
+
 ulong imx_get_perclk(int clk);
 ulong imx_get_ahbclk(void);
 
 #define imx_get_uartclk() imx_get_perclk(15)
 #define imx_get_fecclk() (imx_get_ahbclk()/2)
 
+unsigned int mxc_get_clock(enum mxc_clock clk);
 
 #endif /* __ASM_ARCH_CLOCK_H */

+ 3 - 0
arch/arm/include/asm/arch-mx25/imx-regs.h

@@ -34,6 +34,9 @@
 #define _IMX_REGS_H
 
 #ifndef __ASSEMBLY__
+
+#include <asm/types.h>
+
 #ifdef CONFIG_FEC_MXC
 extern void mx25_fec_init_pins(void);
 #endif

+ 2 - 0
arch/arm/include/asm/arch-mx28/imx-regs.h

@@ -30,6 +30,8 @@
 #include <asm/arch/regs-digctl.h>
 #include <asm/arch/regs-gpmi.h>
 #include <asm/arch/regs-i2c.h>
+#include <asm/arch/regs-lcdif.h>
+#include <asm/arch/regs-lradc.h>
 #include <asm/arch/regs-ocotp.h>
 #include <asm/arch/regs-pinctrl.h>
 #include <asm/arch/regs-power.h>

+ 212 - 0
arch/arm/include/asm/arch-mx28/regs-lcdif.h

@@ -0,0 +1,212 @@
+/*
+ * Freescale i.MX28 LCDIF Register Definitions
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * Based on code from LTIB:
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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
+ *
+ */
+
+#ifndef __MX28_REGS_LCDIF_H__
+#define __MX28_REGS_LCDIF_H__
+
+#include <asm/arch/regs-common.h>
+
+#ifndef	__ASSEMBLY__
+struct mx28_lcdif_regs {
+	mx28_reg_32(hw_lcdif_ctrl)		/* 0x00 */
+	mx28_reg_32(hw_lcdif_ctrl1)		/* 0x10 */
+	mx28_reg_32(hw_lcdif_ctrl2)		/* 0x20 */
+	mx28_reg_32(hw_lcdif_transfer_count)	/* 0x30 */
+	mx28_reg_32(hw_lcdif_cur_buf)		/* 0x40 */
+	mx28_reg_32(hw_lcdif_next_buf)		/* 0x50 */
+	mx28_reg_32(hw_lcdif_timing)		/* 0x60 */
+	mx28_reg_32(hw_lcdif_vdctrl0)		/* 0x70 */
+	mx28_reg_32(hw_lcdif_vdctrl1)		/* 0x80 */
+	mx28_reg_32(hw_lcdif_vdctrl2)		/* 0x90 */
+	mx28_reg_32(hw_lcdif_vdctrl3)		/* 0xa0 */
+	mx28_reg_32(hw_lcdif_vdctrl4)		/* 0xb0 */
+	mx28_reg_32(hw_lcdif_dvictrl0)		/* 0xc0 */
+	mx28_reg_32(hw_lcdif_dvictrl1)		/* 0xd0 */
+	mx28_reg_32(hw_lcdif_dvictrl2)		/* 0xe0 */
+	mx28_reg_32(hw_lcdif_dvictrl3)		/* 0xf0 */
+	mx28_reg_32(hw_lcdif_dvictrl4)		/* 0x100 */
+	mx28_reg_32(hw_lcdif_csc_coeffctrl0)	/* 0x110 */
+	mx28_reg_32(hw_lcdif_csc_coeffctrl1)	/* 0x120 */
+	mx28_reg_32(hw_lcdif_csc_coeffctrl2)	/* 0x130 */
+	mx28_reg_32(hw_lcdif_csc_coeffctrl3)	/* 0x140 */
+	mx28_reg_32(hw_lcdif_csc_coeffctrl4)	/* 0x150 */
+	mx28_reg_32(hw_lcdif_csc_offset)	/* 0x160 */
+	mx28_reg_32(hw_lcdif_csc_limit)		/* 0x170 */
+	mx28_reg_32(hw_lcdif_data)		/* 0x180 */
+	mx28_reg_32(hw_lcdif_bm_error_stat)	/* 0x190 */
+	mx28_reg_32(hw_lcdif_crc_stat)		/* 0x1a0 */
+	mx28_reg_32(hw_lcdif_lcdif_stat)	/* 0x1b0 */
+	mx28_reg_32(hw_lcdif_version)		/* 0x1c0 */
+	mx28_reg_32(hw_lcdif_debug0)		/* 0x1d0 */
+	mx28_reg_32(hw_lcdif_debug1)		/* 0x1e0 */
+	mx28_reg_32(hw_lcdif_debug2)		/* 0x1f0 */
+};
+#endif
+
+#define	LCDIF_CTRL_SFTRST					(1 << 31)
+#define	LCDIF_CTRL_CLKGATE					(1 << 30)
+#define	LCDIF_CTRL_YCBCR422_INPUT				(1 << 29)
+#define	LCDIF_CTRL_READ_WRITEB					(1 << 28)
+#define	LCDIF_CTRL_WAIT_FOR_VSYNC_EDGE				(1 << 27)
+#define	LCDIF_CTRL_DATA_SHIFT_DIR				(1 << 26)
+#define	LCDIF_CTRL_SHIFT_NUM_BITS_MASK				(0x1f << 21)
+#define	LCDIF_CTRL_SHIFT_NUM_BITS_OFFSET			21
+#define	LCDIF_CTRL_DVI_MODE					(1 << 20)
+#define	LCDIF_CTRL_BYPASS_COUNT					(1 << 19)
+#define	LCDIF_CTRL_VSYNC_MODE					(1 << 18)
+#define	LCDIF_CTRL_DOTCLK_MODE					(1 << 17)
+#define	LCDIF_CTRL_DATA_SELECT					(1 << 16)
+#define	LCDIF_CTRL_INPUT_DATA_SWIZZLE_MASK			(0x3 << 14)
+#define	LCDIF_CTRL_INPUT_DATA_SWIZZLE_OFFSET			14
+#define	LCDIF_CTRL_CSC_DATA_SWIZZLE_MASK			(0x3 << 12)
+#define	LCDIF_CTRL_CSC_DATA_SWIZZLE_OFFSET			12
+#define	LCDIF_CTRL_LCD_DATABUS_WIDTH_MASK			(0x3 << 10)
+#define	LCDIF_CTRL_LCD_DATABUS_WIDTH_OFFSET			10
+#define	LCDIF_CTRL_LCD_DATABUS_WIDTH_16BIT			(0 << 10)
+#define	LCDIF_CTRL_LCD_DATABUS_WIDTH_8BIT			(1 << 10)
+#define	LCDIF_CTRL_LCD_DATABUS_WIDTH_18BIT			(2 << 10)
+#define	LCDIF_CTRL_LCD_DATABUS_WIDTH_24BIT			(3 << 10)
+#define	LCDIF_CTRL_WORD_LENGTH_MASK				(0x3 << 8)
+#define	LCDIF_CTRL_WORD_LENGTH_OFFSET				8
+#define	LCDIF_CTRL_WORD_LENGTH_16BIT				(0 << 8)
+#define	LCDIF_CTRL_WORD_LENGTH_8BIT				(1 << 8)
+#define	LCDIF_CTRL_WORD_LENGTH_18BIT				(2 << 8)
+#define	LCDIF_CTRL_WORD_LENGTH_24BIT				(3 << 8)
+#define	LCDIF_CTRL_RGB_TO_YCBCR422_CSC				(1 << 7)
+#define	LCDIF_CTRL_LCDIF_MASTER					(1 << 5)
+#define	LCDIF_CTRL_DATA_FORMAT_16_BIT				(1 << 3)
+#define	LCDIF_CTRL_DATA_FORMAT_18_BIT				(1 << 2)
+#define	LCDIF_CTRL_DATA_FORMAT_24_BIT				(1 << 1)
+#define	LCDIF_CTRL_RUN						(1 << 0)
+
+#define	LCDIF_CTRL1_COMBINE_MPU_WR_STRB				(1 << 27)
+#define	LCDIF_CTRL1_BM_ERROR_IRQ_EN				(1 << 26)
+#define	LCDIF_CTRL1_BM_ERROR_IRQ				(1 << 25)
+#define	LCDIF_CTRL1_RECOVER_ON_UNDERFLOW			(1 << 24)
+#define	LCDIF_CTRL1_INTERLACE_FIELDS				(1 << 23)
+#define	LCDIF_CTRL1_START_INTERLACE_FROM_SECOND_FIELD		(1 << 22)
+#define	LCDIF_CTRL1_FIFO_CLEAR					(1 << 21)
+#define	LCDIF_CTRL1_IRQ_ON_ALTERNATE_FIELDS			(1 << 20)
+#define	LCDIF_CTRL1_BYTE_PACKING_FORMAT_MASK			(0xf << 16)
+#define	LCDIF_CTRL1_BYTE_PACKING_FORMAT_OFFSET			16
+#define	LCDIF_CTRL1_OVERFLOW_IRQ_EN				(1 << 15)
+#define	LCDIF_CTRL1_UNDERFLOW_IRQ_EN				(1 << 14)
+#define	LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_EN			(1 << 13)
+#define	LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN				(1 << 12)
+#define	LCDIF_CTRL1_OVERFLOW_IRQ				(1 << 11)
+#define	LCDIF_CTRL1_UNDERFLOW_IRQ				(1 << 10)
+#define	LCDIF_CTRL1_CUR_FRAME_DONE_IRQ				(1 << 9)
+#define	LCDIF_CTRL1_VSYNC_EDGE_IRQ				(1 << 8)
+#define	LCDIF_CTRL1_BUSY_ENABLE					(1 << 2)
+#define	LCDIF_CTRL1_MODE86					(1 << 1)
+#define	LCDIF_CTRL1_RESET					(1 << 0)
+
+#define	LCDIF_CTRL2_OUTSTANDING_REQS_MASK			(0x7 << 21)
+#define	LCDIF_CTRL2_OUTSTANDING_REQS_OFFSET			21
+#define	LCDIF_CTRL2_OUTSTANDING_REQS_REQ_1			(0x0 << 21)
+#define	LCDIF_CTRL2_OUTSTANDING_REQS_REQ_2			(0x1 << 21)
+#define	LCDIF_CTRL2_OUTSTANDING_REQS_REQ_4			(0x2 << 21)
+#define	LCDIF_CTRL2_OUTSTANDING_REQS_REQ_8			(0x3 << 21)
+#define	LCDIF_CTRL2_OUTSTANDING_REQS_REQ_16			(0x4 << 21)
+#define	LCDIF_CTRL2_BURST_LEN_8					(1 << 20)
+#define	LCDIF_CTRL2_ODD_LINE_PATTERN_MASK			(0x7 << 16)
+#define	LCDIF_CTRL2_ODD_LINE_PATTERN_OFFSET			16
+#define	LCDIF_CTRL2_ODD_LINE_PATTERN_RGB			(0x0 << 16)
+#define	LCDIF_CTRL2_ODD_LINE_PATTERN_RBG			(0x1 << 16)
+#define	LCDIF_CTRL2_ODD_LINE_PATTERN_GBR			(0x2 << 16)
+#define	LCDIF_CTRL2_ODD_LINE_PATTERN_GRB			(0x3 << 16)
+#define	LCDIF_CTRL2_ODD_LINE_PATTERN_BRG			(0x4 << 16)
+#define	LCDIF_CTRL2_ODD_LINE_PATTERN_BGR			(0x5 << 16)
+#define	LCDIF_CTRL2_EVEN_LINE_PATTERN_MASK			(0x7 << 12)
+#define	LCDIF_CTRL2_EVEN_LINE_PATTERN_OFFSET			12
+#define	LCDIF_CTRL2_EVEN_LINE_PATTERN_RGB			(0x0 << 12)
+#define	LCDIF_CTRL2_EVEN_LINE_PATTERN_RBG			(0x1 << 12)
+#define	LCDIF_CTRL2_EVEN_LINE_PATTERN_GBR			(0x2 << 12)
+#define	LCDIF_CTRL2_EVEN_LINE_PATTERN_GRB			(0x3 << 12)
+#define	LCDIF_CTRL2_EVEN_LINE_PATTERN_BRG			(0x4 << 12)
+#define	LCDIF_CTRL2_EVEN_LINE_PATTERN_BGR			(0x5 << 12)
+#define	LCDIF_CTRL2_READ_PACK_DIR				(1 << 10)
+#define	LCDIF_CTRL2_READ_MODE_OUTPUT_IN_RGB_FORMAT		(1 << 9)
+#define	LCDIF_CTRL2_READ_MODE_6_BIT_INPUT			(1 << 8)
+#define	LCDIF_CTRL2_READ_MODE_NUM_PACKED_SUBWORDS_MASK		(0x7 << 4)
+#define	LCDIF_CTRL2_READ_MODE_NUM_PACKED_SUBWORDS_OFFSET	4
+#define	LCDIF_CTRL2_INITIAL_DUMMY_READ_MASK			(0x7 << 1)
+#define	LCDIF_CTRL2_INITIAL_DUMMY_READ_OFFSET			1
+
+#define	LCDIF_TRANSFER_COUNT_V_COUNT_MASK			(0xffff << 16)
+#define	LCDIF_TRANSFER_COUNT_V_COUNT_OFFSET			16
+#define	LCDIF_TRANSFER_COUNT_H_COUNT_MASK			(0xffff << 0)
+#define	LCDIF_TRANSFER_COUNT_H_COUNT_OFFSET			0
+
+#define	LCDIF_CUR_BUF_ADDR_MASK					0xffffffff
+#define	LCDIF_CUR_BUF_ADDR_OFFSET				0
+
+#define	LCDIF_NEXT_BUF_ADDR_MASK				0xffffffff
+#define	LCDIF_NEXT_BUF_ADDR_OFFSET				0
+
+#define	LCDIF_TIMING_CMD_HOLD_MASK				(0xff << 24)
+#define	LCDIF_TIMING_CMD_HOLD_OFFSET				24
+#define	LCDIF_TIMING_CMD_SETUP_MASK				(0xff << 16)
+#define	LCDIF_TIMING_CMD_SETUP_OFFSET				16
+#define	LCDIF_TIMING_DATA_HOLD_MASK				(0xff << 8)
+#define	LCDIF_TIMING_DATA_HOLD_OFFSET				8
+#define	LCDIF_TIMING_DATA_SETUP_MASK				(0xff << 0)
+#define	LCDIF_TIMING_DATA_SETUP_OFFSET				0
+
+#define	LCDIF_VDCTRL0_VSYNC_OEB					(1 << 29)
+#define	LCDIF_VDCTRL0_ENABLE_PRESENT				(1 << 28)
+#define	LCDIF_VDCTRL0_VSYNC_POL					(1 << 27)
+#define	LCDIF_VDCTRL0_HSYNC_POL					(1 << 26)
+#define	LCDIF_VDCTRL0_DOTCLK_POL				(1 << 25)
+#define	LCDIF_VDCTRL0_ENABLE_POL				(1 << 24)
+#define	LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT				(1 << 21)
+#define	LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT			(1 << 20)
+#define	LCDIF_VDCTRL0_HALF_LINE					(1 << 19)
+#define	LCDIF_VDCTRL0_HALF_LINE_MODE				(1 << 18)
+#define	LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_MASK			0x3ffff
+#define	LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_OFFSET			0
+
+#define	LCDIF_VDCTRL1_VSYNC_PERIOD_MASK				0xffffffff
+#define	LCDIF_VDCTRL1_VSYNC_PERIOD_OFFSET			0
+
+#define	LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_MASK			(0x3fff << 18)
+#define	LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_OFFSET			18
+#define	LCDIF_VDCTRL2_HSYNC_PERIOD_MASK				0x3ffff
+#define	LCDIF_VDCTRL2_HSYNC_PERIOD_OFFSET			0
+
+#define	LCDIF_VDCTRL3_MUX_SYNC_SIGNALS				(1 << 29)
+#define	LCDIF_VDCTRL3_VSYNC_ONLY				(1 << 28)
+#define	LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_MASK			(0xfff << 16)
+#define	LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_OFFSET		16
+#define	LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_MASK			(0xffff << 0)
+#define	LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_OFFSET			0
+
+#define	LCDIF_VDCTRL4_DOTCLK_DLY_SEL_MASK			(0x7 << 29)
+#define	LCDIF_VDCTRL4_DOTCLK_DLY_SEL_OFFSET			29
+#define	LCDIF_VDCTRL4_SYNC_SIGNALS_ON				(1 << 18)
+#define	LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_MASK		0x3ffff
+#define	LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_OFFSET		0
+
+#endif /* __MX28_REGS_LCDIF_H__ */

+ 400 - 0
arch/arm/include/asm/arch-mx28/regs-lradc.h

@@ -0,0 +1,400 @@
+/*
+ * Freescale i.MX28 LRADC Register Definitions
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * Based on code from LTIB:
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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
+ *
+ */
+
+#ifndef __MX28_REGS_LRADC_H__
+#define __MX28_REGS_LRADC_H__
+
+#include <asm/arch/regs-common.h>
+
+#ifndef	__ASSEMBLY__
+struct mx28_lradc_regs {
+	mx28_reg_32(hw_lradc_ctrl0);
+	mx28_reg_32(hw_lradc_ctrl1);
+	mx28_reg_32(hw_lradc_ctrl2);
+	mx28_reg_32(hw_lradc_ctrl3);
+	mx28_reg_32(hw_lradc_status);
+	mx28_reg_32(hw_lradc_ch0);
+	mx28_reg_32(hw_lradc_ch1);
+	mx28_reg_32(hw_lradc_ch2);
+	mx28_reg_32(hw_lradc_ch3);
+	mx28_reg_32(hw_lradc_ch4);
+	mx28_reg_32(hw_lradc_ch5);
+	mx28_reg_32(hw_lradc_ch6);
+	mx28_reg_32(hw_lradc_ch7);
+	mx28_reg_32(hw_lradc_delay0);
+	mx28_reg_32(hw_lradc_delay1);
+	mx28_reg_32(hw_lradc_delay2);
+	mx28_reg_32(hw_lradc_delay3);
+	mx28_reg_32(hw_lradc_debug0);
+	mx28_reg_32(hw_lradc_debug1);
+	mx28_reg_32(hw_lradc_conversion);
+	mx28_reg_32(hw_lradc_ctrl4);
+	mx28_reg_32(hw_lradc_treshold0);
+	mx28_reg_32(hw_lradc_treshold1);
+	mx28_reg_32(hw_lradc_version);
+};
+#endif
+
+#define	LRADC_CTRL0_SFTRST					(1 << 31)
+#define	LRADC_CTRL0_CLKGATE					(1 << 30)
+#define	LRADC_CTRL0_ONCHIP_GROUNDREF				(1 << 26)
+#define	LRADC_CTRL0_BUTTON1_DETECT_ENABLE			(1 << 25)
+#define	LRADC_CTRL0_BUTTON0_DETECT_ENABLE			(1 << 24)
+#define	LRADC_CTRL0_TOUCH_DETECT_ENABLE				(1 << 23)
+#define	LRADC_CTRL0_TOUCH_SCREEN_TYPE				(1 << 22)
+#define	LRADC_CTRL0_YNLRSW					(1 << 21)
+#define	LRADC_CTRL0_YPLLSW_MASK					(0x3 << 19)
+#define	LRADC_CTRL0_YPLLSW_OFFSET				19
+#define	LRADC_CTRL0_XNURSW_MASK					(0x3 << 17)
+#define	LRADC_CTRL0_XNURSW_OFFSET				17
+#define	LRADC_CTRL0_XPULSW					(1 << 16)
+#define	LRADC_CTRL0_SCHEDULE_MASK				0xff
+#define	LRADC_CTRL0_SCHEDULE_OFFSET				0
+
+#define	LRADC_CTRL1_BUTTON1_DETECT_IRQ_EN			(1 << 28)
+#define	LRADC_CTRL1_BUTTON0_DETECT_IRQ_EN			(1 << 27)
+#define	LRADC_CTRL1_THRESHOLD1_DETECT_IRQ_EN			(1 << 26)
+#define	LRADC_CTRL1_THRESHOLD0_DETECT_IRQ_EN			(1 << 25)
+#define	LRADC_CTRL1_TOUCH_DETECT_IRQ_EN				(1 << 24)
+#define	LRADC_CTRL1_LRADC7_IRQ_EN				(1 << 23)
+#define	LRADC_CTRL1_LRADC6_IRQ_EN				(1 << 22)
+#define	LRADC_CTRL1_LRADC5_IRQ_EN				(1 << 21)
+#define	LRADC_CTRL1_LRADC4_IRQ_EN				(1 << 20)
+#define	LRADC_CTRL1_LRADC3_IRQ_EN				(1 << 19)
+#define	LRADC_CTRL1_LRADC2_IRQ_EN				(1 << 18)
+#define	LRADC_CTRL1_LRADC1_IRQ_EN				(1 << 17)
+#define	LRADC_CTRL1_LRADC0_IRQ_EN				(1 << 16)
+#define	LRADC_CTRL1_BUTTON1_DETECT_IRQ				(1 << 12)
+#define	LRADC_CTRL1_BUTTON0_DETECT_IRQ				(1 << 11)
+#define	LRADC_CTRL1_THRESHOLD1_DETECT_IRQ			(1 << 10)
+#define	LRADC_CTRL1_THRESHOLD0_DETECT_IRQ			(1 << 9)
+#define	LRADC_CTRL1_TOUCH_DETECT_IRQ				(1 << 8)
+#define	LRADC_CTRL1_LRADC7_IRQ					(1 << 7)
+#define	LRADC_CTRL1_LRADC6_IRQ					(1 << 6)
+#define	LRADC_CTRL1_LRADC5_IRQ					(1 << 5)
+#define	LRADC_CTRL1_LRADC4_IRQ					(1 << 4)
+#define	LRADC_CTRL1_LRADC3_IRQ					(1 << 3)
+#define	LRADC_CTRL1_LRADC2_IRQ					(1 << 2)
+#define	LRADC_CTRL1_LRADC1_IRQ					(1 << 1)
+#define	LRADC_CTRL1_LRADC0_IRQ					(1 << 0)
+
+#define	LRADC_CTRL2_DIVIDE_BY_TWO_MASK				(0xff << 24)
+#define	LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET			24
+#define	LRADC_CTRL2_TEMPSENSE_PWD				(1 << 15)
+#define	LRADC_CTRL2_VTHSENSE_MASK				(0x3 << 13)
+#define	LRADC_CTRL2_VTHSENSE_OFFSET				13
+#define	LRADC_CTRL2_DISABLE_MUXAMP_BYPASS			(1 << 12)
+#define	LRADC_CTRL2_TEMP_SENSOR_IENABLE1			(1 << 9)
+#define	LRADC_CTRL2_TEMP_SENSOR_IENABLE0			(1 << 8)
+#define	LRADC_CTRL2_TEMP_ISRC1_MASK				(0xf << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_OFFSET				4
+#define	LRADC_CTRL2_TEMP_ISRC1_300				(0xf << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_280				(0xe << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_260				(0xd << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_240				(0xc << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_220				(0xb << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_200				(0xa << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_180				(0x9 << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_160				(0x8 << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_140				(0x7 << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_120				(0x6 << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_100				(0x5 << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_80				(0x4 << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_60				(0x3 << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_40				(0x2 << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_20				(0x1 << 4)
+#define	LRADC_CTRL2_TEMP_ISRC1_ZERO				(0x0 << 4)
+#define	LRADC_CTRL2_TEMP_ISRC0_MASK				(0xf << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_OFFSET				0
+#define	LRADC_CTRL2_TEMP_ISRC0_300				(0xf << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_280				(0xe << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_260				(0xd << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_240				(0xc << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_220				(0xb << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_200				(0xa << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_180				(0x9 << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_160				(0x8 << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_140				(0x7 << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_120				(0x6 << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_100				(0x5 << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_80				(0x4 << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_60				(0x3 << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_40				(0x2 << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_20				(0x1 << 0)
+#define	LRADC_CTRL2_TEMP_ISRC0_ZERO				(0x0 << 0)
+
+#define	LRADC_CTRL3_DISCARD_MASK				(0x3 << 24)
+#define	LRADC_CTRL3_DISCARD_OFFSET				24
+#define	LRADC_CTRL3_DISCARD_1_SAMPLE				(0x1 << 24)
+#define	LRADC_CTRL3_DISCARD_2_SAMPLES				(0x2 << 24)
+#define	LRADC_CTRL3_DISCARD_3_SAMPLES				(0x3 << 24)
+#define	LRADC_CTRL3_FORCE_ANALOG_PWUP				(1 << 23)
+#define	LRADC_CTRL3_FORCE_ANALOG_PWDN				(1 << 22)
+#define	LRADC_CTRL3_CYCLE_TIME_MASK				(0x3 << 8)
+#define	LRADC_CTRL3_CYCLE_TIME_OFFSET				8
+#define	LRADC_CTRL3_CYCLE_TIME_6MHZ				(0x0 << 8)
+#define	LRADC_CTRL3_CYCLE_TIME_4MHZ				(0x1 << 8)
+#define	LRADC_CTRL3_CYCLE_TIME_3MHZ				(0x2 << 8)
+#define	LRADC_CTRL3_CYCLE_TIME_2MHZ				(0x3 << 8)
+#define	LRADC_CTRL3_HIGH_TIME_MASK				(0x3 << 4)
+#define	LRADC_CTRL3_HIGH_TIME_OFFSET				4
+#define	LRADC_CTRL3_HIGH_TIME_42NS				(0x0 << 4)
+#define	LRADC_CTRL3_HIGH_TIME_83NS				(0x1 << 4)
+#define	LRADC_CTRL3_HIGH_TIME_125NS				(0x2 << 4)
+#define	LRADC_CTRL3_HIGH_TIME_250NS				(0x3 << 4)
+#define	LRADC_CTRL3_DELAY_CLOCK					(1 << 1)
+#define	LRADC_CTRL3_INVERT_CLOCK				(1 << 0)
+
+#define	LRADC_STATUS_BUTTON1_PRESENT				(1 << 28)
+#define	LRADC_STATUS_BUTTON0_PRESENT				(1 << 27)
+#define	LRADC_STATUS_TEMP1_PRESENT				(1 << 26)
+#define	LRADC_STATUS_TEMP0_PRESENT				(1 << 25)
+#define	LRADC_STATUS_TOUCH_PANEL_PRESENT			(1 << 24)
+#define	LRADC_STATUS_CHANNEL7_PRESENT				(1 << 23)
+#define	LRADC_STATUS_CHANNEL6_PRESENT				(1 << 22)
+#define	LRADC_STATUS_CHANNEL5_PRESENT				(1 << 21)
+#define	LRADC_STATUS_CHANNEL4_PRESENT				(1 << 20)
+#define	LRADC_STATUS_CHANNEL3_PRESENT				(1 << 19)
+#define	LRADC_STATUS_CHANNEL2_PRESENT				(1 << 18)
+#define	LRADC_STATUS_CHANNEL1_PRESENT				(1 << 17)
+#define	LRADC_STATUS_CHANNEL0_PRESENT				(1 << 16)
+#define	LRADC_STATUS_BUTTON1_DETECT_RAW				(1 << 2)
+#define	LRADC_STATUS_BUTTON0_DETECT_RAW				(1 << 1)
+#define	LRADC_STATUS_TOUCH_DETECT_RAW				(1 << 0)
+
+#define	LRADC_CH_TOGGLE						(1 << 31)
+#define	LRADC_CH7_TESTMODE_TOGGLE				(1 << 30)
+#define	LRADC_CH_ACCUMULATE					(1 << 29)
+#define	LRADC_CH_NUM_SAMPLES_MASK				(0x1f << 24)
+#define	LRADC_CH_NUM_SAMPLES_OFFSET				24
+#define	LRADC_CH_VALUE_MASK					0x3ffff
+#define	LRADC_CH_VALUE_OFFSET					0
+
+#define	LRADC_DELAY_TRIGGER_LRADCS_MASK				(0xff << 24)
+#define	LRADC_DELAY_TRIGGER_LRADCS_OFFSET			24
+#define	LRADC_DELAY_KICK					(1 << 20)
+#define	LRADC_DELAY_TRIGGER_DELAYS_MASK				(0xf << 16)
+#define	LRADC_DELAY_TRIGGER_DELAYS_OFFSET			16
+#define	LRADC_DELAY_LOOP_COUNT_MASK				(0x1f << 11)
+#define	LRADC_DELAY_LOOP_COUNT_OFFSET				11
+#define	LRADC_DELAY_DELAY_MASK					0x7ff
+#define	LRADC_DELAY_DELAY_OFFSET				0
+
+#define	LRADC_DEBUG0_READONLY_MASK				(0xffff << 16)
+#define	LRADC_DEBUG0_READONLY_OFFSET				16
+#define	LRADC_DEBUG0_STATE_MASK					(0xfff << 0)
+#define	LRADC_DEBUG0_STATE_OFFSET				0
+
+#define	LRADC_DEBUG1_REQUEST_MASK				(0xff << 16)
+#define	LRADC_DEBUG1_REQUEST_OFFSET				16
+#define	LRADC_DEBUG1_TESTMODE_COUNT_MASK			(0x1f << 8)
+#define	LRADC_DEBUG1_TESTMODE_COUNT_OFFSET			8
+#define	LRADC_DEBUG1_TESTMODE6					(1 << 2)
+#define	LRADC_DEBUG1_TESTMODE5					(1 << 1)
+#define	LRADC_DEBUG1_TESTMODE					(1 << 0)
+
+#define	LRADC_CONVERSION_AUTOMATIC				(1 << 20)
+#define	LRADC_CONVERSION_SCALE_FACTOR_MASK			(0x3 << 16)
+#define	LRADC_CONVERSION_SCALE_FACTOR_OFFSET			16
+#define	LRADC_CONVERSION_SCALE_FACTOR_NIMH			(0x0 << 16)
+#define	LRADC_CONVERSION_SCALE_FACTOR_DUAL_NIMH			(0x1 << 16)
+#define	LRADC_CONVERSION_SCALE_FACTOR_LI_ION			(0x2 << 16)
+#define	LRADC_CONVERSION_SCALE_FACTOR_ALT_LI_ION		(0x3 << 16)
+#define	LRADC_CONVERSION_SCALED_BATT_VOLTAGE_MASK		0x3ff
+#define	LRADC_CONVERSION_SCALED_BATT_VOLTAGE_OFFSET		0
+
+#define	LRADC_CTRL4_LRADC7SELECT_MASK				(0xf << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_OFFSET				28
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL0			(0x0 << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL1			(0x1 << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL2			(0x2 << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL3			(0x3 << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL4			(0x4 << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL5			(0x5 << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL6			(0x6 << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL7			(0x7 << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL8			(0x8 << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL9			(0x9 << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL10			(0xa << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL11			(0xb << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL12			(0xc << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL13			(0xd << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL14			(0xe << 28)
+#define	LRADC_CTRL4_LRADC7SELECT_CHANNEL15			(0xf << 28)
+#define	LRADC_CTRL4_LRADC6SELECT_MASK				(0xf << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_OFFSET				24
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL0			(0x0 << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL1			(0x1 << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL2			(0x2 << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL3			(0x3 << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL4			(0x4 << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL5			(0x5 << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL6			(0x6 << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL7			(0x7 << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL8			(0x8 << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL9			(0x9 << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL10			(0xa << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL11			(0xb << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL12			(0xc << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL13			(0xd << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL14			(0xe << 24)
+#define	LRADC_CTRL4_LRADC6SELECT_CHANNEL15			(0xf << 24)
+#define	LRADC_CTRL4_LRADC5SELECT_MASK				(0xf << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_OFFSET				20
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL0			(0x0 << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL1			(0x1 << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL2			(0x2 << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL3			(0x3 << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL4			(0x4 << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL5			(0x5 << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL6			(0x6 << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL7			(0x7 << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL8			(0x8 << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL9			(0x9 << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL10			(0xa << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL11			(0xb << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL12			(0xc << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL13			(0xd << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL14			(0xe << 20)
+#define	LRADC_CTRL4_LRADC5SELECT_CHANNEL15			(0xf << 20)
+#define	LRADC_CTRL4_LRADC4SELECT_MASK				(0xf << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_OFFSET				16
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL0			(0x0 << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL1			(0x1 << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL2			(0x2 << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL3			(0x3 << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL4			(0x4 << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL5			(0x5 << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL6			(0x6 << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL7			(0x7 << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL8			(0x8 << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL9			(0x9 << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL10			(0xa << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL11			(0xb << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL12			(0xc << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL13			(0xd << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL14			(0xe << 16)
+#define	LRADC_CTRL4_LRADC4SELECT_CHANNEL15			(0xf << 16)
+#define	LRADC_CTRL4_LRADC3SELECT_MASK				(0xf << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_OFFSET				12
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL0			(0x0 << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL1			(0x1 << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL2			(0x2 << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL3			(0x3 << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL4			(0x4 << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL5			(0x5 << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL6			(0x6 << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL7			(0x7 << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL8			(0x8 << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL9			(0x9 << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL10			(0xa << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL11			(0xb << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL12			(0xc << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL13			(0xd << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL14			(0xe << 12)
+#define	LRADC_CTRL4_LRADC3SELECT_CHANNEL15			(0xf << 12)
+#define	LRADC_CTRL4_LRADC2SELECT_MASK				(0xf << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_OFFSET				8
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL0			(0x0 << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL1			(0x1 << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL2			(0x2 << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL3			(0x3 << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL4			(0x4 << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL5			(0x5 << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL6			(0x6 << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL7			(0x7 << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL8			(0x8 << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL9			(0x9 << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL10			(0xa << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL11			(0xb << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL12			(0xc << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL13			(0xd << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL14			(0xe << 8)
+#define	LRADC_CTRL4_LRADC2SELECT_CHANNEL15			(0xf << 8)
+#define	LRADC_CTRL4_LRADC1SELECT_MASK				(0xf << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_OFFSET				4
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL0			(0x0 << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL1			(0x1 << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL2			(0x2 << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL3			(0x3 << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL4			(0x4 << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL5			(0x5 << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL6			(0x6 << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL7			(0x7 << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL8			(0x8 << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL9			(0x9 << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL10			(0xa << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL11			(0xb << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL12			(0xc << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL13			(0xd << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL14			(0xe << 4)
+#define	LRADC_CTRL4_LRADC1SELECT_CHANNEL15			(0xf << 4)
+#define	LRADC_CTRL4_LRADC0SELECT_MASK				0xf
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL0			(0x0 << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL1			(0x1 << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL2			(0x2 << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL3			(0x3 << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL4			(0x4 << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL5			(0x5 << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL6			(0x6 << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL7			(0x7 << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL8			(0x8 << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL9			(0x9 << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL10			(0xa << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL11			(0xb << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL12			(0xc << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL13			(0xd << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL14			(0xe << 0)
+#define	LRADC_CTRL4_LRADC0SELECT_CHANNEL15			(0xf << 0)
+
+#define	LRADC_THRESHOLD_ENABLE					(1 << 24)
+#define	LRADC_THRESHOLD_BATTCHRG_DISABLE			(1 << 23)
+#define	LRADC_THRESHOLD_CHANNEL_SEL_MASK			(0x7 << 20)
+#define	LRADC_THRESHOLD_CHANNEL_SEL_OFFSET			20
+#define	LRADC_THRESHOLD_CHANNEL_SEL_CHANNEL0			(0x0 << 20)
+#define	LRADC_THRESHOLD_CHANNEL_SEL_CHANNEL1			(0x1 << 20)
+#define	LRADC_THRESHOLD_CHANNEL_SEL_CHANNEL2			(0x2 << 20)
+#define	LRADC_THRESHOLD_CHANNEL_SEL_CHANNEL3			(0x3 << 20)
+#define	LRADC_THRESHOLD_CHANNEL_SEL_CHANNEL4			(0x4 << 20)
+#define	LRADC_THRESHOLD_CHANNEL_SEL_CHANNEL5			(0x5 << 20)
+#define	LRADC_THRESHOLD_CHANNEL_SEL_CHANNEL6			(0x6 << 20)
+#define	LRADC_THRESHOLD_CHANNEL_SEL_CHANNEL7			(0x7 << 20)
+#define	LRADC_THRESHOLD_SETTING_MASK				(0x3 << 18)
+#define	LRADC_THRESHOLD_SETTING_OFFSET				18
+#define	LRADC_THRESHOLD_SETTING_NO_COMPARE			(0x0 << 18)
+#define	LRADC_THRESHOLD_SETTING_DETECT_LOW			(0x1 << 18)
+#define	LRADC_THRESHOLD_SETTING_DETECT_HIGH			(0x2 << 18)
+#define	LRADC_THRESHOLD_SETTING_RESERVED			(0x3 << 18)
+#define	LRADC_THRESHOLD_VALUE_MASK				0x3ffff
+#define	LRADC_THRESHOLD_VALUE_OFFSET				0
+
+#define	LRADC_VERSION_MAJOR_MASK				(0xff << 24)
+#define	LRADC_VERSION_MAJOR_OFFSET				24
+#define	LRADC_VERSION_MINOR_MASK				(0xff << 16)
+#define	LRADC_VERSION_MINOR_OFFSET				16
+#define	LRADC_VERSION_STEP_MASK					0xffff
+#define	LRADC_VERSION_STEP_OFFSET				0
+
+#endif	/* __MX28_REGS_LRADC_H__ */

+ 30 - 0
arch/arm/include/asm/arch-mx28/sys_proto.h

@@ -39,6 +39,36 @@ void mx28_common_spl_init(const iomux_cfg_t *iomux_setup,
 			const unsigned int iomux_size);
 #endif
 
+struct mx28_pair {
+	uint8_t	boot_pads;
+	uint8_t boot_mask;
+	const char *mode;
+};
+
+static const struct mx28_pair mx28_boot_modes[] = {
+	{ 0x00, 0x0f, "USB #0" },
+	{ 0x01, 0x1f, "I2C #0, master, 3V3" },
+	{ 0x11, 0x1f, "I2C #0, master, 1V8" },
+	{ 0x02, 0x1f, "SSP SPI #2, master, 3V3 NOR" },
+	{ 0x12, 0x1f, "SSP SPI #2, master, 1V8 NOR" },
+	{ 0x03, 0x1f, "SSP SPI #3, master, 3V3 NOR" },
+	{ 0x13, 0x1f, "SSP SPI #3, master, 1V8 NOR" },
+	{ 0x04, 0x1f, "NAND, 3V3" },
+	{ 0x14, 0x1f, "NAND, 1V8" },
+	{ 0x08, 0x1f, "SSP SPI #3, master, 3V3 EEPROM" },
+	{ 0x18, 0x1f, "SSP SPI #3, master, 1V8 EEPROM" },
+	{ 0x09, 0x1f, "SSP SD/MMC #0, 3V3" },
+	{ 0x19, 0x1f, "SSP SD/MMC #0, 1V8" },
+	{ 0x0a, 0x1f, "SSP SD/MMC #1, 3V3" },
+	{ 0x1a, 0x1f, "SSP SD/MMC #1, 1V8" },
+	{ 0x00, 0x00, "Reserved/Unknown/Wrong" },
+};
+
+struct mx28_spl_data {
+	uint8_t		boot_mode_idx;
+	uint32_t	mem_dram_size;
+};
+
 int mx28_dram_init(void);
 
 #endif	/* __MX28_H__ */

+ 6 - 1
arch/arm/include/asm/arch-mx5/clock.h

@@ -32,6 +32,10 @@ enum mxc_clock {
 	MXC_UART_CLK,
 	MXC_CSPI_CLK,
 	MXC_FEC_CLK,
+	MXC_SATA_CLK,
+	MXC_DDR_CLK,
+	MXC_NFC_CLK,
+	MXC_PERIPH_CLK,
 };
 
 unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref);
@@ -39,10 +43,11 @@ unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref);
 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);
 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);
 
 #endif /* __ASM_ARCH_CLOCK_H */

+ 6 - 0
arch/arm/include/asm/arch-mx5/crm_regs.h

@@ -76,6 +76,9 @@ struct mxc_ccm_reg {
 	u32 CCGR4;
 	u32 CCGR5;
 	u32 CCGR6;	/* 0x0080 */
+#ifdef CONFIG_MX53
+	u32 CCGR7;      /* 0x0084 */
+#endif
 	u32 cmeor;
 };
 
@@ -84,6 +87,9 @@ struct mxc_ccm_reg {
 #define MXC_CCM_CACRR_ARM_PODF_MASK		0x7
 
 /* Define the bits in register CBCDR */
+#define MXC_CCM_CBCDR_DDR_HIFREQ_SEL		(0x1 << 30)
+#define MXC_CCM_CBCDR_DDR_PODF_MASK		(0x7 << 27)
+#define MXC_CCM_CBCDR_DDR_PODF_OFFSET		27
 #define MXC_CCM_CBCDR_EMI_CLK_SEL		(0x1 << 26)
 #define MXC_CCM_CBCDR_PERIPH_CLK_SEL		(0x1 << 25)
 #define MXC_CCM_CBCDR_EMI_PODF_OFFSET		22

+ 11 - 0
arch/arm/include/asm/arch-mx5/imx-regs.h

@@ -43,6 +43,7 @@
 #define NFC_BASE_ADDR_AXI       0xF7FF0000
 #define IRAM_BASE_ADDR          0xF8000000
 #define CS1_BASE_ADDR           0xF4000000
+#define SATA_BASE_ADDR		0x10000000
 #else
 #error "CPU_TYPE not defined"
 #endif
@@ -93,6 +94,7 @@
 #define GPIO5_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000DC000)
 #define GPIO6_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000E0000)
 #define GPIO7_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000E4000)
+#define UART4_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000F0000)
 #endif
 /*
  * AIPS 2
@@ -133,6 +135,10 @@
 #define VPU_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000F4000)
 #define SAHARA_BASE_ADDR	(AIPS2_BASE_ADDR + 0x000F8000)
 
+#if defined(CONFIG_MX53)
+#define UART5_BASE_ADDR         (AIPS2_BASE_ADDR + 0x00090000)
+#endif
+
 /*
  * WEIM CSnGCR1
  */
@@ -485,6 +491,11 @@ struct iim_regs {
 	} bank[4];
 };
 
+struct fuse_bank0_regs {
+	u32	fuse0_23[24];
+	u32	gp[8];
+};
+
 struct fuse_bank1_regs {
 	u32	fuse0_8[9];
 	u32	mac_addr[6];

+ 2 - 2
arch/arm/include/asm/arch-mx5/iomux.h

@@ -66,8 +66,8 @@ typedef enum iomux_pad_config {
 	PAD_CTL_HYS_ENABLE = 0x1 << 8,	/* Hysteresis enabled */
 	PAD_CTL_DDR_INPUT_CMOS = 0x0 << 9,/* DDR input CMOS */
 	PAD_CTL_DDR_INPUT_DDR = 0x1 << 9,/* DDR input DDR */
-	PAD_CTL_DRV_VOT_LOW = 0x0 << 13, /* Low voltage mode */
-	PAD_CTL_DRV_VOT_HIGH = 0x1 << 13,/* High voltage mode */
+	PAD_CTL_DRV_VOT_LOW = 0x1 << 13, /* Low voltage mode */
+	PAD_CTL_DRV_VOT_HIGH = 0x0 << 13,/* High voltage mode */
 } iomux_pad_config_t;
 
 /* various IOMUX input functions */

+ 3 - 0
arch/arm/include/asm/arch-mx5/sys_proto.h

@@ -35,5 +35,8 @@ void set_chipselect_size(int const);
  */
 
 int fecmxc_initialize(bd_t *bis);
+u32 get_ahb_clk(void);
+u32 get_periph_clk(void);
+char *get_reset_cause(void);
 
 #endif

+ 1 - 0
arch/arm/include/asm/arch-mx6/clock.h

@@ -47,5 +47,6 @@ u32 imx_get_uartclk(void);
 u32 imx_get_fecclk(void);
 unsigned int mxc_get_clock(enum mxc_clock clk);
 void enable_usboh3_clk(unsigned char enable);
+int enable_sata_clock(void);
 
 #endif /* __ASM_ARCH_CLOCK_H */

+ 1 - 1
arch/arm/include/asm/arch-mx6/ccm_regs.h → arch/arm/include/asm/arch-mx6/crm_regs.h

@@ -20,7 +20,7 @@
 #ifndef __ARCH_ARM_MACH_MX6_CCM_REGS_H__
 #define __ARCH_ARM_MACH_MX6_CCM_REGS_H__
 
-struct imx_ccm_reg {
+struct mxc_ccm_reg {
 	u32 ccr;	/* 0x0000 */
 	u32 ccdr;
 	u32 csr;

+ 9 - 0
arch/arm/include/asm/arch-mx6/imx-regs.h

@@ -436,5 +436,14 @@ struct anatop_regs {
 	u32	digprog;		/* 0x260 */
 };
 
+struct iomuxc_base_regs {
+	u32     gpr[14];        /* 0x000 */
+	u32     obsrv[5];       /* 0x038 */
+	u32     swmux_ctl[197]; /* 0x04c */
+	u32     swpad_ctl[250]; /* 0x360 */
+	u32     swgrp[26];      /* 0x748 */
+	u32     daisy[104];     /* 0x7b0..94c */
+};
+
 #endif /* __ASSEMBLER__*/
 #endif /* __ASM_ARCH_MX6_IMX_REGS_H__ */

+ 111 - 0
arch/arm/include/asm/arch-mx6/iomux-v3.h

@@ -100,4 +100,115 @@ typedef u64 iomux_v3_cfg_t;
 int imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
 int imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count);
 
+/*
+ * IOMUXC_GPR13 bit fields
+ */
+#define IOMUXC_GPR13_SDMA_STOP_REQ	(1<<30)
+#define IOMUXC_GPR13_CAN2_STOP_REQ	(1<<29)
+#define IOMUXC_GPR13_CAN1_STOP_REQ	(1<<28)
+#define IOMUXC_GPR13_ENET_STOP_REQ	(1<<27)
+#define IOMUXC_GPR13_SATA_PHY_8_MASK	(7<<24)
+#define IOMUXC_GPR13_SATA_PHY_7_MASK	(0x1f<<19)
+#define IOMUXC_GPR13_SATA_PHY_6_SHIFT	16
+#define IOMUXC_GPR13_SATA_PHY_6_MASK	(7<<IOMUXC_GPR13_SATA_PHY_6_SHIFT)
+#define IOMUXC_GPR13_SATA_SPEED_MASK	(1<<15)
+#define IOMUXC_GPR13_SATA_PHY_5_MASK	(1<<14)
+#define IOMUXC_GPR13_SATA_PHY_4_MASK	(7<<11)
+#define IOMUXC_GPR13_SATA_PHY_3_MASK	(0x1f<<7)
+#define IOMUXC_GPR13_SATA_PHY_2_MASK	(0x1f<<2)
+#define IOMUXC_GPR13_SATA_PHY_1_MASK	(3<<0)
+
+#define IOMUXC_GPR13_SATA_PHY_8_RXEQ_0P5DB	(0b000<<24)
+#define IOMUXC_GPR13_SATA_PHY_8_RXEQ_1P0DB	(0b001<<24)
+#define IOMUXC_GPR13_SATA_PHY_8_RXEQ_1P5DB	(0b010<<24)
+#define IOMUXC_GPR13_SATA_PHY_8_RXEQ_2P0DB	(0b011<<24)
+#define IOMUXC_GPR13_SATA_PHY_8_RXEQ_2P5DB	(0b100<<24)
+#define IOMUXC_GPR13_SATA_PHY_8_RXEQ_3P0DB	(0b101<<24)
+#define IOMUXC_GPR13_SATA_PHY_8_RXEQ_3P5DB	(0b110<<24)
+#define IOMUXC_GPR13_SATA_PHY_8_RXEQ_4P0DB	(0b111<<24)
+
+#define IOMUXC_GPR13_SATA_PHY_7_SATA1I	(0b10000<<19)
+#define IOMUXC_GPR13_SATA_PHY_7_SATA1M	(0b10000<<19)
+#define IOMUXC_GPR13_SATA_PHY_7_SATA1X	(0b11010<<19)
+#define IOMUXC_GPR13_SATA_PHY_7_SATA2I	(0b10010<<19)
+#define IOMUXC_GPR13_SATA_PHY_7_SATA2M	(0b10010<<19)
+#define IOMUXC_GPR13_SATA_PHY_7_SATA2X	(0b11010<<19)
+
+#define IOMUXC_GPR13_SATA_SPEED_1P5G	(0<<15)
+#define IOMUXC_GPR13_SATA_SPEED_3G	(1<<15)
+
+#define IOMUXC_GPR13_SATA_SATA_PHY_5_SS_DISABLED	(0<<14)
+#define IOMUXC_GPR13_SATA_SATA_PHY_5_SS_ENABLED		(1<<14)
+
+#define IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_16_16	(0<<11)
+#define IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_14_16	(1<<11)
+#define IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_12_16	(2<<11)
+#define IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_10_16	(3<<11)
+#define IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_9_16		(4<<11)
+#define IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_8_16		(5<<11)
+
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_0P00_DB	(0b0000<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_0P37_DB	(0b0001<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_0P74_DB	(0b0010<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_1P11_DB	(0b0011<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_1P48_DB	(0b0100<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_1P85_DB	(0b0101<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_2P22_DB	(0b0110<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_2P59_DB	(0b0111<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_2P96_DB	(0b1000<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_3P33_DB	(0b1001<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_3P70_DB	(0b1010<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_4P07_DB	(0b1011<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_4P44_DB	(0b1100<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_4P81_DB	(0b1101<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_5P28_DB	(0b1110<<7)
+#define IOMUXC_GPR13_SATA_PHY_3_TXBOOST_5P75_DB	(0b1111<<7)
+
+#define IOMUXC_GPR13_SATA_PHY_2_TX_0P937V	(0b00000<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_0P947V	(0b00001<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_0P957V	(0b00010<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_0P966V	(0b00011<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_0P976V	(0b00100<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_0P986V	(0b00101<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_0P996V	(0b00110<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P005V	(0b00111<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P015V	(0b01000<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P025V	(0b01001<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P035V	(0b01010<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P045V	(0b01011<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P054V	(0b01100<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P064V	(0b01101<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P074V	(0b01110<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P084V	(0b01111<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P094V	(0b10000<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P104V	(0b10001<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P113V	(0b10010<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P123V	(0b10011<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P133V	(0b10100<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P143V	(0b10101<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P152V	(0b10110<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P162V	(0b10111<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P172V	(0b11000<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P182V	(0b11001<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P191V	(0b11010<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P201V	(0b11011<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P211V	(0b11100<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P221V	(0b11101<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P230V	(0b11110<<2)
+#define IOMUXC_GPR13_SATA_PHY_2_TX_1P240V	(0b11111<<2)
+
+#define IOMUXC_GPR13_SATA_PHY_1_FAST	0
+#define IOMUXC_GPR13_SATA_PHY_1_MEDIUM	1
+#define IOMUXC_GPR13_SATA_PHY_1_SLOW	2
+
+#define IOMUXC_GPR13_SATA_MASK (IOMUXC_GPR13_SATA_PHY_8_MASK \
+				|IOMUXC_GPR13_SATA_PHY_7_MASK \
+				|IOMUXC_GPR13_SATA_PHY_6_MASK \
+				|IOMUXC_GPR13_SATA_SPEED_MASK \
+				|IOMUXC_GPR13_SATA_PHY_5_MASK \
+				|IOMUXC_GPR13_SATA_PHY_4_MASK \
+				|IOMUXC_GPR13_SATA_PHY_3_MASK \
+				|IOMUXC_GPR13_SATA_PHY_2_MASK \
+				|IOMUXC_GPR13_SATA_PHY_1_MASK)
+
 #endif	/* __MACH_IOMUX_V3_H__*/

+ 4 - 1
arch/arm/include/asm/arch-mx6/sys_proto.h

@@ -28,11 +28,14 @@
 
 u32 get_cpu_rev(void);
 
+void set_vddsoc(u32 mv);
+
 /*
  * Initializes on-chip ethernet controllers.
  * to override, implement board_eth_init()
  */
 
 int fecmxc_initialize(bd_t *bis);
-
+u32 get_ahb_clk(void);
+u32 get_periph_clk(void);
 #endif

Vissa filer visades inte eftersom för många filer har ändrats