summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux.h24
-rw-r--r--arch/arm/mach-tegra/pinmux-t2-tables.c3
-rw-r--r--arch/arm/mach-tegra/pinmux-t3-tables.c3
-rw-r--r--arch/arm/mach-tegra/pinmux.c164
4 files changed, 194 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h
index 47056ace13ca..cb14802be2c6 100644
--- a/arch/arm/mach-tegra/include/mach/pinmux.h
+++ b/arch/arm/mach-tegra/include/mach/pinmux.h
@@ -163,6 +163,24 @@ enum tegra_pin_io {
TEGRA_PIN_INPUT = 1,
};
+enum tegra_pin_lock {
+ TEGRA_PIN_LOCK_DEFAULT = 0,
+ TEGRA_PIN_LOCK_DISABLE,
+ TEGRA_PIN_LOCK_ENABLE,
+};
+
+enum tegra_pin_od {
+ TEGRA_PIN_OD_DEFAULT = 0,
+ TEGRA_PIN_OD_DISABLE,
+ TEGRA_PIN_OD_ENABLE,
+};
+
+enum tegra_pin_ioreset {
+ TEGRA_PIN_IO_RESET_DEFAULT = 0,
+ TEGRA_PIN_IO_RESET_DISABLE,
+ TEGRA_PIN_IO_RESET_ENABLE,
+};
+
enum tegra_vddio {
TEGRA_VDDIO_BB = 0,
TEGRA_VDDIO_LCD,
@@ -189,6 +207,9 @@ struct tegra_pingroup_config {
enum tegra_pullupdown pupd;
enum tegra_tristate tristate;
enum tegra_pin_io io;
+ enum tegra_pin_lock lock;
+ enum tegra_pin_od od;
+ enum tegra_pin_ioreset ioreset;
};
enum tegra_slew {
@@ -280,6 +301,9 @@ struct tegra_pingroup_desc {
s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */
s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */
s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */
+ s8 lock_bit; /* offser of the LOCK bit into mux register bit */
+ s8 od_bit; /* offset of the OD bit into mux register bit */
+ s8 ioreset_bit; /* offset of the IO_RESET bit into mux register bit */
s8 io_default;
};
diff --git a/arch/arm/mach-tegra/pinmux-t2-tables.c b/arch/arm/mach-tegra/pinmux-t2-tables.c
index a6fcd6c62e98..a5dcd107f6d0 100644
--- a/arch/arm/mach-tegra/pinmux-t2-tables.c
+++ b/arch/arm/mach-tegra/pinmux-t2-tables.c
@@ -97,6 +97,9 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE
.pupd_reg = pupd_r, \
.pupd_bit = pupd_b, \
.io_default = 0, \
+ .od_bit = -1, \
+ .lock_bit = -1, \
+ .ioreset_bit = -1, \
}
const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
diff --git a/arch/arm/mach-tegra/pinmux-t3-tables.c b/arch/arm/mach-tegra/pinmux-t3-tables.c
index 798986ba1837..f49af0443cf2 100644
--- a/arch/arm/mach-tegra/pinmux-t3-tables.c
+++ b/arch/arm/mach-tegra/pinmux-t3-tables.c
@@ -99,6 +99,9 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE
.pupd_reg = reg, \
.pupd_bit = 2, \
.io_default = TEGRA_PIN_ ## iod, \
+ .od_bit = 6, \
+ .lock_bit = 7, \
+ .ioreset_bit = 8, \
}
/* !!!FIXME!!! FILL IN fSafe COLUMN IN TABLE ....... */
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
index 2b6b69428588..02895a49a0d2 100644
--- a/arch/arm/mach-tegra/pinmux.c
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -214,6 +214,54 @@ static const char *pupd_name(unsigned long val)
}
}
+static const char *lock_name(unsigned long val)
+{
+ switch(val) {
+ case TEGRA_PIN_LOCK_DEFAULT:
+ return "LOCK_DEFUALT";
+
+ case TEGRA_PIN_LOCK_DISABLE:
+ return "LOCK_DISABLE";
+
+ case TEGRA_PIN_LOCK_ENABLE:
+ return "LOCK_ENABLE";
+ default:
+ return "LOCK_DEFAULT";
+ }
+}
+
+static const char *od_name(unsigned long val)
+{
+ switch(val) {
+ case TEGRA_PIN_OD_DEFAULT:
+ return "OD_DEFAULT";
+
+ case TEGRA_PIN_OD_DISABLE:
+ return "OD_DISABLE";
+
+ case TEGRA_PIN_OD_ENABLE:
+ return "OD_ENABLE";
+ default:
+ return "OD_DEFAULT";
+ }
+}
+
+static const char *ioreset_name(unsigned long val)
+{
+ switch(val) {
+ case TEGRA_PIN_IO_RESET_DEFAULT:
+ return "IO_RESET_DEFAULT";
+
+ case TEGRA_PIN_IO_RESET_DISABLE:
+ return "IO_RESET_DISABLE";
+
+ case TEGRA_PIN_IO_RESET_ENABLE:
+ return "IO_RESET_ENABLE";
+ default:
+ return "IO_RESET_DEFAULT";
+ }
+}
+
#if defined(TEGRA_PINMUX_HAS_IO_DIRECTION)
static const char *io_name(unsigned long val)
{
@@ -338,6 +386,94 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
return 0;
}
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
+static int tegra_pinmux_set_lock(enum tegra_pingroup pg,
+ enum tegra_pin_lock lock)
+{
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].mux_reg < 0)
+ return -EINVAL;
+
+ if ((lock == TEGRA_PIN_LOCK_DEFAULT) || (pingroups[pg].lock_bit < 0))
+ return 0;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(pingroups[pg].mux_reg);
+ reg &= ~(0x1 << pingroups[pg].lock_bit);
+ if (lock == TEGRA_PIN_LOCK_ENABLE)
+ reg |= (0x1 << pingroups[pg].lock_bit);
+
+ pg_writel(reg, pingroups[pg].mux_reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+ return 0;
+}
+
+static int tegra_pinmux_set_od(enum tegra_pingroup pg,
+ enum tegra_pin_od od)
+{
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].mux_reg < 0)
+ return -EINVAL;
+
+ if ((od == TEGRA_PIN_OD_DEFAULT) || (pingroups[pg].od_bit < 0))
+ return 0;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(pingroups[pg].mux_reg);
+ reg &= ~(0x1 << pingroups[pg].od_bit);
+ if (od == TEGRA_PIN_OD_ENABLE)
+ reg |= 1 << pingroups[pg].od_bit;
+
+ pg_writel(reg, pingroups[pg].mux_reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_pinmux_set_ioreset(enum tegra_pingroup pg,
+ enum tegra_pin_ioreset ioreset)
+{
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].mux_reg < 0)
+ return -EINVAL;
+
+ if ((ioreset == TEGRA_PIN_IO_RESET_DEFAULT) || (pingroups[pg].ioreset_bit < 0))
+ return 0;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(pingroups[pg].mux_reg);
+ reg &= ~(0x1 << pingroups[pg].ioreset_bit);
+ if (ioreset == TEGRA_PIN_IO_RESET_ENABLE)
+ reg |= 1 << pingroups[pg].ioreset_bit;
+
+ pg_writel(reg, pingroups[pg].mux_reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+#endif
+
int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
enum tegra_pullupdown pupd)
{
@@ -374,6 +510,11 @@ static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *con
enum tegra_mux_func func = config->func;
enum tegra_pullupdown pupd = config->pupd;
enum tegra_tristate tristate = config->tristate;
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
+ enum tegra_pin_lock lock = config->lock;
+ enum tegra_pin_od od = config->od;
+ enum tegra_pin_ioreset ioreset = config->ioreset;
+#endif
int err;
if (pingroups[pingroup].mux_reg >= 0) {
@@ -396,6 +537,29 @@ static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *con
pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
pingroup_name(pingroup), tri_name(func), err);
}
+
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
+ if (pingroups[pingroup].mux_reg >= 0) {
+ err = tegra_pinmux_set_lock(pingroup, lock);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s lock to %s: %d\n",
+ pingroup_name(pingroup), lock_name(func), err);
+ }
+
+ if (pingroups[pingroup].mux_reg >= 0) {
+ err = tegra_pinmux_set_od(pingroup, od);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s od to %s: %d\n",
+ pingroup_name(pingroup), od_name(func), err);
+ }
+
+ if (pingroups[pingroup].mux_reg >= 0) {
+ err = tegra_pinmux_set_ioreset(pingroup, ioreset);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s ioreset to %s: %d\n",
+ pingroup_name(pingroup), ioreset_name(func), err);
+ }
+#endif
}
void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len)