All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chen-Yu Tsai <wens@csie.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [linux-sunxi] [RFC PATCH 7/8] sunxi: Add basic PSCI implementation for multi-cluster SoCs
Date: Wed, 7 Jun 2017 12:53:34 +0800	[thread overview]
Message-ID: <CAGb2v66-U5rTbtr5jbVE6ghzgAzAbHFeCUiFUhmAfJTNi2P9+Q@mail.gmail.com> (raw)
In-Reply-To: <20170607004721.24194-8-icenowy@aosc.io>

On Wed, Jun 7, 2017 at 8:47 AM, Icenowy Zheng <icenowy@aosc.io> 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>
> ---
>  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
>

I suggest using --find-copies and --find-copies-harder when you
generate the patch.
It should limit the patch to differences between psci.c and 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);
> +#endif
> +}
> +
> +static void __secure sunxi_cpu_set_power(int cluster, int cpu, bool on)
> +{
> +       struct sunxi_prcm_reg *prcm =
> +               (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
> +
> +       sunxi_core_power_switch(&prcm->cpu_pwr_clamp[cluster][cpu],
> +                               &prcm->cpu_pwroff[cluster], on, cpu);
> +}
> +
> +static u32 __secure cp15_read_scr(void)
> +{
> +       u32 scr;
> +
> +       asm volatile ("mrc p15, 0, %0, c1, c1, 0" : "=r" (scr));
> +
> +       return scr;
> +}
> +
> +static void __secure cp15_write_scr(u32 scr)
> +{
> +       asm volatile ("mcr p15, 0, %0, c1, c1, 0" : : "r" (scr));
> +       isb();
> +}
> +
> +int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc)
> +{
> +       struct sunxi_cpucfg_reg *cpucfg =
> +               (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
> +#ifdef CONFIG_MACH_SUN8I_A83T
> +       struct sunxi_r_cpucfg_reg *r_cpucfg =
> +               (struct sunxi_r_cpucfg_reg *)SUNXI_R_CPUCFG_BASE;
> +#else
> +       struct sunxi_prcm_reg *prcm =
> +               (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
> +#endif
> +       u32 cluster = (mpidr >> 8) & 0x1;
> +       u32 cpu = mpidr & 0x3;
> +       u32 cpuid = cpu | (cluster << 2);
> +
> +       /* TODO We don't support multi-cluster yet */
> +       if (cluster > 0)
> +               return ARM_PSCI_RET_INVAL;
> +
> +       /* store target PC */
> +       psci_save_target_pc(cpuid, pc);
> +
> +       /* Set secondary core power on PC */
> +#ifdef CONFIG_MACH_SUN8I_A83T
> +       writel((u32)&psci_cpu_entry, &r_cpucfg->priv0);
> +#else
> +       writel((u32)&psci_cpu_entry, &prcm->cpu_soft_entry);
> +#endif

Could you take a look at the non-MCPM version and move the #ifdefs
into separate functions? Basically we want the main functions to
be as clean and descriptive as possible. You could also structure
it as two patches: the first adding the original A80 version, and
the second modifying it to support the A83T as well.

I'll send a fix for the non-MCPM version fixing the entry address.

Regards
ChenYu

> +
> +       /* Assert power-on reset on target CPU */
> +#ifdef CONFIG_MACH_SUN8I_A83T
> +       clrbits_le32(&r_cpucfg->cpu_rst[cluster], BIT(cpu));
> +#else
> +       clrbits_le32(&prcm->cpu_rst[cluster], BIT(cpu));
> +#endif
> +
> +       /* Cortex-A7: hold L1 cache reset disable signal low */
> +       if (sunxi_cluster_is_a7(cluster))
> +               clrbits_le32(&cpucfg->cluster[cluster].ctrl0,
> +                            CPUCFG_CX_CTRL0_L1_RST_DISABLE(cpu));
> +
> +       /* Lock CPU (Disable external debug access) */
> +       clrbits_le32(&cpucfg->cluster_reset[cluster],
> +                    CPUCFG_CX_RST_DBG(cpu));
> +
> +       /* Cortex-A7: Assert ETM reset */
> +       if (sunxi_cluster_is_a7(cluster))
> +               clrbits_le32(&cpucfg->cluster_reset[cluster],
> +                            CPUCFG_CX_RST_ETM(cpu));
> +
> +       /*
> +        * Allwinner code also asserts resets for NEON on A15. According
> +        * to ARM manuals, asserting power-on reset is sufficient.
> +        */
> +
> +       /* Power up target CPU */
> +       sunxi_cpu_set_power(cluster, cpu, true);
> +
> +       /* De-assert power-on reset on target CPU */
> +#ifdef CONFIG_MACH_SUN8I_A83T
> +       setbits_le32(&r_cpucfg->cpu_rst[cluster], BIT(cpu));
> +#else
> +       setbits_le32(&prcm->cpu_rst[cluster], BIT(cpu));
> +#endif
> +
> +       /* De-assert core reset on target CPU */
> +       setbits_le32(&cpucfg->cluster_reset[cluster],
> +                    CPUCFG_CX_RST_CORE(cpu));
> +
> +       /* Cortex-A7: De-assert ETM reset */
> +       if (sunxi_cluster_is_a7(cluster))
> +               setbits_le32(&cpucfg->cluster_reset[cluster],
> +                            CPUCFG_CX_RST_ETM(cpu));
> +
> +       /* Unlock CPU (Disable external debug access) */
> +       setbits_le32(&cpucfg->cluster_reset[cluster],
> +                    CPUCFG_CX_RST_DBG(cpu));
> +
> +       return ARM_PSCI_RET_SUCCESS;
> +}
> +
> +void __secure psci_arch_init(void)
> +{
> +       u32 reg;
> +
> +       reg = cp15_read_scr();
> +       reg &= ~BIT(0); /* Secure mode */
> +       cp15_write_scr(reg);
> +}
> --
> 2.12.2
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

  reply	other threads:[~2017-06-07  4:53 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-07  0:47 [U-Boot] [RFC PATCH 0/8] Allwinner A83T PSCI SMP support Icenowy Zheng
2017-06-07  0:47 ` [U-Boot] [RFC PATCH 1/8] sun8i: Add TZPC setup for A83T Icenowy Zheng
2017-06-07  3:24   ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
2017-06-07  0:47 ` [U-Boot] [RFC PATCH 2/8] sunxi: add configuration of secure SRAM " Icenowy Zheng
2017-06-07  3:25   ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
2017-06-07  0:47 ` [U-Boot] [RFC PATCH 3/8] sun8i: Add a macro to read the silicon revision Icenowy Zheng
2017-06-07  3:27   ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
2017-06-07  0:47 ` [U-Boot] [RFC PATCH 4/8] sunxi: add SUNXI_R_CPUCFG_BASE for A83T SoC Icenowy Zheng
2017-06-07  3:48   ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
2017-06-07  4:13     ` Chen-Yu Tsai
2017-06-07  0:47 ` [U-Boot] [RFC PATCH 5/8] sunxi: Add CPUCFG register definitions for A80/A83T SoCs Icenowy Zheng
2017-06-07  3:43   ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
2017-06-07  3:44     ` Icenowy Zheng
2017-06-07  6:44   ` [U-Boot] " Maxime Ripard
2017-06-07  6:58     ` Icenowy Zheng
2017-06-07  7:06       ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
2017-06-07  0:47 ` [U-Boot] [RFC PATCH 6/8] sunxi: add multi-cluster CPU PRCM register definition Icenowy Zheng
2017-06-07  3:40   ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
2017-06-07  0:47 ` [U-Boot] [RFC PATCH 7/8] sunxi: Add basic PSCI implementation for multi-cluster SoCs Icenowy Zheng
2017-06-07  4:53   ` Chen-Yu Tsai [this message]
2017-06-07  6:48   ` Maxime Ripard
2017-06-07  6:59     ` [U-Boot] [linux-sunxi] " Icenowy Zheng
2017-06-07  7:54       ` Marc Zyngier
2017-06-07  0:47 ` [U-Boot] [RFC PATCH 8/8] sunxi: enable PSCI for A83T SoC Icenowy Zheng
2017-06-07  3:36   ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
2017-06-07  3:40     ` Icenowy Zheng
2017-06-07  3:47       ` Chen-Yu Tsai
2017-06-07  6:50         ` Maxime Ripard
2017-06-07  6:58           ` Icenowy Zheng
2017-06-07  7:00           ` Chen-Yu Tsai
2017-06-07 12:11             ` Marc Zyngier
2017-06-07 12:12               ` Icenowy Zheng
2017-06-07 12:51                 ` Marc Zyngier
2017-06-07 13:04                   ` Maxime Ripard
2017-06-07 14:06                     ` Marc Zyngier
2017-07-02 14:17                       ` Maxime Ripard
2017-07-02 15:40                         ` André Przywara
2017-07-03  8:21                           ` Maxime Ripard
2017-06-23 13:24                   ` icenowy at aosc.io
2017-06-23 13:35                     ` Maxime Ripard
2017-06-23 13:39                       ` icenowy at aosc.io
2017-06-23 13:50                         ` Chen-Yu Tsai
2017-07-02  7:08                           ` icenowy at aosc.io
2017-07-02 11:22                             ` Marc Zyngier
2017-07-02 12:36                               ` icenowy at aosc.io
2017-07-02 15:27                                 ` Marc Zyngier
2017-07-03 20:37                                   ` Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAGb2v66-U5rTbtr5jbVE6ghzgAzAbHFeCUiFUhmAfJTNi2P9+Q@mail.gmail.com \
    --to=wens@csie.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.