From fc78ddf7d3a20d99669e49c0aba9ea1c9b8c702f Mon Sep 17 00:00:00 2001 From: Youvedeep Singh Date: Thu, 5 Oct 2017 17:57:38 +0530 Subject: [PATCH] ARM: nrf52: Power Management for nrf52 series SOC Add support for nrf52 series SOC. This patch Adds :- 1. Architecture specific Power Management APIs. 2. APIs for invoking various Power Management tasks into nrf52. Signed-off-by: Youvedeep Singh --- arch/arm/soc/nordic_nrf5/nrf52/Kconfig.series | 1 + arch/arm/soc/nordic_nrf5/nrf52/Makefile | 1 + arch/arm/soc/nordic_nrf5/nrf52/power.c | 104 ++++++++++++++++++ arch/arm/soc/nordic_nrf5/nrf52/soc_power.h | 39 +++++++ ext/hal/nordic/hal/nrf_power.h | 1 - 5 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 arch/arm/soc/nordic_nrf5/nrf52/power.c create mode 100644 arch/arm/soc/nordic_nrf5/nrf52/soc_power.h diff --git a/arch/arm/soc/nordic_nrf5/nrf52/Kconfig.series b/arch/arm/soc/nordic_nrf5/nrf52/Kconfig.series index 85a669178af..42601d5f03a 100644 --- a/arch/arm/soc/nordic_nrf5/nrf52/Kconfig.series +++ b/arch/arm/soc/nordic_nrf5/nrf52/Kconfig.series @@ -16,6 +16,7 @@ config SOC_SERIES_NRF52X select CLOCK_CONTROL select CLOCK_CONTROL_NRF5 select SYS_POWER_LOW_POWER_STATE_SUPPORTED + select SYS_POWER_DEEP_SLEEP_SUPPORTED select XIP select HAS_CMSIS select HAS_NORDIC_MDK diff --git a/arch/arm/soc/nordic_nrf5/nrf52/Makefile b/arch/arm/soc/nordic_nrf5/nrf52/Makefile index 8ad96799ff0..624bcbd55f8 100644 --- a/arch/arm/soc/nordic_nrf5/nrf52/Makefile +++ b/arch/arm/soc/nordic_nrf5/nrf52/Makefile @@ -10,6 +10,7 @@ soc-cflags += -DNRF52840_XXAA endif obj-y += soc.o +obj-$(CONFIG_SYS_POWER_MANAGEMENT) += power.o obj-$(CONFIG_ARM_MPU_NRF52X) += mpu_regions.o zephyr: $(KERNEL_HEX_NAME) diff --git a/arch/arm/soc/nordic_nrf5/nrf52/power.c b/arch/arm/soc/nordic_nrf5/nrf52/power.c new file mode 100644 index 00000000000..92f99359938 --- /dev/null +++ b/arch/arm/soc/nordic_nrf5/nrf52/power.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2017 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG +#include + +#include +#include +#include + +extern void nrf_gpiote_clear_port_event(void); +#if defined(CONFIG_SYS_POWER_DEEP_SLEEP) +/* System_OFF is deepest Power state available, On exiting from this + * state CPU including all peripherals reset + */ +static void _system_off(void) +{ + nrf_power_system_off(); +} +#endif + +static void _issue_low_power_command(void) +{ + __WFE(); + __SEV(); + __WFE(); +} + +/* Name: _low_power_mode + * Parameter : Low Power Task ID + * + * Set Notdic SOC specific Low Power Task and invoke + * _WFE event to put the nordic SOC into Low Power State. + */ +static void _low_power_mode(enum power_states state) +{ + switch (state) { + /* CONSTANT LATENCY TASK */ + case SYS_POWER_STATE_CPU_LPS: + nrf_power_task_trigger(NRF_POWER_TASK_CONSTLAT); + break; + /* LOW POWER TASK */ + case SYS_POWER_STATE_CPU_LPS_1: + nrf_power_task_trigger(NRF_POWER_TASK_LOWPWR); + break; + + default: + /* Unsupported State */ + SYS_LOG_ERR("Unsupported State\n"); + break; + } + + /* Issue __WFE*/ + _issue_low_power_command(); + /* Clear the Port Event */ + nrf_gpiote_clear_port_event(); +} + +/* Invoke Low Power/System Off specific Tasks */ +void _sys_soc_set_power_state(enum power_states state) +{ + switch (state) { + case SYS_POWER_STATE_CPU_LPS: + _low_power_mode(SYS_POWER_STATE_CPU_LPS); + break; + case SYS_POWER_STATE_CPU_LPS_1: + _low_power_mode(SYS_POWER_STATE_CPU_LPS_1); + break; +#if defined(CONFIG_SYS_POWER_DEEP_SLEEP) + case SYS_POWER_STATE_DEEP_SLEEP: + _system_off(); + break; +#endif + default: + /* Unsupported State */ + SYS_LOG_ERR("Unsupported State\n"); + break; + } +} + +/* Handle SOC specific activity after Low Power Mode Exit */ +void _sys_soc_power_state_post_ops(enum power_states state) +{ + /* This is placeholder for nrf52 SOC specific task. + * Currently there is no nrf52 SOC specific activity to perform. + */ + switch (state) { + case SYS_POWER_STATE_CPU_LPS: + break; + case SYS_POWER_STATE_CPU_LPS_1: + break; +#if defined(CONFIG_SYS_POWER_DEEP_SLEEP) + case SYS_POWER_STATE_DEEP_SLEEP: + break; +#endif + default: + /* Unsupported State */ + SYS_LOG_ERR("Unsupported State\n"); + break; + } +} diff --git a/arch/arm/soc/nordic_nrf5/nrf52/soc_power.h b/arch/arm/soc/nordic_nrf5/nrf52/soc_power.h new file mode 100644 index 00000000000..701104f7384 --- /dev/null +++ b/arch/arm/soc/nordic_nrf5/nrf52/soc_power.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_POWER_H_ +#define _SOC_POWER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum power_states { + SYS_POWER_STATE_CPU_LPS, /* CONSTLAT Task Activited */ + SYS_POWER_STATE_CPU_LPS_1, /* LOWPWR Task Activated */ + SYS_POWER_STATE_CPU_LPS_2, /* Not supported*/ + SYS_POWER_STATE_DEEP_SLEEP, /* System Off */ + SYS_POWER_STATE_DEEP_SLEEP_1, /* Not Supported */ + SYS_POWER_STATE_DEEP_SLEEP_2, /* Not Supported */ + + SYS_POWER_STATE_MAX /* Do nothing */ +}; + +/** + * @brief Put processor into low power state + */ +void _sys_soc_set_power_state(enum power_states state); + +/** + * @brief Do any SoC or architecture specific post ops after low power states. + */ +void _sys_soc_power_state_post_ops(enum power_states state); + +#ifdef __cplusplus +} +#endif + +#endif /* _SOC_POWER_H_ */ diff --git a/ext/hal/nordic/hal/nrf_power.h b/ext/hal/nordic/hal/nrf_power.h index 5353600ebbd..d86c771080e 100644 --- a/ext/hal/nordic/hal/nrf_power.h +++ b/ext/hal/nordic/hal/nrf_power.h @@ -40,7 +40,6 @@ * Hardware access layer for (POWER) peripheral. */ #include "nrf.h" -#include "nordic_common.h" #include "nrf_assert.h" #include #include