11 #include "sw/device/lib/base/multibits.h"
14 #include "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;
38 static 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);
42 CLKMGR_MEASURE_CTRL_REGWEN_EN_BIT);
47 if (clkmgr == NULL ||
status == NULL) {
50 uint32_t extclk_status_val =
51 mmio_region_read32(clkmgr->
base_addr, CLKMGR_EXTCLK_STATUS_REG_OFFSET);
53 CLKMGR_EXTCLK_STATUS_ACK_FIELD) ==
61 if (clkmgr == NULL || state == NULL) {
65 multi_bit_bool_t clk_jitter_val =
66 mmio_region_read32(clkmgr->
base_addr, CLKMGR_JITTER_ENABLE_REG_OFFSET);
69 *state = clk_jitter_val != kMultiBitBool4False;
76 multi_bit_bool_t new_jitter_enable_val;
83 new_jitter_enable_val = kMultiBitBool4True;
86 new_jitter_enable_val = kMultiBitBool4False;
91 mmio_region_write32(clkmgr->
base_addr, CLKMGR_JITTER_ENABLE_REG_OFFSET,
92 new_jitter_enable_val);
99 if (clkmgr == NULL || state == NULL || !clkmgr_valid_gateable_clock(clock)) {
103 uint32_t clk_enables_val =
104 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET);
113 if (clkmgr == NULL || !clkmgr_valid_gateable_clock(clock) ||
119 uint32_t clk_enables_val =
120 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET);
123 mmio_region_write32(clkmgr->
base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET,
132 if (clkmgr == NULL || state == NULL || !clkmgr_valid_hintable_clock(clock)) {
136 uint32_t clk_hints_val =
137 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_STATUS_REG_OFFSET);
146 if (clkmgr == NULL || !clkmgr_valid_hintable_clock(clock) ||
152 uint32_t clk_hints_val =
153 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_REG_OFFSET);
155 mmio_region_write32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_REG_OFFSET,
164 if (clkmgr == NULL || state == NULL || !clkmgr_valid_hintable_clock(clock)) {
168 uint32_t clk_hints_val =
169 mmio_region_read32(clkmgr->
base_addr, CLKMGR_CLK_HINTS_REG_OFFSET);
177 uint32_t extclk_ctrl_reg = 0;
179 if (clkmgr == NULL) {
184 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_SEL_FIELD, kMultiBitBool4True);
186 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_HI_SPEED_SEL_FIELD,
187 is_low_speed ? kMultiBitBool4False : kMultiBitBool4True);
188 mmio_region_write32(clkmgr->
base_addr, CLKMGR_EXTCLK_CTRL_REG_OFFSET,
195 uint32_t extclk_ctrl_reg = 0;
197 if (clkmgr == NULL) {
202 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_SEL_FIELD, kMultiBitBool4False);
205 extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_HI_SPEED_SEL_FIELD,
207 mmio_region_write32(clkmgr->
base_addr, CLKMGR_EXTCLK_CTRL_REG_OFFSET,
213 if (clkmgr == NULL) {
216 mmio_region_write32(clkmgr->
base_addr, CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET,
223 if (clkmgr == NULL || state == NULL) {
251 #define CNCAT_IMPL(a_, b_) a_##b_
252 #define CNCAT(a_, b_) CNCAT_IMPL(a_, b_)
253 #define CHECK_CLKMGR_IO_MEAS_CTRL_EN_REG_OFFSET ~, ~
254 #define CHECK_CLKMGR_IO_DIV2_MEAS_CTRL_EN_REG_OFFSET ~, ~
255 #define CHECK_CLKMGR_IO_DIV4_MEAS_CTRL_EN_REG_OFFSET ~, ~
256 #define CHECK_CLKMGR_MAIN_MEAS_CTRL_EN_REG_OFFSET ~, ~
257 #define CHECK_CLKMGR_USB_MEAS_CTRL_EN_REG_OFFSET ~, ~
258 #define CHECK_IMPL(a_, b_, c_, ...) c_
259 #define CHECK(tup_) CHECK_IMPL tup_
261 #define IS_KIND_DEFINED(kind_) \
262 CHECK((CNCAT(CHECK_, CLKMGR_##kind_##_MEAS_CTRL_EN_REG_OFFSET), 0, 1))
264 #define IIF_0(true_exp_, false_exp_) false_exp_
265 #define IIF_1(true_exp_, false_exp_) true_exp_
266 #define IIF(condition_, true_exp_, false_exp_) \
267 CNCAT(IIF_, condition_)(true_exp_, false_exp_)
270 dif_clkmgr_measure_clock_t clock,
271 uint32_t lo_threshold,
272 uint32_t hi_threshold) {
273 if (clkmgr == NULL) {
276 if (!clkmgr_measure_ctrl_regwen(clkmgr)) {
280 uint32_t en_offset = 0;
281 uint32_t reg_offset = 0;
286 #define PICK_COUNT_CTRL_FIELDS(kind_) \
287 IIF(IS_KIND_DEFINED(kind_), \
288 en_offset = CLKMGR_##kind_##_MEAS_CTRL_EN_REG_OFFSET; \
289 reg_offset = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_REG_OFFSET; \
290 en_field = CLKMGR_##kind_##_MEAS_CTRL_EN_EN_FIELD; \
291 lo_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_LO_FIELD; \
292 hi_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_HI_FIELD; break, break)
295 PICK_COUNT_CTRL_FIELDS(IO);
297 PICK_COUNT_CTRL_FIELDS(IO_DIV2);
299 PICK_COUNT_CTRL_FIELDS(IO_DIV4);
301 PICK_COUNT_CTRL_FIELDS(MAIN);
303 PICK_COUNT_CTRL_FIELDS(USB);
306 #undef PICK_COUNT_CTRL_FIELDS
309 uint32_t measure_ctrl_reg = 0;
315 mmio_region_write32(clkmgr->
base_addr, (ptrdiff_t)reg_offset,
317 mmio_region_write32(clkmgr->
base_addr, (ptrdiff_t)reg_offset,
320 uint32_t measure_en_reg = 0;
323 mmio_region_write32(clkmgr->
base_addr, (ptrdiff_t)en_offset, measure_en_reg);
329 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock) {
330 if (clkmgr == NULL) {
333 if (!clkmgr_measure_ctrl_regwen(clkmgr)) {
337 uint32_t en_offset = 0;
339 #define PICK_EN_OFFSET(kind_) \
340 IIF(IS_KIND_DEFINED(kind_), \
341 en_offset = CLKMGR_##kind_##_MEAS_CTRL_EN_REG_OFFSET; \
348 PICK_EN_OFFSET(IO_DIV2);
351 PICK_EN_OFFSET(IO_DIV4);
354 PICK_EN_OFFSET(MAIN);
361 #undef PICK_EN_OFFSET
363 mmio_region_write32(clkmgr->
base_addr, (ptrdiff_t)en_offset,
364 kMultiBitBool4False);
369 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
371 if (clkmgr == NULL || state == NULL) {
375 uint32_t en_offset = 0;
377 #define PICK_EN_OFFSET(kind_) \
378 IIF(IS_KIND_DEFINED(kind_), \
379 en_offset = CLKMGR_##kind_##_MEAS_CTRL_EN_REG_OFFSET; \
385 PICK_EN_OFFSET(IO_DIV2);
387 PICK_EN_OFFSET(IO_DIV4);
389 PICK_EN_OFFSET(MAIN);
394 #undef PICK_EN_OFFSET
396 multi_bit_bool_t en_val =
397 mmio_region_read32(clkmgr->
base_addr, (ptrdiff_t)en_offset);
404 const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
405 uint32_t *min_threshold, uint32_t *max_threshold) {
406 if (clkmgr == NULL || min_threshold == NULL || max_threshold == NULL) {
410 uint32_t reg_offset = 0;
414 #define PICK_THRESHOLD_FIELDS(kind_) \
415 IIF(IS_KIND_DEFINED(kind_), \
416 reg_offset = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_REG_OFFSET; \
417 lo_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_LO_FIELD; \
418 hi_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_HI_FIELD; break, break)
420 PICK_THRESHOLD_FIELDS(IO);
422 PICK_THRESHOLD_FIELDS(IO_DIV2);
424 PICK_THRESHOLD_FIELDS(IO_DIV4);
426 PICK_THRESHOLD_FIELDS(MAIN);
428 PICK_THRESHOLD_FIELDS(USB);
431 #undef PICK_THRESHOLD_FIELDS
433 uint32_t thresholds_val =
434 mmio_region_read32(clkmgr->
base_addr, (ptrdiff_t)reg_offset);
443 #undef CHECK_CLKMGR_IO_MEAS_CTRL_EN_REG_OFFSET
444 #undef CHECK_CLKMGR_IO_DIV2_MEAS_CTRL_EN_REG_OFFSET
445 #undef CHECK_CLKMGR_IO_DIV4_MEAS_CTRL_EN_REG_OFFSET
446 #undef CHECK_CLKMGR_MAIN_MEAS_CTRL_EN_REG_OFFSET
447 #undef CHECK_CLKMGR_USB_MEAS_CTRL_EN_REG_OFFSET
450 #undef IS_KIND_DEFINED
457 if (clkmgr == NULL || codes == NULL) {
461 mmio_region_read32(clkmgr->
base_addr, CLKMGR_RECOV_ERR_CODE_REG_OFFSET);
467 if (clkmgr == NULL) {
470 mmio_region_write32(clkmgr->
base_addr, CLKMGR_RECOV_ERR_CODE_REG_OFFSET,
477 if (clkmgr == NULL || codes == NULL) {
481 mmio_region_read32(clkmgr->
base_addr, CLKMGR_FATAL_ERR_CODE_REG_OFFSET);
486 if (clkmgr == NULL) {
492 mmio_region_read32(clkmgr->
base_addr, CLKMGR_EXTCLK_STATUS_REG_OFFSET);
493 }
while (ext_status != kMultiBitBool4True);