On 1/31/19 6:38 PM, Oleksandr Tyshchenko wrote:
> From: Oleksandr Tyshchenko <oleksandr_tyshche...@epam.com>
> 
> Also enable PSCI support for Stout and Lager boards where
> actually the r8a7790 SoC is installed.
> 
> All secondary CPUs will be switched to a non-secure HYP mode
> after booting.
> 
> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshche...@epam.com>
> ---
>  arch/arm/mach-rmobile/Kconfig.32   |   2 +
>  arch/arm/mach-rmobile/Makefile     |   6 +
>  arch/arm/mach-rmobile/pm-r8a7790.c | 408 
> +++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-rmobile/pm-r8a7790.h |  72 +++++++
>  arch/arm/mach-rmobile/psci.c       | 193 ++++++++++++++++++
>  include/configs/lager.h            |   2 +
>  include/configs/stout.h            |   2 +
>  7 files changed, 685 insertions(+)
>  create mode 100644 arch/arm/mach-rmobile/pm-r8a7790.c
>  create mode 100644 arch/arm/mach-rmobile/pm-r8a7790.h
>  create mode 100644 arch/arm/mach-rmobile/psci.c
> 
> diff --git a/arch/arm/mach-rmobile/Kconfig.32 
> b/arch/arm/mach-rmobile/Kconfig.32
> index a2e9e3d..728c323 100644
> --- a/arch/arm/mach-rmobile/Kconfig.32
> +++ b/arch/arm/mach-rmobile/Kconfig.32
> @@ -78,6 +78,7 @@ config TARGET_LAGER
>       imply CMD_DM
>       select CPU_V7_HAS_NONSEC
>       select CPU_V7_HAS_VIRT
> +     select ARCH_SUPPORT_PSCI
>  
>  config TARGET_KZM9G
>       bool "KZM9D board"
> @@ -119,6 +120,7 @@ config TARGET_STOUT
>       imply CMD_DM
>       select CPU_V7_HAS_NONSEC
>       select CPU_V7_HAS_VIRT
> +     select ARCH_SUPPORT_PSCI
>  
>  endchoice
>  
> diff --git a/arch/arm/mach-rmobile/Makefile b/arch/arm/mach-rmobile/Makefile
> index 1f26ada..6f4c513 100644
> --- a/arch/arm/mach-rmobile/Makefile
> +++ b/arch/arm/mach-rmobile/Makefile
> @@ -13,3 +13,9 @@ obj-$(CONFIG_SH73A0) += lowlevel_init.o cpu_info-sh73a0.o 
> pfc-sh73a0.o
>  obj-$(CONFIG_R8A7740) += lowlevel_init.o cpu_info-r8a7740.o pfc-r8a7740.o
>  obj-$(CONFIG_RCAR_GEN2) += lowlevel_init_ca15.o cpu_info-rcar.o
>  obj-$(CONFIG_RCAR_GEN3) += lowlevel_init_gen3.o cpu_info-rcar.o memmap-gen3.o
> +
> +ifndef CONFIG_SPL_BUILD
> +ifdef CONFIG_R8A7790
> +obj-$(CONFIG_ARMV7_PSCI) += psci.o pm-r8a7790.o
> +endif
> +endif
> diff --git a/arch/arm/mach-rmobile/pm-r8a7790.c 
> b/arch/arm/mach-rmobile/pm-r8a7790.c
> new file mode 100644
> index 0000000..c635cf6
> --- /dev/null
> +++ b/arch/arm/mach-rmobile/pm-r8a7790.c
> @@ -0,0 +1,408 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * CPU power management support for Renesas r8a7790 SoC
> + *
> + * Contains functions to control ARM Cortex A15/A7 cores and
> + * related peripherals basically used for PSCI.
> + *
> + * Copyright (C) 2018 EPAM Systems Inc.
> + *
> + * Mainly based on Renesas R-Car Gen2 platform code from Linux:
> + *    arch/arm/mach-shmobile/...
> + */
> +
> +#include <common.h>
> +#include <asm/secure.h>
> +#include <asm/io.h>
> +
> +#include "pm-r8a7790.h"
> +
> +/*****************************************************************************

I'd expect checkpatch to complain about these long lines of asterisks.

> + * APMU definitions
> + 
> *****************************************************************************/
> +#define CA15_APMU_BASE       0xe6152000
> +#define CA7_APMU_BASE        0xe6151000

All these addresses should come from DT. And the driver should be DM
capable and live in drivers/

[...]

> +/*****************************************************************************
> + * Functions which intended to be called from PSCI handlers. These functions
> + * marked as __secure and are placed in .secure section.
> + 
> *****************************************************************************/
> +void __secure r8a7790_apmu_power_on(int cpu)
> +{
> +     int cluster = r8a7790_cluster_id(cpu);
> +     u32 apmu_base;
> +
> +     apmu_base = cluster == 0 ? CA15_APMU_BASE : CA7_APMU_BASE;
> +
> +     /* Request power on */
> +     writel(BIT(r8a7790_core_id(cpu)), apmu_base + WUPCR_OFFS);

wait_for_bit of some sorts ?

> +     /* Wait for APMU to finish */
> +     while (readl(apmu_base + WUPCR_OFFS))
> +             ;

Can this spin forever ?

> +}
> +
> +void __secure r8a7790_apmu_power_off(int cpu)
> +{
> +     int cluster = r8a7790_cluster_id(cpu);
> +     u32 apmu_base;
> +
> +     apmu_base = cluster == 0 ? CA15_APMU_BASE : CA7_APMU_BASE;
> +
> +     /* Request Core Standby for next WFI */
> +     writel(CPUPWR_STANDBY, apmu_base + CPUNCR_OFFS(r8a7790_core_id(cpu)));
> +}
> +
> +void __secure r8a7790_assert_reset(int cpu)
> +{
> +     int cluster = r8a7790_cluster_id(cpu);
> +     u32 mask, magic, rescnt;
> +
> +     mask = BIT(3 - r8a7790_core_id(cpu));
> +     magic = cluster == 0 ? CA15RESCNT_CODE : CA7RESCNT_CODE;
> +     rescnt = RST_BASE + (cluster == 0 ? CA15RESCNT : CA7RESCNT);
> +     writel((readl(rescnt) | mask) | magic, rescnt);
> +}
> +
> +void __secure r8a7790_deassert_reset(int cpu)
> +{
> +     int cluster = r8a7790_cluster_id(cpu);
> +     u32 mask, magic, rescnt;
> +
> +     mask = BIT(3 - r8a7790_core_id(cpu));
> +     magic = cluster == 0 ? CA15RESCNT_CODE : CA7RESCNT_CODE;
> +     rescnt = RST_BASE + (cluster == 0 ? CA15RESCNT : CA7RESCNT);
> +     writel((readl(rescnt) & ~mask) | magic, rescnt);
> +}
> +
> +void __secure r8a7790_system_reset(void)
> +{
> +     u32 bar;
> +
> +     /*
> +      * Before configuring internal watchdog timer (RWDT) to reboot system
> +      * we need to re-program BAR registers for the boot CPU to jump to
> +      * bootrom code. Without taking care of, the boot CPU will jump to
> +      * the reset vector previously installed in ICRAM1, since BAR registers
> +      * keep their values after watchdog triggered reset.
> +      */
> +     bar = (BOOTROM >> 8) & 0xfffffc00;
> +     writel(bar, RST_BASE + CA15BAR);
> +     writel(bar | SBAR_BAREN, RST_BASE + CA15BAR);
> +     writel(bar, RST_BASE + CA7BAR);
> +     writel(bar | SBAR_BAREN, RST_BASE + CA7BAR);
> +     dsb();
> +
> +     /* Now, configure watchdog timer to reboot the system */
> +
> +     /* Trigger reset when counter overflows */
> +     writel(WDTRSTCR_CODE | 0x2, RST_BASE + WDTRSTCR);
> +     dsb();
> +
> +     /* Stop counter */
> +     writel(RWTCSRA_CODE, RWDT_BASE + RWTCSRA);
> +
> +     /* Initialize counter with the highest value  */
> +     writel(RWTCNT_CODE | 0xffff, RWDT_BASE + RWTCNT);
> +
> +     while (readb(RWDT_BASE + RWTCSRA) & RWTCSRA_WRFLG)
> +             ;
> +
> +     /* Start counter */
> +     writel(RWTCSRA_CODE | RWTCSRA_TME, RWDT_BASE + RWTCSRA);

This seems to reimplement the reset code that's in U-Boot already. Why ?

> +}
> +
> +/*****************************************************************************
> + * Functions which intended to be called from PSCI board initialization.
> + 
> *****************************************************************************/
> +static int sysc_power_up(int scu)
> +{
> +     u32 status, chan_offs, isr_bit;
> +     int i, j, ret = 0;
> +
> +     if (scu == CA15_SCU) {
> +             chan_offs = CA15_SCU_CHAN_OFFS;
> +             isr_bit = CA15_SCU_ISR_BIT;
> +     } else {
> +             chan_offs = CA7_SCU_CHAN_OFFS;
> +             isr_bit = CA7_SCU_ISR_BIT;
> +     }
> +
> +     writel(BIT(isr_bit), SYSC_BASE + SYSCISCR);
> +
> +     /* Submit power resume request until it was accepted */
> +     for (i = 0; i < PWRER_RETRIES; i++) {
> +             /* Wait until SYSC is ready to accept a power resume request */
> +             for (j = 0; j < SYSCSR_RETRIES; j++) {
> +                     if (readl(SYSC_BASE + SYSCSR) & BIT(1))
> +                             break;
> +
> +                     udelay(SYSCSR_DELAY_US);
> +             }
> +
> +             if (j == SYSCSR_RETRIES)
> +                     return -EAGAIN;
> +
> +             /* Submit power resume request */
> +             writel(BIT(0), SYSC_BASE + chan_offs + PWRONCR_OFFS);
> +
> +             /* Check if power resume request was accepted */
> +             status = readl(SYSC_BASE + chan_offs + PWRER_OFFS);
> +             if (!(status & BIT(0)))
> +                     break;
> +
> +             udelay(PWRER_DELAY_US);
> +     }
> +
> +     if (i == PWRER_RETRIES)
> +             return -EIO;
> +
> +     /* Wait until the power resume request has completed */
> +     for (i = 0; i < SYSCISR_RETRIES; i++) {
> +             if (readl(SYSC_BASE + SYSCISR) & BIT(isr_bit))
> +                     break;
> +             udelay(SYSCISR_DELAY_US);
> +     }
> +
> +     if (i == SYSCISR_RETRIES)
> +             ret = -EIO;
> +
> +     writel(BIT(isr_bit), SYSC_BASE + SYSCISCR);
> +
> +     return ret;
> +}
> +
> +static bool sysc_power_is_off(int scu)
> +{
> +     u32 status, chan_offs;
> +
> +     chan_offs = scu == CA15_SCU ? CA15_SCU_CHAN_OFFS : CA7_SCU_CHAN_OFFS;
> +
> +     /* Check if SCU is in power shutoff state */
> +     status = readl(SYSC_BASE + chan_offs + PWRSR_OFFS);
> +     if (status & BIT(0))
> +             return true;
> +
> +     return false;
> +}
> +
> +static void apmu_setup_debug_mode(int cpu)
> +{
> +     int cluster = r8a7790_cluster_id(cpu);
> +     u32 apmu_base, reg;
> +
> +     apmu_base = cluster == 0 ? CA15_APMU_BASE : CA7_APMU_BASE;
> +
> +     /*
> +      * Enable reset requests derived from power shutoff to the AP-system
> +      * CPU cores in debug mode. Without taking care of, they may fail to
> +      * resume from the power shutoff state.
> +      */
> +     reg = readl(apmu_base + DBGRCR_OFFS);
> +     reg |= DBGCPUREN | DBGCPUNREN(r8a7790_core_id(cpu)) | DBGCPUPREN;
> +     writel(reg, apmu_base + DBGRCR_OFFS);

setbits_le32()

> +}
> +
> +/*
> + * Reset vector for secondary CPUs.
> + * This will be mapped at address 0 by SBAR register.
> + * We need _long_ jump to the physical address.
> + */
> +asm("        .arm\n"
> +     "       .align 12\n"
> +     "       .globl shmobile_boot_vector\n"
> +     "shmobile_boot_vector:\n"
> +     "       ldr r1, 1f\n"
> +     "       bx      r1\n"
> +     "       .type shmobile_boot_vector, %function\n"
> +     "       .size shmobile_boot_vector, .-shmobile_boot_vector\n"
> +     "       .align  2\n"
> +     "       .globl  shmobile_boot_fn\n"
> +     "shmobile_boot_fn:\n"
> +     "1:     .space  4\n"
> +     "       .globl  shmobile_boot_size\n"
> +     "shmobile_boot_size:\n"
> +     "       .long   .-shmobile_boot_vector\n");

Why can't this be implemented in C ?

> +extern void shmobile_boot_vector(void);
> +extern unsigned long shmobile_boot_fn;
> +extern unsigned long shmobile_boot_size;

Are the externs necessary ?

> +void r8a7790_prepare_cpus(unsigned long addr, u32 nr_cpus)
> +{
> +     int cpu = get_current_cpu();
> +     int i, ret = 0;
> +     u32 bar;
> +
> +     shmobile_boot_fn = addr;
> +     dsb();
> +
> +     /* Install reset vector */
> +     memcpy_toio((void __iomem *)ICRAM1, shmobile_boot_vector,
> +                 shmobile_boot_size);
> +     dmb();

Does this take into consideration caches ?

> +     /* Setup reset vectors */
> +     bar = (ICRAM1 >> 8) & 0xfffffc00;
> +     writel(bar, RST_BASE + CA15BAR);
> +     writel(bar | SBAR_BAREN, RST_BASE + CA15BAR);
> +     writel(bar, RST_BASE + CA7BAR);
> +     writel(bar | SBAR_BAREN, RST_BASE + CA7BAR);
> +     dsb();
> +
> +     /* Perform setup for debug mode for all CPUs */
> +     for (i = 0; i < nr_cpus; i++)
> +             apmu_setup_debug_mode(i);
> +
> +     /*
> +      * Indicate the completion status of power shutoff/resume procedure
> +      * for CA15/CA7 SCU.
> +      */
> +     writel(BIT(CA15_SCU_ISR_BIT) | BIT(CA7_SCU_ISR_BIT),
> +            SYSC_BASE + SYSCIER);
> +
> +     /* Power on CA15/CA7 SCU */
> +     if (sysc_power_is_off(CA15_SCU))
> +             ret += sysc_power_up(CA15_SCU);
> +     if (sysc_power_is_off(CA7_SCU))
> +             ret += sysc_power_up(CA7_SCU);
> +     if (ret)
> +             printf("warning: some of secondary CPUs may not boot\n");

"some" is not very useful for debugging,.

> +     /* Keep secondary CPUs in reset */
> +     for (i = 0; i < nr_cpus; i++) {
> +             /* Make sure that we don't reset boot CPU */
> +             if (i == cpu)
> +                     continue;
> +
> +             r8a7790_assert_reset(i);
> +     }
> +
> +     /*
> +      * Enable snoop requests and DVM message requests for slave interfaces
> +      * S4 (CA7) and S3 (CA15).
> +      */
> +     writel(readl(CCI_BASE + CCI_SLAVE3 + CCI_SNOOP) | CCI_ENABLE_REQ,
> +            CCI_BASE + CCI_SLAVE3 + CCI_SNOOP);
> +     writel(readl(CCI_BASE + CCI_SLAVE4 + CCI_SNOOP) | CCI_ENABLE_REQ,
> +            CCI_BASE + CCI_SLAVE4 + CCI_SNOOP);
> +     /* Wait for pending bit low */
> +     while (readl(CCI_BASE + CCI_STATUS))
> +             ;

can this spin forever ?

> +}
> diff --git a/arch/arm/mach-rmobile/pm-r8a7790.h 
> b/arch/arm/mach-rmobile/pm-r8a7790.h
> new file mode 100644
> index 0000000..f649dd8
> --- /dev/null
> +++ b/arch/arm/mach-rmobile/pm-r8a7790.h
> @@ -0,0 +1,72 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2018 EPAM Systems Inc.
> + */
> +
> +#ifndef __PM_R8A7790_H__
> +#define __PM_R8A7790_H__
> +
> +#include <linux/types.h>
> +
> +void r8a7790_apmu_power_on(int cpu);
> +void r8a7790_apmu_power_off(int cpu);
> +void r8a7790_assert_reset(int cpu);
> +void r8a7790_deassert_reset(int cpu);
> +
> +void r8a7790_prepare_cpus(unsigned long addr, u32 nr_cpus);
> +void r8a7790_system_reset(void);
> +
> +#define R8A7790_NR_CLUSTERS                          2
> +#define R8A7790_NR_CPUS_PER_CLUSTER          4
> +
> +/* Convert linear CPU index to core/cluster ID */
> +#define r8a7790_cluster_id(cpu)      ((cpu) / R8A7790_NR_CPUS_PER_CLUSTER)
> +#define r8a7790_core_id(cpu) ((cpu) % R8A7790_NR_CPUS_PER_CLUSTER)
> +
> +#define MPIDR_AFFLVL_MASK    GENMASK(7, 0)
> +#define MPIDR_AFF0_SHIFT     0
> +#define MPIDR_AFF1_SHIFT     8
> +
> +/* All functions are inline so that they can be called from .secure section. 
> */
> +
> +/*
> + * Convert CPU ID in MPIDR format to linear CPU index.
> + *
> + * Below the possible CPU IDs and corresponding CPU indexes:
> + * CPU ID       CPU index
> + * 0x80000000 - 0x00000000
> + * 0x80000001 - 0x00000001
> + * 0x80000002 - 0x00000002
> + * 0x80000003 - 0x00000003
> + * 0x80000100 - 0x00000004
> + * 0x80000101 - 0x00000005
> + * 0x80000102 - 0x00000006
> + * 0x80000103 - 0x00000007
> + */
> +static inline int mpidr_to_cpu_index(u32 mpidr)
> +{
> +     u32 cluster_id, cpu_id;
> +
> +     cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
> +     cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
> +
> +     if (cluster_id >= R8A7790_NR_CLUSTERS)
> +             return -1;
> +
> +     if (cpu_id >= R8A7790_NR_CPUS_PER_CLUSTER)
> +             return -1;
> +
> +     return (cpu_id + (cluster_id * R8A7790_NR_CPUS_PER_CLUSTER));
> +}
> +
> +/* Return an index of the CPU which performs this call */
> +static inline int get_current_cpu(void)
> +{
> +     u32 mpidr;
> +
> +     asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r"(mpidr));
> +
> +     return mpidr_to_cpu_index(mpidr);
> +}
> +
> +#endif /* __PM_R8A7790_H__ */
> diff --git a/arch/arm/mach-rmobile/psci.c b/arch/arm/mach-rmobile/psci.c
> new file mode 100644
> index 0000000..95850b8
> --- /dev/null
> +++ b/arch/arm/mach-rmobile/psci.c
> @@ -0,0 +1,193 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * This file implements basic PSCI support for Renesas r8a7790 SoC
> + *
> + * Copyright (C) 2018 EPAM Systems Inc.
> + *
> + * Based on arch/arm/mach-uniphier/arm32/psci.c
> + */
> +
> +#include <common.h>
> +#include <linux/psci.h>
> +#include <asm/io.h>
> +#include <asm/psci.h>
> +#include <asm/secure.h>
> +
> +#include "pm-r8a7790.h"
> +
> +#define R8A7790_PSCI_NR_CPUS 8
> +#if R8A7790_PSCI_NR_CPUS > CONFIG_ARMV7_PSCI_NR_CPUS
> +#error "invalid value for CONFIG_ARMV7_PSCI_NR_CPUS"
> +#endif
> +
> +#define GICC_CTLR_OFFSET     0x2000
> +
> +/*
> + * The boot CPU is powered on by default, but it's index is not a const
> + * value. An index the boot CPU has, depends on whether it is CA15 (index 0)
> + * or CA7 (index 4).
> + * So, we update state for the boot CPU during PSCI board initialization.
> + */
> +u8 psci_state[R8A7790_PSCI_NR_CPUS] __secure_data = {
> +             PSCI_AFFINITY_LEVEL_OFF,
> +             PSCI_AFFINITY_LEVEL_OFF,
> +             PSCI_AFFINITY_LEVEL_OFF,
> +             PSCI_AFFINITY_LEVEL_OFF,
> +             PSCI_AFFINITY_LEVEL_OFF,
> +             PSCI_AFFINITY_LEVEL_OFF,
> +             PSCI_AFFINITY_LEVEL_OFF,
> +             PSCI_AFFINITY_LEVEL_OFF};
> +
> +void __secure psci_set_state(int cpu, u8 state)
> +{
> +     psci_state[cpu] = state;
> +     dsb();
> +     isb();
> +}
> +
> +u32 __secure psci_get_cpu_id(void)
> +{
> +     return get_current_cpu();
> +}
> +
> +void __secure psci_arch_cpu_entry(void)
> +{
> +     int cpu = get_current_cpu();
> +
> +     psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON);
> +}
> +
> +int __secure psci_features(u32 function_id, u32 psci_fid)
> +{
> +     switch (psci_fid) {
> +     case ARM_PSCI_0_2_FN_PSCI_VERSION:
> +     case ARM_PSCI_0_2_FN_CPU_OFF:
> +     case ARM_PSCI_0_2_FN_CPU_ON:
> +     case ARM_PSCI_0_2_FN_AFFINITY_INFO:
> +     case ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
> +     case ARM_PSCI_0_2_FN_SYSTEM_OFF:
> +     case ARM_PSCI_0_2_FN_SYSTEM_RESET:
> +             return 0x0;
> +     }
> +
> +     return ARM_PSCI_RET_NI;
> +}
> +
> +u32 __secure psci_version(u32 function_id)
> +{
> +     return ARM_PSCI_VER_1_0;
> +}
> +
> +int __secure psci_affinity_info(u32 function_id, u32 target_affinity,
> +                             u32 lowest_affinity_level)
> +{
> +     int cpu;
> +
> +     if (lowest_affinity_level > 0)
> +             return ARM_PSCI_RET_INVAL;
> +
> +     cpu = mpidr_to_cpu_index(target_affinity);
> +     if (cpu == -1)
> +             return ARM_PSCI_RET_INVAL;
> +
> +     /* TODO flush cache */
> +     return psci_state[cpu];
> +}
> +
> +int __secure psci_migrate_info_type(u32 function_id)
> +{
> +     /* Trusted OS is either not present or does not require migration */
> +     return 2;
> +}
> +
> +int __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 entry_point,
> +                      u32 context_id)
> +{
> +     int cpu;
> +
> +     cpu = mpidr_to_cpu_index(target_cpu);
> +     if (cpu == -1)
> +             return ARM_PSCI_RET_INVAL;
> +
> +     if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON)
> +             return ARM_PSCI_RET_ALREADY_ON;
> +
> +     if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON_PENDING)
> +             return ARM_PSCI_RET_ON_PENDING;
> +
> +     psci_save(cpu, entry_point, context_id);
> +
> +     psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON_PENDING);
> +
> +     r8a7790_assert_reset(cpu);
> +     r8a7790_apmu_power_on(cpu);
> +     r8a7790_deassert_reset(cpu);
> +
> +     return ARM_PSCI_RET_SUCCESS;
> +}
> +
> +int __secure psci_cpu_off(void)
> +{
> +     int cpu = get_current_cpu();
> +
> +     /*
> +      * Place the CPU interface in a state where it can never make a CPU
> +      * exit WFI as result of an asserted interrupt.
> +      */
> +     writel(0, CONFIG_ARM_GIC_BASE_ADDRESS + GICC_CTLR_OFFSET);
> +     dsb();
> +
> +     /* Select next sleep mode using the APMU */
> +     r8a7790_apmu_power_off(cpu);
> +
> +     /* Do ARM specific CPU shutdown */
> +     psci_cpu_off_common();
> +
> +     psci_set_state(cpu, PSCI_AFFINITY_LEVEL_OFF);
> +
> +     /* Drain the WB before WFI */
> +     dsb();
> +
> +     while (1)
> +             wfi();
> +}
> +
> +void __secure psci_system_reset(u32 function_id)
> +{
> +     r8a7790_system_reset();
> +
> +     /* Drain the WB before WFI */
> +     dsb();
> +
> +     /* The system is about to be rebooted, so just waiting for this */
> +     while (1)
> +             wfi();
> +}
> +
> +void __secure psci_system_off(u32 function_id)
> +{
> +     /* Drain the WB before WFI */
> +     dsb();
> +
> +     /*
> +      * System Off is not implemented yet, so waiting for powering off
> +      * manually
> +      */
> +     while (1)
> +             wfi();
> +}
> +
> +void psci_board_init(void)
> +{
> +     int cpu = get_current_cpu();
> +
> +     /* Update state for the boot CPU */
> +     psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON);
> +
> +     /*
> +      * Perform needed actions for the secondary CPUs to be ready
> +      * for powering on
> +      */
> +     r8a7790_prepare_cpus((unsigned long)psci_cpu_entry,
> +                          R8A7790_PSCI_NR_CPUS);
> +}
> diff --git a/include/configs/lager.h b/include/configs/lager.h
> index d8a0b01..d70c147 100644
> --- a/include/configs/lager.h
> +++ b/include/configs/lager.h
> @@ -51,4 +51,6 @@
>  /* The PERIPHBASE in the CBAR register is wrong, so override it */
>  #define CONFIG_ARM_GIC_BASE_ADDRESS          0xf1000000
>  
> +#define CONFIG_ARMV7_PSCI_1_0

Why is this in board code, shouldn't that be in platform code ?


[...]

-- 
Best regards,
Marek Vasut
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to