xref: /rk3399_ARM-atf/plat/allwinner/common/sunxi_cpu_ops.c (revision 080939f9244f1717c7bb4c32ff30fb72032d36fb)
1333d66cfSSamuel Holland /*
2a1d349beSSamuel Holland  * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
3333d66cfSSamuel Holland  *
4333d66cfSSamuel Holland  * SPDX-License-Identifier: BSD-3-Clause
5333d66cfSSamuel Holland  */
6333d66cfSSamuel Holland 
77db0c960SAndre Przywara #include <assert.h>
809d40e0eSAntonio Nino Diaz 
9333d66cfSSamuel Holland #include <platform_def.h>
1009d40e0eSAntonio Nino Diaz 
1109d40e0eSAntonio Nino Diaz #include <arch_helpers.h>
1209d40e0eSAntonio Nino Diaz #include <common/debug.h>
1309d40e0eSAntonio Nino Diaz #include <drivers/delay_timer.h>
1409d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
1509d40e0eSAntonio Nino Diaz #include <lib/utils_def.h>
1609d40e0eSAntonio Nino Diaz #include <plat/common/platform.h>
1709d40e0eSAntonio Nino Diaz 
18333d66cfSSamuel Holland #include <sunxi_cpucfg.h>
197db0c960SAndre Przywara #include <sunxi_mmap.h>
204ec1a239SAndre Przywara #include <sunxi_private.h>
21333d66cfSSamuel Holland 
22333d66cfSSamuel Holland static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core)
23333d66cfSSamuel Holland {
24333d66cfSSamuel Holland 	if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff)
25333d66cfSSamuel Holland 		return;
26333d66cfSSamuel Holland 
2727f9616fSAndre Przywara 	VERBOSE("PSCI: Disabling power to cluster %d core %d\n", cluster, core);
28333d66cfSSamuel Holland 
29333d66cfSSamuel Holland 	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xff);
30333d66cfSSamuel Holland }
31333d66cfSSamuel Holland 
32333d66cfSSamuel Holland static void sunxi_cpu_enable_power(unsigned int cluster, unsigned int core)
33333d66cfSSamuel Holland {
34333d66cfSSamuel Holland 	if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0)
35333d66cfSSamuel Holland 		return;
36333d66cfSSamuel Holland 
3727f9616fSAndre Przywara 	VERBOSE("PSCI: Enabling power to cluster %d core %d\n", cluster, core);
38333d66cfSSamuel Holland 
39333d66cfSSamuel Holland 	/* Power enable sequence from original Allwinner sources */
40333d66cfSSamuel Holland 	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xfe);
41333d66cfSSamuel Holland 	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xf8);
42333d66cfSSamuel Holland 	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xe0);
43333d66cfSSamuel Holland 	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x80);
44333d66cfSSamuel Holland 	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x00);
4586a7429eSIcenowy Zheng 	udelay(1);
46333d66cfSSamuel Holland }
47333d66cfSSamuel Holland 
48a1d349beSSamuel Holland /* We can't turn ourself off like this, but it works for other cores. */
49a1d349beSSamuel Holland static void sunxi_cpu_off(u_register_t mpidr)
50333d66cfSSamuel Holland {
515d4bd66dSSamuel Holland 	unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr);
525d4bd66dSSamuel Holland 	unsigned int core    = MPIDR_AFFLVL0_VAL(mpidr);
537db0c960SAndre Przywara 
5427f9616fSAndre Przywara 	VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core);
55333d66cfSSamuel Holland 
56333d66cfSSamuel Holland 	/* Deassert DBGPWRDUP */
57333d66cfSSamuel Holland 	mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
587db0c960SAndre Przywara 	/* Activate the core output clamps, but not for core 0. */
595d4bd66dSSamuel Holland 	if (core != 0)
60a1d349beSSamuel Holland 		mmio_setbits_32(SUNXI_POWEROFF_GATING_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 	/* Remove power from the CPU */
64333d66cfSSamuel Holland 	sunxi_cpu_disable_power(cluster, core);
657db0c960SAndre Przywara }
667db0c960SAndre Przywara 
675d4bd66dSSamuel Holland void sunxi_cpu_on(u_register_t mpidr)
68333d66cfSSamuel Holland {
695d4bd66dSSamuel Holland 	unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr);
705d4bd66dSSamuel Holland 	unsigned int core    = MPIDR_AFFLVL0_VAL(mpidr);
715d4bd66dSSamuel Holland 
7227f9616fSAndre Przywara 	VERBOSE("PSCI: Powering on cluster %d core %d\n", cluster, core);
73333d66cfSSamuel Holland 
74333d66cfSSamuel Holland 	/* Assert CPU core reset */
75333d66cfSSamuel Holland 	mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
76333d66cfSSamuel Holland 	/* Assert CPU power-on reset */
77333d66cfSSamuel Holland 	mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
78333d66cfSSamuel Holland 	/* Set CPU to start in AArch64 mode */
79*080939f9SIcenowy Zheng 	mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster),
80*080939f9SIcenowy Zheng 			BIT(SUNXI_AA64nAA32_OFFSET + core));
81333d66cfSSamuel Holland 	/* Apply power to the CPU */
82333d66cfSSamuel Holland 	sunxi_cpu_enable_power(cluster, core);
83333d66cfSSamuel Holland 	/* Release the core output clamps */
84333d66cfSSamuel Holland 	mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
85333d66cfSSamuel Holland 	/* Deassert CPU power-on reset */
86333d66cfSSamuel Holland 	mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
87333d66cfSSamuel Holland 	/* Deassert CPU core reset */
88333d66cfSSamuel Holland 	mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
89333d66cfSSamuel Holland 	/* Assert DBGPWRDUP */
90333d66cfSSamuel Holland 	mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
91333d66cfSSamuel Holland }
92333d66cfSSamuel Holland 
93a1d349beSSamuel Holland void sunxi_cpu_power_off_others(void)
94333d66cfSSamuel Holland {
95a1d349beSSamuel Holland 	u_register_t self = read_mpidr();
965d4bd66dSSamuel Holland 	unsigned int cluster;
975d4bd66dSSamuel Holland 	unsigned int core;
985d4bd66dSSamuel Holland 
995d4bd66dSSamuel Holland 	for (cluster = 0; cluster < PLATFORM_CLUSTER_COUNT; ++cluster) {
1005d4bd66dSSamuel Holland 		for (core = 0; core < PLATFORM_MAX_CPUS_PER_CLUSTER; ++core) {
1015d4bd66dSSamuel Holland 			u_register_t mpidr = (cluster << MPIDR_AFF1_SHIFT) |
1025d4bd66dSSamuel Holland 					     (core    << MPIDR_AFF0_SHIFT) |
1035d4bd66dSSamuel Holland 					     BIT(31);
104a1d349beSSamuel Holland 			if (mpidr != self)
1055d4bd66dSSamuel Holland 				sunxi_cpu_off(mpidr);
1065d4bd66dSSamuel Holland 		}
107333d66cfSSamuel Holland 	}
108333d66cfSSamuel Holland }
109