1 /*
2 * SPDX-FileCopyrightText: Copyright 2019-2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the License); you may
6 * not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #ifndef ETHOSU_DRIVER_H
19 #define ETHOSU_DRIVER_H
20
21 /******************************************************************************
22 * Includes
23 ******************************************************************************/
24
25 #include "ethosu_types.h"
26
27 #include <stdbool.h>
28 #include <stddef.h>
29 #include <stdint.h>
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 /******************************************************************************
36 * Defines
37 ******************************************************************************/
38
39 #define ETHOSU_DRIVER_VERSION_MAJOR 0 ///< Driver major version
40 #define ETHOSU_DRIVER_VERSION_MINOR 16 ///< Driver minor version
41 #define ETHOSU_DRIVER_VERSION_PATCH 0 ///< Driver patch version
42
43 #define ETHOSU_SEMAPHORE_WAIT_FOREVER (UINT64_MAX)
44
45 #ifndef ETHOSU_SEMAPHORE_WAIT_INFERENCE
46 #define ETHOSU_SEMAPHORE_WAIT_INFERENCE ETHOSU_SEMAPHORE_WAIT_FOREVER
47 #endif
48
49 /******************************************************************************
50 * Types
51 ******************************************************************************/
52
53 enum ethosu_job_state
54 {
55 ETHOSU_JOB_IDLE = 0,
56 ETHOSU_JOB_RUNNING,
57 ETHOSU_JOB_DONE
58 };
59
60 enum ethosu_job_result
61 {
62 ETHOSU_JOB_RESULT_OK = 0,
63 ETHOSU_JOB_RESULT_TIMEOUT,
64 ETHOSU_JOB_RESULT_ERROR
65 };
66
67 struct ethosu_job
68 {
69 volatile enum ethosu_job_state state;
70 volatile enum ethosu_job_result result;
71 const void *custom_data_ptr;
72 int custom_data_size;
73 const uint64_t *base_addr;
74 const size_t *base_addr_size;
75 int num_base_addr;
76 void *user_arg;
77 };
78
79 struct ethosu_driver
80 {
81 struct ethosu_device dev;
82 struct ethosu_driver *next;
83 struct ethosu_job job;
84 void *semaphore;
85 uint64_t fast_memory;
86 size_t fast_memory_size;
87 uint32_t power_request_counter;
88 bool reserved;
89 uint8_t basep_flush_mask;
90 uint8_t basep_invalidate_mask;
91 };
92
93 struct ethosu_driver_version
94 {
95 uint8_t major;
96 uint8_t minor;
97 uint8_t patch;
98 };
99
100 enum ethosu_request_clients
101 {
102 ETHOSU_PMU_REQUEST = 0,
103 ETHOSU_INFERENCE_REQUEST = 1,
104 };
105
106 /******************************************************************************
107 * Prototypes (weak functions in driver)
108 ******************************************************************************/
109
110 /**
111 * Interrupt handler to be called on IRQ from Ethos-U
112 *
113 * @param drv Pointer to driver handle
114 */
115 void ethosu_irq_handler(struct ethosu_driver *drv);
116
117 /**
118 * Flush/clean the data cache by address and size.
119 * NOTE: It is not recommended to implement this, but let the application code
120 * make sure that any data needed by the NPU is flushed before invoking
121 * an inference.
122 *
123 * Addresses passed to this function must be 32 byte aligned.
124 *
125 * @param p 32 byte aligned address
126 * @param bytes Size of memory block in bytes
127 */
128 void ethosu_flush_dcache(uint32_t *p, size_t bytes);
129
130 /**
131 * Invalidate the data cache by address and size.
132 * NOTE: The driver will only call this for the scratch/tensor arena base
133 * pointer.
134 *
135 * Addresses passed to this function must be 32 byte aligned.
136 *
137 * @param p 32 byte aligned address
138 * @param bytes Size in bytes
139 */
140 void ethosu_invalidate_dcache(uint32_t *p, size_t bytes);
141
142 /**
143 * Minimal mutex implementation for baremetal applications. See
144 * ethosu_driver.c.
145 *
146 * @return Pointer to mutex handle
147 */
148 void *ethosu_mutex_create(void);
149
150 /**
151 * Destroy mutex.
152 *
153 * @param mutex Pointer to mutex handle
154 */
155 void ethosu_mutex_destroy(void *mutex);
156
157 /**
158 * Minimal sempahore implementation for baremetal applications. See
159 * ethosu_driver.c.
160 *
161 * @return Pointer to semaphore handle
162 */
163 void *ethosu_semaphore_create(void);
164
165 /**
166 * Destroy semaphore.
167 *
168 * @param sem Pointer to semaphore handle
169 */
170 void ethosu_semaphore_destroy(void *sem);
171
172 /**
173 * Lock mutex.
174 *
175 * @param mutex Pointer to mutex handle
176 * @returns 0 on success, else negative error code
177 */
178 int ethosu_mutex_lock(void *mutex);
179
180 /**
181 * Unlock mutex.
182 *
183 * @param mutex Pointer to mutex handle
184 * @returns 0 on success, else negative error code
185 */
186 int ethosu_mutex_unlock(void *mutex);
187
188 /**
189 * Take semaphore.
190 *
191 * @param sem Pointer to semaphore handle
192 * @param timeout Timeout value (unit impl. defined)
193 * @returns 0 on success else negative error code
194 */
195 int ethosu_semaphore_take(void *sem, uint64_t timeout);
196
197 /**
198 * Give semaphore.
199 *
200 * @param sem Pointer to semaphore handle
201 * @returns 0 on success, else negative error code
202 */
203 int ethosu_semaphore_give(void *sem);
204
205 /**
206 * Callback invoked just before the inference is started.
207 *
208 * @param drv Pointer to driver handle
209 * @param user_arg User argument provided to ethosu_invoke_*()
210 */
211 void ethosu_inference_begin(struct ethosu_driver *drv, void *user_arg);
212
213 /**
214 * Callback invoked just after the inference has completed.
215 *
216 * @param drv Pointer to driver handle
217 * @param user_arg User argument provided to ethosu_invoke_*()
218 */
219 void ethosu_inference_end(struct ethosu_driver *drv, void *user_arg);
220
221 /**
222 * Remapping command stream and base pointer addresses.
223 *
224 * @param address Address to be remapped.
225 * @param index -1 command stream, 0-n base address index
226 *
227 * @return Remapped address
228 */
229 uint64_t ethosu_address_remap(uint64_t address, int index);
230
231 /******************************************************************************
232 * Prototypes
233 ******************************************************************************/
234
235 /**
236 * Set cache mask for cache flush/clean and invalidation per base pointer.
237 *
238 * @param drv Pointer to driver handle
239 * @param flush_mask Base pointer cache flush mask (bit 0 == basep 0)
240 * @param invalidate_mask Base pointer cache invalidation mask (bit 0 == basep 0)
241 */
242 void ethosu_set_basep_cache_mask(struct ethosu_driver *drv, uint8_t flush_mask, uint8_t invalidate_mask);
243
244 /**
245 * Initialize the Ethos-U driver.
246 *
247 * @param drv Pointer to driver handle
248 * @param base_address NPU register base address
249 * @param fast_memory Fast memory area, used for Ethos-U65 with spilling
250 * @param fast_memory_size Size in bytes of fast memory area
251 * @param secure_enable Configure NPU in secure- or non-secure mode
252 * @param privilege_enable Configure NPU in privileged- or non-privileged mode
253 * @return 0 on success, else negative error code
254 */
255 int ethosu_init(struct ethosu_driver *drv,
256 void *const base_address,
257 const void *fast_memory,
258 const size_t fast_memory_size,
259 uint32_t secure_enable,
260 uint32_t privilege_enable);
261
262 /**
263 * Deinitialize the Ethos-U driver.
264 *
265 * @param drv Pointer to driver handle
266 */
267 void ethosu_deinit(struct ethosu_driver *drv);
268
269 /**
270 * Soft resets the Ethos-U device.
271 *
272 * @param drv Pointer to driver handle
273 * @return 0 on success, else negative error code
274 */
275 int ethosu_soft_reset(struct ethosu_driver *drv);
276
277 /**
278 * Request to disable Q-channel power gating of the Ethos-U device.
279 * Power requests are ref.counted. Increases count.
280 * (Note: clock gating is made to follow power gating)
281 *
282 * @param drv Pointer to driver handle
283 * @return 0 on success, else negative error code
284 */
285 int ethosu_request_power(struct ethosu_driver *drv);
286
287 /**
288 * Release disable request for Q-channel power gating of the Ethos-U device.
289 * Power requests are ref.counted. Decreases count.
290 *
291 * @param drv Pointer to driver handle
292 */
293 void ethosu_release_power(struct ethosu_driver *drv);
294
295 /**
296 * Get Ethos-U driver version.
297 *
298 * @param ver Driver version struct
299 */
300 void ethosu_get_driver_version(struct ethosu_driver_version *ver);
301
302 /**
303 * Get Ethos-U hardware information.
304 *
305 * @param drv Pointer to driver handle
306 * @param hw Hardware information struct
307 */
308 void ethosu_get_hw_info(struct ethosu_driver *drv, struct ethosu_hw_info *hw);
309
310 /**
311 * Invoke command stream.
312 *
313 * @param drv Pointer to driver handle
314 * @param custom_data_ptr Custom data payload
315 * @param custom_data_size Size in bytes of custom data
316 * @param base_addr Array of base address pointers
317 * @param base_addr_size Size in bytes of each address in base_addr
318 * @param num_base_addr Number of elements in base_addr array
319 * @param user_arg User argument, will be passed to
320 * ethosu_inference_begin() and ethosu_inference_end()
321 * @return 0 on success, else negative error code
322 */
323 int ethosu_invoke_v3(struct ethosu_driver *drv,
324 const void *custom_data_ptr,
325 const int custom_data_size,
326 uint64_t *const base_addr,
327 const size_t *base_addr_size,
328 const int num_base_addr,
329 void *user_arg);
330
331 #define ethosu_invoke(drv, custom_data_ptr, custom_data_size, base_addr, base_addr_size, num_base_addr) \
332 ethosu_invoke_v3(drv, custom_data_ptr, custom_data_size, base_addr, base_addr_size, num_base_addr, 0)
333
334 /**
335 * Invoke command stream using async interface.
336 * Must be followed by call(s) to ethosu_wait() upon successful return.
337 *
338 * @see ethosu_invoke_v3 for documentation.
339 */
340 int ethosu_invoke_async(struct ethosu_driver *drv,
341 const void *custom_data_ptr,
342 const int custom_data_size,
343 uint64_t *const base_addr,
344 const size_t *base_addr_size,
345 const int num_base_addr,
346 void *user_arg);
347
348 /**
349 * Wait for inference to complete (block=true)
350 * Poll status or finish up if inference is complete (block=false)
351 * (This function is only intended to be used in conjuction with ethosu_invoke_async)
352 *
353 * @param drv Pointer to driver handle
354 * @param block If call should block if inference is running
355 * @return -2 on inference not invoked, -1 on inference error, 0 on success, 1 on inference running
356 */
357 int ethosu_wait(struct ethosu_driver *drv, bool block);
358
359 /**
360 * Reserves a driver to execute inference with. Call will block until a driver
361 * is available.
362 *
363 * @return Pointer to driver handle.
364 */
365 struct ethosu_driver *ethosu_reserve_driver(void);
366
367 /**
368 * Release driver that was previously reserved with @see ethosu_reserve_driver.
369 *
370 * @param drv Pointer to driver handle
371 */
372 void ethosu_release_driver(struct ethosu_driver *drv);
373
374 /**
375 * Static inline for backwards-compatibility.
376 *
377 * @see ethosu_invoke_v3 for documentation.
378 */
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)379 static inline int ethosu_invoke_v2(const void *custom_data_ptr,
380 const int custom_data_size,
381 uint64_t *const base_addr,
382 const size_t *base_addr_size,
383 const int num_base_addr)
384 {
385 struct ethosu_driver *drv = ethosu_reserve_driver();
386 if (!drv)
387 {
388 return -1;
389 }
390 int result = ethosu_invoke_v3(drv, custom_data_ptr, custom_data_size, base_addr, base_addr_size, num_base_addr, 0);
391 ethosu_release_driver(drv);
392 return result;
393 }
394
395 #ifdef __cplusplus
396 }
397 #endif
398
399 #endif // ETHOSU_DRIVER_H
400