aboutsummaryrefslogtreecommitdiff
path: root/ethosu_pmu
diff options
context:
space:
mode:
Diffstat (limited to 'ethosu_pmu')
-rw-r--r--ethosu_pmu/CMakeLists.txt39
-rw-r--r--ethosu_pmu/common.h50
-rw-r--r--ethosu_pmu/driver.c82
-rw-r--r--ethosu_pmu/ethosu_pmu_config.h.in34
-rw-r--r--ethosu_pmu/include/pmu_ethosu.h452
5 files changed, 657 insertions, 0 deletions
diff --git a/ethosu_pmu/CMakeLists.txt b/ethosu_pmu/CMakeLists.txt
new file mode 100644
index 0000000..98c403e
--- /dev/null
+++ b/ethosu_pmu/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the License); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an AS IS BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Global options
+#
+
+set(NPU_PMCR "0x0" CACHE STRING "Register control b0 = CNT_EN = Enable counters (RW), b1 = EVENT_CNT_RST = Reset event counters (WO), b2 = CYCLE_CNT_RST = Reset cycle counter (WO), b[15:11] = Number of event counters (RO)")
+set(NPU_PMCNTENSET "0x0" CACHE STRING "Bit k enables event counter k. k=31 enables the cycle counter. Read value is current status.")
+set(NPU_PMCNTENCLR "0x0" CACHE STRING "Bit k disables event counter k. k=31 disables the cycle counter. Reda value is current status.")
+set(NPU_PMOVSSET "0x0" CACHE STRING "Overflow detection set. Bit k is for counter k. k=31 is cycle counter.")
+set(NPU_PMOVSCLR "0x0" CACHE STRING "Overflow detection clear. Bit k is for counter k. k=31 is cycle counter.")
+set(NPU_PMINTSET "0x0" CACHE STRING "Interrupt set. Bit k is for counter k. k=31 is cycle counter.")
+set(NPU_PMINTCLR "0x8003" CACHE STRING "Interrupt clear. Bit k is for counter k. k=31 is cycle counter.")
+set(NPU_PMCCNTR "0x0" CACHE STRING "Cycle counter, 48 bits value")
+set(NPU_PMCCNTR_CFG "0x0" CACHE STRING "b[9:0] Start Event – this event number starts the cycle counter b[25:16] Stop Event – this event number stops the cycle counter")
+
+#
+# Build binaries
+#
+
+add_library(ethosu_core_driver_pmu STATIC driver.c)
+target_include_directories(ethosu_core_driver_pmu PUBLIC include PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/ethosu_pmu_config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/ethosu_pmu_config.h")
diff --git a/ethosu_pmu/common.h b/ethosu_pmu/common.h
new file mode 100644
index 0000000..f42a65e
--- /dev/null
+++ b/ethosu_pmu/common.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ethosu_pmu_common_h
+#define ethosu_pmu_common_h
+
+#include <stdint.h>
+
+/* Separators for EXPAND_(name) macros */
+#define COMMA ,
+#define SEMICOLON ;
+#define COLON :
+#define NOTHING
+
+#if defined(CPU_CORTEX_M55)
+#define NPU_BASE ((uint32_t)0x41700000)
+#else
+#define NPU_BASE ((uint32_t)0x41105000)
+#endif
+
+#define ETHOSU_PMU_CTRL_BASE (NPU_BASE + ((uint32_t)0x180))
+#define ETHOSU_PMU_CNTR_BASE (NPU_BASE + ((uint32_t)0x300))
+#define ETHOSU_PMU_EVNT_BASE (NPU_BASE + ((uint32_t)0x380))
+
+#define __init __attribute__((constructor))
+#define __exit __attribute__((destructor))
+
+#ifdef NEVER
+#define INIT __init void
+#define EXIT __exit void
+#else
+#define INIT static __init void
+#define EXIT static __init void
+#endif
+
+#endif // mpu_pmu_common_h
diff --git a/ethosu_pmu/driver.c b/ethosu_pmu/driver.c
new file mode 100644
index 0000000..80cd79a
--- /dev/null
+++ b/ethosu_pmu/driver.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "common.h"
+#include "ethosu55_interface.h"
+#include "ethosu_pmu_config.h"
+#include <assert.h>
+#include <ethosu_driver.h>
+#include <pmu_ethosu.h>
+#include <stdint.h>
+
+PMU_Ethosu_ctrl_Type *ethosu_pmu_ctrl = (PMU_Ethosu_ctrl_Type *)ETHOSU_PMU_CTRL_BASE;
+PMU_Ethosu_cntr_Type *ethosu_pmu_cntr = (PMU_Ethosu_cntr_Type *)ETHOSU_PMU_CNTR_BASE;
+PMU_Ethosu_evnt_Type *ethosu_pmu_evnt = (PMU_Ethosu_evnt_Type *)ETHOSU_PMU_EVNT_BASE;
+
+// Local functions & macros
+#define PMUREG0(NAME) INIT_##NAME
+
+#define ETHOSU_PMU_INIT(N) \
+ *ethosu_pmu_ctrl = (PMU_Ethosu_ctrl_Type){.PMCR = PMUREG##N(PMCR), \
+ .PMCNTENSET = PMUREG##N(PMCNTENSET), \
+ .PMCNTENCLR = PMUREG##N(PMCNTENCLR), \
+ .PMOVSSET = PMUREG##N(PMOVSSET), \
+ .PMOVSCLR = PMUREG##N(PMOVSCLR), \
+ .PMINTSET = PMUREG##N(PMINTSET), \
+ .PMINTCLR = PMUREG##N(PMINTCLR), \
+ .PMCCNTR = PMUREG##N(PMCCNTR), \
+ .PMCCNTR_CFG = PMUREG##N(PMCCNTR_CFG)};
+
+// Public interfaces
+
+#define EVTYPE(A, name) \
+ case PMU_EVENT_TYPE_##name: \
+ return ETHOSU_PMU_##name
+enum ethosu_pmu_event_type pmu_event_type(uint32_t id)
+{
+ switch (id)
+ {
+ EXPAND_PMU_EVENT_TYPE(EVTYPE, SEMICOLON);
+ }
+ return ETHOSU_PMU_SENTINEL;
+}
+
+#define EVID(A, name) (PMU_EVENT_TYPE_##name)
+static const enum pmu_event_type eventbyid[] = {EXPAND_PMU_EVENT_TYPE(EVID, COMMA)};
+uint32_t pmu_event_value(enum ethosu_pmu_event_type event)
+{
+ if (!(event < ETHOSU_PMU_SENTINEL) || (event < 0))
+ {
+ return (uint32_t)(-1);
+ }
+
+ return eventbyid[event];
+}
+
+// Driver Init/exit functions
+INIT ethosu_pmu_driver_init(void)
+{
+ ETHOSU_PMU_INIT(0)
+
+ for (int i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
+ {
+ *ethosu_pmu_cntr[i] = 0;
+ *ethosu_pmu_evnt[i] = 0;
+ }
+}
+
+EXIT ethosu_pmu_driver_exit(void) {}
diff --git a/ethosu_pmu/ethosu_pmu_config.h.in b/ethosu_pmu/ethosu_pmu_config.h.in
new file mode 100644
index 0000000..05ca476
--- /dev/null
+++ b/ethosu_pmu/ethosu_pmu_config.h.in
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* ETHOSU_PMU config file */
+#ifndef ethosu_pmu_config_h
+#define ethosu_pmu_config_h
+
+/* Initial values */
+#define INIT_PMCR (@NPU_PMCR@)
+#define INIT_PMCNTENSET (@NPU_PMCNTENSET@)
+#define INIT_PMCNTENCLR (@NPU_PMCNTENCLR@)
+#define INIT_PMOVSSET (@NPU_PMOVSSET@)
+#define INIT_PMOVSCLR (@NPU_PMOVSCLR@)
+#define INIT_PMINTSET (@NPU_PMINTSET@)
+#define INIT_PMINTCLR (@NPU_PMINTCLR@)
+#define INIT_PMCCNTR (@NPU_PMCCNTR@)
+#define INIT_PMCCNTR_CFG (@NPU_PMCCNTR_CFG@)
+
+#endif
diff --git a/ethosu_pmu/include/pmu_ethosu.h b/ethosu_pmu/include/pmu_ethosu.h
new file mode 100644
index 0000000..b8b1a23
--- /dev/null
+++ b/ethosu_pmu/include/pmu_ethosu.h
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined(__ICCARM__)
+#pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__clang__)
+#pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef PMU_ETHOSU_H
+#define PMU_ETHOSU_H
+
+#define ETHOSU_PMU_NCOUNTERS 4
+
+#include <cmsis_compiler.h>
+
+#ifdef NOTNOW
+#if defined(CPU_CORTEX_M55)
+#include <core_cm55.h>
+#elif defined(CPU_CORTEX_M33)
+#include <core_cm33.h>
+#else
+#error npu-pmu not supported for CPU
+#endif
+#else
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+#define __I volatile /*!< Defines 'read only' permissions */
+#else
+#define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+#endif
+
+typedef struct
+{
+ __IOM uint32_t PMCR;
+ __IOM uint32_t PMCNTENSET;
+ __IOM uint32_t PMCNTENCLR;
+ __IOM uint32_t PMOVSSET;
+ __IOM uint32_t PMOVSCLR;
+ __IOM uint32_t PMINTSET;
+ __IOM uint32_t PMINTCLR;
+ __IOM uint64_t PMCCNTR;
+ __IOM uint32_t PMCCNTR_CFG;
+} PMU_Ethosu_ctrl_Type;
+
+typedef uint32_t PMU_Ethosu_cntr_Type[ETHOSU_PMU_NCOUNTERS];
+typedef uint32_t PMU_Ethosu_evnt_Type[ETHOSU_PMU_NCOUNTERS];
+
+/** \brief HW Supported ETHOSU PMU Events
+ *
+ * Note: These values are symbolic. Actual HW-values may change. I.e. always use API
+ * to set/get actual event-type value.
+ * */
+enum ethosu_pmu_event_type
+{
+ ETHOSU_PMU_CYCLE = 0,
+ ETHOSU_PMU_NPU_IDLE,
+ ETHOSU_PMU_MAC_ACTIVE,
+ ETHOSU_PMU_MAC_ACTIVE_8BIT,
+ ETHOSU_PMU_MAC_ACTIVE_16BIT,
+ ETHOSU_PMU_MAC_DPU_ACTIVE,
+ ETHOSU_PMU_MAC_STALLED_BY_WD_ACC,
+ ETHOSU_PMU_MAC_STALLED_BY_WD,
+ ETHOSU_PMU_MAC_STALLED_BY_ACC,
+ ETHOSU_PMU_MAC_STALLED_BY_IB,
+ ETHOSU_PMU_AO_ACTIVE,
+ ETHOSU_PMU_AO_ACTIVE_8BIT,
+ ETHOSU_PMU_AO_ACTIVE_16BIT,
+ ETHOSU_PMU_AO_STALLED_BY_OFMP_OB,
+ ETHOSU_PMU_AO_STALLED_BY_OFMP,
+ ETHOSU_PMU_AO_STALLED_BY_OB,
+ ETHOSU_PMU_AO_STALLED_BY_ACC_IB,
+ ETHOSU_PMU_AO_STALLED_BY_ACC,
+ ETHOSU_PMU_AO_STALLED_BY_IB,
+ ETHOSU_PMU_WD_ACTIVE,
+ ETHOSU_PMU_WD_STALLED,
+ ETHOSU_PMU_WD_STALLED_BY_WS,
+ ETHOSU_PMU_WD_STALLED_BY_WD_BUF,
+ ETHOSU_PMU_WD_PARSE_ACTIVE,
+ ETHOSU_PMU_WD_PARSE_STALLED,
+ ETHOSU_PMU_WD_PARSE_STALLED_IN,
+ ETHOSU_PMU_WD_PARSE_STALLED_OUT,
+ ETHOSU_PMU_AXI0_RD_TRANS_ACCEPTED,
+ ETHOSU_PMU_AXI0_RD_TRANS_COMPLETED,
+ ETHOSU_PMU_AXI0_RD_DATA_BEAT_RECEIVED,
+ ETHOSU_PMU_AXI0_RD_TRAN_REQ_STALLED,
+ ETHOSU_PMU_AXI0_WR_TRANS_ACCEPTED,
+ ETHOSU_PMU_AXI0_WR_TRANS_COMPLETED_M,
+ ETHOSU_PMU_AXI0_WR_TRANS_COMPLETED_S,
+ ETHOSU_PMU_AXI0_WR_DATA_BEAT_WRITTEN,
+ ETHOSU_PMU_AXI0_WR_TRAN_REQ_STALLED,
+ ETHOSU_PMU_AXI0_WR_DATA_BEAT_STALLED,
+ ETHOSU_PMU_AXI0_ENABLED_CYCLES,
+ ETHOSU_PMU_AXI0_RD_STALL_LIMIT,
+ ETHOSU_PMU_AXI0_WR_STALL_LIMIT,
+ ETHOSU_PMU_AXI1_RD_TRANS_ACCEPTED,
+ ETHOSU_PMU_AXI1_RD_TRANS_COMPLETED,
+ ETHOSU_PMU_AXI1_RD_DATA_BEAT_RECEIVED,
+ ETHOSU_PMU_AXI1_RD_TRAN_REQ_STALLED,
+ ETHOSU_PMU_AXI1_WR_TRANS_ACCEPTED,
+ ETHOSU_PMU_AXI1_WR_TRANS_COMPLETED_M,
+ ETHOSU_PMU_AXI1_WR_TRANS_COMPLETED_S,
+ ETHOSU_PMU_AXI1_WR_DATA_BEAT_WRITTEN,
+ ETHOSU_PMU_AXI1_WR_TRAN_REQ_STALLED,
+ ETHOSU_PMU_AXI1_WR_DATA_BEAT_STALLED,
+ ETHOSU_PMU_AXI1_ENABLED_CYCLES,
+ ETHOSU_PMU_AXI1_RD_STALL_LIMIT,
+ ETHOSU_PMU_AXI1_WR_STALL_LIMIT,
+ ETHOSU_PMU_AXI_LATENCY_ANY,
+ ETHOSU_PMU_AXI_LATENCY_32,
+ ETHOSU_PMU_AXI_LATENCY_64,
+ ETHOSU_PMU_AXI_LATENCY_128,
+ ETHOSU_PMU_AXI_LATENCY_256,
+ ETHOSU_PMU_AXI_LATENCY_512,
+ ETHOSU_PMU_AXI_LATENCY_1024,
+
+ ETHOSU_PMU_SENTINEL // End-marker (not event)
+};
+
+extern PMU_Ethosu_ctrl_Type *ethosu_pmu_ctrl;
+extern PMU_Ethosu_cntr_Type *ethosu_pmu_cntr;
+extern PMU_Ethosu_evnt_Type *ethosu_pmu_evnt;
+
+#define ETHOSU_PMU_CTRL_ENABLE_Msk (0x0001)
+#define ETHOSU_PMU_CTRL_EVENTCNT_RESET_Msk (0x0002)
+#define ETHOSU_PMU_CTRL_CYCCNT_RESET_Msk (0x0004)
+#define ETHOSU_PMU_CNT1_Msk (1UL << 0)
+#define ETHOSU_PMU_CNT2_Msk (1UL << 1)
+#define ETHOSU_PMU_CNT3_Msk (1UL << 2)
+#define ETHOSU_PMU_CNT4_Msk (1UL << 3)
+#define ETHOSU_PMU_CCNT_Msk (1UL << 31)
+
+/* Transpose functions between HW-event-type and event-id*/
+enum ethosu_pmu_event_type pmu_event_type(uint32_t);
+uint32_t pmu_event_value(enum ethosu_pmu_event_type);
+
+// CMSIS ref API
+/** \brief PMU Functions */
+
+__STATIC_INLINE void ETHOSU_PMU_Enable(void);
+__STATIC_INLINE void ETHOSU_PMU_Disable(void);
+
+__STATIC_INLINE void ETHOSU_PMU_Set_EVTYPER(uint32_t num, enum ethosu_pmu_event_type type);
+__STATIC_INLINE enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(uint32_t num);
+
+__STATIC_INLINE void ETHOSU_PMU_CYCCNT_Reset(void);
+__STATIC_INLINE void ETHOSU_PMU_EVCNTR_ALL_Reset(void);
+
+__STATIC_INLINE void ETHOSU_PMU_CNTR_Enable(uint32_t mask);
+__STATIC_INLINE void ETHOSU_PMU_CNTR_Disable(uint32_t mask);
+__STATIC_INLINE uint32_t ETHOSU_PMU_CNTR_Status();
+
+__STATIC_INLINE uint64_t ETHOSU_PMU_Get_CCNTR(void);
+__STATIC_INLINE void ETHOSU_PMU_Set_CCNTR(uint64_t val);
+__STATIC_INLINE uint32_t ETHOSU_PMU_Get_EVCNTR(uint32_t num);
+__STATIC_INLINE void ETHOSU_PMU_Set_EVCNTR(uint32_t num, uint32_t val);
+
+__STATIC_INLINE uint32_t ETHOSU_PMU_Get_CNTR_OVS(void);
+__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_OVS(uint32_t mask);
+
+__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_IRQ_Enable(uint32_t mask);
+__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_IRQ_Disable(uint32_t mask);
+__STATIC_INLINE uint32_t ETHOSU_PMU_Get_IRQ_Enable();
+
+__STATIC_INLINE void ETHOSU_PMU_CNTR_Increment(uint32_t mask);
+
+/**
+ \brief Enable the PMU
+*/
+__STATIC_INLINE void ETHOSU_PMU_Enable(void)
+{
+ ethosu_pmu_ctrl->PMCR |= ETHOSU_PMU_CTRL_ENABLE_Msk;
+}
+
+/**
+ \brief Disable the PMU
+*/
+__STATIC_INLINE void ETHOSU_PMU_Disable(void)
+{
+ ethosu_pmu_ctrl->PMCR &= ~ETHOSU_PMU_CTRL_ENABLE_Msk;
+}
+
+/**
+ \brief Set event to count for PMU eventer counter
+ \param [in] num Event counter (0-ETHOSU_PMU_NCOUNTERS) to configure
+ \param [in] type Event to count
+*/
+__STATIC_INLINE void ETHOSU_PMU_Set_EVTYPER(uint32_t num, enum ethosu_pmu_event_type type)
+{
+ (*ethosu_pmu_evnt)[num] = pmu_event_value(type);
+}
+
+/**
+ \brief Get event to count for PMU eventer counter
+ \param [in] num Event counter (0-ETHOSU_PMU_NCOUNTERS) to configure
+ \return type Event to count
+*/
+__STATIC_INLINE enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(uint32_t num)
+{
+ return pmu_event_type((*ethosu_pmu_evnt)[num]);
+}
+
+/**
+ \brief Reset cycle counter
+*/
+__STATIC_INLINE void ETHOSU_PMU_CYCCNT_Reset(void)
+{
+ ethosu_pmu_ctrl->PMCR |= ETHOSU_PMU_CTRL_CYCCNT_RESET_Msk;
+}
+
+/**
+ \brief Reset all event counters
+*/
+__STATIC_INLINE void ETHOSU_PMU_EVCNTR_ALL_Reset(void)
+{
+ ethosu_pmu_ctrl->PMCR |= ETHOSU_PMU_CTRL_EVENTCNT_RESET_Msk;
+}
+
+/**
+ \brief Enable counters
+ \param [in] mask Counters to enable
+ \note Enables one or more of the following:
+ - event counters (bit 0-ETHOSU_PMU_NCOUNTERS)
+ - cycle counter (bit 31)
+*/
+__STATIC_INLINE void ETHOSU_PMU_CNTR_Enable(uint32_t mask)
+{
+ ethosu_pmu_ctrl->PMCNTENSET = mask;
+}
+
+/**
+ \brief Disable counters
+ \param [in] mask Counters to disable
+ \note Disables one or more of the following:
+ - event counters (bit 0-ETHOSU_PMU_NCOUNTERS)
+ - cycle counter (bit 31)
+*/
+__STATIC_INLINE void ETHOSU_PMU_CNTR_Disable(uint32_t mask)
+{
+ ethosu_pmu_ctrl->PMCNTENCLR = mask;
+}
+
+/**
+ \brief Determine counters activation
+
+ \return Event count
+ \param [in] mask Counters to enable
+ \return a bitmask where bit-set means:
+ - event counters activated (bit 0-ETHOSU_PMU_NCOUNTERS)
+ - cycle counter activate (bit 31)
+ \note ETHOSU specific. Usage breaks CMSIS complience
+*/
+__STATIC_INLINE uint32_t ETHOSU_PMU_CNTR_Status()
+{
+ return ethosu_pmu_ctrl->PMCNTENSET;
+}
+
+/**
+ \brief Read cycle counter (64 bit)
+ \return Cycle count
+ \note Two HW 32-bit registers that can increment independently in-between reads.
+ To work-around raciness yet still avoid turning
+ off the event both are read as one value twice. If the latter read
+ is not greater than the former, it means overflow of LSW without
+ incrementing MSW has occurred, in which case the former value is used.
+*/
+__STATIC_INLINE uint64_t ETHOSU_PMU_Get_CCNTR(void)
+{
+ uint64_t val1 = ethosu_pmu_ctrl->PMCCNTR;
+ uint64_t val2 = ethosu_pmu_ctrl->PMCCNTR;
+
+ if (val2 > val1)
+ {
+ return val2;
+ }
+ return val1;
+}
+
+/**
+ \brief Set cycle counter (64 bit)
+ \param [in] val Conter value
+ \note Two HW 32-bit registers that can increment independently in-between reads.
+ To work-around raciness, counter is temporary disabled if enabled.
+ \note ETHOSU specific. Usage breaks CMSIS complience
+*/
+__STATIC_INLINE void ETHOSU_PMU_Set_CCNTR(uint64_t val)
+{
+ uint32_t mask = ETHOSU_PMU_CNTR_Status();
+
+ if (mask & ETHOSU_PMU_CCNT_Msk)
+ {
+ ETHOSU_PMU_CNTR_Disable(ETHOSU_PMU_CCNT_Msk);
+ }
+
+ ethosu_pmu_ctrl->PMCCNTR = val;
+
+ if (mask & ETHOSU_PMU_CCNT_Msk)
+ {
+ ETHOSU_PMU_CNTR_Enable(ETHOSU_PMU_CCNT_Msk);
+ }
+}
+
+/**
+ \brief Read event counter
+ \param [in] num Event counter (0-ETHOSU_PMU_NCOUNTERS)
+ \return Event count
+*/
+__STATIC_INLINE uint32_t ETHOSU_PMU_Get_EVCNTR(uint32_t num)
+{
+ return (*ethosu_pmu_cntr)[num];
+}
+
+/**
+ \brief Set event counter value
+ \param [in] num Event counter (0-ETHOSU_PMU_NCOUNTERS)
+ \param [in] val Conter value
+ \note ETHOSU specific. Usage breaks CMSIS complience
+*/
+__STATIC_INLINE void ETHOSU_PMU_Set_EVCNTR(uint32_t num, uint32_t val)
+{
+ (*ethosu_pmu_cntr)[num] = val;
+}
+/**
+ \brief Read counter overflow status
+ \return Counter overflow status bits for the following:
+ - event counters (bit 0-ETHOSU_PMU_NCOUNTERS))
+ - cycle counter (bit 31)
+*/
+__STATIC_INLINE uint32_t ETHOSU_PMU_Get_CNTR_OVS(void)
+{
+ return ethosu_pmu_ctrl->PMOVSSET;
+}
+
+/**
+ \brief Clear counter overflow status
+ \param [in] mask Counter overflow status bits to clear
+ \note Clears overflow status bits for one or more of the following:
+ - event counters (bit 0-ETHOSU_PMU_NCOUNTERS)
+ - cycle counter (bit 31)
+*/
+__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_OVS(uint32_t mask)
+{
+ ethosu_pmu_ctrl->PMOVSCLR = mask;
+}
+
+/**
+ \brief Enable counter overflow interrupt request
+ \param [in] mask Counter overflow interrupt request bits to set
+ \note Sets overflow interrupt request bits for one or more of the following:
+ - event counters (bit 0-ETHOSU_PMU_NCOUNTERS)
+ - cycle counter (bit 31)
+*/
+__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_IRQ_Enable(uint32_t mask)
+{
+ ethosu_pmu_ctrl->PMINTSET = mask;
+}
+
+/**
+ \brief Disable counter overflow interrupt request
+ \param [in] mask Counter overflow interrupt request bits to clear
+ \note Clears overflow interrupt request bits for one or more of the following:
+ - event counters (bit 0-ETHOSU_PMU_NCOUNTERS)
+ - cycle counter (bit 31)
+*/
+__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_IRQ_Disable(uint32_t mask)
+{
+ ethosu_pmu_ctrl->PMINTCLR = mask;
+}
+
+/**
+ \brief Get counters overflow interrupt request stiinings
+ \return mask Counter overflow interrupt request bits
+ \note Sets overflow interrupt request bits for one or more of the following:
+ - event counters (bit 0-ETHOSU_PMU_NCOUNTERS)
+ - cycle counter (bit 31)
+ \note ETHOSU specific. Usage breaks CMSIS complience
+*/
+__STATIC_INLINE uint32_t ETHOSU_PMU_Get_IRQ_Enable()
+{
+ return ethosu_pmu_ctrl->PMINTSET;
+}
+
+/**
+ \brief Software increment event counter
+ \param [in] mask Counters to increment
+ - event counters (bit 0-ETHOSU_PMU_NCOUNTERS)
+ - cycle counter (bit 31)
+ \note Software increment bits for one or more event counters.
+*/
+__STATIC_INLINE void ETHOSU_PMU_CNTR_Increment(uint32_t mask)
+{
+ uint32_t cntrs_active = ETHOSU_PMU_CNTR_Status();
+
+ if (mask & ETHOSU_PMU_CCNT_Msk)
+ {
+ if (mask & ETHOSU_PMU_CCNT_Msk)
+ {
+ ETHOSU_PMU_CNTR_Disable(ETHOSU_PMU_CCNT_Msk);
+ ethosu_pmu_ctrl->PMCCNTR = ETHOSU_PMU_Get_CCNTR() + 1;
+ if (cntrs_active & ETHOSU_PMU_CCNT_Msk)
+ {
+ ETHOSU_PMU_CNTR_Enable(ETHOSU_PMU_CCNT_Msk);
+ }
+ }
+ }
+ for (int i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
+ {
+ uint32_t cntr = (0x0001 << i);
+
+ if (mask & cntr)
+ {
+ ETHOSU_PMU_CNTR_Disable(cntr);
+ (*ethosu_pmu_cntr)[i]++;
+ if (cntrs_active & cntr)
+ {
+ ETHOSU_PMU_CNTR_Enable(cntr);
+ }
+ }
+ }
+}
+
+#endif /* PMU_ETHOSU_H */