Files
build/patch/atf/atf-spacemit/002-Update-for-v1.0beta3.1.patch
The-going 2e5611c92d spacemit: opensbi, u-boot, kernel legacy: Update for v1.0.15
Re-extract the kernel patches as a series.
Re-extract the u-boot patches as "git format-patch" command.

Unified patch extraction makes it easier to work with patches.
2024-10-09 20:47:00 +02:00

1202 lines
40 KiB
Diff

From 7aad08218f25d4eed674bc172995f38291ebfb5e Mon Sep 17 00:00:00 2001
From: James Deng <james.deng@spacemit.com>
Date: Mon, 15 Apr 2024 11:42:57 +0800
Subject: Update for v1.0beta3.1
---
debian/.gitignore | 1 +
debian/README.source | 7 +
debian/bin/git-snapshot | 18 ++
debian/control | 24 +++
debian/copyright | 177 ++++++++++++++++++
debian/opensbi-spacemit.docs | 2 +
debian/opensbi-spacemit.install | 1 +
debian/opensbi-spacemit.lintian-overrides | 9 +
debian/opensbi-spacemit.postinst | 45 +++++
debian/rules | 27 +++
debian/source/format | 1 +
debian/upstream/metadata | 5 +
debian/watch | 3 +
include/sbi/riscv_encoding.h | 1 +
include/sbi_utils/irqchip/fdt_irqchip_plic.h | 2 -
lib/sbi/sbi_console.c | 7 +
lib/sbi/sbi_hart.c | 6 +
lib/utils/Kconfig | 7 +
lib/utils/arm_scmi/css/common/css_pm.c | 3 +-
lib/utils/irqchip/fdt_irqchip_plic.c | 5 -
lib/utils/psci/psci_common.c | 52 +++++
lib/utils/psci/psci_main.c | 82 ++++++--
lib/utils/psci/psci_private.h | 4 +
.../spacemit/plat/k1x/underly_implement.c | 61 +++++-
lib/utils/psci/spacemit/plat/plat_pm.c | 25 ++-
platform/generic/spacemit/spacemit_k1.c | 175 +++++++++++------
26 files changed, 659 insertions(+), 91 deletions(-)
create mode 100644 debian/.gitignore
create mode 100644 debian/README.source
create mode 100755 debian/bin/git-snapshot
create mode 100644 debian/control
create mode 100644 debian/copyright
create mode 100644 debian/opensbi-spacemit.docs
create mode 100644 debian/opensbi-spacemit.install
create mode 100644 debian/opensbi-spacemit.lintian-overrides
create mode 100755 debian/opensbi-spacemit.postinst
create mode 100755 debian/rules
create mode 100644 debian/source/format
create mode 100644 debian/upstream/metadata
create mode 100644 debian/watch
diff --git a/debian/.gitignore b/debian/.gitignore
new file mode 100644
index 000000000000..6d10dce740f7
--- /dev/null
+++ b/debian/.gitignore
@@ -0,0 +1 @@
+changelog
diff --git a/debian/README.source b/debian/README.source
new file mode 100644
index 000000000000..bd33e1488fcf
--- /dev/null
+++ b/debian/README.source
@@ -0,0 +1,7 @@
+Upstream git snapshots are produced with:
+
+ ./debian/bin/git-snapshot COMMIT
+
+Which produces an upstream version based on "git describe" output.
+
+ -- Vagrant Cascadian <vagrant@debian.org>, Thu, 30 May 2019 15:02:49 -0700
diff --git a/debian/bin/git-snapshot b/debian/bin/git-snapshot
new file mode 100755
index 000000000000..6db5eb241d78
--- /dev/null
+++ b/debian/bin/git-snapshot
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+set -e
+
+commit="$1"
+test -z "$commit" && echo "invalid commit" && exit 1
+package=opensbi
+archive=tar.gz
+version=$(git describe "$commit" | sed -e 's,-,+,' -e 's,-g,.,' -e 's,^v,,g')
+output=../${package}_${version}.orig.${archive}
+test -f "${output}" && echo "already present: ${output}" && exit 1
+
+git archive \
+ --format=${archive} \
+ --prefix=${package}-${version}/ \
+ --output=${output} \
+ ${commit} && \
+ echo "successfully created: ${output}"
diff --git a/debian/control b/debian/control
new file mode 100644
index 000000000000..6c4a1747b5f3
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,24 @@
+Source: opensbi-spacemit
+Section: misc
+Priority: optional
+Maintainer: Vagrant Cascadian <vagrant@debian.org>
+Uploaders: Karsten Merker <merker@debian.org>
+Build-Depends: debhelper-compat (=13),
+ python3,
+ u-boot-tools,
+Standards-Version: 4.6.2
+Rules-Requires-Root: no
+Vcs-Browser: https://salsa.debian.org/opensbi-team/opensbi
+Vcs-Git: https://salsa.debian.org/opensbi-team/opensbi.git
+Homepage: https://github.com/riscv-software-src/opensbi
+
+Package: opensbi-spacemit
+Architecture: all
+Multi-Arch: foreign
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: RISC-V Open Source Supervisor Binary Interface
+ An open-source reference implementation of the RISC-V SBI
+ specifications for platform-specific firmwares executing in M-mode.
+ .
+ The following firmware platforms are provided:
+ generic
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 000000000000..cfbcf75e0649
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,177 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: opensbi
+Source: https://github.com/riscv-software-src/opensbi
+
+Files: *
+Copyright: 2019-2020 Western Digital Corporation or its affiliates and
+ other contributors.
+ 2019-2022 Western Digital Corporation or its affiliates.
+ 2021 Christoph Müllner <cmuellner@linux.com>
+ 2021 YADRO
+ 2021 Cobham Gaisler AB.
+ 2021 Gabriel Somlo
+ 2021-2022 SiFive
+ 2021-2022 Samuel Holland <samuel@sholland.org>
+ 2022 Ventana Micro Systems Inc.
+ 2022 Andes Technology Corporation
+ 2022 StarFive Technology Co., Ltd.
+ 2022 Renesas Electronics Corporation
+ 2023 RISC-V International
+License: BSD-2-clause
+
+Files: include/sbi_utils/sys/htif.h
+ lib/utils/sys/htif.c
+Copyright: 2010-2020, The Regents of the University of California
+License: BSD-3-clause
+
+Files: debian/*
+Copyright: 2019-2022 Vagrant Cascadian <vagrant@debian.org>
+License: BSD-2-clause
+
+Files: platform/generic/renesas/rzfive/rzfive.c
+Copyright: 2022 Renesas Electronics Corp.
+License: GPL-2
+
+Files: platform/fpga/ariane/*
+Copyright: 2019 FORTH-ICS/CARV
+License: BSD-2-clause
+
+Files: lib/utils/libfdt/*
+Copyright: 2006-2012 David Gibson, IBM Corporation.
+ 2012 Kim Phillips, Freescale Semiconductor.
+ 2014 David Gibson <david@gibson.dropbear.id.au>
+ 2016 Free Electrons
+ 2016 NextThing Co.
+ 2018 embedded brains GmbH
+License: BSD-2-clause or GPL-2+
+
+Files: lib/utils/libfdt/objects.mk
+Copyright: 2019 Western Digital Corporation or its affiliates.
+License: BSD-2-clause
+
+Files:
+ lib/utils/libquad/divdi3.c
+ lib/utils/libquad/moddi3.c
+ lib/utils/libquad/qdivrem.c
+ lib/utils/libquad/quad.h
+ lib/utils/libquad/udivdi3.c
+ lib/utils/libquad/umoddi3.c
+Copyright:
+ 1992, 1993 The Regents of the University of California.
+License: BSD-3-clause
+
+Files:
+ lib/utils/libquad/include/limits.h
+ lib/utils/libquad/include/sys/cdefs.h
+ lib/utils/libquad/include/sys/types.h
+ lib/utils/libquad/objects.mk
+Copyright: 2021 Jessica Clarke <jrtc27@jrtc27.com>
+License: BSD-2-clause
+
+Files:
+ include/sbi_utils/fdt/*
+ lib/utils/fdt/*
+Copyright:
+ 2020 Bin Meng <bmeng.cn@gmail.com>
+ 2021 Western Digital Corporation or its affiliates.
+License: BSD-2-clause
+
+Files: scripts/Kconfiglib/*
+Copyright: 2011-2019, Ulf Magnusson <ulfalizer@gmail.com>
+License: ISC
+
+License: BSD-2-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ .
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+License: BSD-3-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ .
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ .
+ 3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+License: GPL-2+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+ .
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ MA 02110-1301 USA
+ .
+ On Debian systems, the complete text of the GNU General Public
+ License Version 2.0 can be found in
+ `/usr/share/common-licenses/GPL-2'.
+
+License: GPL-2
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; version 2 of the
+ License.
+ .
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ MA 02110-1301 USA
+ .
+ On Debian systems, the complete text of the GNU General Public
+ License Version 2.0 can be found in
+ `/usr/share/common-licenses/GPL-2'.
+
+License: ISC
+ Permission to use, copy, modify, and/or distribute this software for
+ any purpose with or without fee is hereby granted, provided that the
+ above copyright notice and this permission notice appear in all
+ copies.
diff --git a/debian/opensbi-spacemit.docs b/debian/opensbi-spacemit.docs
new file mode 100644
index 000000000000..85f6f20d235f
--- /dev/null
+++ b/debian/opensbi-spacemit.docs
@@ -0,0 +1,2 @@
+docs/
+CONTRIBUTORS.md
diff --git a/debian/opensbi-spacemit.install b/debian/opensbi-spacemit.install
new file mode 100644
index 000000000000..d1897d557a11
--- /dev/null
+++ b/debian/opensbi-spacemit.install
@@ -0,0 +1 @@
+build/platform/generic/firmware/fw_*.itb /usr/lib/riscv64-linux-gnu/opensbi/generic/
diff --git a/debian/opensbi-spacemit.lintian-overrides b/debian/opensbi-spacemit.lintian-overrides
new file mode 100644
index 000000000000..8b6168d15e45
--- /dev/null
+++ b/debian/opensbi-spacemit.lintian-overrides
@@ -0,0 +1,9 @@
+# These are binary firmware for use with qemu.
+opensbi binary: arch-independent-package-contains-binary-or-object *usr/lib/*/opensbi/*/fw_*.elf*
+
+# Needs to be statically linked.
+opensbi binary: statically-linked-binary *usr/lib/*/opensbi/*/fw_*.elf*
+
+# Binary firmwares being installed into multi-arch directory for
+# future-proofing if riscv32 becomes a thing.
+opensbi binary: triplet-dir-and-architecture-mismatch is for riscv64 instead of all *usr/lib/riscv64-linux-gnu/*
diff --git a/debian/opensbi-spacemit.postinst b/debian/opensbi-spacemit.postinst
new file mode 100755
index 000000000000..1f6feca80674
--- /dev/null
+++ b/debian/opensbi-spacemit.postinst
@@ -0,0 +1,45 @@
+#!/bin/sh
+set -e
+
+case "$1" in
+configure)
+ target=""
+ if grep -q '^spacemit' /sys/firmware/devicetree/base/model; then
+ target="spacemit"
+ else
+ exit 0
+ fi
+
+ for x in $(cat /proc/cmdline); do
+ case $x in
+ root=*)
+ ROOT=${x#root=}
+ ;;
+ esac
+ done
+
+ if [ -n $ROOT ]; then
+ case $ROOT in
+ "/dev/mmcblk0"*)
+ OPENSBI=/dev/mmcblk0p3
+ ;;
+ "/dev/mmcblk2"*)
+ OPENSBI=/dev/mmcblk2p3
+ ;;
+ *)
+ echo "Unsupported root=$ROOT"
+ exit 0
+ ;;
+ esac
+ else
+ echo "Missing root= in cmdline"
+ exit 0
+ fi
+
+ if [ -n "$target" ] && [ -e $OPENSBI ]; then
+ dd if=/usr/lib/riscv64-linux-gnu/opensbi/generic/fw_dynamic.itb of=$OPENSBI bs=1 && sync
+ fi
+ ;;
+esac
+
+exit 0
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 000000000000..ab9cc10c406c
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,27 @@
+#!/usr/bin/make -f
+# Always set CROSS_COMPILE, which also works for native builds.
+export CROSS_COMPILE=riscv64-unknown-linux-gnu-
+export ARCH=riscv
+
+# Enable verbose build by default, disable when terse is specified.
+ifeq (,$(filter terse,$(DEB_BUILD_OPTIONS)))
+VERBOSE=1
+else
+VERBOSE=0
+endif
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ make \
+ V=$(VERBOSE) \
+ PLATFORM_DEFCONFIG=k1_defconfig \
+ PLATFORM=generic ; \
+
+override_dh_installdocs:
+ dh_installdocs --exclude=doxygen.cfg
+
+override_dh_install:
+ chmod -x build/platform/generic/firmware/fw_*.bin
+ dh_install
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 000000000000..163aaf8d82b6
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/upstream/metadata b/debian/upstream/metadata
new file mode 100644
index 000000000000..f716ba77edcd
--- /dev/null
+++ b/debian/upstream/metadata
@@ -0,0 +1,5 @@
+---
+Bug-Database: https://github.com/riscv-software-src/opensbi/issues
+Bug-Submit: https://github.com/riscv-software-src/opensbi/issues/new
+Repository: https://github.com/riscv-software-src/opensbi.git
+Repository-Browse: https://github.com/riscv-software-src/opensbi
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 000000000000..508d476a75c0
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,3 @@
+version=4
+opts=filenamemangle=s/\/(.*)v/@PACKAGE@-/ \
+ https://github.com/riscv-software-src/@PACKAGE@/tags .*/v@ANY_VERSION@.tar.gz
diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h
index 54e09d44528b..5abb8e4c776b 100644
--- a/include/sbi/riscv_encoding.h
+++ b/include/sbi/riscv_encoding.h
@@ -709,6 +709,7 @@
#define CSR_MIPH 0x354
#define CSR_TCMCFG 0x5DB
+#define CSR_FEATURECTL 0xbf9
/* ===== Trap/Exception Causes ===== */
diff --git a/include/sbi_utils/irqchip/fdt_irqchip_plic.h b/include/sbi_utils/irqchip/fdt_irqchip_plic.h
index b892b0bc70f8..df645dd00ee3 100644
--- a/include/sbi_utils/irqchip/fdt_irqchip_plic.h
+++ b/include/sbi_utils/irqchip/fdt_irqchip_plic.h
@@ -28,8 +28,6 @@ void fdt_plic_context_save(bool smode, u32 *enable, u32 *threshold, u32 num);
void fdt_plic_context_restore(bool smode, const u32 *enable, u32 threshold,
u32 num);
-void fdt_plic_context_exit(void);
-
void thead_plic_restore(void);
#endif
diff --git a/lib/sbi/sbi_console.c b/lib/sbi/sbi_console.c
index 168dffd06429..9d917ec78927 100644
--- a/lib/sbi/sbi_console.c
+++ b/lib/sbi/sbi_console.c
@@ -422,6 +422,7 @@ int sbi_snprintf(char *out, u32 out_sz, const char *format, ...)
return retval;
}
+#ifdef CONFIG_ENABLE_LOGGING
int sbi_printf(const char *format, ...)
{
va_list args;
@@ -435,6 +436,12 @@ int sbi_printf(const char *format, ...)
return retval;
}
+#else
+int sbi_printf(const char *format, ...)
+{
+ return 0;
+}
+#endif
int sbi_dprintf(const char *format, ...)
{
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 3a3265df7f20..a3f752d27105 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -819,6 +819,12 @@ sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
}
csr_write(CSR_TCMCFG, 1);
+ /*
+ * update 0xfb9 csr:
+ * bit9: for emprove fence operation
+ * bit23 for disable vector load/store dual-issue
+ */
+ csr_set(CSR_FEATURECTL, (1<<9)|(1<<23));
register unsigned long a0 asm("a0") = arg0;
register unsigned long a1 asm("a1") = arg1;
diff --git a/lib/utils/Kconfig b/lib/utils/Kconfig
index 3ac04ab1ab4f..dab9bf956598 100644
--- a/lib/utils/Kconfig
+++ b/lib/utils/Kconfig
@@ -24,4 +24,11 @@ source "$(OPENSBI_SRC_DIR)/lib/utils/timer/Kconfig"
source "$(OPENSBI_SRC_DIR)/lib/utils/psci/Kconfig"
+config ENABLE_LOGGING
+ bool "Enable Logging"
+ default n
+ help
+ Enables or disables logging throughout the system.
+ Enable this option to allow the system to print log messages.
+
endmenu
diff --git a/lib/utils/arm_scmi/css/common/css_pm.c b/lib/utils/arm_scmi/css/common/css_pm.c
index 8d17b6be442f..83908c747d8d 100644
--- a/lib/utils/arm_scmi/css/common/css_pm.c
+++ b/lib/utils/arm_scmi/css/common/css_pm.c
@@ -114,8 +114,7 @@ static void css_power_down_common(const psci_power_state_t *target_state)
static int css_pwr_domain_off_early(const psci_power_state_t *target_state)
{
/* the ipi's pending is cleared before */
- /* disable the plic irq */
- fdt_plic_context_exit();
+ csr_clear(CSR_MIE, MIP_SSIP | MIP_MSIP | MIP_STIP | MIP_MTIP | MIP_SEIP | MIP_MEIP);
/* clear the external irq pending */
csr_clear(CSR_MIP, MIP_MEIP);
csr_clear(CSR_MIP, MIP_SEIP);
diff --git a/lib/utils/irqchip/fdt_irqchip_plic.c b/lib/utils/irqchip/fdt_irqchip_plic.c
index 0a2d61b0beca..829c5ee20341 100644
--- a/lib/utils/irqchip/fdt_irqchip_plic.c
+++ b/lib/utils/irqchip/fdt_irqchip_plic.c
@@ -85,11 +85,6 @@ static int irqchip_plic_warm_init(void)
plic_get_hart_scontext(scratch));
}
-void fdt_plic_context_exit(void)
-{
- irqchip_plic_warm_init();
-}
-
static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
struct plic_data *pd)
{
diff --git a/lib/utils/psci/psci_common.c b/lib/utils/psci/psci_common.c
index f4b4bee03ec4..0a8ebd1319fd 100644
--- a/lib/utils/psci/psci_common.c
+++ b/lib/utils/psci/psci_common.c
@@ -870,3 +870,55 @@ void riscv_pwr_state_to_psci(unsigned int rstate, unsigned int *pstate)
if (rstate & (PSTATE_PWR_LVL_MASK << RSTATE_PWR_LVL_SHIFT))
*pstate |= (rstate & (PSTATE_PWR_LVL_MASK << RSTATE_PWR_LVL_SHIFT));
}
+
+/*******************************************************************************
+ * This function verifies that all the other cores in the system have been
+ * turned OFF and the current CPU is the last running CPU in the system.
+ * Returns true, if the current CPU is the last ON CPU or false otherwise.
+ ******************************************************************************/
+bool psci_is_last_on_cpu(void)
+{
+ unsigned int cpu_idx;
+ unsigned int hartid = current_hartid();
+ int my_idx = plat_core_pos_by_mpidr(hartid);
+
+ for (cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
+ if (cpu_idx == my_idx) {
+ if (psci_get_aff_info_state() != AFF_STATE_ON) {
+ sbi_printf("%s:%d\n", __func__, __LINE__);
+ sbi_hart_hang();
+ }
+ continue;
+ }
+
+ if (psci_get_aff_info_state_by_idx(cpu_idx) != AFF_STATE_OFF) {
+ sbi_printf("core=%u other than current core=%u %s\n",
+ cpu_idx, my_idx, "running in the system");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/******************************************************************************
+ * This function retrieves the `psci_power_state_t` for system suspend from
+ * the platform.
+ *****************************************************************************/
+void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info)
+{
+ /*
+ * Assert that the required pm_ops hook is implemented to ensure that
+ * the capability detected during psci_setup() is valid.
+ */
+ if (psci_plat_pm_ops->get_sys_suspend_power_state == NULL) {
+ sbi_printf("%s:%d\n", __func__, __LINE__);
+ sbi_hart_hang();
+ }
+
+ /*
+ * Query the platform for the power_state required for system suspend
+ */
+ psci_plat_pm_ops->get_sys_suspend_power_state(state_info);
+}
+
diff --git a/lib/utils/psci/psci_main.c b/lib/utils/psci/psci_main.c
index f2441f57e16e..a3ce138c00cc 100644
--- a/lib/utils/psci/psci_main.c
+++ b/lib/utils/psci/psci_main.c
@@ -9,34 +9,32 @@
/*******************************************************************************
* PSCI frontend api for servicing SMCs. Described in the PSCI spec.
******************************************************************************/
-int psci_cpu_on(u_register_t target_cpu,
- uintptr_t entrypoint)
-
+int psci_cpu_on(u_register_t target_cpu, uintptr_t entrypoint)
{
- int rc;
+ int rc;
- /* Determine if the cpu exists of not */
- rc = psci_validate_mpidr(target_cpu);
- if (rc != PSCI_E_SUCCESS)
- return PSCI_E_INVALID_PARAMS;
+ /* Determine if the cpu exists of not */
+ rc = psci_validate_mpidr(target_cpu);
+ if (rc != PSCI_E_SUCCESS)
+ return PSCI_E_INVALID_PARAMS;
- /*
- * To turn this cpu on, specify which power
- * levels need to be turned on
- */
- return psci_cpu_on_start(target_cpu, entrypoint);
+ /*
+ * To turn this cpu on, specify which power
+ * levels need to be turned on
+ */
+ return psci_cpu_on_start(target_cpu, entrypoint);
}
int psci_affinity_info(u_register_t target_affinity,
unsigned int lowest_affinity_level)
{
- int ret;
- unsigned int target_idx;
+ int ret;
+ unsigned int target_idx;
psci_cpu_data_t *svc_cpu_data;
struct sbi_scratch *scratch = sbi_hartid_to_scratch(target_affinity);
svc_cpu_data = sbi_scratch_offset_ptr(scratch, psci_delta_off);
- /* We dont support level higher than PSCI_CPU_PWR_LVL */
+ /* We dont support level higher than PSCI_CPU_PWR_LVL */
if (lowest_affinity_level > PSCI_CPU_PWR_LVL)
return PSCI_E_INVALID_PARAMS;
@@ -186,3 +184,55 @@ int psci_cpu_suspend(unsigned int power_state,
return rc;
}
+int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id)
+{
+ int rc;
+ psci_power_state_t state_info;
+ /* entry_point_info_t ep; */
+
+ /* Check if the current CPU is the last ON CPU in the system */
+ if (!psci_is_last_on_cpu())
+ return PSCI_E_DENIED;
+
+ /* Validate the entry point and get the entry_point_info */
+/**
+ * rc = psci_validate_entry_point(&ep, entrypoint, context_id);
+ * if (rc != PSCI_E_SUCCESS)
+ * return rc;
+ */
+
+ /* Query the psci_power_state for system suspend */
+ psci_query_sys_suspend_pwrstate(&state_info);
+
+ /*
+ * Check if platform allows suspend to Highest power level
+ * (System level)
+ */
+ if (psci_find_target_suspend_lvl(&state_info) < PLAT_MAX_PWR_LVL)
+ return PSCI_E_DENIED;
+
+ /* Ensure that the psci_power_state makes sense */
+ if (psci_validate_suspend_req(&state_info, PSTATE_TYPE_POWERDOWN)
+ != PSCI_E_SUCCESS) {
+ sbi_printf("%s:%d\n", __func__, __LINE__);
+ sbi_hart_hang();
+ }
+
+ if (is_local_state_off(
+ state_info.pwr_domain_state[PLAT_MAX_PWR_LVL]) == 0) {
+ sbi_printf("%s:%d\n", __func__, __LINE__);
+ sbi_hart_hang();
+ }
+
+ /*
+ * Do what is needed to enter the system suspend state. This function
+ * might return if the power down was abandoned for any reason, e.g.
+ * arrival of an interrupt
+ */
+ rc = psci_cpu_suspend_start(/* &ep */entrypoint,
+ PLAT_MAX_PWR_LVL,
+ &state_info,
+ PSTATE_TYPE_POWERDOWN);
+
+ return rc;
+}
diff --git a/lib/utils/psci/psci_private.h b/lib/utils/psci/psci_private.h
index d1cd2ba84742..c768d3f379ab 100644
--- a/lib/utils/psci/psci_private.h
+++ b/lib/utils/psci/psci_private.h
@@ -142,6 +142,10 @@ int psci_cpu_suspend_start(/* const entry_point_info_t *ep */ uintptr_t entrypoi
void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info);
void riscv_pwr_state_to_psci(unsigned int rstate, unsigned int *pstate);
+bool psci_is_last_on_cpu(void);
+void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info);
+int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id);
+
/* Helper function to identify a CPU standby request in PSCI Suspend call */
static inline bool is_cpu_standby_req(unsigned int is_power_down_state,
unsigned int retn_lvl)
diff --git a/lib/utils/psci/spacemit/plat/k1x/underly_implement.c b/lib/utils/psci/spacemit/plat/k1x/underly_implement.c
index 9976b5774039..279e6d5dc741 100644
--- a/lib/utils/psci/spacemit/plat/k1x/underly_implement.c
+++ b/lib/utils/psci/spacemit/plat/k1x/underly_implement.c
@@ -27,10 +27,20 @@
#define PMU_ACPR_CLUSTER0_REG (0xd4051090)
#define PMU_ACPR_CLUSTER1_REG (0xd4051094)
+#define PMU_ACPR_UNKONW_REG (0xd4050038)
+
#define CPU_PWR_DOWN_VALUE (0x3)
#define CLUSTER_PWR_DOWN_VALUE (0x3)
#define CLUSTER_AXISDO_OFFSET (31)
+#define CLUSTER_DDRSD_OFFSET (27)
+#define CLUSTER_APBSD_OFFSET (26)
+#define CLUSTER_VCXOSD_OFFSET (19)
+#define CLUSTER_BIT29_OFFSET (29)
+#define CLUSTER_BIT14_OFFSET (14)
+#define CLUSTER_BIT30_OFFSET (30)
+#define CLUSTER_BIT25_OFFSET (25)
+#define CLUSTER_BIT13_OFFSET (13)
struct pmu_cap_wakeup {
unsigned int pmu_cap_core0_wakeup;
@@ -39,7 +49,7 @@ struct pmu_cap_wakeup {
unsigned int pmu_cap_core3_wakeup;
};
-/* D1P */
+/* D1P & D2 ? */
void spacemit_top_on(u_register_t mpidr)
{
unsigned int *cluster0_acpr = NULL;
@@ -49,15 +59,31 @@ void spacemit_top_on(u_register_t mpidr)
cluster1_acpr = (unsigned int *)PMU_ACPR_CLUSTER1_REG;
unsigned int value = readl(cluster0_acpr);
- value &= ~(1 << CLUSTER_AXISDO_OFFSET);
+ value &= ~((1 << CLUSTER_AXISDO_OFFSET) |
+ (1 << CLUSTER_DDRSD_OFFSET) |
+ (1 << CLUSTER_APBSD_OFFSET) |
+ (1 << CLUSTER_VCXOSD_OFFSET) |
+ (1 << CLUSTER_BIT29_OFFSET) |
+ (1 << CLUSTER_BIT14_OFFSET) |
+ (1 << CLUSTER_BIT30_OFFSET) |
+ (1 << CLUSTER_BIT25_OFFSET) |
+ (1 << CLUSTER_BIT13_OFFSET));
writel(value, cluster0_acpr);
value = readl(cluster1_acpr);
- value &= ~(1 << CLUSTER_AXISDO_OFFSET);
+ value &= ~((1 << CLUSTER_AXISDO_OFFSET) |
+ (1 << CLUSTER_DDRSD_OFFSET) |
+ (1 << CLUSTER_APBSD_OFFSET) |
+ (1 << CLUSTER_VCXOSD_OFFSET) |
+ (1 << CLUSTER_BIT29_OFFSET) |
+ (1 << CLUSTER_BIT14_OFFSET) |
+ (1 << CLUSTER_BIT30_OFFSET) |
+ (1 << CLUSTER_BIT25_OFFSET) |
+ (1 << CLUSTER_BIT13_OFFSET));
writel(value, cluster1_acpr);
}
-/* D1P */
+/* D1P & D2 ? */
void spacemit_top_off(u_register_t mpidr)
{
unsigned int *cluster0_acpr = NULL;
@@ -67,12 +93,35 @@ void spacemit_top_off(u_register_t mpidr)
cluster1_acpr = (unsigned int *)PMU_ACPR_CLUSTER1_REG;
unsigned int value = readl(cluster0_acpr);
- value |= (1 << CLUSTER_AXISDO_OFFSET);
+ value |= (1 << CLUSTER_AXISDO_OFFSET) |
+ (1 << CLUSTER_DDRSD_OFFSET) |
+ (1 << CLUSTER_APBSD_OFFSET) |
+ (1 << CLUSTER_VCXOSD_OFFSET) |
+ (1 << CLUSTER_BIT29_OFFSET) |
+ (1 << CLUSTER_BIT14_OFFSET) |
+ (1 << CLUSTER_BIT30_OFFSET) |
+ (1 << CLUSTER_BIT25_OFFSET) |
+ (1 << CLUSTER_BIT13_OFFSET);
writel(value, cluster0_acpr);
value = readl(cluster1_acpr);
- value |= (1 << CLUSTER_AXISDO_OFFSET);
+ value |= (1 << CLUSTER_AXISDO_OFFSET) |
+ (1 << CLUSTER_DDRSD_OFFSET) |
+ (1 << CLUSTER_APBSD_OFFSET) |
+ (1 << CLUSTER_VCXOSD_OFFSET) |
+ (1 << CLUSTER_BIT29_OFFSET) |
+ (1 << CLUSTER_BIT14_OFFSET) |
+ (1 << CLUSTER_BIT30_OFFSET) |
+ (1 << CLUSTER_BIT25_OFFSET) |
+ (1 << CLUSTER_BIT13_OFFSET);
writel(value, cluster1_acpr);
+
+ value = readl((unsigned int *)PMU_ACPR_UNKONW_REG);
+ value |= (1 << 2);
+ writel(value, (unsigned int *)PMU_ACPR_UNKONW_REG);
+
+ /* for wakeup debug */
+ writel(0xffff, (unsigned int *)0xd4051030);
}
/* M2 */
diff --git a/lib/utils/psci/spacemit/plat/plat_pm.c b/lib/utils/psci/spacemit/plat/plat_pm.c
index 464a56a277ef..da6f958157fa 100644
--- a/lib/utils/psci/spacemit/plat/plat_pm.c
+++ b/lib/utils/psci/spacemit/plat/plat_pm.c
@@ -16,6 +16,9 @@
#define SYSTEM_PWR_STATE(state) \
((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
+/* reserved for future used */
+/* unsigned long __plic_regsave_offset_ptr; */
+
static int spacemit_pwr_domain_on(u_register_t mpidr)
{
/* wakeup the cpu */
@@ -54,8 +57,7 @@ static void spacemit_pwr_domain_on_finish(const psci_power_state_t *target_state
static int spacemit_pwr_domain_off_early(const psci_power_state_t *target_state)
{
/* the ipi's pending is cleared before */
- /* disable the plic irq */
- fdt_plic_context_exit();
+ csr_clear(CSR_MIE, MIP_SSIP | MIP_MSIP | MIP_STIP | MIP_MTIP | MIP_SEIP | MIP_MEIP);
/* clear the external irq pending */
csr_clear(CSR_MIP, MIP_MEIP);
csr_clear(CSR_MIP, MIP_SEIP);
@@ -70,9 +72,9 @@ static int spacemit_pwr_domain_off_early(const psci_power_state_t *target_state)
static void spacemit_pwr_domain_off(const psci_power_state_t *target_state)
{
- unsigned int hartid = current_hartid();
+ unsigned int hartid = current_hartid();
- if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
+ if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
#if defined(CONFIG_PLATFORM_SPACEMIT_K1X)
/* disable the tcm */
csr_write(CSR_TCMCFG, 0);
@@ -82,11 +84,11 @@ static void spacemit_pwr_domain_off(const psci_power_state_t *target_state)
}
if (SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
+ /* D1P */
spacemit_top_off(hartid);
}
spacemit_assert_cpu(hartid);
-
}
static void spacemit_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
@@ -183,7 +185,7 @@ static void spacemit_pwr_domain_suspend(const psci_power_state_t *target_state)
}
if (SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
- /* D1P */
+ /* D1P & D2 */
spacemit_top_off(hartid);
}
@@ -223,7 +225,7 @@ static void spacemit_pwr_domain_suspend_finish(const psci_power_state_t *target_
}
if (SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
- /* D1P */
+ /* D1P & D2 */
spacemit_top_on(hartid);
}
@@ -236,6 +238,14 @@ static void spacemit_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *
csr_clear(CSR_MIE, MIP_SSIP | MIP_MSIP | MIP_STIP | MIP_MTIP | MIP_SEIP | MIP_MEIP);
}
+static void spacemit_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ int i;
+
+ for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+}
+
static const plat_psci_ops_t spacemit_psci_ops = {
.cpu_standby = NULL,
.pwr_domain_on = spacemit_pwr_domain_on,
@@ -248,6 +258,7 @@ static const plat_psci_ops_t spacemit_psci_ops = {
.pwr_domain_suspend = spacemit_pwr_domain_suspend,
.pwr_domain_suspend_pwrdown_early = spacemit_pwr_domain_suspend_pwrdown_early,
.pwr_domain_suspend_finish = spacemit_pwr_domain_suspend_finish,
+ .get_sys_suspend_power_state = spacemit_get_sys_suspend_power_state,
};
int plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops)
diff --git a/platform/generic/spacemit/spacemit_k1.c b/platform/generic/spacemit/spacemit_k1.c
index 8664e05e7910..38794c2dfbb5 100644
--- a/platform/generic/spacemit/spacemit_k1.c
+++ b/platform/generic/spacemit/spacemit_k1.c
@@ -21,6 +21,7 @@
#include <sbi/sbi_ecall_interface.h>
#include <sbi_utils/psci/psci.h>
#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_system.h>
#include <sbi_utils/cache/cacheflush.h>
#include <../../../lib/utils/psci/psci_private.h>
#include <sbi_utils/psci/plat/arm/common/plat_arm.h>
@@ -29,63 +30,110 @@
extern struct sbi_platform platform;
+/* reserved for future use */
+/* extern unsigned long __plic_regsave_offset_ptr; */
+
PLAT_CCI_MAP
static void wakeup_other_core(void)
{
- int i;
- u32 hartid, clusterid, cluster_enabled = 0;
- unsigned int cur_hartid = current_hartid();
- struct sbi_scratch *scratch = sbi_hartid_to_scratch(cur_hartid);
+ int i;
+ u32 hartid, clusterid, cluster_enabled = 0;
+ unsigned int cur_hartid = current_hartid();
+ struct sbi_scratch *scratch = sbi_hartid_to_scratch(cur_hartid);
#if defined(CONFIG_PLATFORM_SPACEMIT_K1X)
- /* set other cpu's boot-entry */
- writel(scratch->warmboot_addr & 0xffffffff, (u32 *)C0_RVBADDR_LO_ADDR);
- writel((scratch->warmboot_addr >> 32) & 0xffffffff, (u32 *)C0_RVBADDR_HI_ADDR);
+ /* set other cpu's boot-entry */
+ writel(scratch->warmboot_addr & 0xffffffff, (u32 *)C0_RVBADDR_LO_ADDR);
+ writel((scratch->warmboot_addr >> 32) & 0xffffffff, (u32 *)C0_RVBADDR_HI_ADDR);
- writel(scratch->warmboot_addr & 0xffffffff, (u32 *)C1_RVBADDR_LO_ADDR);
- writel((scratch->warmboot_addr >> 32) & 0xffffffff, (u32 *)C1_RVBADDR_HI_ADDR);
+ writel(scratch->warmboot_addr & 0xffffffff, (u32 *)C1_RVBADDR_LO_ADDR);
+ writel((scratch->warmboot_addr >> 32) & 0xffffffff, (u32 *)C1_RVBADDR_HI_ADDR);
#elif defined(CONFIG_PLATFORM_SPACEMIT_K1PRO)
- for (i = 0; i < platform.hart_count; i++) {
- hartid = platform.hart_index2id[i];
+ for (i = 0; i < platform.hart_count; i++) {
+ hartid = platform.hart_index2id[i];
unsigned long core_index = MPIDR_AFFLVL1_VAL(hartid) * PLATFORM_MAX_CPUS_PER_CLUSTER
- + MPIDR_AFFLVL0_VAL(hartid);
+ + MPIDR_AFFLVL0_VAL(hartid);
writel(scratch->warmboot_addr & 0xffffffff, (u32 *)(CORE0_RVBADDR_LO_ADDR + core_index * CORE_RVBADDR_STEP));
writel((scratch->warmboot_addr >> 32) & 0xffffffff, (u32 *)(CORE0_RVBADDR_HI_ADDR + core_index * CORE_RVBADDR_STEP));
- }
+ }
#endif
#ifdef CONFIG_ARM_PSCI_SUPPORT
- unsigned char *cpu_topology = plat_get_power_domain_tree_desc();
+ unsigned char *cpu_topology = plat_get_power_domain_tree_desc();
#endif
- // hart0 is already boot up
- for (i = 0; i < platform.hart_count; i++) {
- hartid = platform.hart_index2id[i];
+ // hart0 is already boot up
+ for (i = 0; i < platform.hart_count; i++) {
+ hartid = platform.hart_index2id[i];
- clusterid = MPIDR_AFFLVL1_VAL(hartid);
+ clusterid = MPIDR_AFFLVL1_VAL(hartid);
- /* we only enable snoop of cluster0 */
- if (0 == (cluster_enabled & (1 << clusterid))) {
- cluster_enabled |= 1 << clusterid;
- if (0 == clusterid) {
- cci_enable_snoop_dvm_reqs(clusterid);
- }
+ /* we only enable snoop of cluster0 */
+ if (0 == (cluster_enabled & (1 << clusterid))) {
+ cluster_enabled |= 1 << clusterid;
+ if (0 == clusterid) {
+ cci_enable_snoop_dvm_reqs(clusterid);
+ }
#ifdef CONFIG_ARM_PSCI_SUPPORT
- cpu_topology[CLUSTER_INDEX_IN_CPU_TOPOLOGY]++;
+ cpu_topology[CLUSTER_INDEX_IN_CPU_TOPOLOGY]++;
#endif
- }
+ }
#ifdef CONFIG_ARM_PSCI_SUPPORT
- /* we only support 2 cluster by now */
- if (clusterid == PLATFORM_CLUSTER_COUNT - 1)
- cpu_topology[CLUSTER1_INDEX_IN_CPU_TOPOLOGY]++;
- else
- cpu_topology[CLUSTER0_INDEX_IN_CPU_TOPOLOGY]++;
+ /* we only support 2 cluster by now */
+ if (clusterid == PLATFORM_CLUSTER_COUNT - 1)
+ cpu_topology[CLUSTER1_INDEX_IN_CPU_TOPOLOGY]++;
+ else
+ cpu_topology[CLUSTER0_INDEX_IN_CPU_TOPOLOGY]++;
#endif
- }
+ }
+
+/**
+ * // reserved for future used
+ * // get the number of plic registers
+ * u32 *regnum_pos;
+ * int noff = -1, fdtlen, regnum, regsize;
+ * const fdt32_t *fdtval;
+ * void *fdt = fdt_get_address();
+ * const struct fdt_match match_table = { .compatible = "riscv,plic0", };
+ *
+ * noff = fdt_find_match(fdt, noff, &match_table, NULL);
+ * if (noff >= 0) {
+ * fdtval = fdt_getprop(fdt, noff, "riscv,ndev", &fdtlen);
+ * if (fdtlen > 0) {
+ * regnum = fdt32_to_cpu(*fdtval);
+ * regsize =
+ * // regnum + regsize
+ * sizeof(u32) + sizeof(u32) +
+ * // plic priority regisrer
+ * sizeof(u8) * regnum +
+ * // plic enable register
+ * (sizeof(u32) * (regnum / 32 + 1) +
+ * // plic threshold regisrer
+ * sizeof (u32) * 1) * 2; // smode and machine mode
+ *
+ * __plic_regsave_offset_ptr = sbi_scratch_alloc_offset(regsize);
+ * if (__plic_regsave_offset_ptr == 0) {
+ * sbi_hart_hang();
+ * }
+ * }
+ * }
+ *
+ * if (__plic_regsave_offset_ptr) {
+ * for (i = 0; i < platform.hart_count; i++) {
+ * hartid = platform.hart_index2id[i];
+ * scratch = sbi_hartid_to_scratch(hartid);
+ * u32 *regnum_pos = sbi_scratch_offset_ptr(scratch, __plic_regsave_offset_ptr);
+ *
+ * regnum_pos[0] = regnum;
+ * regnum_pos[1] = regsize;
+ * csi_dcache_clean_invalid_range((uintptr_t)regnum_pos, regsize);
+ * }
+ * }
+ */
}
/*
@@ -93,24 +141,24 @@ static void wakeup_other_core(void)
*/
static int spacemit_k1_early_init(bool cold_boot, const struct fdt_match *match)
{
- if (cold_boot) {
- /* initiate cci */
- cci_init(PLATFORM_CCI_ADDR, cci_map, array_size(cci_map));
- /* enable dcache */
- csi_enable_dcache();
- /* wakeup other core ? */
- wakeup_other_core();
- /* initialize */
+ if (cold_boot) {
+ /* initiate cci */
+ cci_init(PLATFORM_CCI_ADDR, cci_map, array_size(cci_map));
+ /* enable dcache */
+ csi_enable_dcache();
+ /* wakeup other core ? */
+ wakeup_other_core();
+ /* initialize */
#ifdef CONFIG_ARM_SCMI_PROTOCOL_SUPPORT
- plat_arm_pwrc_setup();
+ plat_arm_pwrc_setup();
#endif
- } else {
+ } else {
#ifdef CONFIG_ARM_PSCI_SUPPORT
- psci_warmboot_entrypoint();
+ psci_warmboot_entrypoint();
#endif
- }
+ }
- return 0;
+ return 0;
}
#ifdef CONFIG_ARM_PSCI_SUPPORT
@@ -127,14 +175,12 @@ static int spacemit_hart_start(unsigned int hartid, unsigned long saddr)
static int spacemit_hart_stop(void)
{
psci_cpu_off();
-
return 0;
}
static int spacemit_hart_suspend(unsigned int suspend_type)
{
psci_cpu_suspend(suspend_type, 0, 0);
-
return 0;
}
@@ -150,6 +196,27 @@ static const struct sbi_hsm_device spacemit_hsm_ops = {
.hart_suspend = spacemit_hart_suspend,
.hart_resume = spacemit_hart_resume,
};
+
+static int spacemit_system_suspend_check(u32 sleep_type)
+{
+ return sleep_type == SBI_SUSP_SLEEP_TYPE_SUSPEND ? 0 : SBI_EINVAL;
+}
+
+static int spacemit_system_suspend(u32 sleep_type, unsigned long mmode_resume_addr)
+{
+ if (sleep_type != SBI_SUSP_SLEEP_TYPE_SUSPEND)
+ return SBI_EINVAL;
+
+ psci_system_suspend(mmode_resume_addr, 0);
+
+ return SBI_OK;
+}
+
+static struct sbi_system_suspend_device spacemit_system_suspend_ops = {
+ .name = "spacemit-system-suspend",
+ .system_suspend_check = spacemit_system_suspend_check,
+ .system_suspend = spacemit_system_suspend,
+};
#endif
/*
@@ -158,14 +225,16 @@ static const struct sbi_hsm_device spacemit_hsm_ops = {
static int spacemit_k1_final_init(bool cold_boot, const struct fdt_match *match)
{
#ifdef CONFIG_ARM_PSCI_SUPPORT
- /* for clod boot, we build the cpu topology structure */
- if (cold_boot) {
- sbi_hsm_set_device(&spacemit_hsm_ops);
- return psci_setup();
- }
+ /* for clod boot, we build the cpu topology structure */
+ if (cold_boot) {
+ sbi_hsm_set_device(&spacemit_hsm_ops);
+ /* register system-suspend ops */
+ sbi_system_suspend_set_device(&spacemit_system_suspend_ops);
+ return psci_setup();
+ }
#endif
- return 0;
+ return 0;
}
static bool spacemit_cold_boot_allowed(u32 hartid, const struct fdt_match *match)
--
2.35.3