1 /*
2 * Copyright (c) 2015-2016, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 /** ============================================================================
33 * @file Power.h
34 *
35 * @brief Power manager interface
36 *
37 * The Power header file should be included in an application as follows:
38 * @code
39 * #include <ti/drv/pm/Power.h>
40 * @endcode
41 *
42 * # Operation #
43 * The Power manager facilitates the transition of the CPU from active state
44 * to one of the sleep states and vice versa. It provides drivers the
45 * ability to set and release dependencies on hardware resources and keeps
46 * a reference count on each resource to know when to enable or disable the
47 * peripheral clock to the resource. It provides drivers the ability to
48 * register a callback function upon a specific power event. In addition,
49 * drivers and apps can set or release constraints to prevent the CPU from
50 * transitioning into a particular sleep state.
51 *
52 * ============================================================================
53 */
55 #ifndef ti_drivers_Power__include
56 #define ti_drivers_Power__include
58 #include <stdint.h>
59 #include <src/pmrtos/common/List.h>
61 #ifdef __cplusplus
62 extern "C" {
63 #endif
65 /* Power latency types */
66 #define Power_TOTAL 1 /*!< total latency */
67 #define Power_RESUME 2 /*!< resume latency */
69 /* Power notify responses */
70 #define Power_NOTIFYDONE 0 /*!< OK, notify completed */
71 #define Power_NOTIFYERROR 1 /*!< an error occurred during notify */
73 /* Power status */
74 #define Power_SOK 0 /*!< OK, operation succeeded */
75 #define Power_EFAIL 1 /*!< general failure */
76 #define Power_EINVALIDPOINTER 2 /*!< invalid pointer */
77 #define Power_ECHANGE_NOT_ALLOWED 3 /*!< change is not allowed */
78 #define Power_EBUSY 4 /*!< busy with another transition */
80 /* Power transition states */
81 #define Power_ACTIVE 1 /*!< normal active state */
82 #define Power_ENTERING_SLEEP 2 /*!< entering a sleep state */
83 #define Power_EXITING_SLEEP 3 /*!< exiting a sleep state */
84 #define Power_ENTERING_SHUTDOWN 4 /*!< entering a shutdown state */
85 #define Power_CHANGING_PERF_LEVEL 5 /*!< moving to new performance level */
87 /*!
88 * @brief Power policy initialization function pointer
89 */
90 typedef void (*Power_PolicyInitFxn)(void);
92 /*!
93 * @brief Power policy function pointer
94 */
95 typedef void (*Power_PolicyFxn)(void);
97 /*!
98 * @brief Power notify function pointer
99 */
100 typedef int (*Power_NotifyFxn)(unsigned int eventType, uintptr_t eventArg,
101 uintptr_t clientArg);
103 /*!
104 * @brief Power notify object structure.
105 *
106 * This struct specification is for internal use. Notification clients must
107 * pre-allocate a notify object when registering for a notification;
108 * Power_registerNotify() will take care initializing the internal elements
109 * appropriately.
110 */
111 typedef struct Power_NotifyObj {
112 List_Elem link; /*!< for placing on the notify list */
113 unsigned int eventTypes; /*!< the event type */
114 Power_NotifyFxn notifyFxn; /*!< notification function */
115 uintptr_t clientArg; /*!< argument provided by client */
116 } Power_NotifyObj;
118 /*!
119 * @brief Enable the configured power policy to run when the CPU is idle
120 *
121 * Calling this function sets a flag that will cause the configured power
122 * policy function to be invoked on each pass through the Idle loop. This
123 * runtime function call will essentially override a 'false' setting of the
124 * "enablePolicy" setting in the Power manager configuration object.
125 *
126 * For some processor families automatic power transitions are at odds with
127 * the debugger, and having the policy running by default makes application
128 * debug difficult. This convenience function allows an application to be
129 * initially configured, built, and debugged, without automatic power
130 * transitions during idle time. When the application is found to be working,
131 * this function can be called (typically in main()) to enable the policy
132 * to run, without having to change the application configuration. Note that
133 * there is no comparable 'disable' policy function; once the policy has
134 * been enabled to run, it will always run until the applicaiton is rebooted.
135 *
136 */
137 void Power_enablePolicy(void);
139 /*!
140 * @brief Get the constraints that have been declared with Power
141 *
142 * This function returns a bitmask indicating the constraints that are
143 * currently declared to the Power manager (via previous calls to
144 * Power_setConstraint()). For each constraint that is currently declared,
145 * the corresponding bit in the bitmask will be set. For example, if two
146 * clients have independently declared two different constraints, the returned
147 * bitmask will have two bits set.
148 *
149 * Constraint identifiers are device specific, and defined in the
150 * device-specific Power include file. For example, the constraints for
151 * PRCM are defined in PowerPRCM.h. The corresponding bit in the
152 * bitmask returned by this function can be derived by a left-shift using
153 * the constraint identifier. For example, for PRCM, for the corresponding
154 * bit for the PowerPRCM_DISALLOW_SLEEP constraint, the bit position is
155 * determined by the operation: (1 << PowerPRCM_DISALLOW_SLEEP)
156 *
157 * @return A bitmask of the currently declared constraints.
158 *
159 * @return Power_SOK
160 *
161 * @sa Power_setConstraint
162 */
163 unsigned int Power_getConstraintMask(void);
165 /*!
166 * @brief Get the current dependency count for a resource
167 *
168 * This function returns the number of dependencies that are currently
169 * declared upon a resource.
170 *
171 * Resource identifiers are device specific, and defined in the
172 * device-specific Power include file. For example, the resources for
173 * PRCM are defined in PowerPRCM.h.
174 *
175 * @param resourceId resource id
176 *
177 * @return The number of dependencies declared upon the resource.
178 *
179 * @sa Power_setDependency
180 */
181 unsigned int Power_getDependencyCount(unsigned int resourceId);
183 /*!
184 * @brief Get the current performance level
185 *
186 * This function returns the current device performance level in effect.
187 *
188 * If performance scaling is not supported for the device, this function
189 * will always indicate a performance level of zero.
190 *
191 * @return The current performance level.
192 *
193 * @sa Power_setPerformanceLevel
194 */
195 unsigned int Power_getPerformanceLevel(void);
197 /*!
198 * @brief Get the hardware transition latency for a sleep state
199 *
200 * This function reports the minimal hardware transition latency for a specific
201 * sleep state. The reported latency is that for a direct transition, and does
202 * not include any additional latency that might occur due to software-based
203 * notifications.
204 *
205 * Sleep states are device specific, and defined in the device-specific Power
206 * include file. For example, the sleep states for PRCM are defined in
207 * PowerPRCM.h.
208 *
209 * This function is typically called by the power policy function. The latency
210 * is reported in units of microseconds.
211 *
212 * @param sleepState the sleep state
213 *
214 * @param type the latency type (Power_TOTAL or Power_RESUME)
215 *
216 * @return The latency value, in units of microseconds.
217 */
218 unsigned int Power_getTransitionLatency(unsigned int sleepState,
219 unsigned int type);
221 /*!
222 * @brief Get the current transition state of the Power manager
223 *
224 * This function returns the current transition state for the Power manager.
225 * For example, when no transitions are in progress, a status of Power_ACTIVE
226 * is returned. Power_ENTERING_SLEEP is returned during the transition to
227 * sleep, before sleep has occurred. And Power_EXITING_SLEEP will be returned
228 * after wakeup, as the device is being transtioned back to Power_ACTIVE.
229 *
230 * @return The current Power manager transition state.
231 *
232 */
233 unsigned int Power_getTransitionState(void);
235 /*!
236 * @brief Power function to be added to the application idle loop
237 *
238 * This function should be added to the application idle loop. (The method to
239 * do this depends upon the operating system being used.) This function
240 * will invoke the configured power policy function when appropriate. The
241 * specific policy function to be invoked is configured as the 'policyFxn'
242 * in the application-defined Power configuration object.
243 *
244 */
245 void Power_idleFunc(void);
247 /*!
248 * @brief Power initialization function
249 *
250 * This function initializes Power manager internal state. It must be called
251 * prior to any other Power API. This function is normally called as part
252 * of TI-RTOS board initialization, for example, from within the
253 * the \<board name\>_initGeneral() function.
254 *
255 * @return Power_SOK
256 */
257 unsigned int Power_init(void);
259 /*!
260 * @brief Register a function to be called upon a specific power event
261 *
262 * This function registers a function to be called when a Power event occurs.
263 * Registrations and the corresponding notifications are processed in
264 * first-in-first-out (FIFO) order. The function registered must behave as
265 * described later, below.
266 *
267 * The pNotifyObj parameter is a pointer to a pre-allocated, opaque object
268 * that will be used by Power to support the notification. This object could
269 * be dynamically allocated, or declared as a global object. This function
270 * will properly initialized the object's fields as appropriate; the caller
271 * just needs to provide a pointer to this pre-existing object.
272 *
273 * The eventTypes parameter identifies the type of power event(s) for which
274 * the notify function being registered is to be called. (Event identifiers are
275 * device specific, and defined in the device-specific Power include file.
276 * For example, the events for PRCM are defined in PowerPRCM.h.) The
277 * eventTypes parameter for this function call is treated as a bitmask, so
278 * multiple event types can be registered at once, using a common callback
279 * function. For example, to call the specified notifyFxn when both
280 * the entering deepsleep and awake from deepsleep events occur, eventTypes
281 * should be specified as: PowerPRCM_ENTERING_DEEPSLEEP |
282 * PowerPRCM_AWAKE_DEEPSLEEP
283 *
284 * The notifyFxn parameter specifies a callback function to be called when the
285 * specified Power event occurs. The notifyFxn must implement the following
286 * signature:
287 * status = notifyFxn(eventType, eventArg, clientArg);
288 *
289 * Where: eventType identifies the event being signalled, eventArg is an
290 * optional event-specific argument, and clientArg is an abitrary argument
291 * specified by the client at registration. Note that multipe types of events
292 * can be specified when registering the notification callback function,
293 * but when the callback function is actually called by Power, only a
294 * single eventType will be specified for the callback (i.e., the current
295 * event). The status returned by the client notification function must
296 * be one of the following constants: Power_NOTIFYDONE if the client processed
297 * the notification successfully, or Power_NOTIFYERROR if an error occurred
298 * during notification.
299 *
300 * The clientArg parameter is an arbitrary, client-defined argument to be
301 * passed back to the client upon notification. This argument may allow one
302 * notify function to be used by multiple instances of a driver (that is, the
303 * clientArg can be used to identify the instance of the driver that is being
304 * notified).
305 *
306 * @param pNotifyObj notification object (preallocated by caller)
307 *
308 * @param eventTypes event type or types
309 *
310 * @param notifyFxn client's callback function
311 *
312 * @param clientArg client-specified argument to pass with notification
313 *
314 * @return Power_SOK
315 *
316 * @sa Power_unregisterNotify
317 */
318 unsigned int Power_registerNotify(Power_NotifyObj *pNotifyObj,
319 unsigned int eventTypes,
320 Power_NotifyFxn notifyFxn,
321 uintptr_t clientArg);
323 /*!
324 * @brief Release a previously declared constraint
325 *
326 * This function releases a constraint that was previously declared with
327 * Power_setConstraint(). For example, if a device driver is starting an I/O
328 * transaction and wants to prohibit activation of a sleep state during the
329 * transaction, it uses Power_setConstraint() to declare the constraint,
330 * before starting the transaction. When the transaction completes, the
331 * driver calls this function to release the constraint, to allow the Power
332 * manager to once again allow transitions to sleep.
333 *
334 * Constraint identifiers are device specific, and defined in the
335 * device-specific Power include file. For example, the constraints for
336 * PRCM are defined in PowerPRCM.h.
337 *
338 * Only one constraint can be specified with each call to this function; to
339 * release multiple constraints this function must be called multiple times.
340 *
341 * It is critical that clients call Power_releaseConstraint() when operational
342 * constraints no longer exists. Otherwise, Power may be left unnecessarily
343 * restricted from activating power savings.
344 *
345 * @param constraintId constraint id
346 *
347 * @return Power_SOK
348 *
349 * @sa Power_setConstraint
350 */
351 unsigned int Power_releaseConstraint(unsigned int constraintId);
353 /*!
354 * @brief Release a previously declared dependency
355 *
356 * This function releases a dependency that had been previously declared upon
357 * a resource (by a call to Power_setDependency()).
358 *
359 * Resource identifiers are device specific, and defined in the
360 * device-specific Power include file. For example, the resources for
361 * PRCM are defined in PowerPRCM.h.
362 *
363 * @param resourceId resource id
364 *
365 * @return Power_SOK on success.
366 * Power_INVALIDINPUT if the resourceId passed is incorrect.
367 * Power_EFAIL if desired power state is not allowed by the module.
368 *
369 * @sa Power_setDependency
370 */
371 uint32_t Power_releaseDependency(unsigned int resourceId);
373 /*!
374 * @brief Declare an operational constraint
375 *
376 * Before taking certain actions, the Power manager checks to see if the
377 * requested action would conflict with a client-declared constraint. If the
378 * action does conflict, Power will not proceed with the request. This is the
379 * function that allows clients to declare their constraints with Power.
380 *
381 * Constraint identifiers are device specific, and defined in the
382 * device-specific Power include file. For example, the constraints for
383 * PRCM are defined in PowerPRCM.h.
384 *
385 * Only one constraint can be specified with each call to this function; to
386 * declare multiple constraints this function must be called multiple times.
387 *
388 * @param constraintId constraint id
389 *
390 * @return Power_SOK
391 *
392 * @sa Power_releaseConstraint
393 */
394 unsigned int Power_setConstraint(unsigned int constraintId);
396 /*!
397 * @brief Declare a dependency upon a resource
398 *
399 * This function declares a dependency upon a resource. For example, if a
400 * UART driver needs a specific UART peripheral, it uses this function to
401 * declare this to the Power manager. If the resource had been inactive,
402 * then Power will activate the peripheral during this function call.
403 *
404 * What is needed to make a peripheral resource 'active' will vary by device
405 * family. For some devices this may be a simple enable of a clock to the
406 * specified peripheral. For others it may also require a power on of a
407 * power domain. In either case, the Power manager will take care of these
408 * details, and will also implement reference counting for resources and their
409 * interdependencies. For example, if multiple UART peripherals reside in
410 * a shared serial power domain, the Power manager will power up the serial
411 * domain when it is first needed, and then automatically power the domain off
412 * later, when all related dependencies for the relevant peripherals are
413 * released.
414 *
415 * Resource identifiers are device specific, and defined in the
416 * device-specific Power include file. For example, the resources for
417 * PRCM are defined in PowerPRCM.h.
418 *
419 * @param resourceId resource id
420 *
421 * @return Power_SOK on success.
422 * Power_INVALIDINPUT if the resourceId passed is incorrect.
423 * Power_EFAIL if desired power state is not allowed by the module.
424 *
425 * @sa Power_releaseDependency
426 */
427 uint32_t Power_setDependency(unsigned int resourceId);
429 /*!
430 * @brief Set the MCU performance level
431 *
432 * This function manages a transition to a new device performance level.
433 * Before the actual transition is initiated, notifications will be sent to
434 * any clients who've registered (with Power_registerNotify()) for a
435 * 'start change performance level' notification. The event name is device
436 * specific, and defined in the device-specific Power include file. For
437 * example, for PRCM, the event is "PowerPRCM_START_CHANGE_PERF_LEVEL",
438 * which is defined in PowerPRCM.h. Once notifications have been completed,
439 * the change to the performance level is initiated. After the level change
440 * is completed, there is a comparable event that can be used to signal a
441 * client that the change has completed. For example, on PRCM the
442 * "PowerPRCM_DONE_CHANGE_PERF_LEVEL" event can be used to signal
443 * completion.
444 *
445 * This function will not return until the new performance level is in effect.
446 * If performance scaling is not supported for the device, or is prohibited
447 * by an active constraint, or if the specified level is invalid, then an
448 * error status will be returned.
449 *
450 * @param level the new performance level
451 *
452 * @return Power_SOK on success. Power_EFAIL if: performance scaling is not
453 * supported, or if the scaling routines encountered an error during
454 * initialization, or if the specified performance level is out of range
455 * of valid levels. Power_EBUSY is returned if the Power manager is
456 * already busy with another transition, or if a single constraint that
457 * locks any performance level changes has been declared.
458 * Power_ECHANGE_NOT_ALLOWED is returned if the requested level has been
459 * explicitly prohibited by a level-specific constraint.
460 *
461 * @sa Power_getPerformanceLevel
462 */
463 unsigned int Power_setPerformanceLevel(unsigned int level);
465 /*!
466 * @brief Put the device into a shutdown state
467 *
468 * This function will transition the device into a shutdown state.
469 * Before the actual transition is initiated, notifications will be sent to
470 * any clients who've registered (with Power_registerNotify()) for an
471 * 'entering shutdown' event. The event name is device specific, and defined
472 * in the device-specific Power include file. For example, for PRCM, the
473 * event is "PowerPRCM_ENTERING_SHUTDOWN", which is defined in
474 * PowerPRCM.h. Once notifications have been completed, the device shutdown
475 * will commmence.
476 *
477 * If the device is successfully transitioned to shutdown, this function
478 * call will never return. Upon wakeup, the device and application will
479 * be rebooted (through a device reset). If the transition is not
480 * successful, one of the error codes listed below will be returned.
481 *
482 * On some devices a timed wakeup from shutdown can be specified, using
483 * the shutdownTime parameter. This enables an autonomous application reboot
484 * at a future time. For example, an application can go to shutdown, and then
485 * automatically reboot at a future time to do some work. And once that work
486 * is done, the application can shutdown again, for another timed interval.
487 * The time interval is specified via the shutdownTime parameter. (On devices
488 * that do not support this feature, any value specified for shutdownTime will
489 * be ignored.) If the specified shutdownTime is less than the total
490 * shutdown latency for the device, then shutdownTime will be ignored. The
491 * shutdown latency for the device can be found in the device-specific Power
492 * include file. For example, for the PRCM, this latency is defined in
493 * PowerPRCM.h, as "PowerPRCM_TOTALTIMESHUTDOWN".)
494 *
495 * @param shutdownState the device-specific shutdown state
496 *
497 * @param shutdownTime the amount of time (in milliseconds) to keep the
498 * the device in the shutdown state; this parameter
499 * is not supported on all device families
500 *
501 * @return An error status if the transition did not occur:
502 * Power_ECHANGE_NOT_ALLOWED if the transition is prohibited by a
503 * constraint; Power_EBUSY if the Power manager is already busy with
504 * another transition.
505 */
506 unsigned int Power_shutdown(unsigned int shutdownState,
507 unsigned int shutdownTime);
509 /*!
510 * @brief Transition the device into a sleep state
511 *
512 * This function is called from the power policy when it has made a decision
513 * to put the device in a specific sleep state. This function returns to the
514 * caller (the policy function) once the device has awoken from sleep.
515 *
516 * This function must be called with interrupts disabled, and should not be
517 * called directly by the application, or by any drivers.
518 * This function does not check declared constraints; the policy function
519 * must check constraints before calling this function to initiate sleep.
520 *
521 * @param sleepState the sleep state
522 *
523 * @return A status code indicating success or failure: Power_SOK if the
524 * device was put to sleep and then awoken; Power_EFAIL if a failure
525 * occurred during client notifications; or Power_EBUSY if the Power
526 * manager is already busy with another transition.
527 */
528 unsigned int Power_sleep(unsigned int sleepState);
530 /*!
531 * @brief Unregister previously registered notifications
532 *
533 * This function unregisters for event notifications that were previously
534 * registered with Power_registerNotify(). The caller must specify a pointer
535 * to the same notification object used during registration.
536 *
537 * @param pNotifyObj notify object
538 *
539 * @sa Power_registerNotify
540 */
541 void Power_unregisterNotify(Power_NotifyObj *pNotifyObj);
543 #ifdef __cplusplus
544 }
545 #endif
547 #endif /* ti_drivers_Power__include */