aboutsummaryrefslogtreecommitdiff
path: root/include/ethosu_driver.h
blob: e2d3f5ba9f3bf871dd5d7d002463cf99ee8ebaa8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
/*
 * SPDX-FileCopyrightText: Copyright 2019-2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ETHOSU_DRIVER_H
#define ETHOSU_DRIVER_H

/******************************************************************************
 * Includes
 ******************************************************************************/

#include "ethosu_types.h"

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/******************************************************************************
 * Defines
 ******************************************************************************/

#define ETHOSU_DRIVER_VERSION_MAJOR 0  ///< Driver major version
#define ETHOSU_DRIVER_VERSION_MINOR 16 ///< Driver minor version
#define ETHOSU_DRIVER_VERSION_PATCH 0  ///< Driver patch version

#define ETHOSU_SEMAPHORE_WAIT_FOREVER (UINT64_MAX)

#ifndef ETHOSU_SEMAPHORE_WAIT_INFERENCE
#define ETHOSU_SEMAPHORE_WAIT_INFERENCE ETHOSU_SEMAPHORE_WAIT_FOREVER
#endif

/******************************************************************************
 * Types
 ******************************************************************************/

// Forward declare
struct ethosu_device;

enum ethosu_job_state
{
    ETHOSU_JOB_IDLE = 0,
    ETHOSU_JOB_RUNNING,
    ETHOSU_JOB_DONE
};

enum ethosu_job_result
{
    ETHOSU_JOB_RESULT_OK = 0,
    ETHOSU_JOB_RESULT_TIMEOUT,
    ETHOSU_JOB_RESULT_ERROR
};

struct ethosu_job
{
    volatile enum ethosu_job_state state;
    volatile enum ethosu_job_result result;
    const void *custom_data_ptr;
    int custom_data_size;
    const uint64_t *base_addr;
    const size_t *base_addr_size;
    int num_base_addr;
    void *user_arg;
};

struct ethosu_driver
{
    struct ethosu_device *dev;
    struct ethosu_driver *next;
    struct ethosu_job job;
    void *semaphore;
    uint64_t fast_memory;
    size_t fast_memory_size;
    uint32_t power_request_counter;
    bool reserved;
};

struct ethosu_driver_version
{
    uint8_t major;
    uint8_t minor;
    uint8_t patch;
};

enum ethosu_request_clients
{
    ETHOSU_PMU_REQUEST       = 0,
    ETHOSU_INFERENCE_REQUEST = 1,
};

/******************************************************************************
 * Prototypes (weak functions in driver)
 ******************************************************************************/

/**
 * Interrupt handler to be called on IRQ from Ethos-U
 *
 * @param drv       Pointer to driver handle
 */
void ethosu_irq_handler(struct ethosu_driver *drv);

/**
 * Flush/clean the data cache by address and size. Passing NULL as p argument
 * expects the whole cache to be flushed.
 *
 * Addresses passed to this function must be 16 byte aligned.
 *
 * @param p         16 byte aligned address
 * @param bytes     Size of memory block in bytes
 */
void ethosu_flush_dcache(uint32_t *p, size_t bytes);

/**
 * Invalidate the data cache by address and size. Passing NULL as p argument
 * expects the whole cache to be invalidated.
 *
 * Addresses passed to this function must be 16 byte aligned.
 *
 * @param p         16 byte aligned address
 * @param bytes     Size in bytes
 */
void ethosu_invalidate_dcache(uint32_t *p, size_t bytes);

/**
 * Minimal mutex implementation for baremetal applications. See
 * ethosu_driver.c.
 *
 * @return Pointer to mutex handle
 */
void *ethosu_mutex_create(void);

/**
 * Destroy mutex.
 *
 * @param mutex     Pointer to mutex handle
 */
void ethosu_mutex_destroy(void *mutex);

/**
 * Minimal sempahore implementation for baremetal applications. See
 * ethosu_driver.c.
 *
 * @return Pointer to semaphore handle
 */
void *ethosu_semaphore_create(void);

/**
 * Destroy semaphore.
 *
 * @param sem       Pointer to semaphore handle
 */
void ethosu_semaphore_destroy(void *sem);

/**
 * Lock mutex.
 *
 * @param mutex     Pointer to mutex handle
 * @returns 0 on success, else negative error code
 */
int ethosu_mutex_lock(void *mutex);

/**
 * Unlock mutex.
 *
 * @param mutex     Pointer to mutex handle
 * @returns 0 on success, else negative error code
 */
int ethosu_mutex_unlock(void *mutex);

/**
 * Take semaphore.
 *
 * @param sem       Pointer to semaphore handle
 * @param timeout   Timeout value (unit impl. defined)
 * @returns 0 on success else negative error code
 */
int ethosu_semaphore_take(void *sem, uint64_t timeout);

/**
 * Give semaphore.
 *
 * @param sem       Pointer to semaphore handle
 * @returns 0 on success, else negative error code
 */
int ethosu_semaphore_give(void *sem);

/**
 * Callback invoked just before the inference is started.
 *
 * @param drv       Pointer to driver handle
 * @param user_arg  User argument provided to ethosu_invoke_*()
 */
void ethosu_inference_begin(struct ethosu_driver *drv, void *user_arg);

/**
 * Callback invoked just after the inference has completed.
 *
 * @param drv       Pointer to driver handle
 * @param user_arg  User argument provided to ethosu_invoke_*()
 */
void ethosu_inference_end(struct ethosu_driver *drv, void *user_arg);

/**
 * Remapping command stream and base pointer addresses.
 *
 * @param address   Address to be remapped.
 * @param index     -1 command stream, 0-n base address index
 *
 * @return Remapped address
 */
uint64_t ethosu_address_remap(uint64_t address, int index);

/******************************************************************************
 * Prototypes
 ******************************************************************************/

/**
 * Initialize the Ethos-U driver.
 *
 * @param drv               Pointer to driver handle
 * @param base_address      NPU register base address
 * @param fast_memory       Fast memory area, used for Ethos-U65 with spilling
 * @param fast_memory_size  Size in bytes of fast memory area
 * @param secure_enable     Configure NPU in secure- or non-secure mode
 * @param privilege_enable  Configure NPU in privileged- or non-privileged mode
 * @return 0 on success, else negative error code
 */
int ethosu_init(struct ethosu_driver *drv,
                void *const base_address,
                const void *fast_memory,
                const size_t fast_memory_size,
                uint32_t secure_enable,
                uint32_t privilege_enable);

/**
 * Deinitialize the Ethos-U driver.
 *
 * @param drv       Pointer to driver handle
 */
void ethosu_deinit(struct ethosu_driver *drv);

/**
 * Soft resets the Ethos-U device.
 *
 * @param drv       Pointer to driver handle
 * @return 0 on success, else negative error code
 */
int ethosu_soft_reset(struct ethosu_driver *drv);

/**
 * Request to disable Q-channel power gating of the Ethos-U device.
 * Power requests are ref.counted. Increases count.
 * (Note: clock gating is made to follow power gating)
 *
 * @param drv       Pointer to driver handle
 * @return 0 on success, else negative error code
 */
int ethosu_request_power(struct ethosu_driver *drv);

/**
 * Release disable request for Q-channel power gating of the Ethos-U device.
 * Power requests are ref.counted. Decreases count.
 *
 * @param drv       Pointer to driver handle
 */
void ethosu_release_power(struct ethosu_driver *drv);

/**
 * Get Ethos-U driver version.
 *
 * @param ver       Driver version struct
 */
void ethosu_get_driver_version(struct ethosu_driver_version *ver);

/**
 * Get Ethos-U hardware information.
 *
 * @param drv       Pointer to driver handle
 * @param hw        Hardware information struct
 */
void ethosu_get_hw_info(struct ethosu_driver *drv, struct ethosu_hw_info *hw);

/**
 * Invoke command stream.
 *
 * @param drv               Pointer to driver handle
 * @param custom_data_ptr   Custom data payload
 * @param custom_data_size  Size in bytes of custom data
 * @param base_addr         Array of base address pointers
 * @param base_addr_size    Size in bytes of each address in base_addr
 * @param num_base_addr     Number of elements in base_addr array
 * @param user_arg          User argument, will be passed to
 *                          ethosu_inference_begin() and ethosu_inference_end()
 * @return 0 on success, else negative error code
 */
int ethosu_invoke_v3(struct ethosu_driver *drv,
                     const void *custom_data_ptr,
                     const int custom_data_size,
                     uint64_t *const base_addr,
                     const size_t *base_addr_size,
                     const int num_base_addr,
                     void *user_arg);

#define ethosu_invoke(drv, custom_data_ptr, custom_data_size, base_addr, base_addr_size, num_base_addr)                \
    ethosu_invoke_v3(drv, custom_data_ptr, custom_data_size, base_addr, base_addr_size, num_base_addr, 0)

/**
 * Invoke command stream using async interface.
 * Must be followed by call(s) to ethosu_wait() upon successful return.
 *
 * @see ethosu_invoke_v3 for documentation.
 */
int ethosu_invoke_async(struct ethosu_driver *drv,
                        const void *custom_data_ptr,
                        const int custom_data_size,
                        uint64_t *const base_addr,
                        const size_t *base_addr_size,
                        const int num_base_addr,
                        void *user_arg);

/**
 * Wait for inference to complete (block=true)
 * Poll status or finish up if inference is complete (block=false)
 * (This function is only intended to be used in conjuction with ethosu_invoke_async)
 *
 * @param drv       Pointer to driver handle
 * @param block     If call should block if inference is running
 * @return -2 on inference not invoked, -1 on inference error, 0 on success, 1 on inference running
 */
int ethosu_wait(struct ethosu_driver *drv, bool block);

/**
 * Reserves a driver to execute inference with. Call will block until a driver
 * is available.
 *
 * @return Pointer to driver handle.
 */
struct ethosu_driver *ethosu_reserve_driver(void);

/**
 * Release driver that was previously reserved with @see ethosu_reserve_driver.
 *
 * @param drv       Pointer to driver handle
 */
void ethosu_release_driver(struct ethosu_driver *drv);

/**
 * Static inline for backwards-compatibility.
 *
 * @see ethosu_invoke_v3 for documentation.
 */
static inline int ethosu_invoke_v2(const void *custom_data_ptr,
                                   const int custom_data_size,
                                   uint64_t *const base_addr,
                                   const size_t *base_addr_size,
                                   const int num_base_addr)
{
    struct ethosu_driver *drv = ethosu_reserve_driver();
    if (!drv)
    {
        return -1;
    }
    int result = ethosu_invoke_v3(drv, custom_data_ptr, custom_data_size, base_addr, base_addr_size, num_base_addr, 0);
    ethosu_release_driver(drv);
    return result;
}

#ifdef __cplusplus
}
#endif

#endif // ETHOSU_DRIVER_H