Software APIs
ast_clk_outs_test.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 
8 #include "sw/device/lib/testing/aon_timer_testutils.h"
9 #include "sw/device/lib/testing/clkmgr_testutils.h"
10 #include "sw/device/lib/testing/pwrmgr_testutils.h"
11 #include "sw/device/lib/testing/sensor_ctrl_testutils.h"
12 #include "sw/device/lib/testing/test_framework/check.h"
14 
16 
17 OTTF_DEFINE_TEST_CONFIG();
18 
19 /**
20  * AST CLK OUTPUTS TEST
21  *
22  * This test measures clock counts with clkmgr frequency measurements,
23  * performing 100 measurements per round. Measurement errors (fast or slow
24  * clocks) are recorded as recoverable error in clkmgr.
25  *
26  * After 100 measurements, this configures the clock counters per external
27  * clock and low speed settings before entering low-power mode, where all but
28  * the aon clock are off. The expectation is that main and io clocks will
29  * report errors, but div2 and div4 should not.
30  *
31  * When the dut wakes up, another 100 measurements are done before the
32  * test finishes.
33  *
34  * Notice the test overrides the hardware behavior so it comes out with
35  * calibrated USB clock, otherwise the USB clock frequency will be incorrect.
36  * USB calibration should be a separate test, and may be vendor-specific.
37  */
38 enum {
39  kWaitForCSRPollingUs = 1, // 1us
40  kMeasurementsPerRound = 100,
41 };
42 
43 static dif_clkmgr_t clkmgr;
44 static dif_pwrmgr_t pwrmgr;
45 
46 bool test_main(void) {
47  dif_sensor_ctrl_t sensor_ctrl;
48  dif_aon_timer_t aon_timer;
49 
50  uint32_t delay_micros = 0;
51  CHECK_STATUS_OK(aon_timer_testutils_get_us_from_aon_cycles(
52  kMeasurementsPerRound, &delay_micros));
53 
54  CHECK_DIF_OK(dif_clkmgr_init(
56  CHECK_DIF_OK(dif_sensor_ctrl_init(
58  &sensor_ctrl));
59  CHECK_DIF_OK(dif_pwrmgr_init(
61  CHECK_DIF_OK(dif_aon_timer_init(
63 
64  LOG_INFO("TEST: wait for ast init");
65  IBEX_SPIN_FOR(sensor_ctrl_ast_init_done(&sensor_ctrl), 1000);
66  LOG_INFO("TEST: done ast init");
67 
68  if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) == true) {
69  // At POR.
70  LOG_INFO("Run clock measurements right after POR");
71  CHECK_STATUS_OK(
72  clkmgr_testutils_enable_clock_counts_with_expected_thresholds(
73  &clkmgr, /*jitter_enabled=*/false, /*external_clk=*/false,
74  /*low_speed=*/false));
75  busy_spin_micros(delay_micros);
76 
77  // check results
78  CHECK_STATUS_OK(clkmgr_testutils_check_measurement_counts(&clkmgr));
79  CHECK_STATUS_OK(clkmgr_testutils_disable_clock_counts(&clkmgr));
80 
81  // Set wakeup timer to 100 us to have enough down time, and also wait before
82  // entering deep sleep to have a chance to measure before sleeping.
83  // As a side-effect of deep sleep the clock measurements are disabled, but
84  // recoverable errors are not cleared.
85  //
86  // Set the counters so we should get an error unless they are cleared.
87  uint64_t wakeup_threshold = kDeviceType == kDeviceSimVerilator ? 1000 : 100;
88  CHECK_STATUS_OK(
89  aon_timer_testutils_wakeup_config(&aon_timer, wakeup_threshold));
90 
91  LOG_INFO("Start clock measurements to cause an error for main and io clk.");
92  CHECK_STATUS_OK(
93  clkmgr_testutils_enable_clock_counts_with_expected_thresholds(
94  &clkmgr, /*jitter_enabled=*/false, /*external_clk=*/true,
95  /*low_speed=*/true));
96  // Disable writes to measure ctrl registers.
97  CHECK_DIF_OK(dif_clkmgr_measure_ctrl_disable(&clkmgr));
98 
99  busy_spin_micros(delay_micros);
100 
101  CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
102  &pwrmgr, kDifPwrmgrWakeupRequestSourceFive,
103  kDifPwrmgrDomainOptionUsbClockInActivePower));
104 
105  LOG_INFO("TEST: Issue WFI to enter deep sleep");
107 
108  } else if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(
109  &pwrmgr, kDifPwrmgrWakeupRequestSourceFive)) == true) {
110  // Fail if some measurements are enabled.
111  bool all_disabled = UNWRAP(clkmgr_testutils_check_measurement_enables(
112  &clkmgr, kDifToggleDisabled));
113  CHECK(all_disabled);
114  // Check measurement control regwen is enabled.
115  dif_toggle_t state;
116  CHECK_DIF_OK(dif_clkmgr_measure_ctrl_get_enable(&clkmgr, &state));
117  CHECK(state == kDifToggleEnabled);
118  LOG_INFO("Check for all clock measurements disabled done");
119 
120  // Check we have a measurement error for the main clock.
121  dif_clkmgr_recov_err_codes_t expected_err_codes =
122  kDifClkmgrRecovErrTypeMainMeas | kDifClkmgrRecovErrTypeIoMeas;
124  CHECK_DIF_OK(dif_clkmgr_recov_err_code_get_codes(&clkmgr, &err_codes));
125  CHECK(err_codes == expected_err_codes,
126  "expected main and io clk measurement error 0x%x, but got 0x%x",
127  expected_err_codes, err_codes);
128 
129  // Clear measurement errors.
130  CHECK_DIF_OK(dif_clkmgr_recov_err_code_clear_codes(&clkmgr, UINT32_MAX));
131 
132  LOG_INFO("TEST: one more measurement");
133  CHECK_STATUS_OK(
134  clkmgr_testutils_enable_clock_counts_with_expected_thresholds(
135  &clkmgr, /*jitter_enabled=*/false, /*external_clk=*/false,
136  /*low_speed=*/false));
137  busy_spin_micros(delay_micros);
138  CHECK_STATUS_OK(clkmgr_testutils_check_measurement_counts(&clkmgr));
139  CHECK_STATUS_OK(clkmgr_testutils_disable_clock_counts(&clkmgr));
140 
141  LOG_INFO("TEST: done");
142  return true;
143  } else { // error
144  dif_pwrmgr_wakeup_reason_t wakeup_reason;
145  CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(&pwrmgr, &wakeup_reason));
146  LOG_ERROR("Unexpected wakeup detected: type = %d, request_source = %d",
147  wakeup_reason.types, wakeup_reason.request_sources);
148  return false;
149  }
150 
151  return false;
152 }