1 /*
2 * Copyright (c) 2021-2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7 #include "hpm_clock_drv.h"
8 #include "hpm_sysctl_drv.h"
9 #include "hpm_soc.h"
10 #include "hpm_common.h"
11 #include "hpm_pllctlv2_drv.h"
12 /***********************************************************************************************************************
13 * Definitions
14 **********************************************************************************************************************/
15
16 /* Clock preset values */
17 #define FREQ_PRESET1_OSC0_CLK0 (24000000UL)
18 #define FREQ_PRESET1_PLL0_CLK0 (720000000UL)
19 #define FREQ_PRESET1_PLL0_CLK1 (600000000UL)
20 #define FREQ_PRESET1_PLL0_CLK2 (400000000UL)
21 #define FREQ_PRESET1_PLL1_CLK0 (800000000UL)
22 #define FREQ_PRESET1_PLL1_CLK1 (666000000UL)
23 #define FREQ_PRESET1_PLL1_CLK2 (500000000UL)
24 #define FREQ_PRESET1_PLL1_CLK3 (266000000UL)
25 #define FREQ_32KHz (32768UL)
26 #define ADC_INSTANCE_NUM ARRAY_SIZE(HPM_SYSCTL->ADCCLK)
27 #define DAC_INSTANCE_NUM ARRAY_SIZE(HPM_SYSCTL->DACCLK)
28 #define WDG_INSTANCE_NUM (2U)
29 #define BUS_FREQ_MAX (200000000UL)
30 #define FREQ_1MHz (1000000UL)
31
32 /* Clock On/Off definitions */
33 #define CLOCK_ON (true)
34 #define CLOCK_OFF (false)
35
36
37 /***********************************************************************************************************************
38 * Prototypes
39 **********************************************************************************************************************/
40
41 /**
42 * @brief Get Clock frequency for IP in common group
43 */
44 static uint32_t get_frequency_for_ip_in_common_group(clock_node_t node);
45
46 /**
47 * @brief Get Clock frequency for ADC
48 */
49 static uint32_t get_frequency_for_adc(uint32_t clk_src_type, uint32_t instance);
50
51 /**
52 * @brief Get Clock frequency for DAC
53 */
54 static uint32_t get_frequency_for_dac(uint32_t instance);
55
56 /**
57 * @brief Get Clock frequency for WDG
58 */
59 static uint32_t get_frequency_for_ewdg(uint32_t instance);
60
61 /**
62 * @brief Get Clock frequency for PWDG
63 */
64 static uint32_t get_frequency_for_pewdg(void);
65
66 /**
67 * @brief Turn on/off the IP clock
68 */
69 static void switch_ip_clock(clock_name_t clock_name, bool on);
70
71 static uint32_t get_frequency_for_cpu(void);
72 static uint32_t get_frequency_for_ahb(void);
73
74
75 /***********************************************************************************************************************
76 * Variables
77 **********************************************************************************************************************/
78 static const clock_node_t s_adc_clk_mux_node[] = {
79 clock_node_ahb,
80 clock_node_ana0
81 };
82
83 static const clock_node_t s_dac_clk_mux_node[] = {
84 clock_node_ahb,
85 clock_node_ana2
86 };
87
88 static EWDG_Type *const s_wdgs[] = { HPM_EWDG0, HPM_EWDG1};
89
90 uint32_t hpm_core_clock;
91
92
93 /***********************************************************************************************************************
94 * Codes
95 **********************************************************************************************************************/
clock_get_frequency(clock_name_t clock_name)96 uint32_t clock_get_frequency(clock_name_t clock_name)
97 {
98 uint32_t clk_freq = 0UL;
99 uint32_t clk_src_type = GET_CLK_SRC_GROUP_FROM_NAME(clock_name);
100 uint32_t node_or_instance = GET_CLK_NODE_FROM_NAME(clock_name);
101 switch (clk_src_type) {
102 case CLK_SRC_GROUP_COMMON:
103 clk_freq = get_frequency_for_ip_in_common_group((clock_node_t) node_or_instance);
104 break;
105 case CLK_SRC_GROUP_ADC:
106 clk_freq = get_frequency_for_adc(CLK_SRC_GROUP_ADC, node_or_instance);
107 break;
108 case CLK_SRC_GROUP_DAC:
109 clk_freq = get_frequency_for_dac(node_or_instance);
110 break;
111 case CLK_SRC_GROUP_EWDG:
112 clk_freq = get_frequency_for_ewdg(node_or_instance);
113 break;
114 case CLK_SRC_GROUP_PEWDG:
115 clk_freq = get_frequency_for_pewdg();
116 break;
117 case CLK_SRC_GROUP_PMIC:
118 clk_freq = FREQ_PRESET1_OSC0_CLK0;
119 break;
120 case CLK_SRC_GROUP_CPU0:
121 clk_freq = get_frequency_for_cpu();
122 break;
123 case CLK_SRC_GROUP_AHB:
124 clk_freq = get_frequency_for_ahb();
125 break;
126 case CLK_SRC_GROUP_SRC:
127 clk_freq = get_frequency_for_source((clock_source_t) node_or_instance);
128 break;
129 default:
130 clk_freq = 0UL;
131 break;
132 }
133 return clk_freq;
134 }
135
get_frequency_for_source(clock_source_t source)136 uint32_t get_frequency_for_source(clock_source_t source)
137 {
138 uint32_t clk_freq = 0UL;
139 switch (source) {
140 case clock_source_osc0_clk0:
141 clk_freq = FREQ_PRESET1_OSC0_CLK0;
142 break;
143 case clock_source_pll0_clk0:
144 clk_freq = pllctlv2_get_pll_postdiv_freq_in_hz(HPM_PLLCTLV2, 0U, 0U);
145 break;
146 case clock_source_pll0_clk1:
147 clk_freq = pllctlv2_get_pll_postdiv_freq_in_hz(HPM_PLLCTLV2, 0U, 1U);
148 break;
149 case clock_source_pll0_clk2:
150 clk_freq = pllctlv2_get_pll_postdiv_freq_in_hz(HPM_PLLCTLV2, 0U, 2U);
151 break;
152 case clock_source_pll1_clk0:
153 clk_freq = pllctlv2_get_pll_postdiv_freq_in_hz(HPM_PLLCTLV2, 1U, 0U);
154 break;
155 case clock_source_pll1_clk1:
156 clk_freq = pllctlv2_get_pll_postdiv_freq_in_hz(HPM_PLLCTLV2, 1U, 1U);
157 break;
158 case clock_source_pll1_clk2:
159 clk_freq = pllctlv2_get_pll_postdiv_freq_in_hz(HPM_PLLCTLV2, 1U, 2U);
160 break;
161 case clock_source_pll1_clk3:
162 clk_freq = pllctlv2_get_pll_postdiv_freq_in_hz(HPM_PLLCTLV2, 1U, 3U);
163 break;
164 default:
165 clk_freq = 0UL;
166 break;
167 }
168
169 return clk_freq;
170 }
171
get_frequency_for_ip_in_common_group(clock_node_t node)172 static uint32_t get_frequency_for_ip_in_common_group(clock_node_t node)
173 {
174 uint32_t clk_freq = 0UL;
175 uint32_t node_or_instance = GET_CLK_NODE_FROM_NAME(node);
176
177 if (node_or_instance < clock_node_end) {
178 uint32_t clk_node = (uint32_t) node_or_instance;
179
180 uint32_t clk_div = 1UL + SYSCTL_CLOCK_DIV_GET(HPM_SYSCTL->CLOCK[clk_node]);
181 clock_source_t clk_mux = (clock_source_t) SYSCTL_CLOCK_MUX_GET(HPM_SYSCTL->CLOCK[clk_node]);
182 clk_freq = get_frequency_for_source(clk_mux) / clk_div;
183 }
184 return clk_freq;
185 }
186
get_frequency_for_adc(uint32_t clk_src_type,uint32_t instance)187 static uint32_t get_frequency_for_adc(uint32_t clk_src_type, uint32_t instance)
188 {
189 uint32_t clk_freq = 0UL;
190 bool is_mux_valid = false;
191 clock_node_t node = clock_node_end;
192 uint32_t adc_index = instance;
193
194 (void) clk_src_type;
195
196 if (adc_index < ADC_INSTANCE_NUM) {
197 uint32_t mux_in_reg = SYSCTL_ADCCLK_MUX_GET(HPM_SYSCTL->ADCCLK[adc_index]);
198 if (mux_in_reg < ARRAY_SIZE(s_adc_clk_mux_node)) {
199 node = s_adc_clk_mux_node[mux_in_reg];
200 is_mux_valid = true;
201 }
202 }
203
204 if (is_mux_valid) {
205 if (node != clock_node_ahb) {
206 node += instance;
207 clk_freq = get_frequency_for_ip_in_common_group(node);
208 } else {
209 clk_freq = get_frequency_for_ahb();
210 }
211 }
212 return clk_freq;
213 }
214
get_frequency_for_dac(uint32_t instance)215 static uint32_t get_frequency_for_dac(uint32_t instance)
216 {
217 uint32_t clk_freq = 0UL;
218 bool is_mux_valid = false;
219 clock_node_t node = clock_node_end;
220 if (instance < DAC_INSTANCE_NUM) {
221 uint32_t mux_in_reg = SYSCTL_DACCLK_MUX_GET(HPM_SYSCTL->DACCLK[instance]);
222 if (mux_in_reg < ARRAY_SIZE(s_dac_clk_mux_node)) {
223 node = s_dac_clk_mux_node[mux_in_reg];
224 is_mux_valid = true;
225 }
226 }
227
228 if (is_mux_valid) {
229 if (node == clock_node_ahb) {
230 clk_freq = get_frequency_for_ahb();
231 } else {
232 node += instance;
233 clk_freq = get_frequency_for_ip_in_common_group(node);
234 }
235 }
236
237 return clk_freq;
238 }
239
get_frequency_for_ewdg(uint32_t instance)240 static uint32_t get_frequency_for_ewdg(uint32_t instance)
241 {
242 uint32_t freq_in_hz;
243 if (EWDG_CTRL0_CLK_SEL_GET(s_wdgs[instance]->CTRL0) == 0) {
244 freq_in_hz = get_frequency_for_ahb();
245 } else {
246 freq_in_hz = FREQ_32KHz;
247 }
248
249 return freq_in_hz;
250 }
251
get_frequency_for_pewdg(void)252 static uint32_t get_frequency_for_pewdg(void)
253 {
254 uint32_t freq_in_hz;
255 if (EWDG_CTRL0_CLK_SEL_GET(HPM_PEWDG->CTRL0) == 0) {
256 freq_in_hz = FREQ_PRESET1_OSC0_CLK0;
257 } else {
258 freq_in_hz = FREQ_32KHz;
259 }
260
261 return freq_in_hz;
262 }
263
get_frequency_for_cpu(void)264 static uint32_t get_frequency_for_cpu(void)
265 {
266 uint32_t mux = SYSCTL_CLOCK_CPU_MUX_GET(HPM_SYSCTL->CLOCK_CPU[0]);
267 uint32_t div = SYSCTL_CLOCK_CPU_DIV_GET(HPM_SYSCTL->CLOCK_CPU[0]) + 1U;
268 return (get_frequency_for_source(mux) / div);
269 }
270
get_frequency_for_ahb(void)271 static uint32_t get_frequency_for_ahb(void)
272 {
273 uint32_t div = SYSCTL_CLOCK_CPU_SUB0_DIV_GET(HPM_SYSCTL->CLOCK_CPU[0]) + 1U;
274 return (get_frequency_for_cpu() / div);
275 }
276
clock_get_source(clock_name_t clock_name)277 clk_src_t clock_get_source(clock_name_t clock_name)
278 {
279 uint8_t clk_src_group = CLK_SRC_GROUP_INVALID;
280 uint8_t clk_src_index = 0xFU;
281 uint32_t clk_src_type = GET_CLK_SRC_GROUP_FROM_NAME(clock_name);
282 uint32_t node_or_instance = GET_CLK_NODE_FROM_NAME(clock_name);
283 switch (clk_src_type) {
284 case CLK_SRC_GROUP_COMMON:
285 clk_src_group = CLK_SRC_GROUP_COMMON;
286 clk_src_index = SYSCTL_CLOCK_MUX_GET(HPM_SYSCTL->CLOCK[node_or_instance]);
287 break;
288 case CLK_SRC_GROUP_ADC:
289 if (node_or_instance < ADC_INSTANCE_NUM) {
290 clk_src_group = CLK_SRC_GROUP_ADC;
291 clk_src_index = SYSCTL_ADCCLK_MUX_GET(HPM_SYSCTL->ADCCLK[node_or_instance]);
292 }
293 break;
294 case CLK_SRC_GROUP_DAC:
295 if (node_or_instance < DAC_INSTANCE_NUM) {
296 clk_src_group = CLK_SRC_GROUP_DAC;
297 clk_src_index = SYSCTL_DACCLK_MUX_GET(HPM_SYSCTL->DACCLK[node_or_instance]);
298 }
299 break;
300 case CLK_SRC_GROUP_EWDG:
301 if (node_or_instance < WDG_INSTANCE_NUM) {
302 clk_src_group = CLK_SRC_GROUP_EWDG;
303 clk_src_index = EWDG_CTRL0_CLK_SEL_GET(s_wdgs[node_or_instance]->CTRL0);
304 }
305 break;
306 case CLK_SRC_GROUP_PEWDG:
307 clk_src_group = CLK_SRC_GROUP_PEWDG;
308 clk_src_index = EWDG_CTRL0_CLK_SEL_GET(HPM_PEWDG->CTRL0);
309 break;
310 case CLK_SRC_GROUP_PMIC:
311 clk_src_group = CLK_SRC_GROUP_COMMON;
312 clk_src_index = clock_source_osc0_clk0;
313 break;
314 case CLK_SRC_GROUP_CPU0:
315 case CLK_SRC_GROUP_AHB:
316 clk_src_group = CLK_SRC_GROUP_CPU0;
317 clk_src_index = SYSCTL_CLOCK_CPU_MUX_GET(HPM_SYSCTL->CLOCK_CPU[0]);
318 break;
319 case CLK_SRC_GROUP_SRC:
320 clk_src_index = (clk_src_t) node_or_instance;
321 break;
322 default:
323 clk_src_group = CLK_SRC_GROUP_INVALID;
324 break;
325 }
326
327 clk_src_t clk_src;
328 if (clk_src_group != CLK_SRC_GROUP_INVALID) {
329 clk_src = MAKE_CLK_SRC(clk_src_group, clk_src_index);
330 } else {
331 clk_src = clk_src_invalid;
332 }
333
334 return clk_src;
335 }
336
clock_get_divider(clock_name_t clock_name)337 uint32_t clock_get_divider(clock_name_t clock_name)
338 {
339 uint32_t clk_divider = CLOCK_DIV_INVALID;
340 uint32_t clk_src_type = GET_CLK_SRC_GROUP_FROM_NAME(clock_name);
341 uint32_t node_or_instance = GET_CLK_NODE_FROM_NAME(clock_name);
342 switch (clk_src_type) {
343 case CLK_SRC_GROUP_COMMON:
344 clk_divider = 1UL + SYSCTL_CLOCK_DIV_GET(HPM_SYSCTL->CLOCK[node_or_instance]);
345 break;
346 case CLK_SRC_GROUP_EWDG:
347 clk_divider = 1;
348 break;
349 case CLK_SRC_GROUP_PEWDG:
350 clk_divider = 1;
351 break;
352 case CLK_SRC_GROUP_PMIC:
353 clk_divider = 1;
354 break;
355 case CLK_SRC_GROUP_CPU0:
356 clk_divider = 1UL + SYSCTL_CLOCK_CPU_DIV_GET(HPM_SYSCTL->CLOCK_CPU[0]);
357 break;
358 case CLK_SRC_GROUP_AHB:
359 clk_divider = 1UL + SYSCTL_CLOCK_CPU_SUB0_DIV_GET(HPM_SYSCTL->CLOCK_CPU[0]);
360 break;
361 default:
362 clk_divider = CLOCK_DIV_INVALID;
363 break;
364 }
365 return clk_divider;
366 }
367
clock_set_adc_source(clock_name_t clock_name,clk_src_t src)368 hpm_stat_t clock_set_adc_source(clock_name_t clock_name, clk_src_t src)
369 {
370 uint32_t clk_src_type = GET_CLK_SRC_GROUP_FROM_NAME(clock_name);
371 uint32_t node_or_instance = GET_CLK_NODE_FROM_NAME(clock_name);
372
373 if ((clk_src_type != CLK_SRC_GROUP_ADC) || (node_or_instance >= ADC_INSTANCE_NUM)) {
374 return status_clk_invalid;
375 }
376
377 if ((src < clk_adc_src_ahb0) || (src > clk_adc_src_ana1)) {
378 return status_clk_src_invalid;
379 }
380
381 uint32_t clk_src_index = GET_CLK_SRC_INDEX(src);
382 HPM_SYSCTL->ADCCLK[node_or_instance] =
383 (HPM_SYSCTL->ADCCLK[node_or_instance] & ~SYSCTL_ADCCLK_MUX_MASK) | SYSCTL_ADCCLK_MUX_SET(clk_src_index);
384
385 return status_success;
386 }
387
clock_set_dac_source(clock_name_t clock_name,clk_src_t src)388 hpm_stat_t clock_set_dac_source(clock_name_t clock_name, clk_src_t src)
389 {
390 uint32_t clk_src_type = GET_CLK_SRC_GROUP_FROM_NAME(clock_name);
391 uint32_t node_or_instance = GET_CLK_NODE_FROM_NAME(clock_name);
392
393 if ((clk_src_type != CLK_SRC_GROUP_DAC) || (node_or_instance >= DAC_INSTANCE_NUM)) {
394 return status_clk_invalid;
395 }
396
397 if ((src < clk_dac_src_ahb0) || (src > clk_dac_src_ana3)) {
398 return status_clk_src_invalid;
399 }
400
401 uint32_t clk_src_index = GET_CLK_SRC_INDEX(src);
402 HPM_SYSCTL->DACCLK[node_or_instance] =
403 (HPM_SYSCTL->DACCLK[node_or_instance] & ~SYSCTL_DACCLK_MUX_MASK) | SYSCTL_DACCLK_MUX_SET(clk_src_index);
404
405 return status_success;
406 }
407
clock_set_wdg_source(clock_name_t clock_name,clk_src_t src)408 hpm_stat_t clock_set_wdg_source(clock_name_t clock_name, clk_src_t src)
409 {
410 uint32_t clk_src_grp = GET_CLK_SRC_GROUP(clock_name);
411 if ((clk_src_grp != CLK_SRC_GROUP_EWDG) && (clk_src_grp != CLK_SRC_GROUP_PEWDG)) {
412 return status_invalid_argument;
413 }
414 if (clock_name == clock_pwdg) {
415 if ((src == clk_pwdg_src_osc24m) || (src == clk_pwdg_src_osc32k)) {
416 uint32_t wdg_clk_src_in_ip = (uint32_t)(src - clk_pwdg_src_osc24m);
417 HPM_PEWDG->CTRL0 = (HPM_PEWDG->CTRL0 & ~EWDG_CTRL0_CLK_SEL_MASK) | EWDG_CTRL0_CLK_SEL_SET(wdg_clk_src_in_ip);
418 } else {
419 return status_invalid_argument;
420 }
421 } else {
422 uint32_t instance = GET_CLK_SRC_INDEX(clock_name);
423 if ((src == clk_wdg_src_ahb0) || (src == clk_wdg_src_osc32k)) {
424 uint32_t wdg_clk_src_in_ip = (uint32_t)(src - clk_wdg_src_ahb0);
425 s_wdgs[instance]->CTRL0 = (s_wdgs[instance]->CTRL0 & ~EWDG_CTRL0_CLK_SEL_MASK) | EWDG_CTRL0_CLK_SEL_SET(wdg_clk_src_in_ip);
426 } else {
427 return status_invalid_argument;
428 }
429 }
430 return status_success;
431 }
432
clock_set_source_divider(clock_name_t clock_name,clk_src_t src,uint32_t div)433 hpm_stat_t clock_set_source_divider(clock_name_t clock_name, clk_src_t src, uint32_t div)
434 {
435 hpm_stat_t status = status_success;
436 uint32_t clk_src_type = GET_CLK_SRC_GROUP_FROM_NAME(clock_name);
437 uint32_t node_or_instance = GET_CLK_NODE_FROM_NAME(clock_name);
438 switch (clk_src_type) {
439 case CLK_SRC_GROUP_COMMON:
440 if ((div < 1U) || (div > 256U)) {
441 status = status_clk_div_invalid;
442 } else {
443 clock_source_t clk_src = GET_CLOCK_SOURCE_FROM_CLK_SRC(src);
444 sysctl_config_clock(HPM_SYSCTL, (clock_node_t) node_or_instance, clk_src, div);
445 }
446 break;
447 case CLK_SRC_GROUP_ADC:
448 case CLK_SRC_GROUP_DAC:
449 case CLK_SRC_GROUP_EWDG:
450 case CLK_SRC_GROUP_PEWDG:
451 case CLK_SRC_GROUP_SRC:
452 status = status_clk_operation_unsupported;
453 break;
454 case CLK_SRC_GROUP_PMIC:
455 status = status_clk_fixed;
456 break;
457 case CLK_SRC_GROUP_AHB:
458 status = status_clk_shared_cpu0;
459 break;
460 case CLK_SRC_GROUP_CPU0:
461 if (node_or_instance == clock_node_cpu0) {
462 /* Note: the AXI and AHB BUS share the same CPU clock, once the CPU clock frequency
463 * changes, the AXI and AHB clock changes accordingly, here the driver ensures the
464 * AXI and AHB bus clock frequency is in valid range.
465 */
466 uint32_t expected_freq = get_frequency_for_source((clock_source_t) src) / div;
467 uint32_t ahb_sub_div = (expected_freq + BUS_FREQ_MAX - 1U) / BUS_FREQ_MAX;
468 sysctl_config_cpu0_domain_clock(HPM_SYSCTL, (clock_source_t) src, div, ahb_sub_div);
469 } else {
470 status = status_clk_shared_cpu0;
471 }
472 break;
473 default:
474 status = status_clk_src_invalid;
475 break;
476 }
477
478 return status;
479 }
480
switch_ip_clock(clock_name_t clock_name,bool on)481 static void switch_ip_clock(clock_name_t clock_name, bool on)
482 {
483 uint32_t resource = GET_CLK_RESOURCE_FROM_NAME(clock_name);
484
485 if (resource < sysctl_resource_end) {
486 uint32_t mode = on ? 1UL : 2UL;
487 HPM_SYSCTL->RESOURCE[resource] =
488 (HPM_SYSCTL->RESOURCE[resource] & ~SYSCTL_RESOURCE_MODE_MASK) | SYSCTL_RESOURCE_MODE_SET(mode);
489 }
490 }
491
492
clock_enable(clock_name_t clock_name)493 void clock_enable(clock_name_t clock_name)
494 {
495 switch_ip_clock(clock_name, CLOCK_ON);
496 }
497
clock_disable(clock_name_t clock_name)498 void clock_disable(clock_name_t clock_name)
499 {
500 switch_ip_clock(clock_name, CLOCK_OFF);
501 }
502
clock_add_to_group(clock_name_t clock_name,uint32_t group)503 void clock_add_to_group(clock_name_t clock_name, uint32_t group)
504 {
505 uint32_t resource = GET_CLK_RESOURCE_FROM_NAME(clock_name);
506
507 if (resource < sysctl_resource_end) {
508 sysctl_enable_group_resource(HPM_SYSCTL, group, resource, true);
509 }
510 }
511
clock_remove_from_group(clock_name_t clock_name,uint32_t group)512 void clock_remove_from_group(clock_name_t clock_name, uint32_t group)
513 {
514 uint32_t resource = GET_CLK_RESOURCE_FROM_NAME(clock_name);
515
516 if (resource < sysctl_resource_end) {
517 sysctl_enable_group_resource(HPM_SYSCTL, group, resource, false);
518 }
519 }
520
clock_check_in_group(clock_name_t clock_name,uint32_t group)521 bool clock_check_in_group(clock_name_t clock_name, uint32_t group)
522 {
523 uint32_t resource = GET_CLK_RESOURCE_FROM_NAME(clock_name);
524
525 return sysctl_check_group_resource_enable(HPM_SYSCTL, group, resource);
526 }
527
clock_connect_group_to_cpu(uint32_t group,uint32_t cpu)528 void clock_connect_group_to_cpu(uint32_t group, uint32_t cpu)
529 {
530 if (cpu == 0U) {
531 HPM_SYSCTL->AFFILIATE[cpu].SET = (1UL << group);
532 }
533 }
534
clock_disconnect_group_from_cpu(uint32_t group,uint32_t cpu)535 void clock_disconnect_group_from_cpu(uint32_t group, uint32_t cpu)
536 {
537 if (cpu == 0U) {
538 HPM_SYSCTL->AFFILIATE[cpu].CLEAR = (1UL << group);
539 }
540 }
541
clock_cpu_delay_us(uint32_t us)542 void clock_cpu_delay_us(uint32_t us)
543 {
544 uint32_t ticks_per_us = (hpm_core_clock + FREQ_1MHz - 1U) / FREQ_1MHz;
545 uint64_t expected_ticks = hpm_csr_get_core_cycle() + ticks_per_us * us;
546 while (hpm_csr_get_core_cycle() < expected_ticks) {
547 }
548 }
549
clock_cpu_delay_ms(uint32_t ms)550 void clock_cpu_delay_ms(uint32_t ms)
551 {
552 uint32_t ticks_per_us = (hpm_core_clock + FREQ_1MHz - 1U) / FREQ_1MHz;
553 uint64_t expected_ticks = hpm_csr_get_core_cycle() + (uint64_t)ticks_per_us * 1000UL * ms;
554 while (hpm_csr_get_core_cycle() < expected_ticks) {
555 }
556 }
557
clock_update_core_clock(void)558 void clock_update_core_clock(void)
559 {
560 hpm_core_clock = clock_get_frequency(clock_cpu0);
561 }
562