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 <twar...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to