blob: 1d3b66c42536fd8f632d97ce50dd186db8818594 [file] [log] [blame]
Kristofer Jonsson537c71c2020-05-05 14:17:22 +02001/*
2 * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
3 *
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
23#include "ethosu55_interface.h"
24#include "ethosu_common.h"
25#include <assert.h>
26#include <ethosu_driver.h>
27#include <pmu_ethosu.h>
28#include <stdint.h>
29
30/*****************************************************************************
31 * Defines
32 *****************************************************************************/
33
34#define COMMA ,
35#define SEMICOLON ;
36
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020037#define EVTYPE(A, name) \
38 case PMU_EVENT_TYPE_##name: \
39 return ETHOSU_PMU_##name
40
41#define EVID(A, name) (PMU_EVENT_TYPE_##name)
42
Bhavik Patel8e32b0b2020-06-23 13:48:25 +020043#define ETHOSU_PMCCNTR_CFG_START_STOP_EVENT_MASK (0x3FF)
44
45#define NPU_REG_PMEVCNTR(x) (NPU_REG_PMEVCNTR0 + ((x) * sizeof(uint32_t)))
46#define NPU_REG_PMEVTYPER(x) (NPU_REG_PMEVTYPER0 + ((x) * sizeof(uint32_t)))
47
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020048/*****************************************************************************
49 * Variables
50 *****************************************************************************/
51
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020052static const enum pmu_event_type eventbyid[] = {EXPAND_PMU_EVENT_TYPE(EVID, COMMA)};
53
54/*****************************************************************************
55 * Functions
56 *****************************************************************************/
57
58enum ethosu_pmu_event_type pmu_event_type(uint32_t id)
59{
60 switch (id)
61 {
62 EXPAND_PMU_EVENT_TYPE(EVTYPE, SEMICOLON);
63 }
64
65 return ETHOSU_PMU_SENTINEL;
66}
67
68uint32_t pmu_event_value(enum ethosu_pmu_event_type event)
69{
70 if (!(event < ETHOSU_PMU_SENTINEL) || (event < 0))
71 {
72 return (uint32_t)(-1);
73 }
74
75 return eventbyid[event];
76}
77
78void ethosu_pmu_driver_init(void)
79{
80#ifdef PMU_AUTOINIT
Bhavik Patel8e32b0b2020-06-23 13:48:25 +020081 write_reg(NPU_REG_PMCR, INIT_PMCR);
82 write_reg(NPU_REG_PMCNTENSET, INIT_PMCNTENSET);
83 write_reg(NPU_REG_PMCNTENCLR, INIT_PMCNTENCLR);
84 write_reg(NPU_REG_PMOVSSET, INIT_PMOVSSET);
85 write_reg(NPU_REG_PMOVSCLR, INIT_PMOVSCLR);
86 write_reg(NPU_REG_PMINTSET, INIT_PMINTSET);
87 write_reg(NPU_REG_PMINTCLR, INIT_PMINTCLR);
88 write_reg(NPU_REG_PMCCNTR_LO, INIT_PMCCNTR);
89 write_reg(NPU_REG_PMCCNTR_HI, INIT_PMCCNTR);
90 write_reg(NPU_REG_PMCCNTR_CFG, INIT_PMCCNTR_CFG);
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020091
92 for (int i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
93 {
Bhavik Patel8e32b0b2020-06-23 13:48:25 +020094 write_reg(NPU_REG_PMEVCNTR(i), 0);
95 write_reg(NPU_REG_PMEVTYPER(i), 0);
Kristofer Jonsson537c71c2020-05-05 14:17:22 +020096 }
97#endif
98}
99
100void ethosu_pmu_driver_exit(void) {}
Bhavik Patel8e32b0b2020-06-23 13:48:25 +0200101
102void ETHOSU_PMU_Enable(void)
103{
104 struct pmcr_r pmcr;
105 pmcr.word = read_reg(NPU_REG_PMCR);
106 pmcr.cnt_en = 1;
107 write_reg(NPU_REG_PMCR, pmcr.word);
108}
109
110void ETHOSU_PMU_Disable(void)
111{
112 struct pmcr_r pmcr;
113 pmcr.word = read_reg(NPU_REG_PMCR);
114 pmcr.cnt_en = 0;
115 write_reg(NPU_REG_PMCR, pmcr.word);
116}
117
118void ETHOSU_PMU_Set_EVTYPER(uint32_t num, enum ethosu_pmu_event_type type)
119{
120 write_reg(NPU_REG_PMEVTYPER(num), pmu_event_value(type));
121}
122
123enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(uint32_t num)
124{
125 return pmu_event_type(read_reg(NPU_REG_PMEVTYPER(num)));
126}
127
128void ETHOSU_PMU_CYCCNT_Reset(void)
129{
130 struct pmcr_r pmcr;
131 pmcr.word = read_reg(NPU_REG_PMCR);
132 pmcr.cycle_cnt_rst = 1;
133 write_reg(NPU_REG_PMCR, pmcr.word);
134}
135
136void ETHOSU_PMU_EVCNTR_ALL_Reset(void)
137{
138 struct pmcr_r pmcr;
139 pmcr.word = read_reg(NPU_REG_PMCR);
140 pmcr.event_cnt_rst = 1;
141 write_reg(NPU_REG_PMCR, pmcr.word);
142}
143
144void ETHOSU_PMU_CNTR_Enable(uint32_t mask)
145{
146 write_reg(NPU_REG_PMCNTENSET, mask);
147}
148
149void ETHOSU_PMU_CNTR_Disable(uint32_t mask)
150{
151 write_reg(NPU_REG_PMCNTENCLR, mask);
152}
153
154uint32_t ETHOSU_PMU_CNTR_Status()
155{
156 return read_reg(NPU_REG_PMCNTENSET);
157}
158
159uint64_t ETHOSU_PMU_Get_CCNTR(void)
160{
161 uint64_t val1 = (((uint64_t)read_reg(NPU_REG_PMCCNTR_HI)) << 32) | read_reg(NPU_REG_PMCCNTR_LO);
162 uint64_t val2 = (((uint64_t)read_reg(NPU_REG_PMCCNTR_HI)) << 32) | read_reg(NPU_REG_PMCCNTR_LO);
163
164 if (val2 > val1)
165 {
166 return val2;
167 }
168 return val1;
169}
170
171void ETHOSU_PMU_Set_CCNTR(uint64_t val)
172{
173 uint32_t mask = ETHOSU_PMU_CNTR_Status();
174
175 if (mask & ETHOSU_PMU_CCNT_Msk)
176 {
177 ETHOSU_PMU_CNTR_Disable(ETHOSU_PMU_CCNT_Msk);
178 }
179
180 write_reg(NPU_REG_PMCCNTR_LO, (val & MASK_0_31_BITS));
181 write_reg(NPU_REG_PMCCNTR_HI, (val & MASK_32_47_BITS) >> 32);
182
183 if (mask & ETHOSU_PMU_CCNT_Msk)
184 {
185 ETHOSU_PMU_CNTR_Enable(ETHOSU_PMU_CCNT_Msk);
186 }
187}
188
189uint32_t ETHOSU_PMU_Get_EVCNTR(uint32_t num)
190{
191 return read_reg(NPU_REG_PMEVCNTR(num));
192}
193
194void ETHOSU_PMU_Set_EVCNTR(uint32_t num, uint32_t val)
195{
196 write_reg(NPU_REG_PMEVCNTR(num), val);
197}
198
199uint32_t ETHOSU_PMU_Get_CNTR_OVS(void)
200{
201 return read_reg(NPU_REG_PMOVSSET);
202}
203
204// TODO: check if this function name match with the description &
205// implementation.
206void ETHOSU_PMU_Set_CNTR_OVS(uint32_t mask)
207{
208 write_reg(NPU_REG_PMOVSCLR, mask);
209}
210
211void ETHOSU_PMU_Set_CNTR_IRQ_Enable(uint32_t mask)
212{
213 write_reg(NPU_REG_PMINTSET, mask);
214}
215
216void ETHOSU_PMU_Set_CNTR_IRQ_Disable(uint32_t mask)
217{
218 write_reg(NPU_REG_PMINTCLR, mask);
219}
220
221uint32_t ETHOSU_PMU_Get_IRQ_Enable()
222{
223 return read_reg(NPU_REG_PMINTSET);
224}
225
226void ETHOSU_PMU_CNTR_Increment(uint32_t mask)
227{
228 uint32_t cntrs_active = ETHOSU_PMU_CNTR_Status();
229
230 if (mask & ETHOSU_PMU_CCNT_Msk)
231 {
232 if (mask & ETHOSU_PMU_CCNT_Msk)
233 {
234 ETHOSU_PMU_CNTR_Disable(ETHOSU_PMU_CCNT_Msk);
235 uint64_t val = ETHOSU_PMU_Get_CCNTR() + 1;
236 write_reg(NPU_REG_PMCCNTR_LO, (val & MASK_0_31_BITS));
237 write_reg(NPU_REG_PMCCNTR_HI, (val & MASK_32_47_BITS) >> 32);
238 if (cntrs_active & ETHOSU_PMU_CCNT_Msk)
239 {
240 ETHOSU_PMU_CNTR_Enable(ETHOSU_PMU_CCNT_Msk);
241 }
242 }
243 }
244 for (int i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
245 {
246 uint32_t cntr = (0x0001 << i);
247
248 if (mask & cntr)
249 {
250 ETHOSU_PMU_CNTR_Disable(cntr);
251 uint32_t val = read_reg(NPU_REG_PMEVCNTR(i));
252 write_reg(NPU_REG_PMEVCNTR(i), val + 1);
253 if (cntrs_active & cntr)
254 {
255 ETHOSU_PMU_CNTR_Enable(cntr);
256 }
257 }
258 }
259}
260
261void ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(uint32_t start_event)
262{
263 struct pmccntr_cfg_r cfg;
264 cfg.word = read_reg(NPU_REG_PMCCNTR_CFG);
265 cfg.CYCLE_CNT_CFG_START = start_event & ETHOSU_PMCCNTR_CFG_START_STOP_EVENT_MASK;
266 write_reg(NPU_REG_PMCCNTR_CFG, cfg.word);
267}
268
269void ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(uint32_t stop_event)
270{
271 struct pmccntr_cfg_r cfg;
272 cfg.word = read_reg(NPU_REG_PMCCNTR_CFG);
273 cfg.CYCLE_CNT_CFG_STOP = stop_event & ETHOSU_PMCCNTR_CFG_START_STOP_EVENT_MASK;
274 write_reg(NPU_REG_PMCCNTR_CFG, cfg.word);
275}