I've found out more inconsistencies in the powergate implementation. I'll post
the patches later on today, and the patch below can be dropped.
Sorry for the noise.
Mike Rapoport wrote:
The powergate status register has PCIE and VDEC bits swapped. Using
decicated tegra_powergate_get_status function instead of reading the
PWRGATE_STATUS register allows to workaround this problem.
Signed-off-by: Mike Rapoport <mike@xxxxxxxxxxxxxx>
---
v2 changes: incorporated feedback from Erik Gilling
---
arch/arm/mach-tegra/powergate.c | 28 +++++++++++++++++++++++-----
1 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
index c286dad..863c8f5 100644
--- a/arch/arm/mach-tegra/powergate.c
+++ b/arch/arm/mach-tegra/powergate.c
@@ -52,6 +52,27 @@ static void pmc_write(u32 val, unsigned long reg)
writel(val, pmc + reg);
}
+static bool tegra_powergate_get_status(int id)
+{
+ u32 mask;
+ u32 val;
+
+ /*
+ * Tegra 2 has a bug where PCIE and VDE clamping masks are
+ * swapped relatively to the partition ids
+ */
+ if (id == TEGRA_POWERGATE_VDEC)
+ mask = (1 << TEGRA_POWERGATE_PCIE);
+ else if (id == TEGRA_POWERGATE_PCIE)
+ mask = (1 << TEGRA_POWERGATE_VDEC);
+ else
+ mask = (1 << id);
+
+ val = pmc_read(PWRGATE_STATUS);
+
+ return !!(val & mask);
+}
+
static int tegra_powergate_set(int id, bool new_state)
{
bool status;
@@ -59,7 +80,7 @@ static int tegra_powergate_set(int id, bool new_state)
spin_lock_irqsave(&tegra_powergate_lock, flags);
- status = pmc_read(PWRGATE_STATUS) & (1 << id);
+ status = tegra_powergate_get_status(id);
if (status == new_state) {
spin_unlock_irqrestore(&tegra_powergate_lock, flags);
@@ -91,13 +112,10 @@ int tegra_powergate_power_off(int id)
bool tegra_powergate_is_powered(int id)
{
- u32 status;
-
if (id < 0 || id >= TEGRA_NUM_POWERGATE)
return -EINVAL;
- status = pmc_read(PWRGATE_STATUS) & (1 << id);
- return !!status;
+ return tegra_powergate_get_status(id);
}
int tegra_powergate_remove_clamping(int id)
--
Sincerely yours,
Mike.
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html