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