5 #include "sw/device/lib/testing/clkmgr_testutils.h"
10 #define MODULE_ID MAKE_MODULE_ID('c', 'm', 't')
13 #if defined(OPENTITAN_IS_EARLGREY)
14 "io_clk",
"io_div2_clk",
15 #elif defined(OPENTITAN_IS_DARJEELING)
18 #error Unsupported top
20 "io_div4_clk",
"main_clk",
"usb_clk"};
25 extern bool clkmgr_testutils_get_trans_clock_status(
28 extern status_t clkmgr_testutils_check_trans_clock_gating(
30 bool exp_clock_enabled, uint32_t timeout_usec);
51 static uint32_t kVariabilityPercentage = 5;
56 static uint32_t kJitterVariabilityPercentage = 12;
60 static inline uint32_t get_count_variability(uint32_t cycles,
61 uint32_t variability_percentage) {
62 return ((cycles * variability_percentage) + 99) / 100 + 1;
65 static uint32_t cast_safely(uint64_t val) {
66 CHECK(val <= UINT32_MAX);
70 void initialize_expected_counts(
void) {
76 const uint32_t kDeviceCpuCount =
79 const uint32_t kDeviceIoCount =
83 #if defined(OPENTITAN_IS_EARLGREY)
84 const uint32_t kDeviceIoDiv2Count =
89 const uint32_t kDeviceIoDiv4Count =
92 const uint32_t kDeviceUsbCount =
96 LOG_INFO(
"Variability for Io %d is %d", kDeviceIoCount,
97 get_count_variability(kDeviceIoCount, kVariabilityPercentage));
98 LOG_INFO(
"Variability for Cpu %d is %d", kDeviceCpuCount,
99 get_count_variability(kDeviceCpuCount, kVariabilityPercentage));
103 #if defined(OPENTITAN_IS_EARLGREY)
104 kNoJitterCountInfos[kDifClkmgrMeasureClockIo] =
106 .variability = get_count_variability(
107 kDeviceIoCount, kVariabilityPercentage)};
108 kNoJitterCountInfos[kDifClkmgrMeasureClockIoDiv2] =
110 .variability = get_count_variability(
111 kDeviceIoDiv2Count, kVariabilityPercentage)};
115 .variability = get_count_variability(
116 kDeviceIoDiv4Count, kVariabilityPercentage)};
119 .variability = get_count_variability(
120 kDeviceCpuCount, kVariabilityPercentage)};
123 .variability = get_count_variability(
124 kDeviceUsbCount, kVariabilityPercentage)};
129 #if defined(OPENTITAN_IS_EARLGREY)
130 kJitterCountInfos[kDifClkmgrMeasureClockIo] =
131 kNoJitterCountInfos[kDifClkmgrMeasureClockIo];
132 kJitterCountInfos[kDifClkmgrMeasureClockIoDiv2] =
133 kNoJitterCountInfos[kDifClkmgrMeasureClockIoDiv2];
139 .variability = get_count_variability(
140 kDeviceCpuCount - kDeviceCpuCount / 10,
141 kJitterVariabilityPercentage)};
146 const char *clkmgr_testutils_measurement_name(
147 dif_clkmgr_measure_clock_t clock) {
149 #if defined(OPENTITAN_IS_EARLGREY)
150 case kDifClkmgrMeasureClockIo:
152 case kDifClkmgrMeasureClockIoDiv2:
162 LOG_ERROR(
"Unexpected clock measurement %d", clock);
164 return "unexpected clock";
167 status_t clkmgr_testutils_enable_clock_count(
const dif_clkmgr_t *clkmgr,
168 dif_clkmgr_measure_clock_t clock,
169 uint32_t lo_threshold,
170 uint32_t hi_threshold) {
171 LOG_INFO(
"Enabling clock count measurement for %s(%d) lo %d hi %d",
172 measure_clock_names[clock], clock, lo_threshold, hi_threshold);
178 status_t clkmgr_testutils_enable_clock_counts_with_expected_thresholds(
179 const dif_clkmgr_t *clkmgr,
bool jitter_enabled,
bool external_clk,
181 static bool counts_initialized =
false;
182 if (!counts_initialized) {
183 initialize_expected_counts();
184 counts_initialized =
true;
186 TRY_CHECK(!(external_clk && jitter_enabled));
187 for (
int clk = 0; clk <
ARRAYSIZE(kNoJitterCountInfos); ++clk) {
189 if (jitter_enabled) {
190 count_info = &kJitterCountInfos[clk];
191 }
else if (external_clk) {
192 #if defined(OPENTITAN_IS_EARLGREY)
194 if (clk == kDifClkmgrMeasureClockIo ||
196 count_info = &kNoJitterCountInfos[kDifClkmgrMeasureClockIoDiv2];
198 count_info = &kNoJitterCountInfos[clk];
202 count_info = &kNoJitterCountInfos[kDifClkmgrMeasureClockIo];
204 count_info = &kNoJitterCountInfos[clk];
207 #elif defined(OPENTITAN_IS_DARJEELING)
208 TRY_CHECK(
false,
"Darjeeling has no external clock");
211 #error Unsupported top
214 count_info = &kNoJitterCountInfos[clk];
216 TRY(clkmgr_testutils_enable_clock_count(
217 clkmgr, (dif_clkmgr_measure_clock_t)clk,
218 count_info->count - count_info->variability,
219 count_info->count + count_info->variability));
224 status_t clkmgr_testutils_check_measurement_enables(
225 const dif_clkmgr_t *clkmgr,
dif_toggle_t expected_status) {
228 dif_clkmgr_measure_clock_t clock = (dif_clkmgr_measure_clock_t)i;
231 if (actual_status != expected_status) {
232 LOG_INFO(
"Unexpected enable for clock %d: expected %s", i,
237 return OK_STATUS(success);
240 status_t clkmgr_testutils_disable_clock_counts(
const dif_clkmgr_t *clkmgr) {
241 LOG_INFO(
"Disabling all clock count measurements");
243 dif_clkmgr_measure_clock_t clock = (dif_clkmgr_measure_clock_t)i;
246 LOG_INFO(
"Disabling all clock count done");
250 status_t clkmgr_testutils_check_measurement_counts(
const dif_clkmgr_t *clkmgr) {
254 if (err_codes != 0) {
255 LOG_ERROR(
"Unexpected recoverable error codes 0x%x", err_codes);
258 LOG_INFO(
"Clock measurements are okay");
265 status_t clkmgr_testutils_enable_external_clock_blocking(
266 const dif_clkmgr_t *clkmgr,
bool is_low_speed) {
267 LOG_INFO(
"Configure clkmgr to enable external clock");
270 LOG_INFO(
"Switching to external clock completes");