diff options
| -rw-r--r-- | arch/arm/cpu/armv7/tegra2/pinmux.c | 522 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-tegra2/pinmux.h | 192 | ||||
| -rw-r--r-- | board/nvidia/common/board.c | 42 | 
3 files changed, 707 insertions, 49 deletions
diff --git a/arch/arm/cpu/armv7/tegra2/pinmux.c b/arch/arm/cpu/armv7/tegra2/pinmux.c index 01a3d841b..b053f9060 100644 --- a/arch/arm/cpu/armv7/tegra2/pinmux.c +++ b/arch/arm/cpu/armv7/tegra2/pinmux.c @@ -27,9 +27,463 @@  #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]); +} diff --git a/arch/arm/include/asm/arch-tegra2/pinmux.h b/arch/arm/include/asm/arch-tegra2/pinmux.h index e8ef63271..469d742cc 100644 --- a/arch/arm/include/asm/arch-tegra2/pinmux.h +++ b/arch/arm/include/asm/arch-tegra2/pinmux.h @@ -24,7 +24,14 @@  #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 */ diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c index 35ff2ef03..5ba7bda33 100644 --- a/board/nvidia/common/board.c +++ b/board/nvidia/common/board.c @@ -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);  |