mirror of
https://github.com/libretro/Lakka-LibreELEC.git
synced 2025-03-01 10:21:22 +00:00
576 lines
15 KiB
Diff
576 lines
15 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Samuel Holland <samuel@sholland.org>
|
|
Date: Fri, 20 Nov 2020 01:25:26 -0600
|
|
Subject: [PATCH] sunxi: A wild PSCI implementation appears...
|
|
|
|
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
|
---
|
|
arch/arm/cpu/armv7/Kconfig | 1 -
|
|
arch/arm/cpu/armv7/sunxi/Makefile | 2 +-
|
|
arch/arm/cpu/armv7/sunxi/psci-scpi.c | 463 +++++++++++++++++++++++++++
|
|
arch/arm/include/asm/psci.h | 9 +-
|
|
arch/arm/include/asm/system.h | 13 +-
|
|
tools/sunxi_egon.c | 2 +-
|
|
6 files changed, 480 insertions(+), 10 deletions(-)
|
|
create mode 100644 arch/arm/cpu/armv7/sunxi/psci-scpi.c
|
|
|
|
--- a/arch/arm/cpu/armv7/Kconfig
|
|
+++ b/arch/arm/cpu/armv7/Kconfig
|
|
@@ -44,7 +44,6 @@ config ARMV7_PSCI
|
|
choice
|
|
prompt "Supported PSCI version"
|
|
depends on ARMV7_PSCI
|
|
- default ARMV7_PSCI_0_1 if ARCH_SUNXI
|
|
default ARMV7_PSCI_1_0
|
|
help
|
|
Select the supported PSCI version.
|
|
--- a/arch/arm/cpu/armv7/sunxi/Makefile
|
|
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
|
|
@@ -11,7 +11,7 @@ obj-$(CONFIG_MACH_SUN6I) += tzpc.o
|
|
obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o
|
|
|
|
ifndef CONFIG_SPL_BUILD
|
|
-obj-$(CONFIG_ARMV7_PSCI) += psci.o
|
|
+obj-$(CONFIG_ARMV7_PSCI) += psci-scpi.o
|
|
endif
|
|
|
|
ifdef CONFIG_SPL_BUILD
|
|
--- /dev/null
|
|
+++ b/arch/arm/cpu/armv7/sunxi/psci-scpi.c
|
|
@@ -0,0 +1,463 @@
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
+/*
|
|
+ * Copyright (C) 2016
|
|
+ * Author: Chen-Yu Tsai <wens@csie.org>
|
|
+ *
|
|
+ * Based on assembly code by Marc Zyngier <marc.zyngier@arm.com>,
|
|
+ * which was based on code by Carl van Schaik <carl@ok-labs.com>.
|
|
+ */
|
|
+
|
|
+#include <config.h>
|
|
+#include <common.h>
|
|
+#include <asm/cache.h>
|
|
+
|
|
+#include <asm/arch/cpu.h>
|
|
+#include <asm/arch/cpucfg.h>
|
|
+#include <asm/arch/prcm.h>
|
|
+#include <asm/armv7.h>
|
|
+#include <asm/gic.h>
|
|
+#include <asm/io.h>
|
|
+#include <asm/psci.h>
|
|
+#include <asm/secure.h>
|
|
+#include <asm/system.h>
|
|
+
|
|
+#define SUNXI_SCP_BASE 0x00048000
|
|
+#define SUNXI_SCP_MAGIC 0xb4400012
|
|
+
|
|
+#define OR1K_VEC_FIRST 0x01
|
|
+#define OR1K_VEC_LAST 0x0e
|
|
+#define OR1K_VEC_ADDR(n) (0x100 * (n))
|
|
+
|
|
+#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
|
|
+#define GICC_BASE (SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15)
|
|
+
|
|
+#define HW_ON 0
|
|
+#define HW_OFF 1
|
|
+#define HW_STANDBY 2
|
|
+
|
|
+#define MPIDR_AFFLVL0(mpidr) (mpidr & 0xf)
|
|
+#define MPIDR_AFFLVL1(mpidr) (mpidr >> 8 & 0xf)
|
|
+
|
|
+enum {
|
|
+ CORE_POWER_LEVEL = 0,
|
|
+ CLUSTER_POWER_LEVEL = 1,
|
|
+ CSS_POWER_LEVEL = 2,
|
|
+};
|
|
+
|
|
+enum {
|
|
+ SCPI_CMD_SCP_READY = 0x01,
|
|
+ SCPI_CMD_SET_CSS_POWER_STATE = 0x03,
|
|
+ SCPI_CMD_GET_CSS_POWER_STATE = 0x04,
|
|
+ SCPI_CMD_SET_SYS_POWER_STATE = 0x05,
|
|
+};
|
|
+
|
|
+enum {
|
|
+ SCPI_E_OK = 0,
|
|
+ SCPI_E_PARAM = 1,
|
|
+ SCPI_E_ALIGN = 2,
|
|
+ SCPI_E_SIZE = 3,
|
|
+ SCPI_E_HANDLER = 4,
|
|
+ SCPI_E_ACCESS = 5,
|
|
+ SCPI_E_RANGE = 6,
|
|
+ SCPI_E_TIMEOUT = 7,
|
|
+ SCPI_E_NOMEM = 8,
|
|
+ SCPI_E_PWRSTATE = 9,
|
|
+ SCPI_E_SUPPORT = 10,
|
|
+ SCPI_E_DEVICE = 11,
|
|
+ SCPI_E_BUSY = 12,
|
|
+ SCPI_E_OS = 13,
|
|
+ SCPI_E_DATA = 14,
|
|
+ SCPI_E_STATE = 15,
|
|
+};
|
|
+
|
|
+enum {
|
|
+ SCPI_POWER_ON = 0x00,
|
|
+ SCPI_POWER_RETENTION = 0x01,
|
|
+ SCPI_POWER_OFF = 0x03,
|
|
+};
|
|
+
|
|
+enum {
|
|
+ SCPI_SYSTEM_SHUTDOWN = 0x00,
|
|
+ SCPI_SYSTEM_REBOOT = 0x01,
|
|
+ SCPI_SYSTEM_RESET = 0x02,
|
|
+};
|
|
+
|
|
+#define SCPI_SHMEM_BASE 0x0004be00
|
|
+#define SCPI_SHMEM ((struct scpi_shmem *)SCPI_SHMEM_BASE)
|
|
+
|
|
+#define SCPI_MESSAGE_SIZE 0x100
|
|
+#define SCPI_PAYLOAD_SIZE (SCPI_MESSAGE_SIZE - sizeof(struct scpi_header))
|
|
+
|
|
+#define SCPI_RX_CHANNEL 1
|
|
+#define SCPI_TX_CHANNEL 0
|
|
+#define SCPI_VIRTUAL_CHANNEL BIT(0)
|
|
+
|
|
+struct scpi_header {
|
|
+ u8 command;
|
|
+ u8 sender;
|
|
+ u16 size;
|
|
+ u32 status;
|
|
+};
|
|
+
|
|
+struct scpi_message {
|
|
+ struct scpi_header header;
|
|
+ u8 payload[SCPI_PAYLOAD_SIZE];
|
|
+};
|
|
+
|
|
+struct scpi_shmem {
|
|
+ struct scpi_message rx;
|
|
+ struct scpi_message tx;
|
|
+};
|
|
+
|
|
+#define SUNXI_MSGBOX_BASE 0x01c17000
|
|
+#define REMOTE_IRQ_STAT_REG (SUNXI_MSGBOX_BASE + 0x0050)
|
|
+#define LOCAL_IRQ_STAT_REG (SUNXI_MSGBOX_BASE + 0x0070)
|
|
+#define MSG_STAT_REG(n) (SUNXI_MSGBOX_BASE + 0x0140 + 0x4 * (n))
|
|
+#define MSG_DATA_REG(n) (SUNXI_MSGBOX_BASE + 0x0180 + 0x4 * (n))
|
|
+
|
|
+#define RX_IRQ(n) BIT(0 + 2 * (n))
|
|
+#define TX_IRQ(n) BIT(1 + 2 * (n))
|
|
+
|
|
+static u32 __secure_data ccu_save[2];
|
|
+
|
|
+static u32 __secure_data lock;
|
|
+
|
|
+static inline u32 __secure read_mpidr(void)
|
|
+{
|
|
+ u32 v;
|
|
+ asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (v));
|
|
+ return v;
|
|
+}
|
|
+
|
|
+static void __secure scpi_begin_command(void)
|
|
+{
|
|
+ u32 mpidr = read_mpidr();
|
|
+
|
|
+ do {
|
|
+ while (readl(&lock));
|
|
+ writel(mpidr, &lock);
|
|
+ dsb();
|
|
+ } while (readl(&lock) != mpidr);
|
|
+ while (readl(REMOTE_IRQ_STAT_REG) & RX_IRQ(SCPI_TX_CHANNEL));
|
|
+}
|
|
+
|
|
+static void __secure scpi_send_command(void)
|
|
+{
|
|
+ writel(SCPI_VIRTUAL_CHANNEL, MSG_DATA_REG(SCPI_TX_CHANNEL));
|
|
+}
|
|
+
|
|
+static void __secure scpi_wait_response(void)
|
|
+{
|
|
+ while (!readl(MSG_STAT_REG(SCPI_RX_CHANNEL)));
|
|
+}
|
|
+
|
|
+static void __secure scpi_end_command(void)
|
|
+{
|
|
+ while (readl(MSG_STAT_REG(SCPI_RX_CHANNEL)))
|
|
+ readl(MSG_DATA_REG(SCPI_RX_CHANNEL));
|
|
+ writel(RX_IRQ(SCPI_RX_CHANNEL), LOCAL_IRQ_STAT_REG);
|
|
+ writel(0, &lock);
|
|
+}
|
|
+
|
|
+static void __secure scpi_set_css_power_state(u32 target_cpu, u32 core_state,
|
|
+ u32 cluster_state, u32 css_state)
|
|
+{
|
|
+ struct scpi_shmem *shmem = SCPI_SHMEM;
|
|
+
|
|
+ scpi_begin_command();
|
|
+
|
|
+ shmem->tx.header.command = SCPI_CMD_SET_CSS_POWER_STATE;
|
|
+ shmem->tx.header.size = 4;
|
|
+
|
|
+ shmem->tx.payload[0] = target_cpu >> 4 | target_cpu;
|
|
+ shmem->tx.payload[1] = cluster_state << 4 | core_state;
|
|
+ shmem->tx.payload[2] = css_state;
|
|
+ shmem->tx.payload[3] = 0;
|
|
+
|
|
+ scpi_send_command();
|
|
+ scpi_end_command();
|
|
+}
|
|
+
|
|
+static s32 __secure scpi_get_css_power_state(u32 target_cpu, u8 *core_states,
|
|
+ u8 *cluster_state)
|
|
+{
|
|
+ struct scpi_shmem *shmem = SCPI_SHMEM;
|
|
+ u32 cluster = MPIDR_AFFLVL1(target_cpu);
|
|
+ u32 offset;
|
|
+ s32 ret;
|
|
+
|
|
+ scpi_begin_command();
|
|
+
|
|
+ shmem->tx.header.command = SCPI_CMD_GET_CSS_POWER_STATE;
|
|
+ shmem->tx.header.size = 0;
|
|
+
|
|
+ scpi_send_command();
|
|
+ scpi_wait_response();
|
|
+
|
|
+ for (offset = 0; offset < shmem->rx.header.size; offset += 2) {
|
|
+ if ((shmem->rx.payload[offset] & 0xf) == cluster) {
|
|
+ *cluster_state = shmem->rx.payload[offset+0] >> 4;
|
|
+ *core_states = shmem->rx.payload[offset+1];
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ret = shmem->rx.header.status;
|
|
+
|
|
+ scpi_end_command();
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static s32 __secure scpi_set_sys_power_state(u32 sys_state)
|
|
+{
|
|
+ struct scpi_shmem *shmem = SCPI_SHMEM;
|
|
+ s32 ret;
|
|
+
|
|
+ scpi_begin_command();
|
|
+
|
|
+ shmem->tx.header.command = SCPI_CMD_SET_SYS_POWER_STATE;
|
|
+ shmem->tx.header.size = 1;
|
|
+
|
|
+ shmem->tx.payload[0] = sys_state;
|
|
+
|
|
+ scpi_send_command();
|
|
+ scpi_wait_response();
|
|
+
|
|
+ ret = shmem->rx.header.status;
|
|
+
|
|
+ scpi_end_command();
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+void psci_enable_smp(void);
|
|
+
|
|
+static s32 __secure psci_suspend_common(u32 pc, u32 context_id, u32 core_state,
|
|
+ u32 cluster_state, u32 css_state)
|
|
+
|
|
+{
|
|
+ u32 target_cpu = read_mpidr();
|
|
+
|
|
+ if (core_state == SCPI_POWER_OFF) {
|
|
+ psci_save(MPIDR_AFFLVL0(target_cpu), pc, context_id);
|
|
+
|
|
+ if (MPIDR_AFFLVL0(target_cpu) == 0) {
|
|
+ ccu_save[0] = readl(0x1c20050);
|
|
+ ccu_save[1] = readl(0x1c20054);
|
|
+ writel((ccu_save[1] & ~(3 << 12)) | (1 << 12), 0x1c20054);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ scpi_set_css_power_state(target_cpu, core_state,
|
|
+ cluster_state, css_state);
|
|
+
|
|
+ psci_cpu_off_common();
|
|
+
|
|
+ wfi();
|
|
+
|
|
+ psci_enable_smp();
|
|
+
|
|
+ return ARM_PSCI_RET_SUCCESS;
|
|
+}
|
|
+
|
|
+u32 __secure psci_version(void)
|
|
+{
|
|
+ return ARM_PSCI_VER_1_1;
|
|
+}
|
|
+
|
|
+s32 __secure psci_cpu_suspend(u32 __always_unused function_id,
|
|
+ u32 power_state, u32 pc, u32 context_id)
|
|
+{
|
|
+ return psci_suspend_common(pc, context_id,
|
|
+ power_state >> 0 & 0xf,
|
|
+ power_state >> 4 & 0xf,
|
|
+ power_state >> 8 & 0xf);
|
|
+}
|
|
+
|
|
+s32 __secure psci_cpu_off(void)
|
|
+{
|
|
+ u32 pc = 0, context_id = 0;
|
|
+
|
|
+ return psci_suspend_common(pc, context_id, SCPI_POWER_OFF,
|
|
+ SCPI_POWER_OFF, SCPI_POWER_ON);
|
|
+}
|
|
+
|
|
+s32 __secure psci_cpu_on(u32 __always_unused function_id,
|
|
+ u32 target_cpu, u32 pc, u32 context_id)
|
|
+{
|
|
+ psci_save(MPIDR_AFFLVL0(target_cpu), pc, context_id);
|
|
+
|
|
+ scpi_set_css_power_state(target_cpu, SCPI_POWER_ON,
|
|
+ SCPI_POWER_ON, SCPI_POWER_ON);
|
|
+
|
|
+ return ARM_PSCI_RET_SUCCESS;
|
|
+}
|
|
+
|
|
+s32 __secure psci_affinity_info(u32 function_id,
|
|
+ u32 target_cpu, u32 power_level)
|
|
+{
|
|
+ if (power_level != CORE_POWER_LEVEL)
|
|
+ return ARM_PSCI_RET_INVAL;
|
|
+
|
|
+ /* This happens to have the same HW_ON/HW_OFF encoding. */
|
|
+ return psci_node_hw_state(function_id, target_cpu, power_level);
|
|
+}
|
|
+
|
|
+void __secure psci_system_off(void)
|
|
+{
|
|
+ scpi_set_sys_power_state(SCPI_SYSTEM_SHUTDOWN);
|
|
+
|
|
+ /* Wait to be turned off. */
|
|
+ for (;;) wfi();
|
|
+}
|
|
+
|
|
+void __secure psci_system_reset(void)
|
|
+{
|
|
+ scpi_set_sys_power_state(SCPI_SYSTEM_REBOOT);
|
|
+
|
|
+ /* Wait to be turned off. */
|
|
+ for (;;) wfi();
|
|
+}
|
|
+
|
|
+s32 __secure psci_features(u32 __always_unused function_id,
|
|
+ u32 psci_fid)
|
|
+{
|
|
+ switch (psci_fid) {
|
|
+ case ARM_PSCI_0_2_FN_PSCI_VERSION:
|
|
+ case ARM_PSCI_0_2_FN_CPU_SUSPEND:
|
|
+ case ARM_PSCI_0_2_FN_CPU_OFF:
|
|
+ case ARM_PSCI_0_2_FN_CPU_ON:
|
|
+ case ARM_PSCI_0_2_FN_AFFINITY_INFO:
|
|
+ case ARM_PSCI_0_2_FN_SYSTEM_OFF:
|
|
+ case ARM_PSCI_0_2_FN_SYSTEM_RESET:
|
|
+ case ARM_PSCI_1_0_FN_PSCI_FEATURES:
|
|
+ case ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND:
|
|
+ case ARM_PSCI_1_0_FN_NODE_HW_STATE:
|
|
+ case ARM_PSCI_1_0_FN_SYSTEM_SUSPEND:
|
|
+ case ARM_PSCI_1_1_FN_SYSTEM_RESET2:
|
|
+ return ARM_PSCI_RET_SUCCESS;
|
|
+ default:
|
|
+ return ARM_PSCI_RET_NI;
|
|
+ }
|
|
+}
|
|
+
|
|
+s32 __secure psci_cpu_default_suspend(u32 __always_unused function_id,
|
|
+ u32 pc, u32 context_id)
|
|
+{
|
|
+ return psci_suspend_common(pc, context_id, SCPI_POWER_RETENTION,
|
|
+ SCPI_POWER_RETENTION, SCPI_POWER_RETENTION);
|
|
+}
|
|
+
|
|
+s32 __secure psci_node_hw_state(u32 __always_unused function_id,
|
|
+ u32 target_cpu, u32 power_level)
|
|
+{
|
|
+ u32 core = MPIDR_AFFLVL0(target_cpu);
|
|
+ u8 core_states, cluster_state;
|
|
+
|
|
+ if (power_level >= CSS_POWER_LEVEL)
|
|
+ return HW_ON;
|
|
+ if (scpi_get_css_power_state(target_cpu, &core_states, &cluster_state))
|
|
+ return ARM_PSCI_RET_NI;
|
|
+ if (power_level == CLUSTER_POWER_LEVEL) {
|
|
+ if (cluster_state == SCPI_POWER_ON)
|
|
+ return HW_ON;
|
|
+ if (cluster_state < SCPI_POWER_OFF)
|
|
+ return HW_STANDBY;
|
|
+ return HW_OFF;
|
|
+ }
|
|
+
|
|
+ return (core_states & BIT(core)) ? HW_ON : HW_OFF;
|
|
+}
|
|
+
|
|
+s32 __secure psci_system_suspend(u32 __always_unused function_id,
|
|
+ u32 pc, u32 context_id)
|
|
+{
|
|
+ return psci_suspend_common(pc, context_id, SCPI_POWER_OFF,
|
|
+ SCPI_POWER_OFF, SCPI_POWER_OFF);
|
|
+}
|
|
+
|
|
+s32 __secure psci_system_reset2(u32 __always_unused function_id,
|
|
+ u32 reset_type, u32 cookie)
|
|
+{
|
|
+ s32 ret;
|
|
+
|
|
+ if (reset_type)
|
|
+ return ARM_PSCI_RET_INVAL;
|
|
+
|
|
+ ret = scpi_set_sys_power_state(SCPI_SYSTEM_RESET);
|
|
+ if (ret)
|
|
+ return ARM_PSCI_RET_INVAL;
|
|
+
|
|
+ /* Wait to be turned off. */
|
|
+ for (;;) wfi();
|
|
+}
|
|
+
|
|
+/*
|
|
+ * R40 is different from other single cluster SoCs. The secondary core
|
|
+ * entry address register is in the SRAM controller address range.
|
|
+ */
|
|
+#define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0 (0xbc)
|
|
+
|
|
+#ifdef CONFIG_MACH_SUN8I_R40
|
|
+/* secondary core entry address is programmed differently on R40 */
|
|
+static void __secure sunxi_set_entry_address(void *entry)
|
|
+{
|
|
+ writel((u32)entry,
|
|
+ SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
|
|
+}
|
|
+#else
|
|
+static void __secure sunxi_set_entry_address(void *entry)
|
|
+{
|
|
+ struct sunxi_cpucfg_reg *cpucfg =
|
|
+ (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
|
|
+
|
|
+ writel((u32)entry, &cpucfg->priv0);
|
|
+}
|
|
+#endif
|
|
+
|
|
+void __secure psci_arch_init(void)
|
|
+{
|
|
+ static bool __secure_data once;
|
|
+
|
|
+ /* Be cool with non-secure. */
|
|
+ writel(0xff, GICC_BASE + GICC_PMR);
|
|
+
|
|
+ if (!once) {
|
|
+ once = true;
|
|
+
|
|
+ /* Redirect CPU0 to PSCI. */
|
|
+ writel(0x16aaefe8, 0x1f01da0);
|
|
+ writel(0xaa16efe8, 0x1f01da0);
|
|
+ writel(0x47000, 0x1f01da8);
|
|
+
|
|
+ /* Set secondary core power-on PC. */
|
|
+ sunxi_set_entry_address(psci_cpu_entry);
|
|
+
|
|
+ /* Wait for the SCP firmware to boot. */
|
|
+ scpi_begin_command();
|
|
+ scpi_wait_response();
|
|
+ scpi_end_command();
|
|
+ } else if (MPIDR_AFFLVL0(read_mpidr()) == 0) {
|
|
+ writel(ccu_save[0], 0x1c20050);
|
|
+ writel(ccu_save[1], 0x1c20054);
|
|
+ }
|
|
+}
|
|
+
|
|
+void psci_board_init(void)
|
|
+{
|
|
+ /* Check for a valid SCP firmware, and boot the SCP if found. */
|
|
+ if (readl(SUNXI_SCP_BASE) == SUNXI_SCP_MAGIC) {
|
|
+ /* Program exception vectors to the firmware entry point. */
|
|
+ for (u32 i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) {
|
|
+ u32 vector = SUNXI_SRAM_A2_BASE + OR1K_VEC_ADDR(i);
|
|
+ u32 offset = SUNXI_SCP_BASE - vector;
|
|
+
|
|
+ writel(offset >> 2, vector);
|
|
+ }
|
|
+
|
|
+ /* Take the SCP out of reset. */
|
|
+ writel(0x1, SUNXI_CPUCFG_BASE);
|
|
+ }
|
|
+}
|
|
--- a/arch/arm/include/asm/psci.h
|
|
+++ b/arch/arm/include/asm/psci.h
|
|
@@ -22,8 +22,9 @@
|
|
#include <linux/bitops.h>
|
|
#endif
|
|
|
|
-#define ARM_PSCI_VER_1_0 (0x00010000)
|
|
#define ARM_PSCI_VER_0_2 (0x00000002)
|
|
+#define ARM_PSCI_VER_1_0 (0x00010000)
|
|
+#define ARM_PSCI_VER_1_1 (0x00010001)
|
|
|
|
/* PSCI 0.1 interface */
|
|
#define ARM_PSCI_FN_BASE 0x95c1ba5e
|
|
@@ -68,7 +69,6 @@
|
|
#define ARM_PSCI_0_2_FN64_AFFINITY_INFO ARM_PSCI_0_2_FN64(4)
|
|
#define ARM_PSCI_0_2_FN64_MIGRATE ARM_PSCI_0_2_FN64(5)
|
|
#define ARM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU ARM_PSCI_0_2_FN64(7)
|
|
-#define ARM_PSCI_0_2_FN64_SYSTEM_RESET2 ARM_PSCI_0_2_FN64(18)
|
|
|
|
/* PSCI 1.0 interface */
|
|
#define ARM_PSCI_1_0_FN_PSCI_FEATURES ARM_PSCI_0_2_FN(10)
|
|
@@ -86,6 +86,11 @@
|
|
#define ARM_PSCI_1_0_FN64_STAT_RESIDENCY ARM_PSCI_0_2_FN64(16)
|
|
#define ARM_PSCI_1_0_FN64_STAT_COUNT ARM_PSCI_0_2_FN64(17)
|
|
|
|
+/* PSCI 1.1 interface */
|
|
+#define ARM_PSCI_1_1_FN_SYSTEM_RESET2 ARM_PSCI_0_2_FN(18)
|
|
+
|
|
+#define ARM_PSCI_1_1_FN64_SYSTEM_RESET2 ARM_PSCI_0_2_FN64(18)
|
|
+
|
|
/* 1KB stack per core */
|
|
#define ARM_PSCI_STACK_SHIFT 10
|
|
#define ARM_PSCI_STACK_SIZE (1 << ARM_PSCI_STACK_SHIFT)
|
|
--- a/arch/arm/include/asm/system.h
|
|
+++ b/arch/arm/include/asm/system.h
|
|
@@ -549,17 +549,20 @@ void mmu_page_table_flush(unsigned long
|
|
#ifdef CONFIG_ARMV7_PSCI
|
|
void psci_arch_cpu_entry(void);
|
|
void psci_arch_init(void);
|
|
+
|
|
u32 psci_version(void);
|
|
-s32 psci_features(u32 function_id, u32 psci_fid);
|
|
+s32 psci_cpu_suspend(u32 function_id, u32 power_state, u32 pc, u32 context_id);
|
|
s32 psci_cpu_off(void);
|
|
-s32 psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc,
|
|
- u32 context_id);
|
|
-s32 psci_affinity_info(u32 function_id, u32 target_affinity,
|
|
- u32 lowest_affinity_level);
|
|
+s32 psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc, u32 context_id);
|
|
+s32 psci_affinity_info(u32 function_id, u32 target_affinity, u32 power_level);
|
|
u32 psci_migrate_info_type(void);
|
|
void psci_system_off(void);
|
|
void psci_system_reset(void);
|
|
s32 psci_features(u32 function_id, u32 psci_fid);
|
|
+s32 psci_cpu_default_suspend(u32 function_id, u32 pc, u32 context_id);
|
|
+s32 psci_node_hw_state(u32 function_id, u32 target_cpu, u32 power_level);
|
|
+s32 psci_system_suspend(u32 function_id, u32 pc, u32 context_id);
|
|
+s32 psci_system_reset2(u32 function_id, u32 reset_type, u32 cookie);
|
|
#endif
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
--- a/tools/sunxi_egon.c
|
|
+++ b/tools/sunxi_egon.c
|
|
@@ -12,7 +12,7 @@
|
|
* NAND requires 8K padding. SD/eMMC gets away with 512 bytes,
|
|
* but let's use the larger padding to cover both.
|
|
*/
|
|
-#define PAD_SIZE 8192
|
|
+#define PAD_SIZE 1024
|
|
|
|
static int egon_check_params(struct image_tool_params *params)
|
|
{
|