[U-Boot] [PATCH V3 4/7] Tegra30: Add common CPU (shared) files

Tom Warren twarren.nvidia at gmail.com
Wed Dec 12 00:34:15 CET 2012


These files are used by both SPL and main U-Boot.
Also made minor changes to shared Tegra code to support
T30 differences.

Signed-off-by: Tom Warren <twarren at nvidia.com>
---
V2:
* Differentiate between T20 and T30 in ODMDATA and query_sdram_size.
* Fix numerous func entries in pingroup table as per Stephen.
* Added warning about LOCK bit in pinmux_set_lock.
V3:
* Always program PLLP to 408MHz
* Use generic SoC string in print_cpuinfo

 arch/arm/cpu/tegra-common/ap.c                     |   14 +-
 arch/arm/cpu/tegra-common/board.c                  |   41 ++-
 arch/arm/cpu/tegra-common/sys_info.c               |   16 +-
 arch/arm/cpu/tegra20-common/warmboot.c             |    2 +-
 .../{arm720t/tegra30 => tegra30-common}/Makefile   |   11 +-
 .../cpu/{tegra20-common => tegra30-common}/clock.c |  516 +++++++++-----------
 arch/arm/cpu/tegra30-common/funcmux.c              |   57 +++
 arch/arm/cpu/tegra30-common/pinmux.c               |  506 +++++++++++++++++++
 arch/arm/include/asm/arch-tegra/ap.h               |   52 +--
 9 files changed, 880 insertions(+), 335 deletions(-)
 copy arch/arm/cpu/{arm720t/tegra30 => tegra30-common}/Makefile (80%)
 copy arch/arm/cpu/{tegra20-common => tegra30-common}/clock.c (74%)
 create mode 100644 arch/arm/cpu/tegra30-common/funcmux.c
 create mode 100644 arch/arm/cpu/tegra30-common/pinmux.c

diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c
index c4eb137..aebe29e 100644
--- a/arch/arm/cpu/tegra-common/ap.c
+++ b/arch/arm/cpu/tegra-common/ap.c
@@ -20,10 +20,14 @@
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
+
+/* Tegra AP (Application Processor) code */
+
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/gp_padctrl.h>
 #include <asm/arch-tegra/ap.h>
+#include <asm/arch-tegra/clock.h>
 #include <asm/arch-tegra/fuse.h>
 #include <asm/arch-tegra/pmc.h>
 #include <asm/arch-tegra/scu.h>
@@ -58,6 +62,12 @@ int tegra_get_chip_type(void)
 			return TEGRA_SOC_T25;
 		}
 		break;
+	case CHIPID_TEGRA30:
+		switch (tegra_sku_id) {
+		case SKU_ID_T30:
+			return TEGRA_SOC_T30;
+		}
+		break;
 	}
 	/* unknown sku id */
 	return TEGRA_SOC_UNKNOWN;
@@ -93,7 +103,7 @@ static u32 get_odmdata(void)
 
 	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);
 
 	return odmdata;
@@ -127,5 +137,5 @@ void s_init(void)
 		"orr	r0, r0, #0x41\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? */
 }
diff --git a/arch/arm/cpu/tegra-common/board.c b/arch/arm/cpu/tegra-common/board.c
index b2e10c6..af1879c 100644
--- a/arch/arm/cpu/tegra-common/board.c
+++ b/arch/arm/cpu/tegra-common/board.c
@@ -54,16 +54,37 @@ unsigned int query_sdram_size(void)
 	reg = readl(&pmc->pmc_scratch20);
 	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) {
 	case 1:
 		return 0x10000000;	/* 256 MB */
+	case 0:
 	case 2:
 	default:
 		return 0x20000000;	/* 512 MB */
 	case 3:
 		return 0x40000000;	/* 1GB */
 	}
+#else	/* Tegra30 */
+	/* 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)
@@ -82,19 +103,27 @@ int checkboard(void)
 #endif	/* CONFIG_DISPLAY_BOARDINFO */
 
 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,
-#elif defined(CONFIG_TEGRA_UARTA_GPU)
+ #elif defined(CONFIG_TEGRA_UARTA_GPU)
 	FUNCMUX_UART1_GPU,
-#elif defined(CONFIG_TEGRA_UARTA_SDIO1)
+ #elif defined(CONFIG_TEGRA_UARTA_SDIO1)
 	FUNCMUX_UART1_SDIO1,
-#else
+ #else
 	FUNCMUX_UART1_IRRX_IRTX,
-#endif
+ #endif
 	FUNCMUX_UART2_IRDA,
 	-1,
 	FUNCMUX_UART4_GMC,
 	-1,
+#else	/* Tegra30 */
+	FUNCMUX_UART1_ULPI,	/* UARTA */
+	-1,
+	-1,
+	-1,
+	-1,
+#endif
 };
 
 /**
diff --git a/arch/arm/cpu/tegra-common/sys_info.c b/arch/arm/cpu/tegra-common/sys_info.c
index 1a0bb56..4632f15 100644
--- a/arch/arm/cpu/tegra-common/sys_info.c
+++ b/arch/arm/cpu/tegra-common/sys_info.c
@@ -22,12 +22,26 @@
  */
 
 #include <common.h>
+#include <linux/ctype.h>
 
 #ifdef CONFIG_DISPLAY_CPUINFO
+void upstring(char *s)
+{
+	while (*s) {
+		*s = toupper(*s);
+		s++;
+	}
+}
+
 /* Print CPU information */
 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. */
 	return 0;
diff --git a/arch/arm/cpu/tegra20-common/warmboot.c b/arch/arm/cpu/tegra20-common/warmboot.c
index 157b9ab..0d472cf 100644
--- a/arch/arm/cpu/tegra20-common/warmboot.c
+++ b/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
  * 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 */
 union xm2cfga_reg {
diff --git a/arch/arm/cpu/arm720t/tegra30/Makefile b/arch/arm/cpu/tegra30-common/Makefile
similarity index 80%
copy from arch/arm/cpu/arm720t/tegra30/Makefile
copy to arch/arm/cpu/tegra30-common/Makefile
index bd96997..75fef32 100644
--- a/arch/arm/cpu/arm720t/tegra30/Makefile
+++ b/arch/arm/cpu/tegra30-common/Makefile
@@ -19,12 +19,15 @@
 
 include $(TOPDIR)/config.mk
 
-LIB	= $(obj)lib$(SOC).o
+# The AVP is ARMv4T architecture so we must use special compiler
+# flags for any startup files it might use.
 
-COBJS-y	+= cpu.o
+LIB	= $(obj)lib$(SOC)-common.o
 
-SRCS	:= $(COBJS-y:.o=.c)
-OBJS	:= $(addprefix $(obj),$(COBJS-y))
+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)
 
diff --git a/arch/arm/cpu/tegra20-common/clock.c b/arch/arm/cpu/tegra30-common/clock.c
similarity index 74%
copy from arch/arm/cpu/tegra20-common/clock.c
copy to arch/arm/cpu/tegra30-common/clock.c
index 12987a6..5db9d20 100644
--- a/arch/arm/cpu/tegra20-common/clock.c
+++ b/arch/arm/cpu/tegra30-common/clock.c
@@ -1,25 +1,20 @@
 /*
- * Copyright (c) 2011 The Chromium OS Authors.
- * See file CREDITS for list of people who contributed to this
- * project.
+ * 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 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 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 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.
+ * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/* Tegra20 Clock control functions */
+/* Tegra30 Clock control functions */
 
 #include <common.h>
 #include <asm/io.h>
@@ -49,7 +44,7 @@ static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = {
 };
 
 /*
- * 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 Tegra3 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.
@@ -68,9 +63,11 @@ enum clock_type_id {
 	CLOCK_TYPE_MCPT,
 	CLOCK_TYPE_PCM,
 	CLOCK_TYPE_PCMT,
-	CLOCK_TYPE_PCMT16,	/* CLOCK_TYPE_PCMT with 16-bit divider */
-	CLOCK_TYPE_PCXTS,
 	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 */
@@ -83,113 +80,55 @@ enum clock_type_id {
 char pllp_valid = 1;	/* PLLP is set up correctly */
 
 enum {
-	CLOCK_MAX_MUX	= 4	/* number of source options for each clock */
+	CLOCK_MAX_MUX	= 8	/* number of source options for each clock */
 };
 
-/*
- * Clock source mux for each clock type. This just converts our enum into
- * a list of mux sources for use by the code. Note that CLOCK_TYPE_PCXTS
- * is special as it has 5 sources. Since it also has a different number of
- * bits in its register for the source, we just handle it with a special
- * case in the code.
- */
-#define CLK(x) CLOCK_ID_ ## x
-static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX] = {
-	{ CLK(AUDIO),	CLK(XCPU),	CLK(PERIPH),	CLK(OSC)	},
-	{ CLK(MEMORY),	CLK(CGENERAL),	CLK(PERIPH),	CLK(AUDIO)	},
-	{ CLK(MEMORY),	CLK(CGENERAL),	CLK(PERIPH),	CLK(OSC)	},
-	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(NONE)	},
-	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(OSC)	},
-	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(OSC)	},
-	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(XCPU),	CLK(OSC)	},
-	{ CLK(PERIPH),	CLK(DISPLAY),	CLK(CGENERAL),	CLK(OSC)	},
+enum {
+	MASK_BITS_31_30	= 2,	/* num of bits used to specify clock source */
+	MASK_BITS_31_29,
+	MASK_BITS_29_28,
 };
 
 /*
- * Clock peripheral IDs which sadly don't match up with PERIPH_ID. This is
- * not in the header file since it is for purely internal use - 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.
+ * Clock source mux for each clock type. This just converts our enum into
+ * a list of mux sources for use by the code.
  *
- * Note to SOC vendors: perhaps define a unified numbering for peripherals and
- * use it for reset, clock enable, clock source/divider and even pinmuxing
- * if you can.
+ * Note:
+ *  The extra column in each clock source array is used to store the mask
+ *  bits in its register for the source.
  */
-enum periphc_internal_id {
-	/* 0x00 */
-	PERIPHC_I2S1,
-	PERIPHC_I2S2,
-	PERIPHC_SPDIF_OUT,
-	PERIPHC_SPDIF_IN,
-	PERIPHC_PWM,
-	PERIPHC_SPI1,
-	PERIPHC_SPI2,
-	PERIPHC_SPI3,
-
-	/* 0x08 */
-	PERIPHC_XIO,
-	PERIPHC_I2C1,
-	PERIPHC_DVC_I2C,
-	PERIPHC_TWC,
-	PERIPHC_0c,
-	PERIPHC_10,	/* PERIPHC_SPI1, what is this really? */
-	PERIPHC_DISP1,
-	PERIPHC_DISP2,
-
-	/* 0x10 */
-	PERIPHC_CVE,
-	PERIPHC_IDE0,
-	PERIPHC_VI,
-	PERIPHC_1c,
-	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_21,
-	PERIPHC_TVO,
-	PERIPHC_HDMI,
-	PERIPHC_24,
-	PERIPHC_TVDAC,
-	PERIPHC_I2C2,
-	PERIPHC_EMC,
-
-	/* 0x28 */
-	PERIPHC_UART3,
-	PERIPHC_29,
-	PERIPHC_VI_SENSOR,
-	PERIPHC_2b,
-	PERIPHC_2c,
-	PERIPHC_SPI4,
-	PERIPHC_I2C3,
-	PERIPHC_SDMMC3,
-
-	/* 0x30 */
-	PERIPHC_UART4,
-	PERIPHC_UART5,
-	PERIPHC_VDE,
-	PERIPHC_OWR,
-	PERIPHC_NOR,
-	PERIPHC_CSITE,
-
-	PERIPHC_COUNT,
-
-	PERIPHC_NONE = -1,
+#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(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}
 };
 
 /* return 1 if a periphc_internal_id is in range */
@@ -207,24 +146,24 @@ static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
 	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_PCXTS),
-	TYPE(PERIPHC_SPI1,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_SPI22,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_SPI3,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_PWM,	CLOCK_TYPE_PCST),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SBC2,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SBC3,	CLOCK_TYPE_PCMT),
 
 	/* 0x08 */
-	TYPE(PERIPHC_XIO,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_I2C1,	CLOCK_TYPE_PCMT16),
-	TYPE(PERIPHC_DVC_I2C,	CLOCK_TYPE_PCMT16),
-	TYPE(PERIPHC_TWC,	CLOCK_TYPE_PCMT),
 	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
-	TYPE(PERIPHC_SPI1,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_DISP1,	CLOCK_TYPE_PDCT),
-	TYPE(PERIPHC_DISP2,	CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_I2C1,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_DVC_I2C,	CLOCK_TYPE_PCMT),
+	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_IDE0,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
 	TYPE(PERIPHC_VI,	CLOCK_TYPE_MCPA),
 	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
 	TYPE(PERIPHC_SDMMC1,	CLOCK_TYPE_PCMT),
@@ -246,10 +185,10 @@ static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
 	TYPE(PERIPHC_HOST1X,	CLOCK_TYPE_MCPA),
 	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
 	TYPE(PERIPHC_TVO,	CLOCK_TYPE_PDCT),
-	TYPE(PERIPHC_HDMI,	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_I2C2,	CLOCK_TYPE_PCMT),
 	TYPE(PERIPHC_EMC,	CLOCK_TYPE_MCPT),
 
 	/* 0x28 */
@@ -258,8 +197,8 @@ static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
 	TYPE(PERIPHC_VI,	CLOCK_TYPE_MCPA),
 	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
 	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
-	TYPE(PERIPHC_SPI4,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_I2C3,	CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_SBC4,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_I2C3,	CLOCK_TYPE_PCMT),
 	TYPE(PERIPHC_SDMMC3,	CLOCK_TYPE_PCMT),
 
 	/* 0x30 */
@@ -269,6 +208,43 @@ static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
 	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 */
+	TYPE(PERIPHC_G3D2,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_MSELECT,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_TSENSOR,	CLOCK_TYPE_PCM),
+	TYPE(PERIPHC_I2S3,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_I2S4,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_I2C4,	CLOCK_TYPE_PCMT),
+	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_PCM),
+	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_PCMT),
+	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_SATAOOB,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SATA,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_HDA,	CLOCK_TYPE_PCMT),
 };
 
 /*
@@ -284,15 +260,15 @@ static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
 static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
 	/* Low word: 31:0 */
 	NONE(CPU),
-	NONE(RESERVED1),
-	NONE(RESERVED2),
-	NONE(AC97),
-	NONE(RTC),
+	NONE(COP),
+	NONE(TRIGSYS),
+	NONE(RESERVED3),
+	NONE(RESERVED4),
 	NONE(TMR),
 	PERIPHC_UART1,
 	PERIPHC_UART2,	/* and vfir 0x68 */
 
-	/* 0x08 */
+	/* 8 */
 	NONE(GPIO),
 	PERIPHC_SDMMC2,
 	NONE(SPDIF),		/* 0x08 and 0x0c, unclear which to use */
@@ -302,8 +278,8 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
 	PERIPHC_SDMMC1,
 	PERIPHC_SDMMC4,
 
-	/* 0x10 */
-	PERIPHC_TWC,
+	/* 16 */
+	NONE(RESERVED16),
 	PERIPHC_PWM,
 	PERIPHC_I2S2,
 	PERIPHC_EPP,
@@ -312,14 +288,14 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
 	NONE(USBD),
 	NONE(ISP),
 
-	/* 0x18 */
+	/* 24 */
 	PERIPHC_G3D,
-	PERIPHC_IDE0,
+	NONE(RESERVED25),
 	PERIPHC_DISP2,
 	PERIPHC_DISP1,
 	PERIPHC_HOST1X,
 	NONE(VCP),
-	NONE(RESERVED30),
+	PERIPHC_I2S0,
 	NONE(CACHE2),
 
 	/* Middle word: 63:32 */
@@ -327,32 +303,32 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
 	NONE(AHBDMA),
 	NONE(APBDMA),
 	NONE(RESERVED35),
-	NONE(KBC),
+	NONE(RESERVED36),
 	NONE(STAT_MON),
-	NONE(PMC),
-	NONE(FUSE),
+	NONE(RESERVED38),
+	NONE(RESERVED39),
 
-	/* 0x28 */
+	/* 40 */
 	NONE(KFUSE),
 	NONE(SBC1),	/* SBC1, 0x34, is this SPI1? */
 	PERIPHC_NOR,
-	PERIPHC_SPI1,
-	PERIPHC_SPI2,
-	PERIPHC_XIO,
-	PERIPHC_SPI3,
+	NONE(RESERVED43),
+	PERIPHC_SBC2,
+	NONE(RESERVED45),
+	PERIPHC_SBC3,
 	PERIPHC_DVC_I2C,
 
-	/* 0x30 */
+	/* 48 */
 	NONE(DSI),
 	PERIPHC_TVO,	/* also CVE 0x40 */
 	PERIPHC_MIPI,
 	PERIPHC_HDMI,
-	PERIPHC_CSITE,
+	NONE(CSI),
 	PERIPHC_TVDAC,
 	PERIPHC_I2C2,
 	PERIPHC_UART3,
 
-	/* 0x38 */
+	/* 56 */
 	NONE(RESERVED56),
 	PERIPHC_EMC,
 	NONE(USB2),
@@ -363,47 +339,104 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
 	NONE(BSEV),
 
 	/* Upper word 95:64 */
-	NONE(SPEEDO),
+	PERIPHC_SPEEDO,
 	PERIPHC_UART4,
 	PERIPHC_UART5,
 	PERIPHC_I2C3,
-	PERIPHC_SPI4,
+	PERIPHC_SBC4,
 	PERIPHC_SDMMC3,
 	NONE(PCIE),
 	PERIPHC_OWR,
 
-	/* 0x48 */
+	/* 72 */
 	NONE(AFI),
-	NONE(CORESIGHT),
-	NONE(RESERVED74),
+	PERIPHC_CSITE,
+	NONE(PCIEXCLK),
 	NONE(AVPUCQ),
 	NONE(RESERVED76),
 	NONE(RESERVED77),
 	NONE(RESERVED78),
-	NONE(RESERVED79),
+	NONE(DTV),
 
-	/* 0x50 */
-	NONE(RESERVED80),
-	NONE(RESERVED81),
-	NONE(RESERVED82),
+	/* 80 */
+	PERIPHC_NANDSPEED,
+	PERIPHC_I2CSLOW,
+	NONE(DSIB),
 	NONE(RESERVED83),
 	NONE(IRAMA),
 	NONE(IRAMB),
 	NONE(IRAMC),
 	NONE(IRAMD),
 
-	/* 0x58 */
+	/* 88 */
 	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 */
+	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),
 };
 
 /*
@@ -458,7 +491,6 @@ int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
 	data = readl(&pll->pll_misc);
 	*cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT;
 	*lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT;
-
 	return 0;
 }
 
@@ -491,37 +523,6 @@ unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
 	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 */
 static u32 *get_periph_source_reg(enum periph_id periph_id)
 {
@@ -529,10 +530,18 @@ static u32 *get_periph_source_reg(enum periph_id periph_id)
 			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
 	enum periphc_internal_id internal_id;
 
-	assert(clock_periph_id_isvalid(periph_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);
-	return &clkrst->crc_clk_src[internal_id];
+	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];
 }
 
 void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source,
@@ -614,34 +623,6 @@ unsigned long clock_get_periph_rate(enum periph_id periph_id,
 		(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
@@ -710,33 +691,12 @@ static int get_periph_clock_source(enum periph_id periph_id,
 	type = clock_periph_type[internal_id];
 	assert(clock_type_id_isvalid(type));
 
-	/*
-	 * Special cases here for the clock with a 4-bit source mux and I2C
-	 * with its 16-bit divisor
-	 */
-	if (type == CLOCK_TYPE_PCXTS)
-		*mux_bits = 4;
-	else
-		*mux_bits = 2;
-	if (type == CLOCK_TYPE_PCMT16)
-		*divider_bits = 16;
-	else
-		*divider_bits = 8;
+	*mux_bits = clock_source[type][CLOCK_MAX_MUX];
 
 	for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
 		if (clock_source[type][mux] == parent)
 			return mux;
 
-	/*
-	 * Not found: it might be looking for the 'S' in CLOCK_TYPE_PCXTS
-	 * which is not in our table. If not, then they are asking for a
-	 * source which this peripheral can't access through its mux.
-	 */
-	assert(type == CLOCK_TYPE_PCXTS);
-	assert(parent == CLOCK_ID_SFROM32KHZ);
-	if (type == CLOCK_TYPE_PCXTS && parent == CLOCK_ID_SFROM32KHZ)
-		return 4;	/* mux value for this clock */
-
 	/* 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);
@@ -780,8 +740,8 @@ 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;
+	int mux_bits, source;
+	int divider, divider_bits = 0;
 
 	/* work out the source clock and set it */
 	source = get_periph_clock_source(periph_id, parent, &mux_bits,
@@ -829,11 +789,15 @@ 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 = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
+	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);
@@ -856,11 +820,15 @@ 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 = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
+	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);
@@ -887,8 +855,8 @@ void reset_cmplx_set_enable(int cpu, int which, int reset)
 			(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);
+	/* Form the mask, which depends on the cpu chosen. Tegra3 has 4 */
+	assert(cpu >= 0 && cpu < 4);
 	mask = which << cpu;
 
 	/* either enable or disable those reset for that CPU */
@@ -1075,31 +1043,29 @@ int clock_verify(void)
 		printf("Warning: PLLP %x is not correct\n", reg);
 		return -1;
 	}
-	debug("PLLX %x is correct\n", reg);
+	debug("PLLP %x is correct\n", reg);
 	return 0;
 }
 
 void clock_early_init(void)
 {
 	/*
-	 * PLLP output frequency set to 216MHz
-	 * PLLC output frequency set to 600Mhz
-	 *
-	 * TODO: Can we calculate these values instead of hard-coding?
+	 * 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, 432, 12, 1, 8);
-		clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
+		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, 432, 26, 1, 8);
+		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, 432, 13, 1, 8);
+		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:
diff --git a/arch/arm/cpu/tegra30-common/funcmux.c b/arch/arm/cpu/tegra30-common/funcmux.c
new file mode 100644
index 0000000..e24c57e
--- /dev/null
+++ b/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;
+}
diff --git a/arch/arm/cpu/tegra30-common/pinmux.c b/arch/arm/cpu/tegra30-common/pinmux.c
new file mode 100644
index 0000000..122665f
--- /dev/null
+++ b/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]);
+}
diff --git a/arch/arm/include/asm/arch-tegra/ap.h b/arch/arm/include/asm/arch-tegra/ap.h
index 70d94c5..73dfd39 100644
--- a/arch/arm/include/asm/arch-tegra/ap.h
+++ b/arch/arm/include/asm/arch-tegra/ap.h
@@ -23,67 +23,27 @@
 #include <asm/types.h>
 
 /* Stabilization delays, in usec */
-#define PLL_STABILIZATION_DELAY (300)
+#define PLL_STABILIZATION_DELAY	(300)
 #define IO_STABILIZATION_DELAY	(1000)
 
-#define NVBL_PLLP_KHZ	(216000)
-
 #define PLLX_ENABLED		(1 << 30)
 #define CCLK_BURST_POLICY	0x20008888
 #define SUPER_CCLK_DIVIDER	0x80000000
 
 /* 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 */
-#define CLK_FREQUENCY(REF, REG)  (((REF) * 2) / (REG + 2))
+#define CLK_FREQUENCY(REF, REG)	(((REF) * 2) / (REG + 2))
 
 /* AVP/CPU ID */
 #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;
 
-/* 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 CSITE_CPU_DBG0_LAR		(NV_PA_CSITE_BASE + 0x10FB0)
-- 
1.7.0.4



More information about the U-Boot mailing list