Software APIs
clkmgr_smoketest.c
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 #include "dt/dt_clkmgr.h"
9 #include "sw/device/lib/testing/test_framework/check.h"
11 
12 static_assert(kDtClkmgrCount >= 1,
13  "This test requires at least one Clkmgr instance");
14 
15 static dt_clkmgr_t kTestClkmgr = (dt_clkmgr_t)0;
16 
17 OTTF_DEFINE_TEST_CONFIG();
18 
19 /**
20  * Test that all 'gateable' clocks, directly controlled by software,
21  * can be enabled and disabled.
22  */
23 static void test_gateable_clocks(const dif_clkmgr_t *clkmgr,
24  size_t num_clocks) {
25  for (dif_clkmgr_gateable_clock_t clock = 0; clock < num_clocks; ++clock) {
26  // Get the initial state of the clock. The clock might be enabled or
27  // disabled depending on reset behavior - either is fine for the purposes of
28  // this test.
29  dif_toggle_t state;
30  CHECK_DIF_OK(dif_clkmgr_gateable_clock_get_enabled(clkmgr, clock, &state));
31 
32  // Toggle the enable twice so that it ends up in its original state.
33  for (int j = 0; j < 2; ++j) {
34  dif_toggle_t expected_state =
36  dif_toggle_t actual_state = state;
37  CHECK_DIF_OK(
38  dif_clkmgr_gateable_clock_set_enabled(clkmgr, clock, expected_state));
39  CHECK_DIF_OK(
40  dif_clkmgr_gateable_clock_get_enabled(clkmgr, clock, &actual_state));
41  CHECK(actual_state == expected_state);
42 
43  state = actual_state;
44  }
45  }
46 }
47 
48 /**
49  * Test that all 'hintable' clocks, indirectly controlled by software,
50  * can have their hint toggled and status checked.
51  */
52 void test_hintable_clocks(const dif_clkmgr_t *clkmgr, size_t num_clocks) {
53  for (dif_clkmgr_hintable_clock_t clock = 0; clock < num_clocks; ++clock) {
54  // Get the initial state of the hint for the clock The clock hint might be
55  // enabled or disabled depending on reset behavior - either is fine for the
56  // purposes of this test.
57  dif_toggle_t state;
58  CHECK_DIF_OK(dif_clkmgr_hintable_clock_get_hint(clkmgr, clock, &state));
59 
60  // Toggle the hint twice so that it ends up in its original state.
61  for (int j = 0; j < 2; ++j) {
62  dif_toggle_t expected_state =
64  dif_toggle_t actual_state = state;
65  CHECK_DIF_OK(
66  dif_clkmgr_hintable_clock_set_hint(clkmgr, clock, expected_state));
67  CHECK_DIF_OK(
68  dif_clkmgr_hintable_clock_get_hint(clkmgr, clock, &actual_state));
69  CHECK(actual_state == expected_state);
70 
71  // If the clock hint is enabled then the clock should always be enabled.
72  if (actual_state == kDifToggleEnabled) {
74  CHECK_DIF_OK(
75  dif_clkmgr_hintable_clock_get_enabled(clkmgr, clock, &state));
76  CHECK(state == kDifToggleEnabled,
77  "clock %u hint is enabled but status is disabled", clock);
78  }
79 
80  state = actual_state;
81  }
82  }
83 }
84 
85 bool test_main(void) {
86  dif_clkmgr_t clkmgr;
87  CHECK_DIF_OK(dif_clkmgr_init_from_dt(kTestClkmgr, &clkmgr));
88 
89  test_gateable_clocks(&clkmgr, dt_clkmgr_gateable_clock_count(kTestClkmgr));
90  test_hintable_clocks(&clkmgr, dt_clkmgr_hintable_clock_count(kTestClkmgr));
91 
92  return true;
93 }