Tegra2: Add additional pin multiplexing features
authorSimon Glass <sjg@chromium.org>
Tue, 30 Aug 2011 06:23:14 +0000 (06:23 +0000)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Sun, 4 Sep 2011 09:36:15 +0000 (11:36 +0200)
This adds an enum for each pin and some functions for changing the pin
muxing setup.

Signed-off-by: Simon Glass <sjg@chromium.org>
arch/arm/cpu/armv7/tegra2/Makefile
arch/arm/cpu/armv7/tegra2/pinmux.c [new file with mode: 0644]
arch/arm/include/asm/arch-tegra2/pinmux.h
board/nvidia/common/board.c

index b35764c32176514184eee0cadb60cfe10a49d16a..f673f036f97fa385a12a62253cbedf2fca215f5f 100644 (file)
@@ -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 (file)
index 0000000..5594ab8
--- /dev/null
@@ -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);
+}
index cce936ddc80e059fdabfe54194d01296e397ae1b..b8a4753c813f3debf7896829b8a1b68d41d3c471 100644 (file)
 #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 */
index 945141e7d3c498cf2f30f6f61984f75162b39080..799dd3a629666afa7e2bc8186c052c91c09b9dab 100644 (file)
@@ -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);
 }
 
 /*