aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/pinmux.c
diff options
context:
space:
mode:
authorErik Gilling <konkers@android.com>2010-02-23 21:46:37 -0500
committerErik Gilling <konkers@android.com>2010-08-05 17:57:02 -0400
commita4417c84513650a0f9e4de6a0bb2c5480e45b2a7 (patch)
treeb62ffaabf7a6734f9a2be505b219f9367e3509ed /arch/arm/mach-tegra/pinmux.c
parent3c92db9ac0ca3eee8e46e2424b6c074e2e394ad9 (diff)
[ARM] tegra: add pinmux support
v2: fixes from Russell King - include linux/io.h instead of asm/io.h v3: - Add drive strength controls - Replace typedef enums with plain enums Signed-off-by: Erik Gilling <konkers@android.com> Signed-off-by: Colin Cross <ccross@android.com>
Diffstat (limited to 'arch/arm/mach-tegra/pinmux.c')
-rw-r--r--arch/arm/mach-tegra/pinmux.c945
1 files changed, 945 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
new file mode 100644
index 000000000000..13ae10237e84
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -0,0 +1,945 @@
1/*
2 * linux/arch/arm/mach-tegra/pinmux.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17
18#include <linux/kernel.h>
19#include <linux/errno.h>
20#include <linux/spinlock.h>
21#include <linux/io.h>
22
23#include <mach/iomap.h>
24#include <mach/pinmux.h>
25
26
27#define TEGRA_TRI_STATE(x) (0x14 + (4 * (x)))
28#define TEGRA_PP_MUX_CTL(x) (0x80 + (4 * (x)))
29#define TEGRA_PP_PU_PD(x) (0xa0 + (4 * (x)))
30
31#define REG_A 0
32#define REG_B 1
33#define REG_C 2
34#define REG_D 3
35#define REG_E 4
36#define REG_F 5
37#define REG_G 6
38
39#define REG_N -1
40
41#define HSM_EN(reg) (((reg) >> 2) & 0x1)
42#define SCHMT_EN(reg) (((reg) >> 3) & 0x1)
43#define LPMD(reg) (((reg) >> 4) & 0x3)
44#define DRVDN(reg) (((reg) >> 12) & 0x1f)
45#define DRVUP(reg) (((reg) >> 20) & 0x1f)
46#define SLWR(reg) (((reg) >> 28) & 0x3)
47#define SLWF(reg) (((reg) >> 30) & 0x3)
48
49struct tegra_pingroup_desc {
50 const char *name;
51 int funcs[4];
52 s8 tri_reg; /* offset into the TRISTATE_REG_* register bank */
53 s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */
54 s8 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */
55 s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */
56 s8 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */
57 s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */
58};
59
60#define PINGROUP(pg_name, f0, f1, f2, f3, \
61 tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \
62 [TEGRA_PINGROUP_ ## pg_name] = { \
63 .name = #pg_name, \
64 .funcs = { \
65 TEGRA_MUX_ ## f0, \
66 TEGRA_MUX_ ## f1, \
67 TEGRA_MUX_ ## f2, \
68 TEGRA_MUX_ ## f3, \
69 }, \
70 .tri_reg = REG_ ## tri_r, \
71 .tri_bit = tri_b, \
72 .mux_reg = REG_ ## mux_r, \
73 .mux_bit = mux_b, \
74 .pupd_reg = REG_ ## pupd_r, \
75 .pupd_bit = pupd_b, \
76 }
77
78static const struct tegra_pingroup_desc pingroups[TEGRA_MAX_PINGROUP] = {
79 PINGROUP(ATA, IDE, NAND, GMI, RSVD, A, 0, A, 24, A, 0),
80 PINGROUP(ATB, IDE, NAND, GMI, SDIO4, A, 1, A, 16, A, 2),
81 PINGROUP(ATC, IDE, NAND, GMI, SDIO4, A, 2, A, 22, A, 4),
82 PINGROUP(ATD, IDE, NAND, GMI, SDIO4, A, 3, A, 20, A, 6),
83 PINGROUP(ATE, IDE, NAND, GMI, RSVD, B, 25, A, 12, A, 8),
84 PINGROUP(CDEV1, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, A, 4, C, 2, C, 0),
85 PINGROUP(CDEV2, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, A, 5, C, 4, C, 2),
86 PINGROUP(CRTP, CRT, RSVD, RSVD, RSVD, D, 14, G, 20, B, 24),
87 PINGROUP(CSUS, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, A, 6, C, 6, D, 24),
88 PINGROUP(DAP1, DAP1, RSVD, GMI, SDIO2, A, 7, C, 20, A, 10),
89 PINGROUP(DAP2, DAP2, TWC, RSVD, GMI, A, 8, C, 22, A, 12),
90 PINGROUP(DAP3, DAP3, RSVD, RSVD, RSVD, A, 9, C, 24, A, 14),
91 PINGROUP(DAP4, DAP4, RSVD, GMI, RSVD, A, 10, C, 26, A, 16),
92 PINGROUP(DDC, I2C2, RSVD, RSVD, RSVD, B, 31, C, 0, E, 28),
93 PINGROUP(DTA, RSVD, SDIO2, VI, RSVD, A, 11, B, 20, A, 18),
94 PINGROUP(DTB, RSVD, RSVD, VI, SPI1, A, 12, B, 22, A, 20),
95 PINGROUP(DTC, RSVD, RSVD, VI, RSVD, A, 13, B, 26, A, 22),
96 PINGROUP(DTD, RSVD, SDIO2, VI, RSVD, A, 14, B, 28, A, 24),
97 PINGROUP(DTE, RSVD, RSVD, VI, SPI1, A, 15, B, 30, A, 26),
98 PINGROUP(DTF, I2C3, RSVD, VI, RSVD, D, 12, G, 30, A, 28),
99 PINGROUP(GMA, UARTE, SPI3, GMI, SDIO4, A, 28, B, 0, E, 20),
100 PINGROUP(GMB, IDE, NAND, GMI, GMI_INT, B, 29, C, 28, E, 22),
101 PINGROUP(GMC, UARTD, SPI4, GMI, SFLASH, A, 29, B, 2, E, 24),
102 PINGROUP(GMD, RSVD, NAND, GMI, SFLASH, B, 30, C, 30, E, 26),
103 PINGROUP(GME, RSVD, DAP5, GMI, SDIO4, B, 0, D, 0, C, 24),
104 PINGROUP(GPU, PWM, UARTA, GMI, RSVD, A, 16, D, 4, B, 20),
105 PINGROUP(GPU7, RTCK, RSVD, RSVD, RSVD, D, 11, G, 28, B, 6),
106 PINGROUP(GPV, PCIE, RSVD, RSVD, RSVD, A, 17, D, 2, A, 30),
107 PINGROUP(HDINT, HDMI, RSVD, RSVD, RSVD, C, 23, B, 4, D, 22),
108 PINGROUP(I2CP, I2C, RSVD, RSVD, RSVD, A, 18, C, 8, B, 2),
109 PINGROUP(IRRX, UARTA, UARTB, GMI, SPI4, A, 20, C, 18, C, 22),
110 PINGROUP(IRTX, UARTA, UARTB, GMI, SPI4, A, 19, C, 16, C, 20),
111 PINGROUP(KBCA, KBC, NAND, SDIO2, EMC_TEST0_DLL, A, 22, C, 10, B, 8),
112 PINGROUP(KBCB, KBC, NAND, SDIO2, MIO, A, 21, C, 12, B, 10),
113 PINGROUP(KBCC, KBC, NAND, TRACE, EMC_TEST1_DLL, B, 26, C, 14, B, 12),
114 PINGROUP(KBCD, KBC, NAND, SDIO2, MIO, D, 10, G, 26, B, 14),
115 PINGROUP(KBCE, KBC, NAND, OWR, RSVD, A, 26, A, 28, E, 2),
116 PINGROUP(KBCF, KBC, NAND, TRACE, MIO, A, 27, A, 26, E, 0),
117 PINGROUP(LCSN, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 31, E, 12, D, 20),
118 PINGROUP(LD0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 0, F, 0, D, 12),
119 PINGROUP(LD1, DISPLAYA, DISPLAYB, XIO, RSVD, C, 1, F, 2, D, 12),
120 PINGROUP(LD10, DISPLAYA, DISPLAYB, XIO, RSVD, C, 10, F, 20, D, 12),
121 PINGROUP(LD11, DISPLAYA, DISPLAYB, XIO, RSVD, C, 11, F, 22, D, 12),
122 PINGROUP(LD12, DISPLAYA, DISPLAYB, XIO, RSVD, C, 12, F, 24, D, 12),
123 PINGROUP(LD13, DISPLAYA, DISPLAYB, XIO, RSVD, C, 13, F, 26, D, 12),
124 PINGROUP(LD14, DISPLAYA, DISPLAYB, XIO, RSVD, C, 14, F, 28, D, 12),
125 PINGROUP(LD15, DISPLAYA, DISPLAYB, XIO, RSVD, C, 15, F, 30, D, 12),
126 PINGROUP(LD16, DISPLAYA, DISPLAYB, XIO, RSVD, C, 16, G, 0, D, 12),
127 PINGROUP(LD17, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 17, G, 2, D, 12),
128 PINGROUP(LD2, DISPLAYA, DISPLAYB, XIO, RSVD, C, 2, F, 4, D, 12),
129 PINGROUP(LD3, DISPLAYA, DISPLAYB, XIO, RSVD, C, 3, F, 6, D, 12),
130 PINGROUP(LD4, DISPLAYA, DISPLAYB, XIO, RSVD, C, 4, F, 8, D, 12),
131 PINGROUP(LD5, DISPLAYA, DISPLAYB, XIO, RSVD, C, 5, F, 10, D, 12),
132 PINGROUP(LD6, DISPLAYA, DISPLAYB, XIO, RSVD, C, 6, F, 12, D, 12),
133 PINGROUP(LD7, DISPLAYA, DISPLAYB, XIO, RSVD, C, 7, F, 14, D, 12),
134 PINGROUP(LD8, DISPLAYA, DISPLAYB, XIO, RSVD, C, 8, F, 16, D, 12),
135 PINGROUP(LD9, DISPLAYA, DISPLAYB, XIO, RSVD, C, 9, F, 18, D, 12),
136 PINGROUP(LDC, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 30, E, 14, D, 20),
137 PINGROUP(LDI, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 6, G, 16, D, 18),
138 PINGROUP(LHP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 18, G, 10, D, 16),
139 PINGROUP(LHP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 19, G, 4, D, 14),
140 PINGROUP(LHP2, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 20, G, 6, D, 14),
141 PINGROUP(LHS, DISPLAYA, DISPLAYB, XIO, RSVD, D, 7, E, 22, D, 22),
142 PINGROUP(LM0, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 24, E, 26, D, 22),
143 PINGROUP(LM1, DISPLAYA, DISPLAYB, RSVD, CRT, C, 25, E, 28, D, 22),
144 PINGROUP(LPP, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 8, G, 14, D, 18),
145 PINGROUP(LPW0, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 3, E, 0, D, 20),
146 PINGROUP(LPW1, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 4, E, 2, D, 20),
147 PINGROUP(LPW2, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 5, E, 4, D, 20),
148 PINGROUP(LSC0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 27, E, 18, D, 22),
149 PINGROUP(LSC1, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 28, E, 20, D, 20),
150 PINGROUP(LSCK, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 29, E, 16, D, 20),
151 PINGROUP(LSDA, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 1, E, 8, D, 20),
152 PINGROUP(LSDI, DISPLAYA, DISPLAYB, SPI3, RSVD, D, 2, E, 6, D, 20),
153 PINGROUP(LSPI, DISPLAYA, DISPLAYB, XIO, HDMI, D, 0, E, 10, D, 22),
154 PINGROUP(LVP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 21, E, 30, D, 22),
155 PINGROUP(LVP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 22, G, 8, D, 16),
156 PINGROUP(LVS, DISPLAYA, DISPLAYB, XIO, RSVD, C, 26, E, 24, D, 22),
157 PINGROUP(OWC, OWR, RSVD, RSVD, RSVD, A, 31, B, 8, E, 30),
158 PINGROUP(PMC, PWR_ON, PWR_INTR, RSVD, RSVD, A, 23, G, 18, N, -1),
159 PINGROUP(PTA, I2C2, HDMI, GMI, RSVD, A, 24, G, 22, B, 4),
160 PINGROUP(RM, I2C, RSVD, RSVD, RSVD, A, 25, A, 14, B, 0),
161 PINGROUP(SDB, UARTA, PWM, SDIO3, SPI2, D, 15, D, 10, N, -1),
162 PINGROUP(SDC, PWM, TWC, SDIO3, SPI3, B, 1, D, 12, D, 28),
163 PINGROUP(SDD, UARTA, PWM, SDIO3, SPI3, B, 2, D, 14, D, 30),
164 PINGROUP(SDIO1, SDIO1, RSVD, UARTE, UARTA, A, 30, A, 30, E, 18),
165 PINGROUP(SLXA, PCIE, SPI4, SDIO3, SPI2, B, 3, B, 6, B, 22),
166 PINGROUP(SLXC, SPDIF, SPI4, SDIO3, SPI2, B, 5, B, 10, B, 26),
167 PINGROUP(SLXD, SPDIF, SPI4, SDIO3, SPI2, B, 6, B, 12, B, 28),
168 PINGROUP(SLXK, PCIE, SPI4, SDIO3, SPI2, B, 7, B, 14, B, 30),
169 PINGROUP(SPDI, SPDIF, RSVD, I2C, SDIO2, B, 8, D, 8, B, 16),
170 PINGROUP(SPDO, SPDIF, RSVD, I2C, SDIO2, B, 9, D, 6, B, 18),
171 PINGROUP(SPIA, SPI1, SPI2, SPI3, GMI, B, 10, D, 30, C, 4),
172 PINGROUP(SPIB, SPI1, SPI2, SPI3, GMI, B, 11, D, 28, C, 6),
173 PINGROUP(SPIC, SPI1, SPI2, SPI3, GMI, B, 12, D, 26, C, 8),
174 PINGROUP(SPID, SPI2, SPI1, SPI2_ALT, GMI, B, 13, D, 24, C, 10),
175 PINGROUP(SPIE, SPI2, SPI1, SPI2_ALT, GMI, B, 14, D, 22, C, 12),
176 PINGROUP(SPIF, SPI3, SPI1, SPI2, RSVD, B, 15, D, 20, C, 14),
177 PINGROUP(SPIG, SPI3, SPI2, SPI2_ALT, I2C, B, 16, D, 18, C, 16),
178 PINGROUP(SPIH, SPI3, SPI2, SPI2_ALT, I2C, B, 17, D, 16, C, 18),
179 PINGROUP(UAA, SPI3, MIPI_HS, UARTA, ULPI, B, 18, A, 0, D, 0),
180 PINGROUP(UAB, SPI2, MIPI_HS, UARTA, ULPI, B, 19, A, 2, D, 2),
181 PINGROUP(UAC, OWR, RSVD, RSVD, RSVD, B, 20, A, 4, D, 4),
182 PINGROUP(UAD, IRDA, SPDIF, UARTA, SPI4, B, 21, A, 6, D, 6),
183 PINGROUP(UCA, UARTC, RSVD, GMI, RSVD, B, 22, B, 16, D, 8),
184 PINGROUP(UCB, UARTC, PWM, GMI, RSVD, B, 23, B, 18, D, 10),
185 PINGROUP(UDA, SPI1, RSVD, UARTD, ULPI, D, 13, A, 8, E, 16),
186 /* these pin groups only have pullup and pull down control */
187 PINGROUP(CK32, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 14),
188 PINGROUP(DDRC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, D, 26),
189 PINGROUP(PMCA, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 4),
190 PINGROUP(PMCB, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 6),
191 PINGROUP(PMCC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 8),
192 PINGROUP(PMCD, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 10),
193 PINGROUP(PMCE, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 12),
194 PINGROUP(XM2C, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 30),
195 PINGROUP(XM2D, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 28),
196};
197
198static char *tegra_mux_names[TEGRA_MAX_MUX] = {
199 [TEGRA_MUX_AHB_CLK] = "AHB_CLK",
200 [TEGRA_MUX_APB_CLK] = "APB_CLK",
201 [TEGRA_MUX_AUDIO_SYNC] = "AUDIO_SYNC",
202 [TEGRA_MUX_CRT] = "CRT",
203 [TEGRA_MUX_DAP1] = "DAP1",
204 [TEGRA_MUX_DAP2] = "DAP2",
205 [TEGRA_MUX_DAP3] = "DAP3",
206 [TEGRA_MUX_DAP4] = "DAP4",
207 [TEGRA_MUX_DAP5] = "DAP5",
208 [TEGRA_MUX_DISPLAYA] = "DISPLAYA",
209 [TEGRA_MUX_DISPLAYB] = "DISPLAYB",
210 [TEGRA_MUX_EMC_TEST0_DLL] = "EMC_TEST0_DLL",
211 [TEGRA_MUX_EMC_TEST1_DLL] = "EMC_TEST1_DLL",
212 [TEGRA_MUX_GMI] = "GMI",
213 [TEGRA_MUX_GMI_INT] = "GMI_INT",
214 [TEGRA_MUX_HDMI] = "HDMI",
215 [TEGRA_MUX_I2C] = "I2C",
216 [TEGRA_MUX_I2C2] = "I2C2",
217 [TEGRA_MUX_I2C3] = "I2C3",
218 [TEGRA_MUX_IDE] = "IDE",
219 [TEGRA_MUX_IRDA] = "IRDA",
220 [TEGRA_MUX_KBC] = "KBC",
221 [TEGRA_MUX_MIO] = "MIO",
222 [TEGRA_MUX_MIPI_HS] = "MIPI_HS",
223 [TEGRA_MUX_NAND] = "NAND",
224 [TEGRA_MUX_OSC] = "OSC",
225 [TEGRA_MUX_OWR] = "OWR",
226 [TEGRA_MUX_PCIE] = "PCIE",
227 [TEGRA_MUX_PLLA_OUT] = "PLLA_OUT",
228 [TEGRA_MUX_PLLC_OUT1] = "PLLC_OUT1",
229 [TEGRA_MUX_PLLM_OUT1] = "PLLM_OUT1",
230 [TEGRA_MUX_PLLP_OUT2] = "PLLP_OUT2",
231 [TEGRA_MUX_PLLP_OUT3] = "PLLP_OUT3",
232 [TEGRA_MUX_PLLP_OUT4] = "PLLP_OUT4",
233 [TEGRA_MUX_PWM] = "PWM",
234 [TEGRA_MUX_PWR_INTR] = "PWR_INTR",
235 [TEGRA_MUX_PWR_ON] = "PWR_ON",
236 [TEGRA_MUX_RTCK] = "RTCK",
237 [TEGRA_MUX_SDIO1] = "SDIO1",
238 [TEGRA_MUX_SDIO2] = "SDIO2",
239 [TEGRA_MUX_SDIO3] = "SDIO3",
240 [TEGRA_MUX_SDIO4] = "SDIO4",
241 [TEGRA_MUX_SFLASH] = "SFLASH",
242 [TEGRA_MUX_SPDIF] = "SPDIF",
243 [TEGRA_MUX_SPI1] = "SPI1",
244 [TEGRA_MUX_SPI2] = "SPI2",
245 [TEGRA_MUX_SPI2_ALT] = "SPI2_ALT",
246 [TEGRA_MUX_SPI3] = "SPI3",
247 [TEGRA_MUX_SPI4] = "SPI4",
248 [TEGRA_MUX_TRACE] = "TRACE",
249 [TEGRA_MUX_TWC] = "TWC",
250 [TEGRA_MUX_UARTA] = "UARTA",
251 [TEGRA_MUX_UARTB] = "UARTB",
252 [TEGRA_MUX_UARTC] = "UARTC",
253 [TEGRA_MUX_UARTD] = "UARTD",
254 [TEGRA_MUX_UARTE] = "UARTE",
255 [TEGRA_MUX_ULPI] = "ULPI",
256 [TEGRA_MUX_VI] = "VI",
257 [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK",
258 [TEGRA_MUX_XIO] = "XIO",
259};
260
261struct tegra_drive_pingroup_desc {
262 const char *name;
263 s16 reg;
264};
265
266#define DRIVE_PINGROUP(pg_name, r) \
267 [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
268 .name = #pg_name, \
269 .reg = r \
270 }
271
272static const struct tegra_drive_pingroup_desc drive_pingroups[TEGRA_MAX_PINGROUP] = {
273 DRIVE_PINGROUP(AO1, 0x868),
274 DRIVE_PINGROUP(AO2, 0x86c),
275 DRIVE_PINGROUP(AT1, 0x870),
276 DRIVE_PINGROUP(AT2, 0x874),
277 DRIVE_PINGROUP(CDEV1, 0x878),
278 DRIVE_PINGROUP(CDEV2, 0x87c),
279 DRIVE_PINGROUP(CSUS, 0x880),
280 DRIVE_PINGROUP(DAP1, 0x884),
281 DRIVE_PINGROUP(DAP2, 0x888),
282 DRIVE_PINGROUP(DAP3, 0x88c),
283 DRIVE_PINGROUP(DAP4, 0x890),
284 DRIVE_PINGROUP(DBG, 0x894),
285 DRIVE_PINGROUP(LCD1, 0x898),
286 DRIVE_PINGROUP(LCD2, 0x89c),
287 DRIVE_PINGROUP(SDMMC2, 0x8a0),
288 DRIVE_PINGROUP(SDMMC3, 0x8a4),
289 DRIVE_PINGROUP(SPI, 0x8a8),
290 DRIVE_PINGROUP(UAA, 0x8ac),
291 DRIVE_PINGROUP(UAB, 0x8b0),
292 DRIVE_PINGROUP(UART2, 0x8b4),
293 DRIVE_PINGROUP(UART3, 0x8b8),
294 DRIVE_PINGROUP(VI1, 0x8bc),
295 DRIVE_PINGROUP(VI2, 0x8c0),
296 DRIVE_PINGROUP(XM2A, 0x8c4),
297 DRIVE_PINGROUP(XM2C, 0x8c8),
298 DRIVE_PINGROUP(XM2D, 0x8cc),
299 DRIVE_PINGROUP(XM2CLK, 0x8d0),
300 DRIVE_PINGROUP(MEMCOMP, 0x8d4),
301};
302
303static const char *tegra_drive_names[TEGRA_MAX_DRIVE] = {
304 [TEGRA_DRIVE_DIV_8] = "DIV_8",
305 [TEGRA_DRIVE_DIV_4] = "DIV_4",
306 [TEGRA_DRIVE_DIV_2] = "DIV_2",
307 [TEGRA_DRIVE_DIV_1] = "DIV_1",
308};
309
310static const char *tegra_slew_names[TEGRA_MAX_SLEW] = {
311 [TEGRA_SLEW_FASTEST] = "FASTEST",
312 [TEGRA_SLEW_FAST] = "FAST",
313 [TEGRA_SLEW_SLOW] = "SLOW",
314 [TEGRA_SLEW_SLOWEST] = "SLOWEST",
315};
316
317static DEFINE_SPINLOCK(mux_lock);
318
319static const char *pingroup_name(enum tegra_pingroup pg)
320{
321 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
322 return "<UNKNOWN>";
323
324 return pingroups[pg].name;
325}
326
327static const char *func_name(enum tegra_mux_func func)
328{
329 if (func == TEGRA_MUX_RSVD1)
330 return "RSVD1";
331
332 if (func == TEGRA_MUX_RSVD2)
333 return "RSVD2";
334
335 if (func == TEGRA_MUX_RSVD3)
336 return "RSVD3";
337
338 if (func == TEGRA_MUX_RSVD4)
339 return "RSVD4";
340
341 if (func == TEGRA_MUX_NONE)
342 return "NONE";
343
344 if (func < 0 || func >= TEGRA_MAX_MUX)
345 return "<UNKNOWN>";
346
347 return tegra_mux_names[func];
348}
349
350
351static const char *tri_name(unsigned long val)
352{
353 return val ? "TRISTATE" : "NORMAL";
354}
355
356static const char *pupd_name(unsigned long val)
357{
358 switch (val) {
359 case 0:
360 return "NORMAL";
361
362 case 1:
363 return "PULL_DOWN";
364
365 case 2:
366 return "PULL_UP";
367
368 default:
369 return "RSVD";
370 }
371}
372
373
374static inline unsigned long pg_readl(unsigned long offset)
375{
376 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
377}
378
379static inline void pg_writel(unsigned long value, unsigned long offset)
380{
381 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
382}
383
384int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func)
385{
386 int mux = -1;
387 int i;
388 unsigned long reg;
389 unsigned long flags;
390
391 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
392 return -ERANGE;
393
394 if (pingroups[pg].mux_reg == REG_N)
395 return -EINVAL;
396
397 if (func < 0)
398 return -ERANGE;
399
400 if (func & TEGRA_MUX_RSVD) {
401 mux = func & 0x3;
402 } else {
403 for (i = 0; i < 4; i++) {
404 if (pingroups[pg].funcs[i] == func) {
405 mux = i;
406 break;
407 }
408 }
409 }
410
411 if (mux < 0)
412 return -EINVAL;
413
414 spin_lock_irqsave(&mux_lock, flags);
415
416 reg = pg_readl(TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg));
417 reg &= ~(0x3 << pingroups[pg].mux_bit);
418 reg |= mux << pingroups[pg].mux_bit;
419 pg_writel(reg, TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg));
420
421 spin_unlock_irqrestore(&mux_lock, flags);
422
423 return 0;
424}
425
426int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
427 enum tegra_tristate tristate)
428{
429 unsigned long reg;
430 unsigned long flags;
431
432 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
433 return -ERANGE;
434
435 if (pingroups[pg].tri_reg == REG_N)
436 return -EINVAL;
437
438 spin_lock_irqsave(&mux_lock, flags);
439
440 reg = pg_readl(TEGRA_TRI_STATE(pingroups[pg].tri_reg));
441 reg &= ~(0x1 << pingroups[pg].tri_bit);
442 if (tristate)
443 reg |= 1 << pingroups[pg].tri_bit;
444 pg_writel(reg, TEGRA_TRI_STATE(pingroups[pg].tri_reg));
445
446 spin_unlock_irqrestore(&mux_lock, flags);
447
448 return 0;
449}
450
451int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
452 enum tegra_pullupdown pupd)
453{
454 unsigned long reg;
455 unsigned long flags;
456
457 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
458 return -ERANGE;
459
460 if (pingroups[pg].pupd_reg == REG_N)
461 return -EINVAL;
462
463 if (pupd != TEGRA_PUPD_NORMAL &&
464 pupd != TEGRA_PUPD_PULL_DOWN &&
465 pupd != TEGRA_PUPD_PULL_UP)
466 return -EINVAL;
467
468
469 spin_lock_irqsave(&mux_lock, flags);
470
471 reg = pg_readl(TEGRA_PP_PU_PD(pingroups[pg].pupd_reg));
472 reg &= ~(0x3 << pingroups[pg].pupd_bit);
473 reg |= pupd << pingroups[pg].pupd_bit;
474 pg_writel(reg, TEGRA_PP_PU_PD(pingroups[pg].pupd_reg));
475
476 spin_unlock_irqrestore(&mux_lock, flags);
477
478 return 0;
479}
480
481void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup,
482 enum tegra_mux_func func,
483 enum tegra_pullupdown pupd,
484 enum tegra_tristate tristate)
485{
486 int err;
487
488 if (pingroups[pingroup].mux_reg != REG_N) {
489 err = tegra_pinmux_set_func(pingroup, func);
490 if (err < 0)
491 pr_err("pinmux: can't set pingroup %s func to %s: %d\n",
492 pingroup_name(pingroup), func_name(func), err);
493 }
494
495 if (pingroups[pingroup].pupd_reg != REG_N) {
496 err = tegra_pinmux_set_pullupdown(pingroup, pupd);
497 if (err < 0)
498 pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n",
499 pingroup_name(pingroup), pupd_name(pupd), err);
500 }
501
502 if (pingroups[pingroup].tri_reg != REG_N) {
503 err = tegra_pinmux_set_tristate(pingroup, tristate);
504 if (err < 0)
505 pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
506 pingroup_name(pingroup), tri_name(func), err);
507 }
508}
509
510
511
512void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len)
513{
514 int i;
515
516 for (i = 0; i < len; i++)
517 tegra_pinmux_config_pingroup(config[i].pingroup,
518 config[i].func,
519 config[i].pupd,
520 config[i].tristate);
521}
522
523static const char *drive_pinmux_name(enum tegra_drive_pingroup pg)
524{
525 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
526 return "<UNKNOWN>";
527
528 return drive_pingroups[pg].name;
529}
530
531static const char *enable_name(unsigned long val)
532{
533 return val ? "ENABLE" : "DISABLE";
534}
535
536static const char *drive_name(unsigned long val)
537{
538 if (val >= TEGRA_MAX_DRIVE)
539 return "<UNKNOWN>";
540
541 return tegra_drive_names[val];
542}
543
544static const char *slew_name(unsigned long val)
545{
546 if (val >= TEGRA_MAX_SLEW)
547 return "<UNKNOWN>";
548
549 return tegra_slew_names[val];
550}
551
552static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
553 enum tegra_hsm hsm)
554{
555 unsigned long flags;
556 u32 reg;
557 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
558 return -ERANGE;
559
560 if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE)
561 return -EINVAL;
562
563 spin_lock_irqsave(&mux_lock, flags);
564
565 reg = pg_readl(drive_pingroups[pg].reg);
566 if (hsm == TEGRA_HSM_ENABLE)
567 reg |= (1 << 2);
568 else
569 reg &= ~(1 << 2);
570 pg_writel(reg, drive_pingroups[pg].reg);
571
572 spin_unlock_irqrestore(&mux_lock, flags);
573
574 return 0;
575}
576
577static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
578 enum tegra_schmitt schmitt)
579{
580 unsigned long flags;
581 u32 reg;
582 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
583 return -ERANGE;
584
585 if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE)
586 return -EINVAL;
587
588 spin_lock_irqsave(&mux_lock, flags);
589
590 reg = pg_readl(drive_pingroups[pg].reg);
591 if (schmitt == TEGRA_SCHMITT_ENABLE)
592 reg |= (1 << 3);
593 else
594 reg &= ~(1 << 3);
595 pg_writel(reg, drive_pingroups[pg].reg);
596
597 spin_unlock_irqrestore(&mux_lock, flags);
598
599 return 0;
600}
601
602static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
603 enum tegra_drive drive)
604{
605 unsigned long flags;
606 u32 reg;
607 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
608 return -ERANGE;
609
610 if (drive < 0 || drive >= TEGRA_MAX_DRIVE)
611 return -EINVAL;
612
613 spin_lock_irqsave(&mux_lock, flags);
614
615 reg = pg_readl(drive_pingroups[pg].reg);
616 reg &= ~(0x3 << 4);
617 reg |= drive << 4;
618 pg_writel(reg, drive_pingroups[pg].reg);
619
620 spin_unlock_irqrestore(&mux_lock, flags);
621
622 return 0;
623}
624
625static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
626 enum tegra_pull_strength pull_down)
627{
628 unsigned long flags;
629 u32 reg;
630 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
631 return -ERANGE;
632
633 if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL)
634 return -EINVAL;
635
636 spin_lock_irqsave(&mux_lock, flags);
637
638 reg = pg_readl(drive_pingroups[pg].reg);
639 reg &= ~(0x1f << 12);
640 reg |= pull_down << 12;
641 pg_writel(reg, drive_pingroups[pg].reg);
642
643 spin_unlock_irqrestore(&mux_lock, flags);
644
645 return 0;
646}
647
648static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
649 enum tegra_pull_strength pull_up)
650{
651 unsigned long flags;
652 u32 reg;
653 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
654 return -ERANGE;
655
656 if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL)
657 return -EINVAL;
658
659 spin_lock_irqsave(&mux_lock, flags);
660
661 reg = pg_readl(drive_pingroups[pg].reg);
662 reg &= ~(0x1f << 12);
663 reg |= pull_up << 12;
664 pg_writel(reg, drive_pingroups[pg].reg);
665
666 spin_unlock_irqrestore(&mux_lock, flags);
667
668 return 0;
669}
670
671static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
672 enum tegra_slew slew_rising)
673{
674 unsigned long flags;
675 u32 reg;
676 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
677 return -ERANGE;
678
679 if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW)
680 return -EINVAL;
681
682 spin_lock_irqsave(&mux_lock, flags);
683
684 reg = pg_readl(drive_pingroups[pg].reg);
685 reg &= ~(0x3 << 28);
686 reg |= slew_rising << 28;
687 pg_writel(reg, drive_pingroups[pg].reg);
688
689 spin_unlock_irqrestore(&mux_lock, flags);
690
691 return 0;
692}
693
694static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
695 enum tegra_slew slew_falling)
696{
697 unsigned long flags;
698 u32 reg;
699 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
700 return -ERANGE;
701
702 if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW)
703 return -EINVAL;
704
705 spin_lock_irqsave(&mux_lock, flags);
706
707 reg = pg_readl(drive_pingroups[pg].reg);
708 reg &= ~(0x3 << 30);
709 reg |= slew_falling << 30;
710 pg_writel(reg, drive_pingroups[pg].reg);
711
712 spin_unlock_irqrestore(&mux_lock, flags);
713
714 return 0;
715}
716
717static void tegra_drive_pinmux_config_pingroup(enum tegra_drive_pingroup pingroup,
718 enum tegra_hsm hsm,
719 enum tegra_schmitt schmitt,
720 enum tegra_drive drive,
721 enum tegra_pull_strength pull_down,
722 enum tegra_pull_strength pull_up,
723 enum tegra_slew slew_rising,
724 enum tegra_slew slew_falling)
725{
726 int err;
727
728 err = tegra_drive_pinmux_set_hsm(pingroup, hsm);
729 if (err < 0)
730 pr_err("pinmux: can't set pingroup %s hsm to %s: %d\n",
731 drive_pinmux_name(pingroup),
732 enable_name(hsm), err);
733
734 err = tegra_drive_pinmux_set_schmitt(pingroup, schmitt);
735 if (err < 0)
736 pr_err("pinmux: can't set pingroup %s schmitt to %s: %d\n",
737 drive_pinmux_name(pingroup),
738 enable_name(schmitt), err);
739
740 err = tegra_drive_pinmux_set_drive(pingroup, drive);
741 if (err < 0)
742 pr_err("pinmux: can't set pingroup %s drive to %s: %d\n",
743 drive_pinmux_name(pingroup),
744 drive_name(drive), err);
745
746 err = tegra_drive_pinmux_set_pull_down(pingroup, pull_down);
747 if (err < 0)
748 pr_err("pinmux: can't set pingroup %s pull down to %d: %d\n",
749 drive_pinmux_name(pingroup),
750 pull_down, err);
751
752 err = tegra_drive_pinmux_set_pull_up(pingroup, pull_up);
753 if (err < 0)
754 pr_err("pinmux: can't set pingroup %s pull up to %d: %d\n",
755 drive_pinmux_name(pingroup),
756 pull_up, err);
757
758 err = tegra_drive_pinmux_set_slew_rising(pingroup, slew_rising);
759 if (err < 0)
760 pr_err("pinmux: can't set pingroup %s rising slew to %s: %d\n",
761 drive_pinmux_name(pingroup),
762 slew_name(slew_rising), err);
763
764 err = tegra_drive_pinmux_set_slew_falling(pingroup, slew_falling);
765 if (err < 0)
766 pr_err("pinmux: can't set pingroup %s falling slew to %s: %d\n",
767 drive_pinmux_name(pingroup),
768 slew_name(slew_falling), err);
769}
770
771void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
772 int len)
773{
774 int i;
775
776 for (i = 0; i < len; i++)
777 tegra_drive_pinmux_config_pingroup(config[i].pingroup,
778 config[i].hsm,
779 config[i].schmitt,
780 config[i].drive,
781 config[i].pull_down,
782 config[i].pull_up,
783 config[i].slew_rising,
784 config[i].slew_falling);
785}
786
787
788#ifdef CONFIG_DEBUG_FS
789
790#include <linux/debugfs.h>
791#include <linux/seq_file.h>
792
793static void dbg_pad_field(struct seq_file *s, int len)
794{
795 seq_putc(s, ',');
796
797 while (len-- > -1)
798 seq_putc(s, ' ');
799}
800
801static int dbg_pinmux_show(struct seq_file *s, void *unused)
802{
803 int i;
804 int len;
805
806 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
807 unsigned long tri;
808 unsigned long mux;
809 unsigned long pupd;
810
811 seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name);
812 len = strlen(pingroups[i].name);
813 dbg_pad_field(s, 5 - len);
814
815 if (pingroups[i].mux_reg == REG_N) {
816 seq_printf(s, "TEGRA_MUX_NONE");
817 len = strlen("NONE");
818 } else {
819 mux = (pg_readl(TEGRA_PP_MUX_CTL(pingroups[i].mux_reg)) >>
820 pingroups[i].mux_bit) & 0x3;
821 if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) {
822 seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
823 len = 5;
824 } else {
825 seq_printf(s, "TEGRA_MUX_%s",
826 tegra_mux_names[pingroups[i].funcs[mux]]);
827 len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]);
828 }
829 }
830 dbg_pad_field(s, 13-len);
831
832 if (pingroups[i].mux_reg == REG_N) {
833 seq_printf(s, "TEGRA_PUPD_NORMAL");
834 len = strlen("NORMAL");
835 } else {
836 pupd = (pg_readl(TEGRA_PP_PU_PD(pingroups[i].pupd_reg)) >>
837 pingroups[i].pupd_bit) & 0x3;
838 seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
839 len = strlen(pupd_name(pupd));
840 }
841 dbg_pad_field(s, 9 - len);
842
843 if (pingroups[i].tri_reg == REG_N) {
844 seq_printf(s, "TEGRA_TRI_NORMAL");
845 } else {
846 tri = (pg_readl(TEGRA_TRI_STATE(pingroups[i].tri_reg)) >>
847 pingroups[i].tri_bit) & 0x1;
848
849 seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
850 }
851 seq_printf(s, "},\n");
852 }
853 return 0;
854}
855
856static int dbg_pinmux_open(struct inode *inode, struct file *file)
857{
858 return single_open(file, dbg_pinmux_show, &inode->i_private);
859}
860
861static const struct file_operations debug_fops = {
862 .open = dbg_pinmux_open,
863 .read = seq_read,
864 .llseek = seq_lseek,
865 .release = single_release,
866};
867
868static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
869{
870 int i;
871 int len;
872
873 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
874 u32 reg;
875
876 seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s",
877 drive_pingroups[i].name);
878 len = strlen(drive_pingroups[i].name);
879 dbg_pad_field(s, 7 - len);
880
881
882 reg = pg_readl(drive_pingroups[i].reg);
883 if (HSM_EN(reg)) {
884 seq_printf(s, "TEGRA_HSM_ENABLE");
885 len = 16;
886 } else {
887 seq_printf(s, "TEGRA_HSM_DISABLE");
888 len = 17;
889 }
890 dbg_pad_field(s, 17 - len);
891
892 if (SCHMT_EN(reg)) {
893 seq_printf(s, "TEGRA_SCHMITT_ENABLE");
894 len = 21;
895 } else {
896 seq_printf(s, "TEGRA_SCHMITT_DISABLE");
897 len = 22;
898 }
899 dbg_pad_field(s, 22 - len);
900
901 seq_printf(s, "TEGRA_DRIVE_%s", drive_name(LPMD(reg)));
902 len = strlen(drive_name(LPMD(reg)));
903 dbg_pad_field(s, 5 - len);
904
905 seq_printf(s, "TEGRA_PULL_%d", DRVDN(reg));
906 len = DRVDN(reg) < 10 ? 1 : 2;
907 dbg_pad_field(s, 2 - len);
908
909 seq_printf(s, "TEGRA_PULL_%d", DRVUP(reg));
910 len = DRVUP(reg) < 10 ? 1 : 2;
911 dbg_pad_field(s, 2 - len);
912
913 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWR(reg)));
914 len = strlen(slew_name(SLWR(reg)));
915 dbg_pad_field(s, 7 - len);
916
917 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWF(reg)));
918
919 seq_printf(s, "},\n");
920 }
921 return 0;
922}
923
924static int dbg_drive_pinmux_open(struct inode *inode, struct file *file)
925{
926 return single_open(file, dbg_drive_pinmux_show, &inode->i_private);
927}
928
929static const struct file_operations debug_drive_fops = {
930 .open = dbg_drive_pinmux_open,
931 .read = seq_read,
932 .llseek = seq_lseek,
933 .release = single_release,
934};
935
936static int __init tegra_pinmux_debuginit(void)
937{
938 (void) debugfs_create_file("tegra_pinmux", S_IRUGO,
939 NULL, NULL, &debug_fops);
940 (void) debugfs_create_file("tegra_pinmux_drive", S_IRUGO,
941 NULL, NULL, &debug_drive_fops);
942 return 0;
943}
944late_initcall(tegra_pinmux_debuginit);
945#endif