]>
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> |
b1df3a2b | 35 | #include <drm/drm_drv.h> |
9338203c | 36 | #include <drm/drm_encoder.h> |
8f44ca22 | 37 | #include <drm/drm_fb_helper.h> |
a3d63977 | 38 | #include <drm/drm_gem.h> |
c66df701 | 39 | #include <drm/drm_gem_shmem_helper.h> |
a3d63977 | 40 | #include <drm/drm_ioctl.h> |
fcd70cd3 | 41 | #include <drm/drm_probe_helper.h> |
1dc34852 | 42 | #include <drm/virtgpu_drm.h> |
dc5698e8 DA |
43 | |
44 | #define DRIVER_NAME "virtio_gpu" | |
45 | #define DRIVER_DESC "virtio GPU" | |
46 | #define DRIVER_DATE "0" | |
47 | ||
48 | #define DRIVER_MAJOR 0 | |
68629652 GP |
49 | #define DRIVER_MINOR 1 |
50 | #define DRIVER_PATCHLEVEL 0 | |
dc5698e8 | 51 | |
4441235f | 52 | struct virtio_gpu_object_params { |
f9659329 GH |
53 | uint32_t format; |
54 | uint32_t width; | |
55 | uint32_t height; | |
4441235f | 56 | unsigned long size; |
530b2842 | 57 | bool dumb; |
fd4d6a42 | 58 | /* 3d */ |
530b2842 | 59 | bool virgl; |
fd4d6a42 GH |
60 | uint32_t target; |
61 | uint32_t bind; | |
62 | uint32_t depth; | |
63 | uint32_t array_size; | |
64 | uint32_t last_level; | |
65 | uint32_t nr_samples; | |
66 | uint32_t flags; | |
4441235f GH |
67 | }; |
68 | ||
dc5698e8 | 69 | struct virtio_gpu_object { |
c66df701 | 70 | struct drm_gem_shmem_object base; |
dc5698e8 | 71 | uint32_t hw_res_handle; |
dc5698e8 | 72 | bool dumb; |
23c897d7 | 73 | bool created; |
dc5698e8 DA |
74 | }; |
75 | #define gem_to_virtio_gpu_obj(gobj) \ | |
c66df701 | 76 | container_of((gobj), struct virtio_gpu_object, base.base) |
dc5698e8 | 77 | |
f651c8b0 GS |
78 | struct virtio_gpu_object_shmem { |
79 | struct virtio_gpu_object base; | |
80 | struct sg_table *pages; | |
81 | uint32_t mapped; | |
82 | }; | |
83 | ||
84 | #define to_virtio_gpu_shmem(virtio_gpu_object) \ | |
85 | container_of((virtio_gpu_object), struct virtio_gpu_object_shmem, base) | |
86 | ||
98abe21d GH |
87 | struct virtio_gpu_object_array { |
88 | struct ww_acquire_ctx ticket; | |
f0c6cef7 | 89 | struct list_head next; |
98abe21d GH |
90 | u32 nents, total; |
91 | struct drm_gem_object *objs[]; | |
92 | }; | |
93 | ||
dc5698e8 DA |
94 | struct virtio_gpu_vbuffer; |
95 | struct virtio_gpu_device; | |
96 | ||
97 | typedef void (*virtio_gpu_resp_cb)(struct virtio_gpu_device *vgdev, | |
98 | struct virtio_gpu_vbuffer *vbuf); | |
99 | ||
100 | struct virtio_gpu_fence_driver { | |
101 | atomic64_t last_seq; | |
102 | uint64_t sync_seq; | |
30b9c96c | 103 | uint64_t context; |
dc5698e8 DA |
104 | struct list_head fences; |
105 | spinlock_t lock; | |
106 | }; | |
107 | ||
108 | struct virtio_gpu_fence { | |
f54d1867 | 109 | struct dma_fence f; |
dc5698e8 DA |
110 | struct virtio_gpu_fence_driver *drv; |
111 | struct list_head node; | |
dc5698e8 | 112 | }; |
dc5698e8 DA |
113 | |
114 | struct virtio_gpu_vbuffer { | |
115 | char *buf; | |
116 | int size; | |
117 | ||
118 | void *data_buf; | |
119 | uint32_t data_size; | |
120 | ||
121 | char *resp_buf; | |
122 | int resp_size; | |
dc5698e8 | 123 | virtio_gpu_resp_cb resp_cb; |
1ed5f698 | 124 | void *resp_cb_data; |
dc5698e8 | 125 | |
da758d51 | 126 | struct virtio_gpu_object_array *objs; |
dc5698e8 DA |
127 | struct list_head list; |
128 | }; | |
129 | ||
130 | struct virtio_gpu_output { | |
131 | int index; | |
132 | struct drm_crtc crtc; | |
133 | struct drm_connector conn; | |
134 | struct drm_encoder enc; | |
135 | struct virtio_gpu_display_one info; | |
136 | struct virtio_gpu_update_cursor cursor; | |
b4b01b49 | 137 | struct edid *edid; |
dc5698e8 DA |
138 | int cur_x; |
139 | int cur_y; | |
6c19787e | 140 | bool enabled; |
dc5698e8 DA |
141 | }; |
142 | #define drm_crtc_to_virtio_gpu_output(x) \ | |
143 | container_of(x, struct virtio_gpu_output, crtc) | |
dc5698e8 DA |
144 | |
145 | struct virtio_gpu_framebuffer { | |
146 | struct drm_framebuffer base; | |
9fdd90c0 | 147 | struct virtio_gpu_fence *fence; |
dc5698e8 DA |
148 | }; |
149 | #define to_virtio_gpu_framebuffer(x) \ | |
150 | container_of(x, struct virtio_gpu_framebuffer, base) | |
151 | ||
dc5698e8 DA |
152 | struct virtio_gpu_queue { |
153 | struct virtqueue *vq; | |
154 | spinlock_t qlock; | |
155 | wait_queue_head_t ack_queue; | |
156 | struct work_struct dequeue_work; | |
157 | }; | |
158 | ||
62fb7a5e GH |
159 | struct virtio_gpu_drv_capset { |
160 | uint32_t id; | |
161 | uint32_t max_version; | |
162 | uint32_t max_size; | |
163 | }; | |
164 | ||
165 | struct virtio_gpu_drv_cap_cache { | |
166 | struct list_head head; | |
167 | void *caps_cache; | |
168 | uint32_t id; | |
169 | uint32_t version; | |
170 | uint32_t size; | |
171 | atomic_t is_valid; | |
172 | }; | |
173 | ||
dc5698e8 DA |
174 | struct virtio_gpu_device { |
175 | struct device *dev; | |
176 | struct drm_device *ddev; | |
177 | ||
178 | struct virtio_device *vdev; | |
179 | ||
dc5698e8 DA |
180 | struct virtio_gpu_output outputs[VIRTIO_GPU_MAX_SCANOUTS]; |
181 | uint32_t num_scanouts; | |
182 | ||
183 | struct virtio_gpu_queue ctrlq; | |
184 | struct virtio_gpu_queue cursorq; | |
f5985bf9 | 185 | struct kmem_cache *vbufs; |
dc5698e8 | 186 | |
cca41da1 | 187 | atomic_t pending_commands; |
7082e7a4 | 188 | |
1938d1ae | 189 | struct ida resource_ida; |
dc5698e8 DA |
190 | |
191 | wait_queue_head_t resp_wq; | |
192 | /* current display info */ | |
193 | spinlock_t display_info_lock; | |
441012af | 194 | bool display_info_pending; |
dc5698e8 DA |
195 | |
196 | struct virtio_gpu_fence_driver fence_drv; | |
197 | ||
1938d1ae | 198 | struct ida ctx_id_ida; |
dc5698e8 | 199 | |
62fb7a5e | 200 | bool has_virgl_3d; |
b4b01b49 | 201 | bool has_edid; |
5edbb560 | 202 | bool has_indirect; |
62fb7a5e | 203 | |
dc5698e8 | 204 | struct work_struct config_changed_work; |
62fb7a5e | 205 | |
f0c6cef7 GH |
206 | struct work_struct obj_free_work; |
207 | spinlock_t obj_free_lock; | |
208 | struct list_head obj_free_list; | |
209 | ||
62fb7a5e GH |
210 | struct virtio_gpu_drv_capset *capsets; |
211 | uint32_t num_capsets; | |
212 | struct list_head cap_cache; | |
dc5698e8 DA |
213 | }; |
214 | ||
215 | struct virtio_gpu_fpriv { | |
216 | uint32_t ctx_id; | |
d2a983b2 GS |
217 | bool context_created; |
218 | struct mutex context_lock; | |
dc5698e8 DA |
219 | }; |
220 | ||
221 | /* virtio_ioctl.c */ | |
222 | #define DRM_VIRTIO_NUM_IOCTLS 10 | |
223 | extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; | |
c3e2850a | 224 | void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file); |
dc5698e8 DA |
225 | |
226 | /* virtio_kms.c */ | |
d516e75c EG |
227 | int virtio_gpu_init(struct drm_device *dev); |
228 | void virtio_gpu_deinit(struct drm_device *dev); | |
b1df3a2b | 229 | void virtio_gpu_release(struct drm_device *dev); |
62fb7a5e GH |
230 | int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file); |
231 | void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file); | |
dc5698e8 DA |
232 | |
233 | /* virtio_gem.c */ | |
234 | void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj); | |
235 | int virtio_gpu_gem_init(struct virtio_gpu_device *vgdev); | |
236 | void virtio_gpu_gem_fini(struct virtio_gpu_device *vgdev); | |
237 | int virtio_gpu_gem_create(struct drm_file *file, | |
238 | struct drm_device *dev, | |
4441235f | 239 | struct virtio_gpu_object_params *params, |
dc5698e8 DA |
240 | struct drm_gem_object **obj_p, |
241 | uint32_t *handle_p); | |
62fb7a5e GH |
242 | int virtio_gpu_gem_object_open(struct drm_gem_object *obj, |
243 | struct drm_file *file); | |
244 | void virtio_gpu_gem_object_close(struct drm_gem_object *obj, | |
245 | struct drm_file *file); | |
dc5698e8 DA |
246 | int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, |
247 | struct drm_device *dev, | |
248 | struct drm_mode_create_dumb *args); | |
dc5698e8 DA |
249 | int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, |
250 | struct drm_device *dev, | |
251 | uint32_t handle, uint64_t *offset_p); | |
252 | ||
98abe21d GH |
253 | struct virtio_gpu_object_array *virtio_gpu_array_alloc(u32 nents); |
254 | struct virtio_gpu_object_array* | |
255 | virtio_gpu_array_from_handles(struct drm_file *drm_file, u32 *handles, u32 nents); | |
256 | void virtio_gpu_array_add_obj(struct virtio_gpu_object_array *objs, | |
257 | struct drm_gem_object *obj); | |
258 | int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs); | |
259 | void virtio_gpu_array_unlock_resv(struct virtio_gpu_object_array *objs); | |
260 | void virtio_gpu_array_add_fence(struct virtio_gpu_object_array *objs, | |
261 | struct dma_fence *fence); | |
262 | void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs); | |
f0c6cef7 GH |
263 | void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev, |
264 | struct virtio_gpu_object_array *objs); | |
265 | void virtio_gpu_array_put_free_work(struct work_struct *work); | |
98abe21d | 266 | |
dc5698e8 DA |
267 | /* virtio vg */ |
268 | int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev); | |
269 | void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev); | |
dc5698e8 | 270 | void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, |
23c897d7 | 271 | struct virtio_gpu_object *bo, |
530b2842 | 272 | struct virtio_gpu_object_params *params, |
e2324300 | 273 | struct virtio_gpu_object_array *objs, |
530b2842 | 274 | struct virtio_gpu_fence *fence); |
dc5698e8 | 275 | void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, |
1ed5f698 | 276 | struct virtio_gpu_object *bo); |
dc5698e8 | 277 | void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, |
af334c5d | 278 | uint64_t offset, |
64f1cc99 GH |
279 | uint32_t width, uint32_t height, |
280 | uint32_t x, uint32_t y, | |
3d3bdbc0 | 281 | struct virtio_gpu_object_array *objs, |
4d55fd66 | 282 | struct virtio_gpu_fence *fence); |
dc5698e8 DA |
283 | void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, |
284 | uint32_t resource_id, | |
285 | uint32_t x, uint32_t y, | |
286 | uint32_t width, uint32_t height); | |
287 | void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, | |
288 | uint32_t scanout_id, uint32_t resource_id, | |
289 | uint32_t width, uint32_t height, | |
290 | uint32_t x, uint32_t y); | |
291 | int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, | |
292 | struct virtio_gpu_object *obj, | |
2f2aa137 GH |
293 | struct virtio_gpu_mem_entry *ents, |
294 | unsigned int nents); | |
dc5698e8 DA |
295 | int virtio_gpu_attach_status_page(struct virtio_gpu_device *vgdev); |
296 | int virtio_gpu_detach_status_page(struct virtio_gpu_device *vgdev); | |
297 | void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev, | |
298 | struct virtio_gpu_output *output); | |
299 | int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev); | |
62fb7a5e GH |
300 | int virtio_gpu_cmd_get_capset_info(struct virtio_gpu_device *vgdev, int idx); |
301 | int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev, | |
302 | int idx, int version, | |
303 | struct virtio_gpu_drv_cap_cache **cache_p); | |
b4b01b49 | 304 | int virtio_gpu_cmd_get_edids(struct virtio_gpu_device *vgdev); |
62fb7a5e GH |
305 | void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t id, |
306 | uint32_t nlen, const char *name); | |
307 | void virtio_gpu_cmd_context_destroy(struct virtio_gpu_device *vgdev, | |
308 | uint32_t id); | |
309 | void virtio_gpu_cmd_context_attach_resource(struct virtio_gpu_device *vgdev, | |
310 | uint32_t ctx_id, | |
93c38d15 | 311 | struct virtio_gpu_object_array *objs); |
62fb7a5e GH |
312 | void virtio_gpu_cmd_context_detach_resource(struct virtio_gpu_device *vgdev, |
313 | uint32_t ctx_id, | |
93c38d15 | 314 | struct virtio_gpu_object_array *objs); |
62fb7a5e GH |
315 | void virtio_gpu_cmd_submit(struct virtio_gpu_device *vgdev, |
316 | void *data, uint32_t data_size, | |
da758d51 GH |
317 | uint32_t ctx_id, |
318 | struct virtio_gpu_object_array *objs, | |
319 | struct virtio_gpu_fence *fence); | |
62fb7a5e | 320 | void virtio_gpu_cmd_transfer_from_host_3d(struct virtio_gpu_device *vgdev, |
375f156a | 321 | uint32_t ctx_id, |
62fb7a5e | 322 | uint64_t offset, uint32_t level, |
1dc34852 | 323 | struct drm_virtgpu_3d_box *box, |
375f156a | 324 | struct virtio_gpu_object_array *objs, |
4d55fd66 | 325 | struct virtio_gpu_fence *fence); |
62fb7a5e | 326 | void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, |
af334c5d | 327 | uint32_t ctx_id, |
62fb7a5e | 328 | uint64_t offset, uint32_t level, |
1dc34852 | 329 | struct drm_virtgpu_3d_box *box, |
3d3bdbc0 | 330 | struct virtio_gpu_object_array *objs, |
4d55fd66 | 331 | struct virtio_gpu_fence *fence); |
62fb7a5e GH |
332 | void |
333 | virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, | |
23c897d7 | 334 | struct virtio_gpu_object *bo, |
530b2842 | 335 | struct virtio_gpu_object_params *params, |
e2324300 | 336 | struct virtio_gpu_object_array *objs, |
530b2842 | 337 | struct virtio_gpu_fence *fence); |
dc5698e8 DA |
338 | void virtio_gpu_ctrl_ack(struct virtqueue *vq); |
339 | void virtio_gpu_cursor_ack(struct virtqueue *vq); | |
62fb7a5e | 340 | void virtio_gpu_fence_ack(struct virtqueue *vq); |
dc5698e8 DA |
341 | void virtio_gpu_dequeue_ctrl_func(struct work_struct *work); |
342 | void virtio_gpu_dequeue_cursor_func(struct work_struct *work); | |
62fb7a5e | 343 | void virtio_gpu_dequeue_fence_func(struct work_struct *work); |
dc5698e8 | 344 | |
cca41da1 | 345 | void virtio_gpu_notify(struct virtio_gpu_device *vgdev); |
7082e7a4 | 346 | |
dc5698e8 | 347 | /* virtio_gpu_display.c */ |
d516e75c | 348 | void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); |
dc5698e8 DA |
349 | void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); |
350 | ||
351 | /* virtio_gpu_plane.c */ | |
d519cb76 | 352 | uint32_t virtio_gpu_translate_format(uint32_t drm_fourcc); |
dc5698e8 | 353 | struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, |
bbbed888 | 354 | enum drm_plane_type type, |
dc5698e8 DA |
355 | int index); |
356 | ||
dc5698e8 | 357 | /* virtio_gpu_fence.c */ |
9fdd90c0 RF |
358 | struct virtio_gpu_fence *virtio_gpu_fence_alloc( |
359 | struct virtio_gpu_device *vgdev); | |
fa2b7c21 | 360 | void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, |
dc5698e8 | 361 | struct virtio_gpu_ctrl_hdr *cmd_hdr, |
4d55fd66 | 362 | struct virtio_gpu_fence *fence); |
dc5698e8 DA |
363 | void virtio_gpu_fence_event_process(struct virtio_gpu_device *vdev, |
364 | u64 last_seq); | |
365 | ||
366 | /* virtio_gpu_object */ | |
1ed5f698 | 367 | void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo); |
c66df701 GH |
368 | struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev, |
369 | size_t size); | |
dc5698e8 | 370 | int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, |
4441235f | 371 | struct virtio_gpu_object_params *params, |
530b2842 GH |
372 | struct virtio_gpu_object **bo_ptr, |
373 | struct virtio_gpu_fence *fence); | |
18b39fb9 | 374 | |
bc1a4130 | 375 | bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo); |
18b39fb9 | 376 | |
11a8f280 | 377 | /* virtgpu_prime.c */ |
a0cecc23 DA |
378 | struct drm_gem_object *virtgpu_gem_prime_import_sg_table( |
379 | struct drm_device *dev, struct dma_buf_attachment *attach, | |
380 | struct sg_table *sgt); | |
11a8f280 | 381 | |
093bd9cf | 382 | /* virgl debugfs */ |
dc5698e8 | 383 | int virtio_gpu_debugfs_init(struct drm_minor *minor); |
dc5698e8 DA |
384 | |
385 | #endif |