1333d66cfSSamuel Holland /* 2333d66cfSSamuel Holland * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. 3333d66cfSSamuel Holland * 4333d66cfSSamuel Holland * SPDX-License-Identifier: BSD-3-Clause 5333d66cfSSamuel Holland */ 6333d66cfSSamuel Holland 7333d66cfSSamuel Holland #include <debug.h> 8333d66cfSSamuel Holland #include <mmio.h> 9333d66cfSSamuel Holland #include <platform_def.h> 10333d66cfSSamuel Holland #include <sunxi_mmap.h> 11333d66cfSSamuel Holland #include <sunxi_cpucfg.h> 12333d66cfSSamuel Holland #include <utils_def.h> 13333d66cfSSamuel Holland 14333d66cfSSamuel Holland #include "sunxi_private.h" 15333d66cfSSamuel Holland 16333d66cfSSamuel Holland static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core) 17333d66cfSSamuel Holland { 18333d66cfSSamuel Holland if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff) 19333d66cfSSamuel Holland return; 20333d66cfSSamuel Holland 21*27f9616fSAndre Przywara VERBOSE("PSCI: Disabling power to cluster %d core %d\n", cluster, core); 22333d66cfSSamuel Holland 23333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xff); 24333d66cfSSamuel Holland } 25333d66cfSSamuel Holland 26333d66cfSSamuel Holland static void sunxi_cpu_enable_power(unsigned int cluster, unsigned int core) 27333d66cfSSamuel Holland { 28333d66cfSSamuel Holland if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0) 29333d66cfSSamuel Holland return; 30333d66cfSSamuel Holland 31*27f9616fSAndre Przywara VERBOSE("PSCI: Enabling power to cluster %d core %d\n", cluster, core); 32333d66cfSSamuel Holland 33333d66cfSSamuel Holland /* Power enable sequence from original Allwinner sources */ 34333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xfe); 35333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xf8); 36333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xe0); 37333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x80); 38333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x00); 39333d66cfSSamuel Holland } 40333d66cfSSamuel Holland 41333d66cfSSamuel Holland void sunxi_cpu_off(unsigned int cluster, unsigned int core) 42333d66cfSSamuel Holland { 43*27f9616fSAndre Przywara VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core); 44333d66cfSSamuel Holland 45333d66cfSSamuel Holland /* Deassert DBGPWRDUP */ 46333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); 47333d66cfSSamuel Holland /* Activate the core output clamps */ 48333d66cfSSamuel Holland mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core)); 49333d66cfSSamuel Holland /* Assert CPU power-on reset */ 50333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); 51333d66cfSSamuel Holland /* Remove power from the CPU */ 52333d66cfSSamuel Holland sunxi_cpu_disable_power(cluster, core); 53333d66cfSSamuel Holland } 54333d66cfSSamuel Holland 55333d66cfSSamuel Holland void sunxi_cpu_on(unsigned int cluster, unsigned int core) 56333d66cfSSamuel Holland { 57*27f9616fSAndre Przywara VERBOSE("PSCI: Powering on cluster %d core %d\n", cluster, core); 58333d66cfSSamuel Holland 59333d66cfSSamuel Holland /* Assert CPU core reset */ 60333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); 61333d66cfSSamuel Holland /* Assert CPU power-on reset */ 62333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); 63333d66cfSSamuel Holland /* Set CPU to start in AArch64 mode */ 64333d66cfSSamuel Holland mmio_setbits_32(SUNXI_CPUCFG_CLS_CTRL_REG0(cluster), BIT(24 + core)); 65333d66cfSSamuel Holland /* Apply power to the CPU */ 66333d66cfSSamuel Holland sunxi_cpu_enable_power(cluster, core); 67333d66cfSSamuel Holland /* Release the core output clamps */ 68333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core)); 69333d66cfSSamuel Holland /* Deassert CPU power-on reset */ 70333d66cfSSamuel Holland mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); 71333d66cfSSamuel Holland /* Deassert CPU core reset */ 72333d66cfSSamuel Holland mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); 73333d66cfSSamuel Holland /* Assert DBGPWRDUP */ 74333d66cfSSamuel Holland mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); 75333d66cfSSamuel Holland } 76333d66cfSSamuel Holland 77333d66cfSSamuel Holland void sunxi_disable_secondary_cpus(unsigned int primary_cpu) 78333d66cfSSamuel Holland { 79333d66cfSSamuel Holland for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu += 1) { 80333d66cfSSamuel Holland if (cpu == primary_cpu) 81333d66cfSSamuel Holland continue; 82333d66cfSSamuel Holland sunxi_cpu_off(cpu / PLATFORM_MAX_CPUS_PER_CLUSTER, 83333d66cfSSamuel Holland cpu % PLATFORM_MAX_CPUS_PER_CLUSTER); 84333d66cfSSamuel Holland } 85333d66cfSSamuel Holland } 86