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