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
23extern "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 */
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 */
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
76typedef 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 */
193 bool *is_locked);
194
195/**
196 * Lock jitter enable.
197 * @param clkmgr Clock Manager Handle.
198 * @returns The result of the operation.
199 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
533#ifdef __cplusplus
534} // extern "C"
535#endif // __cplusplus
536
537#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_CLKMGR_H_