1*333d66cfSSamuel Holland /* 2*333d66cfSSamuel Holland * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. 3*333d66cfSSamuel Holland * 4*333d66cfSSamuel Holland * SPDX-License-Identifier: BSD-3-Clause 5*333d66cfSSamuel Holland */ 6*333d66cfSSamuel Holland 7*333d66cfSSamuel Holland #include <debug.h> 8*333d66cfSSamuel Holland #include <mmio.h> 9*333d66cfSSamuel Holland #include <platform_def.h> 10*333d66cfSSamuel Holland #include <sunxi_mmap.h> 11*333d66cfSSamuel Holland #include <sunxi_cpucfg.h> 12*333d66cfSSamuel Holland #include <utils_def.h> 13*333d66cfSSamuel Holland 14*333d66cfSSamuel Holland #include "sunxi_private.h" 15*333d66cfSSamuel Holland 16*333d66cfSSamuel Holland static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core) 17*333d66cfSSamuel Holland { 18*333d66cfSSamuel Holland if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff) 19*333d66cfSSamuel Holland return; 20*333d66cfSSamuel Holland 21*333d66cfSSamuel Holland INFO("PSCI: Disabling power to cluster %d core %d\n", cluster, core); 22*333d66cfSSamuel Holland 23*333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xff); 24*333d66cfSSamuel Holland } 25*333d66cfSSamuel Holland 26*333d66cfSSamuel Holland static void sunxi_cpu_enable_power(unsigned int cluster, unsigned int core) 27*333d66cfSSamuel Holland { 28*333d66cfSSamuel Holland if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0) 29*333d66cfSSamuel Holland return; 30*333d66cfSSamuel Holland 31*333d66cfSSamuel Holland INFO("PSCI: Enabling power to cluster %d core %d\n", cluster, core); 32*333d66cfSSamuel Holland 33*333d66cfSSamuel Holland /* Power enable sequence from original Allwinner sources */ 34*333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xfe); 35*333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xf8); 36*333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xe0); 37*333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x80); 38*333d66cfSSamuel Holland mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x00); 39*333d66cfSSamuel Holland } 40*333d66cfSSamuel Holland 41*333d66cfSSamuel Holland void sunxi_cpu_off(unsigned int cluster, unsigned int core) 42*333d66cfSSamuel Holland { 43*333d66cfSSamuel Holland INFO("PSCI: Powering off cluster %d core %d\n", cluster, core); 44*333d66cfSSamuel Holland 45*333d66cfSSamuel Holland /* Deassert DBGPWRDUP */ 46*333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); 47*333d66cfSSamuel Holland /* Activate the core output clamps */ 48*333d66cfSSamuel Holland mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core)); 49*333d66cfSSamuel Holland /* Assert CPU power-on reset */ 50*333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); 51*333d66cfSSamuel Holland /* Remove power from the CPU */ 52*333d66cfSSamuel Holland sunxi_cpu_disable_power(cluster, core); 53*333d66cfSSamuel Holland } 54*333d66cfSSamuel Holland 55*333d66cfSSamuel Holland void sunxi_cpu_on(unsigned int cluster, unsigned int core) 56*333d66cfSSamuel Holland { 57*333d66cfSSamuel Holland INFO("PSCI: Powering on cluster %d core %d\n", cluster, core); 58*333d66cfSSamuel Holland 59*333d66cfSSamuel Holland /* Assert CPU core reset */ 60*333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); 61*333d66cfSSamuel Holland /* Assert CPU power-on reset */ 62*333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); 63*333d66cfSSamuel Holland /* Set CPU to start in AArch64 mode */ 64*333d66cfSSamuel Holland mmio_setbits_32(SUNXI_CPUCFG_CLS_CTRL_REG0(cluster), BIT(24 + core)); 65*333d66cfSSamuel Holland /* Apply power to the CPU */ 66*333d66cfSSamuel Holland sunxi_cpu_enable_power(cluster, core); 67*333d66cfSSamuel Holland /* Release the core output clamps */ 68*333d66cfSSamuel Holland mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core)); 69*333d66cfSSamuel Holland /* Deassert CPU power-on reset */ 70*333d66cfSSamuel Holland mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); 71*333d66cfSSamuel Holland /* Deassert CPU core reset */ 72*333d66cfSSamuel Holland mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); 73*333d66cfSSamuel Holland /* Assert DBGPWRDUP */ 74*333d66cfSSamuel Holland mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); 75*333d66cfSSamuel Holland } 76*333d66cfSSamuel Holland 77*333d66cfSSamuel Holland void sunxi_disable_secondary_cpus(unsigned int primary_cpu) 78*333d66cfSSamuel Holland { 79*333d66cfSSamuel Holland for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu += 1) { 80*333d66cfSSamuel Holland if (cpu == primary_cpu) 81*333d66cfSSamuel Holland continue; 82*333d66cfSSamuel Holland sunxi_cpu_off(cpu / PLATFORM_MAX_CPUS_PER_CLUSTER, 83*333d66cfSSamuel Holland cpu % PLATFORM_MAX_CPUS_PER_CLUSTER); 84*333d66cfSSamuel Holland } 85*333d66cfSSamuel Holland } 86