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

Allen Martin amartin at nvidia.com
Wed Dec 12 01:45:31 CET 2012


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 at nvidia.com>
> ---
> V2:
> * Differentiate between T20 and T30 in ODMDATA and query_sdram_size.
> * Fix numerous func entries in pingroup table as per Stephen.
> * Added warning about LOCK bit in pinmux_set_lock.
> V3:
> * Always program PLLP to 408MHz
> * Use generic SoC string in print_cpuinfo
> 
>  arch/arm/cpu/tegra-common/ap.c                     |   14 +-
>  arch/arm/cpu/tegra-common/board.c                  |   41 ++-
>  arch/arm/cpu/tegra-common/sys_info.c               |   16 +-
>  arch/arm/cpu/tegra20-common/warmboot.c             |    2 +-
>  .../{arm720t/tegra30 => tegra30-common}/Makefile   |   11 +-
>  .../cpu/{tegra20-common => tegra30-common}/clock.c |  516 +++++++++-----------
>  arch/arm/cpu/tegra30-common/funcmux.c              |   57 +++
>  arch/arm/cpu/tegra30-common/pinmux.c               |  506 +++++++++++++++++++
>  arch/arm/include/asm/arch-tegra/ap.h               |   52 +--
>  9 files changed, 880 insertions(+), 335 deletions(-)
>  copy arch/arm/cpu/{arm720t/tegra30 => tegra30-common}/Makefile (80%)
>  copy arch/arm/cpu/{tegra20-common => tegra30-common}/clock.c (74%)
>  create mode 100644 arch/arm/cpu/tegra30-common/funcmux.c
>  create mode 100644 arch/arm/cpu/tegra30-common/pinmux.c
> 
> diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c
> index c4eb137..aebe29e 100644
> --- a/arch/arm/cpu/tegra-common/ap.c
> +++ b/arch/arm/cpu/tegra-common/ap.c
> @@ -20,10 +20,14 @@
>  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>  * MA 02111-1307 USA
>  */
> +
> +/* Tegra AP (Application Processor) code */
> +
>  #include <common.h>
>  #include <asm/io.h>
>  #include <asm/arch/gp_padctrl.h>
>  #include <asm/arch-tegra/ap.h>
> +#include <asm/arch-tegra/clock.h>
>  #include <asm/arch-tegra/fuse.h>
>  #include <asm/arch-tegra/pmc.h>
>  #include <asm/arch-tegra/scu.h>
> @@ -58,6 +62,12 @@ int tegra_get_chip_type(void)
>                         return TEGRA_SOC_T25;
>                 }
>                 break;
> +       case CHIPID_TEGRA30:
> +               switch (tegra_sku_id) {
> +               case SKU_ID_T30:
> +                       return TEGRA_SOC_T30;
> +               }
> +               break;
>         }
>         /* unknown sku id */
>         return TEGRA_SOC_UNKNOWN;
> @@ -93,7 +103,7 @@ static u32 get_odmdata(void)
> 
>         u32 bct_start, odmdata;
> 
> -       bct_start = readl(AP20_BASE_PA_SRAM + NVBOOTINFOTABLE_BCTPTR);
> +       bct_start = readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BCTPTR);
>         odmdata = readl(bct_start + BCT_ODMDATA_OFFSET);
> 
>         return odmdata;
> @@ -127,5 +137,5 @@ void s_init(void)
>                 "orr    r0, r0, #0x41\n"
>                 "mcr    p15, 0, r0, c1, c0, 1\n");
> 
> -       /* FIXME: should have ap20's L2 disabled too? */
> +       /* FIXME: should have SoC's L2 disabled too? */

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
> 

-- 
nvpublic


More information about the U-Boot mailing list