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