11#include "sw/device/lib/base/multibits.h"
14#include "hw/top/clkmgr_regs.h"
20 CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS <= CLKMGR_PARAM_REG_WIDTH,
21 "Expected the number of gateable clocks to be <= the width of a CSR.");
27 CLKMGR_PARAM_NUM_HINTABLE_CLOCKS <= CLKMGR_PARAM_REG_WIDTH,
28 "Expected the number of hintable clocks to be <= the width of a CSR.");
31 return clock < CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS;
35 return clock < CLKMGR_PARAM_NUM_HINTABLE_CLOCKS;
38static bool clkmgr_measure_ctrl_regwen(
const dif_clkmgr_t *clkmgr) {
39 uint32_t measure_ctrl_regwen_val = mmio_region_read32(
40 clkmgr->
base_addr, CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET);
41 return bitfield_bit32_read(measure_ctrl_regwen_val,
42 CLKMGR_MEASURE_CTRL_REGWEN_EN_BIT);
51static bool jitter_enable_register_is_locked(
const dif_clkmgr_t *clkmgr) {
54 return !bitfield_bit32_read(
55 mmio_region_read32(clkmgr->
base_addr, CLKMGR_JITTER_REGWEN_REG_OFFSET),
56 CLKMGR_JITTER_REGWEN_EN_BIT);
59#if OPENTITAN_CLKMGR_HAS_SW_EXTCLK_REGWEN
66static bool extclk_control_register_is_locked(
const dif_clkmgr_t *clkmgr) {
69 return !bitfield_bit32_read(
71 CLKMGR_EXTCLK_CTRL_REGWEN_REG_OFFSET),
72 CLKMGR_EXTCLK_CTRL_REGWEN_EN_BIT);
77 if (clkmgr == NULL ||
status == NULL) {
80 uint32_t extclk_status_val =
81 mmio_region_read32(clkmgr->
base_addr, CLKMGR_EXTCLK_STATUS_REG_OFFSET);
82 *
status = bitfield_field32_read(extclk_status_val,
83 CLKMGR_EXTCLK_STATUS_ACK_FIELD) ==
92 if (clkmgr == NULL || is_locked == NULL) {
96 *is_locked = jitter_enable_register_is_locked(clkmgr);
102 if (clkmgr == NULL) {
105 mmio_region_write32(clkmgr->
base_addr, CLKMGR_JITTER_REGWEN_REG_OFFSET, 0);
111 if (clkmgr == NULL || state == NULL) {
115 multi_bit_bool_t clk_jitter_val =
116 mmio_region_read32(clkmgr->
base_addr, CLKMGR_JITTER_ENABLE_REG_OFFSET);
127 multi_bit_bool_t new_jitter_enable_val;
128 if (clkmgr == NULL) {
131 if (jitter_enable_register_is_locked(clkmgr)) {
137 new_jitter_enable_val = kMultiBitBool4True;
140 new_jitter_enable_val = kMultiBitBool4False;
145 mmio_region_write32(clkmgr->
base_addr, CLKMGR_JITTER_ENABLE_REG_OFFSET,
146 new_jitter_enable_val);
154 if (clkmgr == NULL || clock == NULL) {
172 if (clkmgr == NULL || state == NULL || !clkmgr_valid_gateable_clock(clock)) {
176 uint32_t clk_enables_val =
177 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET);
178 *state = dif_bool_to_toggle(bitfield_bit32_read(clk_enables_val, clock));
186 if (clkmgr == NULL || !clkmgr_valid_gateable_clock(clock) ||
187 !dif_is_valid_toggle(new_state)) {
191 bool new_clk_enables_bit = dif_toggle_to_bool(new_state);
192 uint32_t clk_enables_val =
193 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET);
195 bitfield_bit32_write(clk_enables_val, clock, new_clk_enables_bit);
196 mmio_region_write32(clkmgr->
base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET,
206 if (clkmgr == NULL || clock == NULL) {
224 if (clkmgr == NULL || state == NULL || !clkmgr_valid_hintable_clock(clock)) {
228 uint32_t clk_hints_val =
229 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_STATUS_REG_OFFSET);
230 *state = dif_bool_to_toggle(bitfield_bit32_read(clk_hints_val, clock));
238 if (clkmgr == NULL || !clkmgr_valid_hintable_clock(clock) ||
239 !dif_is_valid_toggle(new_state)) {
243 bool new_clk_hints_bit = dif_toggle_to_bool(new_state);
244 uint32_t clk_hints_val =
245 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_REG_OFFSET);
246 clk_hints_val = bitfield_bit32_write(clk_hints_val, clock, new_clk_hints_bit);
247 mmio_region_write32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_REG_OFFSET,
256 if (clkmgr == NULL || state == NULL || !clkmgr_valid_hintable_clock(clock)) {
260 uint32_t clk_hints_val =
261 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_REG_OFFSET);
262 *state = dif_bool_to_toggle(bitfield_bit32_read(clk_hints_val, clock));
267#if OPENTITAN_CLKMGR_HAS_SW_EXTCLK_REGWEN
268dif_result_t dif_clkmgr_external_clock_control_is_locked(
270 if (clkmgr == NULL || is_locked == NULL) {
274 *is_locked = extclk_control_register_is_locked(clkmgr);
281 if (clkmgr == NULL) {
284 mmio_region_write32(clkmgr->
base_addr, CLKMGR_EXTCLK_CTRL_REGWEN_REG_OFFSET,
291 uint32_t extclk_ctrl_reg = 0;
293 if (clkmgr == NULL) {
297 if (extclk_control_register_is_locked(clkmgr)) {
301 extclk_ctrl_reg = bitfield_field32_write(
302 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_SEL_FIELD, kMultiBitBool4True);
303 extclk_ctrl_reg = bitfield_field32_write(
304 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_HI_SPEED_SEL_FIELD,
305 is_low_speed ? kMultiBitBool4False : kMultiBitBool4True);
306 mmio_region_write32(clkmgr->
base_addr, CLKMGR_EXTCLK_CTRL_REG_OFFSET,
313 uint32_t extclk_ctrl_reg = 0;
315 if (clkmgr == NULL) {
319 if (extclk_control_register_is_locked(clkmgr)) {
323 extclk_ctrl_reg = bitfield_field32_write(
324 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_SEL_FIELD, kMultiBitBool4False);
326 extclk_ctrl_reg = bitfield_field32_write(
327 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_HI_SPEED_SEL_FIELD,
329 mmio_region_write32(clkmgr->
base_addr, CLKMGR_EXTCLK_CTRL_REG_OFFSET,
336 if (clkmgr == NULL) {
339 mmio_region_write32(clkmgr->
base_addr, CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET,
346 if (clkmgr == NULL || state == NULL) {
349 *state = dif_bool_to_toggle(clkmgr_measure_ctrl_regwen(clkmgr));
355 dif_clkmgr_measure_clock_t *clock) {
356 if (clkmgr == NULL || clock == NULL) {
372 dif_clkmgr_measure_clock_t clock,
373 uint32_t lo_threshold,
374 uint32_t hi_threshold) {
375 if (clkmgr == NULL) {
378 if (!clkmgr_measure_ctrl_regwen(clkmgr)) {
389 uint32_t measure_ctrl_reg = 0;
390 measure_ctrl_reg = bitfield_field32_write(
392 measure_ctrl_reg = bitfield_field32_write(
400 uint32_t measure_en_reg =
409 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock) {
410 if (clkmgr == NULL) {
413 if (!clkmgr_measure_ctrl_regwen(clkmgr)) {
424 uint32_t measure_en_reg = bitfield_field32_write(
432 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
434 if (clkmgr == NULL || state == NULL) {
447 *state = dif_multi_bit_bool_to_toggle(
454 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
455 uint32_t *min_threshold, uint32_t *max_threshold) {
456 if (clkmgr == NULL || min_threshold == NULL || max_threshold == NULL) {
467 uint32_t thresholds_val = mmio_region_read32(
479 if (clkmgr == NULL || codes == NULL) {
483 mmio_region_read32(clkmgr->
base_addr, CLKMGR_RECOV_ERR_CODE_REG_OFFSET);
489 if (clkmgr == NULL) {
492 mmio_region_write32(clkmgr->
base_addr, CLKMGR_RECOV_ERR_CODE_REG_OFFSET,
499 if (clkmgr == NULL || codes == NULL) {
503 mmio_region_read32(clkmgr->
base_addr, CLKMGR_FATAL_ERR_CODE_REG_OFFSET);
507#if OPENTITAN_CLKMGR_HAS_SW_EXTCLK_REGWEN
509 if (clkmgr == NULL) {
515 mmio_region_read32(clkmgr->
base_addr, CLKMGR_EXTCLK_STATUS_REG_OFFSET);
516 }
while (ext_status != kMultiBitBool4True);