Software APIs
dif_clkmgr.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors (OpenTitan project).
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_CLKMGR_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_CLKMGR_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/top_earlgrey/ip_autogen/clkmgr/doc/">Clock Manager</a>
11  * Device Interface Functions
12  */
13 
14 #include <stdint.h>
15 
19 
20 #include "sw/device/lib/dif/autogen/dif_clkmgr_autogen.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif // __cplusplus
25 
26 /**
27  * An Index of a "Gateable" Clock.
28  *
29  * "Gateable" clocks are under full software control: they can be enabled and
30  * disabled by software, which directly starts and stops the identified clock.
31  */
32 typedef uint32_t dif_clkmgr_gateable_clock_t;
33 
34 /**
35  * An Index of a "Hintable" Clock.
36  *
37  * "Hintable" clocks are under partial software control: software can suggest
38  * they are stopped, but the clock manager may delay stopping the peripheral, or
39  * may ignore the request altogether.
40  */
41 typedef uint32_t dif_clkmgr_hintable_clock_t;
42 
44 #if defined(OPENTITAN_IS_EARLGREY)
45  /**
46  * The Io clock.
47  */
48  kDifClkmgrMeasureClockIo,
49  /**
50  * The Io_div2 clock.
51  */
52  kDifClkmgrMeasureClockIoDiv2,
53 #elif defined(OPENTITAN_IS_DARJEELING)
54 // Darjeeling doesn't have Io / Io_div2 clock measurements.
55 #else
56 #error "dif_clkmgr does not support this top"
57 #endif
58  /**
59  * The Io div4 clock.
60  */
62  /**
63  * The Main clock.
64  */
66  /**
67  * The Usb clock.
68  */
70  /**
71  * Total number of clock measurements.
72  */
74 } dif_clkmgr_measure_clock_t;
75 
76 typedef enum dif_clkmgr_recov_err_type {
77 #if defined(OPENTITAN_IS_EARLGREY)
78  /**
79  * A recoverable update error for one of the clocks.
80  */
81  kDifClkmgrRecovErrTypeShadowUpdate = 1u << 0,
82  /**
83  * A recoverable measurement error for IO clock.
84  */
85  kDifClkmgrRecovErrTypeIoMeas = 1u << 1,
86  /**
87  * A recoverable measurement error for IO_DIV2 clock.
88  */
89  kDifClkmgrRecovErrTypeIoDiv2Meas = 1u << 2,
90  /**
91  * A recoverable measurement error for IO_DIV4 clock.
92  */
93  kDifClkmgrRecovErrTypeIoDiv4Meas = 1u << 3,
94  /**
95  * A recoverable measurement error for MAIN clock.
96  */
97  kDifClkmgrRecovErrTypeMainMeas = 1u << 4,
98  /**
99  * A recoverable measurement error for USB clock.
100  */
101  kDifClkmgrRecovErrTypeUsbMeas = 1u << 5,
102  /**
103  * A recoverable timeout error for IO clock.
104  */
105  kDifClkmgrRecovErrTypeIoTimeout = 1u << 6,
106  /**
107  * A recoverable timeout error for IO_DIV2 clock.
108  */
109  kDifClkmgrRecovErrTypeIoDiv2Timeout = 1u << 7,
110  /**
111  * A recoverable timeout error for IO_DIV4 clock.
112  */
113  kDifClkmgrRecovErrTypeIoDiv4Timeout = 1u << 8,
114  /**
115  * A recoverable timeout error for MAIN clock.
116  */
117  kDifClkmgrRecovErrTypeMainTimeout = 1u << 9,
118  /**
119  * A recoverable timeout error for USB clock.
120  */
121  kDifClkmgrRecovErrTypeUsbTimeout = 1u << 10,
122 #elif defined(OPENTITAN_IS_DARJEELING)
123  /**
124  * A recoverable update error for one of the clocks.
125  */
126  kDifClkmgrRecovErrTypeShadowUpdate = 1u << 0,
127  /**
128  * A recoverable measurement error for IO_DIV4 clock.
129  */
130  kDifClkmgrRecovErrTypeIoDiv4Meas = 1u << 1,
131  /**
132  * A recoverable measurement error for MAIN clock.
133  */
134  kDifClkmgrRecovErrTypeMainMeas = 1u << 2,
135  /**
136  * A recoverable measurement error for USB clock.
137  */
138  kDifClkmgrRecovErrTypeUsbMeas = 1u << 3,
139  /**
140  * A recoverable timeout error for IO_DIV4 clock.
141  */
142  kDifClkmgrRecovErrTypeIoDiv4Timeout = 1u << 4,
143  /**
144  * A recoverable timeout error for MAIN clock.
145  */
146  kDifClkmgrRecovErrTypeMainTimeout = 1u << 5,
147  /**
148  * A recoverable timeout error for USB clock.
149  */
150  kDifClkmgrRecovErrTypeUsbTimeout = 1u << 6,
151 #else
152 #error "dif_clkmgr does not support this top"
153 #endif
154 } dif_clkmgr_recov_err_type_t;
155 
156 /**
157  * A set of recoverable errors.
158  *
159  * This type is used to clear and read the recoverable error codes.
160  */
162 
164  /**
165  * A fatal error for regfile integrity.
166  */
168  /**
169  * A fatal error for a duplicate idle counter.
170  */
172  /**
173  * A fatal error for a shadow register storage.
174  */
176 } dif_clkmgr_fatal_err_type_t;
177 
178 /**
179  * A set of fatal errors.
180  *
181  * This type is used to read the fatal error codes.
182  */
184 
185 /**
186  * Check if jitter enable is locked.
187  * @param clkmgr Clock Manager Handle.
188  * @param[out] is_locked whether jitter is locked or not.
189  * @returns The result of the operation.
190  */
192 dif_result_t dif_clkmgr_jitter_enable_is_locked(const dif_clkmgr_t *clkmgr,
193  bool *is_locked);
194 
195 /**
196  * Lock jitter enable.
197  * @param clkmgr Clock Manager Handle.
198  * @returns The result of the operation.
199  */
201 dif_result_t dif_clkmgr_lock_jitter_enable(const dif_clkmgr_t *clkmgr);
202 
203 /**
204  * Check if jitter is Enabled.
205  * @param clkmgr Clock Manager Handle.
206  * @param[out] is_enabled whether jitter is enabled or not.
207  * @returns The result of the operation.
208  */
210 dif_result_t dif_clkmgr_jitter_get_enabled(const dif_clkmgr_t *clkmgr,
211  dif_toggle_t *state);
212 
213 /**
214  * Enable of Disable jitter.
215  * @param clkmgr Clock Manager Handle.
216  * @param new_state whether to enable or disable jitter.
217  * @returns The result of the operation.
218  */
220 dif_result_t dif_clkmgr_jitter_set_enabled(const dif_clkmgr_t *clkmgr,
221  dif_toggle_t new_state);
222 
223 /**
224  * Obtain the index of a gateable clock for a device.
225  *
226  * Given a module instance (identified by its instance ID), return the
227  * index of the gateable clock which controls this device and can be used
228  * with the clkmgr DIF.
229  *
230  * Example (find gateable clock of UART0):
231  * ```c
232  * dif_clkmgr_gateable_clock_t clock;
233  * CHECK_DIF_OK(dif_clkmgr_find_gateable_clock(
234  * clkmgr, kDtInstanceIdUart0, &clock));
235  * ```
236  *
237  * @param clkmgr A clock manager handle.
238  * @param inst_id An instance ID.
239  * @param[out] clock The index of the clock.
240  * @return `kDifError` if no gateable clock matches the description,
241  * `kDifOk` otherwise.
242  */
244 dif_result_t dif_clkmgr_find_gateable_clock(const dif_clkmgr_t *clkmgr,
245  dt_instance_id_t inst_id,
247 
248 /**
249  * Check if a Gateable Clock is Enabled or Disabled.
250  *
251  * @param clkmgr Clock Manager Handle.
252  * @param clock Gateable Clock ID.
253  * @param[out] is_enabled whether the clock is enabled or not.
254  * @returns The result of the operation.
255  */
258  const dif_clkmgr_t *clkmgr, dif_clkmgr_gateable_clock_t clock,
259  dif_toggle_t *state);
260 
261 /**
262  * Enable or Disable a Gateable Clock.
263  *
264  * @param clkmgr Clock Manager Handle.
265  * @param clock Gateable Clock ID.
266  * @param new_state whether to enable or disable the clock.
267  * @returns The result of the operation.
268  */
271  const dif_clkmgr_t *clkmgr, dif_clkmgr_gateable_clock_t clock,
272  dif_toggle_t new_state);
273 
274 /**
275  * Obtain the index of a hintable clock for a device.
276  *
277  * Given a module instance (identified by its instance ID), return the
278  * index of the hintable clock which controls this device and can be used
279  * with the clkmgr DIF.
280  *
281  * Example (find hintable clock of KMAC):
282  * ```c
283  * dif_clkmgr_hintable_clock_t clock;
284  * CHECK_DIF_OK(dif_clkmgr_find_hintable_clock(
285  * clkmgr, kDtInstanceIdKmac, &clock));
286  * ```
287  *
288  * @param clkmgr A clock manager handle.
289  * @param inst_id An instance ID.
290  * @param[out] clock The index of the clock.
291  * @return `kDifError` if no hintable clock matches the description,
292  * `kDifOk` otherwise.
293  */
295 dif_result_t dif_clkmgr_find_hintable_clock(const dif_clkmgr_t *clkmgr,
296  dt_instance_id_t inst_id,
298 
299 /**
300  * Check if a Hintable Clock is Enabled or Disabled.
301  *
302  * Hintable clocks are not under full software control, but this operation
303  * accurately reflects the state of the current clock, regardless of any hint
304  * requests made by software.
305  *
306  * To read what hint the software has given the hardware, use
307  * #dif_clkmgr_hintable_clock_get_hint.
308  *
309  * @param clkmgr Clock Manager Handle.
310  * @param clock Hintable Clock ID.
311  * @param[out] is_enabled whether the clock is enabled or not.
312  * @returns The result of the operation.
313  */
316  const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock,
317  dif_toggle_t *state);
318 
319 /**
320  * Enable or Disable a Hintable Clock.
321  *
322  * This only sets a hint that the clock should be enabled or disabled. The clock
323  * manager is in control of whether the clock should actually be enabled or
324  * disabled.
325  *
326  * To read what hint the software has given the hardware, use
327  * #dif_clkmgr_hintable_clock_get_hint. To read whether the clock is currently
328  * enabled or disabled, use #dif_clkmgr_hintable_clock_get_enabled.
329  *
330  * @param clkmgr Clock Manager Handle.
331  * @param clock Hintable Clock ID.
332  * @param new_state whether to enable or disable the clock.
333  * @returns The result of the operation.
334  */
337  const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock,
338  dif_toggle_t new_state);
339 
340 /**
341  * Read the current Hint for a Hintable Clock.
342  *
343  * Hintable clocks are not under full software control; this operation
344  * accurately reflects the current software hint, not the current state of the
345  * clock.
346  *
347  * To read whether the clock is currently enabled or disabled, use
348  * #dif_clkmgr_hintable_clock_get_enabled.
349  *
350  * @param clkmgr Clock Manager Handle.
351  * @param clock Hintable Clock ID.
352  * @param[out] hinted_is_enabled the current software request (hint) for this
353  * clock.
354  * @returns The result of the operation.
355  */
358  const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock,
359  dif_toggle_t *state);
360 
361 /**
362  * Check if external clock control is locked.
363  * @param clkmgr Clock Manager Handle.
364  * @param[out] is_locked whether external clock control is locked or not.
365  * @returns The result of the operation.
366  */
369  const dif_clkmgr_t *clkmgr, bool *is_locked);
370 
371 /**
372  * Lock external clock control.
373  * @param clkmgr Clock Manager Handle.
374  * @returns The result of the operation.
375  */
377 dif_result_t dif_clkmgr_lock_external_clock_control(const dif_clkmgr_t *clkmgr);
378 
379 /**
380  * Enable chip to use the external clock.
381  *
382  * @param clkmgr Clock Manager Handle.
383  * @param is_low_speed External clock is low speed or high speed.
384  * @returns The result of the operation.
385  * High speed - external clock is close to nominal speeds (e.g. external clock
386  * is 96MHz and nominal frequency is 96MHz-100MHz). Low speed - external clock
387  * is half of nominal speeds (e.g. external clock is 48MHz and nominal frequency
388  * is 96MHz-100MHz).
389  *
390  */
392 dif_result_t dif_clkmgr_external_clock_set_enabled(const dif_clkmgr_t *clkmgr,
393  bool is_low_speed);
394 
395 /**
396  * Disable chip to use the external clock.
397  *
398  * @param clkmgr Clock Manager Handle.
399  * @returns The result of the operation.
400  */
402 dif_result_t dif_clkmgr_external_clock_set_disabled(const dif_clkmgr_t *clkmgr);
403 
404 /**
405  * Determine if the transition to using external clock is complete.
406  *
407  * @param clkmgr Clock Manager Handle.
408  * @param[out] status Set to true if the transition is complete.
409  * @returns The result of the operation once it completes.
410  */
412 dif_result_t dif_clkmgr_external_clock_is_settled(const dif_clkmgr_t *clkmgr,
413  bool *status);
414 
415 /**
416  * Disable measurement control updates.
417  *
418  * This can only be disabled, and stays disabled until the next POR.
419  *
420  * @param clkmgr Clock Manager Handle.
421  * @returns The result of the operation.
422  */
424 dif_result_t dif_clkmgr_measure_ctrl_disable(const dif_clkmgr_t *clkmgr);
425 
426 /**
427  * Get measurement control state.
428  *
429  * @param clkmgr Clock Manager Handle.
430  * @param[out] state The state of control enable.
431  * @returns The result of the operation.
432  */
434 dif_result_t dif_clkmgr_measure_ctrl_get_enable(const dif_clkmgr_t *clkmgr,
435  dif_toggle_t *state);
436 
437 /**
438  * Configure count measurements.
439  *
440  * @param clkmgr Clock Manager Handle.
441  * @param clock A clock to be measured.
442  * @param min_threshold The smallest permissible cycle count.
443  * @param max_threshold The largest permissible cycle count.
444  * @returns The result of the operation.
445  */
447 dif_result_t dif_clkmgr_enable_measure_counts(const dif_clkmgr_t *clkmgr,
448  dif_clkmgr_measure_clock_t clock,
449  uint32_t min_threshold,
450  uint32_t max_threshold);
451 
452 /**
453  * Disable count measurements.
454  *
455  * Does not modify the thresholds.
456  *
457  * @param clkmgr Clock Manager Handle.
458  * @param clock A clock to be measured.
459  * @returns The result of the operation.
460  */
463  const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock);
464 
465 /**
466  * Get the count measurement enable.
467  *
468  * @param clkmgr Clock Manager Handle.
469  * @param clock A clock to be measured.
470  * @param[out] state The state of control enable.
471  * @returns The result of the operation.
472  */
475  const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
476  dif_toggle_t *state);
477 
478 /**
479  * Get the count measurement thresholds.
480  *
481  * @param clkmgr Clock Manager Handle.
482  * @param clock A clock to be measured.
483  * @param[out] min_threshold The minumum threshold.
484  * @param[out] max_threshold The maximum threshold.
485  * @returns The result of the operation.
486  */
489  const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
490  uint32_t *min_threshold, uint32_t *max_threshold);
491 
492 /**
493  * Read the recoverable error codes.
494  *
495  * @param clkmgr Clock Manager Handle.
496  * @param[out] codes The recoverable error codes.
497  * @returns The result of the operation.
498  */
501  const dif_clkmgr_t *clkmgr, dif_clkmgr_recov_err_codes_t *codes);
502 
503 /**
504  * Clear selected recoverable error codes.
505  *
506  * @param clkmgr Clock Manager Handle.
507  * @param codes The recoverable error codes to be cleared.
508  * @returns The result of the operation.
509  */
512  const dif_clkmgr_t *clkmgr, dif_clkmgr_recov_err_codes_t codes);
513 
514 /**
515  * Read the fatal error codes.
516  *
517  * @param clkmgr Clock Manager Handle.
518  * @param[out] codes The fatal error codes.
519  * @returns The result of the operation.
520  */
523  const dif_clkmgr_t *clkmgr, dif_clkmgr_fatal_err_codes_t *codes);
524 
525 /**
526  * Wait for external clock switch to finish.
527  *
528  * @param clkmgr Clock Manager Handle.
529  * @returns The result of the operation.
530  */
532 dif_result_t dif_clkmgr_wait_for_ext_clk_switch(const dif_clkmgr_t *clkmgr);
533 #ifdef __cplusplus
534 } // extern "C"
535 #endif // __cplusplus
536 
537 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_CLKMGR_H_