tegra_pinmux.c revision 308335
1/*-
2 * Copyright (c) 2016 Michal Meloun <mmel@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: stable/11/sys/arm/nvidia/tegra_pinmux.c 308335 2016-11-05 10:56:32Z mmel $");
29
30/*
31 * Pin multiplexer driver for Tegra SoCs.
32 */
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/bus.h>
36#include <sys/kernel.h>
37#include <sys/module.h>
38#include <sys/malloc.h>
39#include <sys/rman.h>
40
41#include <machine/bus.h>
42#include <machine/fdt.h>
43
44#include <dev/fdt/fdt_common.h>
45#include <dev/fdt/fdt_pinctrl.h>
46#include <dev/ofw/openfirm.h>
47#include <dev/ofw/ofw_bus.h>
48#include <dev/ofw/ofw_bus_subr.h>
49
50/* Pin multipexor register. */
51#define	TEGRA_MUX_FUNCTION_MASK  0x03
52#define	TEGRA_MUX_FUNCTION_SHIFT 0
53#define	TEGRA_MUX_PUPD_MASK  0x03
54#define	TEGRA_MUX_PUPD_SHIFT 2
55#define	TEGRA_MUX_TRISTATE_SHIFT 4
56#define	TEGRA_MUX_ENABLE_INPUT_SHIFT 5
57#define	TEGRA_MUX_OPEN_DRAIN_SHIFT 6
58#define	TEGRA_MUX_LOCK_SHIFT 7
59#define	TEGRA_MUX_IORESET_SHIFT 8
60#define	TEGRA_MUX_RCV_SEL_SHIFT 9
61
62
63/* Pin goup register. */
64#define	TEGRA_GRP_HSM_SHIFT 2
65#define	TEGRA_GRP_SCHMT_SHIFT 3
66#define	TEGRA_GRP_DRV_TYPE_SHIFT 6
67#define	TEGRA_GRP_DRV_TYPE_MASK 0x03
68#define	TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT 28
69#define	TEGRA_GRP_DRV_DRVDN_SLWR_MASK 0x03
70#define	TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT 30
71#define	TEGRA_GRP_DRV_DRVUP_SLWF_MASK 0x03
72
73struct pinmux_softc {
74	device_t	dev;
75	struct resource	*pad_mem_res;
76	struct resource	*mux_mem_res;
77	struct resource	*mipi_mem_res;
78};
79
80static struct ofw_compat_data compat_data[] = {
81	{"nvidia,tegra124-pinmux",	1},
82	{NULL,				0},
83};
84
85enum prop_id {
86	PROP_ID_PULL,
87	PROP_ID_TRISTATE,
88	PROP_ID_ENABLE_INPUT,
89	PROP_ID_OPEN_DRAIN,
90	PROP_ID_LOCK,
91	PROP_ID_IORESET,
92	PROP_ID_RCV_SEL,
93	PROP_ID_HIGH_SPEED_MODE,
94	PROP_ID_SCHMITT,
95	PROP_ID_LOW_POWER_MODE,
96	PROP_ID_DRIVE_DOWN_STRENGTH,
97	PROP_ID_DRIVE_UP_STRENGTH,
98	PROP_ID_SLEW_RATE_FALLING,
99	PROP_ID_SLEW_RATE_RISING,
100	PROP_ID_DRIVE_TYPE,
101
102	PROP_ID_MAX_ID
103};
104
105/* Numeric based parameters. */
106static const struct prop_name {
107	const char *name;
108	enum prop_id id;
109} prop_names[] = {
110	{"nvidia,pull",			PROP_ID_PULL},
111	{"nvidia,tristate",		PROP_ID_TRISTATE},
112	{"nvidia,enable-input",		PROP_ID_ENABLE_INPUT},
113	{"nvidia,open-drain",		PROP_ID_OPEN_DRAIN},
114	{"nvidia,lock",			PROP_ID_LOCK},
115	{"nvidia,io-reset",		PROP_ID_IORESET},
116	{"nvidia,rcv-sel",		PROP_ID_RCV_SEL},
117	{"nvidia,high-speed-mode",	PROP_ID_HIGH_SPEED_MODE},
118	{"nvidia,schmitt",		PROP_ID_SCHMITT},
119	{"nvidia,low-power-mode",	PROP_ID_LOW_POWER_MODE},
120	{"nvidia,pull-down-strength",	PROP_ID_DRIVE_DOWN_STRENGTH},
121	{"nvidia,pull-up-strength",	PROP_ID_DRIVE_UP_STRENGTH},
122	{"nvidia,slew-rate-falling",	PROP_ID_SLEW_RATE_FALLING},
123	{"nvidia,slew-rate-rising",	PROP_ID_SLEW_RATE_RISING},
124	{"nvidia,drive-type",		PROP_ID_DRIVE_TYPE},
125};
126
127/*
128 * configuration for one pin group.
129 */
130struct pincfg {
131	char	*function;
132	int	params[PROP_ID_MAX_ID];
133};
134#define	GPIO_BANK_A	 0
135#define	GPIO_BANK_B	 1
136#define	GPIO_BANK_C	 2
137#define	GPIO_BANK_D	 3
138#define	GPIO_BANK_E	 4
139#define	GPIO_BANK_F	 5
140#define	GPIO_BANK_G	 6
141#define	GPIO_BANK_H	 7
142#define	GPIO_BANK_I	 8
143#define	GPIO_BANK_J	 9
144#define	GPIO_BANK_K	10
145#define	GPIO_BANK_L	11
146#define	GPIO_BANK_M	12
147#define	GPIO_BANK_N	13
148#define	GPIO_BANK_O	14
149#define	GPIO_BANK_P	15
150#define	GPIO_BANK_Q	16
151#define	GPIO_BANK_R	17
152#define	GPIO_BANK_S	18
153#define	GPIO_BANK_T	19
154#define	GPIO_BANK_U	20
155#define	GPIO_BANK_V	21
156#define	GPIO_BANK_W	22
157#define	GPIO_BANK_X	23
158#define	GPIO_BANK_Y	24
159#define	GPIO_BANK_Z	25
160#define	GPIO_BANK_AA	26
161#define	GPIO_BANK_BB	27
162#define	GPIO_BANK_CC	28
163#define	GPIO_BANK_DD	29
164#define	GPIO_BANK_EE	30
165#define	GPIO_BANK_FF	31
166#define	GPIO_NUM(b, p) (8 * (b) + (p))
167
168struct tegra_mux {
169	char *name;
170	bus_size_t reg;
171	char *functions[4];
172	int gpio_num;
173};
174
175#define	GMUX(r, gb, gi, nm, f1, f2, f3, f4)				\
176{									\
177	.name = #nm,							\
178	.reg = r,							\
179	.gpio_num = GPIO_NUM(GPIO_BANK_##gb, gi),			\
180	.functions = {#f1, #f2, #f3, #f4},				\
181}
182
183#define	FMUX(r, nm, f1, f2, f3, f4)					\
184{									\
185	.name = #nm,							\
186	.reg = r,							\
187	.gpio_num = -1,							\
188	.functions = {#f1, #f2, #f3, #f4},				\
189}
190
191static const struct tegra_mux pin_mux_tbl[] = {
192	GMUX(0x000,  O, 1, ulpi_data0_po1,         spi3,       hsi,        uarta,        ulpi),
193	GMUX(0x004,  O, 2, ulpi_data1_po2,         spi3,       hsi,        uarta,        ulpi),
194	GMUX(0x008,  O, 3, ulpi_data2_po3,         spi3,       hsi,        uarta,        ulpi),
195	GMUX(0x00C,  O, 4, ulpi_data3_po4,         spi3,       hsi,        uarta,        ulpi),
196	GMUX(0x010,  O, 5, ulpi_data4_po5,         spi2,       hsi,        uarta,        ulpi),
197	GMUX(0x014,  O, 6, ulpi_data5_po6,         spi2,       hsi,        uarta,        ulpi),
198	GMUX(0x018,  O, 7, ulpi_data6_po7,         spi2,       hsi,        uarta,        ulpi),
199	GMUX(0x01C,  O, 0, ulpi_data7_po0,         spi2,       hsi,        uarta,        ulpi),
200	GMUX(0x020,  P, 9, ulpi_clk_py0,           spi1,       spi5,       uartd,        ulpi),
201	GMUX(0x024,  P, 1, ulpi_dir_py1,           spi1,       spi5,       uartd,        ulpi),
202	GMUX(0x028,  P, 2, ulpi_nxt_py2,           spi1,       spi5,       uartd,        ulpi),
203	GMUX(0x02C,  P, 3, ulpi_stp_py3,           spi1,       spi5,       uartd,        ulpi),
204	GMUX(0x030,  P, 0, dap3_fs_pp0,            i2s2,       spi5,       displaya,     displayb),
205	GMUX(0x034,  P, 1, dap3_din_pp1,           i2s2,       spi5,       displaya,     displayb),
206	GMUX(0x038,  P, 2, dap3_dout_pp2,          i2s2,       spi5,       displaya,     rsvd4),
207	GMUX(0x03C,  P, 3, dap3_sclk_pp3,          i2s2,       spi5,       rsvd3,        displayb),
208	GMUX(0x040,  V, 0, pv0,                    rsvd1,      rsvd2,      rsvd3,        rsvd4),
209	GMUX(0x044,  V, 1, pv1,                    rsvd1,      rsvd2,      rsvd3,        rsvd4),
210	GMUX(0x048,  Z, 0, sdmmc1_clk_pz0,         sdmmc1,     clk12,      rsvd3,        rsvd4),
211	GMUX(0x04C,  Z, 1, sdmmc1_cmd_pz1,         sdmmc1,     spdif,      spi4,         uarta),
212	GMUX(0x050,  Y, 4, sdmmc1_dat3_py4,        sdmmc1,     spdif,      spi4,         uarta),
213	GMUX(0x054,  Y, 5, sdmmc1_dat2_py5,        sdmmc1,     pwm0,       spi4,         uarta),
214	GMUX(0x058,  Y, 6, sdmmc1_dat1_py6,        sdmmc1,     pwm1,       spi4,         uarta),
215	GMUX(0x05C,  Y, 7, sdmmc1_dat0_py7,        sdmmc1,     rsvd2,      spi4,         uarta),
216	GMUX(0x068,  W, 5, clk2_out_pw5,           extperiph2, rsvd2,      rsvd3,        rsvd4),
217	GMUX(0x06C, CC, 5, clk2_req_pcc5,          dap,        rsvd2,      rsvd3,        rsvd4),
218	GMUX(0x110,  N, 7, hdmi_int_pn7,           rsvd1,      rsvd2,      rsvd3,        rsvd4),
219	GMUX(0x114,  V, 4, ddc_scl_pv4,            i2c4,       rsvd2,      rsvd3,        rsvd4),
220	GMUX(0x118,  V, 5, ddc_sda_pv5,            i2c4,       rsvd2,      rsvd3,        rsvd4),
221	GMUX(0x164,  V, 3, uart2_rxd_pc3,          irda,       spdif,      uarta,        spi4),
222	GMUX(0x168,  C, 2, uart2_txd_pc2,          irda,       spdif,      uarta,        spi4),
223	GMUX(0x16C,  J, 6, uart2_rts_n_pj6,        uarta,      uartb,      gmi,          spi4),
224	GMUX(0x170,  J, 5, uart2_cts_n_pj5,        uarta,      uartb,      gmi,          spi4),
225	GMUX(0x174,  W, 6, uart3_txd_pw6,          uartc,      rsvd2,      gmi,          spi4),
226	GMUX(0x178,  W, 7, uart3_rxd_pw7,          uartc,      rsvd2,      gmi,          spi4),
227	GMUX(0x17C,  S, 1, uart3_cts_n_pa1,        uartc,      sdmmc1,     dtv,          gmi),
228	GMUX(0x180,  C, 0, uart3_rts_n_pc0,        uartc,      pwm0,       dtv,          gmi),
229	GMUX(0x184,  U, 0, pu0,                    owr,        uarta,      gmi,          rsvd4),
230	GMUX(0x188,  U, 1, pu1,                    rsvd1,      uarta,      gmi,          rsvd4),
231	GMUX(0x18C,  U, 2, pu2,                    rsvd1,      uarta,      gmi,          rsvd4),
232	GMUX(0x190,  U, 3, pu3,                    pwm0,       uarta,      gmi,          displayb),
233	GMUX(0x194,  U, 4, pu4,                    pwm1,       uarta,      gmi,          displayb),
234	GMUX(0x198,  U, 5, pu5,                    pwm2,       uarta,      gmi,          displayb),
235	GMUX(0x19C,  U, 6, pu6,                    pwm3,       uarta,      rsvd3,        gmi),
236	GMUX(0x1A0,  C, 5, gen1_i2c_sda_pc5,       i2c1,       rsvd2,      rsvd3,        rsvd4),
237	GMUX(0x1A4,  C, 4, gen1_i2c_scl_pc4,       i2c1,       rsvd2,      rsvd3,        rsvd4),
238	GMUX(0x1A8,  P, 3, dap4_fs_pp4,            i2s3,       gmi,        dtv,          rsvd4),
239	GMUX(0x1AC,  P, 4, dap4_din_pp5,           i2s3,       gmi,        rsvd3,        rsvd4),
240	GMUX(0x1B0,  P, 5, dap4_dout_pp6,          i2s3,       gmi,        dtv,          rsvd4),
241	GMUX(0x1B4,  P, 7, dap4_sclk_pp7,          i2s3,       gmi,        rsvd3,        rsvd4),
242	GMUX(0x1B8,  P, 0, clk3_out_pee0,          extperiph3, rsvd2,      rsvd3,        rsvd4),
243	GMUX(0x1BC, EE, 1, clk3_req_pee1,          dev3,       rsvd2,      rsvd3,        rsvd4),
244	GMUX(0x1C0,  C, 7, pc7,                    rsvd1,      rsvd2,      gmi,          gmi_alt),
245	GMUX(0x1C4,  I, 5, pi5,                    sdmmc2,     rsvd2,      gmi,          rsvd4),
246	GMUX(0x1C8,  I, 7, pi7,                    rsvd1,      trace,      gmi,          dtv),
247	GMUX(0x1CC,  K, 0, pk0,                    rsvd1,      sdmmc3,     gmi,          soc),
248	GMUX(0x1D0,  K, 1, pk1,                    sdmmc2,     trace,      gmi,          rsvd4),
249	GMUX(0x1D4,  J, 0, pj0,                    rsvd1,      rsvd2,      gmi,          usb),
250	GMUX(0x1D8,  J, 2, pj2,                    rsvd1,      rsvd2,      gmi,          soc),
251	GMUX(0x1DC,  K, 3, pk3,                    sdmmc2,     trace,      gmi,          ccla),
252	GMUX(0x1E0,  K, 4, pk4,                    sdmmc2,     rsvd2,      gmi,          gmi_alt),
253	GMUX(0x1E4,  K, 2, pk2,                    rsvd1,      rsvd2,      gmi,          rsvd4),
254	GMUX(0x1E8,  I, 3, pi3,                    rsvd1,      rsvd2,      gmi,          spi4),
255	GMUX(0x1EC,  I, 6, pi6,                    rsvd1,      rsvd2,      gmi,          sdmmc2),
256	GMUX(0x1F0,  G, 0, pg0,                    rsvd1,      rsvd2,      gmi,          rsvd4),
257	GMUX(0x1F4,  G, 1, pg1,                    rsvd1,      rsvd2,      gmi,          rsvd4),
258	GMUX(0x1F8,  G, 2, pg2,                    rsvd1,      trace,      gmi,          rsvd4),
259	GMUX(0x1FC,  G, 3, pg3,                    rsvd1,      trace,      gmi,          rsvd4),
260	GMUX(0x200,  G, 4, pg4,                    rsvd1,      tmds,       gmi,          spi4),
261	GMUX(0x204,  G, 5, pg5,                    rsvd1,      rsvd2,      gmi,          spi4),
262	GMUX(0x208,  G, 6, pg6,                    rsvd1,      rsvd2,      gmi,          spi4),
263	GMUX(0x20C,  G, 7, pg7,                    rsvd1,      rsvd2,      gmi,          spi4),
264	GMUX(0x210,  H, 0, ph0,                    pwm0,       trace,      gmi,          dtv),
265	GMUX(0x214,  H, 1, ph1,                    pwm1,       tmds,       gmi,          displaya),
266	GMUX(0x218,  H, 2, ph2,                    pwm2,       tmds,       gmi,          cldvfs),
267	GMUX(0x21C,  H, 3, ph3,                    pwm3,       spi4,       gmi,          cldvfs),
268	GMUX(0x220,  H, 4, ph4,                    sdmmc2,     rsvd2,      gmi,          rsvd4),
269	GMUX(0x224,  H, 5, ph5,                    sdmmc2,     rsvd2,      gmi,          rsvd4),
270	GMUX(0x228,  H, 6, ph6,                    sdmmc2,     trace,      gmi,          dtv),
271	GMUX(0x22C,  H, 7, ph7,                    sdmmc2,     trace,      gmi,          dtv),
272	GMUX(0x230,  J, 7, pj7,                    uartd,      rsvd2,      gmi,          gmi_alt),
273	GMUX(0x234,  B, 0, pb0,                    uartd,      rsvd2,      gmi,          rsvd4),
274	GMUX(0x238,  B, 1, pb1,                    uartd,      rsvd2,      gmi,          rsvd4),
275	GMUX(0x23C,  K, 7, pk7,                    uartd,      rsvd2,      gmi,          rsvd4),
276	GMUX(0x240,  I, 0, pi0,                    rsvd1,      rsvd2,      gmi,          rsvd4),
277	GMUX(0x244,  I, 1, pi1,                    rsvd1,      rsvd2,      gmi,          rsvd4),
278	GMUX(0x248,  I, 2, pi2,                    sdmmc2,     trace,      gmi,          rsvd4),
279	GMUX(0x24C,  I, 4, pi4,                    spi4,       trace,      gmi,          displaya),
280	GMUX(0x250,  T, 5, gen2_i2c_scl_pt5,       i2c2,       rsvd2,      gmi,          rsvd4),
281	GMUX(0x254,  T, 6, gen2_i2c_sda_pt6,       i2c2,       rsvd2,      gmi,          rsvd4),
282	GMUX(0x258, CC, 4, sdmmc4_clk_pcc4,        sdmmc4,     rsvd2,      gmi,          rsvd4),
283	GMUX(0x25C,  T, 7, sdmmc4_cmd_pt7,         sdmmc4,     rsvd2,      gmi,          rsvd4),
284	GMUX(0x260, AA, 0, sdmmc4_dat0_paa0,       sdmmc4,     spi3,       gmi,          rsvd4),
285	GMUX(0x264, AA, 1, sdmmc4_dat1_paa1,       sdmmc4,     spi3,       gmi,          rsvd4),
286	GMUX(0x268, AA, 2, sdmmc4_dat2_paa2,       sdmmc4,     spi3,       gmi,          rsvd4),
287	GMUX(0x26C, AA, 3, sdmmc4_dat3_paa3,       sdmmc4,     spi3,       gmi,          rsvd4),
288	GMUX(0x270, AA, 4, sdmmc4_dat4_paa4,       sdmmc4,     spi3,       gmi,          rsvd4),
289	GMUX(0x274, AA, 5, sdmmc4_dat5_paa5,       sdmmc4,     spi3,       rsvd3,        rsvd4),
290	GMUX(0x278, AA, 6, sdmmc4_dat6_paa6,       sdmmc4,     spi3,       gmi,          rsvd4),
291	GMUX(0x27C, AA, 7, sdmmc4_dat7_paa7,       sdmmc4,     rsvd2,      gmi,          rsvd4),
292	GMUX(0x284, CC, 0, cam_mclk_pcc0,          vi,         vi_alt1,    vi_alt3,      sdmmc2),
293	GMUX(0x288, CC, 1, pcc1,                   i2s4,       rsvd2,      rsvd3,        sdmmc2),
294	GMUX(0x28C, BB, 0, pbb0,                   vgp6,       vimclk2,    sdmmc2,       vimclk2_alt),
295	GMUX(0x290, BB, 1, cam_i2c_scl_pbb1,       vgp1,       i2c3,       rsvd3,        sdmmc2),
296	GMUX(0x294, BB, 2, cam_i2c_sda_pbb2,       vgp2,       i2c3,       rsvd3,        sdmmc2),
297	GMUX(0x298, BB, 3, pbb3,                   vgp3,       displaya,   displayb,     sdmmc2),
298	GMUX(0x29C, BB, 4, pbb4,                   vgp4,       displaya,   displayb,     sdmmc2),
299	GMUX(0x2A0, BB, 5, pbb5,                   vgp5,       displaya,   rsvd3,        sdmmc2),
300	GMUX(0x2A4, BB, 6, pbb6,                   i2s4,       rsvd2,      displayb,     sdmmc2),
301	GMUX(0x2A8, BB, 7, pbb7,                   i2s4,       rsvd2,      rsvd3,        sdmmc2),
302	GMUX(0x2AC, CC, 2, pcc2,                   i2s4,       rsvd2,      sdmmc3,       sdmmc2),
303	FMUX(0x2B0,        jtag_rtck,              rtck,       rsvd2,      rsvd3,        rsvd4),
304	GMUX(0x2B4,  Z, 6, pwr_i2c_scl_pz6,        i2cpwr,     rsvd2,      rsvd3,        rsvd4),
305	GMUX(0x2B8,  Z, 7, pwr_i2c_sda_pz7,        i2cpwr,     rsvd2,      rsvd3,        rsvd4),
306	GMUX(0x2BC,  R, 0, kb_row0_pr0,            kbc,        rsvd2,      rsvd3,        rsvd4),
307	GMUX(0x2C0,  R, 1, kb_row1_pr1,            kbc,        rsvd2,      rsvd3,        rsvd4),
308	GMUX(0x2C4,  R, 2, kb_row2_pr2,            kbc,        rsvd2,      rsvd3,        rsvd4),
309	GMUX(0x2C8,  R, 3, kb_row3_pr3,            kbc,        displaya,   sys,          displayb),
310	GMUX(0x2CC,  R, 4, kb_row4_pr4,            kbc,        displaya,   rsvd3,        displayb),
311	GMUX(0x2D0,  R, 5, kb_row5_pr5,            kbc,        displaya,   rsvd3,        displayb),
312	GMUX(0x2D4,  R, 6, kb_row6_pr6,            kbc,        displaya,   displaya_alt, displayb),
313	GMUX(0x2D8,  R, 7, kb_row7_pr7,            kbc,        rsvd2,      cldvfs,       uarta),
314	GMUX(0x2DC,  S, 0, kb_row8_ps0,            kbc,        rsvd2,      cldvfs,       uarta),
315	GMUX(0x2E0,  S, 1, kb_row9_ps1,            kbc,        rsvd2,      rsvd3,        uarta),
316	GMUX(0x2E4,  S, 2, kb_row10_ps2,           kbc,        rsvd2,      rsvd3,        uarta),
317	GMUX(0x2E8,  S, 3, kb_row11_ps3,           kbc,        rsvd2,      rsvd3,        irda),
318	GMUX(0x2EC,  S, 4, kb_row12_ps4,           kbc,        rsvd2,      rsvd3,        irda),
319	GMUX(0x2F0,  S, 5, kb_row13_ps5,           kbc,        rsvd2,      spi2,         rsvd4),
320	GMUX(0x2F4,  S, 6, kb_row14_ps6,           kbc,        rsvd2,      spi2,         rsvd4),
321	GMUX(0x2F8,  S, 7, kb_row15_ps7,           kbc,        soc,        rsvd3,        rsvd4),
322	GMUX(0x2FC,  Q, 0, kb_col0_pq0,            kbc,        rsvd2,      spi2,         rsvd4),
323	GMUX(0x300,  Q, 1, kb_col1_pq1,            kbc,        rsvd2,      spi2,         rsvd4),
324	GMUX(0x304,  Q, 2, kb_col2_pq2,            kbc,        rsvd2,      spi2,         rsvd4),
325	GMUX(0x308,  Q, 3, kb_col3_pq3,            kbc,        displaya,   pwm2,         uarta),
326	GMUX(0x30C,  Q, 4, kb_col4_pq4,            kbc,        owr,        sdmmc3,       uarta),
327	GMUX(0x310,  Q, 5, kb_col5_pq5,            kbc,        rsvd2,      sdmmc3,       rsvd4),
328	GMUX(0x314,  Q, 6, kb_col6_pq6,            kbc,        rsvd2,      spi2,         uartd),
329	GMUX(0x318,  Q, 7, kb_col7_pq7,            kbc,        rsvd2,      spi2,         uartd),
330	GMUX(0x31C,  A, 0, clk_32k_out_pa0,        blink,      soc,        rsvd3,        rsvd4),
331	FMUX(0x324,        core_pwr_req,           pwron,      rsvd2,      rsvd3,        rsvd4),
332	FMUX(0x328,        cpu_pwr_req,            cpu,        rsvd2,      rsvd3,        rsvd4),
333	FMUX(0x32C,        pwr_int_n,              pmi,        rsvd2,      rsvd3,        rsvd4),
334	FMUX(0x330,        clk_32k_in,             clk,        rsvd2,      rsvd3,        rsvd4),
335	FMUX(0x334,        owr,                    owr,        rsvd2,      rsvd3,        rsvd4),
336	GMUX(0x338,  N, 0, dap1_fs_pn0,            i2s0,       hda,        gmi,          rsvd4),
337	GMUX(0x33C,  N, 1, dap1_din_pn1,           i2s0,       hda,        gmi,          rsvd4),
338	GMUX(0x340,  N, 2, dap1_dout_pn2,          i2s0,       hda,        gmi,          sata),
339	GMUX(0x344,  N, 3, dap1_sclk_pn3,          i2s0,       hda,        gmi,          rsvd4),
340	GMUX(0x348, EE, 2, dap_mclk1_req_pee2,     dap,        dap1,       sata,         rsvd4),
341	GMUX(0x34C,  W, 4, dap_mclk1_pw4,          extperiph1, dap2,       rsvd3,        rsvd4),
342	GMUX(0x350,  K, 6, spdif_in_pk6,           spdif,      rsvd2,      rsvd3,        i2c3),
343	GMUX(0x354,  K, 5, spdif_out_pk5,          spdif,      rsvd2,      rsvd3,        i2c3),
344	GMUX(0x358,  A, 2, dap2_fs_pa2,            i2s1,       hda,        gmi,          rsvd4),
345	GMUX(0x35C,  A, 4, dap2_din_pa4,           i2s1,       hda,        gmi,          rsvd4),
346	GMUX(0x360,  A, 5, dap2_dout_pa5,          i2s1,       hda,        gmi,          rsvd4),
347	GMUX(0x364,  A, 3, dap2_sclk_pa3,          i2s1,       hda,        gmi,          rsvd4),
348	GMUX(0x368,  X, 0, dvfs_pwm_px0,           spi6,       cldvfs,     gmi,          rsvd4),
349	GMUX(0x36C,  X, 1, gpio_x1_aud_px1,        spi6,       rsvd2,      gmi,          rsvd4),
350	GMUX(0x370,  X, 3, gpio_x3_aud_px3,        spi6,       spi1,       gmi,          rsvd4),
351	GMUX(0x374,  X, 2, dvfs_clk_px2,           spi6,       cldvfs,     gmi,          rsvd4),
352	GMUX(0x378,  X, 4, gpio_x4_aud_px4,        gmi,        spi1,       spi2,         dap2),
353	GMUX(0x37C,  X, 5, gpio_x5_aud_px5,        gmi,        spi1,       spi2,         rsvd4),
354	GMUX(0x380,  X, 6, gpio_x6_aud_px6,        spi6,       spi1,       spi2,         gmi),
355	GMUX(0x384,  X, 7, gpio_x7_aud_px7,        rsvd1,      spi1,       spi2,         rsvd4),
356	GMUX(0x390,  A, 6, sdmmc3_clk_pa6,         sdmmc3,     rsvd2,      rsvd3,        spi3),
357	GMUX(0x394,  A, 7, sdmmc3_cmd_pa7,         sdmmc3,     pwm3,       uarta,        spi3),
358	GMUX(0x398,  B, 7, sdmmc3_dat0_pb7,        sdmmc3,     rsvd2,      rsvd3,        spi3),
359	GMUX(0x39C,  B, 6, sdmmc3_dat1_pb6,        sdmmc3,     pwm2,       uarta,        spi3),
360	GMUX(0x3A0,  B, 5, sdmmc3_dat2_pb5,        sdmmc3,     pwm1,       displaya,     spi3),
361	GMUX(0x3A4,  B, 4, sdmmc3_dat3_pb4,        sdmmc3,     pwm0,       displayb,     spi3),
362	GMUX(0x3BC, DD, 1, pex_l0_rst_n_pdd1,      pe0,        rsvd2,      rsvd3,        rsvd4),
363	GMUX(0x3C0, DD, 2, pex_l0_clkreq_n_pdd2,   pe0,        rsvd2,      rsvd3,        rsvd4),
364	GMUX(0x3C4, DD, 3, pex_wake_n_pdd3,        pe,         rsvd2,      rsvd3,        rsvd4),
365	GMUX(0x3CC, DD, 5, pex_l1_rst_n_pdd5,      pe1,        rsvd2,      rsvd3,        rsvd4),
366	GMUX(0x3D0, DD, 6, pex_l1_clkreq_n_pdd6,   pe1,        rsvd2,      rsvd3,        rsvd4),
367	GMUX(0x3E0, EE, 3, hdmi_cec_pee3,          cec,        rsvd2,      rsvd3,        rsvd4),
368	GMUX(0x3E4,  V, 3, sdmmc1_wp_n_pv3,        sdmmc1,     clk12,      spi4,         uarta),
369	GMUX(0x3E8,  V, 2, sdmmc3_cd_n_pv2,        sdmmc3,     owr,        rsvd3,        rsvd4),
370	GMUX(0x3EC,  W, 2, gpio_w2_aud_pw2,        spi6,       rsvd2,      spi2,         i2c1),
371	GMUX(0x3F0,  W, 3, gpio_w3_aud_pw3,        spi6,       spi1,       spi2,         i2c1),
372	GMUX(0x3F4,  N, 4, usb_vbus_en0_pn4,       usb,        rsvd2,      rsvd3,        rsvd4),
373	GMUX(0x3F8,  N, 5, usb_vbus_en1_pn5,       usb,        rsvd2,      rsvd3,        rsvd4),
374	GMUX(0x3FC, EE, 5, sdmmc3_clk_lb_in_pee5,  sdmmc3,     rsvd2,      rsvd3,        rsvd4),
375	GMUX(0x400, EE, 4, sdmmc3_clk_lb_out_pee4, sdmmc3,     rsvd2,      rsvd3,        rsvd4),
376	FMUX(0x404,        gmi_clk_lb,             sdmmc2,     rsvd2,      gmi,          rsvd4),
377	FMUX(0x408,        reset_out_n,            rsvd1,      rsvd2,      rsvd3,        reset_out_n),
378	GMUX(0x40C,  T, 0, kb_row16_pt0,           kbc,        rsvd2,      rsvd3,        uartc),
379	GMUX(0x410,  T, 1, kb_row17_pt1,           kbc,        rsvd2,      rsvd3,        uartc),
380	GMUX(0x414, FF, 1, usb_vbus_en2_pff1,      usb,        rsvd2,      rsvd3,        rsvd4),
381	GMUX(0x418, FF, 2, pff2,                   sata,       rsvd2,      rsvd3,        rsvd4),
382	GMUX(0x430, FF, 0, dp_hpd_pff0,            dp,         rsvd2,      rsvd3,        rsvd4),
383};
384
385struct tegra_grp {
386	char *name;
387	bus_size_t reg;
388	int drvdn_shift;
389	int drvdn_mask;
390	int drvup_shift;
391	int drvup_mask;
392};
393
394#define	GRP(r, nm, dn_s, dn_w, up_s, up_w)				\
395{									\
396	.name = #nm,							\
397	.reg = r - 0x868,						\
398	.drvdn_shift = dn_s,						\
399	.drvdn_mask = (1 << dn_w) - 1,					\
400	.drvup_shift = up_s,						\
401	.drvup_mask = (1 << dn_w) - 1,					\
402}
403
404/* Use register offsets from TRM */
405static const struct tegra_grp pin_grp_tbl[] = {
406	GRP(0x868, ao1,          12,  5,  20,  5),
407	GRP(0x86C, ao2,          12,  5,  20,  5),
408	GRP(0x870, at1,          12,  7,  20,  7),
409	GRP(0x874, at2,          12,  7,  20,  7),
410	GRP(0x878, at3,          12,  7,  20,  7),
411	GRP(0x87C, at4,          12,  7,  20,  7),
412	GRP(0x880, at5,          14,  5,  19,  5),
413	GRP(0x884, cdev1,        12,  5,  20,  5),
414	GRP(0x888, cdev2,        12,  5,  20,  5),
415	GRP(0x890, dap1,         12,  5,  20,  5),
416	GRP(0x894, dap2,         12,  5,  20,  5),
417	GRP(0x898, dap3,         12,  5,  20,  5),
418	GRP(0x89C, dap4,         12,  5,  20,  5),
419	GRP(0x8A0, dbg,          12,  5,  20,  5),
420	GRP(0x8B0, sdio3,        12,  7,  20,  7),
421	GRP(0x8B4, spi,          12,  5,  20,  5),
422	GRP(0x8B8, uaa,          12,  5,  20,  5),
423	GRP(0x8BC, uab,          12,  5,  20,  5),
424	GRP(0x8C0, uart2,        12,  5,  20,  5),
425	GRP(0x8C4, uart3,        12,  5,  20,  5),
426	GRP(0x8EC, sdio1,        12,  7,  20,  7),
427	GRP(0x8FC, ddc,          12,  5,  20,  5),
428	GRP(0x900, gma,          14,  5,  20,  5),
429	GRP(0x910, gme,          14,  5,  19,  5),
430	GRP(0x914, gmf,          14,  5,  19,  5),
431	GRP(0x918, gmg,          14,  5,  19,  5),
432	GRP(0x91C, gmh,          14,  5,  19,  5),
433	GRP(0x920, owr,          12,  5,  20,  5),
434	GRP(0x924, uda,          12,  5,  20,  5),
435	GRP(0x928, gpv,          12,  5,  20,  5),
436	GRP(0x92C, dev3,         12,  5,  20,  5),
437	GRP(0x938, cec,          12,  5,  20,  5),
438	GRP(0x994, at6,          12,  7,  20,  7),
439	GRP(0x998, dap5,         12,  5,  20,  5),
440	GRP(0x99C, usb_vbus_en,  12,  5,  20,  5),
441	GRP(0x9A8, ao3,          12,  5,  -1,  0),
442	GRP(0x9B0, ao0,          12,  5,  20,  5),
443	GRP(0x9B4, hv0,          12,  5,  -1,  0),
444	GRP(0x9C4, sdio4,        12,  5,  20,  5),
445	GRP(0x9C8, ao4,          12,  7,  20,  7),
446};
447
448static const struct tegra_grp *
449pinmux_search_grp(char *grp_name)
450{
451	int i;
452
453	for (i = 0; i < nitems(pin_grp_tbl); i++) {
454		if (strcmp(grp_name, pin_grp_tbl[i].name) == 0)
455			return 	(&pin_grp_tbl[i]);
456	}
457	return (NULL);
458}
459
460static const struct tegra_mux *
461pinmux_search_mux(char *pin_name)
462{
463	int i;
464
465	for (i = 0; i < nitems(pin_mux_tbl); i++) {
466		if (strcmp(pin_name, pin_mux_tbl[i].name) == 0)
467			return 	(&pin_mux_tbl[i]);
468	}
469	return (NULL);
470}
471
472static int
473pinmux_mux_function(const struct tegra_mux *mux, char *fnc_name)
474{
475	int i;
476
477	for (i = 0; i < 4; i++) {
478		if (strcmp(fnc_name, mux->functions[i]) == 0)
479			return 	(i);
480	}
481	return (-1);
482}
483
484static int
485pinmux_config_mux(struct pinmux_softc *sc, char *pin_name,
486    const struct tegra_mux *mux, struct pincfg *cfg)
487{
488	int tmp;
489	uint32_t reg;
490
491	reg = bus_read_4(sc->mux_mem_res, mux->reg);
492
493	if (cfg->function != NULL) {
494		tmp = pinmux_mux_function(mux, cfg->function);
495		if (tmp == -1) {
496			device_printf(sc->dev,
497			    "Unknown function %s for pin %s\n", cfg->function,
498			    pin_name);
499			return (ENXIO);
500		}
501		reg &= ~(TEGRA_MUX_FUNCTION_MASK << TEGRA_MUX_FUNCTION_SHIFT);
502		reg |=  (tmp & TEGRA_MUX_FUNCTION_MASK) <<
503		    TEGRA_MUX_FUNCTION_SHIFT;
504	}
505	if (cfg->params[PROP_ID_PULL] != -1) {
506		reg &= ~(TEGRA_MUX_PUPD_MASK << TEGRA_MUX_PUPD_SHIFT);
507		reg |=  (cfg->params[PROP_ID_PULL] & TEGRA_MUX_PUPD_MASK) <<
508		    TEGRA_MUX_PUPD_SHIFT;
509	}
510	if (cfg->params[PROP_ID_TRISTATE] != -1) {
511		reg &= ~(1 << TEGRA_MUX_TRISTATE_SHIFT);
512		reg |=  (cfg->params[PROP_ID_TRISTATE] & 1) <<
513		    TEGRA_MUX_TRISTATE_SHIFT;
514	}
515	if (cfg->params[TEGRA_MUX_ENABLE_INPUT_SHIFT] != -1) {
516		reg &= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT);
517		reg |=  (cfg->params[TEGRA_MUX_ENABLE_INPUT_SHIFT] & 1) <<
518		    TEGRA_MUX_ENABLE_INPUT_SHIFT;
519	}
520	if (cfg->params[PROP_ID_ENABLE_INPUT] != -1) {
521		reg &= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT);
522		reg |=  (cfg->params[PROP_ID_ENABLE_INPUT] & 1) <<
523		    TEGRA_MUX_ENABLE_INPUT_SHIFT;
524	}
525	if (cfg->params[PROP_ID_ENABLE_INPUT] != -1) {
526		reg &= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT);
527		reg |=  (cfg->params[PROP_ID_OPEN_DRAIN] & 1) <<
528		    TEGRA_MUX_ENABLE_INPUT_SHIFT;
529	}
530	if (cfg->params[PROP_ID_LOCK] != -1) {
531		reg &= ~(1 << TEGRA_MUX_LOCK_SHIFT);
532		reg |=  (cfg->params[PROP_ID_LOCK] & 1) <<
533		    TEGRA_MUX_LOCK_SHIFT;
534	}
535	if (cfg->params[PROP_ID_IORESET] != -1) {
536		reg &= ~(1 << TEGRA_MUX_IORESET_SHIFT);
537		reg |=  (cfg->params[PROP_ID_IORESET] & 1) <<
538		    TEGRA_MUX_IORESET_SHIFT;
539	}
540	if (cfg->params[PROP_ID_RCV_SEL] != -1) {
541		reg &= ~(1 << TEGRA_MUX_RCV_SEL_SHIFT);
542		reg |=  (cfg->params[PROP_ID_RCV_SEL] & 1) <<
543		    TEGRA_MUX_RCV_SEL_SHIFT;
544	}
545	bus_write_4(sc->mux_mem_res, mux->reg, reg);
546	return (0);
547}
548
549static int
550pinmux_config_grp(struct pinmux_softc *sc, char *grp_name,
551    const struct tegra_grp *grp, struct pincfg *cfg)
552{
553	uint32_t reg;
554
555	reg = bus_read_4(sc->pad_mem_res, grp->reg);
556
557	if (cfg->params[PROP_ID_HIGH_SPEED_MODE] != -1) {
558		reg &= ~(1 << TEGRA_GRP_HSM_SHIFT);
559		reg |=  (cfg->params[PROP_ID_HIGH_SPEED_MODE] & 1) <<
560		    TEGRA_GRP_HSM_SHIFT;
561	}
562	if (cfg->params[PROP_ID_SCHMITT] != -1) {
563		reg &= ~(1 << TEGRA_GRP_SCHMT_SHIFT);
564		reg |=  (cfg->params[PROP_ID_SCHMITT] & 1) <<
565		    TEGRA_GRP_SCHMT_SHIFT;
566	}
567	if (cfg->params[PROP_ID_DRIVE_TYPE] != -1) {
568		reg &= ~(TEGRA_GRP_DRV_TYPE_MASK << TEGRA_GRP_DRV_TYPE_SHIFT);
569		reg |=  (cfg->params[PROP_ID_DRIVE_TYPE] &
570		    TEGRA_GRP_DRV_TYPE_MASK) << TEGRA_GRP_DRV_TYPE_SHIFT;
571	}
572	if (cfg->params[PROP_ID_SLEW_RATE_RISING] != -1) {
573		reg &= ~(TEGRA_GRP_DRV_DRVDN_SLWR_MASK <<
574		    TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT);
575		reg |=  (cfg->params[PROP_ID_SLEW_RATE_RISING] &
576		    TEGRA_GRP_DRV_DRVDN_SLWR_MASK) <<
577		    TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT;
578	}
579	if (cfg->params[PROP_ID_SLEW_RATE_FALLING] != -1) {
580		reg &= ~(TEGRA_GRP_DRV_DRVUP_SLWF_MASK <<
581		    TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT);
582		reg |=  (cfg->params[PROP_ID_SLEW_RATE_FALLING] &
583		    TEGRA_GRP_DRV_DRVUP_SLWF_MASK) <<
584		    TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT;
585	}
586	if ((cfg->params[PROP_ID_DRIVE_DOWN_STRENGTH] != -1) &&
587		 (grp->drvdn_mask != -1)) {
588		reg &= ~(grp->drvdn_shift << grp->drvdn_mask);
589		reg |=  (cfg->params[PROP_ID_DRIVE_DOWN_STRENGTH] &
590		    grp->drvdn_mask) << grp->drvdn_shift;
591	}
592	if ((cfg->params[PROP_ID_DRIVE_UP_STRENGTH] != -1) &&
593		 (grp->drvup_mask != -1)) {
594		reg &= ~(grp->drvup_shift << grp->drvup_mask);
595		reg |=  (cfg->params[PROP_ID_DRIVE_UP_STRENGTH] &
596		    grp->drvup_mask) << grp->drvup_shift;
597	}
598	bus_write_4(sc->pad_mem_res, grp->reg, reg);
599	return (0);
600}
601
602static int
603pinmux_config_node(struct pinmux_softc *sc, char *pin_name, struct pincfg *cfg)
604{
605	const struct tegra_mux *mux;
606	const struct tegra_grp *grp;
607	uint32_t reg;
608	int rv;
609
610	/* Handle MIPI special case first */
611	if (strcmp(pin_name, "dsi_b") == 0) {
612		if (cfg->function == NULL) {
613			/* nothing to set */
614			return (0);
615		}
616		reg = bus_read_4(sc->mipi_mem_res, 0); /* register 0x820 */
617		if (strcmp(cfg->function, "csi") == 0)
618			reg &= ~(1 << 1);
619		else if (strcmp(cfg->function, "dsi_b") == 0)
620			reg |= (1 << 1);
621		bus_write_4(sc->mipi_mem_res, 0, reg); /* register 0x820 */
622	}
623
624	/* Handle pin muxes */
625	mux = pinmux_search_mux(pin_name);
626	if (mux != NULL) {
627		if (mux->gpio_num != -1) {
628			/* XXXX TODO: Reserve gpio here */
629		}
630		rv = pinmux_config_mux(sc, pin_name, mux, cfg);
631		return (rv);
632	}
633
634	/* Handle pin groups */
635	grp = pinmux_search_grp(pin_name);
636	if (grp != NULL) {
637		rv = pinmux_config_grp(sc, pin_name, grp, cfg);
638		return (rv);
639	}
640
641	device_printf(sc->dev, "Unknown pin: %s\n", pin_name);
642	return (ENXIO);
643}
644
645static int
646pinmux_read_node(struct pinmux_softc *sc, phandle_t node, struct pincfg *cfg,
647    char **pins, int *lpins)
648{
649	int rv, i;
650
651	*lpins = OF_getprop_alloc(node, "nvidia,pins", 1, (void **)pins);
652	if (*lpins <= 0)
653		return (ENOENT);
654
655	/* Read function (mux) settings. */
656	rv = OF_getprop_alloc(node, "nvidia,function", 1,
657	    (void **)&cfg->function);
658	if (rv <= 0)
659		cfg->function = NULL;
660
661	/* Read numeric properties. */
662	for (i = 0; i < PROP_ID_MAX_ID; i++) {
663		rv = OF_getencprop(node, prop_names[i].name, &cfg->params[i],
664		    sizeof(cfg->params[i]));
665		if (rv <= 0)
666			cfg->params[i] = -1;
667	}
668	return (0);
669}
670
671static int
672pinmux_process_node(struct pinmux_softc *sc, phandle_t node)
673{
674	struct pincfg cfg;
675	char *pins, *pname;
676	int i, len, lpins, rv;
677
678	rv = pinmux_read_node(sc, node, &cfg, &pins, &lpins);
679	if (rv != 0)
680		return (rv);
681
682	len = 0;
683	pname = pins;
684	do {
685		i = strlen(pname) + 1;
686		rv = pinmux_config_node(sc, pname, &cfg);
687		if (rv != 0)
688			device_printf(sc->dev,
689			    "Cannot configure pin: %s: %d\n", pname, rv);
690
691		len += i;
692		pname += i;
693	} while (len < lpins);
694
695	if (pins != NULL)
696		OF_prop_free(pins);
697	if (cfg.function != NULL)
698		OF_prop_free(cfg.function);
699	return (rv);
700}
701
702static int pinmux_configure(device_t dev, phandle_t cfgxref)
703{
704	struct pinmux_softc *sc;
705	phandle_t node, cfgnode;
706	int rv;
707
708	sc = device_get_softc(dev);
709	cfgnode = OF_node_from_xref(cfgxref);
710
711
712	for (node = OF_child(cfgnode); node != 0; node = OF_peer(node)) {
713		if (!fdt_is_enabled(node))
714			continue;
715		rv = pinmux_process_node(sc, node);
716	}
717	return (0);
718}
719
720static int
721pinmux_probe(device_t dev)
722{
723
724	if (!ofw_bus_status_okay(dev))
725		return (ENXIO);
726
727	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
728		return (ENXIO);
729
730	device_set_desc(dev, "Tegra pin configuration");
731	return (BUS_PROBE_DEFAULT);
732}
733
734static int
735pinmux_detach(device_t dev)
736{
737
738	/* This device is always present. */
739	return (EBUSY);
740}
741
742static int
743pinmux_attach(device_t dev)
744{
745	struct pinmux_softc * sc;
746	int rid;
747
748	sc = device_get_softc(dev);
749	sc->dev = dev;
750
751	rid = 0;
752	sc->pad_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
753	    RF_ACTIVE);
754	if (sc->pad_mem_res == NULL) {
755		device_printf(dev, "Cannot allocate memory resources\n");
756		return (ENXIO);
757	}
758
759	rid = 1;
760	sc->mux_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
761	    RF_ACTIVE);
762	if (sc->mux_mem_res == NULL) {
763		device_printf(dev, "Cannot allocate memory resources\n");
764		return (ENXIO);
765	}
766
767	rid = 2;
768	sc->mipi_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
769	    RF_ACTIVE);
770	if (sc->mipi_mem_res == NULL) {
771		device_printf(dev, "Cannot allocate memory resources\n");
772		return (ENXIO);
773	}
774
775	/* Register as a pinctrl device and process default configuration */
776	fdt_pinctrl_register(dev, NULL);
777	fdt_pinctrl_configure_by_name(dev, "boot");
778
779	return (0);
780}
781
782
783static device_method_t tegra_pinmux_methods[] = {
784	/* Device interface */
785	DEVMETHOD(device_probe,         pinmux_probe),
786	DEVMETHOD(device_attach,        pinmux_attach),
787	DEVMETHOD(device_detach,        pinmux_detach),
788
789	/* fdt_pinctrl interface */
790	DEVMETHOD(fdt_pinctrl_configure,pinmux_configure),
791
792	DEVMETHOD_END
793};
794
795static devclass_t tegra_pinmux_devclass;
796static DEFINE_CLASS_0(pinmux, tegra_pinmux_driver, tegra_pinmux_methods,
797    sizeof(struct pinmux_softc));
798EARLY_DRIVER_MODULE(tegra_pinmux, simplebus, tegra_pinmux_driver,
799    tegra_pinmux_devclass, NULL, NULL, 71);
800