Commit | Line | Data |
---|---|---|
dc5698e8 DA |
1 | /* |
2 | * Copyright (C) 2015 Red Hat, Inc. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * Permission is hereby granted, free of charge, to any person obtaining | |
6 | * a copy of this software and associated documentation files (the | |
7 | * "Software"), to deal in the Software without restriction, including | |
8 | * without limitation the rights to use, copy, modify, merge, publish, | |
9 | * distribute, sublicense, and/or sell copies of the Software, and to | |
10 | * permit persons to whom the Software is furnished to do so, subject to | |
11 | * the following conditions: | |
12 | * | |
13 | * The above copyright notice and this permission notice (including the | |
14 | * next paragraph) shall be included in all copies or substantial | |
15 | * portions of the Software. | |
16 | * | |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
20 | * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | |
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
24 | */ | |
25 | ||
26 | #ifndef VIRTIO_DRV_H | |
27 | #define VIRTIO_DRV_H | |
28 | ||
29 | #include <linux/virtio.h> | |
30 | #include <linux/virtio_ids.h> | |
31 | #include <linux/virtio_config.h> | |
32 | #include <linux/virtio_gpu.h> | |
33 | ||
e7cf0963 | 34 | #include <drm/drm_atomic.h> |
9338203c | 35 | #include <drm/drm_encoder.h> |
8f44ca22 | 36 | #include <drm/drm_fb_helper.h> |
a3d63977 | 37 | #include <drm/drm_gem.h> |
c66df701 | 38 | #include <drm/drm_gem_shmem_helper.h> |
a3d63977 | 39 | #include <drm/drm_ioctl.h> |
fcd70cd3 | 40 | #include <drm/drm_probe_helper.h> |
dc5698e8 DA |
41 | |
42 | #define DRIVER_NAME "virtio_gpu" | |
43 | #define DRIVER_DESC "virtio GPU" | |
44 | #define DRIVER_DATE "0" | |
45 | ||
46 | #define DRIVER_MAJOR 0 | |
68629652 GP |
47 | #define DRIVER_MINOR 1 |
48 | #define DRIVER_PATCHLEVEL 0 | |
dc5698e8 | 49 | |
4441235f | 50 | struct virtio_gpu_object_params { |
f9659329 GH |
51 | uint32_t format; |
52 | uint32_t width; | |
53 | uint32_t height; | |
4441235f | 54 | unsigned long size; |
530b2842 | 55 | bool dumb; |
fd4d6a42 | 56 | /* 3d */ |
530b2842 | 57 | bool virgl; |
fd4d6a42 GH |
58 | uint32_t target; |
59 | uint32_t bind; | |
60 | uint32_t depth; | |
61 | uint32_t array_size; | |
62 | uint32_t last_level; | |
63 | uint32_t nr_samples; | |
64 | uint32_t flags; | |
4441235f GH |
65 | }; |
66 | ||
dc5698e8 | 67 | struct virtio_gpu_object { |
c66df701 | 68 | struct drm_gem_shmem_object base; |
dc5698e8 DA |
69 | uint32_t hw_res_handle; |
70 | ||
71 | struct sg_table *pages; | |
a3b815f0 | 72 | uint32_t mapped; |
dc5698e8 | 73 | bool dumb; |
23c897d7 | 74 | bool created; |
dc5698e8 DA |
75 | }; |
76 | #define gem_to_virtio_gpu_obj(gobj) \ | |
c66df701 | 77 | container_of((gobj), struct virtio_gpu_object, base.base) |
dc5698e8 | 78 | |
98abe21d GH |
79 | struct virtio_gpu_object_array { |
80 | struct ww_acquire_ctx ticket; | |
f0c6cef7 | 81 | struct list_head next; |
98abe21d GH |
82 | u32 nents, total; |
83 | struct drm_gem_object *objs[]; | |
84 | }; | |
85 | ||
dc5698e8 DA |
86 | struct virtio_gpu_vbuffer; |
87 | struct virtio_gpu_device; | |
88 | ||
89 | typedef void (*virtio_gpu_resp_cb)(struct virtio_gpu_device *vgdev, | |
90 | struct virtio_gpu_vbuffer *vbuf); | |
91 | ||
92 | struct virtio_gpu_fence_driver { | |
93 | atomic64_t last_seq; | |
94 | uint64_t sync_seq; | |
30b9c96c | 95 | uint64_t context; |
dc5698e8 DA |
96 | struct list_head fences; |
97 | spinlock_t lock; | |
98 | }; | |
99 | ||
100 | struct virtio_gpu_fence { | |
f54d1867 | 101 | struct dma_fence f; |
dc5698e8 DA |
102 | struct virtio_gpu_fence_driver *drv; |
103 | struct list_head node; | |
dc5698e8 DA |
104 | }; |
105 | #define to_virtio_fence(x) \ | |
106 | container_of(x, struct virtio_gpu_fence, f) | |
107 | ||
108 | struct virtio_gpu_vbuffer { | |
109 | char *buf; | |
110 | int size; | |
111 | ||
112 | void *data_buf; | |
113 | uint32_t data_size; | |
114 | ||
115 | char *resp_buf; | |
116 | int resp_size; | |
dc5698e8 DA |
117 | virtio_gpu_resp_cb resp_cb; |
118 | ||
da758d51 | 119 | struct virtio_gpu_object_array *objs; |
dc5698e8 DA |
120 | struct list_head list; |
121 | }; | |
122 | ||
123 | struct virtio_gpu_output { | |
124 | int index; | |
125 | struct drm_crtc crtc; | |
126 | struct drm_connector conn; | |
127 | struct drm_encoder enc; | |
128 | struct virtio_gpu_display_one info; | |
129 | struct virtio_gpu_update_cursor cursor; | |
b4b01b49 | 130 | struct edid *edid; |
dc5698e8 DA |
131 | int cur_x; |
132 | int cur_y; | |
6c19787e | 133 | bool enabled; |
dc5698e8 DA |
134 | }; |
135 | #define drm_crtc_to_virtio_gpu_output(x) \ | |
136 | container_of(x, struct virtio_gpu_output, crtc) | |
137 | #define drm_connector_to_virtio_gpu_output(x) \ | |
138 | container_of(x, struct virtio_gpu_output, conn) | |
139 | #define drm_encoder_to_virtio_gpu_output(x) \ | |
140 | container_of(x, struct virtio_gpu_output, enc) | |
141 | ||
142 | struct virtio_gpu_framebuffer { | |
143 | struct drm_framebuffer base; | |
9fdd90c0 | 144 | struct virtio_gpu_fence *fence; |
dc5698e8 DA |
145 | }; |
146 | #define to_virtio_gpu_framebuffer(x) \ | |
147 | container_of(x, struct virtio_gpu_framebuffer, base) | |
148 | ||
dc5698e8 DA |
149 | struct virtio_gpu_queue { |
150 | struct virtqueue *vq; | |
151 | spinlock_t qlock; | |
152 | wait_queue_head_t ack_queue; | |
153 | struct work_struct dequeue_work; | |
154 | }; | |
155 | ||
62fb7a5e GH |
156 | struct virtio_gpu_drv_capset { |
157 | uint32_t id; | |
158 | uint32_t max_version; | |
159 | uint32_t max_size; | |
160 | }; | |
161 | ||
162 | struct virtio_gpu_drv_cap_cache { | |
163 | struct list_head head; | |
164 | void *caps_cache; | |
165 | uint32_t id; | |
166 | uint32_t version; | |
167 | uint32_t size; | |
168 | atomic_t is_valid; | |
169 | }; | |
170 | ||
dc5698e8 DA |
171 | struct virtio_gpu_device { |
172 | struct device *dev; | |
173 | struct drm_device *ddev; | |
174 | ||
175 | struct virtio_device *vdev; | |
176 | ||
dc5698e8 DA |
177 | struct virtio_gpu_output outputs[VIRTIO_GPU_MAX_SCANOUTS]; |
178 | uint32_t num_scanouts; | |
179 | ||
180 | struct virtio_gpu_queue ctrlq; | |
181 | struct virtio_gpu_queue cursorq; | |
f5985bf9 | 182 | struct kmem_cache *vbufs; |
dc5698e8 DA |
183 | bool vqs_ready; |
184 | ||
1938d1ae | 185 | struct ida resource_ida; |
dc5698e8 DA |
186 | |
187 | wait_queue_head_t resp_wq; | |
188 | /* current display info */ | |
189 | spinlock_t display_info_lock; | |
441012af | 190 | bool display_info_pending; |
dc5698e8 DA |
191 | |
192 | struct virtio_gpu_fence_driver fence_drv; | |
193 | ||
1938d1ae | 194 | struct ida ctx_id_ida; |
dc5698e8 | 195 | |
62fb7a5e | 196 | bool has_virgl_3d; |
b4b01b49 | 197 | bool has_edid; |
62fb7a5e | 198 | |
dc5698e8 | 199 | struct work_struct config_changed_work; |
62fb7a5e | 200 | |
f0c6cef7 GH |
201 | struct work_struct obj_free_work; |
202 | spinlock_t obj_free_lock; | |
203 | struct list_head obj_free_list; | |
204 | ||
62fb7a5e GH |
205 | struct virtio_gpu_drv_capset *capsets; |
206 | uint32_t num_capsets; | |
207 | struct list_head cap_cache; | |
dc5698e8 DA |
208 | }; |
209 | ||
210 | struct virtio_gpu_fpriv { | |
211 | uint32_t ctx_id; | |
212 | }; | |
213 | ||
214 | /* virtio_ioctl.c */ | |
215 | #define DRM_VIRTIO_NUM_IOCTLS 10 | |
216 | extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; | |
217 | ||
218 | /* virtio_kms.c */ | |
d516e75c EG |
219 | int virtio_gpu_init(struct drm_device *dev); |
220 | void virtio_gpu_deinit(struct drm_device *dev); | |
62fb7a5e GH |
221 | int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file); |
222 | void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file); | |
dc5698e8 DA |
223 | |
224 | /* virtio_gem.c */ | |
225 | void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj); | |
226 | int virtio_gpu_gem_init(struct virtio_gpu_device *vgdev); | |
227 | void virtio_gpu_gem_fini(struct virtio_gpu_device *vgdev); | |
228 | int virtio_gpu_gem_create(struct drm_file *file, | |
229 | struct drm_device *dev, | |
4441235f | 230 | struct virtio_gpu_object_params *params, |
dc5698e8 DA |
231 | struct drm_gem_object **obj_p, |
232 | uint32_t *handle_p); | |
62fb7a5e GH |
233 | int virtio_gpu_gem_object_open(struct drm_gem_object *obj, |
234 | struct drm_file *file); | |
235 | void virtio_gpu_gem_object_close(struct drm_gem_object *obj, | |
236 | struct drm_file *file); | |
dc5698e8 DA |
237 | int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, |
238 | struct drm_device *dev, | |
239 | struct drm_mode_create_dumb *args); | |
dc5698e8 DA |
240 | int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, |
241 | struct drm_device *dev, | |
242 | uint32_t handle, uint64_t *offset_p); | |
243 | ||
98abe21d GH |
244 | struct virtio_gpu_object_array *virtio_gpu_array_alloc(u32 nents); |
245 | struct virtio_gpu_object_array* | |
246 | virtio_gpu_array_from_handles(struct drm_file *drm_file, u32 *handles, u32 nents); | |
247 | void virtio_gpu_array_add_obj(struct virtio_gpu_object_array *objs, | |
248 | struct drm_gem_object *obj); | |
249 | int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs); | |
250 | void virtio_gpu_array_unlock_resv(struct virtio_gpu_object_array *objs); | |
251 | void virtio_gpu_array_add_fence(struct virtio_gpu_object_array *objs, | |
252 | struct dma_fence *fence); | |
253 | void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs); | |
f0c6cef7 GH |
254 | void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev, |
255 | struct virtio_gpu_object_array *objs); | |
256 | void virtio_gpu_array_put_free_work(struct work_struct *work); | |
98abe21d | 257 | |
dc5698e8 DA |
258 | /* virtio vg */ |
259 | int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev); | |
260 | void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev); | |
dc5698e8 | 261 | void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, |
23c897d7 | 262 | struct virtio_gpu_object *bo, |
530b2842 | 263 | struct virtio_gpu_object_params *params, |
e2324300 | 264 | struct virtio_gpu_object_array *objs, |
530b2842 | 265 | struct virtio_gpu_fence *fence); |
dc5698e8 DA |
266 | void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, |
267 | uint32_t resource_id); | |
268 | void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, | |
af334c5d | 269 | uint64_t offset, |
64f1cc99 GH |
270 | uint32_t width, uint32_t height, |
271 | uint32_t x, uint32_t y, | |
3d3bdbc0 | 272 | struct virtio_gpu_object_array *objs, |
4d55fd66 | 273 | struct virtio_gpu_fence *fence); |
dc5698e8 DA |
274 | void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, |
275 | uint32_t resource_id, | |
276 | uint32_t x, uint32_t y, | |
277 | uint32_t width, uint32_t height); | |
278 | void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, | |
279 | uint32_t scanout_id, uint32_t resource_id, | |
280 | uint32_t width, uint32_t height, | |
281 | uint32_t x, uint32_t y); | |
282 | int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, | |
283 | struct virtio_gpu_object *obj, | |
4d55fd66 | 284 | struct virtio_gpu_fence *fence); |
b3f13ec9 GH |
285 | void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev, |
286 | struct virtio_gpu_object *obj); | |
dc5698e8 DA |
287 | int virtio_gpu_attach_status_page(struct virtio_gpu_device *vgdev); |
288 | int virtio_gpu_detach_status_page(struct virtio_gpu_device *vgdev); | |
289 | void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev, | |
290 | struct virtio_gpu_output *output); | |
291 | int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev); | |
62fb7a5e GH |
292 | int virtio_gpu_cmd_get_capset_info(struct virtio_gpu_device *vgdev, int idx); |
293 | int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev, | |
294 | int idx, int version, | |
295 | struct virtio_gpu_drv_cap_cache **cache_p); | |
b4b01b49 | 296 | int virtio_gpu_cmd_get_edids(struct virtio_gpu_device *vgdev); |
62fb7a5e GH |
297 | void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t id, |
298 | uint32_t nlen, const char *name); | |
299 | void virtio_gpu_cmd_context_destroy(struct virtio_gpu_device *vgdev, | |
300 | uint32_t id); | |
301 | void virtio_gpu_cmd_context_attach_resource(struct virtio_gpu_device *vgdev, | |
302 | uint32_t ctx_id, | |
93c38d15 | 303 | struct virtio_gpu_object_array *objs); |
62fb7a5e GH |
304 | void virtio_gpu_cmd_context_detach_resource(struct virtio_gpu_device *vgdev, |
305 | uint32_t ctx_id, | |
93c38d15 | 306 | struct virtio_gpu_object_array *objs); |
62fb7a5e GH |
307 | void virtio_gpu_cmd_submit(struct virtio_gpu_device *vgdev, |
308 | void *data, uint32_t data_size, | |
da758d51 GH |
309 | uint32_t ctx_id, |
310 | struct virtio_gpu_object_array *objs, | |
311 | struct virtio_gpu_fence *fence); | |
62fb7a5e | 312 | void virtio_gpu_cmd_transfer_from_host_3d(struct virtio_gpu_device *vgdev, |
375f156a | 313 | uint32_t ctx_id, |
62fb7a5e GH |
314 | uint64_t offset, uint32_t level, |
315 | struct virtio_gpu_box *box, | |
375f156a | 316 | struct virtio_gpu_object_array *objs, |
4d55fd66 | 317 | struct virtio_gpu_fence *fence); |
62fb7a5e | 318 | void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, |
af334c5d | 319 | uint32_t ctx_id, |
62fb7a5e GH |
320 | uint64_t offset, uint32_t level, |
321 | struct virtio_gpu_box *box, | |
3d3bdbc0 | 322 | struct virtio_gpu_object_array *objs, |
4d55fd66 | 323 | struct virtio_gpu_fence *fence); |
62fb7a5e GH |
324 | void |
325 | virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, | |
23c897d7 | 326 | struct virtio_gpu_object *bo, |
530b2842 | 327 | struct virtio_gpu_object_params *params, |
e2324300 | 328 | struct virtio_gpu_object_array *objs, |
530b2842 | 329 | struct virtio_gpu_fence *fence); |
dc5698e8 DA |
330 | void virtio_gpu_ctrl_ack(struct virtqueue *vq); |
331 | void virtio_gpu_cursor_ack(struct virtqueue *vq); | |
62fb7a5e | 332 | void virtio_gpu_fence_ack(struct virtqueue *vq); |
dc5698e8 DA |
333 | void virtio_gpu_dequeue_ctrl_func(struct work_struct *work); |
334 | void virtio_gpu_dequeue_cursor_func(struct work_struct *work); | |
62fb7a5e | 335 | void virtio_gpu_dequeue_fence_func(struct work_struct *work); |
dc5698e8 DA |
336 | |
337 | /* virtio_gpu_display.c */ | |
338 | int virtio_gpu_framebuffer_init(struct drm_device *dev, | |
339 | struct virtio_gpu_framebuffer *vgfb, | |
1eb83451 | 340 | const struct drm_mode_fb_cmd2 *mode_cmd, |
dc5698e8 | 341 | struct drm_gem_object *obj); |
d516e75c | 342 | void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); |
dc5698e8 DA |
343 | void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); |
344 | ||
345 | /* virtio_gpu_plane.c */ | |
d519cb76 | 346 | uint32_t virtio_gpu_translate_format(uint32_t drm_fourcc); |
dc5698e8 | 347 | struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, |
bbbed888 | 348 | enum drm_plane_type type, |
dc5698e8 DA |
349 | int index); |
350 | ||
dc5698e8 | 351 | /* virtio_gpu_fence.c */ |
530b2842 | 352 | bool virtio_fence_signaled(struct dma_fence *f); |
9fdd90c0 RF |
353 | struct virtio_gpu_fence *virtio_gpu_fence_alloc( |
354 | struct virtio_gpu_device *vgdev); | |
fa2b7c21 | 355 | void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, |
dc5698e8 | 356 | struct virtio_gpu_ctrl_hdr *cmd_hdr, |
4d55fd66 | 357 | struct virtio_gpu_fence *fence); |
dc5698e8 DA |
358 | void virtio_gpu_fence_event_process(struct virtio_gpu_device *vdev, |
359 | u64 last_seq); | |
360 | ||
361 | /* virtio_gpu_object */ | |
c66df701 GH |
362 | struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev, |
363 | size_t size); | |
dc5698e8 | 364 | int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, |
4441235f | 365 | struct virtio_gpu_object_params *params, |
530b2842 GH |
366 | struct virtio_gpu_object **bo_ptr, |
367 | struct virtio_gpu_fence *fence); | |
dc5698e8 | 368 | |
11a8f280 | 369 | /* virtgpu_prime.c */ |
a0cecc23 DA |
370 | struct drm_gem_object *virtgpu_gem_prime_import_sg_table( |
371 | struct drm_device *dev, struct dma_buf_attachment *attach, | |
372 | struct sg_table *sgt); | |
11a8f280 | 373 | |
dc5698e8 DA |
374 | static inline u64 virtio_gpu_object_mmap_offset(struct virtio_gpu_object *bo) |
375 | { | |
c66df701 | 376 | return drm_vma_node_offset_addr(&bo->base.base.vma_node); |
dc5698e8 DA |
377 | } |
378 | ||
dc5698e8 DA |
379 | /* virgl debufs */ |
380 | int virtio_gpu_debugfs_init(struct drm_minor *minor); | |
dc5698e8 DA |
381 | |
382 | #endif |