diff mbox

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

Message ID 1355268858-7868-5-git-send-email-twarren@nvidia.com
State Accepted
Delegated to: Tom Warren
Headers show

Commit Message

Tom Warren Dec. 11, 2012, 11:34 p.m. UTC
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@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

Comments

Allen Martin Dec. 12, 2012, 12:45 a.m. UTC | #1
On Tue, Dec 11, 2012 at 03:34:15PM -0800, Tom Warren wrote:
> 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@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? */

We should probably just remove this README, I don't believe it applies
any more.

>  }
> 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,

Shouldn't there be entries for other UART selections here?

> +#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.

The SPL build should make this transparent to this Makefile.

> 
> -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
>
Tom Warren Dec. 12, 2012, 4:14 p.m. UTC | #2
Allen,

On Tue, Dec 11, 2012 at 5:45 PM, Allen Martin <amartin@nvidia.com> wrote:
> On Tue, Dec 11, 2012 at 03:34:15PM -0800, Tom Warren wrote:
>> 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@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
>>
<snip>
>>
>> -       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? */
>
> We should probably just remove this README, I don't believe it applies
> any more.

By README, you mean FIXME? It can be removed, but only if I'm forced
to do a V4 patchset for more substantive changes. Otherwise I'll put
it in my list of 'cleanup' items.

>
>>  }
>> 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
<snip>
>>
>>  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,
>
> Shouldn't there be entries for other UART selections here?

Right now, there are no other T30 boards in my possession with any
other UARTs used for debug output. Stephen's soon-to-be-adopted
ODMDATA/ODMDATA2 changes will hopefully remove the need for these
tables.

<snip>

>> 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.
>
> The SPL build should make this transparent to this Makefile.

I"ll remove the comment if I do a V4 patchset, otherwise it'll go in
the 'cleanup' patchset.

Thanks,

Tom
Stephen Warren Dec. 12, 2012, 10:06 p.m. UTC | #3
On 12/12/2012 09:14 AM, Tom Warren wrote:
> Allen,
> 
> On Tue, Dec 11, 2012 at 5:45 PM, Allen Martin <amartin@nvidia.com> wrote:
>> On Tue, Dec 11, 2012 at 03:34:15PM -0800, Tom Warren wrote:
>>> 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@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
>>>
> <snip>
>>>
>>> -       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? */
>>
>> We should probably just remove this README, I don't believe it applies
>> any more.
> 
> By README, you mean FIXME? It can be removed, but only if I'm forced
> to do a V4 patchset for more substantive changes. Otherwise I'll put
> it in my list of 'cleanup' items.

In my opinion at least, for very minor stuff like this, you can just
implement the review feedback and apply the patches without the need to
actually repost it. Anything much more than editing a comment, removing
a stale comment or removing some added lines from the patch that
shouldn't be added would warrant a repost though.
Stephen Warren Dec. 12, 2012, 10:09 p.m. UTC | #4
On 12/11/2012 04:34 PM, Tom Warren wrote:
> These files are used by both SPL and main U-Boot.
> Also made minor changes to shared Tegra code to support
> T30 differences.

Reviewed-by: Stephen Warren <swarren@nvidia.com>

(briefly!)
Tom Warren Dec. 12, 2012, 11:07 p.m. UTC | #5
Stephen,

On Wed, Dec 12, 2012 at 3:06 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 12/12/2012 09:14 AM, Tom Warren wrote:
>> Allen,
>>
>> On Tue, Dec 11, 2012 at 5:45 PM, Allen Martin <amartin@nvidia.com> wrote:
>>> On Tue, Dec 11, 2012 at 03:34:15PM -0800, Tom Warren wrote:
>>>> 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@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
>>>>
>> <snip>
>>>>
>>>> -       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? */
>>>
>>> We should probably just remove this README, I don't believe it applies
>>> any more.
>>
>> By README, you mean FIXME? It can be removed, but only if I'm forced
>> to do a V4 patchset for more substantive changes. Otherwise I'll put
>> it in my list of 'cleanup' items.
>
> In my opinion at least, for very minor stuff like this, you can just
> implement the review feedback and apply the patches without the need to
> actually repost it. Anything much more than editing a comment, removing
> a stale comment or removing some added lines from the patch that
> shouldn't be added would warrant a repost though.

I see - another good point. I'd always been really anal about patches
and bumped another Vx for even minor stuff.

I can drop the stuff you and Allen mentioned when I apply these to
u-boot-tegra/next. Thanks.
diff mbox

Patch

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)