void-packages/srcpkgs/pinephone-uboot/patches/armtf/0003-allwinner-Remove-legacy-native-power-management.patch
2020-09-11 20:38:49 +07:00

902 lines
28 KiB
Diff

From 67767123b31cfbb206e3eb2b7ca845794e025ffc Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 17 May 2020 19:12:27 -0500
Subject: [PATCH 3/5] allwinner: Remove legacy native power management
Signed-off-by: Samuel Holland <samuel@sholland.org>
Change-Id: Id85732db352f811dd6d5e6064624bb4752bda0f3
---
plat/allwinner/common/allwinner-common.mk | 1 -
plat/allwinner/common/arisc_off.S | 115 -------------
plat/allwinner/common/include/sunxi_private.h | 7 -
plat/allwinner/common/sunxi_bl31_setup.c | 3 -
plat/allwinner/common/sunxi_common.c | 76 ---------
plat/allwinner/common/sunxi_cpu_ops.c | 123 --------------
plat/allwinner/common/sunxi_pm.c | 80 +++------
.../sun50i_a64/include/core_off_arisc.h | 39 -----
plat/allwinner/sun50i_a64/sunxi_power.c | 156 ++----------------
.../sun50i_h6/include/core_off_arisc.h | 39 -----
plat/allwinner/sun50i_h6/sunxi_power.c | 25 ---
11 files changed, 40 insertions(+), 624 deletions(-)
delete mode 100644 plat/allwinner/common/arisc_off.S
delete mode 100644 plat/allwinner/common/sunxi_cpu_ops.c
delete mode 100644 plat/allwinner/sun50i_a64/include/core_off_arisc.h
delete mode 100644 plat/allwinner/sun50i_h6/include/core_off_arisc.h
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index e60ebc6f2..617eb6de2 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -31,7 +31,6 @@ BL31_SOURCES += drivers/allwinner/axp/common.c \
plat/common/plat_gicv2.c \
plat/common/plat_psci_common.c \
${AW_PLAT}/common/sunxi_bl31_setup.c \
- ${AW_PLAT}/common/sunxi_cpu_ops.c \
${AW_PLAT}/common/sunxi_pm.c \
${AW_PLAT}/${PLAT}/sunxi_power.c \
${AW_PLAT}/common/sunxi_security.c \
diff --git a/plat/allwinner/common/arisc_off.S b/plat/allwinner/common/arisc_off.S
deleted file mode 100644
index ed10832c9..000000000
--- a/plat/allwinner/common/arisc_off.S
+++ /dev/null
@@ -1,115 +0,0 @@
-# turn_off_core.S
-#
-# Copyright (c) 2018, Andre Przywara <osp@andrep.de>
-# SPDX-License-Identifier: BSD-3-Clause
-#
-# OpenRISC assembly to turn off an ARM core on an Allwinner SoC from
-# the arisc management controller.
-# Generate a binary representation with:
-# $ or1k-elf-as -c -o turn_off_core.o turn_off_core.S
-# $ or1k-elf-objcopy -O binary --reverse-bytes=4 turn_off_core.o \
-# turn_off_core.bin
-# The encoded instructions go into an array defined in
-# plat/allwinner/sun50i_*/include/core_off_arisc.h, to be handed off to
-# the arisc processor.
-#
-# This routine is meant to be called directly from arisc reset (put the
-# start address in the reset vector), to be actually triggered by that
-# very ARM core to be turned off.
-# It expects the core number presented as a mask in the upper half of
-# r3, so to be patched in the lower 16 bits of the first instruction,
-# overwriting the 0 in this code here.
-# The code will do the following:
-# - Read the C_CPU_STATUS register, which contains the status of the WFI
-# lines of each of the four A53 cores.
-# - Loop until the core in question reaches WFI.
-# - Using that mask, activate the core output clamps by setting the
-# respective core bit in CPUX_PWROFF_GATING_REG (0x1f01500).
-# Note that the clamp for core 0 covers more than just the core, activating
-# it hangs the whole system. So we skip this step for core 0.
-# - Using the negated mask, assert the core's reset line by clearing the
-# respective bit in C_RST_CTRL (0x1f01c30).
-# - Finally turn off the core's power switch by writing 0xff to the
-# respective CPUx_PWR_SWITCH_REG (0x1f01540 ff.)
-# - Assert the arisc's own reset to end execution.
-# This also signals other arisc users that the chip is free again.
-# So in C this would look like:
-# while (!(readl(0x1700030) & (1U << core_nr)))
-# ;
-# if (core_nr != 0)
-# writel(readl(0x1f01500) | (1U << core_nr), 0x1f01500);
-# writel(readl(0x1f01c30) & ~(1U << core_nr), 0x1f01c30);
-# writel(0xff, 0x1f01540 + (core_nr * 4));
-# (using A64/H5 addresses)
-
-.text
-_start:
- l.movhi r3, 0 # FIXUP! with core mask
- l.movhi r0, 0 # clear r0
- l.movhi r13, 0x170 # r13: CPU_CFG_BASE=0x01700000
-wait_wfi:
- l.lwz r5, 0x30(r13) # load C_CPU_STATUS
- l.and r5, r5, r3 # mask requested core
- l.sfeq r5, r0 # is it not yet in WFI?
- l.bf wait_wfi # try again
-
- l.srli r6, r3, 16 # move mask to lower 16 bits
- l.sfeqi r6, 1 # core 0 is special
- l.bf 1f # don't touch the bit for core 0
- l.movhi r13, 0x1f0 # address of R_CPUCFG (delay)
- l.lwz r5, 0x1500(r13) # core output clamps
- l.or r5, r5, r6 # set bit to ...
- l.sw 0x1500(r13), r5 # ... activate for our core
-
-1: l.lwz r5, 0x1c30(r13) # CPU power-on reset
- l.xori r6, r6, -1 # negate core mask
- l.and r5, r5, r6 # clear bit to ...
- l.sw 0x1c30(r13), r5 # ... assert for our core
-
- l.ff1 r6, r3 # get core number from high mask
- l.addi r6, r6, -17 # convert to 0-3
- l.slli r6, r6, 2 # r5: core number*4 (0-12)
- l.add r6, r6, r13 # add to base address
- l.ori r5, r0, 0xff # 0xff means all switches off
- l.sw 0x1540(r6), r5 # core power switch registers
-
-reset: l.sw 0x1c00(r13),r0 # pull down our own reset line
-
- l.j reset # just in case ....
- l.nop 0x0 # (delay slot)
-
-# same as above, but with the MMIO addresses matching the H6 SoC
-_start_h6:
- l.movhi r3, 0 # FIXUP! with core mask
- l.movhi r0, 0 # clear r0
- l.movhi r13, 0x901 # r13: CPU_CFG_BASE=0x09010000
-1:
- l.lwz r5, 0x80(r13) # load C_CPU_STATUS
- l.and r5, r5, r3 # mask requested core
- l.sfeq r5, r0 # is it not yet in WFI?
- l.bf 1b # try again
-
- l.srli r6, r3, 16 # move mask to lower 16 bits(ds)
- l.sfeqi r6, 1 # core 0 is special
- l.bf 1f # don't touch the bit for core 0
- l.movhi r13, 0x700 # address of R_CPUCFG (ds)
- l.lwz r5, 0x0444(r13) # core output clamps
- l.or r5, r5, r6 # set bit to ...
- l.sw 0x0444(r13), r5 # ... activate for our core
-
-1: l.lwz r5, 0x0440(r13) # CPU power-on reset
- l.xori r6, r6, -1 # negate core mask
- l.and r5, r5, r6 # clear bit to ...
- l.sw 0x0440(r13), r5 # ... assert for our core
-
- l.ff1 r6, r3 # get core number from high mask
- l.addi r6, r6, -17 # convert to 0-3
- l.slli r6, r6, 2 # r5: core number*4 (0-12)
- l.add r6, r6, r13 # add to base address
- l.ori r5, r0, 0xff # 0xff means all switches off
- l.sw 0x0450(r6), r5 # core power switch registers
-
-1: l.sw 0x0400(r13),r0 # pull down our own reset line
-
- l.j 1b # just in case ...
- l.nop 0x0 # (delay slot)
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index dcf3dc965..7b6cff07c 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -9,17 +9,10 @@
void sunxi_configure_mmu_el3(int flags);
-void sunxi_cpu_on(u_register_t mpidr);
-void sunxi_cpu_off(u_register_t mpidr);
-void sunxi_disable_secondary_cpus(u_register_t primary_mpidr);
-void sunxi_power_down(void);
-
int sunxi_pmic_setup(uint16_t socid, const void *fdt);
void sunxi_security_setup(void);
uint16_t sunxi_read_soc_id(void);
-void sunxi_set_gpio_out(char port, int pin, bool level_high);
int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb);
-void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param);
#endif /* SUNXI_PRIVATE_H */
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index e836a345b..fe511d02c 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -100,9 +100,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-
- /* Turn off all secondary CPUs */
- sunxi_disable_secondary_cpus(read_mpidr());
}
void bl31_plat_arch_setup(void)
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 0ca18adc3..61826c6af 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -82,35 +82,6 @@ uint16_t sunxi_read_soc_id(void)
return reg >> 16;
}
-/*
- * Configure a given pin to the GPIO-OUT function and sets its level.
- * The port is given as a capital letter, the pin is the number within
- * this port group.
- * So to set pin PC7 to high, use: sunxi_set_gpio_out('C', 7, true);
- */
-void sunxi_set_gpio_out(char port, int pin, bool level_high)
-{
- uintptr_t port_base;
-
- if (port < 'A' || port > 'L')
- return;
- if (port == 'L')
- port_base = SUNXI_R_PIO_BASE;
- else
- port_base = SUNXI_PIO_BASE + (port - 'A') * 0x24;
-
- /* Set the new level first before configuring the pin. */
- if (level_high)
- mmio_setbits_32(port_base + 0x10, BIT(pin));
- else
- mmio_clrbits_32(port_base + 0x10, BIT(pin));
-
- /* configure pin as GPIO out (4(3) bits per pin, 1: GPIO out */
- mmio_clrsetbits_32(port_base + (pin / 8) * 4,
- 0x7 << ((pin % 8) * 4),
- 0x1 << ((pin % 8) * 4));
-}
-
int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb)
{
uint32_t pin_func = 0x77;
@@ -165,50 +136,3 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb)
return 0;
}
-
-/* This lock synchronises access to the arisc management processor. */
-DEFINE_BAKERY_LOCK(arisc_lock);
-
-/*
- * Tell the "arisc" SCP core (an OpenRISC core) to execute some code.
- * We don't have any service running there, so we place some OpenRISC code
- * in SRAM, put the address of that into the reset vector and release the
- * arisc reset line. The SCP will execute that code and pull the line up again.
- */
-void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param)
-{
- uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE + 0x100;
-
- do {
- bakery_lock_get(&arisc_lock);
- /* Wait until the arisc is in reset state. */
- if (!(mmio_read_32(SUNXI_R_CPUCFG_BASE) & BIT(0)))
- break;
-
- bakery_lock_release(&arisc_lock);
- } while (1);
-
- /* Patch up the code to feed in an input parameter. */
- code[0] = (code[0] & ~0xffff) | param;
- clean_dcache_range((uintptr_t)code, size);
-
- /*
- * The OpenRISC unconditional branch has opcode 0, the branch offset
- * is in the lower 26 bits, containing the distance to the target,
- * in instruction granularity (32 bits).
- */
- mmio_write_32(arisc_reset_vec, ((uintptr_t)code - arisc_reset_vec) / 4);
- clean_dcache_range(arisc_reset_vec, 4);
-
- /* De-assert the arisc reset line to let it run. */
- mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0));
-
- /*
- * We release the lock here, although the arisc is still busy.
- * But as long as it runs, the reset line is high, so other users
- * won't leave the loop above.
- * Once it has finished, the code is supposed to clear the reset line,
- * to signal this to other users.
- */
- bakery_lock_release(&arisc_lock);
-}
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
deleted file mode 100644
index 6e29b69bf..000000000
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <platform_def.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <drivers/delay_timer.h>
-#include <lib/mmio.h>
-#include <lib/utils_def.h>
-#include <plat/common/platform.h>
-
-#include <core_off_arisc.h>
-#include <sunxi_cpucfg.h>
-#include <sunxi_mmap.h>
-#include <sunxi_private.h>
-
-static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core)
-{
- if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff)
- return;
-
- VERBOSE("PSCI: Disabling power to cluster %d core %d\n", cluster, core);
-
- mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xff);
-}
-
-static void sunxi_cpu_enable_power(unsigned int cluster, unsigned int core)
-{
- if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0)
- return;
-
- VERBOSE("PSCI: Enabling power to cluster %d core %d\n", cluster, core);
-
- /* Power enable sequence from original Allwinner sources */
- mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xfe);
- mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xf8);
- mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xe0);
- mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x80);
- mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x00);
-}
-
-void sunxi_cpu_off(u_register_t mpidr)
-{
- unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr);
- unsigned int core = MPIDR_AFFLVL0_VAL(mpidr);
-
- VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core);
-
- /* Deassert DBGPWRDUP */
- mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
-
- /* We can't turn ourself off like this, but it works for other cores. */
- if (read_mpidr() != mpidr) {
- /* Activate the core output clamps, but not for core 0. */
- if (core != 0)
- mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster),
- BIT(core));
- /* Assert CPU power-on reset */
- mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
- /* Remove power from the CPU */
- sunxi_cpu_disable_power(cluster, core);
-
- return;
- }
-
- /* Simplifies assembly, all SoCs so far are single cluster anyway. */
- assert(cluster == 0);
-
- /*
- * If we are supposed to turn ourself off, tell the arisc SCP
- * to do that work for us. The code expects the core mask to be
- * patched into the first instruction.
- */
- sunxi_execute_arisc_code(arisc_core_off, sizeof(arisc_core_off),
- BIT_32(core));
-}
-
-void sunxi_cpu_on(u_register_t mpidr)
-{
- unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr);
- unsigned int core = MPIDR_AFFLVL0_VAL(mpidr);
-
- VERBOSE("PSCI: Powering on cluster %d core %d\n", cluster, core);
-
- /* Assert CPU core reset */
- mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
- /* Assert CPU power-on reset */
- mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
- /* Set CPU to start in AArch64 mode */
- mmio_setbits_32(SUNXI_CPUCFG_CLS_CTRL_REG0(cluster), BIT(24 + core));
- /* Apply power to the CPU */
- sunxi_cpu_enable_power(cluster, core);
- /* Release the core output clamps */
- mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
- /* Deassert CPU power-on reset */
- mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
- /* Deassert CPU core reset */
- mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
- /* Assert DBGPWRDUP */
- mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
-}
-
-void sunxi_disable_secondary_cpus(u_register_t primary_mpidr)
-{
- unsigned int cluster;
- unsigned int core;
-
- for (cluster = 0; cluster < PLATFORM_CLUSTER_COUNT; ++cluster) {
- for (core = 0; core < PLATFORM_MAX_CPUS_PER_CLUSTER; ++core) {
- u_register_t mpidr = (cluster << MPIDR_AFF1_SHIFT) |
- (core << MPIDR_AFF0_SHIFT) |
- BIT(31);
- if (mpidr != primary_mpidr)
- sunxi_cpu_off(mpidr);
- }
- }
-}
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 17ef7bfda..9cb31bf15 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -53,8 +53,6 @@
*/
#define SCP_FIRMWARE_MAGIC 0xb4400012
-static bool scpi_available;
-
static inline scpi_power_state_t scpi_map_state(plat_local_state_t psci_state)
{
if (is_local_state_run(psci_state))
@@ -80,14 +78,10 @@ static int sunxi_pwr_domain_on(u_register_t mpidr)
if (mpidr_is_valid(mpidr) == 0)
return PSCI_E_INTERN_FAIL;
- if (scpi_available) {
- scpi_set_css_power_state(mpidr,
- scpi_power_on,
- scpi_power_on,
- scpi_power_on);
- } else {
- sunxi_cpu_on(mpidr);
- }
+ scpi_set_css_power_state(mpidr,
+ scpi_power_on,
+ scpi_power_on,
+ scpi_power_on);
return PSCI_E_SUCCESS;
}
@@ -101,20 +95,10 @@ static void sunxi_pwr_domain_off(const psci_power_state_t *target_state)
if (is_local_state_off(cpu_pwr_state))
gicv2_cpuif_disable();
- if (scpi_available) {
- scpi_set_css_power_state(read_mpidr(),
- scpi_map_state(cpu_pwr_state),
- scpi_map_state(cluster_pwr_state),
- scpi_map_state(system_pwr_state));
- }
-}
-
-static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state)
-{
- sunxi_cpu_off(read_mpidr());
-
- while (1)
- wfi();
+ scpi_set_css_power_state(read_mpidr(),
+ scpi_map_state(cpu_pwr_state),
+ scpi_map_state(cluster_pwr_state),
+ scpi_map_state(system_pwr_state));
}
static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
@@ -131,22 +115,12 @@ static void __dead2 sunxi_system_off(void)
{
gicv2_cpuif_disable();
- if (scpi_available) {
- /* Send the power down request to the SCP */
- uint32_t ret = scpi_sys_power_state(scpi_system_shutdown);
+ /* Send the power down request to the SCP */
+ uint32_t ret = scpi_sys_power_state(scpi_system_shutdown);
- if (ret == SCP_OK)
- wfi();
-
- ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret);
- }
-
- /* Turn off all secondary CPUs */
- sunxi_disable_secondary_cpus(read_mpidr());
-
- sunxi_power_down();
+ if (ret == SCP_OK)
+ wfi();
- wfi();
ERROR("PSCI: Cannot turn off system, halting\n");
panic();
}
@@ -155,15 +129,11 @@ static void __dead2 sunxi_system_reset(void)
{
gicv2_cpuif_disable();
- if (scpi_available) {
- /* Send the system reset request to the SCP */
- uint32_t ret = scpi_sys_power_state(scpi_system_reboot);
-
- if (ret == SCP_OK)
- wfi();
+ /* Send the system reset request to the SCP */
+ uint32_t ret = scpi_sys_power_state(scpi_system_reboot);
- ERROR("PSCI: SCPI %s failed: %d\n", "reboot", ret);
- }
+ if (ret == SCP_OK)
+ wfi();
/* Reset the whole system when the watchdog times out */
mmio_write_32(SUNXI_WDOG0_CFG_REG, 1);
@@ -249,20 +219,26 @@ static int sunxi_get_node_hw_state(u_register_t mpidr,
return ((cpu_state & BIT(cpu)) != 0) ? HW_ON : HW_OFF;
}
-static plat_psci_ops_t sunxi_psci_ops = {
+static const plat_psci_ops_t sunxi_psci_ops = {
.cpu_standby = sunxi_cpu_standby,
.pwr_domain_on = sunxi_pwr_domain_on,
.pwr_domain_off = sunxi_pwr_domain_off,
+ .pwr_domain_suspend = sunxi_pwr_domain_off,
.pwr_domain_on_finish = sunxi_pwr_domain_on_finish,
+ .pwr_domain_suspend_finish = sunxi_pwr_domain_on_finish,
.system_off = sunxi_system_off,
.system_reset = sunxi_system_reset,
.validate_power_state = sunxi_validate_power_state,
.validate_ns_entrypoint = sunxi_validate_ns_entrypoint,
+ .get_sys_suspend_power_state = sunxi_get_sys_suspend_power_state,
+ .get_node_hw_state = sunxi_get_node_hw_state,
};
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
+ bool scpi_available = false;
+
assert(psci_ops);
/* Program all CPU entry points. */
@@ -292,16 +268,6 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
NOTICE("PSCI: System suspend is %s\n",
scpi_available ? "available via SCPI" : "unavailable");
- if (scpi_available) {
- /* Suspend is only available via SCPI. */
- sunxi_psci_ops.pwr_domain_suspend = sunxi_pwr_domain_off;
- sunxi_psci_ops.pwr_domain_suspend_finish = sunxi_pwr_domain_on_finish;
- sunxi_psci_ops.get_sys_suspend_power_state = sunxi_get_sys_suspend_power_state;
- sunxi_psci_ops.get_node_hw_state = sunxi_get_node_hw_state;
- } else {
- /* This is only needed when SCPI is unavailable. */
- sunxi_psci_ops.pwr_domain_pwr_down_wfi = sunxi_pwr_down_wfi;
- }
*psci_ops = &sunxi_psci_ops;
diff --git a/plat/allwinner/sun50i_a64/include/core_off_arisc.h b/plat/allwinner/sun50i_a64/include/core_off_arisc.h
deleted file mode 100644
index ae436ca1b..000000000
--- a/plat/allwinner/sun50i_a64/include/core_off_arisc.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-static uint32_t arisc_core_off[] = {
- 0x18600000, /* l.movhi r3, <corenr> */
- 0x18000000, /* l.movhi r0, 0x0 */
- 0x19a00170, /* l.movhi r13, 0x170 */
- 0x84ad0030, /* l.lwz r5, 0x30(r13) */
- 0xe0a51803, /* l.and r5, r5, r3 */
- 0xe4050000, /* l.sfeq r5, r0 */
- 0x13fffffd, /* l.bf -12 */
-
- 0xb8c30050, /* l.srli r6, r3, 16 */
- 0xbc060001, /* l.sfeqi r6, 1 */
- 0x10000005, /* l.bf +20 */
- 0x19a001f0, /* l.movhi r13, 0x1f0 */
- 0x84ad1500, /* l.lwz r5, 0x1500(r13) */
- 0xe0a53004, /* l.or r5, r5, r6 */
- 0xd44d2d00, /* l.sw 0x1500(r13), r5 */
-
- 0x84ad1c30, /* l.lwz r5, 0x1c30(r13) */
- 0xacc6ffff, /* l.xori r6, r6, -1 */
- 0xe0a53003, /* l.and r5, r5, r6 */
- 0xd46d2c30, /* l.sw 0x1c30(r13), r5 */
-
- 0xe0c3000f, /* l.ff1 r6, r3 */
- 0x9cc6ffef, /* l.addi r6, r6, -17 */
- 0xb8c60002, /* l.slli r6, r6, 2 */
- 0xe0c66800, /* l.add r6, r6, r13 */
- 0xa8a000ff, /* l.ori r5, r0, 0xff */
- 0xd4462d40, /* l.sw 0x1540(r6), r5 */
-
- 0xd46d0400, /* l.sw 0x1c00(r13), r0 */
- 0x03ffffff, /* l.j -1 */
- 0x15000000, /* l.nop */
-};
diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c
index 5b7d76ae9..d0b53d4e4 100644
--- a/plat/allwinner/sun50i_a64/sunxi_power.c
+++ b/plat/allwinner/sun50i_a64/sunxi_power.c
@@ -12,76 +12,22 @@
#include <common/debug.h>
#include <drivers/allwinner/axp.h>
#include <drivers/allwinner/sunxi_rsb.h>
-#include <lib/mmio.h>
#include <sunxi_def.h>
#include <sunxi_mmap.h>
#include <sunxi_private.h>
-static enum pmic_type {
- UNKNOWN,
- GENERIC_H5,
- GENERIC_A64,
- REF_DESIGN_H5, /* regulators controlled by GPIO pins on port L */
- AXP803_RSB, /* PMIC connected via RSB on most A64 boards */
-} pmic;
-
#define AXP803_HW_ADDR 0x3a3
#define AXP803_RT_ADDR 0x2d
-/*
- * On boards without a proper PMIC we struggle to turn off the system properly.
- * Try to turn off as much off the system as we can, to reduce power
- * consumption. This should be entered with only one core running and SMP
- * disabled.
- * This function only cares about peripherals.
- */
-static void sunxi_turn_off_soc(uint16_t socid)
+int axp_read(uint8_t reg)
{
- int i;
-
- /** Turn off most peripherals, most importantly DRAM users. **/
- /* Keep DRAM controller running for now. */
- mmio_clrbits_32(SUNXI_CCU_BASE + 0x2c0, ~BIT_32(14));
- mmio_clrbits_32(SUNXI_CCU_BASE + 0x60, ~BIT_32(14));
- /* Contains msgbox (bit 21) and spinlock (bit 22) */
- mmio_write_32(SUNXI_CCU_BASE + 0x2c4, 0);
- mmio_write_32(SUNXI_CCU_BASE + 0x64, 0);
- mmio_write_32(SUNXI_CCU_BASE + 0x2c8, 0);
- /* Keep PIO controller running for now. */
- mmio_clrbits_32(SUNXI_CCU_BASE + 0x68, ~(BIT_32(5)));
- mmio_write_32(SUNXI_CCU_BASE + 0x2d0, 0);
- /* Contains UART0 (bit 16) */
- mmio_write_32(SUNXI_CCU_BASE + 0x2d8, 0);
- mmio_write_32(SUNXI_CCU_BASE + 0x6c, 0);
- mmio_write_32(SUNXI_CCU_BASE + 0x70, 0);
-
- /** Turn off DRAM controller. **/
- mmio_clrbits_32(SUNXI_CCU_BASE + 0x2c0, BIT_32(14));
- mmio_clrbits_32(SUNXI_CCU_BASE + 0x60, BIT_32(14));
-
- /** Migrate CPU and bus clocks away from the PLLs. **/
- /* AHB1: use OSC24M/1, APB1 = AHB1 / 2 */
- mmio_write_32(SUNXI_CCU_BASE + 0x54, 0x1000);
- /* APB2: use OSC24M */
- mmio_write_32(SUNXI_CCU_BASE + 0x58, 0x1000000);
- /* AHB2: use AHB1 clock */
- mmio_write_32(SUNXI_CCU_BASE + 0x5c, 0);
- /* CPU: use OSC24M */
- mmio_write_32(SUNXI_CCU_BASE + 0x50, 0x10000);
-
- /** Turn off PLLs. **/
- for (i = 0; i < 6; i++)
- mmio_clrbits_32(SUNXI_CCU_BASE + i * 8, BIT(31));
- switch (socid) {
- case SUNXI_SOC_H5:
- mmio_clrbits_32(SUNXI_CCU_BASE + 0x44, BIT(31));
- break;
- case SUNXI_SOC_A64:
- mmio_clrbits_32(SUNXI_CCU_BASE + 0x2c, BIT(31));
- mmio_clrbits_32(SUNXI_CCU_BASE + 0x4c, BIT(31));
- break;
- }
+ return rsb_read(AXP803_RT_ADDR, reg);
+}
+
+int axp_write(uint8_t reg, uint8_t val)
+{
+ return rsb_write(AXP803_RT_ADDR, reg, val);
}
static int rsb_init(void)
@@ -119,92 +65,24 @@ static int rsb_init(void)
return axp_check_id();
}
-int axp_read(uint8_t reg)
-{
- return rsb_read(AXP803_RT_ADDR, reg);
-}
-
-int axp_write(uint8_t reg, uint8_t val)
-{
- return rsb_write(AXP803_RT_ADDR, reg, val);
-}
-
int sunxi_pmic_setup(uint16_t socid, const void *fdt)
{
int ret;
- switch (socid) {
- case SUNXI_SOC_H5:
- NOTICE("PMIC: Assuming H5 reference regulator design\n");
-
- pmic = REF_DESIGN_H5;
+ if (socid != SUNXI_SOC_A64)
+ return 0;
- break;
- case SUNXI_SOC_A64:
- pmic = GENERIC_A64;
+ INFO("PMIC: Probing AXP803 on RSB\n");
- INFO("PMIC: Probing AXP803 on RSB\n");
-
- ret = sunxi_init_platform_r_twi(socid, true);
- if (ret)
- return ret;
+ ret = sunxi_init_platform_r_twi(socid, true);
+ if (ret)
+ return ret;
- ret = rsb_init();
- if (ret)
- return ret;
+ ret = rsb_init();
+ if (ret)
+ return ret;
- pmic = AXP803_RSB;
- axp_setup_regulators(fdt);
+ axp_setup_regulators(fdt);
- break;
- default:
- return -ENODEV;
- }
return 0;
}
-
-void sunxi_power_down(void)
-{
- switch (pmic) {
- case GENERIC_H5:
- /* Turn off as many peripherals and clocks as we can. */
- sunxi_turn_off_soc(SUNXI_SOC_H5);
- /* Turn off the pin controller now. */
- mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
- break;
- case GENERIC_A64:
- /* Turn off as many peripherals and clocks as we can. */
- sunxi_turn_off_soc(SUNXI_SOC_A64);
- /* Turn off the pin controller now. */
- mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
- break;
- case REF_DESIGN_H5:
- sunxi_turn_off_soc(SUNXI_SOC_H5);
-
- /*
- * Switch PL pins to power off the board:
- * - PL5 (VCC_IO) -> high
- * - PL8 (PWR-STB = CPU power supply) -> low
- * - PL9 (PWR-DRAM) ->low
- * - PL10 (power LED) -> low
- * Note: Clearing PL8 will reset the board, so keep it up.
- */
- sunxi_set_gpio_out('L', 5, 1);
- sunxi_set_gpio_out('L', 9, 0);
- sunxi_set_gpio_out('L', 10, 0);
-
- /* Turn off pin controller now. */
- mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
-
- break;
- case AXP803_RSB:
- /* (Re-)init RSB in case the rich OS has disabled it. */
- sunxi_init_platform_r_twi(SUNXI_SOC_A64, true);
- rsb_init();
- axp_power_off();
- break;
- default:
- break;
- }
-
-}
diff --git a/plat/allwinner/sun50i_h6/include/core_off_arisc.h b/plat/allwinner/sun50i_h6/include/core_off_arisc.h
deleted file mode 100644
index 63a5d8d96..000000000
--- a/plat/allwinner/sun50i_h6/include/core_off_arisc.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-static uint32_t arisc_core_off[] = {
- 0x18600000, /* l.movhi r3, <corenr> */
- 0x18000000, /* l.movhi r0, 0x0 */
- 0x19a00901, /* l.movhi r13, 0x901 */
- 0x84ad0080, /* l.lwz r5, 0x80(r13) */
- 0xe0a51803, /* l.and r5, r5, r3 */
- 0xe4050000, /* l.sfeq r5, r0 */
- 0x13fffffd, /* l.bf -12 */
- 0xb8c30050, /* l.srli r6, r3, 16 */
-
- 0xbc060001, /* l.sfeqi r6, 1 */
- 0x10000005, /* l.bf +20 */
- 0x19a00700, /* l.movhi r13, 0x700 */
- 0x84ad0444, /* l.lwz r5, 0x0444(r13) */
- 0xe0a53004, /* l.or r5, r5, r6 */
- 0xd40d2c44, /* l.sw 0x0444(r13), r5 */
-
- 0x84ad0440, /* l.lwz r5, 0x0440(r13) */
- 0xacc6ffff, /* l.xori r6, r6, -1 */
- 0xe0a53003, /* l.and r5, r5, r6 */
- 0xd40d2c40, /* l.sw 0x0440(r13), r5 */
-
- 0xe0c3000f, /* l.ff1 r6, r3 */
- 0x9cc6ffef, /* l.addi r6, r6, -17 */
- 0xb8c60002, /* l.slli r6, r6, 2 */
- 0xe0c66800, /* l.add r6, r6, r13 */
- 0xa8a000ff, /* l.ori r5, r0, 0xff */
- 0xd4062c50, /* l.sw 0x0450(r6), r5 */
-
- 0xd40d0400, /* l.sw 0x0400(r13), r0 */
- 0x03ffffff, /* l.j -1 */
- 0x15000000, /* l.nop */
-};
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index 443015bac..f1ab84fc4 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -6,14 +6,10 @@
*/
#include <errno.h>
-#include <string.h>
-#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/allwinner/axp.h>
-#include <drivers/delay_timer.h>
#include <drivers/mentor/mi2cv.h>
-#include <lib/mmio.h>
#include <sunxi_def.h>
#include <sunxi_mmap.h>
@@ -21,11 +17,6 @@
#define AXP805_ADDR 0x36
-static enum pmic_type {
- UNKNOWN,
- AXP805,
-} pmic;
-
int axp_read(uint8_t reg)
{
uint8_t val;
@@ -86,23 +77,7 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt)
if (ret)
return ret;
- pmic = AXP805;
axp_setup_regulators(fdt);
return 0;
}
-
-void sunxi_power_down(void)
-{
- switch (pmic) {
- case AXP805:
- /* Re-initialise after rich OS might have used it. */
- sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
- /* initialise mi2cv driver */
- i2c_init((void *)SUNXI_R_I2C_BASE);
- axp_power_off();
- break;
- default:
- break;
- }
-}
--
2.28.0