
于 2017年6月7日 GMT+08:00 下午2:48:55, Maxime Ripard maxime.ripard@free-electrons.com 写到:
Hi,
On Wed, Jun 07, 2017 at 08:47:20AM +0800, Icenowy Zheng wrote:
From: Chen-Yu Tsai wens@csie.org
Allwinner A80 and A83T SoCs have two clusters of CPU, each cluster contains 4 cores. A80 is Cortex-A15 + Cortex-A7 configuration, while A83T has two clusters of Cortex-A7.
This patch adds a basic version that allows bringing up the four
cores
in the first cluster. The structure is based on existing sunxi PSCI
code.
Signed-off-by: Chen-Yu Tsai wens@csie.org [Icenowy: adapt for A83T] Signed-off-by: Icenowy Zheng icenowy@aosc.io
Ideally, Marc should be in Cc in order to review this.
Who?
arch/arm/cpu/armv7/sunxi/Makefile | 4 + arch/arm/cpu/armv7/sunxi/psci-mcpm.c | 258
+++++++++++++++++++++++++++++++++++
2 files changed, 262 insertions(+) create mode 100644 arch/arm/cpu/armv7/sunxi/psci-mcpm.c
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile
b/arch/arm/cpu/armv7/sunxi/Makefile
index 8c026ff052..c789f686fd 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -14,8 +14,12 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o obj-$(CONFIG_MACH_SUN8I_A83T) += tzpc.o
ifndef CONFIG_SPL_BUILD +ifdef CONFIG_MACH_SUN8I_A83T +obj-$(CONFIG_ARMV7_PSCI) += psci-mcpm.o +else obj-$(CONFIG_ARMV7_PSCI) += psci.o endif +endif
ifdef CONFIG_SPL_BUILD obj-y += fel_utils.o diff --git a/arch/arm/cpu/armv7/sunxi/psci-mcpm.c
b/arch/arm/cpu/armv7/sunxi/psci-mcpm.c
new file mode 100644 index 0000000000..ba8d669c7e --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/psci-mcpm.c @@ -0,0 +1,258 @@ +/*
- Copyright (C) 2016
- Author: Chen-Yu Tsai wens@csie.org
- Based on assembly code by Marc Zyngier marc.zyngier@arm.com,
- which was based on code by Carl van Schaik carl@ok-labs.com.
- SPDX-License-Identifier: GPL-2.0
- */
+#include <config.h> +#include <common.h>
+#include <asm/arch/cpu.h> +#include <asm/arch/cpucfg.h> +#include <asm/arch/prcm.h> +#include <asm/armv7.h> +#include <asm/io.h> +#include <asm/psci.h> +#include <asm/secure.h>
+#include <linux/bitops.h>
+/*
- NOTE dense CPU IDs (0~3 for first cluster of 4 cores, 4~7 for the
- second cluster) are used throughout the PSCI code. Any MPIDR
style
- values must be converted.
- */
+/*
- Provide a dense CPU ID for 2-cluster systems. This must be coded
in
- assembly as it gets called from psci_stack_setup, when the stack
isn't
- available yet.
- Only r0 and r3 is usable. r8 - r12 are available if this function
is
- only called from psci_stack_setup, which we cannot guarantee.
- */
+u32 __secure __naked psci_get_cpu_id(void) +{
- asm volatile (
"mrc p15, 0, r3, c0, c0, 5 @ Get MPIDR\n"
"lsr r0, r3, #6\n"
"and r3, r3, #3\n"
"and r0, r0, #4\n"
"orr r0, r0, r3\n"
"bx lr\n"
- );
- /*
* The last five lines are the compiler generated assembly code for
*
* return (reg & 0x3) | (((reg >> 8) & 0x1) << 2);
*
* We can't guarantee that all compilers correctly use only r0 and
* r3, so we use inline assembly here.
*/
+}
+static void __secure cp15_write_cntp_tval(u32 tval) +{
- asm volatile ("mcr p15, 0, %0, c14, c2, 0" : : "r" (tval));
+}
+static void __secure cp15_write_cntp_ctl(u32 val) +{
- asm volatile ("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
+}
+static u32 __secure cp15_read_cntp_ctl(void) +{
- u32 val;
- asm volatile ("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
- return val;
+}
+#define ONE_US (COUNTER_FREQUENCY / 1000000)
+/* Use a different name to avoid clashing with the non-secure
function */
+static void __secure __udelay_sec(unsigned long us) +{
- u32 reg = ONE_US * us;
- cp15_write_cntp_tval(reg);
- isb();
- cp15_write_cntp_ctl(3);
- do {
isb();
reg = cp15_read_cntp_ctl();
- } while (!(reg & BIT(2)));
- cp15_write_cntp_ctl(0);
- isb();
+}
+static void __secure clamp_release(u32 *clamp) +{
- writel(0xff, clamp);
- __udelay_sec(10);
- writel(0xfe, clamp);
- __udelay_sec(10);
- writel(0xf8, clamp);
- __udelay_sec(10);
- writel(0xf0, clamp);
- __udelay_sec(10);
- writel(0x00, clamp);
+}
+static void __secure clamp_set(u32 *clamp) +{
- writel(0xff, clamp);
+}
+static void __secure sunxi_core_power_switch(u32 *clamp, u32
*pwroff,
bool on, int cpu)
+{
- if (on) {
/* Release power clamp */
clamp_release(clamp);
__udelay_sec(20);
/* Clear power gating */
clrbits_le32(pwroff, BIT(cpu));
- } else {
/* Set power gating */
setbits_le32(pwroff, BIT(cpu));
__udelay_sec(20);
/* Activate power clamp */
clamp_set(clamp);
- }
+}
+static int __secure sunxi_cluster_is_a7(int cluster) +{ +#ifdef CONFIG_MACH_SUN8I_A83T
- return 1;
+#else
- return (clustter == 0);
This doesn't compile.
Maxime