]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/nvidia/tegra_pinmux.c
Update edk2 headers to stable202005
[FreeBSD/FreeBSD.git] / sys / arm / nvidia / tegra_pinmux.c
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$");
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
73 struct 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
80 static struct ofw_compat_data compat_data[] = {
81         {"nvidia,tegra124-pinmux",      1},
82         {NULL,                          0},
83 };
84
85 enum 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. */
106 static 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  */
130 struct 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
168 struct 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
191 static 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
385 struct 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 */
405 static 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
448 static const struct tegra_grp *
449 pinmux_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
460 static const struct tegra_mux *
461 pinmux_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
472 static int
473 pinmux_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
484 static int
485 pinmux_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
549 static int
550 pinmux_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
602 static int
603 pinmux_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
645 static int
646 pinmux_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", (void **)pins);
652         if (*lpins <= 0)
653                 return (ENOENT);
654
655         /* Read function (mux) settings. */
656         rv = OF_getprop_alloc(node, "nvidia,function",
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
671 static int
672 pinmux_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
702 static 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 (!ofw_bus_node_status_okay(node))
714                         continue;
715                 rv = pinmux_process_node(sc, node);
716         }
717         return (0);
718 }
719
720 static int
721 pinmux_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
734 static int
735 pinmux_detach(device_t dev)
736 {
737
738         /* This device is always present. */
739         return (EBUSY);
740 }
741
742 static int
743 pinmux_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
783 static 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
795 static devclass_t tegra_pinmux_devclass;
796 static DEFINE_CLASS_0(pinmux, tegra_pinmux_driver, tegra_pinmux_methods,
797     sizeof(struct pinmux_softc));
798 EARLY_DRIVER_MODULE(tegra_pinmux, simplebus, tegra_pinmux_driver,
799     tegra_pinmux_devclass, NULL, NULL, 71);