mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-20 03:04:01 +08:00
d457ef358f
This supports power-gated idle on secondary CPUs for Tegra30. The secondary CPUs can go into powered-down state independently. When CPU goes into this state, it saves it's contexts and puts itself to flow controlled WFI state. After that, it will been power gated. Be aware of that, you may see the legacy power state "LP2" in the code which is exactly the same meaning of "CPU power down". Based on the work by: Scott Williams <scwilliams@nvidia.com> Signed-off-by: Joseph Lo <josephl@nvidia.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
89 lines
2.4 KiB
C
89 lines
2.4 KiB
C
/*
|
|
* Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef __MACH_TEGRA_SLEEP_H
|
|
#define __MACH_TEGRA_SLEEP_H
|
|
|
|
#include "iomap.h"
|
|
|
|
#define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \
|
|
+ IO_CPU_VIRT)
|
|
#define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
|
|
+ IO_PPSB_VIRT)
|
|
#define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
|
|
+ IO_PPSB_VIRT)
|
|
|
|
#ifdef __ASSEMBLY__
|
|
/* returns the offset of the flow controller halt register for a cpu */
|
|
.macro cpu_to_halt_reg rd, rcpu
|
|
cmp \rcpu, #0
|
|
subne \rd, \rcpu, #1
|
|
movne \rd, \rd, lsl #3
|
|
addne \rd, \rd, #0x14
|
|
moveq \rd, #0
|
|
.endm
|
|
|
|
/* returns the offset of the flow controller csr register for a cpu */
|
|
.macro cpu_to_csr_reg rd, rcpu
|
|
cmp \rcpu, #0
|
|
subne \rd, \rcpu, #1
|
|
movne \rd, \rd, lsl #3
|
|
addne \rd, \rd, #0x18
|
|
moveq \rd, #8
|
|
.endm
|
|
|
|
/* returns the ID of the current processor */
|
|
.macro cpu_id, rd
|
|
mrc p15, 0, \rd, c0, c0, 5
|
|
and \rd, \rd, #0xF
|
|
.endm
|
|
|
|
/* loads a 32-bit value into a register without a data access */
|
|
.macro mov32, reg, val
|
|
movw \reg, #:lower16:\val
|
|
movt \reg, #:upper16:\val
|
|
.endm
|
|
|
|
/* Macro to exit SMP coherency. */
|
|
.macro exit_smp, tmp1, tmp2
|
|
mrc p15, 0, \tmp1, c1, c0, 1 @ ACTLR
|
|
bic \tmp1, \tmp1, #(1<<6) | (1<<0) @ clear ACTLR.SMP | ACTLR.FW
|
|
mcr p15, 0, \tmp1, c1, c0, 1 @ ACTLR
|
|
isb
|
|
cpu_id \tmp1
|
|
mov \tmp1, \tmp1, lsl #2
|
|
mov \tmp2, #0xf
|
|
mov \tmp2, \tmp2, lsl \tmp1
|
|
mov32 \tmp1, TEGRA_ARM_PERIF_VIRT + 0xC
|
|
str \tmp2, [\tmp1] @ invalidate SCU tags for CPU
|
|
dsb
|
|
.endm
|
|
#else
|
|
void tegra_resume(void);
|
|
|
|
#ifdef CONFIG_HOTPLUG_CPU
|
|
void tegra20_hotplug_init(void);
|
|
void tegra30_hotplug_init(void);
|
|
#else
|
|
static inline void tegra20_hotplug_init(void) {}
|
|
static inline void tegra30_hotplug_init(void) {}
|
|
#endif
|
|
|
|
int tegra30_sleep_cpu_secondary_finish(unsigned long);
|
|
|
|
#endif
|
|
#endif
|