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