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_PINS_HAVE_E_INPUT 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 #endif 32 33 #ifdef TEGRA_PMX_PINS_HAVE_LOCK 34 /* return 1 if a pin_lock is in range */ 35 #define pmux_pin_lock_isvalid(lock) \ 36 (((lock) >= PMUX_PIN_LOCK_DISABLE) && ((lock) <= PMUX_PIN_LOCK_ENABLE)) 37 #endif 38 39 #ifdef TEGRA_PMX_PINS_HAVE_OD 40 /* return 1 if a pin_od is in range */ 41 #define pmux_pin_od_isvalid(od) \ 42 (((od) >= PMUX_PIN_OD_DISABLE) && ((od) <= PMUX_PIN_OD_ENABLE)) 43 #endif 44 45 #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET 46 /* return 1 if a pin_ioreset_is in range */ 47 #define pmux_pin_ioreset_isvalid(ioreset) \ 48 (((ioreset) >= PMUX_PIN_IO_RESET_DISABLE) && \ 49 ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE)) 50 #endif 51 52 #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL 53 /* return 1 if a pin_rcv_sel_is in range */ 54 #define pmux_pin_rcv_sel_isvalid(rcv_sel) \ 55 (((rcv_sel) >= PMUX_PIN_RCV_SEL_NORMAL) && \ 56 ((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH)) 57 #endif 58 59 #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV 60 /* return 1 if a pin_e_io_hv is in range */ 61 #define pmux_pin_e_io_hv_isvalid(e_io_hv) \ 62 (((e_io_hv) >= PMUX_PIN_E_IO_HV_NORMAL) && \ 63 ((e_io_hv) <= PMUX_PIN_E_IO_HV_HIGH)) 64 #endif 65 66 #ifdef TEGRA_PMX_GRPS_HAVE_LPMD 67 #define pmux_lpmd_isvalid(lpm) \ 68 (((lpm) >= PMUX_LPMD_X8) && ((lpm) <= PMUX_LPMD_X)) 69 #endif 70 71 #if defined(TEGRA_PMX_PINS_HAVE_SCHMT) || defined(TEGRA_PMX_GRPS_HAVE_SCHMT) 72 #define pmux_schmt_isvalid(schmt) \ 73 (((schmt) >= PMUX_SCHMT_DISABLE) && ((schmt) <= PMUX_SCHMT_ENABLE)) 74 #endif 75 76 #if defined(TEGRA_PMX_PINS_HAVE_HSM) || defined(TEGRA_PMX_GRPS_HAVE_HSM) 77 #define pmux_hsm_isvalid(hsm) \ 78 (((hsm) >= PMUX_HSM_DISABLE) && ((hsm) <= PMUX_HSM_ENABLE)) 79 #endif 80 81 #define _R(offset) (u32 *)(NV_PA_APB_MISC_BASE + (offset)) 82 83 #if defined(CONFIG_TEGRA20) 84 85 #define MUX_REG(grp) _R(0x80 + ((tegra_soc_pingroups[grp].ctl_id / 16) * 4)) 86 #define MUX_SHIFT(grp) ((tegra_soc_pingroups[grp].ctl_id % 16) * 2) 87 88 #define PULL_REG(grp) _R(0xa0 + ((tegra_soc_pingroups[grp].pull_id / 16) * 4)) 89 #define PULL_SHIFT(grp) ((tegra_soc_pingroups[grp].pull_id % 16) * 2) 90 91 #define TRI_REG(grp) _R(0x14 + (((grp) / 32) * 4)) 92 #define TRI_SHIFT(grp) ((grp) % 32) 93 94 #else 95 96 #define REG(pin) _R(0x3000 + ((pin) * 4)) 97 98 #define MUX_REG(pin) REG(pin) 99 #define MUX_SHIFT(pin) 0 100 101 #define PULL_REG(pin) REG(pin) 102 #define PULL_SHIFT(pin) 2 103 104 #define TRI_REG(pin) REG(pin) 105 #define TRI_SHIFT(pin) 4 106 107 #endif /* CONFIG_TEGRA20 */ 108 109 #define DRV_REG(group) _R(TEGRA_PMX_SOC_DRV_GROUP_BASE_REG + ((group) * 4)) 110 111 #define MIPIPADCTRL_REG(group) _R(TEGRA_PMX_SOC_MIPIPADCTRL_BASE_REG + ((group) * 4)) 112 113 /* 114 * We could force arch-tegraNN/pinmux.h to define all of these. However, 115 * that's a lot of defines, and for now it's manageable to just put a 116 * special case here. It's possible this decision will change with future 117 * SoCs. 118 */ 119 #ifdef CONFIG_TEGRA210 120 #define IO_SHIFT 6 121 #define LOCK_SHIFT 7 122 #ifdef TEGRA_PMX_PINS_HAVE_HSM 123 #define HSM_SHIFT 9 124 #endif 125 #define E_IO_HV_SHIFT 10 126 #define OD_SHIFT 11 127 #ifdef TEGRA_PMX_PINS_HAVE_SCHMT 128 #define SCHMT_SHIFT 12 129 #endif 130 #else 131 #define IO_SHIFT 5 132 #define OD_SHIFT 6 133 #define LOCK_SHIFT 7 134 #define IO_RESET_SHIFT 8 135 #define RCV_SEL_SHIFT 9 136 #endif 137 138 #ifdef TEGRA_PMX_SOC_HAS_IO_CLAMPING 139 /* This register/field only exists on Tegra114 and later */ 140 #define APB_MISC_PP_PINMUX_GLOBAL_0 0x40 141 #define CLAMP_INPUTS_WHEN_TRISTATED 1 142 143 void pinmux_set_tristate_input_clamping(void) 144 { 145 u32 *reg = _R(APB_MISC_PP_PINMUX_GLOBAL_0); 146 147 setbits_le32(reg, CLAMP_INPUTS_WHEN_TRISTATED); 148 } 149 150 void pinmux_clear_tristate_input_clamping(void) 151 { 152 u32 *reg = _R(APB_MISC_PP_PINMUX_GLOBAL_0); 153 154 clrbits_le32(reg, CLAMP_INPUTS_WHEN_TRISTATED); 155 } 156 #endif 157 158 void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func) 159 { 160 u32 *reg = MUX_REG(pin); 161 int i, mux = -1; 162 u32 val; 163 164 if (func == PMUX_FUNC_DEFAULT) 165 return; 166 167 /* Error check on pin and func */ 168 assert(pmux_pingrp_isvalid(pin)); 169 assert(pmux_func_isvalid(func)); 170 171 if (func >= PMUX_FUNC_RSVD1) { 172 mux = (func - PMUX_FUNC_RSVD1) & 3; 173 } else { 174 /* Search for the appropriate function */ 175 for (i = 0; i < 4; i++) { 176 if (tegra_soc_pingroups[pin].funcs[i] == func) { 177 mux = i; 178 break; 179 } 180 } 181 } 182 assert(mux != -1); 183 184 val = readl(reg); 185 val &= ~(3 << MUX_SHIFT(pin)); 186 val |= (mux << MUX_SHIFT(pin)); 187 writel(val, reg); 188 } 189 190 void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd) 191 { 192 u32 *reg = PULL_REG(pin); 193 u32 val; 194 195 /* Error check on pin and pupd */ 196 assert(pmux_pingrp_isvalid(pin)); 197 assert(pmux_pin_pupd_isvalid(pupd)); 198 199 val = readl(reg); 200 val &= ~(3 << PULL_SHIFT(pin)); 201 val |= (pupd << PULL_SHIFT(pin)); 202 writel(val, reg); 203 } 204 205 static void pinmux_set_tristate(enum pmux_pingrp pin, int tri) 206 { 207 u32 *reg = TRI_REG(pin); 208 u32 val; 209 210 /* Error check on pin */ 211 assert(pmux_pingrp_isvalid(pin)); 212 assert(pmux_pin_tristate_isvalid(tri)); 213 214 val = readl(reg); 215 if (tri == PMUX_TRI_TRISTATE) 216 val |= (1 << TRI_SHIFT(pin)); 217 else 218 val &= ~(1 << TRI_SHIFT(pin)); 219 writel(val, reg); 220 } 221 222 void pinmux_tristate_enable(enum pmux_pingrp pin) 223 { 224 pinmux_set_tristate(pin, PMUX_TRI_TRISTATE); 225 } 226 227 void pinmux_tristate_disable(enum pmux_pingrp pin) 228 { 229 pinmux_set_tristate(pin, PMUX_TRI_NORMAL); 230 } 231 232 #ifdef TEGRA_PMX_PINS_HAVE_E_INPUT 233 void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io) 234 { 235 u32 *reg = REG(pin); 236 u32 val; 237 238 if (io == PMUX_PIN_NONE) 239 return; 240 241 /* Error check on pin and io */ 242 assert(pmux_pingrp_isvalid(pin)); 243 assert(pmux_pin_io_isvalid(io)); 244 245 val = readl(reg); 246 if (io == PMUX_PIN_INPUT) 247 val |= (io & 1) << IO_SHIFT; 248 else 249 val &= ~(1 << IO_SHIFT); 250 writel(val, reg); 251 } 252 #endif 253 254 #ifdef TEGRA_PMX_PINS_HAVE_LOCK 255 static void pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock) 256 { 257 u32 *reg = REG(pin); 258 u32 val; 259 260 if (lock == PMUX_PIN_LOCK_DEFAULT) 261 return; 262 263 /* Error check on pin and lock */ 264 assert(pmux_pingrp_isvalid(pin)); 265 assert(pmux_pin_lock_isvalid(lock)); 266 267 val = readl(reg); 268 if (lock == PMUX_PIN_LOCK_ENABLE) { 269 val |= (1 << LOCK_SHIFT); 270 } else { 271 if (val & (1 << LOCK_SHIFT)) 272 printf("%s: Cannot clear LOCK bit!\n", __func__); 273 val &= ~(1 << LOCK_SHIFT); 274 } 275 writel(val, reg); 276 277 return; 278 } 279 #endif 280 281 #ifdef TEGRA_PMX_PINS_HAVE_OD 282 static void pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od) 283 { 284 u32 *reg = REG(pin); 285 u32 val; 286 287 if (od == PMUX_PIN_OD_DEFAULT) 288 return; 289 290 /* Error check on pin and od */ 291 assert(pmux_pingrp_isvalid(pin)); 292 assert(pmux_pin_od_isvalid(od)); 293 294 val = readl(reg); 295 if (od == PMUX_PIN_OD_ENABLE) 296 val |= (1 << OD_SHIFT); 297 else 298 val &= ~(1 << OD_SHIFT); 299 writel(val, reg); 300 301 return; 302 } 303 #endif 304 305 #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET 306 static void pinmux_set_ioreset(enum pmux_pingrp pin, 307 enum pmux_pin_ioreset ioreset) 308 { 309 u32 *reg = REG(pin); 310 u32 val; 311 312 if (ioreset == PMUX_PIN_IO_RESET_DEFAULT) 313 return; 314 315 /* Error check on pin and ioreset */ 316 assert(pmux_pingrp_isvalid(pin)); 317 assert(pmux_pin_ioreset_isvalid(ioreset)); 318 319 val = readl(reg); 320 if (ioreset == PMUX_PIN_IO_RESET_ENABLE) 321 val |= (1 << IO_RESET_SHIFT); 322 else 323 val &= ~(1 << IO_RESET_SHIFT); 324 writel(val, reg); 325 326 return; 327 } 328 #endif 329 330 #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL 331 static void pinmux_set_rcv_sel(enum pmux_pingrp pin, 332 enum pmux_pin_rcv_sel rcv_sel) 333 { 334 u32 *reg = REG(pin); 335 u32 val; 336 337 if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT) 338 return; 339 340 /* Error check on pin and rcv_sel */ 341 assert(pmux_pingrp_isvalid(pin)); 342 assert(pmux_pin_rcv_sel_isvalid(rcv_sel)); 343 344 val = readl(reg); 345 if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH) 346 val |= (1 << RCV_SEL_SHIFT); 347 else 348 val &= ~(1 << RCV_SEL_SHIFT); 349 writel(val, reg); 350 351 return; 352 } 353 #endif 354 355 #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV 356 static void pinmux_set_e_io_hv(enum pmux_pingrp pin, 357 enum pmux_pin_e_io_hv e_io_hv) 358 { 359 u32 *reg = REG(pin); 360 u32 val; 361 362 if (e_io_hv == PMUX_PIN_E_IO_HV_DEFAULT) 363 return; 364 365 /* Error check on pin and e_io_hv */ 366 assert(pmux_pingrp_isvalid(pin)); 367 assert(pmux_pin_e_io_hv_isvalid(e_io_hv)); 368 369 val = readl(reg); 370 if (e_io_hv == PMUX_PIN_E_IO_HV_HIGH) 371 val |= (1 << E_IO_HV_SHIFT); 372 else 373 val &= ~(1 << E_IO_HV_SHIFT); 374 writel(val, reg); 375 376 return; 377 } 378 #endif 379 380 #ifdef TEGRA_PMX_PINS_HAVE_SCHMT 381 static void pinmux_set_schmt(enum pmux_pingrp pin, enum pmux_schmt schmt) 382 { 383 u32 *reg = REG(grp); 384 u32 val; 385 386 /* NONE means unspecified/do not change/use POR value */ 387 if (schmt == PMUX_SCHMT_NONE) 388 return; 389 390 /* Error check pad */ 391 assert(pmux_pingrp_isvalid(pin)); 392 assert(pmux_schmt_isvalid(schmt)); 393 394 val = readl(reg); 395 if (schmt == PMUX_SCHMT_ENABLE) 396 val |= (1 << SCHMT_SHIFT); 397 else 398 val &= ~(1 << SCHMT_SHIFT); 399 writel(val, reg); 400 401 return; 402 } 403 #endif 404 405 #ifdef TEGRA_PMX_PINS_HAVE_HSM 406 static void pinmux_set_hsm(enum pmux_pingrp pin, enum pmux_hsm hsm) 407 { 408 u32 *reg = REG(grp); 409 u32 val; 410 411 /* NONE means unspecified/do not change/use POR value */ 412 if (hsm == PMUX_HSM_NONE) 413 return; 414 415 /* Error check pad */ 416 assert(pmux_pingrp_isvalid(pin)); 417 assert(pmux_hsm_isvalid(hsm)); 418 419 val = readl(reg); 420 if (hsm == PMUX_HSM_ENABLE) 421 val |= (1 << HSM_SHIFT); 422 else 423 val &= ~(1 << HSM_SHIFT); 424 writel(val, reg); 425 426 return; 427 } 428 #endif 429 430 static void pinmux_config_pingrp(const struct pmux_pingrp_config *config) 431 { 432 enum pmux_pingrp pin = config->pingrp; 433 434 pinmux_set_func(pin, config->func); 435 pinmux_set_pullupdown(pin, config->pull); 436 pinmux_set_tristate(pin, config->tristate); 437 #ifdef TEGRA_PMX_PINS_HAVE_E_INPUT 438 pinmux_set_io(pin, config->io); 439 #endif 440 #ifdef TEGRA_PMX_PINS_HAVE_LOCK 441 pinmux_set_lock(pin, config->lock); 442 #endif 443 #ifdef TEGRA_PMX_PINS_HAVE_OD 444 pinmux_set_od(pin, config->od); 445 #endif 446 #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET 447 pinmux_set_ioreset(pin, config->ioreset); 448 #endif 449 #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL 450 pinmux_set_rcv_sel(pin, config->rcv_sel); 451 #endif 452 #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV 453 pinmux_set_e_io_hv(pin, config->e_io_hv); 454 #endif 455 #ifdef TEGRA_PMX_PINS_HAVE_SCHMT 456 pinmux_set_schmt(pin, config->schmt); 457 #endif 458 #ifdef TEGRA_PMX_PINS_HAVE_HSM 459 pinmux_set_hsm(pin, config->hsm); 460 #endif 461 } 462 463 void pinmux_config_pingrp_table(const struct pmux_pingrp_config *config, 464 int len) 465 { 466 int i; 467 468 for (i = 0; i < len; i++) 469 pinmux_config_pingrp(&config[i]); 470 } 471 472 #ifdef TEGRA_PMX_SOC_HAS_DRVGRPS 473 474 #define pmux_drvgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PMUX_DRVGRP_COUNT)) 475 476 #define pmux_slw_isvalid(slw) \ 477 (((slw) >= PMUX_SLWF_MIN) && ((slw) <= PMUX_SLWF_MAX)) 478 479 #define pmux_drv_isvalid(drv) \ 480 (((drv) >= PMUX_DRVUP_MIN) && ((drv) <= PMUX_DRVUP_MAX)) 481 482 #ifdef TEGRA_PMX_GRPS_HAVE_HSM 483 #define HSM_SHIFT 2 484 #endif 485 #ifdef TEGRA_PMX_GRPS_HAVE_SCHMT 486 #define SCHMT_SHIFT 3 487 #endif 488 #ifdef TEGRA_PMX_GRPS_HAVE_LPMD 489 #define LPMD_SHIFT 4 490 #define LPMD_MASK (3 << LPMD_SHIFT) 491 #endif 492 /* 493 * Note that the following DRV* and SLW* defines are accurate for many drive 494 * groups on many SoCs. We really need a per-group data structure to solve 495 * this, since the fields are in different positions/sizes in different 496 * registers (for different groups). 497 * 498 * On Tegra30/114/124, the DRV*_SHIFT values vary. 499 * On Tegra30, the SLW*_SHIFT values vary. 500 * On Tegra30/114/124/210, the DRV*_MASK values vary, although the values 501 * below are wide enough to cover the widest fields, and hopefully don't 502 * interfere with any other fields. 503 * On Tegra30, the SLW*_MASK values vary, but we can't use a value that's 504 * wide enough to cover all cases, since that would cause the field to 505 * overlap with other fields in the narrower cases. 506 */ 507 #define DRVDN_SHIFT 12 508 #define DRVDN_MASK (0x7F << DRVDN_SHIFT) 509 #define DRVUP_SHIFT 20 510 #define DRVUP_MASK (0x7F << DRVUP_SHIFT) 511 #define SLWR_SHIFT 28 512 #define SLWR_MASK (3 << SLWR_SHIFT) 513 #define SLWF_SHIFT 30 514 #define SLWF_MASK (3 << SLWF_SHIFT) 515 516 static void pinmux_set_drvup_slwf(enum pmux_drvgrp grp, int slwf) 517 { 518 u32 *reg = DRV_REG(grp); 519 u32 val; 520 521 /* NONE means unspecified/do not change/use POR value */ 522 if (slwf == PMUX_SLWF_NONE) 523 return; 524 525 /* Error check on pad and slwf */ 526 assert(pmux_drvgrp_isvalid(grp)); 527 assert(pmux_slw_isvalid(slwf)); 528 529 val = readl(reg); 530 val &= ~SLWF_MASK; 531 val |= (slwf << SLWF_SHIFT); 532 writel(val, reg); 533 534 return; 535 } 536 537 static void pinmux_set_drvdn_slwr(enum pmux_drvgrp grp, int slwr) 538 { 539 u32 *reg = DRV_REG(grp); 540 u32 val; 541 542 /* NONE means unspecified/do not change/use POR value */ 543 if (slwr == PMUX_SLWR_NONE) 544 return; 545 546 /* Error check on pad and slwr */ 547 assert(pmux_drvgrp_isvalid(grp)); 548 assert(pmux_slw_isvalid(slwr)); 549 550 val = readl(reg); 551 val &= ~SLWR_MASK; 552 val |= (slwr << SLWR_SHIFT); 553 writel(val, reg); 554 555 return; 556 } 557 558 static void pinmux_set_drvup(enum pmux_drvgrp grp, int drvup) 559 { 560 u32 *reg = DRV_REG(grp); 561 u32 val; 562 563 /* NONE means unspecified/do not change/use POR value */ 564 if (drvup == PMUX_DRVUP_NONE) 565 return; 566 567 /* Error check on pad and drvup */ 568 assert(pmux_drvgrp_isvalid(grp)); 569 assert(pmux_drv_isvalid(drvup)); 570 571 val = readl(reg); 572 val &= ~DRVUP_MASK; 573 val |= (drvup << DRVUP_SHIFT); 574 writel(val, reg); 575 576 return; 577 } 578 579 static void pinmux_set_drvdn(enum pmux_drvgrp grp, int drvdn) 580 { 581 u32 *reg = DRV_REG(grp); 582 u32 val; 583 584 /* NONE means unspecified/do not change/use POR value */ 585 if (drvdn == PMUX_DRVDN_NONE) 586 return; 587 588 /* Error check on pad and drvdn */ 589 assert(pmux_drvgrp_isvalid(grp)); 590 assert(pmux_drv_isvalid(drvdn)); 591 592 val = readl(reg); 593 val &= ~DRVDN_MASK; 594 val |= (drvdn << DRVDN_SHIFT); 595 writel(val, reg); 596 597 return; 598 } 599 600 #ifdef TEGRA_PMX_GRPS_HAVE_LPMD 601 static void pinmux_set_lpmd(enum pmux_drvgrp grp, enum pmux_lpmd lpmd) 602 { 603 u32 *reg = DRV_REG(grp); 604 u32 val; 605 606 /* NONE means unspecified/do not change/use POR value */ 607 if (lpmd == PMUX_LPMD_NONE) 608 return; 609 610 /* Error check pad and lpmd value */ 611 assert(pmux_drvgrp_isvalid(grp)); 612 assert(pmux_lpmd_isvalid(lpmd)); 613 614 val = readl(reg); 615 val &= ~LPMD_MASK; 616 val |= (lpmd << LPMD_SHIFT); 617 writel(val, reg); 618 619 return; 620 } 621 #endif 622 623 #ifdef TEGRA_PMX_GRPS_HAVE_SCHMT 624 static void pinmux_set_schmt(enum pmux_drvgrp grp, enum pmux_schmt schmt) 625 { 626 u32 *reg = DRV_REG(grp); 627 u32 val; 628 629 /* NONE means unspecified/do not change/use POR value */ 630 if (schmt == PMUX_SCHMT_NONE) 631 return; 632 633 /* Error check pad */ 634 assert(pmux_drvgrp_isvalid(grp)); 635 assert(pmux_schmt_isvalid(schmt)); 636 637 val = readl(reg); 638 if (schmt == PMUX_SCHMT_ENABLE) 639 val |= (1 << SCHMT_SHIFT); 640 else 641 val &= ~(1 << SCHMT_SHIFT); 642 writel(val, reg); 643 644 return; 645 } 646 #endif 647 648 #ifdef TEGRA_PMX_GRPS_HAVE_HSM 649 static void pinmux_set_hsm(enum pmux_drvgrp grp, enum pmux_hsm hsm) 650 { 651 u32 *reg = DRV_REG(grp); 652 u32 val; 653 654 /* NONE means unspecified/do not change/use POR value */ 655 if (hsm == PMUX_HSM_NONE) 656 return; 657 658 /* Error check pad */ 659 assert(pmux_drvgrp_isvalid(grp)); 660 assert(pmux_hsm_isvalid(hsm)); 661 662 val = readl(reg); 663 if (hsm == PMUX_HSM_ENABLE) 664 val |= (1 << HSM_SHIFT); 665 else 666 val &= ~(1 << HSM_SHIFT); 667 writel(val, reg); 668 669 return; 670 } 671 #endif 672 673 static void pinmux_config_drvgrp(const struct pmux_drvgrp_config *config) 674 { 675 enum pmux_drvgrp grp = config->drvgrp; 676 677 pinmux_set_drvup_slwf(grp, config->slwf); 678 pinmux_set_drvdn_slwr(grp, config->slwr); 679 pinmux_set_drvup(grp, config->drvup); 680 pinmux_set_drvdn(grp, config->drvdn); 681 #ifdef TEGRA_PMX_GRPS_HAVE_LPMD 682 pinmux_set_lpmd(grp, config->lpmd); 683 #endif 684 #ifdef TEGRA_PMX_GRPS_HAVE_SCHMT 685 pinmux_set_schmt(grp, config->schmt); 686 #endif 687 #ifdef TEGRA_PMX_GRPS_HAVE_HSM 688 pinmux_set_hsm(grp, config->hsm); 689 #endif 690 } 691 692 void pinmux_config_drvgrp_table(const struct pmux_drvgrp_config *config, 693 int len) 694 { 695 int i; 696 697 for (i = 0; i < len; i++) 698 pinmux_config_drvgrp(&config[i]); 699 } 700 #endif /* TEGRA_PMX_SOC_HAS_DRVGRPS */ 701 702 #ifdef TEGRA_PMX_SOC_HAS_MIPI_PAD_CTRL_GRPS 703 704 #define pmux_mipipadctrlgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PMUX_MIPIPADCTRLGRP_COUNT)) 705 706 static void pinmux_mipipadctrl_set_func(enum pmux_mipipadctrlgrp grp, 707 enum pmux_func func) 708 { 709 u32 *reg = MIPIPADCTRL_REG(grp); 710 int i, mux = -1; 711 u32 val; 712 713 if (func == PMUX_FUNC_DEFAULT) 714 return; 715 716 /* Error check grp and func */ 717 assert(pmux_mipipadctrlgrp_isvalid(grp)); 718 assert(pmux_func_isvalid(func)); 719 720 if (func >= PMUX_FUNC_RSVD1) { 721 mux = (func - PMUX_FUNC_RSVD1) & 1; 722 } else { 723 /* Search for the appropriate function */ 724 for (i = 0; i < 2; i++) { 725 if (tegra_soc_mipipadctrl_groups[grp].funcs[i] 726 == func) { 727 mux = i; 728 break; 729 } 730 } 731 } 732 assert(mux != -1); 733 734 val = readl(reg); 735 val &= ~(1 << 1); 736 val |= (mux << 1); 737 writel(val, reg); 738 } 739 740 static void pinmux_config_mipipadctrlgrp(const struct pmux_mipipadctrlgrp_config *config) 741 { 742 enum pmux_mipipadctrlgrp grp = config->grp; 743 744 pinmux_mipipadctrl_set_func(grp, config->func); 745 } 746 747 void pinmux_config_mipipadctrlgrp_table( 748 const struct pmux_mipipadctrlgrp_config *config, int len) 749 { 750 int i; 751 752 for (i = 0; i < len; i++) 753 pinmux_config_mipipadctrlgrp(&config[i]); 754 } 755 #endif /* TEGRA_PMX_SOC_HAS_MIPI_PAD_CTRL_GRPS */ 756