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> 12*4ec1a239SAndre Przywara #include <sunxi_private.h> 13333d66cfSSamuel Holland #include <utils_def.h> 14333d66cfSSamuel Holland 15333d66cfSSamuel Holland static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core) 16333d66cfSSamuel Holland { 17333d66cfSSamuel Holland if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff) 18333d66cfSSamuel Holland return; 19333d66cfSSamuel Holland 2027f9616fSAndre Przywara VERBOSE("PSCI: Disabling power to cluster %d core %d\n", cluster, core); 21333d66cfSSamuel Holland 22333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xff); 23333d66cfSSamuel Holland } 24333d66cfSSamuel Holland 25333d66cfSSamuel Holland static void sunxi_cpu_enable_power(unsigned int cluster, unsigned int core) 26333d66cfSSamuel Holland { 27333d66cfSSamuel Holland if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0) 28333d66cfSSamuel Holland return; 29333d66cfSSamuel Holland 3027f9616fSAndre Przywara VERBOSE("PSCI: Enabling power to cluster %d core %d\n", cluster, core); 31333d66cfSSamuel Holland 32333d66cfSSamuel Holland /* Power enable sequence from original Allwinner sources */ 33333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xfe); 34333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xf8); 35333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xe0); 36333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x80); 37333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x00); 38333d66cfSSamuel Holland } 39333d66cfSSamuel Holland 40333d66cfSSamuel Holland void sunxi_cpu_off(unsigned int cluster, unsigned int core) 41333d66cfSSamuel Holland { 4227f9616fSAndre Przywara VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core); 43333d66cfSSamuel Holland 44333d66cfSSamuel Holland /* Deassert DBGPWRDUP */ 45333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); 46333d66cfSSamuel Holland /* Activate the core output clamps */ 47333d66cfSSamuel Holland mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core)); 48333d66cfSSamuel Holland /* Assert CPU power-on reset */ 49333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); 50333d66cfSSamuel Holland /* Remove power from the CPU */ 51333d66cfSSamuel Holland sunxi_cpu_disable_power(cluster, core); 52333d66cfSSamuel Holland } 53333d66cfSSamuel Holland 54333d66cfSSamuel Holland void sunxi_cpu_on(unsigned int cluster, unsigned int core) 55333d66cfSSamuel Holland { 5627f9616fSAndre Przywara VERBOSE("PSCI: Powering on cluster %d core %d\n", cluster, core); 57333d66cfSSamuel Holland 58333d66cfSSamuel Holland /* Assert CPU core reset */ 59333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); 60333d66cfSSamuel Holland /* Assert CPU power-on reset */ 61333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); 62333d66cfSSamuel Holland /* Set CPU to start in AArch64 mode */ 63333d66cfSSamuel Holland mmio_setbits_32(SUNXI_CPUCFG_CLS_CTRL_REG0(cluster), BIT(24 + core)); 64333d66cfSSamuel Holland /* Apply power to the CPU */ 65333d66cfSSamuel Holland sunxi_cpu_enable_power(cluster, core); 66333d66cfSSamuel Holland /* Release the core output clamps */ 67333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core)); 68333d66cfSSamuel Holland /* Deassert CPU power-on reset */ 69333d66cfSSamuel Holland mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); 70333d66cfSSamuel Holland /* Deassert CPU core reset */ 71333d66cfSSamuel Holland mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); 72333d66cfSSamuel Holland /* Assert DBGPWRDUP */ 73333d66cfSSamuel Holland mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); 74333d66cfSSamuel Holland } 75333d66cfSSamuel Holland 76333d66cfSSamuel Holland void sunxi_disable_secondary_cpus(unsigned int primary_cpu) 77333d66cfSSamuel Holland { 78333d66cfSSamuel Holland for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu += 1) { 79333d66cfSSamuel Holland if (cpu == primary_cpu) 80333d66cfSSamuel Holland continue; 81333d66cfSSamuel Holland sunxi_cpu_off(cpu / PLATFORM_MAX_CPUS_PER_CLUSTER, 82333d66cfSSamuel Holland cpu % PLATFORM_MAX_CPUS_PER_CLUSTER); 83333d66cfSSamuel Holland } 84333d66cfSSamuel Holland } 85