blob: 9cb67ce6865917803302092a2b6e4b51eaa63be3 [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;
41#else
42 UNUSED(dev);
43 UNUSED(base_address);
44#endif
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020045 return ETHOSU_SUCCESS;
46}
47
Bhavik Pateldae5be02020-06-18 15:25:15 +020048enum ethosu_error_codes ethosu_get_id(struct ethosu_device *dev, struct ethosu_id *id)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020049{
50 struct id_r _id;
51
52#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +020053 _id.word = ethosu_read_reg(dev, NPU_REG_ID);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020054#else
Bhavik Pateldae5be02020-06-18 15:25:15 +020055 UNUSED(dev);
56
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020057 _id.word = 0;
58 _id.arch_patch_rev = NNX_ARCH_VERSION_PATCH;
59 _id.arch_minor_rev = NNX_ARCH_VERSION_MINOR;
60 _id.arch_major_rev = NNX_ARCH_VERSION_MAJOR;
61#endif
62
63 id->version_status = _id.version_status;
64 id->version_minor = _id.version_minor;
65 id->version_major = _id.version_major;
66 id->product_major = _id.product_major;
67 id->arch_patch_rev = _id.arch_patch_rev;
68 id->arch_minor_rev = _id.arch_minor_rev;
69 id->arch_major_rev = _id.arch_major_rev;
70
71 return ETHOSU_SUCCESS;
72}
73
Bhavik Pateldae5be02020-06-18 15:25:15 +020074enum ethosu_error_codes ethosu_get_config(struct ethosu_device *dev, struct ethosu_config *config)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020075{
76 struct config_r cfg = {.word = 0};
77
78#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +020079 cfg.word = ethosu_read_reg(dev, NPU_REG_CONFIG);
80#else
81 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020082#endif
83
84 config->macs_per_cc = cfg.macs_per_cc;
85 config->cmd_stream_version = cfg.cmd_stream_version;
86 config->shram_size = cfg.shram_size;
87
88 return ETHOSU_SUCCESS;
89}
90
Bhavik Pateldae5be02020-06-18 15:25:15 +020091enum ethosu_error_codes ethosu_run_command_stream(struct ethosu_device *dev,
92 const uint8_t *cmd_stream_ptr,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020093 uint32_t cms_length,
94 const uint64_t *base_addr,
95 int num_base_addr)
96{
Bhavik Patele645fed2020-06-12 14:46:47 +020097 enum ethosu_error_codes ret_code = ETHOSU_SUCCESS;
98
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020099#if !defined(ARM_NPU_STUB)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200100 ASSERT(num_base_addr <= ETHOSU_DRIVER_BASEP_INDEXES);
101
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200102 uint64_t qbase = (uint64_t)cmd_stream_ptr + BASE_POINTER_OFFSET;
103 ASSERT(qbase <= ADDRESS_MASK);
104 LOG_DEBUG("QBASE=0x%016llx, QSIZE=%u, base_pointer_offset=0x%08x\n", qbase, cms_length, BASE_POINTER_OFFSET);
105 ethosu_write_reg(dev, NPU_REG_QBASE0, qbase & 0xffffffff);
106 ethosu_write_reg(dev, NPU_REG_QBASE1, qbase >> 32);
107 ethosu_write_reg(dev, NPU_REG_QSIZE, cms_length);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200108
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200109 for (int i = 0; i < num_base_addr; i++)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200110 {
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200111 uint64_t addr = base_addr[i] + BASE_POINTER_OFFSET;
112 ASSERT(addr <= ADDRESS_MASK);
113 LOG_DEBUG("BASEP%d=0x%016llx\n", i, addr);
114 ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i) * BASEP_OFFSET, addr & 0xffffffff);
115 ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i + 1) * BASEP_OFFSET, addr >> 32);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200116 }
117
Bhavik Pateldae5be02020-06-18 15:25:15 +0200118 ret_code = ethosu_set_command_run(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200119#else
120 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200121 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200122 stream_length = cms_length;
123 UNUSED(cmd_stream_ptr);
124 UNUSED(base_addr);
125 ASSERT(num_base_addr < ETHOSU_DRIVER_BASEP_INDEXES);
126#if defined(NDEBUG)
127 UNUSED(num_base_addr);
128#endif
129#endif
130
Bhavik Patele645fed2020-06-12 14:46:47 +0200131 return ret_code;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200132}
133
Bhavik Pateldae5be02020-06-18 15:25:15 +0200134enum ethosu_error_codes ethosu_is_irq_raised(struct ethosu_device *dev, uint8_t *irq_raised)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200135{
136#if !defined(ARM_NPU_STUB)
137 struct status_r status;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200138 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200139 if (status.irq_raised == 1)
140 {
141 *irq_raised = 1;
142 }
143 else
144 {
145 *irq_raised = 0;
146 }
147#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200148 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200149 *irq_raised = 1;
150#endif
151 return ETHOSU_SUCCESS;
152}
153
Bhavik Pateldae5be02020-06-18 15:25:15 +0200154enum ethosu_error_codes ethosu_clear_irq_status(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200155{
156#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200157 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200158 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200159 struct cmd_r cmd;
Per Ã…strand9716b5e2020-08-19 13:15:06 +0200160
Bhavik Patele645fed2020-06-12 14:46:47 +0200161 cmd.word = 0;
162 cmd.clear_irq = 1;
163 cmd.clock_q_enable = oldcmd.clock_q_enable;
164 cmd.power_q_enable = oldcmd.power_q_enable;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200165 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200166#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200167 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200168#endif
169 return ETHOSU_SUCCESS;
170}
171
Bhavik Patele645fed2020-06-12 14:46:47 +0200172// TODO Understand settings of privilege/security level and update API.
Bhavik Pateldae5be02020-06-18 15:25:15 +0200173enum ethosu_error_codes ethosu_soft_reset(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200174{
175 enum ethosu_error_codes return_code = ETHOSU_SUCCESS;
176#if !defined(ARM_NPU_STUB)
177 struct reset_r reset;
178 struct prot_r prot;
179
180 reset.word = 0;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200181 reset.pending_CPL = PRIVILEGE_LEVEL_USER; // TODO, how to get the host privilege level
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200182 reset.pending_CSL = SECURITY_LEVEL_NON_SECURE; // TODO, how to get Security level
183
Bhavik Pateldae5be02020-06-18 15:25:15 +0200184 prot.word = ethosu_read_reg(dev, NPU_REG_PROT);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200185
186 if (prot.active_CPL < reset.pending_CPL && prot.active_CSL > reset.pending_CSL)
187 {
188 // Register access not permitted
189 return ETHOSU_GENERIC_FAILURE;
190 }
191 // Reset and set security level
Bhavik Pateldae5be02020-06-18 15:25:15 +0200192 ethosu_write_reg(dev, NPU_REG_RESET, reset.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200193
Bhavik Pateldae5be02020-06-18 15:25:15 +0200194 return_code = ethosu_wait_for_reset(dev);
195#else
196 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200197#endif
198
199 return return_code;
200}
201
Bhavik Pateldae5be02020-06-18 15:25:15 +0200202enum ethosu_error_codes ethosu_wait_for_reset(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200203{
204#if !defined(ARM_NPU_STUB)
205 struct status_r status;
206
207 // Wait until reset status indicates that reset has been completed
208 for (int i = 0; i < 100000; i++)
209 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200210 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200211 if (0 == status.reset_status)
212 {
213 break;
214 }
215 }
216
217 if (1 == status.reset_status)
218 {
219 return ETHOSU_GENERIC_FAILURE;
220 }
Bhavik Pateldae5be02020-06-18 15:25:15 +0200221#else
222 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200223#endif
224
225 return ETHOSU_SUCCESS;
226}
227
Bhavik Pateldae5be02020-06-18 15:25:15 +0200228enum ethosu_error_codes ethosu_read_apb_reg(struct ethosu_device *dev,
229 uint32_t start_address,
230 uint16_t num_reg,
231 uint32_t *reg)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200232{
233#if !defined(ARM_NPU_STUB)
234 uint32_t address = start_address;
235
Douglas Troha2e7e3b72020-05-14 20:28:31 +0200236 ASSERT((start_address + num_reg) < ID_REGISTERS_SIZE);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200237
238 for (int i = 0; i < num_reg; i++)
239 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200240 reg[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200241 address += REG_OFFSET;
242 }
243#else
244 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200245 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200246 UNUSED(start_address);
247 UNUSED(num_reg);
248 UNUSED(reg);
249#endif
250
251 return ETHOSU_SUCCESS;
252}
253
Bhavik Pateldae5be02020-06-18 15:25:15 +0200254enum ethosu_error_codes ethosu_set_qconfig(struct ethosu_device *dev, enum ethosu_memory_type memory_type)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200255{
256 if (memory_type > ETHOSU_AXI1_OUTSTANDING_COUNTER3)
257 {
258 return ETHOSU_INVALID_PARAM;
259 }
260#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200261 ethosu_write_reg(dev, NPU_REG_QCONFIG, memory_type);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200262#else
263 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200264 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200265 UNUSED(memory_type);
266#endif
267 return ETHOSU_SUCCESS;
268}
269
Bhavik Pateldae5be02020-06-18 15:25:15 +0200270enum ethosu_error_codes ethosu_set_regioncfg(struct ethosu_device *dev,
271 uint8_t region,
272 enum ethosu_memory_type memory_type)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200273{
274 if (region > 7)
275 {
276 return ETHOSU_INVALID_PARAM;
277 }
278#if !defined(ARM_NPU_STUB)
279 struct regioncfg_r regioncfg;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200280 regioncfg.word = ethosu_read_reg(dev, NPU_REG_REGIONCFG);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200281 regioncfg.word &= ~(0x3 << (2 * region));
282 regioncfg.word |= (memory_type & 0x3) << (2 * region);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200283 ethosu_write_reg(dev, NPU_REG_REGIONCFG, regioncfg.word);
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200284 LOG_DEBUG("REGIONCFG%u=0x%08x\n", region, 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;
Per Ã…strand9716b5e2020-08-19 13:15:06 +0200302 axi_limit0.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200303 axi_limit0.max_beats = max_beats;
304 axi_limit0.memtype = memtype;
305 axi_limit0.max_outstanding_read_m1 = max_reads - 1;
306 axi_limit0.max_outstanding_write_m1 = max_writes - 1;
307
Bhavik Pateldae5be02020-06-18 15:25:15 +0200308 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT0, axi_limit0.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200309#else
310 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200311 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200312 UNUSED(max_beats);
313 UNUSED(memtype);
314 UNUSED(max_reads);
315 UNUSED(max_writes);
316#endif
317
318 return ETHOSU_SUCCESS;
319}
320
Bhavik Pateldae5be02020-06-18 15:25:15 +0200321enum ethosu_error_codes ethosu_set_axi_limit1(struct ethosu_device *dev,
322 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200323 enum ethosu_axi_limit_mem_type memtype,
324 uint8_t max_reads,
325 uint8_t max_writes)
326{
327#if !defined(ARM_NPU_STUB)
328 struct axi_limit1_r axi_limit1;
Per Ã…strand9716b5e2020-08-19 13:15:06 +0200329 axi_limit1.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200330 axi_limit1.max_beats = max_beats;
331 axi_limit1.memtype = memtype;
332 axi_limit1.max_outstanding_read_m1 = max_reads - 1;
333 axi_limit1.max_outstanding_write_m1 = max_writes - 1;
334
Bhavik Pateldae5be02020-06-18 15:25:15 +0200335 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT1, axi_limit1.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200336#else
337 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200338 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200339 UNUSED(max_beats);
340 UNUSED(memtype);
341 UNUSED(max_reads);
342 UNUSED(max_writes);
343#endif
344
345 return ETHOSU_SUCCESS;
346}
347
Bhavik Pateldae5be02020-06-18 15:25:15 +0200348enum ethosu_error_codes ethosu_set_axi_limit2(struct ethosu_device *dev,
349 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200350 enum ethosu_axi_limit_mem_type memtype,
351 uint8_t max_reads,
352 uint8_t max_writes)
353{
354#if !defined(ARM_NPU_STUB)
355 struct axi_limit2_r axi_limit2;
Per Ã…strand9716b5e2020-08-19 13:15:06 +0200356 axi_limit2.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200357 axi_limit2.max_beats = max_beats;
358 axi_limit2.memtype = memtype;
359 axi_limit2.max_outstanding_read_m1 = max_reads - 1;
360 axi_limit2.max_outstanding_write_m1 = max_writes - 1;
361
Bhavik Pateldae5be02020-06-18 15:25:15 +0200362 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT2, axi_limit2.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200363#else
364 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200365 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200366 UNUSED(max_beats);
367 UNUSED(memtype);
368 UNUSED(max_reads);
369 UNUSED(max_writes);
370#endif
371
372 return ETHOSU_SUCCESS;
373}
374
Bhavik Pateldae5be02020-06-18 15:25:15 +0200375enum ethosu_error_codes ethosu_set_axi_limit3(struct ethosu_device *dev,
376 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200377 enum ethosu_axi_limit_mem_type memtype,
378 uint8_t max_reads,
379 uint8_t max_writes)
380{
381#if !defined(ARM_NPU_STUB)
382 struct axi_limit3_r axi_limit3;
Per Ã…strand9716b5e2020-08-19 13:15:06 +0200383 axi_limit3.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200384 axi_limit3.max_beats = max_beats;
385 axi_limit3.memtype = memtype;
386 axi_limit3.max_outstanding_read_m1 = max_reads - 1;
387 axi_limit3.max_outstanding_write_m1 = max_writes - 1;
388
Bhavik Pateldae5be02020-06-18 15:25:15 +0200389 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT3, axi_limit3.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200390#else
391 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200392 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200393 UNUSED(max_beats);
394 UNUSED(memtype);
395 UNUSED(max_reads);
396 UNUSED(max_writes);
397#endif
398
399 return ETHOSU_SUCCESS;
400}
401
Bhavik Pateldae5be02020-06-18 15:25:15 +0200402enum ethosu_error_codes ethosu_get_revision(struct ethosu_device *dev, uint32_t *revision)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200403{
404#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200405 *revision = ethosu_read_reg(dev, NPU_REG_REVISION);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200406#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200407 UNUSED(dev);
408 *revision = 0xDEADC0DE;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200409#endif
410 return ETHOSU_SUCCESS;
411}
412
Bhavik Pateldae5be02020-06-18 15:25:15 +0200413enum ethosu_error_codes ethosu_get_qread(struct ethosu_device *dev, uint32_t *qread)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200414{
415#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200416 *qread = ethosu_read_reg(dev, NPU_REG_QREAD);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200417#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200418 UNUSED(dev);
419 *qread = stream_length;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200420#endif
421 return ETHOSU_SUCCESS;
422}
423
Bhavik Pateldae5be02020-06-18 15:25:15 +0200424enum ethosu_error_codes ethosu_get_status_mask(struct ethosu_device *dev, uint16_t *status_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200425{
426#if !defined(ARM_NPU_STUB)
427 struct status_r status;
428
Bhavik Pateldae5be02020-06-18 15:25:15 +0200429 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200430 *status_mask = status.word & 0xFFFF;
431#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200432 UNUSED(dev);
433 *status_mask = 0x0000;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200434#endif
435 return ETHOSU_SUCCESS;
436}
437
Bhavik Pateldae5be02020-06-18 15:25:15 +0200438enum ethosu_error_codes ethosu_get_irq_history_mask(struct ethosu_device *dev, uint16_t *irq_history_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200439{
440#if !defined(ARM_NPU_STUB)
441 struct status_r status;
442
Bhavik Pateldae5be02020-06-18 15:25:15 +0200443 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200444 *irq_history_mask = status.irq_history_mask;
445#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200446 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200447 *irq_history_mask = 0xffff;
448#endif
449 return ETHOSU_SUCCESS;
450}
451
Bhavik Pateldae5be02020-06-18 15:25:15 +0200452enum 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 +0200453{
454#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200455 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200456 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200457
458 struct cmd_r cmd;
459 cmd.word = 0;
460 cmd.clock_q_enable = oldcmd.clock_q_enable;
461 cmd.power_q_enable = oldcmd.power_q_enable;
462 cmd.clear_irq_history = irq_history_clear_mask;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200463 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200464#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200465 UNUSED(dev);
Bhavik Patelbcb5aaa2020-05-12 10:09:41 +0200466 UNUSED(irq_history_clear_mask);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200467#endif
468 return ETHOSU_SUCCESS;
469}
470
Bhavik Pateldae5be02020-06-18 15:25:15 +0200471enum ethosu_error_codes ethosu_set_command_run(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200472{
473#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200474 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200475 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200476
477 struct cmd_r cmd;
478 cmd.word = 0;
479 cmd.transition_to_running_state = 1;
480 cmd.clock_q_enable = oldcmd.clock_q_enable;
481 cmd.power_q_enable = oldcmd.power_q_enable;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200482 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200483#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200484 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200485#endif
486 return ETHOSU_SUCCESS;
487}
488
Bhavik Pateldae5be02020-06-18 15:25:15 +0200489enum ethosu_error_codes ethosu_get_shram_data(struct ethosu_device *dev, int section, uint32_t *shram_p)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200490{
491#if !defined(ARM_NPU_STUB)
492 int i = 0;
493 uint32_t address = NPU_REG_SHARED_BUFFER0;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200494 ethosu_write_reg(dev, NPU_REG_DEBUG_ADDRESS, section * BYTES_1KB);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200495
496 while (address <= NPU_REG_SHARED_BUFFER255)
497 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200498 shram_p[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200499 address += REG_OFFSET;
500 i++;
501 }
502#else
503 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200504 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200505 UNUSED(section);
506 UNUSED(shram_p);
507#endif
508
509 return ETHOSU_SUCCESS;
510}
511
Bhavik Pateldae5be02020-06-18 15:25:15 +0200512enum ethosu_error_codes ethosu_set_clock_and_power(struct ethosu_device *dev,
513 enum ethosu_clock_q_request clock_q,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200514 enum ethosu_power_q_request power_q)
515{
516#if !defined(ARM_NPU_STUB)
517 struct cmd_r cmd;
518 cmd.word = 0;
519 cmd.clock_q_enable = clock_q;
520 cmd.power_q_enable = power_q;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200521 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200522#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200523 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200524 UNUSED(clock_q);
525 UNUSED(power_q);
526#endif
527 return ETHOSU_SUCCESS;
528}
Bhavik Pateldae5be02020-06-18 15:25:15 +0200529
530uint32_t ethosu_read_reg(struct ethosu_device *dev, uint32_t address)
531{
532#if !defined(ARM_NPU_STUB)
533 ASSERT(dev->base_address != NULL);
534
535 volatile uint32_t *reg = (uint32_t *)(uintptr_t)(dev->base_address + address);
536 return *reg;
537#else
538 UNUSED(dev);
539 UNUSED(address);
540
541 return 0;
542#endif
543}
544
545void ethosu_write_reg(struct ethosu_device *dev, uint32_t address, uint32_t value)
546{
547#if !defined(ARM_NPU_STUB)
548 ASSERT(dev->base_address != NULL);
549
550 volatile uint32_t *reg = (uint32_t *)(uintptr_t)(dev->base_address + address);
551 *reg = value;
552#else
553 UNUSED(dev);
554 UNUSED(address);
555 UNUSED(value);
556#endif
557}
Bhavik Patel5da40922020-07-15 10:06:43 +0200558
559enum ethosu_error_codes ethosu_save_pmu_config(struct ethosu_device *dev)
560{
561#if !defined(ARM_NPU_STUB)
562 dev->pmccntr = ETHOSU_PMU_Get_CCNTR();
563 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
564 {
565 dev->pmu_evcntr[i] = ETHOSU_PMU_Get_EVCNTR(i);
566 dev->pmu_evtypr[i] = ETHOSU_PMU_Get_EVTYPER(i);
567 }
568 if (!dev->restore_pmu_config)
569 {
570 dev->restore_pmu_config = true;
571 }
572#else
573 UNUSED(dev);
574#endif
575
576 return ETHOSU_SUCCESS;
577}
578
579enum ethosu_error_codes ethosu_restore_pmu_config(struct ethosu_device *dev)
580{
581#if !defined(ARM_NPU_STUB)
582 if (dev->restore_pmu_config)
583 {
584 ETHOSU_PMU_Set_CCNTR(dev->pmccntr);
585 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
586 {
587 ETHOSU_PMU_Set_EVCNTR(i, dev->pmu_evcntr[i]);
588 ETHOSU_PMU_Set_EVTYPER(i, dev->pmu_evtypr[i]);
589 }
590 }
591#else
592 UNUSED(dev);
593#endif
594
595 return ETHOSU_SUCCESS;
596}