blob: 35dd4f62d8984da51bdbbfb8447a51241eeb052d [file] [log] [blame]
Sam Elliott91df54a2020-10-27 13:12:21 +00001// 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_CLKMGR_H_
6#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_CLKMGR_H_
7
8/**
9 * @file
10 * @brief <a href="/hw/ip/clkmgr/doc/">Clock manager</a> Device Interface
11 * Functions
12 */
13
14#include <stdint.h>
15
16#include "sw/device/lib/base/mmio.h"
17#include "sw/device/lib/dif/dif_warn_unused_result.h"
18
19#ifdef __cplusplus
20extern "C" {
21#endif // __cplusplus
22
23/**
Sam Elliott79d5a792020-11-16 12:22:17 +000024 * An Index of a "Gateable" Clock.
25 *
26 * "Gateable" clocks are under full software control: they can be enabled and
27 * disabled by software, which directly starts and stops the identified clock.
28 */
29typedef uint32_t dif_clkmgr_gateable_clock_t;
30
31/**
32 * An Index of a "Hintable" Clock.
33 *
34 * "Hintable" clocks are under partial software control: software can suggest
35 * they are stopped, but the clock manager may delay stopping the peripheral, or
36 * may ignore the request altogether.
37 */
38typedef uint32_t dif_clkmgr_hintable_clock_t;
39
40/**
Sam Elliott91df54a2020-10-27 13:12:21 +000041 * A toggle state: enabled, or disabled.
42 *
43 * This enum may be used instead of a `bool` when describing an enabled/disabled
44 * state.
45 */
46typedef enum dif_clkmgr_toggle {
47 /*
48 * The "enabled" state.
49 */
50 kDifClkmgrToggleEnabled,
51 /**
52 * The "disabled" state.
53 */
54 kDifClkmgrToggleDisabled,
55} dif_clkmgr_toggle_t;
56
57/**
58 * Hardware instantiation parameters for a clock manager.
59 *
60 * This struct describes information about the underlying hardware instance that
61 * is not determined until the hardware design is used as part of a top-level
62 * design.
63 */
64typedef struct dif_clkmgr_params {
65 /**
66 * The base address for the clock manager hardware registers.
67 */
68 mmio_region_t base_addr;
Sam Elliott79d5a792020-11-16 12:22:17 +000069 /**
70 * The last index of gateable clocks being managed by this clock manager.
71 */
72 dif_clkmgr_gateable_clock_t last_gateable_clock;
73 /**
74 * The last index of of hintable clocks being managed by this clock manager.
75 */
76 dif_clkmgr_hintable_clock_t last_hintable_clock;
Sam Elliott91df54a2020-10-27 13:12:21 +000077} dif_clkmgr_params_t;
78
79/**
80 * A handle to a clock manager.
81 *
82 * This type should be treated as opaque by users.
83 */
84typedef struct dif_clkmgr {
85 dif_clkmgr_params_t params;
86} dif_clkmgr_t;
87
88/**
89 * The result of a clock manager operation.
90 */
91typedef enum dif_clkmgr_result {
92 /**
93 * Indicates that the operation succeeded.
94 */
95 kDifClkmgrOk = 0,
96 /**
97 * Indicates some unspecified failure.
98 */
99 kDifClkmgrError = 1,
100 /**
101 * Indicates that some parameter passed into a function failed a
102 * precondition.
103 *
Michael Mundayd55bc6c2021-02-26 12:24:44 +0000104 * When this value is returned, no hardware operations occurred.
Sam Elliott91df54a2020-10-27 13:12:21 +0000105 */
106 kDifClkmgrBadArg = 2,
107} dif_clkmgr_result_t;
108
109/**
Sam Elliott91df54a2020-10-27 13:12:21 +0000110 * Creates a new handle for a clock manager.
111 *
112 * This function does not actuate the hardware.
113 *
114 * @param params Hardware instance parameters.
115 * @param[out] handle Out param for the initialized handle.
116 * @return The result of the operation.
117 */
118DIF_WARN_UNUSED_RESULT
119dif_clkmgr_result_t dif_clkmgr_init(dif_clkmgr_params_t params,
120 dif_clkmgr_t *handle);
121
122/**
123 * Check if a Gateable Clock is Enabled or Disabled.
124 *
125 * @param handle Clock Manager Handle.
126 * @param clock Gateable Clock ID.
127 * @param[out] is_enabled whether the clock is enabled or not.
128 * @returns The result of the operation.
129 */
130DIF_WARN_UNUSED_RESULT
131dif_clkmgr_result_t dif_clkmgr_gateable_clock_get_enabled(
132 const dif_clkmgr_t *handle, dif_clkmgr_gateable_clock_t clock,
133 bool *is_enabled);
134
135/**
136 * Enable or Disable a Gateable Clock.
137 *
138 * @param handle Clock Manager Handle.
139 * @param clock Gateable Clock ID.
140 * @param new_state whether to enable or disable the clock.
141 * @returns The result of the operation.
142 */
143DIF_WARN_UNUSED_RESULT
144dif_clkmgr_result_t dif_clkmgr_gateable_clock_set_enabled(
145 const dif_clkmgr_t *handle, dif_clkmgr_gateable_clock_t clock,
146 dif_clkmgr_toggle_t new_state);
147
148/**
149 * Check if a Hintable Clock is Enabled or Disabled.
150 *
151 * Hintable clocks are not under full software control, but this operation
152 * accurately reflects the state of the current clock, regardless of any hint
153 * requests made by software.
154 *
155 * To read what hint the software has given the hardware, use
156 * #dif_clkmgr_hintable_clock_get_hint.
157 *
158 * @param handle Clock Manager Handle.
159 * @param clock Hintable Clock ID.
160 * @param[out] is_enabled whether the clock is enabled or not.
161 * @returns The result of the operation.
162 */
163DIF_WARN_UNUSED_RESULT
164dif_clkmgr_result_t dif_clkmgr_hintable_clock_get_enabled(
165 const dif_clkmgr_t *handle, dif_clkmgr_hintable_clock_t clock,
166 bool *is_enabled);
167
168/**
169 * Enable or Disable a Hintable Clock.
170 *
171 * This only sets a hint that the clock should be enabled or disabled. The clock
172 * manager is in control of whether the clock should actually be enabled or
173 * disabled.
174 *
175 * To read what hint the software has given the hardware, use
176 * #dif_clkmgr_hintable_clock_get_hint. To read whether the clock is currently
177 * enabled or disabled, use #dif_clkmgr_hintable_clock_get_enabled.
178 *
179 * @param handle Clock Manager Handle.
180 * @param clock Hintable Clock ID.
181 * @param new_state whether to enable or disable the clock.
182 * @returns The result of the operation.
183 */
184DIF_WARN_UNUSED_RESULT
185dif_clkmgr_result_t dif_clkmgr_hintable_clock_set_hint(
186 const dif_clkmgr_t *handle, dif_clkmgr_hintable_clock_t clock,
187 dif_clkmgr_toggle_t new_state);
188
189/**
190 * Read the current Hint for a Hintable Clock.
191 *
192 * Hintable clocks are not under full software control; this operation
193 * accurately reflects the current software hint, not the current state of the
194 * clock.
195 *
196 * To read whether the clock is currently enabled or disabled, use
197 * #dif_clkmgr_hintable_clock_get_enabled.
198 *
199 * @param handle Clock Manager Handle.
200 * @param clock Hintable Clock ID.
Tobias Wölfel01ec7cf2021-02-12 11:57:12 +0100201 * @param[out] hinted_is_enabled the current software request (hint) for this
202 * clock.
Sam Elliott91df54a2020-10-27 13:12:21 +0000203 * @returns The result of the operation.
204 */
205DIF_WARN_UNUSED_RESULT
206dif_clkmgr_result_t dif_clkmgr_hintable_clock_get_hint(
207 const dif_clkmgr_t *handle, dif_clkmgr_hintable_clock_t clock,
208 bool *hinted_is_enabled);
209
210#ifdef __cplusplus
211} // extern "C"
212#endif // __cplusplus
213
214#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_CLKMGR_H_