blob: 4729c495590da9d679d163a9b93fe9bd31a27d96 [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"
Kristofer Jonsson125429a2020-08-20 16:52:23 +020020#include "ethosu_config.h"
Bhavik Patel790ef362020-06-03 10:05:28 +020021
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020022#include <assert.h>
Bhavik Pateldae5be02020-06-18 15:25:15 +020023#include <stddef.h>
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020024#include <stdio.h>
25
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020026#define BASEP_OFFSET 4
27#define REG_OFFSET 4
28#define BYTES_1KB 1024
29
Kristofer Jonsson125429a2020-08-20 16:52:23 +020030#define ADDRESS_BITS 48
31#define ADDRESS_MASK ((1ull << ADDRESS_BITS) - 1)
32
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020033#if defined(ARM_NPU_STUB)
34static uint32_t stream_length = 0;
35#endif
36
Bhavik Pateldae5be02020-06-18 15:25:15 +020037enum ethosu_error_codes ethosu_dev_init(struct ethosu_device *dev, const void *base_address)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020038{
Bhavik Pateldae5be02020-06-18 15:25:15 +020039#if !defined(ARM_NPU_STUB)
40 dev->base_address = (uintptr_t)base_address;
Kristofer Jonssonef387ea2020-08-25 16:32:21 +020041 ethosu_save_pmu_config(dev);
Bhavik Pateldae5be02020-06-18 15:25:15 +020042#else
43 UNUSED(dev);
44 UNUSED(base_address);
45#endif
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020046 return ETHOSU_SUCCESS;
47}
48
Bhavik Pateldae5be02020-06-18 15:25:15 +020049enum ethosu_error_codes ethosu_get_id(struct ethosu_device *dev, struct ethosu_id *id)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020050{
51 struct id_r _id;
52
53#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +020054 _id.word = ethosu_read_reg(dev, NPU_REG_ID);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020055#else
Bhavik Pateldae5be02020-06-18 15:25:15 +020056 UNUSED(dev);
57
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020058 _id.word = 0;
59 _id.arch_patch_rev = NNX_ARCH_VERSION_PATCH;
60 _id.arch_minor_rev = NNX_ARCH_VERSION_MINOR;
61 _id.arch_major_rev = NNX_ARCH_VERSION_MAJOR;
62#endif
63
64 id->version_status = _id.version_status;
65 id->version_minor = _id.version_minor;
66 id->version_major = _id.version_major;
67 id->product_major = _id.product_major;
68 id->arch_patch_rev = _id.arch_patch_rev;
69 id->arch_minor_rev = _id.arch_minor_rev;
70 id->arch_major_rev = _id.arch_major_rev;
71
72 return ETHOSU_SUCCESS;
73}
74
Bhavik Pateldae5be02020-06-18 15:25:15 +020075enum ethosu_error_codes ethosu_get_config(struct ethosu_device *dev, struct ethosu_config *config)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020076{
77 struct config_r cfg = {.word = 0};
78
79#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +020080 cfg.word = ethosu_read_reg(dev, NPU_REG_CONFIG);
81#else
82 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020083#endif
84
85 config->macs_per_cc = cfg.macs_per_cc;
86 config->cmd_stream_version = cfg.cmd_stream_version;
87 config->shram_size = cfg.shram_size;
88
89 return ETHOSU_SUCCESS;
90}
91
Bhavik Pateldae5be02020-06-18 15:25:15 +020092enum ethosu_error_codes ethosu_run_command_stream(struct ethosu_device *dev,
93 const uint8_t *cmd_stream_ptr,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020094 uint32_t cms_length,
95 const uint64_t *base_addr,
96 int num_base_addr)
97{
Bhavik Patele645fed2020-06-12 14:46:47 +020098 enum ethosu_error_codes ret_code = ETHOSU_SUCCESS;
99
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200100#if !defined(ARM_NPU_STUB)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200101 ASSERT(num_base_addr <= ETHOSU_DRIVER_BASEP_INDEXES);
102
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200103 uint64_t qbase = (uint64_t)cmd_stream_ptr + BASE_POINTER_OFFSET;
104 ASSERT(qbase <= ADDRESS_MASK);
105 LOG_DEBUG("QBASE=0x%016llx, QSIZE=%u, base_pointer_offset=0x%08x\n", qbase, cms_length, BASE_POINTER_OFFSET);
106 ethosu_write_reg(dev, NPU_REG_QBASE0, qbase & 0xffffffff);
107 ethosu_write_reg(dev, NPU_REG_QBASE1, qbase >> 32);
108 ethosu_write_reg(dev, NPU_REG_QSIZE, cms_length);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200109
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200110 for (int i = 0; i < num_base_addr; i++)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200111 {
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200112 uint64_t addr = base_addr[i] + BASE_POINTER_OFFSET;
113 ASSERT(addr <= ADDRESS_MASK);
114 LOG_DEBUG("BASEP%d=0x%016llx\n", i, addr);
115 ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i) * BASEP_OFFSET, addr & 0xffffffff);
116 ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i + 1) * BASEP_OFFSET, addr >> 32);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200117 }
118
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 struct cmd_r cmd;
Per Ã…strand9716b5e2020-08-19 13:15:06 +0200161
Bhavik Patele645fed2020-06-12 14:46:47 +0200162 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 Jonsson125429a2020-08-20 16:52:23 +0200285 LOG_DEBUG("REGIONCFG%u=0x%08x\n", region, regioncfg.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200286#else
287 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200288 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200289 UNUSED(region);
290 UNUSED(memory_type);
291#endif
292 return ETHOSU_SUCCESS;
293}
294
Bhavik Pateldae5be02020-06-18 15:25:15 +0200295enum ethosu_error_codes ethosu_set_axi_limit0(struct ethosu_device *dev,
296 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200297 enum ethosu_axi_limit_mem_type memtype,
298 uint8_t max_reads,
299 uint8_t max_writes)
300{
301#if !defined(ARM_NPU_STUB)
302 struct axi_limit0_r axi_limit0;
Per Ã…strand9716b5e2020-08-19 13:15:06 +0200303 axi_limit0.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200304 axi_limit0.max_beats = max_beats;
305 axi_limit0.memtype = memtype;
306 axi_limit0.max_outstanding_read_m1 = max_reads - 1;
307 axi_limit0.max_outstanding_write_m1 = max_writes - 1;
308
Bhavik Pateldae5be02020-06-18 15:25:15 +0200309 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT0, axi_limit0.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200310#else
311 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200312 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200313 UNUSED(max_beats);
314 UNUSED(memtype);
315 UNUSED(max_reads);
316 UNUSED(max_writes);
317#endif
318
319 return ETHOSU_SUCCESS;
320}
321
Bhavik Pateldae5be02020-06-18 15:25:15 +0200322enum ethosu_error_codes ethosu_set_axi_limit1(struct ethosu_device *dev,
323 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200324 enum ethosu_axi_limit_mem_type memtype,
325 uint8_t max_reads,
326 uint8_t max_writes)
327{
328#if !defined(ARM_NPU_STUB)
329 struct axi_limit1_r axi_limit1;
Per Ã…strand9716b5e2020-08-19 13:15:06 +0200330 axi_limit1.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200331 axi_limit1.max_beats = max_beats;
332 axi_limit1.memtype = memtype;
333 axi_limit1.max_outstanding_read_m1 = max_reads - 1;
334 axi_limit1.max_outstanding_write_m1 = max_writes - 1;
335
Bhavik Pateldae5be02020-06-18 15:25:15 +0200336 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT1, axi_limit1.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200337#else
338 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200339 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200340 UNUSED(max_beats);
341 UNUSED(memtype);
342 UNUSED(max_reads);
343 UNUSED(max_writes);
344#endif
345
346 return ETHOSU_SUCCESS;
347}
348
Bhavik Pateldae5be02020-06-18 15:25:15 +0200349enum ethosu_error_codes ethosu_set_axi_limit2(struct ethosu_device *dev,
350 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200351 enum ethosu_axi_limit_mem_type memtype,
352 uint8_t max_reads,
353 uint8_t max_writes)
354{
355#if !defined(ARM_NPU_STUB)
356 struct axi_limit2_r axi_limit2;
Per Ã…strand9716b5e2020-08-19 13:15:06 +0200357 axi_limit2.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200358 axi_limit2.max_beats = max_beats;
359 axi_limit2.memtype = memtype;
360 axi_limit2.max_outstanding_read_m1 = max_reads - 1;
361 axi_limit2.max_outstanding_write_m1 = max_writes - 1;
362
Bhavik Pateldae5be02020-06-18 15:25:15 +0200363 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT2, axi_limit2.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200364#else
365 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200366 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200367 UNUSED(max_beats);
368 UNUSED(memtype);
369 UNUSED(max_reads);
370 UNUSED(max_writes);
371#endif
372
373 return ETHOSU_SUCCESS;
374}
375
Bhavik Pateldae5be02020-06-18 15:25:15 +0200376enum ethosu_error_codes ethosu_set_axi_limit3(struct ethosu_device *dev,
377 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200378 enum ethosu_axi_limit_mem_type memtype,
379 uint8_t max_reads,
380 uint8_t max_writes)
381{
382#if !defined(ARM_NPU_STUB)
383 struct axi_limit3_r axi_limit3;
Per Ã…strand9716b5e2020-08-19 13:15:06 +0200384 axi_limit3.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200385 axi_limit3.max_beats = max_beats;
386 axi_limit3.memtype = memtype;
387 axi_limit3.max_outstanding_read_m1 = max_reads - 1;
388 axi_limit3.max_outstanding_write_m1 = max_writes - 1;
389
Bhavik Pateldae5be02020-06-18 15:25:15 +0200390 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT3, axi_limit3.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200391#else
392 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200393 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200394 UNUSED(max_beats);
395 UNUSED(memtype);
396 UNUSED(max_reads);
397 UNUSED(max_writes);
398#endif
399
400 return ETHOSU_SUCCESS;
401}
402
Bhavik Pateldae5be02020-06-18 15:25:15 +0200403enum ethosu_error_codes ethosu_get_revision(struct ethosu_device *dev, uint32_t *revision)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200404{
405#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200406 *revision = ethosu_read_reg(dev, NPU_REG_REVISION);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200407#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200408 UNUSED(dev);
409 *revision = 0xDEADC0DE;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200410#endif
411 return ETHOSU_SUCCESS;
412}
413
Bhavik Pateldae5be02020-06-18 15:25:15 +0200414enum ethosu_error_codes ethosu_get_qread(struct ethosu_device *dev, uint32_t *qread)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200415{
416#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200417 *qread = ethosu_read_reg(dev, NPU_REG_QREAD);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200418#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200419 UNUSED(dev);
420 *qread = stream_length;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200421#endif
422 return ETHOSU_SUCCESS;
423}
424
Bhavik Pateldae5be02020-06-18 15:25:15 +0200425enum ethosu_error_codes ethosu_get_status_mask(struct ethosu_device *dev, uint16_t *status_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200426{
427#if !defined(ARM_NPU_STUB)
428 struct status_r status;
429
Bhavik Pateldae5be02020-06-18 15:25:15 +0200430 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200431 *status_mask = status.word & 0xFFFF;
432#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200433 UNUSED(dev);
434 *status_mask = 0x0000;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200435#endif
436 return ETHOSU_SUCCESS;
437}
438
Bhavik Pateldae5be02020-06-18 15:25:15 +0200439enum ethosu_error_codes ethosu_get_irq_history_mask(struct ethosu_device *dev, uint16_t *irq_history_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200440{
441#if !defined(ARM_NPU_STUB)
442 struct status_r status;
443
Bhavik Pateldae5be02020-06-18 15:25:15 +0200444 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200445 *irq_history_mask = status.irq_history_mask;
446#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200447 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200448 *irq_history_mask = 0xffff;
449#endif
450 return ETHOSU_SUCCESS;
451}
452
Bhavik Pateldae5be02020-06-18 15:25:15 +0200453enum 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 +0200454{
455#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200456 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200457 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200458
459 struct cmd_r cmd;
460 cmd.word = 0;
461 cmd.clock_q_enable = oldcmd.clock_q_enable;
462 cmd.power_q_enable = oldcmd.power_q_enable;
463 cmd.clear_irq_history = irq_history_clear_mask;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200464 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200465#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200466 UNUSED(dev);
Bhavik Patelbcb5aaa2020-05-12 10:09:41 +0200467 UNUSED(irq_history_clear_mask);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200468#endif
469 return ETHOSU_SUCCESS;
470}
471
Bhavik Pateldae5be02020-06-18 15:25:15 +0200472enum ethosu_error_codes ethosu_set_command_run(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200473{
474#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200475 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200476 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200477
478 struct cmd_r cmd;
479 cmd.word = 0;
480 cmd.transition_to_running_state = 1;
481 cmd.clock_q_enable = oldcmd.clock_q_enable;
482 cmd.power_q_enable = oldcmd.power_q_enable;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200483 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200484#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200485 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200486#endif
487 return ETHOSU_SUCCESS;
488}
489
Bhavik Pateldae5be02020-06-18 15:25:15 +0200490enum ethosu_error_codes ethosu_get_shram_data(struct ethosu_device *dev, int section, uint32_t *shram_p)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200491{
492#if !defined(ARM_NPU_STUB)
493 int i = 0;
494 uint32_t address = NPU_REG_SHARED_BUFFER0;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200495 ethosu_write_reg(dev, NPU_REG_DEBUG_ADDRESS, section * BYTES_1KB);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200496
497 while (address <= NPU_REG_SHARED_BUFFER255)
498 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200499 shram_p[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200500 address += REG_OFFSET;
501 i++;
502 }
503#else
504 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200505 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200506 UNUSED(section);
507 UNUSED(shram_p);
508#endif
509
510 return ETHOSU_SUCCESS;
511}
512
Bhavik Pateldae5be02020-06-18 15:25:15 +0200513enum ethosu_error_codes ethosu_set_clock_and_power(struct ethosu_device *dev,
514 enum ethosu_clock_q_request clock_q,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200515 enum ethosu_power_q_request power_q)
516{
517#if !defined(ARM_NPU_STUB)
518 struct cmd_r cmd;
519 cmd.word = 0;
520 cmd.clock_q_enable = clock_q;
521 cmd.power_q_enable = power_q;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200522 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200523#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200524 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200525 UNUSED(clock_q);
526 UNUSED(power_q);
527#endif
528 return ETHOSU_SUCCESS;
529}
Bhavik Pateldae5be02020-06-18 15:25:15 +0200530
531uint32_t ethosu_read_reg(struct ethosu_device *dev, uint32_t address)
532{
533#if !defined(ARM_NPU_STUB)
534 ASSERT(dev->base_address != NULL);
535
536 volatile uint32_t *reg = (uint32_t *)(uintptr_t)(dev->base_address + address);
537 return *reg;
538#else
539 UNUSED(dev);
540 UNUSED(address);
541
542 return 0;
543#endif
544}
545
546void ethosu_write_reg(struct ethosu_device *dev, uint32_t address, uint32_t value)
547{
548#if !defined(ARM_NPU_STUB)
549 ASSERT(dev->base_address != NULL);
550
551 volatile uint32_t *reg = (uint32_t *)(uintptr_t)(dev->base_address + address);
552 *reg = value;
553#else
554 UNUSED(dev);
555 UNUSED(address);
556 UNUSED(value);
557#endif
558}
Bhavik Patel5da40922020-07-15 10:06:43 +0200559
560enum ethosu_error_codes ethosu_save_pmu_config(struct ethosu_device *dev)
561{
562#if !defined(ARM_NPU_STUB)
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200563 // Save the PMU control register
564 dev->pmcr = ethosu_read_reg(dev, NPU_REG_PMCR);
565
566 // Save IRQ control
567 dev->pmint = ethosu_read_reg(dev, NPU_REG_PMINTSET);
568
569 // Save the enabled events mask
570 dev->pmcnten = ethosu_read_reg(dev, NPU_REG_PMCNTENSET);
571
572 // Save start and stop event
573 dev->pmccntr_cfg = ethosu_read_reg(dev, NPU_REG_PMCCNTR_CFG);
574
575 // Save the cycle counter
Bhavik Patel5da40922020-07-15 10:06:43 +0200576 dev->pmccntr = ETHOSU_PMU_Get_CCNTR();
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200577
578 // Save the event settings and counters
Bhavik Patel5da40922020-07-15 10:06:43 +0200579 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
580 {
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200581 dev->pmu_evcntr[i] = ethosu_read_reg(dev, NPU_REG_PMEVCNTR0 + i * sizeof(uint32_t));
582 dev->pmu_evtypr[i] = ethosu_read_reg(dev, NPU_REG_PMEVTYPER0 + i * sizeof(uint32_t));
Bhavik Patel5da40922020-07-15 10:06:43 +0200583 }
584#else
585 UNUSED(dev);
586#endif
587
588 return ETHOSU_SUCCESS;
589}
590
591enum ethosu_error_codes ethosu_restore_pmu_config(struct ethosu_device *dev)
592{
593#if !defined(ARM_NPU_STUB)
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200594 // Restore PMU control register
595 ethosu_write_reg(dev, NPU_REG_PMCR, dev->pmcr);
596
597 // Restore IRQ control
598 ethosu_write_reg(dev, NPU_REG_PMINTSET, dev->pmint);
599
600 // Restore enabled event mask
601 ethosu_write_reg(dev, NPU_REG_PMCNTENSET, dev->pmcnten);
602
603 // Restore start and stop event
604 ethosu_write_reg(dev, NPU_REG_PMCCNTR_CFG, dev->pmccntr_cfg);
605
606 // Restore the cycle counter
607 ETHOSU_PMU_Set_CCNTR(dev->pmccntr);
608
609 // Restore event settings and counters
610 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
Bhavik Patel5da40922020-07-15 10:06:43 +0200611 {
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200612 ethosu_write_reg(dev, NPU_REG_PMEVCNTR0 + i * sizeof(uint32_t), dev->pmu_evcntr[i]);
613 ethosu_write_reg(dev, NPU_REG_PMEVTYPER0 + i * sizeof(uint32_t), dev->pmu_evtypr[i]);
Bhavik Patel5da40922020-07-15 10:06:43 +0200614 }
615#else
616 UNUSED(dev);
617#endif
618
619 return ETHOSU_SUCCESS;
620}