Home | History | Annotate | Download | only in mach-tegra
      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