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