soc: arm: nrf51: Backport power management code from nRF52

This commit ports power management code from nRF52 to the nRF51 SoC,
enabling usage of Zephyr Power Management policies on this platform.

Signed-off-by: Piotr Zięcik <piotr.ziecik@nordicsemi.no>
This commit is contained in:
Piotr Zięcik 2019-01-02 13:39:25 +01:00 committed by Carles Cufí
commit 2587ed0090
4 changed files with 151 additions and 2 deletions

View file

@ -13,7 +13,8 @@ config SOC_SERIES_NRF51X
select NRF_RTC_TIMER
select CLOCK_CONTROL
select CLOCK_CONTROL_NRF
select SYS_POWER_LOW_POWER_STATE_SUPPORTED
select SYS_POWER_DEEP_SLEEP_SUPPORTED
select SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED
select XIP
select HAS_CMSIS
select HAS_NRFX

View file

@ -1,11 +1,95 @@
/*
* Copyright (c) 2018 Intel Corporation.
* Copyright (c) 2017 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <soc_power.h>
#include <nrf_power.h>
#include <logging/log.h>
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
/* Invoke Low Power/System Off specific Tasks */
void sys_set_power_state(enum power_states state)
{
switch (state) {
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
#ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED
case SYS_POWER_STATE_DEEP_SLEEP:
nrf_power_system_off();
break;
#endif
#endif
default:
LOG_ERR("Unsupported power state %u", state);
break;
}
}
/* Handle SOC specific activity after Low Power Mode Exit */
void sys_power_state_post_ops(enum power_states state)
{
switch (state) {
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
#ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED
case SYS_POWER_STATE_DEEP_SLEEP:
/* Nothing to do. */
break;
#endif
#endif
default:
LOG_ERR("Unsupported power state %u", state);
break;
}
/*
* System is now in active mode. Reenable interrupts which were disabled
* when OS started idling code.
*/
irq_unlock(0);
}
bool sys_is_valid_power_state(enum power_states state)
{
switch (state) {
#ifdef CONFIG_SYS_POWER_LOW_POWER_STATE
#ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_SUPPORTED
case SYS_POWER_STATE_CPU_LPS:
return true;
#endif
#ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_1_SUPPORTED
case SYS_POWER_STATE_CPU_LPS_1:
return true;
#endif
#ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_2_SUPPORTED
case SYS_POWER_STATE_CPU_LPS_2:
return true;
#endif
#endif /* CONFIG_SYS_POWER_LOW_POWER_STATE */
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
#ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED
case SYS_POWER_STATE_DEEP_SLEEP:
return true;
#endif
#ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_1_SUPPORTED
case SYS_POWER_STATE_DEEP_SLEEP_1:
return true;
#endif
#ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_2_SUPPORTED
case SYS_POWER_STATE_DEEP_SLEEP_2:
return true;
#endif
#endif /* CONFIG_SYS_POWER_DEEP_SLEEP */
default:
return false;
}
/* Not reached */
}
/* Overrides the weak ARM implementation:
Set general purpose retention register and reboot */
void sys_arch_reboot(int type)

View file

@ -16,6 +16,8 @@
#include <nrf_common.h>
#include <nrf.h>
#include <soc_power.h>
/* Add include for DTS generated information */
#include <generated_dts_board.h>

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2017 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _SOC_POWER_H_
#define _SOC_POWER_H_
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
enum power_states {
#ifdef CONFIG_SYS_POWER_LOW_POWER_STATE
# ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_SUPPORTED
SYS_POWER_STATE_CPU_LPS, /* Not used */
# endif
# ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_1_SUPPORTED
SYS_POWER_STATE_CPU_LPS_1, /* Not used */
# endif
# ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_2_SUPPORTED
SYS_POWER_STATE_CPU_LPS_2, /* Not used */
# endif
#endif /* CONFIG_SYS_POWER_LOW_POWER_STATE */
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
# ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED
SYS_POWER_STATE_DEEP_SLEEP, /* System OFF */
# endif
# ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_1_SUPPORTED
SYS_POWER_STATE_DEEP_SLEEP_1, /* Not used */
# endif
# ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_2_SUPPORTED
SYS_POWER_STATE_DEEP_SLEEP_2, /* Not used */
# endif
#endif /* CONFIG_SYS_POWER_DEEP_SLEEP */
SYS_POWER_STATE_MAX /* Do nothing */
};
/**
* @brief Put processor into low power state
*/
void sys_set_power_state(enum power_states state);
/**
* @brief Check the low power state is supported by SoC
*/
bool sys_is_valid_power_state(enum power_states state);
/**
* @brief Do any SoC or architecture specific post ops after low power states.
*/
void sys_power_state_post_ops(enum power_states state);
#ifdef __cplusplus
}
#endif
#endif /* _SOC_POWER_H_ */