blob: 16673257cc7ccfd9ce971d30a93345bdea329dfe [file] [log] [blame]
Kristofer Jonsson49bdee82020-04-06 13:21:21 +02001/*
Anton Mobergb8bcf132021-03-29 10:02:25 +02002 * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
Kristofer Jonsson49bdee82020-04-06 13:21:21 +02003 *
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;
Anton Mobergb8bcf132021-03-29 10:02:25 +020094 config->custom_dma = cfg.custom_dma;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +020095
96 return ETHOSU_SUCCESS;
97}
98
Bhavik Pateldae5be02020-06-18 15:25:15 +020099enum ethosu_error_codes ethosu_run_command_stream(struct ethosu_device *dev,
100 const uint8_t *cmd_stream_ptr,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200101 uint32_t cms_length,
102 const uint64_t *base_addr,
103 int num_base_addr)
104{
Bhavik Patele645fed2020-06-12 14:46:47 +0200105 enum ethosu_error_codes ret_code = ETHOSU_SUCCESS;
106
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200107#if !defined(ARM_NPU_STUB)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200108 ASSERT(num_base_addr <= ETHOSU_DRIVER_BASEP_INDEXES);
109
Per Åstrandc6c1db12020-09-28 08:41:45 +0200110 uint64_t qbase = (uintptr_t)cmd_stream_ptr + BASE_POINTER_OFFSET;
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200111 ASSERT(qbase <= ADDRESS_MASK);
112 LOG_DEBUG("QBASE=0x%016llx, QSIZE=%u, base_pointer_offset=0x%08x\n", qbase, cms_length, BASE_POINTER_OFFSET);
113 ethosu_write_reg(dev, NPU_REG_QBASE0, qbase & 0xffffffff);
114 ethosu_write_reg(dev, NPU_REG_QBASE1, qbase >> 32);
115 ethosu_write_reg(dev, NPU_REG_QSIZE, cms_length);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200116
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200117 for (int i = 0; i < num_base_addr; i++)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200118 {
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200119 uint64_t addr = base_addr[i] + BASE_POINTER_OFFSET;
120 ASSERT(addr <= ADDRESS_MASK);
121 LOG_DEBUG("BASEP%d=0x%016llx\n", i, addr);
122 ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i) * BASEP_OFFSET, addr & 0xffffffff);
123 ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i + 1) * BASEP_OFFSET, addr >> 32);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200124 }
125
Bhavik Pateldae5be02020-06-18 15:25:15 +0200126 ret_code = ethosu_set_command_run(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200127#else
128 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200129 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200130 stream_length = cms_length;
131 UNUSED(cmd_stream_ptr);
132 UNUSED(base_addr);
133 ASSERT(num_base_addr < ETHOSU_DRIVER_BASEP_INDEXES);
134#if defined(NDEBUG)
135 UNUSED(num_base_addr);
136#endif
137#endif
138
Bhavik Patele645fed2020-06-12 14:46:47 +0200139 return ret_code;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200140}
141
Bhavik Pateldae5be02020-06-18 15:25:15 +0200142enum ethosu_error_codes ethosu_is_irq_raised(struct ethosu_device *dev, uint8_t *irq_raised)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200143{
144#if !defined(ARM_NPU_STUB)
145 struct status_r status;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200146 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200147 if (status.irq_raised == 1)
148 {
149 *irq_raised = 1;
150 }
151 else
152 {
153 *irq_raised = 0;
154 }
155#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200156 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200157 *irq_raised = 1;
158#endif
159 return ETHOSU_SUCCESS;
160}
161
Bhavik Pateldae5be02020-06-18 15:25:15 +0200162enum ethosu_error_codes ethosu_clear_irq_status(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200163{
164#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200165 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200166 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200167 struct cmd_r cmd;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200168
Bhavik Patele645fed2020-06-12 14:46:47 +0200169 cmd.word = 0;
170 cmd.clear_irq = 1;
171 cmd.clock_q_enable = oldcmd.clock_q_enable;
172 cmd.power_q_enable = oldcmd.power_q_enable;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200173 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100174 LOG_DEBUG("CMD=0x%08x\n", cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200175#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200176 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200177#endif
178 return ETHOSU_SUCCESS;
179}
180
Bhavik Pateldae5be02020-06-18 15:25:15 +0200181enum ethosu_error_codes ethosu_soft_reset(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200182{
183 enum ethosu_error_codes return_code = ETHOSU_SUCCESS;
184#if !defined(ARM_NPU_STUB)
185 struct reset_r reset;
186 struct prot_r prot;
187
188 reset.word = 0;
Per Åstrande6498f02020-11-09 15:33:12 +0100189 reset.pending_CPL = dev->privileged ? PRIVILEGE_LEVEL_PRIVILEGED : PRIVILEGE_LEVEL_USER;
190 reset.pending_CSL = dev->secure ? SECURITY_LEVEL_SECURE : SECURITY_LEVEL_NON_SECURE;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200191
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200192 // Reset and set security level
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100193 LOG_INFO("Soft reset NPU\n");
Bhavik Pateldae5be02020-06-18 15:25:15 +0200194 ethosu_write_reg(dev, NPU_REG_RESET, reset.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200195
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200196 // Wait for reset to complete
Bhavik Pateldae5be02020-06-18 15:25:15 +0200197 return_code = ethosu_wait_for_reset(dev);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100198 if (return_code != ETHOSU_SUCCESS)
199 {
200 LOG_ERR("Soft reset timed out\n");
201 return return_code;
202 }
203
204 // Verify that NPU has switched security state and privilege level
205 prot.word = ethosu_read_reg(dev, NPU_REG_PROT);
206 if (prot.active_CPL != reset.pending_CPL || prot.active_CSL != reset.pending_CSL)
207 {
208 LOG_ERR("Failed to switch security state and privilege level\n");
209 // Register access not permitted
210 return ETHOSU_GENERIC_FAILURE;
211 }
Bhavik Patel5f8dad12020-09-30 09:06:52 +0200212
Per Åstrande6498f02020-11-09 15:33:12 +0100213 // Save the prot register
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100214 dev->proto = ethosu_read_reg(dev, NPU_REG_PROT);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200215
216 // Soft reset will clear the PMU configuration and counters. The shadow PMU counters
217 // are cleared by saving the PMU counters to ram, which will read back zeros.
218 // The PMU configuration will be restored in the invoke function after power save
219 // has been disabled.
220 ethosu_save_pmu_counters(dev);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200221#else
222 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200223#endif
224
225 return return_code;
226}
227
Bhavik Pateldae5be02020-06-18 15:25:15 +0200228enum ethosu_error_codes ethosu_wait_for_reset(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200229{
230#if !defined(ARM_NPU_STUB)
231 struct status_r status;
232
233 // Wait until reset status indicates that reset has been completed
234 for (int i = 0; i < 100000; i++)
235 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200236 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200237 if (0 == status.reset_status)
238 {
239 break;
240 }
241 }
242
243 if (1 == status.reset_status)
244 {
245 return ETHOSU_GENERIC_FAILURE;
246 }
Bhavik Pateldae5be02020-06-18 15:25:15 +0200247#else
248 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200249#endif
250
251 return ETHOSU_SUCCESS;
252}
253
Bhavik Pateldae5be02020-06-18 15:25:15 +0200254enum ethosu_error_codes ethosu_read_apb_reg(struct ethosu_device *dev,
255 uint32_t start_address,
256 uint16_t num_reg,
257 uint32_t *reg)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200258{
259#if !defined(ARM_NPU_STUB)
260 uint32_t address = start_address;
261
Douglas Troha2e7e3b72020-05-14 20:28:31 +0200262 ASSERT((start_address + num_reg) < ID_REGISTERS_SIZE);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200263
264 for (int i = 0; i < num_reg; i++)
265 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200266 reg[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200267 address += REG_OFFSET;
268 }
269#else
270 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200271 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200272 UNUSED(start_address);
273 UNUSED(num_reg);
274 UNUSED(reg);
275#endif
276
277 return ETHOSU_SUCCESS;
278}
279
Bhavik Pateldae5be02020-06-18 15:25:15 +0200280enum ethosu_error_codes ethosu_set_qconfig(struct ethosu_device *dev, enum ethosu_memory_type memory_type)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200281{
282 if (memory_type > ETHOSU_AXI1_OUTSTANDING_COUNTER3)
283 {
284 return ETHOSU_INVALID_PARAM;
285 }
286#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200287 ethosu_write_reg(dev, NPU_REG_QCONFIG, memory_type);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100288 LOG_DEBUG("QCONFIG=0x%08x\n", memory_type);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200289#else
290 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200291 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200292 UNUSED(memory_type);
293#endif
294 return ETHOSU_SUCCESS;
295}
296
Bhavik Pateldae5be02020-06-18 15:25:15 +0200297enum ethosu_error_codes ethosu_set_regioncfg(struct ethosu_device *dev,
298 uint8_t region,
299 enum ethosu_memory_type memory_type)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200300{
301 if (region > 7)
302 {
303 return ETHOSU_INVALID_PARAM;
304 }
305#if !defined(ARM_NPU_STUB)
306 struct regioncfg_r regioncfg;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200307 regioncfg.word = ethosu_read_reg(dev, NPU_REG_REGIONCFG);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200308 regioncfg.word &= ~(0x3 << (2 * region));
309 regioncfg.word |= (memory_type & 0x3) << (2 * region);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200310 ethosu_write_reg(dev, NPU_REG_REGIONCFG, regioncfg.word);
Kristofer Jonsson125429a2020-08-20 16:52:23 +0200311 LOG_DEBUG("REGIONCFG%u=0x%08x\n", region, regioncfg.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200312#else
313 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200314 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200315 UNUSED(region);
316 UNUSED(memory_type);
317#endif
318 return ETHOSU_SUCCESS;
319}
320
Bhavik Pateldae5be02020-06-18 15:25:15 +0200321enum ethosu_error_codes ethosu_set_axi_limit0(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_limit0_r axi_limit0;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200329 axi_limit0.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200330 axi_limit0.max_beats = max_beats;
331 axi_limit0.memtype = memtype;
332 axi_limit0.max_outstanding_read_m1 = max_reads - 1;
333 axi_limit0.max_outstanding_write_m1 = max_writes - 1;
334
Bhavik Pateldae5be02020-06-18 15:25:15 +0200335 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT0, axi_limit0.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100336 LOG_DEBUG("AXI_LIMIT0=0x%08x\n", axi_limit0.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_limit1(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_limit1_r axi_limit1;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200357 axi_limit1.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200358 axi_limit1.max_beats = max_beats;
359 axi_limit1.memtype = memtype;
360 axi_limit1.max_outstanding_read_m1 = max_reads - 1;
361 axi_limit1.max_outstanding_write_m1 = max_writes - 1;
362
Bhavik Pateldae5be02020-06-18 15:25:15 +0200363 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT1, axi_limit1.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100364 LOG_DEBUG("AXI_LIMIT1=0x%08x\n", axi_limit1.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200365#else
366 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200367 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200368 UNUSED(max_beats);
369 UNUSED(memtype);
370 UNUSED(max_reads);
371 UNUSED(max_writes);
372#endif
373
374 return ETHOSU_SUCCESS;
375}
376
Bhavik Pateldae5be02020-06-18 15:25:15 +0200377enum ethosu_error_codes ethosu_set_axi_limit2(struct ethosu_device *dev,
378 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200379 enum ethosu_axi_limit_mem_type memtype,
380 uint8_t max_reads,
381 uint8_t max_writes)
382{
383#if !defined(ARM_NPU_STUB)
384 struct axi_limit2_r axi_limit2;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200385 axi_limit2.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200386 axi_limit2.max_beats = max_beats;
387 axi_limit2.memtype = memtype;
388 axi_limit2.max_outstanding_read_m1 = max_reads - 1;
389 axi_limit2.max_outstanding_write_m1 = max_writes - 1;
390
Bhavik Pateldae5be02020-06-18 15:25:15 +0200391 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT2, axi_limit2.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100392 LOG_DEBUG("AXI_LIMIT2=0x%08x\n", axi_limit2.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200393#else
394 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200395 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200396 UNUSED(max_beats);
397 UNUSED(memtype);
398 UNUSED(max_reads);
399 UNUSED(max_writes);
400#endif
401
402 return ETHOSU_SUCCESS;
403}
404
Bhavik Pateldae5be02020-06-18 15:25:15 +0200405enum ethosu_error_codes ethosu_set_axi_limit3(struct ethosu_device *dev,
406 enum ethosu_axi_limit_beats max_beats,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200407 enum ethosu_axi_limit_mem_type memtype,
408 uint8_t max_reads,
409 uint8_t max_writes)
410{
411#if !defined(ARM_NPU_STUB)
412 struct axi_limit3_r axi_limit3;
Per Åstrand9716b5e2020-08-19 13:15:06 +0200413 axi_limit3.word = 0;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200414 axi_limit3.max_beats = max_beats;
415 axi_limit3.memtype = memtype;
416 axi_limit3.max_outstanding_read_m1 = max_reads - 1;
417 axi_limit3.max_outstanding_write_m1 = max_writes - 1;
418
Bhavik Pateldae5be02020-06-18 15:25:15 +0200419 ethosu_write_reg(dev, NPU_REG_AXI_LIMIT3, axi_limit3.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100420 LOG_DEBUG("AXI_LIMIT3=0x%08x\n", axi_limit3.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200421#else
422 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200423 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200424 UNUSED(max_beats);
425 UNUSED(memtype);
426 UNUSED(max_reads);
427 UNUSED(max_writes);
428#endif
429
430 return ETHOSU_SUCCESS;
431}
432
Bhavik Pateldae5be02020-06-18 15:25:15 +0200433enum ethosu_error_codes ethosu_get_revision(struct ethosu_device *dev, uint32_t *revision)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200434{
435#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200436 *revision = ethosu_read_reg(dev, NPU_REG_REVISION);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200437#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200438 UNUSED(dev);
439 *revision = 0xDEADC0DE;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200440#endif
441 return ETHOSU_SUCCESS;
442}
443
Bhavik Pateldae5be02020-06-18 15:25:15 +0200444enum ethosu_error_codes ethosu_get_qread(struct ethosu_device *dev, uint32_t *qread)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200445{
446#if !defined(ARM_NPU_STUB)
Bhavik Pateldae5be02020-06-18 15:25:15 +0200447 *qread = ethosu_read_reg(dev, NPU_REG_QREAD);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200448#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200449 UNUSED(dev);
450 *qread = stream_length;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200451#endif
452 return ETHOSU_SUCCESS;
453}
454
Bhavik Pateldae5be02020-06-18 15:25:15 +0200455enum ethosu_error_codes ethosu_get_status_mask(struct ethosu_device *dev, uint16_t *status_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200456{
457#if !defined(ARM_NPU_STUB)
458 struct status_r status;
459
Bhavik Pateldae5be02020-06-18 15:25:15 +0200460 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200461 *status_mask = status.word & 0xFFFF;
462#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200463 UNUSED(dev);
464 *status_mask = 0x0000;
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200465#endif
466 return ETHOSU_SUCCESS;
467}
468
Bhavik Pateldae5be02020-06-18 15:25:15 +0200469enum ethosu_error_codes ethosu_get_irq_history_mask(struct ethosu_device *dev, uint16_t *irq_history_mask)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200470{
471#if !defined(ARM_NPU_STUB)
472 struct status_r status;
473
Bhavik Pateldae5be02020-06-18 15:25:15 +0200474 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200475 *irq_history_mask = status.irq_history_mask;
476#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200477 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200478 *irq_history_mask = 0xffff;
479#endif
480 return ETHOSU_SUCCESS;
481}
482
Bhavik Pateldae5be02020-06-18 15:25:15 +0200483enum 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 +0200484{
485#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200486 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200487 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200488
489 struct cmd_r cmd;
490 cmd.word = 0;
491 cmd.clock_q_enable = oldcmd.clock_q_enable;
492 cmd.power_q_enable = oldcmd.power_q_enable;
493 cmd.clear_irq_history = irq_history_clear_mask;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200494 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100495 LOG_DEBUG("CMD=0x%08x\n", cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200496#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200497 UNUSED(dev);
Bhavik Patelbcb5aaa2020-05-12 10:09:41 +0200498 UNUSED(irq_history_clear_mask);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200499#endif
500 return ETHOSU_SUCCESS;
501}
502
Bhavik Pateldae5be02020-06-18 15:25:15 +0200503enum ethosu_error_codes ethosu_set_command_run(struct ethosu_device *dev)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200504{
505#if !defined(ARM_NPU_STUB)
Bhavik Patele645fed2020-06-12 14:46:47 +0200506 struct cmd_r oldcmd;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200507 oldcmd.word = ethosu_read_reg(dev, NPU_REG_CMD);
Bhavik Patele645fed2020-06-12 14:46:47 +0200508
509 struct cmd_r cmd;
510 cmd.word = 0;
511 cmd.transition_to_running_state = 1;
512 cmd.clock_q_enable = oldcmd.clock_q_enable;
513 cmd.power_q_enable = oldcmd.power_q_enable;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200514 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100515 LOG_DEBUG("CMD=0x%08x\n", cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200516#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200517 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200518#endif
519 return ETHOSU_SUCCESS;
520}
521
Bhavik Pateldae5be02020-06-18 15:25:15 +0200522enum ethosu_error_codes ethosu_get_shram_data(struct ethosu_device *dev, int section, uint32_t *shram_p)
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200523{
524#if !defined(ARM_NPU_STUB)
525 int i = 0;
526 uint32_t address = NPU_REG_SHARED_BUFFER0;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200527 ethosu_write_reg(dev, NPU_REG_DEBUG_ADDRESS, section * BYTES_1KB);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200528
529 while (address <= NPU_REG_SHARED_BUFFER255)
530 {
Bhavik Pateldae5be02020-06-18 15:25:15 +0200531 shram_p[i] = ethosu_read_reg(dev, address);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200532 address += REG_OFFSET;
533 i++;
534 }
535#else
536 // NPU stubbed
Bhavik Pateldae5be02020-06-18 15:25:15 +0200537 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200538 UNUSED(section);
539 UNUSED(shram_p);
540#endif
541
542 return ETHOSU_SUCCESS;
543}
544
Bhavik Pateldae5be02020-06-18 15:25:15 +0200545enum ethosu_error_codes ethosu_set_clock_and_power(struct ethosu_device *dev,
546 enum ethosu_clock_q_request clock_q,
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200547 enum ethosu_power_q_request power_q)
548{
549#if !defined(ARM_NPU_STUB)
550 struct cmd_r cmd;
551 cmd.word = 0;
552 cmd.clock_q_enable = clock_q;
553 cmd.power_q_enable = power_q;
Bhavik Pateldae5be02020-06-18 15:25:15 +0200554 ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
Kristofer Jonssonc6e7a1f2020-11-24 09:20:14 +0100555 LOG_DEBUG("CMD=0x%08x\n", cmd.word);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200556#else
Bhavik Pateldae5be02020-06-18 15:25:15 +0200557 UNUSED(dev);
Kristofer Jonsson49bdee82020-04-06 13:21:21 +0200558 UNUSED(clock_q);
559 UNUSED(power_q);
560#endif
561 return ETHOSU_SUCCESS;
562}
Bhavik Pateldae5be02020-06-18 15:25:15 +0200563
564uint32_t ethosu_read_reg(struct ethosu_device *dev, uint32_t address)
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 return *reg;
572#else
573 UNUSED(dev);
574 UNUSED(address);
575
576 return 0;
577#endif
578}
579
580void ethosu_write_reg(struct ethosu_device *dev, uint32_t address, uint32_t value)
581{
582#if !defined(ARM_NPU_STUB)
Per Åstrandc8019012020-09-28 08:44:42 +0200583 ASSERT(dev->base_address != 0);
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200584 ASSERT(address % 4 == 0);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200585
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200586 volatile uint32_t *reg = dev->base_address + address / sizeof(uint32_t);
Bhavik Pateldae5be02020-06-18 15:25:15 +0200587 *reg = value;
588#else
589 UNUSED(dev);
590 UNUSED(address);
591 UNUSED(value);
592#endif
593}
Bhavik Patel5da40922020-07-15 10:06:43 +0200594
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200595void ethosu_write_reg_shadow(struct ethosu_device *dev, uint32_t address, uint32_t value, uint32_t *shadow)
596{
597 ethosu_write_reg(dev, address, value);
598 *shadow = ethosu_read_reg(dev, address);
599}
600
Bhavik Patel5da40922020-07-15 10:06:43 +0200601enum ethosu_error_codes ethosu_save_pmu_config(struct ethosu_device *dev)
602{
603#if !defined(ARM_NPU_STUB)
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200604 // Save the PMU control register
605 dev->pmcr = ethosu_read_reg(dev, NPU_REG_PMCR);
606
607 // Save IRQ control
608 dev->pmint = ethosu_read_reg(dev, NPU_REG_PMINTSET);
609
610 // Save the enabled events mask
611 dev->pmcnten = ethosu_read_reg(dev, NPU_REG_PMCNTENSET);
612
613 // Save start and stop event
614 dev->pmccntr_cfg = ethosu_read_reg(dev, NPU_REG_PMCCNTR_CFG);
615
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200616 // Save the event settings and counters
Bhavik Patel5da40922020-07-15 10:06:43 +0200617 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
618 {
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200619 dev->pmu_evtypr[i] = ethosu_read_reg(dev, NPU_REG_PMEVTYPER0 + i * sizeof(uint32_t));
Bhavik Patel5da40922020-07-15 10:06:43 +0200620 }
621#else
622 UNUSED(dev);
623#endif
624
625 return ETHOSU_SUCCESS;
626}
627
628enum ethosu_error_codes ethosu_restore_pmu_config(struct ethosu_device *dev)
629{
630#if !defined(ARM_NPU_STUB)
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200631 // Restore PMU control register
632 ethosu_write_reg(dev, NPU_REG_PMCR, dev->pmcr);
633
634 // Restore IRQ control
635 ethosu_write_reg(dev, NPU_REG_PMINTSET, dev->pmint);
636
637 // Restore enabled event mask
638 ethosu_write_reg(dev, NPU_REG_PMCNTENSET, dev->pmcnten);
639
640 // Restore start and stop event
641 ethosu_write_reg(dev, NPU_REG_PMCCNTR_CFG, dev->pmccntr_cfg);
642
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200643 // Save the event settings and counters
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200644 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
Bhavik Patel5da40922020-07-15 10:06:43 +0200645 {
Kristofer Jonssonef387ea2020-08-25 16:32:21 +0200646 ethosu_write_reg(dev, NPU_REG_PMEVTYPER0 + i * sizeof(uint32_t), dev->pmu_evtypr[i]);
Bhavik Patel5da40922020-07-15 10:06:43 +0200647 }
648#else
649 UNUSED(dev);
650#endif
651
652 return ETHOSU_SUCCESS;
653}
Bhavik Patel5f8dad12020-09-30 09:06:52 +0200654
Kristofer Jonsson4dc73dc2020-10-16 12:33:47 +0200655enum ethosu_error_codes ethosu_save_pmu_counters(struct ethosu_device *dev)
656{
657#if !defined(ARM_NPU_STUB)
658 // Save the cycle counter
659 dev->pmccntr[0] = ethosu_read_reg(dev, NPU_REG_PMCCNTR_LO);
660 dev->pmccntr[1] = ethosu_read_reg(dev, NPU_REG_PMCCNTR_HI);
661
662 // Save the event settings and counters
663 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
664 {
665 dev->pmu_evcntr[i] = ethosu_read_reg(dev, NPU_REG_PMEVCNTR0 + i * sizeof(uint32_t));
666 }
667#else
668 UNUSED(dev);
669#endif
670
671 return ETHOSU_SUCCESS;
672}
673
Bhavik Patel5f8dad12020-09-30 09:06:52 +0200674bool ethosu_status_has_error(struct ethosu_device *dev)
675{
676 bool status_error = false;
677#if !defined(ARM_NPU_STUB)
678 struct status_r status;
679 status.word = ethosu_read_reg(dev, NPU_REG_STATUS);
680 status_error = ((1 == status.bus_status) || (1 == status.cmd_parse_error) || (1 == status.wd_fault) ||
681 (1 == status.ecc_fault));
682#else
683 UNUSED(dev);
684#endif
685 return status_error;
686}