ARM: tegra: moving the CPU power timer function to PMC driver
authorJoseph Lo <josephl@nvidia.com>
Wed, 3 Apr 2013 11:31:28 +0000 (19:31 +0800)
committerStephen Warren <swarren@nvidia.com>
Wed, 3 Apr 2013 20:30:22 +0000 (14:30 -0600)
The CPU power timer set up function was related to PMC register. Now moving
it to PMC driver. And it also help to clean up the PM related code later.

The timer was calculated based on the input clock of PMC. In this patch, we
also get the clock from DT.

Signed-off-by: Joseph Lo <josephl@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pmc.c
arch/arm/mach-tegra/pmc.h

index f0315c95c76d552485af66495c24fec61030faa1..b02ebe767e7f3ec8c196e9c7a2f442e2ee5d3345 100644 (file)
@@ -61,6 +61,7 @@ u32 tegra_uart_config[4] = {
 void __init tegra_dt_init_irq(void)
 {
        tegra_clocks_init();
+       tegra_pmc_init();
        tegra_init_irq();
        irqchip_init();
 }
@@ -100,7 +101,6 @@ void __init tegra_init_early(void)
        tegra_apb_io_init();
        tegra_init_fuse();
        tegra_init_cache();
-       tegra_pmc_init();
        tegra_powergate_init();
        tegra_hotplug_init();
 }
index 0494f739c95f935975787d563169d95eca40dbed..5f5611f40b43229635abf7884e5609f655cb472a 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/cpumask.h>
 #include <linux/delay.h>
 #include <linux/cpu_pm.h>
-#include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/clk/tegra.h>
 
 #include "reset.h"
 #include "flowctrl.h"
 #include "fuse.h"
+#include "pmc.h"
 #include "sleep.h"
 
 #define TEGRA_POWER_CPU_PWRREQ_OE      (1 << 16)  /* CPU pwr req enable */
 
 #define PMC_CTRL               0x0
-#define PMC_CPUPWRGOOD_TIMER   0xc8
-#define PMC_CPUPWROFF_TIMER    0xcc
 
 #ifdef CONFIG_PM_SLEEP
 static DEFINE_SPINLOCK(tegra_lp2_lock);
 static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
-static struct clk *tegra_pclk;
 void (*tegra_tear_down_cpu)(void);
 
-static void set_power_timers(unsigned long us_on, unsigned long us_off)
-{
-       unsigned long long ticks;
-       unsigned long long pclk;
-       unsigned long rate;
-       static unsigned long tegra_last_pclk;
-
-       if (tegra_pclk == NULL) {
-               tegra_pclk = clk_get_sys(NULL, "pclk");
-               WARN_ON(IS_ERR(tegra_pclk));
-       }
-
-       rate = clk_get_rate(tegra_pclk);
-
-       if (WARN_ON_ONCE(rate <= 0))
-               pclk = 100000000;
-       else
-               pclk = rate;
-
-       if ((rate != tegra_last_pclk)) {
-               ticks = (us_on * pclk) + 999999ull;
-               do_div(ticks, 1000000);
-               writel((unsigned long)ticks, pmc + PMC_CPUPWRGOOD_TIMER);
-
-               ticks = (us_off * pclk) + 999999ull;
-               do_div(ticks, 1000000);
-               writel((unsigned long)ticks, pmc + PMC_CPUPWROFF_TIMER);
-               wmb();
-       }
-       tegra_last_pclk = pclk;
-}
-
 /*
  * restore_cpu_complex
  *
index b30e921cc3a9c88b5295cb825b9f3a162f1cd20c..faa33e8f937d774757ffaa10a77fb0aca80f6e10 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -27,6 +28,9 @@
 #define PMC_REMOVE_CLAMPING            0x34
 #define PMC_PWRGATE_STATUS             0x38
 
+#define PMC_CPUPWRGOOD_TIMER   0xc8
+#define PMC_CPUPWROFF_TIMER    0xcc
+
 #define TEGRA_POWERGATE_PCIE   3
 #define TEGRA_POWERGATE_VDEC   4
 #define TEGRA_POWERGATE_CPU1   9
@@ -43,6 +47,7 @@ static DEFINE_SPINLOCK(tegra_powergate_lock);
 
 static void __iomem *tegra_pmc_base;
 static bool tegra_pmc_invert_interrupt;
+static struct clk *tegra_pclk;
 
 static inline u32 tegra_pmc_readl(u32 reg)
 {
@@ -133,6 +138,34 @@ int tegra_pmc_cpu_remove_clamping(int cpuid)
        return tegra_pmc_powergate_remove_clamping(id);
 }
 
+#ifdef CONFIG_PM_SLEEP
+void set_power_timers(unsigned long us_on, unsigned long us_off)
+{
+       unsigned long long ticks;
+       unsigned long long pclk;
+       unsigned long rate;
+       static unsigned long tegra_last_pclk;
+
+       rate = clk_get_rate(tegra_pclk);
+       if (WARN_ON_ONCE(rate <= 0))
+               pclk = 100000000;
+       else
+               pclk = rate;
+
+       if ((rate != tegra_last_pclk)) {
+               ticks = (us_on * pclk) + 999999ull;
+               do_div(ticks, 1000000);
+               tegra_pmc_writel((unsigned long)ticks, PMC_CPUPWRGOOD_TIMER);
+
+               ticks = (us_off * pclk) + 999999ull;
+               do_div(ticks, 1000000);
+               tegra_pmc_writel((unsigned long)ticks, PMC_CPUPWROFF_TIMER);
+               wmb();
+       }
+       tegra_last_pclk = pclk;
+}
+#endif
+
 static const struct of_device_id matches[] __initconst = {
        { .compatible = "nvidia,tegra114-pmc" },
        { .compatible = "nvidia,tegra30-pmc" },
@@ -151,6 +184,8 @@ static void tegra_pmc_parse_dt(void)
 
        tegra_pmc_invert_interrupt = of_property_read_bool(np,
                                     "nvidia,invert-interrupt");
+       tegra_pclk = of_clk_get_by_name(np, "pclk");
+       WARN_ON(IS_ERR(tegra_pclk));
 }
 
 void __init tegra_pmc_init(void)
index 7d44710368bea565cd0b9f66022d25909d55ca5b..22f16c9dd44de9a52641bfccba1c819c999347fd 100644 (file)
 #ifndef __MACH_TEGRA_PMC_H
 #define __MACH_TEGRA_PMC_H
 
+#ifdef CONFIG_PM_SLEEP
+void set_power_timers(unsigned long us_on, unsigned long us_off);
+#endif
+
 bool tegra_pmc_cpu_is_powered(int cpuid);
 int tegra_pmc_cpu_power_on(int cpuid);
 int tegra_pmc_cpu_remove_clamping(int cpuid);