1 /*
2  * Copyright (c) 2019-2022 Arm Limited. All rights reserved.
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 /******************************************************************************
45  * Types
46  ******************************************************************************/
47 
48 // Forward declare
49 struct ethosu_device;
50 
51 enum ethosu_job_state
52 {
53     ETHOSU_JOB_IDLE = 0,
54     ETHOSU_JOB_RUNNING,
55     ETHOSU_JOB_DONE
56 };
57 
58 struct ethosu_job
59 {
60     volatile enum ethosu_job_state state;
61     const void *custom_data_ptr;
62     int custom_data_size;
63     const uint64_t *base_addr;
64     const size_t *base_addr_size;
65     int num_base_addr;
66     void *user_arg;
67 };
68 
69 struct ethosu_driver
70 {
71     struct ethosu_device *dev;
72     struct ethosu_driver *next;
73     struct ethosu_job job;
74     void *semaphore;
75     uint64_t fast_memory;
76     size_t fast_memory_size;
77     uint32_t power_request_counter;
78     bool status_error;
79     bool reserved;
80 };
81 
82 struct ethosu_driver_version
83 {
84     uint8_t major;
85     uint8_t minor;
86     uint8_t patch;
87 };
88 
89 enum ethosu_request_clients
90 {
91     ETHOSU_PMU_REQUEST       = 0,
92     ETHOSU_INFERENCE_REQUEST = 1,
93 };
94 
95 /******************************************************************************
96  * Prototypes (weak functions in driver)
97  ******************************************************************************/
98 
99 /**
100  * Interrupt handler to be called on IRQ from Ethos-U
101  */
102 void ethosu_irq_handler(struct ethosu_driver *drv);
103 
104 /*
105  * Flush/clean the data cache by address and size. Passing NULL as p argument
106  * expects the whole cache to be flushed.
107  */
108 
109 void ethosu_flush_dcache(uint32_t *p, size_t bytes);
110 /*
111  * Invalidate the data cache by address and size. Passing NULL as p argument
112  * expects the whole cache to be invalidated.
113  */
114 void ethosu_invalidate_dcache(uint32_t *p, size_t bytes);
115 
116 /*
117  * Minimal sempahore and mutex implementation for baremetal applications. See
118  * ethosu_driver.c.
119  */
120 void *ethosu_mutex_create(void);
121 void *ethosu_semaphore_create(void);
122 /*
123  * Returns:
124  *   -1 on error
125  *    0 on success
126  */
127 int ethosu_mutex_lock(void *mutex);
128 int ethosu_mutex_unlock(void *mutex);
129 int ethosu_semaphore_take(void *sem);
130 int ethosu_semaphore_give(void *sem);
131 
132 /*
133  * Callbacks for begin/end of inference. user_data pointer is passed to the
134  * ethosu_invoke() call and forwarded to the callback functions.
135  */
136 void ethosu_inference_begin(struct ethosu_driver *drv, void *user_arg);
137 void ethosu_inference_end(struct ethosu_driver *drv, void *user_arg);
138 
139 /******************************************************************************
140  * Prototypes
141  ******************************************************************************/
142 
143 /**
144  * Initialize the Ethos-U driver.
145  */
146 int ethosu_init(struct ethosu_driver *drv,
147                 const void *base_address,
148                 const void *fast_memory,
149                 const size_t fast_memory_size,
150                 uint32_t secure_enable,
151                 uint32_t privilege_enable);
152 
153 /**
154  * Deinitialize the Ethos-U driver.
155  */
156 void ethosu_deinit(struct ethosu_driver *drv);
157 
158 /**
159  * Soft resets the Ethos-U device.
160  */
161 bool ethosu_soft_reset(struct ethosu_driver *drv);
162 
163 /**
164  * Request to disable Q-channel power gating of the Ethos-U device.
165  * Power requests are ref.counted. Increases count.
166  * (Note: clock gating is made to follow power gating)
167  */
168 bool ethosu_request_power(struct ethosu_driver *drv);
169 
170 /**
171  * Release disable request for Q-channel power gating of the Ethos-U device.
172  * Power requests are ref.counted. Decreases count.
173  */
174 void ethosu_release_power(struct ethosu_driver *drv);
175 
176 /**
177  * Get Ethos-U driver version.
178  */
179 void ethosu_get_driver_version(struct ethosu_driver_version *ver);
180 
181 /**
182  * Get Ethos-U hardware information.
183  */
184 void ethosu_get_hw_info(struct ethosu_driver *drv, struct ethosu_hw_info *hw);
185 
186 /**
187  * Invoke Vela command stream.
188  */
189 int ethosu_invoke_v3(struct ethosu_driver *drv,
190                      const void *custom_data_ptr,
191                      const int custom_data_size,
192                      const uint64_t *base_addr,
193                      const size_t *base_addr_size,
194                      const int num_base_addr,
195                      void *user_arg);
196 
197 #define ethosu_invoke(drv, custom_data_ptr, custom_data_size, base_addr, base_addr_size, num_base_addr)                \
198     ethosu_invoke_v3(drv, custom_data_ptr, custom_data_size, base_addr, base_addr_size, num_base_addr, 0)
199 
200 /**
201  * Invoke Vela command stream using async interface.
202  * Must be followed by call(s) to ethosu_wait() upon successful return.
203  * Returns
204  *   -1 on error
205  *    0 on success
206  */
207 int ethosu_invoke_async(struct ethosu_driver *drv,
208                         const void *custom_data_ptr,
209                         const int custom_data_size,
210                         const uint64_t *base_addr,
211                         const size_t *base_addr_size,
212                         const int num_base_addr,
213                         void *user_arg);
214 
215 /**
216  * Wait for inference to complete (block=true)
217  * Poll status or finish up if inference is complete (block=false)
218  * (This function is only intended to be used in conjuction with ethosu_invoke_async)
219  * Returns
220  *    1 on inference running (only for block=false)
221  *    0 on inference success
222  *   -1 on inference error
223  *   -2 on inference not invoked
224  */
225 int ethosu_wait(struct ethosu_driver *drv, bool block);
226 
227 /**
228  * Reserves a driver to execute inference with
229  */
230 struct ethosu_driver *ethosu_reserve_driver(void);
231 
232 /**
233  * Change driver status to available
234  */
235 void ethosu_release_driver(struct ethosu_driver *drv);
236 
237 /**
238  * Static inline for backwards-compatibility
239  */
ethosu_invoke_v2(const void * custom_data_ptr,const int custom_data_size,const uint64_t * base_addr,const size_t * base_addr_size,const int num_base_addr)240 static inline int ethosu_invoke_v2(const void *custom_data_ptr,
241                                    const int custom_data_size,
242                                    const uint64_t *base_addr,
243                                    const size_t *base_addr_size,
244                                    const int num_base_addr)
245 {
246     struct ethosu_driver *drv = ethosu_reserve_driver();
247     int result = ethosu_invoke_v3(drv, custom_data_ptr, custom_data_size, base_addr, base_addr_size, num_base_addr, 0);
248     ethosu_release_driver(drv);
249     return result;
250 }
251 
252 #ifdef __cplusplus
253 }
254 #endif
255 
256 #endif // ETHOSU_DRIVER_H
257