From 136810fa7e8f7f21c0bfb17dd5c81b247fc1e305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonny=20Sv=C3=A4rd?= Date: Wed, 13 Oct 2021 16:04:26 +0200 Subject: Autumn clean/refactor of NPU driver A continuation of the spring clean/refactor work. Create a better separation between driver and device(s). A short summary of what this commit contains: - Split device and driver - Simplify and hide the internal device interface - Remove (broken) abort inference functionality - Refactoring of structure - Optimizations and bugfixes Change-Id: I8988bc5f163f9ea62add2a933e4f100a82cc8d35 --- src/ethosu_pmu.c | 138 ++++++++++++++++++++++--------------------------------- 1 file changed, 54 insertions(+), 84 deletions(-) (limited to 'src/ethosu_pmu.c') diff --git a/src/ethosu_pmu.c b/src/ethosu_pmu.c index d1cd79c..8059010 100644 --- a/src/ethosu_pmu.c +++ b/src/ethosu_pmu.c @@ -20,9 +20,9 @@ * Includes *****************************************************************************/ -#include "ethosu55_interface.h" -#include "ethosu_common.h" +#include "ethosu_device.h" #include "ethosu_driver.h" +#include "ethosu_interface.h" #include "ethosu_log.h" #include "pmu_ethosu.h" @@ -34,23 +34,23 @@ * Defines *****************************************************************************/ +#define MASK_0_31_BITS (0xFFFFFFFF) +#define MASK_32_47_BITS (0xFFFF00000000) + #define COMMA , #define SEMICOLON ; #define EVTYPE(A, name) \ - case PMU_EVENT_TYPE_##name: \ + case PMU_EVENT_##name: \ return ETHOSU_PMU_##name -#define EVID(A, name) (PMU_EVENT_TYPE_##name) - -#define NPU_REG_PMEVCNTR(x) (NPU_REG_PMEVCNTR0 + ((x) * sizeof(uint32_t))) -#define NPU_REG_PMEVTYPER(x) (NPU_REG_PMEVTYPER0 + ((x) * sizeof(uint32_t))) +#define EVID(A, name) (PMU_EVENT_##name) /***************************************************************************** * Variables *****************************************************************************/ -static const enum pmu_event_type eventbyid[] = {EXPAND_PMU_EVENT_TYPE(EVID, COMMA)}; +static const enum pmu_event eventbyid[] = {EXPAND_PMU_EVENT(EVID, COMMA)}; /***************************************************************************** * Static functions @@ -60,7 +60,7 @@ static enum ethosu_pmu_event_type pmu_event_type(uint32_t id) { switch (id) { - EXPAND_PMU_EVENT_TYPE(EVTYPE, SEMICOLON); + EXPAND_PMU_EVENT(EVTYPE, SEMICOLON); default: LOG_ERR("Unknown PMU event id: 0x%" PRIx32 "\n", id); } @@ -88,21 +88,17 @@ static uint32_t pmu_event_value(enum ethosu_pmu_event_type event) void ETHOSU_PMU_Enable(struct ethosu_driver *drv) { LOG_DEBUG("Enable PMU\n"); - struct pmcr_r pmcr; - pmcr.word = drv->dev.pmcr; - pmcr.cnt_en = 1; + struct pmcr_r pmcr = {0}; + pmcr.cnt_en = 1; set_clock_and_power_request(drv, ETHOSU_PMU_REQUEST, ETHOSU_CLOCK_Q_DISABLE, ETHOSU_POWER_Q_DISABLE); - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCR, pmcr.word, &drv->dev.pmcr); + drv->dev->reg->PMCR.word = pmcr.word; } void ETHOSU_PMU_Disable(struct ethosu_driver *drv) { LOG_DEBUG("Disable PMU\n"); - struct pmcr_r pmcr; - pmcr.word = drv->dev.pmcr; - pmcr.cnt_en = 0; set_clock_and_power_request(drv, ETHOSU_PMU_REQUEST, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_ENABLE); - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCR, pmcr.word, &drv->dev.pmcr); + drv->dev->reg->PMCR.word = 0; } void ETHOSU_PMU_Set_EVTYPER(struct ethosu_driver *drv, uint32_t num, enum ethosu_pmu_event_type type) @@ -110,13 +106,13 @@ void ETHOSU_PMU_Set_EVTYPER(struct ethosu_driver *drv, uint32_t num, enum ethosu assert(num < ETHOSU_PMU_NCOUNTERS); uint32_t val = pmu_event_value(type); LOG_DEBUG("num=%u, type=%d, val=%u\n", num, type, val); - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMEVTYPER(num), val, &drv->dev.pmu_evtypr[num]); + drv->dev->reg->PMEVTYPER[num].word = val; } enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(struct ethosu_driver *drv, uint32_t num) { assert(num < ETHOSU_PMU_NCOUNTERS); - uint32_t val = drv->dev.pmu_evtypr[num]; + uint32_t val = drv->dev->reg->PMEVTYPER[num].word; enum ethosu_pmu_event_type type = pmu_event_type(val); LOG_DEBUG("num=%u, type=%d, val=%u\n", num, type, val); return type; @@ -124,66 +120,48 @@ enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(struct ethosu_driver *drv, uin void ETHOSU_PMU_CYCCNT_Reset(struct ethosu_driver *drv) { - LOG_DEBUG("Reset PMU\n"); + LOG_DEBUG("Reset PMU cycle counter\n"); struct pmcr_r pmcr; - pmcr.word = drv->dev.pmcr; - pmcr.cycle_cnt_rst = 1; - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCR, pmcr.word, &drv->dev.pmcr); - drv->dev.pmccntr[0] = 0; - drv->dev.pmccntr[1] = 0; + pmcr.word = drv->dev->reg->PMCR.word; + pmcr.cycle_cnt_rst = 1; + drv->dev->reg->PMCR.word = pmcr.word; } void ETHOSU_PMU_EVCNTR_ALL_Reset(struct ethosu_driver *drv) { LOG_DEBUG("Reset all events\n"); struct pmcr_r pmcr; - pmcr.word = drv->dev.pmcr; - pmcr.event_cnt_rst = 1; - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCR, pmcr.word, &drv->dev.pmcr); - - for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++) - { - drv->dev.pmu_evcntr[i] = 0; - } + pmcr.word = drv->dev->reg->PMCR.word; + pmcr.event_cnt_rst = 1; + drv->dev->reg->PMCR.word = pmcr.word; } void ETHOSU_PMU_CNTR_Enable(struct ethosu_driver *drv, uint32_t mask) { LOG_DEBUG("mask=0x%08x\n", mask); - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCNTENSET, mask, &drv->dev.pmcnten); + drv->dev->reg->PMCNTENSET.word = mask; } void ETHOSU_PMU_CNTR_Disable(struct ethosu_driver *drv, uint32_t mask) { LOG_DEBUG("mask=0x%08x\n", mask); - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCNTENCLR, mask, &drv->dev.pmcnten); + drv->dev->reg->PMCNTENCLR.word = mask; } uint32_t ETHOSU_PMU_CNTR_Status(struct ethosu_driver *drv) { - LOG_DEBUG("mask=0x%08x\n", drv->dev.pmcnten); - return drv->dev.pmcnten; + uint32_t pmcntenset = drv->dev->reg->PMCNTENSET.word; + LOG_DEBUG("mask=0x%08x\n", pmcntenset); + return pmcntenset; } uint64_t ETHOSU_PMU_Get_CCNTR(struct ethosu_driver *drv) { - uint32_t val_lo = ethosu_dev_read_reg(&drv->dev, NPU_REG_PMCCNTR_LO); - uint32_t val_hi = ethosu_dev_read_reg(&drv->dev, NPU_REG_PMCCNTR_HI); + uint32_t val_lo = drv->dev->reg->PMCCNTR.CYCLE_CNT_LO; + uint32_t val_hi = drv->dev->reg->PMCCNTR.CYCLE_CNT_HI; uint64_t val = ((uint64_t)val_hi << 32) | val_lo; - uint64_t shadow = ((uint64_t)drv->dev.pmccntr[1] << 32) | drv->dev.pmccntr[0]; - - LOG_DEBUG("val=%" PRIu64 ", shadow=%" PRIu64 "\n", val, shadow); - - // Return the shadow variable in case the NPU was powered off and lost the cycle count - if (shadow > val) - { - return shadow; - } - - // Update the shadow variable - drv->dev.pmccntr[0] = val_lo; - drv->dev.pmccntr[1] = val_hi; + LOG_DEBUG("val=%" PRIu64 "\n", val); return val; } @@ -198,8 +176,8 @@ void ETHOSU_PMU_Set_CCNTR(struct ethosu_driver *drv, uint64_t val) ETHOSU_PMU_CNTR_Disable(drv, ETHOSU_PMU_CCNT_Msk); } - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCCNTR_LO, val & MASK_0_31_BITS, &drv->dev.pmccntr[0]); - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCCNTR_HI, (val & MASK_32_47_BITS) >> 32, &drv->dev.pmccntr[1]); + drv->dev->reg->PMCCNTR.CYCLE_CNT_LO = val & MASK_0_31_BITS; + drv->dev->reg->PMCCNTR.CYCLE_CNT_HI = (val & MASK_32_47_BITS) >> 32; if (active) { @@ -210,17 +188,8 @@ void ETHOSU_PMU_Set_CCNTR(struct ethosu_driver *drv, uint64_t val) uint32_t ETHOSU_PMU_Get_EVCNTR(struct ethosu_driver *drv, uint32_t num) { assert(num < ETHOSU_PMU_NCOUNTERS); - uint32_t val = ethosu_dev_read_reg(&drv->dev, NPU_REG_PMEVCNTR(num)); - LOG_DEBUG("num=%u, val=%u, shadow=%u\n", num, val, drv->dev.pmu_evcntr[num]); - - // Return the shadow variable in case the NPU was powered off and lost the event count - if (drv->dev.pmu_evcntr[num] > val) - { - return drv->dev.pmu_evcntr[num]; - } - - // Update the shadow variable - drv->dev.pmu_evcntr[num] = val; + uint32_t val = drv->dev->reg->PMEVCNTR[num].word; + LOG_DEBUG("num=%u, val=%u\n", num, val); return val; } @@ -229,37 +198,38 @@ void ETHOSU_PMU_Set_EVCNTR(struct ethosu_driver *drv, uint32_t num, uint32_t val { assert(num < ETHOSU_PMU_NCOUNTERS); LOG_DEBUG("num=%u, val=%u\n", num, val); - ethosu_dev_write_reg(&drv->dev, NPU_REG_PMEVCNTR(num), val); + drv->dev->reg->PMEVCNTR[num].word = val; } uint32_t ETHOSU_PMU_Get_CNTR_OVS(struct ethosu_driver *drv) { LOG_DEBUG(""); - return ethosu_dev_read_reg(&drv->dev, NPU_REG_PMOVSSET); + return drv->dev->reg->PMOVSSET.word; } void ETHOSU_PMU_Set_CNTR_OVS(struct ethosu_driver *drv, uint32_t mask) { LOG_DEBUG(""); - ethosu_dev_write_reg(&drv->dev, NPU_REG_PMOVSCLR, mask); + drv->dev->reg->PMOVSCLR.word = mask; } void ETHOSU_PMU_Set_CNTR_IRQ_Enable(struct ethosu_driver *drv, uint32_t mask) { LOG_DEBUG("mask=0x%08x\n", mask); - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMINTSET, mask, &drv->dev.pmint); + drv->dev->reg->PMINTSET.word = mask; } void ETHOSU_PMU_Set_CNTR_IRQ_Disable(struct ethosu_driver *drv, uint32_t mask) { LOG_DEBUG("mask=0x%08x\n", mask); - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMINTCLR, mask, &drv->dev.pmint); + drv->dev->reg->PMINTCLR.word = mask; } uint32_t ETHOSU_PMU_Get_IRQ_Enable(struct ethosu_driver *drv) { - LOG_DEBUG("mask=0x%08x\n", drv->dev.pmint); - return drv->dev.pmint; + uint32_t pmint = drv->dev->reg->PMINTSET.word; + LOG_DEBUG("mask=0x%08x\n", pmint); + return pmint; } void ETHOSU_PMU_CNTR_Increment(struct ethosu_driver *drv, uint32_t mask) @@ -273,17 +243,17 @@ void ETHOSU_PMU_CNTR_Increment(struct ethosu_driver *drv, uint32_t mask) // Increment cycle counter if (mask & ETHOSU_PMU_CCNT_Msk) { - uint64_t val = ETHOSU_PMU_Get_CCNTR(drv) + 1; - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCCNTR_LO, val & MASK_0_31_BITS, &drv->dev.pmccntr[0]); - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCCNTR_HI, (val & MASK_32_47_BITS) >> 32, &drv->dev.pmccntr[1]); + uint64_t val = ETHOSU_PMU_Get_CCNTR(drv) + 1; + drv->dev->reg->PMCCNTR.CYCLE_CNT_LO = val & MASK_0_31_BITS; + drv->dev->reg->PMCCNTR.CYCLE_CNT_HI = (val & MASK_32_47_BITS) >> 32; } for (int i = 0; i < ETHOSU_PMU_NCOUNTERS; i++) { if (mask & (1 << i)) { - uint32_t val = ETHOSU_PMU_Get_EVCNTR(drv, i); - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMEVCNTR(i), val + 1, &drv->dev.pmu_evcntr[i]); + uint32_t val = ETHOSU_PMU_Get_EVCNTR(drv, i); + drv->dev->reg->PMEVCNTR[i].word = val + 1; } } @@ -296,9 +266,9 @@ void ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(struct ethosu_driver *drv, enum etho LOG_DEBUG("start_event=%u\n", start_event); uint32_t val = pmu_event_value(start_event); struct pmccntr_cfg_r cfg; - cfg.word = drv->dev.pmccntr_cfg; - cfg.CYCLE_CNT_CFG_START = val; - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCCNTR_CFG, cfg.word, &drv->dev.pmccntr_cfg); + cfg.word = drv->dev->reg->PMCCNTR_CFG.word; + cfg.CYCLE_CNT_CFG_START = val; + drv->dev->reg->PMCCNTR_CFG.word = cfg.word; } void ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(struct ethosu_driver *drv, enum ethosu_pmu_event_type stop_event) @@ -306,7 +276,7 @@ void ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(struct ethosu_driver *drv, enum ethos LOG_DEBUG("stop_event=%u\n", stop_event); uint32_t val = pmu_event_value(stop_event); struct pmccntr_cfg_r cfg; - cfg.word = drv->dev.pmccntr_cfg; - cfg.CYCLE_CNT_CFG_STOP = val; - ethosu_dev_write_reg_shadow(&drv->dev, NPU_REG_PMCCNTR_CFG, cfg.word, &drv->dev.pmccntr_cfg); -} \ No newline at end of file + cfg.word = drv->dev->reg->PMCCNTR_CFG.word; + cfg.CYCLE_CNT_CFG_STOP = val; + drv->dev->reg->PMCCNTR_CFG.word = cfg.word; +} -- cgit v1.2.1