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