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