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