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
43typedef uint32_t dif_clkmgr_measure_clock_t;
44
45typedef enum dif_clkmgr_recov_err_type {
46#if defined(OPENTITAN_IS_EARLGREY)
47 /**
48 * A recoverable update error for one of the clocks.
49 */
50 kDifClkmgrRecovErrTypeShadowUpdate = 1u << 0,
51 /**
52 * A recoverable measurement error for IO clock.
53 */
54 kDifClkmgrRecovErrTypeIoMeas = 1u << 1,
55 /**
56 * A recoverable measurement error for IO_DIV4 clock.
57 */
58 kDifClkmgrRecovErrTypeIoDiv4Meas = 1u << 2,
59 /**
60 * A recoverable measurement error for MAIN clock.
61 */
62 kDifClkmgrRecovErrTypeMainMeas = 1u << 3,
63 /**
64 * A recoverable measurement error for USB clock.
65 */
66 kDifClkmgrRecovErrTypeUsbMeas = 1u << 4,
67 /**
68 * A recoverable timeout error for IO clock.
69 */
70 kDifClkmgrRecovErrTypeIoTimeout = 1u << 5,
71 /**
72 * A recoverable timeout error for IO_DIV4 clock.
73 */
74 kDifClkmgrRecovErrTypeIoDiv4Timeout = 1u << 6,
75 /**
76 * A recoverable timeout error for MAIN clock.
77 */
78 kDifClkmgrRecovErrTypeMainTimeout = 1u << 7,
79 /**
80 * A recoverable timeout error for USB clock.
81 */
82 kDifClkmgrRecovErrTypeUsbTimeout = 1u << 8,
83#elif defined(OPENTITAN_IS_DARJEELING)
84 /**
85 * A recoverable update error for one of the clocks.
86 */
87 kDifClkmgrRecovErrTypeShadowUpdate = 1u << 0,
88 /**
89 * A recoverable measurement error for IO clock.
90 */
91 kDifClkmgrRecovErrTypeIoMeas = 1u << 1,
92 /**
93 * A recoverable measurement error for MAIN clock.
94 */
95 kDifClkmgrRecovErrTypeMainMeas = 1u << 2,
96 /**
97 * A recoverable timeout error for IO clock.
98 */
99 kDifClkmgrRecovErrTypeIoTimeout = 1u << 3,
100 /**
101 * A recoverable timeout error for MAIN clock.
102 */
103 kDifClkmgrRecovErrTypeMainTimeout = 1u << 4,
104#else
105#error "dif_clkmgr does not support this top"
106#endif
107} dif_clkmgr_recov_err_type_t;
108
109/**
110 * A set of recoverable errors.
111 *
112 * This type is used to clear and read the recoverable error codes.
113 */
115
117 /**
118 * A fatal error for regfile integrity.
119 */
121 /**
122 * A fatal error for a duplicate idle counter.
123 */
125 /**
126 * A fatal error for a shadow register storage.
127 */
129} dif_clkmgr_fatal_err_type_t;
130
131/**
132 * A set of fatal errors.
133 *
134 * This type is used to read the fatal error codes.
135 */
137
138/**
139 * Check if jitter enable is locked.
140 * @param clkmgr Clock Manager Handle.
141 * @param[out] is_locked whether jitter is locked or not.
142 * @returns The result of the operation.
143 */
146 bool *is_locked);
147
148/**
149 * Lock jitter enable.
150 * @param clkmgr Clock Manager Handle.
151 * @returns The result of the operation.
152 */
155
156/**
157 * Check if jitter is Enabled.
158 * @param clkmgr Clock Manager Handle.
159 * @param[out] is_enabled whether jitter is enabled or not.
160 * @returns The result of the operation.
161 */
164 dif_toggle_t *state);
165
166/**
167 * Enable of Disable jitter.
168 * @param clkmgr Clock Manager Handle.
169 * @param new_state whether to enable or disable jitter.
170 * @returns The result of the operation.
171 */
174 dif_toggle_t new_state);
175
176/**
177 * Obtain the index of a gateable clock for a device.
178 *
179 * Given a module instance (identified by its instance ID), return the
180 * index of the gateable clock which controls this device and can be used
181 * with the clkmgr DIF.
182 *
183 * Example (find gateable clock of UART0):
184 * ```c
185 * dif_clkmgr_gateable_clock_t clock;
186 * CHECK_DIF_OK(dif_clkmgr_find_gateable_clock(
187 * clkmgr, kDtInstanceIdUart0, &clock));
188 * ```
189 *
190 * @param clkmgr A clock manager handle.
191 * @param inst_id An instance ID.
192 * @param[out] clock The index of the clock.
193 * @return `kDifError` if no gateable clock matches the description,
194 * `kDifOk` otherwise.
195 */
198 dt_instance_id_t inst_id,
200
201/**
202 * Check if a Gateable Clock is Enabled or Disabled.
203 *
204 * @param clkmgr Clock Manager Handle.
205 * @param clock Gateable Clock ID.
206 * @param[out] is_enabled whether the clock is enabled or not.
207 * @returns The result of the operation.
208 */
211 const dif_clkmgr_t *clkmgr, dif_clkmgr_gateable_clock_t clock,
212 dif_toggle_t *state);
213
214/**
215 * Enable or Disable a Gateable Clock.
216 *
217 * @param clkmgr Clock Manager Handle.
218 * @param clock Gateable Clock ID.
219 * @param new_state whether to enable or disable the clock.
220 * @returns The result of the operation.
221 */
224 const dif_clkmgr_t *clkmgr, dif_clkmgr_gateable_clock_t clock,
225 dif_toggle_t new_state);
226
227/**
228 * Obtain the index of a hintable clock for a device.
229 *
230 * Given a module instance (identified by its instance ID), return the
231 * index of the hintable clock which controls this device and can be used
232 * with the clkmgr DIF.
233 *
234 * Example (find hintable clock of KMAC):
235 * ```c
236 * dif_clkmgr_hintable_clock_t clock;
237 * CHECK_DIF_OK(dif_clkmgr_find_hintable_clock(
238 * clkmgr, kDtInstanceIdKmac, &clock));
239 * ```
240 *
241 * @param clkmgr A clock manager handle.
242 * @param inst_id An instance ID.
243 * @param[out] clock The index of the clock.
244 * @return `kDifError` if no hintable clock matches the description,
245 * `kDifOk` otherwise.
246 */
249 dt_instance_id_t inst_id,
251
252/**
253 * Check if a Hintable Clock is Enabled or Disabled.
254 *
255 * Hintable clocks are not under full software control, but this operation
256 * accurately reflects the state of the current clock, regardless of any hint
257 * requests made by software.
258 *
259 * To read what hint the software has given the hardware, use
260 * #dif_clkmgr_hintable_clock_get_hint.
261 *
262 * @param clkmgr Clock Manager Handle.
263 * @param clock Hintable Clock ID.
264 * @param[out] is_enabled whether the clock is enabled or not.
265 * @returns The result of the operation.
266 */
269 const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock,
270 dif_toggle_t *state);
271
272/**
273 * Enable or Disable a Hintable Clock.
274 *
275 * This only sets a hint that the clock should be enabled or disabled. The clock
276 * manager is in control of whether the clock should actually be enabled or
277 * disabled.
278 *
279 * To read what hint the software has given the hardware, use
280 * #dif_clkmgr_hintable_clock_get_hint. To read whether the clock is currently
281 * enabled or disabled, use #dif_clkmgr_hintable_clock_get_enabled.
282 *
283 * @param clkmgr Clock Manager Handle.
284 * @param clock Hintable Clock ID.
285 * @param new_state whether to enable or disable the clock.
286 * @returns The result of the operation.
287 */
290 const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock,
291 dif_toggle_t new_state);
292
293/**
294 * Read the current Hint for a Hintable Clock.
295 *
296 * Hintable clocks are not under full software control; this operation
297 * accurately reflects the current software hint, not the current state of the
298 * clock.
299 *
300 * To read whether the clock is currently enabled or disabled, use
301 * #dif_clkmgr_hintable_clock_get_enabled.
302 *
303 * @param clkmgr Clock Manager Handle.
304 * @param clock Hintable Clock ID.
305 * @param[out] hinted_is_enabled the current software request (hint) for this
306 * clock.
307 * @returns The result of the operation.
308 */
311 const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock,
312 dif_toggle_t *state);
313
314#if defined(OPENTITAN_IS_EARLGREY)
315/**
316 * Check if external clock control is locked.
317 * @param clkmgr Clock Manager Handle.
318 * @param[out] is_locked whether external clock control is locked or not.
319 * @returns The result of the operation.
320 */
322dif_result_t dif_clkmgr_external_clock_control_is_locked(
323 const dif_clkmgr_t *clkmgr, bool *is_locked);
324
325/**
326 * Lock external clock control.
327 * @param clkmgr Clock Manager Handle.
328 * @returns The result of the operation.
329 */
331dif_result_t dif_clkmgr_lock_external_clock_control(const dif_clkmgr_t *clkmgr);
332
333/**
334 * Enable chip to use the external clock.
335 *
336 * @param clkmgr Clock Manager Handle.
337 * @param is_low_speed External clock is low speed or high speed.
338 * @returns The result of the operation.
339 * High speed - external clock is close to nominal speeds (e.g. external clock
340 * is 96MHz and nominal frequency is 96MHz-100MHz). Low speed - external clock
341 * is half of nominal speeds (e.g. external clock is 48MHz and nominal frequency
342 * is 96MHz-100MHz).
343 *
344 */
346dif_result_t dif_clkmgr_external_clock_set_enabled(const dif_clkmgr_t *clkmgr,
347 bool is_low_speed);
348
349/**
350 * Disable chip to use the external clock.
351 *
352 * @param clkmgr Clock Manager Handle.
353 * @returns The result of the operation.
354 */
356dif_result_t dif_clkmgr_external_clock_set_disabled(const dif_clkmgr_t *clkmgr);
357
358/**
359 * Determine if the transition to using external clock is complete.
360 *
361 * @param clkmgr Clock Manager Handle.
362 * @param[out] status Set to true if the transition is complete.
363 * @returns The result of the operation once it completes.
364 */
366dif_result_t dif_clkmgr_external_clock_is_settled(const dif_clkmgr_t *clkmgr,
367 bool *status);
368#endif
369
370/**
371 * Disable measurement control updates.
372 *
373 * This can only be disabled, and stays disabled until the next POR.
374 *
375 * @param clkmgr Clock Manager Handle.
376 * @returns The result of the operation.
377 */
380
381/**
382 * Get measurement control state.
383 *
384 * @param clkmgr Clock Manager Handle.
385 * @param[out] state The state of control enable.
386 * @returns The result of the operation.
387 */
390 dif_toggle_t *state);
391
392/**
393 * Obtain the index of a measureable clock for a DT clock.
394 *
395 * Given a clock (identified by its DT index), return the index of the
396 * measurable clock which controls this clock and can be used with the clkmgr
397 * DIF.
398 *
399 * Example (find main measurable clock):
400 * ```c
401 * dif_clkmgr_measure_clock_t clock;
402 * CHECK_DIF_OK(dif_clkmgr_find_measure_clock(
403 * clkmgr, kDtClockMain, &clock));
404 * ```
405 *
406 * @param clkmgr A clock manager handle.
407 * @param dt_clk A DT clock.
408 * @param[out] clock The index of the clock.
409 * @return `kDifError` if this clock is not measurable,
410 * `kDifOk` otherwise.
411 */
414 dt_clock_t dt_clk,
415 dif_clkmgr_measure_clock_t *clock);
416
417/**
418 * Configure count measurements.
419 *
420 * @param clkmgr Clock Manager Handle.
421 * @param clock A clock to be measured.
422 * @param min_threshold The smallest permissible cycle count.
423 * @param max_threshold The largest permissible cycle count.
424 * @returns The result of the operation.
425 */
428 dif_clkmgr_measure_clock_t clock,
429 uint32_t min_threshold,
430 uint32_t max_threshold);
431
432/**
433 * Disable count measurements.
434 *
435 * Does not modify the thresholds.
436 *
437 * @param clkmgr Clock Manager Handle.
438 * @param clock A clock to be measured.
439 * @returns The result of the operation.
440 */
443 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock);
444
445/**
446 * Get the count measurement enable.
447 *
448 * @param clkmgr Clock Manager Handle.
449 * @param clock A clock to be measured.
450 * @param[out] state The state of control enable.
451 * @returns The result of the operation.
452 */
455 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
456 dif_toggle_t *state);
457
458/**
459 * Get the count measurement thresholds.
460 *
461 * @param clkmgr Clock Manager Handle.
462 * @param clock A clock to be measured.
463 * @param[out] min_threshold The minumum threshold.
464 * @param[out] max_threshold The maximum threshold.
465 * @returns The result of the operation.
466 */
469 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
470 uint32_t *min_threshold, uint32_t *max_threshold);
471
472/**
473 * Read the recoverable error codes.
474 *
475 * @param clkmgr Clock Manager Handle.
476 * @param[out] codes The recoverable error codes.
477 * @returns The result of the operation.
478 */
481 const dif_clkmgr_t *clkmgr, dif_clkmgr_recov_err_codes_t *codes);
482
483/**
484 * Clear selected recoverable error codes.
485 *
486 * @param clkmgr Clock Manager Handle.
487 * @param codes The recoverable error codes to be cleared.
488 * @returns The result of the operation.
489 */
492 const dif_clkmgr_t *clkmgr, dif_clkmgr_recov_err_codes_t codes);
493
494/**
495 * Read the fatal error codes.
496 *
497 * @param clkmgr Clock Manager Handle.
498 * @param[out] codes The fatal error codes.
499 * @returns The result of the operation.
500 */
503 const dif_clkmgr_t *clkmgr, dif_clkmgr_fatal_err_codes_t *codes);
504
505#if defined(OPENTITAN_IS_EARLGREY)
506/**
507 * Wait for external clock switch to finish.
508 *
509 * @param clkmgr Clock Manager Handle.
510 * @returns The result of the operation.
511 */
513dif_result_t dif_clkmgr_wait_for_ext_clk_switch(const dif_clkmgr_t *clkmgr);
514
515#endif
516
517#ifdef __cplusplus
518} // extern "C"
519#endif // __cplusplus
520
521#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_CLKMGR_H_