Patchwork [U-Boot,06/11] tegra20: switch over seaboard and ventana to use tablebased pinmux

login
register
mail settings
Submitter Lucas Stach
Date Jan. 24, 2013, 4:48 p.m.
Message ID <1359046100-19385-7-git-send-email-dev@lynxeye.de>
Download mbox | patch
Permalink /patch/215451/
State Deferred
Delegated to: Tom Warren
Headers show

Comments

Lucas Stach - Jan. 24, 2013, 4:48 p.m.
Init pinmux in one shot, in order to avoid any conflicts.

Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
 board/nvidia/seaboard/seaboard.c | 133 +++++++++++++++++++++++++++++++++------
 include/configs/seaboard.h       |   3 +
 include/configs/ventana.h        |   3 +
 3 files changed, 121 insertions(+), 18 deletions(-)
Simon Glass - Jan. 24, 2013, 5:54 p.m.
Hi Lucas,

On Fri, Jan 25, 2013 at 5:48 AM, Lucas Stach <dev@lynxeye.de> wrote:
> Init pinmux in one shot, in order to avoid any conflicts.
>
> Signed-off-by: Lucas Stach <dev@lynxeye.de>
> ---
>  board/nvidia/seaboard/seaboard.c | 133 +++++++++++++++++++++++++++++++++------
>  include/configs/seaboard.h       |   3 +
>  include/configs/ventana.h        |   3 +
>  3 files changed, 121 insertions(+), 18 deletions(-)

This seems like a lot of code and presumably quite a bit of
duplication between boards. What sort of conflicts does this avoid,
and is it the only way of avoiding them?

Also, how does this deal with drivers that want to support different
configurations, such as 4/8 bit MMC, UART flow control, etc.? How does
this fit with what the device tree pinmux specifies in the kernel, and
why would we not move to using that?

Regards,
Simon

>
> diff --git a/board/nvidia/seaboard/seaboard.c b/board/nvidia/seaboard/seaboard.c
> index 3e33da0..b5b4b31 100644
> --- a/board/nvidia/seaboard/seaboard.c
> +++ b/board/nvidia/seaboard/seaboard.c
> @@ -1,6 +1,8 @@
>  /*
>   *  (C) Copyright 2010,2011
>   *  NVIDIA Corporation <www.nvidia.com>
> + *  (C) Copyright 2013
> + *  Lucas Stach
>   *
>   * See file CREDITS for list of people who contributed to this
>   * project.
> @@ -25,7 +27,6 @@
>  #include <asm/io.h>
>  #include <asm/arch/tegra.h>
>  #include <asm/arch/clock.h>
> -#include <asm/arch/funcmux.h>
>  #include <asm/arch/gpio.h>
>  #include <asm/arch/pinmux.h>
>  #include <asm/arch-tegra/mmc.h>
> @@ -47,29 +48,12 @@ void gpio_early_init_uart(void)
>  #endif
>
>  #ifdef CONFIG_TEGRA_MMC
> -/*
> - * Routine: pin_mux_mmc
> - * Description: setup the pin muxes/tristate values for the SDMMC(s)
> - */
> -static void pin_mux_mmc(void)
> -{
> -       funcmux_select(PERIPH_ID_SDMMC4, FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT);
> -       funcmux_select(PERIPH_ID_SDMMC3, FUNCMUX_SDMMC3_SDB_4BIT);
> -
> -       /* For power GPIO PI6 */
> -       pinmux_tristate_disable(PINGRP_ATA);
> -       /* For CD GPIO PI5 */
> -       pinmux_tristate_disable(PINGRP_ATC);
> -}
>
>  /* this is a weak define that we are overriding */
>  int board_mmc_init(bd_t *bd)
>  {
>         debug("board_mmc_init called\n");
>
> -       /* Enable muxes, etc. for SDMMC controllers */
> -       pin_mux_mmc();
> -
>         debug("board_mmc_init: init eMMC\n");
>         /* init dev 0, eMMC chip, with 8-bit bus */
>         tegra_mmc_init(0, 8, -1, -1);
> @@ -87,3 +71,116 @@ void pin_mux_usb(void)
>         /* For USB's GPIO PD0. For now, since we have no pinmux in fdt */
>         pinmux_tristate_disable(PINGRP_SLXK);
>  }
> +static struct pingroup_config seaboard_pinmux[] = {
> +       PINMUX_ENTRY(ATA, IDE, NORMAL, NORMAL), /* GPIO PI6 */
> +       PINMUX_ENTRY(ATB, SDIO4, NORMAL, NORMAL), /* SDMMC4 */
> +       PINMUX_ENTRY(ATC, NAND, NORMAL, NORMAL), /* NAND, GPIO PI5 */
> +       PINMUX_ENTRY(ATD, GMI, NORMAL, NORMAL), /* NAND, GPIO PH1,PH3 */
> +       PINMUX_ENTRY(ATE, GMI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(CDEV1, PLLA_OUT, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(CDEV2, PLLP_OUT4, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(CRTP, CRT, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(CSUS, VI_SENSOR_CLK, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DAP1, DAP1, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DAP2, DAP2, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DAP3, DAP3, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DAP4, DAP4, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DDC, I2C2, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DTA, VI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DTB, VI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DTC, VI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DTD, VI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DTE, VI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(DTF, I2C3, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(GMA, SDIO4, NORMAL, NORMAL), /* SDMMC4 */
> +       PINMUX_ENTRY(GMB, GMI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(GMC, UARTD, NORMAL, NORMAL), /* UART D */
> +       PINMUX_ENTRY(GMD, SFLASH, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(GME, SDIO4, NORMAL, NORMAL), /* SDMMC4 */
> +       PINMUX_ENTRY(GPU, PWM, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(GPU7, RTCK, NORMAL, NORMAL), /* JTAG RTCK */
> +       PINMUX_ENTRY(GPV, PCIE, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(HDINT, HDMI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(I2CP, I2C, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(IRRX, UARTB, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(IRTX, UARTB, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(KBCA, KBC, UP, NORMAL), /* KBC */
> +       PINMUX_ENTRY(KBCB, KBC, UP, NORMAL), /* KBC */
> +       PINMUX_ENTRY(KBCC, KBC, UP, NORMAL), /* KBC */
> +       PINMUX_ENTRY(KBCD, KBC, UP, NORMAL), /* KBC */
> +       PINMUX_ENTRY(KBCE, KBC, UP, NORMAL), /* KBC */
> +       PINMUX_ENTRY(KBCF, KBC, UP, NORMAL), /* KBC */
> +       PINMUX_ENTRY(LCSN, RSVD4, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(LD0, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD1, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD2, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD3, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD4, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD5, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD6, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD7, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD8, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD9, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD10, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD11, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD12, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD13, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD14, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD15, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD16, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LD17, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LDC, RSVD4, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(LDI, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LHP0, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LHP1, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LHP2, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LHS, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LM0, RSVD4, NORMAL, NORMAL), /* GPIO PW0 */
> +       PINMUX_ENTRY(LM1, RSVD4, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(LPP, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LPW0, HDMI, NORMAL, NORMAL), /* GPIO PB2 */
> +       PINMUX_ENTRY(LPW1, RSVD4, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(LPW2, HDMI, NORMAL, NORMAL), /* GPIO PC6 */
> +       PINMUX_ENTRY(LSC0, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LSC1, HDMI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(LSCK, HDMI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(LSDA, HDMI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(LSDI, RSVD4, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(LSPI, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LVP0, RSVD4, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(LVP1, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(LVS, DISPA, NORMAL, NORMAL), /* LCD */
> +       PINMUX_ENTRY(OWC, RSVD2, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(PTA, RSVD4, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(RM, I2C, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SDB, SDIO3, NORMAL, NORMAL), /* SDMMC3 */
> +       PINMUX_ENTRY(SDC, SDIO3, NORMAL, NORMAL), /* SDMMC3 */
> +       PINMUX_ENTRY(SDD, SDIO3, NORMAL, NORMAL), /* SDMMC3 */
> +       PINMUX_ENTRY(SDIO1, SDIO1, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SLXA, PCIE, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SLXC, SPDIF, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SLXD, SPDIF, NORMAL, NORMAL), /* GPIO PD4 */
> +       PINMUX_ENTRY(SLXK, PCIE, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SPDI, RSVD2, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SPDO, RSVD2, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SPIA, GMI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SPIB, GMI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SPIC, GMI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SPID, SPI1, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SPIE, SPI1, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SPIF, SPI1, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SPIG, SPI2_ALT, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(SPIH, SPI2_ALT, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(UAA, ULPI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(UAB, ULPI, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(UAC, RSVD2, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(UAD, UARTB, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(UCA, UARTC, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(UCB, UARTC, NORMAL, TRISTATE),
> +       PINMUX_ENTRY(UDA, ULPI, NORMAL, TRISTATE),
> +};
> +
> +void pinmux_init(void)
> +{
> +       pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux));
> +}
> diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h
> index de0c777..4e3bf1c 100644
> --- a/include/configs/seaboard.h
> +++ b/include/configs/seaboard.h
> @@ -35,6 +35,9 @@
>
>  #include "tegra20-common.h"
>
> +/* Enable tablebased pinmux */
> +#define CONFIG_TEGRA_TABLEBASED_PINMUX
> +
>  /* Enable fdt support for Seaboard. Flash the image in u-boot-dtb.bin */
>  #define CONFIG_DEFAULT_DEVICE_TREE     tegra20-seaboard
>  #define CONFIG_OF_CONTROL
> diff --git a/include/configs/ventana.h b/include/configs/ventana.h
> index b55ebc9..9a023b0 100644
> --- a/include/configs/ventana.h
> +++ b/include/configs/ventana.h
> @@ -27,6 +27,9 @@
>  #include <asm/sizes.h>
>  #include "tegra20-common.h"
>
> +/* Enable tablebased pinmux */
> +#define CONFIG_TEGRA_TABLEBASED_PINMUX
> +
>  /* Enable fdt support for Ventana. Flash the image in u-boot-dtb.bin */
>  #define CONFIG_DEFAULT_DEVICE_TREE     tegra20-ventana
>  #define CONFIG_OF_CONTROL
> --
> 1.8.0.2
>
Lucas Stach - Jan. 24, 2013, 6:22 p.m.
Am Freitag, den 25.01.2013, 06:54 +1300 schrieb Simon Glass:
> Hi Lucas,
> 
> On Fri, Jan 25, 2013 at 5:48 AM, Lucas Stach <dev@lynxeye.de> wrote:
> > Init pinmux in one shot, in order to avoid any conflicts.
> >
> > Signed-off-by: Lucas Stach <dev@lynxeye.de>
> > ---
> >  board/nvidia/seaboard/seaboard.c | 133 +++++++++++++++++++++++++++++++++------
> >  include/configs/seaboard.h       |   3 +
> >  include/configs/ventana.h        |   3 +
> >  3 files changed, 121 insertions(+), 18 deletions(-)
> 
> This seems like a lot of code and presumably quite a bit of
> duplication between boards. What sort of conflicts does this avoid,
> and is it the only way of avoiding them?
> 
I don't see it as duplication, but as explicitly spelling out how the
pinmux configuration should be set up on a certain board.

Before this change we would leave some pads uninitialised in their
(random) reset configuration. For example on the Colibri this leads to
NAND not working as it's wired up to the KBC pads. If we only configure
those, ATC will remain in it's reset state and would be also configured
to the NAND function, which leads to fail. Having an explicit, known to
be conflict free configuration for all pads avoids all those unpleasant
surprises.

> Also, how does this deal with drivers that want to support different
> configurations, such as 4/8 bit MMC, UART flow control, etc.? How does
> this fit with what the device tree pinmux specifies in the kernel, and
> why would we not move to using that?

This is just the pinmux. You have to make sure to match the pinmux with
your driver configuration. This tablebased approach is the same thing as
what is done with Tegra30 in U-Boot.

It's not as runtime flexible as the pinmux used in the Linux kernel, but
also quite a fair bit simpler. I don't see any platform that would need
anything other than the default configuration in U-Boot, so we don't
need the muxing stuff provided by the pinmux framework in the kernel.

While running U-Boot we want to keep most of the pads in tristate and
just enable the ones used by U-Boot itself (boot devices, GPIOs, LCD
pins, etc.), so using the plain kernel pinmux config isn't going to
work. So I think the table based approach is a good compromise between
the need of having an comprehensively defined pinmux, simplicity and
effort needed to define the pinmux.

Regards,
Lucas
Simon Glass - Jan. 25, 2013, 9:20 p.m.
Hi Lucas,

On Fri, Jan 25, 2013 at 7:22 AM, Lucas Stach <dev@lynxeye.de> wrote:
> Am Freitag, den 25.01.2013, 06:54 +1300 schrieb Simon Glass:
>> Hi Lucas,
>>
>> On Fri, Jan 25, 2013 at 5:48 AM, Lucas Stach <dev@lynxeye.de> wrote:
>> > Init pinmux in one shot, in order to avoid any conflicts.
>> >
>> > Signed-off-by: Lucas Stach <dev@lynxeye.de>
>> > ---
>> >  board/nvidia/seaboard/seaboard.c | 133 +++++++++++++++++++++++++++++++++------
>> >  include/configs/seaboard.h       |   3 +
>> >  include/configs/ventana.h        |   3 +
>> >  3 files changed, 121 insertions(+), 18 deletions(-)
>>
>> This seems like a lot of code and presumably quite a bit of
>> duplication between boards. What sort of conflicts does this avoid,
>> and is it the only way of avoiding them?
>>
> I don't see it as duplication, but as explicitly spelling out how the
> pinmux configuration should be set up on a certain board.

I mean that the table is very similar for different boards, so looks
like duplicated coded (133 very similar lines for each board).

Also, this seems to break FDT use. At present it is possible (I think)
to boot the same U-Boot on any board, with the device tree specifying
the config. With your change that is no longer possible, I think?

Looking ahead to T114 I see a similar problem. The funcmux approach
was a compromise in that we could just select appropriate values for
each function - there was no agreement on how to put this in the FDT
though (my intention was that it would depend on the kernel binding,
but that is now defined, so what excuse do we have for not
implementing it in U-Boot?).

>
> Before this change we would leave some pads uninitialised in their
> (random) reset configuration. For example on the Colibri this leads to
> NAND not working as it's wired up to the KBC pads. If we only configure
> those, ATC will remain in it's reset state and would be also configured
> to the NAND function, which leads to fail. Having an explicit, known to
> be conflict free configuration for all pads avoids all those unpleasant
> surprises.

Well yes, but we seem to be right back to where we started, with the
FDT unable to describe a key feature of the boards (pinmux).

>
>> Also, how does this deal with drivers that want to support different
>> configurations, such as 4/8 bit MMC, UART flow control, etc.? How does
>> this fit with what the device tree pinmux specifies in the kernel, and
>> why would we not move to using that?
>
> This is just the pinmux. You have to make sure to match the pinmux with
> your driver configuration. This tablebased approach is the same thing as
> what is done with Tegra30 in U-Boot.
>
> It's not as runtime flexible as the pinmux used in the Linux kernel, but
> also quite a fair bit simpler. I don't see any platform that would need
> anything other than the default configuration in U-Boot, so we don't
> need the muxing stuff provided by the pinmux framework in the kernel.

Fair enough, simple is good, but I'm not sure it will do the job. If
we create different variants of a board, how exactly will we describe
the differences other than by creating a new config, separate U-Boot
build, etc.?

>
> While running U-Boot we want to keep most of the pads in tristate and
> just enable the ones used by U-Boot itself (boot devices, GPIOs, LCD
> pins, etc.), so using the plain kernel pinmux config isn't going to
> work. So I think the table based approach is a good compromise between
> the need of having an comprehensively defined pinmux, simplicity and
> effort needed to define the pinmux.

OK. Can you think of a way to implement this so that we have:

board/nvidia/common/tegra20_dt.c

and the resulting image can run on all T20 boards (given an appropriate DT)?

Regards,
Simon

>
> Regards,
> Lucas
>
>
Lucas Stach - Jan. 25, 2013, 9:38 p.m.
Hello Simon,

Am Samstag, den 26.01.2013, 10:20 +1300 schrieb Simon Glass:
> Hi Lucas,
> 
> On Fri, Jan 25, 2013 at 7:22 AM, Lucas Stach <dev@lynxeye.de> wrote:
> > Am Freitag, den 25.01.2013, 06:54 +1300 schrieb Simon Glass:
> >> Hi Lucas,
> >>
> >> On Fri, Jan 25, 2013 at 5:48 AM, Lucas Stach <dev@lynxeye.de> wrote:
> >> > Init pinmux in one shot, in order to avoid any conflicts.
> >> >
> >> > Signed-off-by: Lucas Stach <dev@lynxeye.de>
> >> > ---
> >> >  board/nvidia/seaboard/seaboard.c | 133 +++++++++++++++++++++++++++++++++------
> >> >  include/configs/seaboard.h       |   3 +
> >> >  include/configs/ventana.h        |   3 +
> >> >  3 files changed, 121 insertions(+), 18 deletions(-)
> >>
> >> This seems like a lot of code and presumably quite a bit of
> >> duplication between boards. What sort of conflicts does this avoid,
> >> and is it the only way of avoiding them?
> >>
> > I don't see it as duplication, but as explicitly spelling out how the
> > pinmux configuration should be set up on a certain board.
> 
> I mean that the table is very similar for different boards, so looks
> like duplicated coded (133 very similar lines for each board).
> 
> Also, this seems to break FDT use. At present it is possible (I think)
> to boot the same U-Boot on any board, with the device tree specifying
> the config. With your change that is no longer possible, I think?
> 
> Looking ahead to T114 I see a similar problem. The funcmux approach
> was a compromise in that we could just select appropriate values for
> each function - there was no agreement on how to put this in the FDT
> though (my intention was that it would depend on the kernel binding,
> but that is now defined, so what excuse do we have for not
> implementing it in U-Boot?).
> 
That Tegra30 doesn't do so either. ;) But I agree, that's no valid
excuse and we should resolve this before Tegra114 introduces more of
this stuff. See below. 
> >
> > Before this change we would leave some pads uninitialised in their
> > (random) reset configuration. For example on the Colibri this leads to
> > NAND not working as it's wired up to the KBC pads. If we only configure
> > those, ATC will remain in it's reset state and would be also configured
> > to the NAND function, which leads to fail. Having an explicit, known to
> > be conflict free configuration for all pads avoids all those unpleasant
> > surprises.
> 
> Well yes, but we seem to be right back to where we started, with the
> FDT unable to describe a key feature of the boards (pinmux).
> 
I see your point now. The obvious answer for now is: it's not regressing
functionality, as we were never able to boot the same U-Boot image by
just changing the DT.

But yes in the end we want to pack this information into the DT files.
But even then it would be nice if people would test this pachset, as I
imagine DT based pinmux is the same as tablebased pinmux, just in a
slightly different flavour. ;) So if people test the tablebased config
now, we can do the conversion to DT based with a lot more confidence.

I'll look into using the kernel pinmux binding minus the MUX stuff, as I
think there's no real reason to have this in U-Boot.

Regards,
Lucas
Simon Glass - Jan. 25, 2013, 9:49 p.m.
Hi Lucas,

On Sat, Jan 26, 2013 at 10:38 AM, Lucas Stach <dev@lynxeye.de> wrote:
> Hello Simon,
>
> Am Samstag, den 26.01.2013, 10:20 +1300 schrieb Simon Glass:
>> Hi Lucas,
>>
>> On Fri, Jan 25, 2013 at 7:22 AM, Lucas Stach <dev@lynxeye.de> wrote:
>> > Am Freitag, den 25.01.2013, 06:54 +1300 schrieb Simon Glass:
>> >> Hi Lucas,
>> >>
>> >> On Fri, Jan 25, 2013 at 5:48 AM, Lucas Stach <dev@lynxeye.de> wrote:
>> >> > Init pinmux in one shot, in order to avoid any conflicts.
>> >> >
>> >> > Signed-off-by: Lucas Stach <dev@lynxeye.de>
>> >> > ---
>> >> >  board/nvidia/seaboard/seaboard.c | 133 +++++++++++++++++++++++++++++++++------
>> >> >  include/configs/seaboard.h       |   3 +
>> >> >  include/configs/ventana.h        |   3 +
>> >> >  3 files changed, 121 insertions(+), 18 deletions(-)
>> >>
>> >> This seems like a lot of code and presumably quite a bit of
>> >> duplication between boards. What sort of conflicts does this avoid,
>> >> and is it the only way of avoiding them?
>> >>
>> > I don't see it as duplication, but as explicitly spelling out how the
>> > pinmux configuration should be set up on a certain board.
>>
>> I mean that the table is very similar for different boards, so looks
>> like duplicated coded (133 very similar lines for each board).
>>
>> Also, this seems to break FDT use. At present it is possible (I think)
>> to boot the same U-Boot on any board, with the device tree specifying
>> the config. With your change that is no longer possible, I think?
>>
>> Looking ahead to T114 I see a similar problem. The funcmux approach
>> was a compromise in that we could just select appropriate values for
>> each function - there was no agreement on how to put this in the FDT
>> though (my intention was that it would depend on the kernel binding,
>> but that is now defined, so what excuse do we have for not
>> implementing it in U-Boot?).
>>
> That Tegra30 doesn't do so either. ;) But I agree, that's no valid
> excuse and we should resolve this before Tegra114 introduces more of
> this stuff. See below.
>> >
>> > Before this change we would leave some pads uninitialised in their
>> > (random) reset configuration. For example on the Colibri this leads to
>> > NAND not working as it's wired up to the KBC pads. If we only configure
>> > those, ATC will remain in it's reset state and would be also configured
>> > to the NAND function, which leads to fail. Having an explicit, known to
>> > be conflict free configuration for all pads avoids all those unpleasant
>> > surprises.
>>
>> Well yes, but we seem to be right back to where we started, with the
>> FDT unable to describe a key feature of the boards (pinmux).
>>
> I see your point now. The obvious answer for now is: it's not regressing
> functionality, as we were never able to boot the same U-Boot image by
> just changing the DT.

Well, kind of. In fact we were able to boot at 3 different T20 boards
just by adding a 'funcmux' property to the device's node to select the
required mux option for that driver. This code is no use on T30/T114,
and was only a stop-gap anyway.

>
> But yes in the end we want to pack this information into the DT files.
> But even then it would be nice if people would test this pachset, as I
> imagine DT based pinmux is the same as tablebased pinmux, just in a
> slightly different flavour. ;) So if people test the tablebased config
> now, we can do the conversion to DT based with a lot more confidence.
>
> I'll look into using the kernel pinmux binding minus the MUX stuff, as I
> think there's no real reason to have this in U-Boot.

Well I would rather than we get that running than switch to
table-driven mux, assuming it is not too big a job?

I imagine perhaps naively that a function could be written which
parses the pinmux and sets it up in U-Boot - effectively using the FDT
as the pinmux table.

Regards,
Simon

>
> Regards,
> Lucas
>
Lucas Stach - Jan. 25, 2013, 9:57 p.m.
Am Samstag, den 26.01.2013, 10:49 +1300 schrieb Simon Glass:
[...]
> > But yes in the end we want to pack this information into the DT files.
> > But even then it would be nice if people would test this pachset, as I
> > imagine DT based pinmux is the same as tablebased pinmux, just in a
> > slightly different flavour. ;) So if people test the tablebased config
> > now, we can do the conversion to DT based with a lot more confidence.
> >
> > I'll look into using the kernel pinmux binding minus the MUX stuff, as I
> > think there's no real reason to have this in U-Boot.
> 
> Well I would rather than we get that running than switch to
> table-driven mux, assuming it is not too big a job?
> 
> I imagine perhaps naively that a function could be written which
> parses the pinmux and sets it up in U-Boot - effectively using the FDT
> as the pinmux table.

That's my plan. But still even if we keep the binding the same, the
actual pinmux config would differ between the kernel and U-Boot (a lot
more pads kept in tristate in U-Boot). So as the FDT would effectively
resemble the same tables I included in this patchset, some testing
coverage of that would smoothen the transition.

Regards,
Lucas
Stephen Warren - Jan. 25, 2013, 10:06 p.m.
On 01/24/2013 10:22 AM, Lucas Stach wrote:
> Am Freitag, den 25.01.2013, 06:54 +1300 schrieb Simon Glass:
>> Hi Lucas,
>>
>> On Fri, Jan 25, 2013 at 5:48 AM, Lucas Stach <dev@lynxeye.de> wrote:
>>> Init pinmux in one shot, in order to avoid any conflicts.
>>>
>>> Signed-off-by: Lucas Stach <dev@lynxeye.de>
>>> ---
>>>  board/nvidia/seaboard/seaboard.c | 133 +++++++++++++++++++++++++++++++++------
>>>  include/configs/seaboard.h       |   3 +
>>>  include/configs/ventana.h        |   3 +
>>>  3 files changed, 121 insertions(+), 18 deletions(-)
>>
>> This seems like a lot of code and presumably quite a bit of
>> duplication between boards. What sort of conflicts does this avoid,
>> and is it the only way of avoiding them?
>>
> I don't see it as duplication, but as explicitly spelling out how the
> pinmux configuration should be set up on a certain board.
> 
> Before this change we would leave some pads uninitialised in their
> (random) reset configuration.

Just being pedantic here, but I don't think the power-on-reset
configuration is random; it's well defined but perhaps just not
documented, and not always what is correct/best for any particular board
design.
Stephen Warren - Jan. 25, 2013, 10:09 p.m.
On 01/25/2013 01:57 PM, Lucas Stach wrote:
> Am Samstag, den 26.01.2013, 10:49 +1300 schrieb Simon Glass:
> [...]
>>> But yes in the end we want to pack this information into the DT files.
>>> But even then it would be nice if people would test this pachset, as I
>>> imagine DT based pinmux is the same as tablebased pinmux, just in a
>>> slightly different flavour. ;) So if people test the tablebased config
>>> now, we can do the conversion to DT based with a lot more confidence.
>>>
>>> I'll look into using the kernel pinmux binding minus the MUX stuff, as I
>>> think there's no real reason to have this in U-Boot.
>>
>> Well I would rather than we get that running than switch to
>> table-driven mux, assuming it is not too big a job?
>>
>> I imagine perhaps naively that a function could be written which
>> parses the pinmux and sets it up in U-Boot - effectively using the FDT
>> as the pinmux table.
> 
> That's my plan. But still even if we keep the binding the same, the
> actual pinmux config would differ between the kernel and U-Boot (a lot
> more pads kept in tristate in U-Boot). So as the FDT would effectively
> resemble the same tables I included in this patchset, some testing
> coverage of that would smoothen the transition.

Why wouldn't the pinmux tables in the FDT passed to U-Boot either be
identical to (a) the kernel, or (b) the small subset of the pinmux
options that U-Boot used to program via code? I don't see any reason for
U-Boot to program all the pingroups to TRISTATE etc.; if it's
programming those pingroups at all, it may as well just program the
correct final value.
Stephen Warren - Jan. 25, 2013, 10:10 p.m.
On 01/25/2013 01:49 PM, Simon Glass wrote:
> Hi Lucas,
> 
> On Sat, Jan 26, 2013 at 10:38 AM, Lucas Stach <dev@lynxeye.de> wrote:
>> Hello Simon,
>>
>> Am Samstag, den 26.01.2013, 10:20 +1300 schrieb Simon Glass:
>>> Hi Lucas,
>>>
>>> On Fri, Jan 25, 2013 at 7:22 AM, Lucas Stach <dev@lynxeye.de> wrote:
>>>> Am Freitag, den 25.01.2013, 06:54 +1300 schrieb Simon Glass:
>>>>> Hi Lucas,
>>>>>
>>>>> On Fri, Jan 25, 2013 at 5:48 AM, Lucas Stach <dev@lynxeye.de> wrote:
>>>>>> Init pinmux in one shot, in order to avoid any conflicts.
>>>>>>
>>>>>> Signed-off-by: Lucas Stach <dev@lynxeye.de>
>>>>>> ---
>>>>>>  board/nvidia/seaboard/seaboard.c | 133 +++++++++++++++++++++++++++++++++------
>>>>>>  include/configs/seaboard.h       |   3 +
>>>>>>  include/configs/ventana.h        |   3 +
>>>>>>  3 files changed, 121 insertions(+), 18 deletions(-)
>>>>>
>>>>> This seems like a lot of code and presumably quite a bit of
>>>>> duplication between boards. What sort of conflicts does this avoid,
>>>>> and is it the only way of avoiding them?
>>>>>
>>>> I don't see it as duplication, but as explicitly spelling out how the
>>>> pinmux configuration should be set up on a certain board.
>>>
>>> I mean that the table is very similar for different boards, so looks
>>> like duplicated coded (133 very similar lines for each board).
>>>
>>> Also, this seems to break FDT use. At present it is possible (I think)
>>> to boot the same U-Boot on any board, with the device tree specifying
>>> the config. With your change that is no longer possible, I think?
>>>
>>> Looking ahead to T114 I see a similar problem. The funcmux approach
>>> was a compromise in that we could just select appropriate values for
>>> each function - there was no agreement on how to put this in the FDT
>>> though (my intention was that it would depend on the kernel binding,
>>> but that is now defined, so what excuse do we have for not
>>> implementing it in U-Boot?).
>>>
>> That Tegra30 doesn't do so either. ;) But I agree, that's no valid
>> excuse and we should resolve this before Tegra114 introduces more of
>> this stuff. See below.
>>>>
>>>> Before this change we would leave some pads uninitialised in their
>>>> (random) reset configuration. For example on the Colibri this leads to
>>>> NAND not working as it's wired up to the KBC pads. If we only configure
>>>> those, ATC will remain in it's reset state and would be also configured
>>>> to the NAND function, which leads to fail. Having an explicit, known to
>>>> be conflict free configuration for all pads avoids all those unpleasant
>>>> surprises.
>>>
>>> Well yes, but we seem to be right back to where we started, with the
>>> FDT unable to describe a key feature of the boards (pinmux).
>>>
>> I see your point now. The obvious answer for now is: it's not regressing
>> functionality, as we were never able to boot the same U-Boot image by
>> just changing the DT.
> 
> Well, kind of. In fact we were able to boot at 3 different T20 boards
> just by adding a 'funcmux' property to the device's node to select the
> required mux option for that driver. This code is no use on T30/T114,
> and was only a stop-gap anyway.

??? I don't believe U-Boot supports any "funcmux" property in the device
tree. Are you referring to some downstream U-Boot? Such a branch
wouldn't be relevant to a patch for upstream U-Boot.
Simon Glass - Jan. 27, 2013, 4:36 p.m.
Hi Stephen,

On Sat, Jan 26, 2013 at 11:10 AM, Stephen Warren <swarren@nvidia.com> wrote:
> On 01/25/2013 01:49 PM, Simon Glass wrote:
>> Hi Lucas,
>>
>> On Sat, Jan 26, 2013 at 10:38 AM, Lucas Stach <dev@lynxeye.de> wrote:
>>> Hello Simon,
>>>
>>> Am Samstag, den 26.01.2013, 10:20 +1300 schrieb Simon Glass:
>>>> Hi Lucas,
>>>>
>>>> On Fri, Jan 25, 2013 at 7:22 AM, Lucas Stach <dev@lynxeye.de> wrote:
>>>>> Am Freitag, den 25.01.2013, 06:54 +1300 schrieb Simon Glass:
>>>>>> Hi Lucas,
>>>>>>
>>>>>> On Fri, Jan 25, 2013 at 5:48 AM, Lucas Stach <dev@lynxeye.de> wrote:
>>>>>>> Init pinmux in one shot, in order to avoid any conflicts.
>>>>>>>
>>>>>>> Signed-off-by: Lucas Stach <dev@lynxeye.de>
>>>>>>> ---
>>>>>>>  board/nvidia/seaboard/seaboard.c | 133 +++++++++++++++++++++++++++++++++------
>>>>>>>  include/configs/seaboard.h       |   3 +
>>>>>>>  include/configs/ventana.h        |   3 +
>>>>>>>  3 files changed, 121 insertions(+), 18 deletions(-)
>>>>>>
>>>>>> This seems like a lot of code and presumably quite a bit of
>>>>>> duplication between boards. What sort of conflicts does this avoid,
>>>>>> and is it the only way of avoiding them?
>>>>>>
>>>>> I don't see it as duplication, but as explicitly spelling out how the
>>>>> pinmux configuration should be set up on a certain board.
>>>>
>>>> I mean that the table is very similar for different boards, so looks
>>>> like duplicated coded (133 very similar lines for each board).
>>>>
>>>> Also, this seems to break FDT use. At present it is possible (I think)
>>>> to boot the same U-Boot on any board, with the device tree specifying
>>>> the config. With your change that is no longer possible, I think?
>>>>
>>>> Looking ahead to T114 I see a similar problem. The funcmux approach
>>>> was a compromise in that we could just select appropriate values for
>>>> each function - there was no agreement on how to put this in the FDT
>>>> though (my intention was that it would depend on the kernel binding,
>>>> but that is now defined, so what excuse do we have for not
>>>> implementing it in U-Boot?).
>>>>
>>> That Tegra30 doesn't do so either. ;) But I agree, that's no valid
>>> excuse and we should resolve this before Tegra114 introduces more of
>>> this stuff. See below.
>>>>>
>>>>> Before this change we would leave some pads uninitialised in their
>>>>> (random) reset configuration. For example on the Colibri this leads to
>>>>> NAND not working as it's wired up to the KBC pads. If we only configure
>>>>> those, ATC will remain in it's reset state and would be also configured
>>>>> to the NAND function, which leads to fail. Having an explicit, known to
>>>>> be conflict free configuration for all pads avoids all those unpleasant
>>>>> surprises.
>>>>
>>>> Well yes, but we seem to be right back to where we started, with the
>>>> FDT unable to describe a key feature of the boards (pinmux).
>>>>
>>> I see your point now. The obvious answer for now is: it's not regressing
>>> functionality, as we were never able to boot the same U-Boot image by
>>> just changing the DT.
>>
>> Well, kind of. In fact we were able to boot at 3 different T20 boards
>> just by adding a 'funcmux' property to the device's node to select the
>> required mux option for that driver. This code is no use on T30/T114,
>> and was only a stop-gap anyway.
>
> ??? I don't believe U-Boot supports any "funcmux" property in the device
> tree. Are you referring to some downstream U-Boot? Such a branch
> wouldn't be relevant to a patch for upstream U-Boot.
>

Yes, downstream. In fact from memory only the UARTs and one i2c port
actually cared on T20 - the rest just used default funcmux.  But we
did agree at the time to omit this 'funcmux' FDT binding from mainline
since there was an expectation that the kernel would soon have FDT
pinmux and we would use that in U-Boot. Now that it is available I
think we should use the kernel's FDT binding instead of static
table-based pinmux.

Regards,
Simon

Patch

diff --git a/board/nvidia/seaboard/seaboard.c b/board/nvidia/seaboard/seaboard.c
index 3e33da0..b5b4b31 100644
--- a/board/nvidia/seaboard/seaboard.c
+++ b/board/nvidia/seaboard/seaboard.c
@@ -1,6 +1,8 @@ 
 /*
  *  (C) Copyright 2010,2011
  *  NVIDIA Corporation <www.nvidia.com>
+ *  (C) Copyright 2013
+ *  Lucas Stach
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -25,7 +27,6 @@ 
 #include <asm/io.h>
 #include <asm/arch/tegra.h>
 #include <asm/arch/clock.h>
-#include <asm/arch/funcmux.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch-tegra/mmc.h>
@@ -47,29 +48,12 @@  void gpio_early_init_uart(void)
 #endif
 
 #ifdef CONFIG_TEGRA_MMC
-/*
- * Routine: pin_mux_mmc
- * Description: setup the pin muxes/tristate values for the SDMMC(s)
- */
-static void pin_mux_mmc(void)
-{
-	funcmux_select(PERIPH_ID_SDMMC4, FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT);
-	funcmux_select(PERIPH_ID_SDMMC3, FUNCMUX_SDMMC3_SDB_4BIT);
-
-	/* For power GPIO PI6 */
-	pinmux_tristate_disable(PINGRP_ATA);
-	/* For CD GPIO PI5 */
-	pinmux_tristate_disable(PINGRP_ATC);
-}
 
 /* this is a weak define that we are overriding */
 int board_mmc_init(bd_t *bd)
 {
 	debug("board_mmc_init called\n");
 
-	/* Enable muxes, etc. for SDMMC controllers */
-	pin_mux_mmc();
-
 	debug("board_mmc_init: init eMMC\n");
 	/* init dev 0, eMMC chip, with 8-bit bus */
 	tegra_mmc_init(0, 8, -1, -1);
@@ -87,3 +71,116 @@  void pin_mux_usb(void)
 	/* For USB's GPIO PD0. For now, since we have no pinmux in fdt */
 	pinmux_tristate_disable(PINGRP_SLXK);
 }
+static struct pingroup_config seaboard_pinmux[] = {
+	PINMUX_ENTRY(ATA, IDE, NORMAL, NORMAL), /* GPIO PI6 */
+	PINMUX_ENTRY(ATB, SDIO4, NORMAL, NORMAL), /* SDMMC4 */
+	PINMUX_ENTRY(ATC, NAND, NORMAL, NORMAL), /* NAND, GPIO PI5 */
+	PINMUX_ENTRY(ATD, GMI, NORMAL, NORMAL), /* NAND, GPIO PH1,PH3 */
+	PINMUX_ENTRY(ATE, GMI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(CDEV1, PLLA_OUT, NORMAL, TRISTATE),
+	PINMUX_ENTRY(CDEV2, PLLP_OUT4, NORMAL, TRISTATE),
+	PINMUX_ENTRY(CRTP, CRT, NORMAL, TRISTATE),
+	PINMUX_ENTRY(CSUS, VI_SENSOR_CLK, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DAP1, DAP1, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DAP2, DAP2, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DAP3, DAP3, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DAP4, DAP4, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DDC, I2C2, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DTA, VI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DTB, VI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DTC, VI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DTD, VI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DTE, VI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(DTF, I2C3, NORMAL, TRISTATE),
+	PINMUX_ENTRY(GMA, SDIO4, NORMAL, NORMAL), /* SDMMC4 */
+	PINMUX_ENTRY(GMB, GMI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(GMC, UARTD, NORMAL, NORMAL), /* UART D */
+	PINMUX_ENTRY(GMD, SFLASH, NORMAL, TRISTATE),
+	PINMUX_ENTRY(GME, SDIO4, NORMAL, NORMAL), /* SDMMC4 */
+	PINMUX_ENTRY(GPU, PWM, NORMAL, TRISTATE),
+	PINMUX_ENTRY(GPU7, RTCK, NORMAL, NORMAL), /* JTAG RTCK */
+	PINMUX_ENTRY(GPV, PCIE, NORMAL, TRISTATE),
+	PINMUX_ENTRY(HDINT, HDMI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(I2CP, I2C, NORMAL, TRISTATE),
+	PINMUX_ENTRY(IRRX, UARTB, NORMAL, TRISTATE),
+	PINMUX_ENTRY(IRTX, UARTB, NORMAL, TRISTATE),
+	PINMUX_ENTRY(KBCA, KBC, UP, NORMAL), /* KBC */
+	PINMUX_ENTRY(KBCB, KBC, UP, NORMAL), /* KBC */
+	PINMUX_ENTRY(KBCC, KBC, UP, NORMAL), /* KBC */
+	PINMUX_ENTRY(KBCD, KBC, UP, NORMAL), /* KBC */
+	PINMUX_ENTRY(KBCE, KBC, UP, NORMAL), /* KBC */
+	PINMUX_ENTRY(KBCF, KBC, UP, NORMAL), /* KBC */
+	PINMUX_ENTRY(LCSN, RSVD4, NORMAL, TRISTATE),
+	PINMUX_ENTRY(LD0, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD1, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD2, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD3, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD4, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD5, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD6, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD7, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD8, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD9, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD10, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD11, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD12, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD13, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD14, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD15, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD16, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LD17, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LDC, RSVD4, NORMAL, TRISTATE),
+	PINMUX_ENTRY(LDI, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LHP0, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LHP1, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LHP2, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LHS, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LM0, RSVD4, NORMAL, NORMAL), /* GPIO PW0 */
+	PINMUX_ENTRY(LM1, RSVD4, NORMAL, TRISTATE),
+	PINMUX_ENTRY(LPP, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LPW0, HDMI, NORMAL, NORMAL), /* GPIO PB2 */
+	PINMUX_ENTRY(LPW1, RSVD4, NORMAL, TRISTATE),
+	PINMUX_ENTRY(LPW2, HDMI, NORMAL, NORMAL), /* GPIO PC6 */
+	PINMUX_ENTRY(LSC0, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LSC1, HDMI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(LSCK, HDMI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(LSDA, HDMI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(LSDI, RSVD4, NORMAL, TRISTATE),
+	PINMUX_ENTRY(LSPI, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LVP0, RSVD4, NORMAL, TRISTATE),
+	PINMUX_ENTRY(LVP1, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(LVS, DISPA, NORMAL, NORMAL), /* LCD */
+	PINMUX_ENTRY(OWC, RSVD2, NORMAL, TRISTATE),
+	PINMUX_ENTRY(PTA, RSVD4, NORMAL, TRISTATE),
+	PINMUX_ENTRY(RM, I2C, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SDB, SDIO3, NORMAL, NORMAL), /* SDMMC3 */
+	PINMUX_ENTRY(SDC, SDIO3, NORMAL, NORMAL), /* SDMMC3 */
+	PINMUX_ENTRY(SDD, SDIO3, NORMAL, NORMAL), /* SDMMC3 */
+	PINMUX_ENTRY(SDIO1, SDIO1, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SLXA, PCIE, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SLXC, SPDIF, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SLXD, SPDIF, NORMAL, NORMAL), /* GPIO PD4 */
+	PINMUX_ENTRY(SLXK, PCIE, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SPDI, RSVD2, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SPDO, RSVD2, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SPIA, GMI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SPIB, GMI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SPIC, GMI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SPID, SPI1, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SPIE, SPI1, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SPIF, SPI1, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SPIG, SPI2_ALT, NORMAL, TRISTATE),
+	PINMUX_ENTRY(SPIH, SPI2_ALT, NORMAL, TRISTATE),
+	PINMUX_ENTRY(UAA, ULPI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(UAB, ULPI, NORMAL, TRISTATE),
+	PINMUX_ENTRY(UAC, RSVD2, NORMAL, TRISTATE),
+	PINMUX_ENTRY(UAD, UARTB, NORMAL, TRISTATE),
+	PINMUX_ENTRY(UCA, UARTC, NORMAL, TRISTATE),
+	PINMUX_ENTRY(UCB, UARTC, NORMAL, TRISTATE),
+	PINMUX_ENTRY(UDA, ULPI, NORMAL, TRISTATE),
+};
+
+void pinmux_init(void)
+{
+	pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux));
+}
diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h
index de0c777..4e3bf1c 100644
--- a/include/configs/seaboard.h
+++ b/include/configs/seaboard.h
@@ -35,6 +35,9 @@ 
 
 #include "tegra20-common.h"
 
+/* Enable tablebased pinmux */
+#define CONFIG_TEGRA_TABLEBASED_PINMUX
+
 /* Enable fdt support for Seaboard. Flash the image in u-boot-dtb.bin */
 #define CONFIG_DEFAULT_DEVICE_TREE	tegra20-seaboard
 #define CONFIG_OF_CONTROL
diff --git a/include/configs/ventana.h b/include/configs/ventana.h
index b55ebc9..9a023b0 100644
--- a/include/configs/ventana.h
+++ b/include/configs/ventana.h
@@ -27,6 +27,9 @@ 
 #include <asm/sizes.h>
 #include "tegra20-common.h"
 
+/* Enable tablebased pinmux */
+#define CONFIG_TEGRA_TABLEBASED_PINMUX
+
 /* Enable fdt support for Ventana. Flash the image in u-boot-dtb.bin */
 #define CONFIG_DEFAULT_DEVICE_TREE	tegra20-ventana
 #define CONFIG_OF_CONTROL