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