soc: nuvoton: numaker: add poweroff for m46x
Add support of sys_poweroff API on m46x series.
It could support SPD standby or DPD deep power down mode.
Signed-off-by: cyliang tw <cyliang@nuvoton.com>
diff --git a/dts/arm/nuvoton/m46x.dtsi b/dts/arm/nuvoton/m46x.dtsi
index f89523c..cdab366 100644
--- a/dts/arm/nuvoton/m46x.dtsi
+++ b/dts/arm/nuvoton/m46x.dtsi
@@ -54,6 +54,7 @@
clk-pclkdiv = <(NUMAKER_CLK_PCLKDIV_APB0DIV_DIV2 |
NUMAKER_CLK_PCLKDIV_APB1DIV_DIV2)>;
core-clock = <200000000>;
+ powerdown-mode = <NUMAKER_CLK_PMUCTL_PDMSEL_DPD>;
pcc: peripheral-clock-controller {
compatible = "nuvoton,numaker-pcc";
diff --git a/dts/bindings/clock/nuvoton,numaker-scc.yaml b/dts/bindings/clock/nuvoton,numaker-scc.yaml
index 99ea7ed..b2143e6 100644
--- a/dts/bindings/clock/nuvoton,numaker-scc.yaml
+++ b/dts/bindings/clock/nuvoton,numaker-scc.yaml
@@ -47,3 +47,9 @@
type: int
description: |
Configure core clock (HCLK)
+
+ powerdown-mode:
+ type: int
+ description: |
+ Configure power down mode, please choose one of NUMAKER_CLK_PMUCTL_PDMSEL_XXX
+ from numaker_xxx_clock.h
diff --git a/include/zephyr/dt-bindings/clock/numaker_m46x_clock.h b/include/zephyr/dt-bindings/clock/numaker_m46x_clock.h
index 9243ab7..82deb4d 100644
--- a/include/zephyr/dt-bindings/clock/numaker_m46x_clock.h
+++ b/include/zephyr/dt-bindings/clock/numaker_m46x_clock.h
@@ -1300,4 +1300,10 @@
/* End of M460 BSP clk.h copy */
+#define NUMAKER_CLK_PMUCTL_PDMSEL_PD 0x00000000
+#define NUMAKER_CLK_PMUCTL_PDMSEL_LLPD 0x00000001
+#define NUMAKER_CLK_PMUCTL_PDMSEL_FWPD 0x00000002
+#define NUMAKER_CLK_PMUCTL_PDMSEL_SPD 0x00000004
+#define NUMAKER_CLK_PMUCTL_PDMSEL_DPD 0x00000006
+
#endif
diff --git a/soc/nuvoton/numaker/m46x/CMakeLists.txt b/soc/nuvoton/numaker/m46x/CMakeLists.txt
index 58be053..16544cf 100644
--- a/soc/nuvoton/numaker/m46x/CMakeLists.txt
+++ b/soc/nuvoton/numaker/m46x/CMakeLists.txt
@@ -6,4 +6,6 @@
zephyr_include_directories(.)
+zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c)
+
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "")
diff --git a/soc/nuvoton/numaker/m46x/Kconfig b/soc/nuvoton/numaker/m46x/Kconfig
index 408b306..3346e1f 100644
--- a/soc/nuvoton/numaker/m46x/Kconfig
+++ b/soc/nuvoton/numaker/m46x/Kconfig
@@ -9,6 +9,7 @@
select CPU_HAS_FPU
select CPU_HAS_ARM_MPU
select CORTEX_M_SYSTICK if SYS_CLOCK_EXISTS
+ select HAS_POWEROFF
config SOC_M467
select HAS_NUMAKER_HAL
diff --git a/soc/nuvoton/numaker/m46x/poweroff.c b/soc/nuvoton/numaker/m46x/poweroff.c
new file mode 100644
index 0000000..4854a1d
--- /dev/null
+++ b/soc/nuvoton/numaker/m46x/poweroff.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024 Nuvoton Technology Corporation.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <zephyr/kernel.h>
+#include <zephyr/devicetree.h>
+#include <zephyr/sys/poweroff.h>
+#include <NuMicro.h>
+
+void z_sys_poweroff(void)
+{
+ SYS_UnlockReg();
+
+ /* Clear all wake-up flag */
+ CLK->PMUSTS |= CLK_PMUSTS_CLRWK_Msk;
+
+ /* Select Power-down mode */
+ CLK_SetPowerDownMode(DT_PROP_OR(DT_NODELABEL(scc), powerdown_mode, CLK_PMUCTL_PDMSEL_SPD));
+
+ /* Enable RTC wake-up */
+ CLK_ENABLE_RTCWK();
+
+ /* Enter to Power-down mode */
+ CLK_PowerDown();
+
+ k_cpu_idle();
+
+ CODE_UNREACHABLE;
+}
diff --git a/soc/nuvoton/numaker/m46x/soc.c b/soc/nuvoton/numaker/m46x/soc.c
index f199312..d62a8bf 100644
--- a/soc/nuvoton/numaker/m46x/soc.c
+++ b/soc/nuvoton/numaker/m46x/soc.c
@@ -16,6 +16,9 @@
/* Unlock protected registers */
SYS_UnlockReg();
+ /* Release I/O hold status */
+ CLK->IOPDCTL = 1;
+
/*
* -------------------
* Init System Clock