aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/arm/mach-tegra/Makefile2
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux.h348
-rw-r--r--arch/arm/mach-tegra/pinmux.c945
3 files changed, 1295 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 122f7dc4eaa1..5e47a71af471 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -4,6 +4,8 @@ obj-y += irq.o
4obj-y += clock.o 4obj-y += clock.o
5obj-y += timer.o 5obj-y += timer.o
6obj-y += gpio.o 6obj-y += gpio.o
7obj-y += pinmux.o
8obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o
7obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o 9obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o
8obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o 10obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
9obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 11obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h
new file mode 100644
index 000000000000..41c8ce5b7c27
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinmux.h
@@ -0,0 +1,348 @@
1/*
2 * linux/arch/arm/mach-tegra/include/mach/pinmux.h
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#ifndef __MACH_TEGRA_PINMUX_H
18#define __MACH_TEGRA_PINMUX_H
19
20enum tegra_pingroup {
21 TEGRA_PINGROUP_ATA = 0,
22 TEGRA_PINGROUP_ATB,
23 TEGRA_PINGROUP_ATC,
24 TEGRA_PINGROUP_ATD,
25 TEGRA_PINGROUP_ATE,
26 TEGRA_PINGROUP_CDEV1,
27 TEGRA_PINGROUP_CDEV2,
28 TEGRA_PINGROUP_CRTP,
29 TEGRA_PINGROUP_CSUS,
30 TEGRA_PINGROUP_DAP1,
31 TEGRA_PINGROUP_DAP2,
32 TEGRA_PINGROUP_DAP3,
33 TEGRA_PINGROUP_DAP4,
34 TEGRA_PINGROUP_DDC,
35 TEGRA_PINGROUP_DTA,
36 TEGRA_PINGROUP_DTB,
37 TEGRA_PINGROUP_DTC,
38 TEGRA_PINGROUP_DTD,
39 TEGRA_PINGROUP_DTE,
40 TEGRA_PINGROUP_DTF,
41 TEGRA_PINGROUP_GMA,
42 TEGRA_PINGROUP_GMB,
43 TEGRA_PINGROUP_GMC,
44 TEGRA_PINGROUP_GMD,
45 TEGRA_PINGROUP_GME,
46 TEGRA_PINGROUP_GPU,
47 TEGRA_PINGROUP_GPU7,
48 TEGRA_PINGROUP_GPV,
49 TEGRA_PINGROUP_HDINT,
50 TEGRA_PINGROUP_I2CP,
51 TEGRA_PINGROUP_IRRX,
52 TEGRA_PINGROUP_IRTX,
53 TEGRA_PINGROUP_KBCA,
54 TEGRA_PINGROUP_KBCB,
55 TEGRA_PINGROUP_KBCC,
56 TEGRA_PINGROUP_KBCD,
57 TEGRA_PINGROUP_KBCE,
58 TEGRA_PINGROUP_KBCF,
59 TEGRA_PINGROUP_LCSN,
60 TEGRA_PINGROUP_LD0,
61 TEGRA_PINGROUP_LD1,
62 TEGRA_PINGROUP_LD10,
63 TEGRA_PINGROUP_LD11,
64 TEGRA_PINGROUP_LD12,
65 TEGRA_PINGROUP_LD13,
66 TEGRA_PINGROUP_LD14,
67 TEGRA_PINGROUP_LD15,
68 TEGRA_PINGROUP_LD16,
69 TEGRA_PINGROUP_LD17,
70 TEGRA_PINGROUP_LD2,
71 TEGRA_PINGROUP_LD3,
72 TEGRA_PINGROUP_LD4,
73 TEGRA_PINGROUP_LD5,
74 TEGRA_PINGROUP_LD6,
75 TEGRA_PINGROUP_LD7,
76 TEGRA_PINGROUP_LD8,
77 TEGRA_PINGROUP_LD9,
78 TEGRA_PINGROUP_LDC,
79 TEGRA_PINGROUP_LDI,
80 TEGRA_PINGROUP_LHP0,
81 TEGRA_PINGROUP_LHP1,
82 TEGRA_PINGROUP_LHP2,
83 TEGRA_PINGROUP_LHS,
84 TEGRA_PINGROUP_LM0,
85 TEGRA_PINGROUP_LM1,
86 TEGRA_PINGROUP_LPP,
87 TEGRA_PINGROUP_LPW0,
88 TEGRA_PINGROUP_LPW1,
89 TEGRA_PINGROUP_LPW2,
90 TEGRA_PINGROUP_LSC0,
91 TEGRA_PINGROUP_LSC1,
92 TEGRA_PINGROUP_LSCK,
93 TEGRA_PINGROUP_LSDA,
94 TEGRA_PINGROUP_LSDI,
95 TEGRA_PINGROUP_LSPI,
96 TEGRA_PINGROUP_LVP0,
97 TEGRA_PINGROUP_LVP1,
98 TEGRA_PINGROUP_LVS,
99 TEGRA_PINGROUP_OWC,
100 TEGRA_PINGROUP_PMC,
101 TEGRA_PINGROUP_PTA,
102 TEGRA_PINGROUP_RM,
103 TEGRA_PINGROUP_SDB,
104 TEGRA_PINGROUP_SDC,
105 TEGRA_PINGROUP_SDD,
106 TEGRA_PINGROUP_SDIO1,
107 TEGRA_PINGROUP_SLXA,
108 TEGRA_PINGROUP_SLXC,
109 TEGRA_PINGROUP_SLXD,
110 TEGRA_PINGROUP_SLXK,
111 TEGRA_PINGROUP_SPDI,
112 TEGRA_PINGROUP_SPDO,
113 TEGRA_PINGROUP_SPIA,
114 TEGRA_PINGROUP_SPIB,
115 TEGRA_PINGROUP_SPIC,
116 TEGRA_PINGROUP_SPID,
117 TEGRA_PINGROUP_SPIE,
118 TEGRA_PINGROUP_SPIF,
119 TEGRA_PINGROUP_SPIG,
120 TEGRA_PINGROUP_SPIH,
121 TEGRA_PINGROUP_UAA,
122 TEGRA_PINGROUP_UAB,
123 TEGRA_PINGROUP_UAC,
124 TEGRA_PINGROUP_UAD,
125 TEGRA_PINGROUP_UCA,
126 TEGRA_PINGROUP_UCB,
127 TEGRA_PINGROUP_UDA,
128 /* these pin groups only have pullup and pull down control */
129 TEGRA_PINGROUP_CK32,
130 TEGRA_PINGROUP_DDRC,
131 TEGRA_PINGROUP_PMCA,
132 TEGRA_PINGROUP_PMCB,
133 TEGRA_PINGROUP_PMCC,
134 TEGRA_PINGROUP_PMCD,
135 TEGRA_PINGROUP_PMCE,
136 TEGRA_PINGROUP_XM2C,
137 TEGRA_PINGROUP_XM2D,
138 TEGRA_MAX_PINGROUP,
139};
140
141enum tegra_mux_func {
142 TEGRA_MUX_RSVD = 0x8000,
143 TEGRA_MUX_RSVD1 = 0x8000,
144 TEGRA_MUX_RSVD2 = 0x8001,
145 TEGRA_MUX_RSVD3 = 0x8002,
146 TEGRA_MUX_RSVD4 = 0x8003,
147 TEGRA_MUX_NONE = -1,
148 TEGRA_MUX_AHB_CLK,
149 TEGRA_MUX_APB_CLK,
150 TEGRA_MUX_AUDIO_SYNC,
151 TEGRA_MUX_CRT,
152 TEGRA_MUX_DAP1,
153 TEGRA_MUX_DAP2,
154 TEGRA_MUX_DAP3,
155 TEGRA_MUX_DAP4,
156 TEGRA_MUX_DAP5,
157 TEGRA_MUX_DISPLAYA,
158 TEGRA_MUX_DISPLAYB,
159 TEGRA_MUX_EMC_TEST0_DLL,
160 TEGRA_MUX_EMC_TEST1_DLL,
161 TEGRA_MUX_GMI,
162 TEGRA_MUX_GMI_INT,
163 TEGRA_MUX_HDMI,
164 TEGRA_MUX_I2C,
165 TEGRA_MUX_I2C2,
166 TEGRA_MUX_I2C3,
167 TEGRA_MUX_IDE,
168 TEGRA_MUX_IRDA,
169 TEGRA_MUX_KBC,
170 TEGRA_MUX_MIO,
171 TEGRA_MUX_MIPI_HS,
172 TEGRA_MUX_NAND,
173 TEGRA_MUX_OSC,
174 TEGRA_MUX_OWR,
175 TEGRA_MUX_PCIE,
176 TEGRA_MUX_PLLA_OUT,
177 TEGRA_MUX_PLLC_OUT1,
178 TEGRA_MUX_PLLM_OUT1,
179 TEGRA_MUX_PLLP_OUT2,
180 TEGRA_MUX_PLLP_OUT3,
181 TEGRA_MUX_PLLP_OUT4,
182 TEGRA_MUX_PWM,
183 TEGRA_MUX_PWR_INTR,
184 TEGRA_MUX_PWR_ON,
185 TEGRA_MUX_RTCK,
186 TEGRA_MUX_SDIO1,
187 TEGRA_MUX_SDIO2,
188 TEGRA_MUX_SDIO3,
189 TEGRA_MUX_SDIO4,
190 TEGRA_MUX_SFLASH,
191 TEGRA_MUX_SPDIF,
192 TEGRA_MUX_SPI1,
193 TEGRA_MUX_SPI2,
194 TEGRA_MUX_SPI2_ALT,
195 TEGRA_MUX_SPI3,
196 TEGRA_MUX_SPI4,
197 TEGRA_MUX_TRACE,
198 TEGRA_MUX_TWC,
199 TEGRA_MUX_UARTA,
200 TEGRA_MUX_UARTB,
201 TEGRA_MUX_UARTC,
202 TEGRA_MUX_UARTD,
203 TEGRA_MUX_UARTE,
204 TEGRA_MUX_ULPI,
205 TEGRA_MUX_VI,
206 TEGRA_MUX_VI_SENSOR_CLK,
207 TEGRA_MUX_XIO,
208 TEGRA_MAX_MUX,
209};
210
211enum tegra_pullupdown {
212 TEGRA_PUPD_NORMAL = 0,
213 TEGRA_PUPD_PULL_DOWN,
214 TEGRA_PUPD_PULL_UP,
215};
216
217enum tegra_tristate {
218 TEGRA_TRI_NORMAL = 0,
219 TEGRA_TRI_TRISTATE = 1,
220};
221
222struct tegra_pingroup_config {
223 enum tegra_pingroup pingroup;
224 enum tegra_mux_func func;
225 enum tegra_pullupdown pupd;
226 enum tegra_tristate tristate;
227};
228
229enum tegra_slew {
230 TEGRA_SLEW_FASTEST = 0,
231 TEGRA_SLEW_FAST,
232 TEGRA_SLEW_SLOW,
233 TEGRA_SLEW_SLOWEST,
234 TEGRA_MAX_SLEW,
235};
236
237enum tegra_pull_strength {
238 TEGRA_PULL_0 = 0,
239 TEGRA_PULL_1,
240 TEGRA_PULL_2,
241 TEGRA_PULL_3,
242 TEGRA_PULL_4,
243 TEGRA_PULL_5,
244 TEGRA_PULL_6,
245 TEGRA_PULL_7,
246 TEGRA_PULL_8,
247 TEGRA_PULL_9,
248 TEGRA_PULL_10,
249 TEGRA_PULL_11,
250 TEGRA_PULL_12,
251 TEGRA_PULL_13,
252 TEGRA_PULL_14,
253 TEGRA_PULL_15,
254 TEGRA_PULL_16,
255 TEGRA_PULL_17,
256 TEGRA_PULL_18,
257 TEGRA_PULL_19,
258 TEGRA_PULL_20,
259 TEGRA_PULL_21,
260 TEGRA_PULL_22,
261 TEGRA_PULL_23,
262 TEGRA_PULL_24,
263 TEGRA_PULL_25,
264 TEGRA_PULL_26,
265 TEGRA_PULL_27,
266 TEGRA_PULL_28,
267 TEGRA_PULL_29,
268 TEGRA_PULL_30,
269 TEGRA_PULL_31,
270 TEGRA_MAX_PULL,
271};
272
273enum tegra_drive_pingroup {
274 TEGRA_DRIVE_PINGROUP_AO1 = 0,
275 TEGRA_DRIVE_PINGROUP_AO2,
276 TEGRA_DRIVE_PINGROUP_AT1,
277 TEGRA_DRIVE_PINGROUP_AT2,
278 TEGRA_DRIVE_PINGROUP_CDEV1,
279 TEGRA_DRIVE_PINGROUP_CDEV2,
280 TEGRA_DRIVE_PINGROUP_CSUS,
281 TEGRA_DRIVE_PINGROUP_DAP1,
282 TEGRA_DRIVE_PINGROUP_DAP2,
283 TEGRA_DRIVE_PINGROUP_DAP3,
284 TEGRA_DRIVE_PINGROUP_DAP4,
285 TEGRA_DRIVE_PINGROUP_DBG,
286 TEGRA_DRIVE_PINGROUP_LCD1,
287 TEGRA_DRIVE_PINGROUP_LCD2,
288 TEGRA_DRIVE_PINGROUP_SDMMC2,
289 TEGRA_DRIVE_PINGROUP_SDMMC3,
290 TEGRA_DRIVE_PINGROUP_SPI,
291 TEGRA_DRIVE_PINGROUP_UAA,
292 TEGRA_DRIVE_PINGROUP_UAB,
293 TEGRA_DRIVE_PINGROUP_UART2,
294 TEGRA_DRIVE_PINGROUP_UART3,
295 TEGRA_DRIVE_PINGROUP_VI1,
296 TEGRA_DRIVE_PINGROUP_VI2,
297 TEGRA_DRIVE_PINGROUP_XM2A,
298 TEGRA_DRIVE_PINGROUP_XM2C,
299 TEGRA_DRIVE_PINGROUP_XM2D,
300 TEGRA_DRIVE_PINGROUP_XM2CLK,
301 TEGRA_DRIVE_PINGROUP_MEMCOMP,
302 TEGRA_MAX_DRIVE_PINGROUP,
303};
304
305enum tegra_drive {
306 TEGRA_DRIVE_DIV_8 = 0,
307 TEGRA_DRIVE_DIV_4,
308 TEGRA_DRIVE_DIV_2,
309 TEGRA_DRIVE_DIV_1,
310 TEGRA_MAX_DRIVE,
311};
312
313enum tegra_hsm {
314 TEGRA_HSM_DISABLE = 0,
315 TEGRA_HSM_ENABLE,
316};
317
318enum tegra_schmitt {
319 TEGRA_SCHMITT_DISABLE = 0,
320 TEGRA_SCHMITT_ENABLE,
321};
322
323struct tegra_drive_pingroup_config {
324 enum tegra_drive_pingroup pingroup;
325 enum tegra_hsm hsm;
326 enum tegra_schmitt schmitt;
327 enum tegra_drive drive;
328 enum tegra_pull_strength pull_down;
329 enum tegra_pull_strength pull_up;
330 enum tegra_slew slew_rising;
331 enum tegra_slew slew_falling;
332};
333
334int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func);
335int tegra_pinmux_set_tristate(enum tegra_pingroup pg, enum tegra_tristate tristate);
336int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, enum tegra_pullupdown pupd);
337
338void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup,
339 enum tegra_mux_func func, enum tegra_pullupdown pupd,
340 enum tegra_tristate tristate);
341
342void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len);
343
344void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
345 int len);
346
347#endif
348
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