1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  * Copyright (c) 2019 Intel Corp.
4  */
5 
6 #include <zephyr/kernel.h>
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/counter.h>
9 
10 #define NR_SAMPLES 10	/* sample timer 10 times */
11 
12 #if defined(CONFIG_COUNTER_CMOS)
sync(const struct device * cmos)13 static uint32_t sync(const struct device *cmos)
14 {
15 	uint32_t this, last;
16 	int err;
17 
18 	err = counter_get_value(cmos, &this);
19 	if (err) {
20 		printk("\tCan't read CMOS clock device.\n");
21 		return 0;
22 	}
23 
24 	do {
25 		last = this;
26 		err = counter_get_value(cmos, &this);
27 		if (err) {
28 			printk("\tCan't read CMOS clock device.\n");
29 			return 0;
30 		}
31 	} while (last == this);
32 
33 	return sys_clock_cycle_get_32();
34 }
35 #endif
36 
timer(void)37 void timer(void)
38 {
39 #if defined(CONFIG_APIC_TIMER)
40 	printk("TIMER: new local APIC");
41 #elif defined(CONFIG_HPET_TIMER)
42 	printk("TIMER: HPET");
43 #else
44 	printk("TIMER: unknown");
45 #endif
46 
47 	printk(", configured frequency = %dHz\n",
48 		sys_clock_hw_cycles_per_sec());
49 
50 #if defined(CONFIG_COUNTER_CMOS)
51 	const struct device *const cmos = DEVICE_DT_GET_ONE(motorola_mc146818);
52 
53 	if (!device_is_ready(cmos)) {
54 		printk("\tCMOS clock device is not ready.\n");
55 	} else {
56 		uint64_t sum = 0;
57 
58 		printk("\tUsing CMOS RTC as reference clock:\n");
59 
60 		for (int i = 0; i < NR_SAMPLES; ++i) {
61 			uint32_t start, end;
62 
63 			start = sync(cmos);
64 			end = sync(cmos);
65 			sum += end - start;
66 
67 			printk("\tstart = %u, end = %u, %u cycles\n",
68 				start, end, end - start);
69 		}
70 
71 		printk("\taverage = %uHz\n", (unsigned) (sum / NR_SAMPLES));
72 	}
73 #endif
74 
75 	printk("\n");
76 }
77