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. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include <linux/kernel.h> 20 #include <linux/spinlock.h> 21 #include <linux/io.h> 22 #include <linux/cpumask.h> 23 #include <linux/delay.h> 24 #include <linux/cpu_pm.h> 25 #include <linux/suspend.h> 26 #include <linux/err.h> 27 #include <linux/clk/tegra.h> 28 29 #include <asm/smp_plat.h> 30 #include <asm/cacheflush.h> 31 #include <asm/suspend.h> 32 #include <asm/idmap.h> 33 #include <asm/proc-fns.h> 34 #include <asm/tlbflush.h> 35 36 #include "iomap.h" 37 #include "reset.h" 38 #include "flowctrl.h" 39 #include "fuse.h" 40 #include "pm.h" 41 #include "pmc.h" 42 #include "sleep.h" 43 44 #ifdef CONFIG_PM_SLEEP 45 static DEFINE_SPINLOCK(tegra_lp2_lock); 46 static u32 iram_save_size; 47 static void *iram_save_addr; 48 struct tegra_lp1_iram tegra_lp1_iram; 49 void (*tegra_tear_down_cpu)(void); 50 void (*tegra_sleep_core_finish)(unsigned long v2p); 51 static int (*tegra_sleep_func)(unsigned long v2p); 52 53 static void tegra_tear_down_cpu_init(void) 54 { 55 switch (tegra_chip_id) { 56 case TEGRA20: 57 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 58 tegra_tear_down_cpu = tegra20_tear_down_cpu; 59 break; 60 case TEGRA30: 61 case TEGRA114: 62 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) || 63 IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC)) 64 tegra_tear_down_cpu = tegra30_tear_down_cpu; 65 break; 66 } 67 } 68 69 /* 70 * restore_cpu_complex 71 * 72 * restores cpu clock setting, clears flow controller 73 * 74 * Always called on CPU 0. 75 */ 76 static void restore_cpu_complex(void) 77 { 78 int cpu = smp_processor_id(); 79 80 BUG_ON(cpu != 0); 81 82 #ifdef CONFIG_SMP 83 cpu = cpu_logical_map(cpu); 84 #endif 85 86 /* Restore the CPU clock settings */ 87 tegra_cpu_clock_resume(); 88 89 flowctrl_cpu_suspend_exit(cpu); 90 } 91 92 /* 93 * suspend_cpu_complex 94 * 95 * saves pll state for use by restart_plls, prepares flow controller for 96 * transition to suspend state 97 * 98 * Must always be called on cpu 0. 99 */ 100 static void suspend_cpu_complex(void) 101 { 102 int cpu = smp_processor_id(); 103 104 BUG_ON(cpu != 0); 105 106 #ifdef CONFIG_SMP 107 cpu = cpu_logical_map(cpu); 108 #endif 109 110 /* Save the CPU clock settings */ 111 tegra_cpu_clock_suspend(); 112 113 flowctrl_cpu_suspend_enter(cpu); 114 } 115 116 void tegra_clear_cpu_in_lp2(void) 117 { 118 int phy_cpu_id = cpu_logical_map(smp_processor_id()); 119 u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; 120 121 spin_lock(&tegra_lp2_lock); 122 123 BUG_ON(!(*cpu_in_lp2 & BIT(phy_cpu_id))); 124 *cpu_in_lp2 &= ~BIT(phy_cpu_id); 125 126 spin_unlock(&tegra_lp2_lock); 127 } 128 129 bool tegra_set_cpu_in_lp2(void) 130 { 131 int phy_cpu_id = cpu_logical_map(smp_processor_id()); 132 bool last_cpu = false; 133 cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask; 134 u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; 135 136 spin_lock(&tegra_lp2_lock); 137 138 BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id))); 139 *cpu_in_lp2 |= BIT(phy_cpu_id); 140 141 if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask)) 142 last_cpu = true; 143 else if (tegra_chip_id == TEGRA20 && phy_cpu_id == 1) 144 tegra20_cpu_set_resettable_soon(); 145 146 spin_unlock(&tegra_lp2_lock); 147 return last_cpu; 148 } 149 150 int tegra_cpu_do_idle(void) 151 { 152 return cpu_do_idle(); 153 } 154 155 static int tegra_sleep_cpu(unsigned long v2p) 156 { 157 setup_mm_for_reboot(); 158 tegra_sleep_cpu_finish(v2p); 159 160 /* should never here */ 161 BUG(); 162 163 return 0; 164 } 165 166 void tegra_idle_lp2_last(void) 167 { 168 tegra_pmc_pm_set(TEGRA_SUSPEND_LP2); 169 170 cpu_cluster_pm_enter(); 171 suspend_cpu_complex(); 172 173 cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu); 174 175 restore_cpu_complex(); 176 cpu_cluster_pm_exit(); 177 } 178 179 enum tegra_suspend_mode tegra_pm_validate_suspend_mode( 180 enum tegra_suspend_mode mode) 181 { 182 /* 183 * The Tegra devices support suspending to LP1 or lower currently. 184 */ 185 if (mode > TEGRA_SUSPEND_LP1) 186 return TEGRA_SUSPEND_LP1; 187 188 return mode; 189 } 190 191 static int tegra_sleep_core(unsigned long v2p) 192 { 193 setup_mm_for_reboot(); 194 tegra_sleep_core_finish(v2p); 195 196 /* should never here */ 197 BUG(); 198 199 return 0; 200 } 201 202 /* 203 * tegra_lp1_iram_hook 204 * 205 * Hooking the address of LP1 reset vector and SDRAM self-refresh code in 206 * SDRAM. These codes not be copied to IRAM in this fuction. We need to 207 * copy these code to IRAM before LP0/LP1 suspend and restore the content 208 * of IRAM after resume. 209 */ 210 static bool tegra_lp1_iram_hook(void) 211 { 212 switch (tegra_chip_id) { 213 case TEGRA20: 214 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 215 tegra20_lp1_iram_hook(); 216 break; 217 case TEGRA30: 218 case TEGRA114: 219 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) || 220 IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC)) 221 tegra30_lp1_iram_hook(); 222 break; 223 default: 224 break; 225 } 226 227 if (!tegra_lp1_iram.start_addr || !tegra_lp1_iram.end_addr) 228 return false; 229 230 iram_save_size = tegra_lp1_iram.end_addr - tegra_lp1_iram.start_addr; 231 iram_save_addr = kmalloc(iram_save_size, GFP_KERNEL); 232 if (!iram_save_addr) 233 return false; 234 235 return true; 236 } 237 238 static bool tegra_sleep_core_init(void) 239 { 240 switch (tegra_chip_id) { 241 case TEGRA20: 242 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 243 tegra20_sleep_core_init(); 244 break; 245 case TEGRA30: 246 case TEGRA114: 247 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) || 248 IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC)) 249 tegra30_sleep_core_init(); 250 break; 251 default: 252 break; 253 } 254 255 if (!tegra_sleep_core_finish) 256 return false; 257 258 return true; 259 } 260 261 static void tegra_suspend_enter_lp1(void) 262 { 263 tegra_pmc_suspend(); 264 265 /* copy the reset vector & SDRAM shutdown code into IRAM */ 266 memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_CODE_AREA), 267 iram_save_size); 268 memcpy(IO_ADDRESS(TEGRA_IRAM_CODE_AREA), tegra_lp1_iram.start_addr, 269 iram_save_size); 270 271 *((u32 *)tegra_cpu_lp1_mask) = 1; 272 } 273 274 static void tegra_suspend_exit_lp1(void) 275 { 276 tegra_pmc_resume(); 277 278 /* restore IRAM */ 279 memcpy(IO_ADDRESS(TEGRA_IRAM_CODE_AREA), iram_save_addr, 280 iram_save_size); 281 282 *(u32 *)tegra_cpu_lp1_mask = 0; 283 } 284 285 static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = { 286 [TEGRA_SUSPEND_NONE] = "none", 287 [TEGRA_SUSPEND_LP2] = "LP2", 288 [TEGRA_SUSPEND_LP1] = "LP1", 289 [TEGRA_SUSPEND_LP0] = "LP0", 290 }; 291 292 static int tegra_suspend_enter(suspend_state_t state) 293 { 294 enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode(); 295 296 if (WARN_ON(mode < TEGRA_SUSPEND_NONE || 297 mode >= TEGRA_MAX_SUSPEND_MODE)) 298 return -EINVAL; 299 300 pr_info("Entering suspend state %s\n", lp_state[mode]); 301 302 tegra_pmc_pm_set(mode); 303 304 local_fiq_disable(); 305 306 suspend_cpu_complex(); 307 switch (mode) { 308 case TEGRA_SUSPEND_LP1: 309 tegra_suspend_enter_lp1(); 310 break; 311 case TEGRA_SUSPEND_LP2: 312 tegra_set_cpu_in_lp2(); 313 break; 314 default: 315 break; 316 } 317 318 cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, tegra_sleep_func); 319 320 switch (mode) { 321 case TEGRA_SUSPEND_LP1: 322 tegra_suspend_exit_lp1(); 323 break; 324 case TEGRA_SUSPEND_LP2: 325 tegra_clear_cpu_in_lp2(); 326 break; 327 default: 328 break; 329 } 330 restore_cpu_complex(); 331 332 local_fiq_enable(); 333 334 return 0; 335 } 336 337 static const struct platform_suspend_ops tegra_suspend_ops = { 338 .valid = suspend_valid_only_mem, 339 .enter = tegra_suspend_enter, 340 }; 341 342 void __init tegra_init_suspend(void) 343 { 344 enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode(); 345 346 if (mode == TEGRA_SUSPEND_NONE) 347 return; 348 349 tegra_tear_down_cpu_init(); 350 tegra_pmc_suspend_init(); 351 352 if (mode >= TEGRA_SUSPEND_LP1) { 353 if (!tegra_lp1_iram_hook() || !tegra_sleep_core_init()) { 354 pr_err("%s: unable to allocate memory for SDRAM" 355 "self-refresh -- LP0/LP1 unavailable\n", 356 __func__); 357 tegra_pmc_set_suspend_mode(TEGRA_SUSPEND_LP2); 358 mode = TEGRA_SUSPEND_LP2; 359 } 360 } 361 362 /* set up sleep function for cpu_suspend */ 363 switch (mode) { 364 case TEGRA_SUSPEND_LP1: 365 tegra_sleep_func = tegra_sleep_core; 366 break; 367 case TEGRA_SUSPEND_LP2: 368 tegra_sleep_func = tegra_sleep_cpu; 369 break; 370 default: 371 break; 372 } 373 374 suspend_set_ops(&tegra_suspend_ops); 375 } 376 #endif 377