aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/pmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/pmc.c')
-rw-r--r--arch/arm/mach-tegra/pmc.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index faa33e8f937d..e896826d7d0f 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -21,6 +21,8 @@
21#include <linux/of.h> 21#include <linux/of.h>
22#include <linux/of_address.h> 22#include <linux/of_address.h>
23 23
24#include "pmc.h"
25
24#define PMC_CTRL 0x0 26#define PMC_CTRL 0x0
25#define PMC_CTRL_INTR_LOW (1 << 17) 27#define PMC_CTRL_INTR_LOW (1 << 17)
26#define PMC_PWRGATE_TOGGLE 0x30 28#define PMC_PWRGATE_TOGGLE 0x30
@@ -49,6 +51,22 @@ static void __iomem *tegra_pmc_base;
49static bool tegra_pmc_invert_interrupt; 51static bool tegra_pmc_invert_interrupt;
50static struct clk *tegra_pclk; 52static struct clk *tegra_pclk;
51 53
54struct pmc_pm_data {
55 u32 cpu_good_time; /* CPU power good time in uS */
56 u32 cpu_off_time; /* CPU power off time in uS */
57 u32 core_osc_time; /* Core power good osc time in uS */
58 u32 core_pmu_time; /* Core power good pmu time in uS */
59 u32 core_off_time; /* Core power off time in uS */
60 bool corereq_high; /* Core power request active-high */
61 bool sysclkreq_high; /* System clock request active-high */
62 bool combined_req; /* Combined pwr req for CPU & Core */
63 bool cpu_pwr_good_en; /* CPU power good signal is enabled */
64 u32 lp0_vec_phy_addr; /* The phy addr of LP0 warm boot code */
65 u32 lp0_vec_size; /* The size of LP0 warm boot code */
66 enum tegra_suspend_mode suspend_mode;
67};
68static struct pmc_pm_data pmc_pm_data;
69
52static inline u32 tegra_pmc_readl(u32 reg) 70static inline u32 tegra_pmc_readl(u32 reg)
53{ 71{
54 return readl(tegra_pmc_base + reg); 72 return readl(tegra_pmc_base + reg);
@@ -176,6 +194,10 @@ static const struct of_device_id matches[] __initconst = {
176static void tegra_pmc_parse_dt(void) 194static void tegra_pmc_parse_dt(void)
177{ 195{
178 struct device_node *np; 196 struct device_node *np;
197 u32 prop;
198 enum tegra_suspend_mode suspend_mode;
199 u32 core_good_time[2] = {0, 0};
200 u32 lp0_vec[2] = {0, 0};
179 201
180 np = of_find_matching_node(NULL, matches); 202 np = of_find_matching_node(NULL, matches);
181 BUG_ON(!np); 203 BUG_ON(!np);
@@ -186,6 +208,67 @@ static void tegra_pmc_parse_dt(void)
186 "nvidia,invert-interrupt"); 208 "nvidia,invert-interrupt");
187 tegra_pclk = of_clk_get_by_name(np, "pclk"); 209 tegra_pclk = of_clk_get_by_name(np, "pclk");
188 WARN_ON(IS_ERR(tegra_pclk)); 210 WARN_ON(IS_ERR(tegra_pclk));
211
212 /* Grabbing the power management configurations */
213 if (of_property_read_u32(np, "nvidia,suspend-mode", &prop)) {
214 suspend_mode = TEGRA_SUSPEND_NONE;
215 } else {
216 switch (prop) {
217 case 0:
218 suspend_mode = TEGRA_SUSPEND_LP0;
219 break;
220 case 1:
221 suspend_mode = TEGRA_SUSPEND_LP1;
222 break;
223 case 2:
224 suspend_mode = TEGRA_SUSPEND_LP2;
225 break;
226 default:
227 suspend_mode = TEGRA_SUSPEND_NONE;
228 break;
229 }
230 }
231
232 if (of_property_read_u32(np, "nvidia,cpu-pwr-good-time", &prop))
233 suspend_mode = TEGRA_SUSPEND_NONE;
234 pmc_pm_data.cpu_good_time = prop;
235
236 if (of_property_read_u32(np, "nvidia,cpu-pwr-off-time", &prop))
237 suspend_mode = TEGRA_SUSPEND_NONE;
238 pmc_pm_data.cpu_off_time = prop;
239
240 if (of_property_read_u32_array(np, "nvidia,core-pwr-good-time",
241 core_good_time, ARRAY_SIZE(core_good_time)))
242 suspend_mode = TEGRA_SUSPEND_NONE;
243 pmc_pm_data.core_osc_time = core_good_time[0];
244 pmc_pm_data.core_pmu_time = core_good_time[1];
245
246 if (of_property_read_u32(np, "nvidia,core-pwr-off-time",
247 &prop))
248 suspend_mode = TEGRA_SUSPEND_NONE;
249 pmc_pm_data.core_off_time = prop;
250
251 pmc_pm_data.corereq_high = of_property_read_bool(np,
252 "nvidia,core-power-req-active-high");
253
254 pmc_pm_data.sysclkreq_high = of_property_read_bool(np,
255 "nvidia,sys-clock-req-active-high");
256
257 pmc_pm_data.combined_req = of_property_read_bool(np,
258 "nvidia,combined-power-req");
259
260 pmc_pm_data.cpu_pwr_good_en = of_property_read_bool(np,
261 "nvidia,cpu-pwr-good-en");
262
263 if (of_property_read_u32_array(np, "nvidia,lp0-vec", lp0_vec,
264 ARRAY_SIZE(lp0_vec)))
265 if (suspend_mode == TEGRA_SUSPEND_LP0)
266 suspend_mode = TEGRA_SUSPEND_LP1;
267
268 pmc_pm_data.lp0_vec_phy_addr = lp0_vec[0];
269 pmc_pm_data.lp0_vec_size = lp0_vec[1];
270
271 pmc_pm_data.suspend_mode = suspend_mode;
189} 272}
190 273
191void __init tegra_pmc_init(void) 274void __init tegra_pmc_init(void)