forked from luck/tmp_suning_uos_patched
ARM: tegra: Core changes for v5.7-rc1
These patches a preparatory work to move the CPU idle drivers into drivers/cpuidle. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEiOrDCAFJzPfAjcif3SOs138+s6EFAl5rtDcTHHRyZWRpbmdA bnZpZGlhLmNvbQAKCRDdI6zXfz6zoYSRD/98HactRMwJb41LlLpaUeNT/xTQk/DB k+Y0NkeiT34QE7c+UcSeDXecnipuajB3kB7kd64lSS0DI0V+KZam1qZUsMTqG7D3 ZLvzIJXykoGf19QC89nN7TnRy/jjRO8ITk/dFjj1BwSP0M1WuWlQAHNXczRyEP77 OLvViPH8YzLkDe2TH8AhbF/zCCnmW9lqCE8oJuQMdMmQo3qOLL6c/CZcxkzo3iVn rUu1uIgNXiY5fBTgl1woP7mSHgYytjAm4WouSpJRoPAodKqlaI61rb7gwbrav+rQ 2kkORNxOr5Eo36wszxxzknY18PCCjbZtNFrZyAGdmu0IePDdxMiWG2z+30OGESam qlzia0Yz82pSBBRgxVO03oTpZGh9jxdHoubIRR3UGVAttD8rdC4xjIkxjv+FbPp/ A0yVKqA5GFpftUKOKFoC056nByfH2UE1XrPoPWKuu9+ED5vKh7tC4cMEJhhUOA6N 6+pqE8FsZ0NTjxT7pvrPtvTI9lCVy8UTTWQomnd1HMxT2tJEijq1mTVPrsZISYQq +DDsww1UpblslFQwZMoGp8D9IXF3VdvmQae/0ko63XUYDw2Nz4gP7yw+mQoDoALP M9W3FE2XK3u0NsCV76nG1yjJ6CtHgMnZx+DM4VwNZ5m29XUvmdwVwcsv2lrP0TES HWpsPD3vQdatug== =nOBN -----END PGP SIGNATURE----- Merge tag 'tegra-for-5.7-arm-core' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into arm/soc ARM: tegra: Core changes for v5.7-rc1 These patches a preparatory work to move the CPU idle drivers into drivers/cpuidle. * tag 'tegra-for-5.7-arm-core' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: ARM: tegra: cpuidle: Remove unnecessary memory barrier ARM: tegra: cpuidle: Make abort_flag atomic ARM: tegra: cpuidle: Handle case where secondary CPU hangs on entering LP2 ARM: tegra: Make outer_disable() open-coded ARM: tegra: Rename some of the newly exposed PM functions ARM: tegra: Expose PM functions required for new cpuidle driver ARM: tegra: Propagate error from tegra_idle_lp2_last() ARM: tegra: Change tegra_set_cpu_in_lp2() type to void ARM: tegra: Remove pen-locking from cpuidle-tegra20 ARM: tegra: Add tegra_pm_park_secondary_cpu() ARM: tegra: Compile sleep-tegra20/30.S unconditionally Link: https://lore.kernel.org/r/20200313165848.2915133-5-thierry.reding@gmail.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
10996b2404
|
@ -8,13 +8,13 @@ obj-y += reset.o
|
||||||
obj-y += reset-handler.o
|
obj-y += reset-handler.o
|
||||||
obj-y += sleep.o
|
obj-y += sleep.o
|
||||||
obj-y += tegra.o
|
obj-y += tegra.o
|
||||||
|
obj-y += sleep-tegra20.o
|
||||||
|
obj-y += sleep-tegra30.o
|
||||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
|
|
||||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
|
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
|
||||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o
|
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o
|
||||||
endif
|
endif
|
||||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o
|
|
||||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o
|
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o
|
||||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o
|
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o
|
||||||
|
@ -22,12 +22,10 @@ endif
|
||||||
obj-$(CONFIG_SMP) += platsmp.o
|
obj-$(CONFIG_SMP) += platsmp.o
|
||||||
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||||
|
|
||||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o
|
|
||||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o
|
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o
|
||||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
|
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
|
||||||
endif
|
endif
|
||||||
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += sleep-tegra30.o
|
|
||||||
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += pm-tegra30.o
|
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += pm-tegra30.o
|
||||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||||
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += cpuidle-tegra114.o
|
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += cpuidle-tegra114.o
|
||||||
|
|
|
@ -12,13 +12,14 @@
|
||||||
|
|
||||||
#include <linux/firmware/trusted_foundations.h>
|
#include <linux/firmware/trusted_foundations.h>
|
||||||
|
|
||||||
|
#include <soc/tegra/pm.h>
|
||||||
|
|
||||||
#include <asm/cpuidle.h>
|
#include <asm/cpuidle.h>
|
||||||
#include <asm/smp_plat.h>
|
#include <asm/smp_plat.h>
|
||||||
#include <asm/suspend.h>
|
#include <asm/suspend.h>
|
||||||
#include <asm/psci.h>
|
#include <asm/psci.h>
|
||||||
|
|
||||||
#include "cpuidle.h"
|
#include "cpuidle.h"
|
||||||
#include "pm.h"
|
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
@ -34,17 +35,17 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
|
||||||
{
|
{
|
||||||
local_fiq_disable();
|
local_fiq_disable();
|
||||||
|
|
||||||
tegra_set_cpu_in_lp2();
|
tegra_pm_set_cpu_in_lp2();
|
||||||
cpu_pm_enter();
|
cpu_pm_enter();
|
||||||
|
|
||||||
call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
|
call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
|
||||||
|
|
||||||
/* Do suspend by ourselves if the firmware does not implement it */
|
/* Do suspend by ourselves if the firmware does not implement it */
|
||||||
if (call_firmware_op(do_idle, 0) == -ENOSYS)
|
if (call_firmware_op(do_idle, 0) == -ENOSYS)
|
||||||
cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
|
cpu_suspend(0, tegra30_pm_secondary_cpu_suspend);
|
||||||
|
|
||||||
cpu_pm_exit();
|
cpu_pm_exit();
|
||||||
tegra_clear_cpu_in_lp2();
|
tegra_pm_clear_cpu_in_lp2();
|
||||||
|
|
||||||
local_fiq_enable();
|
local_fiq_enable();
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,13 @@
|
||||||
#include <linux/tick.h>
|
#include <linux/tick.h>
|
||||||
#include <linux/cpuidle.h>
|
#include <linux/cpuidle.h>
|
||||||
#include <linux/cpu_pm.h>
|
#include <linux/cpu_pm.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include <soc/tegra/flowctrl.h>
|
#include <soc/tegra/flowctrl.h>
|
||||||
|
#include <soc/tegra/irq.h>
|
||||||
|
#include <soc/tegra/pm.h>
|
||||||
|
|
||||||
#include <asm/cpuidle.h>
|
#include <asm/cpuidle.h>
|
||||||
#include <asm/smp_plat.h>
|
#include <asm/smp_plat.h>
|
||||||
|
@ -25,13 +28,11 @@
|
||||||
|
|
||||||
#include "cpuidle.h"
|
#include "cpuidle.h"
|
||||||
#include "iomap.h"
|
#include "iomap.h"
|
||||||
#include "irq.h"
|
|
||||||
#include "pm.h"
|
|
||||||
#include "reset.h"
|
#include "reset.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
static bool abort_flag;
|
static atomic_t abort_flag;
|
||||||
static atomic_t abort_barrier;
|
static atomic_t abort_barrier;
|
||||||
static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
|
static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
|
||||||
struct cpuidle_driver *drv,
|
struct cpuidle_driver *drv,
|
||||||
|
@ -65,28 +66,8 @@ static struct cpuidle_driver tegra_idle_driver = {
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static int tegra20_reset_sleeping_cpu_1(void)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
tegra_pen_lock();
|
|
||||||
|
|
||||||
if (readb(tegra20_cpu1_resettable_status) == CPU_RESETTABLE)
|
|
||||||
tegra20_cpu_shutdown(1);
|
|
||||||
else
|
|
||||||
ret = -EINVAL;
|
|
||||||
|
|
||||||
tegra_pen_unlock();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tegra20_wake_cpu1_from_reset(void)
|
static void tegra20_wake_cpu1_from_reset(void)
|
||||||
{
|
{
|
||||||
tegra_pen_lock();
|
|
||||||
|
|
||||||
tegra20_cpu_clear_resettable();
|
|
||||||
|
|
||||||
/* enable cpu clock on cpu */
|
/* enable cpu clock on cpu */
|
||||||
tegra_enable_cpu_clock(1);
|
tegra_enable_cpu_clock(1);
|
||||||
|
|
||||||
|
@ -95,45 +76,74 @@ static void tegra20_wake_cpu1_from_reset(void)
|
||||||
|
|
||||||
/* unhalt the cpu */
|
/* unhalt the cpu */
|
||||||
flowctrl_write_cpu_halt(1, 0);
|
flowctrl_write_cpu_halt(1, 0);
|
||||||
|
|
||||||
tegra_pen_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tegra20_reset_cpu_1(void)
|
|
||||||
{
|
|
||||||
if (!cpu_online(1) || !tegra20_reset_sleeping_cpu_1())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
tegra20_wake_cpu1_from_reset();
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void tegra20_wake_cpu1_from_reset(void)
|
static inline void tegra20_wake_cpu1_from_reset(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int tegra20_reset_cpu_1(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void tegra20_report_cpus_state(void)
|
||||||
|
{
|
||||||
|
unsigned long cpu, lcpu, csr;
|
||||||
|
|
||||||
|
for_each_cpu(lcpu, cpu_possible_mask) {
|
||||||
|
cpu = cpu_logical_map(lcpu);
|
||||||
|
csr = flowctrl_read_cpu_csr(cpu);
|
||||||
|
|
||||||
|
pr_err("cpu%lu: online=%d flowctrl_csr=0x%08lx\n",
|
||||||
|
cpu, cpu_online(lcpu), csr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tegra20_wait_for_secondary_cpu_parking(void)
|
||||||
|
{
|
||||||
|
unsigned int retries = 3;
|
||||||
|
|
||||||
|
while (retries--) {
|
||||||
|
unsigned int delay_us = 10;
|
||||||
|
unsigned int timeout_us = 500 * 1000 / delay_us;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The primary CPU0 core shall wait for the secondaries
|
||||||
|
* shutdown in order to power-off CPU's cluster safely.
|
||||||
|
* The timeout value depends on the current CPU frequency,
|
||||||
|
* it takes about 40-150us in average and over 1000us in
|
||||||
|
* a worst case scenario.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
if (tegra_cpu_rail_off_ready())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
udelay(delay_us);
|
||||||
|
|
||||||
|
} while (timeout_us--);
|
||||||
|
|
||||||
|
pr_err("secondary CPU taking too long to park\n");
|
||||||
|
|
||||||
|
tegra20_report_cpus_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_err("timed out waiting secondaries to park\n");
|
||||||
|
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
|
static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
|
||||||
struct cpuidle_driver *drv,
|
struct cpuidle_driver *drv,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
while (tegra20_cpu_is_resettable_soon())
|
bool ret;
|
||||||
cpu_relax();
|
|
||||||
|
|
||||||
if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready())
|
if (tegra20_wait_for_secondary_cpu_parking())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tegra_idle_lp2_last();
|
ret = !tegra_pm_enter_lp2();
|
||||||
|
|
||||||
if (cpu_online(1))
|
if (cpu_online(1))
|
||||||
tegra20_wake_cpu1_from_reset();
|
tegra20_wake_cpu1_from_reset();
|
||||||
|
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
@ -141,9 +151,7 @@ static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
|
||||||
struct cpuidle_driver *drv,
|
struct cpuidle_driver *drv,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
cpu_suspend(0, tegra20_sleep_cpu_secondary_finish);
|
cpu_suspend(dev->cpu, tegra_pm_park_secondary_cpu);
|
||||||
|
|
||||||
tegra20_cpu_clear_resettable();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -163,19 +171,20 @@ static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
|
||||||
bool entered_lp2 = false;
|
bool entered_lp2 = false;
|
||||||
|
|
||||||
if (tegra_pending_sgi())
|
if (tegra_pending_sgi())
|
||||||
WRITE_ONCE(abort_flag, true);
|
atomic_set(&abort_flag, 1);
|
||||||
|
|
||||||
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
|
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
|
||||||
|
|
||||||
if (abort_flag) {
|
if (atomic_read(&abort_flag)) {
|
||||||
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
|
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
|
||||||
abort_flag = false; /* clean flag for next coming */
|
/* clean flag for next coming */
|
||||||
|
atomic_set(&abort_flag, 0);
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_fiq_disable();
|
local_fiq_disable();
|
||||||
|
|
||||||
tegra_set_cpu_in_lp2();
|
tegra_pm_set_cpu_in_lp2();
|
||||||
cpu_pm_enter();
|
cpu_pm_enter();
|
||||||
|
|
||||||
if (dev->cpu == 0)
|
if (dev->cpu == 0)
|
||||||
|
@ -184,12 +193,10 @@ static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
|
||||||
entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index);
|
entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index);
|
||||||
|
|
||||||
cpu_pm_exit();
|
cpu_pm_exit();
|
||||||
tegra_clear_cpu_in_lp2();
|
tegra_pm_clear_cpu_in_lp2();
|
||||||
|
|
||||||
local_fiq_enable();
|
local_fiq_enable();
|
||||||
|
|
||||||
smp_rmb();
|
|
||||||
|
|
||||||
return entered_lp2 ? index : 0;
|
return entered_lp2 ? index : 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,12 +17,13 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
#include <soc/tegra/pm.h>
|
||||||
|
|
||||||
#include <asm/cpuidle.h>
|
#include <asm/cpuidle.h>
|
||||||
#include <asm/smp_plat.h>
|
#include <asm/smp_plat.h>
|
||||||
#include <asm/suspend.h>
|
#include <asm/suspend.h>
|
||||||
|
|
||||||
#include "cpuidle.h"
|
#include "cpuidle.h"
|
||||||
#include "pm.h"
|
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
@ -68,9 +69,7 @@ static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tegra_idle_lp2_last();
|
return !tegra_pm_enter_lp2();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
@ -80,7 +79,7 @@ static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
|
||||||
{
|
{
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
|
|
||||||
cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
|
cpu_suspend(0, tegra30_pm_secondary_cpu_suspend);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -98,30 +97,22 @@ static int tegra30_idle_lp2(struct cpuidle_device *dev,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
bool entered_lp2 = false;
|
bool entered_lp2 = false;
|
||||||
bool last_cpu;
|
|
||||||
|
|
||||||
local_fiq_disable();
|
local_fiq_disable();
|
||||||
|
|
||||||
last_cpu = tegra_set_cpu_in_lp2();
|
tegra_pm_set_cpu_in_lp2();
|
||||||
cpu_pm_enter();
|
cpu_pm_enter();
|
||||||
|
|
||||||
if (dev->cpu == 0) {
|
if (dev->cpu == 0)
|
||||||
if (last_cpu)
|
entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv, index);
|
||||||
entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv,
|
else
|
||||||
index);
|
|
||||||
else
|
|
||||||
cpu_do_idle();
|
|
||||||
} else {
|
|
||||||
entered_lp2 = tegra30_cpu_core_power_down(dev, drv, index);
|
entered_lp2 = tegra30_cpu_core_power_down(dev, drv, index);
|
||||||
}
|
|
||||||
|
|
||||||
cpu_pm_exit();
|
cpu_pm_exit();
|
||||||
tegra_clear_cpu_in_lp2();
|
tegra_pm_clear_cpu_in_lp2();
|
||||||
|
|
||||||
local_fiq_enable();
|
local_fiq_enable();
|
||||||
|
|
||||||
smp_rmb();
|
|
||||||
|
|
||||||
return (entered_lp2) ? index : 0;
|
return (entered_lp2) ? index : 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,9 +18,10 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/syscore_ops.h>
|
#include <linux/syscore_ops.h>
|
||||||
|
|
||||||
|
#include <soc/tegra/irq.h>
|
||||||
|
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "iomap.h"
|
#include "iomap.h"
|
||||||
#include "irq.h"
|
|
||||||
|
|
||||||
#define SGI_MASK 0xFFFF
|
#define SGI_MASK 0xFFFF
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ static void suspend_cpu_complex(void)
|
||||||
flowctrl_cpu_suspend_enter(cpu);
|
flowctrl_cpu_suspend_enter(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tegra_clear_cpu_in_lp2(void)
|
void tegra_pm_clear_cpu_in_lp2(void)
|
||||||
{
|
{
|
||||||
int phy_cpu_id = cpu_logical_map(smp_processor_id());
|
int phy_cpu_id = cpu_logical_map(smp_processor_id());
|
||||||
u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
|
u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
|
||||||
|
@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void)
|
||||||
spin_unlock(&tegra_lp2_lock);
|
spin_unlock(&tegra_lp2_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tegra_set_cpu_in_lp2(void)
|
void tegra_pm_set_cpu_in_lp2(void)
|
||||||
{
|
{
|
||||||
int phy_cpu_id = cpu_logical_map(smp_processor_id());
|
int phy_cpu_id = cpu_logical_map(smp_processor_id());
|
||||||
bool last_cpu = false;
|
|
||||||
cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
|
|
||||||
u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
|
u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
|
||||||
|
|
||||||
spin_lock(&tegra_lp2_lock);
|
spin_lock(&tegra_lp2_lock);
|
||||||
|
@ -135,22 +133,15 @@ bool tegra_set_cpu_in_lp2(void)
|
||||||
BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
|
BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
|
||||||
*cpu_in_lp2 |= BIT(phy_cpu_id);
|
*cpu_in_lp2 |= BIT(phy_cpu_id);
|
||||||
|
|
||||||
if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
|
|
||||||
last_cpu = true;
|
|
||||||
else if (tegra_get_chip_id() == TEGRA20 && phy_cpu_id == 1)
|
|
||||||
tegra20_cpu_set_resettable_soon();
|
|
||||||
|
|
||||||
spin_unlock(&tegra_lp2_lock);
|
spin_unlock(&tegra_lp2_lock);
|
||||||
return last_cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tegra_cpu_do_idle(void)
|
|
||||||
{
|
|
||||||
return cpu_do_idle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_sleep_cpu(unsigned long v2p)
|
static int tegra_sleep_cpu(unsigned long 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
|
* L2 cache disabling using kernel API only allowed when all
|
||||||
* secondary CPU's are offline. Cache have to be disabled with
|
* secondary CPU's are offline. Cache have to be disabled with
|
||||||
|
@ -159,9 +150,10 @@ static int tegra_sleep_cpu(unsigned long v2p)
|
||||||
* if any of secondary CPU's is online and this is the LP2-idle
|
* if any of secondary CPU's is online and this is the LP2-idle
|
||||||
* code-path only for Tegra20/30.
|
* code-path only for Tegra20/30.
|
||||||
*/
|
*/
|
||||||
if (trusted_foundations_registered())
|
#ifdef CONFIG_OUTER_CACHE
|
||||||
outer_disable();
|
if (trusted_foundations_registered() && outer_cache.disable)
|
||||||
|
outer_cache.disable();
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Note that besides of setting up CPU reset vector this firmware
|
* Note that besides of setting up CPU reset vector this firmware
|
||||||
* call may also do the following, depending on the FW version:
|
* call may also do the following, depending on the FW version:
|
||||||
|
@ -202,14 +194,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
|
||||||
tegra_pmc_enter_suspend_mode(mode);
|
tegra_pmc_enter_suspend_mode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tegra_idle_lp2_last(void)
|
int tegra_pm_enter_lp2(void)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
tegra_pm_set(TEGRA_SUSPEND_LP2);
|
tegra_pm_set(TEGRA_SUSPEND_LP2);
|
||||||
|
|
||||||
cpu_cluster_pm_enter();
|
cpu_cluster_pm_enter();
|
||||||
suspend_cpu_complex();
|
suspend_cpu_complex();
|
||||||
|
|
||||||
cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
|
err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Resume L2 cache if it wasn't re-enabled early during resume,
|
* Resume L2 cache if it wasn't re-enabled early during resume,
|
||||||
|
@ -221,6 +215,8 @@ void tegra_idle_lp2_last(void)
|
||||||
|
|
||||||
restore_cpu_complex();
|
restore_cpu_complex();
|
||||||
cpu_cluster_pm_exit();
|
cpu_cluster_pm_exit();
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
|
enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
|
||||||
|
@ -365,7 +361,7 @@ static int tegra_suspend_enter(suspend_state_t state)
|
||||||
tegra_suspend_enter_lp1();
|
tegra_suspend_enter_lp1();
|
||||||
break;
|
break;
|
||||||
case TEGRA_SUSPEND_LP2:
|
case TEGRA_SUSPEND_LP2:
|
||||||
tegra_set_cpu_in_lp2();
|
tegra_pm_set_cpu_in_lp2();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -386,7 +382,7 @@ static int tegra_suspend_enter(suspend_state_t state)
|
||||||
tegra_suspend_exit_lp1();
|
tegra_suspend_exit_lp1();
|
||||||
break;
|
break;
|
||||||
case TEGRA_SUSPEND_LP2:
|
case TEGRA_SUSPEND_LP2:
|
||||||
tegra_clear_cpu_in_lp2();
|
tegra_pm_clear_cpu_in_lp2();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -436,4 +432,18 @@ void __init tegra_init_suspend(void)
|
||||||
|
|
||||||
suspend_set_ops(&tegra_suspend_ops);
|
suspend_set_ops(&tegra_suspend_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tegra_pm_park_secondary_cpu(unsigned long 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
|
#endif
|
||||||
|
|
|
@ -23,10 +23,6 @@ void tegra20_sleep_core_init(void);
|
||||||
void tegra30_lp1_iram_hook(void);
|
void tegra30_lp1_iram_hook(void);
|
||||||
void tegra30_sleep_core_init(void);
|
void tegra30_sleep_core_init(void);
|
||||||
|
|
||||||
void tegra_clear_cpu_in_lp2(void);
|
|
||||||
bool tegra_set_cpu_in_lp2(void);
|
|
||||||
int tegra_cpu_do_idle(void);
|
|
||||||
void tegra_idle_lp2_last(void);
|
|
||||||
extern void (*tegra_tear_down_cpu)(void);
|
extern void (*tegra_tear_down_cpu)(void);
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
|
|
@ -183,17 +183,6 @@ after_errata:
|
||||||
bleq __die @ CPU not present (to OS)
|
bleq __die @ CPU not present (to OS)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
|
||||||
/* Are we on Tegra20? */
|
|
||||||
cmp r6, #TEGRA20
|
|
||||||
bne 1f
|
|
||||||
/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
|
|
||||||
mov r0, #CPU_NOT_RESETTABLE
|
|
||||||
cmp r10, #0
|
|
||||||
strbne r0, [r12, #RESET_DATA(RESETTABLE_STATUS)]
|
|
||||||
1:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Waking up from LP1? */
|
/* Waking up from LP1? */
|
||||||
ldr r8, [r12, #RESET_DATA(MASK_LP1)]
|
ldr r8, [r12, #RESET_DATA(MASK_LP1)]
|
||||||
tst r8, r11 @ if in_lp1
|
tst r8, r11 @ if in_lp1
|
||||||
|
|
|
@ -16,9 +16,8 @@
|
||||||
#define TEGRA_RESET_STARTUP_SECONDARY 3
|
#define TEGRA_RESET_STARTUP_SECONDARY 3
|
||||||
#define TEGRA_RESET_STARTUP_LP2 4
|
#define TEGRA_RESET_STARTUP_LP2 4
|
||||||
#define TEGRA_RESET_STARTUP_LP1 5
|
#define TEGRA_RESET_STARTUP_LP1 5
|
||||||
#define TEGRA_RESET_RESETTABLE_STATUS 6
|
#define TEGRA_RESET_TF_PRESENT 6
|
||||||
#define TEGRA_RESET_TF_PRESENT 7
|
#define TEGRA_RESET_DATA_SIZE 7
|
||||||
#define TEGRA_RESET_DATA_SIZE 8
|
|
||||||
|
|
||||||
#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
|
#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
|
||||||
|
|
||||||
|
@ -42,10 +41,6 @@ void __tegra_cpu_reset_handler_end(void);
|
||||||
(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
|
(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
|
||||||
((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \
|
((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \
|
||||||
(u32)__tegra_cpu_reset_handler_start)))
|
(u32)__tegra_cpu_reset_handler_start)))
|
||||||
#define tegra20_cpu1_resettable_status \
|
|
||||||
(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
|
|
||||||
((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_RESETTABLE_STATUS] - \
|
|
||||||
(u32)__tegra_cpu_reset_handler_start)))
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define tegra_cpu_reset_handler_offset \
|
#define tegra_cpu_reset_handler_offset \
|
||||||
|
|
|
@ -43,9 +43,6 @@
|
||||||
#define APB_MISC_XM2CFGCPADCTRL2 0x8e4
|
#define APB_MISC_XM2CFGCPADCTRL2 0x8e4
|
||||||
#define APB_MISC_XM2CFGDPADCTRL2 0x8e8
|
#define APB_MISC_XM2CFGDPADCTRL2 0x8e8
|
||||||
|
|
||||||
#define __tegra20_cpu1_resettable_status_offset \
|
|
||||||
(__tegra_cpu_reset_handler_data_offset + RESET_DATA(RESETTABLE_STATUS))
|
|
||||||
|
|
||||||
.macro pll_enable, rd, r_car_base, pll_base
|
.macro pll_enable, rd, r_car_base, pll_base
|
||||||
ldr \rd, [\r_car_base, #\pll_base]
|
ldr \rd, [\r_car_base, #\pll_base]
|
||||||
tst \rd, #(1 << 30)
|
tst \rd, #(1 << 30)
|
||||||
|
@ -90,10 +87,6 @@ ENDPROC(tegra20_hotplug_shutdown)
|
||||||
ENTRY(tegra20_cpu_shutdown)
|
ENTRY(tegra20_cpu_shutdown)
|
||||||
cmp r0, #0
|
cmp r0, #0
|
||||||
reteq lr @ must not be called for CPU 0
|
reteq lr @ must not be called for CPU 0
|
||||||
mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
|
|
||||||
ldr r2, =__tegra20_cpu1_resettable_status_offset
|
|
||||||
mov r12, #CPU_RESETTABLE
|
|
||||||
strb r12, [r1, r2]
|
|
||||||
|
|
||||||
cpu_to_halt_reg r1, r0
|
cpu_to_halt_reg r1, r0
|
||||||
ldr r3, =TEGRA_FLOW_CTRL_VIRT
|
ldr r3, =TEGRA_FLOW_CTRL_VIRT
|
||||||
|
@ -116,107 +109,6 @@ ENDPROC(tegra20_cpu_shutdown)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
/*
|
|
||||||
* tegra_pen_lock
|
|
||||||
*
|
|
||||||
* spinlock implementation with no atomic test-and-set and no coherence
|
|
||||||
* using Peterson's algorithm on strongly-ordered registers
|
|
||||||
* used to synchronize a cpu waking up from wfi with entering lp2 on idle
|
|
||||||
*
|
|
||||||
* The reference link of Peterson's algorithm:
|
|
||||||
* http://en.wikipedia.org/wiki/Peterson's_algorithm
|
|
||||||
*
|
|
||||||
* SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm)
|
|
||||||
* on cpu 0:
|
|
||||||
* r2 = flag[0] (in SCRATCH38)
|
|
||||||
* r3 = flag[1] (in SCRATCH39)
|
|
||||||
* on cpu1:
|
|
||||||
* r2 = flag[1] (in SCRATCH39)
|
|
||||||
* r3 = flag[0] (in SCRATCH38)
|
|
||||||
*
|
|
||||||
* must be called with MMU on
|
|
||||||
* corrupts r0-r3, r12
|
|
||||||
*/
|
|
||||||
ENTRY(tegra_pen_lock)
|
|
||||||
mov32 r3, TEGRA_PMC_VIRT
|
|
||||||
cpu_id r0
|
|
||||||
add r1, r3, #PMC_SCRATCH37
|
|
||||||
cmp r0, #0
|
|
||||||
addeq r2, r3, #PMC_SCRATCH38
|
|
||||||
addeq r3, r3, #PMC_SCRATCH39
|
|
||||||
addne r2, r3, #PMC_SCRATCH39
|
|
||||||
addne r3, r3, #PMC_SCRATCH38
|
|
||||||
|
|
||||||
mov r12, #1
|
|
||||||
str r12, [r2] @ flag[cpu] = 1
|
|
||||||
dsb
|
|
||||||
str r12, [r1] @ !turn = cpu
|
|
||||||
1: dsb
|
|
||||||
ldr r12, [r3]
|
|
||||||
cmp r12, #1 @ flag[!cpu] == 1?
|
|
||||||
ldreq r12, [r1]
|
|
||||||
cmpeq r12, r0 @ !turn == cpu?
|
|
||||||
beq 1b @ while !turn == cpu && flag[!cpu] == 1
|
|
||||||
|
|
||||||
ret lr @ locked
|
|
||||||
ENDPROC(tegra_pen_lock)
|
|
||||||
|
|
||||||
ENTRY(tegra_pen_unlock)
|
|
||||||
dsb
|
|
||||||
mov32 r3, TEGRA_PMC_VIRT
|
|
||||||
cpu_id r0
|
|
||||||
cmp r0, #0
|
|
||||||
addeq r2, r3, #PMC_SCRATCH38
|
|
||||||
addne r2, r3, #PMC_SCRATCH39
|
|
||||||
mov r12, #0
|
|
||||||
str r12, [r2]
|
|
||||||
ret lr
|
|
||||||
ENDPROC(tegra_pen_unlock)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tegra20_cpu_clear_resettable(void)
|
|
||||||
*
|
|
||||||
* Called to clear the "resettable soon" flag in IRAM variable when
|
|
||||||
* it is expected that the secondary CPU will be idle soon.
|
|
||||||
*/
|
|
||||||
ENTRY(tegra20_cpu_clear_resettable)
|
|
||||||
mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
|
|
||||||
ldr r2, =__tegra20_cpu1_resettable_status_offset
|
|
||||||
mov r12, #CPU_NOT_RESETTABLE
|
|
||||||
strb r12, [r1, r2]
|
|
||||||
ret lr
|
|
||||||
ENDPROC(tegra20_cpu_clear_resettable)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tegra20_cpu_set_resettable_soon(void)
|
|
||||||
*
|
|
||||||
* Called to set the "resettable soon" flag in IRAM variable when
|
|
||||||
* it is expected that the secondary CPU will be idle soon.
|
|
||||||
*/
|
|
||||||
ENTRY(tegra20_cpu_set_resettable_soon)
|
|
||||||
mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
|
|
||||||
ldr r2, =__tegra20_cpu1_resettable_status_offset
|
|
||||||
mov r12, #CPU_RESETTABLE_SOON
|
|
||||||
strb r12, [r1, r2]
|
|
||||||
ret lr
|
|
||||||
ENDPROC(tegra20_cpu_set_resettable_soon)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tegra20_cpu_is_resettable_soon(void)
|
|
||||||
*
|
|
||||||
* Returns true if the "resettable soon" flag in IRAM variable has been
|
|
||||||
* set because it is expected that the secondary CPU will be idle soon.
|
|
||||||
*/
|
|
||||||
ENTRY(tegra20_cpu_is_resettable_soon)
|
|
||||||
mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
|
|
||||||
ldr r2, =__tegra20_cpu1_resettable_status_offset
|
|
||||||
ldrb r12, [r1, r2]
|
|
||||||
cmp r12, #CPU_RESETTABLE_SOON
|
|
||||||
moveq r0, #1
|
|
||||||
movne r0, #0
|
|
||||||
ret lr
|
|
||||||
ENDPROC(tegra20_cpu_is_resettable_soon)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tegra20_sleep_core_finish(unsigned long v2p)
|
* tegra20_sleep_core_finish(unsigned long v2p)
|
||||||
*
|
*
|
||||||
|
@ -242,68 +134,6 @@ ENTRY(tegra20_sleep_core_finish)
|
||||||
ret r3
|
ret r3
|
||||||
ENDPROC(tegra20_sleep_core_finish)
|
ENDPROC(tegra20_sleep_core_finish)
|
||||||
|
|
||||||
/*
|
|
||||||
* tegra20_sleep_cpu_secondary_finish(unsigned long v2p)
|
|
||||||
*
|
|
||||||
* Enters WFI on secondary CPU by exiting coherency.
|
|
||||||
*/
|
|
||||||
ENTRY(tegra20_sleep_cpu_secondary_finish)
|
|
||||||
stmfd sp!, {r4-r11, lr}
|
|
||||||
|
|
||||||
mrc p15, 0, r11, c1, c0, 1 @ save actlr before exiting coherency
|
|
||||||
|
|
||||||
/* Flush and disable the L1 data cache */
|
|
||||||
mov r0, #TEGRA_FLUSH_CACHE_LOUIS
|
|
||||||
bl tegra_disable_clean_inv_dcache
|
|
||||||
|
|
||||||
mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT
|
|
||||||
ldr r4, =__tegra20_cpu1_resettable_status_offset
|
|
||||||
mov r3, #CPU_RESETTABLE
|
|
||||||
strb r3, [r0, r4]
|
|
||||||
|
|
||||||
bl tegra_cpu_do_idle
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cpu may be reset while in wfi, which will return through
|
|
||||||
* tegra_resume to cpu_resume
|
|
||||||
* or interrupt may wake wfi, which will return here
|
|
||||||
* cpu state is unchanged - MMU is on, cache is on, coherency
|
|
||||||
* is off, and the data cache is off
|
|
||||||
*
|
|
||||||
* r11 contains the original actlr
|
|
||||||
*/
|
|
||||||
|
|
||||||
bl tegra_pen_lock
|
|
||||||
|
|
||||||
mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT
|
|
||||||
ldr r4, =__tegra20_cpu1_resettable_status_offset
|
|
||||||
mov r3, #CPU_NOT_RESETTABLE
|
|
||||||
strb r3, [r0, r4]
|
|
||||||
|
|
||||||
bl tegra_pen_unlock
|
|
||||||
|
|
||||||
/* Re-enable the data cache */
|
|
||||||
mrc p15, 0, r10, c1, c0, 0
|
|
||||||
orr r10, r10, #CR_C
|
|
||||||
mcr p15, 0, r10, c1, c0, 0
|
|
||||||
isb
|
|
||||||
|
|
||||||
mcr p15, 0, r11, c1, c0, 1 @ reenable coherency
|
|
||||||
|
|
||||||
/* Invalidate the TLBs & BTAC */
|
|
||||||
mov r1, #0
|
|
||||||
mcr p15, 0, r1, c8, c3, 0 @ invalidate shared TLBs
|
|
||||||
mcr p15, 0, r1, c7, c1, 6 @ invalidate shared BTAC
|
|
||||||
dsb
|
|
||||||
isb
|
|
||||||
|
|
||||||
/* the cpu was running with coherency disabled,
|
|
||||||
* caches may be out of date */
|
|
||||||
bl v7_flush_kern_cache_louis
|
|
||||||
|
|
||||||
ldmfd sp!, {r4 - r11, pc}
|
|
||||||
ENDPROC(tegra20_sleep_cpu_secondary_finish)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tegra20_tear_down_cpu
|
* tegra20_tear_down_cpu
|
||||||
*
|
*
|
||||||
|
|
|
@ -265,11 +265,11 @@ ENTRY(tegra30_sleep_core_finish)
|
||||||
ENDPROC(tegra30_sleep_core_finish)
|
ENDPROC(tegra30_sleep_core_finish)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tegra30_sleep_cpu_secondary_finish(unsigned long v2p)
|
* tegra30_pm_secondary_cpu_suspend(unsigned long unused_arg)
|
||||||
*
|
*
|
||||||
* Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
|
* Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
|
||||||
*/
|
*/
|
||||||
ENTRY(tegra30_sleep_cpu_secondary_finish)
|
ENTRY(tegra30_pm_secondary_cpu_suspend)
|
||||||
mov r7, lr
|
mov r7, lr
|
||||||
|
|
||||||
/* Flush and disable the L1 data cache */
|
/* Flush and disable the L1 data cache */
|
||||||
|
@ -281,7 +281,7 @@ ENTRY(tegra30_sleep_cpu_secondary_finish)
|
||||||
bl tegra30_cpu_shutdown
|
bl tegra30_cpu_shutdown
|
||||||
mov r0, #1 @ never return here
|
mov r0, #1 @ never return here
|
||||||
ret r7
|
ret r7
|
||||||
ENDPROC(tegra30_sleep_cpu_secondary_finish)
|
ENDPROC(tegra30_pm_secondary_cpu_suspend)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tegra30_tear_down_cpu
|
* tegra30_tear_down_cpu
|
||||||
|
|
|
@ -114,29 +114,14 @@
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
#else
|
#else
|
||||||
void tegra_pen_lock(void);
|
|
||||||
void tegra_pen_unlock(void);
|
|
||||||
void tegra_resume(void);
|
void tegra_resume(void);
|
||||||
int tegra_sleep_cpu_finish(unsigned long);
|
int tegra_sleep_cpu_finish(unsigned long);
|
||||||
void tegra_disable_clean_inv_dcache(u32 flag);
|
void tegra_disable_clean_inv_dcache(u32 flag);
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
|
||||||
void tegra20_hotplug_shutdown(void);
|
void tegra20_hotplug_shutdown(void);
|
||||||
void tegra30_hotplug_shutdown(void);
|
void tegra30_hotplug_shutdown(void);
|
||||||
#endif
|
|
||||||
|
|
||||||
void tegra20_cpu_shutdown(int cpu);
|
|
||||||
int tegra20_cpu_is_resettable_soon(void);
|
|
||||||
void tegra20_cpu_clear_resettable(void);
|
|
||||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
|
||||||
void tegra20_cpu_set_resettable_soon(void);
|
|
||||||
#else
|
|
||||||
static inline void tegra20_cpu_set_resettable_soon(void) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int tegra20_sleep_cpu_secondary_finish(unsigned long);
|
|
||||||
void tegra20_tear_down_cpu(void);
|
void tegra20_tear_down_cpu(void);
|
||||||
int tegra30_sleep_cpu_secondary_finish(unsigned long);
|
|
||||||
void tegra30_tear_down_cpu(void);
|
void tegra30_tear_down_cpu(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "cpuidle.h"
|
#include "cpuidle.h"
|
||||||
#include "iomap.h"
|
#include "iomap.h"
|
||||||
#include "irq.h"
|
|
||||||
#include "pm.h"
|
#include "pm.h"
|
||||||
#include "reset.h"
|
#include "reset.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
* Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
|
* Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TEGRA_IRQ_H
|
#ifndef __SOC_TEGRA_IRQ_H
|
||||||
#define __TEGRA_IRQ_H
|
#define __SOC_TEGRA_IRQ_H
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARM)
|
||||||
bool tegra_pending_sgi(void);
|
bool tegra_pending_sgi(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* __SOC_TEGRA_IRQ_H */
|
|
@ -6,6 +6,8 @@
|
||||||
#ifndef __SOC_TEGRA_PM_H__
|
#ifndef __SOC_TEGRA_PM_H__
|
||||||
#define __SOC_TEGRA_PM_H__
|
#define __SOC_TEGRA_PM_H__
|
||||||
|
|
||||||
|
#include <linux/errno.h>
|
||||||
|
|
||||||
enum tegra_suspend_mode {
|
enum tegra_suspend_mode {
|
||||||
TEGRA_SUSPEND_NONE = 0,
|
TEGRA_SUSPEND_NONE = 0,
|
||||||
TEGRA_SUSPEND_LP2, /* CPU voltage off */
|
TEGRA_SUSPEND_LP2, /* CPU voltage off */
|
||||||
|
@ -20,6 +22,12 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
|
||||||
|
|
||||||
/* low-level resume entry point */
|
/* low-level resume entry point */
|
||||||
void tegra_resume(void);
|
void tegra_resume(void);
|
||||||
|
|
||||||
|
int tegra30_pm_secondary_cpu_suspend(unsigned long arg);
|
||||||
|
void tegra_pm_clear_cpu_in_lp2(void);
|
||||||
|
void tegra_pm_set_cpu_in_lp2(void);
|
||||||
|
int tegra_pm_enter_lp2(void);
|
||||||
|
int tegra_pm_park_secondary_cpu(unsigned long cpu);
|
||||||
#else
|
#else
|
||||||
static inline enum tegra_suspend_mode
|
static inline enum tegra_suspend_mode
|
||||||
tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
|
tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
|
||||||
|
@ -30,6 +38,29 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
|
||||||
static inline void tegra_resume(void)
|
static inline void tegra_resume(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int tegra30_pm_secondary_cpu_suspend(unsigned long arg)
|
||||||
|
{
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void tegra_pm_clear_cpu_in_lp2(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void tegra_pm_set_cpu_in_lp2(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int tegra_pm_enter_lp2(void)
|
||||||
|
{
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int tegra_pm_park_secondary_cpu(unsigned long cpu)
|
||||||
|
{
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
#endif /* CONFIG_PM_SLEEP */
|
#endif /* CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
#endif /* __SOC_TEGRA_PM_H__ */
|
#endif /* __SOC_TEGRA_PM_H__ */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user