Browse Source

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

Stefano Babic 12 years ago
parent
commit
9cd9b34dc7
100 changed files with 6708 additions and 1332 deletions
  1. 8 0
      MAINTAINERS
  2. 9 9
      Makefile
  3. 13 8
      README
  4. 5 5
      arch/arm/cpu/arm1136/mx31/timer.c
  5. 3 3
      arch/arm/cpu/arm1136/mx35/generic.c
  6. 2 2
      arch/arm/cpu/arm1136/mx35/timer.c
  7. 13 10
      arch/arm/cpu/arm1136/omap24xx/timer.c
  8. 1 0
      arch/arm/cpu/arm720t/tegra-common/Makefile
  9. 333 0
      arch/arm/cpu/arm720t/tegra-common/cpu.c
  10. 27 43
      arch/arm/cpu/arm720t/tegra-common/cpu.h
  11. 1 2
      arch/arm/cpu/arm720t/tegra-common/spl.c
  12. 42 0
      arch/arm/cpu/arm720t/tegra114/Makefile
  13. 19 0
      arch/arm/cpu/arm720t/tegra114/config.mk
  14. 297 0
      arch/arm/cpu/arm720t/tegra114/cpu.c
  15. 14 202
      arch/arm/cpu/arm720t/tegra20/cpu.c
  16. 41 0
      arch/arm/cpu/arm720t/tegra30/Makefile
  17. 19 0
      arch/arm/cpu/arm720t/tegra30/config.mk
  18. 176 0
      arch/arm/cpu/arm720t/tegra30/cpu.c
  19. 9 9
      arch/arm/cpu/arm920t/a320/timer.c
  20. 13 11
      arch/arm/cpu/arm920t/at91/clock.c
  21. 7 7
      arch/arm/cpu/arm920t/at91/timer.c
  22. 15 15
      arch/arm/cpu/arm920t/s3c24x0/timer.c
  23. 9 9
      arch/arm/cpu/arm926ejs/armada100/timer.c
  24. 16 14
      arch/arm/cpu/arm926ejs/at91/clock.c
  25. 9 9
      arch/arm/cpu/arm926ejs/at91/timer.c
  26. 11 10
      arch/arm/cpu/arm926ejs/davinci/timer.c
  27. 2 2
      arch/arm/cpu/arm926ejs/kirkwood/timer.c
  28. 2 2
      arch/arm/cpu/arm926ejs/mb86r0x/timer.c
  29. 2 2
      arch/arm/cpu/arm926ejs/mx25/generic.c
  30. 2 2
      arch/arm/cpu/arm926ejs/mx25/timer.c
  31. 2 2
      arch/arm/cpu/arm926ejs/mx27/timer.c
  32. 2 2
      arch/arm/cpu/arm926ejs/mxs/timer.c
  33. 2 2
      arch/arm/cpu/arm926ejs/omap/timer.c
  34. 2 2
      arch/arm/cpu/arm926ejs/orion5x/timer.c
  35. 9 9
      arch/arm/cpu/arm926ejs/pantheon/timer.c
  36. 2 2
      arch/arm/cpu/arm926ejs/spear/timer.c
  37. 2 2
      arch/arm/cpu/arm926ejs/versatile/timer.c
  38. 1 1
      arch/arm/cpu/armv7/Makefile
  39. 3 0
      arch/arm/cpu/armv7/omap-common/boot-common.c
  40. 11 9
      arch/arm/cpu/armv7/omap-common/timer.c
  41. 7 7
      arch/arm/cpu/armv7/s5p-common/timer.c
  42. 8 7
      arch/arm/cpu/armv7/socfpga/timer.c
  43. 2 2
      arch/arm/cpu/armv7/start.S
  44. 40 0
      arch/arm/cpu/armv7/tegra114/Makefile
  45. 19 0
      arch/arm/cpu/armv7/tegra114/config.mk
  46. 40 0
      arch/arm/cpu/armv7/tegra30/Makefile
  47. 19 0
      arch/arm/cpu/armv7/tegra30/config.mk
  48. 9 7
      arch/arm/cpu/armv7/u8500/timer.c
  49. 1 0
      arch/arm/cpu/armv7/zynq/Makefile
  50. 27 1
      arch/arm/cpu/armv7/zynq/cpu.c
  51. 63 0
      arch/arm/cpu/armv7/zynq/slcr.c
  52. 7 7
      arch/arm/cpu/armv7/zynq/timer.c
  53. 6 6
      arch/arm/cpu/ixp/timer.c
  54. 2 2
      arch/arm/cpu/pxa/timer.c
  55. 1 1
      arch/arm/cpu/tegra-common/Makefile
  56. 20 3
      arch/arm/cpu/tegra-common/ap.c
  57. 51 7
      arch/arm/cpu/tegra-common/board.c
  58. 560 0
      arch/arm/cpu/tegra-common/clock.c
  59. 15 1
      arch/arm/cpu/tegra-common/sys_info.c
  60. 6 6
      arch/arm/cpu/tegra-common/timer.c
  61. 41 0
      arch/arm/cpu/tegra114-common/Makefile
  62. 655 0
      arch/arm/cpu/tegra114-common/clock.c
  63. 63 0
      arch/arm/cpu/tegra114-common/funcmux.c
  64. 506 0
      arch/arm/cpu/tegra114-common/pinmux.c
  65. 20 585
      arch/arm/cpu/tegra20-common/clock.c
  66. 2 2
      arch/arm/cpu/tegra20-common/funcmux.c
  67. 1 1
      arch/arm/cpu/tegra20-common/pinmux.c
  68. 1 1
      arch/arm/cpu/tegra20-common/warmboot.c
  69. 44 0
      arch/arm/cpu/tegra30-common/Makefile
  70. 618 0
      arch/arm/cpu/tegra30-common/clock.c
  71. 57 0
      arch/arm/cpu/tegra30-common/funcmux.c
  72. 506 0
      arch/arm/cpu/tegra30-common/pinmux.c
  73. 5 0
      arch/arm/dts/tegra114.dtsi
  74. 217 195
      arch/arm/dts/tegra20.dtsi
  75. 165 0
      arch/arm/dts/tegra30.dtsi
  76. 8 8
      arch/arm/imx-common/speed.c
  77. 2 2
      arch/arm/imx-common/timer.c
  78. 34 0
      arch/arm/include/asm/arch-am33xx/ddr_defs.h
  79. 2 1
      arch/arm/include/asm/arch-am33xx/mux.h
  80. 1 0
      arch/arm/include/asm/arch-am33xx/spl.h
  81. 6 6
      arch/arm/include/asm/arch-at91/clk.h
  82. 4 0
      arch/arm/include/asm/arch-davinci/gpio.h
  83. 6 46
      arch/arm/include/asm/arch-tegra/ap.h
  84. 4 3
      arch/arm/include/asm/arch-tegra/board.h
  85. 185 11
      arch/arm/include/asm/arch-tegra/clk_rst.h
  86. 60 5
      arch/arm/include/asm/arch-tegra/clock.h
  87. 39 0
      arch/arm/include/asm/arch-tegra/funcmux.h
  88. 40 0
      arch/arm/include/asm/arch-tegra/gp_padctrl.h
  89. 8 0
      arch/arm/include/asm/arch-tegra/pmc.h
  90. 17 2
      arch/arm/include/asm/arch-tegra/tegra.h
  91. 84 0
      arch/arm/include/asm/arch-tegra/tegra_slink.h
  92. 402 0
      arch/arm/include/asm/arch-tegra114/clock-tables.h
  93. 28 0
      arch/arm/include/asm/arch-tegra114/clock.h
  94. 35 0
      arch/arm/include/asm/arch-tegra114/flow.h
  95. 31 0
      arch/arm/include/asm/arch-tegra114/funcmux.h
  96. 59 0
      arch/arm/include/asm/arch-tegra114/gp_padctrl.h
  97. 30 0
      arch/arm/include/asm/arch-tegra114/gpio.h
  98. 22 0
      arch/arm/include/asm/arch-tegra114/hardware.h
  99. 618 0
      arch/arm/include/asm/arch-tegra114/pinmux.h
  100. 23 0
      arch/arm/include/asm/arch-tegra114/pmu.h

+ 8 - 0
MAINTAINERS

@@ -27,6 +27,10 @@ Poonam Aggrwal <poonam.aggrwal@freescale.com>
 
 
 	BSC9131RDB	BSC9131
 	BSC9131RDB	BSC9131
 
 
+Naveen Burmi <NaveenBurmi@freescale.com>
+
+	BSC9132QDS	BSC9132
+
 Greg Allen <gallen@arlut.utexas.edu>
 Greg Allen <gallen@arlut.utexas.edu>
 
 
 	UTX8245		MPC8245
 	UTX8245		MPC8245
@@ -603,6 +607,7 @@ Enric Balletbo i Serra <eballetbo@iseebcn.com>
 
 
 	igep0020	ARM ARMV7 (OMAP3xx SoC)
 	igep0020	ARM ARMV7 (OMAP3xx SoC)
 	igep0030	ARM ARMV7 (OMAP3xx SoC)
 	igep0030	ARM ARMV7 (OMAP3xx SoC)
+	igep0032	ARM ARMV7 (OMAP3xx SoC)
 
 
 Eric Benard <eric@eukrea.com>
 Eric Benard <eric@eukrea.com>
 
 
@@ -815,6 +820,9 @@ Dave Peverley <dpeverley@mpc-data.co.uk>
 
 
 	omap730p2	ARM926EJS
 	omap730p2	ARM926EJS
 
 
+Lars Poeschel <poeschel@lemonage.de>
+	pcm051  	ARM ARMV7 (AM33xx Soc)
+
 Mathieu Poirier <mathieu.poirier@linaro.org>
 Mathieu Poirier <mathieu.poirier@linaro.org>
 
 
 	snowball	ARM ARMV7 (u8500 SoC)
 	snowball	ARM ARMV7 (u8500 SoC)

+ 9 - 9
Makefile

@@ -230,10 +230,6 @@ endif
 # U-Boot objects....order is important (i.e. start must be first)
 # U-Boot objects....order is important (i.e. start must be first)
 
 
 OBJS  = $(CPUDIR)/start.o
 OBJS  = $(CPUDIR)/start.o
-ifeq ($(CPU),x86)
-RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/start16.o
-RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/resetvec.o
-endif
 ifeq ($(CPU),ppc4xx)
 ifeq ($(CPU),ppc4xx)
 OBJS += $(CPUDIR)/resetvec.o
 OBJS += $(CPUDIR)/resetvec.o
 endif
 endif
@@ -241,7 +237,7 @@ ifeq ($(CPU),mpc85xx)
 OBJS += $(CPUDIR)/resetvec.o
 OBJS += $(CPUDIR)/resetvec.o
 endif
 endif
 
 
-OBJS := $(addprefix $(obj),$(OBJS) $(RESET_OBJS-))
+OBJS := $(addprefix $(obj),$(OBJS))
 
 
 HAVE_VENDOR_COMMON_LIB = $(if $(wildcard board/$(VENDOR)/common/Makefile),y,n)
 HAVE_VENDOR_COMMON_LIB = $(if $(wildcard board/$(VENDOR)/common/Makefile),y,n)
 
 
@@ -348,7 +344,7 @@ endif
 ifeq ($(SOC),exynos)
 ifeq ($(SOC),exynos)
 LIBS-y += $(CPUDIR)/s5p-common/libs5p-common.o
 LIBS-y += $(CPUDIR)/s5p-common/libs5p-common.o
 endif
 endif
-ifeq ($(SOC),tegra20)
+ifneq ($(CONFIG_TEGRA),)
 LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o
 LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o
 LIBS-y += arch/$(ARCH)/cpu/tegra-common/libcputegra-common.o
 LIBS-y += arch/$(ARCH)/cpu/tegra-common/libcputegra-common.o
 LIBS-y += $(CPUDIR)/tegra-common/libtegra-common.o
 LIBS-y += $(CPUDIR)/tegra-common/libtegra-common.o
@@ -413,7 +409,7 @@ ALL-$(CONFIG_SPL) += $(obj)$(subst ",,$(CONFIG_SPL_TARGET))
 ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin
 ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin
 
 
 # enable combined SPL/u-boot/dtb rules for tegra
 # enable combined SPL/u-boot/dtb rules for tegra
-ifeq ($(SOC),tegra20)
+ifneq ($(CONFIG_TEGRA),)
 ifeq ($(CONFIG_OF_SEPARATE),y)
 ifeq ($(CONFIG_OF_SEPARATE),y)
 ALL-y += $(obj)u-boot-dtb-tegra.bin
 ALL-y += $(obj)u-boot-dtb-tegra.bin
 else
 else
@@ -485,8 +481,12 @@ $(obj)u-boot.sha1:	$(obj)u-boot.bin
 $(obj)u-boot.dis:	$(obj)u-boot
 $(obj)u-boot.dis:	$(obj)u-boot
 		$(OBJDUMP) -d $< > $@
 		$(OBJDUMP) -d $< > $@
 
 
+
+
 $(obj)u-boot-with-spl.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
 $(obj)u-boot-with-spl.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
-		$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin
+		$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(or $(CONFIG_SPL_PAD_TO),0) \
+			-O binary $(obj)spl/u-boot-spl \
+			$(obj)spl/u-boot-spl-pad.bin
 		cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin > $@
 		cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin > $@
 		rm $(obj)spl/u-boot-spl-pad.bin
 		rm $(obj)spl/u-boot-spl-pad.bin
 
 
@@ -530,7 +530,7 @@ $(obj)u-boot.spr:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
 			conv=notrunc 2>/dev/null
 			conv=notrunc 2>/dev/null
 		cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@
 		cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@
 
 
-ifeq ($(SOC),tegra20)
+ifneq ($(CONFIG_TEGRA),)
 ifeq ($(CONFIG_OF_SEPARATE),y)
 ifeq ($(CONFIG_OF_SEPARATE),y)
 nodtb=dtb
 nodtb=dtb
 dtbfile=$(obj)u-boot.dtb
 dtbfile=$(obj)u-boot.dtb

+ 13 - 8
README

@@ -2819,6 +2819,12 @@ FIT uImage format:
 		CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME
 		CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME
 		Filename to read to load U-Boot when reading from FAT
 		Filename to read to load U-Boot when reading from FAT
 
 
+		CONFIG_SPL_MPC83XX_WAIT_FOR_NAND
+		Set this for NAND SPL on PPC mpc83xx targets, so that
+		start.S waits for the rest of the SPL to load before
+		continuing (the hardware starts execution after just
+		loading the first page rather than the full 4K).
+
 		CONFIG_SPL_NAND_BASE
 		CONFIG_SPL_NAND_BASE
 		Include nand_base.c in the SPL.  Requires
 		Include nand_base.c in the SPL.  Requires
 		CONFIG_SPL_NAND_DRIVERS.
 		CONFIG_SPL_NAND_DRIVERS.
@@ -2876,6 +2882,10 @@ FIT uImage format:
 		CONFIG_SPL_LIBGENERIC_SUPPORT
 		CONFIG_SPL_LIBGENERIC_SUPPORT
 		Support for lib/libgeneric.o in SPL binary
 		Support for lib/libgeneric.o in SPL binary
 
 
+		CONFIG_SPL_PAD_TO
+		Linker address to which the SPL should be padded before
+		appending the SPL payload.
+
 		CONFIG_SPL_TARGET
 		CONFIG_SPL_TARGET
 		Final target image containing SPL and payload.  Some SPLs
 		Final target image containing SPL and payload.  Some SPLs
 		use an arch-specific makefile fragment instead, for
 		use an arch-specific makefile fragment instead, for
@@ -3806,14 +3816,9 @@ Low Level (hardware related) configuration options:
 		be used if available. These functions may be faster under some
 		be used if available. These functions may be faster under some
 		conditions but may increase the binary size.
 		conditions but may increase the binary size.
 
 
-- CONFIG_X86_NO_RESET_VECTOR
-		If defined, the x86 reset vector code is excluded. You will need
-		to do this when U-Boot is running from Coreboot.
-
-- CONFIG_X86_NO_REAL_MODE
-		If defined, x86 real mode code is omitted. This assumes a
-		32-bit environment where such code is not needed. You will
-		need to do this when U-Boot is running from Coreboot.
+- CONFIG_X86_RESET_VECTOR
+		If defined, the x86 reset vector code is included. This is not
+		needed when U-Boot is running from Coreboot.
 
 
 
 
 Freescale QE/FMAN Firmware Support:
 Freescale QE/FMAN Firmware Support:

+ 5 - 5
arch/arm/cpu/arm1136/mx31/timer.c

@@ -115,13 +115,13 @@ unsigned long long get_ticks(void)
 {
 {
 	ulong now = GPTCNT; /* current tick value */
 	ulong now = GPTCNT; /* current tick value */
 
 
-	if (now >= gd->lastinc)	/* normal mode (non roll) */
+	if (now >= gd->arch.lastinc)	/* normal mode (non roll) */
 		/* move stamp forward with absolut diff ticks */
 		/* move stamp forward with absolut diff ticks */
-		gd->tbl += (now - gd->lastinc);
+		gd->arch.tbl += (now - gd->arch.lastinc);
 	else			/* we have rollover of incrementer */
 	else			/* we have rollover of incrementer */
-		gd->tbl += (0xFFFFFFFF - gd->lastinc) + now;
-	gd->lastinc = now;
-	return gd->tbl;
+		gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now;
+	gd->arch.lastinc = now;
+	return gd->arch.tbl;
 }
 }
 
 
 ulong get_timer_masked(void)
 ulong get_timer_masked(void)

+ 3 - 3
arch/arm/cpu/arm1136/mx35/generic.c

@@ -478,11 +478,11 @@ int get_clocks(void)
 {
 {
 #ifdef CONFIG_FSL_ESDHC
 #ifdef CONFIG_FSL_ESDHC
 #if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR
 #if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
 #elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR
 #elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
 #else
 #else
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
 #endif
 #endif
 #endif
 #endif
 	return 0;
 	return 0;

+ 2 - 2
arch/arm/cpu/arm1136/mx35/timer.c

@@ -32,8 +32,8 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp	(gd->tbl)
-#define lastinc		(gd->lastinc)
+#define timestamp	(gd->arch.tbl)
+#define lastinc		(gd->arch.lastinc)
 
 
 /* General purpose timers bitfields */
 /* General purpose timers bitfields */
 #define GPTCR_SWR       (1<<15)	/* Software reset */
 #define GPTCR_SWR       (1<<15)	/* Software reset */

+ 13 - 10
arch/arm/cpu/arm1136/omap24xx/timer.c

@@ -51,8 +51,8 @@ int timer_init (void)
 	*((int32_t *) (CONFIG_SYS_TIMERBASE + TCLR)) = val;	/* start timer */
 	*((int32_t *) (CONFIG_SYS_TIMERBASE + TCLR)) = val;	/* start timer */
 
 
 	/* reset time */
 	/* reset time */
-	gd->lastinc = READ_TIMER;	/* capture current incrementer value */
-	gd->tbl = 0;			/* start "advancing" time stamp */
+	gd->arch.lastinc = READ_TIMER;	/* capture current incrementer value */
+	gd->arch.tbl = 0;		/* start "advancing" time stamp */
 
 
 	return(0);
 	return(0);
 }
 }
@@ -81,8 +81,8 @@ void __udelay (unsigned long usec)
 	tmp = get_timer (0);		/* get current timestamp */
 	tmp = get_timer (0);		/* get current timestamp */
 	if ((tmo + tmp + 1) < tmp) {	/* if setting this forward will roll */
 	if ((tmo + tmp + 1) < tmp) {	/* if setting this forward will roll */
 					/* time stamp, then reset time */
 					/* time stamp, then reset time */
-		gd->lastinc = READ_TIMER;	/* capture incrementer value */
-		gd->tbl = 0;			/* start time stamp */
+		gd->arch.lastinc = READ_TIMER;	/* capture incrementer value */
+		gd->arch.tbl = 0;			/* start time stamp */
 	} else {
 	} else {
 		tmo	+= tmp;		/* else, set advancing stamp wake up time */
 		tmo	+= tmp;		/* else, set advancing stamp wake up time */
 	}
 	}
@@ -94,12 +94,15 @@ ulong get_timer_masked (void)
 {
 {
 	ulong now = READ_TIMER;		/* current tick value */
 	ulong now = READ_TIMER;		/* current tick value */
 
 
-	if (now >= gd->lastinc)		/* normal mode (non roll) */
-		gd->tbl += (now - gd->lastinc); /* move stamp fordward with absoulte diff ticks */
-	else				/* we have rollover of incrementer */
-		gd->tbl += (0xFFFFFFFF - gd->lastinc) + now;
-	gd->lastinc = now;
-	return gd->tbl;
+	if (now >= gd->arch.lastinc) {		/* normal mode (non roll) */
+		/* move stamp fordward with absoulte diff ticks */
+		gd->arch.tbl += (now - gd->arch.lastinc);
+	} else {
+		/* we have rollover of incrementer */
+		gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now;
+	}
+	gd->arch.lastinc = now;
+	return gd->arch.tbl;
 }
 }
 
 
 /* waits specified delay value and resets timestamp */
 /* waits specified delay value and resets timestamp */

+ 1 - 0
arch/arm/cpu/arm720t/tegra-common/Makefile

@@ -28,6 +28,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)libtegra-common.o
 LIB	= $(obj)libtegra-common.o
 
 
 COBJS-$(CONFIG_SPL_BUILD) += spl.o
 COBJS-$(CONFIG_SPL_BUILD) += spl.o
+COBJS-y	+= cpu.o
 
 
 SRCS	:= $(COBJS-y:.o=.c)
 SRCS	:= $(COBJS-y:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS-y))
 OBJS	:= $(addprefix $(obj),$(COBJS-y))

+ 333 - 0
arch/arm/cpu/arm720t/tegra-common/cpu.c

@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gp_padctrl.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/tegra.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/pmc.h>
+#include <asm/arch-tegra/scu.h>
+#include "cpu.h"
+
+int get_num_cpus(void)
+{
+	struct apb_misc_gp_ctlr *gp;
+	uint rev;
+
+	gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
+	rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;
+
+	switch (rev) {
+	case CHIPID_TEGRA20:
+		return 2;
+		break;
+	case CHIPID_TEGRA30:
+	case CHIPID_TEGRA114:
+	default:
+		return 4;
+		break;
+	}
+}
+
+/*
+ * Timing tables for each SOC for all four oscillator options.
+ */
+struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = {
+	/* T20: 1 GHz */
+	/*  n,  m, p, cpcon */
+	{{ 1000, 13, 0, 12},	/* OSC 13M */
+	 { 625,  12, 0, 8},	/* OSC 19.2M */
+	 { 1000, 12, 0, 12},	/* OSC 12M */
+	 { 1000, 26, 0, 12},	/* OSC 26M */
+	},
+
+	/* T25: 1.2 GHz */
+	{{ 923, 10, 0, 12},
+	 { 750, 12, 0, 8},
+	 { 600,  6, 0, 12},
+	 { 600, 13, 0, 12},
+	},
+
+	/* T30: 1.4 GHz */
+	{{ 862, 8, 0, 8},
+	 { 583, 8, 0, 4},
+	 { 700, 6, 0, 8},
+	 { 700, 13, 0, 8},
+	},
+
+	/* T114: 1.4 GHz */
+	{{ 862, 8, 0, 8},
+	 { 583, 8, 0, 4},
+	 { 696, 12, 0, 8},
+	 { 700, 13, 0, 8},
+	},
+};
+
+void adjust_pllp_out_freqs(void)
+{
+	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH];
+	u32 reg;
+
+	/* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */
+	reg = readl(&pll->pll_out[0]);	/* OUTA, contains OUT2 / OUT1 */
+	reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR
+		| (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR;
+	writel(reg, &pll->pll_out[0]);
+
+	reg = readl(&pll->pll_out[1]);   /* OUTB, contains OUT4 / OUT3 */
+	reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR
+		| (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR;
+	writel(reg, &pll->pll_out[1]);
+}
+
+int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm,
+		u32 divp, u32 cpcon)
+{
+	u32 reg;
+
+	/* If PLLX is already enabled, just return */
+	if (readl(&pll->pll_base) & PLL_ENABLE_MASK) {
+		debug("pllx_set_rate: PLLX already enabled, returning\n");
+		return 0;
+	}
+
+	debug(" pllx_set_rate entry\n");
+
+	/* Set BYPASS, m, n and p to PLLX_BASE */
+	reg = PLL_BYPASS_MASK | (divm << PLL_DIVM_SHIFT);
+	reg |= ((divn << PLL_DIVN_SHIFT) | (divp << PLL_DIVP_SHIFT));
+	writel(reg, &pll->pll_base);
+
+	/* Set cpcon to PLLX_MISC */
+	reg = (cpcon << PLL_CPCON_SHIFT);
+
+	/* Set dccon to PLLX_MISC if freq > 600MHz */
+	if (divn > 600)
+		reg |= (1 << PLL_DCCON_SHIFT);
+	writel(reg, &pll->pll_misc);
+
+	/* Enable PLLX */
+	reg = readl(&pll->pll_base);
+	reg |= PLL_ENABLE_MASK;
+
+	/* Disable BYPASS */
+	reg &= ~PLL_BYPASS_MASK;
+	writel(reg, &pll->pll_base);
+
+	/* Set lock_enable to PLLX_MISC */
+	reg = readl(&pll->pll_misc);
+	reg |= PLL_LOCK_ENABLE_MASK;
+	writel(reg, &pll->pll_misc);
+
+	return 0;
+}
+
+void init_pllx(void)
+{
+	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	struct clk_pll_simple *pll = &clkrst->crc_pll_simple[SIMPLE_PLLX];
+	int chip_type;
+	enum clock_osc_freq osc;
+	struct clk_pll_table *sel;
+
+	debug("init_pllx entry\n");
+
+	/* get chip type */
+	chip_type = tegra_get_chip_type();
+	debug(" init_pllx: chip_type = %d\n", chip_type);
+
+	/* get osc freq */
+	osc = clock_get_osc_freq();
+	debug("  init_pllx: osc = %d\n", osc);
+
+	/* set pllx */
+	sel = &tegra_pll_x_table[chip_type][osc];
+	pllx_set_rate(pll, sel->n, sel->m, sel->p, sel->cpcon);
+
+	/* adjust PLLP_out1-4 on T30/T114 */
+	if (chip_type == TEGRA_SOC_T30 || chip_type == TEGRA_SOC_T114) {
+		debug("  init_pllx: adjusting PLLP out freqs\n");
+		adjust_pllp_out_freqs();
+	}
+}
+
+void enable_cpu_clock(int enable)
+{
+	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 clk;
+
+	/*
+	 * NOTE:
+	 * Regardless of whether the request is to enable or disable the CPU
+	 * clock, every processor in the CPU complex except the master (CPU 0)
+	 * will have it's clock stopped because the AVP only talks to the
+	 * master.
+	 */
+
+	if (enable) {
+		/* Initialize PLLX */
+		init_pllx();
+
+		/* Wait until all clocks are stable */
+		udelay(PLL_STABILIZATION_DELAY);
+
+		writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
+		writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div);
+	}
+
+	/*
+	 * Read the register containing the individual CPU clock enables and
+	 * always stop the clocks to CPUs > 0.
+	 */
+	clk = readl(&clkrst->crc_clk_cpu_cmplx);
+	clk |= 1 << CPU1_CLK_STP_SHIFT;
+	if (get_num_cpus() == 4)
+		clk |= (1 << CPU2_CLK_STP_SHIFT) + (1 << CPU3_CLK_STP_SHIFT);
+
+	/* Stop/Unstop the CPU clock */
+	clk &= ~CPU0_CLK_STP_MASK;
+	clk |= !enable << CPU0_CLK_STP_SHIFT;
+	writel(clk, &clkrst->crc_clk_cpu_cmplx);
+
+	clock_enable(PERIPH_ID_CPU);
+}
+
+static int is_cpu_powered(void)
+{
+	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+
+	return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0;
+}
+
+static void remove_cpu_io_clamps(void)
+{
+	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+	u32 reg;
+
+	/* Remove the clamps on the CPU I/O signals */
+	reg = readl(&pmc->pmc_remove_clamping);
+	reg |= CPU_CLMP;
+	writel(reg, &pmc->pmc_remove_clamping);
+
+	/* Give I/O signals time to stabilize */
+	udelay(IO_STABILIZATION_DELAY);
+}
+
+void powerup_cpu(void)
+{
+	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+	u32 reg;
+	int timeout = IO_STABILIZATION_DELAY;
+
+	if (!is_cpu_powered()) {
+		/* Toggle the CPU power state (OFF -> ON) */
+		reg = readl(&pmc->pmc_pwrgate_toggle);
+		reg &= PARTID_CP;
+		reg |= START_CP;
+		writel(reg, &pmc->pmc_pwrgate_toggle);
+
+		/* Wait for the power to come up */
+		while (!is_cpu_powered()) {
+			if (timeout-- == 0)
+				printf("CPU failed to power up!\n");
+			else
+				udelay(10);
+		}
+
+		/*
+		 * Remove the I/O clamps from CPU power partition.
+		 * Recommended only on a Warm boot, if the CPU partition gets
+		 * power gated. Shouldn't cause any harm when called after a
+		 * cold boot according to HW, probably just redundant.
+		 */
+		remove_cpu_io_clamps();
+	}
+}
+
+void reset_A9_cpu(int reset)
+{
+	/*
+	* NOTE:  Regardless of whether the request is to hold the CPU in reset
+	*        or take it out of reset, every processor in the CPU complex
+	*        except the master (CPU 0) will be held in reset because the
+	*        AVP only talks to the master. The AVP does not know that there
+	*        are multiple processors in the CPU complex.
+	*/
+	int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug;
+	int num_cpus = get_num_cpus();
+	int cpu;
+
+	debug("reset_a9_cpu entry\n");
+	/* Hold CPUs 1 onwards in reset, and CPU 0 if asked */
+	for (cpu = 1; cpu < num_cpus; cpu++)
+		reset_cmplx_set_enable(cpu, mask, 1);
+	reset_cmplx_set_enable(0, mask, reset);
+
+	/* Enable/Disable master CPU reset */
+	reset_set_enable(PERIPH_ID_CPU, reset);
+}
+
+void clock_enable_coresight(int enable)
+{
+	u32 rst, src = 2;
+	int chip;
+
+	debug("clock_enable_coresight entry\n");
+	clock_set_enable(PERIPH_ID_CORESIGHT, enable);
+	reset_set_enable(PERIPH_ID_CORESIGHT, !enable);
+
+	if (enable) {
+		/*
+		 * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by
+		 *  1.5, giving an effective frequency of 144MHz.
+		 * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor
+		 *  (bits 7:0), so 00000001b == 1.5 (n+1 + .5)
+		 *
+		 * Clock divider request for 204MHz would setup CSITE clock as
+		 * 144MHz for PLLP base 216MHz and 204MHz for PLLP base 408MHz
+		 */
+		chip = tegra_get_chip_type();
+		if (chip == TEGRA_SOC_T30 || chip == TEGRA_SOC_T114)
+			src = CLK_DIVIDER(NVBL_PLLP_KHZ, 204000);
+		else if (chip == TEGRA_SOC_T20 || chip == TEGRA_SOC_T25)
+			src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000);
+		else
+			printf("%s: Unknown chip type %X!\n", __func__, chip);
+		clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src);
+
+		/* Unlock the CPU CoreSight interfaces */
+		rst = CORESIGHT_UNLOCK;
+		writel(rst, CSITE_CPU_DBG0_LAR);
+		writel(rst, CSITE_CPU_DBG1_LAR);
+		if (get_num_cpus() == 4) {
+			writel(rst, CSITE_CPU_DBG2_LAR);
+			writel(rst, CSITE_CPU_DBG3_LAR);
+		}
+	}
+}
+
+void halt_avp(void)
+{
+	for (;;) {
+		writel((HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \
+			| HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29)),
+			FLOW_CTLR_HALT_COP_EVENTS);
+	}
+}

+ 27 - 43
arch/arm/cpu/arm720t/tegra-common/cpu.h

@@ -26,7 +26,13 @@
 #define PLL_STABILIZATION_DELAY (300)
 #define PLL_STABILIZATION_DELAY (300)
 #define IO_STABILIZATION_DELAY	(1000)
 #define IO_STABILIZATION_DELAY	(1000)
 
 
+#if defined(CONFIG_TEGRA20)
 #define NVBL_PLLP_KHZ	(216000)
 #define NVBL_PLLP_KHZ	(216000)
+#elif defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114)
+#define NVBL_PLLP_KHZ	(408000)
+#else
+#error "Unknown Tegra chip!"
+#endif
 
 
 #define PLLX_ENABLED		(1 << 30)
 #define PLLX_ENABLED		(1 << 30)
 #define CCLK_BURST_POLICY	0x20008888
 #define CCLK_BURST_POLICY	0x20008888
@@ -44,50 +50,11 @@
 
 
 #define CORESIGHT_UNLOCK	0xC5ACCE55;
 #define CORESIGHT_UNLOCK	0xC5ACCE55;
 
 
-/* AP20-Specific Base Addresses */
-
-/* AP20 Base physical address of SDRAM. */
-#define AP20_BASE_PA_SDRAM      0x00000000
-/* AP20 Base physical address of internal SRAM. */
-#define AP20_BASE_PA_SRAM       0x40000000
-/* AP20 Size of internal SRAM (256KB). */
-#define AP20_BASE_PA_SRAM_SIZE  0x00040000
-/* AP20 Base physical address of flash. */
-#define AP20_BASE_PA_NOR_FLASH  0xD0000000
-/* AP20 Base physical address of boot information table. */
-#define AP20_BASE_PA_BOOT_INFO  AP20_BASE_PA_SRAM
-
-/*
- * Super-temporary stacks for EXTREMELY early startup. The values chosen for
- * these addresses must be valid on ALL SOCs because this value is used before
- * we are able to differentiate between the SOC types.
- *
- * NOTE: The since CPU's stack will eventually be moved from IRAM to SDRAM, its
- *       stack is placed below the AVP stack. Once the CPU stack has been moved,
- *       the AVP is free to use the IRAM the CPU stack previously occupied if
- *       it should need to do so.
- *
- * NOTE: In multi-processor CPU complex configurations, each processor will have
- *       its own stack of size CPU_EARLY_BOOT_STACK_SIZE. CPU 0 will have a
- *       limit of CPU_EARLY_BOOT_STACK_LIMIT. Each successive CPU will have a
- *       stack limit that is CPU_EARLY_BOOT_STACK_SIZE less then the previous
- *       CPU.
- */
-
-/* Common AVP early boot stack limit */
-#define AVP_EARLY_BOOT_STACK_LIMIT	\
-	(AP20_BASE_PA_SRAM + (AP20_BASE_PA_SRAM_SIZE/2))
-/* Common AVP early boot stack size */
-#define AVP_EARLY_BOOT_STACK_SIZE	0x1000
-/* Common CPU early boot stack limit */
-#define CPU_EARLY_BOOT_STACK_LIMIT	\
-	(AVP_EARLY_BOOT_STACK_LIMIT - AVP_EARLY_BOOT_STACK_SIZE)
-/* Common CPU early boot stack size */
-#define CPU_EARLY_BOOT_STACK_SIZE	0x1000
-
 #define EXCEP_VECTOR_CPU_RESET_VECTOR	(NV_PA_EVP_BASE + 0x100)
 #define EXCEP_VECTOR_CPU_RESET_VECTOR	(NV_PA_EVP_BASE + 0x100)
 #define CSITE_CPU_DBG0_LAR		(NV_PA_CSITE_BASE + 0x10FB0)
 #define CSITE_CPU_DBG0_LAR		(NV_PA_CSITE_BASE + 0x10FB0)
 #define CSITE_CPU_DBG1_LAR		(NV_PA_CSITE_BASE + 0x12FB0)
 #define CSITE_CPU_DBG1_LAR		(NV_PA_CSITE_BASE + 0x12FB0)
+#define CSITE_CPU_DBG2_LAR		(NV_PA_CSITE_BASE + 0x14FB0)
+#define CSITE_CPU_DBG3_LAR		(NV_PA_CSITE_BASE + 0x16FB0)
 
 
 #define FLOW_CTLR_HALT_COP_EVENTS	(NV_PA_FLOW_BASE + 4)
 #define FLOW_CTLR_HALT_COP_EVENTS	(NV_PA_FLOW_BASE + 4)
 #define FLOW_MODE_STOP			2
 #define FLOW_MODE_STOP			2
@@ -95,6 +62,23 @@
 #define HALT_COP_EVENT_IRQ_1		(1 << 11)
 #define HALT_COP_EVENT_IRQ_1		(1 << 11)
 #define HALT_COP_EVENT_FIQ_1		(1 << 9)
 #define HALT_COP_EVENT_FIQ_1		(1 << 9)
 
 
-void start_cpu(u32 reset_vector);
-int ap20_cpu_is_cortexa9(void);
+#define FLOW_MODE_NONE		0
+
+#define SIMPLE_PLLX     (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE)
+
+struct clk_pll_table {
+	u16	n;
+	u16	m;
+	u8	p;
+	u8	cpcon;
+};
+
+void clock_enable_coresight(int enable);
+void enable_cpu_clock(int enable);
 void halt_avp(void)  __attribute__ ((noreturn));
 void halt_avp(void)  __attribute__ ((noreturn));
+void init_pllx(void);
+void powerup_cpu(void);
+void reset_A9_cpu(int reset);
+void start_cpu(u32 reset_vector);
+int tegra_get_chip_type(void);
+void adjust_pllp_out_freqs(void);

+ 1 - 2
arch/arm/cpu/arm720t/tegra-common/spl.c

@@ -23,7 +23,6 @@
  * MA 02111-1307 USA
  * MA 02111-1307 USA
  */
  */
 #include <common.h>
 #include <common.h>
-#include "cpu.h"
 #include <spl.h>
 #include <spl.h>
 
 
 #include <asm/io.h>
 #include <asm/io.h>
@@ -32,7 +31,7 @@
 #include <asm/arch/tegra.h>
 #include <asm/arch/tegra.h>
 #include <asm/arch-tegra/board.h>
 #include <asm/arch-tegra/board.h>
 #include <asm/arch/spl.h>
 #include <asm/arch/spl.h>
-
+#include "cpu.h"
 
 
 void spl_board_init(void)
 void spl_board_init(void)
 {
 {

+ 42 - 0
arch/arm/cpu/arm720t/tegra114/Makefile

@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+#
+# (C) Copyright 2000-2008
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).o
+
+#COBJS-y	+= cpu.o t11x.o
+COBJS-y	+= cpu.o
+
+SRCS	:= $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS-y))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 19 - 0
arch/arm/cpu/arm720t/tegra114/config.mk

@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+#
+USE_PRIVATE_LIBGCC = yes

+ 297 - 0
arch/arm/cpu/arm720t/tegra114/cpu.c

@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/flow.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/tegra.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/pmc.h>
+#include "../tegra-common/cpu.h"
+
+/* Tegra114-specific CPU init code */
+static void enable_cpu_power_rail(void)
+{
+	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 reg;
+
+	debug("enable_cpu_power_rail entry\n");
+
+	/* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */
+	pinmux_tristate_disable(PINGRP_PWR_I2C_SCL);
+	pinmux_tristate_disable(PINGRP_PWR_I2C_SDA);
+
+	/*
+	 * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (102MHz),
+	 * set it for 25ms (102MHz * .025)
+	 */
+	reg = 0x26E8F0;
+	writel(reg, &pmc->pmc_cpupwrgood_timer);
+
+	/* Set polarity to 0 (normal) and enable CPUPWRREQ_OE */
+	clrbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_POL);
+	setbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_OE);
+
+	/*
+	 * Set CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2_0_CAR2PMC_CPU_ACK_WIDTH
+	 * to 408 to satisfy the requirement of having at least 16 CPU clock
+	 * cycles before clamp removal.
+	 */
+
+	clrbits_le32(&clkrst->crc_cpu_softrst_ctrl2, 0xFFF);
+	setbits_le32(&clkrst->crc_cpu_softrst_ctrl2, 408);
+}
+
+static void enable_cpu_clocks(void)
+{
+	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 reg;
+
+	debug("enable_cpu_clocks entry\n");
+
+	/* Wait for PLL-X to lock */
+	do {
+		reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
+	} while ((reg & (1 << 27)) == 0);
+
+	/* Wait until all clocks are stable */
+	udelay(PLL_STABILIZATION_DELAY);
+
+	writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
+	writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div);
+
+	/* Always enable the main CPU complex clocks */
+	clock_enable(PERIPH_ID_CPU);
+	clock_enable(PERIPH_ID_CPULP);
+	clock_enable(PERIPH_ID_CPUG);
+}
+
+static void remove_cpu_resets(void)
+{
+	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 reg;
+
+	debug("remove_cpu_resets entry\n");
+	/* Take the slow non-CPU partition out of reset */
+	reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr);
+	writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpulp_cmplx_clr);
+
+	/* Take the fast non-CPU partition out of reset */
+	reg = readl(&clkrst->crc_rst_cpug_cmplx_clr);
+	writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpug_cmplx_clr);
+
+	/* Clear the SW-controlled reset of the slow cluster */
+	reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr);
+	reg |= (CLR_CPURESET0+CLR_DBGRESET0+CLR_CORERESET0+CLR_CXRESET0);
+	writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr);
+
+	/* Clear the SW-controlled reset of the fast cluster */
+	reg = readl(&clkrst->crc_rst_cpug_cmplx_clr);
+	reg |= (CLR_CPURESET0+CLR_DBGRESET0+CLR_CORERESET0+CLR_CXRESET0);
+	reg |= (CLR_CPURESET1+CLR_DBGRESET1+CLR_CORERESET1+CLR_CXRESET1);
+	reg |= (CLR_CPURESET2+CLR_DBGRESET2+CLR_CORERESET2+CLR_CXRESET2);
+	reg |= (CLR_CPURESET3+CLR_DBGRESET3+CLR_CORERESET3+CLR_CXRESET3);
+	writel(reg, &clkrst->crc_rst_cpug_cmplx_clr);
+}
+
+/**
+ * The T114 requires some special clock initialization, including setting up
+ * the DVC I2C, turning on MSELECT and selecting the G CPU cluster
+ */
+void t114_init_clocks(void)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
+	u32 val;
+
+	debug("t114_init_clocks entry\n");
+
+	/* Set active CPU cluster to G */
+	clrbits_le32(&flow->cluster_control, 1);
+
+	/*
+	 * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run
+	 * at 108 MHz. This is glitch free as only the source is changed, no
+	 * special precaution needed.
+	 */
+	val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) |
+		(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) |
+		(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) |
+		(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) |
+		(SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT);
+	writel(val, &clkrst->crc_sclk_brst_pol);
+
+	writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div);
+
+	debug("Setting up PLLX\n");
+	init_pllx();
+
+	val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT);
+	writel(val, &clkrst->crc_clk_sys_rate);
+
+	/* Enable clocks to required peripherals. TBD - minimize this list */
+	debug("Enabling clocks\n");
+
+	clock_set_enable(PERIPH_ID_CACHE2, 1);
+	clock_set_enable(PERIPH_ID_GPIO, 1);
+	clock_set_enable(PERIPH_ID_TMR, 1);
+	clock_set_enable(PERIPH_ID_RTC, 1);
+	clock_set_enable(PERIPH_ID_CPU, 1);
+	clock_set_enable(PERIPH_ID_EMC, 1);
+	clock_set_enable(PERIPH_ID_I2C5, 1);
+	clock_set_enable(PERIPH_ID_FUSE, 1);
+	clock_set_enable(PERIPH_ID_PMC, 1);
+	clock_set_enable(PERIPH_ID_APBDMA, 1);
+	clock_set_enable(PERIPH_ID_MEM, 1);
+	clock_set_enable(PERIPH_ID_IRAMA, 1);
+	clock_set_enable(PERIPH_ID_IRAMB, 1);
+	clock_set_enable(PERIPH_ID_IRAMC, 1);
+	clock_set_enable(PERIPH_ID_IRAMD, 1);
+	clock_set_enable(PERIPH_ID_CORESIGHT, 1);
+	clock_set_enable(PERIPH_ID_MSELECT, 1);
+	clock_set_enable(PERIPH_ID_EMC1, 1);
+	clock_set_enable(PERIPH_ID_MC1, 1);
+	clock_set_enable(PERIPH_ID_DVFS, 1);
+
+	/* Switch MSELECT clock to PLLP (00) */
+	clock_ll_set_source(PERIPH_ID_MSELECT, 0);
+
+	/*
+	 * Clock divider request for 102MHz would setup MSELECT clock as
+	 * 102MHz for PLLP base 408MHz
+	 */
+	clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0,
+		(NVBL_PLLP_KHZ/102000));
+
+	/* I2C5 (DVC) gets CLK_M and a divisor of 17 */
+	clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16);
+
+	/* Give clocks time to stabilize */
+	udelay(1000);
+
+	/* Take required peripherals out of reset */
+	debug("Taking periphs out of reset\n");
+	reset_set_enable(PERIPH_ID_CACHE2, 0);
+	reset_set_enable(PERIPH_ID_GPIO, 0);
+	reset_set_enable(PERIPH_ID_TMR, 0);
+	reset_set_enable(PERIPH_ID_COP, 0);
+	reset_set_enable(PERIPH_ID_EMC, 0);
+	reset_set_enable(PERIPH_ID_I2C5, 0);
+	reset_set_enable(PERIPH_ID_FUSE, 0);
+	reset_set_enable(PERIPH_ID_APBDMA, 0);
+	reset_set_enable(PERIPH_ID_MEM, 0);
+	reset_set_enable(PERIPH_ID_CORESIGHT, 0);
+	reset_set_enable(PERIPH_ID_MSELECT, 0);
+	reset_set_enable(PERIPH_ID_EMC1, 0);
+	reset_set_enable(PERIPH_ID_MC1, 0);
+
+	debug("t114_init_clocks exit\n");
+}
+
+static int is_partition_powered(u32 mask)
+{
+	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+	u32 reg;
+
+	/* Get power gate status */
+	reg = readl(&pmc->pmc_pwrgate_status);
+	return (reg & mask) == mask;
+}
+
+static int is_clamp_enabled(u32 mask)
+{
+	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+	u32 reg;
+
+	/* Get clamp status. TODO: Add pmc_clamp_status alias to pmc.h */
+	reg = readl(&pmc->pmc_pwrgate_timer_on);
+	return (reg & mask) == mask;
+}
+
+static void power_partition(u32 status, u32 partid)
+{
+	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+
+	debug("%s: status = %08X, part ID = %08X\n", __func__, status, partid);
+	/* Is the partition already on? */
+	if (!is_partition_powered(status)) {
+		/* No, toggle the partition power state (OFF -> ON) */
+		debug("power_partition, toggling state\n");
+		clrbits_le32(&pmc->pmc_pwrgate_toggle, 0x1F);
+		setbits_le32(&pmc->pmc_pwrgate_toggle, partid);
+		setbits_le32(&pmc->pmc_pwrgate_toggle, START_CP);
+
+		/* Wait for the power to come up */
+		while (!is_partition_powered(status))
+			;
+
+		/* Wait for the clamp status to be cleared */
+		while (is_clamp_enabled(status))
+			;
+
+		/* Give I/O signals time to stabilize */
+		udelay(IO_STABILIZATION_DELAY);
+	}
+}
+
+void powerup_cpus(void)
+{
+	debug("powerup_cpus entry\n");
+
+	/* We boot to the fast cluster */
+	debug("powerup_cpus entry: G cluster\n");
+	/* Power up the fast cluster rail partition */
+	power_partition(CRAIL, CRAILID);
+
+	/* Power up the fast cluster non-CPU partition */
+	power_partition(C0NC, C0NCID);
+
+	/* Power up the fast cluster CPU0 partition */
+	power_partition(CE0, CE0ID);
+}
+
+void start_cpu(u32 reset_vector)
+{
+	debug("start_cpu entry, reset_vector = %x\n", reset_vector);
+
+	t114_init_clocks();
+
+	/* Enable VDD_CPU */
+	enable_cpu_power_rail();
+
+	/* Get the CPU(s) running */
+	enable_cpu_clocks();
+
+	/* Enable CoreSight */
+	clock_enable_coresight(1);
+
+	/* Take CPU(s) out of reset */
+	remove_cpu_resets();
+
+	/*
+	 * Set the entry point for CPU execution from reset,
+	 *  if it's a non-zero value.
+	 */
+	if (reset_vector)
+		writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
+
+	/* If the CPU(s) don't already have power, power 'em up */
+	powerup_cpus();
+}

+ 14 - 202
arch/arm/cpu/arm720t/tegra20/cpu.c

@@ -1,160 +1,25 @@
 /*
 /*
-* (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
-*/
+ * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
 
 
 #include <common.h>
 #include <common.h>
 #include <asm/io.h>
 #include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/pinmux.h>
 #include <asm/arch/tegra.h>
 #include <asm/arch/tegra.h>
-#include <asm/arch-tegra/clk_rst.h>
 #include <asm/arch-tegra/pmc.h>
 #include <asm/arch-tegra/pmc.h>
-#include <asm/arch-tegra/scu.h>
 #include "../tegra-common/cpu.h"
 #include "../tegra-common/cpu.h"
 
 
-/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */
-int ap20_cpu_is_cortexa9(void)
-{
-	u32 id = readb(NV_PA_PG_UP_BASE + PG_UP_TAG_0);
-	return id == (PG_UP_TAG_0_PID_CPU & 0xff);
-}
-
-void init_pllx(void)
-{
-	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-	struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_XCPU];
-	u32 reg;
-
-	/* If PLLX is already enabled, just return */
-	if (readl(&pll->pll_base) & PLL_ENABLE_MASK)
-		return;
-
-	/* Set PLLX_MISC */
-	writel(1 << PLL_CPCON_SHIFT, &pll->pll_misc);
-
-	/* Use 12MHz clock here */
-	reg = PLL_BYPASS_MASK | (12 << PLL_DIVM_SHIFT);
-	reg |= 1000 << PLL_DIVN_SHIFT;
-	writel(reg, &pll->pll_base);
-
-	reg |= PLL_ENABLE_MASK;
-	writel(reg, &pll->pll_base);
-
-	reg &= ~PLL_BYPASS_MASK;
-	writel(reg, &pll->pll_base);
-}
-
-static void enable_cpu_clock(int enable)
-{
-	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-	u32 clk;
-
-	/*
-	 * NOTE:
-	 * Regardless of whether the request is to enable or disable the CPU
-	 * clock, every processor in the CPU complex except the master (CPU 0)
-	 * will have it's clock stopped because the AVP only talks to the
-	 * master. The AVP does not know (nor does it need to know) that there
-	 * are multiple processors in the CPU complex.
-	 */
-
-	if (enable) {
-		/* Initialize PLLX */
-		init_pllx();
-
-		/* Wait until all clocks are stable */
-		udelay(PLL_STABILIZATION_DELAY);
-
-		writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
-		writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div);
-	}
-
-	/*
-	 * Read the register containing the individual CPU clock enables and
-	 * always stop the clock to CPU 1.
-	 */
-	clk = readl(&clkrst->crc_clk_cpu_cmplx);
-	clk |= 1 << CPU1_CLK_STP_SHIFT;
-
-	/* Stop/Unstop the CPU clock */
-	clk &= ~CPU0_CLK_STP_MASK;
-	clk |= !enable << CPU0_CLK_STP_SHIFT;
-	writel(clk, &clkrst->crc_clk_cpu_cmplx);
-
-	clock_enable(PERIPH_ID_CPU);
-}
-
-static int is_cpu_powered(void)
-{
-	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
-
-	return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0;
-}
-
-static void remove_cpu_io_clamps(void)
-{
-	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
-	u32 reg;
-
-	/* Remove the clamps on the CPU I/O signals */
-	reg = readl(&pmc->pmc_remove_clamping);
-	reg |= CPU_CLMP;
-	writel(reg, &pmc->pmc_remove_clamping);
-
-	/* Give I/O signals time to stabilize */
-	udelay(IO_STABILIZATION_DELAY);
-}
-
-static void powerup_cpu(void)
-{
-	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
-	u32 reg;
-	int timeout = IO_STABILIZATION_DELAY;
-
-	if (!is_cpu_powered()) {
-		/* Toggle the CPU power state (OFF -> ON) */
-		reg = readl(&pmc->pmc_pwrgate_toggle);
-		reg &= PARTID_CP;
-		reg |= START_CP;
-		writel(reg, &pmc->pmc_pwrgate_toggle);
-
-		/* Wait for the power to come up */
-		while (!is_cpu_powered()) {
-			if (timeout-- == 0)
-				printf("CPU failed to power up!\n");
-			else
-				udelay(10);
-		}
-
-		/*
-		 * Remove the I/O clamps from CPU power partition.
-		 * Recommended only on a Warm boot, if the CPU partition gets
-		 * power gated. Shouldn't cause any harm when called after a
-		 * cold boot according to HW, probably just redundant.
-		 */
-		remove_cpu_io_clamps();
-	}
-}
-
 static void enable_cpu_power_rail(void)
 static void enable_cpu_power_rail(void)
 {
 {
 	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
 	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
@@ -173,49 +38,6 @@ static void enable_cpu_power_rail(void)
 	udelay(3750);
 	udelay(3750);
 }
 }
 
 
-static void reset_A9_cpu(int reset)
-{
-	/*
-	* NOTE:  Regardless of whether the request is to hold the CPU in reset
-	*        or take it out of reset, every processor in the CPU complex
-	*        except the master (CPU 0) will be held in reset because the
-	*        AVP only talks to the master. The AVP does not know that there
-	*        are multiple processors in the CPU complex.
-	*/
-
-	/* Hold CPU 1 in reset, and CPU 0 if asked */
-	reset_cmplx_set_enable(1, crc_rst_cpu | crc_rst_de | crc_rst_debug, 1);
-	reset_cmplx_set_enable(0, crc_rst_cpu | crc_rst_de | crc_rst_debug,
-			       reset);
-
-	/* Enable/Disable master CPU reset */
-	reset_set_enable(PERIPH_ID_CPU, reset);
-}
-
-static void clock_enable_coresight(int enable)
-{
-	u32 rst, src;
-
-	clock_set_enable(PERIPH_ID_CORESIGHT, enable);
-	reset_set_enable(PERIPH_ID_CORESIGHT, !enable);
-
-	if (enable) {
-		/*
-		 * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by
-		 *  1.5, giving an effective frequency of 144MHz.
-		 * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor
-		 *  (bits 7:0), so 00000001b == 1.5 (n+1 + .5)
-		 */
-		src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000);
-		clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src);
-
-		/* Unlock the CPU CoreSight interfaces */
-		rst = 0xC5ACCE55;
-		writel(rst, CSITE_CPU_DBG0_LAR);
-		writel(rst, CSITE_CPU_DBG1_LAR);
-	}
-}
-
 void start_cpu(u32 reset_vector)
 void start_cpu(u32 reset_vector)
 {
 {
 	/* Enable VDD_CPU */
 	/* Enable VDD_CPU */
@@ -246,13 +68,3 @@ void start_cpu(u32 reset_vector)
 	/* Take the CPU out of reset */
 	/* Take the CPU out of reset */
 	reset_A9_cpu(0);
 	reset_A9_cpu(0);
 }
 }
-
-
-void halt_avp(void)
-{
-	for (;;) {
-		writel((HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \
-			| HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29)),
-			FLOW_CTLR_HALT_COP_EVENTS);
-	}
-}

+ 41 - 0
arch/arm/cpu/arm720t/tegra30/Makefile

@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+#
+# (C) Copyright 2000-2008
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).o
+
+COBJS-y	+= cpu.o
+
+SRCS	:= $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS-y))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 19 - 0
arch/arm/cpu/arm720t/tegra30/config.mk

@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+#
+USE_PRIVATE_LIBGCC = yes

+ 176 - 0
arch/arm/cpu/arm720t/tegra30/cpu.c

@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/flow.h>
+#include <asm/arch/tegra.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/pmc.h>
+#include <asm/arch-tegra/tegra_i2c.h>
+#include "../tegra-common/cpu.h"
+
+/* Tegra30-specific CPU init code */
+void tegra_i2c_ll_write_addr(uint addr, uint config)
+{
+	struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
+
+	writel(addr, &reg->cmd_addr0);
+	writel(config, &reg->cnfg);
+}
+
+void tegra_i2c_ll_write_data(uint data, uint config)
+{
+	struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
+
+	writel(data, &reg->cmd_data1);
+	writel(config, &reg->cnfg);
+}
+
+#define TPS65911_I2C_ADDR		0x5A
+#define TPS65911_VDDCTRL_OP_REG		0x28
+#define TPS65911_VDDCTRL_SR_REG		0x27
+#define TPS65911_VDDCTRL_OP_DATA	(0x2300 | TPS65911_VDDCTRL_OP_REG)
+#define TPS65911_VDDCTRL_SR_DATA	(0x0100 | TPS65911_VDDCTRL_SR_REG)
+#define I2C_SEND_2_BYTES		0x0A02
+
+static void enable_cpu_power_rail(void)
+{
+	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+	u32 reg;
+
+	debug("enable_cpu_power_rail entry\n");
+	reg = readl(&pmc->pmc_cntrl);
+	reg |= CPUPWRREQ_OE;
+	writel(reg, &pmc->pmc_cntrl);
+
+	/*
+	 * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus.
+	 * First set VDD to 1.4V, then enable the VDD regulator.
+	 */
+	tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2);
+	tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES);
+	udelay(1000);
+	tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES);
+	udelay(10 * 1000);
+}
+
+/**
+ * The T30 requires some special clock initialization, including setting up
+ * the dvc i2c, turning on mselect and selecting the G CPU cluster
+ */
+void t30_init_clocks(void)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
+	u32 val;
+
+	debug("t30_init_clocks entry\n");
+	/* Set active CPU cluster to G */
+	clrbits_le32(flow->cluster_control, 1 << 0);
+
+	/*
+	 * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run
+	 * at 108 MHz. This is glitch free as only the source is changed, no
+	 * special precaution needed.
+	 */
+	val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) |
+		(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) |
+		(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) |
+		(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) |
+		(SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT);
+	writel(val, &clkrst->crc_sclk_brst_pol);
+
+	writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div);
+
+	val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) |
+		(1 << CLK_SYS_RATE_AHB_RATE_SHIFT) |
+		(0 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) |
+		(0 << CLK_SYS_RATE_APB_RATE_SHIFT);
+	writel(val, &clkrst->crc_clk_sys_rate);
+
+	/* Put i2c, mselect in reset and enable clocks */
+	reset_set_enable(PERIPH_ID_DVC_I2C, 1);
+	clock_set_enable(PERIPH_ID_DVC_I2C, 1);
+	reset_set_enable(PERIPH_ID_MSELECT, 1);
+	clock_set_enable(PERIPH_ID_MSELECT, 1);
+
+	/* Switch MSELECT clock to PLLP (00) */
+	clock_ll_set_source(PERIPH_ID_MSELECT, 0);
+
+	/*
+	 * Our high-level clock routines are not available prior to
+	 * relocation. We use the low-level functions which require a
+	 * hard-coded divisor. Use CLK_M with divide by (n + 1 = 17)
+	 */
+	clock_ll_set_source_divisor(PERIPH_ID_DVC_I2C, 3, 16);
+
+	/*
+	 * Give clocks time to stabilize, then take i2c and mselect out of
+	 * reset
+	 */
+	udelay(1000);
+	reset_set_enable(PERIPH_ID_DVC_I2C, 0);
+	reset_set_enable(PERIPH_ID_MSELECT, 0);
+}
+
+static void set_cpu_running(int run)
+{
+	struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
+
+	debug("set_cpu_running entry, run = %d\n", run);
+	writel(run ? FLOW_MODE_NONE : FLOW_MODE_STOP, &flow->halt_cpu_events);
+}
+
+void start_cpu(u32 reset_vector)
+{
+	debug("start_cpu entry, reset_vector = %x\n", reset_vector);
+	t30_init_clocks();
+
+	/* Enable VDD_CPU */
+	enable_cpu_power_rail();
+
+	set_cpu_running(0);
+
+	/* Hold the CPUs in reset */
+	reset_A9_cpu(1);
+
+	/* Disable the CPU clock */
+	enable_cpu_clock(0);
+
+	/* Enable CoreSight */
+	clock_enable_coresight(1);
+
+	/*
+	 * Set the entry point for CPU execution from reset,
+	 *  if it's a non-zero value.
+	 */
+	if (reset_vector)
+		writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
+
+	/* Enable the CPU clock */
+	enable_cpu_clock(1);
+
+	/* If the CPU doesn't already have power, power it up */
+	powerup_cpu();
+
+	/* Take the CPU out of reset */
+	reset_A9_cpu(0);
+
+	set_cpu_running(1);
+}

+ 9 - 9
arch/arm/cpu/arm920t/a320/timer.c

@@ -31,14 +31,14 @@ DECLARE_GLOBAL_DATA_PTR;
 static inline unsigned long long tick_to_time(unsigned long long tick)
 static inline unsigned long long tick_to_time(unsigned long long tick)
 {
 {
 	tick *= CONFIG_SYS_HZ;
 	tick *= CONFIG_SYS_HZ;
-	do_div(tick, gd->timer_rate_hz);
+	do_div(tick, gd->arch.timer_rate_hz);
 
 
 	return tick;
 	return tick;
 }
 }
 
 
 static inline unsigned long long usec_to_tick(unsigned long long usec)
 static inline unsigned long long usec_to_tick(unsigned long long usec)
 {
 {
-	usec *= gd->timer_rate_hz;
+	usec *= gd->arch.timer_rate_hz;
 	do_div(usec, 1000000);
 	do_div(usec, 1000000);
 
 
 	return usec;
 	return usec;
@@ -74,8 +74,8 @@ int timer_init(void)
 	cr |= FTTMR010_TM3_ENABLE;
 	cr |= FTTMR010_TM3_ENABLE;
 	writel(cr, &tmr->cr);
 	writel(cr, &tmr->cr);
 
 
-	gd->timer_rate_hz = TIMER_CLOCK;
-	gd->tbu = gd->tbl = 0;
+	gd->arch.timer_rate_hz = TIMER_CLOCK;
+	gd->arch.tbu = gd->arch.tbl = 0;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -89,10 +89,10 @@ unsigned long long get_ticks(void)
 	ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
 	ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
 
 
 	/* increment tbu if tbl has rolled over */
 	/* increment tbu if tbl has rolled over */
-	if (now < gd->tbl)
-		gd->tbu++;
-	gd->tbl = now;
-	return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
+	if (now < gd->arch.tbl)
+		gd->arch.tbu++;
+	gd->arch.tbl = now;
+	return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
 }
 }
 
 
 void __udelay(unsigned long usec)
 void __udelay(unsigned long usec)
@@ -126,5 +126,5 @@ ulong get_timer(ulong base)
  */
  */
 ulong get_tbclk(void)
 ulong get_tbclk(void)
 {
 {
-	return gd->timer_rate_hz;
+	return gd->arch.timer_rate_hz;
 }
 }

+ 13 - 11
arch/arm/cpu/arm920t/at91/clock.c

@@ -29,11 +29,11 @@ static unsigned long at91_css_to_rate(unsigned long css)
 	case AT91_PMC_MCKR_CSS_SLOW:
 	case AT91_PMC_MCKR_CSS_SLOW:
 		return CONFIG_SYS_AT91_SLOW_CLOCK;
 		return CONFIG_SYS_AT91_SLOW_CLOCK;
 	case AT91_PMC_MCKR_CSS_MAIN:
 	case AT91_PMC_MCKR_CSS_MAIN:
-		return gd->main_clk_rate_hz;
+		return gd->arch.main_clk_rate_hz;
 	case AT91_PMC_MCKR_CSS_PLLA:
 	case AT91_PMC_MCKR_CSS_PLLA:
-		return gd->plla_rate_hz;
+		return gd->arch.plla_rate_hz;
 	case AT91_PMC_MCKR_CSS_PLLB:
 	case AT91_PMC_MCKR_CSS_PLLB:
-		return gd->pllb_rate_hz;
+		return gd->arch.pllb_rate_hz;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -124,10 +124,10 @@ int at91_clock_init(unsigned long main_clock)
 		main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
 		main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
 	}
 	}
 #endif
 #endif
-	gd->main_clk_rate_hz = main_clock;
+	gd->arch.main_clk_rate_hz = main_clock;
 
 
 	/* report if PLLA is more than mildly overclocked */
 	/* report if PLLA is more than mildly overclocked */
-	gd->plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
+	gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
 
 
 #ifdef CONFIG_USB_ATMEL
 #ifdef CONFIG_USB_ATMEL
 	/*
 	/*
@@ -136,9 +136,10 @@ int at91_clock_init(unsigned long main_clock)
 	 *
 	 *
 	 * REVISIT:  assumes MCK doesn't derive from PLLB!
 	 * REVISIT:  assumes MCK doesn't derive from PLLB!
 	 */
 	 */
-	gd->at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) |
+	gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) |
 			     AT91_PMC_PLLBR_USBDIV_2;
 			     AT91_PMC_PLLBR_USBDIV_2;
-	gd->pllb_rate_hz = at91_pll_rate(main_clock, gd->at91_pllb_usb_init);
+	gd->arch.pllb_rate_hz = at91_pll_rate(main_clock,
+					      gd->arch.at91_pllb_usb_init);
 #endif
 #endif
 
 
 	/*
 	/*
@@ -146,13 +147,14 @@ int at91_clock_init(unsigned long main_clock)
 	 * For now, assume this parentage won't change.
 	 * For now, assume this parentage won't change.
 	 */
 	 */
 	mckr = readl(&pmc->mckr);
 	mckr = readl(&pmc->mckr);
-	gd->mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
-	freq = gd->mck_rate_hz;
+	gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
+	freq = gd->arch.mck_rate_hz;
 
 
 	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/* prescale */
 	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/* prescale */
 	/* mdiv */
 	/* mdiv */
-	gd->mck_rate_hz = freq / (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
-	gd->cpu_clk_rate_hz = freq;
+	gd->arch.mck_rate_hz = freq /
+			(1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
+	gd->arch.cpu_clk_rate_hz = freq;
 
 
 	return 0;
 	return 0;
 }
 }

+ 7 - 7
arch/arm/cpu/arm920t/at91/timer.c

@@ -63,8 +63,8 @@ int timer_init(void)
 	writel(TIMER_LOAD_VAL, &tc->tc[0].rc);
 	writel(TIMER_LOAD_VAL, &tc->tc[0].rc);
 
 
 	writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr);
 	writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr);
-	gd->lastinc = 0;
-	gd->tbl = 0;
+	gd->arch.lastinc = 0;
+	gd->arch.tbl = 0;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -89,16 +89,16 @@ ulong get_timer_raw(void)
 
 
 	now = readl(&tc->tc[0].cv) & 0x0000ffff;
 	now = readl(&tc->tc[0].cv) & 0x0000ffff;
 
 
-	if (now >= gd->lastinc) {
+	if (now >= gd->arch.lastinc) {
 		/* normal mode */
 		/* normal mode */
-		gd->tbl += now - gd->lastinc;
+		gd->arch.tbl += now - gd->arch.lastinc;
 	} else {
 	} else {
 		/* we have an overflow ... */
 		/* we have an overflow ... */
-		gd->tbl += now + TIMER_LOAD_VAL - gd->lastinc;
+		gd->arch.tbl += now + TIMER_LOAD_VAL - gd->arch.lastinc;
 	}
 	}
-	gd->lastinc = now;
+	gd->arch.lastinc = now;
 
 
-	return gd->tbl;
+	return gd->arch.tbl;
 }
 }
 
 
 ulong get_timer_masked(void)
 ulong get_timer_masked(void)

+ 15 - 15
arch/arm/cpu/arm920t/s3c24x0/timer.c

@@ -45,25 +45,25 @@ int timer_init(void)
 	/* use PWM Timer 4 because it has no output */
 	/* use PWM Timer 4 because it has no output */
 	/* prescaler for Timer 4 is 16 */
 	/* prescaler for Timer 4 is 16 */
 	writel(0x0f00, &timers->tcfg0);
 	writel(0x0f00, &timers->tcfg0);
-	if (gd->tbu == 0) {
+	if (gd->arch.tbu == 0) {
 		/*
 		/*
 		 * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
 		 * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
 		 * (default) and prescaler = 16. Should be 10390
 		 * (default) and prescaler = 16. Should be 10390
 		 * @33.25MHz and 15625 @ 50 MHz
 		 * @33.25MHz and 15625 @ 50 MHz
 		 */
 		 */
-		gd->tbu = get_PCLK() / (2 * 16 * 100);
-		gd->timer_rate_hz = get_PCLK() / (2 * 16);
+		gd->arch.tbu = get_PCLK() / (2 * 16 * 100);
+		gd->arch.timer_rate_hz = get_PCLK() / (2 * 16);
 	}
 	}
 	/* load value for 10 ms timeout */
 	/* load value for 10 ms timeout */
-	writel(gd->tbu, &timers->tcntb4);
+	writel(gd->arch.tbu, &timers->tcntb4);
 	/* auto load, manual update of timer 4 */
 	/* auto load, manual update of timer 4 */
 	tmr = (readl(&timers->tcon) & ~0x0700000) | 0x0600000;
 	tmr = (readl(&timers->tcon) & ~0x0700000) | 0x0600000;
 	writel(tmr, &timers->tcon);
 	writel(tmr, &timers->tcon);
 	/* auto load, start timer 4 */
 	/* auto load, start timer 4 */
 	tmr = (tmr & ~0x0700000) | 0x0500000;
 	tmr = (tmr & ~0x0700000) | 0x0500000;
 	writel(tmr, &timers->tcon);
 	writel(tmr, &timers->tcon);
-	gd->lastinc = 0;
-	gd->tbl = 0;
+	gd->arch.lastinc = 0;
+	gd->arch.tbl = 0;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -82,7 +82,7 @@ void __udelay (unsigned long usec)
 	ulong start = get_ticks();
 	ulong start = get_ticks();
 
 
 	tmo = usec / 1000;
 	tmo = usec / 1000;
-	tmo *= (gd->tbu * 100);
+	tmo *= (gd->arch.tbu * 100);
 	tmo /= 1000;
 	tmo /= 1000;
 
 
 	while ((ulong) (get_ticks() - start) < tmo)
 	while ((ulong) (get_ticks() - start) < tmo)
@@ -93,7 +93,7 @@ ulong get_timer_masked(void)
 {
 {
 	ulong tmr = get_ticks();
 	ulong tmr = get_ticks();
 
 
-	return tmr / (gd->timer_rate_hz / CONFIG_SYS_HZ);
+	return tmr / (gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
 }
 }
 
 
 void udelay_masked(unsigned long usec)
 void udelay_masked(unsigned long usec)
@@ -104,10 +104,10 @@ void udelay_masked(unsigned long usec)
 
 
 	if (usec >= 1000) {
 	if (usec >= 1000) {
 		tmo = usec / 1000;
 		tmo = usec / 1000;
-		tmo *= (gd->tbu * 100);
+		tmo *= (gd->arch.tbu * 100);
 		tmo /= 1000;
 		tmo /= 1000;
 	} else {
 	} else {
-		tmo = usec * (gd->tbu * 100);
+		tmo = usec * (gd->arch.tbu * 100);
 		tmo /= (1000 * 1000);
 		tmo /= (1000 * 1000);
 	}
 	}
 
 
@@ -128,16 +128,16 @@ unsigned long long get_ticks(void)
 	struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
 	struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
 	ulong now = readl(&timers->tcnto4) & 0xffff;
 	ulong now = readl(&timers->tcnto4) & 0xffff;
 
 
-	if (gd->lastinc >= now) {
+	if (gd->arch.lastinc >= now) {
 		/* normal mode */
 		/* normal mode */
-		gd->tbl += gd->lastinc - now;
+		gd->arch.tbl += gd->arch.lastinc - now;
 	} else {
 	} else {
 		/* we have an overflow ... */
 		/* we have an overflow ... */
-		gd->tbl += gd->lastinc + gd->tbu - now;
+		gd->arch.tbl += gd->arch.lastinc + gd->arch.tbu - now;
 	}
 	}
-	gd->lastinc = now;
+	gd->arch.lastinc = now;
 
 
-	return gd->tbl;
+	return gd->arch.tbl;
 }
 }
 
 
 /*
 /*

+ 9 - 9
arch/arm/cpu/arm926ejs/armada100/timer.c

@@ -61,7 +61,7 @@ struct armd1tmr_registers {
 #define	COUNT_RD_REQ		0x1
 #define	COUNT_RD_REQ		0x1
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
-/* Using gd->tbu from timestamp and gd->tbl for lastdec */
+/* Using gd->arch.tbu from timestamp and gd->arch.tbl for lastdec */
 
 
 /* For preventing risk of instability in reading counter value,
 /* For preventing risk of instability in reading counter value,
  * first set read request to register cvwr and then read same
  * first set read request to register cvwr and then read same
@@ -82,16 +82,16 @@ ulong get_timer_masked(void)
 {
 {
 	ulong now = read_timer();
 	ulong now = read_timer();
 
 
-	if (now >= gd->tbl) {
+	if (now >= gd->arch.tbl) {
 		/* normal mode */
 		/* normal mode */
-		gd->tbu += now - gd->tbl;
+		gd->arch.tbu += now - gd->arch.tbl;
 	} else {
 	} else {
 		/* we have an overflow ... */
 		/* we have an overflow ... */
-		gd->tbu += now + TIMER_LOAD_VAL - gd->tbl;
+		gd->arch.tbu += now + TIMER_LOAD_VAL - gd->arch.tbl;
 	}
 	}
-	gd->tbl = now;
+	gd->arch.tbl = now;
 
 
-	return gd->tbu;
+	return gd->arch.tbu;
 }
 }
 
 
 ulong get_timer(ulong base)
 ulong get_timer(ulong base)
@@ -135,9 +135,9 @@ int timer_init(void)
 
 
 	/* Enable timer 0 */
 	/* Enable timer 0 */
 	writel(0x1, &armd1timers->cer);
 	writel(0x1, &armd1timers->cer);
-	/* init the gd->tbu and gd->tbl value */
-	gd->tbl = read_timer();
-	gd->tbu = 0;
+	/* init the gd->arch.tbu and gd->arch.tbl value */
+	gd->arch.tbl = read_timer();
+	gd->arch.tbu = 0;
 
 
 	return 0;
 	return 0;
 }
 }

+ 16 - 14
arch/arm/cpu/arm926ejs/at91/clock.c

@@ -29,11 +29,11 @@ static unsigned long at91_css_to_rate(unsigned long css)
 	case AT91_PMC_MCKR_CSS_SLOW:
 	case AT91_PMC_MCKR_CSS_SLOW:
 		return CONFIG_SYS_AT91_SLOW_CLOCK;
 		return CONFIG_SYS_AT91_SLOW_CLOCK;
 	case AT91_PMC_MCKR_CSS_MAIN:
 	case AT91_PMC_MCKR_CSS_MAIN:
-		return gd->main_clk_rate_hz;
+		return gd->arch.main_clk_rate_hz;
 	case AT91_PMC_MCKR_CSS_PLLA:
 	case AT91_PMC_MCKR_CSS_PLLA:
-		return gd->plla_rate_hz;
+		return gd->arch.plla_rate_hz;
 	case AT91_PMC_MCKR_CSS_PLLB:
 	case AT91_PMC_MCKR_CSS_PLLB:
-		return gd->pllb_rate_hz;
+		return gd->arch.pllb_rate_hz;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -132,10 +132,10 @@ int at91_clock_init(unsigned long main_clock)
 		main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
 		main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
 	}
 	}
 #endif
 #endif
-	gd->main_clk_rate_hz = main_clock;
+	gd->arch.main_clk_rate_hz = main_clock;
 
 
 	/* report if PLLA is more than mildly overclocked */
 	/* report if PLLA is more than mildly overclocked */
-	gd->plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
+	gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
 
 
 #ifdef CONFIG_USB_ATMEL
 #ifdef CONFIG_USB_ATMEL
 	/*
 	/*
@@ -144,9 +144,10 @@ int at91_clock_init(unsigned long main_clock)
 	 *
 	 *
 	 * REVISIT:  assumes MCK doesn't derive from PLLB!
 	 * REVISIT:  assumes MCK doesn't derive from PLLB!
 	 */
 	 */
-	gd->at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) |
+	gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) |
 			     AT91_PMC_PLLBR_USBDIV_2;
 			     AT91_PMC_PLLBR_USBDIV_2;
-	gd->pllb_rate_hz = at91_pll_rate(main_clock, gd->at91_pllb_usb_init);
+	gd->arch.pllb_rate_hz = at91_pll_rate(main_clock,
+					      gd->arch.at91_pllb_usb_init);
 #endif
 #endif
 
 
 	/*
 	/*
@@ -157,15 +158,15 @@ int at91_clock_init(unsigned long main_clock)
 #if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) \
 #if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) \
 		|| defined(CONFIG_AT91SAM9X5)
 		|| defined(CONFIG_AT91SAM9X5)
 	/* plla divisor by 2 */
 	/* plla divisor by 2 */
-	gd->plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12));
+	gd->arch.plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12));
 #endif
 #endif
-	gd->mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
-	freq = gd->mck_rate_hz;
+	gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
+	freq = gd->arch.mck_rate_hz;
 
 
 	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/* prescale */
 	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/* prescale */
 #if defined(CONFIG_AT91SAM9G20)
 #if defined(CONFIG_AT91SAM9G20)
 	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
 	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
-	gd->mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ?
+	gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ?
 		freq / ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 7) : freq;
 		freq / ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 7) : freq;
 	if (mckr & AT91_PMC_MCKR_MDIV_MASK)
 	if (mckr & AT91_PMC_MCKR_MDIV_MASK)
 		freq /= 2;			/* processor clock division */
 		freq /= 2;			/* processor clock division */
@@ -177,14 +178,15 @@ int at91_clock_init(unsigned long main_clock)
 	 *  2   <==>   4
 	 *  2   <==>   4
 	 *  3   <==>   3
 	 *  3   <==>   3
 	 */
 	 */
-	gd->mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ==
+	gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ==
 		(AT91_PMC_MCKR_MDIV_2 | AT91_PMC_MCKR_MDIV_4)
 		(AT91_PMC_MCKR_MDIV_2 | AT91_PMC_MCKR_MDIV_4)
 		? freq / 3
 		? freq / 3
 		: freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
 		: freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
 #else
 #else
-	gd->mck_rate_hz = freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
+	gd->arch.mck_rate_hz = freq /
+			(1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
 #endif
 #endif
-	gd->cpu_clk_rate_hz = freq;
+	gd->arch.cpu_clk_rate_hz = freq;
 
 
 	return 0;
 	return 0;
 }
 }

+ 9 - 9
arch/arm/cpu/arm926ejs/at91/timer.c

@@ -52,14 +52,14 @@ DECLARE_GLOBAL_DATA_PTR;
 static inline unsigned long long tick_to_time(unsigned long long tick)
 static inline unsigned long long tick_to_time(unsigned long long tick)
 {
 {
 	tick *= CONFIG_SYS_HZ;
 	tick *= CONFIG_SYS_HZ;
-	do_div(tick, gd->timer_rate_hz);
+	do_div(tick, gd->arch.timer_rate_hz);
 
 
 	return tick;
 	return tick;
 }
 }
 
 
 static inline unsigned long long usec_to_tick(unsigned long long usec)
 static inline unsigned long long usec_to_tick(unsigned long long usec)
 {
 {
-	usec *= gd->timer_rate_hz;
+	usec *= gd->arch.timer_rate_hz;
 	do_div(usec, 1000000);
 	do_div(usec, 1000000);
 
 
 	return usec;
 	return usec;
@@ -79,8 +79,8 @@ int timer_init(void)
 	/* Enable PITC */
 	/* Enable PITC */
 	writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr);
 	writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr);
 
 
-	gd->timer_rate_hz = gd->mck_rate_hz / 16;
-	gd->tbu = gd->tbl = 0;
+	gd->arch.timer_rate_hz = gd->arch.mck_rate_hz / 16;
+	gd->arch.tbu = gd->arch.tbl = 0;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -95,10 +95,10 @@ unsigned long long get_ticks(void)
 	ulong now = readl(&pit->piir);
 	ulong now = readl(&pit->piir);
 
 
 	/* increment tbu if tbl has rolled over */
 	/* increment tbu if tbl has rolled over */
-	if (now < gd->tbl)
-		gd->tbu++;
-	gd->tbl = now;
-	return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
+	if (now < gd->arch.tbl)
+		gd->arch.tbu++;
+	gd->arch.tbl = now;
+	return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
 }
 }
 
 
 void __udelay(unsigned long usec)
 void __udelay(unsigned long usec)
@@ -132,5 +132,5 @@ ulong get_timer(ulong base)
  */
  */
 ulong get_tbclk(void)
 ulong get_tbclk(void)
 {
 {
-	return gd->timer_rate_hz;
+	return gd->arch.timer_rate_hz;
 }
 }

+ 11 - 10
arch/arm/cpu/arm926ejs/davinci/timer.c

@@ -60,8 +60,8 @@ int timer_init(void)
 	writel(0x0, &timer->tim34);
 	writel(0x0, &timer->tim34);
 	writel(TIMER_LOAD_VAL, &timer->prd34);
 	writel(TIMER_LOAD_VAL, &timer->prd34);
 	writel(2 << 22, &timer->tcr);
 	writel(2 << 22, &timer->tcr);
-	gd->timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV;
-	gd->timer_reset_value = 0;
+	gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV;
+	gd->arch.timer_reset_value = 0;
 
 
 	return(0);
 	return(0);
 }
 }
@@ -74,27 +74,28 @@ unsigned long long get_ticks(void)
 	unsigned long now = readl(&timer->tim34);
 	unsigned long now = readl(&timer->tim34);
 
 
 	/* increment tbu if tbl has rolled over */
 	/* increment tbu if tbl has rolled over */
-	if (now < gd->tbl)
-		gd->tbu++;
-	gd->tbl = now;
+	if (now < gd->arch.tbl)
+		gd->arch.tbu++;
+	gd->arch.tbl = now;
 
 
-	return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
+	return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
 }
 }
 
 
 ulong get_timer(ulong base)
 ulong get_timer(ulong base)
 {
 {
 	unsigned long long timer_diff;
 	unsigned long long timer_diff;
 
 
-	timer_diff = get_ticks() - gd->timer_reset_value;
+	timer_diff = get_ticks() - gd->arch.timer_reset_value;
 
 
-	return lldiv(timer_diff, (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base;
+	return lldiv(timer_diff,
+		     (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) - base;
 }
 }
 
 
 void __udelay(unsigned long usec)
 void __udelay(unsigned long usec)
 {
 {
 	unsigned long long endtime;
 	unsigned long long endtime;
 
 
-	endtime = lldiv((unsigned long long)usec * gd->timer_rate_hz,
+	endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz,
 			1000000UL);
 			1000000UL);
 	endtime += get_ticks();
 	endtime += get_ticks();
 
 
@@ -108,7 +109,7 @@ void __udelay(unsigned long usec)
  */
  */
 ulong get_tbclk(void)
 ulong get_tbclk(void)
 {
 {
-	return gd->timer_rate_hz;
+	return gd->arch.timer_rate_hz;
 }
 }
 
 
 #ifdef CONFIG_HW_WATCHDOG
 #ifdef CONFIG_HW_WATCHDOG

+ 2 - 2
arch/arm/cpu/arm926ejs/kirkwood/timer.c

@@ -86,8 +86,8 @@ struct kwtmr_registers *kwtmr_regs = (struct kwtmr_registers *)KW_TIMER_BASE;
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp gd->tbl
-#define lastdec gd->lastinc
+#define timestamp gd->arch.tbl
+#define lastdec gd->arch.lastinc
 
 
 ulong get_timer_masked(void)
 ulong get_timer_masked(void)
 {
 {

+ 2 - 2
arch/arm/cpu/arm926ejs/mb86r0x/timer.c

@@ -35,8 +35,8 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp gd->tbl
-#define lastdec gd->lastinc
+#define timestamp gd->arch.tbl
+#define lastdec gd->arch.lastinc
 
 
 static inline unsigned long long tick_to_time(unsigned long long tick)
 static inline unsigned long long tick_to_time(unsigned long long tick)
 {
 {

+ 2 - 2
arch/arm/cpu/arm926ejs/mx25/generic.c

@@ -229,9 +229,9 @@ int get_clocks(void)
 {
 {
 #ifdef CONFIG_FSL_ESDHC
 #ifdef CONFIG_FSL_ESDHC
 #if CONFIG_SYS_FSL_ESDHC_ADDR == IMX_MMC_SDHC2_BASE
 #if CONFIG_SYS_FSL_ESDHC_ADDR == IMX_MMC_SDHC2_BASE
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
 #else
 #else
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
 #endif
 #endif
 #endif
 #endif
 	return 0;
 	return 0;

+ 2 - 2
arch/arm/cpu/arm926ejs/mx25/timer.c

@@ -44,8 +44,8 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp	(gd->tbl)
-#define lastinc		(gd->lastinc)
+#define timestamp	(gd->arch.tbl)
+#define lastinc		(gd->arch.lastinc)
 
 
 /*
 /*
  * "time" is measured in 1 / CONFIG_SYS_HZ seconds,
  * "time" is measured in 1 / CONFIG_SYS_HZ seconds,

+ 2 - 2
arch/arm/cpu/arm926ejs/mx27/timer.c

@@ -45,8 +45,8 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp	(gd->tbl)
-#define lastinc		(gd->lastinc)
+#define timestamp	(gd->arch.tbl)
+#define lastinc		(gd->arch.lastinc)
 
 
 /*
 /*
  * "time" is measured in 1 / CONFIG_SYS_HZ seconds,
  * "time" is measured in 1 / CONFIG_SYS_HZ seconds,

+ 2 - 2
arch/arm/cpu/arm926ejs/mxs/timer.c

@@ -36,8 +36,8 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp (gd->tbl)
-#define lastdec (gd->lastinc)
+#define timestamp (gd->arch.tbl)
+#define lastdec (gd->arch.lastinc)
 
 
 /*
 /*
  * This driver uses 1kHz clock source.
  * This driver uses 1kHz clock source.

+ 2 - 2
arch/arm/cpu/arm926ejs/omap/timer.c

@@ -44,8 +44,8 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp gd->tbl
-#define lastdec gd->lastinc
+#define timestamp gd->arch.tbl
+#define lastdec gd->arch.lastinc
 
 
 int timer_init (void)
 int timer_init (void)
 {
 {

+ 2 - 2
arch/arm/cpu/arm926ejs/orion5x/timer.c

@@ -92,8 +92,8 @@ static inline ulong read_timer(void)
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp gd->tbl
-#define lastdec gd->lastinc
+#define timestamp gd->arch.tbl
+#define lastdec gd->arch.lastinc
 
 
 ulong get_timer_masked(void)
 ulong get_timer_masked(void)
 {
 {

+ 9 - 9
arch/arm/cpu/arm926ejs/pantheon/timer.c

@@ -60,7 +60,7 @@ struct panthtmr_registers {
 #define	COUNT_RD_REQ		0x1
 #define	COUNT_RD_REQ		0x1
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
-/* Using gd->tbu from timestamp and gd->tbl for lastdec */
+/* Using gd->arch.tbu from timestamp and gd->arch.tbl for lastdec */
 
 
 /*
 /*
  * For preventing risk of instability in reading counter value,
  * For preventing risk of instability in reading counter value,
@@ -90,16 +90,16 @@ ulong get_timer_masked(void)
 {
 {
 	ulong now = read_timer();
 	ulong now = read_timer();
 
 
-	if (now >= gd->tbl) {
+	if (now >= gd->arch.tbl) {
 		/* normal mode */
 		/* normal mode */
-		gd->tbu += now - gd->tbl;
+		gd->arch.tbu += now - gd->arch.tbl;
 	} else {
 	} else {
 		/* we have an overflow ... */
 		/* we have an overflow ... */
-		gd->tbu += now + TIMER_LOAD_VAL - gd->tbl;
+		gd->arch.tbu += now + TIMER_LOAD_VAL - gd->arch.tbl;
 	}
 	}
-	gd->tbl = now;
+	gd->arch.tbl = now;
 
 
-	return gd->tbu;
+	return gd->arch.tbu;
 }
 }
 
 
 ulong get_timer(ulong base)
 ulong get_timer(ulong base)
@@ -144,9 +144,9 @@ int timer_init(void)
 
 
 	/* Enable timer 0 */
 	/* Enable timer 0 */
 	writel(0x1, &panthtimers->cer);
 	writel(0x1, &panthtimers->cer);
-	/* init the gd->tbu and gd->tbl value */
-	gd->tbl = read_timer();
-	gd->tbu = 0;
+	/* init the gd->arch.tbu and gd->arch.tbl value */
+	gd->arch.tbl = read_timer();
+	gd->arch.tbu = 0;
 
 
 	return 0;
 	return 0;
 }
 }

+ 2 - 2
arch/arm/cpu/arm926ejs/spear/timer.c

@@ -38,8 +38,8 @@ static struct misc_regs *const misc_regs_p =
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp gd->tbl
-#define lastdec gd->lastinc
+#define timestamp gd->arch.tbl
+#define lastdec gd->arch.lastinc
 
 
 int timer_init(void)
 int timer_init(void)
 {
 {

+ 2 - 2
arch/arm/cpu/arm926ejs/versatile/timer.c

@@ -44,8 +44,8 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp gd->tbl
-#define lastdec gd->lastinc
+#define timestamp gd->arch.tbl
+#define lastdec gd->arch.lastinc
 
 
 #define TIMER_ENABLE	(1 << 7)
 #define TIMER_ENABLE	(1 << 7)
 #define TIMER_MODE_MSK	(1 << 6)
 #define TIMER_MODE_MSK	(1 << 6)

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

@@ -32,7 +32,7 @@ COBJS	+= cache_v7.o
 COBJS	+= cpu.o
 COBJS	+= cpu.o
 COBJS	+= syslib.o
 COBJS	+= syslib.o
 
 
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA),)
 SOBJS	+= lowlevel_init.o
 SOBJS	+= lowlevel_init.o
 endif
 endif
 
 

+ 3 - 0
arch/arm/cpu/armv7/omap-common/boot-common.c

@@ -55,6 +55,9 @@ void spl_board_init(void)
 #ifdef CONFIG_SPL_NAND_SUPPORT
 #ifdef CONFIG_SPL_NAND_SUPPORT
 	gpmc_init();
 	gpmc_init();
 #endif
 #endif
+#if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)
+	arch_misc_init();
+#endif
 }
 }
 
 
 int board_mmc_init(bd_t *bis)
 int board_mmc_init(bd_t *bis)

+ 11 - 9
arch/arm/cpu/armv7/omap-common/timer.c

@@ -56,8 +56,9 @@ int timer_init(void)
 		&timer_base->tclr);
 		&timer_base->tclr);
 
 
 	/* reset time, capture current incrementer value time */
 	/* reset time, capture current incrementer value time */
-	gd->lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-	gd->tbl = 0;		/* start "advancing" time stamp from 0 */
+	gd->arch.lastinc = readl(&timer_base->tcrr) /
+					(TIMER_CLOCK / CONFIG_SYS_HZ);
+	gd->arch.tbl = 0;	/* start "advancing" time stamp from 0 */
 
 
 	return 0;
 	return 0;
 }
 }
@@ -91,14 +92,15 @@ ulong get_timer_masked(void)
 	/* current tick value */
 	/* current tick value */
 	ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
 	ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
 
 
-	if (now >= gd->lastinc)	/* normal mode (non roll) */
+	if (now >= gd->arch.lastinc) {	/* normal mode (non roll) */
 		/* move stamp fordward with absoulte diff ticks */
 		/* move stamp fordward with absoulte diff ticks */
-		gd->tbl += (now - gd->lastinc);
-	else	/* we have rollover of incrementer */
-		gd->tbl += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ))
-			     - gd->lastinc) + now;
-	gd->lastinc = now;
-	return gd->tbl;
+		gd->arch.tbl += (now - gd->arch.lastinc);
+	} else {	/* we have rollover of incrementer */
+		gd->arch.tbl += ((TIMER_LOAD_VAL / (TIMER_CLOCK /
+				CONFIG_SYS_HZ)) - gd->arch.lastinc) + now;
+	}
+	gd->arch.lastinc = now;
+	return gd->arch.tbl;
 }
 }
 
 
 /*
 /*

+ 7 - 7
arch/arm/cpu/armv7/s5p-common/timer.c

@@ -105,8 +105,8 @@ void reset_timer_masked(void)
 	struct s5p_timer *const timer = s5p_get_base_timer();
 	struct s5p_timer *const timer = s5p_get_base_timer();
 
 
 	/* reset time */
 	/* reset time */
-	gd->lastinc = readl(&timer->tcnto4);
-	gd->tbl = 0;
+	gd->arch.lastinc = readl(&timer->tcnto4);
+	gd->arch.tbl = 0;
 }
 }
 
 
 unsigned long get_timer_masked(void)
 unsigned long get_timer_masked(void)
@@ -123,14 +123,14 @@ unsigned long get_current_tick(void)
 	unsigned long now = readl(&timer->tcnto4);
 	unsigned long now = readl(&timer->tcnto4);
 	unsigned long count_value = readl(&timer->tcntb4);
 	unsigned long count_value = readl(&timer->tcntb4);
 
 
-	if (gd->lastinc >= now)
-		gd->tbl += gd->lastinc - now;
+	if (gd->arch.lastinc >= now)
+		gd->arch.tbl += gd->arch.lastinc - now;
 	else
 	else
-		gd->tbl += gd->lastinc + count_value - now;
+		gd->arch.tbl += gd->arch.lastinc + count_value - now;
 
 
-	gd->lastinc = now;
+	gd->arch.lastinc = now;
 
 
-	return gd->tbl;
+	return gd->arch.tbl;
 }
 }
 
 
 /*
 /*

+ 8 - 7
arch/arm/cpu/armv7/socfpga/timer.c

@@ -80,16 +80,16 @@ ulong get_timer_masked(void)
 {
 {
 	/* current tick value */
 	/* current tick value */
 	ulong now = read_timer() / (CONFIG_TIMER_CLOCK_KHZ/CONFIG_SYS_HZ);
 	ulong now = read_timer() / (CONFIG_TIMER_CLOCK_KHZ/CONFIG_SYS_HZ);
-	if (gd->lastinc >= now) {
+	if (gd->arch.lastinc >= now) {
 		/* normal mode (non roll) */
 		/* normal mode (non roll) */
 		/* move stamp forward with absolute diff ticks */
 		/* move stamp forward with absolute diff ticks */
-		gd->tbl += gd->lastinc - now;
+		gd->arch.tbl += gd->arch.lastinc - now;
 	} else {
 	} else {
 		/* we have overflow of the count down timer */
 		/* we have overflow of the count down timer */
-		gd->tbl += TIMER_LOAD_VAL - gd->lastinc + now;
+		gd->arch.tbl += TIMER_LOAD_VAL - gd->arch.lastinc + now;
 	}
 	}
-	gd->lastinc = now;
-	return gd->tbl;
+	gd->arch.lastinc = now;
+	return gd->arch.tbl;
 }
 }
 
 
 /*
 /*
@@ -98,7 +98,8 @@ ulong get_timer_masked(void)
 void reset_timer(void)
 void reset_timer(void)
 {
 {
 	/* capture current decrementer value time */
 	/* capture current decrementer value time */
-	gd->lastinc = read_timer() / (CONFIG_TIMER_CLOCK_KHZ/CONFIG_SYS_HZ);
+	gd->arch.lastinc = read_timer() /
+				(CONFIG_TIMER_CLOCK_KHZ / CONFIG_SYS_HZ);
 	/* start "advancing" time stamp from 0 */
 	/* start "advancing" time stamp from 0 */
-	gd->tbl = 0;
+	gd->arch.tbl = 0;
 }
 }

+ 2 - 2
arch/arm/cpu/armv7/start.S

@@ -251,12 +251,12 @@ ENTRY(c_runtime_cpu_setup)
 /*
 /*
  * Move vector table
  * Move vector table
  */
  */
-#if !defined(CONFIG_TEGRA20)
+#if !defined(CONFIG_TEGRA)
 	/* Set vector address in CP15 VBAR register */
 	/* Set vector address in CP15 VBAR register */
 	ldr     r0, =_start
 	ldr     r0, =_start
 	add     r0, r0, r9
 	add     r0, r0, r9
 	mcr     p15, 0, r0, c12, c0, 0  @Set VBAR
 	mcr     p15, 0, r0, c12, c0, 0  @Set VBAR
-#endif /* !Tegra20 */
+#endif /* !Tegra */
 
 
 	bx	lr
 	bx	lr
 
 

+ 40 - 0
arch/arm/cpu/armv7/tegra114/Makefile

@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).o
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 19 - 0
arch/arm/cpu/armv7/tegra114/config.mk

@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+#
+CONFIG_ARCH_DEVICE_TREE := tegra114

+ 40 - 0
arch/arm/cpu/armv7/tegra30/Makefile

@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).o
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 19 - 0
arch/arm/cpu/armv7/tegra30/config.mk

@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+#
+CONFIG_ARCH_DEVICE_TREE := tegra30

+ 9 - 7
arch/arm/cpu/armv7/u8500/timer.c

@@ -100,12 +100,14 @@ ulong get_timer_masked(void)
 	/* current tick value */
 	/* current tick value */
 	ulong now = TICKS_TO_HZ(READ_TIMER());
 	ulong now = TICKS_TO_HZ(READ_TIMER());
 
 
-	if (now >= gd->lastinc)	/* normal (non rollover) */
-		gd->tbl += (now - gd->lastinc);
-	else			/* rollover */
-		gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now;
-	gd->lastinc = now;
-	return gd->tbl;
+	if (now >= gd->arch.lastinc) {	/* normal (non rollover) */
+		gd->arch.tbl += (now - gd->arch.lastinc);
+	} else {			/* rollover */
+		gd->arch.tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) -
+					gd->arch.lastinc) + now;
+	}
+	gd->arch.lastinc = now;
+	return gd->arch.tbl;
 }
 }
 
 
 /* Delay x useconds */
 /* Delay x useconds */
@@ -132,7 +134,7 @@ ulong get_timer(ulong base)
 /*
 /*
  * Emulation of Power architecture long long timebase.
  * Emulation of Power architecture long long timebase.
  *
  *
- * TODO: Support gd->tbu for real long long timebase.
+ * TODO: Support gd->arch.tbu for real long long timebase.
  */
  */
 unsigned long long get_ticks(void)
 unsigned long long get_ticks(void)
 {
 {

+ 1 - 0
arch/arm/cpu/armv7/zynq/Makefile

@@ -30,6 +30,7 @@ LIB	= $(obj)lib$(SOC).o
 
 
 COBJS-y	:= timer.o
 COBJS-y	:= timer.o
 COBJS-y	+= cpu.o
 COBJS-y	+= cpu.o
+COBJS-y	+= slcr.o
 
 
 COBJS	:= $(COBJS-y)
 COBJS	:= $(COBJS-y)
 
 

+ 27 - 1
arch/arm/cpu/armv7/zynq/cpu.c

@@ -21,11 +21,37 @@
  * MA 02111-1307 USA
  * MA 02111-1307 USA
  */
  */
 #include <common.h>
 #include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
 
 
-inline void lowlevel_init(void) {}
+void lowlevel_init(void)
+{
+	zynq_slcr_unlock();
+	/* remap DDR to zero, FILTERSTART */
+	writel(0, &scu_base->filter_start);
+
+	/* Device config APB, unlock the PCAP */
+	writel(0x757BDF0D, &devcfg_base->unlock);
+	writel(0xFFFFFFFF, &devcfg_base->rom_shadow);
+
+	/* OCM_CFG, Mask out the ROM, map ram into upper addresses */
+	writel(0x1F, &slcr_base->ocm_cfg);
+	/* FPGA_RST_CTRL, clear resets on AXI fabric ports */
+	writel(0x0, &slcr_base->fpga_rst_ctrl);
+	/* TZ_DDR_RAM, Set DDR trust zone non-secure */
+	writel(0xFFFFFFFF, &slcr_base->trust_zone);
+	/* Set urgent bits with register */
+	writel(0x0, &slcr_base->ddr_urgent_sel);
+	/* Urgent write, ports S2/S3 */
+	writel(0xC, &slcr_base->ddr_urgent);
+
+	zynq_slcr_lock();
+}
 
 
 void reset_cpu(ulong addr)
 void reset_cpu(ulong addr)
 {
 {
+	zynq_slcr_cpu_reset();
 	while (1)
 	while (1)
 		;
 		;
 }
 }

+ 63 - 0
arch/arm/cpu/armv7/zynq/slcr.c

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013 Xilinx Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <asm/arch/hardware.h>
+
+#define SLCR_LOCK_MAGIC		0x767B
+#define SLCR_UNLOCK_MAGIC	0xDF0D
+
+static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */
+
+void zynq_slcr_lock(void)
+{
+	if (!slcr_lock)
+		writel(SLCR_LOCK_MAGIC, &slcr_base->slcr_lock);
+}
+
+void zynq_slcr_unlock(void)
+{
+	if (slcr_lock)
+		writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock);
+}
+
+/* Reset the entire system */
+void zynq_slcr_cpu_reset(void)
+{
+	/*
+	 * Unlock the SLCR then reset the system.
+	 * Note that this seems to require raw i/o
+	 * functions or there's a lockup?
+	 */
+	zynq_slcr_unlock();
+
+	/*
+	 * Clear 0x0F000000 bits of reboot status register to workaround
+	 * the FSBL not loading the bitstream after soft-reboot
+	 * This is a temporary solution until we know more.
+	 */
+	clrbits_le32(&slcr_base->reboot_status, 0xF000000);
+
+	writel(1, &slcr_base->pss_rst_ctrl);
+}

+ 7 - 7
arch/arm/cpu/armv7/zynq/timer.c

@@ -83,9 +83,9 @@ int timer_init(void)
 								emask);
 								emask);
 
 
 	/* Reset time */
 	/* Reset time */
-	gd->lastinc = readl(&timer_base->counter) /
+	gd->arch.lastinc = readl(&timer_base->counter) /
 					(TIMER_TICK_HZ / CONFIG_SYS_HZ);
 					(TIMER_TICK_HZ / CONFIG_SYS_HZ);
-	gd->tbl = 0;
+	gd->arch.tbl = 0;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -100,16 +100,16 @@ ulong get_timer_masked(void)
 
 
 	now = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ);
 	now = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ);
 
 
-	if (gd->lastinc >= now) {
+	if (gd->arch.lastinc >= now) {
 		/* Normal mode */
 		/* Normal mode */
-		gd->tbl += gd->lastinc - now;
+		gd->arch.tbl += gd->arch.lastinc - now;
 	} else {
 	} else {
 		/* We have an overflow ... */
 		/* We have an overflow ... */
-		gd->tbl += gd->lastinc + TIMER_LOAD_VAL - now;
+		gd->arch.tbl += gd->arch.lastinc + TIMER_LOAD_VAL - now;
 	}
 	}
-	gd->lastinc = now;
+	gd->arch.lastinc = now;
 
 
-	return gd->tbl;
+	return gd->arch.tbl;
 }
 }
 
 
 void __udelay(unsigned long usec)
 void __udelay(unsigned long usec)

+ 6 - 6
arch/arm/cpu/ixp/timer.c

@@ -70,23 +70,23 @@ unsigned long long get_ticks(void)
 
 
 	if (readl(IXP425_OSST) & IXP425_OSST_TIMER_TS_PEND) {
 	if (readl(IXP425_OSST) & IXP425_OSST_TIMER_TS_PEND) {
 		/* rollover of timestamp timer register */
 		/* rollover of timestamp timer register */
-		gd->timestamp += (0xFFFFFFFF - gd->lastinc) + now + 1;
+		gd->arch.timestamp += (0xFFFFFFFF - gd->arch.lastinc) + now + 1;
 		writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
 		writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
 	} else {
 	} else {
 		/* move stamp forward with absolut diff ticks */
 		/* move stamp forward with absolut diff ticks */
-		gd->timestamp += (now - gd->lastinc);
+		gd->arch.timestamp += (now - gd->arch.lastinc);
 	}
 	}
-	gd->lastinc = now;
-	return gd->timestamp;
+	gd->arch.lastinc = now;
+	return gd->arch.timestamp;
 }
 }
 
 
 
 
 void reset_timer_masked(void)
 void reset_timer_masked(void)
 {
 {
 	/* capture current timestamp counter */
 	/* capture current timestamp counter */
-	gd->lastinc = readl(IXP425_OSTS_B);
+	gd->arch.lastinc = readl(IXP425_OSTS_B);
 	/* start "advancing" time stamp from 0 */
 	/* start "advancing" time stamp from 0 */
-	gd->timestamp = 0;
+	gd->arch.timestamp = 0;
 }
 }
 
 
 ulong get_timer_masked(void)
 ulong get_timer_masked(void)

+ 2 - 2
arch/arm/cpu/pxa/timer.c

@@ -31,8 +31,8 @@ DECLARE_GLOBAL_DATA_PTR;
 
 
 #define	TIMER_LOAD_VAL	0xffffffff
 #define	TIMER_LOAD_VAL	0xffffffff
 
 
-#define	timestamp	(gd->tbl)
-#define	lastinc		(gd->lastinc)
+#define	timestamp	(gd->arch.tbl)
+#define	lastinc		(gd->arch.lastinc)
 
 
 #if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS)
 #if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS)
 #define	TIMER_FREQ_HZ	3250000
 #define	TIMER_FREQ_HZ	3250000

+ 1 - 1
arch/arm/cpu/tegra-common/Makefile

@@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)libcputegra-common.o
 LIB	= $(obj)libcputegra-common.o
 
 
 SOBJS += lowlevel_init.o
 SOBJS += lowlevel_init.o
-COBJS-y	+= ap.o board.o sys_info.o timer.o
+COBJS-y	+= ap.o board.o sys_info.o timer.o clock.o
 
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))

+ 20 - 3
arch/arm/cpu/tegra-common/ap.c

@@ -20,13 +20,18 @@
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 * MA 02111-1307 USA
 */
 */
+
+/* Tegra AP (Application Processor) code */
+
 #include <common.h>
 #include <common.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/arch/gp_padctrl.h>
 #include <asm/arch/gp_padctrl.h>
 #include <asm/arch-tegra/ap.h>
 #include <asm/arch-tegra/ap.h>
+#include <asm/arch-tegra/clock.h>
 #include <asm/arch-tegra/fuse.h>
 #include <asm/arch-tegra/fuse.h>
 #include <asm/arch-tegra/pmc.h>
 #include <asm/arch-tegra/pmc.h>
 #include <asm/arch-tegra/scu.h>
 #include <asm/arch-tegra/scu.h>
+#include <asm/arch-tegra/tegra.h>
 #include <asm/arch-tegra/warmboot.h>
 #include <asm/arch-tegra/warmboot.h>
 
 
 int tegra_get_chip_type(void)
 int tegra_get_chip_type(void)
@@ -38,7 +43,7 @@ int tegra_get_chip_type(void)
 	/*
 	/*
 	 * This is undocumented, Chip ID is bits 15:8 of the register
 	 * This is undocumented, Chip ID is bits 15:8 of the register
 	 * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for
 	 * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for
-	 * Tegra30
+	 * Tegra30, and 0x35 for T114.
 	 */
 	 */
 	gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
 	gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
 	rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;
 	rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;
@@ -58,6 +63,18 @@ int tegra_get_chip_type(void)
 			return TEGRA_SOC_T25;
 			return TEGRA_SOC_T25;
 		}
 		}
 		break;
 		break;
+	case CHIPID_TEGRA30:
+		switch (tegra_sku_id) {
+		case SKU_ID_T30:
+			return TEGRA_SOC_T30;
+		}
+		break;
+	case CHIPID_TEGRA114:
+		switch (tegra_sku_id) {
+		case SKU_ID_T114_ENG:
+			return TEGRA_SOC_T114;
+		}
+		break;
 	}
 	}
 	/* unknown sku id */
 	/* unknown sku id */
 	return TEGRA_SOC_UNKNOWN;
 	return TEGRA_SOC_UNKNOWN;
@@ -93,7 +110,7 @@ static u32 get_odmdata(void)
 
 
 	u32 bct_start, odmdata;
 	u32 bct_start, odmdata;
 
 
-	bct_start = readl(AP20_BASE_PA_SRAM + NVBOOTINFOTABLE_BCTPTR);
+	bct_start = readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BCTPTR);
 	odmdata = readl(bct_start + BCT_ODMDATA_OFFSET);
 	odmdata = readl(bct_start + BCT_ODMDATA_OFFSET);
 
 
 	return odmdata;
 	return odmdata;
@@ -127,5 +144,5 @@ void s_init(void)
 		"orr	r0, r0, #0x41\n"
 		"orr	r0, r0, #0x41\n"
 		"mcr	p15, 0, r0, c1, c0, 1\n");
 		"mcr	p15, 0, r0, c1, c0, 1\n");
 
 
-	/* FIXME: should have ap20's L2 disabled too? */
+	/* FIXME: should have SoC's L2 disabled too? */
 }
 }

+ 51 - 7
arch/arm/cpu/tegra-common/board.c

@@ -37,8 +37,10 @@ enum {
 	/* UARTs which we can enable */
 	/* UARTs which we can enable */
 	UARTA	= 1 << 0,
 	UARTA	= 1 << 0,
 	UARTB	= 1 << 1,
 	UARTB	= 1 << 1,
+	UARTC	= 1 << 2,
 	UARTD	= 1 << 3,
 	UARTD	= 1 << 3,
-	UART_COUNT = 4,
+	UARTE	= 1 << 4,
+	UART_COUNT = 5,
 };
 };
 
 
 /*
 /*
@@ -54,16 +56,37 @@ unsigned int query_sdram_size(void)
 	reg = readl(&pmc->pmc_scratch20);
 	reg = readl(&pmc->pmc_scratch20);
 	debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg);
 	debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg);
 
 
-	/* bits 31:28 in OdmData are used for RAM size  */
+#if defined(CONFIG_TEGRA20)
+	/* bits 30:28 in OdmData are used for RAM size on T20  */
+	reg &= 0x70000000;
+
 	switch ((reg) >> 28) {
 	switch ((reg) >> 28) {
 	case 1:
 	case 1:
 		return 0x10000000;	/* 256 MB */
 		return 0x10000000;	/* 256 MB */
+	case 0:
 	case 2:
 	case 2:
 	default:
 	default:
 		return 0x20000000;	/* 512 MB */
 		return 0x20000000;	/* 512 MB */
 	case 3:
 	case 3:
 		return 0x40000000;	/* 1GB */
 		return 0x40000000;	/* 1GB */
 	}
 	}
+#else	/* Tegra30/Tegra114 */
+	/* bits 31:28 in OdmData are used for RAM size on T30  */
+	switch ((reg) >> 28) {
+	case 0:
+	case 1:
+	default:
+		return 0x10000000;	/* 256 MB */
+	case 2:
+		return 0x20000000;	/* 512 MB */
+	case 3:
+		return 0x30000000;	/* 768 MB */
+	case 4:
+		return 0x40000000;	/* 1GB */
+	case 8:
+		return 0x7ff00000;	/* 2GB - 1MB */
+	}
+#endif
 }
 }
 
 
 int dram_init(void)
 int dram_init(void)
@@ -82,19 +105,33 @@ int checkboard(void)
 #endif	/* CONFIG_DISPLAY_BOARDINFO */
 #endif	/* CONFIG_DISPLAY_BOARDINFO */
 
 
 static int uart_configs[] = {
 static int uart_configs[] = {
-#if defined(CONFIG_TEGRA_UARTA_UAA_UAB)
+#if defined(CONFIG_TEGRA20)
+ #if defined(CONFIG_TEGRA_UARTA_UAA_UAB)
 	FUNCMUX_UART1_UAA_UAB,
 	FUNCMUX_UART1_UAA_UAB,
-#elif defined(CONFIG_TEGRA_UARTA_GPU)
+ #elif defined(CONFIG_TEGRA_UARTA_GPU)
 	FUNCMUX_UART1_GPU,
 	FUNCMUX_UART1_GPU,
-#elif defined(CONFIG_TEGRA_UARTA_SDIO1)
+ #elif defined(CONFIG_TEGRA_UARTA_SDIO1)
 	FUNCMUX_UART1_SDIO1,
 	FUNCMUX_UART1_SDIO1,
-#else
+ #else
 	FUNCMUX_UART1_IRRX_IRTX,
 	FUNCMUX_UART1_IRRX_IRTX,
 #endif
 #endif
-	FUNCMUX_UART2_IRDA,
+	FUNCMUX_UART2_UAD,
 	-1,
 	-1,
 	FUNCMUX_UART4_GMC,
 	FUNCMUX_UART4_GMC,
 	-1,
 	-1,
+#elif defined(CONFIG_TEGRA30)
+	FUNCMUX_UART1_ULPI,	/* UARTA */
+	-1,
+	-1,
+	-1,
+	-1,
+#else	/* Tegra114 */
+	-1,
+	-1,
+	-1,
+	FUNCMUX_UART4_GMI,	/* UARTD */
+	-1,
+#endif
 };
 };
 
 
 /**
 /**
@@ -109,6 +146,7 @@ static void setup_uarts(int uart_ids)
 		PERIPH_ID_UART2,
 		PERIPH_ID_UART2,
 		PERIPH_ID_UART3,
 		PERIPH_ID_UART3,
 		PERIPH_ID_UART4,
 		PERIPH_ID_UART4,
+		PERIPH_ID_UART5,
 	};
 	};
 	size_t i;
 	size_t i;
 
 
@@ -132,8 +170,14 @@ void board_init_uart_f(void)
 #ifdef CONFIG_TEGRA_ENABLE_UARTB
 #ifdef CONFIG_TEGRA_ENABLE_UARTB
 	uart_ids |= UARTB;
 	uart_ids |= UARTB;
 #endif
 #endif
+#ifdef CONFIG_TEGRA_ENABLE_UARTC
+	uart_ids |= UARTC;
+#endif
 #ifdef CONFIG_TEGRA_ENABLE_UARTD
 #ifdef CONFIG_TEGRA_ENABLE_UARTD
 	uart_ids |= UARTD;
 	uart_ids |= UARTD;
+#endif
+#ifdef CONFIG_TEGRA_ENABLE_UARTE
+	uart_ids |= UARTE;
 #endif
 #endif
 	setup_uarts(uart_ids);
 	setup_uarts(uart_ids);
 }
 }

+ 560 - 0
arch/arm/cpu/tegra-common/clock.c

@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra SoC common clock control functions */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/tegra.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/timer.h>
+#include <div64.h>
+#include <fdtdec.h>
+
+/*
+ * This is our record of the current clock rate of each clock. We don't
+ * fill all of these in since we are only really interested in clocks which
+ * we use as parents.
+ */
+static unsigned pll_rate[CLOCK_ID_COUNT];
+
+/*
+ * The oscillator frequency is fixed to one of four set values. Based on this
+ * the other clocks are set up appropriately.
+ */
+static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = {
+	13000000,
+	19200000,
+	12000000,
+	26000000,
+};
+
+/* return 1 if a peripheral ID is in range */
+#define clock_type_id_isvalid(id) ((id) >= 0 && \
+		(id) < CLOCK_TYPE_COUNT)
+
+char pllp_valid = 1;	/* PLLP is set up correctly */
+
+/* return 1 if a periphc_internal_id is in range */
+#define periphc_internal_id_isvalid(id) ((id) >= 0 && \
+		(id) < PERIPHC_COUNT)
+
+/* number of clock outputs of a PLL */
+static const u8 pll_num_clkouts[] = {
+	1,	/* PLLC */
+	1,	/* PLLM */
+	4,	/* PLLP */
+	1,	/* PLLA */
+	0,	/* PLLU */
+	0,	/* PLLD */
+};
+
+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)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+
+	assert(clock_id_is_pll(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_is_pll(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)
+{
+	struct clk_pll *pll = get_pll(clkid);
+	u32 data;
+
+	/*
+	 * We cheat by treating all PLL (except PLLU) in the same fashion.
+	 * This works only because:
+	 * - same fields are always mapped at same offsets, except DCCON
+	 * - DCCON is always 0, doesn't conflict
+	 * - M,N, P of PLLP values are ignored for PLLP
+	 */
+	data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT);
+	writel(data, &pll->pll_misc);
+
+	data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) |
+			(0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT);
+
+	if (clkid == CLOCK_ID_USB)
+		data |= divp << PLLU_VCO_FREQ_SHIFT;
+	else
+		data |= divp << PLL_DIVP_SHIFT;
+	writel(data, &pll->pll_base);
+
+	/* calculate the stable time */
+	return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US;
+}
+
+void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source,
+			unsigned divisor)
+{
+	u32 *reg = get_periph_source_reg(periph_id);
+	u32 value;
+
+	value = readl(reg);
+
+	value &= ~OUT_CLK_SOURCE_MASK;
+	value |= source << OUT_CLK_SOURCE_SHIFT;
+
+	value &= ~OUT_CLK_DIVISOR_MASK;
+	value |= divisor << OUT_CLK_DIVISOR_SHIFT;
+
+	writel(value, reg);
+}
+
+void clock_ll_set_source(enum periph_id periph_id, unsigned source)
+{
+	u32 *reg = get_periph_source_reg(periph_id);
+
+	clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
+			source << OUT_CLK_SOURCE_SHIFT);
+}
+
+/**
+ * Given the parent's rate and the required rate for the children, this works
+ * out the peripheral clock divider to use, in 7.1 binary format.
+ *
+ * @param divider_bits	number of divider bits (8 or 16)
+ * @param parent_rate	clock rate of parent clock in Hz
+ * @param rate		required clock rate for this clock
+ * @return divider which should be used
+ */
+static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate,
+			   unsigned long rate)
+{
+	u64 divider = parent_rate * 2;
+	unsigned max_divider = 1 << divider_bits;
+
+	divider += rate - 1;
+	do_div(divider, rate);
+
+	if ((s64)divider - 2 < 0)
+		return 0;
+
+	if ((s64)divider - 2 >= max_divider)
+		return -1;
+
+	return divider - 2;
+}
+
+int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate)
+{
+	struct clk_pll *pll = get_pll(clkid);
+	int data = 0, div = 0, offset = 0;
+
+	if (!clock_id_is_pll(clkid))
+		return -1;
+
+	if (pllout + 1 > pll_num_clkouts[clkid])
+		return -1;
+
+	div = clk_get_divider(8, pll_rate[clkid], rate);
+
+	if (div < 0)
+		return -1;
+
+	/* out2 and out4 are in the high part of the register */
+	if (pllout == PLL_OUT2 || pllout == PLL_OUT4)
+		offset = 16;
+
+	data = (div << PLL_OUT_RATIO_SHIFT) |
+			PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN;
+	clrsetbits_le32(&pll->pll_out[pllout >> 1],
+			PLL_OUT_RATIO_MASK << offset, data << offset);
+
+	return 0;
+}
+
+/**
+ * Given the parent's rate and the divider in 7.1 format, this works out the
+ * resulting peripheral clock rate.
+ *
+ * @param parent_rate	clock rate of parent clock in Hz
+ * @param divider which should be used in 7.1 format
+ * @return effective clock rate of peripheral
+ */
+static unsigned long get_rate_from_divider(unsigned long parent_rate,
+					   int divider)
+{
+	u64 rate;
+
+	rate = (u64)parent_rate * 2;
+	do_div(rate, divider + 2);
+	return rate;
+}
+
+unsigned long clock_get_periph_rate(enum periph_id periph_id,
+		enum clock_id parent)
+{
+	u32 *reg = get_periph_source_reg(periph_id);
+
+	return get_rate_from_divider(pll_rate[parent],
+		(readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT);
+}
+
+/**
+ * Find the best available 7.1 format divisor given a parent clock rate and
+ * required child clock rate. This function assumes that a second-stage
+ * divisor is available which can divide by powers of 2 from 1 to 256.
+ *
+ * @param divider_bits	number of divider bits (8 or 16)
+ * @param parent_rate	clock rate of parent clock in Hz
+ * @param rate		required clock rate for this clock
+ * @param extra_div	value for the second-stage divisor (not set if this
+ *			function returns -1.
+ * @return divider which should be used, or -1 if nothing is valid
+ *
+ */
+static int find_best_divider(unsigned divider_bits, unsigned long parent_rate,
+				unsigned long rate, int *extra_div)
+{
+	int shift;
+	int best_divider = -1;
+	int best_error = rate;
+
+	/* try dividers from 1 to 256 and find closest match */
+	for (shift = 0; shift <= 8 && best_error > 0; shift++) {
+		unsigned divided_parent = parent_rate >> shift;
+		int divider = clk_get_divider(divider_bits, divided_parent,
+						rate);
+		unsigned effective_rate = get_rate_from_divider(divided_parent,
+						divider);
+		int error = rate - effective_rate;
+
+		/* Given a valid divider, look for the lowest error */
+		if (divider != -1 && error < best_error) {
+			best_error = error;
+			*extra_div = 1 << shift;
+			best_divider = divider;
+		}
+	}
+
+	/* return what we found - *extra_div will already be set */
+	return best_divider;
+}
+
+/**
+ * Adjust peripheral PLL to use the given divider and source.
+ *
+ * @param periph_id	peripheral to adjust
+ * @param source	Source number (0-3 or 0-7)
+ * @param mux_bits	Number of mux bits (2 or 4)
+ * @param divider	Required divider in 7.1 or 15.1 format
+ * @return 0 if ok, -1 on error (requesting a parent clock which is not valid
+ *		for this peripheral)
+ */
+static int adjust_periph_pll(enum periph_id periph_id, int source,
+				int mux_bits, unsigned divider)
+{
+	u32 *reg = get_periph_source_reg(periph_id);
+
+	clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK,
+			divider << OUT_CLK_DIVISOR_SHIFT);
+	udelay(1);
+
+	/* work out the source clock and set it */
+	if (source < 0)
+		return -1;
+	if (mux_bits == 4) {
+		clrsetbits_le32(reg, OUT_CLK_SOURCE4_MASK,
+			source << OUT_CLK_SOURCE4_SHIFT);
+	} else {
+		clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
+			source << OUT_CLK_SOURCE_SHIFT);
+	}
+	udelay(2);
+	return 0;
+}
+
+unsigned clock_adjust_periph_pll_div(enum periph_id periph_id,
+		enum clock_id parent, unsigned rate, int *extra_div)
+{
+	unsigned effective_rate;
+	int mux_bits, divider_bits, source;
+	int divider;
+
+	/* work out the source clock and set it */
+	source = get_periph_clock_source(periph_id, parent, &mux_bits,
+					 &divider_bits);
+
+	if (extra_div)
+		divider = find_best_divider(divider_bits, pll_rate[parent],
+						rate, extra_div);
+	else
+		divider = clk_get_divider(divider_bits, pll_rate[parent],
+					  rate);
+	assert(divider >= 0);
+	if (adjust_periph_pll(periph_id, source, mux_bits, divider))
+		return -1U;
+	debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate,
+		get_periph_source_reg(periph_id),
+		readl(get_periph_source_reg(periph_id)));
+
+	/* Check what we ended up with. This shouldn't matter though */
+	effective_rate = clock_get_periph_rate(periph_id, parent);
+	if (extra_div)
+		effective_rate /= *extra_div;
+	if (rate != effective_rate)
+		debug("Requested clock rate %u not honored (got %u)\n",
+			rate, effective_rate);
+	return effective_rate;
+}
+
+unsigned clock_start_periph_pll(enum periph_id periph_id,
+		enum clock_id parent, unsigned rate)
+{
+	unsigned effective_rate;
+
+	reset_set_enable(periph_id, 1);
+	clock_enable(periph_id);
+
+	effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate,
+						 NULL);
+
+	reset_set_enable(periph_id, 0);
+	return effective_rate;
+}
+
+void clock_enable(enum periph_id clkid)
+{
+	clock_set_enable(clkid, 1);
+}
+
+void clock_disable(enum periph_id clkid)
+{
+	clock_set_enable(clkid, 0);
+}
+
+void reset_periph(enum periph_id periph_id, int us_delay)
+{
+	/* Put peripheral into reset */
+	reset_set_enable(periph_id, 1);
+	udelay(us_delay);
+
+	/* Remove reset */
+	reset_set_enable(periph_id, 0);
+
+	udelay(us_delay);
+}
+
+void reset_cmplx_set_enable(int cpu, int which, int reset)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 mask;
+
+	/* Form the mask, which depends on the cpu chosen (2 or 4) */
+	assert(cpu >= 0 && cpu < MAX_NUM_CPU);
+	mask = which << cpu;
+
+	/* either enable or disable those reset for that CPU */
+	if (reset)
+		writel(mask, &clkrst->crc_cpu_cmplx_set);
+	else
+		writel(mask, &clkrst->crc_cpu_cmplx_clr);
+}
+
+unsigned clock_get_rate(enum clock_id clkid)
+{
+	struct clk_pll *pll;
+	u32 base;
+	u32 divm;
+	u64 parent_rate;
+	u64 rate;
+
+	parent_rate = osc_freq[clock_get_osc_freq()];
+	if (clkid == CLOCK_ID_OSC)
+		return parent_rate;
+
+	pll = get_pll(clkid);
+	base = readl(&pll->pll_base);
+
+	/* Oh for bf_unpack()... */
+	rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT);
+	divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
+	if (clkid == CLOCK_ID_USB)
+		divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT;
+	else
+		divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
+	do_div(rate, divm);
+	return rate;
+}
+
+/**
+ * Set the output frequency you want for each PLL clock.
+ * PLL output frequencies are programmed by setting their N, M and P values.
+ * The governing equations are:
+ *     VCO = (Fi / m) * n, Fo = VCO / (2^p)
+ *     where Fo is the output frequency from the PLL.
+ * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi)
+ *     216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1
+ * Please see Tegra TRM section 5.3 to get the detail for PLL Programming
+ *
+ * @param n PLL feedback divider(DIVN)
+ * @param m PLL input divider(DIVN)
+ * @param p post divider(DIVP)
+ * @param cpcon base PLL charge pump(CPCON)
+ * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
+ *		be overriden), 1 if PLL is already correct
+ */
+int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
+{
+	u32 base_reg;
+	u32 misc_reg;
+	struct clk_pll *pll;
+
+	pll = get_pll(clkid);
+
+	base_reg = readl(&pll->pll_base);
+
+	/* Set BYPASS, m, n and p to PLL_BASE */
+	base_reg &= ~PLL_DIVM_MASK;
+	base_reg |= m << PLL_DIVM_SHIFT;
+
+	base_reg &= ~PLL_DIVN_MASK;
+	base_reg |= n << PLL_DIVN_SHIFT;
+
+	base_reg &= ~PLL_DIVP_MASK;
+	base_reg |= p << PLL_DIVP_SHIFT;
+
+	if (clkid == CLOCK_ID_PERIPH) {
+		/*
+		 * If the PLL is already set up, check that it is correct
+		 * and record this info for clock_verify() to check.
+		 */
+		if (base_reg & PLL_BASE_OVRRIDE_MASK) {
+			base_reg |= PLL_ENABLE_MASK;
+			if (base_reg != readl(&pll->pll_base))
+				pllp_valid = 0;
+			return pllp_valid ? 1 : -1;
+		}
+		base_reg |= PLL_BASE_OVRRIDE_MASK;
+	}
+
+	base_reg |= PLL_BYPASS_MASK;
+	writel(base_reg, &pll->pll_base);
+
+	/* Set cpcon to PLL_MISC */
+	misc_reg = readl(&pll->pll_misc);
+	misc_reg &= ~PLL_CPCON_MASK;
+	misc_reg |= cpcon << PLL_CPCON_SHIFT;
+	writel(misc_reg, &pll->pll_misc);
+
+	/* Enable PLL */
+	base_reg |= PLL_ENABLE_MASK;
+	writel(base_reg, &pll->pll_base);
+
+	/* Disable BYPASS */
+	base_reg &= ~PLL_BYPASS_MASK;
+	writel(base_reg, &pll->pll_base);
+
+	return 0;
+}
+
+void clock_ll_start_uart(enum periph_id periph_id)
+{
+	/* Assert UART reset and enable clock */
+	reset_set_enable(periph_id, 1);
+	clock_enable(periph_id);
+	clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */
+
+	/* wait for 2us */
+	udelay(2);
+
+	/* De-assert reset to UART */
+	reset_set_enable(periph_id, 0);
+}
+
+#ifdef CONFIG_OF_CONTROL
+int clock_decode_periph_id(const void *blob, int node)
+{
+	enum periph_id id;
+	u32 cell[2];
+	int err;
+
+	err = fdtdec_get_int_array(blob, node, "clocks", cell,
+				   ARRAY_SIZE(cell));
+	if (err)
+		return -1;
+	id = clk_id_to_periph_id(cell[1]);
+	assert(clock_periph_id_isvalid(id));
+	return id;
+}
+#endif /* CONFIG_OF_CONTROL */
+
+int clock_verify(void)
+{
+	struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH);
+	u32 reg = readl(&pll->pll_base);
+
+	if (!pllp_valid) {
+		printf("Warning: PLLP %x is not correct\n", reg);
+		return -1;
+	}
+	debug("PLLP %x is correct\n", reg);
+	return 0;
+}
+
+void clock_init(void)
+{
+	pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY);
+	pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH);
+	pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL);
+	pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC);
+	pll_rate[CLOCK_ID_SFROM32KHZ] = 32768;
+	pll_rate[CLOCK_ID_XCPU] = clock_get_rate(CLOCK_ID_XCPU);
+	debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]);
+	debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]);
+	debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]);
+	debug("PLLC = %d\n", pll_rate[CLOCK_ID_CGENERAL]);
+	debug("PLLX = %d\n", pll_rate[CLOCK_ID_XCPU]);
+}

+ 15 - 1
arch/arm/cpu/tegra-common/sys_info.c

@@ -22,12 +22,26 @@
  */
  */
 
 
 #include <common.h>
 #include <common.h>
+#include <linux/ctype.h>
 
 
 #ifdef CONFIG_DISPLAY_CPUINFO
 #ifdef CONFIG_DISPLAY_CPUINFO
+void upstring(char *s)
+{
+	while (*s) {
+		*s = toupper(*s);
+		s++;
+	}
+}
+
 /* Print CPU information */
 /* Print CPU information */
 int print_cpuinfo(void)
 int print_cpuinfo(void)
 {
 {
-	puts("TEGRA20\n");
+	char soc_name[10];
+
+	strncpy(soc_name, CONFIG_SYS_SOC, 10);
+	upstring(soc_name);
+	puts(soc_name);
+	puts("\n");
 
 
 	/* TBD: Add printf of major/minor rev info, stepping, etc. */
 	/* TBD: Add printf of major/minor rev info, stepping, etc. */
 	return 0;
 	return 0;

+ 6 - 6
arch/arm/cpu/tegra-common/timer.c

@@ -75,14 +75,14 @@ ulong get_timer_masked(void)
 	/* current tick value */
 	/* current tick value */
 	now = timer_get_us() / (TIMER_CLK / CONFIG_SYS_HZ);
 	now = timer_get_us() / (TIMER_CLK / CONFIG_SYS_HZ);
 
 
-	if (now >= gd->lastinc)	/* normal mode (non roll) */
+	if (now >= gd->arch.lastinc)	/* normal mode (non roll) */
 		/* move stamp forward with absolute diff ticks */
 		/* move stamp forward with absolute diff ticks */
-		gd->tbl += (now - gd->lastinc);
+		gd->arch.tbl += (now - gd->arch.lastinc);
 	else	/* we have rollover of incrementer */
 	else	/* we have rollover of incrementer */
-		gd->tbl += ((TIMER_LOAD_VAL / (TIMER_CLK / CONFIG_SYS_HZ))
-				- gd->lastinc) + now;
-	gd->lastinc = now;
-	return gd->tbl;
+		gd->arch.tbl += ((TIMER_LOAD_VAL / (TIMER_CLK / CONFIG_SYS_HZ))
+				- gd->arch.lastinc) + now;
+	gd->arch.lastinc = now;
+	return gd->arch.tbl;
 }
 }
 
 
 /*
 /*

+ 41 - 0
arch/arm/cpu/tegra114-common/Makefile

@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+#
+# (C) Copyright 2000-2008
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC)-common.o
+
+COBJS-y	+= clock.o funcmux.o pinmux.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 655 - 0
arch/arm/cpu/tegra114-common/clock.c

@@ -0,0 +1,655 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra114 Clock control functions */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/tegra.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/timer.h>
+#include <div64.h>
+#include <fdtdec.h>
+
+/*
+ * Clock types that we can use as a source. The Tegra114 has muxes for the
+ * peripheral clocks, and in most cases there are four options for the clock
+ * source. This gives us a clock 'type' and exploits what commonality exists
+ * in the device.
+ *
+ * Letters are obvious, except for T which means CLK_M, and S which means the
+ * clock derived from 32KHz. Beware that CLK_M (also called OSC in the
+ * datasheet) and PLL_M are different things. The former is the basic
+ * clock supplied to the SOC from an external oscillator. The latter is the
+ * memory clock PLL.
+ *
+ * See definitions in clock_id in the header file.
+ */
+enum clock_type_id {
+	CLOCK_TYPE_AXPT,	/* PLL_A, PLL_X, PLL_P, CLK_M */
+	CLOCK_TYPE_MCPA,	/* and so on */
+	CLOCK_TYPE_MCPT,
+	CLOCK_TYPE_PCM,
+	CLOCK_TYPE_PCMT,
+	CLOCK_TYPE_PCMT16,
+	CLOCK_TYPE_PDCT,
+	CLOCK_TYPE_ACPT,
+	CLOCK_TYPE_ASPTE,
+	CLOCK_TYPE_PMDACD2T,
+	CLOCK_TYPE_PCST,
+
+	CLOCK_TYPE_COUNT,
+	CLOCK_TYPE_NONE = -1,   /* invalid clock type */
+};
+
+enum {
+	CLOCK_MAX_MUX   = 8     /* number of source options for each clock */
+};
+
+enum {
+	MASK_BITS_31_30	= 2,	/* num of bits used to specify clock source */
+	MASK_BITS_31_29,
+	MASK_BITS_29_28,
+};
+
+/*
+ * Clock source mux for each clock type. This just converts our enum into
+ * a list of mux sources for use by the code.
+ *
+ * Note:
+ *  The extra column in each clock source array is used to store the mask
+ *  bits in its register for the source.
+ */
+#define CLK(x) CLOCK_ID_ ## x
+static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = {
+	{ CLK(AUDIO),	CLK(XCPU),	CLK(PERIPH),	CLK(OSC),
+		CLK(NONE),	CLK(NONE),	CLK(NONE),	CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(MEMORY),	CLK(CGENERAL),	CLK(PERIPH),	CLK(AUDIO),
+		CLK(NONE),	CLK(NONE),	CLK(NONE),	CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(MEMORY),	CLK(CGENERAL),	CLK(PERIPH),	CLK(OSC),
+		CLK(NONE),	CLK(NONE),	CLK(NONE),	CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(NONE),
+		CLK(NONE),	CLK(NONE),	CLK(NONE),	CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(OSC),
+		CLK(NONE),	CLK(NONE),	CLK(NONE),	CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(OSC),
+		CLK(NONE),	CLK(NONE),	CLK(NONE),	CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(PERIPH),	CLK(DISPLAY),	CLK(CGENERAL),	CLK(OSC),
+		CLK(NONE),	CLK(NONE),	CLK(NONE),	CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(AUDIO),	CLK(CGENERAL),	CLK(PERIPH),	CLK(OSC),
+		CLK(NONE),	CLK(NONE),	CLK(NONE),	CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(AUDIO),	CLK(SFROM32KHZ),	CLK(PERIPH),	CLK(OSC),
+		CLK(EPCI),	CLK(NONE),	CLK(NONE),	CLK(NONE),
+		MASK_BITS_31_29},
+	{ CLK(PERIPH),	CLK(MEMORY),	CLK(DISPLAY),	CLK(AUDIO),
+		CLK(CGENERAL),	CLK(DISPLAY2),	CLK(OSC),	CLK(NONE),
+		MASK_BITS_31_29},
+	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(SFROM32KHZ),	CLK(OSC),
+		CLK(NONE),	CLK(NONE),	CLK(NONE),	CLK(NONE),
+		MASK_BITS_29_28}
+};
+
+/*
+ * Clock type for each peripheral clock source. We put the name in each
+ * record just so it is easy to match things up
+ */
+#define TYPE(name, type) type
+static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
+	/* 0x00 */
+	TYPE(PERIPHC_I2S1,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_I2S2,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_SPDIF_OUT,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_SPDIF_IN,	CLOCK_TYPE_PCM),
+	TYPE(PERIPHC_PWM,	CLOCK_TYPE_PCST),  /* only PWM uses b29:28 */
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SBC2,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SBC3,	CLOCK_TYPE_PCMT),
+
+	/* 0x08 */
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_I2C1,	CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_I2C5,	CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SBC1,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_DISP1,	CLOCK_TYPE_PMDACD2T),
+	TYPE(PERIPHC_DISP2,	CLOCK_TYPE_PMDACD2T),
+
+	/* 0x10 */
+	TYPE(PERIPHC_CVE,	CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_VI,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SDMMC1,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SDMMC2,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_G3D,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_G2D,	CLOCK_TYPE_MCPA),
+
+	/* 0x18 */
+	TYPE(PERIPHC_NDFLASH,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SDMMC4,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_VFIR,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_EPP,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_MPE,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_MIPI,	CLOCK_TYPE_PCMT),	/* MIPI base-band HSI */
+	TYPE(PERIPHC_UART1,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_UART2,	CLOCK_TYPE_PCMT),
+
+	/* 0x20 */
+	TYPE(PERIPHC_HOST1X,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_TVO,	CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_HDMI,	CLOCK_TYPE_PMDACD2T),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_TVDAC,	CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_I2C2,	CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_EMC,	CLOCK_TYPE_MCPT),
+
+	/* 0x28 */
+	TYPE(PERIPHC_UART3,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_VI,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SBC4,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_I2C3,	CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_SDMMC3,	CLOCK_TYPE_PCMT),
+
+	/* 0x30 */
+	TYPE(PERIPHC_UART4,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_UART5,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_VDE,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_OWR,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_NOR,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_CSITE,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_I2S0,      CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+
+	/* 0x38h */  /* Jumps to reg offset 0x3B0h */
+	TYPE(PERIPHC_G3D2,      CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_MSELECT,   CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_TSENSOR,   CLOCK_TYPE_PCST),	/* s/b PCTS */
+	TYPE(PERIPHC_I2S3,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_I2S4,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_I2C4,	CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_SBC5,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SBC6,	CLOCK_TYPE_PCMT),
+
+	/* 0x40 */
+	TYPE(PERIPHC_AUDIO,	CLOCK_TYPE_ACPT),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_DAM0,	CLOCK_TYPE_ACPT),
+	TYPE(PERIPHC_DAM1,	CLOCK_TYPE_ACPT),
+	TYPE(PERIPHC_DAM2,	CLOCK_TYPE_ACPT),
+	TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_ACTMON,	CLOCK_TYPE_PCST),	/* MASK 31:30 */
+	TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE),
+
+	/* 0x48 */
+	TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE),
+	TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE),
+	TYPE(PERIPHC_NANDSPEED,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_I2CSLOW,	CLOCK_TYPE_PCST),	/* MASK 31:30 */
+	TYPE(PERIPHC_SYS,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SPEEDO,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+
+	/* 0x50 */
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SATAOOB,	CLOCK_TYPE_PCMT),	/* offset 0x420h */
+	TYPE(PERIPHC_SATA,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_HDA,	CLOCK_TYPE_PCMT),
+};
+
+/*
+ * This array translates a periph_id to a periphc_internal_id
+ *
+ * Not present/matched up:
+ *	uint vi_sensor;	 _VI_SENSOR_0,		0x1A8
+ *	SPDIF - which is both 0x08 and 0x0c
+ *
+ */
+#define NONE(name) (-1)
+#define OFFSET(name, value) PERIPHC_ ## name
+static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
+	/* Low word: 31:0 */
+	NONE(CPU),
+	NONE(COP),
+	NONE(TRIGSYS),
+	NONE(RESERVED3),
+	NONE(RTC),
+	NONE(TMR),
+	PERIPHC_UART1,
+	PERIPHC_UART2,	/* and vfir 0x68 */
+
+	/* 8 */
+	NONE(GPIO),
+	PERIPHC_SDMMC2,
+	NONE(SPDIF),		/* 0x08 and 0x0c, unclear which to use */
+	PERIPHC_I2S1,
+	PERIPHC_I2C1,
+	PERIPHC_NDFLASH,
+	PERIPHC_SDMMC1,
+	PERIPHC_SDMMC4,
+
+	/* 16 */
+	NONE(RESERVED16),
+	PERIPHC_PWM,
+	PERIPHC_I2S2,
+	PERIPHC_EPP,
+	PERIPHC_VI,
+	PERIPHC_G2D,
+	NONE(USBD),
+	NONE(ISP),
+
+	/* 24 */
+	PERIPHC_G3D,
+	NONE(RESERVED25),
+	PERIPHC_DISP2,
+	PERIPHC_DISP1,
+	PERIPHC_HOST1X,
+	NONE(VCP),
+	PERIPHC_I2S0,
+	NONE(CACHE2),
+
+	/* Middle word: 63:32 */
+	NONE(MEM),
+	NONE(AHBDMA),
+	NONE(APBDMA),
+	NONE(RESERVED35),
+	NONE(RESERVED36),
+	NONE(STAT_MON),
+	NONE(RESERVED38),
+	NONE(RESERVED39),
+
+	/* 40 */
+	NONE(KFUSE),
+	NONE(SBC1),	/* SBC1, 0x34, is this SPI1? */
+	PERIPHC_NOR,
+	NONE(RESERVED43),
+	PERIPHC_SBC2,
+	NONE(RESERVED45),
+	PERIPHC_SBC3,
+	PERIPHC_I2C5,
+
+	/* 48 */
+	NONE(DSI),
+	PERIPHC_TVO,	/* also CVE 0x40 */
+	PERIPHC_MIPI,
+	PERIPHC_HDMI,
+	NONE(CSI),
+	PERIPHC_TVDAC,
+	PERIPHC_I2C2,
+	PERIPHC_UART3,
+
+	/* 56 */
+	NONE(RESERVED56),
+	PERIPHC_EMC,
+	NONE(USB2),
+	NONE(USB3),
+	PERIPHC_MPE,
+	PERIPHC_VDE,
+	NONE(BSEA),
+	NONE(BSEV),
+
+	/* Upper word 95:64 */
+	PERIPHC_SPEEDO,
+	PERIPHC_UART4,
+	PERIPHC_UART5,
+	PERIPHC_I2C3,
+	PERIPHC_SBC4,
+	PERIPHC_SDMMC3,
+	NONE(PCIE),
+	PERIPHC_OWR,
+
+	/* 72 */
+	NONE(AFI),
+	PERIPHC_CSITE,
+	NONE(PCIEXCLK),
+	NONE(AVPUCQ),
+	NONE(RESERVED76),
+	NONE(RESERVED77),
+	NONE(RESERVED78),
+	NONE(DTV),
+
+	/* 80 */
+	PERIPHC_NANDSPEED,
+	PERIPHC_I2CSLOW,
+	NONE(DSIB),
+	NONE(RESERVED83),
+	NONE(IRAMA),
+	NONE(IRAMB),
+	NONE(IRAMC),
+	NONE(IRAMD),
+
+	/* 88 */
+	NONE(CRAM2),
+	NONE(RESERVED89),
+	NONE(MDOUBLER),
+	NONE(RESERVED91),
+	NONE(SUSOUT),
+	NONE(RESERVED93),
+	NONE(RESERVED94),
+	NONE(RESERVED95),
+
+	/* V word: 31:0 */
+	NONE(CPUG),
+	NONE(CPULP),
+	PERIPHC_G3D2,
+	PERIPHC_MSELECT,
+	PERIPHC_TSENSOR,
+	PERIPHC_I2S3,
+	PERIPHC_I2S4,
+	PERIPHC_I2C4,
+
+	/* 08 */
+	PERIPHC_SBC5,
+	PERIPHC_SBC6,
+	PERIPHC_AUDIO,
+	NONE(APBIF),
+	PERIPHC_DAM0,
+	PERIPHC_DAM1,
+	PERIPHC_DAM2,
+	PERIPHC_HDA2CODEC2X,
+
+	/* 16 */
+	NONE(ATOMICS),
+	NONE(RESERVED17),
+	NONE(RESERVED18),
+	NONE(RESERVED19),
+	NONE(RESERVED20),
+	NONE(RESERVED21),
+	NONE(RESERVED22),
+	PERIPHC_ACTMON,
+
+	/* 24 */
+	NONE(RESERVED24),
+	NONE(RESERVED25),
+	NONE(RESERVED26),
+	NONE(RESERVED27),
+	PERIPHC_SATA,
+	PERIPHC_HDA,
+	NONE(RESERVED30),
+	NONE(RESERVED31),
+
+	/* W word: 31:0 */
+	NONE(HDA2HDMICODEC),
+	NONE(RESERVED1_SATACOLD),
+	NONE(RESERVED2_PCIERX0),
+	NONE(RESERVED3_PCIERX1),
+	NONE(RESERVED4_PCIERX2),
+	NONE(RESERVED5_PCIERX3),
+	NONE(RESERVED6_PCIERX4),
+	NONE(RESERVED7_PCIERX5),
+
+	/* 40 */
+	NONE(CEC),
+	NONE(PCIE2_IOBIST),
+	NONE(EMC_IOBIST),
+	NONE(HDMI_IOBIST),
+	NONE(SATA_IOBIST),
+	NONE(MIPI_IOBIST),
+	NONE(EMC1_IOBIST),
+	NONE(XUSB),
+
+	/* 48 */
+	NONE(CILAB),
+	NONE(CILCD),
+	NONE(CILE),
+	NONE(DSIA_LP),
+	NONE(DSIB_LP),
+	NONE(RESERVED21_ENTROPY),
+	NONE(RESERVED22_W),
+	NONE(RESERVED23_W),
+
+	/* 56 */
+	NONE(RESERVED24_W),
+	NONE(AMX0),
+	NONE(ADX0),
+	NONE(DVFS),
+	NONE(XUSB_SS),
+	NONE(EMC_DLL),
+	NONE(MC1),
+	NONE(EMC1),
+};
+
+/*
+ * Get the oscillator frequency, from the corresponding hardware configuration
+ * field. Note that T30/T114 support 3 new higher freqs, but we map back
+ * to the old T20 freqs. Support for the higher oscillators is TBD.
+ */
+enum clock_osc_freq clock_get_osc_freq(void)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 reg;
+
+	reg = readl(&clkrst->crc_osc_ctrl);
+	reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
+
+	if (reg & 1)				/* one of the newer freqs */
+		printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg);
+
+	return reg >> 2;	/* Map to most common (T20) freqs */
+}
+
+/* Returns a pointer to the clock source register for a peripheral */
+u32 *get_periph_source_reg(enum periph_id periph_id)
+{
+	struct clk_rst_ctlr *clkrst =
+		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	enum periphc_internal_id internal_id;
+
+	/* Coresight is a special case */
+	if (periph_id == PERIPH_ID_CSI)
+		return &clkrst->crc_clk_src[PERIPH_ID_CSI+1];
+
+	assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT);
+	internal_id = periph_id_to_internal_id[periph_id];
+	assert(internal_id != -1);
+	if (internal_id >= PERIPHC_VW_FIRST) {
+		internal_id -= PERIPHC_VW_FIRST;
+		return &clkrst->crc_clk_src_vw[internal_id];
+	} else
+		return &clkrst->crc_clk_src[internal_id];
+}
+
+/**
+ * Given a peripheral ID and the required source clock, this returns which
+ * value should be programmed into the source mux for that peripheral.
+ *
+ * There is special code here to handle the one source type with 5 sources.
+ *
+ * @param periph_id	peripheral to start
+ * @param source	PLL id of required parent clock
+ * @param mux_bits	Set to number of bits in mux register: 2 or 4
+ * @param divider_bits Set to number of divider bits (8 or 16)
+ * @return mux value (0-4, or -1 if not found)
+ */
+int get_periph_clock_source(enum periph_id periph_id,
+	enum clock_id parent, int *mux_bits, int *divider_bits)
+{
+	enum clock_type_id type;
+	enum periphc_internal_id internal_id;
+	int mux;
+
+	assert(clock_periph_id_isvalid(periph_id));
+
+	internal_id = periph_id_to_internal_id[periph_id];
+	assert(periphc_internal_id_isvalid(internal_id));
+
+	type = clock_periph_type[internal_id];
+	assert(clock_type_id_isvalid(type));
+
+	*mux_bits = clock_source[type][CLOCK_MAX_MUX];
+
+	if (type == CLOCK_TYPE_PCMT16)
+		*divider_bits = 16;
+	else
+		*divider_bits = 8;
+
+	for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
+		if (clock_source[type][mux] == parent)
+			return mux;
+
+	/* if we get here, either us or the caller has made a mistake */
+	printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id,
+		parent);
+	return -1;
+}
+
+void clock_set_enable(enum periph_id periph_id, int enable)
+{
+	struct clk_rst_ctlr *clkrst =
+		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 *clk;
+	u32 reg;
+
+	/* Enable/disable the clock to this peripheral */
+	assert(clock_periph_id_isvalid(periph_id));
+	if ((int)periph_id < (int)PERIPH_ID_VW_FIRST)
+		clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
+	else
+		clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)];
+	reg = readl(clk);
+	if (enable)
+		reg |= PERIPH_MASK(periph_id);
+	else
+		reg &= ~PERIPH_MASK(periph_id);
+	writel(reg, clk);
+}
+
+void reset_set_enable(enum periph_id periph_id, int enable)
+{
+	struct clk_rst_ctlr *clkrst =
+		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 *reset;
+	u32 reg;
+
+	/* Enable/disable reset to the peripheral */
+	assert(clock_periph_id_isvalid(periph_id));
+	if (periph_id < PERIPH_ID_VW_FIRST)
+		reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
+	else
+		reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)];
+	reg = readl(reset);
+	if (enable)
+		reg |= PERIPH_MASK(periph_id);
+	else
+		reg &= ~PERIPH_MASK(periph_id);
+	writel(reg, reset);
+}
+
+#ifdef CONFIG_OF_CONTROL
+/*
+ * Convert a device tree clock ID to our peripheral ID. They are mostly
+ * the same but we are very cautious so we check that a valid clock ID is
+ * provided.
+ *
+ * @param clk_id    Clock ID according to tegra114 device tree binding
+ * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
+ */
+enum periph_id clk_id_to_periph_id(int clk_id)
+{
+	if (clk_id > PERIPH_ID_COUNT)
+		return PERIPH_ID_NONE;
+
+	switch (clk_id) {
+	case PERIPH_ID_RESERVED3:
+	case PERIPH_ID_RESERVED16:
+	case PERIPH_ID_RESERVED24:
+	case PERIPH_ID_RESERVED35:
+	case PERIPH_ID_RESERVED43:
+	case PERIPH_ID_RESERVED45:
+	case PERIPH_ID_RESERVED56:
+	case PERIPH_ID_RESERVED76:
+	case PERIPH_ID_RESERVED77:
+	case PERIPH_ID_RESERVED78:
+	case PERIPH_ID_RESERVED83:
+	case PERIPH_ID_RESERVED89:
+	case PERIPH_ID_RESERVED91:
+	case PERIPH_ID_RESERVED93:
+	case PERIPH_ID_RESERVED94:
+	case PERIPH_ID_RESERVED95:
+		return PERIPH_ID_NONE;
+	default:
+		return clk_id;
+	}
+}
+#endif /* CONFIG_OF_CONTROL */
+
+void clock_early_init(void)
+{
+	struct clk_rst_ctlr *clkrst =
+		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+
+	/*
+	 * PLLP output frequency set to 408Mhz
+	 * PLLC output frequency set to 600Mhz
+	 * PLLD output frequency set to 925Mhz
+	 */
+	switch (clock_get_osc_freq()) {
+	case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
+		clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8);
+		clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
+		clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12);
+		break;
+
+	case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
+		clock_set_rate(CLOCK_ID_PERIPH, 408, 26, 0, 8);
+		clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8);
+		clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12);
+		break;
+
+	case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
+		clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8);
+		clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
+		clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12);
+		break;
+	case CLOCK_OSC_FREQ_19_2:
+	default:
+		/*
+		 * These are not supported. It is too early to print a
+		 * message and the UART likely won't work anyway due to the
+		 * oscillator being wrong.
+		 */
+		break;
+	}
+
+	/* PLLC_MISC2: Set dynramp_stepA/B. MISC2 maps to pll_out[1] */
+	writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]);
+
+	/* PLLC_MISC: Set LOCK_ENABLE */
+	writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc);
+	udelay(2);
+
+	/* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */
+	writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc);
+	udelay(2);
+}

+ 63 - 0
arch/arm/cpu/tegra114-common/funcmux.c

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra114 high-level function multiplexing */
+
+#include <common.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/funcmux.h>
+#include <asm/arch/pinmux.h>
+
+int funcmux_select(enum periph_id id, int config)
+{
+	int bad_config = config != FUNCMUX_DEFAULT;
+
+	switch (id) {
+	case PERIPH_ID_UART4:
+		switch (config) {
+		case FUNCMUX_UART4_GMI:
+			pinmux_set_func(PINGRP_GMI_A16, PMUX_FUNC_UARTD);
+			pinmux_set_func(PINGRP_GMI_A17, PMUX_FUNC_UARTD);
+			pinmux_set_func(PINGRP_GMI_A18, PMUX_FUNC_UARTD);
+			pinmux_set_func(PINGRP_GMI_A19, PMUX_FUNC_UARTD);
+
+			pinmux_set_io(PINGRP_GMI_A16, PMUX_PIN_OUTPUT);
+			pinmux_set_io(PINGRP_GMI_A17, PMUX_PIN_INPUT);
+			pinmux_set_io(PINGRP_GMI_A18, PMUX_PIN_INPUT);
+			pinmux_set_io(PINGRP_GMI_A19, PMUX_PIN_OUTPUT);
+
+			pinmux_tristate_disable(PINGRP_GMI_A16);
+			pinmux_tristate_disable(PINGRP_GMI_A17);
+			pinmux_tristate_disable(PINGRP_GMI_A18);
+			pinmux_tristate_disable(PINGRP_GMI_A19);
+			break;
+		}
+		break;
+
+	/* Add other periph IDs here as needed */
+
+	default:
+		debug("%s: invalid periph_id %d", __func__, id);
+		return -1;
+	}
+
+	if (bad_config) {
+		debug("%s: invalid config %d for periph_id %d", __func__,
+		      config, id);
+		return -1;
+	}
+	return 0;
+}

+ 506 - 0
arch/arm/cpu/tegra114-common/pinmux.c

@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra114 pin multiplexing functions */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/tegra.h>
+#include <asm/arch/pinmux.h>
+
+struct tegra_pingroup_desc {
+	const char *name;
+	enum pmux_func funcs[4];
+	enum pmux_func func_safe;
+	enum pmux_vddio vddio;
+	enum pmux_pin_io io;
+};
+
+#define PMUX_MUXCTL_SHIFT	0
+#define PMUX_PULL_SHIFT		2
+#define PMUX_TRISTATE_SHIFT	4
+#define PMUX_TRISTATE_MASK	(1 << PMUX_TRISTATE_SHIFT)
+#define PMUX_IO_SHIFT		5
+#define PMUX_OD_SHIFT		6
+#define PMUX_LOCK_SHIFT		7
+#define PMUX_IO_RESET_SHIFT	8
+
+/* Convenient macro for defining pin group properties */
+#define PIN(pg_name, vdd, f0, f1, f2, f3, iod)	\
+	{						\
+		.vddio = PMUX_VDDIO_ ## vdd,		\
+		.funcs = {				\
+			PMUX_FUNC_ ## f0,		\
+			PMUX_FUNC_ ## f1,		\
+			PMUX_FUNC_ ## f2,		\
+			PMUX_FUNC_ ## f3,		\
+		},					\
+		.func_safe = PMUX_FUNC_RSVD1,		\
+		.io = PMUX_PIN_ ## iod,			\
+	}
+
+/* Input and output pins */
+#define PINI(pg_name, vdd, f0, f1, f2, f3) \
+	PIN(pg_name, vdd, f0, f1, f2, f3, INPUT)
+#define PINO(pg_name, vdd, f0, f1, f2, f3) \
+	PIN(pg_name, vdd, f0, f1, f2, f3, OUTPUT)
+
+const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
+	/*	NAME	  VDD	   f0		f1	   f2	    f3  */
+	PINI(ULPI_DATA0,  BB,	   SPI3,       HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA1,  BB,	   SPI3,       HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA2,  BB,	   SPI3,       HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA3,  BB,	   SPI3,	HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA4,  BB,	   SPI2,	HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA5,  BB,      SPI2,        HSI,       UARTA,   ULPI),
+	PINI(ULPI_DATA6,  BB,      SPI2,        HSI,       UARTA,   ULPI),
+	PINI(ULPI_DATA7,  BB,      SPI2,        HSI,       UARTA,   ULPI),
+	PINI(ULPI_CLK,    BB,      SPI1,       SPI5,       UARTD,   ULPI),
+	PINI(ULPI_DIR,    BB,      SPI1,       SPI5,       UARTD,   ULPI),
+	PINI(ULPI_NXT,    BB,      SPI1,       SPI5,       UARTD,   ULPI),
+	PINI(ULPI_STP,    BB,      SPI1,       SPI5,       UARTD,   ULPI),
+	PINI(DAP3_FS,     BB,      I2S2,       SPI5,       DISPA,   DISPB),
+	PINI(DAP3_DIN,    BB,      I2S2,       SPI5,       DISPA,   DISPB),
+	PINI(DAP3_DOUT,   BB,      I2S2,       SPI5,       DISPA,   DISPB),
+	PINI(DAP3_SCLK,   BB,      I2S2,       SPI5,       DISPA,   DISPB),
+	PINI(GPIO_PV0,    BB,      USB,        RSVD2,      RSVD3,   RSVD4),
+	PINI(GPIO_PV1,    BB,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(SDMMC1_CLK,  SDMMC1,  SDMMC1,     CLK12,      RSVD3,   RSVD4),
+	PINI(SDMMC1_CMD,  SDMMC1,  SDMMC1,     SPDIF,      SPI4,    UARTA),
+	PINI(SDMMC1_DAT3, SDMMC1,  SDMMC1,     SPDIF,      SPI4,    UARTA),
+	PINI(SDMMC1_DAT2, SDMMC1,  SDMMC1,     PWM0,       SPI4,    UARTA),
+	PINI(SDMMC1_DAT1, SDMMC1,  SDMMC1,     PWM1,       SPI4,    UARTA),
+	PINI(SDMMC1_DAT0, SDMMC1,  SDMMC1,     RSVD2,      SPI4,    UARTA),
+	PINI(GPIO_PV2,    BB,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(GPIO_PV3,    BB,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(CLK2_OUT,    SDMMC1,  EXTPERIPH2, RSVD2,      RSVD3,   RSVD4),
+	PINI(CLK2_REQ,    SDMMC1,  DAP,        RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_PWR1,    LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_PWR2,    LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_SDIN,    LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_SDOUT,   LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_WR_N,    LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_CS0_N,   LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_DC0,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_SCK,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_PWR0,    LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_PCLK,    LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_DE,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_HSYNC,   LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_VSYNC,   LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D0,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D1,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D2,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D3,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D4,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D5,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D6,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D7,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D8,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D9,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D10,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D11,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D12,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D13,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D14,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D15,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D16,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D17,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D18,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D19,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D20,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D21,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D22,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_D23,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_CS1_N,   LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_M1,      LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINO(LCD_DC1,     LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(HDMI_INT,    LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(DDC_SCL,     LCD,     I2C4,       RSVD2,      RSVD3,   RSVD4),
+	PINI(DDC_SDA,     LCD,     I2C4,       RSVD2,      RSVD3,   RSVD4),
+	PINI(CRT_HSYNC,   LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(CRT_VSYNC,   LCD,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D0,       VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D1,       VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D2,       VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D3,       VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D4,       VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D5,       VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D6,       VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D7,       VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D8,       VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D9,       VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D10,      VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_D11,      VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_PCLK,     VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_MCLK,     VI,      RSVD1,      RSVD3,      RSVD3,   RSVD4),
+	PINI(VI_VSYNC,    VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(VI_HSYNC,    VI,      RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(UART2_RXD,   UART,    UARTB,      SPDIF,      UARTA,   SPI4),
+	PINI(UART2_TXD,   UART,    UARTB,      SPDIF,      UARTA,   SPI4),
+	PINI(UART2_RTS_N, UART,    UARTA,      UARTB,      RSVD3,   SPI4),
+	PINI(UART2_CTS_N, UART,    UARTA,      UARTB,      RSVD3,   SPI4),
+	PINI(UART3_TXD,   UART,    UARTC,      RSVD2,      RSVD3,   SPI4),
+	PINI(UART3_RXD,   UART,    UARTC,      RSVD2,      RSVD3,   SPI4),
+	PINI(UART3_CTS_N, UART,    UARTC,      SDMMC1,     DTV,     SPI4),
+	PINI(UART3_RTS_N, UART,    UARTC,      PWM0,       DTV,     DISPA),
+	PINI(GPIO_PU0,    UART,    OWR,        UARTA,      RSVD3,   RSVD4),
+	PINI(GPIO_PU1,    UART,    RSVD1,      UARTA,      RSVD3,   RSVD4),
+	PINI(GPIO_PU2,    UART,    RSVD1,      UARTA,      RSVD3,   RSVD4),
+	PINI(GPIO_PU3,    UART,    PWM0,       UARTA,      DISPA,   DISPB),
+	PINI(GPIO_PU4,    UART,    PWM1,       UARTA,      DISPA,   DISPB),
+	PINI(GPIO_PU5,    UART,    PWM2,       UARTA,      DISPA,   DISPB),
+	PINI(GPIO_PU6,    UART,    PWM3,       UARTA,      USB,     DISPB),
+	PINI(GEN1_I2C_SDA, UART,   I2C1,       RSVD2,      RSVD3,   RSVD4),
+	PINI(GEN1_I2C_SCL, UART,   I2C1,       RSVD2,      RSVD3,   RSVD4),
+	PINI(DAP4_FS,     UART,    I2S3,       RSVD2,      DTV,     RSVD4),
+	PINI(DAP4_DIN,    UART,    I2S3,       RSVD2,      RSVD3,   RSVD4),
+	PINI(DAP4_DOUT,   UART,    I2S3,       RSVD2,      DTV,     RSVD4),
+	PINI(DAP4_SCLK,   UART,    I2S3,       RSVD2,      RSVD3,   RSVD4),
+	PINI(CLK3_OUT,    UART,    EXTPERIPH3, RSVD2,      RSVD3,   RSVD4),
+	PINI(CLK3_REQ,    UART,    DEV3,       RSVD2,      RSVD3,   RSVD4),
+	PINI(GMI_WP_N,    GMI,     RSVD1,      NAND,       GMI,     GMI_ALT),
+	PINI(GMI_IORDY,   GMI,     SDMMC2,     RSVD2,      GMI,     TRACE),
+	PINI(GMI_WAIT,    GMI,     SPI4,       NAND,       GMI,     DTV),
+	PINI(GMI_ADV_N,   GMI,     RSVD1,      NAND,       GMI,     TRACE),
+	PINI(GMI_CLK,     GMI,     SDMMC2,     NAND,       GMI,     TRACE),
+	PINI(GMI_CS0_N,   GMI,     RSVD1,      NAND,       GMI,     USB),
+	PINI(GMI_CS1_N,   GMI,     RSVD1,      NAND,       GMI,     SOC),
+	PINI(GMI_CS2_N,   GMI,     SDMMC2,     NAND,       GMI,     TRACE),
+	PINI(GMI_CS3_N,   GMI,     SDMMC2,     NAND,       GMI,     GMI_ALT),
+	PINI(GMI_CS4_N,   GMI,     USB,        NAND,       GMI,     TRACE),
+	PINI(GMI_CS6_N,   GMI,     NAND,       NAND_ALT,   GMI,     SPI4),
+	PINI(GMI_CS7_N,   GMI,     NAND,       NAND_ALT,   GMI,     SDMMC2),
+	PINI(GMI_AD0,     GMI,     RSVD1,      NAND,       GMI,     RSVD4),
+	PINI(GMI_AD1,     GMI,     RSVD1,      NAND,       GMI,     RSVD4),
+	PINI(GMI_AD2,     GMI,     RSVD1,      NAND,       GMI,     RSVD4),
+	PINI(GMI_AD3,     GMI,     RSVD1,      NAND,       GMI,     RSVD4),
+	PINI(GMI_AD4,     GMI,     RSVD1,      NAND,       GMI,     RSVD4),
+	PINI(GMI_AD5,     GMI,     RSVD1,      NAND,       GMI,     SPI4),
+	PINI(GMI_AD6,     GMI,     RSVD1,      NAND,       GMI,     SPI4),
+	PINI(GMI_AD7,     GMI,     RSVD1,      NAND,       GMI,     SPI4),
+	PINI(GMI_AD8,     GMI,     PWM0,       NAND,       GMI,     DTV),
+	PINI(GMI_AD9,     GMI,     PWM1,       NAND,       GMI,     CLDVFS),
+	PINI(GMI_AD10,    GMI,     PWM2,       NAND,       GMI,     CLDVFS),
+	PINI(GMI_AD11,    GMI,     PWM3,       NAND,       GMI,     USB),
+	PINI(GMI_AD12,    GMI,     SDMMC2,     NAND,       GMI,     RSVD4),
+	PINI(GMI_AD13,    GMI,     SDMMC2,     NAND,       GMI,     RSVD4),
+	PINI(GMI_AD14,    GMI,     SDMMC2,     NAND,       GMI,     DTV),
+	PINI(GMI_AD15,    GMI,     SDMMC2,     NAND,       GMI,     DTV),
+	PINI(GMI_A16,     GMI,     UARTD,      TRACE,      GMI,     GMI_ALT),
+	PINI(GMI_A17,     GMI,     UARTD,      RSVD2,      GMI,     TRACE),
+	PINI(GMI_A18,     GMI,     UARTD,      RSVD2,      GMI,     TRACE),
+	PINI(GMI_A19,     GMI,     UARTD,      SPI4,       GMI,     TRACE),
+	PINI(GMI_WR_N,    GMI,     RSVD1,      NAND,       GMI,     SPI4),
+	PINI(GMI_OE_N,    GMI,     RSVD1,      NAND,       GMI,     SOC),
+	PINI(GMI_DQS,     GMI,     SDMMC2,     NAND,       GMI,     TRACE),
+	PINI(GMI_RST_N,   GMI,     NAND,       NAND_ALT,   GMI,     RSVD4),
+	PINI(GEN2_I2C_SCL, GMI,    I2C2,       RSVD2,      GMI,     RSVD4),
+	PINI(GEN2_I2C_SDA, GMI,    I2C2,       RSVD2,      GMI,     RSVD4),
+	PINI(SDMMC4_CLK,  SDMMC4,  SDMMC4,     RSVD2,      GMI,     RSVD4),
+	PINI(SDMMC4_CMD,  SDMMC4,  SDMMC4,     RSVD2,      GMI,     RSVD4),
+	PINI(SDMMC4_DAT0, SDMMC4,  SDMMC4,     SPI3,       GMI,     RSVD4),
+	PINI(SDMMC4_DAT1, SDMMC4,  SDMMC4,     SPI3,       GMI,     RSVD4),
+	PINI(SDMMC4_DAT2, SDMMC4,  SDMMC4,     SPI3,       GMI,     RSVD4),
+	PINI(SDMMC4_DAT3, SDMMC4,  SDMMC4,     SPI3,       GMI,     RSVD4),
+	PINI(SDMMC4_DAT4, SDMMC4,  SDMMC4,     SPI3,       GMI,     RSVD4),
+	PINI(SDMMC4_DAT5, SDMMC4,  SDMMC4,     SPI3,       GMI,     RSVD4),
+	PINI(SDMMC4_DAT6, SDMMC4,  SDMMC4,     SPI3,       GMI,     RSVD4),
+	PINI(SDMMC4_DAT7, SDMMC4,  SDMMC4,     RSVD2,      GMI,     RSVD4),
+	PINI(SDMMC4_RST_N, SDMMC4, RSVD1,      RSVD2,      RSVD3,   SDMMC4),
+	PINI(CAM_MCLK,    CAM,     VI,         VI_ALT1,    VI_ALT2, RSVD4),
+	PINI(GPIO_PCC1,   CAM,     I2S4,       RSVD2,      RSVD3,   RSVD4),
+	PINI(GPIO_PBB0,   CAM,     I2S4,       VI,         VI_ALT1, VI_ALT3),
+	PINI(CAM_I2C_SCL, CAM,     VGP1,       I2C3,       RSVD3,   RSVD4),
+	PINI(CAM_I2C_SDA, CAM,     VGP2,       I2C3,       RSVD3,   RSVD4),
+	PINI(GPIO_PBB3,   CAM,     VGP3,       DISPA,      DISPB,   RSVD4),
+	PINI(GPIO_PBB4,   CAM,     VGP4,       DISPA,      DISPB,   RSVD4),
+	PINI(GPIO_PBB5,   CAM,     VGP5,       DISPA,      DISPB,   RSVD4),
+	PINI(GPIO_PBB6,   CAM,     VGP6,       DISPA,      DISPB,   RSVD4),
+	PINI(GPIO_PBB7,   CAM,     I2S4,       RSVD2,      RSVD3,   RSVD4),
+	PINI(GPIO_PCC2,   CAM,     I2S4,       RSVD2,      RSVD3,   RSVD4),
+	PINI(JTAG_RTCK,   SYS,     RTCK,       RSVD2,      RSVD3,   RSVD4),
+	PINI(PWR_I2C_SCL, SYS,     I2CPWR,     RSVD2,      RSVD3,   RSVD4),
+	PINI(PWR_I2C_SDA, SYS,     I2CPWR,     RSVD2,      RSVD3,   RSVD4),
+	PINI(KB_ROW0,     SYS,     KBC,        RSVD2,      DTV,     RSVD4),
+	PINI(KB_ROW1,     SYS,     KBC,        RSVD2,      DTV,     RSVD4),
+	PINI(KB_ROW2,     SYS,     KBC,        RSVD2,      DTV,     SOC),
+	PINI(KB_ROW3,     SYS,     KBC,        DISPA,      RSVD3,   DISPB),
+	PINI(KB_ROW4,     SYS,     KBC,        DISPA,      SPI2,    DISPB),
+	PINI(KB_ROW5,     SYS,     KBC,        DISPA,      SPI2,    DISPB),
+	PINI(KB_ROW6,     SYS,     KBC,        DISPA,      RSVD3,   DISPB),
+	PINI(KB_ROW7,     SYS,     KBC,        RSVD2,      CLDVFS,  UARTA),
+	PINI(KB_ROW8,     SYS,     KBC,        RSVD2,      RSVD3,   UARTA),
+	PINI(KB_ROW9,     SYS,     KBC,        RSVD2,      RSVD3,   UARTA),
+	PINI(KB_ROW10,    SYS,     KBC,        RSVD2,      RSVD3,   UARTA),
+	PINI(KB_ROW11,    SYS,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(KB_ROW12,    SYS,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(KB_ROW13,    SYS,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(KB_ROW14,    SYS,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(KB_ROW15,    SYS,     RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(KB_COL0,     SYS,     KBC,        USB,        SPI2,    EMC_DLL),
+	PINI(KB_COL1,     SYS,     KBC,        RSVD2,      SPI2,    EMC_DLL),
+	PINI(KB_COL2,     SYS,     KBC,        RSVD2,      SPI2,    RSVD4),
+	PINI(KB_COL3,     SYS,     KBC,        DISPA,      PWM2,    UARTA),
+	PINI(KB_COL4,     SYS,     KBC,        OWR,        SDMMC3,  UARTA),
+	PINI(KB_COL5,     SYS,     KBC,        RSVD2,      SDMMC1,  RSVD4),
+	PINI(KB_COL6,     SYS,     KBC,        RSVD2,      SPI2,    RSVD4),
+	PINI(KB_COL7,     SYS,     KBC,        RSVD2,      SPI2,    RSVD4),
+	PINI(CLK_32K_OUT, SYS,     BLINK,      SOC,        RSVD3,   RSVD4),
+	PINI(SYS_CLK_REQ, SYS,     SYSCLK,     RSVD2,      RSVD3,   RSVD4),
+	PINI(CORE_PWR_REQ, SYS,    PWRON,      RSVD2,      RSVD3,   RSVD4),
+	PINI(CPU_PWR_REQ, SYS,     CPU,        RSVD2,      RSVD3,   RSVD4),
+	PINI(PWR_INT_N,   SYS,     PMI,        RSVD2,      RSVD3,   RSVD4),
+	PINI(CLK_32K_IN,  SYS,     CLK,        RSVD2,      RSVD3,   RSVD4),
+	PINI(OWR,         SYS,     OWR,        RSVD2,      RSVD3,   RSVD4),
+	PINI(DAP1_FS,     AUDIO,   I2S0,       HDA,        GMI,     RSVD4),
+	PINI(DAP1_DIN,    AUDIO,   I2S0,       HDA,        GMI,     RSVD4),
+	PINI(DAP1_DOUT,   AUDIO,   I2S0,       HDA,        GMI,     RSVD4),
+	PINI(DAP1_SCLK,   AUDIO,   I2S0,       HDA,        GMI,     RSVD4),
+	PINI(CLK1_REQ,    AUDIO,   DAP,        DAP1,       RSVD3,   RSVD4),
+	PINI(CLK1_OUT,    AUDIO,   EXTPERIPH1, DAP2,       RSVD3,   RSVD4),
+	PINI(SPDIF_IN,    AUDIO,   SPDIF,      USB,        RSVD3,   RSVD4),
+	PINI(SPDIF_OUT,   AUDIO,   SPDIF,      RSVD2,      RSVD3,   RSVD4),
+	PINI(DAP2_FS,     AUDIO,   I2S1,       HDA,        RSVD3,   RSVD4),
+	PINI(DAP2_DIN,    AUDIO,   I2S1,       HDA,        RSVD3,   RSVD4),
+	PINI(DAP2_DOUT,   AUDIO,   I2S1,       HDA,        RSVD3,   RSVD4),
+	PINI(DAP2_SCLK,   AUDIO,   I2S1,       HDA,        RSVD3,   RSVD4),
+	PINI(SPI2_MOSI,   AUDIO,   SPI6,       CLDVFS,     RSVD3,   RSVD4),
+	PINI(SPI2_MISO,   AUDIO,   SPI6,       RSVD2,      RSVD3,   RSVD4),
+	PINI(SPI2_CS0_N,  AUDIO,   SPI6,       SPI1,       RSVD3,   RSVD4),
+	PINI(SPI2_SCK,    AUDIO,   SPI6,       CLDVFS,     RSVD3,   RSVD4),
+	PINI(SPI1_MOSI,   AUDIO,   RSVD1,      SPI1,       SPI2,    DAP2),
+	PINI(SPI1_SCK,    AUDIO,   RSVD1,      SPI1,       SPI2,    RSVD4),
+	PINI(SPI1_CS0_N,  AUDIO,   SPI6,       SPI1,       SPI2,    RSVD4),
+	PINI(SPI1_MISO,   AUDIO,   RSVD1,      SPI1,       SPI2,    RSVD4),
+	PINI(SPI2_CS1_N,  AUDIO,   RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(SPI2_CS2_N,  AUDIO,   RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(SDMMC3_CLK,  SDMMC3,  SDMMC3,     RSVD2,      RSVD3,   SPI3),
+	PINI(SDMMC3_CMD,  SDMMC3,  SDMMC3,     PWM3,       UARTA,   SPI3),
+	PINI(SDMMC3_DAT0, SDMMC3,  SDMMC3,     RSVD2,      RSVD3,   SPI3),
+	PINI(SDMMC3_DAT1, SDMMC3,  SDMMC3,     PWM2,       UARTA,   SPI3),
+	PINI(SDMMC3_DAT2, SDMMC3,  SDMMC3,     PWM1,       DISPA,   SPI3),
+	PINI(SDMMC3_DAT3, SDMMC3,  SDMMC3,     PWM0,       DISPB,   SPI3),
+	PINI(SDMMC3_DAT4, SDMMC3,  RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(SDMMC3_DAT5, SDMMC3,  RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(SDMMC3_DAT6, SDMMC3,  RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(SDMMC3_DAT7, SDMMC3,  RSVD1,      RSVD2,      RSVD3,   RSVD4),
+	PINI(HDMI_CEC,    SYS,     CEC,        SDMMC3,     RSVD3,   SOC),
+	PINI(SDMMC1_WP_N, SDMMC1,  SDMMC1,     CLK12,      SPI4,    UARTA),
+	PINI(SDMMC3_CD_N, SDMMC3,  SDMMC3,     OWR,        RSVD3,   RSVD4),
+	PINI(SPI1_CS1_N,  AUDIO,   SPI6,       RSVD2,      SPI2,    I2C1),
+	PINI(SPI1_CS2_N,  AUDIO,   SPI6,       SPI1,       SPI2,    I2C1),
+	PINI(USB_VBUS_EN0, SYS,    USB,        RSVD2,      RSVD3,   RSVD4),
+	PINI(USB_VBUS_EN1, SYS,    USB,        RSVD2,      RSVD3,   RSVD4),
+	PINI(SDMMC3_CLK_LB_IN,  SDMMC3, SDMMC3, RSVD2,     RSVD3,   RSVD4),
+	PINO(SDMMC3_CLK_LB_OUT, SDMMC3, SDMMC3, RSVD2,     RSVD3,   RSVD4),
+	PINO(NAND_GMI_CLK_LB,   GMI,    SDMMC2, NAND,      GMI,     RSVD4),
+	PINO(RESET_OUT_N, SYS,     RSVD1,      RSVD2,      RSVD3, RESET_OUT_N),
+};
+
+void pinmux_set_tristate(enum pmux_pingrp pin, int enable)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *tri = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin */
+	assert(pmux_pingrp_isvalid(pin));
+
+	reg = readl(tri);
+	if (enable)
+		reg |= PMUX_TRISTATE_MASK;
+	else
+		reg &= ~PMUX_TRISTATE_MASK;
+	writel(reg, tri);
+}
+
+void pinmux_tristate_enable(enum pmux_pingrp pin)
+{
+	pinmux_set_tristate(pin, 1);
+}
+
+void pinmux_tristate_disable(enum pmux_pingrp pin)
+{
+	pinmux_set_tristate(pin, 0);
+}
+
+void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *pull = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin and pupd */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_pupd_isvalid(pupd));
+
+	reg = readl(pull);
+	reg &= ~(0x3 << PMUX_PULL_SHIFT);
+	reg |= (pupd << PMUX_PULL_SHIFT);
+	writel(reg, pull);
+}
+
+void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *muxctl = &pmt->pmt_ctl[pin];
+	int i, mux = -1;
+	u32 reg;
+
+	/* Error check on pin and func */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_func_isvalid(func));
+
+	/* Handle special values */
+	if (func == PMUX_FUNC_SAFE)
+		func = tegra_soc_pingroups[pin].func_safe;
+
+	if (func & PMUX_FUNC_RSVD1) {
+		mux = func & 0x3;
+	} else {
+		/* Search for the appropriate function */
+		for (i = 0; i < 4; i++) {
+			if (tegra_soc_pingroups[pin].funcs[i] == func) {
+				mux = i;
+				break;
+			}
+		}
+	}
+	assert(mux != -1);
+
+	reg = readl(muxctl);
+	reg &= ~(0x3 << PMUX_MUXCTL_SHIFT);
+	reg |= (mux << PMUX_MUXCTL_SHIFT);
+	writel(reg, muxctl);
+
+}
+
+void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *pin_io = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin and io */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_io_isvalid(io));
+
+	reg = readl(pin_io);
+	reg &= ~(0x1 << PMUX_IO_SHIFT);
+	reg |= (io & 0x1) << PMUX_IO_SHIFT;
+	writel(reg, pin_io);
+}
+
+static int pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *pin_lock = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin and lock */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_lock_isvalid(lock));
+
+	if (lock == PMUX_PIN_LOCK_DEFAULT)
+		return 0;
+
+	reg = readl(pin_lock);
+	reg &= ~(0x1 << PMUX_LOCK_SHIFT);
+	if (lock == PMUX_PIN_LOCK_ENABLE)
+		reg |= (0x1 << PMUX_LOCK_SHIFT);
+	else {
+		/* lock == DISABLE, which isn't possible */
+		printf("%s: Warning: lock == %d, DISABLE is not allowed!\n",
+			__func__, lock);
+	}
+	writel(reg, pin_lock);
+
+	return 0;
+}
+
+static int pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *pin_od = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin and od */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_od_isvalid(od));
+
+	if (od == PMUX_PIN_OD_DEFAULT)
+		return 0;
+
+	reg = readl(pin_od);
+	reg &= ~(0x1 << PMUX_OD_SHIFT);
+	if (od == PMUX_PIN_OD_ENABLE)
+		reg |= (0x1 << PMUX_OD_SHIFT);
+	writel(reg, pin_od);
+
+	return 0;
+}
+
+static int pinmux_set_ioreset(enum pmux_pingrp pin,
+				enum pmux_pin_ioreset ioreset)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *pin_ioreset = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin and ioreset */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_ioreset_isvalid(ioreset));
+
+	if (ioreset == PMUX_PIN_IO_RESET_DEFAULT)
+		return 0;
+
+	reg = readl(pin_ioreset);
+	reg &= ~(0x1 << PMUX_IO_RESET_SHIFT);
+	if (ioreset == PMUX_PIN_IO_RESET_ENABLE)
+		reg |= (0x1 << PMUX_IO_RESET_SHIFT);
+	writel(reg, pin_ioreset);
+
+	return 0;
+}
+
+void pinmux_config_pingroup(struct pingroup_config *config)
+{
+	enum pmux_pingrp pin = config->pingroup;
+
+	pinmux_set_func(pin, config->func);
+	pinmux_set_pullupdown(pin, config->pull);
+	pinmux_set_tristate(pin, config->tristate);
+	pinmux_set_io(pin, config->io);
+	pinmux_set_lock(pin, config->lock);
+	pinmux_set_od(pin, config->od);
+	pinmux_set_ioreset(pin, config->ioreset);
+}
+
+void pinmux_config_table(struct pingroup_config *config, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		pinmux_config_pingroup(&config[i]);
+}

+ 20 - 585
arch/arm/cpu/tegra20-common/clock.c

@@ -30,24 +30,6 @@
 #include <div64.h>
 #include <div64.h>
 #include <fdtdec.h>
 #include <fdtdec.h>
 
 
-/*
- * This is our record of the current clock rate of each clock. We don't
- * fill all of these in since we are only really interested in clocks which
- * we use as parents.
- */
-static unsigned pll_rate[CLOCK_ID_COUNT];
-
-/*
- * The oscillator frequency is fixed to one of four set values. Based on this
- * the other clocks are set up appropriately.
- */
-static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = {
-	13000000,
-	19200000,
-	12000000,
-	26000000,
-};
-
 /*
 /*
  * Clock types that we can use as a source. The Tegra20 has muxes for the
  * Clock types that we can use as a source. The Tegra20 has muxes for the
  * peripheral clocks, and in most cases there are four options for the clock
  * peripheral clocks, and in most cases there are four options for the clock
@@ -76,12 +58,6 @@ enum clock_type_id {
 	CLOCK_TYPE_NONE = -1,	/* invalid clock type */
 	CLOCK_TYPE_NONE = -1,	/* invalid clock type */
 };
 };
 
 
-/* return 1 if a peripheral ID is in range */
-#define clock_type_id_isvalid(id) ((id) >= 0 && \
-		(id) < CLOCK_TYPE_COUNT)
-
-char pllp_valid = 1;	/* PLLP is set up correctly */
-
 enum {
 enum {
 	CLOCK_MAX_MUX	= 4	/* number of source options for each clock */
 	CLOCK_MAX_MUX	= 4	/* number of source options for each clock */
 };
 };
@@ -192,10 +168,6 @@ enum periphc_internal_id {
 	PERIPHC_NONE = -1,
 	PERIPHC_NONE = -1,
 };
 };
 
 
-/* return 1 if a periphc_internal_id is in range */
-#define periphc_internal_id_isvalid(id) ((id) >= 0 && \
-		(id) < PERIPHC_COUNT)
-
 /*
 /*
  * Clock type for each peripheral clock source. We put the name in each
  * Clock type for each peripheral clock source. We put the name in each
  * record just so it is easy to match things up
  * record just so it is easy to match things up
@@ -396,19 +368,9 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
 	NONE(CRAM2),
 	NONE(CRAM2),
 };
 };
 
 
-/* number of clock outputs of a PLL */
-static const u8 pll_num_clkouts[] = {
-	1,	/* PLLC */
-	1,	/* PLLM */
-	4,	/* PLLP */
-	1,	/* PLLA */
-	0,	/* PLLU */
-	0,	/* PLLD */
-};
-
 /*
 /*
  * Get the oscillator frequency, from the corresponding hardware configuration
  * Get the oscillator frequency, from the corresponding hardware configuration
- * field.
+ * field. T20 has 4 frequencies that it supports.
  */
  */
 enum clock_osc_freq clock_get_osc_freq(void)
 enum clock_osc_freq clock_get_osc_freq(void)
 {
 {
@@ -420,110 +382,8 @@ enum clock_osc_freq clock_get_osc_freq(void)
 	return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
 	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)
-{
-	struct clk_rst_ctlr *clkrst =
-			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-
-	assert(clock_id_is_pll(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_is_pll(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)
-{
-	struct clk_pll *pll = get_pll(clkid);
-	u32 data;
-
-	/*
-	 * We cheat by treating all PLL (except PLLU) in the same fashion.
-	 * This works only because:
-	 * - same fields are always mapped at same offsets, except DCCON
-	 * - DCCON is always 0, doesn't conflict
-	 * - M,N, P of PLLP values are ignored for PLLP
-	 */
-	data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT);
-	writel(data, &pll->pll_misc);
-
-	data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) |
-			(0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT);
-
-	if (clkid == CLOCK_ID_USB)
-		data |= divp << PLLU_VCO_FREQ_SHIFT;
-	else
-		data |= divp << PLL_DIVP_SHIFT;
-	writel(data, &pll->pll_base);
-
-	/* calculate the stable time */
-	return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US;
-}
-
-/* return 1 if a peripheral ID is in range and valid */
-static int clock_periph_id_isvalid(enum periph_id id)
-{
-	if (id < PERIPH_ID_FIRST || id >= PERIPH_ID_COUNT)
-		printf("Peripheral id %d out of range\n", id);
-	else {
-		switch (id) {
-		case PERIPH_ID_RESERVED1:
-		case PERIPH_ID_RESERVED2:
-		case PERIPH_ID_RESERVED30:
-		case PERIPH_ID_RESERVED35:
-		case PERIPH_ID_RESERVED56:
-		case PERIPH_ID_RESERVED74:
-		case PERIPH_ID_RESERVED76:
-		case PERIPH_ID_RESERVED77:
-		case PERIPH_ID_RESERVED78:
-		case PERIPH_ID_RESERVED79:
-		case PERIPH_ID_RESERVED80:
-		case PERIPH_ID_RESERVED81:
-		case PERIPH_ID_RESERVED82:
-		case PERIPH_ID_RESERVED83:
-		case PERIPH_ID_RESERVED91:
-			printf("Peripheral id %d is reserved\n", id);
-			break;
-		default:
-			return 1;
-		}
-	}
-	return 0;
-}
-
 /* Returns a pointer to the clock source register for a peripheral */
 /* Returns a pointer to the clock source register for a peripheral */
-static u32 *get_periph_source_reg(enum periph_id periph_id)
+u32 *get_periph_source_reg(enum periph_id periph_id)
 {
 {
 	struct clk_rst_ctlr *clkrst =
 	struct clk_rst_ctlr *clkrst =
 			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
 			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
@@ -535,154 +395,6 @@ static u32 *get_periph_source_reg(enum periph_id periph_id)
 	return &clkrst->crc_clk_src[internal_id];
 	return &clkrst->crc_clk_src[internal_id];
 }
 }
 
 
-void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source,
-			      unsigned divisor)
-{
-	u32 *reg = get_periph_source_reg(periph_id);
-	u32 value;
-
-	value = readl(reg);
-
-	value &= ~OUT_CLK_SOURCE_MASK;
-	value |= source << OUT_CLK_SOURCE_SHIFT;
-
-	value &= ~OUT_CLK_DIVISOR_MASK;
-	value |= divisor << OUT_CLK_DIVISOR_SHIFT;
-
-	writel(value, reg);
-}
-
-void clock_ll_set_source(enum periph_id periph_id, unsigned source)
-{
-	u32 *reg = get_periph_source_reg(periph_id);
-
-	clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
-			source << OUT_CLK_SOURCE_SHIFT);
-}
-
-/**
- * Given the parent's rate and the required rate for the children, this works
- * out the peripheral clock divider to use, in 7.1 binary format.
- *
- * @param divider_bits	number of divider bits (8 or 16)
- * @param parent_rate	clock rate of parent clock in Hz
- * @param rate		required clock rate for this clock
- * @return divider which should be used
- */
-static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate,
-			   unsigned long rate)
-{
-	u64 divider = parent_rate * 2;
-	unsigned max_divider = 1 << divider_bits;
-
-	divider += rate - 1;
-	do_div(divider, rate);
-
-	if ((s64)divider - 2 < 0)
-		return 0;
-
-	if ((s64)divider - 2 >= max_divider)
-		return -1;
-
-	return divider - 2;
-}
-
-/**
- * Given the parent's rate and the divider in 7.1 format, this works out the
- * resulting peripheral clock rate.
- *
- * @param parent_rate	clock rate of parent clock in Hz
- * @param divider which should be used in 7.1 format
- * @return effective clock rate of peripheral
- */
-static unsigned long get_rate_from_divider(unsigned long parent_rate,
-					   int divider)
-{
-	u64 rate;
-
-	rate = (u64)parent_rate * 2;
-	do_div(rate, divider + 2);
-	return rate;
-}
-
-unsigned long clock_get_periph_rate(enum periph_id periph_id,
-		enum clock_id parent)
-{
-	u32 *reg = get_periph_source_reg(periph_id);
-
-	return get_rate_from_divider(pll_rate[parent],
-		(readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT);
-}
-
-int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate)
-{
-	struct clk_pll *pll = get_pll(clkid);
-	int data = 0, div = 0, offset = 0;
-
-	if (!clock_id_is_pll(clkid))
-		return -1;
-
-	if (pllout + 1 > pll_num_clkouts[clkid])
-		return -1;
-
-	div = clk_get_divider(8, pll_rate[clkid], rate);
-
-	if (div < 0)
-		return -1;
-
-	/* out2 and out4 are in the high part of the register */
-	if (pllout == PLL_OUT2 || pllout == PLL_OUT4)
-		offset = 16;
-
-	data = (div << PLL_OUT_RATIO_SHIFT) |
-			PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN;
-	clrsetbits_le32(&pll->pll_out[pllout >> 1],
-			PLL_OUT_RATIO_MASK << offset, data << offset);
-
-	return 0;
-}
-
-/**
- * Find the best available 7.1 format divisor given a parent clock rate and
- * required child clock rate. This function assumes that a second-stage
- * divisor is available which can divide by powers of 2 from 1 to 256.
- *
- * @param divider_bits	number of divider bits (8 or 16)
- * @param parent_rate	clock rate of parent clock in Hz
- * @param rate		required clock rate for this clock
- * @param extra_div	value for the second-stage divisor (not set if this
- *			function returns -1.
- * @return divider which should be used, or -1 if nothing is valid
- *
- */
-static int find_best_divider(unsigned divider_bits, unsigned long parent_rate,
-			     unsigned long rate, int *extra_div)
-{
-	int shift;
-	int best_divider = -1;
-	int best_error = rate;
-
-	/* try dividers from 1 to 256 and find closest match */
-	for (shift = 0; shift <= 8 && best_error > 0; shift++) {
-		unsigned divided_parent = parent_rate >> shift;
-		int divider = clk_get_divider(divider_bits, divided_parent,
-					      rate);
-		unsigned effective_rate = get_rate_from_divider(divided_parent,
-						       divider);
-		int error = rate - effective_rate;
-
-		/* Given a valid divider, look for the lowest error */
-		if (divider != -1 && error < best_error) {
-			best_error = error;
-			*extra_div = 1 << shift;
-			best_divider = divider;
-		}
-	}
-
-	/* return what we found - *extra_div will already be set */
-	return best_divider;
-}
-
 /**
 /**
  * Given a peripheral ID and the required source clock, this returns which
  * Given a peripheral ID and the required source clock, this returns which
  * value should be programmed into the source mux for that peripheral.
  * value should be programmed into the source mux for that peripheral.
@@ -695,7 +407,7 @@ static int find_best_divider(unsigned divider_bits, unsigned long parent_rate,
  * @param divider_bits	Set to number of divider bits (8 or 16)
  * @param divider_bits	Set to number of divider bits (8 or 16)
  * @return mux value (0-4, or -1 if not found)
  * @return mux value (0-4, or -1 if not found)
  */
  */
-static int get_periph_clock_source(enum periph_id periph_id,
+int get_periph_clock_source(enum periph_id periph_id,
 		enum clock_id parent, int *mux_bits, int *divider_bits)
 		enum clock_id parent, int *mux_bits, int *divider_bits)
 {
 {
 	enum clock_type_id type;
 	enum clock_type_id type;
@@ -743,88 +455,6 @@ static int get_periph_clock_source(enum periph_id periph_id,
 	return -1;
 	return -1;
 }
 }
 
 
-/**
- * Adjust peripheral PLL to use the given divider and source.
- *
- * @param periph_id	peripheral to adjust
- * @param source	Source number (0-3 or 0-7)
- * @param mux_bits	Number of mux bits (2 or 4)
- * @param divider	Required divider in 7.1 or 15.1 format
- * @return 0 if ok, -1 on error (requesting a parent clock which is not valid
- *		for this peripheral)
- */
-static int adjust_periph_pll(enum periph_id periph_id, int source,
-			     int mux_bits, unsigned divider)
-{
-	u32 *reg = get_periph_source_reg(periph_id);
-
-	clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK,
-			divider << OUT_CLK_DIVISOR_SHIFT);
-	udelay(1);
-
-	/* work out the source clock and set it */
-	if (source < 0)
-		return -1;
-	if (mux_bits == 4) {
-		clrsetbits_le32(reg, OUT_CLK_SOURCE4_MASK,
-			source << OUT_CLK_SOURCE4_SHIFT);
-	} else {
-		clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
-			source << OUT_CLK_SOURCE_SHIFT);
-	}
-	udelay(2);
-	return 0;
-}
-
-unsigned clock_adjust_periph_pll_div(enum periph_id periph_id,
-		enum clock_id parent, unsigned rate, int *extra_div)
-{
-	unsigned effective_rate;
-	int mux_bits, divider_bits, source;
-	int divider;
-
-	/* work out the source clock and set it */
-	source = get_periph_clock_source(periph_id, parent, &mux_bits,
-					 &divider_bits);
-
-	if (extra_div)
-		divider = find_best_divider(divider_bits, pll_rate[parent],
-					    rate, extra_div);
-	else
-		divider = clk_get_divider(divider_bits, pll_rate[parent],
-					  rate);
-	assert(divider >= 0);
-	if (adjust_periph_pll(periph_id, source, mux_bits, divider))
-		return -1U;
-	debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate,
-		get_periph_source_reg(periph_id),
-		readl(get_periph_source_reg(periph_id)));
-
-	/* Check what we ended up with. This shouldn't matter though */
-	effective_rate = clock_get_periph_rate(periph_id, parent);
-	if (extra_div)
-		effective_rate /= *extra_div;
-	if (rate != effective_rate)
-		debug("Requested clock rate %u not honored (got %u)\n",
-		       rate, effective_rate);
-	return effective_rate;
-}
-
-unsigned clock_start_periph_pll(enum periph_id periph_id,
-		enum clock_id parent, unsigned rate)
-{
-	unsigned effective_rate;
-
-	reset_set_enable(periph_id, 1);
-	clock_enable(periph_id);
-
-	effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate,
-						 NULL);
-
-	reset_set_enable(periph_id, 0);
-	return effective_rate;
-}
-
 void clock_set_enable(enum periph_id periph_id, int enable)
 void clock_set_enable(enum periph_id periph_id, int enable)
 {
 {
 	struct clk_rst_ctlr *clkrst =
 	struct clk_rst_ctlr *clkrst =
@@ -842,16 +472,6 @@ void clock_set_enable(enum periph_id periph_id, int enable)
 	writel(reg, clk);
 	writel(reg, clk);
 }
 }
 
 
-void clock_enable(enum periph_id clkid)
-{
-	clock_set_enable(clkid, 1);
-}
-
-void clock_disable(enum periph_id clkid)
-{
-	clock_set_enable(clkid, 0);
-}
-
 void reset_set_enable(enum periph_id periph_id, int enable)
 void reset_set_enable(enum periph_id periph_id, int enable)
 {
 {
 	struct clk_rst_ctlr *clkrst =
 	struct clk_rst_ctlr *clkrst =
@@ -869,146 +489,6 @@ void reset_set_enable(enum periph_id periph_id, int enable)
 	writel(reg, reset);
 	writel(reg, reset);
 }
 }
 
 
-void reset_periph(enum periph_id periph_id, int us_delay)
-{
-	/* Put peripheral into reset */
-	reset_set_enable(periph_id, 1);
-	udelay(us_delay);
-
-	/* Remove reset */
-	reset_set_enable(periph_id, 0);
-
-	udelay(us_delay);
-}
-
-void reset_cmplx_set_enable(int cpu, int which, int reset)
-{
-	struct clk_rst_ctlr *clkrst =
-			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-	u32 mask;
-
-	/* Form the mask, which depends on the cpu chosen. Tegra20 has 2 */
-	assert(cpu >= 0 && cpu < 2);
-	mask = which << cpu;
-
-	/* either enable or disable those reset for that CPU */
-	if (reset)
-		writel(mask, &clkrst->crc_cpu_cmplx_set);
-	else
-		writel(mask, &clkrst->crc_cpu_cmplx_clr);
-}
-
-unsigned clock_get_rate(enum clock_id clkid)
-{
-	struct clk_pll *pll;
-	u32 base;
-	u32 divm;
-	u64 parent_rate;
-	u64 rate;
-
-	parent_rate = osc_freq[clock_get_osc_freq()];
-	if (clkid == CLOCK_ID_OSC)
-		return parent_rate;
-
-	pll = get_pll(clkid);
-	base = readl(&pll->pll_base);
-
-	/* Oh for bf_unpack()... */
-	rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT);
-	divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
-	if (clkid == CLOCK_ID_USB)
-		divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT;
-	else
-		divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
-	do_div(rate, divm);
-	return rate;
-}
-
-/**
- * Set the output frequency you want for each PLL clock.
- * PLL output frequencies are programmed by setting their N, M and P values.
- * The governing equations are:
- *     VCO = (Fi / m) * n, Fo = VCO / (2^p)
- *     where Fo is the output frequency from the PLL.
- * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi)
- *     216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1
- * Please see Tegra TRM section 5.3 to get the detail for PLL Programming
- *
- * @param n PLL feedback divider(DIVN)
- * @param m PLL input divider(DIVN)
- * @param p post divider(DIVP)
- * @param cpcon base PLL charge pump(CPCON)
- * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
- *		be overriden), 1 if PLL is already correct
- */
-static int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
-{
-	u32 base_reg;
-	u32 misc_reg;
-	struct clk_pll *pll;
-
-	pll = get_pll(clkid);
-
-	base_reg = readl(&pll->pll_base);
-
-	/* Set BYPASS, m, n and p to PLL_BASE */
-	base_reg &= ~PLL_DIVM_MASK;
-	base_reg |= m << PLL_DIVM_SHIFT;
-
-	base_reg &= ~PLL_DIVN_MASK;
-	base_reg |= n << PLL_DIVN_SHIFT;
-
-	base_reg &= ~PLL_DIVP_MASK;
-	base_reg |= p << PLL_DIVP_SHIFT;
-
-	if (clkid == CLOCK_ID_PERIPH) {
-		/*
-		 * If the PLL is already set up, check that it is correct
-		 * and record this info for clock_verify() to check.
-		 */
-		if (base_reg & PLL_BASE_OVRRIDE_MASK) {
-			base_reg |= PLL_ENABLE_MASK;
-			if (base_reg != readl(&pll->pll_base))
-				pllp_valid = 0;
-			return pllp_valid ? 1 : -1;
-		}
-		base_reg |= PLL_BASE_OVRRIDE_MASK;
-	}
-
-	base_reg |= PLL_BYPASS_MASK;
-	writel(base_reg, &pll->pll_base);
-
-	/* Set cpcon to PLL_MISC */
-	misc_reg = readl(&pll->pll_misc);
-	misc_reg &= ~PLL_CPCON_MASK;
-	misc_reg |= cpcon << PLL_CPCON_SHIFT;
-	writel(misc_reg, &pll->pll_misc);
-
-	/* Enable PLL */
-	base_reg |= PLL_ENABLE_MASK;
-	writel(base_reg, &pll->pll_base);
-
-	/* Disable BYPASS */
-	base_reg &= ~PLL_BYPASS_MASK;
-	writel(base_reg, &pll->pll_base);
-
-	return 0;
-}
-
-void clock_ll_start_uart(enum periph_id periph_id)
-{
-	/* Assert UART reset and enable clock */
-	reset_set_enable(periph_id, 1);
-	clock_enable(periph_id);
-	clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */
-
-	/* wait for 2us */
-	udelay(2);
-
-	/* De-assert reset to UART */
-	reset_set_enable(periph_id, 0);
-}
-
 #ifdef CONFIG_OF_CONTROL
 #ifdef CONFIG_OF_CONTROL
 /*
 /*
  * Convert a device tree clock ID to our peripheral ID. They are mostly
  * Convert a device tree clock ID to our peripheral ID. They are mostly
@@ -1018,67 +498,34 @@ void clock_ll_start_uart(enum periph_id periph_id)
  * @param clk_id	Clock ID according to tegra20 device tree binding
  * @param clk_id	Clock ID according to tegra20 device tree binding
  * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
  * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
  */
  */
-static enum periph_id clk_id_to_periph_id(int clk_id)
+enum periph_id clk_id_to_periph_id(int clk_id)
 {
 {
-	if (clk_id > 95)
+	if (clk_id > PERIPH_ID_COUNT)
 		return PERIPH_ID_NONE;
 		return PERIPH_ID_NONE;
 
 
 	switch (clk_id) {
 	switch (clk_id) {
-	case 1:
-	case 2:
-	case 7:
-	case 10:
-	case 20:
-	case 30:
-	case 35:
-	case 49:
-	case 56:
-	case 74:
-	case 76:
-	case 77:
-	case 78:
-	case 79:
-	case 80:
-	case 81:
-	case 82:
-	case 83:
-	case 91:
-	case 95:
+	case PERIPH_ID_RESERVED1:
+	case PERIPH_ID_RESERVED2:
+	case PERIPH_ID_RESERVED30:
+	case PERIPH_ID_RESERVED35:
+	case PERIPH_ID_RESERVED56:
+	case PERIPH_ID_RESERVED74:
+	case PERIPH_ID_RESERVED76:
+	case PERIPH_ID_RESERVED77:
+	case PERIPH_ID_RESERVED78:
+	case PERIPH_ID_RESERVED79:
+	case PERIPH_ID_RESERVED80:
+	case PERIPH_ID_RESERVED81:
+	case PERIPH_ID_RESERVED82:
+	case PERIPH_ID_RESERVED83:
+	case PERIPH_ID_RESERVED91:
 		return PERIPH_ID_NONE;
 		return PERIPH_ID_NONE;
 	default:
 	default:
 		return clk_id;
 		return clk_id;
 	}
 	}
 }
 }
-
-int clock_decode_periph_id(const void *blob, int node)
-{
-	enum periph_id id;
-	u32 cell[2];
-	int err;
-
-	err = fdtdec_get_int_array(blob, node, "clocks", cell,
-				   ARRAY_SIZE(cell));
-	if (err)
-		return -1;
-	id = clk_id_to_periph_id(cell[1]);
-	assert(clock_periph_id_isvalid(id));
-	return id;
-}
 #endif /* CONFIG_OF_CONTROL */
 #endif /* CONFIG_OF_CONTROL */
 
 
-int clock_verify(void)
-{
-	struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH);
-	u32 reg = readl(&pll->pll_base);
-
-	if (!pllp_valid) {
-		printf("Warning: PLLP %x is not correct\n", reg);
-		return -1;
-	}
-	debug("PLLX %x is correct\n", reg);
-	return 0;
-}
-
 void clock_early_init(void)
 void clock_early_init(void)
 {
 {
 	/*
 	/*
@@ -1112,15 +559,3 @@ void clock_early_init(void)
 		break;
 		break;
 	}
 	}
 }
 }
-
-void clock_init(void)
-{
-	pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY);
-	pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH);
-	pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL);
-	pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC);
-	pll_rate[CLOCK_ID_SFROM32KHZ] = 32768;
-	debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]);
-	debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]);
-	debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]);
-}

+ 2 - 2
arch/arm/cpu/tegra20-common/funcmux.c

@@ -98,8 +98,8 @@ int funcmux_select(enum periph_id id, int config)
 		break;
 		break;
 
 
 	case PERIPH_ID_UART2:
 	case PERIPH_ID_UART2:
-		if (config == FUNCMUX_UART2_IRDA) {
-			pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA);
+		if (config == FUNCMUX_UART2_UAD) {
+			pinmux_set_func(PINGRP_UAD, PMUX_FUNC_UARTB);
 			pinmux_tristate_disable(PINGRP_UAD);
 			pinmux_tristate_disable(PINGRP_UAD);
 		}
 		}
 		break;
 		break;

+ 1 - 1
arch/arm/cpu/tegra20-common/pinmux.c

@@ -390,7 +390,7 @@ const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
 	PIN(UAA,  BB,    SPI3,   MIPI_HS, UARTA,    ULPI,        MIPI_HS),
 	PIN(UAA,  BB,    SPI3,   MIPI_HS, UARTA,    ULPI,        MIPI_HS),
 	PIN(UAB,  BB,    SPI2,   MIPI_HS, UARTA,    ULPI,        MIPI_HS),
 	PIN(UAB,  BB,    SPI2,   MIPI_HS, UARTA,    ULPI,        MIPI_HS),
 	PIN(UAC,  BB,    OWR,    RSVD,   RSVD,      RSVD,        RSVD4),
 	PIN(UAC,  BB,    OWR,    RSVD,   RSVD,      RSVD,        RSVD4),
-	PIN(UAD,  UART,  IRDA,   SPDIF,  UARTA,     SPI4,        SPDIF),
+	PIN(UAD,  UART,  UARTB,  SPDIF,  UARTA,     SPI4,        SPDIF),
 	PIN(UCA,  UART,  UARTC,  RSVD,   GMI,       RSVD,        RSVD4),
 	PIN(UCA,  UART,  UARTC,  RSVD,   GMI,       RSVD,        RSVD4),
 	PIN(UCB,  UART,  UARTC,  PWM,    GMI,       RSVD,        RSVD4),
 	PIN(UCB,  UART,  UARTC,  PWM,    GMI,       RSVD,        RSVD4),
 
 

+ 1 - 1
arch/arm/cpu/tegra20-common/warmboot.c

@@ -46,7 +46,7 @@ DECLARE_GLOBAL_DATA_PTR;
  * This is the place in SRAM where the SDRAM parameters are stored. There
  * This is the place in SRAM where the SDRAM parameters are stored. There
  * are 4 blocks, one for each RAM code
  * are 4 blocks, one for each RAM code
  */
  */
-#define SDRAM_PARAMS_BASE	(AP20_BASE_PA_SRAM + 0x188)
+#define SDRAM_PARAMS_BASE	(NV_PA_BASE_SRAM + 0x188)
 
 
 /* TODO: If we later add support for the Misc GP controller, refactor this */
 /* TODO: If we later add support for the Misc GP controller, refactor this */
 union xm2cfga_reg {
 union xm2cfga_reg {

+ 44 - 0
arch/arm/cpu/tegra30-common/Makefile

@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+#
+# (C) Copyright 2000-2008
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+#
+
+include $(TOPDIR)/config.mk
+
+# The AVP is ARMv4T architecture so we must use special compiler
+# flags for any startup files it might use.
+
+LIB	= $(obj)lib$(SOC)-common.o
+
+COBJS-y	+= clock.o funcmux.o pinmux.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################

+ 618 - 0
arch/arm/cpu/tegra30-common/clock.c

@@ -0,0 +1,618 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra30 Clock control functions */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/tegra.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/timer.h>
+#include <div64.h>
+#include <fdtdec.h>
+
+/*
+ * Clock types that we can use as a source. The Tegra30 has muxes for the
+ * peripheral clocks, and in most cases there are four options for the clock
+ * source. This gives us a clock 'type' and exploits what commonality exists
+ * in the device.
+ *
+ * Letters are obvious, except for T which means CLK_M, and S which means the
+ * clock derived from 32KHz. Beware that CLK_M (also called OSC in the
+ * datasheet) and PLL_M are different things. The former is the basic
+ * clock supplied to the SOC from an external oscillator. The latter is the
+ * memory clock PLL.
+ *
+ * See definitions in clock_id in the header file.
+ */
+enum clock_type_id {
+	CLOCK_TYPE_AXPT,	/* PLL_A, PLL_X, PLL_P, CLK_M */
+	CLOCK_TYPE_MCPA,	/* and so on */
+	CLOCK_TYPE_MCPT,
+	CLOCK_TYPE_PCM,
+	CLOCK_TYPE_PCMT,
+	CLOCK_TYPE_PCMT16,
+	CLOCK_TYPE_PDCT,
+	CLOCK_TYPE_ACPT,
+	CLOCK_TYPE_ASPTE,
+	CLOCK_TYPE_PMDACD2T,
+	CLOCK_TYPE_PCST,
+
+	CLOCK_TYPE_COUNT,
+	CLOCK_TYPE_NONE = -1,   /* invalid clock type */
+};
+
+enum {
+	CLOCK_MAX_MUX   = 8     /* number of source options for each clock */
+};
+
+enum {
+	MASK_BITS_31_30 = 2,    /* num of bits used to specify clock source */
+	MASK_BITS_31_29,
+	MASK_BITS_29_28,
+};
+
+/*
+ * Clock source mux for each clock type. This just converts our enum into
+ * a list of mux sources for use by the code.
+ *
+ * Note:
+ *  The extra column in each clock source array is used to store the mask
+ *  bits in its register for the source.
+ */
+#define CLK(x) CLOCK_ID_ ## x
+static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = {
+	{ CLK(AUDIO),   CLK(XCPU),      CLK(PERIPH),    CLK(OSC),
+		CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(MEMORY),  CLK(CGENERAL),  CLK(PERIPH),    CLK(AUDIO),
+		CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(MEMORY),  CLK(CGENERAL),  CLK(PERIPH),    CLK(OSC),
+		CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(PERIPH),  CLK(CGENERAL),  CLK(MEMORY),    CLK(NONE),
+		CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(PERIPH),  CLK(CGENERAL),  CLK(MEMORY),    CLK(OSC),
+		CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(PERIPH),  CLK(CGENERAL),  CLK(MEMORY),    CLK(OSC),
+		CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(PERIPH),  CLK(DISPLAY),   CLK(CGENERAL),  CLK(OSC),
+		CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(AUDIO),   CLK(CGENERAL),  CLK(PERIPH),    CLK(OSC),
+		CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+		MASK_BITS_31_30},
+	{ CLK(AUDIO),   CLK(SFROM32KHZ),	CLK(PERIPH),   CLK(OSC),
+		CLK(EPCI),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+		MASK_BITS_31_29},
+	{ CLK(PERIPH),  CLK(MEMORY),    CLK(DISPLAY),   CLK(AUDIO),
+		CLK(CGENERAL),  CLK(DISPLAY2),  CLK(OSC),       CLK(NONE),
+		MASK_BITS_31_29},
+	{ CLK(PERIPH),  CLK(CGENERAL),  CLK(SFROM32KHZ), CLK(OSC),
+		CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+		MASK_BITS_29_28}
+};
+
+/*
+ * Clock type for each peripheral clock source. We put the name in each
+ * record just so it is easy to match things up
+ */
+#define TYPE(name, type) type
+static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
+	/* 0x00 */
+	TYPE(PERIPHC_I2S1,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_I2S2,      CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_SPDIF_IN,  CLOCK_TYPE_PCM),
+	TYPE(PERIPHC_PWM,       CLOCK_TYPE_PCST),  /* only PWM uses b29:28 */
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SBC2,      CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SBC3,      CLOCK_TYPE_PCMT),
+
+	/* 0x08 */
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_I2C1,      CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_DVC_I2C,   CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SBC1,      CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_DISP1,     CLOCK_TYPE_PMDACD2T),
+	TYPE(PERIPHC_DISP2,     CLOCK_TYPE_PMDACD2T),
+
+	/* 0x10 */
+	TYPE(PERIPHC_CVE,       CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_VI,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SDMMC1,    CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SDMMC2,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_G3D,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_G2D,	CLOCK_TYPE_MCPA),
+
+	/* 0x18 */
+	TYPE(PERIPHC_NDFLASH,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SDMMC4,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_VFIR,      CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_EPP,       CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_MPE,       CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_MIPI,      CLOCK_TYPE_PCMT),       /* MIPI base-band HSI */
+	TYPE(PERIPHC_UART1,     CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_UART2,     CLOCK_TYPE_PCMT),
+
+	/* 0x20 */
+	TYPE(PERIPHC_HOST1X,    CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_TVO,       CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_HDMI,      CLOCK_TYPE_PMDACD2T),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_TVDAC,     CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_I2C2,      CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_EMC,	CLOCK_TYPE_MCPT),
+
+	/* 0x28 */
+	TYPE(PERIPHC_UART3,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_VI,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SBC4,      CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_I2C3,      CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_SDMMC3,    CLOCK_TYPE_PCMT),
+
+	/* 0x30 */
+	TYPE(PERIPHC_UART4,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_UART5,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_VDE,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_OWR,       CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_NOR,       CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_CSITE,     CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_I2S0,      CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+
+	/* 0x38h */	     /* Jumps to reg offset 0x3B0h - new for T30 */
+	TYPE(PERIPHC_G3D2,      CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_MSELECT,   CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_TSENSOR,   CLOCK_TYPE_PCST),       /* s/b PCTS */
+	TYPE(PERIPHC_I2S3,      CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_I2S4,      CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_I2C4,      CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_SBC5,      CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SBC6,      CLOCK_TYPE_PCMT),
+
+	/* 0x40 */
+	TYPE(PERIPHC_AUDIO,     CLOCK_TYPE_ACPT),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_DAM0,      CLOCK_TYPE_ACPT),
+	TYPE(PERIPHC_DAM1,      CLOCK_TYPE_ACPT),
+	TYPE(PERIPHC_DAM2,      CLOCK_TYPE_ACPT),
+	TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_ACTMON,    CLOCK_TYPE_PCST),       /* MASK 31:30 */
+	TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE),
+
+	/* 0x48 */
+	TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE),
+	TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE),
+	TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_I2CSLOW,   CLOCK_TYPE_PCST),       /* MASK 31:30 */
+	TYPE(PERIPHC_SYS,       CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SPEEDO,    CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+
+	/* 0x50 */
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,      CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SATAOOB,   CLOCK_TYPE_PCMT),       /* offset 0x420h */
+	TYPE(PERIPHC_SATA,      CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_HDA,       CLOCK_TYPE_PCMT),
+};
+
+/*
+ * This array translates a periph_id to a periphc_internal_id
+ *
+ * Not present/matched up:
+ *	uint vi_sensor;	 _VI_SENSOR_0,		0x1A8
+ *	SPDIF - which is both 0x08 and 0x0c
+ *
+ */
+#define NONE(name) (-1)
+#define OFFSET(name, value) PERIPHC_ ## name
+static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
+	/* Low word: 31:0 */
+	NONE(CPU),
+	NONE(COP),
+	NONE(TRIGSYS),
+	NONE(RESERVED3),
+	NONE(RESERVED4),
+	NONE(TMR),
+	PERIPHC_UART1,
+	PERIPHC_UART2,  /* and vfir 0x68 */
+
+	/* 8 */
+	NONE(GPIO),
+	PERIPHC_SDMMC2,
+	NONE(SPDIF),	    /* 0x08 and 0x0c, unclear which to use */
+	PERIPHC_I2S1,
+	PERIPHC_I2C1,
+	PERIPHC_NDFLASH,
+	PERIPHC_SDMMC1,
+	PERIPHC_SDMMC4,
+
+	/* 16 */
+	NONE(RESERVED16),
+	PERIPHC_PWM,
+	PERIPHC_I2S2,
+	PERIPHC_EPP,
+	PERIPHC_VI,
+	PERIPHC_G2D,
+	NONE(USBD),
+	NONE(ISP),
+
+	/* 24 */
+	PERIPHC_G3D,
+	NONE(RESERVED25),
+	PERIPHC_DISP2,
+	PERIPHC_DISP1,
+	PERIPHC_HOST1X,
+	NONE(VCP),
+	PERIPHC_I2S0,
+	NONE(CACHE2),
+
+	/* Middle word: 63:32 */
+	NONE(MEM),
+	NONE(AHBDMA),
+	NONE(APBDMA),
+	NONE(RESERVED35),
+	NONE(RESERVED36),
+	NONE(STAT_MON),
+	NONE(RESERVED38),
+	NONE(RESERVED39),
+
+	/* 40 */
+	NONE(KFUSE),
+	PERIPHC_SBC1,
+	PERIPHC_NOR,
+	NONE(RESERVED43),
+	PERIPHC_SBC2,
+	NONE(RESERVED45),
+	PERIPHC_SBC3,
+	PERIPHC_DVC_I2C,
+
+	/* 48 */
+	NONE(DSI),
+	PERIPHC_TVO,    /* also CVE 0x40 */
+	PERIPHC_MIPI,
+	PERIPHC_HDMI,
+	NONE(CSI),
+	PERIPHC_TVDAC,
+	PERIPHC_I2C2,
+	PERIPHC_UART3,
+
+	/* 56 */
+	NONE(RESERVED56),
+	PERIPHC_EMC,
+	NONE(USB2),
+	NONE(USB3),
+	PERIPHC_MPE,
+	PERIPHC_VDE,
+	NONE(BSEA),
+	NONE(BSEV),
+
+	/* Upper word 95:64 */
+	PERIPHC_SPEEDO,
+	PERIPHC_UART4,
+	PERIPHC_UART5,
+	PERIPHC_I2C3,
+	PERIPHC_SBC4,
+	PERIPHC_SDMMC3,
+	NONE(PCIE),
+	PERIPHC_OWR,
+
+	/* 72 */
+	NONE(AFI),
+	PERIPHC_CSITE,
+	NONE(PCIEXCLK),
+	NONE(AVPUCQ),
+	NONE(RESERVED76),
+	NONE(RESERVED77),
+	NONE(RESERVED78),
+	NONE(DTV),
+
+	/* 80 */
+	PERIPHC_NANDSPEED,
+	PERIPHC_I2CSLOW,
+	NONE(DSIB),
+	NONE(RESERVED83),
+	NONE(IRAMA),
+	NONE(IRAMB),
+	NONE(IRAMC),
+	NONE(IRAMD),
+
+	/* 88 */
+	NONE(CRAM2),
+	NONE(RESERVED89),
+	NONE(MDOUBLER),
+	NONE(RESERVED91),
+	NONE(SUSOUT),
+	NONE(RESERVED93),
+	NONE(RESERVED94),
+	NONE(RESERVED95),
+
+	/* V word: 31:0 */
+	NONE(CPUG),
+	NONE(CPULP),
+	PERIPHC_G3D2,
+	PERIPHC_MSELECT,
+	PERIPHC_TSENSOR,
+	PERIPHC_I2S3,
+	PERIPHC_I2S4,
+	PERIPHC_I2C4,
+
+	/* 08 */
+	PERIPHC_SBC5,
+	PERIPHC_SBC6,
+	PERIPHC_AUDIO,
+	NONE(APBIF),
+	PERIPHC_DAM0,
+	PERIPHC_DAM1,
+	PERIPHC_DAM2,
+	PERIPHC_HDA2CODEC2X,
+
+	/* 16 */
+	NONE(ATOMICS),
+	NONE(RESERVED17),
+	NONE(RESERVED18),
+	NONE(RESERVED19),
+	NONE(RESERVED20),
+	NONE(RESERVED21),
+	NONE(RESERVED22),
+	PERIPHC_ACTMON,
+
+	/* 24 */
+	NONE(RESERVED24),
+	NONE(RESERVED25),
+	NONE(RESERVED26),
+	NONE(RESERVED27),
+	PERIPHC_SATA,
+	PERIPHC_HDA,
+	NONE(RESERVED30),
+	NONE(RESERVED31),
+
+	/* W word: 31:0 */
+	NONE(HDA2HDMICODEC),
+	NONE(SATACOLD),
+	NONE(RESERVED0_PCIERX0),
+	NONE(RESERVED1_PCIERX1),
+	NONE(RESERVED2_PCIERX2),
+	NONE(RESERVED3_PCIERX3),
+	NONE(RESERVED4_PCIERX4),
+	NONE(RESERVED5_PCIERX5),
+
+	/* 40 */
+	NONE(CEC),
+	NONE(RESERVED6_PCIE2),
+	NONE(RESERVED7_EMC),
+	NONE(RESERVED8_HDMI),
+	NONE(RESERVED9_SATA),
+	NONE(RESERVED10_MIPI),
+	NONE(EX_RESERVED46),
+	NONE(EX_RESERVED47),
+};
+
+/*
+ * Get the oscillator frequency, from the corresponding hardware configuration
+ * field. Note that T30 supports 3 new higher freqs, but we map back
+ * to the old T20 freqs. Support for the higher oscillators is TBD.
+ */
+enum clock_osc_freq clock_get_osc_freq(void)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 reg;
+
+	reg = readl(&clkrst->crc_osc_ctrl);
+	reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
+
+	if (reg & 1)			/* one of the newer freqs */
+		printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg);
+
+	return reg >> 2;	/* Map to most common (T20) freqs */
+}
+
+/* Returns a pointer to the clock source register for a peripheral */
+u32 *get_periph_source_reg(enum periph_id periph_id)
+{
+	struct clk_rst_ctlr *clkrst =
+		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	enum periphc_internal_id internal_id;
+
+	/* Coresight is a special case */
+	if (periph_id == PERIPH_ID_CSI)
+		return &clkrst->crc_clk_src[PERIPH_ID_CSI+1];
+
+	assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT);
+	internal_id = periph_id_to_internal_id[periph_id];
+	assert(internal_id != -1);
+	if (internal_id >= PERIPHC_VW_FIRST) {
+		internal_id -= PERIPHC_VW_FIRST;
+		return &clkrst->crc_clk_src_vw[internal_id];
+	} else
+		return &clkrst->crc_clk_src[internal_id];
+}
+
+/**
+ * Given a peripheral ID and the required source clock, this returns which
+ * value should be programmed into the source mux for that peripheral.
+ *
+ * There is special code here to handle the one source type with 5 sources.
+ *
+ * @param periph_id	peripheral to start
+ * @param source	PLL id of required parent clock
+ * @param mux_bits	Set to number of bits in mux register: 2 or 4
+ * @param divider_bits  Set to number of divider bits (8 or 16)
+ * @return mux value (0-4, or -1 if not found)
+ */
+int get_periph_clock_source(enum periph_id periph_id,
+	enum clock_id parent, int *mux_bits, int *divider_bits)
+{
+	enum clock_type_id type;
+	enum periphc_internal_id internal_id;
+	int mux;
+
+	assert(clock_periph_id_isvalid(periph_id));
+
+	internal_id = periph_id_to_internal_id[periph_id];
+	assert(periphc_internal_id_isvalid(internal_id));
+
+	type = clock_periph_type[internal_id];
+	assert(clock_type_id_isvalid(type));
+
+	*mux_bits = clock_source[type][CLOCK_MAX_MUX];
+
+	if (type == CLOCK_TYPE_PCMT16)
+		*divider_bits = 16;
+	else
+		*divider_bits = 8;
+
+	for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
+		if (clock_source[type][mux] == parent)
+			return mux;
+
+	/* if we get here, either us or the caller has made a mistake */
+	printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id,
+		parent);
+	return -1;
+}
+
+void clock_set_enable(enum periph_id periph_id, int enable)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 *clk;
+	u32 reg;
+
+	/* Enable/disable the clock to this peripheral */
+	assert(clock_periph_id_isvalid(periph_id));
+	if ((int)periph_id < (int)PERIPH_ID_VW_FIRST)
+		clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
+	else
+		clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)];
+	reg = readl(clk);
+	if (enable)
+		reg |= PERIPH_MASK(periph_id);
+	else
+		reg &= ~PERIPH_MASK(periph_id);
+	writel(reg, clk);
+}
+
+void reset_set_enable(enum periph_id periph_id, int enable)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 *reset;
+	u32 reg;
+
+	/* Enable/disable reset to the peripheral */
+	assert(clock_periph_id_isvalid(periph_id));
+	if (periph_id < PERIPH_ID_VW_FIRST)
+		reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
+	else
+		reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)];
+	reg = readl(reset);
+	if (enable)
+		reg |= PERIPH_MASK(periph_id);
+	else
+		reg &= ~PERIPH_MASK(periph_id);
+	writel(reg, reset);
+}
+
+#ifdef CONFIG_OF_CONTROL
+/*
+ * Convert a device tree clock ID to our peripheral ID. They are mostly
+ * the same but we are very cautious so we check that a valid clock ID is
+ * provided.
+ *
+ * @param clk_id	Clock ID according to tegra30 device tree binding
+ * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
+ */
+enum periph_id clk_id_to_periph_id(int clk_id)
+{
+	if (clk_id > PERIPH_ID_COUNT)
+		return PERIPH_ID_NONE;
+
+	switch (clk_id) {
+	case PERIPH_ID_RESERVED3:
+	case PERIPH_ID_RESERVED4:
+	case PERIPH_ID_RESERVED16:
+	case PERIPH_ID_RESERVED24:
+	case PERIPH_ID_RESERVED35:
+	case PERIPH_ID_RESERVED43:
+	case PERIPH_ID_RESERVED45:
+	case PERIPH_ID_RESERVED56:
+	case PERIPH_ID_RESERVED76:
+	case PERIPH_ID_RESERVED77:
+	case PERIPH_ID_RESERVED78:
+	case PERIPH_ID_RESERVED83:
+	case PERIPH_ID_RESERVED89:
+	case PERIPH_ID_RESERVED91:
+	case PERIPH_ID_RESERVED93:
+	case PERIPH_ID_RESERVED94:
+	case PERIPH_ID_RESERVED95:
+		return PERIPH_ID_NONE;
+	default:
+		return clk_id;
+	}
+}
+#endif /* CONFIG_OF_CONTROL */
+
+void clock_early_init(void)
+{
+	/*
+	 * PLLP output frequency set to 408Mhz
+	 * PLLC output frequency set to 228Mhz
+	 */
+	switch (clock_get_osc_freq()) {
+	case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
+		clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8);
+		clock_set_rate(CLOCK_ID_CGENERAL, 456, 12, 1, 8);
+		break;
+
+	case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
+		clock_set_rate(CLOCK_ID_PERIPH, 408, 26, 0, 8);
+		clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8);
+		break;
+
+	case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
+		clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8);
+		clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
+		break;
+	case CLOCK_OSC_FREQ_19_2:
+	default:
+		/*
+		 * These are not supported. It is too early to print a
+		 * message and the UART likely won't work anyway due to the
+		 * oscillator being wrong.
+		 */
+		break;
+	}
+}

+ 57 - 0
arch/arm/cpu/tegra30-common/funcmux.c

@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra30 high-level function multiplexing */
+
+#include <common.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/funcmux.h>
+#include <asm/arch/pinmux.h>
+
+int funcmux_select(enum periph_id id, int config)
+{
+	int bad_config = config != FUNCMUX_DEFAULT;
+
+	switch (id) {
+	case PERIPH_ID_UART1:
+		switch (config) {
+		case FUNCMUX_UART1_ULPI:
+			pinmux_set_func(PINGRP_ULPI_DATA0, PMUX_FUNC_UARTA);
+			pinmux_set_func(PINGRP_ULPI_DATA1, PMUX_FUNC_UARTA);
+			pinmux_set_func(PINGRP_ULPI_DATA2, PMUX_FUNC_UARTA);
+			pinmux_set_func(PINGRP_ULPI_DATA3, PMUX_FUNC_UARTA);
+			pinmux_tristate_disable(PINGRP_ULPI_DATA0);
+			pinmux_tristate_disable(PINGRP_ULPI_DATA1);
+			pinmux_tristate_disable(PINGRP_ULPI_DATA2);
+			pinmux_tristate_disable(PINGRP_ULPI_DATA3);
+			break;
+		}
+		break;
+
+	/* Add other periph IDs here as needed */
+
+	default:
+		debug("%s: invalid periph_id %d", __func__, id);
+		return -1;
+	}
+
+	if (bad_config) {
+		debug("%s: invalid config %d for periph_id %d", __func__,
+		      config, id);
+		return -1;
+	}
+	return 0;
+}

+ 506 - 0
arch/arm/cpu/tegra30-common/pinmux.c

@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra30 pin multiplexing functions */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/tegra.h>
+#include <asm/arch/pinmux.h>
+
+struct tegra_pingroup_desc {
+	const char *name;
+	enum pmux_func funcs[4];
+	enum pmux_func func_safe;
+	enum pmux_vddio vddio;
+	enum pmux_pin_io io;
+};
+
+#define PMUX_MUXCTL_SHIFT	0
+#define PMUX_PULL_SHIFT		2
+#define PMUX_TRISTATE_SHIFT	4
+#define PMUX_TRISTATE_MASK	(1 << PMUX_TRISTATE_SHIFT)
+#define PMUX_IO_SHIFT		5
+#define PMUX_OD_SHIFT		6
+#define PMUX_LOCK_SHIFT		7
+#define PMUX_IO_RESET_SHIFT	8
+
+/* Convenient macro for defining pin group properties */
+#define PIN(pg_name, vdd, f0, f1, f2, f3, iod)	\
+	{						\
+		.vddio = PMUX_VDDIO_ ## vdd,		\
+		.funcs = {				\
+			PMUX_FUNC_ ## f0,		\
+			PMUX_FUNC_ ## f1,		\
+			PMUX_FUNC_ ## f2,		\
+			PMUX_FUNC_ ## f3,		\
+		},					\
+		.func_safe = PMUX_FUNC_RSVD1,		\
+		.io = PMUX_PIN_ ## iod,			\
+	}
+
+/* Input and output pins */
+#define PINI(pg_name, vdd, f0, f1, f2, f3) \
+	PIN(pg_name, vdd, f0, f1, f2, f3, INPUT)
+#define PINO(pg_name, vdd, f0, f1, f2, f3) \
+	PIN(pg_name, vdd, f0, f1, f2, f3, OUTPUT)
+
+const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
+	/*	NAME	  VDD	   f0		f1	   f2	    f3  */
+	PINI(ULPI_DATA0,  BB,	   SPI3,	HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA1,  BB,	   SPI3,	HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA2,  BB,	   SPI3,	HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA3,  BB,	   SPI3,	HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA4,  BB,	   SPI2,	HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA5,  BB,	   SPI2,	HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA6,  BB,	   SPI2,	HSI,	   UARTA,   ULPI),
+	PINI(ULPI_DATA7,  BB,	   SPI2,	HSI,	   UARTA,   ULPI),
+	PINI(ULPI_CLK,	  BB,	   SPI1,	RSVD2,	   UARTD,   ULPI),
+	PINI(ULPI_DIR,	  BB,	   SPI1,	RSVD2,	   UARTD,   ULPI),
+	PINI(ULPI_NXT,	  BB,	   SPI1,	RSVD2,	   UARTD,   ULPI),
+	PINI(ULPI_STP,	  BB,	   SPI1,	RSVD2,	   UARTD,   ULPI),
+	PINI(DAP3_FS,	  BB,	   I2S2,	RSVD2,	   DISPA,   DISPB),
+	PINI(DAP3_DIN,	  BB,	   I2S2,	RSVD2,	   DISPA,   DISPB),
+	PINI(DAP3_DOUT,	  BB,	   I2S2,	RSVD2,	   DISPA,   DISPB),
+	PINI(DAP3_SCLK,	  BB,	   I2S2,	RSVD2,	   DISPA,   DISPB),
+	PINI(GPIO_PV0,	  BB,	   RSVD1,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(GPIO_PV1,	  BB,	   RSVD1,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(SDMMC1_CLK,  SDMMC1,  SDMMC1,	RSVD2,	   RSVD3,   UARTA),
+	PINI(SDMMC1_CMD,  SDMMC1,  SDMMC1,	RSVD2,	   RSVD3,   UARTA),
+	PINI(SDMMC1_DAT3, SDMMC1,  SDMMC1,	RSVD2,	   UARTE,   UARTA),
+	PINI(SDMMC1_DAT2, SDMMC1,  SDMMC1,	RSVD2,	   UARTE,   UARTA),
+	PINI(SDMMC1_DAT1, SDMMC1,  SDMMC1,	RSVD2,	   UARTE,   UARTA),
+	PINI(SDMMC1_DAT0, SDMMC1,  SDMMC1,	RSVD2,	   UARTE,   UARTA),
+	PINI(GPIO_PV2,	  SDMMC1,  OWR,		RSVD2,	   RSVD3,   RSVD4),
+	PINI(GPIO_PV3,	  SDMMC1,  CLK_12M_OUT,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(CLK2_OUT,	  SDMMC1,  EXTPERIPH2,	RSVD2,     RSVD3,   RSVD4),
+	PINI(CLK2_REQ,	  SDMMC1,  DAP,		RSVD2,	   RSVD3,   RSVD4),
+	PINO(LCD_PWR1,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_PWR2,	  LCD,	   DISPA,	DISPB,	   SPI5,    HDCP),
+	PINO(LCD_SDIN,	  LCD,	   DISPA,	DISPB,	   SPI5,    RSVD4),
+	PINO(LCD_SDOUT,	  LCD,	   DISPA,	DISPB,	   SPI5,    HDCP),
+	PINO(LCD_WR_N,	  LCD,	   DISPA,	DISPB,	   SPI5,    HDCP),
+	PINO(LCD_CS0_N,	  LCD,	   DISPA,	DISPB,	   SPI5,    RSVD4),
+	PINO(LCD_DC0,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_SCK,	  LCD,	   DISPA,	DISPB,	   SPI5,    HDCP),
+	PINO(LCD_PWR0,	  LCD,	   DISPA,	DISPB,	   SPI5,    HDCP),
+	PINO(LCD_PCLK,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_DE,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_HSYNC,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_VSYNC,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D0,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D1,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D2,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D3,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D4,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D5,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D6,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D7,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D8,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D9,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D10,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D11,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D12,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D13,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D14,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D15,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D16,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D17,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D18,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D19,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D20,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D21,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D22,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_D23,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_CS1_N,	  LCD,	   DISPA,	DISPB,	   SPI5,    RSVD4),
+	PINO(LCD_M1,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINO(LCD_DC1,	  LCD,	   DISPA,	DISPB,	   RSVD3,   RSVD4),
+	PINI(HDMI_INT,	  LCD,	   HDMI,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(DDC_SCL,	  LCD,	   I2C4,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(DDC_SDA,	  LCD,	   I2C4,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(CRT_HSYNC,	  LCD,	   CRT,		RSVD2,	   RSVD3,   RSVD4),
+	PINI(CRT_VSYNC,	  LCD,	   CRT,		RSVD2,	   RSVD3,   RSVD4),
+	PINI(VI_D0,	  VI,	   DDR,		RSVD2,	   VI,      RSVD4),
+	PINI(VI_D1,	  VI,	   DDR,		SDMMC2,	   VI,      RSVD4),
+	PINI(VI_D2,	  VI,	   DDR,		SDMMC2,	   VI,      RSVD4),
+	PINI(VI_D3,	  VI,	   DDR,		SDMMC2,	   VI,      RSVD4),
+	PINI(VI_D4,	  VI,	   DDR,		SDMMC2,	   VI,      RSVD4),
+	PINI(VI_D5,	  VI,	   DDR,		SDMMC2,	   VI,      RSVD4),
+	PINI(VI_D6,	  VI,	   DDR,		SDMMC2,	   VI,      RSVD4),
+	PINI(VI_D7,	  VI,	   DDR,		SDMMC2,	   VI,      RSVD4),
+	PINI(VI_D8,	  VI,	   DDR,		SDMMC2,	   VI,      RSVD4),
+	PINI(VI_D9,	  VI,	   DDR,		SDMMC2,	   VI,      RSVD4),
+	PINI(VI_D10,	  VI,	   DDR,		RSVD2,	   VI,      RSVD4),
+	PINI(VI_D11,	  VI,	   DDR,		RSVD2,	   VI,      RSVD4),
+	PINI(VI_PCLK,	  VI,	   RSVD1,	SDMMC2,	   VI,      RSVD4),
+	PINI(VI_MCLK,	  VI,	   VI,		VI,	   VI,      VI),
+	PINI(VI_VSYNC,	  VI,	   DDR,		RSVD2,	   VI,      RSVD4),
+	PINI(VI_HSYNC,	  VI,	   DDR,		RSVD2,	   VI,      RSVD4),
+	PINI(UART2_RXD,	  UART,	   UARTB,	SPDIF,	   UARTA,   SPI4),
+	PINI(UART2_TXD,	  UART,	   UARTB,	SPDIF,	   UARTA,   SPI4),
+	PINI(UART2_RTS_N, UART,	   UARTA,	UARTB,	   GMI,     SPI4),
+	PINI(UART2_CTS_N, UART,	   UARTA,	UARTB,	   GMI,     SPI4),
+	PINI(UART3_TXD,	  UART,	   UARTC,	RSVD2,	   GMI,     RSVD4),
+	PINI(UART3_RXD,	  UART,	   UARTC,	RSVD2,	   GMI,     RSVD4),
+	PINI(UART3_CTS_N, UART,	   UARTC,	RSVD2,	   GMI,     RSVD4),
+	PINI(UART3_RTS_N, UART,	   UARTC,	PWM0,	   GMI,     RSVD4),
+	PINI(GPIO_PU0,	  UART,	   OWR,		UARTA,	   GMI,     RSVD4),
+	PINI(GPIO_PU1,	  UART,	   RSVD1,	UARTA,	   GMI,     RSVD4),
+	PINI(GPIO_PU2,	  UART,	   RSVD1,	UARTA,	   GMI,     RSVD4),
+	PINI(GPIO_PU3,	  UART,	   PWM0,	UARTA,	   GMI,     RSVD4),
+	PINI(GPIO_PU4,	  UART,	   PWM1,	UARTA,	   GMI,     RSVD4),
+	PINI(GPIO_PU5,	  UART,	   PWM2,	UARTA,	   GMI,     RSVD4),
+	PINI(GPIO_PU6,	  UART,	   PWM3,	UARTA,	   GMI,     RSVD4),
+	PINI(GEN1_I2C_SDA, UART,   I2C1,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(GEN1_I2C_SCL, UART,   I2C1,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(DAP4_FS,	  UART,	   I2S3,	RSVD2,	   GMI,     RSVD4),
+	PINI(DAP4_DIN,	  UART,	   I2S3,	RSVD2,	   GMI,     RSVD4),
+	PINI(DAP4_DOUT,	  UART,	   I2S3,	RSVD2,	   GMI,     RSVD4),
+	PINI(DAP4_SCLK,	  UART,	   I2S3,	RSVD2,	   GMI,     RSVD4),
+	PINI(CLK3_OUT,	  UART,	   EXTPERIPH3,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(CLK3_REQ,	  UART,	   DEV3,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(GMI_WP_N,	  GMI,	   RSVD1,	NAND,	   GMI,     GMI_ALT),
+	PINI(GMI_IORDY,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_WAIT,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_ADV_N,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_CLK,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_CS0_N,	  GMI,	   RSVD1,	NAND,	   GMI,     DTV),
+	PINI(GMI_CS1_N,	  GMI,	   RSVD1,	NAND,	   GMI,     DTV),
+	PINI(GMI_CS2_N,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_CS3_N,	  GMI,	   RSVD1,	NAND,	   GMI,     GMI_ALT),
+	PINI(GMI_CS4_N,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_CS6_N,	  GMI,	   NAND,	NAND_ALT,  GMI,     SATA),
+	PINI(GMI_CS7_N,	  GMI,	   NAND,	NAND_ALT,  GMI,     GMI_ALT),
+	PINI(GMI_AD0,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD1,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD2,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD3,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD4,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD5,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD6,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD7,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD8,	  GMI,	   PWM0,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD9,	  GMI,	   PWM1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD10,	  GMI,	   PWM2,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD11,	  GMI,	   PWM3,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD12,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD13,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD14,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_AD15,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_A16,	  GMI,	   UARTD,	SPI4,	   GMI,     GMI_ALT),
+	PINI(GMI_A17,	  GMI,	   UARTD,	SPI4,	   GMI,     DTV),
+	PINI(GMI_A18,	  GMI,	   UARTD,	SPI4,	   GMI,     DTV),
+	PINI(GMI_A19,	  GMI,	   UARTD,	SPI4,	   GMI,     RSVD4),
+	PINI(GMI_WR_N,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_OE_N,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_DQS,	  GMI,	   RSVD1,	NAND,	   GMI,     RSVD4),
+	PINI(GMI_RST_N,	  GMI,	   NAND,	NAND_ALT,  GMI,     RSVD4),
+	PINI(GEN2_I2C_SCL, GMI,	   I2C2,	HDCP,	   GMI,     RSVD4),
+	PINI(GEN2_I2C_SDA, GMI,    I2C2,	HDCP,	   GMI,     RSVD4),
+	PINI(SDMMC4_CLK,  SDMMC4,   RSVD1,	NAND,	   GMI,     SDMMC4),
+	PINI(SDMMC4_CMD,  SDMMC4,   I2C3,	NAND,	   GMI,     SDMMC4),
+	PINI(SDMMC4_DAT0, SDMMC4,   UARTE,	SPI3,	   GMI,     SDMMC4),
+	PINI(SDMMC4_DAT1, SDMMC4,   UARTE,	SPI3,	   GMI,     SDMMC4),
+	PINI(SDMMC4_DAT2, SDMMC4,   UARTE,	SPI3,	   GMI,     SDMMC4),
+	PINI(SDMMC4_DAT3, SDMMC4,   UARTE,	SPI3,	   GMI,     SDMMC4),
+	PINI(SDMMC4_DAT4, SDMMC4,   I2C3,	I2S4,	   GMI,     SDMMC4),
+	PINI(SDMMC4_DAT5, SDMMC4,   VGP3,	I2S4,	   GMI,     SDMMC4),
+	PINI(SDMMC4_DAT6, SDMMC4,   VGP4,	I2S4,	   GMI,     SDMMC4),
+	PINI(SDMMC4_DAT7, SDMMC4,   VGP5,	I2S4,	   GMI,     SDMMC4),
+	PINI(SDMMC4_RST_N, SDMMC4,  VGP6,	RSVD2,	   RSVD3,   SDMMC4),
+	PINI(CAM_MCLK,	  CAM,	   VI,		RSVD2,	   VI_ALT2, SDMMC4),
+	PINI(GPIO_PCC1,	  CAM,	   I2S4,	RSVD2,	   RSVD3,   SDMMC4),
+	PINI(GPIO_PBB0,	  CAM,	   I2S4,	RSVD2,	   RSVD3,   SDMMC4),
+	PINI(CAM_I2C_SCL, CAM,	   VGP1,	I2C3,	   RSVD3,   SDMMC4),
+	PINI(CAM_I2C_SDA, CAM,	   VGP2,	I2C3,	   RSVD3,   SDMMC4),
+	PINI(GPIO_PBB3,	  CAM,	   VGP3,	DISPA,	   DISPB,   SDMMC4),
+	PINI(GPIO_PBB4,	  CAM,	   VGP4,	DISPA,	   DISPB,   SDMMC4),
+	PINI(GPIO_PBB5,	  CAM,	   VGP5,	DISPA,	   DISPB,   SDMMC4),
+	PINI(GPIO_PBB6,	  CAM,	   VGP6,	DISPA,	   DISPB,   SDMMC4),
+	PINI(GPIO_PBB7,	  CAM,	   I2S4,	RSVD2,	   RSVD3,   SDMMC4),
+	PINI(GPIO_PCC2,	  CAM,	   I2S4,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(JTAG_RTCK,	  SYS,	   RTCK,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(PWR_I2C_SCL, SYS,	   I2CPWR,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(PWR_I2C_SDA, SYS,	   I2CPWR,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(KB_ROW0,	  SYS,	   KBC,		NAND,	   RSVD3,   RSVD4),
+	PINI(KB_ROW1,	  SYS,	   KBC,		NAND,	   RSVD3,   RSVD4),
+	PINI(KB_ROW2,	  SYS,	   KBC,		NAND,	   RSVD3,   RSVD4),
+	PINI(KB_ROW3,	  SYS,	   KBC,		NAND,	   RSVD3,   RSVD4),
+	PINI(KB_ROW4,	  SYS,	   KBC,		NAND,	   TRACE,   RSVD4),
+	PINI(KB_ROW5,	  SYS,	   KBC,		NAND,	   TRACE,   OWR),
+	PINI(KB_ROW6,	  SYS,	   KBC,		NAND,	   SDMMC2,  MIO),
+	PINI(KB_ROW7,	  SYS,	   KBC,		NAND,	   SDMMC2,  MIO),
+	PINI(KB_ROW8,	  SYS,	   KBC,		NAND,	   SDMMC2,  MIO),
+	PINI(KB_ROW9,	  SYS,	   KBC,		NAND,	   SDMMC2,  MIO),
+	PINI(KB_ROW10,	  SYS,	   KBC,		NAND,	   SDMMC2,  MIO),
+	PINI(KB_ROW11,	  SYS,	   KBC,		NAND,	   SDMMC2,  MIO),
+	PINI(KB_ROW12,	  SYS,	   KBC,		NAND,	   SDMMC2,  MIO),
+	PINI(KB_ROW13,	  SYS,	   KBC,		NAND,	   SDMMC2,  MIO),
+	PINI(KB_ROW14,	  SYS,	   KBC,		NAND,	   SDMMC2,  MIO),
+	PINI(KB_ROW15,	  SYS,	   KBC,		NAND,	   SDMMC2,  MIO),
+	PINI(KB_COL0,	  SYS,	   KBC,		NAND,	   TRACE,   TEST),
+	PINI(KB_COL1,	  SYS,	   KBC,		NAND,	   TRACE,   TEST),
+	PINI(KB_COL2,	  SYS,	   KBC,		NAND,	   TRACE,   RSVD4),
+	PINI(KB_COL3,	  SYS,	   KBC,		NAND,	   TRACE,   RSVD4),
+	PINI(KB_COL4,	  SYS,	   KBC,		NAND,	   TRACE,   RSVD4),
+	PINI(KB_COL5,	  SYS,	   KBC,		NAND,	   TRACE,   RSVD4),
+	PINI(KB_COL6,	  SYS,	   KBC,		NAND,	   TRACE,   MIO),
+	PINI(KB_COL7,	  SYS,	   KBC,		NAND,	   TRACE,   MIO),
+	PINI(CLK_32K_OUT, SYS,	   BLINK,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(SYS_CLK_REQ, SYS,	   SYSCLK,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(CORE_PWR_REQ, SYS,	   CORE_PWR_REQ, RSVD2,	   RSVD3,   RSVD4),
+	PINI(CPU_PWR_REQ, SYS,	   CPU_PWR_REQ,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(PWR_INT_N,	  SYS,	   PWR_INT_N,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(CLK_32K_IN,  SYS,	   CLK_32K_IN,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(OWR,	  SYS,	   OWR,		CEC,	   RSVD3,   RSVD4),
+	PINI(DAP1_FS,	  AUDIO,   I2S0,	HDA,	   GMI,     SDMMC2),
+	PINI(DAP1_DIN,	  AUDIO,   I2S0,	HDA,	   GMI,     SDMMC2),
+	PINI(DAP1_DOUT,	  AUDIO,   I2S0,	HDA,	   GMI,     SDMMC2),
+	PINI(DAP1_SCLK,	  AUDIO,   I2S0,	HDA,	   GMI,     SDMMC2),
+	PINI(CLK1_REQ,	  AUDIO,   DAP,		HDA,	   RSVD3,   RSVD4),
+	PINI(CLK1_OUT,	  AUDIO,   EXTPERIPH1,	RSVD2,	   RSVD3,   RSVD4),
+	PINI(SPDIF_IN,	  AUDIO,   SPDIF,	HDA,	   I2C1,    SDMMC2),
+	PINI(SPDIF_OUT,	  AUDIO,   SPDIF,	RSVD2,	   I2C1,    SDMMC2),
+	PINI(DAP2_FS,	  AUDIO,   I2S1,	HDA,	   RSVD3,   GMI),
+	PINI(DAP2_DIN,	  AUDIO,   I2S1,	HDA,	   RSVD3,   GMI),
+	PINI(DAP2_DOUT,	  AUDIO,   I2S1,	HDA,	   RSVD3,   GMI),
+	PINI(DAP2_SCLK,	  AUDIO,   I2S1,	HDA,	   RSVD3,   GMI),
+	PINI(SPI2_MOSI,	  AUDIO,   SPI6,	SPI2,	   GMI,     GMI),
+	PINI(SPI2_MISO,	  AUDIO,   SPI6,	SPI2,	   GMI,     GMI),
+	PINI(SPI2_CS0_N,  AUDIO,   SPI6,	SPI2,	   GMI,     GMI),
+	PINI(SPI2_SCK,	  AUDIO,   SPI6,	SPI2,	   GMI,     GMI),
+	PINI(SPI1_MOSI,	  AUDIO,   SPI2,	SPI1,	   SPI2_ALT, GMI),
+	PINI(SPI1_SCK,	  AUDIO,   SPI2,	SPI1,	   SPI2_ALT, GMI),
+	PINI(SPI1_CS0_N,  AUDIO,   SPI2,	SPI1,	   SPI2_ALT, GMI),
+	PINI(SPI1_MISO,	  AUDIO,   SPI3,	SPI1,	   SPI2_ALT, RSVD4),
+	PINI(SPI2_CS1_N,  AUDIO,   SPI3,	SPI2,	   SPI2_ALT, I2C1),
+	PINI(SPI2_CS2_N,  AUDIO,   SPI3,	SPI2,	   SPI2_ALT, I2C1),
+	PINI(SDMMC3_CLK,  SDMMC3,  UARTA,	PWM2,	   SDMMC3,  SPI3),
+	PINI(SDMMC3_CMD,  SDMMC3,  UARTA,	PWM3,	   SDMMC3,  SPI2),
+	PINI(SDMMC3_DAT0, SDMMC3,  RSVD1,	RSVD2,	   SDMMC3,  SPI3),
+	PINI(SDMMC3_DAT1, SDMMC3,  RSVD1,	RSVD2,	   SDMMC3,  SPI3),
+	PINI(SDMMC3_DAT2, SDMMC3,  RSVD1,	PWM1,	   SDMMC3,  SPI3),
+	PINI(SDMMC3_DAT3, SDMMC3,  RSVD1,	PWM0,	   SDMMC3,  SPI3),
+	PINI(SDMMC3_DAT4, SDMMC3,  PWM1,	SPI4,	   SDMMC3,  SPI2),
+	PINI(SDMMC3_DAT5, SDMMC3,  PWM0,	SPI4,	   SDMMC3,  SPI2),
+	PINI(SDMMC3_DAT6, SDMMC3,  SPDIF,	SPI4,	   SDMMC3,  SPI2),
+	PINI(SDMMC3_DAT7, SDMMC3,  SPDIF,	SPI4,	   SDMMC3,  SPI2),
+	PINI(PEX_L0_PRSNT_N,	PEXCTL,   PCIE,	HDA,	   RSVD3,   RSVD4),
+	PINI(PEX_L0_RST_N,	PEXCTL,   PCIE,	HDA,	   RSVD3,   RSVD4),
+	PINI(PEX_L0_CLKREQ_N,	PEXCTL,   PCIE,	HDA,	   RSVD3,   RSVD4),
+	PINI(PEX_WAKE_N,	PEXCTL,   PCIE,	HDA,	   RSVD3,   RSVD4),
+	PINI(PEX_L1_PRSNT_N,	PEXCTL,   PCIE,	HDA,	   RSVD3,   RSVD4),
+	PINI(PEX_L1_RST_N,	PEXCTL,   PCIE,	HDA,	   RSVD3,   RSVD4),
+	PINI(PEX_L1_CLKREQ_N,	PEXCTL,   PCIE,	HDA,	   RSVD3,   RSVD4),
+	PINI(PEX_L2_PRSNT_N,	PEXCTL,   PCIE,	HDA,	   RSVD3,   RSVD4),
+	PINI(PEX_L2_RST_N,	PEXCTL,   PCIE,	HDA,	   RSVD3,   RSVD4),
+	PINI(PEX_L2_CLKREQ_N,	PEXCTL,   PCIE,	HDA,	   RSVD3,   RSVD4),
+	PINI(HDMI_CEC,		SYS,      CEC,	RSVD2,	   RSVD3,   RSVD4),
+};
+
+void pinmux_set_tristate(enum pmux_pingrp pin, int enable)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *tri = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin */
+	assert(pmux_pingrp_isvalid(pin));
+
+	reg = readl(tri);
+	if (enable)
+		reg |= PMUX_TRISTATE_MASK;
+	else
+		reg &= ~PMUX_TRISTATE_MASK;
+	writel(reg, tri);
+}
+
+void pinmux_tristate_enable(enum pmux_pingrp pin)
+{
+	pinmux_set_tristate(pin, 1);
+}
+
+void pinmux_tristate_disable(enum pmux_pingrp pin)
+{
+	pinmux_set_tristate(pin, 0);
+}
+
+void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *pull = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin and pupd */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_pupd_isvalid(pupd));
+
+	reg = readl(pull);
+	reg &= ~(0x3 << PMUX_PULL_SHIFT);
+	reg |= (pupd << PMUX_PULL_SHIFT);
+	writel(reg, pull);
+}
+
+void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *muxctl = &pmt->pmt_ctl[pin];
+	int i, mux = -1;
+	u32 reg;
+
+	/* Error check on pin and func */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_func_isvalid(func));
+
+	/* Handle special values */
+	if (func == PMUX_FUNC_SAFE)
+		func = tegra_soc_pingroups[pin].func_safe;
+
+	if (func & PMUX_FUNC_RSVD1) {
+		mux = func & 0x3;
+	} else {
+		/* Search for the appropriate function */
+		for (i = 0; i < 4; i++) {
+			if (tegra_soc_pingroups[pin].funcs[i] == func) {
+				mux = i;
+				break;
+			}
+		}
+	}
+	assert(mux != -1);
+
+	reg = readl(muxctl);
+	reg &= ~(0x3 << PMUX_MUXCTL_SHIFT);
+	reg |= (mux << PMUX_MUXCTL_SHIFT);
+	writel(reg, muxctl);
+
+}
+
+void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *pin_io = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin and io */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_io_isvalid(io));
+
+	reg = readl(pin_io);
+	reg &= ~(0x1 << PMUX_IO_SHIFT);
+	reg |= (io & 0x1) << PMUX_IO_SHIFT;
+	writel(reg, pin_io);
+}
+
+static int pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *pin_lock = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin and lock */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_lock_isvalid(lock));
+
+	if (lock == PMUX_PIN_LOCK_DEFAULT)
+		return 0;
+
+	reg = readl(pin_lock);
+	reg &= ~(0x1 << PMUX_LOCK_SHIFT);
+	if (lock == PMUX_PIN_LOCK_ENABLE)
+		reg |= (0x1 << PMUX_LOCK_SHIFT);
+	else {
+		/* lock == DISABLE, which isn't possible */
+		printf("%s: Warning: lock == %d, DISABLE is not allowed!\n",
+			__func__, lock);
+	}
+	writel(reg, pin_lock);
+
+	return 0;
+}
+
+static int pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *pin_od = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin and od */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_od_isvalid(od));
+
+	if (od == PMUX_PIN_OD_DEFAULT)
+		return 0;
+
+	reg = readl(pin_od);
+	reg &= ~(0x1 << PMUX_OD_SHIFT);
+	if (od == PMUX_PIN_OD_ENABLE)
+		reg |= (0x1 << PMUX_OD_SHIFT);
+	writel(reg, pin_od);
+
+	return 0;
+}
+
+static int pinmux_set_ioreset(enum pmux_pingrp pin,
+				enum pmux_pin_ioreset ioreset)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *pin_ioreset = &pmt->pmt_ctl[pin];
+	u32 reg;
+
+	/* Error check on pin and ioreset */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_ioreset_isvalid(ioreset));
+
+	if (ioreset == PMUX_PIN_IO_RESET_DEFAULT)
+		return 0;
+
+	reg = readl(pin_ioreset);
+	reg &= ~(0x1 << PMUX_IO_RESET_SHIFT);
+	if (ioreset == PMUX_PIN_IO_RESET_ENABLE)
+		reg |= (0x1 << PMUX_IO_RESET_SHIFT);
+	writel(reg, pin_ioreset);
+
+	return 0;
+}
+
+void pinmux_config_pingroup(struct pingroup_config *config)
+{
+	enum pmux_pingrp pin = config->pingroup;
+
+	pinmux_set_func(pin, config->func);
+	pinmux_set_pullupdown(pin, config->pull);
+	pinmux_set_tristate(pin, config->tristate);
+	pinmux_set_io(pin, config->io);
+	pinmux_set_lock(pin, config->lock);
+	pinmux_set_od(pin, config->od);
+	pinmux_set_ioreset(pin, config->ioreset);
+}
+
+void pinmux_config_table(struct pingroup_config *config, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		pinmux_config_pingroup(&config[i]);
+}

+ 5 - 0
arch/arm/dts/tegra114.dtsi

@@ -0,0 +1,5 @@
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "nvidia,tegra114";
+};

+ 217 - 195
arch/arm/dts/tegra20.dtsi

@@ -4,19 +4,101 @@
 	compatible = "nvidia,tegra20";
 	compatible = "nvidia,tegra20";
 	interrupt-parent = <&intc>;
 	interrupt-parent = <&intc>;
 
 
-	tegra_car: clock@60006000 {
-		compatible = "nvidia,tegra20-car";
-		reg = <0x60006000 0x1000>;
-		#clock-cells = <1>;
-	};
+	host1x {
+		compatible = "nvidia,tegra20-host1x", "simple-bus";
+		reg = <0x50000000 0x00024000>;
+		interrupts = <0 65 0x04   /* mpcore syncpt */
+			      0 67 0x04>; /* mpcore general */
+		status = "disabled";
 
 
-	clocks {
 		#address-cells = <1>;
 		#address-cells = <1>;
-		#size-cells = <0>;
+		#size-cells = <1>;
+
+		ranges = <0x54000000 0x54000000 0x04000000>;
+
+		/* video-encoding/decoding */
+		mpe {
+			reg = <0x54040000 0x00040000>;
+			interrupts = <0 68 0x04>;
+			status = "disabled";
+		};
+
+		/* video input */
+		vi {
+			reg = <0x54080000 0x00040000>;
+			interrupts = <0 69 0x04>;
+			status = "disabled";
+		};
+
+		/* EPP */
+		epp {
+			reg = <0x540c0000 0x00040000>;
+			interrupts = <0 70 0x04>;
+			status = "disabled";
+		};
+
+		/* ISP */
+		isp {
+			reg = <0x54100000 0x00040000>;
+			interrupts = <0 71 0x04>;
+			status = "disabled";
+		};
+
+		/* 2D engine */
+		gr2d {
+			reg = <0x54140000 0x00040000>;
+			interrupts = <0 72 0x04>;
+			status = "disabled";
+		};
+
+		/* 3D engine */
+		gr3d {
+			reg = <0x54180000 0x00040000>;
+			status = "disabled";
+		};
+
+		/* display controllers */
+		dc@54200000 {
+			compatible = "nvidia,tegra20-dc";
+			reg = <0x54200000 0x00040000>;
+			interrupts = <0 73 0x04>;
+			status = "disabled";
+
+			rgb {
+				status = "disabled";
+			};
+		};
+
+		dc@54240000 {
+			compatible = "nvidia,tegra20-dc";
+			reg = <0x54240000 0x00040000>;
+			interrupts = <0 74 0x04>;
+			status = "disabled";
+
+			rgb {
+				status = "disabled";
+			};
+		};
+
+		/* outputs */
+		hdmi {
+			compatible = "nvidia,tegra20-hdmi";
+			reg = <0x54280000 0x00040000>;
+			interrupts = <0 75 0x04>;
+			status = "disabled";
+		};
 
 
-		osc: clock {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
+		tvo {
+			compatible = "nvidia,tegra20-tvo";
+			reg = <0x542c0000 0x00040000>;
+			interrupts = <0 76 0x04>;
+			status = "disabled";
+		};
+
+		dsi {
+			compatible = "nvidia,tegra20-dsi";
+			reg = <0x54300000 0x00040000>;
+			status = "disabled";
 		};
 		};
 	};
 	};
 
 
@@ -28,44 +110,54 @@
 		      < 0x50040100 0x0100 >;
 		      < 0x50040100 0x0100 >;
 	};
 	};
 
 
-	i2c@7000c000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "nvidia,tegra20-i2c";
-		reg = <0x7000C000 0x100>;
-		interrupts = < 70 >;
-		/* PERIPH_ID_I2C1, PLL_P_OUT3 */
-		clocks = <&tegra_car 12>, <&tegra_car 124>;
+	tegra_car: clock@60006000 {
+		compatible = "nvidia,tegra20-car";
+		reg = <0x60006000 0x1000>;
+		#clock-cells = <1>;
 	};
 	};
 
 
-	i2c@7000c400 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "nvidia,tegra20-i2c";
-		reg = <0x7000C400 0x100>;
-		interrupts = < 116 >;
-		/* PERIPH_ID_I2C2, PLL_P_OUT3 */
-		clocks = <&tegra_car 54>, <&tegra_car 124>;
+	apbdma: dma {
+		compatible = "nvidia,tegra20-apbdma";
+		reg = <0x6000a000 0x1200>;
+		interrupts = <0 104 0x04
+			      0 105 0x04
+			      0 106 0x04
+			      0 107 0x04
+			      0 108 0x04
+			      0 109 0x04
+			      0 110 0x04
+			      0 111 0x04
+			      0 112 0x04
+			      0 113 0x04
+			      0 114 0x04
+			      0 115 0x04
+			      0 116 0x04
+			      0 117 0x04
+			      0 118 0x04
+			      0 119 0x04>;
 	};
 	};
 
 
-	i2c@7000c500 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "nvidia,tegra20-i2c";
-		reg = <0x7000C500 0x100>;
-		interrupts = < 124 >;
-		/* PERIPH_ID_I2C3, PLL_P_OUT3 */
-		clocks = <&tegra_car 67>, <&tegra_car 124>;
+	gpio: gpio@6000d000 {
+		compatible = "nvidia,tegra20-gpio";
+		reg = < 0x6000d000 0x1000 >;
+		interrupts = < 64 65 66 67 87 119 121 >;
+		#gpio-cells = <2>;
+		gpio-controller;
 	};
 	};
 
 
-	i2c@7000d000 {
+	pinmux: pinmux@70000000 {
+		compatible = "nvidia,tegra20-pinmux";
+		reg = < 0x70000014 0x10    /* Tri-state registers */
+			0x70000080 0x20    /* Mux registers */
+			0x700000a0 0x14    /* Pull-up/down registers */
+			0x70000868 0xa8 >; /* Pad control registers */
+	};
+
+	das@70000c00 {
 		#address-cells = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#size-cells = <0>;
-		compatible = "nvidia,tegra20-i2c-dvc";
-		reg = <0x7000D000 0x200>;
-		interrupts = < 85 >;
-		/* PERIPH_ID_DVC_I2C, PLL_P_OUT3 */
-		clocks = <&tegra_car 47>, <&tegra_car 124>;
+		compatible = "nvidia,tegra20-das";
+		reg = <0x70000c00 0x80>;
 	};
 	};
 
 
 	i2s@70002800 {
 	i2s@70002800 {
@@ -86,29 +178,6 @@
 		dma-channel = < 1 >;
 		dma-channel = < 1 >;
 	};
 	};
 
 
-	das@70000c00 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "nvidia,tegra20-das";
-		reg = <0x70000c00 0x80>;
-	};
-
-	gpio: gpio@6000d000 {
-		compatible = "nvidia,tegra20-gpio";
-		reg = < 0x6000d000 0x1000 >;
-		interrupts = < 64 65 66 67 87 119 121 >;
-		#gpio-cells = <2>;
-		gpio-controller;
-	};
-
-	pinmux: pinmux@70000000 {
-		compatible = "nvidia,tegra20-pinmux";
-		reg = < 0x70000014 0x10    /* Tri-state registers */
-			0x70000080 0x20    /* Mux registers */
-			0x700000a0 0x14    /* Pull-up/down registers */
-			0x70000868 0xa8 >; /* Pad control registers */
-	};
-
 	serial@70006000 {
 	serial@70006000 {
 		compatible = "nvidia,tegra20-uart";
 		compatible = "nvidia,tegra20-uart";
 		reg = <0x70006000 0x40>;
 		reg = <0x70006000 0x40>;
@@ -144,28 +213,81 @@
 		interrupts = < 123 >;
 		interrupts = < 123 >;
 	};
 	};
 
 
-	sdhci@c8000000 {
-		compatible = "nvidia,tegra20-sdhci";
-		reg = <0xc8000000 0x200>;
-		interrupts = < 46 >;
+	nand: nand-controller@70008000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra20-nand";
+		reg = <0x70008000 0x100>;
 	};
 	};
 
 
-	sdhci@c8000200 {
-		compatible = "nvidia,tegra20-sdhci";
-		reg = <0xc8000200 0x200>;
-		interrupts = < 47 >;
+	pwm: pwm@7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
 	};
 	};
 
 
-	sdhci@c8000400 {
-		compatible = "nvidia,tegra20-sdhci";
-		reg = <0xc8000400 0x200>;
-		interrupts = < 51 >;
+	i2c@7000c000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra20-i2c";
+		reg = <0x7000C000 0x100>;
+		interrupts = < 70 >;
+		/* PERIPH_ID_I2C1, PLL_P_OUT3 */
+		clocks = <&tegra_car 12>, <&tegra_car 124>;
 	};
 	};
 
 
-	sdhci@c8000600 {
-		compatible = "nvidia,tegra20-sdhci";
-		reg = <0xc8000600 0x200>;
-		interrupts = < 63 >;
+	spi@7000c380 {
+		compatible = "nvidia,tegra20-sflash";
+		reg = <0x7000c380 0x80>;
+		interrupts = <0 39 0x04>;
+		nvidia,dma-request-selector = <&apbdma 11>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+		/* PERIPH_ID_SPI1, PLLP_OUT0 */
+		clocks = <&tegra_car 43>;
+	};
+
+	i2c@7000c400 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra20-i2c";
+		reg = <0x7000C400 0x100>;
+		interrupts = < 116 >;
+		/* PERIPH_ID_I2C2, PLL_P_OUT3 */
+		clocks = <&tegra_car 54>, <&tegra_car 124>;
+	};
+
+	i2c@7000c500 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra20-i2c";
+		reg = <0x7000C500 0x100>;
+		interrupts = < 124 >;
+		/* PERIPH_ID_I2C3, PLL_P_OUT3 */
+		clocks = <&tegra_car 67>, <&tegra_car 124>;
+	};
+
+	i2c@7000d000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra20-i2c-dvc";
+		reg = <0x7000D000 0x200>;
+		interrupts = < 85 >;
+		/* PERIPH_ID_DVC_I2C, PLL_P_OUT3 */
+		clocks = <&tegra_car 47>, <&tegra_car 124>;
+	};
+
+	kbc@7000e200 {
+		compatible = "nvidia,tegra20-kbc";
+		reg = <0x7000e200 0x0078>;
+	};
+
+	emc@7000f400 {
+		#address-cells = < 1 >;
+		#size-cells = < 0 >;
+		compatible = "nvidia,tegra20-emc";
+		reg = <0x7000f400 0x200>;
 	};
 	};
 
 
 	usb@c5000000 {
 	usb@c5000000 {
@@ -193,127 +315,27 @@
 		clocks = <&tegra_car 59>;	/* PERIPH_ID_USB3 */
 		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>;
+	sdhci@c8000000 {
+		compatible = "nvidia,tegra20-sdhci";
+		reg = <0xc8000000 0x200>;
+		interrupts = < 46 >;
 	};
 	};
 
 
-	nand: nand-controller@70008000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "nvidia,tegra20-nand";
-		reg = <0x70008000 0x100>;
+	sdhci@c8000200 {
+		compatible = "nvidia,tegra20-sdhci";
+		reg = <0xc8000200 0x200>;
+		interrupts = < 47 >;
 	};
 	};
 
 
-	pwm: pwm@7000a000 {
-		compatible = "nvidia,tegra20-pwm";
-		reg = <0x7000a000 0x100>;
-		#pwm-cells = <2>;
+	sdhci@c8000400 {
+		compatible = "nvidia,tegra20-sdhci";
+		reg = <0xc8000400 0x200>;
+		interrupts = < 51 >;
 	};
 	};
 
 
-	host1x {
-		compatible = "nvidia,tegra20-host1x", "simple-bus";
-		reg = <0x50000000 0x00024000>;
-		interrupts = <0 65 0x04   /* mpcore syncpt */
-			      0 67 0x04>; /* mpcore general */
-		status = "disabled";
-
-		#address-cells = <1>;
-		#size-cells = <1>;
-
-		ranges = <0x54000000 0x54000000 0x04000000>;
-
-		/* video-encoding/decoding */
-		mpe {
-			reg = <0x54040000 0x00040000>;
-			interrupts = <0 68 0x04>;
-			status = "disabled";
-		};
-
-		/* video input */
-		vi {
-			reg = <0x54080000 0x00040000>;
-			interrupts = <0 69 0x04>;
-			status = "disabled";
-		};
-
-		/* EPP */
-		epp {
-			reg = <0x540c0000 0x00040000>;
-			interrupts = <0 70 0x04>;
-			status = "disabled";
-		};
-
-		/* ISP */
-		isp {
-			reg = <0x54100000 0x00040000>;
-			interrupts = <0 71 0x04>;
-			status = "disabled";
-		};
-
-		/* 2D engine */
-		gr2d {
-			reg = <0x54140000 0x00040000>;
-			interrupts = <0 72 0x04>;
-			status = "disabled";
-		};
-
-		/* 3D engine */
-		gr3d {
-			reg = <0x54180000 0x00040000>;
-			status = "disabled";
-		};
-
-		/* display controllers */
-		dc@54200000 {
-			compatible = "nvidia,tegra20-dc";
-			reg = <0x54200000 0x00040000>;
-			interrupts = <0 73 0x04>;
-			status = "disabled";
-
-			rgb {
-				status = "disabled";
-			};
-		};
-
-		dc@54240000 {
-			compatible = "nvidia,tegra20-dc";
-			reg = <0x54240000 0x00040000>;
-			interrupts = <0 74 0x04>;
-			status = "disabled";
-
-			rgb {
-				status = "disabled";
-			};
-		};
-
-		/* outputs */
-		hdmi {
-			compatible = "nvidia,tegra20-hdmi";
-			reg = <0x54280000 0x00040000>;
-			interrupts = <0 75 0x04>;
-			status = "disabled";
-		};
-
-		tvo {
-			compatible = "nvidia,tegra20-tvo";
-			reg = <0x542c0000 0x00040000>;
-			interrupts = <0 76 0x04>;
-			status = "disabled";
-		};
-
-		dsi {
-			compatible = "nvidia,tegra20-dsi";
-			reg = <0x54300000 0x00040000>;
-			status = "disabled";
-		};
+	sdhci@c8000600 {
+		compatible = "nvidia,tegra20-sdhci";
+		reg = <0xc8000600 0x200>;
+		interrupts = < 63 >;
 	};
 	};
-
 };
 };

+ 165 - 0
arch/arm/dts/tegra30.dtsi

@@ -0,0 +1,165 @@
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "nvidia,tegra30";
+
+	tegra_car: clock@60006000 {
+		compatible = "nvidia,tegra30-car", "nvidia,tegra20-car";
+		reg = <0x60006000 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	apbdma: dma {
+		compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
+		reg = <0x6000a000 0x1400>;
+		interrupts = <0 104 0x04
+			      0 105 0x04
+			      0 106 0x04
+			      0 107 0x04
+			      0 108 0x04
+			      0 109 0x04
+			      0 110 0x04
+			      0 111 0x04
+			      0 112 0x04
+			      0 113 0x04
+			      0 114 0x04
+			      0 115 0x04
+			      0 116 0x04
+			      0 117 0x04
+			      0 118 0x04
+			      0 119 0x04
+			      0 128 0x04
+			      0 129 0x04
+			      0 130 0x04
+			      0 131 0x04
+			      0 132 0x04
+			      0 133 0x04
+			      0 134 0x04
+			      0 135 0x04
+			      0 136 0x04
+			      0 137 0x04
+			      0 138 0x04
+			      0 139 0x04
+			      0 140 0x04
+			      0 141 0x04
+			      0 142 0x04
+			      0 143 0x04>;
+	};
+
+	i2c@7000c000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+		reg = <0x7000C000 0x100>;
+		/* PERIPH_ID_I2C1, CLK_M */
+		clocks = <&tegra_car 12>;
+	};
+
+	i2c@7000c400 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+		reg = <0x7000C400 0x100>;
+		/* PERIPH_ID_I2C2, CLK_M */
+		clocks = <&tegra_car 54>;
+	};
+
+	i2c@7000c500 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+		reg = <0x7000C500 0x100>;
+		/* PERIPH_ID_I2C3, CLK_M */
+		clocks = <&tegra_car 67>;
+	};
+
+	i2c@7000c700 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+		reg = <0x7000C700 0x100>;
+		/* PERIPH_ID_I2C4, CLK_M */
+		clocks = <&tegra_car 103>;
+	};
+
+	i2c@7000d000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+		reg = <0x7000D000 0x100>;
+		/* PERIPH_ID_I2C_DVC, CLK_M */
+		clocks = <&tegra_car 47>;
+	};
+
+	spi@7000d400 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000d400 0x200>;
+		interrupts = <0 59 0x04>;
+		nvidia,dma-request-selector = <&apbdma 15>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+		/* PERIPH_ID_SBC1, PLLP_OUT0 */
+		clocks = <&tegra_car 41>;
+	};
+
+	spi@7000d600 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000d600 0x200>;
+		interrupts = <0 82 0x04>;
+		nvidia,dma-request-selector = <&apbdma 16>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+		/* PERIPH_ID_SBC2, PLLP_OUT0 */
+		clocks = <&tegra_car 44>;
+	};
+
+	spi@7000d800 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000d480 0x200>;
+		interrupts = <0 83 0x04>;
+		nvidia,dma-request-selector = <&apbdma 17>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+		/* PERIPH_ID_SBC3, PLLP_OUT0 */
+		clocks = <&tegra_car 46>;
+	};
+
+	spi@7000da00 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000da00 0x200>;
+		interrupts = <0 93 0x04>;
+		nvidia,dma-request-selector = <&apbdma 18>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+		/* PERIPH_ID_SBC4, PLLP_OUT0 */
+		clocks = <&tegra_car 68>;
+	};
+
+	spi@7000dc00 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000dc00 0x200>;
+		interrupts = <0 94 0x04>;
+		nvidia,dma-request-selector = <&apbdma 27>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+		/* PERIPH_ID_SBC5, PLLP_OUT0 */
+		clocks = <&tegra_car 104>;
+	};
+
+	spi@7000de00 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000de00 0x200>;
+		interrupts = <0 79 0x04>;
+		nvidia,dma-request-selector = <&apbdma 28>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+		/* PERIPH_ID_SBC6, PLLP_OUT0 */
+		clocks = <&tegra_car 105>;
+	};
+};

+ 8 - 8
arch/arm/imx-common/speed.c

@@ -37,23 +37,23 @@ int get_clocks(void)
 #ifdef CONFIG_FSL_ESDHC
 #ifdef CONFIG_FSL_ESDHC
 #ifdef CONFIG_FSL_USDHC
 #ifdef CONFIG_FSL_USDHC
 #if CONFIG_SYS_FSL_ESDHC_ADDR == USDHC2_BASE_ADDR
 #if CONFIG_SYS_FSL_ESDHC_ADDR == USDHC2_BASE_ADDR
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
 #elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC3_BASE_ADDR
 #elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC3_BASE_ADDR
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
 #elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC4_BASE_ADDR
 #elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC4_BASE_ADDR
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
 #else
 #else
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
 #endif
 #endif
 #else
 #else
 #if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR
 #if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
 #elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR
 #elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
 #elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC4_BASE_ADDR
 #elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC4_BASE_ADDR
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
 #else
 #else
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
 #endif
 #endif
 #endif
 #endif
 #endif
 #endif

+ 2 - 2
arch/arm/imx-common/timer.c

@@ -48,8 +48,8 @@ static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR;
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#define timestamp (gd->tbl)
-#define lastinc (gd->lastinc)
+#define timestamp (gd->arch.tbl)
+#define lastinc (gd->arch.lastinc)
 
 
 static inline unsigned long long tick_to_time(unsigned long long tick)
 static inline unsigned long long tick_to_time(unsigned long long tick)
 {
 {

+ 34 - 0
arch/arm/include/asm/arch-am33xx/ddr_defs.h

@@ -65,6 +65,40 @@
 #define MT41J128MJT125_PHY_FIFO_WE		0x100
 #define MT41J128MJT125_PHY_FIFO_WE		0x100
 #define MT41J128MJT125_IOCTRL_VALUE		0x18B
 #define MT41J128MJT125_IOCTRL_VALUE		0x18B
 
 
+/* Micron MT41J256M8HX-15E */
+#define MT41J256M8HX15E_EMIF_READ_LATENCY	0x06
+#define MT41J256M8HX15E_EMIF_TIM1		0x0888A39B
+#define MT41J256M8HX15E_EMIF_TIM2		0x26337FDA
+#define MT41J256M8HX15E_EMIF_TIM3		0x501F830F
+#define MT41J256M8HX15E_EMIF_SDCFG		0x61C04B32
+#define MT41J256M8HX15E_EMIF_SDREF		0x0000093B
+#define MT41J256M8HX15E_ZQ_CFG			0x50074BE4
+#define MT41J256M8HX15E_DLL_LOCK_DIFF		0x1
+#define MT41J256M8HX15E_RATIO			0x40
+#define MT41J256M8HX15E_INVERT_CLKOUT		0x1
+#define MT41J256M8HX15E_RD_DQS			0x3B
+#define MT41J256M8HX15E_WR_DQS			0x85
+#define MT41J256M8HX15E_PHY_WR_DATA		0xC1
+#define MT41J256M8HX15E_PHY_FIFO_WE		0x100
+#define MT41J256M8HX15E_IOCTRL_VALUE		0x18B
+
+/* Micron MT41J512M8RH-125 on EVM v1.5 */
+#define MT41J512M8RH125_EMIF_READ_LATENCY	0x06
+#define MT41J512M8RH125_EMIF_TIM1		0x0888A39B
+#define MT41J512M8RH125_EMIF_TIM2		0x26517FDA
+#define MT41J512M8RH125_EMIF_TIM3		0x501F84EF
+#define MT41J512M8RH125_EMIF_SDCFG		0x61C04BB2
+#define MT41J512M8RH125_EMIF_SDREF		0x0000093B
+#define MT41J512M8RH125_ZQ_CFG			0x50074BE4
+#define MT41J512M8RH125_DLL_LOCK_DIFF		0x1
+#define MT41J512M8RH125_RATIO			0x80
+#define MT41J512M8RH125_INVERT_CLKOUT		0x0
+#define MT41J512M8RH125_RD_DQS			0x3B
+#define MT41J512M8RH125_WR_DQS			0x3C
+#define MT41J512M8RH125_PHY_FIFO_WE		0xA5
+#define MT41J512M8RH125_PHY_WR_DATA		0x74
+#define MT41J512M8RH125_IOCTRL_VALUE		0x18B
+
 /**
 /**
  * Configure SDRAM
  * Configure SDRAM
  */
  */

+ 2 - 1
arch/arm/include/asm/arch-am33xx/mux.h

@@ -25,7 +25,8 @@
 /* PAD Control Fields */
 /* PAD Control Fields */
 #define SLEWCTRL	(0x1 << 6)
 #define SLEWCTRL	(0x1 << 6)
 #define RXACTIVE	(0x1 << 5)
 #define RXACTIVE	(0x1 << 5)
-#define PULLUP_EN	(0x1 << 4) /* Pull UP Selection */
+#define PULLDOWN_EN	(0x0 << 4) /* Pull Down Selection */
+#define PULLUP_EN	(0x1 << 4) /* Pull Up Selection */
 #define PULLUDEN	(0x0 << 3) /* Pull up enabled */
 #define PULLUDEN	(0x0 << 3) /* Pull up enabled */
 #define PULLUDDIS	(0x1 << 3) /* Pull up disabled */
 #define PULLUDDIS	(0x1 << 3) /* Pull up disabled */
 #define MODE(val)	val	/* used for Readability */
 #define MODE(val)	val	/* used for Readability */

+ 1 - 0
arch/arm/include/asm/arch-am33xx/spl.h

@@ -29,6 +29,7 @@
 #define BOOT_DEVICE_MMC2	9	/* eMMC or daughter card */
 #define BOOT_DEVICE_MMC2	9	/* eMMC or daughter card */
 #define BOOT_DEVICE_SPI		11
 #define BOOT_DEVICE_SPI		11
 #define BOOT_DEVICE_UART	65
 #define BOOT_DEVICE_UART	65
+#define BOOT_DEVICE_USBETH	68
 #define BOOT_DEVICE_CPGMAC	70
 #define BOOT_DEVICE_CPGMAC	70
 #define BOOT_DEVICE_MMC2_2      0xFF
 #define BOOT_DEVICE_MMC2_2      0xFF
 #endif
 #endif

+ 6 - 6
arch/arm/include/asm/arch-at91/clk.h

@@ -31,37 +31,37 @@
 static inline unsigned long get_cpu_clk_rate(void)
 static inline unsigned long get_cpu_clk_rate(void)
 {
 {
 	DECLARE_GLOBAL_DATA_PTR;
 	DECLARE_GLOBAL_DATA_PTR;
-	return gd->cpu_clk_rate_hz;
+	return gd->arch.cpu_clk_rate_hz;
 }
 }
 
 
 static inline unsigned long get_main_clk_rate(void)
 static inline unsigned long get_main_clk_rate(void)
 {
 {
 	DECLARE_GLOBAL_DATA_PTR;
 	DECLARE_GLOBAL_DATA_PTR;
-	return gd->main_clk_rate_hz;
+	return gd->arch.main_clk_rate_hz;
 }
 }
 
 
 static inline unsigned long get_mck_clk_rate(void)
 static inline unsigned long get_mck_clk_rate(void)
 {
 {
 	DECLARE_GLOBAL_DATA_PTR;
 	DECLARE_GLOBAL_DATA_PTR;
-	return gd->mck_rate_hz;
+	return gd->arch.mck_rate_hz;
 }
 }
 
 
 static inline unsigned long get_plla_clk_rate(void)
 static inline unsigned long get_plla_clk_rate(void)
 {
 {
 	DECLARE_GLOBAL_DATA_PTR;
 	DECLARE_GLOBAL_DATA_PTR;
-	return gd->plla_rate_hz;
+	return gd->arch.plla_rate_hz;
 }
 }
 
 
 static inline unsigned long get_pllb_clk_rate(void)
 static inline unsigned long get_pllb_clk_rate(void)
 {
 {
 	DECLARE_GLOBAL_DATA_PTR;
 	DECLARE_GLOBAL_DATA_PTR;
-	return gd->pllb_rate_hz;
+	return gd->arch.pllb_rate_hz;
 }
 }
 
 
 static inline u32 get_pllb_init(void)
 static inline u32 get_pllb_init(void)
 {
 {
 	DECLARE_GLOBAL_DATA_PTR;
 	DECLARE_GLOBAL_DATA_PTR;
-	return gd->at91_pllb_usb_init;
+	return gd->arch.at91_pllb_usb_init;
 }
 }
 
 
 static inline unsigned long get_macb_pclk_rate(unsigned int dev_id)
 static inline unsigned long get_macb_pclk_rate(unsigned int dev_id)

+ 4 - 0
arch/arm/include/asm/arch-davinci/gpio.h

@@ -67,7 +67,11 @@ struct davinci_gpio_bank {
 
 
 #define gpio_status()		gpio_info()
 #define gpio_status()		gpio_info()
 #define GPIO_NAME_SIZE		20
 #define GPIO_NAME_SIZE		20
+#if defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850)
+#define MAX_NUM_GPIOS		128
+#else
 #define MAX_NUM_GPIOS		144
 #define MAX_NUM_GPIOS		144
+#endif
 #define GPIO_BANK(gp)		(davinci_gpio_bank01 + ((gp) >> 5))
 #define GPIO_BANK(gp)		(davinci_gpio_bank01 + ((gp) >> 5))
 #define GPIO_BIT(gp)		((gp) & 0x1F)
 #define GPIO_BIT(gp)		((gp) & 0x1F)
 
 

+ 6 - 46
arch/arm/include/asm/arch-tegra/ap.h

@@ -23,67 +23,27 @@
 #include <asm/types.h>
 #include <asm/types.h>
 
 
 /* Stabilization delays, in usec */
 /* Stabilization delays, in usec */
-#define PLL_STABILIZATION_DELAY (300)
+#define PLL_STABILIZATION_DELAY	(300)
 #define IO_STABILIZATION_DELAY	(1000)
 #define IO_STABILIZATION_DELAY	(1000)
 
 
-#define NVBL_PLLP_KHZ	(216000)
-
 #define PLLX_ENABLED		(1 << 30)
 #define PLLX_ENABLED		(1 << 30)
 #define CCLK_BURST_POLICY	0x20008888
 #define CCLK_BURST_POLICY	0x20008888
 #define SUPER_CCLK_DIVIDER	0x80000000
 #define SUPER_CCLK_DIVIDER	0x80000000
 
 
 /* Calculate clock fractional divider value from ref and target frequencies */
 /* Calculate clock fractional divider value from ref and target frequencies */
-#define CLK_DIVIDER(REF, FREQ)  ((((REF) * 2) / FREQ) - 2)
+#define CLK_DIVIDER(REF, FREQ)	((((REF) * 2) / FREQ) - 2)
 
 
 /* Calculate clock frequency value from reference and clock divider value */
 /* Calculate clock frequency value from reference and clock divider value */
-#define CLK_FREQUENCY(REF, REG)  (((REF) * 2) / (REG + 2))
+#define CLK_FREQUENCY(REF, REG)	(((REF) * 2) / (REG + 2))
 
 
 /* AVP/CPU ID */
 /* AVP/CPU ID */
 #define PG_UP_TAG_0_PID_CPU	0x55555555	/* CPU aka "a9" aka "mpcore" */
 #define PG_UP_TAG_0_PID_CPU	0x55555555	/* CPU aka "a9" aka "mpcore" */
-#define PG_UP_TAG_0             0x0
+#define PG_UP_TAG_0		0x0
 
 
 #define CORESIGHT_UNLOCK	0xC5ACCE55;
 #define CORESIGHT_UNLOCK	0xC5ACCE55;
 
 
-/* AP20-Specific Base Addresses */
-
-/* AP20 Base physical address of SDRAM. */
-#define AP20_BASE_PA_SDRAM      0x00000000
-/* AP20 Base physical address of internal SRAM. */
-#define AP20_BASE_PA_SRAM       0x40000000
-/* AP20 Size of internal SRAM (256KB). */
-#define AP20_BASE_PA_SRAM_SIZE  0x00040000
-/* AP20 Base physical address of flash. */
-#define AP20_BASE_PA_NOR_FLASH  0xD0000000
-/* AP20 Base physical address of boot information table. */
-#define AP20_BASE_PA_BOOT_INFO  AP20_BASE_PA_SRAM
-
-/*
- * Super-temporary stacks for EXTREMELY early startup. The values chosen for
- * these addresses must be valid on ALL SOCs because this value is used before
- * we are able to differentiate between the SOC types.
- *
- * NOTE: The since CPU's stack will eventually be moved from IRAM to SDRAM, its
- *       stack is placed below the AVP stack. Once the CPU stack has been moved,
- *       the AVP is free to use the IRAM the CPU stack previously occupied if
- *       it should need to do so.
- *
- * NOTE: In multi-processor CPU complex configurations, each processor will have
- *       its own stack of size CPU_EARLY_BOOT_STACK_SIZE. CPU 0 will have a
- *       limit of CPU_EARLY_BOOT_STACK_LIMIT. Each successive CPU will have a
- *       stack limit that is CPU_EARLY_BOOT_STACK_SIZE less then the previous
- *       CPU.
- */
-
-/* Common AVP early boot stack limit */
-#define AVP_EARLY_BOOT_STACK_LIMIT	\
-	(AP20_BASE_PA_SRAM + (AP20_BASE_PA_SRAM_SIZE/2))
-/* Common AVP early boot stack size */
-#define AVP_EARLY_BOOT_STACK_SIZE	0x1000
-/* Common CPU early boot stack limit */
-#define CPU_EARLY_BOOT_STACK_LIMIT	\
-	(AVP_EARLY_BOOT_STACK_LIMIT - AVP_EARLY_BOOT_STACK_SIZE)
-/* Common CPU early boot stack size */
-#define CPU_EARLY_BOOT_STACK_SIZE	0x1000
+/* AP base physical address of internal SRAM */
+#define NV_PA_BASE_SRAM		0x40000000
 
 
 #define EXCEP_VECTOR_CPU_RESET_VECTOR	(NV_PA_EVP_BASE + 0x100)
 #define EXCEP_VECTOR_CPU_RESET_VECTOR	(NV_PA_EVP_BASE + 0x100)
 #define CSITE_CPU_DBG0_LAR		(NV_PA_CSITE_BASE + 0x10FB0)
 #define CSITE_CPU_DBG0_LAR		(NV_PA_CSITE_BASE + 0x10FB0)

+ 4 - 3
arch/arm/include/asm/arch-tegra/board.h

@@ -41,8 +41,9 @@ void gpio_early_init(void);  /* overrideable GPIO config        */
  * an empty stub function will be called.
  * an empty stub function will be called.
  */
  */
 
 
-void pin_mux_usb(void);      /* overrideable USB pinmux setup   */
-void pin_mux_spi(void);      /* overrideable SPI pinmux setup   */
-void pin_mux_nand(void);     /* overrideable NAND pinmux setup  */
+void pin_mux_usb(void);      /* overrideable USB pinmux setup     */
+void pin_mux_spi(void);      /* overrideable SPI pinmux setup     */
+void pin_mux_nand(void);     /* overrideable NAND pinmux setup    */
+void pin_mux_display(void);  /* overrideable DISPLAY pinmux setup */
 
 
 #endif
 #endif

+ 185 - 11
arch/arm/include/asm/arch-tegra/clk_rst.h

@@ -21,8 +21,8 @@
  * MA 02111-1307 USA
  * MA 02111-1307 USA
  */
  */
 
 
-#ifndef _CLK_RST_H_
-#define _CLK_RST_H_
+#ifndef _TEGRA_CLK_RST_H_
+#define _TEGRA_CLK_RST_H_
 
 
 /* PLL registers - there are several PLLs in the clock controller */
 /* PLL registers - there are several PLLs in the clock controller */
 struct clk_pll {
 struct clk_pll {
@@ -37,6 +37,12 @@ struct clk_pll_simple {
 	uint pll_misc;		/* other misc things */
 	uint pll_misc;		/* other misc things */
 };
 };
 
 
+/* RST_DEV_(L,H,U,V,W)_(SET,CLR) and CLK_ENB_(L,H,U,V,W)_(SET,CLR) */
+struct clk_set_clr {
+	uint set;
+	uint clr;
+};
+
 /*
 /*
  * Most PLLs use the clk_pll structure, but some have a simpler two-member
  * Most PLLs use the clk_pll structure, but some have a simpler two-member
  * structure for which we use clk_pll_simple. The reason for this non-
  * structure for which we use clk_pll_simple. The reason for this non-
@@ -45,8 +51,10 @@ struct clk_pll_simple {
 enum {
 enum {
 	TEGRA_CLK_PLLS		= 6,	/* Number of normal PLLs */
 	TEGRA_CLK_PLLS		= 6,	/* Number of normal PLLs */
 	TEGRA_CLK_SIMPLE_PLLS	= 3,	/* Number of simple PLLs */
 	TEGRA_CLK_SIMPLE_PLLS	= 3,	/* Number of simple PLLs */
-	TEGRA_CLK_REGS		= 3,	/* Number of clock enable registers */
-	TEGRA_CLK_SOURCES	= 64,	/* Number of peripheral clock sources */
+	TEGRA_CLK_REGS		= 3,	/* Number of clock enable regs L/H/U */
+	TEGRA_CLK_SOURCES	= 64,	/* Number of ppl clock sources L/H/U */
+	TEGRA_CLK_REGS_VW	= 2,	/* Number of clock enable regs V/W */
+	TEGRA_CLK_SOURCES_VW	= 32,	/* Number of ppl clock sources V/W*/
 };
 };
 
 
 /* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
 /* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
@@ -82,14 +90,80 @@ struct clk_rst_ctlr {
 	uint crc_reserved11;		/* _reserved_11,	0xFC */
 	uint crc_reserved11;		/* _reserved_11,	0xFC */
 
 
 	uint crc_clk_src[TEGRA_CLK_SOURCES]; /*_I2S1_0...	0x100-1fc */
 	uint crc_clk_src[TEGRA_CLK_SOURCES]; /*_I2S1_0...	0x100-1fc */
-	uint crc_reserved20[80];	/*			0x200-33C */
-	uint crc_cpu_cmplx_set;		/* _CPU_CMPLX_SET_0,	0x340	  */
-	uint crc_cpu_cmplx_clr;		/* _CPU_CMPLX_CLR_0,	0x344     */
+
+	uint crc_reserved20[64];	/* _reserved_20,	0x200-2fc */
+
+	/* _RST_DEV_L/H/U_SET_0 0x300 ~ 0x314 */
+	struct clk_set_clr crc_rst_dev_ex[TEGRA_CLK_REGS];
+
+	uint crc_reserved30[2];		/* _reserved_30,	0x318, 0x31c */
+
+	/* _CLK_ENB_L/H/U_CLR_0 0x320 ~ 0x334 */
+	struct clk_set_clr crc_clk_enb_ex[TEGRA_CLK_REGS];
+
+	uint crc_reserved31[2];		/* _reserved_31,	0x338, 0x33c */
+
+	uint crc_cpu_cmplx_set;		/* _RST_CPU_CMPLX_SET_0,    0x340 */
+	uint crc_cpu_cmplx_clr;		/* _RST_CPU_CMPLX_CLR_0,    0x344 */
+
+	/* Additional (T30) registers */
+	uint crc_clk_cpu_cmplx_set;	/* _CLK_CPU_CMPLX_SET_0,    0x348 */
+	uint crc_clk_cpu_cmplx_clr;	/* _CLK_CPU_CMPLX_SET_0,    0x34c */
+
+	uint crc_reserved32[2];		/* _reserved_32,      0x350,0x354 */
+
+	uint crc_rst_dev_vw[TEGRA_CLK_REGS_VW]; /* _RST_DEVICES_V/W_0 */
+	uint crc_clk_out_enb_vw[TEGRA_CLK_REGS_VW]; /* _CLK_OUT_ENB_V/W_0 */
+	uint crc_cclkg_brst_pol;	/* _CCLKG_BURST_POLICY_0,   0x368 */
+	uint crc_super_cclkg_div;	/* _SUPER_CCLKG_DIVIDER_0,  0x36C */
+	uint crc_cclklp_brst_pol;	/* _CCLKLP_BURST_POLICY_0,  0x370 */
+	uint crc_super_cclkp_div;	/* _SUPER_CCLKLP_DIVIDER_0, 0x374 */
+	uint crc_clk_cpug_cmplx;	/* _CLK_CPUG_CMPLX_0,       0x378 */
+	uint crc_clk_cpulp_cmplx;	/* _CLK_CPULP_CMPLX_0,      0x37C */
+	uint crc_cpu_softrst_ctrl;	/* _CPU_SOFTRST_CTRL_0,     0x380 */
+	uint crc_cpu_softrst_ctrl1;	/* _CPU_SOFTRST_CTR1L_0,    0x384 */
+	uint crc_cpu_softrst_ctrl2;	/* _CPU_SOFTRST_CTRL2_0,    0x388 */
+	uint crc_reserved33[9];		/* _reserved_33,        0x38c-3ac */
+	uint crc_clk_src_vw[TEGRA_CLK_SOURCES_VW]; /* _G3D2_0..., 0x3b0-0x42c */
+	/* _RST_DEV_V/W_SET_0 0x430 ~ 0x43c */
+	struct clk_set_clr crc_rst_dev_ex_vw[TEGRA_CLK_REGS_VW];
+	/* _CLK_ENB_V/W_CLR_0 0x440 ~ 0x44c */
+	struct clk_set_clr crc_clk_enb_ex_vw[TEGRA_CLK_REGS_VW];
+	/* Additional (T114) registers */
+	uint crc_rst_cpug_cmplx_set;	/* _RST_CPUG_CMPLX_SET_0,  0x450 */
+	uint crc_rst_cpug_cmplx_clr;	/* _RST_CPUG_CMPLX_CLR_0,  0x454 */
+	uint crc_rst_cpulp_cmplx_set;	/* _RST_CPULP_CMPLX_SET_0, 0x458 */
+	uint crc_rst_cpulp_cmplx_clr;	/* _RST_CPULP_CMPLX_CLR_0, 0x45C */
+	uint crc_clk_cpug_cmplx_set;	/* _CLK_CPUG_CMPLX_SET_0,  0x460 */
+	uint crc_clk_cpug_cmplx_clr;	/* _CLK_CPUG_CMPLX_CLR_0,  0x464 */
+	uint crc_clk_cpulp_cmplx_set;	/* _CLK_CPULP_CMPLX_SET_0, 0x468 */
+	uint crc_clk_cpulp_cmplx_clr;	/* _CLK_CPULP_CMPLX_CLR_0, 0x46C */
+	uint crc_cpu_cmplx_status;	/* _CPU_CMPLX_STATUS_0,    0x470 */
+	uint crc_reserved40[1];		/* _reserved_40,        0x474 */
+	uint crc_intstatus;		/* __INTSTATUS_0,       0x478 */
+	uint crc_intmask;		/* __INTMASK_0,         0x47C */
+	uint crc_utmip_pll_cfg0;	/* _UTMIP_PLL_CFG0_0,	0x480 */
+	uint crc_utmip_pll_cfg1;	/* _UTMIP_PLL_CFG1_0,	0x484 */
+	uint crc_utmip_pll_cfg2;	/* _UTMIP_PLL_CFG2_0,	0x488 */
+
+	uint crc_plle_aux;		/* _PLLE_AUX_0,		0x48C */
+	uint crc_sata_pll_cfg0;		/* _SATA_PLL_CFG0_0,	0x490 */
+	uint crc_sata_pll_cfg1;		/* _SATA_PLL_CFG1_0,	0x494 */
+	uint crc_pcie_pll_cfg0;		/* _PCIE_PLL_CFG0_0,	0x498 */
+
+	uint crc_prog_audio_dly_clk;	/* _PROG_AUDIO_DLY_CLK_0, 0x49C */
+	uint crc_audio_sync_clk_i2s0;	/* _AUDIO_SYNC_CLK_I2S0_0, 0x4A0 */
+	uint crc_audio_sync_clk_i2s1;	/* _AUDIO_SYNC_CLK_I2S1_0, 0x4A4 */
+	uint crc_audio_sync_clk_i2s2;	/* _AUDIO_SYNC_CLK_I2S2_0, 0x4A8 */
+	uint crc_audio_sync_clk_i2s3;	/* _AUDIO_SYNC_CLK_I2S3_0, 0x4AC */
+	uint crc_audio_sync_clk_i2s4;	/* _AUDIO_SYNC_CLK_I2S4_0, 0x4B0 */
+	uint crc_audio_sync_clk_spdif;	/* _AUDIO_SYNC_CLK_SPDIF_0, 0x4B4 */
 };
 };
 
 
 /* CLK_RST_CONTROLLER_CLK_CPU_CMPLX_0 */
 /* CLK_RST_CONTROLLER_CLK_CPU_CMPLX_0 */
+#define CPU3_CLK_STP_SHIFT	11
+#define CPU2_CLK_STP_SHIFT	10
 #define CPU1_CLK_STP_SHIFT	9
 #define CPU1_CLK_STP_SHIFT	9
-
 #define CPU0_CLK_STP_SHIFT	8
 #define CPU0_CLK_STP_SHIFT	8
 #define CPU0_CLK_STP_MASK	(1U << CPU0_CLK_STP_SHIFT)
 #define CPU0_CLK_STP_MASK	(1U << CPU0_CLK_STP_SHIFT)
 
 
@@ -120,6 +194,12 @@ struct clk_rst_ctlr {
 #define PLL_OUT_RATIO_MASK	(0xffU << PLL_OUT_RATIO_SHIFT)
 #define PLL_OUT_RATIO_MASK	(0xffU << PLL_OUT_RATIO_SHIFT)
 
 
 /* CLK_RST_CONTROLLER_PLLx_MISC_0 */
 /* CLK_RST_CONTROLLER_PLLx_MISC_0 */
+#define PLL_DCCON_SHIFT		20
+#define PLL_DCCON_MASK		(1U << PLL_DCCON_SHIFT)
+
+#define PLL_LOCK_ENABLE_SHIFT	18
+#define PLL_LOCK_ENABLE_MASK	(1U << PLL_LOCK_ENABLE_SHIFT)
+
 #define PLL_CPCON_SHIFT		8
 #define PLL_CPCON_SHIFT		8
 #define PLL_CPCON_MASK		(15U << PLL_CPCON_SHIFT)
 #define PLL_CPCON_MASK		(15U << PLL_CPCON_SHIFT)
 
 
@@ -129,9 +209,23 @@ struct clk_rst_ctlr {
 #define PLLU_VCO_FREQ_SHIFT	20
 #define PLLU_VCO_FREQ_SHIFT	20
 #define PLLU_VCO_FREQ_MASK	(1U << PLLU_VCO_FREQ_SHIFT)
 #define PLLU_VCO_FREQ_MASK	(1U << PLLU_VCO_FREQ_SHIFT)
 
 
+#define PLLP_OUT1_OVR		(1 << 2)
+#define PLLP_OUT2_OVR		(1 << 18)
+#define PLLP_OUT3_OVR		(1 << 2)
+#define PLLP_OUT4_OVR		(1 << 18)
+#define PLLP_OUT1_RATIO		8
+#define PLLP_OUT2_RATIO		24
+#define PLLP_OUT3_RATIO		8
+#define PLLP_OUT4_RATIO		24
+
+enum {
+	IN_408_OUT_204_DIVISOR = 2,
+	IN_408_OUT_102_DIVISOR = 6,
+	IN_408_OUT_48_DIVISOR = 15,
+	IN_408_OUT_9_6_DIVISOR = 83,
+};
+
 /* CLK_RST_CONTROLLER_OSC_CTRL_0 */
 /* CLK_RST_CONTROLLER_OSC_CTRL_0 */
-#define OSC_FREQ_SHIFT		30
-#define OSC_FREQ_MASK		(3U << OSC_FREQ_SHIFT)
 #define OSC_XOBP_SHIFT		1
 #define OSC_XOBP_SHIFT		1
 #define OSC_XOBP_MASK		(1U << OSC_XOBP_SHIFT)
 #define OSC_XOBP_MASK		(1U << OSC_XOBP_SHIFT)
 
 
@@ -151,4 +245,84 @@ struct clk_rst_ctlr {
 #define OUT_CLK_SOURCE4_SHIFT	28
 #define OUT_CLK_SOURCE4_SHIFT	28
 #define OUT_CLK_SOURCE4_MASK	(15U << OUT_CLK_SOURCE4_SHIFT)
 #define OUT_CLK_SOURCE4_MASK	(15U << OUT_CLK_SOURCE4_SHIFT)
 
 
-#endif	/* CLK_RST_H */
+/* CLK_RST_CONTROLLER_SCLK_BURST_POLICY */
+#define SCLK_SYS_STATE_SHIFT    28U
+#define SCLK_SYS_STATE_MASK     (15U << SCLK_SYS_STATE_SHIFT)
+enum {
+	SCLK_SYS_STATE_STDBY,
+	SCLK_SYS_STATE_IDLE,
+	SCLK_SYS_STATE_RUN,
+	SCLK_SYS_STATE_IRQ = 4U,
+	SCLK_SYS_STATE_FIQ = 8U,
+};
+#define SCLK_COP_FIQ_MASK       (1 << 27)
+#define SCLK_CPU_FIQ_MASK       (1 << 26)
+#define SCLK_COP_IRQ_MASK       (1 << 25)
+#define SCLK_CPU_IRQ_MASK       (1 << 24)
+
+#define SCLK_SWAKEUP_FIQ_SOURCE_SHIFT		12
+#define SCLK_SWAKEUP_FIQ_SOURCE_MASK		\
+		(7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT)
+#define SCLK_SWAKEUP_IRQ_SOURCE_SHIFT		8
+#define SCLK_SWAKEUP_IRQ_SOURCE_MASK		\
+		(7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT)
+#define SCLK_SWAKEUP_RUN_SOURCE_SHIFT		4
+#define SCLK_SWAKEUP_RUN_SOURCE_MASK		\
+		(7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT)
+#define SCLK_SWAKEUP_IDLE_SOURCE_SHIFT		0
+
+#define SCLK_SWAKEUP_IDLE_SOURCE_MASK		\
+		(7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT)
+enum {
+	SCLK_SOURCE_CLKM,
+	SCLK_SOURCE_PLLC_OUT1,
+	SCLK_SOURCE_PLLP_OUT4,
+	SCLK_SOURCE_PLLP_OUT3,
+	SCLK_SOURCE_PLLP_OUT2,
+	SCLK_SOURCE_CLKD,
+	SCLK_SOURCE_CLKS,
+	SCLK_SOURCE_PLLM_OUT1,
+};
+#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)
+
+/* CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER */
+#define SUPER_SCLK_ENB_SHIFT		31U
+#define SUPER_SCLK_ENB_MASK		(1U << 31)
+#define SUPER_SCLK_DIVIDEND_SHIFT	8
+#define SUPER_SCLK_DIVIDEND_MASK	(0xff << SUPER_SCLK_DIVIDEND_SHIFT)
+#define SUPER_SCLK_DIVISOR_SHIFT	0
+#define SUPER_SCLK_DIVISOR_MASK		(0xff << SUPER_SCLK_DIVISOR_SHIFT)
+
+/* CLK_RST_CONTROLLER_CLK_SYSTEM_RATE */
+#define CLK_SYS_RATE_HCLK_DISABLE_SHIFT 7
+#define CLK_SYS_RATE_HCLK_DISABLE_MASK  (1 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT)
+#define CLK_SYS_RATE_AHB_RATE_SHIFT     4
+#define CLK_SYS_RATE_AHB_RATE_MASK      (3 << CLK_SYS_RATE_AHB_RATE_SHIFT)
+#define CLK_SYS_RATE_PCLK_DISABLE_SHIFT 3
+#define CLK_SYS_RATE_PCLK_DISABLE_MASK  (1 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT)
+#define CLK_SYS_RATE_APB_RATE_SHIFT     0
+#define CLK_SYS_RATE_APB_RATE_MASK      (3 << CLK_SYS_RATE_AHB_RATE_SHIFT)
+
+/* CLK_RST_CONTROLLER_RST_CPUxx_CMPLX_CLR */
+#define CLR_CPURESET0   (1 << 0)
+#define CLR_CPURESET1   (1 << 1)
+#define CLR_CPURESET2   (1 << 2)
+#define CLR_CPURESET3   (1 << 3)
+#define CLR_DBGRESET0   (1 << 12)
+#define CLR_DBGRESET1   (1 << 13)
+#define CLR_DBGRESET2   (1 << 14)
+#define CLR_DBGRESET3   (1 << 15)
+#define CLR_CORERESET0  (1 << 16)
+#define CLR_CORERESET1  (1 << 17)
+#define CLR_CORERESET2  (1 << 18)
+#define CLR_CORERESET3  (1 << 19)
+#define CLR_CXRESET0    (1 << 20)
+#define CLR_CXRESET1    (1 << 21)
+#define CLR_CXRESET2    (1 << 22)
+#define CLR_CXRESET3    (1 << 23)
+#define CLR_NONCPURESET (1 << 29)
+
+#endif	/* _TEGRA_CLK_RST_H_ */

+ 60 - 5
arch/arm/include/asm/arch-tegra/clock.h

@@ -21,8 +21,8 @@
 
 
 /* Tegra clock control functions */
 /* Tegra clock control functions */
 
 
-#ifndef _CLOCK_H
-#define _CLOCK_H
+#ifndef _TEGRA_CLOCK_H_
+#define _TEGRA_CLOCK_H_
 
 
 /* Set of oscillator frequencies supported in the internal API. */
 /* Set of oscillator frequencies supported in the internal API. */
 enum clock_osc_freq {
 enum clock_osc_freq {
@@ -82,7 +82,7 @@ int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout,
  * @returns 0 if ok, -1 on error (invalid clock id)
  * @returns 0 if ok, -1 on error (invalid clock id)
  */
  */
 int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
 int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
-		      u32 *divp, u32 *cpcon, u32 *lfcon);
+		u32 *divp, u32 *cpcon, u32 *lfcon);
 
 
 /*
 /*
  * Enable a clock
  * Enable a clock
@@ -136,7 +136,7 @@ enum crc_reset_id {
 /**
 /**
  * Put parts of the CPU complex into or out of reset.\
  * Put parts of the CPU complex into or out of reset.\
  *
  *
- * @param cpu		cpu number (0 or 1 on Tegra2)
+ * @param cpu		cpu number (0 or 1 on Tegra2, 0-3 on Tegra3)
  * @param which		which parts of the complex to affect (OR of crc_reset_id)
  * @param which		which parts of the complex to affect (OR of crc_reset_id)
  * @param reset		1 to assert reset, 0 to de-assert
  * @param reset		1 to assert reset, 0 to de-assert
  */
  */
@@ -262,4 +262,59 @@ void clock_init(void);
 /* Initialize the PLLs */
 /* Initialize the PLLs */
 void clock_early_init(void);
 void clock_early_init(void);
 
 
-#endif	/* _CLOCK_H_ */
+/* Returns a pointer to the clock source register for a peripheral */
+u32 *get_periph_source_reg(enum periph_id periph_id);
+
+/**
+ * Given a peripheral ID and the required source clock, this returns which
+ * value should be programmed into the source mux for that peripheral.
+ *
+ * There is special code here to handle the one source type with 5 sources.
+ *
+ * @param periph_id     peripheral to start
+ * @param source        PLL id of required parent clock
+ * @param mux_bits      Set to number of bits in mux register: 2 or 4
+ * @param divider_bits  Set to number of divider bits (8 or 16)
+ * @return mux value (0-4, or -1 if not found)
+ */
+int get_periph_clock_source(enum periph_id periph_id,
+		enum clock_id parent, int *mux_bits, int *divider_bits);
+
+/*
+ * Convert a device tree clock ID to our peripheral ID. They are mostly
+ * the same but we are very cautious so we check that a valid clock ID is
+ * provided.
+ *
+ * @param clk_id        Clock ID according to tegra30 device tree binding
+ * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
+ */
+enum periph_id clk_id_to_periph_id(int clk_id);
+
+/**
+ * Set the output frequency you want for each PLL clock.
+ * PLL output frequencies are programmed by setting their N, M and P values.
+ * The governing equations are:
+ *     VCO = (Fi / m) * n, Fo = VCO / (2^p)
+ *     where Fo is the output frequency from the PLL.
+ * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi)
+ *     216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1
+ * Please see Tegra TRM section 5.3 to get the detail for PLL Programming
+ *
+ * @param n PLL feedback divider(DIVN)
+ * @param m PLL input divider(DIVN)
+ * @param p post divider(DIVP)
+ * @param cpcon base PLL charge pump(CPCON)
+ * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
+ *              be overriden), 1 if PLL is already correct
+ */
+int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon);
+
+/* return 1 if a peripheral ID is in range */
+#define clock_type_id_isvalid(id) ((id) >= 0 && \
+		(id) < CLOCK_TYPE_COUNT)
+
+/* return 1 if a periphc_internal_id is in range */
+#define periphc_internal_id_isvalid(id) ((id) >= 0 && \
+		(id) < PERIPHC_COUNT)
+
+#endif  /* _TEGRA_CLOCK_H_ */

+ 39 - 0
arch/arm/include/asm/arch-tegra/funcmux.h

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra high-level function multiplexing */
+
+#ifndef _TEGRA_FUNCMUX_H_
+#define _TEGRA_FUNCMUX_H_
+
+/**
+ * Select a config for a particular peripheral.
+ *
+ * Each peripheral can operate through a number of configurations,
+ * which are sets of pins that it uses to bring out its signals.
+ * The basic config is 0, and higher numbers indicate different
+ * pinmux settings to bring the peripheral out on other pins,
+ *
+ * This function also disables tristate for the function's pins,
+ * so that they operate in normal mode.
+ *
+ * @param id		Peripheral id
+ * @param config	Configuration to use (FUNCMUX_...), 0 for default
+ * @return 0 if ok, -1 on error (e.g. incorrect id or config)
+ */
+int funcmux_select(enum periph_id id, int config);
+
+#endif	/* _TEGRA_FUNCMUX_H_ */

+ 40 - 0
arch/arm/include/asm/arch-tegra/gp_padctrl.h

@@ -0,0 +1,40 @@
+/*
+ *  (C) Copyright 2010-2012
+ *  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 _TEGRA_GP_PADCTRL_H_
+#define _TEGRA_GP_PADCTRL_H_
+
+#define GP_HIDREV			0x804
+
+/* bit fields definitions for APB_MISC_GP_HIDREV register */
+#define HIDREV_CHIPID_SHIFT		8
+#define HIDREV_CHIPID_MASK		(0xff << HIDREV_CHIPID_SHIFT)
+#define HIDREV_MAJORPREV_SHIFT		4
+#define HIDREV_MAJORPREV_MASK		(0xf << HIDREV_MAJORPREV_SHIFT)
+
+/* CHIPID field returned from APB_MISC_GP_HIDREV register */
+#define CHIPID_TEGRA20			0x20
+#define CHIPID_TEGRA30			0x30
+#define CHIPID_TEGRA114			0x35
+
+#endif	/* _TEGRA_GP_PADCTRL_H_ */

+ 8 - 0
arch/arm/include/asm/arch-tegra/pmc.h

@@ -128,5 +128,13 @@ struct pmc_ctlr {
 #define START_CP	(1 << 8)
 #define START_CP	(1 << 8)
 
 
 #define CPUPWRREQ_OE	(1 << 16)
 #define CPUPWRREQ_OE	(1 << 16)
+#define CPUPWRREQ_POL	(1 << 15)
+
+#define CRAILID		(0)
+#define CE0ID		(14)
+#define C0NCID		(15)
+#define CRAIL		(1 << CRAILID)
+#define CE0		(1 << CE0ID)
+#define C0NC		(1 << C0NCID)
 
 
 #endif	/* PMC_H */
 #endif	/* PMC_H */

+ 17 - 2
arch/arm/include/asm/arch-tegra/tegra.h

@@ -40,6 +40,12 @@
 #define NV_PA_APB_UARTE_BASE	(NV_PA_APB_MISC_BASE + 0x6400)
 #define NV_PA_APB_UARTE_BASE	(NV_PA_APB_MISC_BASE + 0x6400)
 #define NV_PA_NAND_BASE		(NV_PA_APB_MISC_BASE + 0x8000)
 #define NV_PA_NAND_BASE		(NV_PA_APB_MISC_BASE + 0x8000)
 #define NV_PA_SPI_BASE		(NV_PA_APB_MISC_BASE + 0xC380)
 #define NV_PA_SPI_BASE		(NV_PA_APB_MISC_BASE + 0xC380)
+#define NV_PA_SLINK1_BASE	(NV_PA_APB_MISC_BASE + 0xD400)
+#define NV_PA_SLINK2_BASE	(NV_PA_APB_MISC_BASE + 0xD600)
+#define NV_PA_SLINK3_BASE	(NV_PA_APB_MISC_BASE + 0xD800)
+#define NV_PA_SLINK4_BASE	(NV_PA_APB_MISC_BASE + 0xDA00)
+#define NV_PA_SLINK5_BASE	(NV_PA_APB_MISC_BASE + 0xDC00)
+#define NV_PA_SLINK6_BASE	(NV_PA_APB_MISC_BASE + 0xDE00)
 #define TEGRA_DVC_BASE		(NV_PA_APB_MISC_BASE + 0xD000)
 #define TEGRA_DVC_BASE		(NV_PA_APB_MISC_BASE + 0xD000)
 #define NV_PA_PMC_BASE		(NV_PA_APB_MISC_BASE + 0xE400)
 #define NV_PA_PMC_BASE		(NV_PA_APB_MISC_BASE + 0xE400)
 #define NV_PA_EMC_BASE		(NV_PA_APB_MISC_BASE + 0xF400)
 #define NV_PA_EMC_BASE		(NV_PA_APB_MISC_BASE + 0xF400)
@@ -72,14 +78,23 @@ enum {
 	SKU_ID_T25		= 0x18,
 	SKU_ID_T25		= 0x18,
 	SKU_ID_AP25E		= 0x1b,
 	SKU_ID_AP25E		= 0x1b,
 	SKU_ID_T25E		= 0x1c,
 	SKU_ID_T25E		= 0x1c,
+	SKU_ID_T30		= 0x81, /* Cardhu value */
+	SKU_ID_T114_ENG		= 0x00, /* Dalmore value, unfused */
 };
 };
 
 
-/* These are the SOC categories that affect clocking */
+/*
+ * These are used to distinguish SOC types for setting up clocks. Mostly
+ * we can tell the clocking required by looking at the SOC sku_id, but
+ * for T30 it is a user option as to whether to run PLLP in fast or slow
+ * mode, so we have two options there.
+ */
 enum {
 enum {
 	TEGRA_SOC_T20,
 	TEGRA_SOC_T20,
 	TEGRA_SOC_T25,
 	TEGRA_SOC_T25,
+	TEGRA_SOC_T30,
+	TEGRA_SOC_T114,
 
 
-	TEGRA_SOC_COUNT,
+	TEGRA_SOC_CNT,
 	TEGRA_SOC_UNKNOWN	= -1,
 	TEGRA_SOC_UNKNOWN	= -1,
 };
 };
 
 

+ 84 - 0
arch/arm/include/asm/arch-tegra/tegra_slink.h

@@ -0,0 +1,84 @@
+/*
+ * NVIDIA Tegra SPI-SLINK controller
+ *
+ * Copyright 2010-2013 NVIDIA Corporation
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * 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 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 _TEGRA_SLINK_H_
+#define _TEGRA_SLINK_H_
+
+#include <asm/types.h>
+
+struct slink_tegra {
+	u32 command;	/* SLINK_COMMAND_0 register  */
+	u32 command2;	/* SLINK_COMMAND2_0 reg */
+	u32 status;	/* SLINK_STATUS_0 register */
+	u32 reserved;	/* Reserved offset 0C */
+	u32 mas_data;	/* SLINK_MAS_DATA_0 reg */
+	u32 slav_data;	/* SLINK_SLAVE_DATA_0 reg */
+	u32 dma_ctl;	/* SLINK_DMA_CTL_0 register */
+	u32 status2;	/* SLINK_STATUS2_0 reg */
+	u32 rsvd[56];	/* 0x20 to 0xFF reserved */
+	u32 tx_fifo;	/* SLINK_TX_FIFO_0 reg off 100h */
+	u32 rsvd2[31];	/* 0x104 to 0x17F reserved */
+	u32 rx_fifo;	/* SLINK_RX_FIFO_0 reg off 180h */
+};
+
+/* COMMAND */
+#define SLINK_CMD_ENB			(1 << 31)
+#define SLINK_CMD_GO			(1 << 30)
+#define SLINK_CMD_M_S			(1 << 28)
+#define SLINK_CMD_CK_SDA		(1 << 21)
+#define SLINK_CMD_CS_POL		(1 << 13)
+#define SLINK_CMD_CS_VAL		(1 << 12)
+#define SLINK_CMD_CS_SOFT		(1 << 11)
+#define SLINK_CMD_BIT_LENGTH		(1 << 4)
+#define SLINK_CMD_BIT_LENGTH_MASK	0x0000001F
+/* COMMAND2 */
+#define SLINK_CMD2_TXEN			(1 << 30)
+#define SLINK_CMD2_RXEN			(1 << 31)
+#define SLINK_CMD2_SS_EN		(1 << 18)
+#define SLINK_CMD2_SS_EN_SHIFT		18
+#define SLINK_CMD2_SS_EN_MASK		0x000C0000
+#define SLINK_CMD2_CS_ACTIVE_BETWEEN	(1 << 17)
+/* STATUS */
+#define SLINK_STAT_BSY			(1 << 31)
+#define SLINK_STAT_RDY			(1 << 30)
+#define SLINK_STAT_ERR			(1 << 29)
+#define SLINK_STAT_RXF_FLUSH		(1 << 27)
+#define SLINK_STAT_TXF_FLUSH		(1 << 26)
+#define SLINK_STAT_RXF_OVF		(1 << 25)
+#define SLINK_STAT_TXF_UNR		(1 << 24)
+#define SLINK_STAT_RXF_EMPTY		(1 << 23)
+#define SLINK_STAT_RXF_FULL		(1 << 22)
+#define SLINK_STAT_TXF_EMPTY		(1 << 21)
+#define SLINK_STAT_TXF_FULL		(1 << 20)
+#define SLINK_STAT_TXF_OVF		(1 << 19)
+#define SLINK_STAT_RXF_UNR		(1 << 18)
+#define SLINK_STAT_CUR_BLKCNT		(1 << 15)
+/* STATUS2 */
+#define SLINK_STAT2_RXF_FULL_CNT	(1 << 16)
+#define SLINK_STAT2_TXF_FULL_CNT	(1 << 0)
+
+#define SPI_TIMEOUT		1000
+#define TEGRA_SPI_MAX_FREQ	52000000
+
+#endif	/* _TEGRA_SLINK_H_ */

+ 402 - 0
arch/arm/include/asm/arch-tegra114/clock-tables.h

@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra114 clock PLL tables */
+
+#ifndef _TEGRA114_CLOCK_TABLES_H_
+#define _TEGRA114_CLOCK_TABLES_H_
+
+/* The PLLs supported by the hardware */
+enum clock_id {
+	CLOCK_ID_FIRST,
+	CLOCK_ID_CGENERAL = CLOCK_ID_FIRST,
+	CLOCK_ID_MEMORY,
+	CLOCK_ID_PERIPH,
+	CLOCK_ID_AUDIO,
+	CLOCK_ID_USB,
+	CLOCK_ID_DISPLAY,
+
+	/* now the simple ones */
+	CLOCK_ID_FIRST_SIMPLE,
+	CLOCK_ID_XCPU = CLOCK_ID_FIRST_SIMPLE,
+	CLOCK_ID_EPCI,
+	CLOCK_ID_SFROM32KHZ,
+
+	/* These are the base clocks (inputs to the Tegra SOC) */
+	CLOCK_ID_32KHZ,
+	CLOCK_ID_OSC,
+
+	CLOCK_ID_COUNT,	/* number of PLLs */
+	CLOCK_ID_DISPLAY2,	/* placeholder */
+	CLOCK_ID_NONE = -1,
+};
+
+/* The clocks supported by the hardware */
+enum periph_id {
+	PERIPH_ID_FIRST,
+
+	/* Low word: 31:0 (DEVICES_L) */
+	PERIPH_ID_CPU = PERIPH_ID_FIRST,
+	PERIPH_ID_COP,
+	PERIPH_ID_TRIGSYS,
+	PERIPH_ID_RESERVED3,
+	PERIPH_ID_RTC,
+	PERIPH_ID_TMR,
+	PERIPH_ID_UART1,
+	PERIPH_ID_UART2,
+
+	/* 8 */
+	PERIPH_ID_GPIO,
+	PERIPH_ID_SDMMC2,
+	PERIPH_ID_SPDIF,
+	PERIPH_ID_I2S1,
+	PERIPH_ID_I2C1,
+	PERIPH_ID_NDFLASH,
+	PERIPH_ID_SDMMC1,
+	PERIPH_ID_SDMMC4,
+
+	/* 16 */
+	PERIPH_ID_RESERVED16,
+	PERIPH_ID_PWM,
+	PERIPH_ID_I2S2,
+	PERIPH_ID_EPP,
+	PERIPH_ID_VI,
+	PERIPH_ID_2D,
+	PERIPH_ID_USBD,
+	PERIPH_ID_ISP,
+
+	/* 24 */
+	PERIPH_ID_3D,
+	PERIPH_ID_RESERVED24,
+	PERIPH_ID_DISP2,
+	PERIPH_ID_DISP1,
+	PERIPH_ID_HOST1X,
+	PERIPH_ID_VCP,
+	PERIPH_ID_I2S0,
+	PERIPH_ID_CACHE2,
+
+	/* Middle word: 63:32 (DEVICES_H) */
+	PERIPH_ID_MEM,
+	PERIPH_ID_AHBDMA,
+	PERIPH_ID_APBDMA,
+	PERIPH_ID_RESERVED35,
+	PERIPH_ID_KBC,
+	PERIPH_ID_STAT_MON,
+	PERIPH_ID_PMC,
+	PERIPH_ID_FUSE,
+
+	/* 40 */
+	PERIPH_ID_KFUSE,
+	PERIPH_ID_SBC1,
+	PERIPH_ID_SNOR,
+	PERIPH_ID_RESERVED43,
+	PERIPH_ID_SBC2,
+	PERIPH_ID_RESERVED45,
+	PERIPH_ID_SBC3,
+	PERIPH_ID_I2C5,
+
+	/* 48 */
+	PERIPH_ID_DSI,
+	PERIPH_ID_TVO,
+	PERIPH_ID_MIPI,
+	PERIPH_ID_HDMI,
+	PERIPH_ID_CSI,
+	PERIPH_ID_TVDAC,
+	PERIPH_ID_I2C2,
+	PERIPH_ID_UART3,
+
+	/* 56 */
+	PERIPH_ID_RESERVED56,
+	PERIPH_ID_EMC,
+	PERIPH_ID_USB2,
+	PERIPH_ID_USB3,
+	PERIPH_ID_MPE,
+	PERIPH_ID_VDE,
+	PERIPH_ID_BSEA,
+	PERIPH_ID_BSEV,
+
+	/* Upper word 95:64 (DEVICES_U) */
+	PERIPH_ID_SPEEDO,
+	PERIPH_ID_UART4,
+	PERIPH_ID_UART5,
+	PERIPH_ID_I2C3,
+	PERIPH_ID_SBC4,
+	PERIPH_ID_SDMMC3,
+	PERIPH_ID_PCIE,
+	PERIPH_ID_OWR,
+
+	/* 72 */
+	PERIPH_ID_AFI,
+	PERIPH_ID_CORESIGHT,
+	PERIPH_ID_PCIEXCLK,
+	PERIPH_ID_AVPUCQ,
+	PERIPH_ID_RESERVED76,
+	PERIPH_ID_RESERVED77,
+	PERIPH_ID_RESERVED78,
+	PERIPH_ID_DTV,
+
+	/* 80 */
+	PERIPH_ID_NANDSPEED,
+	PERIPH_ID_I2CSLOW,
+	PERIPH_ID_DSIB,
+	PERIPH_ID_RESERVED83,
+	PERIPH_ID_IRAMA,
+	PERIPH_ID_IRAMB,
+	PERIPH_ID_IRAMC,
+	PERIPH_ID_IRAMD,
+
+	/* 88 */
+	PERIPH_ID_CRAM2,
+	PERIPH_ID_RESERVED89,
+	PERIPH_ID_MDOUBLER,
+	PERIPH_ID_RESERVED91,
+	PERIPH_ID_SUSOUT,
+	PERIPH_ID_RESERVED93,
+	PERIPH_ID_RESERVED94,
+	PERIPH_ID_RESERVED95,
+
+	PERIPH_ID_VW_FIRST,
+	/* V word: 31:0 */
+	PERIPH_ID_CPUG = PERIPH_ID_VW_FIRST,
+	PERIPH_ID_CPULP,
+	PERIPH_ID_3D2,
+	PERIPH_ID_MSELECT,
+	PERIPH_ID_TSENSOR,
+	PERIPH_ID_I2S3,
+	PERIPH_ID_I2S4,
+	PERIPH_ID_I2C4,
+
+	/* 104 */
+	PERIPH_ID_SBC5,
+	PERIPH_ID_SBC6,
+	PERIPH_ID_AUDIO,
+	PERIPH_ID_APBIF,
+	PERIPH_ID_DAM0,
+	PERIPH_ID_DAM1,
+	PERIPH_ID_DAM2,
+	PERIPH_ID_HDA2CODEC2X,
+
+	/* 112 */
+	PERIPH_ID_ATOMICS,
+	PERIPH_ID_EX_RESERVED17,
+	PERIPH_ID_EX_RESERVED18,
+	PERIPH_ID_EX_RESERVED19,
+	PERIPH_ID_EX_RESERVED20,
+	PERIPH_ID_EX_RESERVED21,
+	PERIPH_ID_EX_RESERVED22,
+	PERIPH_ID_ACTMON,
+
+	/* 120 */
+	PERIPH_ID_EX_RESERVED24,
+	PERIPH_ID_EX_RESERVED25,
+	PERIPH_ID_EX_RESERVED26,
+	PERIPH_ID_EX_RESERVED27,
+	PERIPH_ID_SATA,
+	PERIPH_ID_HDA,
+	PERIPH_ID_EX_RESERVED30,
+	PERIPH_ID_EX_RESERVED31,
+
+	/* W word: 31:0 */
+	PERIPH_ID_HDA2HDMICODEC,
+	PERIPH_ID_RESERVED1_SATACOLD,
+	PERIPH_ID_RESERVED2_PCIERX0,
+	PERIPH_ID_RESERVED3_PCIERX1,
+	PERIPH_ID_RESERVED4_PCIERX2,
+	PERIPH_ID_RESERVED5_PCIERX3,
+	PERIPH_ID_RESERVED6_PCIERX4,
+	PERIPH_ID_RESERVED7_PCIERX5,
+
+	/* 136 */
+	PERIPH_ID_CEC,
+	PERIPH_ID_PCIE2_IOBIST,
+	PERIPH_ID_EMC_IOBIST,
+	PERIPH_ID_HDMI_IOBIST,
+	PERIPH_ID_SATA_IOBIST,
+	PERIPH_ID_MIPI_IOBIST,
+	PERIPH_ID_EMC1_IOBIST,
+	PERIPH_ID_XUSB,
+
+	/* 144 */
+	PERIPH_ID_CILAB,
+	PERIPH_ID_CILCD,
+	PERIPH_ID_CILE,
+	PERIPH_ID_DSIA_LP,
+	PERIPH_ID_DSIB_LP,
+	PERIPH_ID_RESERVED21_ENTROPY,
+	PERIPH_ID_RESERVED22_W,
+	PERIPH_ID_RESERVED23_W,
+
+	/* 152 */
+	PERIPH_ID_RESERVED24_W,
+	PERIPH_ID_AMX0,
+	PERIPH_ID_ADX0,
+	PERIPH_ID_DVFS,
+	PERIPH_ID_XUSB_SS,
+	PERIPH_ID_EMC_DLL,
+	PERIPH_ID_MC1,
+	PERIPH_ID_EMC1,
+
+	PERIPH_ID_COUNT,
+	PERIPH_ID_NONE = -1,
+};
+
+enum pll_out_id {
+	PLL_OUT1,
+	PLL_OUT2,
+	PLL_OUT3,
+	PLL_OUT4
+};
+
+/*
+ * Clock peripheral IDs which sadly don't match up with PERIPH_ID. we want
+ * callers to use the PERIPH_ID for all access to peripheral clocks to avoid
+ * confusion bewteen PERIPH_ID_... and PERIPHC_...
+ *
+ * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be
+ * confusing.
+ */
+enum periphc_internal_id {
+	/* 0x00 */
+	PERIPHC_I2S1,
+	PERIPHC_I2S2,
+	PERIPHC_SPDIF_OUT,
+	PERIPHC_SPDIF_IN,
+	PERIPHC_PWM,
+	PERIPHC_05h,
+	PERIPHC_SBC2,
+	PERIPHC_SBC3,
+
+	/* 0x08 */
+	PERIPHC_08h,
+	PERIPHC_I2C1,
+	PERIPHC_I2C5,
+	PERIPHC_0bh,
+	PERIPHC_0ch,
+	PERIPHC_SBC1,
+	PERIPHC_DISP1,
+	PERIPHC_DISP2,
+
+	/* 0x10 */
+	PERIPHC_CVE,
+	PERIPHC_11h,
+	PERIPHC_VI,
+	PERIPHC_13h,
+	PERIPHC_SDMMC1,
+	PERIPHC_SDMMC2,
+	PERIPHC_G3D,
+	PERIPHC_G2D,
+
+	/* 0x18 */
+	PERIPHC_NDFLASH,
+	PERIPHC_SDMMC4,
+	PERIPHC_VFIR,
+	PERIPHC_EPP,
+	PERIPHC_MPE,
+	PERIPHC_MIPI,
+	PERIPHC_UART1,
+	PERIPHC_UART2,
+
+	/* 0x20 */
+	PERIPHC_HOST1X,
+	PERIPHC_21h,
+	PERIPHC_TVO,
+	PERIPHC_HDMI,
+	PERIPHC_24h,
+	PERIPHC_TVDAC,
+	PERIPHC_I2C2,
+	PERIPHC_EMC,
+
+	/* 0x28 */
+	PERIPHC_UART3,
+	PERIPHC_29h,
+	PERIPHC_VI_SENSOR,
+	PERIPHC_2bh,
+	PERIPHC_2ch,
+	PERIPHC_SBC4,
+	PERIPHC_I2C3,
+	PERIPHC_SDMMC3,
+
+	/* 0x30 */
+	PERIPHC_UART4,
+	PERIPHC_UART5,
+	PERIPHC_VDE,
+	PERIPHC_OWR,
+	PERIPHC_NOR,
+	PERIPHC_CSITE,
+	PERIPHC_I2S0,
+	PERIPHC_37h,
+
+	PERIPHC_VW_FIRST,
+	/* 0x38 */
+	PERIPHC_G3D2 = PERIPHC_VW_FIRST,
+	PERIPHC_MSELECT,
+	PERIPHC_TSENSOR,
+	PERIPHC_I2S3,
+	PERIPHC_I2S4,
+	PERIPHC_I2C4,
+	PERIPHC_SBC5,
+	PERIPHC_SBC6,
+
+	/* 0x40 */
+	PERIPHC_AUDIO,
+	PERIPHC_41h,
+	PERIPHC_DAM0,
+	PERIPHC_DAM1,
+	PERIPHC_DAM2,
+	PERIPHC_HDA2CODEC2X,
+	PERIPHC_ACTMON,
+	PERIPHC_EXTPERIPH1,
+
+	/* 0x48 */
+	PERIPHC_EXTPERIPH2,
+	PERIPHC_EXTPERIPH3,
+	PERIPHC_NANDSPEED,
+	PERIPHC_I2CSLOW,
+	PERIPHC_SYS,
+	PERIPHC_SPEEDO,
+	PERIPHC_4eh,
+	PERIPHC_4fh,
+
+	/* 0x50 */
+	PERIPHC_50h,
+	PERIPHC_51h,
+	PERIPHC_52h,
+	PERIPHC_53h,
+	PERIPHC_SATAOOB,
+	PERIPHC_SATA,
+	PERIPHC_HDA,
+
+	PERIPHC_COUNT,
+
+	PERIPHC_NONE = -1,
+};
+
+/* Converts a clock number to a clock register: 0=L, 1=H, 2=U, 0=V, 1=W */
+#define PERIPH_REG(id) \
+	(id < PERIPH_ID_VW_FIRST) ? \
+		((id) >> 5) : ((id - PERIPH_ID_VW_FIRST) >> 5)
+
+/* Mask value for a clock (within PERIPH_REG(id)) */
+#define PERIPH_MASK(id) (1 << ((id) & 0x1f))
+
+/* return 1 if a PLL ID is in range */
+#define clock_id_is_pll(id) ((id) >= CLOCK_ID_FIRST && (id) < CLOCK_ID_COUNT)
+
+/* return 1 if a peripheral ID is in range */
+#define clock_periph_id_isvalid(id) ((id) >= PERIPH_ID_FIRST && \
+		(id) < PERIPH_ID_COUNT)
+
+#endif	/* _TEGRA114_CLOCK_TABLES_H_ */

+ 28 - 0
arch/arm/include/asm/arch-tegra114/clock.h

@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra114 clock control functions */
+
+#ifndef _TEGRA114_CLOCK_H_
+#define _TEGRA114_CLOCK_H_
+
+#include <asm/arch-tegra/clock.h>
+
+/* CLK_RST_CONTROLLER_OSC_CTRL_0 */
+#define OSC_FREQ_SHIFT          28
+#define OSC_FREQ_MASK           (0xF << OSC_FREQ_SHIFT)
+
+#endif	/* _TEGRA114_CLOCK_H_ */

+ 35 - 0
arch/arm/include/asm/arch-tegra114/flow.h

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TEGRA114_FLOW_H_
+#define _TEGRA114_FLOW_H_
+
+struct flow_ctlr {
+	u32 halt_cpu_events;
+	u32 halt_cop_events;
+	u32 cpu_csr;
+	u32 cop_csr;
+	u32 xrq_events;
+	u32 halt_cpu1_events;
+	u32 cpu1_csr;
+	u32 halt_cpu2_events;
+	u32 cpu2_csr;
+	u32 halt_cpu3_events;
+	u32 cpu3_csr;
+	u32 cluster_control;
+};
+
+#endif	/* _TEGRA114_FLOW_H_ */

+ 31 - 0
arch/arm/include/asm/arch-tegra114/funcmux.h

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Tegra114 high-level function multiplexing */
+
+#ifndef _TEGRA114_FUNCMUX_H_
+#define _TEGRA114_FUNCMUX_H_
+
+#include <asm/arch-tegra/funcmux.h>
+
+/* Configs supported by the func mux */
+enum {
+	FUNCMUX_DEFAULT = 0,	/* default config */
+
+	/* UART configs */
+	FUNCMUX_UART4_GMI = 0,
+};
+#endif	/* _TEGRA114_FUNCMUX_H_ */

+ 59 - 0
arch/arm/include/asm/arch-tegra114/gp_padctrl.h

@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TEGRA114_GP_PADCTRL_H_
+#define _TEGRA114_GP_PADCTRL_H_
+
+#include <asm/arch-tegra/gp_padctrl.h>
+
+/* APB_MISC_GP and padctrl registers */
+struct apb_misc_gp_ctlr {
+	u32	modereg;	/* 0x00: APB_MISC_GP_MODEREG */
+	u32	hidrev;		/* 0x04: APB_MISC_GP_HIDREV */
+	u32	reserved0[22];	/* 0x08 - 0x5C: */
+	u32	emu_revid;	/* 0x60: APB_MISC_GP_EMU_REVID */
+	u32	xactor_scratch;	/* 0x64: APB_MISC_GP_XACTOR_SCRATCH */
+	u32	aocfg1;		/* 0x68: APB_MISC_GP_AOCFG1PADCTRL */
+	u32	aocfg2;		/* 0x6c: APB_MISC_GP_AOCFG2PADCTRL */
+	u32	atcfg1;		/* 0x70: APB_MISC_GP_ATCFG1PADCTRL */
+	u32	atcfg2;		/* 0x74: APB_MISC_GP_ATCFG2PADCTRL */
+	u32	atcfg3;		/* 0x78: APB_MISC_GP_ATCFG3PADCTRL */
+	u32	atcfg4;		/* 0x7C: APB_MISC_GP_ATCFG4PADCTRL */
+	u32	atcfg5;		/* 0x80: APB_MISC_GP_ATCFG5PADCTRL */
+	u32	cdev1cfg;	/* 0x84: APB_MISC_GP_CDEV1CFGPADCTRL */
+	u32	cdev2cfg;	/* 0x88: APB_MISC_GP_CDEV2CFGPADCTRL */
+	u32	csuscfg;	/* 0x8C: APB_MISC_GP_CSUSCFGPADCTRL */
+	u32	dap1cfg;	/* 0x90: APB_MISC_GP_DAP1CFGPADCTRL */
+	u32	dap2cfg;	/* 0x94: APB_MISC_GP_DAP2CFGPADCTRL */
+	u32	dap3cfg;	/* 0x98: APB_MISC_GP_DAP3CFGPADCTRL */
+	u32	dap4cfg;	/* 0x9C: APB_MISC_GP_DAP4CFGPADCTRL */
+	u32	dbgcfg;		/* 0xA0: APB_MISC_GP_DBGCFGPADCTRL */
+	u32	lcdcfg1;	/* 0xA4: APB_MISC_GP_LCDCFG1PADCTRL */
+	u32	lcdcfg2;	/* 0xA8: APB_MISC_GP_LCDCFG2PADCTRL */
+	u32	sdio2cfg;	/* 0xAC: APB_MISC_GP_SDIO2CFGPADCTRL */
+	u32	sdio3cfg;	/* 0xB0: APB_MISC_GP_SDIO3CFGPADCTRL */
+	u32	spicfg;		/* 0xB4: APB_MISC_GP_SPICFGPADCTRL */
+	u32	uaacfg;		/* 0xB8: APB_MISC_GP_UAACFGPADCTRL */
+	u32	uabcfg;		/* 0xBC: APB_MISC_GP_UABCFGPADCTRL */
+	u32	uart2cfg;	/* 0xC0: APB_MISC_GP_UART2CFGPADCTRL */
+	u32	uart3cfg;	/* 0xC4: APB_MISC_GP_UART3CFGPADCTRL */
+	u32	vicfg1;		/* 0xC8: APB_MISC_GP_VICFG1PADCTRL */
+	u32	vivttgen;	/* 0xCC: APB_MISC_GP_VIVTTGENPADCTRL */
+	u32	reserved1[7];	/* 0xD0-0xE8: */
+	u32	sdio1cfg;	/* 0xEC: APB_MISC_GP_SDIO1CFGPADCTRL */
+};
+
+#endif	/* _TEGRA114_GP_PADCTRL_H_ */

+ 30 - 0
arch/arm/include/asm/arch-tegra114/gpio.h

@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TEGRA114_GPIO_H_
+#define _TEGRA114_GPIO_H_
+
+/*
+ * The Tegra114 GPIO controller has 246 GPIOS in 8 banks of 4 ports,
+ * each with 8 GPIOs.
+ */
+#define TEGRA_GPIO_PORTS	4	/* number of ports per bank */
+#define TEGRA_GPIO_BANKS	8	/* number of banks */
+
+#include <asm/arch-tegra/gpio.h>
+#include <asm/arch-tegra30/gpio.h>
+
+#endif	/* _TEGRA114_GPIO_H_ */

+ 22 - 0
arch/arm/include/asm/arch-tegra114/hardware.h

@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TEGRA114_HARDWARE_H_
+#define _TEGRA114_HARDWARE_H_
+
+/* include tegra specific hardware definitions */
+
+#endif /* _TEGRA114_HARDWARE_H_ */

+ 618 - 0
arch/arm/include/asm/arch-tegra114/pinmux.h

@@ -0,0 +1,618 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TEGRA114_PINMUX_H_
+#define _TEGRA114_PINMUX_H_
+
+/*
+ * Pin groups which we adjust. There are three basic attributes of each pin
+ * group which use this enum:
+ *
+ *	- function
+ *	- pullup / pulldown
+ *	- tristate or normal
+ */
+enum pmux_pingrp {
+	PINGRP_ULPI_DATA0 = 0,  /* offset 0x3000 */
+	PINGRP_ULPI_DATA1,
+	PINGRP_ULPI_DATA2,
+	PINGRP_ULPI_DATA3,
+	PINGRP_ULPI_DATA4,
+	PINGRP_ULPI_DATA5,
+	PINGRP_ULPI_DATA6,
+	PINGRP_ULPI_DATA7,
+	PINGRP_ULPI_CLK,
+	PINGRP_ULPI_DIR,
+	PINGRP_ULPI_NXT,
+	PINGRP_ULPI_STP,
+	PINGRP_DAP3_FS,
+	PINGRP_DAP3_DIN,
+	PINGRP_DAP3_DOUT,
+	PINGRP_DAP3_SCLK,
+	PINGRP_GPIO_PV0,
+	PINGRP_GPIO_PV1,
+	PINGRP_SDMMC1_CLK,
+	PINGRP_SDMMC1_CMD,
+	PINGRP_SDMMC1_DAT3,
+	PINGRP_SDMMC1_DAT2,
+	PINGRP_SDMMC1_DAT1,
+	PINGRP_SDMMC1_DAT0,
+	PINGRP_GPIO_PV2,
+	PINGRP_GPIO_PV3,
+	PINGRP_CLK2_OUT,
+	PINGRP_CLK2_REQ,
+	PINGRP_LCD_PWR1,
+	PINGRP_LCD_PWR2,
+	PINGRP_LCD_SDIN,
+	PINGRP_LCD_SDOUT,
+	PINGRP_LCD_WR_N,
+	PINGRP_LCD_CS0_N,
+	PINGRP_LCD_DC0,
+	PINGRP_LCD_SCK,
+	PINGRP_LCD_PWR0,
+	PINGRP_LCD_PCLK,
+	PINGRP_LCD_DE,
+	PINGRP_LCD_HSYNC,
+	PINGRP_LCD_VSYNC,
+	PINGRP_LCD_D0,
+	PINGRP_LCD_D1,
+	PINGRP_LCD_D2,
+	PINGRP_LCD_D3,
+	PINGRP_LCD_D4,
+	PINGRP_LCD_D5,
+	PINGRP_LCD_D6,
+	PINGRP_LCD_D7,
+	PINGRP_LCD_D8,
+	PINGRP_LCD_D9,
+	PINGRP_LCD_D10,
+	PINGRP_LCD_D11,
+	PINGRP_LCD_D12,
+	PINGRP_LCD_D13,
+	PINGRP_LCD_D14,
+	PINGRP_LCD_D15,
+	PINGRP_LCD_D16,
+	PINGRP_LCD_D17,
+	PINGRP_LCD_D18,
+	PINGRP_LCD_D19,
+	PINGRP_LCD_D20,
+	PINGRP_LCD_D21,
+	PINGRP_LCD_D22,
+	PINGRP_LCD_D23,
+	PINGRP_LCD_CS1_N,
+	PINGRP_LCD_M1,
+	PINGRP_LCD_DC1,
+	PINGRP_HDMI_INT,
+	PINGRP_DDC_SCL,
+	PINGRP_DDC_SDA,
+	PINGRP_CRT_HSYNC,
+	PINGRP_CRT_VSYNC,
+	PINGRP_VI_D0,
+	PINGRP_VI_D1,
+	PINGRP_VI_D2,
+	PINGRP_VI_D3,
+	PINGRP_VI_D4,
+	PINGRP_VI_D5,
+	PINGRP_VI_D6,
+	PINGRP_VI_D7,
+	PINGRP_VI_D8,
+	PINGRP_VI_D9,
+	PINGRP_VI_D10,
+	PINGRP_VI_D11,
+	PINGRP_VI_PCLK,
+	PINGRP_VI_MCLK,
+	PINGRP_VI_VSYNC,
+	PINGRP_VI_HSYNC,
+	PINGRP_UART2_RXD,
+	PINGRP_UART2_TXD,
+	PINGRP_UART2_RTS_N,
+	PINGRP_UART2_CTS_N,
+	PINGRP_UART3_TXD,
+	PINGRP_UART3_RXD,
+	PINGRP_UART3_CTS_N,
+	PINGRP_UART3_RTS_N,
+	PINGRP_GPIO_PU0,
+	PINGRP_GPIO_PU1,
+	PINGRP_GPIO_PU2,
+	PINGRP_GPIO_PU3,
+	PINGRP_GPIO_PU4,
+	PINGRP_GPIO_PU5,
+	PINGRP_GPIO_PU6,
+	PINGRP_GEN1_I2C_SDA,
+	PINGRP_GEN1_I2C_SCL,
+	PINGRP_DAP4_FS,
+	PINGRP_DAP4_DIN,
+	PINGRP_DAP4_DOUT,
+	PINGRP_DAP4_SCLK,
+	PINGRP_CLK3_OUT,
+	PINGRP_CLK3_REQ,
+	PINGRP_GMI_WP_N,
+	PINGRP_GMI_IORDY,
+	PINGRP_GMI_WAIT,
+	PINGRP_GMI_ADV_N,
+	PINGRP_GMI_CLK,
+	PINGRP_GMI_CS0_N,
+	PINGRP_GMI_CS1_N,
+	PINGRP_GMI_CS2_N,
+	PINGRP_GMI_CS3_N,
+	PINGRP_GMI_CS4_N,
+	PINGRP_GMI_CS6_N,
+	PINGRP_GMI_CS7_N,
+	PINGRP_GMI_AD0,
+	PINGRP_GMI_AD1,
+	PINGRP_GMI_AD2,
+	PINGRP_GMI_AD3,
+	PINGRP_GMI_AD4,
+	PINGRP_GMI_AD5,
+	PINGRP_GMI_AD6,
+	PINGRP_GMI_AD7,
+	PINGRP_GMI_AD8,
+	PINGRP_GMI_AD9,
+	PINGRP_GMI_AD10,
+	PINGRP_GMI_AD11,
+	PINGRP_GMI_AD12,
+	PINGRP_GMI_AD13,
+	PINGRP_GMI_AD14,
+	PINGRP_GMI_AD15,
+	PINGRP_GMI_A16,
+	PINGRP_GMI_A17,
+	PINGRP_GMI_A18,
+	PINGRP_GMI_A19,
+	PINGRP_GMI_WR_N,
+	PINGRP_GMI_OE_N,
+	PINGRP_GMI_DQS,
+	PINGRP_GMI_RST_N,
+	PINGRP_GEN2_I2C_SCL,
+	PINGRP_GEN2_I2C_SDA,
+	PINGRP_SDMMC4_CLK,
+	PINGRP_SDMMC4_CMD,
+	PINGRP_SDMMC4_DAT0,
+	PINGRP_SDMMC4_DAT1,
+	PINGRP_SDMMC4_DAT2,
+	PINGRP_SDMMC4_DAT3,
+	PINGRP_SDMMC4_DAT4,
+	PINGRP_SDMMC4_DAT5,
+	PINGRP_SDMMC4_DAT6,
+	PINGRP_SDMMC4_DAT7,
+	PINGRP_SDMMC4_RST_N,
+	PINGRP_CAM_MCLK,
+	PINGRP_GPIO_PCC1,
+	PINGRP_GPIO_PBB0,
+	PINGRP_CAM_I2C_SCL,
+	PINGRP_CAM_I2C_SDA,
+	PINGRP_GPIO_PBB3,
+	PINGRP_GPIO_PBB4,
+	PINGRP_GPIO_PBB5,
+	PINGRP_GPIO_PBB6,
+	PINGRP_GPIO_PBB7,
+	PINGRP_GPIO_PCC2,
+	PINGRP_JTAG_RTCK,
+	PINGRP_PWR_I2C_SCL,
+	PINGRP_PWR_I2C_SDA,
+	PINGRP_KB_ROW0,
+	PINGRP_KB_ROW1,
+	PINGRP_KB_ROW2,
+	PINGRP_KB_ROW3,
+	PINGRP_KB_ROW4,
+	PINGRP_KB_ROW5,
+	PINGRP_KB_ROW6,
+	PINGRP_KB_ROW7,
+	PINGRP_KB_ROW8,
+	PINGRP_KB_ROW9,
+	PINGRP_KB_ROW10,
+	PINGRP_KB_ROW11,
+	PINGRP_KB_ROW12,
+	PINGRP_KB_ROW13,
+	PINGRP_KB_ROW14,
+	PINGRP_KB_ROW15,
+	PINGRP_KB_COL0,
+	PINGRP_KB_COL1,
+	PINGRP_KB_COL2,
+	PINGRP_KB_COL3,
+	PINGRP_KB_COL4,
+	PINGRP_KB_COL5,
+	PINGRP_KB_COL6,
+	PINGRP_KB_COL7,
+	PINGRP_CLK_32K_OUT,
+	PINGRP_SYS_CLK_REQ,
+	PINGRP_CORE_PWR_REQ,
+	PINGRP_CPU_PWR_REQ,
+	PINGRP_PWR_INT_N,
+	PINGRP_CLK_32K_IN,
+	PINGRP_OWR,
+	PINGRP_DAP1_FS,
+	PINGRP_DAP1_DIN,
+	PINGRP_DAP1_DOUT,
+	PINGRP_DAP1_SCLK,
+	PINGRP_CLK1_REQ,
+	PINGRP_CLK1_OUT,
+	PINGRP_SPDIF_IN,
+	PINGRP_SPDIF_OUT,
+	PINGRP_DAP2_FS,
+	PINGRP_DAP2_DIN,
+	PINGRP_DAP2_DOUT,
+	PINGRP_DAP2_SCLK,
+	PINGRP_SPI2_MOSI,
+	PINGRP_SPI2_MISO,
+	PINGRP_SPI2_CS0_N,
+	PINGRP_SPI2_SCK,
+	PINGRP_SPI1_MOSI,
+	PINGRP_SPI1_SCK,
+	PINGRP_SPI1_CS0_N,
+	PINGRP_SPI1_MISO,
+	PINGRP_SPI2_CS1_N,
+	PINGRP_SPI2_CS2_N,
+	PINGRP_SDMMC3_CLK,
+	PINGRP_SDMMC3_CMD,
+	PINGRP_SDMMC3_DAT0,
+	PINGRP_SDMMC3_DAT1,
+	PINGRP_SDMMC3_DAT2,
+	PINGRP_SDMMC3_DAT3,
+	PINGRP_SDMMC3_DAT4,
+	PINGRP_SDMMC3_DAT5,
+	PINGRP_SDMMC3_DAT6,
+	PINGRP_SDMMC3_DAT7,
+	PINGRP_PEX_L0_PRSNT_N,
+	PINGRP_PEX_L0_RST_N,
+	PINGRP_PEX_L0_CLKREQ_N,
+	PINGRP_PEX_WAKE_N,
+	PINGRP_PEX_L1_PRSNT_N,
+	PINGRP_PEX_L1_RST_N,
+	PINGRP_PEX_L1_CLKREQ_N,
+	PINGRP_PEX_L2_PRSNT_N,
+	PINGRP_PEX_L2_RST_N,
+	PINGRP_PEX_L2_CLKREQ_N,
+	PINGRP_HDMI_CEC,	/* offset 0x33e0 */
+	PINGRP_SDMMC1_WP_N,
+	PINGRP_SDMMC3_CD_N,
+	PINGRP_SPI1_CS1_N,
+	PINGRP_SPI1_CS2_N,
+	PINGRP_USB_VBUS_EN0,    /* offset 0x33f4 */
+	PINGRP_USB_VBUS_EN1,
+	PINGRP_SDMMC3_CLK_LB_IN,
+	PINGRP_SDMMC3_CLK_LB_OUT,
+	PINGRP_NAND_GMI_CLK_LB,
+	PINGRP_RESET_OUT_N,
+	PINGRP_COUNT,
+};
+
+enum pdrive_pingrp {
+	PDRIVE_PINGROUP_AO1 = 0, /* offset 0x868 */
+	PDRIVE_PINGROUP_AO2,
+	PDRIVE_PINGROUP_AT1,
+	PDRIVE_PINGROUP_AT2,
+	PDRIVE_PINGROUP_AT3,
+	PDRIVE_PINGROUP_AT4,
+	PDRIVE_PINGROUP_AT5,
+	PDRIVE_PINGROUP_CDEV1,
+	PDRIVE_PINGROUP_CDEV2,
+	PDRIVE_PINGROUP_CSUS,
+	PDRIVE_PINGROUP_DAP1,
+	PDRIVE_PINGROUP_DAP2,
+	PDRIVE_PINGROUP_DAP3,
+	PDRIVE_PINGROUP_DAP4,
+	PDRIVE_PINGROUP_DBG,
+	PDRIVE_PINGROUP_LCD1,
+	PDRIVE_PINGROUP_LCD2,
+	PDRIVE_PINGROUP_SDIO2,
+	PDRIVE_PINGROUP_SDIO3,
+	PDRIVE_PINGROUP_SPI,
+	PDRIVE_PINGROUP_UAA,
+	PDRIVE_PINGROUP_UAB,
+	PDRIVE_PINGROUP_UART2,
+	PDRIVE_PINGROUP_UART3,
+	PDRIVE_PINGROUP_VI1 = 24,       /* offset 0x8c8 */
+	PDRIVE_PINGROUP_SDIO1 = 33,     /* offset 0x8ec */
+	PDRIVE_PINGROUP_CRT = 36,       /* offset 0x8f8 */
+	PDRIVE_PINGROUP_DDC,
+	PDRIVE_PINGROUP_GMA,
+	PDRIVE_PINGROUP_GMB,
+	PDRIVE_PINGROUP_GMC,
+	PDRIVE_PINGROUP_GMD,
+	PDRIVE_PINGROUP_GME,
+	PDRIVE_PINGROUP_GMF,
+	PDRIVE_PINGROUP_GMG,
+	PDRIVE_PINGROUP_GMH,
+	PDRIVE_PINGROUP_OWR,
+	PDRIVE_PINGROUP_UAD,
+	PDRIVE_PINGROUP_GPV,
+	PDRIVE_PINGROUP_DEV3 = 49,      /* offset 0x92c */
+	PDRIVE_PINGROUP_CEC = 52,       /* offset 0x938 */
+	PDRIVE_PINGROUP_AT6,
+	PDRIVE_PINGROUP_DAP5,
+	PDRIVE_PINGROUP_VBUS,
+	PDRIVE_PINGROUP_COUNT,
+};
+
+/*
+ * Functions which can be assigned to each of the pin groups. The values here
+ * bear no relation to the values programmed into pinmux registers and are
+ * purely a convenience. The translation is done through a table search.
+ */
+enum pmux_func {
+	PMUX_FUNC_AHB_CLK,
+	PMUX_FUNC_APB_CLK,
+	PMUX_FUNC_AUDIO_SYNC,
+	PMUX_FUNC_CRT,
+	PMUX_FUNC_DAP1,
+	PMUX_FUNC_DAP2,
+	PMUX_FUNC_DAP3,
+	PMUX_FUNC_DAP4,
+	PMUX_FUNC_DAP5,
+	PMUX_FUNC_DISPA,
+	PMUX_FUNC_DISPB,
+	PMUX_FUNC_EMC_TEST0_DLL,
+	PMUX_FUNC_EMC_TEST1_DLL,
+	PMUX_FUNC_GMI,
+	PMUX_FUNC_GMI_INT,
+	PMUX_FUNC_HDMI,
+	PMUX_FUNC_I2C1,
+	PMUX_FUNC_I2C2,
+	PMUX_FUNC_I2C3,
+	PMUX_FUNC_IDE,
+	PMUX_FUNC_KBC,
+	PMUX_FUNC_MIO,
+	PMUX_FUNC_MIPI_HS,
+	PMUX_FUNC_NAND,
+	PMUX_FUNC_OSC,
+	PMUX_FUNC_OWR,
+	PMUX_FUNC_PCIE,
+	PMUX_FUNC_PLLA_OUT,
+	PMUX_FUNC_PLLC_OUT1,
+	PMUX_FUNC_PLLM_OUT1,
+	PMUX_FUNC_PLLP_OUT2,
+	PMUX_FUNC_PLLP_OUT3,
+	PMUX_FUNC_PLLP_OUT4,
+	PMUX_FUNC_PWM,
+	PMUX_FUNC_PWR_INTR,
+	PMUX_FUNC_PWR_ON,
+	PMUX_FUNC_RTCK,
+	PMUX_FUNC_SDMMC1,
+	PMUX_FUNC_SDMMC2,
+	PMUX_FUNC_SDMMC3,
+	PMUX_FUNC_SDMMC4,
+	PMUX_FUNC_SFLASH,
+	PMUX_FUNC_SPDIF,
+	PMUX_FUNC_SPI1,
+	PMUX_FUNC_SPI2,
+	PMUX_FUNC_SPI2_ALT,
+	PMUX_FUNC_SPI3,
+	PMUX_FUNC_SPI4,
+	PMUX_FUNC_TRACE,
+	PMUX_FUNC_TWC,
+	PMUX_FUNC_UARTA,
+	PMUX_FUNC_UARTB,
+	PMUX_FUNC_UARTC,
+	PMUX_FUNC_UARTD,
+	PMUX_FUNC_UARTE,
+	PMUX_FUNC_ULPI,
+	PMUX_FUNC_VI,
+	PMUX_FUNC_VI_SENSOR_CLK,
+	PMUX_FUNC_XIO,
+	PMUX_FUNC_BLINK,
+	PMUX_FUNC_CEC,
+	PMUX_FUNC_CLK12,
+	PMUX_FUNC_DAP,
+	PMUX_FUNC_DAPSDMMC2,
+	PMUX_FUNC_DDR,
+	PMUX_FUNC_DEV3,
+	PMUX_FUNC_DTV,
+	PMUX_FUNC_VI_ALT1,
+	PMUX_FUNC_VI_ALT2,
+	PMUX_FUNC_VI_ALT3,
+	PMUX_FUNC_EMC_DLL,
+	PMUX_FUNC_EXTPERIPH1,
+	PMUX_FUNC_EXTPERIPH2,
+	PMUX_FUNC_EXTPERIPH3,
+	PMUX_FUNC_GMI_ALT,
+	PMUX_FUNC_HDA,
+	PMUX_FUNC_HSI,
+	PMUX_FUNC_I2C4,
+	PMUX_FUNC_I2C5,
+	PMUX_FUNC_I2CPWR,
+	PMUX_FUNC_I2S0,
+	PMUX_FUNC_I2S1,
+	PMUX_FUNC_I2S2,
+	PMUX_FUNC_I2S3,
+	PMUX_FUNC_I2S4,
+	PMUX_FUNC_NAND_ALT,
+	PMUX_FUNC_POPSDIO4,
+	PMUX_FUNC_POPSDMMC4,
+	PMUX_FUNC_PWM0,
+	PMUX_FUNC_PWM1,
+	PMUX_FUNC_PWM2,
+	PMUX_FUNC_PWM3,
+	PMUX_FUNC_SATA,
+	PMUX_FUNC_SPI5,
+	PMUX_FUNC_SPI6,
+	PMUX_FUNC_SYSCLK,
+	PMUX_FUNC_VGP1,
+	PMUX_FUNC_VGP2,
+	PMUX_FUNC_VGP3,
+	PMUX_FUNC_VGP4,
+	PMUX_FUNC_VGP5,
+	PMUX_FUNC_VGP6,
+
+	PMUX_FUNC_USB,
+	PMUX_FUNC_SOC,
+	PMUX_FUNC_CPU,
+	PMUX_FUNC_CLK,
+	PMUX_FUNC_PWRON,
+	PMUX_FUNC_PMI,
+	PMUX_FUNC_CLDVFS,
+	PMUX_FUNC_RESET_OUT_N,
+
+	PMUX_FUNC_SAFE,
+	PMUX_FUNC_MAX,
+
+	PMUX_FUNC_RSVD1 = 0x8000,
+	PMUX_FUNC_RSVD2 = 0x8001,
+	PMUX_FUNC_RSVD3 = 0x8002,
+	PMUX_FUNC_RSVD4 = 0x8003,
+};
+
+/* return 1 if a pmux_func is in range */
+#define pmux_func_isvalid(func) ((((func) >= 0) && ((func) < PMUX_FUNC_MAX)) \
+	|| (((func) >= PMUX_FUNC_RSVD1) && ((func) <= PMUX_FUNC_RSVD4)))
+
+/* return 1 if a pingrp is in range */
+#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PINGRP_COUNT))
+
+/* The pullup/pulldown state of a pin group */
+enum pmux_pull {
+	PMUX_PULL_NORMAL = 0,
+	PMUX_PULL_DOWN,
+	PMUX_PULL_UP,
+};
+/* return 1 if a pin_pupd_is in range */
+#define pmux_pin_pupd_isvalid(pupd) (((pupd) >= PMUX_PULL_NORMAL) && \
+				((pupd) <= PMUX_PULL_UP))
+
+/* Defines whether a pin group is tristated or in normal operation */
+enum pmux_tristate {
+	PMUX_TRI_NORMAL = 0,
+	PMUX_TRI_TRISTATE = 1,
+};
+/* return 1 if a pin_tristate_is in range */
+#define pmux_pin_tristate_isvalid(tristate) (((tristate) >= PMUX_TRI_NORMAL) \
+				&& ((tristate) <= PMUX_TRI_TRISTATE))
+
+enum pmux_pin_io {
+	PMUX_PIN_OUTPUT = 0,
+	PMUX_PIN_INPUT = 1,
+};
+/* return 1 if a pin_io_is in range */
+#define pmux_pin_io_isvalid(io) (((io) >= PMUX_PIN_OUTPUT) && \
+				((io) <= PMUX_PIN_INPUT))
+
+enum pmux_pin_lock {
+	PMUX_PIN_LOCK_DEFAULT = 0,
+	PMUX_PIN_LOCK_DISABLE,
+	PMUX_PIN_LOCK_ENABLE,
+};
+/* return 1 if a pin_lock is in range */
+#define pmux_pin_lock_isvalid(lock) (((lock) >= PMUX_PIN_LOCK_DEFAULT) && \
+				((lock) <= PMUX_PIN_LOCK_ENABLE))
+
+enum pmux_pin_od {
+	PMUX_PIN_OD_DEFAULT = 0,
+	PMUX_PIN_OD_DISABLE,
+	PMUX_PIN_OD_ENABLE,
+};
+/* return 1 if a pin_od is in range */
+#define pmux_pin_od_isvalid(od) (((od) >= PMUX_PIN_OD_DEFAULT) && \
+				((od) <= PMUX_PIN_OD_ENABLE))
+
+enum pmux_pin_ioreset {
+	PMUX_PIN_IO_RESET_DEFAULT = 0,
+	PMUX_PIN_IO_RESET_DISABLE,
+	PMUX_PIN_IO_RESET_ENABLE,
+};
+/* return 1 if a pin_ioreset_is in range */
+#define pmux_pin_ioreset_isvalid(ioreset) \
+				(((ioreset) >= PMUX_PIN_IO_RESET_DEFAULT) && \
+				((ioreset) <= PMUX_PIN_IO_RESET_ENABLE))
+
+/* Available power domains used by pin groups */
+enum pmux_vddio {
+	PMUX_VDDIO_BB = 0,
+	PMUX_VDDIO_LCD,
+	PMUX_VDDIO_VI,
+	PMUX_VDDIO_UART,
+	PMUX_VDDIO_DDR,
+	PMUX_VDDIO_NAND,
+	PMUX_VDDIO_SYS,
+	PMUX_VDDIO_AUDIO,
+	PMUX_VDDIO_SD,
+	PMUX_VDDIO_CAM,
+	PMUX_VDDIO_GMI,
+	PMUX_VDDIO_PEXCTL,
+	PMUX_VDDIO_SDMMC1,
+	PMUX_VDDIO_SDMMC3,
+	PMUX_VDDIO_SDMMC4,
+
+	PMUX_VDDIO_NONE
+};
+
+/* T114 pin drive group and pin mux registers */
+#define PDRIVE_PINGROUP_OFFSET  (0x868 >> 2)
+#define PMUX_OFFSET     ((0x3000 >> 2) - PDRIVE_PINGROUP_OFFSET - \
+			PDRIVE_PINGROUP_COUNT)
+struct pmux_tri_ctlr {
+	uint pmt_reserved0;		/* ABP_MISC_PP_ reserved offset 00 */
+	uint pmt_reserved1;		/* ABP_MISC_PP_ reserved offset 04 */
+	uint pmt_strap_opt_a;		/* _STRAPPING_OPT_A_0, offset 08   */
+	uint pmt_reserved2;		/* ABP_MISC_PP_ reserved offset 0C */
+	uint pmt_reserved3;		/* ABP_MISC_PP_ reserved offset 10 */
+	uint pmt_reserved4[4];		/* _TRI_STATE_REG_A/B/C/D in t20 */
+	uint pmt_cfg_ctl;		/* _CONFIG_CTL_0, offset 24        */
+
+	uint pmt_reserved[528];		/* ABP_MISC_PP_ reserved offs 28-864 */
+
+	uint pmt_drive[PDRIVE_PINGROUP_COUNT];	/* pin drive grps offs 868 */
+	uint pmt_reserved5[PMUX_OFFSET];
+	uint pmt_ctl[PINGRP_COUNT];	/* mux/pupd/tri regs, offset 0x3000 */
+};
+
+/*
+ * This defines the configuration for a pin, including the function assigned,
+ * pull up/down settings and tristate settings. Having set up one of these
+ * you can call pinmux_config_pingroup() to configure a pin in one step. Also
+ * available is pinmux_config_table() to configure a list of pins.
+ */
+struct pingroup_config {
+	enum pmux_pingrp pingroup;	/* pin group PINGRP_...             */
+	enum pmux_func func;		/* function to assign FUNC_...      */
+	enum pmux_pull pull;		/* pull up/down/normal PMUX_PULL_...*/
+	enum pmux_tristate tristate;	/* tristate or normal PMUX_TRI_...  */
+	enum pmux_pin_io io;		/* input or output PMUX_PIN_...  */
+	enum pmux_pin_lock lock;	/* lock enable/disable PMUX_PIN...  */
+	enum pmux_pin_od od;		/* open-drain or push-pull driver  */
+	enum pmux_pin_ioreset ioreset;	/* input/output reset PMUX_PIN...  */
+};
+
+/* Set a pin group to tristate */
+void pinmux_tristate_enable(enum pmux_pingrp pin);
+
+/* Set a pin group to normal (non tristate) */
+void pinmux_tristate_disable(enum pmux_pingrp pin);
+
+/* Set the pull up/down feature for a pin group */
+void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd);
+
+/* Set the mux function for a pin group */
+void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func);
+
+/* Set the complete configuration for a pin group */
+void pinmux_config_pingroup(struct pingroup_config *config);
+
+/* Set a pin group to tristate or normal */
+void pinmux_set_tristate(enum pmux_pingrp pin, int enable);
+
+/* Set a pin group as input or output */
+void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io);
+
+/**
+ * Configure a list of pin groups
+ *
+ * @param config	List of config items
+ * @param len		Number of config items in list
+ */
+void pinmux_config_table(struct pingroup_config *config, int len);
+
+/* Set a group of pins from a table */
+void pinmux_init(void);
+
+#endif  /* _TEGRA114_PINMUX_H_ */

+ 23 - 0
arch/arm/include/asm/arch-tegra114/pmu.h

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TEGRA114_PMU_H_
+#define _TEGRA114_PMU_H_
+
+/* Set core and CPU voltages to nominal levels */
+int pmu_set_nominal(void);
+
+#endif	/* _TEGRA114_PMU_H_ */

Some files were not shown because too many files changed in this diff