aboutsummaryrefslogtreecommitdiff
path: root/src/ethosu_pmu.c
diff options
context:
space:
mode:
authorBhavik Patel <bhavik.patel@arm.com>2020-06-23 13:48:25 +0200
committerBhavik Patel <bhavik.patel@arm.com>2020-07-02 19:00:39 +0200
commit8e32b0b72be3b109a921bcb33778eb515d27ef70 (patch)
tree7554a04678112784861cbed80d1e41a8a3215efd /src/ethosu_pmu.c
parenta20e5a734a0d211c7e4395b6e5d7519d28a96b3c (diff)
downloadethos-u-core-driver-8e32b0b72be3b109a921bcb33778eb515d27ef70.tar.gz
Move PMU functions from pmu_ethosu.h to ethosu_pmu.c
This change is done as a prerequisite to be able to set base address for NPU through ethosu_init(). So instead of using a mamory mapped struct we use the same functions to read/write PMU registers as the rest of the ethos-u driver. Change-Id: Ie1f6e6af4627cbe9375e2b2d079ba8017b6294d3
Diffstat (limited to 'src/ethosu_pmu.c')
-rw-r--r--src/ethosu_pmu.c211
1 files changed, 192 insertions, 19 deletions
diff --git a/src/ethosu_pmu.c b/src/ethosu_pmu.c
index 5e5490c..1d3b66c 100644
--- a/src/ethosu_pmu.c
+++ b/src/ethosu_pmu.c
@@ -34,24 +34,21 @@
#define COMMA ,
#define SEMICOLON ;
-#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 EVTYPE(A, name) \
case PMU_EVENT_TYPE_##name: \
return ETHOSU_PMU_##name
#define EVID(A, name) (PMU_EVENT_TYPE_##name)
+#define ETHOSU_PMCCNTR_CFG_START_STOP_EVENT_MASK (0x3FF)
+
+#define NPU_REG_PMEVCNTR(x) (NPU_REG_PMEVCNTR0 + ((x) * sizeof(uint32_t)))
+#define NPU_REG_PMEVTYPER(x) (NPU_REG_PMEVTYPER0 + ((x) * sizeof(uint32_t)))
+
/*****************************************************************************
* Variables
*****************************************************************************/
-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;
-
static const enum pmu_event_type eventbyid[] = {EXPAND_PMU_EVENT_TYPE(EVID, COMMA)};
/*****************************************************************************
@@ -81,22 +78,198 @@ uint32_t pmu_event_value(enum ethosu_pmu_event_type event)
void ethosu_pmu_driver_init(void)
{
#ifdef PMU_AUTOINIT
- *ethosu_pmu_ctrl = (PMU_Ethosu_ctrl_Type){.PMCR = INIT_PMCR,
- .PMCNTENSET = INIT_PMCNTENSET,
- .PMCNTENCLR = INIT_PMCNTENCLR,
- .PMOVSSET = INIT_PMOVSSET,
- .PMOVSCLR = INIT_PMOVSCLR,
- .PMINTSET = INIT_PMINTSET,
- .PMINTCLR = INIT_PMINTCLR,
- .PMCCNTR = INIT_PMCCNTR,
- .PMCCNTR_CFG = INIT_PMCCNTR_CFG};
+ write_reg(NPU_REG_PMCR, INIT_PMCR);
+ write_reg(NPU_REG_PMCNTENSET, INIT_PMCNTENSET);
+ write_reg(NPU_REG_PMCNTENCLR, INIT_PMCNTENCLR);
+ write_reg(NPU_REG_PMOVSSET, INIT_PMOVSSET);
+ write_reg(NPU_REG_PMOVSCLR, INIT_PMOVSCLR);
+ write_reg(NPU_REG_PMINTSET, INIT_PMINTSET);
+ write_reg(NPU_REG_PMINTCLR, INIT_PMINTCLR);
+ write_reg(NPU_REG_PMCCNTR_LO, INIT_PMCCNTR);
+ write_reg(NPU_REG_PMCCNTR_HI, INIT_PMCCNTR);
+ write_reg(NPU_REG_PMCCNTR_CFG, INIT_PMCCNTR_CFG);
for (int i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
{
- *ethosu_pmu_cntr[i] = 0;
- *ethosu_pmu_evnt[i] = 0;
+ write_reg(NPU_REG_PMEVCNTR(i), 0);
+ write_reg(NPU_REG_PMEVTYPER(i), 0);
}
#endif
}
void ethosu_pmu_driver_exit(void) {}
+
+void ETHOSU_PMU_Enable(void)
+{
+ struct pmcr_r pmcr;
+ pmcr.word = read_reg(NPU_REG_PMCR);
+ pmcr.cnt_en = 1;
+ write_reg(NPU_REG_PMCR, pmcr.word);
+}
+
+void ETHOSU_PMU_Disable(void)
+{
+ struct pmcr_r pmcr;
+ pmcr.word = read_reg(NPU_REG_PMCR);
+ pmcr.cnt_en = 0;
+ write_reg(NPU_REG_PMCR, pmcr.word);
+}
+
+void ETHOSU_PMU_Set_EVTYPER(uint32_t num, enum ethosu_pmu_event_type type)
+{
+ write_reg(NPU_REG_PMEVTYPER(num), pmu_event_value(type));
+}
+
+enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(uint32_t num)
+{
+ return pmu_event_type(read_reg(NPU_REG_PMEVTYPER(num)));
+}
+
+void ETHOSU_PMU_CYCCNT_Reset(void)
+{
+ struct pmcr_r pmcr;
+ pmcr.word = read_reg(NPU_REG_PMCR);
+ pmcr.cycle_cnt_rst = 1;
+ write_reg(NPU_REG_PMCR, pmcr.word);
+}
+
+void ETHOSU_PMU_EVCNTR_ALL_Reset(void)
+{
+ struct pmcr_r pmcr;
+ pmcr.word = read_reg(NPU_REG_PMCR);
+ pmcr.event_cnt_rst = 1;
+ write_reg(NPU_REG_PMCR, pmcr.word);
+}
+
+void ETHOSU_PMU_CNTR_Enable(uint32_t mask)
+{
+ write_reg(NPU_REG_PMCNTENSET, mask);
+}
+
+void ETHOSU_PMU_CNTR_Disable(uint32_t mask)
+{
+ write_reg(NPU_REG_PMCNTENCLR, mask);
+}
+
+uint32_t ETHOSU_PMU_CNTR_Status()
+{
+ return read_reg(NPU_REG_PMCNTENSET);
+}
+
+uint64_t ETHOSU_PMU_Get_CCNTR(void)
+{
+ uint64_t val1 = (((uint64_t)read_reg(NPU_REG_PMCCNTR_HI)) << 32) | read_reg(NPU_REG_PMCCNTR_LO);
+ uint64_t val2 = (((uint64_t)read_reg(NPU_REG_PMCCNTR_HI)) << 32) | read_reg(NPU_REG_PMCCNTR_LO);
+
+ if (val2 > val1)
+ {
+ return val2;
+ }
+ return val1;
+}
+
+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);
+ }
+
+ write_reg(NPU_REG_PMCCNTR_LO, (val & MASK_0_31_BITS));
+ write_reg(NPU_REG_PMCCNTR_HI, (val & MASK_32_47_BITS) >> 32);
+
+ if (mask & ETHOSU_PMU_CCNT_Msk)
+ {
+ ETHOSU_PMU_CNTR_Enable(ETHOSU_PMU_CCNT_Msk);
+ }
+}
+
+uint32_t ETHOSU_PMU_Get_EVCNTR(uint32_t num)
+{
+ return read_reg(NPU_REG_PMEVCNTR(num));
+}
+
+void ETHOSU_PMU_Set_EVCNTR(uint32_t num, uint32_t val)
+{
+ write_reg(NPU_REG_PMEVCNTR(num), val);
+}
+
+uint32_t ETHOSU_PMU_Get_CNTR_OVS(void)
+{
+ return read_reg(NPU_REG_PMOVSSET);
+}
+
+// TODO: check if this function name match with the description &
+// implementation.
+void ETHOSU_PMU_Set_CNTR_OVS(uint32_t mask)
+{
+ write_reg(NPU_REG_PMOVSCLR, mask);
+}
+
+void ETHOSU_PMU_Set_CNTR_IRQ_Enable(uint32_t mask)
+{
+ write_reg(NPU_REG_PMINTSET, mask);
+}
+
+void ETHOSU_PMU_Set_CNTR_IRQ_Disable(uint32_t mask)
+{
+ write_reg(NPU_REG_PMINTCLR, mask);
+}
+
+uint32_t ETHOSU_PMU_Get_IRQ_Enable()
+{
+ return read_reg(NPU_REG_PMINTSET);
+}
+
+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);
+ uint64_t val = ETHOSU_PMU_Get_CCNTR() + 1;
+ write_reg(NPU_REG_PMCCNTR_LO, (val & MASK_0_31_BITS));
+ write_reg(NPU_REG_PMCCNTR_HI, (val & MASK_32_47_BITS) >> 32);
+ 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);
+ uint32_t val = read_reg(NPU_REG_PMEVCNTR(i));
+ write_reg(NPU_REG_PMEVCNTR(i), val + 1);
+ if (cntrs_active & cntr)
+ {
+ ETHOSU_PMU_CNTR_Enable(cntr);
+ }
+ }
+ }
+}
+
+void ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(uint32_t start_event)
+{
+ struct pmccntr_cfg_r cfg;
+ cfg.word = read_reg(NPU_REG_PMCCNTR_CFG);
+ cfg.CYCLE_CNT_CFG_START = start_event & ETHOSU_PMCCNTR_CFG_START_STOP_EVENT_MASK;
+ write_reg(NPU_REG_PMCCNTR_CFG, cfg.word);
+}
+
+void ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(uint32_t stop_event)
+{
+ struct pmccntr_cfg_r cfg;
+ cfg.word = read_reg(NPU_REG_PMCCNTR_CFG);
+ cfg.CYCLE_CNT_CFG_STOP = stop_event & ETHOSU_PMCCNTR_CFG_START_STOP_EVENT_MASK;
+ write_reg(NPU_REG_PMCCNTR_CFG, cfg.word);
+}