1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2015 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 /*!
25  * Define the entry points which the NVKMS kernel interface layer
26  * provides to core NVKMS.
27  */
28 
29 #if !defined(_NVIDIA_MODESET_OS_INTERFACE_H_)
30 #define _NVIDIA_MODESET_OS_INTERFACE_H_
31 
32 #if defined(NV_KERNEL_INTERFACE_LAYER) && defined(NV_LINUX)
33 #include <linux/stddef.h>  /* size_t */
34 #else
35 #include <stddef.h>        /* size_t */
36 #endif
37 #include "nvtypes.h" /* NvU8 */
38 
39 #include "nvkms.h"
40 #include "nv_stdarg.h"
41 
42 enum NvKmsSyncPtOp {
43     NVKMS_SYNCPT_OP_ALLOC,
44     NVKMS_SYNCPT_OP_GET,
45     NVKMS_SYNCPT_OP_PUT,
46     NVKMS_SYNCPT_OP_FD_TO_ID_AND_THRESH,
47     NVKMS_SYNCPT_OP_ID_AND_THRESH_TO_FD,
48     NVKMS_SYNCPT_OP_READ_MINVAL,
49 };
50 
51 typedef struct {
52 
53     struct {
54         const char *syncpt_name;        /*  in   */
55         NvU32 id;                       /*  out  */
56     } alloc;
57 
58     struct {
59         NvU32 id;                       /*  in   */
60     } put;
61 
62     struct {
63         NvS32 fd;                       /*  in   */
64         NvU32 id;                       /*  out  */
65         NvU32 thresh;                   /*  out  */
66     } fd_to_id_and_thresh;
67 
68     struct {
69         NvU32 id;                       /*  in   */
70         NvU32 thresh;                   /*  in   */
71         NvS32 fd;                       /*  out  */
72     } id_and_thresh_to_fd;
73 
74     struct {
75         NvU32 id;                       /*  in   */
76         NvU32 minval;                   /*  out  */
77     } read_minval;
78 } NvKmsSyncPtOpParams;
79 
80 NvBool nvkms_output_rounding_fix(void);
81 
82 void   nvkms_call_rm    (void *ops);
83 void*  nvkms_alloc      (size_t size,
84                          NvBool zero);
85 void   nvkms_free       (void *ptr,
86                          size_t size);
87 void*  nvkms_memset     (void *ptr,
88                          NvU8 c,
89                          size_t size);
90 void*  nvkms_memcpy     (void *dest,
91                          const void *src,
92                          size_t n);
93 void*  nvkms_memmove    (void *dest,
94                          const void *src,
95                          size_t n);
96 int    nvkms_memcmp     (const void *s1,
97                          const void *s2,
98                          size_t n);
99 size_t nvkms_strlen     (const char *s);
100 int    nvkms_strcmp     (const char *s1,
101                          const char *s2);
102 char*  nvkms_strncpy    (char *dest,
103                          const char *src,
104                          size_t n);
105 void   nvkms_usleep     (NvU64 usec);
106 NvU64  nvkms_get_usec   (void);
107 int    nvkms_copyin     (void *kptr,
108                          NvU64 uaddr,
109                          size_t n);
110 int    nvkms_copyout    (NvU64 uaddr,
111                          const void *kptr,
112                          size_t n);
113 void   nvkms_yield      (void);
114 void   nvkms_dump_stack (void);
115 NvBool nvkms_syncpt_op  (enum NvKmsSyncPtOp op,
116                          NvKmsSyncPtOpParams *params);
117 int    nvkms_snprintf   (char *str,
118                          size_t size,
119                          const char *format, ...)
120     __attribute__((format (printf, 3, 4)));
121 
122 int    nvkms_vsnprintf  (char *str,
123                          size_t size,
124                          const char *format,
125                          va_list ap);
126 
127 #define NVKMS_LOG_LEVEL_INFO  0
128 #define NVKMS_LOG_LEVEL_WARN  1
129 #define NVKMS_LOG_LEVEL_ERROR 2
130 
131 void   nvkms_log        (const int level,
132                          const char *gpuPrefix,
133                          const char *msg);
134 
135 /*!
136  * Refcounted pointer to an object that may be freed while references still
137  * exist.
138  *
139  * This structure is intended to be used for nvkms timers to refer to objects
140  * that may be freed while timers with references to the object are still
141  * pending.
142  *
143  * When the owner of an nvkms_ref_ptr is freed, the teardown code should call
144  * nvkms_free_ref_ptr().  That marks the pointer as invalid so that later calls
145  * to nvkms_dec_ref() (i.e. from a workqueue callback) return NULL rather than
146  * the pointer originally passed to nvkms_alloc_ref_ptr().
147  */
148 struct nvkms_ref_ptr;
149 
150 /*!
151  * Allocate and initialize a ref_ptr.
152  *
153  * The pointer stored in the ref_ptr is initialized to ptr, and its refcount is
154  * initialized to 1.
155  */
156 struct nvkms_ref_ptr* nvkms_alloc_ref_ptr(void *ptr);
157 
158 /*!
159  * Clear a ref_ptr.
160  *
161  * This function sets the pointer stored in the ref_ptr to NULL and drops the
162  * reference created by nvkms_alloc_ref_ptr().  This function should be called
163  * when the object pointed to by the ref_ptr is freed.
164  *
165  * A caller should make sure that no code that can call nvkms_inc_ref() can
166  * execute after nvkms_free_ref_ptr() is called.
167  */
168 void nvkms_free_ref_ptr(struct nvkms_ref_ptr *ref_ptr);
169 
170 /*!
171  * Increment the refcount of a ref_ptr.
172  *
173  * This function should be used when a pointer to the ref_ptr is stored
174  * somewhere.  For example, when the ref_ptr is used as the argument to
175  * nvkms_alloc_timer.
176  *
177  * This may be called outside of the nvkms_lock, for example by an RM callback.
178  */
179 void nvkms_inc_ref(struct nvkms_ref_ptr *ref_ptr);
180 
181 /*!
182  * Decrement the refcount of a ref_ptr and extract the embedded pointer.
183  *
184  * This should be used by code that needs to atomically determine whether the
185  * object pointed to by the ref_ptr still exists.  To prevent the object from
186  * being destroyed while the current thread is executing, this should be called
187  * from inside the nvkms_lock.
188  */
189 void* nvkms_dec_ref(struct nvkms_ref_ptr *ref_ptr);
190 
191 typedef void nvkms_timer_proc_t(void *dataPtr, NvU32 dataU32);
192 typedef struct nvkms_timer_t nvkms_timer_handle_t;
193 
194 /*!
195  * Schedule a callback function to be called in the future.
196  *
197  * The callback function 'proc' will be called with the arguments
198  * 'dataPtr' and 'dataU32' at 'usec' (or later) microseconds from now.
199  * If usec==0, the callback will be scheduled to be called as soon as
200  * possible.
201  *
202  * The callback function is guaranteed to be called back with the
203  * nvkms_lock held, and in process context.
204  *
205  * Returns an opaque handle, nvkms_timer_handle_t*, or NULL on
206  * failure.  If non-NULL, the caller is responsible for caching the
207  * handle and eventually calling nvkms_free_timer() to free the
208  * memory.
209  *
210  * The nvkms_lock may be held when nvkms_alloc_timer() is called, but
211  * the nvkms_lock is not required.
212  */
213 nvkms_timer_handle_t* nvkms_alloc_timer (nvkms_timer_proc_t *proc,
214                                          void *dataPtr, NvU32 dataU32,
215                                          NvU64 usec);
216 
217 /*!
218  * Schedule a callback function to be called in the future.
219  *
220  * This function is like nvkms_alloc_timer() except that instead of returning a
221  * pointer to a structure that the caller should free later, the timer will free
222  * itself after executing the callback function.  This is only intended for
223  * cases where the caller cannot cache the nvkms_alloc_timer() return value.
224  */
225 NvBool
226 nvkms_alloc_timer_with_ref_ptr(nvkms_timer_proc_t *proc,
227                                struct nvkms_ref_ptr *ref_ptr,
228                                NvU32 dataU32, NvU64 usec);
229 
230 /*!
231  * Free the nvkms_timer_t object.  If the callback function has not
232  * yet been called, freeing the nvkms_timer_handle_t will guarantee
233  * that it is not called.
234  *
235  * The nvkms_lock must be held when calling nvkms_free_timer().
236  */
237 void nvkms_free_timer  (nvkms_timer_handle_t *handle);
238 
239 
240 
241 /*!
242  * Notify the NVKMS kernel interface that the event queue has changed.
243  *
244  * \param[in]  pOpenKernel      This indicates the file descriptor
245  *                              ("per-open") of the client whose event queue
246  *                              has been updated.  This is the pointer
247  *                              passed by the kernel interface to nvKmsOpen().
248  * \param[in]  eventsAvailable  If TRUE, a new event has been added to the
249  *                              event queue.  If FALSE, the last event has
250  *                              been removed from the event queue.
251  */
252 void
253 nvkms_event_queue_changed(nvkms_per_open_handle_t *pOpenKernel,
254                           NvBool eventsAvailable);
255 
256 
257 /*!
258  * Get the "per-open" data (the pointer returned by nvKmsOpen())
259  * associated with this fd.
260  */
261 void* nvkms_get_per_open_data(int fd);
262 
263 
264 /*!
265  * Raise and lower the reference count of the specified GPU.
266  */
267 NvBool nvkms_open_gpu(NvU32 gpuId);
268 void nvkms_close_gpu(NvU32 gpuId);
269 
270 
271 /*!
272  * Enumerate nvidia gpus.
273  */
274 
275 NvU32 nvkms_enumerate_gpus(nv_gpu_info_t *gpu_info);
276 
277 /*!
278  * Availability of write combining support for video memory.
279  */
280 
281 NvBool nvkms_allow_write_combining(void);
282 
283 /*!
284  * Checks whether the fd is associated with an nvidia character device.
285  */
286 NvBool nvkms_fd_is_nvidia_chardev(int fd);
287 
288 /*!
289  * NVKMS interface for kernel space NVKMS clients like KAPI
290  */
291 
292 struct nvkms_per_open;
293 
294 struct nvkms_per_open* nvkms_open_from_kapi
295 (
296     struct NvKmsKapiDevice *device
297 );
298 
299 void nvkms_close_from_kapi(struct nvkms_per_open *popen);
300 
301 NvBool nvkms_ioctl_from_kapi
302 (
303     struct nvkms_per_open *popen,
304     NvU32 cmd, void *params_address, const size_t params_size
305 );
306 
307 /*!
308  * APIs for locking.
309  */
310 
311 typedef struct nvkms_sema_t nvkms_sema_handle_t;
312 
313 nvkms_sema_handle_t*
314      nvkms_sema_alloc    (void);
315 void nvkms_sema_free     (nvkms_sema_handle_t *sema);
316 void nvkms_sema_down     (nvkms_sema_handle_t *sema);
317 void nvkms_sema_up       (nvkms_sema_handle_t *sema);
318 
319 /*!
320  * APIs to register/unregister backlight device.
321  */
322 struct nvkms_backlight_device;
323 
324 struct nvkms_backlight_device*
325 nvkms_register_backlight(NvU32 gpu_id, NvU32 display_id, void *drv_priv,
326                          NvU32 current_brightness);
327 
328 void nvkms_unregister_backlight(struct nvkms_backlight_device *nvkms_bd);
329 
330 #endif /* _NVIDIA_MODESET_OS_INTERFACE_H_ */
331 
332