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 --- |