diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c index cbad720ff1a3bcdc44147eb94b18edb204d430c8..43c03ac511fc33a8d9419dd2fdb7d0380418b888 100644 --- a/plat/allwinner/common/sunxi_cpu_ops.c +++ b/plat/allwinner/common/sunxi_cpu_ops.c @@ -15,11 +15,14 @@ #include #include -#include #include #include #include +#ifndef SUNXI_CPUIDLE_EN_REG +#include +#endif + static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core) { if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff) @@ -72,6 +75,14 @@ void sunxi_cpu_power_off_self(void) /* Simplifies assembly, all SoCs so far are single cluster anyway. */ assert(MPIDR_AFFLVL1_VAL(mpidr) == 0); +#ifdef SUNXI_CPUIDLE_EN_REG + /* Enable the CPUIDLE hardware (only really needs to be done once). */ + mmio_write_32(SUNXI_CPUIDLE_EN_REG, 0x16aa0000); + mmio_write_32(SUNXI_CPUIDLE_EN_REG, 0xaa160001); + + /* Trigger power off for this core. */ + mmio_write_32(SUNXI_CORE_CLOSE_REG, BIT_32(core)); +#else /* * If we are supposed to turn ourself off, tell the arisc SCP * to do that work for us. The code expects the core mask to be @@ -79,6 +90,7 @@ void sunxi_cpu_power_off_self(void) */ sunxi_execute_arisc_code(arisc_core_off, sizeof(arisc_core_off), BIT_32(core)); +#endif } void sunxi_cpu_on(u_register_t mpidr) diff --git a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h index 556fb97dc516f7fff1ecbfbb8f9175626d4b1cbe..a2b94af13a9fa24f0d98a601af823a645bb64d68 100644 --- a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h +++ b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,4 +24,9 @@ #define SUNXI_CPU_POWER_CLAMP_REG(c, n) (SUNXI_R_CPUCFG_BASE + 0x0050 + \ (c) * 0x10 + (n) * 4) +#define SUNXI_CPUIDLE_EN_REG (SUNXI_R_CPUCFG_BASE + 0x0100) +#define SUNXI_CORE_CLOSE_REG (SUNXI_R_CPUCFG_BASE + 0x0104) +#define SUNXI_PWR_SW_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0140) +#define SUNXI_CONFIG_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0144) + #endif /* SUNXI_CPUCFG_H */