staticvoid tegra_tear_down_cpu_init(void)
{ switch (tegra_get_chip_id()) { case TEGRA20: if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
tegra_tear_down_cpu = tegra20_tear_down_cpu; break; case TEGRA30: case TEGRA114: case TEGRA124: if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
tegra_tear_down_cpu = tegra30_tear_down_cpu; break;
}
}
/* * restore_cpu_complex * * restores cpu clock setting, clears flow controller * * Always called on CPU 0.
*/ staticvoid restore_cpu_complex(void)
{ int cpu = smp_processor_id();
BUG_ON(cpu != 0);
#ifdef CONFIG_SMP
cpu = cpu_logical_map(cpu); #endif
/* Restore the CPU clock settings */
tegra_cpu_clock_resume();
flowctrl_cpu_suspend_exit(cpu);
}
/* * suspend_cpu_complex * * saves pll state for use by restart_plls, prepares flow controller for * transition to suspend state * * Must always be called on cpu 0.
*/ staticvoid suspend_cpu_complex(void)
{ int cpu = smp_processor_id();
BUG_ON(cpu != 0);
#ifdef CONFIG_SMP
cpu = cpu_logical_map(cpu); #endif
/* Save the CPU clock settings */
tegra_cpu_clock_suspend();
staticint tegra_sleep_cpu(unsignedlong v2p)
{ if (tegra_cpu_car_ops->rail_off_ready &&
WARN_ON(!tegra_cpu_rail_off_ready())) return -EBUSY;
/* * L2 cache disabling using kernel API only allowed when all * secondary CPU's are offline. Cache have to be disabled with * MMU-on if cache maintenance is done via Trusted Foundations * firmware. Note that CPUIDLE won't ever enter powergate on Tegra30 * if any of secondary CPU's is online and this is the LP2-idle * code-path only for Tegra20/30.
*/ #ifdef CONFIG_OUTER_CACHE if (trusted_foundations_registered() && outer_cache.disable)
outer_cache.disable(); #endif /* * Note that besides of setting up CPU reset vector this firmware * call may also do the following, depending on the FW version: * 1) Disable L2. But this doesn't matter since we already * disabled the L2. * 2) Disable D-cache. This need to be taken into account in * particular by the tegra_disable_clean_inv_dcache() which * shall avoid the re-disable.
*/
call_firmware_op(prepare_idle, TF_PM_MODE_LP2);
switch (tegra_get_chip_id()) { case TEGRA20: case TEGRA30: break; default: /* Turn off CRAIL */
value = flowctrl_read_cpu_csr(0);
value &= ~FLOW_CTRL_CSR_ENABLE_EXT_MASK;
value |= FLOW_CTRL_CSR_ENABLE_EXT_CRAIL;
flowctrl_write_cpu_csr(0, value); break;
}
/* * Resume L2 cache if it wasn't re-enabled early during resume, * which is the case for Tegra30 that has to re-enable the cache * via firmware call. In other cases cache is already enabled and * hence re-enabling is a no-op. This is always a no-op on Tegra114+.
*/
outer_resume();
restore_cpu_complex();
cpu_cluster_pm_exit();
call_firmware_op(prepare_idle, TF_PM_MODE_NONE);
return err;
}
enum tegra_suspend_mode tegra_pm_validate_suspend_mode( enum tegra_suspend_mode mode)
{ /* * The Tegra devices support suspending to LP1 or lower currently.
*/ if (mode > TEGRA_SUSPEND_LP1) return TEGRA_SUSPEND_LP1;
return mode;
}
staticint tegra_sleep_core(unsignedlong v2p)
{ /* * Cache have to be disabled with MMU-on if cache maintenance is done * via Trusted Foundations firmware. This is a no-op on Tegra114+.
*/ if (trusted_foundations_registered())
outer_disable();
/* * tegra_lp1_iram_hook * * Hooking the address of LP1 reset vector and SDRAM self-refresh code in * SDRAM. These codes not be copied to IRAM in this fuction. We need to * copy these code to IRAM before LP0/LP1 suspend and restore the content * of IRAM after resume.
*/ staticbool tegra_lp1_iram_hook(void)
{ switch (tegra_get_chip_id()) { case TEGRA20: if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
tegra20_lp1_iram_hook(); break; case TEGRA30: case TEGRA114: case TEGRA124: if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
tegra30_lp1_iram_hook(); break; default: break;
}
if (!tegra_lp1_iram.start_addr || !tegra_lp1_iram.end_addr) returnfalse;
staticbool tegra_sleep_core_init(void)
{ switch (tegra_get_chip_id()) { case TEGRA20: if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
tegra20_sleep_core_init(); break; case TEGRA30: case TEGRA114: case TEGRA124: if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
tegra30_sleep_core_init(); break; default: break;
}
/* * Resume L2 cache if it wasn't re-enabled early during resume, * which is the case for Tegra30 that has to re-enable the cache * via firmware call. In other cases cache is already enabled and * hence re-enabling is a no-op.
*/
outer_resume();
switch (mode) { case TEGRA_SUSPEND_LP1:
tegra_suspend_exit_lp1(); break; case TEGRA_SUSPEND_LP2:
tegra_pm_clear_cpu_in_lp2(); break; default: break;
}
restore_cpu_complex();
if (mode >= TEGRA_SUSPEND_LP1) { if (!tegra_lp1_iram_hook() || !tegra_sleep_core_init()) {
pr_err("%s: unable to allocate memory for SDRAM" "self-refresh -- LP0/LP1 unavailable\n",
__func__);
tegra_pmc_set_suspend_mode(TEGRA_SUSPEND_LP2);
mode = TEGRA_SUSPEND_LP2;
}
}
/* set up sleep function for cpu_suspend */ switch (mode) { case TEGRA_SUSPEND_LP1:
tegra_sleep_func = tegra_sleep_core; break; case TEGRA_SUSPEND_LP2:
tegra_sleep_func = tegra_sleep_cpu; break; default: break;
}
suspend_set_ops(&tegra_suspend_ops);
}
int tegra_pm_park_secondary_cpu(unsignedlong cpu)
{ if (cpu > 0) {
tegra_disable_clean_inv_dcache(TEGRA_FLUSH_CACHE_LOUIS);
if (tegra_get_chip_id() == TEGRA20)
tegra20_hotplug_shutdown(); else
tegra30_hotplug_shutdown();
}
return -EINVAL;
} #endif
Messung V0.5
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.