109f455dcSMasahiro Yamada /*
209f455dcSMasahiro Yamada * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
309f455dcSMasahiro Yamada * Copyright (c) 2011 The Chromium OS Authors.
409f455dcSMasahiro Yamada *
509f455dcSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+
609f455dcSMasahiro Yamada */
709f455dcSMasahiro Yamada
809f455dcSMasahiro Yamada #include <common.h>
909f455dcSMasahiro Yamada #include <asm/io.h>
1009f455dcSMasahiro Yamada #include <asm/arch/pinmux.h>
1109f455dcSMasahiro Yamada
1209f455dcSMasahiro Yamada /* return 1 if a pingrp is in range */
1309f455dcSMasahiro Yamada #define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PMUX_PINGRP_COUNT))
1409f455dcSMasahiro Yamada
1509f455dcSMasahiro Yamada /* return 1 if a pmux_func is in range */
1609f455dcSMasahiro Yamada #define pmux_func_isvalid(func) \
1709f455dcSMasahiro Yamada (((func) >= 0) && ((func) < PMUX_FUNC_COUNT))
1809f455dcSMasahiro Yamada
1909f455dcSMasahiro Yamada /* return 1 if a pin_pupd_is in range */
2009f455dcSMasahiro Yamada #define pmux_pin_pupd_isvalid(pupd) \
2109f455dcSMasahiro Yamada (((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP))
2209f455dcSMasahiro Yamada
2309f455dcSMasahiro Yamada /* return 1 if a pin_tristate_is in range */
2409f455dcSMasahiro Yamada #define pmux_pin_tristate_isvalid(tristate) \
2509f455dcSMasahiro Yamada (((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE))
2609f455dcSMasahiro Yamada
277a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_E_INPUT
2809f455dcSMasahiro Yamada /* return 1 if a pin_io_is in range */
2909f455dcSMasahiro Yamada #define pmux_pin_io_isvalid(io) \
3009f455dcSMasahiro Yamada (((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT))
317a28441fSStephen Warren #endif
3209f455dcSMasahiro Yamada
337a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_LOCK
3409f455dcSMasahiro Yamada /* return 1 if a pin_lock is in range */
3509f455dcSMasahiro Yamada #define pmux_pin_lock_isvalid(lock) \
3609f455dcSMasahiro Yamada (((lock) >= PMUX_PIN_LOCK_DISABLE) && ((lock) <= PMUX_PIN_LOCK_ENABLE))
377a28441fSStephen Warren #endif
3809f455dcSMasahiro Yamada
397a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_OD
4009f455dcSMasahiro Yamada /* return 1 if a pin_od is in range */
4109f455dcSMasahiro Yamada #define pmux_pin_od_isvalid(od) \
4209f455dcSMasahiro Yamada (((od) >= PMUX_PIN_OD_DISABLE) && ((od) <= PMUX_PIN_OD_ENABLE))
437a28441fSStephen Warren #endif
4409f455dcSMasahiro Yamada
457a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET
4609f455dcSMasahiro Yamada /* return 1 if a pin_ioreset_is in range */
4709f455dcSMasahiro Yamada #define pmux_pin_ioreset_isvalid(ioreset) \
4809f455dcSMasahiro Yamada (((ioreset) >= PMUX_PIN_IO_RESET_DISABLE) && \
4909f455dcSMasahiro Yamada ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE))
507a28441fSStephen Warren #endif
5109f455dcSMasahiro Yamada
527a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL
5309f455dcSMasahiro Yamada /* return 1 if a pin_rcv_sel_is in range */
5409f455dcSMasahiro Yamada #define pmux_pin_rcv_sel_isvalid(rcv_sel) \
5509f455dcSMasahiro Yamada (((rcv_sel) >= PMUX_PIN_RCV_SEL_NORMAL) && \
5609f455dcSMasahiro Yamada ((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH))
577a28441fSStephen Warren #endif
5809f455dcSMasahiro Yamada
59f4d7c9ddSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV
60f4d7c9ddSStephen Warren /* return 1 if a pin_e_io_hv is in range */
61f4d7c9ddSStephen Warren #define pmux_pin_e_io_hv_isvalid(e_io_hv) \
62f4d7c9ddSStephen Warren (((e_io_hv) >= PMUX_PIN_E_IO_HV_NORMAL) && \
63f4d7c9ddSStephen Warren ((e_io_hv) <= PMUX_PIN_E_IO_HV_HIGH))
64f4d7c9ddSStephen Warren #endif
65f4d7c9ddSStephen Warren
66bc134728SStephen Warren #ifdef TEGRA_PMX_GRPS_HAVE_LPMD
67bc134728SStephen Warren #define pmux_lpmd_isvalid(lpm) \
68bc134728SStephen Warren (((lpm) >= PMUX_LPMD_X8) && ((lpm) <= PMUX_LPMD_X))
69bc134728SStephen Warren #endif
70bc134728SStephen Warren
71f2c60eedSStephen Warren #if defined(TEGRA_PMX_PINS_HAVE_SCHMT) || defined(TEGRA_PMX_GRPS_HAVE_SCHMT)
72bc134728SStephen Warren #define pmux_schmt_isvalid(schmt) \
73bc134728SStephen Warren (((schmt) >= PMUX_SCHMT_DISABLE) && ((schmt) <= PMUX_SCHMT_ENABLE))
74bc134728SStephen Warren #endif
75bc134728SStephen Warren
76f2c60eedSStephen Warren #if defined(TEGRA_PMX_PINS_HAVE_HSM) || defined(TEGRA_PMX_GRPS_HAVE_HSM)
77bc134728SStephen Warren #define pmux_hsm_isvalid(hsm) \
78bc134728SStephen Warren (((hsm) >= PMUX_HSM_DISABLE) && ((hsm) <= PMUX_HSM_ENABLE))
79bc134728SStephen Warren #endif
80bc134728SStephen Warren
81*f49357baSThierry Reding #define _R(offset) (u32 *)((unsigned long)NV_PA_APB_MISC_BASE + (offset))
8209f455dcSMasahiro Yamada
8309f455dcSMasahiro Yamada #if defined(CONFIG_TEGRA20)
8409f455dcSMasahiro Yamada
8509f455dcSMasahiro Yamada #define MUX_REG(grp) _R(0x80 + ((tegra_soc_pingroups[grp].ctl_id / 16) * 4))
8609f455dcSMasahiro Yamada #define MUX_SHIFT(grp) ((tegra_soc_pingroups[grp].ctl_id % 16) * 2)
8709f455dcSMasahiro Yamada
8809f455dcSMasahiro Yamada #define PULL_REG(grp) _R(0xa0 + ((tegra_soc_pingroups[grp].pull_id / 16) * 4))
8909f455dcSMasahiro Yamada #define PULL_SHIFT(grp) ((tegra_soc_pingroups[grp].pull_id % 16) * 2)
9009f455dcSMasahiro Yamada
9109f455dcSMasahiro Yamada #define TRI_REG(grp) _R(0x14 + (((grp) / 32) * 4))
9209f455dcSMasahiro Yamada #define TRI_SHIFT(grp) ((grp) % 32)
9309f455dcSMasahiro Yamada
9409f455dcSMasahiro Yamada #else
9509f455dcSMasahiro Yamada
9609f455dcSMasahiro Yamada #define REG(pin) _R(0x3000 + ((pin) * 4))
9709f455dcSMasahiro Yamada
9809f455dcSMasahiro Yamada #define MUX_REG(pin) REG(pin)
9909f455dcSMasahiro Yamada #define MUX_SHIFT(pin) 0
10009f455dcSMasahiro Yamada
10109f455dcSMasahiro Yamada #define PULL_REG(pin) REG(pin)
10209f455dcSMasahiro Yamada #define PULL_SHIFT(pin) 2
10309f455dcSMasahiro Yamada
10409f455dcSMasahiro Yamada #define TRI_REG(pin) REG(pin)
10509f455dcSMasahiro Yamada #define TRI_SHIFT(pin) 4
10609f455dcSMasahiro Yamada
10709f455dcSMasahiro Yamada #endif /* CONFIG_TEGRA20 */
10809f455dcSMasahiro Yamada
109790f7719SStephen Warren #define DRV_REG(group) _R(TEGRA_PMX_SOC_DRV_GROUP_BASE_REG + ((group) * 4))
11009f455dcSMasahiro Yamada
1115ee7ec7bSStephen Warren #define MIPIPADCTRL_REG(group) _R(TEGRA_PMX_SOC_MIPIPADCTRL_BASE_REG + ((group) * 4))
1125ee7ec7bSStephen Warren
113b2cd3d81SStephen Warren /*
114b2cd3d81SStephen Warren * We could force arch-tegraNN/pinmux.h to define all of these. However,
115b2cd3d81SStephen Warren * that's a lot of defines, and for now it's manageable to just put a
116b2cd3d81SStephen Warren * special case here. It's possible this decision will change with future
117b2cd3d81SStephen Warren * SoCs.
118b2cd3d81SStephen Warren */
119b2cd3d81SStephen Warren #ifdef CONFIG_TEGRA210
120b2cd3d81SStephen Warren #define IO_SHIFT 6
121b2cd3d81SStephen Warren #define LOCK_SHIFT 7
122f2c60eedSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_HSM
123f2c60eedSStephen Warren #define HSM_SHIFT 9
124f2c60eedSStephen Warren #endif
125f4d7c9ddSStephen Warren #define E_IO_HV_SHIFT 10
126b2cd3d81SStephen Warren #define OD_SHIFT 11
127f2c60eedSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_SCHMT
128f2c60eedSStephen Warren #define SCHMT_SHIFT 12
129f2c60eedSStephen Warren #endif
130b2cd3d81SStephen Warren #else
13109f455dcSMasahiro Yamada #define IO_SHIFT 5
13209f455dcSMasahiro Yamada #define OD_SHIFT 6
13309f455dcSMasahiro Yamada #define LOCK_SHIFT 7
13409f455dcSMasahiro Yamada #define IO_RESET_SHIFT 8
13509f455dcSMasahiro Yamada #define RCV_SEL_SHIFT 9
136b2cd3d81SStephen Warren #endif
13709f455dcSMasahiro Yamada
1387a28441fSStephen Warren #ifdef TEGRA_PMX_SOC_HAS_IO_CLAMPING
13909f455dcSMasahiro Yamada /* This register/field only exists on Tegra114 and later */
14009f455dcSMasahiro Yamada #define APB_MISC_PP_PINMUX_GLOBAL_0 0x40
14109f455dcSMasahiro Yamada #define CLAMP_INPUTS_WHEN_TRISTATED 1
14209f455dcSMasahiro Yamada
pinmux_set_tristate_input_clamping(void)14309f455dcSMasahiro Yamada void pinmux_set_tristate_input_clamping(void)
14409f455dcSMasahiro Yamada {
14509f455dcSMasahiro Yamada u32 *reg = _R(APB_MISC_PP_PINMUX_GLOBAL_0);
14609f455dcSMasahiro Yamada
147f799b03fSStephen Warren setbits_le32(reg, CLAMP_INPUTS_WHEN_TRISTATED);
148f799b03fSStephen Warren }
149f799b03fSStephen Warren
pinmux_clear_tristate_input_clamping(void)150f799b03fSStephen Warren void pinmux_clear_tristate_input_clamping(void)
151f799b03fSStephen Warren {
152f799b03fSStephen Warren u32 *reg = _R(APB_MISC_PP_PINMUX_GLOBAL_0);
153f799b03fSStephen Warren
154f799b03fSStephen Warren clrbits_le32(reg, CLAMP_INPUTS_WHEN_TRISTATED);
15509f455dcSMasahiro Yamada }
15609f455dcSMasahiro Yamada #endif
15709f455dcSMasahiro Yamada
pinmux_set_func(enum pmux_pingrp pin,enum pmux_func func)15809f455dcSMasahiro Yamada void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
15909f455dcSMasahiro Yamada {
16009f455dcSMasahiro Yamada u32 *reg = MUX_REG(pin);
16109f455dcSMasahiro Yamada int i, mux = -1;
16209f455dcSMasahiro Yamada u32 val;
16309f455dcSMasahiro Yamada
16409f455dcSMasahiro Yamada if (func == PMUX_FUNC_DEFAULT)
16509f455dcSMasahiro Yamada return;
16609f455dcSMasahiro Yamada
16709f455dcSMasahiro Yamada /* Error check on pin and func */
16809f455dcSMasahiro Yamada assert(pmux_pingrp_isvalid(pin));
16909f455dcSMasahiro Yamada assert(pmux_func_isvalid(func));
17009f455dcSMasahiro Yamada
17109f455dcSMasahiro Yamada if (func >= PMUX_FUNC_RSVD1) {
17209f455dcSMasahiro Yamada mux = (func - PMUX_FUNC_RSVD1) & 3;
17309f455dcSMasahiro Yamada } else {
17409f455dcSMasahiro Yamada /* Search for the appropriate function */
17509f455dcSMasahiro Yamada for (i = 0; i < 4; i++) {
17609f455dcSMasahiro Yamada if (tegra_soc_pingroups[pin].funcs[i] == func) {
17709f455dcSMasahiro Yamada mux = i;
17809f455dcSMasahiro Yamada break;
17909f455dcSMasahiro Yamada }
18009f455dcSMasahiro Yamada }
18109f455dcSMasahiro Yamada }
18209f455dcSMasahiro Yamada assert(mux != -1);
18309f455dcSMasahiro Yamada
18409f455dcSMasahiro Yamada val = readl(reg);
18509f455dcSMasahiro Yamada val &= ~(3 << MUX_SHIFT(pin));
18609f455dcSMasahiro Yamada val |= (mux << MUX_SHIFT(pin));
18709f455dcSMasahiro Yamada writel(val, reg);
18809f455dcSMasahiro Yamada }
18909f455dcSMasahiro Yamada
pinmux_set_pullupdown(enum pmux_pingrp pin,enum pmux_pull pupd)19009f455dcSMasahiro Yamada void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
19109f455dcSMasahiro Yamada {
19209f455dcSMasahiro Yamada u32 *reg = PULL_REG(pin);
19309f455dcSMasahiro Yamada u32 val;
19409f455dcSMasahiro Yamada
19509f455dcSMasahiro Yamada /* Error check on pin and pupd */
19609f455dcSMasahiro Yamada assert(pmux_pingrp_isvalid(pin));
19709f455dcSMasahiro Yamada assert(pmux_pin_pupd_isvalid(pupd));
19809f455dcSMasahiro Yamada
19909f455dcSMasahiro Yamada val = readl(reg);
20009f455dcSMasahiro Yamada val &= ~(3 << PULL_SHIFT(pin));
20109f455dcSMasahiro Yamada val |= (pupd << PULL_SHIFT(pin));
20209f455dcSMasahiro Yamada writel(val, reg);
20309f455dcSMasahiro Yamada }
20409f455dcSMasahiro Yamada
pinmux_set_tristate(enum pmux_pingrp pin,int tri)20509f455dcSMasahiro Yamada static void pinmux_set_tristate(enum pmux_pingrp pin, int tri)
20609f455dcSMasahiro Yamada {
20709f455dcSMasahiro Yamada u32 *reg = TRI_REG(pin);
20809f455dcSMasahiro Yamada u32 val;
20909f455dcSMasahiro Yamada
21009f455dcSMasahiro Yamada /* Error check on pin */
21109f455dcSMasahiro Yamada assert(pmux_pingrp_isvalid(pin));
21209f455dcSMasahiro Yamada assert(pmux_pin_tristate_isvalid(tri));
21309f455dcSMasahiro Yamada
21409f455dcSMasahiro Yamada val = readl(reg);
21509f455dcSMasahiro Yamada if (tri == PMUX_TRI_TRISTATE)
21609f455dcSMasahiro Yamada val |= (1 << TRI_SHIFT(pin));
21709f455dcSMasahiro Yamada else
21809f455dcSMasahiro Yamada val &= ~(1 << TRI_SHIFT(pin));
21909f455dcSMasahiro Yamada writel(val, reg);
22009f455dcSMasahiro Yamada }
22109f455dcSMasahiro Yamada
pinmux_tristate_enable(enum pmux_pingrp pin)22209f455dcSMasahiro Yamada void pinmux_tristate_enable(enum pmux_pingrp pin)
22309f455dcSMasahiro Yamada {
22409f455dcSMasahiro Yamada pinmux_set_tristate(pin, PMUX_TRI_TRISTATE);
22509f455dcSMasahiro Yamada }
22609f455dcSMasahiro Yamada
pinmux_tristate_disable(enum pmux_pingrp pin)22709f455dcSMasahiro Yamada void pinmux_tristate_disable(enum pmux_pingrp pin)
22809f455dcSMasahiro Yamada {
22909f455dcSMasahiro Yamada pinmux_set_tristate(pin, PMUX_TRI_NORMAL);
23009f455dcSMasahiro Yamada }
23109f455dcSMasahiro Yamada
2327a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_E_INPUT
pinmux_set_io(enum pmux_pingrp pin,enum pmux_pin_io io)23309f455dcSMasahiro Yamada void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io)
23409f455dcSMasahiro Yamada {
23509f455dcSMasahiro Yamada u32 *reg = REG(pin);
23609f455dcSMasahiro Yamada u32 val;
23709f455dcSMasahiro Yamada
23809f455dcSMasahiro Yamada if (io == PMUX_PIN_NONE)
23909f455dcSMasahiro Yamada return;
24009f455dcSMasahiro Yamada
24109f455dcSMasahiro Yamada /* Error check on pin and io */
24209f455dcSMasahiro Yamada assert(pmux_pingrp_isvalid(pin));
24309f455dcSMasahiro Yamada assert(pmux_pin_io_isvalid(io));
24409f455dcSMasahiro Yamada
24509f455dcSMasahiro Yamada val = readl(reg);
24609f455dcSMasahiro Yamada if (io == PMUX_PIN_INPUT)
24709f455dcSMasahiro Yamada val |= (io & 1) << IO_SHIFT;
24809f455dcSMasahiro Yamada else
24909f455dcSMasahiro Yamada val &= ~(1 << IO_SHIFT);
25009f455dcSMasahiro Yamada writel(val, reg);
25109f455dcSMasahiro Yamada }
2527a28441fSStephen Warren #endif
25309f455dcSMasahiro Yamada
2547a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_LOCK
pinmux_set_lock(enum pmux_pingrp pin,enum pmux_pin_lock lock)25509f455dcSMasahiro Yamada static void pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock)
25609f455dcSMasahiro Yamada {
25709f455dcSMasahiro Yamada u32 *reg = REG(pin);
25809f455dcSMasahiro Yamada u32 val;
25909f455dcSMasahiro Yamada
26009f455dcSMasahiro Yamada if (lock == PMUX_PIN_LOCK_DEFAULT)
26109f455dcSMasahiro Yamada return;
26209f455dcSMasahiro Yamada
26309f455dcSMasahiro Yamada /* Error check on pin and lock */
26409f455dcSMasahiro Yamada assert(pmux_pingrp_isvalid(pin));
26509f455dcSMasahiro Yamada assert(pmux_pin_lock_isvalid(lock));
26609f455dcSMasahiro Yamada
26709f455dcSMasahiro Yamada val = readl(reg);
26809f455dcSMasahiro Yamada if (lock == PMUX_PIN_LOCK_ENABLE) {
26909f455dcSMasahiro Yamada val |= (1 << LOCK_SHIFT);
27009f455dcSMasahiro Yamada } else {
27109f455dcSMasahiro Yamada if (val & (1 << LOCK_SHIFT))
27209f455dcSMasahiro Yamada printf("%s: Cannot clear LOCK bit!\n", __func__);
27309f455dcSMasahiro Yamada val &= ~(1 << LOCK_SHIFT);
27409f455dcSMasahiro Yamada }
27509f455dcSMasahiro Yamada writel(val, reg);
27609f455dcSMasahiro Yamada
27709f455dcSMasahiro Yamada return;
27809f455dcSMasahiro Yamada }
2797a28441fSStephen Warren #endif
28009f455dcSMasahiro Yamada
2817a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_OD
pinmux_set_od(enum pmux_pingrp pin,enum pmux_pin_od od)28209f455dcSMasahiro Yamada static void pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od)
28309f455dcSMasahiro Yamada {
28409f455dcSMasahiro Yamada u32 *reg = REG(pin);
28509f455dcSMasahiro Yamada u32 val;
28609f455dcSMasahiro Yamada
28709f455dcSMasahiro Yamada if (od == PMUX_PIN_OD_DEFAULT)
28809f455dcSMasahiro Yamada return;
28909f455dcSMasahiro Yamada
29009f455dcSMasahiro Yamada /* Error check on pin and od */
29109f455dcSMasahiro Yamada assert(pmux_pingrp_isvalid(pin));
29209f455dcSMasahiro Yamada assert(pmux_pin_od_isvalid(od));
29309f455dcSMasahiro Yamada
29409f455dcSMasahiro Yamada val = readl(reg);
29509f455dcSMasahiro Yamada if (od == PMUX_PIN_OD_ENABLE)
29609f455dcSMasahiro Yamada val |= (1 << OD_SHIFT);
29709f455dcSMasahiro Yamada else
29809f455dcSMasahiro Yamada val &= ~(1 << OD_SHIFT);
29909f455dcSMasahiro Yamada writel(val, reg);
30009f455dcSMasahiro Yamada
30109f455dcSMasahiro Yamada return;
30209f455dcSMasahiro Yamada }
3037a28441fSStephen Warren #endif
30409f455dcSMasahiro Yamada
3057a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET
pinmux_set_ioreset(enum pmux_pingrp pin,enum pmux_pin_ioreset ioreset)30609f455dcSMasahiro Yamada static void pinmux_set_ioreset(enum pmux_pingrp pin,
30709f455dcSMasahiro Yamada enum pmux_pin_ioreset ioreset)
30809f455dcSMasahiro Yamada {
30909f455dcSMasahiro Yamada u32 *reg = REG(pin);
31009f455dcSMasahiro Yamada u32 val;
31109f455dcSMasahiro Yamada
31209f455dcSMasahiro Yamada if (ioreset == PMUX_PIN_IO_RESET_DEFAULT)
31309f455dcSMasahiro Yamada return;
31409f455dcSMasahiro Yamada
31509f455dcSMasahiro Yamada /* Error check on pin and ioreset */
31609f455dcSMasahiro Yamada assert(pmux_pingrp_isvalid(pin));
31709f455dcSMasahiro Yamada assert(pmux_pin_ioreset_isvalid(ioreset));
31809f455dcSMasahiro Yamada
31909f455dcSMasahiro Yamada val = readl(reg);
32009f455dcSMasahiro Yamada if (ioreset == PMUX_PIN_IO_RESET_ENABLE)
32109f455dcSMasahiro Yamada val |= (1 << IO_RESET_SHIFT);
32209f455dcSMasahiro Yamada else
32309f455dcSMasahiro Yamada val &= ~(1 << IO_RESET_SHIFT);
32409f455dcSMasahiro Yamada writel(val, reg);
32509f455dcSMasahiro Yamada
32609f455dcSMasahiro Yamada return;
32709f455dcSMasahiro Yamada }
3287a28441fSStephen Warren #endif
32909f455dcSMasahiro Yamada
3307a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL
pinmux_set_rcv_sel(enum pmux_pingrp pin,enum pmux_pin_rcv_sel rcv_sel)33109f455dcSMasahiro Yamada static void pinmux_set_rcv_sel(enum pmux_pingrp pin,
33209f455dcSMasahiro Yamada enum pmux_pin_rcv_sel rcv_sel)
33309f455dcSMasahiro Yamada {
33409f455dcSMasahiro Yamada u32 *reg = REG(pin);
33509f455dcSMasahiro Yamada u32 val;
33609f455dcSMasahiro Yamada
33709f455dcSMasahiro Yamada if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT)
33809f455dcSMasahiro Yamada return;
33909f455dcSMasahiro Yamada
34009f455dcSMasahiro Yamada /* Error check on pin and rcv_sel */
34109f455dcSMasahiro Yamada assert(pmux_pingrp_isvalid(pin));
34209f455dcSMasahiro Yamada assert(pmux_pin_rcv_sel_isvalid(rcv_sel));
34309f455dcSMasahiro Yamada
34409f455dcSMasahiro Yamada val = readl(reg);
34509f455dcSMasahiro Yamada if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH)
34609f455dcSMasahiro Yamada val |= (1 << RCV_SEL_SHIFT);
34709f455dcSMasahiro Yamada else
34809f455dcSMasahiro Yamada val &= ~(1 << RCV_SEL_SHIFT);
34909f455dcSMasahiro Yamada writel(val, reg);
35009f455dcSMasahiro Yamada
35109f455dcSMasahiro Yamada return;
35209f455dcSMasahiro Yamada }
3537a28441fSStephen Warren #endif
35409f455dcSMasahiro Yamada
355f4d7c9ddSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV
pinmux_set_e_io_hv(enum pmux_pingrp pin,enum pmux_pin_e_io_hv e_io_hv)356f4d7c9ddSStephen Warren static void pinmux_set_e_io_hv(enum pmux_pingrp pin,
357f4d7c9ddSStephen Warren enum pmux_pin_e_io_hv e_io_hv)
358f4d7c9ddSStephen Warren {
359f4d7c9ddSStephen Warren u32 *reg = REG(pin);
360f4d7c9ddSStephen Warren u32 val;
361f4d7c9ddSStephen Warren
362f4d7c9ddSStephen Warren if (e_io_hv == PMUX_PIN_E_IO_HV_DEFAULT)
363f4d7c9ddSStephen Warren return;
364f4d7c9ddSStephen Warren
365f4d7c9ddSStephen Warren /* Error check on pin and e_io_hv */
366f4d7c9ddSStephen Warren assert(pmux_pingrp_isvalid(pin));
367f4d7c9ddSStephen Warren assert(pmux_pin_e_io_hv_isvalid(e_io_hv));
368f4d7c9ddSStephen Warren
369f4d7c9ddSStephen Warren val = readl(reg);
370f4d7c9ddSStephen Warren if (e_io_hv == PMUX_PIN_E_IO_HV_HIGH)
371f4d7c9ddSStephen Warren val |= (1 << E_IO_HV_SHIFT);
372f4d7c9ddSStephen Warren else
373f4d7c9ddSStephen Warren val &= ~(1 << E_IO_HV_SHIFT);
374f4d7c9ddSStephen Warren writel(val, reg);
375f4d7c9ddSStephen Warren
376f4d7c9ddSStephen Warren return;
377f4d7c9ddSStephen Warren }
378f4d7c9ddSStephen Warren #endif
379f4d7c9ddSStephen Warren
380f2c60eedSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_SCHMT
pinmux_set_schmt(enum pmux_pingrp pin,enum pmux_schmt schmt)381f2c60eedSStephen Warren static void pinmux_set_schmt(enum pmux_pingrp pin, enum pmux_schmt schmt)
382f2c60eedSStephen Warren {
383f2c60eedSStephen Warren u32 *reg = REG(grp);
384f2c60eedSStephen Warren u32 val;
385f2c60eedSStephen Warren
386f2c60eedSStephen Warren /* NONE means unspecified/do not change/use POR value */
387f2c60eedSStephen Warren if (schmt == PMUX_SCHMT_NONE)
388f2c60eedSStephen Warren return;
389f2c60eedSStephen Warren
390f2c60eedSStephen Warren /* Error check pad */
391f2c60eedSStephen Warren assert(pmux_pingrp_isvalid(pin));
392f2c60eedSStephen Warren assert(pmux_schmt_isvalid(schmt));
393f2c60eedSStephen Warren
394f2c60eedSStephen Warren val = readl(reg);
395f2c60eedSStephen Warren if (schmt == PMUX_SCHMT_ENABLE)
396f2c60eedSStephen Warren val |= (1 << SCHMT_SHIFT);
397f2c60eedSStephen Warren else
398f2c60eedSStephen Warren val &= ~(1 << SCHMT_SHIFT);
399f2c60eedSStephen Warren writel(val, reg);
400f2c60eedSStephen Warren
401f2c60eedSStephen Warren return;
402f2c60eedSStephen Warren }
403f2c60eedSStephen Warren #endif
404f2c60eedSStephen Warren
405f2c60eedSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_HSM
pinmux_set_hsm(enum pmux_pingrp pin,enum pmux_hsm hsm)406f2c60eedSStephen Warren static void pinmux_set_hsm(enum pmux_pingrp pin, enum pmux_hsm hsm)
407f2c60eedSStephen Warren {
408f2c60eedSStephen Warren u32 *reg = REG(grp);
409f2c60eedSStephen Warren u32 val;
410f2c60eedSStephen Warren
411f2c60eedSStephen Warren /* NONE means unspecified/do not change/use POR value */
412f2c60eedSStephen Warren if (hsm == PMUX_HSM_NONE)
413f2c60eedSStephen Warren return;
414f2c60eedSStephen Warren
415f2c60eedSStephen Warren /* Error check pad */
416f2c60eedSStephen Warren assert(pmux_pingrp_isvalid(pin));
417f2c60eedSStephen Warren assert(pmux_hsm_isvalid(hsm));
418f2c60eedSStephen Warren
419f2c60eedSStephen Warren val = readl(reg);
420f2c60eedSStephen Warren if (hsm == PMUX_HSM_ENABLE)
421f2c60eedSStephen Warren val |= (1 << HSM_SHIFT);
422f2c60eedSStephen Warren else
423f2c60eedSStephen Warren val &= ~(1 << HSM_SHIFT);
424f2c60eedSStephen Warren writel(val, reg);
425f2c60eedSStephen Warren
426f2c60eedSStephen Warren return;
427f2c60eedSStephen Warren }
428f2c60eedSStephen Warren #endif
429f2c60eedSStephen Warren
pinmux_config_pingrp(const struct pmux_pingrp_config * config)43009f455dcSMasahiro Yamada static void pinmux_config_pingrp(const struct pmux_pingrp_config *config)
43109f455dcSMasahiro Yamada {
43209f455dcSMasahiro Yamada enum pmux_pingrp pin = config->pingrp;
43309f455dcSMasahiro Yamada
43409f455dcSMasahiro Yamada pinmux_set_func(pin, config->func);
43509f455dcSMasahiro Yamada pinmux_set_pullupdown(pin, config->pull);
43609f455dcSMasahiro Yamada pinmux_set_tristate(pin, config->tristate);
4377a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_E_INPUT
43809f455dcSMasahiro Yamada pinmux_set_io(pin, config->io);
43909f455dcSMasahiro Yamada #endif
4407a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_LOCK
4417a28441fSStephen Warren pinmux_set_lock(pin, config->lock);
4427a28441fSStephen Warren #endif
4437a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_OD
4447a28441fSStephen Warren pinmux_set_od(pin, config->od);
4457a28441fSStephen Warren #endif
4467a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET
4477a28441fSStephen Warren pinmux_set_ioreset(pin, config->ioreset);
4487a28441fSStephen Warren #endif
4497a28441fSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL
4507a28441fSStephen Warren pinmux_set_rcv_sel(pin, config->rcv_sel);
45109f455dcSMasahiro Yamada #endif
452f4d7c9ddSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV
453f4d7c9ddSStephen Warren pinmux_set_e_io_hv(pin, config->e_io_hv);
454f4d7c9ddSStephen Warren #endif
455f2c60eedSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_SCHMT
456f2c60eedSStephen Warren pinmux_set_schmt(pin, config->schmt);
457f2c60eedSStephen Warren #endif
458f2c60eedSStephen Warren #ifdef TEGRA_PMX_PINS_HAVE_HSM
459f2c60eedSStephen Warren pinmux_set_hsm(pin, config->hsm);
460f2c60eedSStephen Warren #endif
46109f455dcSMasahiro Yamada }
46209f455dcSMasahiro Yamada
pinmux_config_pingrp_table(const struct pmux_pingrp_config * config,int len)46309f455dcSMasahiro Yamada void pinmux_config_pingrp_table(const struct pmux_pingrp_config *config,
46409f455dcSMasahiro Yamada int len)
46509f455dcSMasahiro Yamada {
46609f455dcSMasahiro Yamada int i;
46709f455dcSMasahiro Yamada
46809f455dcSMasahiro Yamada for (i = 0; i < len; i++)
46909f455dcSMasahiro Yamada pinmux_config_pingrp(&config[i]);
47009f455dcSMasahiro Yamada }
47109f455dcSMasahiro Yamada
4727a28441fSStephen Warren #ifdef TEGRA_PMX_SOC_HAS_DRVGRPS
47309f455dcSMasahiro Yamada
47409f455dcSMasahiro Yamada #define pmux_drvgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PMUX_DRVGRP_COUNT))
47509f455dcSMasahiro Yamada
47609f455dcSMasahiro Yamada #define pmux_slw_isvalid(slw) \
47709f455dcSMasahiro Yamada (((slw) >= PMUX_SLWF_MIN) && ((slw) <= PMUX_SLWF_MAX))
47809f455dcSMasahiro Yamada
47909f455dcSMasahiro Yamada #define pmux_drv_isvalid(drv) \
48009f455dcSMasahiro Yamada (((drv) >= PMUX_DRVUP_MIN) && ((drv) <= PMUX_DRVUP_MAX))
48109f455dcSMasahiro Yamada
482439f5768SStephen Warren #ifdef TEGRA_PMX_GRPS_HAVE_HSM
48309f455dcSMasahiro Yamada #define HSM_SHIFT 2
484439f5768SStephen Warren #endif
485439f5768SStephen Warren #ifdef TEGRA_PMX_GRPS_HAVE_SCHMT
48609f455dcSMasahiro Yamada #define SCHMT_SHIFT 3
487439f5768SStephen Warren #endif
488439f5768SStephen Warren #ifdef TEGRA_PMX_GRPS_HAVE_LPMD
48909f455dcSMasahiro Yamada #define LPMD_SHIFT 4
49009f455dcSMasahiro Yamada #define LPMD_MASK (3 << LPMD_SHIFT)
491439f5768SStephen Warren #endif
4929f21c1a3SStephen Warren /*
4939f21c1a3SStephen Warren * Note that the following DRV* and SLW* defines are accurate for many drive
4949f21c1a3SStephen Warren * groups on many SoCs. We really need a per-group data structure to solve
4959f21c1a3SStephen Warren * this, since the fields are in different positions/sizes in different
4969f21c1a3SStephen Warren * registers (for different groups).
4979f21c1a3SStephen Warren *
4989f21c1a3SStephen Warren * On Tegra30/114/124, the DRV*_SHIFT values vary.
4999f21c1a3SStephen Warren * On Tegra30, the SLW*_SHIFT values vary.
5009f21c1a3SStephen Warren * On Tegra30/114/124/210, the DRV*_MASK values vary, although the values
5019f21c1a3SStephen Warren * below are wide enough to cover the widest fields, and hopefully don't
5029f21c1a3SStephen Warren * interfere with any other fields.
5039f21c1a3SStephen Warren * On Tegra30, the SLW*_MASK values vary, but we can't use a value that's
5049f21c1a3SStephen Warren * wide enough to cover all cases, since that would cause the field to
5059f21c1a3SStephen Warren * overlap with other fields in the narrower cases.
5069f21c1a3SStephen Warren */
50709f455dcSMasahiro Yamada #define DRVDN_SHIFT 12
50809f455dcSMasahiro Yamada #define DRVDN_MASK (0x7F << DRVDN_SHIFT)
50909f455dcSMasahiro Yamada #define DRVUP_SHIFT 20
51009f455dcSMasahiro Yamada #define DRVUP_MASK (0x7F << DRVUP_SHIFT)
51109f455dcSMasahiro Yamada #define SLWR_SHIFT 28
51209f455dcSMasahiro Yamada #define SLWR_MASK (3 << SLWR_SHIFT)
51309f455dcSMasahiro Yamada #define SLWF_SHIFT 30
51409f455dcSMasahiro Yamada #define SLWF_MASK (3 << SLWF_SHIFT)
51509f455dcSMasahiro Yamada
pinmux_set_drvup_slwf(enum pmux_drvgrp grp,int slwf)51609f455dcSMasahiro Yamada static void pinmux_set_drvup_slwf(enum pmux_drvgrp grp, int slwf)
51709f455dcSMasahiro Yamada {
51809f455dcSMasahiro Yamada u32 *reg = DRV_REG(grp);
51909f455dcSMasahiro Yamada u32 val;
52009f455dcSMasahiro Yamada
52109f455dcSMasahiro Yamada /* NONE means unspecified/do not change/use POR value */
52209f455dcSMasahiro Yamada if (slwf == PMUX_SLWF_NONE)
52309f455dcSMasahiro Yamada return;
52409f455dcSMasahiro Yamada
52509f455dcSMasahiro Yamada /* Error check on pad and slwf */
52609f455dcSMasahiro Yamada assert(pmux_drvgrp_isvalid(grp));
52709f455dcSMasahiro Yamada assert(pmux_slw_isvalid(slwf));
52809f455dcSMasahiro Yamada
52909f455dcSMasahiro Yamada val = readl(reg);
53009f455dcSMasahiro Yamada val &= ~SLWF_MASK;
53109f455dcSMasahiro Yamada val |= (slwf << SLWF_SHIFT);
53209f455dcSMasahiro Yamada writel(val, reg);
53309f455dcSMasahiro Yamada
53409f455dcSMasahiro Yamada return;
53509f455dcSMasahiro Yamada }
53609f455dcSMasahiro Yamada
pinmux_set_drvdn_slwr(enum pmux_drvgrp grp,int slwr)53709f455dcSMasahiro Yamada static void pinmux_set_drvdn_slwr(enum pmux_drvgrp grp, int slwr)
53809f455dcSMasahiro Yamada {
53909f455dcSMasahiro Yamada u32 *reg = DRV_REG(grp);
54009f455dcSMasahiro Yamada u32 val;
54109f455dcSMasahiro Yamada
54209f455dcSMasahiro Yamada /* NONE means unspecified/do not change/use POR value */
54309f455dcSMasahiro Yamada if (slwr == PMUX_SLWR_NONE)
54409f455dcSMasahiro Yamada return;
54509f455dcSMasahiro Yamada
54609f455dcSMasahiro Yamada /* Error check on pad and slwr */
54709f455dcSMasahiro Yamada assert(pmux_drvgrp_isvalid(grp));
54809f455dcSMasahiro Yamada assert(pmux_slw_isvalid(slwr));
54909f455dcSMasahiro Yamada
55009f455dcSMasahiro Yamada val = readl(reg);
55109f455dcSMasahiro Yamada val &= ~SLWR_MASK;
55209f455dcSMasahiro Yamada val |= (slwr << SLWR_SHIFT);
55309f455dcSMasahiro Yamada writel(val, reg);
55409f455dcSMasahiro Yamada
55509f455dcSMasahiro Yamada return;
55609f455dcSMasahiro Yamada }
55709f455dcSMasahiro Yamada
pinmux_set_drvup(enum pmux_drvgrp grp,int drvup)55809f455dcSMasahiro Yamada static void pinmux_set_drvup(enum pmux_drvgrp grp, int drvup)
55909f455dcSMasahiro Yamada {
56009f455dcSMasahiro Yamada u32 *reg = DRV_REG(grp);
56109f455dcSMasahiro Yamada u32 val;
56209f455dcSMasahiro Yamada
56309f455dcSMasahiro Yamada /* NONE means unspecified/do not change/use POR value */
56409f455dcSMasahiro Yamada if (drvup == PMUX_DRVUP_NONE)
56509f455dcSMasahiro Yamada return;
56609f455dcSMasahiro Yamada
56709f455dcSMasahiro Yamada /* Error check on pad and drvup */
56809f455dcSMasahiro Yamada assert(pmux_drvgrp_isvalid(grp));
56909f455dcSMasahiro Yamada assert(pmux_drv_isvalid(drvup));
57009f455dcSMasahiro Yamada
57109f455dcSMasahiro Yamada val = readl(reg);
57209f455dcSMasahiro Yamada val &= ~DRVUP_MASK;
57309f455dcSMasahiro Yamada val |= (drvup << DRVUP_SHIFT);
57409f455dcSMasahiro Yamada writel(val, reg);
57509f455dcSMasahiro Yamada
57609f455dcSMasahiro Yamada return;
57709f455dcSMasahiro Yamada }
57809f455dcSMasahiro Yamada
pinmux_set_drvdn(enum pmux_drvgrp grp,int drvdn)57909f455dcSMasahiro Yamada static void pinmux_set_drvdn(enum pmux_drvgrp grp, int drvdn)
58009f455dcSMasahiro Yamada {
58109f455dcSMasahiro Yamada u32 *reg = DRV_REG(grp);
58209f455dcSMasahiro Yamada u32 val;
58309f455dcSMasahiro Yamada
58409f455dcSMasahiro Yamada /* NONE means unspecified/do not change/use POR value */
58509f455dcSMasahiro Yamada if (drvdn == PMUX_DRVDN_NONE)
58609f455dcSMasahiro Yamada return;
58709f455dcSMasahiro Yamada
58809f455dcSMasahiro Yamada /* Error check on pad and drvdn */
58909f455dcSMasahiro Yamada assert(pmux_drvgrp_isvalid(grp));
59009f455dcSMasahiro Yamada assert(pmux_drv_isvalid(drvdn));
59109f455dcSMasahiro Yamada
59209f455dcSMasahiro Yamada val = readl(reg);
59309f455dcSMasahiro Yamada val &= ~DRVDN_MASK;
59409f455dcSMasahiro Yamada val |= (drvdn << DRVDN_SHIFT);
59509f455dcSMasahiro Yamada writel(val, reg);
59609f455dcSMasahiro Yamada
59709f455dcSMasahiro Yamada return;
59809f455dcSMasahiro Yamada }
59909f455dcSMasahiro Yamada
600439f5768SStephen Warren #ifdef TEGRA_PMX_GRPS_HAVE_LPMD
pinmux_set_lpmd(enum pmux_drvgrp grp,enum pmux_lpmd lpmd)60109f455dcSMasahiro Yamada static void pinmux_set_lpmd(enum pmux_drvgrp grp, enum pmux_lpmd lpmd)
60209f455dcSMasahiro Yamada {
60309f455dcSMasahiro Yamada u32 *reg = DRV_REG(grp);
60409f455dcSMasahiro Yamada u32 val;
60509f455dcSMasahiro Yamada
60609f455dcSMasahiro Yamada /* NONE means unspecified/do not change/use POR value */
60709f455dcSMasahiro Yamada if (lpmd == PMUX_LPMD_NONE)
60809f455dcSMasahiro Yamada return;
60909f455dcSMasahiro Yamada
61009f455dcSMasahiro Yamada /* Error check pad and lpmd value */
61109f455dcSMasahiro Yamada assert(pmux_drvgrp_isvalid(grp));
61209f455dcSMasahiro Yamada assert(pmux_lpmd_isvalid(lpmd));
61309f455dcSMasahiro Yamada
61409f455dcSMasahiro Yamada val = readl(reg);
61509f455dcSMasahiro Yamada val &= ~LPMD_MASK;
61609f455dcSMasahiro Yamada val |= (lpmd << LPMD_SHIFT);
61709f455dcSMasahiro Yamada writel(val, reg);
61809f455dcSMasahiro Yamada
61909f455dcSMasahiro Yamada return;
62009f455dcSMasahiro Yamada }
621439f5768SStephen Warren #endif
62209f455dcSMasahiro Yamada
623439f5768SStephen Warren #ifdef TEGRA_PMX_GRPS_HAVE_SCHMT
pinmux_set_schmt(enum pmux_drvgrp grp,enum pmux_schmt schmt)62409f455dcSMasahiro Yamada static void pinmux_set_schmt(enum pmux_drvgrp grp, enum pmux_schmt schmt)
62509f455dcSMasahiro Yamada {
62609f455dcSMasahiro Yamada u32 *reg = DRV_REG(grp);
62709f455dcSMasahiro Yamada u32 val;
62809f455dcSMasahiro Yamada
62909f455dcSMasahiro Yamada /* NONE means unspecified/do not change/use POR value */
63009f455dcSMasahiro Yamada if (schmt == PMUX_SCHMT_NONE)
63109f455dcSMasahiro Yamada return;
63209f455dcSMasahiro Yamada
63309f455dcSMasahiro Yamada /* Error check pad */
63409f455dcSMasahiro Yamada assert(pmux_drvgrp_isvalid(grp));
63509f455dcSMasahiro Yamada assert(pmux_schmt_isvalid(schmt));
63609f455dcSMasahiro Yamada
63709f455dcSMasahiro Yamada val = readl(reg);
63809f455dcSMasahiro Yamada if (schmt == PMUX_SCHMT_ENABLE)
63909f455dcSMasahiro Yamada val |= (1 << SCHMT_SHIFT);
64009f455dcSMasahiro Yamada else
64109f455dcSMasahiro Yamada val &= ~(1 << SCHMT_SHIFT);
64209f455dcSMasahiro Yamada writel(val, reg);
64309f455dcSMasahiro Yamada
64409f455dcSMasahiro Yamada return;
64509f455dcSMasahiro Yamada }
646439f5768SStephen Warren #endif
64709f455dcSMasahiro Yamada
648439f5768SStephen Warren #ifdef TEGRA_PMX_GRPS_HAVE_HSM
pinmux_set_hsm(enum pmux_drvgrp grp,enum pmux_hsm hsm)64909f455dcSMasahiro Yamada static void pinmux_set_hsm(enum pmux_drvgrp grp, enum pmux_hsm hsm)
65009f455dcSMasahiro Yamada {
65109f455dcSMasahiro Yamada u32 *reg = DRV_REG(grp);
65209f455dcSMasahiro Yamada u32 val;
65309f455dcSMasahiro Yamada
65409f455dcSMasahiro Yamada /* NONE means unspecified/do not change/use POR value */
65509f455dcSMasahiro Yamada if (hsm == PMUX_HSM_NONE)
65609f455dcSMasahiro Yamada return;
65709f455dcSMasahiro Yamada
65809f455dcSMasahiro Yamada /* Error check pad */
65909f455dcSMasahiro Yamada assert(pmux_drvgrp_isvalid(grp));
66009f455dcSMasahiro Yamada assert(pmux_hsm_isvalid(hsm));
66109f455dcSMasahiro Yamada
66209f455dcSMasahiro Yamada val = readl(reg);
66309f455dcSMasahiro Yamada if (hsm == PMUX_HSM_ENABLE)
66409f455dcSMasahiro Yamada val |= (1 << HSM_SHIFT);
66509f455dcSMasahiro Yamada else
66609f455dcSMasahiro Yamada val &= ~(1 << HSM_SHIFT);
66709f455dcSMasahiro Yamada writel(val, reg);
66809f455dcSMasahiro Yamada
66909f455dcSMasahiro Yamada return;
67009f455dcSMasahiro Yamada }
671439f5768SStephen Warren #endif
67209f455dcSMasahiro Yamada
pinmux_config_drvgrp(const struct pmux_drvgrp_config * config)67309f455dcSMasahiro Yamada static void pinmux_config_drvgrp(const struct pmux_drvgrp_config *config)
67409f455dcSMasahiro Yamada {
67509f455dcSMasahiro Yamada enum pmux_drvgrp grp = config->drvgrp;
67609f455dcSMasahiro Yamada
67709f455dcSMasahiro Yamada pinmux_set_drvup_slwf(grp, config->slwf);
67809f455dcSMasahiro Yamada pinmux_set_drvdn_slwr(grp, config->slwr);
67909f455dcSMasahiro Yamada pinmux_set_drvup(grp, config->drvup);
68009f455dcSMasahiro Yamada pinmux_set_drvdn(grp, config->drvdn);
681439f5768SStephen Warren #ifdef TEGRA_PMX_GRPS_HAVE_LPMD
68209f455dcSMasahiro Yamada pinmux_set_lpmd(grp, config->lpmd);
683439f5768SStephen Warren #endif
684439f5768SStephen Warren #ifdef TEGRA_PMX_GRPS_HAVE_SCHMT
68509f455dcSMasahiro Yamada pinmux_set_schmt(grp, config->schmt);
686439f5768SStephen Warren #endif
687439f5768SStephen Warren #ifdef TEGRA_PMX_GRPS_HAVE_HSM
68809f455dcSMasahiro Yamada pinmux_set_hsm(grp, config->hsm);
689439f5768SStephen Warren #endif
69009f455dcSMasahiro Yamada }
69109f455dcSMasahiro Yamada
pinmux_config_drvgrp_table(const struct pmux_drvgrp_config * config,int len)69209f455dcSMasahiro Yamada void pinmux_config_drvgrp_table(const struct pmux_drvgrp_config *config,
69309f455dcSMasahiro Yamada int len)
69409f455dcSMasahiro Yamada {
69509f455dcSMasahiro Yamada int i;
69609f455dcSMasahiro Yamada
69709f455dcSMasahiro Yamada for (i = 0; i < len; i++)
69809f455dcSMasahiro Yamada pinmux_config_drvgrp(&config[i]);
69909f455dcSMasahiro Yamada }
700c21478bcSStephen Warren #endif /* TEGRA_PMX_SOC_HAS_DRVGRPS */
7015ee7ec7bSStephen Warren
7025ee7ec7bSStephen Warren #ifdef TEGRA_PMX_SOC_HAS_MIPI_PAD_CTRL_GRPS
7035ee7ec7bSStephen Warren
7045ee7ec7bSStephen Warren #define pmux_mipipadctrlgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PMUX_MIPIPADCTRLGRP_COUNT))
7055ee7ec7bSStephen Warren
pinmux_mipipadctrl_set_func(enum pmux_mipipadctrlgrp grp,enum pmux_func func)7065ee7ec7bSStephen Warren static void pinmux_mipipadctrl_set_func(enum pmux_mipipadctrlgrp grp,
7075ee7ec7bSStephen Warren enum pmux_func func)
7085ee7ec7bSStephen Warren {
7095ee7ec7bSStephen Warren u32 *reg = MIPIPADCTRL_REG(grp);
7105ee7ec7bSStephen Warren int i, mux = -1;
7115ee7ec7bSStephen Warren u32 val;
7125ee7ec7bSStephen Warren
7135ee7ec7bSStephen Warren if (func == PMUX_FUNC_DEFAULT)
7145ee7ec7bSStephen Warren return;
7155ee7ec7bSStephen Warren
7165ee7ec7bSStephen Warren /* Error check grp and func */
7175ee7ec7bSStephen Warren assert(pmux_mipipadctrlgrp_isvalid(grp));
7185ee7ec7bSStephen Warren assert(pmux_func_isvalid(func));
7195ee7ec7bSStephen Warren
7205ee7ec7bSStephen Warren if (func >= PMUX_FUNC_RSVD1) {
7215ee7ec7bSStephen Warren mux = (func - PMUX_FUNC_RSVD1) & 1;
7225ee7ec7bSStephen Warren } else {
7235ee7ec7bSStephen Warren /* Search for the appropriate function */
7245ee7ec7bSStephen Warren for (i = 0; i < 2; i++) {
7255ee7ec7bSStephen Warren if (tegra_soc_mipipadctrl_groups[grp].funcs[i]
7265ee7ec7bSStephen Warren == func) {
7275ee7ec7bSStephen Warren mux = i;
7285ee7ec7bSStephen Warren break;
7295ee7ec7bSStephen Warren }
7305ee7ec7bSStephen Warren }
7315ee7ec7bSStephen Warren }
7325ee7ec7bSStephen Warren assert(mux != -1);
7335ee7ec7bSStephen Warren
7345ee7ec7bSStephen Warren val = readl(reg);
7355ee7ec7bSStephen Warren val &= ~(1 << 1);
7365ee7ec7bSStephen Warren val |= (mux << 1);
7375ee7ec7bSStephen Warren writel(val, reg);
7385ee7ec7bSStephen Warren }
7395ee7ec7bSStephen Warren
pinmux_config_mipipadctrlgrp(const struct pmux_mipipadctrlgrp_config * config)7405ee7ec7bSStephen Warren static void pinmux_config_mipipadctrlgrp(const struct pmux_mipipadctrlgrp_config *config)
7415ee7ec7bSStephen Warren {
7425ee7ec7bSStephen Warren enum pmux_mipipadctrlgrp grp = config->grp;
7435ee7ec7bSStephen Warren
7445ee7ec7bSStephen Warren pinmux_mipipadctrl_set_func(grp, config->func);
7455ee7ec7bSStephen Warren }
7465ee7ec7bSStephen Warren
pinmux_config_mipipadctrlgrp_table(const struct pmux_mipipadctrlgrp_config * config,int len)7475ee7ec7bSStephen Warren void pinmux_config_mipipadctrlgrp_table(
7485ee7ec7bSStephen Warren const struct pmux_mipipadctrlgrp_config *config, int len)
7495ee7ec7bSStephen Warren {
7505ee7ec7bSStephen Warren int i;
7515ee7ec7bSStephen Warren
7525ee7ec7bSStephen Warren for (i = 0; i < len; i++)
7535ee7ec7bSStephen Warren pinmux_config_mipipadctrlgrp(&config[i]);
7545ee7ec7bSStephen Warren }
7555ee7ec7bSStephen Warren #endif /* TEGRA_PMX_SOC_HAS_MIPI_PAD_CTRL_GRPS */
756