* [PATCH V3 1/3] ARM: tegra: get PMC clock source from DT
2013-04-02 11:19 [PATCH V3 0/3] ARM: tegra: add clock source for PMC Joseph Lo
@ 2013-04-02 11:19 ` Joseph Lo
2013-04-02 19:33 ` Stephen Warren
2013-04-02 11:19 ` [PATCH V3 2/3] ARM: dts: tegra: add clock source for PMC Joseph Lo
2013-04-02 11:19 ` [PATCH V3 3/3] ARM: tegra: moving the CPU power timer function to PMC driver Joseph Lo
2 siblings, 1 reply; 8+ messages in thread
From: Joseph Lo @ 2013-04-02 11:19 UTC (permalink / raw)
To: linux-arm-kernel
Adding the bindings of the clock source of PMC in DT. And getting
the clock from DT.
Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
V3:
* add binding document for the clock source of PMC
* get the clock from DT by of_get_clk_by_name()
* fix WARN_ON_ONCE to WARN_ON when there is no clock define in DT
V2:
* new in this series
---
.../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 23 ++++++++++++++++++++++
arch/arm/mach-tegra/common.c | 2 +-
arch/arm/mach-tegra/pmc.c | 4 ++++
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
index b5846e2..1cb8f6b 100644
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
@@ -9,11 +9,34 @@ Properties:
signal is fed into the PMC. This signal is optionally inverted, and then
fed into the ARM GIC. The PMC is not involved in the detection or
handling of this interrupt signal, merely its inversion.
+- clocks : the source clock of PMC
+- clock-names : the name of source clock of PMC
Example:
+/ SoC dts including file
pmc at 7000f400 {
compatible = "nvidia,tegra20-pmc";
reg = <0x7000e400 0x400>;
nvidia,invert-interrupt;
+ clocks = <&tegra_car 110>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
};
+
+/ Tegra board dts file
+{
+ ...
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock at 0 {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+ ...
+}
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index f0315c9..b02ebe7 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -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();
}
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index b30e921..dbe2577 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -19,6 +19,7 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/clk.h>
#define PMC_CTRL 0x0
#define PMC_CTRL_INTR_LOW (1 << 17)
@@ -43,6 +44,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)
{
@@ -151,6 +153,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)
--
1.8.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V3 1/3] ARM: tegra: get PMC clock source from DT
2013-04-02 11:19 ` [PATCH V3 1/3] ARM: tegra: get PMC clock source from DT Joseph Lo
@ 2013-04-02 19:33 ` Stephen Warren
0 siblings, 0 replies; 8+ messages in thread
From: Stephen Warren @ 2013-04-02 19:33 UTC (permalink / raw)
To: linux-arm-kernel
On 04/02/2013 05:19 AM, Joseph Lo wrote:
> Adding the bindings of the clock source of PMC in DT. And getting
> the clock from DT.
> .../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 23 ++++++++++++++++++++++
> arch/arm/mach-tegra/common.c | 2 +-
> arch/arm/mach-tegra/pmc.c | 4 ++++
I'd like to re-order and split up this series slightly differently.
Patch (1) should include the binding updates (nvidia,tegra20-pmc.txt)
from this patch 1/3 and the DT changes (*.dts) from patch 2/3.
Patch (2) should contain be the current patch 3/3 plus the *.c changes
from this patch 1/3.
That ensures that:
a) The DT binding changes happen before (or rather at the same time) as
the first other change that relies on them.
b) The DT changes happen before the code changes, which is required to
avoid the code-changes causing WARN_ON(IS_ERR(tegra_pclk)) from firing
before all the patches are applied.
c) The new code to retrieve tegra_pclk isn't added without anything that
uses the new variable; it's added only when something makes use of it.
> diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
> +- clocks : the source clock of PMC
> +- clock-names : the name of source clock of PMC
"the" is wrong here, since there is more than one clock. Also, the
binding document needs to define the set of clocks that those properties
must provide. I suggest the following wording, which I cribbed from the
Tegra audio bindings:
- clocks : Must contain an entry for each entry in clock-names.
- clock-names : Must include the following entries:
"pclk" (The Tegra clock of that name),
"clk32k_in" (The 32KHz clock input to Tegra).
That text should also be added to the "Required properties" section, not
the "Optional proeprties" section.
> +/ SoC dts including file
> pmc at 7000f400 {
> compatible = "nvidia,tegra20-pmc";
> reg = <0x7000e400 0x400>;
> nvidia,invert-interrupt;
> + clocks = <&tegra_car 110>, <&clk32k_in>;
> + clock-names = "pclk", "clk32k_in";
In this example, I'd prefer the clocks properties to be before the
custom nvidia,invert-interrupt property, so that all standard and
required properties are first, then custom properties. so, compatible,
reg, clock*, nvidia,invert-interrupt.
> diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
> void __init tegra_dt_init_irq(void)
> {
> tegra_clocks_init();
> + tegra_pmc_init();
> tegra_init_irq();
> irqchip_init();
> }
I'll let this slide for now. Please be aware that I'd prefer all
non-IRQ-related initialization to happen somewhere inside the machine's
.init_machine() callback, not its .init_irq() callback. However, we can
clean this up later; most likely a lot of the calls in
tegra_init_early() should move too.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH V3 2/3] ARM: dts: tegra: add clock source for PMC
2013-04-02 11:19 [PATCH V3 0/3] ARM: tegra: add clock source for PMC Joseph Lo
2013-04-02 11:19 ` [PATCH V3 1/3] ARM: tegra: get PMC clock source from DT Joseph Lo
@ 2013-04-02 11:19 ` Joseph Lo
2013-04-02 19:36 ` Stephen Warren
2013-04-02 11:19 ` [PATCH V3 3/3] ARM: tegra: moving the CPU power timer function to PMC driver Joseph Lo
2 siblings, 1 reply; 8+ messages in thread
From: Joseph Lo @ 2013-04-02 11:19 UTC (permalink / raw)
To: linux-arm-kernel
Adding the clock sources of PMC into DTS for Tegra20 and Tegra30.
Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
V3:
* add clk32k_in as one of the PMC clock source.
* add a fixed clock of clk32k_in for Tegra20 & Tegra30
V2:
* new in this change
---
arch/arm/boot/dts/tegra20-colibri-512.dtsi | 13 +++++++++++++
arch/arm/boot/dts/tegra20-harmony.dts | 13 +++++++++++++
arch/arm/boot/dts/tegra20-paz00.dts | 13 +++++++++++++
arch/arm/boot/dts/tegra20-seaboard.dts | 13 +++++++++++++
arch/arm/boot/dts/tegra20-tamonten.dtsi | 13 +++++++++++++
arch/arm/boot/dts/tegra20-trimslice.dts | 13 +++++++++++++
arch/arm/boot/dts/tegra20-ventana.dts | 13 +++++++++++++
arch/arm/boot/dts/tegra20-whistler.dts | 13 +++++++++++++
arch/arm/boot/dts/tegra20.dtsi | 2 ++
arch/arm/boot/dts/tegra30-beaver.dts | 13 +++++++++++++
arch/arm/boot/dts/tegra30-cardhu.dtsi | 13 +++++++++++++
arch/arm/boot/dts/tegra30.dtsi | 2 ++
12 files changed, 134 insertions(+)
diff --git a/arch/arm/boot/dts/tegra20-colibri-512.dtsi b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
index cb73e62..4c107e6 100644
--- a/arch/arm/boot/dts/tegra20-colibri-512.dtsi
+++ b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
@@ -8,6 +8,19 @@
reg = <0x00000000 0x20000000>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
host1x {
hdmi {
vdd-supply = <&hdmi_vdd_reg>;
diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts
index 5fb0888..6e6899a 100644
--- a/arch/arm/boot/dts/tegra20-harmony.dts
+++ b/arch/arm/boot/dts/tegra20-harmony.dts
@@ -10,6 +10,19 @@
reg = <0x00000000 0x40000000>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
host1x {
hdmi {
status = "okay";
diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts
index 43fd28b..54b05b2 100644
--- a/arch/arm/boot/dts/tegra20-paz00.dts
+++ b/arch/arm/boot/dts/tegra20-paz00.dts
@@ -10,6 +10,19 @@
reg = <0x00000000 0x20000000>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
host1x {
hdmi {
status = "okay";
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts
index 4f810a5..3b347b8 100644
--- a/arch/arm/boot/dts/tegra20-seaboard.dts
+++ b/arch/arm/boot/dts/tegra20-seaboard.dts
@@ -10,6 +10,19 @@
reg = <0x00000000 0x40000000>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
host1x {
hdmi {
status = "okay";
diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi
index 6e9d91f..0c7bc18 100644
--- a/arch/arm/boot/dts/tegra20-tamonten.dtsi
+++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi
@@ -8,6 +8,19 @@
reg = <0x00000000 0x20000000>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
host1x {
hdmi {
vdd-supply = <&hdmi_vdd_reg>;
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts
index 955bf49..b265ebd 100644
--- a/arch/arm/boot/dts/tegra20-trimslice.dts
+++ b/arch/arm/boot/dts/tegra20-trimslice.dts
@@ -10,6 +10,19 @@
reg = <0x00000000 0x40000000>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
host1x {
hdmi {
status = "okay";
diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts
index 3f8ae10..157a2cd 100644
--- a/arch/arm/boot/dts/tegra20-ventana.dts
+++ b/arch/arm/boot/dts/tegra20-ventana.dts
@@ -10,6 +10,19 @@
reg = <0x00000000 0x40000000>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
host1x {
hdmi {
status = "okay";
diff --git a/arch/arm/boot/dts/tegra20-whistler.dts b/arch/arm/boot/dts/tegra20-whistler.dts
index 87e2d85..87632df 100644
--- a/arch/arm/boot/dts/tegra20-whistler.dts
+++ b/arch/arm/boot/dts/tegra20-whistler.dts
@@ -10,6 +10,19 @@
reg = <0x00000000 0x20000000>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
host1x {
hdmi {
status = "okay";
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 26c1134..5fc661d 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -419,6 +419,8 @@
pmc {
compatible = "nvidia,tegra20-pmc";
reg = <0x7000e400 0x400>;
+ clocks = <&tegra_car 110>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
};
memory-controller at 7000f000 {
diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts
index 0a2cd24..c3e0f25 100644
--- a/arch/arm/boot/dts/tegra30-beaver.dts
+++ b/arch/arm/boot/dts/tegra30-beaver.dts
@@ -10,6 +10,19 @@
reg = <0x80000000 0x80000000>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
pinmux {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
index 11204e1..eeea511 100644
--- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -31,6 +31,19 @@
reg = <0x80000000 0x40000000>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
pinmux {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 6042cc1..15ded60 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -428,6 +428,8 @@
pmc {
compatible = "nvidia,tegra30-pmc";
reg = <0x7000e400 0x400>;
+ clocks = <&tegra_car 218>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
};
memory-controller {
--
1.8.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V3 2/3] ARM: dts: tegra: add clock source for PMC
2013-04-02 11:19 ` [PATCH V3 2/3] ARM: dts: tegra: add clock source for PMC Joseph Lo
@ 2013-04-02 19:36 ` Stephen Warren
0 siblings, 0 replies; 8+ messages in thread
From: Stephen Warren @ 2013-04-02 19:36 UTC (permalink / raw)
To: linux-arm-kernel
On 04/02/2013 05:19 AM, Joseph Lo wrote:
> Adding the clock sources of PMC into DTS for Tegra20 and Tegra30.
Why only Tegra20 and Tegra30; don't you need to make the exact same
changes to tegra114-dalmore.dts and tegra114-pluto.dts? (I think the
answer is yes, you do).
> diff --git a/arch/arm/boot/dts/tegra20-colibri-512.dtsi b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
> index cb73e62..4c107e6 100644
> --- a/arch/arm/boot/dts/tegra20-colibri-512.dtsi
> +++ b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
> @@ -8,6 +8,19 @@
> reg = <0x00000000 0x20000000>;
> };
>
> + clocks {
...
> + };
> +
> host1x {
The node order is wrong here. The order should be:
1) Any nodes that existed in any included file, in the same order as
they existed in the included file.
2) Any new nodes that have a reg property, sorted by reg property.
3) Any new nodes without a reg property, sorted alpha-numerically by
node name.
So in this file for example, the new nod should exist between
sdhci at c8000600 and sound.
This same comment applies to every file in this patch.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH V3 3/3] ARM: tegra: moving the CPU power timer function to PMC driver
2013-04-02 11:19 [PATCH V3 0/3] ARM: tegra: add clock source for PMC Joseph Lo
2013-04-02 11:19 ` [PATCH V3 1/3] ARM: tegra: get PMC clock source from DT Joseph Lo
2013-04-02 11:19 ` [PATCH V3 2/3] ARM: dts: tegra: add clock source for PMC Joseph Lo
@ 2013-04-02 11:19 ` Joseph Lo
2013-04-02 19:37 ` Stephen Warren
2013-04-02 19:42 ` Stephen Warren
2 siblings, 2 replies; 8+ messages in thread
From: Joseph Lo @ 2013-04-02 11:19 UTC (permalink / raw)
To: linux-arm-kernel
The CPU power timer set up fucntion was related to PMC register. Now moving
it to PMC driver. And it also help to clean up the PM related code later.
Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
V3:
* no change
V2:
* the PCLK is from DT not hard code
---
arch/arm/mach-tegra/pm.c | 37 +------------------------------------
arch/arm/mach-tegra/pmc.c | 32 ++++++++++++++++++++++++++++++++
arch/arm/mach-tegra/pmc.h | 4 ++++
3 files changed, 37 insertions(+), 36 deletions(-)
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index acacbe8..ef12c0d 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -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>
@@ -37,52 +36,18 @@
#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
*
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index dbe2577..8abf02f 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -28,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
@@ -135,6 +138,35 @@ 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" },
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
index 7d44710..22f16c9 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
+#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);
--
1.8.2
^ permalink raw reply related [flat|nested] 8+ messages in thread