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