blob: adfdbb11f0c0cafacbf1d6128ff6236244615ed6 [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 Jonsson49bdee82020-04-06 13:21:21 +0200173#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200174 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200175#endif
176 return ETHOSU_SUCCESS;
177}
178
Bhavik Pateldae5be02020-06-18 15:25:15 +0200179enum ethosu_error_codes ethosu_soft_reset(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200180{
181 enum ethosu_error_codes return_code = ETHOSU_SUCCESS;
182#if !defined(ARM_NPU_STUB)
183 struct reset_r reset;
184 struct prot_r prot;
185
186 reset.word = 0;
Per Åstrande6498f02020-11-09 15:33:12 +0100187 reset.pending_CPL = dev->privileged ? PRIVILEGE_LEVEL_PRIVILEGED : PRIVILEGE_LEVEL_USER;
188 reset.pending_CSL = dev->secure ? SECURITY_LEVEL_SECURE : SECURITY_LEVEL_NON_SECURE;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200189
Bhavik Pateldae5be02020-06-18 15:25:15 +0200190 prot.word = ethosu_read_reg(dev, NPU_REG_PROT);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200191
192 if (prot.active_CPL < reset.pending_CPL && prot.active_CSL > reset.pending_CSL)
193 {
Per Åstrande6498f02020-11-09 15:33:12 +0100194 LOG_ERR("Failed to reset NPU\n");
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200195 // Register access not permitted
196 return ETHOSU_GENERIC_FAILURE;
197 }
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200198
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200199 // Reset and set security level
Bhavik Pateldae5be02020-06-18 15:25:15 +0200200 ethosu_write_reg(dev, NPU_REG_RESET, reset.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200201
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200202 // Wait for reset to complete
Bhavik Pateldae5be02020-06-18 15:25:15 +0200203 return_code = ethosu_wait_for_reset(dev);
Bhavik Patel5f8dad12020-09-30 09:06:52 +0200204
Per Åstrande6498f02020-11-09 15:33:12 +0100205 // Save the prot register
Bhavik Patel5f8dad12020-09-30 09:06:52 +0200206 dev->reset = ethosu_read_reg(dev, NPU_REG_PROT);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200207
208 // Soft reset will clear the PMU configuration and counters. The shadow PMU counters
209 // are cleared by saving the PMU counters to ram, which will read back zeros.
210 // The PMU configuration will be restored in the invoke function after power save
211 // has been disabled.
212 ethosu_save_pmu_counters(dev);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200213#else
214 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200215#endif
216
217 return return_code;
218}
219
Bhavik Pateldae5be02020-06-18 15:25:15 +0200220enum ethosu_error_codes ethosu_wait_for_reset(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200221{
222#if !defined(ARM_NPU_STUB)
223 struct status_r status;
224
225 // Wait until reset status indicates that reset has been completed
226 for (int i = 0; i < 100000; i++)
227 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200228 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200229 if (0 == status.reset_status)
230 {
231 break;
232 }
233 }
234
235 if (1 == status.reset_status)
236 {
237 return ETHOSU_GENERIC_FAILURE;
238 }
Bhavik Pateldae5be02020-06-18 15:25:15 +0200239#else
240 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200241#endif
242
243 return ETHOSU_SUCCESS;
244}
245
Bhavik Pateldae5be02020-06-18 15:25:15 +0200246enum ethosu_error_codes ethosu_read_apb_reg(struct ethosu_device *dev,
247 uint32_t start_address,
248 uint16_t num_reg,
249 uint32_t *reg)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200250{
251#if !defined(ARM_NPU_STUB)
252 uint32_t address = start_address;
253
Douglas Troha2e7e3b72020-05-14 20:28:31 +0200254 ASSERT((start_address + num_reg) < ID_REGISTERS_SIZE);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200255
256 for (int i = 0; i < num_reg; i++)
257 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200258 reg[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200259 address += REG_OFFSET;
260 }
261#else
262 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200263 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200264 UNUSED(start_address);
265 UNUSED(num_reg);
266 UNUSED(reg);
267#endif
268
269 return ETHOSU_SUCCESS;
270}
271
Bhavik Pateldae5be02020-06-18 15:25:15 +0200272enum ethosu_error_codes ethosu_set_qconfig(struct ethosu_device *dev, enum ethosu_memory_type memory_type)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200273{
274 if (memory_type > ETHOSU_AXI1_OUTSTANDING_COUNTER3)
275 {
276 return ETHOSU_INVALID_PARAM;
277 }
278#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200279 ethosu_write_reg(dev, NPU_REG_QCONFIG, memory_type);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200280#else
281 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200282 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200283 UNUSED(memory_type);
284#endif
285 return ETHOSU_SUCCESS;
286}
287
Bhavik Pateldae5be02020-06-18 15:25:15 +0200288enum ethosu_error_codes ethosu_set_regioncfg(struct ethosu_device *dev,
289 uint8_t region,
290 enum ethosu_memory_type memory_type)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200291{
292 if (region > 7)
293 {
294 return ETHOSU_INVALID_PARAM;
295 }
296#if !defined(ARM_NPU_STUB)
297 struct regioncfg_r regioncfg;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200298 regioncfg.word = ethosu_read_reg(dev, NPU_REG_REGIONCFG);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200299 regioncfg.word &= ~(0x3 << (2 * region));
300 regioncfg.word |= (memory_type & 0x3) << (2 * region);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200301 ethosu_write_reg(dev, NPU_REG_REGIONCFG, regioncfg.word);
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200302 LOG_DEBUG("REGIONCFG%u=0x%08x\n", region, regioncfg.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200303#else
304 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200305 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200306 UNUSED(region);
307 UNUSED(memory_type);
308#endif
309 return ETHOSU_SUCCESS;
310}
311
Bhavik Pateldae5be02020-06-18 15:25:15 +0200312enum ethosu_error_codes ethosu_set_axi_limit0(struct ethosu_device *dev,
313 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200314 enum ethosu_axi_limit_mem_type memtype,
315 uint8_t max_reads,
316 uint8_t max_writes)
317{
318#if !defined(ARM_NPU_STUB)
319 struct axi_limit0_r axi_limit0;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200320 axi_limit0.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200321 axi_limit0.max_beats = max_beats;
322 axi_limit0.memtype = memtype;
323 axi_limit0.max_outstanding_read_m1 = max_reads - 1;
324 axi_limit0.max_outstanding_write_m1 = max_writes - 1;
325
Bhavik Pateldae5be02020-06-18 15:25:15 +0200326 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT0, axi_limit0.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200327#else
328 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200329 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200330 UNUSED(max_beats);
331 UNUSED(memtype);
332 UNUSED(max_reads);
333 UNUSED(max_writes);
334#endif
335
336 return ETHOSU_SUCCESS;
337}
338
Bhavik Pateldae5be02020-06-18 15:25:15 +0200339enum ethosu_error_codes ethosu_set_axi_limit1(struct ethosu_device *dev,
340 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200341 enum ethosu_axi_limit_mem_type memtype,
342 uint8_t max_reads,
343 uint8_t max_writes)
344{
345#if !defined(ARM_NPU_STUB)
346 struct axi_limit1_r axi_limit1;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200347 axi_limit1.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200348 axi_limit1.max_beats = max_beats;
349 axi_limit1.memtype = memtype;
350 axi_limit1.max_outstanding_read_m1 = max_reads - 1;
351 axi_limit1.max_outstanding_write_m1 = max_writes - 1;
352
Bhavik Pateldae5be02020-06-18 15:25:15 +0200353 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT1, axi_limit1.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200354#else
355 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200356 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200357 UNUSED(max_beats);
358 UNUSED(memtype);
359 UNUSED(max_reads);
360 UNUSED(max_writes);
361#endif
362
363 return ETHOSU_SUCCESS;
364}
365
Bhavik Pateldae5be02020-06-18 15:25:15 +0200366enum ethosu_error_codes ethosu_set_axi_limit2(struct ethosu_device *dev,
367 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200368 enum ethosu_axi_limit_mem_type memtype,
369 uint8_t max_reads,
370 uint8_t max_writes)
371{
372#if !defined(ARM_NPU_STUB)
373 struct axi_limit2_r axi_limit2;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200374 axi_limit2.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200375 axi_limit2.max_beats = max_beats;
376 axi_limit2.memtype = memtype;
377 axi_limit2.max_outstanding_read_m1 = max_reads - 1;
378 axi_limit2.max_outstanding_write_m1 = max_writes - 1;
379
Bhavik Pateldae5be02020-06-18 15:25:15 +0200380 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT2, axi_limit2.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200381#else
382 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200383 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200384 UNUSED(max_beats);
385 UNUSED(memtype);
386 UNUSED(max_reads);
387 UNUSED(max_writes);
388#endif
389
390 return ETHOSU_SUCCESS;
391}
392
Bhavik Pateldae5be02020-06-18 15:25:15 +0200393enum ethosu_error_codes ethosu_set_axi_limit3(struct ethosu_device *dev,
394 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200395 enum ethosu_axi_limit_mem_type memtype,
396 uint8_t max_reads,
397 uint8_t max_writes)
398{
399#if !defined(ARM_NPU_STUB)
400 struct axi_limit3_r axi_limit3;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200401 axi_limit3.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200402 axi_limit3.max_beats = max_beats;
403 axi_limit3.memtype = memtype;
404 axi_limit3.max_outstanding_read_m1 = max_reads - 1;
405 axi_limit3.max_outstanding_write_m1 = max_writes - 1;
406
Bhavik Pateldae5be02020-06-18 15:25:15 +0200407 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT3, axi_limit3.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200408#else
409 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200410 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200411 UNUSED(max_beats);
412 UNUSED(memtype);
413 UNUSED(max_reads);
414 UNUSED(max_writes);
415#endif
416
417 return ETHOSU_SUCCESS;
418}
419
Bhavik Pateldae5be02020-06-18 15:25:15 +0200420enum ethosu_error_codes ethosu_get_revision(struct ethosu_device *dev, uint32_t *revision)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200421{
422#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200423 *revision = ethosu_read_reg(dev, NPU_REG_REVISION);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200424#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200425 UNUSED(dev);
426 *revision = 0xDEADC0DE;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200427#endif
428 return ETHOSU_SUCCESS;
429}
430
Bhavik Pateldae5be02020-06-18 15:25:15 +0200431enum ethosu_error_codes ethosu_get_qread(struct ethosu_device *dev, uint32_t *qread)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200432{
433#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200434 *qread = ethosu_read_reg(dev, NPU_REG_QREAD);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200435#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200436 UNUSED(dev);
437 *qread = stream_length;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200438#endif
439 return ETHOSU_SUCCESS;
440}
441
Bhavik Pateldae5be02020-06-18 15:25:15 +0200442enum ethosu_error_codes ethosu_get_status_mask(struct ethosu_device *dev, uint16_t *status_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200443{
444#if !defined(ARM_NPU_STUB)
445 struct status_r status;
446
Bhavik Pateldae5be02020-06-18 15:25:15 +0200447 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200448 *status_mask = status.word & 0xFFFF;
449#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200450 UNUSED(dev);
451 *status_mask = 0x0000;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200452#endif
453 return ETHOSU_SUCCESS;
454}
455
Bhavik Pateldae5be02020-06-18 15:25:15 +0200456enum ethosu_error_codes ethosu_get_irq_history_mask(struct ethosu_device *dev, uint16_t *irq_history_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200457{
458#if !defined(ARM_NPU_STUB)
459 struct status_r status;
460
Bhavik Pateldae5be02020-06-18 15:25:15 +0200461 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200462 *irq_history_mask = status.irq_history_mask;
463#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200464 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200465 *irq_history_mask = 0xffff;
466#endif
467 return ETHOSU_SUCCESS;
468}
469
Bhavik Pateldae5be02020-06-18 15:25:15 +0200470enum 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 +0200471{
472#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200473 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200474 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200475
476 struct cmd_r cmd;
477 cmd.word = 0;
478 cmd.clock_q_enable = oldcmd.clock_q_enable;
479 cmd.power_q_enable = oldcmd.power_q_enable;
480 cmd.clear_irq_history = irq_history_clear_mask;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200481 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200482#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200483 UNUSED(dev);
Bhavik Patelbcb5aaa2020-05-12 10:09:41 +0200484 UNUSED(irq_history_clear_mask);
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_set_command_run(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200490{
491#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200492 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200493 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200494
495 struct cmd_r cmd;
496 cmd.word = 0;
497 cmd.transition_to_running_state = 1;
498 cmd.clock_q_enable = oldcmd.clock_q_enable;
499 cmd.power_q_enable = oldcmd.power_q_enable;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200500 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200501#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200502 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200503#endif
504 return ETHOSU_SUCCESS;
505}
506
Bhavik Pateldae5be02020-06-18 15:25:15 +0200507enum ethosu_error_codes ethosu_get_shram_data(struct ethosu_device *dev, int section, uint32_t *shram_p)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200508{
509#if !defined(ARM_NPU_STUB)
510 int i = 0;
511 uint32_t address = NPU_REG_SHARED_BUFFER0;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200512 ethosu_write_reg(dev, NPU_REG_DEBUG_ADDRESS, section * BYTES_1KB);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200513
514 while (address <= NPU_REG_SHARED_BUFFER255)
515 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200516 shram_p[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200517 address += REG_OFFSET;
518 i++;
519 }
520#else
521 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200522 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200523 UNUSED(section);
524 UNUSED(shram_p);
525#endif
526
527 return ETHOSU_SUCCESS;
528}
529
Bhavik Pateldae5be02020-06-18 15:25:15 +0200530enum ethosu_error_codes ethosu_set_clock_and_power(struct ethosu_device *dev,
531 enum ethosu_clock_q_request clock_q,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200532 enum ethosu_power_q_request power_q)
533{
534#if !defined(ARM_NPU_STUB)
535 struct cmd_r cmd;
536 cmd.word = 0;
537 cmd.clock_q_enable = clock_q;
538 cmd.power_q_enable = power_q;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200539 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200540#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200541 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200542 UNUSED(clock_q);
543 UNUSED(power_q);
544#endif
545 return ETHOSU_SUCCESS;
546}
Bhavik Pateldae5be02020-06-18 15:25:15 +0200547
548uint32_t ethosu_read_reg(struct ethosu_device *dev, uint32_t address)
549{
550#if !defined(ARM_NPU_STUB)
Per Åstrandc8019012020-09-28 08:44:42 +0200551 ASSERT(dev->base_address != 0);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200552 ASSERT(address % 4 == 0);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200553
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200554 volatile uint32_t *reg = dev->base_address + address / sizeof(uint32_t);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200555 return *reg;
556#else
557 UNUSED(dev);
558 UNUSED(address);
559
560 return 0;
561#endif
562}
563
564void ethosu_write_reg(struct ethosu_device *dev, uint32_t address, uint32_t value)
565{
566#if !defined(ARM_NPU_STUB)
Per Åstrandc8019012020-09-28 08:44:42 +0200567 ASSERT(dev->base_address != 0);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200568 ASSERT(address % 4 == 0);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200569
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200570 volatile uint32_t *reg = dev->base_address + address / sizeof(uint32_t);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200571 *reg = value;
572#else
573 UNUSED(dev);
574 UNUSED(address);
575 UNUSED(value);
576#endif
577}
Bhavik Patel5da40922020-07-15 10:06:43 +0200578
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200579void ethosu_write_reg_shadow(struct ethosu_device *dev, uint32_t address, uint32_t value, uint32_t *shadow)
580{
581 ethosu_write_reg(dev, address, value);
582 *shadow = ethosu_read_reg(dev, address);
583}
584
Bhavik Patel5da40922020-07-15 10:06:43 +0200585enum ethosu_error_codes ethosu_save_pmu_config(struct ethosu_device *dev)
586{
587#if !defined(ARM_NPU_STUB)
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200588 // Save the PMU control register
589 dev->pmcr = ethosu_read_reg(dev, NPU_REG_PMCR);
590
591 // Save IRQ control
592 dev->pmint = ethosu_read_reg(dev, NPU_REG_PMINTSET);
593
594 // Save the enabled events mask
595 dev->pmcnten = ethosu_read_reg(dev, NPU_REG_PMCNTENSET);
596
597 // Save start and stop event
598 dev->pmccntr_cfg = ethosu_read_reg(dev, NPU_REG_PMCCNTR_CFG);
599
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200600 // Save the event settings and counters
Bhavik Patel5da40922020-07-15 10:06:43 +0200601 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
602 {
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200603 dev->pmu_evtypr[i] = ethosu_read_reg(dev, NPU_REG_PMEVTYPER0 + i * sizeof(uint32_t));
Bhavik Patel5da40922020-07-15 10:06:43 +0200604 }
605#else
606 UNUSED(dev);
607#endif
608
609 return ETHOSU_SUCCESS;
610}
611
612enum ethosu_error_codes ethosu_restore_pmu_config(struct ethosu_device *dev)
613{
614#if !defined(ARM_NPU_STUB)
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200615 // Restore PMU control register
616 ethosu_write_reg(dev, NPU_REG_PMCR, dev->pmcr);
617
618 // Restore IRQ control
619 ethosu_write_reg(dev, NPU_REG_PMINTSET, dev->pmint);
620
621 // Restore enabled event mask
622 ethosu_write_reg(dev, NPU_REG_PMCNTENSET, dev->pmcnten);
623
624 // Restore start and stop event
625 ethosu_write_reg(dev, NPU_REG_PMCCNTR_CFG, dev->pmccntr_cfg);
626
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200627 // Save the event settings and counters
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200628 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
Bhavik Patel5da40922020-07-15 10:06:43 +0200629 {
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200630 ethosu_write_reg(dev, NPU_REG_PMEVTYPER0 + i * sizeof(uint32_t), dev->pmu_evtypr[i]);
Bhavik Patel5da40922020-07-15 10:06:43 +0200631 }
632#else
633 UNUSED(dev);
634#endif
635
636 return ETHOSU_SUCCESS;
637}
Bhavik Patel5f8dad12020-09-30 09:06:52 +0200638
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200639enum ethosu_error_codes ethosu_save_pmu_counters(struct ethosu_device *dev)
640{
641#if !defined(ARM_NPU_STUB)
642 // Save the cycle counter
643 dev->pmccntr[0] = ethosu_read_reg(dev, NPU_REG_PMCCNTR_LO);
644 dev->pmccntr[1] = ethosu_read_reg(dev, NPU_REG_PMCCNTR_HI);
645
646 // Save the event settings and counters
647 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
648 {
649 dev->pmu_evcntr[i] = ethosu_read_reg(dev, NPU_REG_PMEVCNTR0 + i * sizeof(uint32_t));
650 }
651#else
652 UNUSED(dev);
653#endif
654
655 return ETHOSU_SUCCESS;
656}
657
Bhavik Patel5f8dad12020-09-30 09:06:52 +0200658bool ethosu_status_has_error(struct ethosu_device *dev)
659{
660 bool status_error = false;
661#if !defined(ARM_NPU_STUB)
662 struct status_r status;
663 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
664 status_error = ((1 == status.bus_status) || (1 == status.cmd_parse_error) || (1 == status.wd_fault) ||
665 (1 == status.ecc_fault));
666#else
667 UNUSED(dev);
668#endif
669 return status_error;
670}