blob: f8250bc99453a4730ae6a019229f4a15f895c49e [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
Per Åstrande6498f02020-11-09 15:33:12 +010037enum ethosu_error_codes ethosu_dev_init(struct ethosu_device *dev,
38 const void *base_address,
39 uint32_t secure_enable,
40 uint32_t privilege_enable)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020041{
Bhavik Pateldae5be02020-06-18 15:25:15 +020042#if !defined(ARM_NPU_STUB)
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +020043 dev->base_address = (volatile uint32_t *)base_address;
Per Åstrande6498f02020-11-09 15:33:12 +010044 dev->secure = secure_enable;
45 dev->privileged = privilege_enable;
46
Kristofer Jonssonef387ea2020-08-25 16:32:21 +020047 ethosu_save_pmu_config(dev);
Bhavik Pateldae5be02020-06-18 15:25:15 +020048#else
49 UNUSED(dev);
50 UNUSED(base_address);
51#endif
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020052 return ETHOSU_SUCCESS;
53}
54
Bhavik Pateldae5be02020-06-18 15:25:15 +020055enum ethosu_error_codes ethosu_get_id(struct ethosu_device *dev, struct ethosu_id *id)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020056{
57 struct id_r _id;
58
59#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +020060 _id.word = ethosu_read_reg(dev, NPU_REG_ID);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020061#else
Bhavik Pateldae5be02020-06-18 15:25:15 +020062 UNUSED(dev);
63
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020064 _id.word = 0;
65 _id.arch_patch_rev = NNX_ARCH_VERSION_PATCH;
66 _id.arch_minor_rev = NNX_ARCH_VERSION_MINOR;
67 _id.arch_major_rev = NNX_ARCH_VERSION_MAJOR;
68#endif
69
70 id->version_status = _id.version_status;
71 id->version_minor = _id.version_minor;
72 id->version_major = _id.version_major;
73 id->product_major = _id.product_major;
74 id->arch_patch_rev = _id.arch_patch_rev;
75 id->arch_minor_rev = _id.arch_minor_rev;
76 id->arch_major_rev = _id.arch_major_rev;
77
78 return ETHOSU_SUCCESS;
79}
80
Bhavik Pateldae5be02020-06-18 15:25:15 +020081enum ethosu_error_codes ethosu_get_config(struct ethosu_device *dev, struct ethosu_config *config)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020082{
83 struct config_r cfg = {.word = 0};
84
85#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +020086 cfg.word = ethosu_read_reg(dev, NPU_REG_CONFIG);
87#else
88 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020089#endif
90
91 config->macs_per_cc = cfg.macs_per_cc;
92 config->cmd_stream_version = cfg.cmd_stream_version;
93 config->shram_size = cfg.shram_size;
94
95 return ETHOSU_SUCCESS;
96}
97
Bhavik Pateldae5be02020-06-18 15:25:15 +020098enum ethosu_error_codes ethosu_run_command_stream(struct ethosu_device *dev,
99 const uint8_t *cmd_stream_ptr,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200100 uint32_t cms_length,
101 const uint64_t *base_addr,
102 int num_base_addr)
103{
Bhavik Patele645fed2020-06-12 14:46:47 +0200104 enum ethosu_error_codes ret_code = ETHOSU_SUCCESS;
105
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200106#if !defined(ARM_NPU_STUB)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200107 ASSERT(num_base_addr <= ETHOSU_DRIVER_BASEP_INDEXES);
108
Per Åstrandc6c1db12020-09-28 08:41:45 +0200109 uint64_t qbase = (uintptr_t)cmd_stream_ptr + BASE_POINTER_OFFSET;
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200110 ASSERT(qbase <= ADDRESS_MASK);
111 LOG_DEBUG("QBASE=0x%016llx, QSIZE=%u, base_pointer_offset=0x%08x\n", qbase, cms_length, BASE_POINTER_OFFSET);
112 ethosu_write_reg(dev, NPU_REG_QBASE0, qbase & 0xffffffff);
113 ethosu_write_reg(dev, NPU_REG_QBASE1, qbase >> 32);
114 ethosu_write_reg(dev, NPU_REG_QSIZE, cms_length);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200115
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200116 for (int i = 0; i < num_base_addr; i++)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200117 {
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200118 uint64_t addr = base_addr[i] + BASE_POINTER_OFFSET;
119 ASSERT(addr <= ADDRESS_MASK);
120 LOG_DEBUG("BASEP%d=0x%016llx\n", i, addr);
121 ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i) * BASEP_OFFSET, addr & 0xffffffff);
122 ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i + 1) * BASEP_OFFSET, addr >> 32);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200123 }
124
Bhavik Pateldae5be02020-06-18 15:25:15 +0200125 ret_code = ethosu_set_command_run(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200126#else
127 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200128 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200129 stream_length = cms_length;
130 UNUSED(cmd_stream_ptr);
131 UNUSED(base_addr);
132 ASSERT(num_base_addr < ETHOSU_DRIVER_BASEP_INDEXES);
133#if defined(NDEBUG)
134 UNUSED(num_base_addr);
135#endif
136#endif
137
Bhavik Patele645fed2020-06-12 14:46:47 +0200138 return ret_code;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200139}
140
Bhavik Pateldae5be02020-06-18 15:25:15 +0200141enum ethosu_error_codes ethosu_is_irq_raised(struct ethosu_device *dev, uint8_t *irq_raised)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200142{
143#if !defined(ARM_NPU_STUB)
144 struct status_r status;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200145 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200146 if (status.irq_raised == 1)
147 {
148 *irq_raised = 1;
149 }
150 else
151 {
152 *irq_raised = 0;
153 }
154#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200155 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200156 *irq_raised = 1;
157#endif
158 return ETHOSU_SUCCESS;
159}
160
Bhavik Pateldae5be02020-06-18 15:25:15 +0200161enum ethosu_error_codes ethosu_clear_irq_status(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200162{
163#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200164 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200165 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200166 struct cmd_r cmd;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200167
Bhavik Patele645fed2020-06-12 14:46:47 +0200168 cmd.word = 0;
169 cmd.clear_irq = 1;
170 cmd.clock_q_enable = oldcmd.clock_q_enable;
171 cmd.power_q_enable = oldcmd.power_q_enable;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200172 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100173 LOG_DEBUG("CMD=0x%08x\n", cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200174#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200175 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200176#endif
177 return ETHOSU_SUCCESS;
178}
179
Bhavik Pateldae5be02020-06-18 15:25:15 +0200180enum ethosu_error_codes ethosu_soft_reset(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200181{
182 enum ethosu_error_codes return_code = ETHOSU_SUCCESS;
183#if !defined(ARM_NPU_STUB)
184 struct reset_r reset;
185 struct prot_r prot;
186
187 reset.word = 0;
Per Åstrande6498f02020-11-09 15:33:12 +0100188 reset.pending_CPL = dev->privileged ? PRIVILEGE_LEVEL_PRIVILEGED : PRIVILEGE_LEVEL_USER;
189 reset.pending_CSL = dev->secure ? SECURITY_LEVEL_SECURE : SECURITY_LEVEL_NON_SECURE;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200190
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200191 // Reset and set security level
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100192 LOG_INFO("Soft reset NPU\n");
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
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200195 // Wait for reset to complete
Bhavik Pateldae5be02020-06-18 15:25:15 +0200196 return_code = ethosu_wait_for_reset(dev);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100197 if (return_code != ETHOSU_SUCCESS)
198 {
199 LOG_ERR("Soft reset timed out\n");
200 return return_code;
201 }
202
203 // Verify that NPU has switched security state and privilege level
204 prot.word = ethosu_read_reg(dev, NPU_REG_PROT);
205 if (prot.active_CPL != reset.pending_CPL || prot.active_CSL != reset.pending_CSL)
206 {
207 LOG_ERR("Failed to switch security state and privilege level\n");
208 // Register access not permitted
209 return ETHOSU_GENERIC_FAILURE;
210 }
Bhavik Patel5f8dad12020-09-30 09:06:52 +0200211
Per Åstrande6498f02020-11-09 15:33:12 +0100212 // Save the prot register
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100213 dev->proto = ethosu_read_reg(dev, NPU_REG_PROT);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200214
215 // Soft reset will clear the PMU configuration and counters. The shadow PMU counters
216 // are cleared by saving the PMU counters to ram, which will read back zeros.
217 // The PMU configuration will be restored in the invoke function after power save
218 // has been disabled.
219 ethosu_save_pmu_counters(dev);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200220#else
221 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200222#endif
223
224 return return_code;
225}
226
Bhavik Pateldae5be02020-06-18 15:25:15 +0200227enum ethosu_error_codes ethosu_wait_for_reset(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200228{
229#if !defined(ARM_NPU_STUB)
230 struct status_r status;
231
232 // Wait until reset status indicates that reset has been completed
233 for (int i = 0; i < 100000; i++)
234 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200235 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200236 if (0 == status.reset_status)
237 {
238 break;
239 }
240 }
241
242 if (1 == status.reset_status)
243 {
244 return ETHOSU_GENERIC_FAILURE;
245 }
Bhavik Pateldae5be02020-06-18 15:25:15 +0200246#else
247 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200248#endif
249
250 return ETHOSU_SUCCESS;
251}
252
Bhavik Pateldae5be02020-06-18 15:25:15 +0200253enum ethosu_error_codes ethosu_read_apb_reg(struct ethosu_device *dev,
254 uint32_t start_address,
255 uint16_t num_reg,
256 uint32_t *reg)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200257{
258#if !defined(ARM_NPU_STUB)
259 uint32_t address = start_address;
260
Douglas Troha2e7e3b72020-05-14 20:28:31 +0200261 ASSERT((start_address + num_reg) < ID_REGISTERS_SIZE);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200262
263 for (int i = 0; i < num_reg; i++)
264 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200265 reg[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200266 address += REG_OFFSET;
267 }
268#else
269 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200270 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200271 UNUSED(start_address);
272 UNUSED(num_reg);
273 UNUSED(reg);
274#endif
275
276 return ETHOSU_SUCCESS;
277}
278
Bhavik Pateldae5be02020-06-18 15:25:15 +0200279enum ethosu_error_codes ethosu_set_qconfig(struct ethosu_device *dev, enum ethosu_memory_type memory_type)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200280{
281 if (memory_type > ETHOSU_AXI1_OUTSTANDING_COUNTER3)
282 {
283 return ETHOSU_INVALID_PARAM;
284 }
285#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200286 ethosu_write_reg(dev, NPU_REG_QCONFIG, memory_type);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100287 LOG_DEBUG("QCONFIG=0x%08x\n", memory_type);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200288#else
289 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200290 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200291 UNUSED(memory_type);
292#endif
293 return ETHOSU_SUCCESS;
294}
295
Bhavik Pateldae5be02020-06-18 15:25:15 +0200296enum ethosu_error_codes ethosu_set_regioncfg(struct ethosu_device *dev,
297 uint8_t region,
298 enum ethosu_memory_type memory_type)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200299{
300 if (region > 7)
301 {
302 return ETHOSU_INVALID_PARAM;
303 }
304#if !defined(ARM_NPU_STUB)
305 struct regioncfg_r regioncfg;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200306 regioncfg.word = ethosu_read_reg(dev, NPU_REG_REGIONCFG);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200307 regioncfg.word &= ~(0x3 << (2 * region));
308 regioncfg.word |= (memory_type & 0x3) << (2 * region);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200309 ethosu_write_reg(dev, NPU_REG_REGIONCFG, regioncfg.word);
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200310 LOG_DEBUG("REGIONCFG%u=0x%08x\n", region, regioncfg.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200311#else
312 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200313 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200314 UNUSED(region);
315 UNUSED(memory_type);
316#endif
317 return ETHOSU_SUCCESS;
318}
319
Bhavik Pateldae5be02020-06-18 15:25:15 +0200320enum ethosu_error_codes ethosu_set_axi_limit0(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_limit0_r axi_limit0;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200328 axi_limit0.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200329 axi_limit0.max_beats = max_beats;
330 axi_limit0.memtype = memtype;
331 axi_limit0.max_outstanding_read_m1 = max_reads - 1;
332 axi_limit0.max_outstanding_write_m1 = max_writes - 1;
333
Bhavik Pateldae5be02020-06-18 15:25:15 +0200334 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT0, axi_limit0.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100335 LOG_DEBUG("AXI_LIMIT0=0x%08x\n", axi_limit0.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_limit1(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_limit1_r axi_limit1;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200356 axi_limit1.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200357 axi_limit1.max_beats = max_beats;
358 axi_limit1.memtype = memtype;
359 axi_limit1.max_outstanding_read_m1 = max_reads - 1;
360 axi_limit1.max_outstanding_write_m1 = max_writes - 1;
361
Bhavik Pateldae5be02020-06-18 15:25:15 +0200362 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT1, axi_limit1.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100363 LOG_DEBUG("AXI_LIMIT1=0x%08x\n", axi_limit1.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_limit2(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_limit2_r axi_limit2;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200384 axi_limit2.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200385 axi_limit2.max_beats = max_beats;
386 axi_limit2.memtype = memtype;
387 axi_limit2.max_outstanding_read_m1 = max_reads - 1;
388 axi_limit2.max_outstanding_write_m1 = max_writes - 1;
389
Bhavik Pateldae5be02020-06-18 15:25:15 +0200390 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT2, axi_limit2.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100391 LOG_DEBUG("AXI_LIMIT2=0x%08x\n", axi_limit2.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200392#else
393 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200394 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200395 UNUSED(max_beats);
396 UNUSED(memtype);
397 UNUSED(max_reads);
398 UNUSED(max_writes);
399#endif
400
401 return ETHOSU_SUCCESS;
402}
403
Bhavik Pateldae5be02020-06-18 15:25:15 +0200404enum ethosu_error_codes ethosu_set_axi_limit3(struct ethosu_device *dev,
405 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200406 enum ethosu_axi_limit_mem_type memtype,
407 uint8_t max_reads,
408 uint8_t max_writes)
409{
410#if !defined(ARM_NPU_STUB)
411 struct axi_limit3_r axi_limit3;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200412 axi_limit3.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200413 axi_limit3.max_beats = max_beats;
414 axi_limit3.memtype = memtype;
415 axi_limit3.max_outstanding_read_m1 = max_reads - 1;
416 axi_limit3.max_outstanding_write_m1 = max_writes - 1;
417
Bhavik Pateldae5be02020-06-18 15:25:15 +0200418 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT3, axi_limit3.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100419 LOG_DEBUG("AXI_LIMIT3=0x%08x\n", axi_limit3.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200420#else
421 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200422 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200423 UNUSED(max_beats);
424 UNUSED(memtype);
425 UNUSED(max_reads);
426 UNUSED(max_writes);
427#endif
428
429 return ETHOSU_SUCCESS;
430}
431
Bhavik Pateldae5be02020-06-18 15:25:15 +0200432enum ethosu_error_codes ethosu_get_revision(struct ethosu_device *dev, uint32_t *revision)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200433{
434#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200435 *revision = ethosu_read_reg(dev, NPU_REG_REVISION);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200436#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200437 UNUSED(dev);
438 *revision = 0xDEADC0DE;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200439#endif
440 return ETHOSU_SUCCESS;
441}
442
Bhavik Pateldae5be02020-06-18 15:25:15 +0200443enum ethosu_error_codes ethosu_get_qread(struct ethosu_device *dev, uint32_t *qread)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200444{
445#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200446 *qread = ethosu_read_reg(dev, NPU_REG_QREAD);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200447#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200448 UNUSED(dev);
449 *qread = stream_length;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200450#endif
451 return ETHOSU_SUCCESS;
452}
453
Bhavik Pateldae5be02020-06-18 15:25:15 +0200454enum ethosu_error_codes ethosu_get_status_mask(struct ethosu_device *dev, uint16_t *status_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200455{
456#if !defined(ARM_NPU_STUB)
457 struct status_r status;
458
Bhavik Pateldae5be02020-06-18 15:25:15 +0200459 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200460 *status_mask = status.word & 0xFFFF;
461#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200462 UNUSED(dev);
463 *status_mask = 0x0000;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200464#endif
465 return ETHOSU_SUCCESS;
466}
467
Bhavik Pateldae5be02020-06-18 15:25:15 +0200468enum ethosu_error_codes ethosu_get_irq_history_mask(struct ethosu_device *dev, uint16_t *irq_history_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200469{
470#if !defined(ARM_NPU_STUB)
471 struct status_r status;
472
Bhavik Pateldae5be02020-06-18 15:25:15 +0200473 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200474 *irq_history_mask = status.irq_history_mask;
475#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200476 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200477 *irq_history_mask = 0xffff;
478#endif
479 return ETHOSU_SUCCESS;
480}
481
Bhavik Pateldae5be02020-06-18 15:25:15 +0200482enum 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 +0200483{
484#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200485 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200486 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200487
488 struct cmd_r cmd;
489 cmd.word = 0;
490 cmd.clock_q_enable = oldcmd.clock_q_enable;
491 cmd.power_q_enable = oldcmd.power_q_enable;
492 cmd.clear_irq_history = irq_history_clear_mask;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200493 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100494 LOG_DEBUG("CMD=0x%08x\n", cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200495#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200496 UNUSED(dev);
Bhavik Patelbcb5aaa2020-05-12 10:09:41 +0200497 UNUSED(irq_history_clear_mask);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200498#endif
499 return ETHOSU_SUCCESS;
500}
501
Bhavik Pateldae5be02020-06-18 15:25:15 +0200502enum ethosu_error_codes ethosu_set_command_run(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200503{
504#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200505 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200506 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200507
508 struct cmd_r cmd;
509 cmd.word = 0;
510 cmd.transition_to_running_state = 1;
511 cmd.clock_q_enable = oldcmd.clock_q_enable;
512 cmd.power_q_enable = oldcmd.power_q_enable;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200513 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100514 LOG_DEBUG("CMD=0x%08x\n", cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200515#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200516 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200517#endif
518 return ETHOSU_SUCCESS;
519}
520
Bhavik Pateldae5be02020-06-18 15:25:15 +0200521enum ethosu_error_codes ethosu_get_shram_data(struct ethosu_device *dev, int section, uint32_t *shram_p)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200522{
523#if !defined(ARM_NPU_STUB)
524 int i = 0;
525 uint32_t address = NPU_REG_SHARED_BUFFER0;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200526 ethosu_write_reg(dev, NPU_REG_DEBUG_ADDRESS, section * BYTES_1KB);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200527
528 while (address <= NPU_REG_SHARED_BUFFER255)
529 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200530 shram_p[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200531 address += REG_OFFSET;
532 i++;
533 }
534#else
535 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200536 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200537 UNUSED(section);
538 UNUSED(shram_p);
539#endif
540
541 return ETHOSU_SUCCESS;
542}
543
Bhavik Pateldae5be02020-06-18 15:25:15 +0200544enum ethosu_error_codes ethosu_set_clock_and_power(struct ethosu_device *dev,
545 enum ethosu_clock_q_request clock_q,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200546 enum ethosu_power_q_request power_q)
547{
548#if !defined(ARM_NPU_STUB)
549 struct cmd_r cmd;
550 cmd.word = 0;
551 cmd.clock_q_enable = clock_q;
552 cmd.power_q_enable = power_q;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200553 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100554 LOG_DEBUG("CMD=0x%08x\n", cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200555#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200556 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200557 UNUSED(clock_q);
558 UNUSED(power_q);
559#endif
560 return ETHOSU_SUCCESS;
561}
Bhavik Pateldae5be02020-06-18 15:25:15 +0200562
563uint32_t ethosu_read_reg(struct ethosu_device *dev, uint32_t address)
564{
565#if !defined(ARM_NPU_STUB)
Per Åstrandc8019012020-09-28 08:44:42 +0200566 ASSERT(dev->base_address != 0);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200567 ASSERT(address % 4 == 0);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200568
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200569 volatile uint32_t *reg = dev->base_address + address / sizeof(uint32_t);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200570 return *reg;
571#else
572 UNUSED(dev);
573 UNUSED(address);
574
575 return 0;
576#endif
577}
578
579void ethosu_write_reg(struct ethosu_device *dev, uint32_t address, uint32_t value)
580{
581#if !defined(ARM_NPU_STUB)
Per Åstrandc8019012020-09-28 08:44:42 +0200582 ASSERT(dev->base_address != 0);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200583 ASSERT(address % 4 == 0);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200584
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200585 volatile uint32_t *reg = dev->base_address + address / sizeof(uint32_t);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200586 *reg = value;
587#else
588 UNUSED(dev);
589 UNUSED(address);
590 UNUSED(value);
591#endif
592}
Bhavik Patel5da40922020-07-15 10:06:43 +0200593
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200594void ethosu_write_reg_shadow(struct ethosu_device *dev, uint32_t address, uint32_t value, uint32_t *shadow)
595{
596 ethosu_write_reg(dev, address, value);
597 *shadow = ethosu_read_reg(dev, address);
598}
599
Bhavik Patel5da40922020-07-15 10:06:43 +0200600enum ethosu_error_codes ethosu_save_pmu_config(struct ethosu_device *dev)
601{
602#if !defined(ARM_NPU_STUB)
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200603 // Save the PMU control register
604 dev->pmcr = ethosu_read_reg(dev, NPU_REG_PMCR);
605
606 // Save IRQ control
607 dev->pmint = ethosu_read_reg(dev, NPU_REG_PMINTSET);
608
609 // Save the enabled events mask
610 dev->pmcnten = ethosu_read_reg(dev, NPU_REG_PMCNTENSET);
611
612 // Save start and stop event
613 dev->pmccntr_cfg = ethosu_read_reg(dev, NPU_REG_PMCCNTR_CFG);
614
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200615 // Save the event settings and counters
Bhavik Patel5da40922020-07-15 10:06:43 +0200616 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
617 {
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200618 dev->pmu_evtypr[i] = ethosu_read_reg(dev, NPU_REG_PMEVTYPER0 + i * sizeof(uint32_t));
Bhavik Patel5da40922020-07-15 10:06:43 +0200619 }
620#else
621 UNUSED(dev);
622#endif
623
624 return ETHOSU_SUCCESS;
625}
626
627enum ethosu_error_codes ethosu_restore_pmu_config(struct ethosu_device *dev)
628{
629#if !defined(ARM_NPU_STUB)
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200630 // Restore PMU control register
631 ethosu_write_reg(dev, NPU_REG_PMCR, dev->pmcr);
632
633 // Restore IRQ control
634 ethosu_write_reg(dev, NPU_REG_PMINTSET, dev->pmint);
635
636 // Restore enabled event mask
637 ethosu_write_reg(dev, NPU_REG_PMCNTENSET, dev->pmcnten);
638
639 // Restore start and stop event
640 ethosu_write_reg(dev, NPU_REG_PMCCNTR_CFG, dev->pmccntr_cfg);
641
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200642 // Save the event settings and counters
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200643 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
Bhavik Patel5da40922020-07-15 10:06:43 +0200644 {
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200645 ethosu_write_reg(dev, NPU_REG_PMEVTYPER0 + i * sizeof(uint32_t), dev->pmu_evtypr[i]);
Bhavik Patel5da40922020-07-15 10:06:43 +0200646 }
647#else
648 UNUSED(dev);
649#endif
650
651 return ETHOSU_SUCCESS;
652}
Bhavik Patel5f8dad12020-09-30 09:06:52 +0200653
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200654enum ethosu_error_codes ethosu_save_pmu_counters(struct ethosu_device *dev)
655{
656#if !defined(ARM_NPU_STUB)
657 // Save the cycle counter
658 dev->pmccntr[0] = ethosu_read_reg(dev, NPU_REG_PMCCNTR_LO);
659 dev->pmccntr[1] = ethosu_read_reg(dev, NPU_REG_PMCCNTR_HI);
660
661 // Save the event settings and counters
662 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
663 {
664 dev->pmu_evcntr[i] = ethosu_read_reg(dev, NPU_REG_PMEVCNTR0 + i * sizeof(uint32_t));
665 }
666#else
667 UNUSED(dev);
668#endif
669
670 return ETHOSU_SUCCESS;
671}
672
Bhavik Patel5f8dad12020-09-30 09:06:52 +0200673bool ethosu_status_has_error(struct ethosu_device *dev)
674{
675 bool status_error = false;
676#if !defined(ARM_NPU_STUB)
677 struct status_r status;
678 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
679 status_error = ((1 == status.bus_status) || (1 == status.cmd_parse_error) || (1 == status.wd_fault) ||
680 (1 == status.ecc_fault));
681#else
682 UNUSED(dev);
683#endif
684 return status_error;
685}