1 /*
2  * SPDX-FileCopyrightText: <text>Copyright 2025 Arm Limited and/or its
3  * affiliates <open-source-office@arm.com></text>
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /* PMU integration for Ethos-U in Zephyr TFLM sample */
8 
9 #include <ethosu_driver.h>
10 #include <pmu_ethosu.h>
11 
12 #include <cinttypes>
13 #include <cstdio>
14 
15 /* Selected PMU events (configured via CMake definitions ETHOSU_PMU_EVENT_N) */
16 static const enum ethosu_pmu_event_type pmu_events[ETHOSU_PMU_NCOUNTERS] = {
17 	ETHOSU_PMU_EVENT_0, ETHOSU_PMU_EVENT_1, ETHOSU_PMU_EVENT_2, ETHOSU_PMU_EVENT_3,
18 #if (ETHOSU_PMU_NCOUNTERS > 4)
19 	ETHOSU_PMU_EVENT_4, ETHOSU_PMU_EVENT_5, ETHOSU_PMU_EVENT_6, ETHOSU_PMU_EVENT_7,
20 #endif
21 };
22 
pmu_counter_mask(uint32_t idx)23 static inline uint32_t pmu_counter_mask(uint32_t idx)
24 {
25 	switch (idx) {
26 	case 0:
27 		return ETHOSU_PMU_CNT1_Msk;
28 	case 1:
29 		return ETHOSU_PMU_CNT2_Msk;
30 	case 2:
31 		return ETHOSU_PMU_CNT3_Msk;
32 	case 3:
33 		return ETHOSU_PMU_CNT4_Msk;
34 #if (ETHOSU_PMU_NCOUNTERS > 4)
35 	case 4:
36 		return ETHOSU_PMU_CNT5_Msk;
37 	case 5:
38 		return ETHOSU_PMU_CNT6_Msk;
39 	case 6:
40 		return ETHOSU_PMU_CNT7_Msk;
41 	case 7:
42 		return ETHOSU_PMU_CNT8_Msk;
43 #endif
44 	default:
45 		return 0;
46 	}
47 }
48 
ethosu_inference_begin(struct ethosu_driver * drv,void *)49 extern "C" void ethosu_inference_begin(struct ethosu_driver *drv, void *)
50 {
51 	ETHOSU_PMU_Enable(drv);
52 
53 	for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
54 		ETHOSU_PMU_Set_EVTYPER(drv, i, pmu_events[i]);
55 		ETHOSU_PMU_CNTR_Enable(drv, pmu_counter_mask(i));
56 	}
57 
58 	ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(drv, ETHOSU_PMU_NPU_IDLE);
59 	ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(drv, ETHOSU_PMU_NPU_ACTIVE);
60 	ETHOSU_PMU_CNTR_Enable(drv, ETHOSU_PMU_CCNT_Msk);
61 	ETHOSU_PMU_CYCCNT_Reset(drv);
62 	ETHOSU_PMU_EVCNTR_ALL_Reset(drv);
63 }
64 
ethosu_inference_end(struct ethosu_driver * drv,void *)65 extern "C" void ethosu_inference_end(struct ethosu_driver *drv, void *)
66 {
67 	const uint64_t cycles = ETHOSU_PMU_Get_CCNTR(drv);
68 
69 	uint32_t pmu_values[ETHOSU_PMU_NCOUNTERS] = {};
70 	for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
71 		pmu_values[i] = ETHOSU_PMU_Get_EVCNTR(drv, i);
72 	}
73 	ETHOSU_PMU_Disable(drv);
74 
75 	printf("\nEthos-U PMU report:\n");
76 	printf("ethosu_pmu_cycle_cntr : %" PRIu64 "\n", cycles);
77 	for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
78 		printf("ethosu_pmu_cntr%" PRIu32 " : %" PRIu32 "\n", i, pmu_values[i]);
79 	}
80 }
81