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