From 5da4092d07c31acaa3d44ac57fa3b02a3be67182 Mon Sep 17 00:00:00 2001 From: Bhavik Patel Date: Wed, 15 Jul 2020 10:06:43 +0200 Subject: MLBEDSW-2594 Initialize the Ethos-U before every job This includes resetting the Ethos-U and restoring the previosuly saved PMU configuration (if any). Change-Id: Id952fb6fef513468952b6a469e857510f8c0214c --- include/ethosu_device.h | 23 +++++++++++++++++++++++ include/pmu_ethosu.h | 1 - src/ethosu_device.c | 39 +++++++++++++++++++++++++++++++++++++++ src/ethosu_driver.c | 9 ++++++++- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/include/ethosu_device.h b/include/ethosu_device.h index 46772ba..81f24a9 100644 --- a/include/ethosu_device.h +++ b/include/ethosu_device.h @@ -22,6 +22,9 @@ * Includes ******************************************************************************/ +#include "pmu_ethosu.h" + +#include #include #ifdef __cplusplus @@ -51,6 +54,10 @@ enum ethosu_error_codes struct ethosu_device { uintptr_t base_address; + bool restore_pmu_config; + uint64_t pmccntr; + uint32_t pmu_evcntr[ETHOSU_PMU_NCOUNTERS]; + enum ethosu_pmu_event_type pmu_evtypr[ETHOSU_PMU_NCOUNTERS]; }; struct ethosu_id @@ -355,6 +362,22 @@ uint32_t ethosu_read_reg(struct ethosu_device *dev, uint32_t address); void ethosu_write_reg(struct ethosu_device *dev, uint32_t address, uint32_t value); +/** + * Save the PMU configuration to ethosu_device struct. + * \param[in] dev Ethos-U device where the PMU configuration is + * saved. + * \return \ref ethosu_error_codes + */ +enum ethosu_error_codes ethosu_save_pmu_config(struct ethosu_device *dev); + +/** + * Restore the PMU configuration from a ethosu_device struct. + * \param[in] dev Ethos-U device where the PMU configuration is + * stored. + * \return \ref ethosu_error_codes + */ +enum ethosu_error_codes ethosu_restore_pmu_config(struct ethosu_device *dev); + #ifdef __cplusplus } #endif diff --git a/include/pmu_ethosu.h b/include/pmu_ethosu.h index e83b879..41614e7 100644 --- a/include/pmu_ethosu.h +++ b/include/pmu_ethosu.h @@ -19,7 +19,6 @@ #ifndef PMU_ETHOSU_H #define PMU_ETHOSU_H -#include "ethosu_device.h" #include #ifdef __cplusplus diff --git a/src/ethosu_device.c b/src/ethosu_device.c index 9bda87d..60fc243 100644 --- a/src/ethosu_device.c +++ b/src/ethosu_device.c @@ -551,3 +551,42 @@ void ethosu_write_reg(struct ethosu_device *dev, uint32_t address, uint32_t valu UNUSED(value); #endif } + +enum ethosu_error_codes ethosu_save_pmu_config(struct ethosu_device *dev) +{ +#if !defined(ARM_NPU_STUB) + dev->pmccntr = ETHOSU_PMU_Get_CCNTR(); + for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++) + { + dev->pmu_evcntr[i] = ETHOSU_PMU_Get_EVCNTR(i); + dev->pmu_evtypr[i] = ETHOSU_PMU_Get_EVTYPER(i); + } + if (!dev->restore_pmu_config) + { + dev->restore_pmu_config = true; + } +#else + UNUSED(dev); +#endif + + return ETHOSU_SUCCESS; +} + +enum ethosu_error_codes ethosu_restore_pmu_config(struct ethosu_device *dev) +{ +#if !defined(ARM_NPU_STUB) + if (dev->restore_pmu_config) + { + ETHOSU_PMU_Set_CCNTR(dev->pmccntr); + for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++) + { + ETHOSU_PMU_Set_EVCNTR(i, dev->pmu_evcntr[i]); + ETHOSU_PMU_Set_EVTYPER(i, dev->pmu_evtypr[i]); + } + } +#else + UNUSED(dev); +#endif + + return ETHOSU_SUCCESS; +} diff --git a/src/ethosu_driver.c b/src/ethosu_driver.c index 1a9337e..9d74980 100644 --- a/src/ethosu_driver.c +++ b/src/ethosu_driver.c @@ -29,7 +29,12 @@ #include #include -struct ethosu_driver ethosu_drv = {.dev = {.base_address = NULL}, .abort_inference = false}; +struct ethosu_driver ethosu_drv = {.dev = {.base_address = NULL, + .restore_pmu_config = false, + .pmccntr = 0, + .pmu_evcntr = {0, 0, 0, 0}, + .pmu_evtypr = {0, 0, 0, 0}}, + .abort_inference = false}; // IRQ static volatile bool irq_triggered = false; @@ -276,6 +281,7 @@ int ethosu_invoke(const void *custom_data_ptr, int custom_data_32bit_size = (custom_data_size / BYTES_IN_32_BITS - CUSTOM_OPTION_LENGTH_32_BIT_WORD); ethosu_set_clock_and_power(ðosu_drv.dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE); + ethosu_restore_pmu_config(ðosu_drv.dev); while (data_ptr < (data_start_ptr + custom_data_32bit_size)) { int ret = 0; @@ -337,6 +343,7 @@ int ethosu_invoke(const void *custom_data_ptr, break; } } + ethosu_save_pmu_config(ðosu_drv.dev); ethosu_set_clock_and_power(ðosu_drv.dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_ENABLE); return return_code; } -- cgit v1.2.1