tegra2: Add more pinmux functions
authorSimon Glass <sjg@chromium.org>
Wed, 21 Sep 2011 12:40:06 +0000 (12:40 +0000)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Thu, 27 Oct 2011 19:56:29 +0000 (21:56 +0200)
This adds support for changing pinmux functions of pin groups. This is done
by defining a PMUX_FUNC_... enum which can be used to select the function for
each group using pinmux_set_func(). It is also possible to enable
pullup/pulldown, and the existing tristate functionality is retained.

Also provided is a means of configuring a list of pingroups by providing a
configuration table to pinmux_config_table().

Signed-off-by: Simon Glass <sjg@chromium.org>
Tested-by: Tom Warren <twarren@nvidia.com>
arch/arm/cpu/armv7/tegra2/pinmux.c
arch/arm/include/asm/arch-tegra2/pinmux.h
board/nvidia/common/board.c

index 01a3d84..b053f90 100644 (file)
 #include <common.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
+ * pullup/pulldown registers.
+ */
+enum pmux_ctlid {
+       /* 0: APB_MISC_PP_PIN_MUX_CTL_A_0 */
+       MUXCTL_UAA,
+       MUXCTL_UAB,
+       MUXCTL_UAC,
+       MUXCTL_UAD,
+       MUXCTL_UDA,
+       MUXCTL_RESERVED5,
+       MUXCTL_ATE,
+       MUXCTL_RM,
+
+       MUXCTL_ATB,
+       MUXCTL_RESERVED9,
+       MUXCTL_ATD,
+       MUXCTL_ATC,
+       MUXCTL_ATA,
+       MUXCTL_KBCF,
+       MUXCTL_KBCE,
+       MUXCTL_SDMMC1,
+
+       /* 16: APB_MISC_PP_PIN_MUX_CTL_B_0 */
+       MUXCTL_GMA,
+       MUXCTL_GMC,
+       MUXCTL_HDINT,
+       MUXCTL_SLXA,
+       MUXCTL_OWC,
+       MUXCTL_SLXC,
+       MUXCTL_SLXD,
+       MUXCTL_SLXK,
+
+       MUXCTL_UCA,
+       MUXCTL_UCB,
+       MUXCTL_DTA,
+       MUXCTL_DTB,
+       MUXCTL_RESERVED28,
+       MUXCTL_DTC,
+       MUXCTL_DTD,
+       MUXCTL_DTE,
+
+       /* 32: APB_MISC_PP_PIN_MUX_CTL_C_0 */
+       MUXCTL_DDC,
+       MUXCTL_CDEV1,
+       MUXCTL_CDEV2,
+       MUXCTL_CSUS,
+       MUXCTL_I2CP,
+       MUXCTL_KBCA,
+       MUXCTL_KBCB,
+       MUXCTL_KBCC,
+
+       MUXCTL_IRTX,
+       MUXCTL_IRRX,
+       MUXCTL_DAP1,
+       MUXCTL_DAP2,
+       MUXCTL_DAP3,
+       MUXCTL_DAP4,
+       MUXCTL_GMB,
+       MUXCTL_GMD,
+
+       /* 48: APB_MISC_PP_PIN_MUX_CTL_D_0 */
+       MUXCTL_GME,
+       MUXCTL_GPV,
+       MUXCTL_GPU,
+       MUXCTL_SPDO,
+       MUXCTL_SPDI,
+       MUXCTL_SDB,
+       MUXCTL_SDC,
+       MUXCTL_SDD,
+
+       MUXCTL_SPIH,
+       MUXCTL_SPIG,
+       MUXCTL_SPIF,
+       MUXCTL_SPIE,
+       MUXCTL_SPID,
+       MUXCTL_SPIC,
+       MUXCTL_SPIB,
+       MUXCTL_SPIA,
+
+       /* 64: APB_MISC_PP_PIN_MUX_CTL_E_0 */
+       MUXCTL_LPW0,
+       MUXCTL_LPW1,
+       MUXCTL_LPW2,
+       MUXCTL_LSDI,
+       MUXCTL_LSDA,
+       MUXCTL_LSPI,
+       MUXCTL_LCSN,
+       MUXCTL_LDC,
+
+       MUXCTL_LSCK,
+       MUXCTL_LSC0,
+       MUXCTL_LSC1,
+       MUXCTL_LHS,
+       MUXCTL_LVS,
+       MUXCTL_LM0,
+       MUXCTL_LM1,
+       MUXCTL_LVP0,
+
+       /* 80: APB_MISC_PP_PIN_MUX_CTL_F_0 */
+       MUXCTL_LD0,
+       MUXCTL_LD1,
+       MUXCTL_LD2,
+       MUXCTL_LD3,
+       MUXCTL_LD4,
+       MUXCTL_LD5,
+       MUXCTL_LD6,
+       MUXCTL_LD7,
+
+       MUXCTL_LD8,
+       MUXCTL_LD9,
+       MUXCTL_LD10,
+       MUXCTL_LD11,
+       MUXCTL_LD12,
+       MUXCTL_LD13,
+       MUXCTL_LD14,
+       MUXCTL_LD15,
+
+       /* 96: APB_MISC_PP_PIN_MUX_CTL_G_0 */
+       MUXCTL_LD16,
+       MUXCTL_LD17,
+       MUXCTL_LHP1,
+       MUXCTL_LHP2,
+       MUXCTL_LVP1,
+       MUXCTL_LHP0,
+       MUXCTL_RESERVED102,
+       MUXCTL_LPP,
+
+       MUXCTL_LDI,
+       MUXCTL_PMC,
+       MUXCTL_CRTP,
+       MUXCTL_PTA,
+       MUXCTL_RESERVED108,
+       MUXCTL_KBCD,
+       MUXCTL_GPU7,
+       MUXCTL_DTF,
+
+       MUXCTL_NONE = -1,
+};
+
+/*
+ * And this defines the order of the pullup/pulldown controls which are again
+ * in a different order
+ */
+enum pmux_pullid {
+       /* 0: APB_MISC_PP_PULLUPDOWN_REG_A_0 */
+       PUCTL_ATA,
+       PUCTL_ATB,
+       PUCTL_ATC,
+       PUCTL_ATD,
+       PUCTL_ATE,
+       PUCTL_DAP1,
+       PUCTL_DAP2,
+       PUCTL_DAP3,
+
+       PUCTL_DAP4,
+       PUCTL_DTA,
+       PUCTL_DTB,
+       PUCTL_DTC,
+       PUCTL_DTD,
+       PUCTL_DTE,
+       PUCTL_DTF,
+       PUCTL_GPV,
+
+       /* 16: APB_MISC_PP_PULLUPDOWN_REG_B_0 */
+       PUCTL_RM,
+       PUCTL_I2CP,
+       PUCTL_PTA,
+       PUCTL_GPU7,
+       PUCTL_KBCA,
+       PUCTL_KBCB,
+       PUCTL_KBCC,
+       PUCTL_KBCD,
+
+       PUCTL_SPDI,
+       PUCTL_SPDO,
+       PUCTL_GPSLXAU,
+       PUCTL_CRTP,
+       PUCTL_SLXC,
+       PUCTL_SLXD,
+       PUCTL_SLXK,
+
+       /* 32: APB_MISC_PP_PULLUPDOWN_REG_C_0 */
+       PUCTL_CDEV1,
+       PUCTL_CDEV2,
+       PUCTL_SPIA,
+       PUCTL_SPIB,
+       PUCTL_SPIC,
+       PUCTL_SPID,
+       PUCTL_SPIE,
+       PUCTL_SPIF,
+
+       PUCTL_SPIG,
+       PUCTL_SPIH,
+       PUCTL_IRTX,
+       PUCTL_IRRX,
+       PUCTL_GME,
+       PUCTL_RESERVED45,
+       PUCTL_XM2D,
+       PUCTL_XM2C,
+
+       /* 48: APB_MISC_PP_PULLUPDOWN_REG_D_0 */
+       PUCTL_UAA,
+       PUCTL_UAB,
+       PUCTL_UAC,
+       PUCTL_UAD,
+       PUCTL_UCA,
+       PUCTL_UCB,
+       PUCTL_LD17,
+       PUCTL_LD19_18,
+
+       PUCTL_LD21_20,
+       PUCTL_LD23_22,
+       PUCTL_LS,
+       PUCTL_LC,
+       PUCTL_CSUS,
+       PUCTL_DDRC,
+       PUCTL_SDC,
+       PUCTL_SDD,
+
+       /* 64: APB_MISC_PP_PULLUPDOWN_REG_E_0 */
+       PUCTL_KBCF,
+       PUCTL_KBCE,
+       PUCTL_PMCA,
+       PUCTL_PMCB,
+       PUCTL_PMCC,
+       PUCTL_PMCD,
+       PUCTL_PMCE,
+       PUCTL_CK32,
+
+       PUCTL_UDA,
+       PUCTL_SDMMC1,
+       PUCTL_GMA,
+       PUCTL_GMB,
+       PUCTL_GMC,
+       PUCTL_GMD,
+       PUCTL_DDC,
+       PUCTL_OWC,
+
+       PUCTL_NONE = -1
+};
+
+struct tegra_pingroup_desc {
+       const char *name;
+       enum pmux_func funcs[4];
+       enum pmux_func func_safe;
+       enum pmux_vddio vddio;
+       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)                \
+       {                                               \
+               .vddio = PMUX_VDDIO_ ## vdd,            \
+               .funcs = {                              \
+                       PMUX_FUNC_ ## f0,                       \
+                       PMUX_FUNC_ ## f1,                       \
+                       PMUX_FUNC_ ## f2,                       \
+                       PMUX_FUNC_ ## f3,                       \
+               },                                      \
+               .func_safe = PMUX_FUNC_ ## f_safe,              \
+               .ctl_id = mux,                          \
+               .pull_id = pupd                         \
+       }
+
+/* A normal pin group where the mux name and pull-up name match */
+#define PIN(pg_name, vdd, f0, f1, f2, f3, f_safe)              \
+               PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe,    \
+                       MUXCTL_ ## pg_name, PUCTL_ ## pg_name)
+
+/* A pin group where the pull-up name doesn't have a 1-1 mapping */
+#define PINP(pg_name, vdd, f0, f1, f2, f3, f_safe, pupd)               \
+               PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe,    \
+                       MUXCTL_ ## pg_name, PUCTL_ ## pupd)
+
+/* A pin group number which is not used */
+#define PIN_RESERVED \
+       PIN(NONE, NONE, NONE, NONE, NONE, NONE, NONE)
+
+const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
+       PIN(ATA,  NAND,  IDE,    NAND,   GMI,       RSVD,        IDE),
+       PIN(ATB,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
+       PIN(ATC,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
+       PIN(ATD,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
+       PIN(CDEV1, AUDIO, OSC,   PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC),
+       PIN(CDEV2, AUDIO, OSC,   AHB_CLK, APB_CLK, PLLP_OUT4,    OSC),
+       PIN(CSUS, VI, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK,
+               PLLC_OUT1),
+       PIN(DAP1, AUDIO, DAP1,   RSVD,   GMI,       SDIO2,       DAP1),
+
+       PIN(DAP2, AUDIO, DAP2,   TWC,    RSVD,      GMI,         DAP2),
+       PIN(DAP3, BB,    DAP3,   RSVD,   RSVD,      RSVD,        DAP3),
+       PIN(DAP4, UART,  DAP4,   RSVD,   GMI,       RSVD,        DAP4),
+       PIN(DTA,  VI,    RSVD,   SDIO2,  VI,        RSVD,        RSVD4),
+       PIN(DTB,  VI,    RSVD,   RSVD,   VI,        SPI1,        RSVD1),
+       PIN(DTC,  VI,    RSVD,   RSVD,   VI,        RSVD,        RSVD1),
+       PIN(DTD,  VI,    RSVD,   SDIO2,  VI,        RSVD,        RSVD1),
+       PIN(DTE,  VI,    RSVD,   RSVD,   VI,        SPI1,        RSVD1),
+
+       PINP(GPU, UART,  PWM,    UARTA,  GMI,       RSVD,        RSVD4,
+               GPSLXAU),
+       PIN(GPV,  SD,    PCIE,   RSVD,   RSVD,      RSVD,        PCIE),
+       PIN(I2CP, SYS,   I2C,    RSVD,   RSVD,      RSVD,        RSVD4),
+       PIN(IRTX, UART,  UARTA,  UARTB,  GMI,       SPI4,        UARTB),
+       PIN(IRRX, UART,  UARTA,  UARTB,  GMI,       SPI4,        UARTB),
+       PIN(KBCB, SYS,   KBC,    NAND,   SDIO2,     MIO,         KBC),
+       PIN(KBCA, SYS,   KBC,    NAND,   SDIO2,     EMC_TEST0_DLL, KBC),
+       PINP(PMC, SYS,   PWR_ON, PWR_INTR, RSVD,    RSVD,        PWR_ON, NONE),
+
+       PIN(PTA,  NAND,  I2C2,   HDMI,   GMI,       RSVD,        RSVD4),
+       PIN(RM,   UART,  I2C,    RSVD,   RSVD,      RSVD,        RSVD4),
+       PIN(KBCE, SYS,   KBC,    NAND,   OWR,       RSVD,        KBC),
+       PIN(KBCF, SYS,   KBC,    NAND,   TRACE,     MIO,         KBC),
+       PIN(GMA,  NAND,  UARTE,  SPI3,   GMI,       SDIO4,       SPI3),
+       PIN(GMC,  NAND,  UARTD,  SPI4,   GMI,       SFLASH,      SPI4),
+       PIN(SDMMC1, BB,  SDIO1,  RSVD,   UARTE,     UARTA,       RSVD2),
+       PIN(OWC,  SYS,   OWR,    RSVD,   RSVD,      RSVD,        OWR),
+
+       PIN(GME,  NAND,  RSVD,   DAP5,   GMI,       SDIO4,       GMI),
+       PIN(SDC,  SD,    PWM,    TWC,    SDIO3,     SPI3,        TWC),
+       PIN(SDD,  SD,    UARTA,  PWM,    SDIO3,     SPI3,        PWM),
+       PIN_RESERVED,
+       PINP(SLXA, SD,   PCIE,   SPI4,   SDIO3,     SPI2,        PCIE, CRTP),
+       PIN(SLXC, SD,    SPDIF,  SPI4,   SDIO3,     SPI2,        SPI4),
+       PIN(SLXD, SD,    SPDIF,  SPI4,   SDIO3,     SPI2,        SPI4),
+       PIN(SLXK, SD,    PCIE,   SPI4,   SDIO3,     SPI2,        PCIE),
+
+       PIN(SPDI, AUDIO, SPDIF,  RSVD,   I2C,       SDIO2,       RSVD2),
+       PIN(SPDO, AUDIO, SPDIF,  RSVD,   I2C,       SDIO2,       RSVD2),
+       PIN(SPIA, AUDIO, SPI1,   SPI2,   SPI3,      GMI,         GMI),
+       PIN(SPIB, AUDIO, SPI1,   SPI2,   SPI3,      GMI,         GMI),
+       PIN(SPIC, AUDIO, SPI1,   SPI2,   SPI3,      GMI,         GMI),
+       PIN(SPID, AUDIO, SPI2,   SPI1,   SPI2_ALT,  GMI,         GMI),
+       PIN(SPIE, AUDIO, SPI2,   SPI1,   SPI2_ALT,  GMI,         GMI),
+       PIN(SPIF, AUDIO, SPI3,   SPI1,   SPI2,      RSVD,        RSVD4),
+
+       PIN(SPIG, AUDIO, SPI3,   SPI2,   SPI2_ALT,  I2C,         SPI2_ALT),
+       PIN(SPIH, AUDIO, SPI3,   SPI2,   SPI2_ALT,  I2C,         SPI2_ALT),
+       PIN(UAA,  BB,    SPI3,   MIPI_HS, UARTA,    ULPI,        MIPI_HS),
+       PIN(UAB,  BB,    SPI2,   MIPI_HS, UARTA,    ULPI,        MIPI_HS),
+       PIN(UAC,  BB,    OWR,    RSVD,   RSVD,      RSVD,        RSVD4),
+       PIN(UAD,  UART,  IRDA,   SPDIF,  UARTA,     SPI4,        SPDIF),
+       PIN(UCA,  UART,  UARTC,  RSVD,   GMI,       RSVD,        RSVD4),
+       PIN(UCB,  UART,  UARTC,  PWM,    GMI,       RSVD,        RSVD4),
+
+       PIN_RESERVED,
+       PIN(ATE,  NAND,  IDE,    NAND,   GMI,       RSVD,        IDE),
+       PIN(KBCC, SYS,   KBC,    NAND,   TRACE,     EMC_TEST1_DLL, KBC),
+       PIN_RESERVED,
+       PIN_RESERVED,
+       PIN(GMB,  NAND,  IDE,    NAND,   GMI,       GMI_INT,     GMI),
+       PIN(GMD,  NAND,  RSVD,   NAND,   GMI,       SFLASH,      GMI),
+       PIN(DDC,  LCD,   I2C2,   RSVD,   RSVD,      RSVD,        RSVD4),
+
+       /* 64 */
+       PINP(LD0,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD1,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD2,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD3,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD4,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD5,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD6,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD7,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+
+       PINP(LD8,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD9,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD10, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD11, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD12, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD13, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD14, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD15, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+
+       PINP(LD16, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+       PINP(LD17, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD17),
+       PINP(LHP0, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD21_20),
+       PINP(LHP1, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD19_18),
+       PINP(LHP2, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD19_18),
+       PINP(LVP0, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LC),
+       PINP(LVP1, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD21_20),
+       PINP(HDINT, LCD, HDMI,   RSVD,   RSVD,      RSVD,     HDMI , LC),
+
+       PINP(LM0,  LCD,  DISPA,  DISPB,  SPI3,      RSVD,     RSVD4, LC),
+       PINP(LM1,  LCD,  DISPA,  DISPB,  RSVD,      CRT,      RSVD3, LC),
+       PINP(LVS,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LC),
+       PINP(LSC0, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LC),
+       PINP(LSC1, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
+       PINP(LSCK, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
+       PINP(LDC,  LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LS),
+       PINP(LCSN, LCD,  DISPA,  DISPB,  SPI3,      RSVD,     RSVD4, LS),
+
+       /* 96 */
+       PINP(LSPI, LCD,  DISPA,  DISPB,  XIO,       HDMI,     DISPA, LC),
+       PINP(LSDA, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
+       PINP(LSDI, LCD,  DISPA,  DISPB,  SPI3,      RSVD,     DISPA, LS),
+       PINP(LPW0, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
+       PINP(LPW1, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LS),
+       PINP(LPW2, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
+       PINP(LDI,  LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD23_22),
+       PINP(LHS,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LC),
+
+       PINP(LPP,  LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD23_22),
+       PIN_RESERVED,
+       PIN(KBCD,  SYS,  KBC,    NAND,   SDIO2,     MIO,      KBC),
+       PIN(GPU7,  SYS,  RTCK,   RSVD,   RSVD,      RSVD,     RTCK),
+       PIN(DTF,   VI,   I2C3,   RSVD,   VI,        RSVD,     RSVD4),
+       PIN(UDA,   BB,   SPI1,   RSVD,   UARTD,     ULPI,     RSVD2),
+       PIN(CRTP,  LCD,  CRT,    RSVD,   RSVD,      RSVD,     RSVD),
+       PINP(SDB,  SD,   UARTA,  PWM,    SDIO3,     SPI2,     PWM,   NONE),
+
+       /* these pin groups only have pullup and pull down control */
+       PINALL(CK32,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+               PUCTL_NONE),
+       PINALL(DDRC,  DDR,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+               PUCTL_NONE),
+       PINALL(PMCA,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+               PUCTL_NONE),
+       PINALL(PMCB,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+               PUCTL_NONE),
+       PINALL(PMCC,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+               PUCTL_NONE),
+       PINALL(PMCD,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+               PUCTL_NONE),
+       PINALL(PMCE,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+               PUCTL_NONE),
+       PINALL(XM2C,  DDR,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+               PUCTL_NONE),
+       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;
+       struct pmux_tri_ctlr *pmt =
+                       (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
        u32 *tri = &pmt->pmt_tri[TRISTATE_REG(pin)];
        u32 reg;
 
@@ -50,3 +504,69 @@ 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(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(struct pingroup_config *config, int len)
+{
+       int i;
+
+       for (i = 0; i < len; i++)
+               pinmux_config_pingroup(&config[i]);
+}
index e8ef632..469d742 100644 (file)
 #ifndef _PINMUX_H_
 #define _PINMUX_H_
 
-/* Pin groups which we can set to tristate or normal */
+/*
+ * Pin groups which we adjust. There are three basic attributes of each pin
+ * group which use this enum:
+ *
+ *     - function
+ *     - pullup / pulldown
+ *     - tristate or normal
+ */
 enum pmux_pingrp {
        /* APB_MISC_PP_TRISTATE_REG_A_0 */
        PINGRP_ATA,
@@ -155,37 +162,169 @@ enum pmux_pingrp {
        PINGRP_UDA,
        PINGRP_CRTP,
        PINGRP_SDB,
+
+       /* these pin groups only have pullup and pull down control */
+       PINGRP_FIRST_NO_MUX,
+       PINGRP_CK32 = PINGRP_FIRST_NO_MUX,
+       PINGRP_DDRC,
+       PINGRP_PMCA,
+       PINGRP_PMCB,
+       PINGRP_PMCC,
+       PINGRP_PMCD,
+       PINGRP_PMCE,
+       PINGRP_XM2C,
+       PINGRP_XM2D,
+
+       PINGRP_COUNT,
+};
+
+/*
+ * Functions which can be assigned to each of the pin groups. The values here
+ * bear no relation to the values programmed into pinmux registers and are
+ * purely a convenience. The translation is done through a table search.
+ */
+enum pmux_func {
+       PMUX_FUNC_AHB_CLK,
+       PMUX_FUNC_APB_CLK,
+       PMUX_FUNC_AUDIO_SYNC,
+       PMUX_FUNC_CRT,
+       PMUX_FUNC_DAP1,
+       PMUX_FUNC_DAP2,
+       PMUX_FUNC_DAP3,
+       PMUX_FUNC_DAP4,
+       PMUX_FUNC_DAP5,
+       PMUX_FUNC_DISPA,
+       PMUX_FUNC_DISPB,
+       PMUX_FUNC_EMC_TEST0_DLL,
+       PMUX_FUNC_EMC_TEST1_DLL,
+       PMUX_FUNC_GMI,
+       PMUX_FUNC_GMI_INT,
+       PMUX_FUNC_HDMI,
+       PMUX_FUNC_I2C,
+       PMUX_FUNC_I2C2,
+       PMUX_FUNC_I2C3,
+       PMUX_FUNC_IDE,
+       PMUX_FUNC_IRDA,
+       PMUX_FUNC_KBC,
+       PMUX_FUNC_MIO,
+       PMUX_FUNC_MIPI_HS,
+       PMUX_FUNC_NAND,
+       PMUX_FUNC_OSC,
+       PMUX_FUNC_OWR,
+       PMUX_FUNC_PCIE,
+       PMUX_FUNC_PLLA_OUT,
+       PMUX_FUNC_PLLC_OUT1,
+       PMUX_FUNC_PLLM_OUT1,
+       PMUX_FUNC_PLLP_OUT2,
+       PMUX_FUNC_PLLP_OUT3,
+       PMUX_FUNC_PLLP_OUT4,
+       PMUX_FUNC_PWM,
+       PMUX_FUNC_PWR_INTR,
+       PMUX_FUNC_PWR_ON,
+       PMUX_FUNC_RTCK,
+       PMUX_FUNC_SDIO1,
+       PMUX_FUNC_SDIO2,
+       PMUX_FUNC_SDIO3,
+       PMUX_FUNC_SDIO4,
+       PMUX_FUNC_SFLASH,
+       PMUX_FUNC_SPDIF,
+       PMUX_FUNC_SPI1,
+       PMUX_FUNC_SPI2,
+       PMUX_FUNC_SPI2_ALT,
+       PMUX_FUNC_SPI3,
+       PMUX_FUNC_SPI4,
+       PMUX_FUNC_TRACE,
+       PMUX_FUNC_TWC,
+       PMUX_FUNC_UARTA,
+       PMUX_FUNC_UARTB,
+       PMUX_FUNC_UARTC,
+       PMUX_FUNC_UARTD,
+       PMUX_FUNC_UARTE,
+       PMUX_FUNC_ULPI,
+       PMUX_FUNC_VI,
+       PMUX_FUNC_VI_SENSOR_CLK,
+       PMUX_FUNC_XIO,
+       PMUX_FUNC_SAFE,
+
+       /* These don't have a name, but can be used in the table */
+       PMUX_FUNC_RSVD1,
+       PMUX_FUNC_RSVD2,
+       PMUX_FUNC_RSVD3,
+       PMUX_FUNC_RSVD4,
+       PMUX_FUNC_RSVD, /* Not valid and should not be used */
+
+       PMUX_FUNC_COUNT,
+
+       PMUX_FUNC_NONE = -1,
 };
 
+/* return 1 if a pmux_func is in range */
+#define pmux_func_isvalid(func) ((func) >= 0 && (func) < PMUX_FUNC_COUNT && \
+               (func) != PMUX_FUNC_RSVD)
+
+/* 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,
+};
 
-#define TEGRA_TRISTATE_REGS 4
+/* Available power domains used by pin groups */
+enum pmux_vddio {
+       PMUX_VDDIO_BB = 0,
+       PMUX_VDDIO_LCD,
+       PMUX_VDDIO_VI,
+       PMUX_VDDIO_UART,
+       PMUX_VDDIO_DDR,
+       PMUX_VDDIO_NAND,
+       PMUX_VDDIO_SYS,
+       PMUX_VDDIO_AUDIO,
+       PMUX_VDDIO_SD,
+
+       PMUX_VDDIO_NONE
+};
+
+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_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[TEGRA_TRISTATE_REGS]; /* _TRI_STATE_REG_A/B/C/D_0 14-20 */
-       uint pmt_cfg_ctl;               /* _CONFIG_CTL_0, offset 24 */
+       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_a;                 /* _PINGRP_MUX_CTL_A_0, offset 80 */
-       uint pmt_ctl_b;                 /* _PINGRP_MUX_CTL_B_0, offset 84 */
-       uint pmt_ctl_c;                 /* _PINGRP_MUX_CTL_C_0, offset 88 */
-       uint pmt_ctl_d;                 /* _PINGRP_MUX_CTL_D_0, offset 8C */
-       uint pmt_ctl_e;                 /* _PINGRP_MUX_CTL_E_0, offset 90 */
-       uint pmt_ctl_f;                 /* _PINGRP_MUX_CTL_F_0, offset 94 */
-       uint pmt_ctl_g;                 /* _PINGRP_MUX_CTL_G_0, offset 98 */
+       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  */
 };
 
-/* Converts a pin group to a tristate register: 0=A, 1=B, 2=C, 3=D */
-#define TRISTATE_REG(id) ((id) >> 5)
-
-/* Mask value for a tristate (within TRISTATE_REG(id)) */
-#define TRISTATE_MASK(id) (1 << ((id) & 0x1f))
+/*
+ * 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);
@@ -193,4 +332,23 @@ 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);
+
+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(struct pingroup_config *config, int len);
+
 #endif /* PINMUX_H */
index 35ff2ef..5ba7bda 100644 (file)
@@ -86,21 +86,15 @@ static void clock_init_uart(void)
  */
 static void pin_mux_uart(void)
 {
-       struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-       u32 reg;
-
 #if defined(CONFIG_TEGRA2_ENABLE_UARTA)
-       reg = readl(&pmt->pmt_ctl_c);
-       reg &= 0xFFF0FFFF;      /* IRRX_/IRTX_SEL [19:16] = 00 UARTA */
-       writel(reg, &pmt->pmt_ctl_c);
+       pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA);
+       pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA);
 
        pinmux_tristate_disable(PINGRP_IRRX);
        pinmux_tristate_disable(PINGRP_IRTX);
 #endif /* CONFIG_TEGRA2_ENABLE_UARTA */
 #if defined(CONFIG_TEGRA2_ENABLE_UARTD)
-       reg = readl(&pmt->pmt_ctl_b);
-       reg &= 0xFFFFFFF3;      /* GMC_SEL [3:2] = 00, UARTD */
-       writel(reg, &pmt->pmt_ctl_b);
+       pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD);
 
        pinmux_tristate_disable(PINGRP_GMC);
 #endif /* CONFIG_TEGRA2_ENABLE_UARTD */
@@ -123,33 +117,19 @@ static void clock_init_mmc(void)
  */
 static void pin_mux_mmc(void)
 {
-       struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-       u32 reg;
-
-       /* SDMMC4 */
-       /* config 2, x8 on 2nd set of pins */
-       reg = readl(&pmt->pmt_ctl_a);
-       reg |= (3 << 16);       /* ATB_SEL [17:16] = 11 SDIO4 */
-       writel(reg, &pmt->pmt_ctl_a);
-       reg = readl(&pmt->pmt_ctl_b);
-       reg |= (3 << 0);        /* GMA_SEL [1:0] = 11 SDIO4 */
-       writel(reg, &pmt->pmt_ctl_b);
-       reg = readl(&pmt->pmt_ctl_d);
-       reg |= (3 << 0);        /* GME_SEL [1:0] = 11 SDIO4 */
-       writel(reg, &pmt->pmt_ctl_d);
+       /* SDMMC4: config 3, x8 on 2nd set of pins */
+       pinmux_set_func(PINGRP_ATB, PMUX_FUNC_SDIO4);
+       pinmux_set_func(PINGRP_GMA, PMUX_FUNC_SDIO4);
+       pinmux_set_func(PINGRP_GME, PMUX_FUNC_SDIO4);
 
        pinmux_tristate_disable(PINGRP_ATB);
        pinmux_tristate_disable(PINGRP_GMA);
        pinmux_tristate_disable(PINGRP_GME);
 
-       /* SDMMC3 */
-       /* SDIO3_CLK, SDIO3_CMD, SDIO3_DAT[3:0] */
-       reg = readl(&pmt->pmt_ctl_d);
-       reg &= 0xFFFF03FF;
-       reg |= (2 << 10);       /* SDB_SEL [11:10] = 01 SDIO3 */
-       reg |= (2 << 12);       /* SDC_SEL [13:12] = 01 SDIO3 */
-       reg |= (2 << 14);       /* SDD_SEL [15:14] = 01 SDIO3 */
-       writel(reg, &pmt->pmt_ctl_d);
+       /* SDMMC3: SDIO3_CLK, SDIO3_CMD, SDIO3_DAT[3:0] */
+       pinmux_set_func(PINGRP_SDB, PMUX_FUNC_SDIO3);
+       pinmux_set_func(PINGRP_SDC, PMUX_FUNC_SDIO3);
+       pinmux_set_func(PINGRP_SDD, PMUX_FUNC_SDIO3);
 
        pinmux_tristate_disable(PINGRP_SDC);
        pinmux_tristate_disable(PINGRP_SDD);