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