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 | #include <drm/drmP.h> | |
27 | #include "virtgpu_drv.h" | |
28 | ||
29 | static const char *virtio_get_driver_name(struct fence *f) | |
30 | { | |
31 | return "virtio_gpu"; | |
32 | } | |
33 | ||
34 | static const char *virtio_get_timeline_name(struct fence *f) | |
35 | { | |
36 | return "controlq"; | |
37 | } | |
38 | ||
39 | static bool virtio_enable_signaling(struct fence *f) | |
40 | { | |
41 | return true; | |
42 | } | |
43 | ||
44 | static bool virtio_signaled(struct fence *f) | |
45 | { | |
46 | struct virtio_gpu_fence *fence = to_virtio_fence(f); | |
47 | ||
48 | if (atomic64_read(&fence->drv->last_seq) >= fence->seq) | |
49 | return true; | |
50 | return false; | |
51 | } | |
52 | ||
53 | static void virtio_fence_value_str(struct fence *f, char *str, int size) | |
54 | { | |
55 | struct virtio_gpu_fence *fence = to_virtio_fence(f); | |
56 | ||
57 | snprintf(str, size, "%llu", fence->seq); | |
58 | } | |
59 | ||
60 | static void virtio_timeline_value_str(struct fence *f, char *str, int size) | |
61 | { | |
62 | struct virtio_gpu_fence *fence = to_virtio_fence(f); | |
63 | ||
d549f545 | 64 | snprintf(str, size, "%llu", (u64)atomic64_read(&fence->drv->last_seq)); |
dc5698e8 DA |
65 | } |
66 | ||
67 | static const struct fence_ops virtio_fence_ops = { | |
68 | .get_driver_name = virtio_get_driver_name, | |
69 | .get_timeline_name = virtio_get_timeline_name, | |
70 | .enable_signaling = virtio_enable_signaling, | |
71 | .signaled = virtio_signaled, | |
72 | .wait = fence_default_wait, | |
73 | .fence_value_str = virtio_fence_value_str, | |
74 | .timeline_value_str = virtio_timeline_value_str, | |
75 | }; | |
76 | ||
77 | int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, | |
78 | struct virtio_gpu_ctrl_hdr *cmd_hdr, | |
79 | struct virtio_gpu_fence **fence) | |
80 | { | |
81 | struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv; | |
82 | unsigned long irq_flags; | |
83 | ||
ec2f0577 | 84 | *fence = kmalloc(sizeof(struct virtio_gpu_fence), GFP_ATOMIC); |
dc5698e8 DA |
85 | if ((*fence) == NULL) |
86 | return -ENOMEM; | |
87 | ||
88 | spin_lock_irqsave(&drv->lock, irq_flags); | |
89 | (*fence)->drv = drv; | |
90 | (*fence)->seq = ++drv->sync_seq; | |
91 | fence_init(&(*fence)->f, &virtio_fence_ops, &drv->lock, | |
92 | 0, (*fence)->seq); | |
93 | fence_get(&(*fence)->f); | |
94 | list_add_tail(&(*fence)->node, &drv->fences); | |
95 | spin_unlock_irqrestore(&drv->lock, irq_flags); | |
96 | ||
97 | cmd_hdr->flags |= cpu_to_le32(VIRTIO_GPU_FLAG_FENCE); | |
98 | cmd_hdr->fence_id = cpu_to_le64((*fence)->seq); | |
99 | return 0; | |
100 | } | |
101 | ||
102 | void virtio_gpu_fence_event_process(struct virtio_gpu_device *vgdev, | |
103 | u64 last_seq) | |
104 | { | |
105 | struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv; | |
106 | struct virtio_gpu_fence *fence, *tmp; | |
107 | unsigned long irq_flags; | |
108 | ||
109 | spin_lock_irqsave(&drv->lock, irq_flags); | |
110 | atomic64_set(&vgdev->fence_drv.last_seq, last_seq); | |
111 | list_for_each_entry_safe(fence, tmp, &drv->fences, node) { | |
112 | if (last_seq < fence->seq) | |
113 | continue; | |
114 | fence_signal_locked(&fence->f); | |
115 | list_del(&fence->node); | |
116 | fence_put(&fence->f); | |
117 | } | |
118 | spin_unlock_irqrestore(&drv->lock, irq_flags); | |
119 | } |