1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright 2020 Michal Meloun <mmel@FreeBSD.org> 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