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