1e9034789SMichal Meloun /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3e9034789SMichal Meloun *
4e9034789SMichal Meloun * Copyright 2020 Michal Meloun <mmel@FreeBSD.org>
5e9034789SMichal Meloun *
6e9034789SMichal Meloun * Redistribution and use in source and binary forms, with or without
7e9034789SMichal Meloun * modification, are permitted provided that the following conditions
8e9034789SMichal Meloun * are met:
9e9034789SMichal Meloun * 1. Redistributions of source code must retain the above copyright
10e9034789SMichal Meloun * notice, this list of conditions and the following disclaimer.
11e9034789SMichal Meloun * 2. Redistributions in binary form must reproduce the above copyright
12e9034789SMichal Meloun * notice, this list of conditions and the following disclaimer in the
13e9034789SMichal Meloun * documentation and/or other materials provided with the distribution.
14e9034789SMichal Meloun *
15e9034789SMichal Meloun * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16e9034789SMichal Meloun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17e9034789SMichal Meloun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18e9034789SMichal Meloun * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19e9034789SMichal Meloun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20e9034789SMichal Meloun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21e9034789SMichal Meloun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22e9034789SMichal Meloun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23e9034789SMichal Meloun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24e9034789SMichal Meloun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25e9034789SMichal Meloun * SUCH DAMAGE.
26e9034789SMichal Meloun */
27e9034789SMichal Meloun
28e9034789SMichal Meloun #include <sys/cdefs.h>
29e9034789SMichal Meloun /*
30e9034789SMichal Meloun * Pin multiplexer driver for Tegra SoCs.
31e9034789SMichal Meloun */
32e9034789SMichal Meloun #include <sys/param.h>
33e9034789SMichal Meloun #include <sys/systm.h>
34e9034789SMichal Meloun #include <sys/bus.h>
35e9034789SMichal Meloun #include <sys/kernel.h>
36e9034789SMichal Meloun #include <sys/module.h>
37e9034789SMichal Meloun #include <sys/malloc.h>
38e9034789SMichal Meloun #include <sys/rman.h>
39e9034789SMichal Meloun
40e9034789SMichal Meloun #include <machine/bus.h>
41e9034789SMichal Meloun
42e9034789SMichal Meloun #include <dev/fdt/fdt_common.h>
43e9034789SMichal Meloun #include <dev/fdt/fdt_pinctrl.h>
44e9034789SMichal Meloun #include <dev/ofw/openfirm.h>
45e9034789SMichal Meloun #include <dev/ofw/ofw_bus.h>
46e9034789SMichal Meloun #include <dev/ofw/ofw_bus_subr.h>
47e9034789SMichal Meloun
48e9034789SMichal Meloun /* Pin multipexor register. */
49e9034789SMichal Meloun #define TEGRA_MUX_FUNCTION_MASK 0x03
50e9034789SMichal Meloun #define TEGRA_MUX_FUNCTION_SHIFT 0
51e9034789SMichal Meloun #define TEGRA_MUX_PUPD_MASK 0x03
52e9034789SMichal Meloun #define TEGRA_MUX_PUPD_SHIFT 2
53e9034789SMichal Meloun #define TEGRA_MUX_TRISTATE_SHIFT 4
54e9034789SMichal Meloun #define TEGRA_MUX_ENABLE_INPUT_SHIFT 5
55e9034789SMichal Meloun #define TEGRA_MUX_OPEN_DRAIN_SHIFT 6
56e9034789SMichal Meloun #define TEGRA_MUX_LOCK_SHIFT 7
57e9034789SMichal Meloun #define TEGRA_MUX_IORESET_SHIFT 8
58e9034789SMichal Meloun #define TEGRA_MUX_RCV_SEL_SHIFT 9
59e9034789SMichal Meloun
60e9034789SMichal Meloun
61e9034789SMichal Meloun /* Pin goup register. */
62e9034789SMichal Meloun #define TEGRA_GRP_HSM_SHIFT 2
63e9034789SMichal Meloun #define TEGRA_GRP_SCHMT_SHIFT 3
64e9034789SMichal Meloun #define TEGRA_GRP_DRV_TYPE_SHIFT 6
65e9034789SMichal Meloun #define TEGRA_GRP_DRV_TYPE_MASK 0x03
66e9034789SMichal Meloun #define TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT 28
67e9034789SMichal Meloun #define TEGRA_GRP_DRV_DRVDN_SLWR_MASK 0x03
68e9034789SMichal Meloun #define TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT 30
69e9034789SMichal Meloun #define TEGRA_GRP_DRV_DRVUP_SLWF_MASK 0x03
70e9034789SMichal Meloun
71e9034789SMichal Meloun struct pinmux_softc {
72e9034789SMichal Meloun device_t dev;
73e9034789SMichal Meloun struct resource *pad_mem_res;
74e9034789SMichal Meloun struct resource *mux_mem_res;
75e9034789SMichal Meloun };
76e9034789SMichal Meloun
77e9034789SMichal Meloun static struct ofw_compat_data compat_data[] = {
78e9034789SMichal Meloun {"nvidia,tegra210-pinmux", 1},
79e9034789SMichal Meloun {NULL, 0},
80e9034789SMichal Meloun };
81e9034789SMichal Meloun
82e9034789SMichal Meloun enum prop_id {
83e9034789SMichal Meloun PROP_ID_PULL,
84e9034789SMichal Meloun PROP_ID_TRISTATE,
85e9034789SMichal Meloun PROP_ID_ENABLE_INPUT,
86e9034789SMichal Meloun PROP_ID_OPEN_DRAIN,
87e9034789SMichal Meloun PROP_ID_LOCK,
88e9034789SMichal Meloun PROP_ID_IORESET,
89e9034789SMichal Meloun PROP_ID_RCV_SEL,
90e9034789SMichal Meloun PROP_ID_HIGH_SPEED_MODE,
91e9034789SMichal Meloun PROP_ID_SCHMITT,
92e9034789SMichal Meloun PROP_ID_LOW_POWER_MODE,
93e9034789SMichal Meloun PROP_ID_DRIVE_DOWN_STRENGTH,
94e9034789SMichal Meloun PROP_ID_DRIVE_UP_STRENGTH,
95e9034789SMichal Meloun PROP_ID_SLEW_RATE_FALLING,
96e9034789SMichal Meloun PROP_ID_SLEW_RATE_RISING,
97e9034789SMichal Meloun PROP_ID_DRIVE_TYPE,
98e9034789SMichal Meloun
99e9034789SMichal Meloun PROP_ID_MAX_ID
100e9034789SMichal Meloun };
101e9034789SMichal Meloun
102e9034789SMichal Meloun /* Numeric based parameters. */
103e9034789SMichal Meloun static const struct prop_name {
104e9034789SMichal Meloun const char *name;
105e9034789SMichal Meloun enum prop_id id;
106e9034789SMichal Meloun } prop_names[] = {
107e9034789SMichal Meloun {"nvidia,pull", PROP_ID_PULL},
108e9034789SMichal Meloun {"nvidia,tristate", PROP_ID_TRISTATE},
109e9034789SMichal Meloun {"nvidia,enable-input", PROP_ID_ENABLE_INPUT},
110e9034789SMichal Meloun {"nvidia,open-drain", PROP_ID_OPEN_DRAIN},
111e9034789SMichal Meloun {"nvidia,lock", PROP_ID_LOCK},
112e9034789SMichal Meloun {"nvidia,io-reset", PROP_ID_IORESET},
113e9034789SMichal Meloun {"nvidia,rcv-sel", PROP_ID_RCV_SEL},
114e9034789SMichal Meloun {"nvidia,io-hv", PROP_ID_RCV_SEL},
115e9034789SMichal Meloun {"nvidia,high-speed-mode", PROP_ID_HIGH_SPEED_MODE},
116e9034789SMichal Meloun {"nvidia,schmitt", PROP_ID_SCHMITT},
117e9034789SMichal Meloun {"nvidia,low-power-mode", PROP_ID_LOW_POWER_MODE},
118e9034789SMichal Meloun {"nvidia,pull-down-strength", PROP_ID_DRIVE_DOWN_STRENGTH},
119e9034789SMichal Meloun {"nvidia,pull-up-strength", PROP_ID_DRIVE_UP_STRENGTH},
120e9034789SMichal Meloun {"nvidia,slew-rate-falling", PROP_ID_SLEW_RATE_FALLING},
121e9034789SMichal Meloun {"nvidia,slew-rate-rising", PROP_ID_SLEW_RATE_RISING},
122e9034789SMichal Meloun {"nvidia,drive-type", PROP_ID_DRIVE_TYPE},
123e9034789SMichal Meloun };
124e9034789SMichal Meloun
125e9034789SMichal Meloun /*
126e9034789SMichal Meloun * configuration for one pin group.
127e9034789SMichal Meloun */
128e9034789SMichal Meloun struct pincfg {
129e9034789SMichal Meloun char *function;
130e9034789SMichal Meloun int params[PROP_ID_MAX_ID];
131e9034789SMichal Meloun };
132e9034789SMichal Meloun #define GPIO_BANK_A 0
133e9034789SMichal Meloun #define GPIO_BANK_B 1
134e9034789SMichal Meloun #define GPIO_BANK_C 2
135e9034789SMichal Meloun #define GPIO_BANK_D 3
136e9034789SMichal Meloun #define GPIO_BANK_E 4
137e9034789SMichal Meloun #define GPIO_BANK_F 5
138e9034789SMichal Meloun #define GPIO_BANK_G 6
139e9034789SMichal Meloun #define GPIO_BANK_H 7
140e9034789SMichal Meloun #define GPIO_BANK_I 8
141e9034789SMichal Meloun #define GPIO_BANK_J 9
142e9034789SMichal Meloun #define GPIO_BANK_K 10
143e9034789SMichal Meloun #define GPIO_BANK_L 11
144e9034789SMichal Meloun #define GPIO_BANK_M 12
145e9034789SMichal Meloun #define GPIO_BANK_N 13
146e9034789SMichal Meloun #define GPIO_BANK_O 14
147e9034789SMichal Meloun #define GPIO_BANK_P 15
148e9034789SMichal Meloun #define GPIO_BANK_Q 16
149e9034789SMichal Meloun #define GPIO_BANK_R 17
150e9034789SMichal Meloun #define GPIO_BANK_S 18
151e9034789SMichal Meloun #define GPIO_BANK_T 19
152e9034789SMichal Meloun #define GPIO_BANK_U 20
153e9034789SMichal Meloun #define GPIO_BANK_V 21
154e9034789SMichal Meloun #define GPIO_BANK_W 22
155e9034789SMichal Meloun #define GPIO_BANK_X 23
156e9034789SMichal Meloun #define GPIO_BANK_Y 24
157e9034789SMichal Meloun #define GPIO_BANK_Z 25
158e9034789SMichal Meloun #define GPIO_BANK_AA 26
159e9034789SMichal Meloun #define GPIO_BANK_BB 27
160e9034789SMichal Meloun #define GPIO_BANK_CC 28
161e9034789SMichal Meloun #define GPIO_BANK_DD 29
162e9034789SMichal Meloun #define GPIO_BANK_EE 30
163e9034789SMichal Meloun #define GPIO_NUM(b, p) (8 * (b) + (p))
164e9034789SMichal Meloun
165e9034789SMichal Meloun struct tegra_grp {
166e9034789SMichal Meloun char *name;
167e9034789SMichal Meloun bus_size_t reg;
168e9034789SMichal Meloun int drvdn_shift;
169e9034789SMichal Meloun int drvdn_mask;
170e9034789SMichal Meloun int drvup_shift;
171e9034789SMichal Meloun int drvup_mask;
172e9034789SMichal Meloun };
173e9034789SMichal Meloun
174e9034789SMichal Meloun #define GRP(r, nm, dn_s, dn_w, up_s, up_w) \
175e9034789SMichal Meloun { \
176e9034789SMichal Meloun .name = #nm, \
177e9034789SMichal Meloun .reg = r - 0x8D4, \
178e9034789SMichal Meloun .drvdn_shift = dn_s, \
179e9034789SMichal Meloun .drvdn_mask = (1 << dn_w) - 1, \
180e9034789SMichal Meloun .drvup_shift = up_s, \
181e9034789SMichal Meloun .drvup_mask = (1 << up_w) - 1, \
182e9034789SMichal Meloun }
183e9034789SMichal Meloun
184e9034789SMichal Meloun /* Use register offsets from TRM */
185e9034789SMichal Meloun static const struct tegra_grp pin_grp_tbl[] = {
186e9034789SMichal Meloun GRP(0x9c0, pa6, 12, 5, 20, 5),
187e9034789SMichal Meloun GRP(0x9c4, pcc7, 12, 5, 20, 5),
188e9034789SMichal Meloun GRP(0x9c8, pe6, 12, 5, 20, 5),
189e9034789SMichal Meloun GRP(0x9cc, pe7, 12, 5, 20, 5),
190e9034789SMichal Meloun GRP(0x9d0, ph6, 12, 5, 20, 5),
191e9034789SMichal Meloun GRP(0x9d4, pk0, 0, 0, 0, 0),
192e9034789SMichal Meloun GRP(0x9d8, pk1, 0, 0, 0, 0),
193e9034789SMichal Meloun GRP(0x9dc, pk2, 0, 0, 0, 0),
194e9034789SMichal Meloun GRP(0x9e0, pk3, 0, 0, 0, 0),
195e9034789SMichal Meloun GRP(0x9e4, pk4, 0, 0, 0, 0),
196e9034789SMichal Meloun GRP(0x9e8, pk5, 0, 0, 0, 0),
197e9034789SMichal Meloun GRP(0x9ec, pk6, 0, 0, 0, 0),
198e9034789SMichal Meloun GRP(0x9f0, pk7, 0, 0, 0, 0),
199e9034789SMichal Meloun GRP(0x9f4, pl0, 0, 0, 0, 0),
200e9034789SMichal Meloun GRP(0x9f8, pl1, 0, 0, 0, 0),
201e9034789SMichal Meloun GRP(0x9fc, pz0, 12, 7, 20, 7),
202e9034789SMichal Meloun GRP(0xa00, pz1, 12, 7, 20, 7),
203e9034789SMichal Meloun GRP(0xa04, pz2, 12, 7, 20, 7),
204e9034789SMichal Meloun GRP(0xa08, pz3, 12, 7, 20, 7),
205e9034789SMichal Meloun GRP(0xa0c, pz4, 12, 7, 20, 7),
206e9034789SMichal Meloun GRP(0xa10, pz5, 12, 7, 20, 7),
207e9034789SMichal Meloun GRP(0xa98, sdmmc1, 12, 7, 20, 7),
208e9034789SMichal Meloun GRP(0xa9c, sdmmc2, 2, 6, 8, 6),
209e9034789SMichal Meloun GRP(0xab0, sdmmc3, 12, 7, 20, 7),
210e9034789SMichal Meloun GRP(0xab4, sdmmc4, 2, 6, 8, 6),
211e9034789SMichal Meloun };
212e9034789SMichal Meloun
213e9034789SMichal Meloun struct tegra_mux {
214e9034789SMichal Meloun struct tegra_grp grp;
215e9034789SMichal Meloun char *name;
216e9034789SMichal Meloun bus_size_t reg;
217e9034789SMichal Meloun char *functions[4];
218e9034789SMichal Meloun int gpio_num;
219e9034789SMichal Meloun
220e9034789SMichal Meloun };
221e9034789SMichal Meloun
222e9034789SMichal Meloun #define GMUX(r, gb, gi, nm, f1, f2, f3, f4, gr, dn_s, dn_w, up_s, up_w) \
223e9034789SMichal Meloun { \
224e9034789SMichal Meloun .name = #nm, \
225e9034789SMichal Meloun .reg = r, \
226e9034789SMichal Meloun .gpio_num = GPIO_NUM(GPIO_BANK_##gb, gi), \
227e9034789SMichal Meloun .functions = {#f1, #f2, #f3, #f4}, \
228e9034789SMichal Meloun .grp.name = #nm, \
229e9034789SMichal Meloun .grp.reg = gr - 0x8D4, \
230e9034789SMichal Meloun .grp.drvdn_shift = dn_s, \
231e9034789SMichal Meloun .grp.drvdn_mask = (1 << dn_w) - 1, \
232e9034789SMichal Meloun .grp.drvup_shift = up_s, \
233e9034789SMichal Meloun .grp.drvup_mask = (1 << up_w) - 1, \
234e9034789SMichal Meloun }
235e9034789SMichal Meloun
236e9034789SMichal Meloun #define FMUX(r, nm, f1, f2, f3, f4, gr, dn_s, dn_w, up_s, up_w) \
237e9034789SMichal Meloun { \
238e9034789SMichal Meloun .name = #nm, \
239e9034789SMichal Meloun .reg = r, \
240e9034789SMichal Meloun .gpio_num = -1, \
241e9034789SMichal Meloun .functions = {#f1, #f2, #f3, #f4}, \
242e9034789SMichal Meloun .grp.name = #nm, \
243e9034789SMichal Meloun .grp.reg = gr - 0x8D4, \
244e9034789SMichal Meloun .grp.drvdn_shift = dn_s, \
245e9034789SMichal Meloun .grp.drvdn_mask = (1 << dn_w) - 1, \
246e9034789SMichal Meloun .grp.drvup_shift = up_s, \
247e9034789SMichal Meloun .grp.drvup_mask = (1 << up_w) - 1, \
248e9034789SMichal Meloun }
249e9034789SMichal Meloun
250e9034789SMichal Meloun static const struct tegra_mux pin_mux_tbl[] = {
251e9034789SMichal Meloun GMUX(0x000, M, 0, sdmmc1_clk_pm0, sdmmc1, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
252e9034789SMichal Meloun GMUX(0x004, M, 1, sdmmc1_cmd_pm1, sdmmc1, spi3, rsvd2, rsvd3, -1, 0, 0, 0, 0),
253e9034789SMichal Meloun GMUX(0x008, M, 2, sdmmc1_dat3_pm2, sdmmc1, spi3, rsvd2, rsvd3, -1, 0, 0, 0, 0),
254e9034789SMichal Meloun GMUX(0x00c, M, 3, sdmmc1_dat2_pm3, sdmmc1, spi3, rsvd2, rsvd3, -1, 0, 0, 0, 0),
255e9034789SMichal Meloun GMUX(0x010, M, 4, sdmmc1_dat1_pm4, sdmmc1, spi3, rsvd2, rsvd3, -1, 0, 0, 0, 0),
256e9034789SMichal Meloun GMUX(0x014, M, 5, sdmmc1_dat0_pm5, sdmmc1, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
257e9034789SMichal Meloun GMUX(0x01c, P, 0, sdmmc3_clk_pp0, sdmmc3, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
258e9034789SMichal Meloun GMUX(0x020, P, 1, sdmmc3_cmd_pp1, sdmmc3, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
259e9034789SMichal Meloun GMUX(0x024, P, 5, sdmmc3_dat0_pp5, sdmmc3, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
260e9034789SMichal Meloun GMUX(0x028, P, 4, sdmmc3_dat1_pp4, sdmmc3, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
261e9034789SMichal Meloun GMUX(0x02c, P, 3, sdmmc3_dat2_pp3, sdmmc3, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
262e9034789SMichal Meloun GMUX(0x030, P, 2, sdmmc3_dat3_pp2, sdmmc3, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
263e9034789SMichal Meloun GMUX(0x038, A, 0, pex_l0_rst_n_pa0, pe0, rsvd1, rsvd2, rsvd3, 0xa5c, 12, 5, 20, 5),
264e9034789SMichal Meloun GMUX(0x03c, A, 1, pex_l0_clkreq_n_pa1, pe0, rsvd1, rsvd2, rsvd3, 0xa58, 12, 5, 20, 5),
265e9034789SMichal Meloun GMUX(0x040, A, 2, pex_wake_n_pa2, pe, rsvd1, rsvd2, rsvd3, 0xa68, 12, 5, 20, 5),
266e9034789SMichal Meloun GMUX(0x044, A, 3, pex_l1_rst_n_pa3, pe1, rsvd1, rsvd2, rsvd3, 0xa64, 12, 5, 20, 5),
267e9034789SMichal Meloun GMUX(0x048, A, 4, pex_l1_clkreq_n_pa4, pe1, rsvd1, rsvd2, rsvd3, 0xa60, 12, 5, 20, 5),
268e9034789SMichal Meloun GMUX(0x04c, A, 5, sata_led_active_pa5, sata, rsvd1, rsvd2, rsvd3, 0xa94, 12, 5, 20, 5),
269e9034789SMichal Meloun GMUX(0x050, C, 0, spi1_mosi_pc0, spi1, rsvd1, rsvd2, rsvd3, 0xae0, 0, 0, 0, 0),
270e9034789SMichal Meloun GMUX(0x054, C, 1, spi1_miso_pc1, spi1, rsvd1, rsvd2, rsvd3, 0xadc, 0, 0, 0, 0),
271e9034789SMichal Meloun GMUX(0x058, C, 2, spi1_sck_pc2, spi1, rsvd1, rsvd2, rsvd3, 0xae4, 0, 0, 0, 0),
272e9034789SMichal Meloun GMUX(0x05c, C, 3, spi1_cs0_pc3, spi1, rsvd1, rsvd2, rsvd3, 0xad4, 0, 0, 0, 0),
273e9034789SMichal Meloun GMUX(0x060, C, 4, spi1_cs1_pc4, spi1, rsvd1, rsvd2, rsvd3, 0xad8, 0, 0, 0, 0),
274e9034789SMichal Meloun GMUX(0x064, B, 4, spi2_mosi_pb4, spi2, dtv, rsvd2, rsvd3, 0xaf4, 0, 0, 0, 0),
275e9034789SMichal Meloun GMUX(0x068, B, 5, spi2_miso_pb5, spi2, dtv, rsvd2, rsvd3, 0xaf0, 0, 0, 0, 0),
276e9034789SMichal Meloun GMUX(0x06c, B, 6, spi2_sck_pb6, spi2, dtv, rsvd2, rsvd3, 0xaf8, 0, 0, 0, 0),
277e9034789SMichal Meloun GMUX(0x070, B, 7, spi2_cs0_pb7, spi2, dtv, rsvd2, rsvd3, 0xae8, 0, 0, 0, 0),
278e9034789SMichal Meloun GMUX(0x074, DD, 0, spi2_cs1_pdd0, spi2, rsvd1, rsvd2, rsvd3, 0xaec, 0, 0, 0, 0),
279e9034789SMichal Meloun GMUX(0x078, C, 7, spi4_mosi_pc7, spi4, rsvd1, rsvd2, rsvd3, 0xb04, 0, 0, 0, 0),
280e9034789SMichal Meloun GMUX(0x07c, D, 0, spi4_miso_pd0, spi4, rsvd1, rsvd2, rsvd3, 0xb00, 0, 0, 0, 0),
281e9034789SMichal Meloun GMUX(0x080, C, 5, spi4_sck_pc5, spi4, rsvd1, rsvd2, rsvd3, 0xb08, 0, 0, 0, 0),
282e9034789SMichal Meloun GMUX(0x084, C, 6, spi4_cs0_pc6, spi4, rsvd1, rsvd2, rsvd3, 0xafc, 0, 0, 0, 0),
283e9034789SMichal Meloun GMUX(0x088, EE, 0, qspi_sck_pee0, qspi, rsvd1, rsvd2, rsvd3, 0xa90, 0, 0, 0, 0),
284e9034789SMichal Meloun GMUX(0x08c, EE, 1, qspi_cs_n_pee1, qspi, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
285e9034789SMichal Meloun GMUX(0x090, EE, 2, qspi_io0_pee2, qspi, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
286e9034789SMichal Meloun GMUX(0x094, EE, 3, qspi_io1_pee3, qspi, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
287e9034789SMichal Meloun GMUX(0x098, EE, 4, qspi_io2_pee4, qspi, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
288e9034789SMichal Meloun GMUX(0x09c, EE, 5, qspi_io3_pee5, qspi, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
289e9034789SMichal Meloun GMUX(0x0a4, E, 0, dmic1_clk_pe0, dmic1, i2s3, rsvd2, rsvd3, 0x984, 12, 5, 20, 5),
290e9034789SMichal Meloun GMUX(0x0a8, E, 1, dmic1_dat_pe1, dmic1, i2s3, rsvd2, rsvd3, 0x988, 12, 5, 20, 5),
291e9034789SMichal Meloun GMUX(0x0ac, E, 2, dmic2_clk_pe2, dmic2, i2s3, rsvd2, rsvd3, 0x98c, 12, 5, 20, 5),
292e9034789SMichal Meloun GMUX(0x0b0, E, 3, dmic2_dat_pe3, dmic2, i2s3, rsvd2, rsvd3, 0x990, 12, 5, 20, 5),
293e9034789SMichal Meloun GMUX(0x0b4, E, 4, dmic3_clk_pe4, dmic3, i2s5a, rsvd2, rsvd3, 0x994, 12, 5, 20, 5),
294e9034789SMichal Meloun GMUX(0x0b8, E, 5, dmic3_dat_pe5, dmic3, i2s5a, rsvd2, rsvd3, 0x998, 12, 5, 20, 5),
295e9034789SMichal Meloun GMUX(0x0bc, J, 1, gen1_i2c_scl_pj1, i2c1, rsvd1, rsvd2, rsvd3, 0x9a8, 12, 5, 20, 5),
296e9034789SMichal Meloun GMUX(0x0c0, J, 0, gen1_i2c_sda_pj0, i2c1, rsvd1, rsvd2, rsvd3, 0x9ac, 12, 5, 20, 5),
297e9034789SMichal Meloun GMUX(0x0c4, J, 2, gen2_i2c_scl_pj2, i2c2, rsvd1, rsvd2, rsvd3, 0x9b0, 12, 5, 20, 5),
298e9034789SMichal Meloun GMUX(0x0c8, J, 3, gen2_i2c_sda_pj3, i2c2, rsvd1, rsvd2, rsvd3, 0x9b4, 12, 5, 20, 5),
299e9034789SMichal Meloun GMUX(0x0cc, F, 0, gen3_i2c_scl_pf0, i2c3, rsvd1, rsvd2, rsvd3, 0x9b8, 12, 5, 20, 5),
300e9034789SMichal Meloun GMUX(0x0d0, F, 1, gen3_i2c_sda_pf1, i2c3, rsvd1, rsvd2, rsvd3, 0x9bc, 12, 5, 20, 5),
301e9034789SMichal Meloun GMUX(0x0d4, S, 2, cam_i2c_scl_ps2, i2c3, i2cvi, rsvd2, rsvd3, 0x934, 12, 5, 20, 5),
302e9034789SMichal Meloun GMUX(0x0d8, S, 3, cam_i2c_sda_ps3, i2c3, i2cvi, rsvd2, rsvd3, 0x938, 12, 5, 20, 5),
303e9034789SMichal Meloun GMUX(0x0dc, Y, 3, pwr_i2c_scl_py3, i2cpmu, rsvd1, rsvd2, rsvd3, 0xa6c, 12, 5, 20, 5),
304e9034789SMichal Meloun GMUX(0x0e0, Y, 4, pwr_i2c_sda_py4, i2cpmu, rsvd1, rsvd2, rsvd3, 0xa70, 12, 5, 20, 5),
305e9034789SMichal Meloun GMUX(0x0e4, U, 0, uart1_tx_pu0, uarta, rsvd1, rsvd2, rsvd3, 0xb28, 12, 5, 20, 5),
306e9034789SMichal Meloun GMUX(0x0e8, U, 1, uart1_rx_pu1, uarta, rsvd1, rsvd2, rsvd3, 0xb24, 12, 5, 20, 5),
307e9034789SMichal Meloun GMUX(0x0ec, U, 2, uart1_rts_pu2, uarta, rsvd1, rsvd2, rsvd3, 0xb20, 12, 5, 20, 5),
308e9034789SMichal Meloun GMUX(0x0f0, U, 3, uart1_cts_pu3, uarta, rsvd1, rsvd2, rsvd3, 0xb1c, 12, 5, 20, 5),
309e9034789SMichal Meloun GMUX(0x0f4, G, 0, uart2_tx_pg0, uartb, i2s4a, spdif, uart, 0xb38, 12, 5, 20, 5),
310e9034789SMichal Meloun GMUX(0x0f8, G, 1, uart2_rx_pg1, uartb, i2s4a, spdif, uart, 0xb34, 12, 5, 20, 5),
311e9034789SMichal Meloun GMUX(0x0fc, G, 2, uart2_rts_pg2, uartb, i2s4a, rsvd2, uart, 0xb30, 12, 5, 20, 5),
312e9034789SMichal Meloun GMUX(0x100, G, 3, uart2_cts_pg3, uartb, i2s4a, rsvd2, uart, 0xb2c, 12, 5, 20, 5),
313e9034789SMichal Meloun GMUX(0x104, D, 1, uart3_tx_pd1, uartc, spi4, rsvd2, rsvd3, 0xb48, 12, 5, 20, 5),
314e9034789SMichal Meloun GMUX(0x108, D, 2, uart3_rx_pd2, uartc, spi4, rsvd2, rsvd3, 0xb44, 12, 5, 20, 5),
315e9034789SMichal Meloun GMUX(0x10c, D, 3, uart3_rts_pd3, uartc, spi4, rsvd2, rsvd3, 0xb40, 12, 5, 20, 5),
316e9034789SMichal Meloun GMUX(0x110, D, 4, uart3_cts_pd4, uartc, spi4, rsvd2, rsvd3, 0xb3c, 12, 5, 20, 5),
317e9034789SMichal Meloun GMUX(0x114, I, 4, uart4_tx_pi4, uartd, uart, rsvd2, rsvd3, 0xb58, 12, 5, 20, 5),
318e9034789SMichal Meloun GMUX(0x118, I, 5, uart4_rx_pi5, uartd, uart, rsvd2, rsvd3, 0xb54, 12, 5, 20, 5),
319e9034789SMichal Meloun GMUX(0x11c, I, 6, uart4_rts_pi6, uartd, uart, rsvd2, rsvd3, 0xb50, 12, 5, 20, 5),
320e9034789SMichal Meloun GMUX(0x120, I, 7, uart4_cts_pi7, uartd, uart, rsvd2, rsvd3, 0xb4c, 12, 5, 20, 5),
321e9034789SMichal Meloun GMUX(0x124, B, 0, dap1_fs_pb0, i2s1, rsvd1, rsvd2, rsvd3, 0x95c, 0, 0, 0, 0),
322e9034789SMichal Meloun GMUX(0x128, B, 1, dap1_din_pb1, i2s1, rsvd1, rsvd2, rsvd3, 0x954, 0, 0, 0, 0),
323e9034789SMichal Meloun GMUX(0x12c, B, 2, dap1_dout_pb2, i2s1, rsvd1, rsvd2, rsvd3, 0x958, 0, 0, 0, 0),
324e9034789SMichal Meloun GMUX(0x130, B, 3, dap1_sclk_pb3, i2s1, rsvd1, rsvd2, rsvd3, 0x960, 0, 0, 0, 0),
325e9034789SMichal Meloun GMUX(0x134, AA, 0, dap2_fs_paa0, i2s2, rsvd1, rsvd2, rsvd3, 0x96c, 0, 0, 0, 0),
326e9034789SMichal Meloun GMUX(0x138, AA, 2, dap2_din_paa2, i2s2, rsvd1, rsvd2, rsvd3, 0x964, 0, 0, 0, 0),
327e9034789SMichal Meloun GMUX(0x13c, AA, 3, dap2_dout_paa3, i2s2, rsvd1, rsvd2, rsvd3, 0x968, 0, 0, 0, 0),
328e9034789SMichal Meloun GMUX(0x140, AA, 1, dap2_sclk_paa1, i2s2, rsvd1, rsvd2, rsvd3, 0x970, 0, 0, 0, 0),
329e9034789SMichal Meloun GMUX(0x144, J, 4, dap4_fs_pj4, i2s4b, rsvd1, rsvd2, rsvd3, 0x97c, 12, 5, 20, 5),
330e9034789SMichal Meloun GMUX(0x148, J, 5, dap4_din_pj5, i2s4b, rsvd1, rsvd2, rsvd3, 0x974, 12, 5, 20, 5),
331e9034789SMichal Meloun GMUX(0x14c, J, 6, dap4_dout_pj6, i2s4b, rsvd1, rsvd2, rsvd3, 0x978, 12, 5, 20, 5),
332e9034789SMichal Meloun GMUX(0x150, J, 7, dap4_sclk_pj7, i2s4b, rsvd1, rsvd2, rsvd3, 0x980, 12, 5, 20, 5),
333e9034789SMichal Meloun GMUX(0x154, S, 0, cam1_mclk_ps0, extperiph3, rsvd1, rsvd2, rsvd3, 0x918, 12, 5, 20, 5),
334e9034789SMichal Meloun GMUX(0x158, S, 1, cam2_mclk_ps1, extperiph3, rsvd1, rsvd2, rsvd3, 0x924, 12, 5, 20, 5),
335e9034789SMichal Meloun FMUX(0x15c, jtag_rtck, jtag, rsvd1, rsvd2, rsvd3, 0xa2c, 12, 5, 20, 5),
336e9034789SMichal Meloun FMUX(0x160, clk_32k_in, clk, rsvd1, rsvd2, rsvd3, 0x940, 12, 5, 20, 5),
337e9034789SMichal Meloun GMUX(0x164, Y, 5, clk_32k_out_py5, soc, blink, rsvd2, rsvd3, 0x944, 12, 5, 20, 5),
338e9034789SMichal Meloun FMUX(0x168, batt_bcl, bcl, rsvd1, rsvd2, rsvd3, 0x8f8, 12, 5, 20, 5),
339e9034789SMichal Meloun FMUX(0x16c, clk_req, sys, rsvd1, rsvd2, rsvd3, 0x948, 12, 5, 20, 5),
340e9034789SMichal Meloun FMUX(0x170, cpu_pwr_req, cpu, rsvd1, rsvd2, rsvd3, 0x950, 12, 5, 20, 5),
341e9034789SMichal Meloun FMUX(0x174, pwr_int_n, pmi, rsvd1, rsvd2, rsvd3, 0xa74, 12, 5, 20, 5),
342e9034789SMichal Meloun FMUX(0x178, shutdown, shutdown, rsvd1, rsvd2, rsvd3, 0xac8, 12, 5, 20, 5),
343e9034789SMichal Meloun FMUX(0x17c, core_pwr_req, core, rsvd1, rsvd2, rsvd3, 0x94c, 12, 5, 20, 5),
344e9034789SMichal Meloun GMUX(0x180, BB, 0, aud_mclk_pbb0, aud, rsvd1, rsvd2, rsvd3, 0x8f4, 12, 5, 20, 5),
345e9034789SMichal Meloun GMUX(0x184, BB, 1, dvfs_pwm_pbb1, rsvd0, cldvfs, spi3, rsvd3, 0x9a4, 12, 5, 20, 5),
346e9034789SMichal Meloun GMUX(0x188, BB, 2, dvfs_clk_pbb2, rsvd0, cldvfs, spi3, rsvd3, 0x9a0, 12, 5, 20, 5),
347e9034789SMichal Meloun GMUX(0x18c, BB, 3, gpio_x1_aud_pbb3, rsvd0, rsvd1, spi3, rsvd3, 0xa14, 12, 5, 20, 5),
348e9034789SMichal Meloun GMUX(0x190, BB, 4, gpio_x3_aud_pbb4, rsvd0, rsvd1, spi3, rsvd3, 0xa18, 12, 5, 20, 5),
349e9034789SMichal Meloun GMUX(0x194, CC, 7, pcc7, rsvd0, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
350e9034789SMichal Meloun GMUX(0x198, CC, 0, hdmi_cec_pcc0, cec, rsvd1, rsvd2, rsvd3, 0xa24, 12, 5, 20, 5),
351e9034789SMichal Meloun GMUX(0x19c, CC, 1, hdmi_int_dp_hpd_pcc1, dp, rsvd1, rsvd2, rsvd3, 0xa28, 12, 5, 20, 5),
352e9034789SMichal Meloun GMUX(0x1a0, CC, 2, spdif_out_pcc2, spdif, rsvd1, rsvd2, rsvd3, 0xad0, 12, 5, 20, 5),
353e9034789SMichal Meloun GMUX(0x1a4, CC, 3, spdif_in_pcc3, spdif, rsvd1, rsvd2, rsvd3, 0xacc, 12, 5, 20, 5),
354e9034789SMichal Meloun GMUX(0x1a8, CC, 4, usb_vbus_en0_pcc4, usb, rsvd1, rsvd2, rsvd3, 0xb5c, 12, 5, 20, 5),
355e9034789SMichal Meloun GMUX(0x1ac, CC, 5, usb_vbus_en1_pcc5, usb, rsvd1, rsvd2, rsvd3, 0xb60, 12, 5, 20, 5),
356e9034789SMichal Meloun GMUX(0x1b0, CC, 6, dp_hpd0_pcc6, dp, rsvd1, rsvd2, rsvd3, 0x99c, 12, 5, 20, 5),
357e9034789SMichal Meloun GMUX(0x1b4, H, 0, wifi_en_ph0, rsvd0, rsvd1, rsvd2, rsvd3, 0xb64, 12, 5, 20, 5),
358e9034789SMichal Meloun GMUX(0x1b8, H, 1, wifi_rst_ph1, rsvd0, rsvd1, rsvd2, rsvd3, 0xb68, 12, 5, 20, 5),
359e9034789SMichal Meloun GMUX(0x1bc, H, 2, wifi_wake_ap_ph2, rsvd0, rsvd1, rsvd2, rsvd3, 0xb6c, 12, 5, 20, 5),
360e9034789SMichal Meloun GMUX(0x1c0, H, 3, ap_wake_bt_ph3, rsvd0, uartb, spdif, rsvd3, 0x8ec, 12, 5, 20, 5),
361e9034789SMichal Meloun GMUX(0x1c4, H, 4, bt_rst_ph4, rsvd0, uartb, spdif, rsvd3, 0x8fc, 12, 5, 20, 5),
362e9034789SMichal Meloun GMUX(0x1c8, H, 5, bt_wake_ap_ph5, rsvd0, rsvd1, rsvd2, rsvd3, 0x900, 12, 5, 20, 5),
363e9034789SMichal Meloun GMUX(0x1cc, H, 7, ap_wake_nfc_ph7, rsvd0, rsvd1, rsvd2, rsvd3, 0x8f0, 12, 5, 20, 5),
364e9034789SMichal Meloun GMUX(0x1d0, I, 0, nfc_en_pi0, rsvd0, rsvd1, rsvd2, rsvd3, 0xa50, 12, 5, 20, 5),
365e9034789SMichal Meloun GMUX(0x1d4, I, 1, nfc_int_pi1, rsvd0, rsvd1, rsvd2, rsvd3, 0xa54, 12, 5, 20, 5),
366e9034789SMichal Meloun GMUX(0x1d8, I, 2, gps_en_pi2, rsvd0, rsvd1, rsvd2, rsvd3, 0xa1c, 12, 5, 20, 5),
367e9034789SMichal Meloun GMUX(0x1dc, I, 3, gps_rst_pi3, rsvd0, rsvd1, rsvd2, rsvd3, 0xa20, 12, 5, 20, 5),
368e9034789SMichal Meloun GMUX(0x1e0, S, 4, cam_rst_ps4, vgp1, rsvd1, rsvd2, rsvd3, 0x93c, 12, 5, 20, 5),
369e9034789SMichal Meloun GMUX(0x1e4, S, 5, cam_af_en_ps5, vimclk, vgp2, rsvd2, rsvd3, 0x92c, 12, 5, 20, 5),
370e9034789SMichal Meloun GMUX(0x1e8, S, 6, cam_flash_en_ps6, vimclk, vgp3, rsvd2, rsvd3, 0x930, 12, 5, 20, 5),
371e9034789SMichal Meloun GMUX(0x1ec, S, 7, cam1_pwdn_ps7, vgp4, rsvd1, rsvd2, rsvd3, 0x91c, 12, 5, 20, 5),
372e9034789SMichal Meloun GMUX(0x1f0, T, 0, cam2_pwdn_pt0, vgp5, rsvd1, rsvd2, rsvd3, 0x928, 12, 5, 20, 5),
373e9034789SMichal Meloun GMUX(0x1f4, T, 1, cam1_strobe_pt1, vgp6, rsvd1, rsvd2, rsvd3, 0x920, 12, 5, 20, 5),
374e9034789SMichal Meloun GMUX(0x1f8, Y, 2, lcd_te_py2, displaya, rsvd1, rsvd2, rsvd3, 0xa44, 12, 5, 20, 5),
375e9034789SMichal Meloun GMUX(0x1fc, V, 0, lcd_bl_pwm_pv0, displaya, pwm0, sor0, rsvd3, 0xa34, 12, 5, 20, 5),
376e9034789SMichal Meloun GMUX(0x200, V, 1, lcd_bl_en_pv1, rsvd0, rsvd1, rsvd2, rsvd3, 0xa30, 12, 5, 20, 5),
377e9034789SMichal Meloun GMUX(0x204, V, 2, lcd_rst_pv2, rsvd0, rsvd1, rsvd2, rsvd3, 0xa40, 12, 5, 20, 5),
378e9034789SMichal Meloun GMUX(0x208, V, 3, lcd_gpio1_pv3, displayb, rsvd1, rsvd2, rsvd3, 0xa38, 12, 5, 20, 5),
379e9034789SMichal Meloun GMUX(0x20c, V, 4, lcd_gpio2_pv4, displayb, pwm1, rsvd2, sor1, 0xa3c, 12, 5, 20, 5),
380e9034789SMichal Meloun GMUX(0x210, V, 5, ap_ready_pv5, rsvd0, rsvd1, rsvd2, rsvd3, 0x8e8, 12, 5, 20, 5),
381e9034789SMichal Meloun GMUX(0x214, V, 6, touch_rst_pv6, rsvd0, rsvd1, rsvd2, rsvd3, 0xb18, 12, 5, 20, 5),
382e9034789SMichal Meloun GMUX(0x218, V, 7, touch_clk_pv7, touch, rsvd1, rsvd2, rsvd3, 0xb10, 12, 5, 20, 5),
383e9034789SMichal Meloun GMUX(0x21c, X, 0, modem_wake_ap_px0, rsvd0, rsvd1, rsvd2, rsvd3, 0xa48, 12, 5, 20, 5),
384e9034789SMichal Meloun GMUX(0x220, X, 1, touch_int_px1, rsvd0, rsvd1, rsvd2, rsvd3, 0xb14, 12, 5, 20, 5),
385e9034789SMichal Meloun GMUX(0x224, X, 2, motion_int_px2, rsvd0, rsvd1, rsvd2, rsvd3, 0xa4c, 12, 5, 20, 5),
386e9034789SMichal Meloun GMUX(0x228, X, 3, als_prox_int_px3, rsvd0, rsvd1, rsvd2, rsvd3, 0x8e4, 12, 5, 20, 5),
387e9034789SMichal Meloun GMUX(0x22c, X, 4, temp_alert_px4, rsvd0, rsvd1, rsvd2, rsvd3, 0xb0c, 12, 5, 20, 5),
388e9034789SMichal Meloun GMUX(0x230, X, 5, button_power_on_px5, rsvd0, rsvd1, rsvd2, rsvd3, 0x908, 12, 5, 20, 5),
389e9034789SMichal Meloun GMUX(0x234, X, 6, button_vol_up_px6, rsvd0, rsvd1, rsvd2, rsvd3, 0x914, 12, 5, 20, 5),
390e9034789SMichal Meloun GMUX(0x238, X, 7, button_vol_down_px7, rsvd0, rsvd1, rsvd2, rsvd3, 0x910, 12, 5, 20, 5),
391e9034789SMichal Meloun GMUX(0x23c, Y, 0, button_slide_sw_py0, rsvd0, rsvd1, rsvd2, rsvd3, 0x90c, 12, 5, 20, 5),
392e9034789SMichal Meloun GMUX(0x240, Y, 1, button_home_py1, rsvd0, rsvd1, rsvd2, rsvd3, 0x904, 12, 5, 20, 5),
393e9034789SMichal Meloun GMUX(0x244, A, 6, pa6, sata, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
394e9034789SMichal Meloun GMUX(0x248, E, 6, pe6, rsvd0, i2s5a, pwm2, rsvd3, -1, 0, 0, 0, 0),
395e9034789SMichal Meloun GMUX(0x24c, E, 7, pe7, rsvd0, i2s5a, pwm3, rsvd3, -1, 0, 0, 0, 0),
396e9034789SMichal Meloun GMUX(0x250, H, 6, ph6, rsvd0, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
397e9034789SMichal Meloun GMUX(0x254, K, 0, pk0, iqc0, i2s5b, rsvd2, rsvd3, -1, 0, 0, 0, 0),
398e9034789SMichal Meloun GMUX(0x258, K, 1, pk1, iqc0, i2s5b, rsvd2, rsvd3, -1, 0, 0, 0, 0),
399e9034789SMichal Meloun GMUX(0x25c, K, 2, pk2, iqc0, i2s5b, rsvd2, rsvd3, -1, 0, 0, 0, 0),
400e9034789SMichal Meloun GMUX(0x260, K, 3, pk3, iqc0, i2s5b, rsvd2, rsvd3, -1, 0, 0, 0, 0),
401e9034789SMichal Meloun GMUX(0x264, K, 4, pk4, iqc1, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
402e9034789SMichal Meloun GMUX(0x268, K, 5, pk5, iqc1, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
403e9034789SMichal Meloun GMUX(0x26c, K, 6, pk6, iqc1, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
404e9034789SMichal Meloun GMUX(0x270, K, 7, pk7, iqc1, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
405e9034789SMichal Meloun GMUX(0x274, L, 0, pl0, rsvd0, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
406e9034789SMichal Meloun GMUX(0x278, L, 1, pl1, soc, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
407e9034789SMichal Meloun GMUX(0x27c, Z, 0, pz0, vimclk2, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
408e9034789SMichal Meloun GMUX(0x280, Z, 1, pz1, vimclk2, sdmmc1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
409e9034789SMichal Meloun GMUX(0x284, Z, 2, pz2, sdmmc3, ccla, rsvd2, rsvd3, -1, 0, 0, 0, 0),
410e9034789SMichal Meloun GMUX(0x288, Z, 3, pz3, sdmmc3, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
411e9034789SMichal Meloun GMUX(0x28c, Z, 4, pz4, sdmmc1, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
412e9034789SMichal Meloun GMUX(0x290, Z, 5, pz5, soc, rsvd1, rsvd2, rsvd3, -1, 0, 0, 0, 0),
413e9034789SMichal Meloun };
414e9034789SMichal Meloun
415e9034789SMichal Meloun
416e9034789SMichal Meloun static const struct tegra_grp *
pinmux_search_grp(char * grp_name)417e9034789SMichal Meloun pinmux_search_grp(char *grp_name)
418e9034789SMichal Meloun {
419e9034789SMichal Meloun int i;
420e9034789SMichal Meloun
421e9034789SMichal Meloun for (i = 0; i < nitems(pin_grp_tbl); i++) {
422e9034789SMichal Meloun if (strcmp(grp_name, pin_grp_tbl[i].name) == 0)
423e9034789SMichal Meloun return (&pin_grp_tbl[i]);
424e9034789SMichal Meloun }
425e9034789SMichal Meloun return (NULL);
426e9034789SMichal Meloun }
427e9034789SMichal Meloun
428e9034789SMichal Meloun static const struct tegra_mux *
pinmux_search_mux(char * pin_name)429e9034789SMichal Meloun pinmux_search_mux(char *pin_name)
430e9034789SMichal Meloun {
431e9034789SMichal Meloun int i;
432e9034789SMichal Meloun
433e9034789SMichal Meloun for (i = 0; i < nitems(pin_mux_tbl); i++) {
434e9034789SMichal Meloun if (strcmp(pin_name, pin_mux_tbl[i].name) == 0)
435e9034789SMichal Meloun return (&pin_mux_tbl[i]);
436e9034789SMichal Meloun }
437e9034789SMichal Meloun return (NULL);
438e9034789SMichal Meloun }
439e9034789SMichal Meloun
440e9034789SMichal Meloun static int
pinmux_mux_function(const struct tegra_mux * mux,char * fnc_name)441e9034789SMichal Meloun pinmux_mux_function(const struct tegra_mux *mux, char *fnc_name)
442e9034789SMichal Meloun {
443e9034789SMichal Meloun int i;
444e9034789SMichal Meloun
445e9034789SMichal Meloun for (i = 0; i < 4; i++) {
446e9034789SMichal Meloun if (strcmp(fnc_name, mux->functions[i]) == 0)
447e9034789SMichal Meloun return (i);
448e9034789SMichal Meloun }
449e9034789SMichal Meloun return (-1);
450e9034789SMichal Meloun }
451e9034789SMichal Meloun
452e9034789SMichal Meloun static int
pinmux_config_mux(struct pinmux_softc * sc,char * pin_name,const struct tegra_mux * mux,struct pincfg * cfg)453e9034789SMichal Meloun pinmux_config_mux(struct pinmux_softc *sc, char *pin_name,
454e9034789SMichal Meloun const struct tegra_mux *mux, struct pincfg *cfg)
455e9034789SMichal Meloun {
456e9034789SMichal Meloun int tmp;
457e9034789SMichal Meloun uint32_t reg;
458e9034789SMichal Meloun
459e9034789SMichal Meloun reg = bus_read_4(sc->mux_mem_res, mux->reg);
460e9034789SMichal Meloun
461e9034789SMichal Meloun if (cfg->function != NULL) {
462e9034789SMichal Meloun tmp = pinmux_mux_function(mux, cfg->function);
463e9034789SMichal Meloun if (tmp == -1) {
464e9034789SMichal Meloun device_printf(sc->dev,
465e9034789SMichal Meloun "Unknown function %s for pin %s\n", cfg->function,
466e9034789SMichal Meloun pin_name);
467e9034789SMichal Meloun return (ENXIO);
468e9034789SMichal Meloun }
469e9034789SMichal Meloun reg &= ~(TEGRA_MUX_FUNCTION_MASK << TEGRA_MUX_FUNCTION_SHIFT);
470e9034789SMichal Meloun reg |= (tmp & TEGRA_MUX_FUNCTION_MASK) <<
471e9034789SMichal Meloun TEGRA_MUX_FUNCTION_SHIFT;
472e9034789SMichal Meloun }
473e9034789SMichal Meloun if (cfg->params[PROP_ID_PULL] != -1) {
474e9034789SMichal Meloun reg &= ~(TEGRA_MUX_PUPD_MASK << TEGRA_MUX_PUPD_SHIFT);
475e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_PULL] & TEGRA_MUX_PUPD_MASK) <<
476e9034789SMichal Meloun TEGRA_MUX_PUPD_SHIFT;
477e9034789SMichal Meloun }
478e9034789SMichal Meloun if (cfg->params[PROP_ID_TRISTATE] != -1) {
479e9034789SMichal Meloun reg &= ~(1 << TEGRA_MUX_TRISTATE_SHIFT);
480e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_TRISTATE] & 1) <<
481e9034789SMichal Meloun TEGRA_MUX_TRISTATE_SHIFT;
482e9034789SMichal Meloun }
483e9034789SMichal Meloun if (cfg->params[TEGRA_MUX_ENABLE_INPUT_SHIFT] != -1) {
484e9034789SMichal Meloun reg &= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT);
485e9034789SMichal Meloun reg |= (cfg->params[TEGRA_MUX_ENABLE_INPUT_SHIFT] & 1) <<
486e9034789SMichal Meloun TEGRA_MUX_ENABLE_INPUT_SHIFT;
487e9034789SMichal Meloun }
488e9034789SMichal Meloun if (cfg->params[PROP_ID_ENABLE_INPUT] != -1) {
489e9034789SMichal Meloun reg &= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT);
490e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_ENABLE_INPUT] & 1) <<
491e9034789SMichal Meloun TEGRA_MUX_ENABLE_INPUT_SHIFT;
492e9034789SMichal Meloun }
493e9034789SMichal Meloun if (cfg->params[PROP_ID_ENABLE_INPUT] != -1) {
494e9034789SMichal Meloun reg &= ~(1 << TEGRA_MUX_ENABLE_INPUT_SHIFT);
495e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_OPEN_DRAIN] & 1) <<
496e9034789SMichal Meloun TEGRA_MUX_ENABLE_INPUT_SHIFT;
497e9034789SMichal Meloun }
498e9034789SMichal Meloun if (cfg->params[PROP_ID_LOCK] != -1) {
499e9034789SMichal Meloun reg &= ~(1 << TEGRA_MUX_LOCK_SHIFT);
500e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_LOCK] & 1) <<
501e9034789SMichal Meloun TEGRA_MUX_LOCK_SHIFT;
502e9034789SMichal Meloun }
503e9034789SMichal Meloun if (cfg->params[PROP_ID_IORESET] != -1) {
504e9034789SMichal Meloun reg &= ~(1 << TEGRA_MUX_IORESET_SHIFT);
505e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_IORESET] & 1) <<
506e9034789SMichal Meloun TEGRA_MUX_IORESET_SHIFT;
507e9034789SMichal Meloun }
508e9034789SMichal Meloun if (cfg->params[PROP_ID_RCV_SEL] != -1) {
509e9034789SMichal Meloun reg &= ~(1 << TEGRA_MUX_RCV_SEL_SHIFT);
510e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_RCV_SEL] & 1) <<
511e9034789SMichal Meloun TEGRA_MUX_RCV_SEL_SHIFT;
512e9034789SMichal Meloun }
513e9034789SMichal Meloun bus_write_4(sc->mux_mem_res, mux->reg, reg);
514e9034789SMichal Meloun return (0);
515e9034789SMichal Meloun }
516e9034789SMichal Meloun
517e9034789SMichal Meloun static int
pinmux_config_grp(struct pinmux_softc * sc,char * grp_name,const struct tegra_grp * grp,struct pincfg * cfg)518e9034789SMichal Meloun pinmux_config_grp(struct pinmux_softc *sc, char *grp_name,
519e9034789SMichal Meloun const struct tegra_grp *grp, struct pincfg *cfg)
520e9034789SMichal Meloun {
521e9034789SMichal Meloun uint32_t reg;
522e9034789SMichal Meloun
523e9034789SMichal Meloun reg = bus_read_4(sc->pad_mem_res, grp->reg);
524e9034789SMichal Meloun
525e9034789SMichal Meloun if (cfg->params[PROP_ID_HIGH_SPEED_MODE] != -1) {
526e9034789SMichal Meloun reg &= ~(1 << TEGRA_GRP_HSM_SHIFT);
527e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_HIGH_SPEED_MODE] & 1) <<
528e9034789SMichal Meloun TEGRA_GRP_HSM_SHIFT;
529e9034789SMichal Meloun }
530e9034789SMichal Meloun if (cfg->params[PROP_ID_SCHMITT] != -1) {
531e9034789SMichal Meloun reg &= ~(1 << TEGRA_GRP_SCHMT_SHIFT);
532e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_SCHMITT] & 1) <<
533e9034789SMichal Meloun TEGRA_GRP_SCHMT_SHIFT;
534e9034789SMichal Meloun }
535e9034789SMichal Meloun if (cfg->params[PROP_ID_DRIVE_TYPE] != -1) {
536e9034789SMichal Meloun reg &= ~(TEGRA_GRP_DRV_TYPE_MASK << TEGRA_GRP_DRV_TYPE_SHIFT);
537e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_DRIVE_TYPE] &
538e9034789SMichal Meloun TEGRA_GRP_DRV_TYPE_MASK) << TEGRA_GRP_DRV_TYPE_SHIFT;
539e9034789SMichal Meloun }
540e9034789SMichal Meloun if (cfg->params[PROP_ID_SLEW_RATE_RISING] != -1) {
541e9034789SMichal Meloun reg &= ~(TEGRA_GRP_DRV_DRVDN_SLWR_MASK <<
542e9034789SMichal Meloun TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT);
543e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_SLEW_RATE_RISING] &
544e9034789SMichal Meloun TEGRA_GRP_DRV_DRVDN_SLWR_MASK) <<
545e9034789SMichal Meloun TEGRA_GRP_DRV_DRVDN_SLWR_SHIFT;
546e9034789SMichal Meloun }
547e9034789SMichal Meloun if (cfg->params[PROP_ID_SLEW_RATE_FALLING] != -1) {
548e9034789SMichal Meloun reg &= ~(TEGRA_GRP_DRV_DRVUP_SLWF_MASK <<
549e9034789SMichal Meloun TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT);
550e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_SLEW_RATE_FALLING] &
551e9034789SMichal Meloun TEGRA_GRP_DRV_DRVUP_SLWF_MASK) <<
552e9034789SMichal Meloun TEGRA_GRP_DRV_DRVUP_SLWF_SHIFT;
553e9034789SMichal Meloun }
554e9034789SMichal Meloun if ((cfg->params[PROP_ID_DRIVE_DOWN_STRENGTH] != -1) &&
555e9034789SMichal Meloun (grp->drvdn_mask != 0)) {
556e9034789SMichal Meloun reg &= ~(grp->drvdn_shift << grp->drvdn_mask);
557e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_DRIVE_DOWN_STRENGTH] &
558e9034789SMichal Meloun grp->drvdn_mask) << grp->drvdn_shift;
559e9034789SMichal Meloun }
560e9034789SMichal Meloun if ((cfg->params[PROP_ID_DRIVE_UP_STRENGTH] != -1) &&
561e9034789SMichal Meloun (grp->drvup_mask != 0)) {
562e9034789SMichal Meloun reg &= ~(grp->drvup_shift << grp->drvup_mask);
563e9034789SMichal Meloun reg |= (cfg->params[PROP_ID_DRIVE_UP_STRENGTH] &
564e9034789SMichal Meloun grp->drvup_mask) << grp->drvup_shift;
565e9034789SMichal Meloun }
566e9034789SMichal Meloun bus_write_4(sc->pad_mem_res, grp->reg, reg);
567e9034789SMichal Meloun return (0);
568e9034789SMichal Meloun }
569e9034789SMichal Meloun
570e9034789SMichal Meloun static int
pinmux_config_node(struct pinmux_softc * sc,char * pin_name,struct pincfg * cfg)571e9034789SMichal Meloun pinmux_config_node(struct pinmux_softc *sc, char *pin_name, struct pincfg *cfg)
572e9034789SMichal Meloun {
573e9034789SMichal Meloun const struct tegra_mux *mux;
574e9034789SMichal Meloun const struct tegra_grp *grp;
575e9034789SMichal Meloun bool handled;
576e9034789SMichal Meloun int rv;
577e9034789SMichal Meloun
578e9034789SMichal Meloun /* Handle pin muxes */
579e9034789SMichal Meloun mux = pinmux_search_mux(pin_name);
580e9034789SMichal Meloun handled = false;
581e9034789SMichal Meloun if (mux != NULL) {
582e9034789SMichal Meloun if (mux->gpio_num != -1) {
583e9034789SMichal Meloun /* XXXX TODO: Reserve gpio here */
584e9034789SMichal Meloun }
585e9034789SMichal Meloun rv = pinmux_config_mux(sc, pin_name, mux, cfg);
586e9034789SMichal Meloun if (rv != 0)
587e9034789SMichal Meloun return (rv);
588e9034789SMichal Meloun if (mux->grp.reg <= 0) {
589e9034789SMichal Meloun rv = pinmux_config_grp(sc, pin_name, &mux->grp, cfg);
590e9034789SMichal Meloun return (rv);
591e9034789SMichal Meloun }
592e9034789SMichal Meloun handled = true;
593e9034789SMichal Meloun }
594e9034789SMichal Meloun
595e9034789SMichal Meloun /* And/or handle pin groups */
596e9034789SMichal Meloun grp = pinmux_search_grp(pin_name);
597e9034789SMichal Meloun if (grp != NULL) {
598e9034789SMichal Meloun rv = pinmux_config_grp(sc, pin_name, grp, cfg);
599e9034789SMichal Meloun if (rv != 0)
600e9034789SMichal Meloun return (rv);
601e9034789SMichal Meloun handled = true;
602e9034789SMichal Meloun }
603e9034789SMichal Meloun
604e9034789SMichal Meloun if (!handled) {
605e9034789SMichal Meloun device_printf(sc->dev, "Unknown pin: %s\n", pin_name);
606e9034789SMichal Meloun return (ENXIO);
607e9034789SMichal Meloun }
608e9034789SMichal Meloun return (0);
609e9034789SMichal Meloun }
610e9034789SMichal Meloun
611e9034789SMichal Meloun static int
pinmux_read_node(struct pinmux_softc * sc,phandle_t node,struct pincfg * cfg,char ** pins,int * lpins)612e9034789SMichal Meloun pinmux_read_node(struct pinmux_softc *sc, phandle_t node, struct pincfg *cfg,
613e9034789SMichal Meloun char **pins, int *lpins)
614e9034789SMichal Meloun {
615e9034789SMichal Meloun int rv, i;
616e9034789SMichal Meloun
617e9034789SMichal Meloun *lpins = OF_getprop_alloc(node, "nvidia,pins", (void **)pins);
618e9034789SMichal Meloun if (*lpins <= 0)
619e9034789SMichal Meloun return (ENOENT);
620e9034789SMichal Meloun
621e9034789SMichal Meloun /* Read function (mux) settings. */
622e9034789SMichal Meloun rv = OF_getprop_alloc(node, "nvidia,function", (void **)&cfg->function);
623e9034789SMichal Meloun if (rv <= 0)
624e9034789SMichal Meloun cfg->function = NULL;
625e9034789SMichal Meloun
626e9034789SMichal Meloun /* Read numeric properties. */
627e9034789SMichal Meloun for (i = 0; i < PROP_ID_MAX_ID; i++) {
628e9034789SMichal Meloun rv = OF_getencprop(node, prop_names[i].name, &cfg->params[i],
629e9034789SMichal Meloun sizeof(cfg->params[i]));
630e9034789SMichal Meloun if (rv <= 0)
631e9034789SMichal Meloun cfg->params[i] = -1;
632e9034789SMichal Meloun }
633e9034789SMichal Meloun return (0);
634e9034789SMichal Meloun }
635e9034789SMichal Meloun
636e9034789SMichal Meloun static int
pinmux_process_node(struct pinmux_softc * sc,phandle_t node)637e9034789SMichal Meloun pinmux_process_node(struct pinmux_softc *sc, phandle_t node)
638e9034789SMichal Meloun {
639e9034789SMichal Meloun struct pincfg cfg;
640e9034789SMichal Meloun char *pins, *pname;
641e9034789SMichal Meloun int i, len, lpins, rv;
642e9034789SMichal Meloun
643e9034789SMichal Meloun rv = pinmux_read_node(sc, node, &cfg, &pins, &lpins);
644e9034789SMichal Meloun if (rv != 0)
645e9034789SMichal Meloun return (rv);
646e9034789SMichal Meloun
647e9034789SMichal Meloun len = 0;
648e9034789SMichal Meloun pname = pins;
649e9034789SMichal Meloun do {
650e9034789SMichal Meloun i = strlen(pname) + 1;
651e9034789SMichal Meloun rv = pinmux_config_node(sc, pname, &cfg);
652e9034789SMichal Meloun if (rv != 0)
653e9034789SMichal Meloun device_printf(sc->dev, "Cannot configure pin: %s: %d\n",
654e9034789SMichal Meloun pname, rv);
655e9034789SMichal Meloun len += i;
656e9034789SMichal Meloun pname += i;
657e9034789SMichal Meloun } while (len < lpins);
658e9034789SMichal Meloun
659e9034789SMichal Meloun if (pins != NULL)
660e9034789SMichal Meloun OF_prop_free(pins);
661e9034789SMichal Meloun if (cfg.function != NULL)
662e9034789SMichal Meloun OF_prop_free(cfg.function);
663e9034789SMichal Meloun return (rv);
664e9034789SMichal Meloun }
665e9034789SMichal Meloun
pinmux_configure(device_t dev,phandle_t cfgxref)666e9034789SMichal Meloun static int pinmux_configure(device_t dev, phandle_t cfgxref)
667e9034789SMichal Meloun {
668e9034789SMichal Meloun struct pinmux_softc *sc;
669e9034789SMichal Meloun phandle_t node, cfgnode;
670e9034789SMichal Meloun
671e9034789SMichal Meloun sc = device_get_softc(dev);
672e9034789SMichal Meloun cfgnode = OF_node_from_xref(cfgxref);
673e9034789SMichal Meloun
674e9034789SMichal Meloun
675e9034789SMichal Meloun for (node = OF_child(cfgnode); node != 0; node = OF_peer(node)) {
676e9034789SMichal Meloun if (!ofw_bus_node_status_okay(node))
677e9034789SMichal Meloun continue;
6784b9b6a50SJohn Baldwin pinmux_process_node(sc, node);
679e9034789SMichal Meloun }
680e9034789SMichal Meloun return (0);
681e9034789SMichal Meloun }
682e9034789SMichal Meloun
683e9034789SMichal Meloun static int
pinmux_probe(device_t dev)684e9034789SMichal Meloun pinmux_probe(device_t dev)
685e9034789SMichal Meloun {
686e9034789SMichal Meloun
687e9034789SMichal Meloun if (!ofw_bus_status_okay(dev))
688e9034789SMichal Meloun return (ENXIO);
689e9034789SMichal Meloun
690e9034789SMichal Meloun if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
691e9034789SMichal Meloun return (ENXIO);
692e9034789SMichal Meloun
693e9034789SMichal Meloun device_set_desc(dev, "Tegra pin configuration");
694e9034789SMichal Meloun return (BUS_PROBE_DEFAULT);
695e9034789SMichal Meloun }
696e9034789SMichal Meloun
697e9034789SMichal Meloun static int
pinmux_detach(device_t dev)698e9034789SMichal Meloun pinmux_detach(device_t dev)
699e9034789SMichal Meloun {
700e9034789SMichal Meloun
701e9034789SMichal Meloun /* This device is always present. */
702e9034789SMichal Meloun return (EBUSY);
703e9034789SMichal Meloun }
704e9034789SMichal Meloun
705e9034789SMichal Meloun static int
pinmux_attach(device_t dev)706e9034789SMichal Meloun pinmux_attach(device_t dev)
707e9034789SMichal Meloun {
708e9034789SMichal Meloun struct pinmux_softc * sc;
709e9034789SMichal Meloun int rid;
710e9034789SMichal Meloun
711e9034789SMichal Meloun sc = device_get_softc(dev);
712e9034789SMichal Meloun sc->dev = dev;
713e9034789SMichal Meloun
714e9034789SMichal Meloun rid = 0;
715e9034789SMichal Meloun sc->pad_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
716e9034789SMichal Meloun RF_ACTIVE);
717e9034789SMichal Meloun if (sc->pad_mem_res == NULL) {
718e9034789SMichal Meloun device_printf(dev, "Cannot allocate memory resources\n");
719e9034789SMichal Meloun return (ENXIO);
720e9034789SMichal Meloun }
721e9034789SMichal Meloun
722e9034789SMichal Meloun rid = 1;
723e9034789SMichal Meloun sc->mux_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
724e9034789SMichal Meloun RF_ACTIVE);
725e9034789SMichal Meloun if (sc->mux_mem_res == NULL) {
726e9034789SMichal Meloun device_printf(dev, "Cannot allocate memory resources\n");
727e9034789SMichal Meloun return (ENXIO);
728e9034789SMichal Meloun }
729e9034789SMichal Meloun
730e9034789SMichal Meloun
731e9034789SMichal Meloun /* Register as a pinctrl device and process default configuration */
732e9034789SMichal Meloun fdt_pinctrl_register(dev, NULL);
733e9034789SMichal Meloun fdt_pinctrl_configure_by_name(dev, "boot");
734e9034789SMichal Meloun
735e9034789SMichal Meloun return (0);
736e9034789SMichal Meloun }
737e9034789SMichal Meloun
738e9034789SMichal Meloun
739e9034789SMichal Meloun static device_method_t tegra210_pinmux_methods[] = {
740e9034789SMichal Meloun /* Device interface */
741e9034789SMichal Meloun DEVMETHOD(device_probe, pinmux_probe),
742e9034789SMichal Meloun DEVMETHOD(device_attach, pinmux_attach),
743e9034789SMichal Meloun DEVMETHOD(device_detach, pinmux_detach),
744e9034789SMichal Meloun
745e9034789SMichal Meloun /* fdt_pinctrl interface */
746e9034789SMichal Meloun DEVMETHOD(fdt_pinctrl_configure,pinmux_configure),
747e9034789SMichal Meloun
748e9034789SMichal Meloun DEVMETHOD_END
749e9034789SMichal Meloun };
750e9034789SMichal Meloun
751e9034789SMichal Meloun static DEFINE_CLASS_0(pinmux, tegra210_pinmux_driver, tegra210_pinmux_methods,
752e9034789SMichal Meloun sizeof(struct pinmux_softc));
753e9034789SMichal Meloun EARLY_DRIVER_MODULE(tegra210_pinmux, simplebus, tegra210_pinmux_driver,
754289f133bSJohn Baldwin NULL, NULL, 71);
755