xref: /rk3399_ARM-atf/plat/allwinner/common/sunxi_cpu_ops.c (revision 4ec1a2399cf6e182ba2828a40795912d20eca1ab)
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