Software APIs
dif_pwrmgr.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors.
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_PWRMGR_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_PWRMGR_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/pwrmgr/doc/">Power Manager</a> Device Interface
11  * Functions
12  */
13 
14 #include <stdint.h>
15 
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif // __cplusplus
22 
23 /**
24  * Enumeration for enabling/disabling various functionality.
25  */
26 typedef enum dif_pwrmgr_toggle {
27  /**
28  * Enabled state.
29  */
31  /**
32  * Disabled state.
33  */
36 
37 /**
38  * Hardware instantiation parameters for power manager.
39  *
40  * This struct describes information about the underlying hardware that is
41  * not determined until the hardware design is used as part of a top-level
42  * design.
43  */
44 typedef struct dif_pwrmgr_params {
45  /**
46  * Base address of power manager registers.
47  */
50 
51 /**
52  * A handle to power manager.
53  *
54  * This type should be treated as opaque by users.
55  */
56 typedef struct dif_pwrmgr {
57  /**
58  * Hardware instantiation parameters.
59  */
61 } dif_pwrmgr_t;
62 
63 /**
64  * A request type, i.e. wakeup or reset.
65  */
66 typedef enum dif_pwrmgr_req_type {
67  /**
68  * A wakeup request.
69  */
71  /**
72  * A reset request.
73  */
76 
77 /**
78  * Options for enabling/disabling various clock and power domains
79  * in low and active power states.
80  *
81  * Constants below are bitmasks that can be combined to define configurations.
82  *
83  * See also: `dif_pwrmgr_domain_config_t`.
84  */
86  /**
87  * Enable core clock in low power state.
88  */
90  /**
91  * Enable input/output (IO) clock in low power state.
92  */
94  /**
95  * Enable USB clock in low power state.
96  */
98  /**
99  * Enable USB clock in active power state.
100  */
102  /**
103  * Enable main power domain in low power state.
104  */
107 
108 /**
109  * A set of domain options.
110  *
111  * This type is used for specifying and querying which clock and power domains
112  * are enabled in low and active power states.
113  *
114  * See also: `dif_pwrmgr_domain_option_t`.
115  */
117 
118 /**
119  * A wakeup request source.
120  *
121  * Constants below are bitmasks that can be used to define sets of wakeup
122  * request sources.
123  *
124  * See also: `dif_pwrmgr_request_sources_t`.
125  *
126  * Note: This needs to be updated once the HW is finalized.
127  */
129  kDifPwrmgrWakeupRequestSourceOne = (1u << 0),
130  kDifPwrmgrWakeupRequestSourceTwo = (1u << 1),
131  kDifPwrmgrWakeupRequestSourceThree = (1u << 2),
132  kDifPwrmgrWakeupRequestSourceFour = (1u << 3),
134 
135 /**
136  * A reset request source.
137  *
138  * Constants below are bitmasks that can be used to define sets of reset
139  * request sources.
140  *
141  * See also: `dif_pwrmgr_request_sources_t`.
142  *
143  * Note: This needs to be updated once the HW is finalized.
144  */
146  kDifPwrmgrResetRequestSourceOne = (1u << 0),
148 
149 /**
150  * A set of request sources.
151  *
152  * This type is used for specifying which request sources are enabled for a
153  * particular request type, i.e. wakeup or reset, as well querying wakeup
154  * reasons.
155  *
156  * See also: `dif_pwrmgr_wakeup_request_source_t`,
157  * `dif_pwrmgr_reset_request_source_t`.
158  */
160 
161 /**
162  * A wakeup type.
163  *
164  * Constants below are bitmasks that can be used to define sets of wakeup types.
165  *
166  * See also: `dif_pwrmgr_wakeup_types_t`.
167  */
169  /**
170  * Wakeup due to a peripheral request.
171  */
173  /**
174  * Despite low power mode being enabled and executing a wait for interrupt
175  * (WFI) instruction, an interrupt arrived at just the right time to break the
176  * executing core out of WFI.
177  */
179  /**
180  * Despite low power mode being enabled and executing a wait for interrupt
181  * (WFI) instruction, an active flash, life cycle, or OTP operation was
182  * in progress when the power controller attempted to initiate low power
183  * entry.
184  */
187 
188 /**
189  * A set of wakeup types.
190  *
191  * See also: `dif_pwrmgr_wakeup_type_t`.
192  */
194 
195 /**
196  * Wakeup types and requests from sources since the last time recording started.
197  */
198 typedef struct dif_pwrmgr_wakeup_reason {
199  /**
200  * Wakeup types since the last time recording started.
201  */
202  dif_pwrmgr_wakeup_types_t types;
203  /**
204  * Sources that requested wakeup since the last time recording started.
205  */
206  dif_pwrmgr_request_sources_t request_sources;
208 
209 /**
210  * Result of a power manager operation.
211  */
212 typedef enum dif_pwrmgr_result {
213  /**
214  * The call succeeded.
215  */
217  /**
218  * A non-specific error occurred and the hardware is in an invalid or
219  * irrecoverable state.
220  */
222  /**
223  * The caller supplied invalid arguments but the call did not cause any
224  * side-effects and the hardware is in a valid and recoverable state.
225  */
228 
229 /**
230  * Result of a power manager operation that writes to lockable configuration
231  * registers.
232  */
234  /**
235  * The call succeeded.
236  */
238  /**
239  * A non-specific error occurred and the hardware is in an invalid or
240  * irrecoverable state.
241  */
243  /**
244  * The caller supplied invalid arguments but the call did not cause any
245  * side-effects and the hardware is in a valid and recoverable state.
246  */
248  /**
249  * The register that needs to be written to is locked.
250  */
253 
254 /**
255  * Power manager interrupts.
256  */
257 typedef enum dif_pwrmgr_irq {
258  /**
259  * The device woke up from low power state.
260  *
261  * Note: This interrupt is not triggered during power-on reset.
262  */
264  /**
265  * \internal Last power manager interrupt.
266  */
267  kDifPwrmgrIrqLast = kDifPwrmgrIrqWakeup,
269 
270 /**
271  * A snapshot of the enablement state of power manager interrupts.
272  *
273  * This is an opaque type, to be used with the `dif_pwrmgr_irq_disable_all()`
274  * and `dif_pwrmgr_irq_restore_all()` functions.
275  */
276 typedef uint32_t dif_pwrmgr_irq_snapshot_t;
277 
278 /**
279  * Creates a new handle for power manager.
280  *
281  * This function does not actuate the hardware.
282  *
283  * @param params Hardware instantiation parameters.
284  * @param[out] pwrmgr Out-param for the initialized handle.
285  * @return The result of the operation.
286  */
289  dif_pwrmgr_t *pwrmgr);
290 
291 /**
292  * Enables or disables low power state.
293  *
294  * When enabled, the power manager transitions to low power state on the next
295  * wait for interrupt (WFI) instruction. Since the hardware clears the
296  * corresponding bit automatically, this function must be called before each
297  * transition to low power state.
298  *
299  * Note: This function also syncs changes to the slow clock domain for them to
300  * take effect.
301  *
302  * @param pwrmgr A power manager handle.
303  * @param new_state Whether low power state is enabled.
304  * @return The result of the operation.
305  */
307 dif_pwrmgr_config_result_t dif_pwrmgr_low_power_set_enabled(
308  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_toggle_t new_state);
309 
310 /**
311  * Checks whether low power state is enabled.
312  *
313  * @param pwrmgr A power manager handle.
314  * @param[out] cur_state Whether low power state is enabled.
315  * @return The result of the operation.
316  */
319  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_toggle_t *cur_state);
320 
321 /**
322  * Configures power manager to enable/disable various clock and power domains in
323  * low and active power states.
324  *
325  * Note: This function also syncs changes to the slow clock domain for them to
326  * take effect.
327  *
328  * @param pwrmgr A power manager handle.
329  * @param config A domain configuration.
330  * @return The result of the operation.
331  */
333 dif_pwrmgr_config_result_t dif_pwrmgr_set_domain_config(
334  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_domain_config_t config);
335 
336 /**
337  * Gets current power manager configuration.
338  *
339  * @param pwrmgr A power manager handle.
340  * @param[out] config Current configuration.
341  * @return The result of the operation.
342  */
345  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_domain_config_t *config);
346 
347 /**
348  * Sets sources enabled for a request type.
349  *
350  * A wakeup or reset request can be triggered by multiple sources, e.g. GPIO,
351  * watchdog timer, USB, etc. This function sets which sources are enabled for a
352  * particular request type.
353  *
354  * Note: This function also syncs changes to the slow clock domain for them to
355  * take effect.
356  *
357  * @param pwrmgr A power manager handle.
358  * @param req_type A request type.
359  * @param sources Sources enabled for the given request type.
360  * @return The result of the operation.
361  */
363 dif_pwrmgr_config_result_t dif_pwrmgr_set_request_sources(
364  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_req_type_t req_type,
365  dif_pwrmgr_request_sources_t sources);
366 
367 /**
368  * Gets sources enabled for a request type.
369  *
370  * A wakeup or reset request can be triggered by multiple sources, e.g. GPIO,
371  * watchdog timer, USB, etc. This function gets which sources are enabled for a
372  * particular request type.
373  *
374  * @param pwrmgr A power manager handle.
375  * @param req_type A request type.
376  * @param[out] sources Sources enabled for the given request type.
377  * @return The result of the operation.
378  */
381  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_req_type_t req_type,
382  dif_pwrmgr_request_sources_t *sources);
383 
384 /**
385  * Gets request sources that are currently active for a request type.
386  *
387  * @param pwrmgr A power manager handle.
388  * @param req_type A request type.
389  * @param[out] sources Request sources that are currently active for the given
390  * request type.
391  * @return The result of the operation.
392  */
395  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_req_type_t req_type,
396  dif_pwrmgr_request_sources_t *sources);
397 
398 /**
399  * Locks sources of a request type.
400  *
401  * Once the sources of a particular request type is locked, they cannot be
402  * changed until the hardware is reset.
403  *
404  * @param pwrmgr A power manager handle.
405  * @param req_type A request type.
406  * @return The result of the operation.
407  */
410  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_req_type_t req_type);
411 
412 /**
413  * Checks whether sources of a request type is locked.
414  *
415  * @param pwrmgr A power manager handle.
416  * @param req_type A request type.
417  * @param[out] is_locked Whether sources of the given request type is locked.
418  * @return The result of the operation.
419  */
422  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_req_type_t req_type,
423  bool *is_locked);
424 
425 /**
426  * Enables or disables recording of wakeup requests.
427  *
428  * Power manager automatically starts recording wakeup requests when it
429  * begins a valid low power entry. Recording continues until it is explicitly
430  * disabled by calling this function.
431  *
432  * @param pwrmgr A power manager handle.
433  * @param new_state Whether wakeup requests should be recorded.
434  * @return The result of the operation.
435  */
438  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_toggle_t new_state);
439 
440 /**
441  * Checks whether wakeup requests are being recorded.
442  *
443  * @param pwrmgr A power manager handle.
444  * @param[out] cur_state Whether wakeup requests are being recorded.
445  * @return The result of the operation.
446  */
449  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_toggle_t *cur_state);
450 
451 /**
452  * Gets wakeup reason and source requests since the last time recording
453  * started.
454  *
455  * Power manager automatically starts recording wakeup requests when it
456  * begins a valid low power entry. Recording continues until it is explicitly
457  * disabled by calling `dif_pwrmgr_wakeup_request_recording_set_enabled`. Thus,
458  * it is possible to record wakeup requests from multiple sources as well as
459  * multiple wakeup types.
460  *
461  * @param pwrmgr A power manager handle.
462  * @param[out] reason Wakeup reasons.
463  * @return The result of the operation.
464  */
467  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_wakeup_reason_t *reason);
468 
469 /**
470  * Clears wakeup reason(s) recorded since the last time recording started.
471  *
472  * @param pwrmgr A power manager handle.
473  * @return The result of the operation.
474  */
477 
478 /**
479  * Returns whether a particular interrupt is currently pending.
480  *
481  * @param pwrmgr A power manager handle.
482  * @param irq An interrupt type.
483  * @param[out] is_pending Out-param for whether the interrupt is pending.
484  * @return The result of the operation.
485  */
488  dif_pwrmgr_irq_t irq,
489  bool *is_pending);
490 
491 /**
492  * Acknowledges a particular interrupt, indicating to the hardware that it has
493  * been successfully serviced.
494  *
495  * @param pwrmgr A power manager handle.
496  * @param irq An interrupt type.
497  * @return The result of the operation.
498  */
501  dif_pwrmgr_irq_t irq);
502 
503 /**
504  * Checks whether a particular interrupt is currently enabled or disabled.
505  *
506  * @param pwrmgr A power manager handle.
507  * @param irq An interrupt type.
508  * @param[out] state Out-param toggle state of the interrupt.
509  * @return The result of the operation.
510  */
513  dif_pwrmgr_irq_t irq,
514  dif_pwrmgr_toggle_t *state);
515 
516 /**
517  * Sets whether a particular interrupt is currently enabled or disabled.
518  *
519  * @param pwrmgr A power manager handle.
520  * @param irq An interrupt type.
521  * @param state The new toggle state for the interrupt.
522  * @return The result of the operation.
523  */
526  dif_pwrmgr_irq_t irq,
527  dif_pwrmgr_toggle_t state);
528 
529 /**
530  * Forces a particular interrupt, causing it to be serviced as if hardware had
531  * asserted it.
532  *
533  * @param pwrmgr A power manager handle.
534  * @param irq An interrupt type.
535  * @return The result of the operation.
536  */
539  dif_pwrmgr_irq_t irq);
540 
541 /**
542  * Disables all interrupts, optionally snapshotting all toggle state for later
543  * restoration.
544  *
545  * @param pwrmgr A power manager handle.
546  * @param[out] snapshot Out-param for the snapshot; may be `NULL`.
547  * @return The result of the operation.
548  */
551  const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_irq_snapshot_t *snapshot);
552 
553 /**
554  * Restores interrupts from the given snapshot.
555  *
556  * This function can be used with `dif_pwrmgr_irq_disable_all()` to temporary
557  * interrupt save-and-restore.
558  *
559  * @param pwrmgr A power manager handle.
560  * @param snapshot A snapshot to restore from.
561  * @return The result of the operation.
562  */
565  const dif_pwrmgr_t *pwrmgr, const dif_pwrmgr_irq_snapshot_t *snapshot);
566 
567 #ifdef __cplusplus
568 } // extern "C"
569 #endif // __cplusplus
570 
571 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_PWRMGR_H_