Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 453689e4 authored by Joseph Lo's avatar Joseph Lo Committed by Stephen Warren
Browse files

ARM: tegra20: add CPU hotplug support



Hotplug function put CPU in offline or online mode at runtime.
When the CPU been put into offline, it was been clock gated. The
offline CPU can be power gated, when the remaining CPU goes into
LP2.

Based on the worked by:
Colin Cross <ccross@android.com>
Gary King <gking@nvidia.com>

Signed-off-by: default avatarJoseph Lo <josephl@nvidia.com>
Signed-off-by: default avatarStephen Warren <swarren@nvidia.com>
parent 59b0f682
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_IDLE) += sleep.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra20_clocks.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra20_clocks.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra20_clocks_data.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra20_clocks_data.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= tegra2_emc.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= tegra2_emc.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= sleep-t20.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= tegra30_clocks.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= tegra30_clocks.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= tegra30_clocks_data.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= tegra30_clocks_data.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-t30.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-t30.o
+1 −0
Original line number Original line Diff line number Diff line
@@ -136,6 +136,7 @@ void __init tegra20_init_early(void)
	tegra_init_cache(0x331, 0x441);
	tegra_init_cache(0x331, 0x441);
	tegra_pmc_init();
	tegra_pmc_init();
	tegra_powergate_init();
	tegra_powergate_init();
	tegra20_hotplug_init();
}
}
#endif
#endif
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+8 −0
Original line number Original line Diff line number Diff line
@@ -56,6 +56,14 @@ int platform_cpu_disable(unsigned int cpu)
	return cpu == 0 ? -EPERM : 0;
	return cpu == 0 ? -EPERM : 0;
}
}


#ifdef CONFIG_ARCH_TEGRA_2x_SOC
extern void tegra20_hotplug_shutdown(void);
void __init tegra20_hotplug_init(void)
{
	tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
}
#endif

#ifdef CONFIG_ARCH_TEGRA_3x_SOC
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
extern void tegra30_hotplug_shutdown(void);
extern void tegra30_hotplug_shutdown(void);
void __init tegra30_hotplug_init(void)
void __init tegra30_hotplug_init(void)
+82 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
 * Copyright (c) 2011, Google, Inc.
 *
 * Author: Colin Cross <ccross@android.com>
 *         Gary King <gking@nvidia.com>
 *
 * 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/>.
 */

#include <linux/linkage.h>

#include <asm/assembler.h>

#include <mach/iomap.h>

#include "sleep.h"
#include "flowctrl.h"

#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
/*
 * tegra20_hotplug_shutdown(void)
 *
 * puts the current cpu in reset
 * should never return
 */
ENTRY(tegra20_hotplug_shutdown)
	/* Turn off SMP coherency */
	exit_smp r4, r5

	/* Put this CPU down */
	cpu_id	r0
	bl	tegra20_cpu_shutdown
	mov	pc, lr			@ should never get here
ENDPROC(tegra20_hotplug_shutdown)

/*
 * tegra20_cpu_shutdown(int cpu)
 *
 * r0 is cpu to reset
 *
 * puts the specified CPU in wait-for-event mode on the flow controller
 * and puts the CPU in reset
 * can be called on the current cpu or another cpu
 * if called on the current cpu, does not return
 * MUST NOT BE CALLED FOR CPU 0.
 *
 * corrupts r0-r3, r12
 */
ENTRY(tegra20_cpu_shutdown)
	cmp	r0, #0
	moveq	pc, lr			@ must not be called for CPU 0

	cpu_to_halt_reg r1, r0
	ldr	r3, =TEGRA_FLOW_CTRL_VIRT
	mov	r2, #FLOW_CTRL_WAITEVENT | FLOW_CTRL_JTAG_RESUME
	str	r2, [r3, r1]		@ put flow controller in wait event mode
	ldr	r2, [r3, r1]
	isb
	dsb
	movw	r1, 0x1011
	mov	r1, r1, lsl r0
	ldr	r3, =TEGRA_CLK_RESET_VIRT
	str	r1, [r3, #0x340]	@ put slave CPU in reset
	isb
	dsb
	cpu_id	r3
	cmp	r3, r0
	beq	.
	mov	pc, lr
ENDPROC(tegra20_cpu_shutdown)
#endif
+4 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,8 @@
					+ IO_CPU_VIRT)
					+ IO_CPU_VIRT)
#define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
#define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
					+ IO_PPSB_VIRT)
					+ IO_PPSB_VIRT)
#define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
					+ IO_PPSB_VIRT)


#ifdef __ASSEMBLY__
#ifdef __ASSEMBLY__
/* returns the offset of the flow controller halt register for a cpu */
/* returns the offset of the flow controller halt register for a cpu */
@@ -72,8 +74,10 @@
#else
#else


#ifdef CONFIG_HOTPLUG_CPU
#ifdef CONFIG_HOTPLUG_CPU
void tegra20_hotplug_init(void);
void tegra30_hotplug_init(void);
void tegra30_hotplug_init(void);
#else
#else
static inline void tegra20_hotplug_init(void) {}
static inline void tegra30_hotplug_init(void) {}
static inline void tegra30_hotplug_init(void) {}
#endif
#endif