* [PATCH V3 1/4] ARM: tegra: pmc: convert PMC driver to support DT only
@ 2013-03-01 7:32 Joseph Lo
2013-03-01 7:32 ` [PATCH V3 2/4] ARM: tegra: pmc: add power on function for secondary CPUs Joseph Lo
0 siblings, 1 reply; 3+ messages in thread
From: Joseph Lo @ 2013-03-01 7:32 UTC (permalink / raw)
To: linux-arm-kernel
The Tegra kernel only support boot from DT now. Clean up the PMC driver
to support DT only, that includes:
* remove the ifdef of CONFIG_OF
* replace the static mapping of PMC addr to map from DT
Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
V3:
* BUG_ON directly if no PMC DT node
* remove redundant () in tegra_pmc_writel
V2:
* removing the change from readl_relaxed back to readl, same with the
write function
* adding a BUG() when there is no PMC node in DT
* removeing the redundancy of_have_populated_dt() check
---
arch/arm/mach-tegra/pmc.c | 51 ++++++++++++++++++++---------------------------
1 file changed, 22 insertions(+), 29 deletions(-)
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index 5d79d34..a916eca 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2012,2013 NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -18,59 +18,52 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/of.h>
-
-#include "iomap.h"
+#include <linux/of_address.h>
#define PMC_CTRL 0x0
#define PMC_CTRL_INTR_LOW (1 << 17)
+static void __iomem *tegra_pmc_base;
+static bool tegra_pmc_invert_interrupt;
+
static inline u32 tegra_pmc_readl(u32 reg)
{
- return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
+ return readl(tegra_pmc_base + reg);
}
static inline void tegra_pmc_writel(u32 val, u32 reg)
{
- writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg));
+ writel(val, tegra_pmc_base + reg);
}
-#ifdef CONFIG_OF
static const struct of_device_id matches[] __initconst = {
{ .compatible = "nvidia,tegra114-pmc" },
{ .compatible = "nvidia,tegra30-pmc" },
{ .compatible = "nvidia,tegra20-pmc" },
{ }
};
-#endif
-void __init tegra_pmc_init(void)
+static void tegra_pmc_parse_dt(void)
{
- /*
- * For now, Harmony is the only board that uses the PMC, and it wants
- * the signal inverted. Seaboard would too if it used the PMC.
- * Hopefully by the time other boards want to use the PMC, everything
- * will be device-tree, or they also want it inverted.
- */
- bool invert_interrupt = true;
- u32 val;
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, matches);
+ BUG_ON(!np);
-#ifdef CONFIG_OF
- if (of_have_populated_dt()) {
- struct device_node *np;
+ tegra_pmc_base = of_iomap(np, 0);
- invert_interrupt = false;
+ tegra_pmc_invert_interrupt = of_property_read_bool(np,
+ "nvidia,invert-interrupt");
+}
+
+void __init tegra_pmc_init(void)
+{
+ u32 val;
- np = of_find_matching_node(NULL, matches);
- if (np) {
- if (of_find_property(np, "nvidia,invert-interrupt",
- NULL))
- invert_interrupt = true;
- }
- }
-#endif
+ tegra_pmc_parse_dt();
val = tegra_pmc_readl(PMC_CTRL);
- if (invert_interrupt)
+ if (tegra_pmc_invert_interrupt)
val |= PMC_CTRL_INTR_LOW;
else
val &= ~PMC_CTRL_INTR_LOW;
--
1.8.1.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH V3 2/4] ARM: tegra: pmc: add power on function for secondary CPUs
2013-03-01 7:32 [PATCH V3 1/4] ARM: tegra: pmc: convert PMC driver to support DT only Joseph Lo
@ 2013-03-01 7:32 ` Joseph Lo
2013-03-01 19:29 ` Stephen Warren
0 siblings, 1 reply; 3+ messages in thread
From: Joseph Lo @ 2013-03-01 7:32 UTC (permalink / raw)
To: linux-arm-kernel
Adding the power on function for secondary CPUs in PMC driver, this can
help us to remove legacy powergate driver and add generic power domain
support later.
Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
V3:
* making code more simpler in pmc_powergate_set and is_powered func
V2:
* Don't use ISS_ERR_VALUE for checking error return code
* the CPU power on function only available for secondary CPU which means
we don't support (cpuid <= 0 || cpuid >= num_possible_cpus())
* adding a WARN_ON when the current power state is same with we want to set
---
arch/arm/mach-tegra/pmc.c | 101 +++++++++++++++++++++++++++++++++++++++++++++-
arch/arm/mach-tegra/pmc.h | 4 ++
2 files changed, 103 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index a916eca..b30e921 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -20,8 +20,26 @@
#include <linux/of.h>
#include <linux/of_address.h>
-#define PMC_CTRL 0x0
-#define PMC_CTRL_INTR_LOW (1 << 17)
+#define PMC_CTRL 0x0
+#define PMC_CTRL_INTR_LOW (1 << 17)
+#define PMC_PWRGATE_TOGGLE 0x30
+#define PMC_PWRGATE_TOGGLE_START (1 << 8)
+#define PMC_REMOVE_CLAMPING 0x34
+#define PMC_PWRGATE_STATUS 0x38
+
+#define TEGRA_POWERGATE_PCIE 3
+#define TEGRA_POWERGATE_VDEC 4
+#define TEGRA_POWERGATE_CPU1 9
+#define TEGRA_POWERGATE_CPU2 10
+#define TEGRA_POWERGATE_CPU3 11
+
+static u8 tegra_cpu_domains[] = {
+ 0xFF, /* not available for CPU0 */
+ TEGRA_POWERGATE_CPU1,
+ TEGRA_POWERGATE_CPU2,
+ TEGRA_POWERGATE_CPU3,
+};
+static DEFINE_SPINLOCK(tegra_powergate_lock);
static void __iomem *tegra_pmc_base;
static bool tegra_pmc_invert_interrupt;
@@ -36,6 +54,85 @@ static inline void tegra_pmc_writel(u32 val, u32 reg)
writel(val, tegra_pmc_base + reg);
}
+static int tegra_pmc_get_cpu_powerdomain_id(int cpuid)
+{
+ if (cpuid <= 0 || cpuid >= num_possible_cpus())
+ return -EINVAL;
+ return tegra_cpu_domains[cpuid];
+}
+
+static bool tegra_pmc_powergate_is_powered(int id)
+{
+ return (tegra_pmc_readl(PMC_PWRGATE_STATUS) >> id) & 1;
+}
+
+static int tegra_pmc_powergate_set(int id, bool new_state)
+{
+ bool old_state;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tegra_powergate_lock, flags);
+
+ old_state = tegra_pmc_powergate_is_powered(id);
+ WARN_ON(old_state == new_state);
+
+ tegra_pmc_writel(PMC_PWRGATE_TOGGLE_START | id, PMC_PWRGATE_TOGGLE);
+
+ spin_unlock_irqrestore(&tegra_powergate_lock, flags);
+
+ return 0;
+}
+
+static int tegra_pmc_powergate_remove_clamping(int id)
+{
+ u32 mask;
+
+ /*
+ * Tegra 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);
+
+ tegra_pmc_writel(mask, PMC_REMOVE_CLAMPING);
+
+ return 0;
+}
+
+bool tegra_pmc_cpu_is_powered(int cpuid)
+{
+ int id;
+
+ id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+ if (id < 0)
+ return false;
+ return tegra_pmc_powergate_is_powered(id);
+}
+
+int tegra_pmc_cpu_power_on(int cpuid)
+{
+ int id;
+
+ id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+ if (id < 0)
+ return id;
+ return tegra_pmc_powergate_set(id, true);
+}
+
+int tegra_pmc_cpu_remove_clamping(int cpuid)
+{
+ int id;
+
+ id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+ if (id < 0)
+ return id;
+ return tegra_pmc_powergate_remove_clamping(id);
+}
+
static const struct of_device_id matches[] __initconst = {
{ .compatible = "nvidia,tegra114-pmc" },
{ .compatible = "nvidia,tegra30-pmc" },
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
index 8995ee4..7d44710 100644
--- a/arch/arm/mach-tegra/pmc.h
+++ b/arch/arm/mach-tegra/pmc.h
@@ -18,6 +18,10 @@
#ifndef __MACH_TEGRA_PMC_H
#define __MACH_TEGRA_PMC_H
+bool tegra_pmc_cpu_is_powered(int cpuid);
+int tegra_pmc_cpu_power_on(int cpuid);
+int tegra_pmc_cpu_remove_clamping(int cpuid);
+
void tegra_pmc_init(void);
#endif
--
1.8.1.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH V3 2/4] ARM: tegra: pmc: add power on function for secondary CPUs
2013-03-01 7:32 ` [PATCH V3 2/4] ARM: tegra: pmc: add power on function for secondary CPUs Joseph Lo
@ 2013-03-01 19:29 ` Stephen Warren
0 siblings, 0 replies; 3+ messages in thread
From: Stephen Warren @ 2013-03-01 19:29 UTC (permalink / raw)
To: linux-arm-kernel
On 03/01/2013 12:32 AM, Joseph Lo wrote:
> Adding the power on function for secondary CPUs in PMC driver, this can
> help us to remove legacy powergate driver and add generic power domain
> support later.
OK, I think these look good. I'll apply them for 3.10 when I can.
Note: you reposted 2 out of 4 patches. It'd be best to repost all the
patches in the series. While I understand that the other 2 didn't
change, not reposting them makes it a bit harder to track down which
patches fit together into a series, since I have to find some "V2" and
some "V3" and stick them together. That said, given you've already
posted the patches, there's no need to repost them again to fix them
this time; just a note for next time.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-03-01 19:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-01 7:32 [PATCH V3 1/4] ARM: tegra: pmc: convert PMC driver to support DT only Joseph Lo
2013-03-01 7:32 ` [PATCH V3 2/4] ARM: tegra: pmc: add power on function for secondary CPUs Joseph Lo
2013-03-01 19:29 ` Stephen Warren
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).