From 5b921c53b0487a1734e91b4fc7cf6f2bbfa1ac2c Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Fri, 12 Jul 2024 11:53:32 +0800 Subject: [PATCH] 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 --- dts/arm/nuvoton/m46x.dtsi | 1 + dts/bindings/clock/nuvoton,numaker-scc.yaml | 6 ++++ .../dt-bindings/clock/numaker_m46x_clock.h | 6 ++++ soc/nuvoton/numaker/m46x/CMakeLists.txt | 2 ++ soc/nuvoton/numaker/m46x/Kconfig | 1 + soc/nuvoton/numaker/m46x/poweroff.c | 31 +++++++++++++++++++ soc/nuvoton/numaker/m46x/soc.c | 3 ++ 7 files changed, 50 insertions(+) create mode 100644 soc/nuvoton/numaker/m46x/poweroff.c diff --git a/dts/arm/nuvoton/m46x.dtsi b/dts/arm/nuvoton/m46x.dtsi index f89523c6a81..cdab3667810 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 = ; 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 99ea7ed3adc..b2143e6573e 100644 --- a/dts/bindings/clock/nuvoton,numaker-scc.yaml +++ b/dts/bindings/clock/nuvoton,numaker-scc.yaml @@ -47,3 +47,9 @@ properties: 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 9243ab76b56..82deb4dc649 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 58be053241b..16544cfe556 100644 --- a/soc/nuvoton/numaker/m46x/CMakeLists.txt +++ b/soc/nuvoton/numaker/m46x/CMakeLists.txt @@ -6,4 +6,6 @@ zephyr_sources(soc.c) 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 408b3067bd8..3346e1f9bfc 100644 --- a/soc/nuvoton/numaker/m46x/Kconfig +++ b/soc/nuvoton/numaker/m46x/Kconfig @@ -9,6 +9,7 @@ config SOC_SERIES_M46X 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 00000000000..4854a1d0993 --- /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 +#include +#include +#include + +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 f1993126524..d62a8bf5124 100644 --- a/soc/nuvoton/numaker/m46x/soc.c +++ b/soc/nuvoton/numaker/m46x/soc.c @@ -16,6 +16,9 @@ void z_arm_platform_init(void) /* Unlock protected registers */ SYS_UnlockReg(); + /* Release I/O hold status */ + CLK->IOPDCTL = 1; + /* * ------------------- * Init System Clock