1 /* 2 * Copyright (c) 2011 The Chromium OS Authors. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 /* Tegra20 high-level function multiplexing */ 8 #include <common.h> 9 #include <asm/arch/clock.h> 10 #include <asm/arch/funcmux.h> 11 #include <asm/arch/pinmux.h> 12 13 /* 14 * The PINMUX macro is used to set up pinmux tables. 15 */ 16 #define PINMUX(grp, mux, pupd, tri) \ 17 {PMUX_PINGRP_##grp, PMUX_FUNC_##mux, PMUX_PULL_##pupd, PMUX_TRI_##tri} 18 19 static const struct pmux_pingrp_config disp1_default[] = { 20 PINMUX(LDI, DISPA, NORMAL, NORMAL), 21 PINMUX(LHP0, DISPA, NORMAL, NORMAL), 22 PINMUX(LHP1, DISPA, NORMAL, NORMAL), 23 PINMUX(LHP2, DISPA, NORMAL, NORMAL), 24 PINMUX(LHS, DISPA, NORMAL, NORMAL), 25 PINMUX(LM0, RSVD4, NORMAL, NORMAL), 26 PINMUX(LPP, DISPA, NORMAL, NORMAL), 27 PINMUX(LPW0, DISPA, NORMAL, NORMAL), 28 PINMUX(LPW2, DISPA, NORMAL, NORMAL), 29 PINMUX(LSC0, DISPA, NORMAL, NORMAL), 30 PINMUX(LSPI, DISPA, NORMAL, NORMAL), 31 PINMUX(LVP1, DISPA, NORMAL, NORMAL), 32 PINMUX(LVS, DISPA, NORMAL, NORMAL), 33 PINMUX(SLXD, SPDIF, NORMAL, NORMAL), 34 }; 35 36 37 int funcmux_select(enum periph_id id, int config) 38 { 39 int bad_config = config != FUNCMUX_DEFAULT; 40 41 switch (id) { 42 case PERIPH_ID_UART1: 43 switch (config) { 44 case FUNCMUX_UART1_IRRX_IRTX: 45 pinmux_set_func(PMUX_PINGRP_IRRX, PMUX_FUNC_UARTA); 46 pinmux_set_func(PMUX_PINGRP_IRTX, PMUX_FUNC_UARTA); 47 pinmux_tristate_disable(PMUX_PINGRP_IRRX); 48 pinmux_tristate_disable(PMUX_PINGRP_IRTX); 49 break; 50 case FUNCMUX_UART1_UAA_UAB: 51 pinmux_set_func(PMUX_PINGRP_UAA, PMUX_FUNC_UARTA); 52 pinmux_set_func(PMUX_PINGRP_UAB, PMUX_FUNC_UARTA); 53 pinmux_tristate_disable(PMUX_PINGRP_UAA); 54 pinmux_tristate_disable(PMUX_PINGRP_UAB); 55 bad_config = 0; 56 break; 57 case FUNCMUX_UART1_GPU: 58 pinmux_set_func(PMUX_PINGRP_GPU, PMUX_FUNC_UARTA); 59 pinmux_tristate_disable(PMUX_PINGRP_GPU); 60 bad_config = 0; 61 break; 62 case FUNCMUX_UART1_SDIO1: 63 pinmux_set_func(PMUX_PINGRP_SDIO1, PMUX_FUNC_UARTA); 64 pinmux_tristate_disable(PMUX_PINGRP_SDIO1); 65 bad_config = 0; 66 break; 67 } 68 if (!bad_config) { 69 /* 70 * Tegra appears to boot with function UARTA pre- 71 * selected on mux group SDB. If two mux groups are 72 * both set to the same function, it's unclear which 73 * group's pins drive the RX signals into the HW. 74 * For UARTA, SDB certainly overrides group IRTX in 75 * practice. To solve this, configure some alternative 76 * function on SDB to avoid the conflict. Also, tri- 77 * state the group to avoid driving any signal onto it 78 * until we know what's connected. 79 */ 80 pinmux_tristate_enable(PMUX_PINGRP_SDB); 81 pinmux_set_func(PMUX_PINGRP_SDB, PMUX_FUNC_SDIO3); 82 } 83 break; 84 85 case PERIPH_ID_UART2: 86 if (config == FUNCMUX_UART2_UAD) { 87 pinmux_set_func(PMUX_PINGRP_UAD, PMUX_FUNC_UARTB); 88 pinmux_tristate_disable(PMUX_PINGRP_UAD); 89 } 90 break; 91 92 case PERIPH_ID_UART4: 93 if (config == FUNCMUX_UART4_GMC) { 94 pinmux_set_func(PMUX_PINGRP_GMC, PMUX_FUNC_UARTD); 95 pinmux_tristate_disable(PMUX_PINGRP_GMC); 96 } 97 break; 98 99 case PERIPH_ID_DVC_I2C: 100 /* there is only one selection, pinmux_config is ignored */ 101 if (config == FUNCMUX_DVC_I2CP) { 102 pinmux_set_func(PMUX_PINGRP_I2CP, PMUX_FUNC_I2C); 103 pinmux_tristate_disable(PMUX_PINGRP_I2CP); 104 } 105 break; 106 107 case PERIPH_ID_I2C1: 108 /* support pinmux_config of 0 for now, */ 109 if (config == FUNCMUX_I2C1_RM) { 110 pinmux_set_func(PMUX_PINGRP_RM, PMUX_FUNC_I2C); 111 pinmux_tristate_disable(PMUX_PINGRP_RM); 112 } 113 break; 114 case PERIPH_ID_I2C2: /* I2C2 */ 115 switch (config) { 116 case FUNCMUX_I2C2_DDC: /* DDC pin group, select I2C2 */ 117 pinmux_set_func(PMUX_PINGRP_DDC, PMUX_FUNC_I2C2); 118 /* PTA to HDMI */ 119 pinmux_set_func(PMUX_PINGRP_PTA, PMUX_FUNC_HDMI); 120 pinmux_tristate_disable(PMUX_PINGRP_DDC); 121 break; 122 case FUNCMUX_I2C2_PTA: /* PTA pin group, select I2C2 */ 123 pinmux_set_func(PMUX_PINGRP_PTA, PMUX_FUNC_I2C2); 124 /* set DDC_SEL to RSVDx (RSVD2 works for now) */ 125 pinmux_set_func(PMUX_PINGRP_DDC, PMUX_FUNC_RSVD2); 126 pinmux_tristate_disable(PMUX_PINGRP_PTA); 127 bad_config = 0; 128 break; 129 } 130 break; 131 case PERIPH_ID_I2C3: /* I2C3 */ 132 /* support pinmux_config of 0 for now */ 133 if (config == FUNCMUX_I2C3_DTF) { 134 pinmux_set_func(PMUX_PINGRP_DTF, PMUX_FUNC_I2C3); 135 pinmux_tristate_disable(PMUX_PINGRP_DTF); 136 } 137 break; 138 139 case PERIPH_ID_SDMMC1: 140 if (config == FUNCMUX_SDMMC1_SDIO1_4BIT) { 141 pinmux_set_func(PMUX_PINGRP_SDIO1, PMUX_FUNC_SDIO1); 142 pinmux_tristate_disable(PMUX_PINGRP_SDIO1); 143 } 144 break; 145 146 case PERIPH_ID_SDMMC2: 147 if (config == FUNCMUX_SDMMC2_DTA_DTD_8BIT) { 148 pinmux_set_func(PMUX_PINGRP_DTA, PMUX_FUNC_SDIO2); 149 pinmux_set_func(PMUX_PINGRP_DTD, PMUX_FUNC_SDIO2); 150 151 pinmux_tristate_disable(PMUX_PINGRP_DTA); 152 pinmux_tristate_disable(PMUX_PINGRP_DTD); 153 } 154 break; 155 156 case PERIPH_ID_SDMMC3: 157 switch (config) { 158 case FUNCMUX_SDMMC3_SDB_SLXA_8BIT: 159 pinmux_set_func(PMUX_PINGRP_SLXA, PMUX_FUNC_SDIO3); 160 pinmux_set_func(PMUX_PINGRP_SLXC, PMUX_FUNC_SDIO3); 161 pinmux_set_func(PMUX_PINGRP_SLXD, PMUX_FUNC_SDIO3); 162 pinmux_set_func(PMUX_PINGRP_SLXK, PMUX_FUNC_SDIO3); 163 164 pinmux_tristate_disable(PMUX_PINGRP_SLXA); 165 pinmux_tristate_disable(PMUX_PINGRP_SLXC); 166 pinmux_tristate_disable(PMUX_PINGRP_SLXD); 167 pinmux_tristate_disable(PMUX_PINGRP_SLXK); 168 /* fall through */ 169 170 case FUNCMUX_SDMMC3_SDB_4BIT: 171 pinmux_set_func(PMUX_PINGRP_SDB, PMUX_FUNC_SDIO3); 172 pinmux_set_func(PMUX_PINGRP_SDC, PMUX_FUNC_SDIO3); 173 pinmux_set_func(PMUX_PINGRP_SDD, PMUX_FUNC_SDIO3); 174 175 pinmux_tristate_disable(PMUX_PINGRP_SDB); 176 pinmux_tristate_disable(PMUX_PINGRP_SDC); 177 pinmux_tristate_disable(PMUX_PINGRP_SDD); 178 bad_config = 0; 179 break; 180 } 181 break; 182 183 case PERIPH_ID_SDMMC4: 184 switch (config) { 185 case FUNCMUX_SDMMC4_ATC_ATD_8BIT: 186 pinmux_set_func(PMUX_PINGRP_ATC, PMUX_FUNC_SDIO4); 187 pinmux_set_func(PMUX_PINGRP_ATD, PMUX_FUNC_SDIO4); 188 189 pinmux_tristate_disable(PMUX_PINGRP_ATC); 190 pinmux_tristate_disable(PMUX_PINGRP_ATD); 191 break; 192 193 case FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT: 194 pinmux_set_func(PMUX_PINGRP_GME, PMUX_FUNC_SDIO4); 195 pinmux_tristate_disable(PMUX_PINGRP_GME); 196 /* fall through */ 197 198 case FUNCMUX_SDMMC4_ATB_GMA_4_BIT: 199 pinmux_set_func(PMUX_PINGRP_ATB, PMUX_FUNC_SDIO4); 200 pinmux_set_func(PMUX_PINGRP_GMA, PMUX_FUNC_SDIO4); 201 202 pinmux_tristate_disable(PMUX_PINGRP_ATB); 203 pinmux_tristate_disable(PMUX_PINGRP_GMA); 204 bad_config = 0; 205 break; 206 } 207 break; 208 209 case PERIPH_ID_KBC: 210 if (config == FUNCMUX_DEFAULT) { 211 enum pmux_pingrp grp[] = {PMUX_PINGRP_KBCA, 212 PMUX_PINGRP_KBCB, PMUX_PINGRP_KBCC, 213 PMUX_PINGRP_KBCD, PMUX_PINGRP_KBCE, 214 PMUX_PINGRP_KBCF}; 215 int i; 216 217 for (i = 0; i < ARRAY_SIZE(grp); i++) { 218 pinmux_tristate_disable(grp[i]); 219 pinmux_set_func(grp[i], PMUX_FUNC_KBC); 220 pinmux_set_pullupdown(grp[i], PMUX_PULL_UP); 221 } 222 } 223 break; 224 225 case PERIPH_ID_USB2: 226 if (config == FUNCMUX_USB2_ULPI) { 227 pinmux_set_func(PMUX_PINGRP_UAA, PMUX_FUNC_ULPI); 228 pinmux_set_func(PMUX_PINGRP_UAB, PMUX_FUNC_ULPI); 229 pinmux_set_func(PMUX_PINGRP_UDA, PMUX_FUNC_ULPI); 230 231 pinmux_tristate_disable(PMUX_PINGRP_UAA); 232 pinmux_tristate_disable(PMUX_PINGRP_UAB); 233 pinmux_tristate_disable(PMUX_PINGRP_UDA); 234 } 235 break; 236 237 case PERIPH_ID_SPI1: 238 if (config == FUNCMUX_SPI1_GMC_GMD) { 239 pinmux_set_func(PMUX_PINGRP_GMC, PMUX_FUNC_SFLASH); 240 pinmux_set_func(PMUX_PINGRP_GMD, PMUX_FUNC_SFLASH); 241 242 pinmux_tristate_disable(PMUX_PINGRP_GMC); 243 pinmux_tristate_disable(PMUX_PINGRP_GMD); 244 } 245 break; 246 247 case PERIPH_ID_NDFLASH: 248 switch (config) { 249 case FUNCMUX_NDFLASH_ATC: 250 pinmux_set_func(PMUX_PINGRP_ATC, PMUX_FUNC_NAND); 251 pinmux_tristate_disable(PMUX_PINGRP_ATC); 252 break; 253 case FUNCMUX_NDFLASH_KBC_8_BIT: 254 pinmux_set_func(PMUX_PINGRP_KBCA, PMUX_FUNC_NAND); 255 pinmux_set_func(PMUX_PINGRP_KBCB, PMUX_FUNC_NAND); 256 pinmux_set_func(PMUX_PINGRP_KBCC, PMUX_FUNC_NAND); 257 pinmux_set_func(PMUX_PINGRP_KBCD, PMUX_FUNC_NAND); 258 pinmux_set_func(PMUX_PINGRP_KBCE, PMUX_FUNC_NAND); 259 pinmux_set_func(PMUX_PINGRP_KBCF, PMUX_FUNC_NAND); 260 261 pinmux_tristate_disable(PMUX_PINGRP_KBCA); 262 pinmux_tristate_disable(PMUX_PINGRP_KBCB); 263 pinmux_tristate_disable(PMUX_PINGRP_KBCC); 264 pinmux_tristate_disable(PMUX_PINGRP_KBCD); 265 pinmux_tristate_disable(PMUX_PINGRP_KBCE); 266 pinmux_tristate_disable(PMUX_PINGRP_KBCF); 267 268 bad_config = 0; 269 break; 270 } 271 break; 272 case PERIPH_ID_DISP1: 273 if (config == FUNCMUX_DEFAULT) { 274 int i; 275 276 for (i = PMUX_PINGRP_LD0; i <= PMUX_PINGRP_LD17; i++) { 277 pinmux_set_func(i, PMUX_FUNC_DISPA); 278 pinmux_tristate_disable(i); 279 pinmux_set_pullupdown(i, PMUX_PULL_NORMAL); 280 } 281 pinmux_config_pingrp_table(disp1_default, 282 ARRAY_SIZE(disp1_default)); 283 } 284 break; 285 286 default: 287 debug("%s: invalid periph_id %d", __func__, id); 288 return -1; 289 } 290 291 if (bad_config) { 292 debug("%s: invalid config %d for periph_id %d", __func__, 293 config, id); 294 return -1; 295 } 296 297 return 0; 298 } 299