12#include "sw/device/lib/base/multibits.h"
15#include "hw/top/clkmgr_regs.h"
21 CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS <= CLKMGR_PARAM_REG_WIDTH,
22 "Expected the number of gateable clocks to be <= the width of a CSR.");
28 CLKMGR_PARAM_NUM_HINTABLE_CLOCKS <= CLKMGR_PARAM_REG_WIDTH,
29 "Expected the number of hintable clocks to be <= the width of a CSR.");
32 return clock < CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS;
36 return clock < CLKMGR_PARAM_NUM_HINTABLE_CLOCKS;
39static bool clkmgr_measure_ctrl_regwen(
const dif_clkmgr_t *clkmgr) {
40 uint32_t measure_ctrl_regwen_val = mmio_region_read32(
41 clkmgr->
base_addr, CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET);
42 return bitfield_bit32_read(measure_ctrl_regwen_val,
43 CLKMGR_MEASURE_CTRL_REGWEN_EN_BIT);
52static bool jitter_enable_register_is_locked(
const dif_clkmgr_t *clkmgr) {
55 return !bitfield_bit32_read(
56 mmio_region_read32(clkmgr->
base_addr, CLKMGR_JITTER_REGWEN_REG_OFFSET),
57 CLKMGR_JITTER_REGWEN_EN_BIT);
60#if OPENTITAN_CLKMGR_HAS_SW_EXTCLK_REGWEN
67static bool extclk_control_register_is_locked(
const dif_clkmgr_t *clkmgr) {
70 return !bitfield_bit32_read(
72 CLKMGR_EXTCLK_CTRL_REGWEN_REG_OFFSET),
73 CLKMGR_EXTCLK_CTRL_REGWEN_EN_BIT);
78 if (clkmgr == NULL ||
status == NULL) {
81 uint32_t extclk_status_val =
82 mmio_region_read32(clkmgr->
base_addr, CLKMGR_EXTCLK_STATUS_REG_OFFSET);
83 *
status = bitfield_field32_read(extclk_status_val,
84 CLKMGR_EXTCLK_STATUS_ACK_FIELD) ==
93 if (clkmgr == NULL || is_locked == NULL) {
97 *is_locked = jitter_enable_register_is_locked(clkmgr);
103 if (clkmgr == NULL) {
106 mmio_region_write32(clkmgr->
base_addr, CLKMGR_JITTER_REGWEN_REG_OFFSET, 0);
112 if (clkmgr == NULL || state == NULL) {
116 multi_bit_bool_t clk_jitter_val =
117 mmio_region_read32(clkmgr->
base_addr, CLKMGR_JITTER_ENABLE_REG_OFFSET);
128 multi_bit_bool_t new_jitter_enable_val;
129 if (clkmgr == NULL) {
132 if (jitter_enable_register_is_locked(clkmgr)) {
138 new_jitter_enable_val = kMultiBitBool4True;
141 new_jitter_enable_val = kMultiBitBool4False;
146 mmio_region_write32(clkmgr->
base_addr, CLKMGR_JITTER_ENABLE_REG_OFFSET,
147 new_jitter_enable_val);
155 if (clkmgr == NULL || clock == NULL) {
173 if (clkmgr == NULL || state == NULL || !clkmgr_valid_gateable_clock(clock)) {
177#if CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS == 0
182 uint32_t clk_enables_val =
183 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET);
184 *state = dif_bool_to_toggle(bitfield_bit32_read(clk_enables_val, clock));
193 if (clkmgr == NULL || !clkmgr_valid_gateable_clock(clock) ||
194 !dif_is_valid_toggle(new_state)) {
198#if CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS == 0
203 bool new_clk_enables_bit = dif_toggle_to_bool(new_state);
204 uint32_t clk_enables_val =
205 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET);
207 bitfield_bit32_write(clk_enables_val, clock, new_clk_enables_bit);
208 mmio_region_write32(clkmgr->
base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET,
219 if (clkmgr == NULL || clock == NULL) {
237 if (clkmgr == NULL || state == NULL || !clkmgr_valid_hintable_clock(clock)) {
241#if CLKMGR_PARAM_NUM_HINTABLE_CLOCKS == 0
246 uint32_t clk_hints_val =
247 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_STATUS_REG_OFFSET);
248 *state = dif_bool_to_toggle(bitfield_bit32_read(clk_hints_val, clock));
257 if (clkmgr == NULL || !clkmgr_valid_hintable_clock(clock) ||
258 !dif_is_valid_toggle(new_state)) {
262#if CLKMGR_PARAM_NUM_HINTABLE_CLOCKS == 0
267 bool new_clk_hints_bit = dif_toggle_to_bool(new_state);
268 uint32_t clk_hints_val =
269 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_REG_OFFSET);
270 clk_hints_val = bitfield_bit32_write(clk_hints_val, clock, new_clk_hints_bit);
271 mmio_region_write32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_REG_OFFSET,
281 if (clkmgr == NULL || state == NULL || !clkmgr_valid_hintable_clock(clock)) {
285#if CLKMGR_PARAM_NUM_HINTABLE_CLOCKS == 0
290 uint32_t clk_hints_val =
291 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_REG_OFFSET);
292 *state = dif_bool_to_toggle(bitfield_bit32_read(clk_hints_val, clock));
298#if OPENTITAN_CLKMGR_HAS_SW_EXTCLK_REGWEN
299dif_result_t dif_clkmgr_external_clock_control_is_locked(
301 if (clkmgr == NULL || is_locked == NULL) {
305 *is_locked = extclk_control_register_is_locked(clkmgr);
312 if (clkmgr == NULL) {
315 mmio_region_write32(clkmgr->
base_addr, CLKMGR_EXTCLK_CTRL_REGWEN_REG_OFFSET,
322 uint32_t extclk_ctrl_reg = 0;
324 if (clkmgr == NULL) {
328 if (extclk_control_register_is_locked(clkmgr)) {
332 extclk_ctrl_reg = bitfield_field32_write(
333 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_SEL_FIELD, kMultiBitBool4True);
334 extclk_ctrl_reg = bitfield_field32_write(
335 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_HI_SPEED_SEL_FIELD,
336 is_low_speed ? kMultiBitBool4False : kMultiBitBool4True);
337 mmio_region_write32(clkmgr->
base_addr, CLKMGR_EXTCLK_CTRL_REG_OFFSET,
344 uint32_t extclk_ctrl_reg = 0;
346 if (clkmgr == NULL) {
350 if (extclk_control_register_is_locked(clkmgr)) {
354 extclk_ctrl_reg = bitfield_field32_write(
355 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_SEL_FIELD, kMultiBitBool4False);
357 extclk_ctrl_reg = bitfield_field32_write(
358 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_HI_SPEED_SEL_FIELD,
360 mmio_region_write32(clkmgr->
base_addr, CLKMGR_EXTCLK_CTRL_REG_OFFSET,
367 if (clkmgr == NULL) {
370 mmio_region_write32(clkmgr->
base_addr, CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET,
377 if (clkmgr == NULL || state == NULL) {
380 *state = dif_bool_to_toggle(clkmgr_measure_ctrl_regwen(clkmgr));
386 dif_clkmgr_measure_clock_t *clock) {
387 if (clkmgr == NULL || clock == NULL) {
403 dif_clkmgr_measure_clock_t clock,
404 uint32_t lo_threshold,
405 uint32_t hi_threshold) {
406 if (clkmgr == NULL) {
409 if (!clkmgr_measure_ctrl_regwen(clkmgr)) {
420 uint32_t measure_ctrl_reg = 0;
421 measure_ctrl_reg = bitfield_field32_write(
423 measure_ctrl_reg = bitfield_field32_write(
431 uint32_t measure_en_reg =
440 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock) {
441 if (clkmgr == NULL) {
444 if (!clkmgr_measure_ctrl_regwen(clkmgr)) {
455 uint32_t measure_en_reg = bitfield_field32_write(
463 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
465 if (clkmgr == NULL || state == NULL) {
478 *state = dif_multi_bit_bool_to_toggle(
485 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
486 uint32_t *min_threshold, uint32_t *max_threshold) {
487 if (clkmgr == NULL || min_threshold == NULL || max_threshold == NULL) {
498 uint32_t thresholds_val = mmio_region_read32(
510 if (clkmgr == NULL || codes == NULL) {
514 mmio_region_read32(clkmgr->
base_addr, CLKMGR_RECOV_ERR_CODE_REG_OFFSET);
520 if (clkmgr == NULL) {
523 mmio_region_write32(clkmgr->
base_addr, CLKMGR_RECOV_ERR_CODE_REG_OFFSET,
530 if (clkmgr == NULL || codes == NULL) {
534 mmio_region_read32(clkmgr->
base_addr, CLKMGR_FATAL_ERR_CODE_REG_OFFSET);
538#if OPENTITAN_CLKMGR_HAS_SW_EXTCLK_REGWEN
540 if (clkmgr == NULL) {
546 mmio_region_read32(clkmgr->
base_addr, CLKMGR_EXTCLK_STATUS_REG_OFFSET);
547 }
while (ext_status != kMultiBitBool4True);