diff options
| author | Simon Glass <sjg@chromium.org> | 2011-08-30 06:23:14 +0000 | 
|---|---|---|
| committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2011-09-04 11:36:15 +0200 | 
| commit | 858bd095e1583f86af93ac1ae8f9e28aebbd0aa5 (patch) | |
| tree | d148a54fa6161e7d13d7ee5518277e03ffbb5375 | |
| parent | b4ba2be8dc2711ad2219186e89b4e10648d52af9 (diff) | |
| download | olio-uboot-2014.01-858bd095e1583f86af93ac1ae8f9e28aebbd0aa5.tar.xz olio-uboot-2014.01-858bd095e1583f86af93ac1ae8f9e28aebbd0aa5.zip | |
Tegra2: Add additional pin multiplexing features
This adds an enum for each pin and some functions for changing the pin
muxing setup.
Signed-off-by: Simon Glass <sjg@chromium.org>
| -rw-r--r-- | arch/arm/cpu/armv7/tegra2/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/tegra2/pinmux.c | 52 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-tegra2/pinmux.h | 161 | ||||
| -rw-r--r-- | board/nvidia/common/board.c | 30 | 
4 files changed, 210 insertions, 35 deletions
| diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile index b35764c32..f673f036f 100644 --- a/arch/arm/cpu/armv7/tegra2/Makefile +++ b/arch/arm/cpu/armv7/tegra2/Makefile @@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk  LIB	=  $(obj)lib$(SOC).o  SOBJS	:= lowlevel_init.o -COBJS	:= ap20.o board.o clock.o sys_info.o timer.o +COBJS	:= ap20.o board.o clock.o pinmux.o sys_info.o timer.o  SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/tegra2/pinmux.c b/arch/arm/cpu/armv7/tegra2/pinmux.c new file mode 100644 index 000000000..5594ab80f --- /dev/null +++ b/arch/arm/cpu/armv7/tegra2/pinmux.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* Tegra2 pin multiplexing functions */ + +#include <asm/io.h> +#include <asm/arch/tegra2.h> +#include <asm/arch/pinmux.h> +#include <common.h> + + +void pinmux_set_tristate(enum pmux_pin pin, int enable) +{ +	struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; +	u32 *tri = &pmt->pmt_tri[TRISTATE_REG(pin)]; +	u32 reg; + +	reg = readl(tri); +	if (enable) +		reg |= TRISTATE_MASK(pin); +	else +		reg &= ~TRISTATE_MASK(pin); +	writel(reg, tri); +} + +void pinmux_tristate_enable(enum pmux_pin pin) +{ +	pinmux_set_tristate(pin, 1); +} + +void pinmux_tristate_disable(enum pmux_pin pin) +{ +	pinmux_set_tristate(pin, 0); +} diff --git a/arch/arm/include/asm/arch-tegra2/pinmux.h b/arch/arm/include/asm/arch-tegra2/pinmux.h index cce936ddc..b8a4753c8 100644 --- a/arch/arm/include/asm/arch-tegra2/pinmux.h +++ b/arch/arm/include/asm/arch-tegra2/pinmux.h @@ -24,6 +24,142 @@  #ifndef _PINMUX_H_  #define _PINMUX_H_ +/* Pins which we can set to tristate or normal */ +enum pmux_pin { +	/* APB_MISC_PP_TRISTATE_REG_A_0 */ +	PIN_ATA, +	PIN_ATB, +	PIN_ATC, +	PIN_ATD, +	PIN_CDEV1, +	PIN_CDEV2, +	PIN_CSUS, +	PIN_DAP1, + +	PIN_DAP2, +	PIN_DAP3, +	PIN_DAP4, +	PIN_DTA, +	PIN_DTB, +	PIN_DTC, +	PIN_DTD, +	PIN_DTE, + +	PIN_GPU, +	PIN_GPV, +	PIN_I2CP, +	PIN_IRTX, +	PIN_IRRX, +	PIN_KBCB, +	PIN_KBCA, +	PIN_PMC, + +	PIN_PTA, +	PIN_RM, +	PIN_KBCE, +	PIN_KBCF, +	PIN_GMA, +	PIN_GMC, +	PIN_SDMMC1, +	PIN_OWC, + +	/* 32: APB_MISC_PP_TRISTATE_REG_B_0 */ +	PIN_GME, +	PIN_SDC, +	PIN_SDD, +	PIN_RESERVED0, +	PIN_SLXA, +	PIN_SLXC, +	PIN_SLXD, +	PIN_SLXK, + +	PIN_SPDI, +	PIN_SPDO, +	PIN_SPIA, +	PIN_SPIB, +	PIN_SPIC, +	PIN_SPID, +	PIN_SPIE, +	PIN_SPIF, + +	PIN_SPIG, +	PIN_SPIH, +	PIN_UAA, +	PIN_UAB, +	PIN_UAC, +	PIN_UAD, +	PIN_UCA, +	PIN_UCB, + +	PIN_RESERVED1, +	PIN_ATE, +	PIN_KBCC, +	PIN_RESERVED2, +	PIN_RESERVED3, +	PIN_GMB, +	PIN_GMD, +	PIN_DDC, + +	/* 64: APB_MISC_PP_TRISTATE_REG_C_0 */ +	PIN_LD0, +	PIN_LD1, +	PIN_LD2, +	PIN_LD3, +	PIN_LD4, +	PIN_LD5, +	PIN_LD6, +	PIN_LD7, + +	PIN_LD8, +	PIN_LD9, +	PIN_LD10, +	PIN_LD11, +	PIN_LD12, +	PIN_LD13, +	PIN_LD14, +	PIN_LD15, + +	PIN_LD16, +	PIN_LD17, +	PIN_LHP0, +	PIN_LHP1, +	PIN_LHP2, +	PIN_LVP0, +	PIN_LVP1, +	PIN_HDINT, + +	PIN_LM0, +	PIN_LM1, +	PIN_LVS, +	PIN_LSC0, +	PIN_LSC1, +	PIN_LSCK, +	PIN_LDC, +	PIN_LCSN, + +	/* 96: APB_MISC_PP_TRISTATE_REG_D_0 */ +	PIN_LSPI, +	PIN_LSDA, +	PIN_LSDI, +	PIN_LPW0, +	PIN_LPW1, +	PIN_LPW2, +	PIN_LDI, +	PIN_LHS, + +	PIN_LPP, +	PIN_RESERVED4, +	PIN_KBCD, +	PIN_GPU7, +	PIN_DTF, +	PIN_UDA, +	PIN_CRTP, +	PIN_SDB, +}; + + +#define TEGRA_TRISTATE_REGS 4 +  /* APB MISC Pin Mux and Tristate (APB_MISC_PP_) registers */  struct pmux_tri_ctlr {  	uint pmt_reserved0;		/* ABP_MISC_PP_ reserved offset 00 */ @@ -31,10 +167,7 @@ struct pmux_tri_ctlr {  	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_a;			/* _TRI_STATE_REG_A_0, offset 14 */ -	uint pmt_tri_b;			/* _TRI_STATE_REG_B_0, offset 18 */ -	uint pmt_tri_c;			/* _TRI_STATE_REG_C_0, offset 1C */ -	uint pmt_tri_d;			/* _TRI_STATE_REG_D_0, offset 20 */ +	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_reserved[22];		/* ABP_MISC_PP_ reserved offs 28-7C */ @@ -48,14 +181,16 @@ struct pmux_tri_ctlr {  	uint pmt_ctl_g;			/* _PIN_MUX_CTL_G_0, offset 98 */  }; -#define Z_GMC			(1 << 29) -#define Z_IRRX			(1 << 20) -#define Z_IRTX			(1 << 19) -#define Z_GMA			(1 << 28) -#define Z_GME			(1 << 0) -#define Z_ATB			(1 << 1) -#define Z_SDB			(1 << 15) -#define Z_SDC			(1 << 1) -#define Z_SDD			(1 << 2) +/* Converts a pin number 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)) + +/* Set a pin to tristate */ +void pinmux_tristate_enable(enum pmux_pin pin); + +/* Set a pin to normal (non tristate) */ +void pinmux_tristate_disable(enum pmux_pin pin);  #endif	/* PINMUX_H */ diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c index 945141e7d..799dd3a62 100644 --- a/board/nvidia/common/board.c +++ b/board/nvidia/common/board.c @@ -143,19 +143,15 @@ static void pin_mux_uart(void)  	reg &= 0xFFF0FFFF;	/* IRRX_/IRTX_SEL [19:16] = 00 UARTA */  	writel(reg, &pmt->pmt_ctl_c); -	reg = readl(&pmt->pmt_tri_a); -	reg &= ~Z_IRRX;		/* Z_IRRX = normal (0) */ -	reg &= ~Z_IRTX;		/* Z_IRTX = normal (0) */ -	writel(reg, &pmt->pmt_tri_a); +	pinmux_tristate_disable(PIN_IRRX); +	pinmux_tristate_disable(PIN_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); -	reg = readl(&pmt->pmt_tri_a); -	reg &= ~Z_GMC;		/* Z_GMC = normal (0) */ -	writel(reg, &pmt->pmt_tri_a); +	pinmux_tristate_disable(PIN_GMC);  #endif	/* CONFIG_TEGRA2_ENABLE_UARTD */  } @@ -222,13 +218,9 @@ static void pin_mux_mmc(void)  	reg |= (3 << 0);	/* GME_SEL [1:0] = 11 SDIO4 */  	writel(reg, &pmt->pmt_ctl_d); -	reg = readl(&pmt->pmt_tri_a); -	reg &= ~Z_ATB;		/* Z_ATB = normal (0) */ -	reg &= ~Z_GMA;		/* Z_GMA = normal (0) */ -	writel(reg, &pmt->pmt_tri_a); -	reg = readl(&pmt->pmt_tri_b); -	reg &= ~Z_GME;		/* Z_GME = normal (0) */ -	writel(reg, &pmt->pmt_tri_b); +	pinmux_tristate_disable(PIN_ATB); +	pinmux_tristate_disable(PIN_GMA); +	pinmux_tristate_disable(PIN_GME);  	/* SDMMC3 */  	/* SDIO3_CLK, SDIO3_CMD, SDIO3_DAT[3:0] */ @@ -239,13 +231,9 @@ static void pin_mux_mmc(void)  	reg |= (2 << 14);	/* SDD_SEL [15:14] = 01 SDIO3 */  	writel(reg, &pmt->pmt_ctl_d); -	reg = readl(&pmt->pmt_tri_b); -	reg &= ~Z_SDC;		/* Z_SDC = normal (0) */ -	reg &= ~Z_SDD;		/* Z_SDD = normal (0) */ -	writel(reg, &pmt->pmt_tri_b); -	reg = readl(&pmt->pmt_tri_d); -	reg &= ~Z_SDB;		/* Z_SDB = normal (0) */ -	writel(reg, &pmt->pmt_tri_d); +	pinmux_tristate_disable(PIN_SDC); +	pinmux_tristate_disable(PIN_SDD); +	pinmux_tristate_disable(PIN_SDB);  }  /* |