From mboxrd@z Thu Jan 1 00:00:00 1970 From: Icenowy Zheng Date: Wed, 07 Jun 2017 14:59:52 +0800 Subject: [U-Boot] [linux-sunxi] Re: [RFC PATCH 7/8] sunxi: Add basic PSCI implementation for multi-cluster SoCs In-Reply-To: <20170607064855.7k3nnj2h36eq2wgt@flea.lan> References: <20170607004721.24194-1-icenowy@aosc.io> <20170607004721.24194-8-icenowy@aosc.io> <20170607064855.7k3nnj2h36eq2wgt@flea.lan> Message-ID: <7032D97D-99C9-4019-B92C-A2B9D428FC61@aosc.io> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit To: u-boot@lists.denx.de 于 2017年6月7日 GMT+08:00 下午2:48:55, Maxime Ripard 写到: >Hi, > >On Wed, Jun 07, 2017 at 08:47:20AM +0800, Icenowy Zheng wrote: >> From: Chen-Yu Tsai >> >> 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 >> [Icenowy: adapt for A83T] >> Signed-off-by: Icenowy Zheng > >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 >> + * >> + * Based on assembly code by Marc Zyngier , >> + * which was based on code by Carl van Schaik . >> + * >> + * SPDX-License-Identifier: GPL-2.0 >> + */ >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> + >> +/* >> + * 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