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