/* * Common IO - basic V1.0.0 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * http://aws.amazon.com/freertos * http://www.FreeRTOS.org */ /** * @file iot_power.h * @brief This file contains all the Power HAL API definitions */ #ifndef _IOT_HAL_POWER_H_ #define _IOT_HAL_POWER_H_ #include #include /** * @defgroup iot_power Power HAL APIs * @{ */ /** * @brief Return values used by the driver. */ #define IOT_POWER_SUCCESS ( 0 ) /*!< Power operation completed successfully. */ #define IOT_POWER_INVALID_VALUE ( 1 ) /*!< At least one parameter is invalid. */ #define IOT_POWER_NOT_INITIALIZED ( 2 ) /*!< Power operation completed successfully. */ #define IOT_POWER_GET_FAILED ( 3 ) /*!< Power get operation failed. */ #define IOT_POWER_SET_FAILED ( 4 ) /*!< Power set operation failed. */ #define IOT_POWER_FUNCTION_NOT_SUPPORTED ( 5 ) /*!< Power operation not supported. */ /** * @brief power descriptor type defined in the source file. */ struct IotPowerDescriptor; /** * @brief IotPowerHandle_t type is the power handle returned by calling iot_power_open() * this is initialized in open and returned to caller. Caller must pass this pointer * to the rest of the APIs. */ typedef struct IotPowerDescriptor * IotPowerHandle_t; /** * @brief Power modes supported by the driver. * These power modes may perform different actions on * different platforms based on the underlying HW support. */ typedef enum { eHighPowerPerfMode, /*!< Set the high performance mode at the SoC level */ eNormalPowerPerfMode, /*!< Set the Normal mode. power_open sets the system to this mode by default*/ eLowPowerPerfMode, /*!< Set the lower performance mode at the Soc level */ eUnknownPowerMode = 0xFFFF /*!< This mode cannot be set, and when a reset_mode is called currentMode will be set to eUnknown */ } IotPowerMode_t; /** * @brief Different Idle mode mappings to the threshold values set using the IOCTLs. */ typedef enum { eIdleNoneMode, /*!< No Idle mode entered. */ eIdlePCMode, /*!< Normal Idle mode with core collapsed or clock gated. Actual * mode implementation may differ based on the underlying SoC support. */ eIdleClkSrcOffModeMode, /*!< Source clock off in addition to core collapse. Actual * mode implementation may differ based on the underlying SoC support. */ eIdleVddOffMode /*!< Vddcore off in addition to clock source and core collapse. Actual * mode implementation may differ based on the underlying SoC support. */ } IotPowerIdleMode_t; /** * @brief Wakeup source information. */ typedef struct IotPowerWakeupSources { uint8_t * pucWakeupSources; /*!< Wakeup sources byte stream, where each bit in the bytes * may indicate a different wakeup source and is platform dependent */ uint16_t usLength; /*!< Length of the Wakeup sources in number of bytes.*/ } IotPowerWakeupSources_t; /** * @brief Ioctl request types. */ typedef enum IotPowerIoctlRequest { eSetPCWakeThreshold, /*!< IdlePCMode is entered when expected idle time provided by RTOS * is greater or equal to the PCWakeThreshold. For example - when * IdleTask runs, all the other tasks are delayed by a time at least * PCWakeThreshold and less than ClkSrcOffWakeThreshold then the * device would enter PCMode. Threshold values are uint32_t in millisecond units.*/ eGetPCWakeThreshold, /*!< Get Wakeup threshold time. Threshold values are uint32_t in millisecond units.*/ eSetClkSrcOffWakeThreshold, /*!< ClkSrcOffModeMode is entered when expected idle time provided * by RTOS is greater or equal to the ClkSrcOffWakeThreshold. For * example - when IdleTask runs, SOC clock sources will be gated for * the time you set to ClkSrcOffWakeThreshold then the device would * enter ClkSrcOffModeMode. Threshold values are uint32_t in millisecond units.*/ eGetClkSrcOffWakeThreshold, /*!< Get Clock off threshold time. Threshold values are uint32_t in millisecond units.*/ eSetVddOfffWakeThreshold, /*!< VddOffMode is entered when expected idle time provided by RTOS * is greater or equal to the VddOfffWakeThreshold. If all idleTask meet * this condition, core will shut off to enter VddOffMode. * Threshold values are uint32_t in millisecond units. */ eGetVddOfffWakeThreshold, /*!< Get power off (vdd rails off - or lower input voltage etc..) threshold time. * Threshold values are uint32_t in millisecond units. */ eSetWakeupSources, /*!< Set wakeup sources that can wake-up the target from idle modes. Wakeup sources * may only be needed for specific idle modes based on the thresholds set above * and may are platform/SoC dependent. Takes input of type IotPowerWakeupSources_t */ eGetWakeupSources, /*!< Get the current wakeup sources set to wakeup the target from idle mode. Returns the * wake-up sources as IotPowerWakeupSources_t type */ eGetLastIdleMode /*!< Get the last Idle mode entered when the target was idle. Returns one of the modes * defined in IotPowerIdleMode_t */ } IotPowerIoctlRequest_t; /** * @brief This callback type is used to set a callback for idle enter and exit notification callback type. * This callback is used for notifying the registered caller(s) before * entering and after coming out of target low power state (i,e:idle/sleep). * bIdleState is used to let the caller know if the callback is called when entering or exiting the low * power mode. "true" indicates that target is entering idle and "false" indicates that its exiting. * The callback is not used for any other mode transitions which are synchronous and blocking. * For example when the caller calls a set_mode to eHighPerfMode, the mode is set in the same context and the call is blocking. * * @param[in] bIdleState IdleState set to "true" when entering idle and "false" when exiting. * @param[in] pvUserContext User Context passed when setting the callback. */ typedef void ( * IotPowerCallback_t )( bool bIdleState, void * pvUserContext ); /** * @brief iot_power_open is used to Initialize the CPU power management driver. * power_open sets up the default mode to eNormalMode, so when the power_open is called, * the caller must set the mode using set_mode to a specific mode of interest. * * @return * - handle to power interface on success * - NULL if already open */ IotPowerHandle_t iot_power_open( void ); /** * @brief iot_power_set_mode is used to set or change the power mode to a specific mode. The actual changes made as part * of switching to a specific power mode are platform specific. When set_mode is called to switch * from high mode to low mode, the target may go through several steps to enter low performance mode. * The aggregation of switching to a particular mode must be made prior to calling this, as a call * to this API may change the CPU frequency and voltage which may affect the software execution. * This API is blocking and the mode switched in the same context as the caller and is a blocking call. * * @param[in] pxPowerHandle handle to power driver returned in * iot_power_open * @param[in] xMode power mode to be switched to. * * @return * - IOT_POWER_SUCCESS on success * - IOT_POWER_INVALID_VALUE if any parameter is invalid * - IOT_POWER_SET_FAILED if unable to set to the desired mode * - IOT_POWER_FUNCTION_NOT_SUPPORTED if specified mode is not supported. */ int32_t iot_power_set_mode( IotPowerHandle_t const pxPowerHandle, IotPowerMode_t xMode ); /** * @brief iot_power_reset_mode is used to reset the mode (i,e remove the vote to set mode). When reset mode is called, * its implicitly notifying the OS to enter deepest low power mode possible in idle state based on * existing timers. If a set_mode is called with any of the performance modes with out calling reset_mode, * then when target enters idle state, it will not be able to enter deep power states since there is an * existing vote for a performance mode from the caller. The target will still do clock gating of the core * by doing a WFI and WFE. * Additionally, if a reset_mode is called, followed by a get_mode, eUnKnownMode will be returned to the caller. * But if reset_mode is called, and then target enters idle state, when coming out of the idle_state it will resume * to a known previous state. * For example, if we take the following flow: * 1. set_mode(eHighPerformanceMode) *  2. reset_modqe() -> At this point the current mode is set to eUnKnownMode *  3. Idle checks to see if it can enter a deep power state based on existing timers. *  4. If a callback is registered, the callback is called with bIdle set to "true" * 4a. The callback can request a mode change causing idle to abort. *  5. Target enters Idle state and goes to 'some' deep power state *  6. Target wakes up due to external interrupt or scheduled timer interrupt. *  7. If a callback is registered, the callback is called with bIdle set to "false" *  8. At this point the caller can set the desired performance state. *  9. Target is set to eHighPerformanceMode as this was the known mode before entering idle. (optional if mode was not set at #6) * * @param[in] pxPowerHandle handle to power driver returned in * iot_power_open * * @return * - IOT_POWER_SUCCESS on success * - IOT_POWER_INVALID_VALUE on pxPowerHandle == NULL * - IOT_POWER_FUNCTION_NOT_SUPPORTED if power reset not supported. */ int32_t iot_power_reset_mode( IotPowerHandle_t const pxPowerHandle ); /** * @brief iot_power_set_callback is used to set the callback to be called when the target is entering low power mode, * and when target is coming out of low power mode. Callback must not use any HW resources * when this callback is called with out first requesting for a performance mode. * * @note Single callback is used for both entering and exiting low power mode. * @note Newly set callback overrides the one previously set * * @warning If input handle or if callback function is NULL, this function silently takes no action. * * @param[in] pxPowerHandle handle to power driver returned in * iot_power_open * @param[in] xCallback The callback function to be called. * @param[in] pvUserContext The user context to be passed when callback is called. */ void iot_power_set_callback( IotPowerHandle_t const pxPowerHandle, IotPowerCallback_t xCallback, void * pvUserContext ); /** * @brief iot_power_ioctl is used to set power configuration and * power properties like Wakeup time thresholds. * Supported IOCTL requests are defined in iot_PowerIoctlRequest_t * * @param[in] pxPowerHandle handle to power driver returned in * iot_power_open() * @param[in] xRequest configuration request of type IotPowerIoctlRequest_t * @param[in,out] pvBuffer buffer holding Power set and get values. * * @return * - IOT_POWER_SUCCESS on success * - IOT_POWER_INVALID_VALUE on any invalid parameter * - IOT_POWER_FUNCTION_NOT_SUPPORTED for any IotPowerIoctlRequest_t not supported. * * @note: For any Set ioctl that is supported, the corresponding Get ioctl must also be supported. */ int32_t iot_power_ioctl( IotPowerHandle_t const pxPowerHandle, IotPowerIoctlRequest_t xRequest, void * const pvBuffer ); /** * @brief iot_power_get_mode is used to get the current power mode the target is in. * * @param[in] pxPowerHandle handle to power driver returned in * iot_power_open * @param[out] xMode current power mode. * * @return * - IOT_POWER_SUCCESS on success * - IOT_POWER_INVALID_VALUE on pxPowerHandle or xMode being NULL * - IOT_POWER_GET_FAILED on error. */ int32_t iot_power_get_mode( IotPowerHandle_t const pxPowerHandle, IotPowerMode_t * xMode ); /** * @brief iot_power_close is used to de-initialize power driver. * * @param[in] pxPowerHandle handle to power driver returned in * iot_power_open * * @return * - IOT_POWER_SUCCESS on success * - IOT_POWER_INVALID_VALUE if * - pxPowerHandle == NULL * - not in open state (already closed). */ int32_t iot_power_close( IotPowerHandle_t const pxPowerHandle ); /** * @} */ #endif /* ifndef _IOT_HAL_POWER_H_ */