blob: 80590108a91a7c035fa793dd9261b137d71c0a5c [file] [log] [blame]
Kristofer Jonsson537c71c2020-05-05 14:17:22 +02001/*
Per Åstrand0fd65ce2021-03-11 10:25:18 +01002 * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
Kristofer Jonsson537c71c2020-05-05 14:17:22 +02003 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/*****************************************************************************
20 * Includes
21 *****************************************************************************/
22
Jonny Svärd136810f2021-10-13 16:04:26 +020023#include "ethosu_device.h"
Bhavik Pateldae5be02020-06-18 15:25:15 +020024#include "ethosu_driver.h"
Jonny Svärd136810f2021-10-13 16:04:26 +020025#include "ethosu_interface.h"
Anton Moberg6eab40b2021-07-07 11:43:51 +020026#include "ethosu_log.h"
Bhavik Pateldae5be02020-06-18 15:25:15 +020027#include "pmu_ethosu.h"
28
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020029#include <assert.h>
Per Åstrande07b1f92020-09-28 08:31:46 +020030#include <inttypes.h>
Bhavik Pateldae5be02020-06-18 15:25:15 +020031#include <stddef.h>
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020032
33/*****************************************************************************
34 * Defines
35 *****************************************************************************/
36
Jonny Svärd136810f2021-10-13 16:04:26 +020037#define MASK_0_31_BITS (0xFFFFFFFF)
38#define MASK_32_47_BITS (0xFFFF00000000)
39
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020040#define COMMA ,
41#define SEMICOLON ;
42
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020043#define EVTYPE(A, name) \
Jonny Svärd136810f2021-10-13 16:04:26 +020044 case PMU_EVENT_##name: \
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020045 return ETHOSU_PMU_##name
46
Jonny Svärd136810f2021-10-13 16:04:26 +020047#define EVID(A, name) (PMU_EVENT_##name)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +020048
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020049/*****************************************************************************
50 * Variables
51 *****************************************************************************/
52
Jonny Svärd136810f2021-10-13 16:04:26 +020053static const enum pmu_event eventbyid[] = {EXPAND_PMU_EVENT(EVID, COMMA)};
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020054
55/*****************************************************************************
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +020056 * Static functions
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020057 *****************************************************************************/
58
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +020059static enum ethosu_pmu_event_type pmu_event_type(uint32_t id)
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020060{
61 switch (id)
62 {
Jonny Svärd136810f2021-10-13 16:04:26 +020063 EXPAND_PMU_EVENT(EVTYPE, SEMICOLON);
Per Åstrande07b1f92020-09-28 08:31:46 +020064 default:
65 LOG_ERR("Unknown PMU event id: 0x%" PRIx32 "\n", id);
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020066 }
67
68 return ETHOSU_PMU_SENTINEL;
69}
70
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +020071static uint32_t pmu_event_value(enum ethosu_pmu_event_type event)
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020072{
Per Åstrand51c18ba2020-09-28 11:25:36 +020073 int a = event;
74 if ((a < ETHOSU_PMU_SENTINEL) && (a >= ETHOSU_PMU_NO_EVENT))
75 {
76 return eventbyid[event];
77 }
78 else
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020079 {
80 return (uint32_t)(-1);
81 }
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020082}
83
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +020084/*****************************************************************************
85 * Functions
86 *****************************************************************************/
Bhavik Patel8e32b0b2020-06-23 13:48:25 +020087
Anton Mobergc6fd88e2021-05-03 17:00:33 +020088void ETHOSU_PMU_Enable(struct ethosu_driver *drv)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +020089{
Anton Moberg6eab40b2021-07-07 11:43:51 +020090 LOG_DEBUG("Enable PMU\n");
Jonny Svärd136810f2021-10-13 16:04:26 +020091 struct pmcr_r pmcr = {0};
92 pmcr.cnt_en = 1;
Anton Moberg0a614292021-03-24 14:08:22 +010093 set_clock_and_power_request(drv, ETHOSU_PMU_REQUEST, ETHOSU_CLOCK_Q_DISABLE, ETHOSU_POWER_Q_DISABLE);
Jonny Svärd136810f2021-10-13 16:04:26 +020094 drv->dev->reg->PMCR.word = pmcr.word;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +020095}
96
Anton Mobergc6fd88e2021-05-03 17:00:33 +020097void ETHOSU_PMU_Disable(struct ethosu_driver *drv)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +020098{
Anton Moberg6eab40b2021-07-07 11:43:51 +020099 LOG_DEBUG("Disable PMU\n");
Anton Moberg0a614292021-03-24 14:08:22 +0100100 set_clock_and_power_request(drv, ETHOSU_PMU_REQUEST, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_ENABLE);
Jonny Svärd136810f2021-10-13 16:04:26 +0200101 drv->dev->reg->PMCR.word = 0;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200102}
103
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200104void ETHOSU_PMU_Set_EVTYPER(struct ethosu_driver *drv, uint32_t num, enum ethosu_pmu_event_type type)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200105{
Kristofer Jonsson1c893b52021-05-26 12:06:14 +0200106 assert(num < ETHOSU_PMU_NCOUNTERS);
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200107 uint32_t val = pmu_event_value(type);
Anton Moberg6eab40b2021-07-07 11:43:51 +0200108 LOG_DEBUG("num=%u, type=%d, val=%u\n", num, type, val);
Jonny Svärd136810f2021-10-13 16:04:26 +0200109 drv->dev->reg->PMEVTYPER[num].word = val;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200110}
111
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200112enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(struct ethosu_driver *drv, uint32_t num)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200113{
Kristofer Jonsson1c893b52021-05-26 12:06:14 +0200114 assert(num < ETHOSU_PMU_NCOUNTERS);
Jonny Svärd136810f2021-10-13 16:04:26 +0200115 uint32_t val = drv->dev->reg->PMEVTYPER[num].word;
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200116 enum ethosu_pmu_event_type type = pmu_event_type(val);
Anton Moberg6eab40b2021-07-07 11:43:51 +0200117 LOG_DEBUG("num=%u, type=%d, val=%u\n", num, type, val);
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200118 return type;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200119}
120
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200121void ETHOSU_PMU_CYCCNT_Reset(struct ethosu_driver *drv)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200122{
Jonny Svärd136810f2021-10-13 16:04:26 +0200123 LOG_DEBUG("Reset PMU cycle counter\n");
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200124 struct pmcr_r pmcr;
Jonny Svärd136810f2021-10-13 16:04:26 +0200125 pmcr.word = drv->dev->reg->PMCR.word;
126 pmcr.cycle_cnt_rst = 1;
127 drv->dev->reg->PMCR.word = pmcr.word;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200128}
129
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200130void ETHOSU_PMU_EVCNTR_ALL_Reset(struct ethosu_driver *drv)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200131{
Anton Moberg6eab40b2021-07-07 11:43:51 +0200132 LOG_DEBUG("Reset all events\n");
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200133 struct pmcr_r pmcr;
Jonny Svärd136810f2021-10-13 16:04:26 +0200134 pmcr.word = drv->dev->reg->PMCR.word;
135 pmcr.event_cnt_rst = 1;
136 drv->dev->reg->PMCR.word = pmcr.word;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200137}
138
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200139void ETHOSU_PMU_CNTR_Enable(struct ethosu_driver *drv, uint32_t mask)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200140{
Anton Moberg6eab40b2021-07-07 11:43:51 +0200141 LOG_DEBUG("mask=0x%08x\n", mask);
Jonny Svärd136810f2021-10-13 16:04:26 +0200142 drv->dev->reg->PMCNTENSET.word = mask;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200143}
144
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200145void ETHOSU_PMU_CNTR_Disable(struct ethosu_driver *drv, uint32_t mask)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200146{
Anton Moberg6eab40b2021-07-07 11:43:51 +0200147 LOG_DEBUG("mask=0x%08x\n", mask);
Jonny Svärd136810f2021-10-13 16:04:26 +0200148 drv->dev->reg->PMCNTENCLR.word = mask;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200149}
150
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200151uint32_t ETHOSU_PMU_CNTR_Status(struct ethosu_driver *drv)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200152{
Jonny Svärd136810f2021-10-13 16:04:26 +0200153 uint32_t pmcntenset = drv->dev->reg->PMCNTENSET.word;
154 LOG_DEBUG("mask=0x%08x\n", pmcntenset);
155 return pmcntenset;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200156}
157
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200158uint64_t ETHOSU_PMU_Get_CCNTR(struct ethosu_driver *drv)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200159{
Jonny Svärd136810f2021-10-13 16:04:26 +0200160 uint32_t val_lo = drv->dev->reg->PMCCNTR.CYCLE_CNT_LO;
161 uint32_t val_hi = drv->dev->reg->PMCCNTR.CYCLE_CNT_HI;
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200162 uint64_t val = ((uint64_t)val_hi << 32) | val_lo;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200163
Jonny Svärd136810f2021-10-13 16:04:26 +0200164 LOG_DEBUG("val=%" PRIu64 "\n", val);
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200165 return val;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200166}
167
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200168void ETHOSU_PMU_Set_CCNTR(struct ethosu_driver *drv, uint64_t val)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200169{
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200170 uint32_t active = ETHOSU_PMU_CNTR_Status(drv) & ETHOSU_PMU_CCNT_Msk;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200171
Anton Moberg6eab40b2021-07-07 11:43:51 +0200172 LOG_DEBUG("val=%llu\n", val);
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200173
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200174 if (active)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200175 {
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200176 ETHOSU_PMU_CNTR_Disable(drv, ETHOSU_PMU_CCNT_Msk);
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200177 }
178
Jonny Svärd136810f2021-10-13 16:04:26 +0200179 drv->dev->reg->PMCCNTR.CYCLE_CNT_LO = val & MASK_0_31_BITS;
180 drv->dev->reg->PMCCNTR.CYCLE_CNT_HI = (val & MASK_32_47_BITS) >> 32;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200181
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200182 if (active)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200183 {
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200184 ETHOSU_PMU_CNTR_Enable(drv, ETHOSU_PMU_CCNT_Msk);
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200185 }
186}
187
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200188uint32_t ETHOSU_PMU_Get_EVCNTR(struct ethosu_driver *drv, uint32_t num)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200189{
Kristofer Jonsson1c893b52021-05-26 12:06:14 +0200190 assert(num < ETHOSU_PMU_NCOUNTERS);
Jonny Svärd136810f2021-10-13 16:04:26 +0200191 uint32_t val = drv->dev->reg->PMEVCNTR[num].word;
192 LOG_DEBUG("num=%u, val=%u\n", num, val);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200193
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200194 return val;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200195}
196
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200197void ETHOSU_PMU_Set_EVCNTR(struct ethosu_driver *drv, uint32_t num, uint32_t val)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200198{
Kristofer Jonsson1c893b52021-05-26 12:06:14 +0200199 assert(num < ETHOSU_PMU_NCOUNTERS);
Anton Moberg6eab40b2021-07-07 11:43:51 +0200200 LOG_DEBUG("num=%u, val=%u\n", num, val);
Jonny Svärd136810f2021-10-13 16:04:26 +0200201 drv->dev->reg->PMEVCNTR[num].word = val;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200202}
203
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200204uint32_t ETHOSU_PMU_Get_CNTR_OVS(struct ethosu_driver *drv)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200205{
Anton Moberg6eab40b2021-07-07 11:43:51 +0200206 LOG_DEBUG("");
Jonny Svärd136810f2021-10-13 16:04:26 +0200207 return drv->dev->reg->PMOVSSET.word;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200208}
209
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200210void ETHOSU_PMU_Set_CNTR_OVS(struct ethosu_driver *drv, uint32_t mask)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200211{
Anton Moberg6eab40b2021-07-07 11:43:51 +0200212 LOG_DEBUG("");
Jonny Svärd136810f2021-10-13 16:04:26 +0200213 drv->dev->reg->PMOVSCLR.word = mask;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200214}
215
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200216void ETHOSU_PMU_Set_CNTR_IRQ_Enable(struct ethosu_driver *drv, uint32_t mask)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200217{
Anton Moberg6eab40b2021-07-07 11:43:51 +0200218 LOG_DEBUG("mask=0x%08x\n", mask);
Jonny Svärd136810f2021-10-13 16:04:26 +0200219 drv->dev->reg->PMINTSET.word = mask;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200220}
221
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200222void ETHOSU_PMU_Set_CNTR_IRQ_Disable(struct ethosu_driver *drv, uint32_t mask)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200223{
Anton Moberg6eab40b2021-07-07 11:43:51 +0200224 LOG_DEBUG("mask=0x%08x\n", mask);
Jonny Svärd136810f2021-10-13 16:04:26 +0200225 drv->dev->reg->PMINTCLR.word = mask;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200226}
227
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200228uint32_t ETHOSU_PMU_Get_IRQ_Enable(struct ethosu_driver *drv)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200229{
Jonny Svärd136810f2021-10-13 16:04:26 +0200230 uint32_t pmint = drv->dev->reg->PMINTSET.word;
231 LOG_DEBUG("mask=0x%08x\n", pmint);
232 return pmint;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200233}
234
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200235void ETHOSU_PMU_CNTR_Increment(struct ethosu_driver *drv, uint32_t mask)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200236{
Anton Moberg6eab40b2021-07-07 11:43:51 +0200237 LOG_DEBUG("");
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200238 uint32_t cntrs_active = ETHOSU_PMU_CNTR_Status(drv);
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200239
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200240 // Disable counters
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200241 ETHOSU_PMU_CNTR_Disable(drv, mask);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200242
243 // Increment cycle counter
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200244 if (mask & ETHOSU_PMU_CCNT_Msk)
245 {
Jonny Svärd136810f2021-10-13 16:04:26 +0200246 uint64_t val = ETHOSU_PMU_Get_CCNTR(drv) + 1;
247 drv->dev->reg->PMCCNTR.CYCLE_CNT_LO = val & MASK_0_31_BITS;
248 drv->dev->reg->PMCCNTR.CYCLE_CNT_HI = (val & MASK_32_47_BITS) >> 32;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200249 }
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200250
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200251 for (int i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
252 {
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200253 if (mask & (1 << i))
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200254 {
Jonny Svärd136810f2021-10-13 16:04:26 +0200255 uint32_t val = ETHOSU_PMU_Get_EVCNTR(drv, i);
256 drv->dev->reg->PMEVCNTR[i].word = val + 1;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200257 }
258 }
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200259
260 // Reenable the active counters
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200261 ETHOSU_PMU_CNTR_Enable(drv, cntrs_active);
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200262}
263
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200264void ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(struct ethosu_driver *drv, enum ethosu_pmu_event_type start_event)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200265{
Anton Moberg6eab40b2021-07-07 11:43:51 +0200266 LOG_DEBUG("start_event=%u\n", start_event);
Per Åstrand0fd65ce2021-03-11 10:25:18 +0100267 uint32_t val = pmu_event_value(start_event);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200268 struct pmccntr_cfg_r cfg;
Jonny Svärd136810f2021-10-13 16:04:26 +0200269 cfg.word = drv->dev->reg->PMCCNTR_CFG.word;
270 cfg.CYCLE_CNT_CFG_START = val;
271 drv->dev->reg->PMCCNTR_CFG.word = cfg.word;
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200272}
273
Anton Mobergc6fd88e2021-05-03 17:00:33 +0200274void ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(struct ethosu_driver *drv, enum ethosu_pmu_event_type stop_event)
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200275{
Anton Moberg6eab40b2021-07-07 11:43:51 +0200276 LOG_DEBUG("stop_event=%u\n", stop_event);
Per Åstrand0fd65ce2021-03-11 10:25:18 +0100277 uint32_t val = pmu_event_value(stop_event);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200278 struct pmccntr_cfg_r cfg;
Jonny Svärd136810f2021-10-13 16:04:26 +0200279 cfg.word = drv->dev->reg->PMCCNTR_CFG.word;
280 cfg.CYCLE_CNT_CFG_STOP = val;
281 drv->dev->reg->PMCCNTR_CFG.word = cfg.word;
282}