blob: 60fc24377a139e4f1014fcf3730158d39e71ee84 [file] [log] [blame]
Kristofer Jonsson49bdee82020-04-06 13:21:21 +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 */
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020018#include "ethosu_device.h"
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020019#include "ethosu_common.h"
Bhavik Patel790ef362020-06-03 10:05:28 +020020
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020021#include <assert.h>
Bhavik Pateldae5be02020-06-18 15:25:15 +020022#include <stddef.h>
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020023#include <stdio.h>
24
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020025#define BASEP_OFFSET 4
26#define REG_OFFSET 4
27#define BYTES_1KB 1024
28
29#if defined(ARM_NPU_STUB)
30static uint32_t stream_length = 0;
31#endif
32
Bhavik Pateldae5be02020-06-18 15:25:15 +020033enum ethosu_error_codes ethosu_dev_init(struct ethosu_device *dev, const void *base_address)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020034{
Bhavik Pateldae5be02020-06-18 15:25:15 +020035#if !defined(ARM_NPU_STUB)
36 dev->base_address = (uintptr_t)base_address;
37#else
38 UNUSED(dev);
39 UNUSED(base_address);
40#endif
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020041 return ETHOSU_SUCCESS;
42}
43
Bhavik Pateldae5be02020-06-18 15:25:15 +020044enum ethosu_error_codes ethosu_get_id(struct ethosu_device *dev, struct ethosu_id *id)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020045{
46 struct id_r _id;
47
48#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +020049 _id.word = ethosu_read_reg(dev, NPU_REG_ID);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020050#else
Bhavik Pateldae5be02020-06-18 15:25:15 +020051 UNUSED(dev);
52
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020053 _id.word = 0;
54 _id.arch_patch_rev = NNX_ARCH_VERSION_PATCH;
55 _id.arch_minor_rev = NNX_ARCH_VERSION_MINOR;
56 _id.arch_major_rev = NNX_ARCH_VERSION_MAJOR;
57#endif
58
59 id->version_status = _id.version_status;
60 id->version_minor = _id.version_minor;
61 id->version_major = _id.version_major;
62 id->product_major = _id.product_major;
63 id->arch_patch_rev = _id.arch_patch_rev;
64 id->arch_minor_rev = _id.arch_minor_rev;
65 id->arch_major_rev = _id.arch_major_rev;
66
67 return ETHOSU_SUCCESS;
68}
69
Bhavik Pateldae5be02020-06-18 15:25:15 +020070enum ethosu_error_codes ethosu_get_config(struct ethosu_device *dev, struct ethosu_config *config)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020071{
72 struct config_r cfg = {.word = 0};
73
74#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +020075 cfg.word = ethosu_read_reg(dev, NPU_REG_CONFIG);
76#else
77 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020078#endif
79
80 config->macs_per_cc = cfg.macs_per_cc;
81 config->cmd_stream_version = cfg.cmd_stream_version;
82 config->shram_size = cfg.shram_size;
83
84 return ETHOSU_SUCCESS;
85}
86
Bhavik Pateldae5be02020-06-18 15:25:15 +020087enum ethosu_error_codes ethosu_run_command_stream(struct ethosu_device *dev,
88 const uint8_t *cmd_stream_ptr,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020089 uint32_t cms_length,
90 const uint64_t *base_addr,
91 int num_base_addr)
92{
Bhavik Patele645fed2020-06-12 14:46:47 +020093 enum ethosu_error_codes ret_code = ETHOSU_SUCCESS;
94
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020095#if !defined(ARM_NPU_STUB)
96 uint32_t qbase0;
97 uint32_t qbase1;
98 uint32_t qsize;
99 uint32_t *reg_basep;
100 int num_base_reg;
101
102 ASSERT(num_base_addr <= ETHOSU_DRIVER_BASEP_INDEXES);
103
104 qbase0 = ((uint64_t)cmd_stream_ptr) & MASK_0_31_BITS;
105 qbase1 = (((uint64_t)cmd_stream_ptr) & MASK_32_47_BITS) >> 32;
106 qsize = cms_length;
107 num_base_reg = num_base_addr * 2;
108 reg_basep = (uint32_t *)base_addr;
109
110 for (int i = 0; i < num_base_reg; i++)
111 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200112 ethosu_write_reg(dev, NPU_REG_BASEP0 + (i * BASEP_OFFSET), reg_basep[i]);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200113 }
114
Bhavik Pateldae5be02020-06-18 15:25:15 +0200115 ethosu_write_reg(dev, NPU_REG_QBASE0, qbase0);
116 ethosu_write_reg(dev, NPU_REG_QBASE1, qbase1);
117 ethosu_write_reg(dev, NPU_REG_QSIZE, qsize);
Bhavik Patele645fed2020-06-12 14:46:47 +0200118
Bhavik Pateldae5be02020-06-18 15:25:15 +0200119 ret_code = ethosu_set_command_run(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200120#else
121 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200122 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200123 stream_length = cms_length;
124 UNUSED(cmd_stream_ptr);
125 UNUSED(base_addr);
126 ASSERT(num_base_addr < ETHOSU_DRIVER_BASEP_INDEXES);
127#if defined(NDEBUG)
128 UNUSED(num_base_addr);
129#endif
130#endif
131
Bhavik Patele645fed2020-06-12 14:46:47 +0200132 return ret_code;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200133}
134
Bhavik Pateldae5be02020-06-18 15:25:15 +0200135enum ethosu_error_codes ethosu_is_irq_raised(struct ethosu_device *dev, uint8_t *irq_raised)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200136{
137#if !defined(ARM_NPU_STUB)
138 struct status_r status;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200139 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200140 if (status.irq_raised == 1)
141 {
142 *irq_raised = 1;
143 }
144 else
145 {
146 *irq_raised = 0;
147 }
148#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200149 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200150 *irq_raised = 1;
151#endif
152 return ETHOSU_SUCCESS;
153}
154
Bhavik Pateldae5be02020-06-18 15:25:15 +0200155enum ethosu_error_codes ethosu_clear_irq_status(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200156{
157#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200158 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200159 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200160
161 struct cmd_r cmd;
162 cmd.word = 0;
163 cmd.clear_irq = 1;
164 cmd.clock_q_enable = oldcmd.clock_q_enable;
165 cmd.power_q_enable = oldcmd.power_q_enable;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200166 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200167#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200168 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200169#endif
170 return ETHOSU_SUCCESS;
171}
172
Bhavik Patele645fed2020-06-12 14:46:47 +0200173// TODO Understand settings of privilege/security level and update API.
Bhavik Pateldae5be02020-06-18 15:25:15 +0200174enum ethosu_error_codes ethosu_soft_reset(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200175{
176 enum ethosu_error_codes return_code = ETHOSU_SUCCESS;
177#if !defined(ARM_NPU_STUB)
178 struct reset_r reset;
179 struct prot_r prot;
180
181 reset.word = 0;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200182 reset.pending_CPL = PRIVILEGE_LEVEL_USER; // TODO, how to get the host privilege level
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200183 reset.pending_CSL = SECURITY_LEVEL_NON_SECURE; // TODO, how to get Security level
184
Bhavik Pateldae5be02020-06-18 15:25:15 +0200185 prot.word = ethosu_read_reg(dev, NPU_REG_PROT);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200186
187 if (prot.active_CPL < reset.pending_CPL && prot.active_CSL > reset.pending_CSL)
188 {
189 // Register access not permitted
190 return ETHOSU_GENERIC_FAILURE;
191 }
192 // Reset and set security level
Bhavik Pateldae5be02020-06-18 15:25:15 +0200193 ethosu_write_reg(dev, NPU_REG_RESET, reset.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200194
Bhavik Pateldae5be02020-06-18 15:25:15 +0200195 return_code = ethosu_wait_for_reset(dev);
196#else
197 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200198#endif
199
200 return return_code;
201}
202
Bhavik Pateldae5be02020-06-18 15:25:15 +0200203enum ethosu_error_codes ethosu_wait_for_reset(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200204{
205#if !defined(ARM_NPU_STUB)
206 struct status_r status;
207
208 // Wait until reset status indicates that reset has been completed
209 for (int i = 0; i < 100000; i++)
210 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200211 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200212 if (0 == status.reset_status)
213 {
214 break;
215 }
216 }
217
218 if (1 == status.reset_status)
219 {
220 return ETHOSU_GENERIC_FAILURE;
221 }
Bhavik Pateldae5be02020-06-18 15:25:15 +0200222#else
223 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200224#endif
225
226 return ETHOSU_SUCCESS;
227}
228
Bhavik Pateldae5be02020-06-18 15:25:15 +0200229enum ethosu_error_codes ethosu_read_apb_reg(struct ethosu_device *dev,
230 uint32_t start_address,
231 uint16_t num_reg,
232 uint32_t *reg)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200233{
234#if !defined(ARM_NPU_STUB)
235 uint32_t address = start_address;
236
Douglas Troha2e7e3b72020-05-14 20:28:31 +0200237 ASSERT((start_address + num_reg) < ID_REGISTERS_SIZE);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200238
239 for (int i = 0; i < num_reg; i++)
240 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200241 reg[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200242 address += REG_OFFSET;
243 }
244#else
245 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200246 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200247 UNUSED(start_address);
248 UNUSED(num_reg);
249 UNUSED(reg);
250#endif
251
252 return ETHOSU_SUCCESS;
253}
254
Bhavik Pateldae5be02020-06-18 15:25:15 +0200255enum ethosu_error_codes ethosu_set_qconfig(struct ethosu_device *dev, enum ethosu_memory_type memory_type)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200256{
257 if (memory_type > ETHOSU_AXI1_OUTSTANDING_COUNTER3)
258 {
259 return ETHOSU_INVALID_PARAM;
260 }
261#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200262 ethosu_write_reg(dev, NPU_REG_QCONFIG, memory_type);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200263#else
264 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200265 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200266 UNUSED(memory_type);
267#endif
268 return ETHOSU_SUCCESS;
269}
270
Bhavik Pateldae5be02020-06-18 15:25:15 +0200271enum ethosu_error_codes ethosu_set_regioncfg(struct ethosu_device *dev,
272 uint8_t region,
273 enum ethosu_memory_type memory_type)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200274{
275 if (region > 7)
276 {
277 return ETHOSU_INVALID_PARAM;
278 }
279#if !defined(ARM_NPU_STUB)
280 struct regioncfg_r regioncfg;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200281 regioncfg.word = ethosu_read_reg(dev, NPU_REG_REGIONCFG);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200282 regioncfg.word &= ~(0x3 << (2 * region));
283 regioncfg.word |= (memory_type & 0x3) << (2 * region);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200284 ethosu_write_reg(dev, NPU_REG_REGIONCFG, regioncfg.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200285#else
286 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200287 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200288 UNUSED(region);
289 UNUSED(memory_type);
290#endif
291 return ETHOSU_SUCCESS;
292}
293
Bhavik Pateldae5be02020-06-18 15:25:15 +0200294enum ethosu_error_codes ethosu_set_axi_limit0(struct ethosu_device *dev,
295 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200296 enum ethosu_axi_limit_mem_type memtype,
297 uint8_t max_reads,
298 uint8_t max_writes)
299{
300#if !defined(ARM_NPU_STUB)
301 struct axi_limit0_r axi_limit0;
302 axi_limit0.max_beats = max_beats;
303 axi_limit0.memtype = memtype;
304 axi_limit0.max_outstanding_read_m1 = max_reads - 1;
305 axi_limit0.max_outstanding_write_m1 = max_writes - 1;
306
Bhavik Pateldae5be02020-06-18 15:25:15 +0200307 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT0, axi_limit0.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200308#else
309 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200310 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200311 UNUSED(max_beats);
312 UNUSED(memtype);
313 UNUSED(max_reads);
314 UNUSED(max_writes);
315#endif
316
317 return ETHOSU_SUCCESS;
318}
319
Bhavik Pateldae5be02020-06-18 15:25:15 +0200320enum ethosu_error_codes ethosu_set_axi_limit1(struct ethosu_device *dev,
321 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200322 enum ethosu_axi_limit_mem_type memtype,
323 uint8_t max_reads,
324 uint8_t max_writes)
325{
326#if !defined(ARM_NPU_STUB)
327 struct axi_limit1_r axi_limit1;
328 axi_limit1.max_beats = max_beats;
329 axi_limit1.memtype = memtype;
330 axi_limit1.max_outstanding_read_m1 = max_reads - 1;
331 axi_limit1.max_outstanding_write_m1 = max_writes - 1;
332
Bhavik Pateldae5be02020-06-18 15:25:15 +0200333 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT1, axi_limit1.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200334#else
335 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200336 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200337 UNUSED(max_beats);
338 UNUSED(memtype);
339 UNUSED(max_reads);
340 UNUSED(max_writes);
341#endif
342
343 return ETHOSU_SUCCESS;
344}
345
Bhavik Pateldae5be02020-06-18 15:25:15 +0200346enum ethosu_error_codes ethosu_set_axi_limit2(struct ethosu_device *dev,
347 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200348 enum ethosu_axi_limit_mem_type memtype,
349 uint8_t max_reads,
350 uint8_t max_writes)
351{
352#if !defined(ARM_NPU_STUB)
353 struct axi_limit2_r axi_limit2;
354 axi_limit2.max_beats = max_beats;
355 axi_limit2.memtype = memtype;
356 axi_limit2.max_outstanding_read_m1 = max_reads - 1;
357 axi_limit2.max_outstanding_write_m1 = max_writes - 1;
358
Bhavik Pateldae5be02020-06-18 15:25:15 +0200359 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT2, axi_limit2.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200360#else
361 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200362 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200363 UNUSED(max_beats);
364 UNUSED(memtype);
365 UNUSED(max_reads);
366 UNUSED(max_writes);
367#endif
368
369 return ETHOSU_SUCCESS;
370}
371
Bhavik Pateldae5be02020-06-18 15:25:15 +0200372enum ethosu_error_codes ethosu_set_axi_limit3(struct ethosu_device *dev,
373 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200374 enum ethosu_axi_limit_mem_type memtype,
375 uint8_t max_reads,
376 uint8_t max_writes)
377{
378#if !defined(ARM_NPU_STUB)
379 struct axi_limit3_r axi_limit3;
380 axi_limit3.max_beats = max_beats;
381 axi_limit3.memtype = memtype;
382 axi_limit3.max_outstanding_read_m1 = max_reads - 1;
383 axi_limit3.max_outstanding_write_m1 = max_writes - 1;
384
Bhavik Pateldae5be02020-06-18 15:25:15 +0200385 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT3, axi_limit3.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200386#else
387 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200388 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200389 UNUSED(max_beats);
390 UNUSED(memtype);
391 UNUSED(max_reads);
392 UNUSED(max_writes);
393#endif
394
395 return ETHOSU_SUCCESS;
396}
397
Bhavik Pateldae5be02020-06-18 15:25:15 +0200398enum ethosu_error_codes ethosu_get_revision(struct ethosu_device *dev, uint32_t *revision)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200399{
400#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200401 *revision = ethosu_read_reg(dev, NPU_REG_REVISION);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200402#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200403 UNUSED(dev);
404 *revision = 0xDEADC0DE;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200405#endif
406 return ETHOSU_SUCCESS;
407}
408
Bhavik Pateldae5be02020-06-18 15:25:15 +0200409enum ethosu_error_codes ethosu_get_qread(struct ethosu_device *dev, uint32_t *qread)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200410{
411#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200412 *qread = ethosu_read_reg(dev, NPU_REG_QREAD);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200413#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200414 UNUSED(dev);
415 *qread = stream_length;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200416#endif
417 return ETHOSU_SUCCESS;
418}
419
Bhavik Pateldae5be02020-06-18 15:25:15 +0200420enum ethosu_error_codes ethosu_get_status_mask(struct ethosu_device *dev, uint16_t *status_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200421{
422#if !defined(ARM_NPU_STUB)
423 struct status_r status;
424
Bhavik Pateldae5be02020-06-18 15:25:15 +0200425 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200426 *status_mask = status.word & 0xFFFF;
427#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200428 UNUSED(dev);
429 *status_mask = 0x0000;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200430#endif
431 return ETHOSU_SUCCESS;
432}
433
Bhavik Pateldae5be02020-06-18 15:25:15 +0200434enum ethosu_error_codes ethosu_get_irq_history_mask(struct ethosu_device *dev, uint16_t *irq_history_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200435{
436#if !defined(ARM_NPU_STUB)
437 struct status_r status;
438
Bhavik Pateldae5be02020-06-18 15:25:15 +0200439 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200440 *irq_history_mask = status.irq_history_mask;
441#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200442 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200443 *irq_history_mask = 0xffff;
444#endif
445 return ETHOSU_SUCCESS;
446}
447
Bhavik Pateldae5be02020-06-18 15:25:15 +0200448enum ethosu_error_codes ethosu_clear_irq_history_mask(struct ethosu_device *dev, uint16_t irq_history_clear_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200449{
450#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200451 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200452 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200453
454 struct cmd_r cmd;
455 cmd.word = 0;
456 cmd.clock_q_enable = oldcmd.clock_q_enable;
457 cmd.power_q_enable = oldcmd.power_q_enable;
458 cmd.clear_irq_history = irq_history_clear_mask;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200459 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200460#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200461 UNUSED(dev);
Bhavik Patelbcb5aaa2020-05-12 10:09:41 +0200462 UNUSED(irq_history_clear_mask);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200463#endif
464 return ETHOSU_SUCCESS;
465}
466
Bhavik Pateldae5be02020-06-18 15:25:15 +0200467enum ethosu_error_codes ethosu_set_command_run(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200468{
469#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200470 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200471 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200472
473 struct cmd_r cmd;
474 cmd.word = 0;
475 cmd.transition_to_running_state = 1;
476 cmd.clock_q_enable = oldcmd.clock_q_enable;
477 cmd.power_q_enable = oldcmd.power_q_enable;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200478 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200479#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200480 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200481#endif
482 return ETHOSU_SUCCESS;
483}
484
Bhavik Pateldae5be02020-06-18 15:25:15 +0200485enum ethosu_error_codes ethosu_get_shram_data(struct ethosu_device *dev, int section, uint32_t *shram_p)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200486{
487#if !defined(ARM_NPU_STUB)
488 int i = 0;
489 uint32_t address = NPU_REG_SHARED_BUFFER0;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200490 ethosu_write_reg(dev, NPU_REG_DEBUG_ADDRESS, section * BYTES_1KB);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200491
492 while (address <= NPU_REG_SHARED_BUFFER255)
493 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200494 shram_p[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200495 address += REG_OFFSET;
496 i++;
497 }
498#else
499 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200500 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200501 UNUSED(section);
502 UNUSED(shram_p);
503#endif
504
505 return ETHOSU_SUCCESS;
506}
507
Bhavik Pateldae5be02020-06-18 15:25:15 +0200508enum ethosu_error_codes ethosu_set_clock_and_power(struct ethosu_device *dev,
509 enum ethosu_clock_q_request clock_q,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200510 enum ethosu_power_q_request power_q)
511{
512#if !defined(ARM_NPU_STUB)
513 struct cmd_r cmd;
514 cmd.word = 0;
515 cmd.clock_q_enable = clock_q;
516 cmd.power_q_enable = power_q;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200517 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200518#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200519 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200520 UNUSED(clock_q);
521 UNUSED(power_q);
522#endif
523 return ETHOSU_SUCCESS;
524}
Bhavik Pateldae5be02020-06-18 15:25:15 +0200525
526uint32_t ethosu_read_reg(struct ethosu_device *dev, uint32_t address)
527{
528#if !defined(ARM_NPU_STUB)
529 ASSERT(dev->base_address != NULL);
530
531 volatile uint32_t *reg = (uint32_t *)(uintptr_t)(dev->base_address + address);
532 return *reg;
533#else
534 UNUSED(dev);
535 UNUSED(address);
536
537 return 0;
538#endif
539}
540
541void ethosu_write_reg(struct ethosu_device *dev, uint32_t address, uint32_t value)
542{
543#if !defined(ARM_NPU_STUB)
544 ASSERT(dev->base_address != NULL);
545
546 volatile uint32_t *reg = (uint32_t *)(uintptr_t)(dev->base_address + address);
547 *reg = value;
548#else
549 UNUSED(dev);
550 UNUSED(address);
551 UNUSED(value);
552#endif
553}
Bhavik Patel5da40922020-07-15 10:06:43 +0200554
555enum ethosu_error_codes ethosu_save_pmu_config(struct ethosu_device *dev)
556{
557#if !defined(ARM_NPU_STUB)
558 dev->pmccntr = ETHOSU_PMU_Get_CCNTR();
559 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
560 {
561 dev->pmu_evcntr[i] = ETHOSU_PMU_Get_EVCNTR(i);
562 dev->pmu_evtypr[i] = ETHOSU_PMU_Get_EVTYPER(i);
563 }
564 if (!dev->restore_pmu_config)
565 {
566 dev->restore_pmu_config = true;
567 }
568#else
569 UNUSED(dev);
570#endif
571
572 return ETHOSU_SUCCESS;
573}
574
575enum ethosu_error_codes ethosu_restore_pmu_config(struct ethosu_device *dev)
576{
577#if !defined(ARM_NPU_STUB)
578 if (dev->restore_pmu_config)
579 {
580 ETHOSU_PMU_Set_CCNTR(dev->pmccntr);
581 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
582 {
583 ETHOSU_PMU_Set_EVCNTR(i, dev->pmu_evcntr[i]);
584 ETHOSU_PMU_Set_EVTYPER(i, dev->pmu_evtypr[i]);
585 }
586 }
587#else
588 UNUSED(dev);
589#endif
590
591 return ETHOSU_SUCCESS;
592}