Implement hart hotplug using HSM extension for AE350
v3 cover Implement hart hotplug using HSM extension for AE350
The following patches include implementing hotplug with ATCSMU deep sleep mode using HSM extension, introduce ATCSMU system device and some fixes, base on OpenSBI v1.2 and test on AE350 platform with the CPU listed below:
RV64:
* AX45MP quad-core
* AX45MP octa-core
* AX25MP quad-core
RV32:
* A45MP quad-core
* A25MP quad-core
Changes v1 -> v2:
* Drop patch for adding secondary_boot callback
* Add a PATCH4 to move ATCSMU related code to lib/utils/sys
* Include RB tags
Changes v2 -> v3:
* Refine PATCH4 suggested by Anup [1]
* Remove redundant headers
* Move is_andes25() to ae350.c
* Add "struct smu_data *smu" parameter to each smu related functions
* Refine PATCH6 suggested by Anup [2]
* Make FDT_RESET_ATCWDT200 depends on SYS_ATCSMU
* PATCH5 & PATCH6: Instantiate struct smu_data in ae350.c and fdt_reset_atcwdt200.c
[1] https://lists.infradead.org/pipermail/opensbi/2023-January/004236.html
[2] https://lists.infradead.org/pipermail/opensbi/2023-January/004237.html
Yu Chien Peter Lin (6):
docs: generic.md: fix typo of andes-ae350
lib: sbi_hsm: handle failure when hart_stop returns SBI_ENOTSUPP
include: types: add always inline compiler attribute
lib: utils: atcsmu: Add Andes System Management Unit support
platform: andes/ae350: Implement hart hotplug using HSM extension
lib: reset/fdt_reset_atcwdt200: Use defined macros and function in
atcsmu.h
docs/platform/generic.md | 2 +- include/sbi/sbi_hsm.h | 8 +- include/sbi/sbi_types.h | 1 + include/sbi_utils/sys/atcsmu.h | 53 +++++++++++++ lib/sbi/sbi_hsm.c | 7 +- lib/utils/reset/Kconfig | 1 + lib/utils/reset/fdt_reset_atcwdt200.c | 21 ++--- lib/utils/sys/Kconfig | 4 + lib/utils/sys/atcsmu.c | 92 ++++++++++++++++++++++ lib/utils/sys/objects.mk | 1 + platform/generic/Kconfig | 1 + platform/generic/andes/ae350.c | 99 ++++++++++++++++++++++++ platform/generic/andes/objects.mk | 2 +- platform/generic/andes/sleep.S | 70 +++++++++++++++++ platform/generic/include/andes/andes45.h | 10 +++ 15 files changed, 351 insertions(+), 21 deletions(-) create mode 100644 include/sbi_utils/sys/atcsmu.h create mode 100644 lib/utils/sys/atcsmu.c create mode 100644 platform/generic/andes/sleep.S create mode 100644 platform/generic/include/andes/andes45.h
Signature · 1 line
2.34.1
PATCH v3 1/6 docs: generic.md: fix typo of andes-ae350
Fix hyperlink due to the typo.
--- docs/platform/generic.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
docs/platform/generic.md +1 -1
@@ -53,7 +53,7 @@ RISC-V Platforms Using Generic Platform * **Spike** (*[spike.md]*) * **T-HEAD C9xx series Processors** (*[thead-c9xx.md]*) -[andes-ae350.md]: andse-ae350.md +[andes-ae350.md]: andes-ae350.md [qemu_virt.md]: qemu_virt.md [renesas-rzfive.md]: renesas-rzfive.md [shakti_cclass.md]: shakti_cclass.md
Signature · 1 line
2.34.1
PATCH v3 2/6 lib: sbi_hsm: handle failure when hart_stop returns SBI_ENOTSUPP
In reply to Yu Chien Peter LinMake use of generic warm-boot path when platform hart_stop callback returns SBI_ENOTSUPP, in case certain hart can not turn off its power domain, or it detects some error occured in power management unit, it can fall through warmboot flow and wait for interrupt in sbi_hsm_hart_wait().
Also improves comment in sbi_hsm_hart_wait().
--- include/sbi/sbi_hsm.h | 8 ++++++-- lib/sbi/sbi_hsm.c | 7 +++---- 2 files changed, 9 insertions(+), 6 deletions(-)
include/sbi/sbi_hsm.h +6 -2
@@ -21,8 +21,12 @@ struct sbi_hsm_device {int (*hart_start)(u32 hartid,ulong saddr);/** -* Stop (or power-down) the current hart from running. This call -* doesn't expect to return if success. +* Stop (or power-down) the current hart from running. +* +* Return SBI_ENOTSUPP if the hart does not support platform-specific +* stop actions. +* +* For successful stop, the call won't return. */ int (*hart_stop)(void );
lib/sbi/sbi_hsm.c +3 -4
@@ -116,7 +116,7 @@ static void sbi_hsm_hart_wait(struct sbi_scratch *scratch, u32 hartid)/* Set MSIE and MEIE bits to receive IPI */ csr_set (CSR_MIE ,MIP_MSIP |MIP_MEIP ); -/* Wait for hart_add call*/ +/* Wait for state transition requested by sbi_hsm_hart_start() */ while (atomic_read (&hdata->state) !=SBI_HSM_STATE_START_PENDING ) {wfi (); };
@@ -228,9 +228,8 @@ void __noreturn sbi_hsm_exit(struct sbi_scratch *scratch) goto fail_exit;if (hsm_device_has_hart_hotplug ()) { -hsm_device_hart_stop (); -/* It should never reach here */ - goto fail_exit; +if (hsm_device_hart_stop () !=SBI_ENOTSUPP ) + goto fail_exit; }/**
Signature · 1 line
2.34.1
PATCH v3 3/6 include: types: add always inline compiler attribute
In reply to Yu Chien Peter LinProvide __always_inline to sbi_types header.
--- include/sbi/sbi_types.h | 1 + 1 file changed, 1 insertion(+)
include/sbi/sbi_types.h +1 -0
@@ -62,6 +62,7 @@ typedef unsigned long physical_size_t;#define __packed __attribute__((packed))#define __noreturn __attribute__((noreturn))#define __aligned (x) __attribute__((aligned(x))) +#define __always_inline inline __attribute__((always_inline))#define likely (x) __builtin_expect((x), 1)#define unlikely (x) __builtin_expect((x), 0)
Signature · 1 line
2.34.1
PATCH v3 4/6 lib: utils: atcsmu: Add Andes System Management Unit support
In reply to Yu Chien Peter LinThis patch adds atcsmu support for Andes AE350 platforms. The SMU provides system management capabilities, including clock, reset and power control based on power domain partitions.
--- include/sbi_utils/sys/atcsmu.h | 53 ++++++++++++++++++++ lib/utils/sys/Kconfig | 4 ++ lib/utils/sys/atcsmu.c | 92 ++++++++++++++++++++++++++++++++++ lib/utils/sys/objects.mk | 1 + platform/generic/Kconfig | 1 + 5 files changed, 151 insertions(+) create mode 100644 include/sbi_utils/sys/atcsmu.h create mode 100644 lib/utils/sys/atcsmu.c
include/sbi_utils/sys/atcsmu.h new file +53 -0
@@ -0,0 +1,53 @@ +/* +* SPDX-License-Identifier: BSD-3-Clause +* +* Copyright (c) 2023 Andes Technology Corporation +*/ + +#ifndef _SYS_ATCSMU_H +#define _SYS_ATCSMU_H + +#include <sbi/sbi_types.h> + +#define PCS0_WE_OFFSET 0x90 +#define PCSm_WE_OFFSET (i) ((i + 3) * 0x20 + PCS0_WE_OFFSET) + +#define PCS0_CTL_OFFSET 0x94 +#define PCSm_CTL_OFFSET (i) ((i + 3) * 0x20 + PCS0_CTL_OFFSET) +#define PCS_CTL_CMD_SHIFT 0 +#define PCS_CTL_PARAM_SHIFT 3 +#define SLEEP_CMD 0x3 +#define WAKEUP_CMD (0x0 | (1 << PCS_CTL_PARAM_SHIFT)) +#define LIGHTSLEEP_MODE 0 +#define DEEPSLEEP_MODE 1 +#define LIGHT_SLEEP_CMD (SLEEP_CMD | (LIGHTSLEEP_MODE << PCS_CTL_PARAM_SHIFT)) +#define DEEP_SLEEP_CMD (SLEEP_CMD | (DEEPSLEEP_MODE << PCS_CTL_PARAM_SHIFT)) + +#define PCS0_CFG_OFFSET 0x80 +#define PCSm_CFG_OFFSET (i) ((i + 3) * 0x20 + PCS0_CFG_OFFSET) +#define PCS_CFG_LIGHT_SLEEP_SHIFT 2 +#define PCS_CFG_LIGHT_SLEEP (1 << PCS_CFG_LIGHT_SLEEP_SHIFT) +#define PCS_CFG_DEEP_SLEEP_SHIFT 3 +#define PCS_CFG_DEEP_SLEEP (1 << PCS_CFG_DEEP_SLEEP_SHIFT) +#define RESET_VEC_LO_OFFSET 0x50 +#define RESET_VEC_HI_OFFSET 0x60 +#define RESET_VEC_8CORE_OFFSET 0x1a0 +#define HARTn_RESET_VEC_LO (n) \ + (RESET_VEC_LO_OFFSET + \ + ((n) < 4 ? 0 : RESET_VEC_8CORE_OFFSET) + ((n) * 0x4)) +#define HARTn_RESET_VEC_HI (n) \ + (RESET_VEC_HI_OFFSET + \ + ((n) < 4 ? 0 : RESET_VEC_8CORE_OFFSET) + ((n) * 0x4)) +#define PCS_MAX_NR 8 +#define FLASH_BASE 0x80000000ULL + +struct smu_data { +unsigned long addr; +}; + +int smu_set_wakeup_events (struct smu_data *smu,u32 events,u32 hartid); +bool smu_support_sleep_mode (struct smu_data *smu,u32 sleep_mode,u32 hartid); +int smu_set_command (struct smu_data *smu,u32 pcs_ctl,u32 hartid); +int smu_set_reset_vector (struct smu_data *smu,ulong wakeup_addr,u32 hartid); + +#endif /* _SYS_ATCSMU_H */
lib/utils/sys/Kconfig +4 -0
@@ -2,6 +2,10 @@ menu "System Device Support" +config SYS_ATCSMU + bool "Andes System Management Unit (SMU) support" + default n + config SYS_HTIF bool "Host transfere interface (HTIF) support" default n
lib/utils/sys/atcsmu.c new file +92 -0
92 lines not on this page · raw message
lib/utils/sys/objects.mk +1 -0
@@ -9,3 +9,4 @@ libsbiutils-objs-$(CONFIG_SYS_HTIF) += sys/htif.o libsbiutils-objs-$(CONFIG_SYS_SIFIVE_TEST) += sys/sifive_test.o +libsbiutils-objs-$(CONFIG_SYS_ATCSMU) += sys/atcsmu.o
platform/generic/Kconfig +1 -0
@@ -30,6 +30,7 @@ config PLATFORM_ALLWINNER_D1 config PLATFORM_ANDES_AE350 bool "Andes AE350 support" + select SYS_ATCSMU default n config PLATFORM_RENESAS_RZFIVE
Signature · 1 line
2.34.1
PATCH v3 4/6 lib: utils: atcsmu: Add Andes System Management Unit support
Quoted 6 lines · Yu Chien Peter Lin
This patch adds atcsmu support for Andes AE350 platforms. The SMU provides system management capabilities, including clock, reset and power control based on power domain partitions.
Signed-off-by Yu Chien Peter Lin <[email protected]>
Looks good to me.
Regards,
Anup
Quoted 211 lines
--- include/sbi_utils/sys/atcsmu.h | 53 ++++++++++++++++++++ lib/utils/sys/Kconfig | 4 ++ lib/utils/sys/atcsmu.c | 92 ++++++++++++++++++++++++++++++++++ lib/utils/sys/objects.mk | 1 + platform/generic/Kconfig | 1 + 5 files changed, 151 insertions(+) create mode 100644 include/sbi_utils/sys/atcsmu.h create mode 100644 lib/utils/sys/atcsmu.cinclude/sbi_utils/sys/atcsmu.h new file +53
-0@@ -0,0 +1,53 @@ +/* +* SPDX-License-Identifier: BSD-3-Clause +* +* Copyright (c) 2023 Andes Technology Corporation +*/ + +#ifndef _SYS_ATCSMU_H +#define _SYS_ATCSMU_H + +#include <sbi/sbi_types.h> + +#define PCS0_WE_OFFSET 0x90 +#define PCSm_WE_OFFSET (i) ((i + 3) * 0x20 + PCS0_WE_OFFSET) + +#define PCS0_CTL_OFFSET 0x94 +#define PCSm_CTL_OFFSET (i) ((i + 3) * 0x20 + PCS0_CTL_OFFSET) +#define PCS_CTL_CMD_SHIFT 0 +#define PCS_CTL_PARAM_SHIFT 3 +#define SLEEP_CMD 0x3 +#define WAKEUP_CMD (0x0 | (1 << PCS_CTL_PARAM_SHIFT)) +#define LIGHTSLEEP_MODE 0 +#define DEEPSLEEP_MODE 1 +#define LIGHT_SLEEP_CMD (SLEEP_CMD | (LIGHTSLEEP_MODE << PCS_CTL_PARAM_SHIFT)) +#define DEEP_SLEEP_CMD (SLEEP_CMD | (DEEPSLEEP_MODE << PCS_CTL_PARAM_SHIFT)) + +#define PCS0_CFG_OFFSET 0x80 +#define PCSm_CFG_OFFSET (i) ((i + 3) * 0x20 + PCS0_CFG_OFFSET) +#define PCS_CFG_LIGHT_SLEEP_SHIFT 2 +#define PCS_CFG_LIGHT_SLEEP (1 << PCS_CFG_LIGHT_SLEEP_SHIFT) +#define PCS_CFG_DEEP_SLEEP_SHIFT 3 +#define PCS_CFG_DEEP_SLEEP (1 << PCS_CFG_DEEP_SLEEP_SHIFT) +#define RESET_VEC_LO_OFFSET 0x50 +#define RESET_VEC_HI_OFFSET 0x60 +#define RESET_VEC_8CORE_OFFSET 0x1a0 +#define HARTn_RESET_VEC_LO (n) \ + (RESET_VEC_LO_OFFSET + \ + ((n) < 4 ? 0 : RESET_VEC_8CORE_OFFSET) + ((n) * 0x4)) +#define HARTn_RESET_VEC_HI (n) \ + (RESET_VEC_HI_OFFSET + \ + ((n) < 4 ? 0 : RESET_VEC_8CORE_OFFSET) + ((n) * 0x4)) +#define PCS_MAX_NR 8 +#define FLASH_BASE 0x80000000ULL + +struct smu_data { +unsigned long addr; +}; + +int smu_set_wakeup_events (struct smu_data *smu,u32 events,u32 hartid); +bool smu_support_sleep_mode (struct smu_data *smu,u32 sleep_mode,u32 hartid); +int smu_set_command (struct smu_data *smu,u32 pcs_ctl,u32 hartid); +int smu_set_reset_vector (struct smu_data *smu,ulong wakeup_addr,u32 hartid); + +#endif /* _SYS_ATCSMU_H */ lib/utils/sys/Kconfig +4
-0@@ -2,6 +2,10 @@ menu "System Device Support" +config SYS_ATCSMU + bool "Andes System Management Unit (SMU) support" + default n + config SYS_HTIF bool "Host transfere interface (HTIF) support" default nlib/utils/sys/atcsmu.c new file +92
-0@@ -0,0 +1,92 @@ +/* +* SPDX-License-Identifier: BSD-3-Clause +* +* Copyright (c) 2023 Andes Technology Corporation +* +* Authors: +* Yu Chien Peter Lin <[email protected]> +*/ + +#include <sbi_utils/sys/atcsmu.h> +#include <sbi/riscv_io.h> +#include <sbi/sbi_console.h> +#include <sbi/sbi_error.h> +#include <sbi/sbi_bitops.h> + +inline int smu_set_wakeup_events (struct smu_data *smu,u32 events,u32 hartid) +{ +if (smu) { +writel (events, (void *)(smu->addr +PCSm_WE_OFFSET (hartid))); +return 0 ; + }else +return SBI_EINVAL ; +} + +inline bool smu_support_sleep_mode (struct smu_data *smu,u32 sleep_mode, +u32 hartid) +{ +u32 pcs_cfg; + +if (!smu) { +sbi_printf ("%s(): Failed to access smu_data\n" , __func__); +return false; + } + + pcs_cfg =readl ((void *)(smu->addr +PCSm_CFG_OFFSET (hartid))); + +switch (sleep_mode) { +case LIGHTSLEEP_MODE : +if (EXTRACT_FIELD (pcs_cfg,PCS_CFG_LIGHT_SLEEP ) ==0 ) { +sbi_printf ( +"SMU: hart%d (PCS%d) does not support light sleep mode\n" , + hartid, hartid +3 ); +return false; + } +break ; +case DEEPSLEEP_MODE : +if (EXTRACT_FIELD (pcs_cfg,PCS_CFG_DEEP_SLEEP ) ==0 ) { +sbi_printf ( +"SMU: hart%d (PCS%d) does not support deep sleep mode\n" , + hartid, hartid +3 ); +return false; + } +break ; + } + +return true; +} + +inline int smu_set_command (struct smu_data *smu,u32 pcs_ctl,u32 hartid) +{ +if (smu) { +writel (pcs_ctl, (void *)(smu->addr +PCSm_CTL_OFFSET (hartid))); +return 0 ; + }else +return SBI_EINVAL ; +} + +inline int smu_set_reset_vector (struct smu_data *smu,ulong wakeup_addr, +u32 hartid) +{ +u32 vec_lo, vec_hi; +u64 reset_vector; + +if (!smu) +return SBI_EINVAL ; + +writel (wakeup_addr, (void *)(smu->addr +HARTn_RESET_VEC_LO (hartid))); +writel ((u64 )wakeup_addr >>32 , + (void *)(smu->addr +HARTn_RESET_VEC_HI (hartid))); + + vec_lo =readl ((void *)(smu->addr +HARTn_RESET_VEC_LO (hartid))); + vec_hi =readl ((void *)(smu->addr +HARTn_RESET_VEC_HI (hartid))); + reset_vector = ((u64 )vec_hi <<32 ) | vec_lo; + +if (reset_vector != (u64 )wakeup_addr) { +sbi_printf ( +"hard%d (PCS%d): Failed to program the reset vector.\n" , + hartid, hartid +3 ); +return SBI_EFAIL ; + }else +return 0 ; +}lib/utils/sys/objects.mk +1
-0@@ -9,3 +9,4 @@ libsbiutils-objs-$(CONFIG_SYS_HTIF) += sys/htif.o libsbiutils-objs-$(CONFIG_SYS_SIFIVE_TEST) += sys/sifive_test.o +libsbiutils-objs-$(CONFIG_SYS_ATCSMU) += sys/atcsmu.oplatform/generic/Kconfig +1
-1@@ -30,6 +30,7 @@ config PLATFORM_ALLWINNER_D1 config PLATFORM_ANDES_AE350 bool "Andes AE350 support" + select SYS_ATCSMU default n config PLATFORM_RENESAS_RZFIVE --2.34.1
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
PATCH v3 4/6 lib: utils: atcsmu: Add Andes System Management Unit support
In reply to Yu Chien Peter LinQuoted 53 lines · Yu Chien Peter Lin
This patch adds atcsmu support for Andes AE350 platforms. The SMU provides system management capabilities, including clock, reset and power control based on power domain partitions.
Signed-off-by Yu Chien Peter Lin <[email protected]>--- include/sbi_utils/sys/atcsmu.h | 53 ++++++++++++++++++++ lib/utils/sys/Kconfig | 4 ++ lib/utils/sys/atcsmu.c | 92 ++++++++++++++++++++++++++++++++++ lib/utils/sys/objects.mk | 1 + platform/generic/Kconfig | 1 + 5 files changed, 151 insertions(+) create mode 100644 include/sbi_utils/sys/atcsmu.h create mode 100644 lib/utils/sys/atcsmu.cinclude/sbi_utils/sys/atcsmu.h new file +32
-0@@ -0,0 +1,53 @@ +/* +* SPDX-License-Identifier: BSD-3-Clause +* +* Copyright (c) 2023 Andes Technology Corporation +*/ + +#ifndef _SYS_ATCSMU_H +#define _SYS_ATCSMU_H + +#include <sbi/sbi_types.h> + +#define PCS0_WE_OFFSET 0x90 +#define PCSm_WE_OFFSET (i) ((i + 3) * 0x20 + PCS0_WE_OFFSET) + +#define PCS0_CTL_OFFSET 0x94 +#define PCSm_CTL_OFFSET (i) ((i + 3) * 0x20 + PCS0_CTL_OFFSET) +#define PCS_CTL_CMD_SHIFT 0 +#define PCS_CTL_PARAM_SHIFT 3 +#define SLEEP_CMD 0x3 +#define WAKEUP_CMD (0x0 | (1 << PCS_CTL_PARAM_SHIFT)) +#define LIGHTSLEEP_MODE 0 +#define DEEPSLEEP_MODE 1 +#define LIGHT_SLEEP_CMD (SLEEP_CMD | (LIGHTSLEEP_MODE << PCS_CTL_PARAM_SHIFT)) +#define DEEP_SLEEP_CMD (SLEEP_CMD | (DEEPSLEEP_MODE << PCS_CTL_PARAM_SHIFT)) + +#define PCS0_CFG_OFFSET 0x80 +#define PCSm_CFG_OFFSET (i) ((i + 3) * 0x20 + PCS0_CFG_OFFSET) +#define PCS_CFG_LIGHT_SLEEP_SHIFT 2 +#define PCS_CFG_LIGHT_SLEEP (1 << PCS_CFG_LIGHT_SLEEP_SHIFT) +#define PCS_CFG_DEEP_SLEEP_SHIFT 3 +#define PCS_CFG_DEEP_SLEEP (1 << PCS_CFG_DEEP_SLEEP_SHIFT) +#define RESET_VEC_LO_OFFSET 0x50
include/sbi_utils/sys/atcsmu.h line 42
Quoted 10 lines
include/sbi_utils/sys/atcsmu.h new file +10
-0+#define RESET_VEC_HI_OFFSET 0x60 +#define RESET_VEC_8CORE_OFFSET 0x1a0 +#define HARTn_RESET_VEC_LO (n) \ + (RESET_VEC_LO_OFFSET + \ + ((n) < 4 ? 0 : RESET_VEC_8CORE_OFFSET) + ((n) * 0x4)) +#define HARTn_RESET_VEC_HI (n) \ + (RESET_VEC_HI_OFFSET + \ + ((n) < 4 ? 0 : RESET_VEC_8CORE_OFFSET) + ((n) * 0x4)) +#define PCS_MAX_NR 8 +#define FLASH_BASE 0x80000000ULL
Just a nit, can the values of macros be aligned for better readability?
Quoted 153 lines
include/sbi_utils/sys/atcsmu.h new file +11
-0+ +struct smu_data { +unsigned long addr; +}; + +int smu_set_wakeup_events (struct smu_data *smu,u32 events,u32 hartid); +bool smu_support_sleep_mode (struct smu_data *smu,u32 sleep_mode,u32 hartid); +int smu_set_command (struct smu_data *smu,u32 pcs_ctl,u32 hartid); +int smu_set_reset_vector (struct smu_data *smu,ulong wakeup_addr,u32 hartid); + +#endif /* _SYS_ATCSMU_H */ lib/utils/sys/Kconfig +4
-0@@ -2,6 +2,10 @@ menu "System Device Support" +config SYS_ATCSMU + bool "Andes System Management Unit (SMU) support" + default n + config SYS_HTIF bool "Host transfere interface (HTIF) support" default nlib/utils/sys/atcsmu.c new file +92
-0@@ -0,0 +1,92 @@ +/* +* SPDX-License-Identifier: BSD-3-Clause +* +* Copyright (c) 2023 Andes Technology Corporation +* +* Authors: +* Yu Chien Peter Lin <[email protected]> +*/ + +#include <sbi_utils/sys/atcsmu.h> +#include <sbi/riscv_io.h> +#include <sbi/sbi_console.h> +#include <sbi/sbi_error.h> +#include <sbi/sbi_bitops.h> + +inline int smu_set_wakeup_events (struct smu_data *smu,u32 events,u32 hartid) +{ +if (smu) { +writel (events, (void *)(smu->addr +PCSm_WE_OFFSET (hartid))); +return 0 ; + }else +return SBI_EINVAL ; +} + +inline bool smu_support_sleep_mode (struct smu_data *smu,u32 sleep_mode, +u32 hartid) +{ +u32 pcs_cfg; + +if (!smu) { +sbi_printf ("%s(): Failed to access smu_data\n" , __func__); +return false; + } + + pcs_cfg =readl ((void *)(smu->addr +PCSm_CFG_OFFSET (hartid))); + +switch (sleep_mode) { +case LIGHTSLEEP_MODE : +if (EXTRACT_FIELD (pcs_cfg,PCS_CFG_LIGHT_SLEEP ) ==0 ) { +sbi_printf ( +"SMU: hart%d (PCS%d) does not support light sleep mode\n" , + hartid, hartid +3 ); +return false; + } +break ; +case DEEPSLEEP_MODE : +if (EXTRACT_FIELD (pcs_cfg,PCS_CFG_DEEP_SLEEP ) ==0 ) { +sbi_printf ( +"SMU: hart%d (PCS%d) does not support deep sleep mode\n" , + hartid, hartid +3 ); +return false; + } +break ; + } + +return true; +} + +inline int smu_set_command (struct smu_data *smu,u32 pcs_ctl,u32 hartid) +{ +if (smu) { +writel (pcs_ctl, (void *)(smu->addr +PCSm_CTL_OFFSET (hartid))); +return 0 ; + }else +return SBI_EINVAL ; +} + +inline int smu_set_reset_vector (struct smu_data *smu,ulong wakeup_addr, +u32 hartid) +{ +u32 vec_lo, vec_hi; +u64 reset_vector; + +if (!smu) +return SBI_EINVAL ; + +writel (wakeup_addr, (void *)(smu->addr +HARTn_RESET_VEC_LO (hartid))); +writel ((u64 )wakeup_addr >>32 , + (void *)(smu->addr +HARTn_RESET_VEC_HI (hartid))); + + vec_lo =readl ((void *)(smu->addr +HARTn_RESET_VEC_LO (hartid))); + vec_hi =readl ((void *)(smu->addr +HARTn_RESET_VEC_HI (hartid))); + reset_vector = ((u64 )vec_hi <<32 ) | vec_lo; + +if (reset_vector != (u64 )wakeup_addr) { +sbi_printf ( +"hard%d (PCS%d): Failed to program the reset vector.\n" , + hartid, hartid +3 ); +return SBI_EFAIL ; + }else +return 0 ; +}lib/utils/sys/objects.mk +1
-0@@ -9,3 +9,4 @@ libsbiutils-objs-$(CONFIG_SYS_HTIF) += sys/htif.o libsbiutils-objs-$(CONFIG_SYS_SIFIVE_TEST) += sys/sifive_test.o +libsbiutils-objs-$(CONFIG_SYS_ATCSMU) += sys/atcsmu.oplatform/generic/Kconfig +1
-0@@ -30,6 +30,7 @@ config PLATFORM_ALLWINNER_D1 config PLATFORM_ANDES_AE350 bool "Andes AE350 support" + select SYS_ATCSMU default n config PLATFORM_RENESAS_RZFIVESignature · 7 lines
2.34.1 -- opensbi mailing list opensbi at lists.infradead.org http://lists.infradead.org/mailman/listinfo/opensbi
PATCH v3 4/6 lib: utils: atcsmu: Add Andes System Management Unit support
Hi Chauhan,
Quoted 57 lines · Himanshu Chauhan
Quoted 56 lines · Yu Chien Peter Lin
This patch adds atcsmu support for Andes AE350 platforms. The SMU provides system management capabilities, including clock, reset and power control based on power domain partitions.
Signed-off-by Yu Chien Peter Lin <[email protected]>--- include/sbi_utils/sys/atcsmu.h | 53 ++++++++++++++++++++ lib/utils/sys/Kconfig | 4 ++ lib/utils/sys/atcsmu.c | 92 ++++++++++++++++++++++++++++++++++ lib/utils/sys/objects.mk | 1 + platform/generic/Kconfig | 1 + 5 files changed, 151 insertions(+) create mode 100644 include/sbi_utils/sys/atcsmu.h create mode 100644 lib/utils/sys/atcsmu.cinclude/sbi_utils/sys/atcsmu.h new file +35
-0@@ -0,0 +1,53 @@ +/* +* SPDX-License-Identifier: BSD-3-Clause +* +* Copyright (c) 2023 Andes Technology Corporation +*/ + +#ifndef _SYS_ATCSMU_H +#define _SYS_ATCSMU_H + +#include <sbi/sbi_types.h> + +#define PCS0_WE_OFFSET 0x90 +#define PCSm_WE_OFFSET (i) ((i + 3) * 0x20 + PCS0_WE_OFFSET) + +#define PCS0_CTL_OFFSET 0x94 +#define PCSm_CTL_OFFSET (i) ((i + 3) * 0x20 + PCS0_CTL_OFFSET) +#define PCS_CTL_CMD_SHIFT 0 +#define PCS_CTL_PARAM_SHIFT 3 +#define SLEEP_CMD 0x3 +#define WAKEUP_CMD (0x0 | (1 << PCS_CTL_PARAM_SHIFT)) +#define LIGHTSLEEP_MODE 0 +#define DEEPSLEEP_MODE 1 +#define LIGHT_SLEEP_CMD (SLEEP_CMD | (LIGHTSLEEP_MODE << PCS_CTL_PARAM_SHIFT)) +#define DEEP_SLEEP_CMD (SLEEP_CMD | (DEEPSLEEP_MODE << PCS_CTL_PARAM_SHIFT)) + +#define PCS0_CFG_OFFSET 0x80 +#define PCSm_CFG_OFFSET (i) ((i + 3) * 0x20 + PCS0_CFG_OFFSET) +#define PCS_CFG_LIGHT_SLEEP_SHIFT 2 +#define PCS_CFG_LIGHT_SLEEP (1 << PCS_CFG_LIGHT_SLEEP_SHIFT) +#define PCS_CFG_DEEP_SLEEP_SHIFT 3 +#define PCS_CFG_DEEP_SLEEP (1 << PCS_CFG_DEEP_SLEEP_SHIFT) +#define RESET_VEC_LO_OFFSET 0x50 +#define RESET_VEC_HI_OFFSET 0x60 +#define RESET_VEC_8CORE_OFFSET 0x1a0 +#define HARTn_RESET_VEC_LO (n) \
Quoted 8 lines
include/sbi_utils/sys/atcsmu.h line 42
Quoted 7 lines
include/sbi_utils/sys/atcsmu.h new file +7
-0+ (RESET_VEC_LO_OFFSET + \ + ((n) < 4 ? 0 : RESET_VEC_8CORE_OFFSET) + ((n) * 0x4)) +#define HARTn_RESET_VEC_HI (n) \ + (RESET_VEC_HI_OFFSET + \ + ((n) < 4 ? 0 : RESET_VEC_8CORE_OFFSET) + ((n) * 0x4)) +#define PCS_MAX_NR 8 +#define FLASH_BASE 0x80000000ULLJust a nit, can the values of macros be aligned for better readability?
Sure, I will fix the indentation.
Thanks,
Peter Lin
PATCH v3 5/6 platform: andes/ae350: Implement hart hotplug using HSM extension
In reply to Yu Chien Peter LinAdd hart_start() and hart_stop() callbacks for the multi-core ae350 platform, it utilizes the ATCSMU to put the harts into power-gated deep sleep mode. The programming sequence is stated as below:
1. Set the wakeup events to PCSm_WE
2. Set the sleep command to PCSm_CTL
3. Set the reset vector to HARTm_RESET_VECTOR_{LO|HI}
4. Write back and invalidate D-cache by executing the CCTL command L1D_WBINVAL_ALL
5. Disable I/D-cache by clearing mcache_ctl.{I|D}C_EN
6. Disable D-cache coherency by clearing mcache_ctl_.DC_COHEN
7. Wait for mcache_ctl.DC_COHSTA to be cleared to ensure the previous step is completed
8. Execute WFI
--- platform/generic/andes/ae350.c | 99 ++++++++++++++++++++++++ platform/generic/andes/objects.mk | 2 +- platform/generic/andes/sleep.S | 70 +++++++++++++++++ platform/generic/include/andes/andes45.h | 10 +++ 4 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 platform/generic/andes/sleep.S create mode 100644 platform/generic/include/andes/andes45.h
platform/generic/andes/ae350.c +99 -0
@@ -10,6 +10,104 @@#include <platform_override.h> #include <sbi_utils/fdt/fdt_helper.h> #include <sbi_utils/fdt/fdt_fixup.h> +#include <sbi_utils/sys/atcsmu.h> +#include <sbi/sbi_bitops.h> +#include <sbi/sbi_error.h> +#include <sbi/sbi_hsm.h> +#include <sbi/sbi_ipi.h> +#include <sbi/sbi_init.h> +#include <andes/andes45.h> + +static struct smu_data smu = {0 }; +extern void __ae350_enable_coherency_warmboot (void ); +extern void __ae350_disable_coherency (void ); + +static __always_inline bool is_andes25(void) +{ +ulong marchid =csr_read (CSR_MARCHID ); +return !!(EXTRACT_FIELD (marchid,CSR_MARCHID_MICROID ) ==0xa25 ); +} + +static int ae350_hart_start (u32 hartid,ulong saddr) +{ +/* Don't send wakeup command at boot-time */ +if (!sbi_init_count (hartid) || (is_andes25 () && hartid ==0 )) +return sbi_ipi_raw_send (hartid); + +/* Write wakeup command to the sleep hart */ +smu_set_command (&smu,WAKEUP_CMD , hartid); + +return 0 ; +} + +static int ae350_hart_stop (void ) +{ +int rc; +u32 hartid =current_hartid (); + +/** +* For Andes AX25MP, the hart0 shares power domain with +* L2-cache, instead of turning it off, it should fall +* through and jump to warmboot_addr. +*/ +if (is_andes25 () && hartid ==0 ) +return SBI_ENOTSUPP ; + +if (!smu_support_sleep_mode (&smu,DEEPSLEEP_MODE , hartid)) +return SBI_ENOTSUPP ; + +/** +* disable all events, the current hart will be +* woken up from reset vector when other hart +* writes its PCS (power control slot) control +* register +*/ +smu_set_wakeup_events (&smu,0x0 , hartid); +smu_set_command (&smu,DEEP_SLEEP_CMD , hartid); + + rc =smu_set_reset_vector (&smu, (ulong )__ae350_enable_coherency_warmboot, + hartid); +if (rc) + goto fail; + +__ae350_disable_coherency (); + +wfi (); + +fail: +/* It should never reach here */ +sbi_hart_hang (); +return 0 ; +} + +static const struct sbi_hsm_device andes_smu = { + .name ="andes_smu" , + .hart_start = ae350_hart_start, + .hart_stop = ae350_hart_stop, +}; + +static void ae350_hsm_device_init (void ) +{ +int rc; +void *fdt; + + fdt =fdt_get_address (); + + rc =fdt_parse_compat_addr (fdt, (uint64_t *)&smu.addr, +"andestech,atcsmu" ); + +if (!rc) { +sbi_hsm_set_device (&andes_smu); + } +} + +static int ae350_final_init (bool cold_boot,const struct fdt_match *match) +{ +if (cold_boot) +ae350_hsm_device_init (); + +return 0 ; +}static const struct fdt_match andes_ae350_match[] = { { .compatible ="andestech,ae350" },
@@ -18,4 +116,5 @@ static const struct fdt_match andes_ae350_match[] = {const struct platform_override andes_ae350 = { .match_table = andes_ae350_match, + .final_init = ae350_final_init, };
platform/generic/andes/objects.mk +1 -1
@@ -3,4 +3,4 @@ # carray-platform_override_modules-$(CONFIG_PLATFORM_ANDES_AE350) += andes_ae350 -platform-objs-$(CONFIG_PLATFORM_ANDES_AE350) += andes/ae350.o +platform-objs-$(CONFIG_PLATFORM_ANDES_AE350) += andes/ae350.o andes/sleep.o
platform/generic/andes/sleep.S new file +70 -0
70 lines not on this page · raw message
platform/generic/include/andes/andes45.h new file +10 -0
@@ -0,0 +1,10 @@ +#ifndef _RISCV_ANDES45_H +#define _RISCV_ANDES45_H + +#define CSR_MARCHID_MICROID 0xfff + +/* Memory and Miscellaneous Registers */ +#define CSR_MCACHE_CTL 0x7ca +#define CSR_MCCTLCOMMAND 0x7cc + +#endif /* _RISCV_ANDES45_H */
Signature · 1 line
2.34.1
PATCH v3 6/6 lib: reset/fdt_reset_atcwdt200: Use defined macros and function in atcsmu.h
In reply to Yu Chien Peter LinReuse the smu related macros and function in atcsmu.h.
--- lib/utils/reset/Kconfig | 1 + lib/utils/reset/fdt_reset_atcwdt200.c | 21 ++++++++------------- 2 files changed, 9 insertions(+), 13 deletions(-)
lib/utils/reset/Kconfig +1 -0
@@ -11,6 +11,7 @@ if FDT_RESET config FDT_RESET_ATCWDT200 bool "Andes WDT FDT reset driver" + depends on SYS_ATCSMU default n config FDT_RESET_GPIO
lib/utils/reset/fdt_reset_atcwdt200.c +8 -13
@@ -16,6 +16,7 @@#include <sbi/sbi_system.h> #include <sbi_utils/fdt/fdt_helper.h> #include <sbi_utils/reset/fdt_reset.h> +#include <sbi_utils/sys/atcsmu.h> #define ATCWDT200_WP_NUM 0x5aa5#define WREN_REG 0x18
@@ -41,14 +42,8 @@#define CLK_PCLK (1 << 1)#define WDT_EN (1 << 0) -#define FLASH_BASE 0x80000000ULL -#define SMU_RESET_VEC_LO_OFF 0x50 -#define SMU_RESET_VEC_HI_OFF 0x60 -#define SMU_HARTn_RESET_VEC_LO (n) (SMU_RESET_VEC_LO_OFF + (n * 0x4)) -#define SMU_HARTn_RESET_VEC_HI (n) (SMU_RESET_VEC_HI_OFF + (n * 0x4)) - -static volatile char *wdt_addr; -static volatile char *smu_addr; +static volatile char *wdt_addr =NULL ; +static struct smu_data smu = {0 };static int ae350_system_reset_check (u32 type,u32 reason) {
@@ -66,16 +61,16 @@ static void ae350_system_reset(u32 type, u32 reason) {const struct sbi_platform *plat =sbi_platform_thishart_ptr (); -for (int i =0 ; i <sbi_platform_hart_count (plat); i++) { -writel (FLASH_BASE , smu_addr +SMU_HARTn_RESET_VEC_LO (i)); -writel (FLASH_BASE >>32 , smu_addr +SMU_HARTn_RESET_VEC_HI (i)); - } +for (int i =0 ; i <sbi_platform_hart_count (plat); i++) +if (smu_set_reset_vector (&smu,FLASH_BASE , i)) + goto fail;/* Program WDT control register */ writew (ATCWDT200_WP_NUM , wdt_addr +WREN_REG );writel (INT_CLK_32768 |INT_EN |RST_CLK_128 |RST_EN |WDT_EN , wdt_addr +CTRL_REG ); +fail:sbi_hart_hang (); }
@@ -104,7 +99,7 @@ static int atcwdt200_reset_init(void *fdt, int nodeoff,if (fdt_parse_compat_addr (fdt, ®_addr,"andestech,atcsmu" ))return SBI_ENODEV ; - smu_addr = (volatile char *)(unsigned long )reg_addr; + smu.addr = (unsigned long )reg_addr;sbi_system_reset_add_device (&atcwdt200_reset);
Signature · 1 line
2.34.1
PATCH v3 6/6 lib: reset/fdt_reset_atcwdt200: Use defined macros and function in atcsmu.h
Quoted 4 lines · Yu Chien Peter Lin
Reuse the smu related macros and function in
atcsmu.h.Signed-off-by Yu Chien Peter Lin <[email protected]>
Looks good to me.
Regards,
Anup
Quoted 84 lines
--- lib/utils/reset/Kconfig | 1 + lib/utils/reset/fdt_reset_atcwdt200.c | 21 ++++++++------------- 2 files changed, 9 insertions(+), 13 deletions(-)lib/utils/reset/Kconfig +1
-0@@ -11,6 +11,7 @@ if FDT_RESET config FDT_RESET_ATCWDT200 bool "Andes WDT FDT reset driver" + depends on SYS_ATCSMU default n config FDT_RESET_GPIOlib/utils/reset/fdt_reset_atcwdt200.c +8
-14@@ -16,6 +16,7 @@#include <sbi/sbi_system.h> #include <sbi_utils/fdt/fdt_helper.h> #include <sbi_utils/reset/fdt_reset.h> +#include <sbi_utils/sys/atcsmu.h> #define ATCWDT200_WP_NUM 0x5aa5#define WREN_REG 0x18@@ -41,14 +42,8 @@#define CLK_PCLK (1 << 1)#define WDT_EN (1 << 0) -#define FLASH_BASE 0x80000000ULL -#define SMU_RESET_VEC_LO_OFF 0x50 -#define SMU_RESET_VEC_HI_OFF 0x60 -#define SMU_HARTn_RESET_VEC_LO (n) (SMU_RESET_VEC_LO_OFF + (n * 0x4)) -#define SMU_HARTn_RESET_VEC_HI (n) (SMU_RESET_VEC_HI_OFF + (n * 0x4)) - -static volatile char *wdt_addr; -static volatile char *smu_addr; +static volatile char *wdt_addr =NULL ; +static struct smu_data smu = {0 };static int ae350_system_reset_check (u32 type,u32 reason) {@@ -66,16 +61,16 @@ static void ae350_system_reset(u32 type, u32 reason) {const struct sbi_platform *plat =sbi_platform_thishart_ptr (); -for (int i =0 ; i <sbi_platform_hart_count (plat); i++) { -writel (FLASH_BASE , smu_addr +SMU_HARTn_RESET_VEC_LO (i)); -writel (FLASH_BASE >>32 , smu_addr +SMU_HARTn_RESET_VEC_HI (i)); - } +for (int i =0 ; i <sbi_platform_hart_count (plat); i++) +if (smu_set_reset_vector (&smu,FLASH_BASE , i)) + goto fail;/* Program WDT control register */ writew (ATCWDT200_WP_NUM , wdt_addr +WREN_REG );writel (INT_CLK_32768 |INT_EN |RST_CLK_128 |RST_EN |WDT_EN , wdt_addr +CTRL_REG ); +fail:sbi_hart_hang (); }@@ -104,7 +99,7 @@ static int atcwdt200_reset_init(void *fdt, int nodeoff,if (fdt_parse_compat_addr (fdt, ®_addr,"andestech,atcsmu" ))return SBI_ENODEV ; - smu_addr = (volatile char *)(unsigned long )reg_addr; + smu.addr = (unsigned long )reg_addr;sbi_system_reset_add_device (&atcwdt200_reset); --2.34.1
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi