pm.c (dd849e581d7d23e1729c23bb2d6b85360ce4dd9d) pm.c (7232398abc6a7186e315425638c367d50c674718)
1/*
2 * CPU complex suspend & resume functions for Tegra SoCs
3 *
4 * Copyright (c) 2009-2012, NVIDIA Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.

--- 14 unchanged lines hidden (view full) ---

23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/spinlock.h>
28#include <linux/suspend.h>
29
30#include <soc/tegra/fuse.h>
1/*
2 * CPU complex suspend & resume functions for Tegra SoCs
3 *
4 * Copyright (c) 2009-2012, NVIDIA Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.

--- 14 unchanged lines hidden (view full) ---

23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/spinlock.h>
28#include <linux/suspend.h>
29
30#include <soc/tegra/fuse.h>
31#include <soc/tegra/pm.h>
32#include <soc/tegra/pmc.h>
31
32#include <asm/cacheflush.h>
33#include <asm/idmap.h>
34#include <asm/proc-fns.h>
35#include <asm/smp_plat.h>
36#include <asm/suspend.h>
37#include <asm/tlbflush.h>
38
39#include "flowctrl.h"
40#include "iomap.h"
33
34#include <asm/cacheflush.h>
35#include <asm/idmap.h>
36#include <asm/proc-fns.h>
37#include <asm/smp_plat.h>
38#include <asm/suspend.h>
39#include <asm/tlbflush.h>
40
41#include "flowctrl.h"
42#include "iomap.h"
41#include "pmc.h"
42#include "pm.h"
43#include "reset.h"
44#include "sleep.h"
45
46#ifdef CONFIG_PM_SLEEP
47static DEFINE_SPINLOCK(tegra_lp2_lock);
48static u32 iram_save_size;
49static void *iram_save_addr;

--- 112 unchanged lines hidden (view full) ---

162 tegra_sleep_cpu_finish(v2p);
163
164 /* should never here */
165 BUG();
166
167 return 0;
168}
169
43#include "pm.h"
44#include "reset.h"
45#include "sleep.h"
46
47#ifdef CONFIG_PM_SLEEP
48static DEFINE_SPINLOCK(tegra_lp2_lock);
49static u32 iram_save_size;
50static void *iram_save_addr;

--- 112 unchanged lines hidden (view full) ---

163 tegra_sleep_cpu_finish(v2p);
164
165 /* should never here */
166 BUG();
167
168 return 0;
169}
170
171static void tegra_pm_set(enum tegra_suspend_mode mode)
172{
173 u32 value;
174
175 switch (tegra_get_chip_id()) {
176 case TEGRA20:
177 case TEGRA30:
178 break;
179 default:
180 /* Turn off CRAIL */
181 value = flowctrl_read_cpu_csr(0);
182 value &= ~FLOW_CTRL_CSR_ENABLE_EXT_MASK;
183 value |= FLOW_CTRL_CSR_ENABLE_EXT_CRAIL;
184 flowctrl_write_cpu_csr(0, value);
185 break;
186 }
187
188 tegra_pmc_enter_suspend_mode(mode);
189}
190
170void tegra_idle_lp2_last(void)
171{
191void tegra_idle_lp2_last(void)
192{
172 tegra_pmc_pm_set(TEGRA_SUSPEND_LP2);
193 tegra_pm_set(TEGRA_SUSPEND_LP2);
173
174 cpu_cluster_pm_enter();
175 suspend_cpu_complex();
176
177 cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
178
179 restore_cpu_complex();
180 cpu_cluster_pm_exit();

--- 82 unchanged lines hidden (view full) ---

263 if (!tegra_sleep_core_finish)
264 return false;
265
266 return true;
267}
268
269static void tegra_suspend_enter_lp1(void)
270{
194
195 cpu_cluster_pm_enter();
196 suspend_cpu_complex();
197
198 cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
199
200 restore_cpu_complex();
201 cpu_cluster_pm_exit();

--- 82 unchanged lines hidden (view full) ---

284 if (!tegra_sleep_core_finish)
285 return false;
286
287 return true;
288}
289
290static void tegra_suspend_enter_lp1(void)
291{
271 tegra_pmc_suspend();
272
273 /* copy the reset vector & SDRAM shutdown code into IRAM */
274 memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA),
275 iram_save_size);
276 memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA),
277 tegra_lp1_iram.start_addr, iram_save_size);
278
279 *((u32 *)tegra_cpu_lp1_mask) = 1;
280}
281
282static void tegra_suspend_exit_lp1(void)
283{
292 /* copy the reset vector & SDRAM shutdown code into IRAM */
293 memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA),
294 iram_save_size);
295 memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA),
296 tegra_lp1_iram.start_addr, iram_save_size);
297
298 *((u32 *)tegra_cpu_lp1_mask) = 1;
299}
300
301static void tegra_suspend_exit_lp1(void)
302{
284 tegra_pmc_resume();
285
286 /* restore IRAM */
287 memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA), iram_save_addr,
288 iram_save_size);
289
290 *(u32 *)tegra_cpu_lp1_mask = 0;
291}
292
293static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = {

--- 8 unchanged lines hidden (view full) ---

302 enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
303
304 if (WARN_ON(mode < TEGRA_SUSPEND_NONE ||
305 mode >= TEGRA_MAX_SUSPEND_MODE))
306 return -EINVAL;
307
308 pr_info("Entering suspend state %s\n", lp_state[mode]);
309
303 /* restore IRAM */
304 memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA), iram_save_addr,
305 iram_save_size);
306
307 *(u32 *)tegra_cpu_lp1_mask = 0;
308}
309
310static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = {

--- 8 unchanged lines hidden (view full) ---

319 enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
320
321 if (WARN_ON(mode < TEGRA_SUSPEND_NONE ||
322 mode >= TEGRA_MAX_SUSPEND_MODE))
323 return -EINVAL;
324
325 pr_info("Entering suspend state %s\n", lp_state[mode]);
326
310 tegra_pmc_pm_set(mode);
327 tegra_pm_set(mode);
311
312 local_fiq_disable();
313
314 suspend_cpu_complex();
315 switch (mode) {
316 case TEGRA_SUSPEND_LP1:
317 tegra_suspend_enter_lp1();
318 break;

--- 31 unchanged lines hidden (view full) ---

350void __init tegra_init_suspend(void)
351{
352 enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
353
354 if (mode == TEGRA_SUSPEND_NONE)
355 return;
356
357 tegra_tear_down_cpu_init();
328
329 local_fiq_disable();
330
331 suspend_cpu_complex();
332 switch (mode) {
333 case TEGRA_SUSPEND_LP1:
334 tegra_suspend_enter_lp1();
335 break;

--- 31 unchanged lines hidden (view full) ---

367void __init tegra_init_suspend(void)
368{
369 enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
370
371 if (mode == TEGRA_SUSPEND_NONE)
372 return;
373
374 tegra_tear_down_cpu_init();
358 tegra_pmc_suspend_init();
359
360 if (mode >= TEGRA_SUSPEND_LP1) {
361 if (!tegra_lp1_iram_hook() || !tegra_sleep_core_init()) {
362 pr_err("%s: unable to allocate memory for SDRAM"
363 "self-refresh -- LP0/LP1 unavailable\n",
364 __func__);
365 tegra_pmc_set_suspend_mode(TEGRA_SUSPEND_LP2);
366 mode = TEGRA_SUSPEND_LP2;

--- 18 unchanged lines hidden ---
375
376 if (mode >= TEGRA_SUSPEND_LP1) {
377 if (!tegra_lp1_iram_hook() || !tegra_sleep_core_init()) {
378 pr_err("%s: unable to allocate memory for SDRAM"
379 "self-refresh -- LP0/LP1 unavailable\n",
380 __func__);
381 tegra_pmc_set_suspend_mode(TEGRA_SUSPEND_LP2);
382 mode = TEGRA_SUSPEND_LP2;

--- 18 unchanged lines hidden ---