diff mbox

[U-Boot,05/11] ARM: tegra: pinctrl: remove duplication

Message ID 1394732527-13961-6-git-send-email-swarren@wwwdotorg.org
State Superseded
Delegated to: Tom Warren
Headers show

Commit Message

Stephen Warren March 13, 2014, 5:42 p.m. UTC
From: Stephen Warren <swarren@nvidia.com>

Much of arch/arm/cpu/tegra*-common/pinmux.c is identical. Remove the
duplication by creating pinmux-common.c for all the identical code.

This leaves:
* arch/arm/include/asm/arch-tegra*/pinmux.h defining only the names of
  the various pins/pin groups, drive groups, and mux functions.
* arch/arm/cpu/tegra*-common/pinmux.c containing only the lookup table
  stating which pin groups support which mux functions.

The code in pinmux-common.c is semantically identical to that in the
various original pinmux.c, but had some consistency and cleanup fixes
applied during migration.

I removed the definition of struct pmux_tri_ctlr, since this is different
between SoCs (especially Tegra20 vs all others), and it's much simpler to
deal with this via the new REG/MUX_REG/... defines. spl.c, warmboot.c,
and warmboot_avp.c needed updates due to this, since they previously
hijacked this struct to encode the location of some non-pinmux registers.
Now, that code simply calculates these register addresses directly using
simple and obvious math. I like this method better irrespective of the
pinmux code cleanup anyway.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
 arch/arm/cpu/arm720t/tegra-common/spl.c     |   4 +-
 arch/arm/cpu/tegra-common/Makefile          |   6 +-
 arch/arm/cpu/tegra-common/pinmux-common.c   | 507 ++++++++++++++++++++++++++++
 arch/arm/cpu/tegra114-common/pinmux.c       | 430 +----------------------
 arch/arm/cpu/tegra124-common/pinmux.c       | 429 +----------------------
 arch/arm/cpu/tegra20-common/pinmux.c        | 124 +------
 arch/arm/cpu/tegra20-common/warmboot.c      |   5 +-
 arch/arm/cpu/tegra20-common/warmboot_avp.c  |   4 +-
 arch/arm/cpu/tegra30-common/pinmux.c        | 400 +---------------------
 arch/arm/include/asm/arch-tegra/pinmux.h    | 189 +++++++++++
 arch/arm/include/asm/arch-tegra114/pinmux.h | 219 +-----------
 arch/arm/include/asm/arch-tegra124/pinmux.h | 216 +-----------
 arch/arm/include/asm/arch-tegra20/pinmux.h  |  85 +----
 arch/arm/include/asm/arch-tegra30/pinmux.h  | 199 +----------
 14 files changed, 738 insertions(+), 2079 deletions(-)
 create mode 100644 arch/arm/cpu/tegra-common/pinmux-common.c
 create mode 100644 arch/arm/include/asm/arch-tegra/pinmux.h

Comments

Simon Glass March 14, 2014, 7:37 p.m. UTC | #1
Hi Stephen,

On 13 March 2014 11:42, Stephen Warren <swarren@wwwdotorg.org> wrote:
> From: Stephen Warren <swarren@nvidia.com>
>
> Much of arch/arm/cpu/tegra*-common/pinmux.c is identical. Remove the
> duplication by creating pinmux-common.c for all the identical code.
>
> This leaves:
> * arch/arm/include/asm/arch-tegra*/pinmux.h defining only the names of
>   the various pins/pin groups, drive groups, and mux functions.
> * arch/arm/cpu/tegra*-common/pinmux.c containing only the lookup table
>   stating which pin groups support which mux functions.
>
> The code in pinmux-common.c is semantically identical to that in the
> various original pinmux.c, but had some consistency and cleanup fixes
> applied during migration.

This patch is very welcome, as You know I was not keen on the
duplication going in in the first place.

>
> I removed the definition of struct pmux_tri_ctlr, since this is different
> between SoCs (especially Tegra20 vs all others), and it's much simpler to
> deal with this via the new REG/MUX_REG/... defines. spl.c, warmboot.c,
> and warmboot_avp.c needed updates due to this, since they previously
> hijacked this struct to encode the location of some non-pinmux registers.
> Now, that code simply calculates these register addresses directly using
> simple and obvious math. I like this method better irrespective of the
> pinmux code cleanup anyway.

Not as keen as you - U-Boot normally uses structures for access to
hardware registers.

>
> Signed-off-by: Stephen Warren <swarren@nvidia.com>
> ---
>  arch/arm/cpu/arm720t/tegra-common/spl.c     |   4 +-
>  arch/arm/cpu/tegra-common/Makefile          |   6 +-
>  arch/arm/cpu/tegra-common/pinmux-common.c   | 507 ++++++++++++++++++++++++++++
>  arch/arm/cpu/tegra114-common/pinmux.c       | 430 +----------------------
>  arch/arm/cpu/tegra124-common/pinmux.c       | 429 +----------------------
>  arch/arm/cpu/tegra20-common/pinmux.c        | 124 +------
>  arch/arm/cpu/tegra20-common/warmboot.c      |   5 +-
>  arch/arm/cpu/tegra20-common/warmboot_avp.c  |   4 +-
>  arch/arm/cpu/tegra30-common/pinmux.c        | 400 +---------------------
>  arch/arm/include/asm/arch-tegra/pinmux.h    | 189 +++++++++++
>  arch/arm/include/asm/arch-tegra114/pinmux.h | 219 +-----------
>  arch/arm/include/asm/arch-tegra124/pinmux.h | 216 +-----------
>  arch/arm/include/asm/arch-tegra20/pinmux.h  |  85 +----
>  arch/arm/include/asm/arch-tegra30/pinmux.h  | 199 +----------
>  14 files changed, 738 insertions(+), 2079 deletions(-)
>  create mode 100644 arch/arm/cpu/tegra-common/pinmux-common.c
>  create mode 100644 arch/arm/include/asm/arch-tegra/pinmux.h
>
> diff --git a/arch/arm/cpu/arm720t/tegra-common/spl.c b/arch/arm/cpu/arm720t/tegra-common/spl.c
> index 5171a8f907a1..4097f3b04362 100644
> --- a/arch/arm/cpu/arm720t/tegra-common/spl.c
> +++ b/arch/arm/cpu/arm720t/tegra-common/spl.c
> @@ -19,10 +19,10 @@
>
>  void spl_board_init(void)
>  {
> -       struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
> +       u32 *cfg_ctl = (u32 *)(NV_PA_APB_MISC_BASE + 0x24);

Open-coded address offset? To me it seems better to have a specific
Tegra20 structure (normal U-Boot approach), or failing  that, worst
case, a #define for this field. Also you should ask your hardware
designers to stop moving things around :-)

>
>         /* enable JTAG */
> -       writel(0xC0, &pmt->pmt_cfg_ctl);
> +       writel(0xC0, cfg_ctl);
>
>         board_init_uart_f();
>
> diff --git a/arch/arm/cpu/tegra-common/Makefile b/arch/arm/cpu/tegra-common/Makefile
> index 34d57349afb5..892556e64451 100644
> --- a/arch/arm/cpu/tegra-common/Makefile
> +++ b/arch/arm/cpu/tegra-common/Makefile
> @@ -7,6 +7,10 @@
>  # SPDX-License-Identifier:     GPL-2.0+
>  #
>
> +obj-y += ap.o
> +obj-y += board.o
> +obj-y += cache.o
> +obj-y += clock.o
>  obj-y += lowlevel_init.o
> -obj-y  += ap.o board.o clock.o cache.o
> +obj-y += pinmux-common.o
>  obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o
> diff --git a/arch/arm/cpu/tegra-common/pinmux-common.c b/arch/arm/cpu/tegra-common/pinmux-common.c
> new file mode 100644
> index 000000000000..10f68ba98b52
> --- /dev/null
> +++ b/arch/arm/cpu/tegra-common/pinmux-common.c
> @@ -0,0 +1,507 @@
> +/*
> + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
> + * Copyright (c) 2011 The Chromium OS Authors.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/pinmux.h>
> +
> +/* return 1 if a pingrp is in range */
> +#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PINGRP_COUNT))
> +
> +/* return 1 if a pmux_func is in range */
> +#define pmux_func_isvalid(func) \
> +       ((((func) >= 0) && ((func) < PMUX_FUNC_COUNT)) || \
> +        (((func) >= PMUX_FUNC_RSVD1) && ((func) <= PMUX_FUNC_RSVD4)))
> +
> +/* return 1 if a pin_pupd_is in range */
> +#define pmux_pin_pupd_isvalid(pupd) \
> +       (((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP))
> +
> +/* return 1 if a pin_tristate_is in range */
> +#define pmux_pin_tristate_isvalid(tristate) \
> +       (((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE))
> +
> +#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC

Do we need this #Ifdef?

> +/* return 1 if a pin_io_is in range */
> +#define pmux_pin_io_isvalid(io) \
> +       (((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT))
> +
> +/* return 1 if a pin_lock is in range */
> +#define pmux_pin_lock_isvalid(lock) \
> +       (((lock) >= PMUX_PIN_LOCK_DISABLE) && ((lock) <= PMUX_PIN_LOCK_ENABLE))
> +
> +/* return 1 if a pin_od is in range */
> +#define pmux_pin_od_isvalid(od) \
> +       (((od) >= PMUX_PIN_OD_DISABLE) && ((od) <= PMUX_PIN_OD_ENABLE))
> +
> +/* return 1 if a pin_ioreset_is in range */
> +#define pmux_pin_ioreset_isvalid(ioreset) \
> +       (((ioreset) >= PMUX_PIN_IO_RESET_DISABLE) && \
> +        ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE))
> +
> +#ifdef TEGRA_PMX_HAS_RCV_SEL
> +/* return 1 if a pin_rcv_sel_is in range */
> +#define pmux_pin_rcv_sel_isvalid(rcv_sel) \
> +       (((rcv_sel) >= PMUX_PIN_RCV_SEL_NORMAL) && \
> +        ((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH))
> +#endif /* TEGRA_PMX_HAS_RCV_SEL */
> +#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */

Do we need this #ifdef?

> +
> +#define _R(offset)     (u32 *)(NV_PA_APB_MISC_BASE + (offset))
> +
> +#if defined(CONFIG_TEGRA20)
> +
> +#define MUX_REG(grp)   _R(0x80 + ((tegra_soc_pingroups[grp].ctl_id / 16) * 4))
> +#define MUX_SHIFT(grp) ((tegra_soc_pingroups[grp].ctl_id % 16) * 2)
> +
> +#define PULL_REG(grp)  _R(0xa0 + ((tegra_soc_pingroups[grp].pull_id / 16) * 4))
> +#define PULL_SHIFT(grp)        ((tegra_soc_pingroups[grp].pull_id % 16) * 2)
> +
> +#define TRI_REG(grp)   _R(0x14 + (((grp) / 32) * 4))
> +#define TRI_SHIFT(grp) ((grp) % 32)
> +
> +#else
> +
> +#define REG(pin)       _R(0x3000 + ((pin) * 4))
> +
> +#define MUX_REG(pin)   REG(pin)
> +#define MUX_SHIFT(pin) 0
> +
> +#define PULL_REG(pin)  REG(pin)
> +#define PULL_SHIFT(pin)        2
> +
> +#define TRI_REG(pin)   REG(pin)
> +#define TRI_SHIFT(pin) 4
> +
> +#endif /* CONFIG_TEGRA20 */
> +
> +#define DRV_REG(group) _R(0x868 + ((group) * 4))
> +
> +#define IO_SHIFT       5
> +#define OD_SHIFT       6
> +#define LOCK_SHIFT     7
> +#define IO_RESET_SHIFT 8
> +#define RCV_SEL_SHIFT  9
> +
> +void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
> +{
> +       u32 *reg = MUX_REG(pin);
> +       int i, mux = -1;
> +       u32 val;
> +
> +       /* Error check on pin and func */
> +       assert(pmux_pingrp_isvalid(pin));
> +       assert(pmux_func_isvalid(func));
> +
> +       if (func & PMUX_FUNC_RSVD1) {
> +               mux = func & 3;
> +       } 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);
> +
> +       val = readl(reg);
> +       val &= ~(3 << MUX_SHIFT(pin));
> +       val |= (mux << MUX_SHIFT(pin));
> +       writel(val, reg);
> +}
> +
> +void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
> +{
> +       u32 *reg = PULL_REG(pin);
> +       u32 val;
> +
> +       /* Error check on pin and pupd */
> +       assert(pmux_pingrp_isvalid(pin));
> +       assert(pmux_pin_pupd_isvalid(pupd));
> +
> +       val = readl(reg);
> +       val &= ~(3 << PULL_SHIFT(pin));
> +       val |= (pupd << PULL_SHIFT(pin));
> +       writel(val, reg);
> +}
> +
> +void pinmux_set_tristate(enum pmux_pingrp pin, int tri)
> +{
> +       u32 *reg = TRI_REG(pin);
> +       u32 val;
> +
> +       /* Error check on pin */
> +       assert(pmux_pingrp_isvalid(pin));
> +       assert(pmux_pin_tristate_isvalid(tri));
> +
> +       val = readl(reg);
> +       if (tri == PMUX_TRI_TRISTATE)
> +               val |= (1 << TRI_SHIFT(pin));
> +       else
> +               val &= ~(1 << TRI_SHIFT(pin));
> +       writel(val, reg);
> +}
> +
> +void pinmux_tristate_enable(enum pmux_pingrp pin)
> +{
> +       pinmux_set_tristate(pin, PMUX_TRI_TRISTATE);
> +}
> +
> +void pinmux_tristate_disable(enum pmux_pingrp pin)
> +{
> +       pinmux_set_tristate(pin, PMUX_TRI_NORMAL);
> +}
> +
> +#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
> +void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io)
> +{
> +       u32 *reg = REG(pin);
> +       u32 val;
> +
> +       if (io == PMUX_PIN_NONE)
> +               return;
> +
> +       /* Error check on pin and io */
> +       assert(pmux_pingrp_isvalid(pin));
> +       assert(pmux_pin_io_isvalid(io));
> +
> +       val = readl(reg);
> +       if (io == PMUX_PIN_INPUT)
> +               val |= (io & 1) << IO_SHIFT;
> +       else
> +               val &= ~(1 << IO_SHIFT);
> +       writel(val, reg);
> +}
> +
> +static void pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock)
> +{
> +       u32 *reg = REG(pin);
> +       u32 val;
> +
> +       if (lock == PMUX_PIN_LOCK_DEFAULT)
> +               return;
> +
> +       /* Error check on pin and lock */
> +       assert(pmux_pingrp_isvalid(pin));
> +       assert(pmux_pin_lock_isvalid(lock));
> +
> +       val = readl(reg);
> +       if (lock == PMUX_PIN_LOCK_ENABLE) {
> +               val |= (1 << LOCK_SHIFT);
> +       } else {
> +               if (val & (1 << LOCK_SHIFT))
> +                       printf("%s: Cannot clear LOCK bit!\n", __func__);
> +               val &= ~(1 << LOCK_SHIFT);
> +       }
> +       writel(val, reg);
> +
> +       return;
> +}
> +
> +static void pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od)
> +{
> +       u32 *reg = REG(pin);
> +       u32 val;
> +
> +       if (od == PMUX_PIN_OD_DEFAULT)
> +               return;
> +
> +       /* Error check on pin and od */
> +       assert(pmux_pingrp_isvalid(pin));
> +       assert(pmux_pin_od_isvalid(od));
> +
> +       val = readl(reg);
> +       if (od == PMUX_PIN_OD_ENABLE)
> +               val |= (1 << OD_SHIFT);
> +       else
> +               val &= ~(1 << OD_SHIFT);
> +       writel(val, reg);
> +
> +       return;
> +}
> +
> +static void pinmux_set_ioreset(enum pmux_pingrp pin,
> +                               enum pmux_pin_ioreset ioreset)
> +{
> +       u32 *reg = REG(pin);
> +       u32 val;
> +
> +       if (ioreset == PMUX_PIN_IO_RESET_DEFAULT)
> +               return;
> +
> +       /* Error check on pin and ioreset */
> +       assert(pmux_pingrp_isvalid(pin));
> +       assert(pmux_pin_ioreset_isvalid(ioreset));
> +
> +       val = readl(reg);
> +       if (ioreset == PMUX_PIN_IO_RESET_ENABLE)
> +               val |= (1 << IO_RESET_SHIFT);
> +       else
> +               val &= ~(1 << IO_RESET_SHIFT);
> +       writel(val, reg);
> +
> +       return;
> +}
> +
> +#ifdef TEGRA_PMX_HAS_RCV_SEL
> +static void pinmux_set_rcv_sel(enum pmux_pingrp pin,
> +                               enum pmux_pin_rcv_sel rcv_sel)
> +{
> +       u32 *reg = REG(pin);
> +       u32 val;
> +
> +       if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT)
> +               return;
> +
> +       /* Error check on pin and rcv_sel */
> +       assert(pmux_pingrp_isvalid(pin));
> +       assert(pmux_pin_rcv_sel_isvalid(rcv_sel));
> +
> +       val = readl(reg);
> +       if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH)
> +               val |= (1 << RCV_SEL_SHIFT);
> +       else
> +               val &= ~(1 << RCV_SEL_SHIFT);
> +       writel(val, reg);
> +
> +       return;
> +}
> +#endif /* TEGRA_PMX_HAS_RCV_SEL */
> +#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */
> +
> +void pinmux_config_pingroup(const 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);
> +#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
> +       pinmux_set_io(pin, config->io);
> +       pinmux_set_lock(pin, config->lock);
> +       pinmux_set_od(pin, config->od);
> +       pinmux_set_ioreset(pin, config->ioreset);
> +#ifdef TEGRA_PMX_HAS_RCV_SEL
> +       pinmux_set_rcv_sel(pin, config->rcv_sel);
> +#endif
> +#endif
> +}
> +
> +void pinmux_config_table(const struct pingroup_config *config, int len)
> +{
> +       int i;
> +
> +       for (i = 0; i < len; i++)
> +               pinmux_config_pingroup(&config[i]);
> +}
> +
> +#ifdef TEGRA_PMX_HAS_PADGRPS

It's really unfortunately to add all these #ifdefs I think. I wonder
if it might be possible to break the pinmux code into several files
and use the Makefile to determine what support is brought in?

> +
> +#define pmux_padgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PDRIVE_PINGROUP_COUNT))
> +
> +#define pmux_pad_slw_isvalid(slw) \
> +       (((slw) >= PGRP_SLWF_MIN) && ((slw) <= PGRP_SLWF_MAX))
> +
> +#define pmux_pad_drv_isvalid(drv) \
> +       (((drv) >= PGRP_DRVUP_MIN) && ((drv) <= PGRP_DRVUP_MAX))
> +
> +#define pmux_pad_lpmd_isvalid(lpm) \
> +       (((lpm) >= PGRP_LPMD_X8) && ((lpm) <= PGRP_LPMD_X))
> +
> +#define pmux_pad_schmt_isvalid(schmt) \
> +       (((schmt) >= PGRP_SCHMT_DISABLE) && ((schmt) <= PGRP_SCHMT_ENABLE))
> +
> +#define pmux_pad_hsm_isvalid(hsm) \
> +       (((hsm) >= PGRP_HSM_DISABLE) && ((hsm) <= PGRP_HSM_ENABLE))
> +
> +#define HSM_SHIFT      2
> +#define SCHMT_SHIFT    3
> +#define LPMD_SHIFT     4
> +#define LPMD_MASK      (3 << LPMD_SHIFT)
> +#define DRVDN_SHIFT    12
> +#define DRVDN_MASK     (0x7F << DRVDN_SHIFT)
> +#define DRVUP_SHIFT    20
> +#define DRVUP_MASK     (0x7F << DRVUP_SHIFT)
> +#define SLWR_SHIFT     28
> +#define SLWR_MASK      (3 << SLWR_SHIFT)
> +#define SLWF_SHIFT     30
> +#define SLWF_MASK      (3 << SLWF_SHIFT)
> +
> +static void padgrp_set_drvup_slwf(enum pdrive_pingrp grp, int slwf)
> +{
> +       u32 *reg = DRV_REG(grp);
> +       u32 val;
> +
> +       /* NONE means unspecified/do not change/use POR value */
> +       if (slwf == PGRP_SLWF_NONE)
> +               return;
> +
> +       /* Error check on pad and slwf */
> +       assert(pmux_padgrp_isvalid(grp));
> +       assert(pmux_pad_slw_isvalid(slwf));
> +
> +       val = readl(reg);
> +       val &= ~SLWF_MASK;
> +       val |= (slwf << SLWF_SHIFT);
> +       writel(val, reg);
> +
> +       return;
> +}
> +
> +static void padgrp_set_drvdn_slwr(enum pdrive_pingrp grp, int slwr)
> +{
> +       u32 *reg = DRV_REG(grp);
> +       u32 val;
> +
> +       /* NONE means unspecified/do not change/use POR value */
> +       if (slwr == PGRP_SLWR_NONE)
> +               return;
> +
> +       /* Error check on pad and slwr */
> +       assert(pmux_padgrp_isvalid(grp));
> +       assert(pmux_pad_slw_isvalid(slwr));
> +
> +       val = readl(reg);
> +       val &= ~SLWR_MASK;
> +       val |= (slwr << SLWR_SHIFT);
> +       writel(val, reg);
> +
> +       return;
> +}
> +
> +static void padgrp_set_drvup(enum pdrive_pingrp grp, int drvup)
> +{
> +       u32 *reg = DRV_REG(grp);
> +       u32 val;
> +
> +       /* NONE means unspecified/do not change/use POR value */
> +       if (drvup == PGRP_DRVUP_NONE)
> +               return;
> +
> +       /* Error check on pad and drvup */
> +       assert(pmux_padgrp_isvalid(grp));
> +       assert(pmux_pad_drv_isvalid(drvup));
> +
> +       val = readl(reg);
> +       val &= ~DRVUP_MASK;
> +       val |= (drvup << DRVUP_SHIFT);
> +       writel(val, reg);
> +
> +       return;
> +}
> +
> +static void padgrp_set_drvdn(enum pdrive_pingrp grp, int drvdn)
> +{
> +       u32 *reg = DRV_REG(grp);
> +       u32 val;
> +
> +       /* NONE means unspecified/do not change/use POR value */
> +       if (drvdn == PGRP_DRVDN_NONE)
> +               return;
> +
> +       /* Error check on pad and drvdn */
> +       assert(pmux_padgrp_isvalid(grp));
> +       assert(pmux_pad_drv_isvalid(drvdn));
> +
> +       val = readl(reg);
> +       val &= ~DRVDN_MASK;
> +       val |= (drvdn << DRVDN_SHIFT);
> +       writel(val, reg);
> +
> +       return;
> +}
> +
> +static void padgrp_set_lpmd(enum pdrive_pingrp grp, enum pgrp_lpmd lpmd)
> +{
> +       u32 *reg = DRV_REG(grp);
> +       u32 val;
> +
> +       /* NONE means unspecified/do not change/use POR value */
> +       if (lpmd == PGRP_LPMD_NONE)
> +               return;
> +
> +       /* Error check pad and lpmd value */
> +       assert(pmux_padgrp_isvalid(grp));
> +       assert(pmux_pad_lpmd_isvalid(lpmd));
> +
> +       val = readl(reg);
> +       val &= ~LPMD_MASK;
> +       val |= (lpmd << LPMD_SHIFT);
> +       writel(val, reg);

You can use clrsetbits_le32() for this sort of thing if you like.

> +
> +       return;
> +}
> +
> +static void padgrp_set_schmt(enum pdrive_pingrp grp, enum pgrp_schmt schmt)
> +{
> +       u32 *reg = DRV_REG(grp);
> +       u32 val;
> +
> +       /* NONE means unspecified/do not change/use POR value */
> +       if (schmt == PGRP_SCHMT_NONE)
> +               return;
> +
> +       /* Error check pad */
> +       assert(pmux_padgrp_isvalid(grp));
> +       assert(pmux_pad_schmt_isvalid(schmt));
> +
> +       val = readl(reg);
> +       if (schmt == PGRP_SCHMT_ENABLE)
> +               val |= (1 << SCHMT_SHIFT);
> +       else
> +               val &= ~(1 << SCHMT_SHIFT);
> +       writel(val, reg);
> +
> +       return;
> +}
> +
> +static void padgrp_set_hsm(enum pdrive_pingrp grp, enum pgrp_hsm hsm)
> +{
> +       u32 *reg = DRV_REG(grp);
> +       u32 val;
> +
> +       /* NONE means unspecified/do not change/use POR value */
> +       if (hsm == PGRP_HSM_NONE)
> +               return;
> +
> +       /* Error check pad */
> +       assert(pmux_padgrp_isvalid(grp));
> +       assert(pmux_pad_hsm_isvalid(hsm));
> +
> +       val = readl(reg);
> +       if (hsm == PGRP_HSM_ENABLE)
> +               val |= (1 << HSM_SHIFT);
> +       else
> +               val &= ~(1 << HSM_SHIFT);
> +       writel(val, reg);
> +
> +       return;
> +}
> +
> +static void padctrl_config_pingroup(const struct padctrl_config *config)
> +{
> +       enum pdrive_pingrp grp = config->padgrp;
> +
> +       padgrp_set_drvup_slwf(grp, config->slwf);
> +       padgrp_set_drvdn_slwr(grp, config->slwr);
> +       padgrp_set_drvup(grp, config->drvup);
> +       padgrp_set_drvdn(grp, config->drvdn);
> +       padgrp_set_lpmd(grp, config->lpmd);
> +       padgrp_set_schmt(grp, config->schmt);
> +       padgrp_set_hsm(grp, config->hsm);
> +}
> +
> +void padgrp_config_table(const struct padctrl_config *config, int len)
> +{
> +       int i;
> +
> +       for (i = 0; i < len; i++)
> +               padctrl_config_pingroup(&config[i]);
> +}
> +#endif /* TEGRA_PMX_HAS_PADGRPS */

Regards,
Simon
Stephen Warren March 20, 2014, 7:57 p.m. UTC | #2
On 03/14/2014 01:37 PM, Simon Glass wrote:
> Hi Stephen,
> 
> On 13 March 2014 11:42, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> From: Stephen Warren <swarren@nvidia.com>
>>
>> Much of arch/arm/cpu/tegra*-common/pinmux.c is identical. Remove the
>> duplication by creating pinmux-common.c for all the identical code.
>>
>> This leaves:
>> * arch/arm/include/asm/arch-tegra*/pinmux.h defining only the names of
>>   the various pins/pin groups, drive groups, and mux functions.
>> * arch/arm/cpu/tegra*-common/pinmux.c containing only the lookup table
>>   stating which pin groups support which mux functions.
>>
>> The code in pinmux-common.c is semantically identical to that in the
>> various original pinmux.c, but had some consistency and cleanup fixes
>> applied during migration.
> 
> This patch is very welcome, as You know I was not keen on the
> duplication going in in the first place.
> 
>>
>> I removed the definition of struct pmux_tri_ctlr, since this is different
>> between SoCs (especially Tegra20 vs all others), and it's much simpler to
>> deal with this via the new REG/MUX_REG/... defines. spl.c, warmboot.c,
>> and warmboot_avp.c needed updates due to this, since they previously
>> hijacked this struct to encode the location of some non-pinmux registers.
>> Now, that code simply calculates these register addresses directly using
>> simple and obvious math. I like this method better irrespective of the
>> pinmux code cleanup anyway.
> 
> Not as keen as you - U-Boot normally uses structures for access to
> hardware registers.

I tend to disagree with this approach. All other SW I'm familiar with
uses simple #defines for offsets. This makes U-Boot rather unfamiliar to
engineers. All HW documentation uses numerical offsets. SW #defines are
extremely easy to validate against the HW documentation, whereas with
structs you have to count out reserved arrays for gaps, put comments in
that contain the offsets to help you match everything up and validate
it, etc.

Still ...

>> diff --git a/arch/arm/cpu/arm720t/tegra-common/spl.c b/arch/arm/cpu/arm720t/tegra-common/spl.c
>> index 5171a8f907a1..4097f3b04362 100644
>> --- a/arch/arm/cpu/arm720t/tegra-common/spl.c
>> +++ b/arch/arm/cpu/arm720t/tegra-common/spl.c
>> @@ -19,10 +19,10 @@
>>
>>  void spl_board_init(void)
>>  {
>> -       struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
>> +       u32 *cfg_ctl = (u32 *)(NV_PA_APB_MISC_BASE + 0x24);
> 
> Open-coded address offset? To me it seems better to have a specific
> Tegra20 structure (normal U-Boot approach), or failing  that, worst
> case, a #define for this field. Also you should ask your hardware
> designers to stop moving things around :-)

Ah, it looks like there's already
./arch/arm/include/asm/arch-tegra20/apb_misc.h that defines the
registers at the start of the apb_misc space that aren't related to
pinmux. I'll uses this struct since it's already there, and add the one
missing field.

>> diff --git a/arch/arm/cpu/tegra-common/pinmux-common.c b/arch/arm/cpu/tegra-common/pinmux-common.c

>> +/* return 1 if a pin_pupd_is in range */
>> +#define pmux_pin_pupd_isvalid(pupd) \
>> +       (((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP))
>> +
>> +/* return 1 if a pin_tristate_is in range */
>> +#define pmux_pin_tristate_isvalid(tristate) \
>> +       (((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE))
>> +
>> +#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
> 
> Do we need this #Ifdef?
>
>> +/* return 1 if a pin_io_is in range */
>> +#define pmux_pin_io_isvalid(io) \
>> +       (((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT))

We certainly need not to compile this code, since e.g. PMUX_PIN_INPUT
doesn't exist on Tegra20 due to equivalent #ifdefs in pinmux.h.

I do explicitly want to keep the ifdefs in pinmux.h, so that APIs are
not prototyped, and values not defined, for features that don't exist on
the SoC that U-Boot is being built for. This validates at compile time
that code isn't using invalid APIs. While pinmux.h could be split up
into a few separate header files to avoid the ifdefs, I think that would
make the header situation far more complex than it needs to be.

I don't see anything wrong with having the same ifdefs in pinmux.c; it's
a very consistent structure. It also means that all the conditional
logic is in code, all implemented consistently via C pre-processor,
rather than some being in the header file and some in the Makefiles, and
hence I think it's easier to keep the two in sync, since they work
identically.

So in summary, I'd like to keep the ifdefs. I think they're pretty
simple and not a maintenance burden. Do you object?
Simon Glass March 21, 2014, 1:25 a.m. UTC | #3
Hi Stephen,

On 20 March 2014 12:57, Stephen Warren <swarren@wwwdotorg.org> wrote:
>
> On 03/14/2014 01:37 PM, Simon Glass wrote:
> > Hi Stephen,
> >
> > On 13 March 2014 11:42, Stephen Warren <swarren@wwwdotorg.org> wrote:
> >> From: Stephen Warren <swarren@nvidia.com>
> >>
> >> Much of arch/arm/cpu/tegra*-common/pinmux.c is identical. Remove the
> >> duplication by creating pinmux-common.c for all the identical code.
> >>
> >> This leaves:
> >> * arch/arm/include/asm/arch-tegra*/pinmux.h defining only the names of
> >>   the various pins/pin groups, drive groups, and mux functions.
> >> * arch/arm/cpu/tegra*-common/pinmux.c containing only the lookup table
> >>   stating which pin groups support which mux functions.
> >>
> >> The code in pinmux-common.c is semantically identical to that in the
> >> various original pinmux.c, but had some consistency and cleanup fixes
> >> applied during migration.
> >
> > This patch is very welcome, as You know I was not keen on the
> > duplication going in in the first place.
> >
> >>
> >> I removed the definition of struct pmux_tri_ctlr, since this is different
> >> between SoCs (especially Tegra20 vs all others), and it's much simpler to
> >> deal with this via the new REG/MUX_REG/... defines. spl.c, warmboot.c,
> >> and warmboot_avp.c needed updates due to this, since they previously
> >> hijacked this struct to encode the location of some non-pinmux registers.
> >> Now, that code simply calculates these register addresses directly using
> >> simple and obvious math. I like this method better irrespective of the
> >> pinmux code cleanup anyway.
> >
> > Not as keen as you - U-Boot normally uses structures for access to
> > hardware registers.
>
> I tend to disagree with this approach. All other SW I'm familiar with
> uses simple #defines for offsets. This makes U-Boot rather unfamiliar to
> engineers. All HW documentation uses numerical offsets. SW #defines are
> extremely easy to validate against the HW documentation, whereas with
> structs you have to count out reserved arrays for gaps, put comments in
> that contain the offsets to help you match everything up and validate
> it, etc.
>
> Still ...
>
> >> diff --git a/arch/arm/cpu/arm720t/tegra-common/spl.c b/arch/arm/cpu/arm720t/tegra-common/spl.c
> >> index 5171a8f907a1..4097f3b04362 100644
> >> --- a/arch/arm/cpu/arm720t/tegra-common/spl.c
> >> +++ b/arch/arm/cpu/arm720t/tegra-common/spl.c
> >> @@ -19,10 +19,10 @@
> >>
> >>  void spl_board_init(void)
> >>  {
> >> -       struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
> >> +       u32 *cfg_ctl = (u32 *)(NV_PA_APB_MISC_BASE + 0x24);
> >
> > Open-coded address offset? To me it seems better to have a specific
> > Tegra20 structure (normal U-Boot approach), or failing  that, worst
> > case, a #define for this field. Also you should ask your hardware
> > designers to stop moving things around :-)
>
> Ah, it looks like there's already
> ./arch/arm/include/asm/arch-tegra20/apb_misc.h that defines the
> registers at the start of the apb_misc space that aren't related to
> pinmux. I'll uses this struct since it's already there, and add the one
> missing field.
>
> >> diff --git a/arch/arm/cpu/tegra-common/pinmux-common.c b/arch/arm/cpu/tegra-common/pinmux-common.c
>
> >> +/* return 1 if a pin_pupd_is in range */
> >> +#define pmux_pin_pupd_isvalid(pupd) \
> >> +       (((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP))
> >> +
> >> +/* return 1 if a pin_tristate_is in range */
> >> +#define pmux_pin_tristate_isvalid(tristate) \
> >> +       (((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE))
> >> +
> >> +#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
> >
> > Do we need this #Ifdef?
> >
> >> +/* return 1 if a pin_io_is in range */
> >> +#define pmux_pin_io_isvalid(io) \
> >> +       (((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT))
>
> We certainly need not to compile this code, since e.g. PMUX_PIN_INPUT
> doesn't exist on Tegra20 due to equivalent #ifdefs in pinmux.h.
>
> I do explicitly want to keep the ifdefs in pinmux.h, so that APIs are
> not prototyped, and values not defined, for features that don't exist on
> the SoC that U-Boot is being built for. This validates at compile time
> that code isn't using invalid APIs. While pinmux.h could be split up
> into a few separate header files to avoid the ifdefs, I think that would
> make the header situation far more complex than it needs to be.

Arguably you have created this problem by having #ifdefs in the C file
- if there was a separate file for each SoC then it would be much
harder to mess this up.

>
>
> I don't see anything wrong with having the same ifdefs in pinmux.c; it's
> a very consistent structure. It also means that all the conditional
> logic is in code, all implemented consistently via C pre-processor,
> rather than some being in the header file and some in the Makefiles, and
> hence I think it's easier to keep the two in sync, since they work
> identically.
>
> So in summary, I'd like to keep the ifdefs. I think they're pretty
> simple and not a maintenance burden. Do you object?

No. I can't possibly object given that you have completed such a great clean-up.

Regards,
Simon
Stephen Warren March 21, 2014, 4:07 a.m. UTC | #4
On 03/20/2014 07:25 PM, Simon Glass wrote:
> Hi Stephen,
> 
> On 20 March 2014 12:57, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>
>> On 03/14/2014 01:37 PM, Simon Glass wrote:
>>> Hi Stephen,
>>>
>>> On 13 March 2014 11:42, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>>> From: Stephen Warren <swarren@nvidia.com>
>>>>
>>>> Much of arch/arm/cpu/tegra*-common/pinmux.c is identical. Remove the
>>>> duplication by creating pinmux-common.c for all the identical code.
>>>>
>>>> This leaves:
>>>> * arch/arm/include/asm/arch-tegra*/pinmux.h defining only the names of
>>>>   the various pins/pin groups, drive groups, and mux functions.
>>>> * arch/arm/cpu/tegra*-common/pinmux.c containing only the lookup table
>>>>   stating which pin groups support which mux functions.
>>>>
>>>> The code in pinmux-common.c is semantically identical to that in the
>>>> various original pinmux.c, but had some consistency and cleanup fixes
>>>> applied during migration.

>>>> diff --git a/arch/arm/cpu/tegra-common/pinmux-common.c b/arch/arm/cpu/tegra-common/pinmux-common.c
>>
>>>> +/* return 1 if a pin_pupd_is in range */
>>>> +#define pmux_pin_pupd_isvalid(pupd) \
>>>> +       (((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP))
>>>> +
>>>> +/* return 1 if a pin_tristate_is in range */
>>>> +#define pmux_pin_tristate_isvalid(tristate) \
>>>> +       (((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE))
>>>> +
>>>> +#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
>>>
>>> Do we need this #Ifdef?
>>>
>>>> +/* return 1 if a pin_io_is in range */
>>>> +#define pmux_pin_io_isvalid(io) \
>>>> +       (((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT))
>>
>> We certainly need not to compile this code, since e.g. PMUX_PIN_INPUT
>> doesn't exist on Tegra20 due to equivalent #ifdefs in pinmux.h.
>>
>> I do explicitly want to keep the ifdefs in pinmux.h, so that APIs are
>> not prototyped, and values not defined, for features that don't exist on
>> the SoC that U-Boot is being built for. This validates at compile time
>> that code isn't using invalid APIs. While pinmux.h could be split up
>> into a few separate header files to avoid the ifdefs, I think that would
>> make the header situation far more complex than it needs to be.
> 
> Arguably you have created this problem by having #ifdefs in the C file
> - if there was a separate file for each SoC then it would be much
> harder to mess this up.

Well, then you get a link error rather than a compiler error for an
unprototyped function or undefined enum/#define. I think the compile
error is a bit more obvious myself, but granted either would work.

...
>> So in summary, I'd like to keep the ifdefs. I think they're pretty
>> simple and not a maintenance burden. Do you object?
> 
> No. I can't possibly object given that you have completed such a great clean-up.

Great, thanks. I'll post V2 tomorrow.
diff mbox

Patch

diff --git a/arch/arm/cpu/arm720t/tegra-common/spl.c b/arch/arm/cpu/arm720t/tegra-common/spl.c
index 5171a8f907a1..4097f3b04362 100644
--- a/arch/arm/cpu/arm720t/tegra-common/spl.c
+++ b/arch/arm/cpu/arm720t/tegra-common/spl.c
@@ -19,10 +19,10 @@ 
 
 void spl_board_init(void)
 {
-	struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *cfg_ctl = (u32 *)(NV_PA_APB_MISC_BASE + 0x24);
 
 	/* enable JTAG */
-	writel(0xC0, &pmt->pmt_cfg_ctl);
+	writel(0xC0, cfg_ctl);
 
 	board_init_uart_f();
 
diff --git a/arch/arm/cpu/tegra-common/Makefile b/arch/arm/cpu/tegra-common/Makefile
index 34d57349afb5..892556e64451 100644
--- a/arch/arm/cpu/tegra-common/Makefile
+++ b/arch/arm/cpu/tegra-common/Makefile
@@ -7,6 +7,10 @@ 
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+obj-y += ap.o
+obj-y += board.o
+obj-y += cache.o
+obj-y += clock.o
 obj-y += lowlevel_init.o
-obj-y	+= ap.o board.o clock.o cache.o
+obj-y += pinmux-common.o
 obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o
diff --git a/arch/arm/cpu/tegra-common/pinmux-common.c b/arch/arm/cpu/tegra-common/pinmux-common.c
new file mode 100644
index 000000000000..10f68ba98b52
--- /dev/null
+++ b/arch/arm/cpu/tegra-common/pinmux-common.c
@@ -0,0 +1,507 @@ 
+/*
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/pinmux.h>
+
+/* return 1 if a pingrp is in range */
+#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PINGRP_COUNT))
+
+/* return 1 if a pmux_func is in range */
+#define pmux_func_isvalid(func) \
+	((((func) >= 0) && ((func) < PMUX_FUNC_COUNT)) || \
+	 (((func) >= PMUX_FUNC_RSVD1) && ((func) <= PMUX_FUNC_RSVD4)))
+
+/* return 1 if a pin_pupd_is in range */
+#define pmux_pin_pupd_isvalid(pupd) \
+	(((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP))
+
+/* return 1 if a pin_tristate_is in range */
+#define pmux_pin_tristate_isvalid(tristate) \
+	(((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE))
+
+#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
+/* return 1 if a pin_io_is in range */
+#define pmux_pin_io_isvalid(io) \
+	(((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT))
+
+/* return 1 if a pin_lock is in range */
+#define pmux_pin_lock_isvalid(lock) \
+	(((lock) >= PMUX_PIN_LOCK_DISABLE) && ((lock) <= PMUX_PIN_LOCK_ENABLE))
+
+/* return 1 if a pin_od is in range */
+#define pmux_pin_od_isvalid(od) \
+	(((od) >= PMUX_PIN_OD_DISABLE) && ((od) <= PMUX_PIN_OD_ENABLE))
+
+/* return 1 if a pin_ioreset_is in range */
+#define pmux_pin_ioreset_isvalid(ioreset) \
+	(((ioreset) >= PMUX_PIN_IO_RESET_DISABLE) && \
+	 ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE))
+
+#ifdef TEGRA_PMX_HAS_RCV_SEL
+/* return 1 if a pin_rcv_sel_is in range */
+#define pmux_pin_rcv_sel_isvalid(rcv_sel) \
+	(((rcv_sel) >= PMUX_PIN_RCV_SEL_NORMAL) && \
+	 ((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH))
+#endif /* TEGRA_PMX_HAS_RCV_SEL */
+#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */
+
+#define _R(offset)	(u32 *)(NV_PA_APB_MISC_BASE + (offset))
+
+#if defined(CONFIG_TEGRA20)
+
+#define MUX_REG(grp)	_R(0x80 + ((tegra_soc_pingroups[grp].ctl_id / 16) * 4))
+#define MUX_SHIFT(grp)	((tegra_soc_pingroups[grp].ctl_id % 16) * 2)
+
+#define PULL_REG(grp)	_R(0xa0 + ((tegra_soc_pingroups[grp].pull_id / 16) * 4))
+#define PULL_SHIFT(grp)	((tegra_soc_pingroups[grp].pull_id % 16) * 2)
+
+#define TRI_REG(grp)	_R(0x14 + (((grp) / 32) * 4))
+#define TRI_SHIFT(grp)	((grp) % 32)
+
+#else
+
+#define REG(pin)	_R(0x3000 + ((pin) * 4))
+
+#define MUX_REG(pin)	REG(pin)
+#define MUX_SHIFT(pin)	0
+
+#define PULL_REG(pin)	REG(pin)
+#define PULL_SHIFT(pin)	2
+
+#define TRI_REG(pin)	REG(pin)
+#define TRI_SHIFT(pin)	4
+
+#endif /* CONFIG_TEGRA20 */
+
+#define DRV_REG(group)	_R(0x868 + ((group) * 4))
+
+#define IO_SHIFT	5
+#define OD_SHIFT	6
+#define LOCK_SHIFT	7
+#define IO_RESET_SHIFT	8
+#define RCV_SEL_SHIFT	9
+
+void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
+{
+	u32 *reg = MUX_REG(pin);
+	int i, mux = -1;
+	u32 val;
+
+	/* Error check on pin and func */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_func_isvalid(func));
+
+	if (func & PMUX_FUNC_RSVD1) {
+		mux = func & 3;
+	} 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);
+
+	val = readl(reg);
+	val &= ~(3 << MUX_SHIFT(pin));
+	val |= (mux << MUX_SHIFT(pin));
+	writel(val, reg);
+}
+
+void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
+{
+	u32 *reg = PULL_REG(pin);
+	u32 val;
+
+	/* Error check on pin and pupd */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_pupd_isvalid(pupd));
+
+	val = readl(reg);
+	val &= ~(3 << PULL_SHIFT(pin));
+	val |= (pupd << PULL_SHIFT(pin));
+	writel(val, reg);
+}
+
+void pinmux_set_tristate(enum pmux_pingrp pin, int tri)
+{
+	u32 *reg = TRI_REG(pin);
+	u32 val;
+
+	/* Error check on pin */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_tristate_isvalid(tri));
+
+	val = readl(reg);
+	if (tri == PMUX_TRI_TRISTATE)
+		val |= (1 << TRI_SHIFT(pin));
+	else
+		val &= ~(1 << TRI_SHIFT(pin));
+	writel(val, reg);
+}
+
+void pinmux_tristate_enable(enum pmux_pingrp pin)
+{
+	pinmux_set_tristate(pin, PMUX_TRI_TRISTATE);
+}
+
+void pinmux_tristate_disable(enum pmux_pingrp pin)
+{
+	pinmux_set_tristate(pin, PMUX_TRI_NORMAL);
+}
+
+#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
+void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io)
+{
+	u32 *reg = REG(pin);
+	u32 val;
+
+	if (io == PMUX_PIN_NONE)
+		return;
+
+	/* Error check on pin and io */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_io_isvalid(io));
+
+	val = readl(reg);
+	if (io == PMUX_PIN_INPUT)
+		val |= (io & 1) << IO_SHIFT;
+	else
+		val &= ~(1 << IO_SHIFT);
+	writel(val, reg);
+}
+
+static void pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock)
+{
+	u32 *reg = REG(pin);
+	u32 val;
+
+	if (lock == PMUX_PIN_LOCK_DEFAULT)
+		return;
+
+	/* Error check on pin and lock */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_lock_isvalid(lock));
+
+	val = readl(reg);
+	if (lock == PMUX_PIN_LOCK_ENABLE) {
+		val |= (1 << LOCK_SHIFT);
+	} else {
+		if (val & (1 << LOCK_SHIFT))
+			printf("%s: Cannot clear LOCK bit!\n", __func__);
+		val &= ~(1 << LOCK_SHIFT);
+	}
+	writel(val, reg);
+
+	return;
+}
+
+static void pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od)
+{
+	u32 *reg = REG(pin);
+	u32 val;
+
+	if (od == PMUX_PIN_OD_DEFAULT)
+		return;
+
+	/* Error check on pin and od */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_od_isvalid(od));
+
+	val = readl(reg);
+	if (od == PMUX_PIN_OD_ENABLE)
+		val |= (1 << OD_SHIFT);
+	else
+		val &= ~(1 << OD_SHIFT);
+	writel(val, reg);
+
+	return;
+}
+
+static void pinmux_set_ioreset(enum pmux_pingrp pin,
+				enum pmux_pin_ioreset ioreset)
+{
+	u32 *reg = REG(pin);
+	u32 val;
+
+	if (ioreset == PMUX_PIN_IO_RESET_DEFAULT)
+		return;
+
+	/* Error check on pin and ioreset */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_ioreset_isvalid(ioreset));
+
+	val = readl(reg);
+	if (ioreset == PMUX_PIN_IO_RESET_ENABLE)
+		val |= (1 << IO_RESET_SHIFT);
+	else
+		val &= ~(1 << IO_RESET_SHIFT);
+	writel(val, reg);
+
+	return;
+}
+
+#ifdef TEGRA_PMX_HAS_RCV_SEL
+static void pinmux_set_rcv_sel(enum pmux_pingrp pin,
+				enum pmux_pin_rcv_sel rcv_sel)
+{
+	u32 *reg = REG(pin);
+	u32 val;
+
+	if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT)
+		return;
+
+	/* Error check on pin and rcv_sel */
+	assert(pmux_pingrp_isvalid(pin));
+	assert(pmux_pin_rcv_sel_isvalid(rcv_sel));
+
+	val = readl(reg);
+	if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH)
+		val |= (1 << RCV_SEL_SHIFT);
+	else
+		val &= ~(1 << RCV_SEL_SHIFT);
+	writel(val, reg);
+
+	return;
+}
+#endif /* TEGRA_PMX_HAS_RCV_SEL */
+#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */
+
+void pinmux_config_pingroup(const 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);
+#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
+	pinmux_set_io(pin, config->io);
+	pinmux_set_lock(pin, config->lock);
+	pinmux_set_od(pin, config->od);
+	pinmux_set_ioreset(pin, config->ioreset);
+#ifdef TEGRA_PMX_HAS_RCV_SEL
+	pinmux_set_rcv_sel(pin, config->rcv_sel);
+#endif
+#endif
+}
+
+void pinmux_config_table(const struct pingroup_config *config, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		pinmux_config_pingroup(&config[i]);
+}
+
+#ifdef TEGRA_PMX_HAS_PADGRPS
+
+#define pmux_padgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PDRIVE_PINGROUP_COUNT))
+
+#define pmux_pad_slw_isvalid(slw) \
+	(((slw) >= PGRP_SLWF_MIN) && ((slw) <= PGRP_SLWF_MAX))
+
+#define pmux_pad_drv_isvalid(drv) \
+	(((drv) >= PGRP_DRVUP_MIN) && ((drv) <= PGRP_DRVUP_MAX))
+
+#define pmux_pad_lpmd_isvalid(lpm) \
+	(((lpm) >= PGRP_LPMD_X8) && ((lpm) <= PGRP_LPMD_X))
+
+#define pmux_pad_schmt_isvalid(schmt) \
+	(((schmt) >= PGRP_SCHMT_DISABLE) && ((schmt) <= PGRP_SCHMT_ENABLE))
+
+#define pmux_pad_hsm_isvalid(hsm) \
+	(((hsm) >= PGRP_HSM_DISABLE) && ((hsm) <= PGRP_HSM_ENABLE))
+
+#define HSM_SHIFT	2
+#define SCHMT_SHIFT	3
+#define LPMD_SHIFT	4
+#define LPMD_MASK	(3 << LPMD_SHIFT)
+#define DRVDN_SHIFT	12
+#define DRVDN_MASK	(0x7F << DRVDN_SHIFT)
+#define DRVUP_SHIFT	20
+#define DRVUP_MASK	(0x7F << DRVUP_SHIFT)
+#define SLWR_SHIFT	28
+#define SLWR_MASK	(3 << SLWR_SHIFT)
+#define SLWF_SHIFT	30
+#define SLWF_MASK	(3 << SLWF_SHIFT)
+
+static void padgrp_set_drvup_slwf(enum pdrive_pingrp grp, int slwf)
+{
+	u32 *reg = DRV_REG(grp);
+	u32 val;
+
+	/* NONE means unspecified/do not change/use POR value */
+	if (slwf == PGRP_SLWF_NONE)
+		return;
+
+	/* Error check on pad and slwf */
+	assert(pmux_padgrp_isvalid(grp));
+	assert(pmux_pad_slw_isvalid(slwf));
+
+	val = readl(reg);
+	val &= ~SLWF_MASK;
+	val |= (slwf << SLWF_SHIFT);
+	writel(val, reg);
+
+	return;
+}
+
+static void padgrp_set_drvdn_slwr(enum pdrive_pingrp grp, int slwr)
+{
+	u32 *reg = DRV_REG(grp);
+	u32 val;
+
+	/* NONE means unspecified/do not change/use POR value */
+	if (slwr == PGRP_SLWR_NONE)
+		return;
+
+	/* Error check on pad and slwr */
+	assert(pmux_padgrp_isvalid(grp));
+	assert(pmux_pad_slw_isvalid(slwr));
+
+	val = readl(reg);
+	val &= ~SLWR_MASK;
+	val |= (slwr << SLWR_SHIFT);
+	writel(val, reg);
+
+	return;
+}
+
+static void padgrp_set_drvup(enum pdrive_pingrp grp, int drvup)
+{
+	u32 *reg = DRV_REG(grp);
+	u32 val;
+
+	/* NONE means unspecified/do not change/use POR value */
+	if (drvup == PGRP_DRVUP_NONE)
+		return;
+
+	/* Error check on pad and drvup */
+	assert(pmux_padgrp_isvalid(grp));
+	assert(pmux_pad_drv_isvalid(drvup));
+
+	val = readl(reg);
+	val &= ~DRVUP_MASK;
+	val |= (drvup << DRVUP_SHIFT);
+	writel(val, reg);
+
+	return;
+}
+
+static void padgrp_set_drvdn(enum pdrive_pingrp grp, int drvdn)
+{
+	u32 *reg = DRV_REG(grp);
+	u32 val;
+
+	/* NONE means unspecified/do not change/use POR value */
+	if (drvdn == PGRP_DRVDN_NONE)
+		return;
+
+	/* Error check on pad and drvdn */
+	assert(pmux_padgrp_isvalid(grp));
+	assert(pmux_pad_drv_isvalid(drvdn));
+
+	val = readl(reg);
+	val &= ~DRVDN_MASK;
+	val |= (drvdn << DRVDN_SHIFT);
+	writel(val, reg);
+
+	return;
+}
+
+static void padgrp_set_lpmd(enum pdrive_pingrp grp, enum pgrp_lpmd lpmd)
+{
+	u32 *reg = DRV_REG(grp);
+	u32 val;
+
+	/* NONE means unspecified/do not change/use POR value */
+	if (lpmd == PGRP_LPMD_NONE)
+		return;
+
+	/* Error check pad and lpmd value */
+	assert(pmux_padgrp_isvalid(grp));
+	assert(pmux_pad_lpmd_isvalid(lpmd));
+
+	val = readl(reg);
+	val &= ~LPMD_MASK;
+	val |= (lpmd << LPMD_SHIFT);
+	writel(val, reg);
+
+	return;
+}
+
+static void padgrp_set_schmt(enum pdrive_pingrp grp, enum pgrp_schmt schmt)
+{
+	u32 *reg = DRV_REG(grp);
+	u32 val;
+
+	/* NONE means unspecified/do not change/use POR value */
+	if (schmt == PGRP_SCHMT_NONE)
+		return;
+
+	/* Error check pad */
+	assert(pmux_padgrp_isvalid(grp));
+	assert(pmux_pad_schmt_isvalid(schmt));
+
+	val = readl(reg);
+	if (schmt == PGRP_SCHMT_ENABLE)
+		val |= (1 << SCHMT_SHIFT);
+	else
+		val &= ~(1 << SCHMT_SHIFT);
+	writel(val, reg);
+
+	return;
+}
+
+static void padgrp_set_hsm(enum pdrive_pingrp grp, enum pgrp_hsm hsm)
+{
+	u32 *reg = DRV_REG(grp);
+	u32 val;
+
+	/* NONE means unspecified/do not change/use POR value */
+	if (hsm == PGRP_HSM_NONE)
+		return;
+
+	/* Error check pad */
+	assert(pmux_padgrp_isvalid(grp));
+	assert(pmux_pad_hsm_isvalid(hsm));
+
+	val = readl(reg);
+	if (hsm == PGRP_HSM_ENABLE)
+		val |= (1 << HSM_SHIFT);
+	else
+		val &= ~(1 << HSM_SHIFT);
+	writel(val, reg);
+
+	return;
+}
+
+static void padctrl_config_pingroup(const struct padctrl_config *config)
+{
+	enum pdrive_pingrp grp = config->padgrp;
+
+	padgrp_set_drvup_slwf(grp, config->slwf);
+	padgrp_set_drvdn_slwr(grp, config->slwr);
+	padgrp_set_drvup(grp, config->drvup);
+	padgrp_set_drvdn(grp, config->drvdn);
+	padgrp_set_lpmd(grp, config->lpmd);
+	padgrp_set_schmt(grp, config->schmt);
+	padgrp_set_hsm(grp, config->hsm);
+}
+
+void padgrp_config_table(const struct padctrl_config *config, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		padctrl_config_pingroup(&config[i]);
+}
+#endif /* TEGRA_PMX_HAS_PADGRPS */
diff --git a/arch/arm/cpu/tegra114-common/pinmux.c b/arch/arm/cpu/tegra114-common/pinmux.c
index e83a29f43a5f..af8b7ca5fc79 100644
--- a/arch/arm/cpu/tegra114-common/pinmux.c
+++ b/arch/arm/cpu/tegra114-common/pinmux.c
@@ -18,38 +18,8 @@ 
 
 #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_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
-#define PMUX_RCV_SEL_SHIFT	9
-
-#define PGRP_HSM_SHIFT		2
-#define PGRP_SCHMT_SHIFT	3
-#define PGRP_LPMD_SHIFT		4
-#define PGRP_LPMD_MASK		(3 << PGRP_LPMD_SHIFT)
-#define PGRP_DRVDN_SHIFT	12
-#define PGRP_DRVDN_MASK		(0x7F << PGRP_DRVDN_SHIFT)
-#define PGRP_DRVUP_SHIFT	20
-#define PGRP_DRVUP_MASK		(0x7F << PGRP_DRVUP_SHIFT)
-#define PGRP_SLWR_SHIFT		28
-#define PGRP_SLWR_MASK		(3 << PGRP_SLWR_SHIFT)
-#define PGRP_SLWF_SHIFT		30
-#define PGRP_SLWF_MASK		(3 << PGRP_SLWF_SHIFT)
-
 /* Convenient macro for defining pin group properties */
 #define PIN(pg_name, vdd, f0, f1, f2, f3, iod)	\
 	{						\
@@ -59,7 +29,6 @@  struct tegra_pingroup_desc {
 			PMUX_FUNC_ ## f2,		\
 			PMUX_FUNC_ ## f3,		\
 		},					\
-		.io = PMUX_PIN_ ## iod,			\
 	}
 
 /* Input and output pins */
@@ -72,7 +41,7 @@  struct tegra_pingroup_desc {
 #define PIN_RESERVED \
 	PIN(NONE, NONE, INVALID, INVALID, INVALID, INVALID, NONE)
 
-const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
+const struct tegra_pingroup_desc tegra114_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),
@@ -334,399 +303,4 @@  const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
 	PIN_RESERVED,	/* Reserved by t114: 0x3404 */
 	PINO(RESET_OUT_N, SYS,     RSVD1,      RSVD2,      RSVD3, RESET_OUT_N),
 };
-
-void pinmux_set_tristate(enum pmux_pingrp pin, int enable)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *tri = &pmt->pmt_ctl[pin];
-	u32 reg;
-
-	/* Error check on pin */
-	assert(pmux_pingrp_isvalid(pin));
-
-	reg = readl(tri);
-	if (enable)
-		reg |= PMUX_TRISTATE_MASK;
-	else
-		reg &= ~PMUX_TRISTATE_MASK;
-	writel(reg, tri);
-}
-
-void pinmux_tristate_enable(enum pmux_pingrp pin)
-{
-	pinmux_set_tristate(pin, 1);
-}
-
-void pinmux_tristate_disable(enum pmux_pingrp pin)
-{
-	pinmux_set_tristate(pin, 0);
-}
-
-void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pull = &pmt->pmt_ctl[pin];
-	u32 reg;
-
-	/* Error check on pin and pupd */
-	assert(pmux_pingrp_isvalid(pin));
-	assert(pmux_pin_pupd_isvalid(pupd));
-
-	reg = readl(pull);
-	reg &= ~(0x3 << PMUX_PULL_SHIFT);
-	reg |= (pupd << PMUX_PULL_SHIFT);
-	writel(reg, pull);
-}
-
-void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *muxctl = &pmt->pmt_ctl[pin];
-	int i, mux = -1;
-	u32 reg;
-
-	/* Error check on pin and func */
-	assert(pmux_pingrp_isvalid(pin));
-	assert(pmux_func_isvalid(func));
-
-	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;
-}
-
-static int pinmux_set_rcv_sel(enum pmux_pingrp pin,
-				enum pmux_pin_rcv_sel rcv_sel)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pin_rcv_sel = &pmt->pmt_ctl[pin];
-	u32 reg;
-
-	/* Error check on pin and rcv_sel */
-	assert(pmux_pingrp_isvalid(pin));
-	assert(pmux_pin_rcv_sel_isvalid(rcv_sel));
-
-	if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT)
-		return 0;
-
-	reg = readl(pin_rcv_sel);
-	reg &= ~(0x1 << PMUX_RCV_SEL_SHIFT);
-	if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH)
-		reg |= (0x1 << PMUX_RCV_SEL_SHIFT);
-	writel(reg, pin_rcv_sel);
-
-	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);
-	pinmux_set_rcv_sel(pin, config->rcv_sel);
-}
-
-void pinmux_config_table(struct pingroup_config *config, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		pinmux_config_pingroup(&config[i]);
-}
-
-static int padgrp_set_drvup_slwf(enum pdrive_pingrp pad, int slwf)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_slwf = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and slwf */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_slw_isvalid(slwf));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (slwf == PGRP_SLWF_NONE)
-		return 0;
-
-	reg = readl(pad_slwf);
-	reg &= ~PGRP_SLWF_MASK;
-	reg |= (slwf << PGRP_SLWF_SHIFT);
-	writel(reg, pad_slwf);
-
-	return 0;
-}
-
-static int padgrp_set_drvdn_slwr(enum pdrive_pingrp pad, int slwr)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_slwr = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and slwr */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_slw_isvalid(slwr));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (slwr == PGRP_SLWR_NONE)
-		return 0;
-
-	reg = readl(pad_slwr);
-	reg &= ~PGRP_SLWR_MASK;
-	reg |= (slwr << PGRP_SLWR_SHIFT);
-	writel(reg, pad_slwr);
-
-	return 0;
-}
-
-static int padgrp_set_drvup(enum pdrive_pingrp pad, int drvup)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_drvup = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and drvup */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_drv_isvalid(drvup));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (drvup == PGRP_DRVUP_NONE)
-		return 0;
-
-	reg = readl(pad_drvup);
-	reg &= ~PGRP_DRVUP_MASK;
-	reg |= (drvup << PGRP_DRVUP_SHIFT);
-	writel(reg, pad_drvup);
-
-	return 0;
-}
-
-static int padgrp_set_drvdn(enum pdrive_pingrp pad, int drvdn)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_drvdn = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and drvdn */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_drv_isvalid(drvdn));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (drvdn == PGRP_DRVDN_NONE)
-		return 0;
-
-	reg = readl(pad_drvdn);
-	reg &= ~PGRP_DRVDN_MASK;
-	reg |= (drvdn << PGRP_DRVDN_SHIFT);
-	writel(reg, pad_drvdn);
-
-	return 0;
-}
-
-static int padgrp_set_lpmd(enum pdrive_pingrp pad, enum pgrp_lpmd lpmd)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_lpmd = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check pad and lpmd value */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_lpmd_isvalid(lpmd));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (lpmd == PGRP_LPMD_NONE)
-		return 0;
-
-	reg = readl(pad_lpmd);
-	reg &= ~PGRP_LPMD_MASK;
-	reg |= (lpmd << PGRP_LPMD_SHIFT);
-	writel(reg, pad_lpmd);
-
-	return 0;
-}
-
-static int padgrp_set_schmt(enum pdrive_pingrp pad, enum pgrp_schmt schmt)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_schmt = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check pad */
-	assert(pmux_padgrp_isvalid(pad));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (schmt == PGRP_SCHMT_NONE)
-		return 0;
-
-	reg = readl(pad_schmt);
-	reg &= ~(1 << PGRP_SCHMT_SHIFT);
-	if (schmt == PGRP_SCHMT_ENABLE)
-		reg |= (0x1 << PGRP_SCHMT_SHIFT);
-	writel(reg, pad_schmt);
-
-	return 0;
-}
-static int padgrp_set_hsm(enum pdrive_pingrp pad, enum pgrp_hsm hsm)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_hsm = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check pad */
-	assert(pmux_padgrp_isvalid(pad));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (hsm == PGRP_HSM_NONE)
-		return 0;
-
-	reg = readl(pad_hsm);
-	reg &= ~(1 << PGRP_HSM_SHIFT);
-	if (hsm == PGRP_HSM_ENABLE)
-		reg |= (0x1 << PGRP_HSM_SHIFT);
-	writel(reg, pad_hsm);
-
-	return 0;
-}
-
-void padctrl_config_pingroup(struct padctrl_config *config)
-{
-	enum pdrive_pingrp pad = config->padgrp;
-
-	padgrp_set_drvup_slwf(pad, config->slwf);
-	padgrp_set_drvdn_slwr(pad, config->slwr);
-	padgrp_set_drvup(pad, config->drvup);
-	padgrp_set_drvdn(pad, config->drvdn);
-	padgrp_set_lpmd(pad, config->lpmd);
-	padgrp_set_schmt(pad, config->schmt);
-	padgrp_set_hsm(pad, config->hsm);
-}
-
-void padgrp_config_table(struct padctrl_config *config, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		padctrl_config_pingroup(&config[i]);
-}
+const struct tegra_pingroup_desc *tegra_soc_pingroups = tegra114_pingroups;
diff --git a/arch/arm/cpu/tegra124-common/pinmux.c b/arch/arm/cpu/tegra124-common/pinmux.c
index 921dd2119b10..f741f83415fa 100644
--- a/arch/arm/cpu/tegra124-common/pinmux.c
+++ b/arch/arm/cpu/tegra124-common/pinmux.c
@@ -9,38 +9,8 @@ 
 
 #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_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
-#define PMUX_RCV_SEL_SHIFT	9
-
-#define PGRP_HSM_SHIFT		2
-#define PGRP_SCHMT_SHIFT	3
-#define PGRP_LPMD_SHIFT		4
-#define PGRP_LPMD_MASK		(3 << PGRP_LPMD_SHIFT)
-#define PGRP_DRVDN_SHIFT	12
-#define PGRP_DRVDN_MASK		(0x7F << PGRP_DRVDN_SHIFT)
-#define PGRP_DRVUP_SHIFT	20
-#define PGRP_DRVUP_MASK		(0x7F << PGRP_DRVUP_SHIFT)
-#define PGRP_SLWR_SHIFT		28
-#define PGRP_SLWR_MASK		(3 << PGRP_SLWR_SHIFT)
-#define PGRP_SLWF_SHIFT		30
-#define PGRP_SLWF_MASK		(3 << PGRP_SLWF_SHIFT)
-
 /* Convenient macro for defining pin group properties */
 #define PIN(pg_name, vdd, f0, f1, f2, f3, iod)	\
 	{						\
@@ -50,7 +20,6 @@  struct tegra_pingroup_desc {
 			PMUX_FUNC_ ## f2,		\
 			PMUX_FUNC_ ## f3,		\
 		},					\
-		.io = PMUX_PIN_ ## iod,			\
 	}
 
 /* Input and output pins */
@@ -63,7 +32,7 @@  struct tegra_pingroup_desc {
 #define PIN_RESERVED \
 	PIN(NONE, NONE, INVALID, INVALID, INVALID, INVALID, NONE)
 
-const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
+const struct tegra_pingroup_desc tegra124_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),
@@ -325,398 +294,4 @@  const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
 	PIN_RESERVED,	/* Reserved: 0x3404 */
 	PINO(RESET_OUT_N, SYS,     RSVD1,      RSVD2,      RSVD3, RESET_OUT_N),
 };
-
-void pinmux_set_tristate(enum pmux_pingrp pin, int enable)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *tri = &pmt->pmt_ctl[pin];
-	u32 reg;
-
-	/* Error check on pin */
-	assert(pmux_pingrp_isvalid(pin));
-
-	reg = readl(tri);
-	if (enable)
-		reg |= PMUX_TRISTATE_MASK;
-	else
-		reg &= ~PMUX_TRISTATE_MASK;
-	writel(reg, tri);
-}
-
-void pinmux_tristate_enable(enum pmux_pingrp pin)
-{
-	pinmux_set_tristate(pin, 1);
-}
-
-void pinmux_tristate_disable(enum pmux_pingrp pin)
-{
-	pinmux_set_tristate(pin, 0);
-}
-
-void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pull = &pmt->pmt_ctl[pin];
-	u32 reg;
-
-	/* Error check on pin and pupd */
-	assert(pmux_pingrp_isvalid(pin));
-	assert(pmux_pin_pupd_isvalid(pupd));
-
-	reg = readl(pull);
-	reg &= ~(0x3 << PMUX_PULL_SHIFT);
-	reg |= (pupd << PMUX_PULL_SHIFT);
-	writel(reg, pull);
-}
-
-void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *muxctl = &pmt->pmt_ctl[pin];
-	int i, mux = -1;
-	u32 reg;
-
-	/* Error check on pin and func */
-	assert(pmux_pingrp_isvalid(pin));
-	assert(pmux_func_isvalid(func));
-
-	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;
-}
-
-static int pinmux_set_rcv_sel(enum pmux_pingrp pin,
-				enum pmux_pin_rcv_sel rcv_sel)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pin_rcv_sel = &pmt->pmt_ctl[pin];
-	u32 reg;
-
-	/* Error check on pin and rcv_sel */
-	assert(pmux_pingrp_isvalid(pin));
-	assert(pmux_pin_rcv_sel_isvalid(rcv_sel));
-
-	if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT)
-		return 0;
-
-	reg = readl(pin_rcv_sel);
-	reg &= ~(0x1 << PMUX_RCV_SEL_SHIFT);
-	if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH)
-		reg |= (0x1 << PMUX_RCV_SEL_SHIFT);
-	writel(reg, pin_rcv_sel);
-
-	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);
-	pinmux_set_rcv_sel(pin, config->rcv_sel);
-}
-
-void pinmux_config_table(struct pingroup_config *config, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		pinmux_config_pingroup(&config[i]);
-}
-
-static int padgrp_set_drvup_slwf(enum pdrive_pingrp pad, int slwf)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_slwf = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and slwf */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_slw_isvalid(slwf));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (slwf == PGRP_SLWF_NONE)
-		return 0;
-
-	reg = readl(pad_slwf);
-	reg &= ~PGRP_SLWF_MASK;
-	reg |= (slwf << PGRP_SLWF_SHIFT);
-	writel(reg, pad_slwf);
-
-	return 0;
-}
-
-static int padgrp_set_drvdn_slwr(enum pdrive_pingrp pad, int slwr)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_slwr = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and slwr */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_slw_isvalid(slwr));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (slwr == PGRP_SLWR_NONE)
-		return 0;
-
-	reg = readl(pad_slwr);
-	reg &= ~PGRP_SLWR_MASK;
-	reg |= (slwr << PGRP_SLWR_SHIFT);
-	writel(reg, pad_slwr);
-
-	return 0;
-}
-
-static int padgrp_set_drvup(enum pdrive_pingrp pad, int drvup)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_drvup = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and drvup */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_drv_isvalid(drvup));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (drvup == PGRP_DRVUP_NONE)
-		return 0;
-
-	reg = readl(pad_drvup);
-	reg &= ~PGRP_DRVUP_MASK;
-	reg |= (drvup << PGRP_DRVUP_SHIFT);
-	writel(reg, pad_drvup);
-
-	return 0;
-}
-
-static int padgrp_set_drvdn(enum pdrive_pingrp pad, int drvdn)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_drvdn = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and drvdn */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_drv_isvalid(drvdn));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (drvdn == PGRP_DRVDN_NONE)
-		return 0;
-
-	reg = readl(pad_drvdn);
-	reg &= ~PGRP_DRVDN_MASK;
-	reg |= (drvdn << PGRP_DRVDN_SHIFT);
-	writel(reg, pad_drvdn);
-
-	return 0;
-}
-
-static int padgrp_set_lpmd(enum pdrive_pingrp pad, enum pgrp_lpmd lpmd)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_lpmd = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check pad and lpmd value */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_lpmd_isvalid(lpmd));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (lpmd == PGRP_LPMD_NONE)
-		return 0;
-
-	reg = readl(pad_lpmd);
-	reg &= ~PGRP_LPMD_MASK;
-	reg |= (lpmd << PGRP_LPMD_SHIFT);
-	writel(reg, pad_lpmd);
-
-	return 0;
-}
-
-static int padgrp_set_schmt(enum pdrive_pingrp pad, enum pgrp_schmt schmt)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_schmt = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check pad */
-	assert(pmux_padgrp_isvalid(pad));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (schmt == PGRP_SCHMT_NONE)
-		return 0;
-
-	reg = readl(pad_schmt);
-	reg &= ~(1 << PGRP_SCHMT_SHIFT);
-	if (schmt == PGRP_SCHMT_ENABLE)
-		reg |= (0x1 << PGRP_SCHMT_SHIFT);
-	writel(reg, pad_schmt);
-
-	return 0;
-}
-static int padgrp_set_hsm(enum pdrive_pingrp pad, enum pgrp_hsm hsm)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_hsm = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check pad */
-	assert(pmux_padgrp_isvalid(pad));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (hsm == PGRP_HSM_NONE)
-		return 0;
-
-	reg = readl(pad_hsm);
-	reg &= ~(1 << PGRP_HSM_SHIFT);
-	if (hsm == PGRP_HSM_ENABLE)
-		reg |= (0x1 << PGRP_HSM_SHIFT);
-	writel(reg, pad_hsm);
-
-	return 0;
-}
-
-void padctrl_config_pingroup(struct padctrl_config *config)
-{
-	enum pdrive_pingrp pad = config->padgrp;
-
-	padgrp_set_drvup_slwf(pad, config->slwf);
-	padgrp_set_drvdn_slwr(pad, config->slwr);
-	padgrp_set_drvup(pad, config->drvup);
-	padgrp_set_drvdn(pad, config->drvdn);
-	padgrp_set_lpmd(pad, config->lpmd);
-	padgrp_set_schmt(pad, config->schmt);
-	padgrp_set_hsm(pad, config->hsm);
-}
-
-void padgrp_config_table(struct padctrl_config *config, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		padctrl_config_pingroup(&config[i]);
-}
+const struct tegra_pingroup_desc *tegra_soc_pingroups = tegra124_pingroups;
diff --git a/arch/arm/cpu/tegra20-common/pinmux.c b/arch/arm/cpu/tegra20-common/pinmux.c
index 14467f01f547..cc1cbefdaca9 100644
--- a/arch/arm/cpu/tegra20-common/pinmux.c
+++ b/arch/arm/cpu/tegra20-common/pinmux.c
@@ -8,10 +8,8 @@ 
 
 #include <common.h>
 #include <asm/io.h>
-#include <asm/arch/tegra.h>
 #include <asm/arch/pinmux.h>
 
-
 /*
  * This defines the order of the pin mux control bits in the registers. For
  * some reason there is no correspendence between the tristate, pin mux and
@@ -256,32 +254,6 @@  enum pmux_pullid {
 	PUCTL_NONE = -1
 };
 
-struct tegra_pingroup_desc {
-	const char *name;
-	enum pmux_func funcs[4];
-	enum pmux_ctlid ctl_id;
-	enum pmux_pullid pull_id;
-};
-
-
-/* Converts a pmux_pingrp number to a tristate register: 0=A, 1=B, 2=C, 3=D */
-#define TRISTATE_REG(pmux_pingrp) ((pmux_pingrp) >> 5)
-
-/* Mask value for a tristate (within TRISTATE_REG(id)) */
-#define TRISTATE_MASK(pmux_pingrp) (1 << ((pmux_pingrp) & 0x1f))
-
-/* Converts a PUCTL id to a pull register: 0=A, 1=B...4=E */
-#define PULL_REG(pmux_pullid) ((pmux_pullid) >> 4)
-
-/* Converts a PUCTL id to a shift position */
-#define PULL_SHIFT(pmux_pullid) ((pmux_pullid << 1) & 0x1f)
-
-/* Converts a MUXCTL id to a ctl register: 0=A, 1=B...6=G */
-#define MUXCTL_REG(pmux_ctlid) ((pmux_ctlid) >> 4)
-
-/* Converts a MUXCTL id to a shift position */
-#define MUXCTL_SHIFT(pmux_ctlid) ((pmux_ctlid << 1) & 0x1f)
-
 /* Convenient macro for defining pin group properties */
 #define PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe, mux, pupd)		\
 	{						\
@@ -309,9 +281,9 @@  struct tegra_pingroup_desc {
 #define PIN_RESERVED \
 	PIN(NONE, NONE, RSVD, RSVD, RSVD, RSVD, RSVD)
 
-#define PMUX_FUNC_RSVD ((enum pmux_func)-1)
+#define PMUX_FUNC_RSVD PMUX_FUNC_RSVD1
 
-const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
+const struct tegra_pingroup_desc tegra20_pingroups[] = {
 	PIN(ATA,  NAND,  IDE,    NAND,   GMI,       RSVD,        IDE),
 	PIN(ATB,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
 	PIN(ATC,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
@@ -462,94 +434,4 @@  const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
 	PINALL(XM2D,  DDR,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
 		PUCTL_NONE),
 };
-
-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_tri[TRISTATE_REG(pin)];
-	u32 reg;
-
-	reg = readl(tri);
-	if (enable)
-		reg |= TRISTATE_MASK(pin);
-	else
-		reg &= ~TRISTATE_MASK(pin);
-	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;
-	enum pmux_pullid pull_id = tegra_soc_pingroups[pin].pull_id;
-	u32 *pull = &pmt->pmt_pull[PULL_REG(pull_id)];
-	u32 mask_bit;
-	u32 reg;
-	mask_bit = PULL_SHIFT(pull_id);
-
-	reg = readl(pull);
-	reg &= ~(0x3 << mask_bit);
-	reg |= pupd << mask_bit;
-	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;
-	enum pmux_ctlid mux_id = tegra_soc_pingroups[pin].ctl_id;
-	u32 *muxctl = &pmt->pmt_ctl[MUXCTL_REG(mux_id)];
-	u32 mask_bit;
-	int i, mux = -1;
-	u32 reg;
-
-	assert(pmux_func_isvalid(func));
-
-	/* Handle special values */
-	if (func >= PMUX_FUNC_RSVD1) {
-		mux = (func - PMUX_FUNC_RSVD1) & 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);
-
-	mask_bit = MUXCTL_SHIFT(mux_id);
-	reg = readl(muxctl);
-	reg &= ~(0x3 << mask_bit);
-	reg |= mux << mask_bit;
-	writel(reg, muxctl);
-}
-
-void pinmux_config_pingroup(const 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);
-}
-
-void pinmux_config_table(const struct pingroup_config *config, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		pinmux_config_pingroup(&config[i]);
-}
+const struct tegra_pingroup_desc *tegra_soc_pingroups = tegra20_pingroups;
diff --git a/arch/arm/cpu/tegra20-common/warmboot.c b/arch/arm/cpu/tegra20-common/warmboot.c
index 8beba53fc357..d6830f63b915 100644
--- a/arch/arm/cpu/tegra20-common/warmboot.c
+++ b/arch/arm/cpu/tegra20-common/warmboot.c
@@ -122,7 +122,7 @@  int warmboot_save_sdram_params(void)
 {
 	u32 ram_code;
 	struct sdram_params sdram;
-	struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *strap_opt_a = (u32 *)(NV_PA_APB_MISC_BASE + 8);
 	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
 	struct apb_misc_gp_ctlr *gp =
 			(struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
@@ -135,8 +135,7 @@  int warmboot_save_sdram_params(void)
 	union fbio_spare_reg fbio_spare;
 
 	/* get ram code that is used as index to array sdram_params in BCT */
-	ram_code = (readl(&pmt->pmt_strap_opt_a) >>
-			STRAP_OPT_A_RAM_CODE_SHIFT) & 3;
+	ram_code = (readl(strap_opt_a) >> STRAP_OPT_A_RAM_CODE_SHIFT) & 3;
 	memcpy(&sdram,
 	       (char *)((struct sdram_params *)SDRAM_PARAMS_BASE + ram_code),
 	       sizeof(sdram));
diff --git a/arch/arm/cpu/tegra20-common/warmboot_avp.c b/arch/arm/cpu/tegra20-common/warmboot_avp.c
index b910f7844bb6..789faa470c75 100644
--- a/arch/arm/cpu/tegra20-common/warmboot_avp.c
+++ b/arch/arm/cpu/tegra20-common/warmboot_avp.c
@@ -21,7 +21,7 @@ 
 
 void wb_start(void)
 {
-	struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *cfg_ctl = (u32 *)(NV_PA_APB_MISC_BASE + 0x24);
 	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
 	struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
 	struct clk_rst_ctlr *clkrst =
@@ -33,7 +33,7 @@  void wb_start(void)
 	u32 reg;
 
 	/* enable JTAG & TBE */
-	writel(CONFIG_CTL_TBE | CONFIG_CTL_JTAG, &pmt->pmt_cfg_ctl);
+	writel(CONFIG_CTL_TBE | CONFIG_CTL_JTAG, cfg_ctl);
 
 	/* Are we running where we're supposed to be? */
 	asm volatile (
diff --git a/arch/arm/cpu/tegra30-common/pinmux.c b/arch/arm/cpu/tegra30-common/pinmux.c
index 8eca0dd65485..a12b0767f2c1 100644
--- a/arch/arm/cpu/tegra30-common/pinmux.c
+++ b/arch/arm/cpu/tegra30-common/pinmux.c
@@ -18,39 +18,10 @@ 
 
 #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_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
-
-#define PGRP_HSM_SHIFT		2
-#define PGRP_SCHMT_SHIFT	3
-#define PGRP_LPMD_SHIFT		4
-#define PGRP_LPMD_MASK		(3 << PGRP_LPMD_SHIFT)
-#define PGRP_DRVDN_SHIFT	12
-#define PGRP_DRVDN_MASK		(0x7F << PGRP_DRVDN_SHIFT)
-#define PGRP_DRVUP_SHIFT	20
-#define PGRP_DRVUP_MASK		(0x7F << PGRP_DRVUP_SHIFT)
-#define PGRP_SLWR_SHIFT		28
-#define PGRP_SLWR_MASK		(3 << PGRP_SLWR_SHIFT)
-#define PGRP_SLWF_SHIFT		30
-#define PGRP_SLWF_MASK		(3 << PGRP_SLWF_SHIFT)
-
 /* Convenient macro for defining pin group properties */
-#define PIN(pg_name, vdd, f0, f1, f2, f3, iod)	\
+#define PIN(pg_name, vdd, f0, f1, f2, f3, iod)		\
 	{						\
 		.funcs = {				\
 			PMUX_FUNC_ ## f0,		\
@@ -58,7 +29,6 @@  struct tegra_pingroup_desc {
 			PMUX_FUNC_ ## f2,		\
 			PMUX_FUNC_ ## f3,		\
 		},					\
-		.io = PMUX_PIN_ ## iod,			\
 	}
 
 /* Input and output pins */
@@ -67,7 +37,7 @@  struct tegra_pingroup_desc {
 #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] = {
+static const struct tegra_pingroup_desc tegra30_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),
@@ -319,368 +289,4 @@  const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
 	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));
-
-	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]);
-}
-
-static int padgrp_set_drvup_slwf(enum pdrive_pingrp pad,
-				int slwf)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_slwf = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and slwf */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_slw_isvalid(slwf));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (slwf == PGRP_SLWF_NONE)
-		return 0;
-
-	reg = readl(pad_slwf);
-	reg &= ~PGRP_SLWF_MASK;
-	reg |= (slwf << PGRP_SLWF_SHIFT);
-	writel(reg, pad_slwf);
-
-	return 0;
-}
-
-static int padgrp_set_drvdn_slwr(enum pdrive_pingrp pad, int slwr)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_slwr = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and slwr */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_slw_isvalid(slwr));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (slwr == PGRP_SLWR_NONE)
-		return 0;
-
-	reg = readl(pad_slwr);
-	reg &= ~PGRP_SLWR_MASK;
-	reg |= (slwr << PGRP_SLWR_SHIFT);
-	writel(reg, pad_slwr);
-
-	return 0;
-}
-
-static int padgrp_set_drvup(enum pdrive_pingrp pad, int drvup)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_drvup = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and drvup */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_drv_isvalid(drvup));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (drvup == PGRP_DRVUP_NONE)
-		return 0;
-
-	reg = readl(pad_drvup);
-	reg &= ~PGRP_DRVUP_MASK;
-	reg |= (drvup << PGRP_DRVUP_SHIFT);
-	writel(reg, pad_drvup);
-
-	return 0;
-}
-
-static int padgrp_set_drvdn(enum pdrive_pingrp pad, int drvdn)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_drvdn = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check on pad and drvdn */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_drv_isvalid(drvdn));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (drvdn == PGRP_DRVDN_NONE)
-		return 0;
-
-	reg = readl(pad_drvdn);
-	reg &= ~PGRP_DRVDN_MASK;
-	reg |= (drvdn << PGRP_DRVDN_SHIFT);
-	writel(reg, pad_drvdn);
-
-	return 0;
-}
-
-static int padgrp_set_lpmd(enum pdrive_pingrp pad, enum pgrp_lpmd lpmd)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_lpmd = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check pad and lpmd value */
-	assert(pmux_padgrp_isvalid(pad));
-	assert(pmux_pad_lpmd_isvalid(lpmd));
-
-	/* NONE means unspecified/do not change/use POR value */
-	if (lpmd == PGRP_LPMD_NONE)
-		return 0;
-
-	reg = readl(pad_lpmd);
-	reg &= ~PGRP_LPMD_MASK;
-	reg |= (lpmd << PGRP_LPMD_SHIFT);
-	writel(reg, pad_lpmd);
-
-	return 0;
-}
-
-static int padgrp_set_schmt(enum pdrive_pingrp pad, enum pgrp_schmt schmt)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_schmt = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check pad */
-	assert(pmux_padgrp_isvalid(pad));
-
-	reg = readl(pad_schmt);
-	reg &= ~(1 << PGRP_SCHMT_SHIFT);
-	if (schmt == PGRP_SCHMT_ENABLE)
-		reg |= (0x1 << PGRP_SCHMT_SHIFT);
-	writel(reg, pad_schmt);
-
-	return 0;
-}
-static int padgrp_set_hsm(enum pdrive_pingrp pad,
-			enum pgrp_hsm hsm)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *pad_hsm = &pmt->pmt_drive[pad];
-	u32 reg;
-
-	/* Error check pad */
-	assert(pmux_padgrp_isvalid(pad));
-
-	reg = readl(pad_hsm);
-	reg &= ~(1 << PGRP_HSM_SHIFT);
-	if (hsm == PGRP_HSM_ENABLE)
-		reg |= (0x1 << PGRP_HSM_SHIFT);
-	writel(reg, pad_hsm);
-
-	return 0;
-}
-
-void padctrl_config_pingroup(struct padctrl_config *config)
-{
-	enum pdrive_pingrp pad = config->padgrp;
-
-	padgrp_set_drvup_slwf(pad, config->slwf);
-	padgrp_set_drvdn_slwr(pad, config->slwr);
-	padgrp_set_drvup(pad, config->drvup);
-	padgrp_set_drvdn(pad, config->drvdn);
-	padgrp_set_lpmd(pad, config->lpmd);
-	padgrp_set_schmt(pad, config->schmt);
-	padgrp_set_hsm(pad, config->hsm);
-}
-
-void padgrp_config_table(struct padctrl_config *config, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		padctrl_config_pingroup(&config[i]);
-}
+const struct tegra_pingroup_desc *tegra_soc_pingroups = tegra30_pingroups;
diff --git a/arch/arm/include/asm/arch-tegra/pinmux.h b/arch/arm/include/asm/arch-tegra/pinmux.h
new file mode 100644
index 000000000000..e97fffdcf87b
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra/pinmux.h
@@ -0,0 +1,189 @@ 
+/*
+ * (C) Copyright 2010-2014
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _TEGRA_PINMUX_H_
+#define _TEGRA_PINMUX_H_
+
+#include <asm/arch/tegra.h>
+
+/* The pullup/pulldown state of a pin group */
+enum pmux_pull {
+	PMUX_PULL_NORMAL = 0,
+	PMUX_PULL_DOWN,
+	PMUX_PULL_UP,
+};
+
+/* Defines whether a pin group is tristated or in normal operation */
+enum pmux_tristate {
+	PMUX_TRI_NORMAL = 0,
+	PMUX_TRI_TRISTATE = 1,
+};
+
+#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
+enum pmux_pin_io {
+	PMUX_PIN_OUTPUT = 0,
+	PMUX_PIN_INPUT = 1,
+	PMUX_PIN_NONE,
+};
+
+enum pmux_pin_lock {
+	PMUX_PIN_LOCK_DEFAULT = 0,
+	PMUX_PIN_LOCK_DISABLE,
+	PMUX_PIN_LOCK_ENABLE,
+};
+
+enum pmux_pin_od {
+	PMUX_PIN_OD_DEFAULT = 0,
+	PMUX_PIN_OD_DISABLE,
+	PMUX_PIN_OD_ENABLE,
+};
+
+enum pmux_pin_ioreset {
+	PMUX_PIN_IO_RESET_DEFAULT = 0,
+	PMUX_PIN_IO_RESET_DISABLE,
+	PMUX_PIN_IO_RESET_ENABLE,
+};
+
+#ifdef TEGRA_PMX_HAS_RCV_SEL
+enum pmux_pin_rcv_sel {
+	PMUX_PIN_RCV_SEL_DEFAULT = 0,
+	PMUX_PIN_RCV_SEL_NORMAL,
+	PMUX_PIN_RCV_SEL_HIGH,
+};
+#endif /* TEGRA_PMX_HAS_RCV_SEL */
+#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */
+
+/*
+ * This defines the configuration for a pin, including the function assigned,
+ * pull up/down settings and tristate settings. Having set up one of these
+ * you can call pinmux_config_pingroup() to configure a pin in one step. Also
+ * available is pinmux_config_table() to configure a list of pins.
+ */
+struct pingroup_config {
+	enum pmux_pingrp pingroup;	/* pin group PINGRP_...             */
+	enum pmux_func func;		/* function to assign FUNC_...      */
+	enum pmux_pull pull;		/* pull up/down/normal PMUX_PULL_...*/
+	enum pmux_tristate tristate;	/* tristate or normal PMUX_TRI_...  */
+#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
+	enum pmux_pin_io io;		/* input or output PMUX_PIN_...  */
+	enum pmux_pin_lock lock;	/* lock enable/disable PMUX_PIN...  */
+	enum pmux_pin_od od;		/* open-drain or push-pull driver  */
+	enum pmux_pin_ioreset ioreset;	/* input/output reset PMUX_PIN...  */
+#ifdef TEGRA_PMX_HAS_RCV_SEL
+	enum pmux_pin_rcv_sel rcv_sel;	/* select between High and Normal  */
+					/* VIL/VIH receivers */
+#endif
+#endif
+};
+
+/* Set the mux function for a pin group */
+void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func);
+
+/* Set the pull up/down feature for a pin group */
+void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd);
+
+/* Set a pin group to tristate or normal */
+void pinmux_set_tristate(enum pmux_pingrp pin, int enable);
+
+/* Set a pin group to tristate */
+void pinmux_tristate_enable(enum pmux_pingrp pin);
+
+/* Set a pin group to normal (non tristate) */
+void pinmux_tristate_disable(enum pmux_pingrp pin);
+
+#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC
+/* Set a pin group as input or output */
+void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io);
+#endif
+
+/* Set the complete configuration for a pin group */
+void pinmux_config_pingroup(const struct pingroup_config *config);
+
+/**
+ * Configure a list of pin groups
+ *
+ * @param config	List of config items
+ * @param len		Number of config items in list
+ */
+void pinmux_config_table(const struct pingroup_config *config, int len);
+
+#ifdef TEGRA_PMX_HAS_PADGRPS
+
+#define PGRP_SLWF_MIN	0
+#define PGRP_SLWF_MAX	3
+#define PGRP_SLWF_NONE	-1
+
+#define PGRP_SLWR_MIN	0
+#define PGRP_SLWR_MAX	3
+#define PGRP_SLWR_NONE	-1
+
+#define PGRP_DRVUP_MIN	0
+#define PGRP_DRVUP_MAX	127
+#define PGRP_DRVUP_NONE	-1
+
+#define PGRP_DRVDN_MIN	0
+#define PGRP_DRVDN_MAX	127
+#define PGRP_DRVDN_NONE	-1
+
+/* Defines a pin group cfg's low-power mode select */
+enum pgrp_lpmd {
+	PGRP_LPMD_X8 = 0,
+	PGRP_LPMD_X4,
+	PGRP_LPMD_X2,
+	PGRP_LPMD_X,
+	PGRP_LPMD_NONE = -1,
+};
+
+/* Defines whether a pin group cfg's schmidt is enabled or not */
+enum pgrp_schmt {
+	PGRP_SCHMT_DISABLE = 0,
+	PGRP_SCHMT_ENABLE = 1,
+	PGRP_SCHMT_NONE = -1,
+};
+
+/* Defines whether a pin group cfg's high-speed mode is enabled or not */
+enum pgrp_hsm {
+	PGRP_HSM_DISABLE = 0,
+	PGRP_HSM_ENABLE = 1,
+	PGRP_HSM_NONE = -1,
+};
+
+/*
+ * This defines the configuration for a pin group's pad control config
+ */
+struct padctrl_config {
+	enum pdrive_pingrp padgrp;	/* pin group PDRIVE_PINGRP_x */
+	int slwf;			/* falling edge slew         */
+	int slwr;			/* rising edge slew          */
+	int drvup;			/* pull-up drive strength    */
+	int drvdn;			/* pull-down drive strength  */
+	enum pgrp_lpmd lpmd;		/* low-power mode selection  */
+	enum pgrp_schmt schmt;		/* schmidt enable            */
+	enum pgrp_hsm hsm;		/* high-speed mode enable    */
+};
+
+/**
+ * Set the GP pad configs
+ *
+ * @param config	List of config items
+ * @param len		Number of config items in list
+ */
+void padgrp_config_table(const struct padctrl_config *config, int len);
+
+#endif /* TEGRA_PMX_HAS_PADGRPS */
+
+struct tegra_pingroup_desc {
+	enum pmux_func funcs[4];
+#if defined(CONFIG_TEGRA20)
+	u32 ctl_id;
+	u32 pull_id;
+#endif /* CONFIG_TEGRA20 */
+};
+
+extern const struct tegra_pingroup_desc *tegra_soc_pingroups;
+
+#endif /* _TEGRA_PINMUX_H_ */
diff --git a/arch/arm/include/asm/arch-tegra114/pinmux.h b/arch/arm/include/asm/arch-tegra114/pinmux.h
index a06b24f412ee..00ef5423547d 100644
--- a/arch/arm/include/asm/arch-tegra114/pinmux.h
+++ b/arch/arm/include/asm/arch-tegra114/pinmux.h
@@ -367,7 +367,7 @@  enum pmux_func {
 	PMUX_FUNC_RESET_OUT_N,
 	/* End of Tegra114 MUX selectors */
 
-	PMUX_FUNC_MAX,
+	PMUX_FUNC_COUNT,
 
 	PMUX_FUNC_INVALID = 0x4000,
 	PMUX_FUNC_RSVD1 = 0x8000,
@@ -376,216 +376,9 @@  enum pmux_func {
 	PMUX_FUNC_RSVD4 = 0x8003,
 };
 
-/* return 1 if a pmux_func is in range */
-#define pmux_func_isvalid(func) ((((func) >= 0) && ((func) < PMUX_FUNC_MAX)) \
-	|| (((func) >= PMUX_FUNC_RSVD1) && ((func) <= PMUX_FUNC_RSVD4)))
+#define TEGRA_PMX_HAS_PIN_IO_BIT_ETC
+#define TEGRA_PMX_HAS_RCV_SEL
+#define TEGRA_PMX_HAS_PADGRPS
+#include <asm/arch-tegra/pinmux.h>
 
-/* return 1 if a pingrp is in range */
-#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PINGRP_COUNT))
-
-/* The pullup/pulldown state of a pin group */
-enum pmux_pull {
-	PMUX_PULL_NORMAL = 0,
-	PMUX_PULL_DOWN,
-	PMUX_PULL_UP,
-};
-/* return 1 if a pin_pupd_is in range */
-#define pmux_pin_pupd_isvalid(pupd) (((pupd) >= PMUX_PULL_NORMAL) && \
-				((pupd) <= PMUX_PULL_UP))
-
-/* Defines whether a pin group is tristated or in normal operation */
-enum pmux_tristate {
-	PMUX_TRI_NORMAL = 0,
-	PMUX_TRI_TRISTATE = 1,
-};
-/* return 1 if a pin_tristate_is in range */
-#define pmux_pin_tristate_isvalid(tristate) (((tristate) >= PMUX_TRI_NORMAL) \
-				&& ((tristate) <= PMUX_TRI_TRISTATE))
-
-enum pmux_pin_io {
-	PMUX_PIN_OUTPUT = 0,
-	PMUX_PIN_INPUT = 1,
-	PMUX_PIN_NONE,
-};
-/* return 1 if a pin_io_is in range */
-#define pmux_pin_io_isvalid(io) (((io) >= PMUX_PIN_OUTPUT) && \
-				((io) <= PMUX_PIN_INPUT))
-
-enum pmux_pin_lock {
-	PMUX_PIN_LOCK_DEFAULT = 0,
-	PMUX_PIN_LOCK_DISABLE,
-	PMUX_PIN_LOCK_ENABLE,
-};
-/* return 1 if a pin_lock is in range */
-#define pmux_pin_lock_isvalid(lock) (((lock) >= PMUX_PIN_LOCK_DEFAULT) && \
-				((lock) <= PMUX_PIN_LOCK_ENABLE))
-
-enum pmux_pin_od {
-	PMUX_PIN_OD_DEFAULT = 0,
-	PMUX_PIN_OD_DISABLE,
-	PMUX_PIN_OD_ENABLE,
-};
-/* return 1 if a pin_od is in range */
-#define pmux_pin_od_isvalid(od) (((od) >= PMUX_PIN_OD_DEFAULT) && \
-				((od) <= PMUX_PIN_OD_ENABLE))
-
-enum pmux_pin_ioreset {
-	PMUX_PIN_IO_RESET_DEFAULT = 0,
-	PMUX_PIN_IO_RESET_DISABLE,
-	PMUX_PIN_IO_RESET_ENABLE,
-};
-/* return 1 if a pin_ioreset_is in range */
-#define pmux_pin_ioreset_isvalid(ioreset) \
-				(((ioreset) >= PMUX_PIN_IO_RESET_DEFAULT) && \
-				((ioreset) <= PMUX_PIN_IO_RESET_ENABLE))
-
-enum pmux_pin_rcv_sel {
-	PMUX_PIN_RCV_SEL_DEFAULT = 0,
-	PMUX_PIN_RCV_SEL_NORMAL,
-	PMUX_PIN_RCV_SEL_HIGH,
-};
-/* return 1 if a pin_rcv_sel_is in range */
-#define pmux_pin_rcv_sel_isvalid(rcv_sel) \
-				(((rcv_sel) >= PMUX_PIN_RCV_SEL_DEFAULT) && \
-				((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH))
-
-#define PGRP_SLWF_NONE	-1
-#define PGRP_SLWF_MAX	3
-#define PGRP_SLWR_NONE	PGRP_SLWF_NONE
-#define PGRP_SLWR_MAX	PGRP_SLWF_MAX
-
-#define PGRP_DRVUP_NONE	-1
-#define PGRP_DRVUP_MAX	127
-#define PGRP_DRVDN_NONE	PGRP_DRVUP_NONE
-#define PGRP_DRVDN_MAX	PGRP_DRVUP_MAX
-
-#define PGRP_SCHMT_NONE	-1
-#define PGRP_HSM_NONE	PGRP_SCHMT_NONE
-
-/* return 1 if a padgrp is in range */
-#define pmux_padgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PDRIVE_PINGROUP_COUNT))
-
-/* return 1 if a slew-rate rising/falling edge value is in range */
-#define pmux_pad_slw_isvalid(slw) (((slw) == PGRP_SLWF_NONE) || \
-				(((slw) >= 0) && ((slw) <= PGRP_SLWF_MAX)))
-
-/* return 1 if a driver output pull-up/down strength code value is in range */
-#define pmux_pad_drv_isvalid(drv) (((drv) == PGRP_DRVUP_NONE) || \
-				(((drv) >= 0) && ((drv) <= PGRP_DRVUP_MAX)))
-
-/* return 1 if a low-power mode value is in range */
-#define pmux_pad_lpmd_isvalid(lpm) (((lpm) == PGRP_LPMD_NONE) || \
-				(((lpm) >= 0) && ((lpm) <= PGRP_LPMD_X)))
-
-/* Defines a pin group cfg's low-power mode select */
-enum pgrp_lpmd {
-	PGRP_LPMD_X8 = 0,
-	PGRP_LPMD_X4,
-	PGRP_LPMD_X2,
-	PGRP_LPMD_X,
-	PGRP_LPMD_NONE = -1,
-};
-
-/* Defines whether a pin group cfg's schmidt is enabled or not */
-enum pgrp_schmt {
-	PGRP_SCHMT_DISABLE = 0,
-	PGRP_SCHMT_ENABLE = 1,
-};
-
-/* Defines whether a pin group cfg's high-speed mode is enabled or not */
-enum pgrp_hsm {
-	PGRP_HSM_DISABLE = 0,
-	PGRP_HSM_ENABLE = 1,
-};
-
-/*
- * This defines the configuration for a pin group's pad control config
- */
-struct padctrl_config {
-	enum pdrive_pingrp padgrp;	/* pin group PDRIVE_PINGRP_x */
-	int slwf;			/* falling edge slew         */
-	int slwr;			/* rising edge slew          */
-	int drvup;			/* pull-up drive strength    */
-	int drvdn;			/* pull-down drive strength  */
-	enum pgrp_lpmd lpmd;		/* low-power mode selection  */
-	enum pgrp_schmt schmt;		/* schmidt enable            */
-	enum pgrp_hsm hsm;		/* high-speed mode enable    */
-};
-
-/* t114 pin drive group and pin mux registers */
-#define PDRIVE_PINGROUP_OFFSET	(0x868 >> 2)
-#define PMUX_OFFSET	((0x3000 >> 2) - PDRIVE_PINGROUP_OFFSET - \
-				PDRIVE_PINGROUP_COUNT)
-struct pmux_tri_ctlr {
-	uint pmt_reserved0;		/* ABP_MISC_PP_ reserved offset 00 */
-	uint pmt_reserved1;		/* ABP_MISC_PP_ reserved offset 04 */
-	uint pmt_strap_opt_a;		/* _STRAPPING_OPT_A_0, offset 08   */
-	uint pmt_reserved2;		/* ABP_MISC_PP_ reserved offset 0C */
-	uint pmt_reserved3;		/* ABP_MISC_PP_ reserved offset 10 */
-	uint pmt_reserved4[4];		/* _TRI_STATE_REG_A/B/C/D in t20 */
-	uint pmt_cfg_ctl;		/* _CONFIG_CTL_0, offset 24        */
-
-	uint pmt_reserved[528];		/* ABP_MISC_PP_ reserved offs 28-864 */
-
-	uint pmt_drive[PDRIVE_PINGROUP_COUNT];	/* pin drive grps offs 868 */
-	uint pmt_reserved5[PMUX_OFFSET];
-	uint pmt_ctl[PINGRP_COUNT];	/* mux/pupd/tri regs, offset 0x3000 */
-};
-
-/*
- * This defines the configuration for a pin, including the function assigned,
- * pull up/down settings and tristate settings. Having set up one of these
- * you can call pinmux_config_pingroup() to configure a pin in one step. Also
- * available is pinmux_config_table() to configure a list of pins.
- */
-struct pingroup_config {
-	enum pmux_pingrp pingroup;	/* pin group PINGRP_...             */
-	enum pmux_func func;		/* function to assign FUNC_...      */
-	enum pmux_pull pull;		/* pull up/down/normal PMUX_PULL_...*/
-	enum pmux_tristate tristate;	/* tristate or normal PMUX_TRI_...  */
-	enum pmux_pin_io io;		/* input or output PMUX_PIN_...  */
-	enum pmux_pin_lock lock;	/* lock enable/disable PMUX_PIN...  */
-	enum pmux_pin_od od;		/* open-drain or push-pull driver  */
-	enum pmux_pin_ioreset ioreset;	/* input/output reset PMUX_PIN...  */
-	enum pmux_pin_rcv_sel rcv_sel;	/* select between High and Normal  */
-					/* VIL/VIH receivers */
-};
-
-/* Set a pin group to tristate */
-void pinmux_tristate_enable(enum pmux_pingrp pin);
-
-/* Set a pin group to normal (non tristate) */
-void pinmux_tristate_disable(enum pmux_pingrp pin);
-
-/* Set the pull up/down feature for a pin group */
-void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd);
-
-/* Set the mux function for a pin group */
-void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func);
-
-/* Set the complete configuration for a pin group */
-void pinmux_config_pingroup(struct pingroup_config *config);
-
-/* Set a pin group to tristate or normal */
-void pinmux_set_tristate(enum pmux_pingrp pin, int enable);
-
-/* Set a pin group as input or output */
-void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io);
-
-/**
- * Configure a list of pin groups
- *
- * @param config	List of config items
- * @param len		Number of config items in list
- */
-void pinmux_config_table(struct pingroup_config *config, int len);
-
-/**
- * Set the GP pad configs
- *
- * @param config	List of config items
- * @param len		Number of config items in list
- */
-void padgrp_config_table(struct padctrl_config *config, int len);
-
-#endif	/* _TEGRA114_PINMUX_H_ */
+#endif /* _TEGRA114_PINMUX_H_ */
diff --git a/arch/arm/include/asm/arch-tegra124/pinmux.h b/arch/arm/include/asm/arch-tegra124/pinmux.h
index 900cf4462264..2c6f0d8e60fc 100644
--- a/arch/arm/include/asm/arch-tegra124/pinmux.h
+++ b/arch/arm/include/asm/arch-tegra124/pinmux.h
@@ -374,7 +374,7 @@  enum pmux_func {
 	PMUX_FUNC_RESET_OUT_N,
 	/* End of Tegra114 MUX selectors */
 
-	PMUX_FUNC_MAX,
+	PMUX_FUNC_COUNT,
 
 	PMUX_FUNC_INVALID = 0x4000,
 	PMUX_FUNC_RSVD1 = 0x8000,
@@ -383,213 +383,9 @@  enum pmux_func {
 	PMUX_FUNC_RSVD4 = 0x8003,
 };
 
-/* return 1 if a pmux_func is in range */
-#define pmux_func_isvalid(func) \
-	((((func) >= 0) && ((func) < PMUX_FUNC_MAX)) || \
-	(((func) >= PMUX_FUNC_RSVD1) && ((func) <= PMUX_FUNC_RSVD4)))
+#define TEGRA_PMX_HAS_PIN_IO_BIT_ETC
+#define TEGRA_PMX_HAS_RCV_SEL
+#define TEGRA_PMX_HAS_PADGRPS
+#include <asm/arch-tegra/pinmux.h>
 
-/* return 1 if a pingrp is in range */
-#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PINGRP_COUNT))
-
-/* The pullup/pulldown state of a pin group */
-enum pmux_pull {
-	PMUX_PULL_NORMAL = 0,
-	PMUX_PULL_DOWN,
-	PMUX_PULL_UP,
-};
-/* return 1 if a pin_pupd_is in range */
-#define pmux_pin_pupd_isvalid(pupd) (((pupd) >= PMUX_PULL_NORMAL) && \
-				((pupd) <= PMUX_PULL_UP))
-
-/* Defines whether a pin group is tristated or in normal operation */
-enum pmux_tristate {
-	PMUX_TRI_NORMAL = 0,
-	PMUX_TRI_TRISTATE = 1,
-};
-/* return 1 if a pin_tristate_is in range */
-#define pmux_pin_tristate_isvalid(tristate) \
-	(((tristate) >= PMUX_TRI_NORMAL) && \
-	((tristate) <= PMUX_TRI_TRISTATE))
-
-enum pmux_pin_io {
-	PMUX_PIN_OUTPUT = 0,
-	PMUX_PIN_INPUT = 1,
-	PMUX_PIN_NONE,
-};
-/* return 1 if a pin_io_is in range */
-#define pmux_pin_io_isvalid(io) (((io) >= PMUX_PIN_OUTPUT) && \
-				((io) <= PMUX_PIN_INPUT))
-
-enum pmux_pin_lock {
-	PMUX_PIN_LOCK_DEFAULT = 0,
-	PMUX_PIN_LOCK_DISABLE,
-	PMUX_PIN_LOCK_ENABLE,
-};
-/* return 1 if a pin_lock is in range */
-#define pmux_pin_lock_isvalid(lock) (((lock) >= PMUX_PIN_LOCK_DEFAULT) && \
-				((lock) <= PMUX_PIN_LOCK_ENABLE))
-
-enum pmux_pin_od {
-	PMUX_PIN_OD_DEFAULT = 0,
-	PMUX_PIN_OD_DISABLE,
-	PMUX_PIN_OD_ENABLE,
-};
-/* return 1 if a pin_od is in range */
-#define pmux_pin_od_isvalid(od) (((od) >= PMUX_PIN_OD_DEFAULT) && \
-				((od) <= PMUX_PIN_OD_ENABLE))
-
-enum pmux_pin_ioreset {
-	PMUX_PIN_IO_RESET_DEFAULT = 0,
-	PMUX_PIN_IO_RESET_DISABLE,
-	PMUX_PIN_IO_RESET_ENABLE,
-};
-/* return 1 if a pin_ioreset_is in range */
-#define pmux_pin_ioreset_isvalid(ioreset) \
-				(((ioreset) >= PMUX_PIN_IO_RESET_DEFAULT) && \
-				((ioreset) <= PMUX_PIN_IO_RESET_ENABLE))
-
-enum pmux_pin_rcv_sel {
-	PMUX_PIN_RCV_SEL_DEFAULT = 0,
-	PMUX_PIN_RCV_SEL_NORMAL,
-	PMUX_PIN_RCV_SEL_HIGH,
-};
-/* return 1 if a pin_rcv_sel_is in range */
-#define pmux_pin_rcv_sel_isvalid(rcv_sel) \
-				(((rcv_sel) >= PMUX_PIN_RCV_SEL_DEFAULT) && \
-				((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH))
-
-#define PGRP_SLWF_NONE	-1
-#define PGRP_SLWF_MAX	3
-#define PGRP_SLWR_NONE	PGRP_SLWF_NONE
-#define PGRP_SLWR_MAX	PGRP_SLWF_MAX
-
-#define PGRP_DRVUP_NONE	-1
-#define PGRP_DRVUP_MAX	127
-#define PGRP_DRVDN_NONE	PGRP_DRVUP_NONE
-#define PGRP_DRVDN_MAX	PGRP_DRVUP_MAX
-
-#define PGRP_SCHMT_NONE	-1
-#define PGRP_HSM_NONE	PGRP_SCHMT_NONE
-
-/* return 1 if a padgrp is in range */
-#define pmux_padgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PDRIVE_PINGROUP_COUNT))
-
-/* return 1 if a slew-rate rising/falling edge value is in range */
-#define pmux_pad_slw_isvalid(slw) (((slw) == PGRP_SLWF_NONE) || \
-				(((slw) >= 0) && ((slw) <= PGRP_SLWF_MAX)))
-
-/* return 1 if a driver output pull-up/down strength code value is in range */
-#define pmux_pad_drv_isvalid(drv) (((drv) == PGRP_DRVUP_NONE) || \
-				(((drv) >= 0) && ((drv) <= PGRP_DRVUP_MAX)))
-
-/* return 1 if a low-power mode value is in range */
-#define pmux_pad_lpmd_isvalid(lpm) (((lpm) == PGRP_LPMD_NONE) || \
-				(((lpm) >= 0) && ((lpm) <= PGRP_LPMD_X)))
-
-/* Defines a pin group cfg's low-power mode select */
-enum pgrp_lpmd {
-	PGRP_LPMD_X8 = 0,
-	PGRP_LPMD_X4,
-	PGRP_LPMD_X2,
-	PGRP_LPMD_X,
-	PGRP_LPMD_NONE = -1,
-};
-
-/* Defines whether a pin group cfg's schmidt is enabled or not */
-enum pgrp_schmt {
-	PGRP_SCHMT_DISABLE = 0,
-	PGRP_SCHMT_ENABLE = 1,
-};
-
-/* Defines whether a pin group cfg's high-speed mode is enabled or not */
-enum pgrp_hsm {
-	PGRP_HSM_DISABLE = 0,
-	PGRP_HSM_ENABLE = 1,
-};
-
-/*
- * This defines the configuration for a pin group's pad control config
- */
-struct padctrl_config {
-	enum pdrive_pingrp padgrp;	/* pin group PDRIVE_PINGRP_x */
-	int slwf;			/* falling edge slew         */
-	int slwr;			/* rising edge slew          */
-	int drvup;			/* pull-up drive strength    */
-	int drvdn;			/* pull-down drive strength  */
-	enum pgrp_lpmd lpmd;		/* low-power mode selection  */
-	enum pgrp_schmt schmt;		/* schmidt enable            */
-	enum pgrp_hsm hsm;		/* high-speed mode enable    */
-};
-
-/* Tegra124 pin drive group and pin mux registers */
-#define PDRIVE_PINGROUP_OFFSET	(0x868 >> 2)
-#define PMUX_OFFSET	((0x3000 >> 2) - PDRIVE_PINGROUP_OFFSET - \
-				PDRIVE_PINGROUP_COUNT)
-struct pmux_tri_ctlr {
-	uint pmt_reserved0[9];		/* ABP_MISC_PP_ offsets 00-20 */
-	uint pmt_cfg_ctl;		/* _CONFIG_CTL_0, offset 24        */
-
-	uint pmt_reserved[528];		/* ABP_MISC_PP_ reserved offs 28-864 */
-
-	uint pmt_drive[PDRIVE_PINGROUP_COUNT];	/* pin drive grps offs 868 */
-	uint pmt_reserved5[PMUX_OFFSET];
-	uint pmt_ctl[PINGRP_COUNT];	/* mux/pupd/tri regs, offset 0x3000 */
-};
-
-/*
- * This defines the configuration for a pin, including the function assigned,
- * pull up/down settings and tristate settings. Having set up one of these
- * you can call pinmux_config_pingroup() to configure a pin in one step. Also
- * available is pinmux_config_table() to configure a list of pins.
- */
-struct pingroup_config {
-	enum pmux_pingrp pingroup;	/* pin group PINGRP_...             */
-	enum pmux_func func;		/* function to assign FUNC_...      */
-	enum pmux_pull pull;		/* pull up/down/normal PMUX_PULL_...*/
-	enum pmux_tristate tristate;	/* tristate or normal PMUX_TRI_...  */
-	enum pmux_pin_io io;		/* input or output PMUX_PIN_...  */
-	enum pmux_pin_lock lock;	/* lock enable/disable PMUX_PIN...  */
-	enum pmux_pin_od od;		/* open-drain or push-pull driver  */
-	enum pmux_pin_ioreset ioreset;	/* input/output reset PMUX_PIN...  */
-	enum pmux_pin_rcv_sel rcv_sel;	/* select between High and Normal  */
-					/* VIL/VIH receivers */
-};
-
-/* Set a pin group to tristate */
-void pinmux_tristate_enable(enum pmux_pingrp pin);
-
-/* Set a pin group to normal (non tristate) */
-void pinmux_tristate_disable(enum pmux_pingrp pin);
-
-/* Set the pull up/down feature for a pin group */
-void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd);
-
-/* Set the mux function for a pin group */
-void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func);
-
-/* Set the complete configuration for a pin group */
-void pinmux_config_pingroup(struct pingroup_config *config);
-
-/* Set a pin group to tristate or normal */
-void pinmux_set_tristate(enum pmux_pingrp pin, int enable);
-
-/* Set a pin group as input or output */
-void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io);
-
-/**
- * Configure a list of pin groups
- *
- * @param config	List of config items
- * @param len		Number of config items in list
- */
-void pinmux_config_table(struct pingroup_config *config, int len);
-
-/**
- * Set the GP pad configs
- *
- * @param config	List of config items
- * @param len		Number of config items in list
- */
-void padgrp_config_table(struct padctrl_config *config, int len);
-
-#endif	/* _TEGRA124_PINMUX_H_ */
+#endif /* _TEGRA124_PINMUX_H_ */
diff --git a/arch/arm/include/asm/arch-tegra20/pinmux.h b/arch/arm/include/asm/arch-tegra20/pinmux.h
index 1980201ce8cc..5517c0783da2 100644
--- a/arch/arm/include/asm/arch-tegra20/pinmux.h
+++ b/arch/arm/include/asm/arch-tegra20/pinmux.h
@@ -5,8 +5,8 @@ 
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-#ifndef _PINMUX_H_
-#define _PINMUX_H_
+#ifndef _TEGRA20_PINMUX_H_
+#define _TEGRA20_PINMUX_H_
 
 /*
  * Pin groups which we adjust. There are three basic attributes of each pin
@@ -236,83 +236,6 @@  enum pmux_func {
 	PMUX_FUNC_RSVD4 = 0x8003,
 };
 
-/* return 1 if a pmux_func is in range */
-#define pmux_func_isvalid(func) \
-	((((func) >= 0) && ((func) < PMUX_FUNC_COUNT)) ||\
-	 (((func) >= PMUX_FUNC_RSVD1) && ((func) <= PMUX_FUNC_RSVD4)))
+#include <asm/arch-tegra/pinmux.h>
 
-/* The pullup/pulldown state of a pin group */
-enum pmux_pull {
-	PMUX_PULL_NORMAL = 0,
-	PMUX_PULL_DOWN,
-	PMUX_PULL_UP,
-};
-
-/* Defines whether a pin group is tristated or in normal operation */
-enum pmux_tristate {
-	PMUX_TRI_NORMAL = 0,
-	PMUX_TRI_TRISTATE = 1,
-};
-
-enum {
-	PMUX_TRISTATE_REGS	= 4,
-	PMUX_MUX_REGS		= 7,
-	PMUX_PULL_REGS		= 5,
-};
-
-/* APB MISC Pin Mux and Tristate (APB_MISC_PP_) registers */
-struct pmux_tri_ctlr {
-	uint pmt_reserved0;		/* ABP_MISC_PP_ reserved offset 00 */
-	uint pmt_reserved1;		/* ABP_MISC_PP_ reserved offset 04 */
-	uint pmt_strap_opt_a;		/* _STRAPPING_OPT_A_0, offset 08   */
-	uint pmt_reserved2;		/* ABP_MISC_PP_ reserved offset 0C */
-	uint pmt_reserved3;		/* ABP_MISC_PP_ reserved offset 10 */
-	uint pmt_tri[PMUX_TRISTATE_REGS];/* _TRI_STATE_REG_A/B/C/D_0 14-20 */
-	uint pmt_cfg_ctl;		/* _CONFIG_CTL_0, offset 24        */
-
-	uint pmt_reserved[22];		/* ABP_MISC_PP_ reserved offs 28-7C */
-
-	uint pmt_ctl[PMUX_MUX_REGS];	/* _PIN_MUX_CTL_A-G_0, offset 80   */
-	uint pmt_reserved4;		/* ABP_MISC_PP_ reserved offset 9c */
-	uint pmt_pull[PMUX_PULL_REGS];	/* APB_MISC_PP_PULLUPDOWN_REG_A-E  */
-};
-
-/*
- * This defines the configuration for a pin, including the function assigned,
- * pull up/down settings and tristate settings. Having set up one of these
- * you can call pinmux_config_pingroup() to configure a pin in one step. Also
- * available is pinmux_config_table() to configure a list of pins.
- */
-struct pingroup_config {
-	enum pmux_pingrp pingroup;	/* pin group PINGRP_...             */
-	enum pmux_func func;		/* function to assign FUNC_...      */
-	enum pmux_pull pull;		/* pull up/down/normal PMUX_PULL_...*/
-	enum pmux_tristate tristate;	/* tristate or normal PMUX_TRI_...  */
-};
-
-/* Set a pin group to tristate */
-void pinmux_tristate_enable(enum pmux_pingrp pin);
-
-/* Set a pin group to normal (non tristate) */
-void pinmux_tristate_disable(enum pmux_pingrp pin);
-
-/* Set the pull up/down feature for a pin group */
-void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd);
-
-/* Set the mux function for a pin group */
-void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func);
-
-/* Set the complete configuration for a pin group */
-void pinmux_config_pingroup(const struct pingroup_config *config);
-
-void pinmux_set_tristate(enum pmux_pingrp pin, int enable);
-
-/**
- * Configuure a list of pin groups
- *
- * @param config	List of config items
- * @param len		Number of config items in list
- */
-void pinmux_config_table(const struct pingroup_config *config, int len);
-
-#endif	/* PINMUX_H */
+#endif /* _TEGRA20_PINMUX_H_ */
diff --git a/arch/arm/include/asm/arch-tegra30/pinmux.h b/arch/arm/include/asm/arch-tegra30/pinmux.h
index 1449f53b333e..e10df76342bb 100644
--- a/arch/arm/include/asm/arch-tegra30/pinmux.h
+++ b/arch/arm/include/asm/arch-tegra30/pinmux.h
@@ -439,7 +439,7 @@  enum pmux_func {
 	PMUX_FUNC_PWR_INT_N,
 	PMUX_FUNC_CLK_32K_IN,
 
-	PMUX_FUNC_MAX,
+	PMUX_FUNC_COUNT,
 
 	PMUX_FUNC_RSVD1 = 0x8000,
 	PMUX_FUNC_RSVD2 = 0x8001,
@@ -447,197 +447,8 @@  enum pmux_func {
 	PMUX_FUNC_RSVD4 = 0x8003,
 };
 
-/* return 1 if a pmux_func is in range */
-#define pmux_func_isvalid(func) ((((func) >= 0) && ((func) < PMUX_FUNC_MAX)) \
-	|| (((func) >= PMUX_FUNC_RSVD1) && ((func) <= PMUX_FUNC_RSVD4)))
+#define TEGRA_PMX_HAS_PIN_IO_BIT_ETC
+#define TEGRA_PMX_HAS_PADGRPS
+#include <asm/arch-tegra/pinmux.h>
 
-/* return 1 if a pingrp is in range */
-#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PINGRP_COUNT))
-
-/* The pullup/pulldown state of a pin group */
-enum pmux_pull {
-	PMUX_PULL_NORMAL = 0,
-	PMUX_PULL_DOWN,
-	PMUX_PULL_UP,
-};
-/* return 1 if a pin_pupd_is in range */
-#define pmux_pin_pupd_isvalid(pupd) (((pupd) >= PMUX_PULL_NORMAL) && \
-				((pupd) <= PMUX_PULL_UP))
-
-/* Defines whether a pin group is tristated or in normal operation */
-enum pmux_tristate {
-	PMUX_TRI_NORMAL = 0,
-	PMUX_TRI_TRISTATE = 1,
-};
-/* return 1 if a pin_tristate_is in range */
-#define pmux_pin_tristate_isvalid(tristate) (((tristate) >= PMUX_TRI_NORMAL) \
-				&& ((tristate) <= PMUX_TRI_TRISTATE))
-
-enum pmux_pin_io {
-	PMUX_PIN_OUTPUT = 0,
-	PMUX_PIN_INPUT = 1,
-};
-/* return 1 if a pin_io_is in range */
-#define pmux_pin_io_isvalid(io) (((io) >= PMUX_PIN_OUTPUT) && \
-				((io) <= PMUX_PIN_INPUT))
-
-enum pmux_pin_lock {
-	PMUX_PIN_LOCK_DEFAULT = 0,
-	PMUX_PIN_LOCK_DISABLE,
-	PMUX_PIN_LOCK_ENABLE,
-};
-/* return 1 if a pin_lock is in range */
-#define pmux_pin_lock_isvalid(lock) (((lock) >= PMUX_PIN_LOCK_DEFAULT) && \
-				((lock) <= PMUX_PIN_LOCK_ENABLE))
-
-enum pmux_pin_od {
-	PMUX_PIN_OD_DEFAULT = 0,
-	PMUX_PIN_OD_DISABLE,
-	PMUX_PIN_OD_ENABLE,
-};
-/* return 1 if a pin_od is in range */
-#define pmux_pin_od_isvalid(od) (((od) >= PMUX_PIN_OD_DEFAULT) && \
-				((od) <= PMUX_PIN_OD_ENABLE))
-
-enum pmux_pin_ioreset {
-	PMUX_PIN_IO_RESET_DEFAULT = 0,
-	PMUX_PIN_IO_RESET_DISABLE,
-	PMUX_PIN_IO_RESET_ENABLE,
-};
-/* return 1 if a pin_ioreset_is in range */
-#define pmux_pin_ioreset_isvalid(ioreset) \
-				(((ioreset) >= PMUX_PIN_IO_RESET_DEFAULT) && \
-				((ioreset) <= PMUX_PIN_IO_RESET_ENABLE))
-
-#define PGRP_SLWF_NONE	-1
-#define PGRP_SLWF_MAX	3
-#define	PGRP_SLWR_NONE	PGRP_SLWF_NONE
-#define PGRP_SLWR_MAX	PGRP_SLWF_MAX
-
-#define PGRP_DRVUP_NONE	-1
-#define PGRP_DRVUP_MAX	127
-#define	PGRP_DRVDN_NONE	PGRP_DRVUP_NONE
-#define PGRP_DRVDN_MAX	PGRP_DRVUP_MAX
-
-/* return 1 if a padgrp is in range */
-#define pmux_padgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PDRIVE_PINGROUP_COUNT))
-
-/* return 1 if a slew-rate rising/falling edge value is in range */
-#define pmux_pad_slw_isvalid(slw) (((slw) >= 0) && ((slw) <= PGRP_SLWF_MAX))
-
-/* return 1 if a driver output pull-up/down strength code value is in range */
-#define pmux_pad_drv_isvalid(drv) (((drv) >= 0) && ((drv) <= PGRP_DRVUP_MAX))
-
-/* return 1 if a low-power mode value is in range */
-#define pmux_pad_lpmd_isvalid(lpm) (((lpm) >= 0) && ((lpm) <= PGRP_LPMD_X))
-
-/* Defines a pin group cfg's low-power mode select */
-enum pgrp_lpmd {
-	PGRP_LPMD_X8 = 0,
-	PGRP_LPMD_X4,
-	PGRP_LPMD_X2,
-	PGRP_LPMD_X,
-	PGRP_LPMD_NONE = -1,
-};
-
-/* Defines whether a pin group cfg's schmidt is enabled or not */
-enum pgrp_schmt {
-	PGRP_SCHMT_DISABLE = 0,
-	PGRP_SCHMT_ENABLE = 1,
-};
-
-/* Defines whether a pin group cfg's high-speed mode is enabled or not */
-enum pgrp_hsm {
-	PGRP_HSM_DISABLE = 0,
-	PGRP_HSM_ENABLE = 1,
-};
-
-/*
- * This defines the configuration for a pin group's pad control config
- */
-struct padctrl_config {
-	enum pdrive_pingrp padgrp;	/* pin group PDRIVE_PINGRP_x */
-	int slwf;			/* falling edge slew         */
-	int slwr;			/* rising edge slew          */
-	int drvup;			/* pull-up drive strength    */
-	int drvdn;			/* pull-down drive strength  */
-	enum pgrp_lpmd lpmd;		/* low-power mode selection  */
-	enum pgrp_schmt schmt;		/* schmidt enable            */
-	enum pgrp_hsm hsm;		/* high-speed mode enable    */
-};
-
-/* t30 pin drive group and pin mux registers */
-#define PDRIVE_PINGROUP_OFFSET	(0x868 >> 2)
-#define PMUX_OFFSET	((0x3000 >> 2) - PDRIVE_PINGROUP_OFFSET - \
-				PDRIVE_PINGROUP_COUNT)
-struct pmux_tri_ctlr {
-	uint pmt_reserved0;		/* ABP_MISC_PP_ reserved offset 00 */
-	uint pmt_reserved1;		/* ABP_MISC_PP_ reserved offset 04 */
-	uint pmt_strap_opt_a;		/* _STRAPPING_OPT_A_0, offset 08   */
-	uint pmt_reserved2;		/* ABP_MISC_PP_ reserved offset 0C */
-	uint pmt_reserved3;		/* ABP_MISC_PP_ reserved offset 10 */
-	uint pmt_reserved4[4];		/* _TRI_STATE_REG_A/B/C/D in t20 */
-	uint pmt_cfg_ctl;		/* _CONFIG_CTL_0, offset 24        */
-
-	uint pmt_reserved[528];		/* ABP_MISC_PP_ reserved offs 28-864 */
-
-	uint pmt_drive[PDRIVE_PINGROUP_COUNT];	/* pin drive grps offs 868 */
-	uint pmt_reserved5[PMUX_OFFSET];
-	uint pmt_ctl[PINGRP_COUNT];	/* mux/pupd/tri regs, offset 0x3000 */
-};
-
-/*
- * This defines the configuration for a pin, including the function assigned,
- * pull up/down settings and tristate settings. Having set up one of these
- * you can call pinmux_config_pingroup() to configure a pin in one step. Also
- * available is pinmux_config_table() to configure a list of pins.
- */
-struct pingroup_config {
-	enum pmux_pingrp pingroup;	/* pin group PINGRP_...             */
-	enum pmux_func func;		/* function to assign FUNC_...      */
-	enum pmux_pull pull;		/* pull up/down/normal PMUX_PULL_...*/
-	enum pmux_tristate tristate;	/* tristate or normal PMUX_TRI_...  */
-	enum pmux_pin_io io;		/* input or output PMUX_PIN_...  */
-	enum pmux_pin_lock lock;	/* lock enable/disable PMUX_PIN...  */
-	enum pmux_pin_od od;		/* open-drain or push-pull driver  */
-	enum pmux_pin_ioreset ioreset;	/* input/output reset PMUX_PIN...  */
-};
-
-/* Set a pin group to tristate */
-void pinmux_tristate_enable(enum pmux_pingrp pin);
-
-/* Set a pin group to normal (non tristate) */
-void pinmux_tristate_disable(enum pmux_pingrp pin);
-
-/* Set the pull up/down feature for a pin group */
-void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd);
-
-/* Set the mux function for a pin group */
-void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func);
-
-/* Set the complete configuration for a pin group */
-void pinmux_config_pingroup(struct pingroup_config *config);
-
-/* Set a pin group to tristate or normal */
-void pinmux_set_tristate(enum pmux_pingrp pin, int enable);
-
-/* Set a pin group as input or output */
-void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io);
-
-/**
- * Configure a list of pin groups
- *
- * @param config	List of config items
- * @param len		Number of config items in list
- */
-void pinmux_config_table(struct pingroup_config *config, int len);
-
-/**
- * Set the GP pad configs
- *
- * @param config	List of config items
- * @param len		Number of config items in list
- */
-void padgrp_config_table(struct padctrl_config *config, int len);
-
-#endif	/* _TEGRA30_PINMUX_H_ */
+#endif /* _TEGRA30_PINMUX_H_ */