1 /* 2 * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. 3 * Copyright (c) 2011 The Chromium OS Authors. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <asm/io.h> 10 #include <asm/arch/pinmux.h> 11 12 /* return 1 if a pingrp is in range */ 13 #define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PMUX_PINGRP_COUNT)) 14 15 /* return 1 if a pmux_func is in range */ 16 #define pmux_func_isvalid(func) \ 17 (((func) >= 0) && ((func) < PMUX_FUNC_COUNT)) 18 19 /* return 1 if a pin_pupd_is in range */ 20 #define pmux_pin_pupd_isvalid(pupd) \ 21 (((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP)) 22 23 /* return 1 if a pin_tristate_is in range */ 24 #define pmux_pin_tristate_isvalid(tristate) \ 25 (((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE)) 26 27 #ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC 28 /* return 1 if a pin_io_is in range */ 29 #define pmux_pin_io_isvalid(io) \ 30 (((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT)) 31 32 /* return 1 if a pin_lock is in range */ 33 #define pmux_pin_lock_isvalid(lock) \ 34 (((lock) >= PMUX_PIN_LOCK_DISABLE) && ((lock) <= PMUX_PIN_LOCK_ENABLE)) 35 36 /* return 1 if a pin_od is in range */ 37 #define pmux_pin_od_isvalid(od) \ 38 (((od) >= PMUX_PIN_OD_DISABLE) && ((od) <= PMUX_PIN_OD_ENABLE)) 39 40 /* return 1 if a pin_ioreset_is in range */ 41 #define pmux_pin_ioreset_isvalid(ioreset) \ 42 (((ioreset) >= PMUX_PIN_IO_RESET_DISABLE) && \ 43 ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE)) 44 45 #ifdef TEGRA_PMX_HAS_RCV_SEL 46 /* return 1 if a pin_rcv_sel_is in range */ 47 #define pmux_pin_rcv_sel_isvalid(rcv_sel) \ 48 (((rcv_sel) >= PMUX_PIN_RCV_SEL_NORMAL) && \ 49 ((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH)) 50 #endif /* TEGRA_PMX_HAS_RCV_SEL */ 51 #endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */ 52 53 #define _R(offset) (u32 *)(NV_PA_APB_MISC_BASE + (offset)) 54 55 #if defined(CONFIG_TEGRA20) 56 57 #define MUX_REG(grp) _R(0x80 + ((tegra_soc_pingroups[grp].ctl_id / 16) * 4)) 58 #define MUX_SHIFT(grp) ((tegra_soc_pingroups[grp].ctl_id % 16) * 2) 59 60 #define PULL_REG(grp) _R(0xa0 + ((tegra_soc_pingroups[grp].pull_id / 16) * 4)) 61 #define PULL_SHIFT(grp) ((tegra_soc_pingroups[grp].pull_id % 16) * 2) 62 63 #define TRI_REG(grp) _R(0x14 + (((grp) / 32) * 4)) 64 #define TRI_SHIFT(grp) ((grp) % 32) 65 66 #else 67 68 #define REG(pin) _R(0x3000 + ((pin) * 4)) 69 70 #define MUX_REG(pin) REG(pin) 71 #define MUX_SHIFT(pin) 0 72 73 #define PULL_REG(pin) REG(pin) 74 #define PULL_SHIFT(pin) 2 75 76 #define TRI_REG(pin) REG(pin) 77 #define TRI_SHIFT(pin) 4 78 79 #endif /* CONFIG_TEGRA20 */ 80 81 #define DRV_REG(group) _R(0x868 + ((group) * 4)) 82 83 #define IO_SHIFT 5 84 #define OD_SHIFT 6 85 #define LOCK_SHIFT 7 86 #define IO_RESET_SHIFT 8 87 #define RCV_SEL_SHIFT 9 88 89 #if !defined(CONFIG_TEGRA20) && !defined(CONFIG_TEGRA30) 90 /* This register/field only exists on Tegra114 and later */ 91 #define APB_MISC_PP_PINMUX_GLOBAL_0 0x40 92 #define CLAMP_INPUTS_WHEN_TRISTATED 1 93 94 void pinmux_set_tristate_input_clamping(void) 95 { 96 u32 *reg = _R(APB_MISC_PP_PINMUX_GLOBAL_0); 97 u32 val; 98 99 val = readl(reg); 100 val |= CLAMP_INPUTS_WHEN_TRISTATED; 101 writel(val, reg); 102 } 103 #endif 104 105 void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func) 106 { 107 u32 *reg = MUX_REG(pin); 108 int i, mux = -1; 109 u32 val; 110 111 if (func == PMUX_FUNC_DEFAULT) 112 return; 113 114 /* Error check on pin and func */ 115 assert(pmux_pingrp_isvalid(pin)); 116 assert(pmux_func_isvalid(func)); 117 118 if (func >= PMUX_FUNC_RSVD1) { 119 mux = (func - PMUX_FUNC_RSVD1) & 3; 120 } else { 121 /* Search for the appropriate function */ 122 for (i = 0; i < 4; i++) { 123 if (tegra_soc_pingroups[pin].funcs[i] == func) { 124 mux = i; 125 break; 126 } 127 } 128 } 129 assert(mux != -1); 130 131 val = readl(reg); 132 val &= ~(3 << MUX_SHIFT(pin)); 133 val |= (mux << MUX_SHIFT(pin)); 134 writel(val, reg); 135 } 136 137 void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd) 138 { 139 u32 *reg = PULL_REG(pin); 140 u32 val; 141 142 /* Error check on pin and pupd */ 143 assert(pmux_pingrp_isvalid(pin)); 144 assert(pmux_pin_pupd_isvalid(pupd)); 145 146 val = readl(reg); 147 val &= ~(3 << PULL_SHIFT(pin)); 148 val |= (pupd << PULL_SHIFT(pin)); 149 writel(val, reg); 150 } 151 152 static void pinmux_set_tristate(enum pmux_pingrp pin, int tri) 153 { 154 u32 *reg = TRI_REG(pin); 155 u32 val; 156 157 /* Error check on pin */ 158 assert(pmux_pingrp_isvalid(pin)); 159 assert(pmux_pin_tristate_isvalid(tri)); 160 161 val = readl(reg); 162 if (tri == PMUX_TRI_TRISTATE) 163 val |= (1 << TRI_SHIFT(pin)); 164 else 165 val &= ~(1 << TRI_SHIFT(pin)); 166 writel(val, reg); 167 } 168 169 void pinmux_tristate_enable(enum pmux_pingrp pin) 170 { 171 pinmux_set_tristate(pin, PMUX_TRI_TRISTATE); 172 } 173 174 void pinmux_tristate_disable(enum pmux_pingrp pin) 175 { 176 pinmux_set_tristate(pin, PMUX_TRI_NORMAL); 177 } 178 179 #ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC 180 void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io) 181 { 182 u32 *reg = REG(pin); 183 u32 val; 184 185 if (io == PMUX_PIN_NONE) 186 return; 187 188 /* Error check on pin and io */ 189 assert(pmux_pingrp_isvalid(pin)); 190 assert(pmux_pin_io_isvalid(io)); 191 192 val = readl(reg); 193 if (io == PMUX_PIN_INPUT) 194 val |= (io & 1) << IO_SHIFT; 195 else 196 val &= ~(1 << IO_SHIFT); 197 writel(val, reg); 198 } 199 200 static void pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock) 201 { 202 u32 *reg = REG(pin); 203 u32 val; 204 205 if (lock == PMUX_PIN_LOCK_DEFAULT) 206 return; 207 208 /* Error check on pin and lock */ 209 assert(pmux_pingrp_isvalid(pin)); 210 assert(pmux_pin_lock_isvalid(lock)); 211 212 val = readl(reg); 213 if (lock == PMUX_PIN_LOCK_ENABLE) { 214 val |= (1 << LOCK_SHIFT); 215 } else { 216 if (val & (1 << LOCK_SHIFT)) 217 printf("%s: Cannot clear LOCK bit!\n", __func__); 218 val &= ~(1 << LOCK_SHIFT); 219 } 220 writel(val, reg); 221 222 return; 223 } 224 225 static void pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od) 226 { 227 u32 *reg = REG(pin); 228 u32 val; 229 230 if (od == PMUX_PIN_OD_DEFAULT) 231 return; 232 233 /* Error check on pin and od */ 234 assert(pmux_pingrp_isvalid(pin)); 235 assert(pmux_pin_od_isvalid(od)); 236 237 val = readl(reg); 238 if (od == PMUX_PIN_OD_ENABLE) 239 val |= (1 << OD_SHIFT); 240 else 241 val &= ~(1 << OD_SHIFT); 242 writel(val, reg); 243 244 return; 245 } 246 247 static void pinmux_set_ioreset(enum pmux_pingrp pin, 248 enum pmux_pin_ioreset ioreset) 249 { 250 u32 *reg = REG(pin); 251 u32 val; 252 253 if (ioreset == PMUX_PIN_IO_RESET_DEFAULT) 254 return; 255 256 /* Error check on pin and ioreset */ 257 assert(pmux_pingrp_isvalid(pin)); 258 assert(pmux_pin_ioreset_isvalid(ioreset)); 259 260 val = readl(reg); 261 if (ioreset == PMUX_PIN_IO_RESET_ENABLE) 262 val |= (1 << IO_RESET_SHIFT); 263 else 264 val &= ~(1 << IO_RESET_SHIFT); 265 writel(val, reg); 266 267 return; 268 } 269 270 #ifdef TEGRA_PMX_HAS_RCV_SEL 271 static void pinmux_set_rcv_sel(enum pmux_pingrp pin, 272 enum pmux_pin_rcv_sel rcv_sel) 273 { 274 u32 *reg = REG(pin); 275 u32 val; 276 277 if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT) 278 return; 279 280 /* Error check on pin and rcv_sel */ 281 assert(pmux_pingrp_isvalid(pin)); 282 assert(pmux_pin_rcv_sel_isvalid(rcv_sel)); 283 284 val = readl(reg); 285 if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH) 286 val |= (1 << RCV_SEL_SHIFT); 287 else 288 val &= ~(1 << RCV_SEL_SHIFT); 289 writel(val, reg); 290 291 return; 292 } 293 #endif /* TEGRA_PMX_HAS_RCV_SEL */ 294 #endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */ 295 296 static void pinmux_config_pingrp(const struct pmux_pingrp_config *config) 297 { 298 enum pmux_pingrp pin = config->pingrp; 299 300 pinmux_set_func(pin, config->func); 301 pinmux_set_pullupdown(pin, config->pull); 302 pinmux_set_tristate(pin, config->tristate); 303 #ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC 304 pinmux_set_io(pin, config->io); 305 pinmux_set_lock(pin, config->lock); 306 pinmux_set_od(pin, config->od); 307 pinmux_set_ioreset(pin, config->ioreset); 308 #ifdef TEGRA_PMX_HAS_RCV_SEL 309 pinmux_set_rcv_sel(pin, config->rcv_sel); 310 #endif 311 #endif 312 } 313 314 void pinmux_config_pingrp_table(const struct pmux_pingrp_config *config, 315 int len) 316 { 317 int i; 318 319 for (i = 0; i < len; i++) 320 pinmux_config_pingrp(&config[i]); 321 } 322 323 #ifdef TEGRA_PMX_HAS_DRVGRPS 324 325 #define pmux_drvgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PMUX_DRVGRP_COUNT)) 326 327 #define pmux_slw_isvalid(slw) \ 328 (((slw) >= PMUX_SLWF_MIN) && ((slw) <= PMUX_SLWF_MAX)) 329 330 #define pmux_drv_isvalid(drv) \ 331 (((drv) >= PMUX_DRVUP_MIN) && ((drv) <= PMUX_DRVUP_MAX)) 332 333 #define pmux_lpmd_isvalid(lpm) \ 334 (((lpm) >= PMUX_LPMD_X8) && ((lpm) <= PMUX_LPMD_X)) 335 336 #define pmux_schmt_isvalid(schmt) \ 337 (((schmt) >= PMUX_SCHMT_DISABLE) && ((schmt) <= PMUX_SCHMT_ENABLE)) 338 339 #define pmux_hsm_isvalid(hsm) \ 340 (((hsm) >= PMUX_HSM_DISABLE) && ((hsm) <= PMUX_HSM_ENABLE)) 341 342 #define HSM_SHIFT 2 343 #define SCHMT_SHIFT 3 344 #define LPMD_SHIFT 4 345 #define LPMD_MASK (3 << LPMD_SHIFT) 346 #define DRVDN_SHIFT 12 347 #define DRVDN_MASK (0x7F << DRVDN_SHIFT) 348 #define DRVUP_SHIFT 20 349 #define DRVUP_MASK (0x7F << DRVUP_SHIFT) 350 #define SLWR_SHIFT 28 351 #define SLWR_MASK (3 << SLWR_SHIFT) 352 #define SLWF_SHIFT 30 353 #define SLWF_MASK (3 << SLWF_SHIFT) 354 355 static void pinmux_set_drvup_slwf(enum pmux_drvgrp grp, int slwf) 356 { 357 u32 *reg = DRV_REG(grp); 358 u32 val; 359 360 /* NONE means unspecified/do not change/use POR value */ 361 if (slwf == PMUX_SLWF_NONE) 362 return; 363 364 /* Error check on pad and slwf */ 365 assert(pmux_drvgrp_isvalid(grp)); 366 assert(pmux_slw_isvalid(slwf)); 367 368 val = readl(reg); 369 val &= ~SLWF_MASK; 370 val |= (slwf << SLWF_SHIFT); 371 writel(val, reg); 372 373 return; 374 } 375 376 static void pinmux_set_drvdn_slwr(enum pmux_drvgrp grp, int slwr) 377 { 378 u32 *reg = DRV_REG(grp); 379 u32 val; 380 381 /* NONE means unspecified/do not change/use POR value */ 382 if (slwr == PMUX_SLWR_NONE) 383 return; 384 385 /* Error check on pad and slwr */ 386 assert(pmux_drvgrp_isvalid(grp)); 387 assert(pmux_slw_isvalid(slwr)); 388 389 val = readl(reg); 390 val &= ~SLWR_MASK; 391 val |= (slwr << SLWR_SHIFT); 392 writel(val, reg); 393 394 return; 395 } 396 397 static void pinmux_set_drvup(enum pmux_drvgrp grp, int drvup) 398 { 399 u32 *reg = DRV_REG(grp); 400 u32 val; 401 402 /* NONE means unspecified/do not change/use POR value */ 403 if (drvup == PMUX_DRVUP_NONE) 404 return; 405 406 /* Error check on pad and drvup */ 407 assert(pmux_drvgrp_isvalid(grp)); 408 assert(pmux_drv_isvalid(drvup)); 409 410 val = readl(reg); 411 val &= ~DRVUP_MASK; 412 val |= (drvup << DRVUP_SHIFT); 413 writel(val, reg); 414 415 return; 416 } 417 418 static void pinmux_set_drvdn(enum pmux_drvgrp grp, int drvdn) 419 { 420 u32 *reg = DRV_REG(grp); 421 u32 val; 422 423 /* NONE means unspecified/do not change/use POR value */ 424 if (drvdn == PMUX_DRVDN_NONE) 425 return; 426 427 /* Error check on pad and drvdn */ 428 assert(pmux_drvgrp_isvalid(grp)); 429 assert(pmux_drv_isvalid(drvdn)); 430 431 val = readl(reg); 432 val &= ~DRVDN_MASK; 433 val |= (drvdn << DRVDN_SHIFT); 434 writel(val, reg); 435 436 return; 437 } 438 439 static void pinmux_set_lpmd(enum pmux_drvgrp grp, enum pmux_lpmd lpmd) 440 { 441 u32 *reg = DRV_REG(grp); 442 u32 val; 443 444 /* NONE means unspecified/do not change/use POR value */ 445 if (lpmd == PMUX_LPMD_NONE) 446 return; 447 448 /* Error check pad and lpmd value */ 449 assert(pmux_drvgrp_isvalid(grp)); 450 assert(pmux_lpmd_isvalid(lpmd)); 451 452 val = readl(reg); 453 val &= ~LPMD_MASK; 454 val |= (lpmd << LPMD_SHIFT); 455 writel(val, reg); 456 457 return; 458 } 459 460 static void pinmux_set_schmt(enum pmux_drvgrp grp, enum pmux_schmt schmt) 461 { 462 u32 *reg = DRV_REG(grp); 463 u32 val; 464 465 /* NONE means unspecified/do not change/use POR value */ 466 if (schmt == PMUX_SCHMT_NONE) 467 return; 468 469 /* Error check pad */ 470 assert(pmux_drvgrp_isvalid(grp)); 471 assert(pmux_schmt_isvalid(schmt)); 472 473 val = readl(reg); 474 if (schmt == PMUX_SCHMT_ENABLE) 475 val |= (1 << SCHMT_SHIFT); 476 else 477 val &= ~(1 << SCHMT_SHIFT); 478 writel(val, reg); 479 480 return; 481 } 482 483 static void pinmux_set_hsm(enum pmux_drvgrp grp, enum pmux_hsm hsm) 484 { 485 u32 *reg = DRV_REG(grp); 486 u32 val; 487 488 /* NONE means unspecified/do not change/use POR value */ 489 if (hsm == PMUX_HSM_NONE) 490 return; 491 492 /* Error check pad */ 493 assert(pmux_drvgrp_isvalid(grp)); 494 assert(pmux_hsm_isvalid(hsm)); 495 496 val = readl(reg); 497 if (hsm == PMUX_HSM_ENABLE) 498 val |= (1 << HSM_SHIFT); 499 else 500 val &= ~(1 << HSM_SHIFT); 501 writel(val, reg); 502 503 return; 504 } 505 506 static void pinmux_config_drvgrp(const struct pmux_drvgrp_config *config) 507 { 508 enum pmux_drvgrp grp = config->drvgrp; 509 510 pinmux_set_drvup_slwf(grp, config->slwf); 511 pinmux_set_drvdn_slwr(grp, config->slwr); 512 pinmux_set_drvup(grp, config->drvup); 513 pinmux_set_drvdn(grp, config->drvdn); 514 pinmux_set_lpmd(grp, config->lpmd); 515 pinmux_set_schmt(grp, config->schmt); 516 pinmux_set_hsm(grp, config->hsm); 517 } 518 519 void pinmux_config_drvgrp_table(const struct pmux_drvgrp_config *config, 520 int len) 521 { 522 int i; 523 524 for (i = 0; i < len; i++) 525 pinmux_config_drvgrp(&config[i]); 526 } 527 #endif /* TEGRA_PMX_HAS_DRVGRPS */ 528