summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Starkey <brian.starkey@arm.com>2017-03-29 12:42:33 -0400
committerLiviu Dudau <Liviu.Dudau@arm.com>2018-06-20 10:29:18 -0400
commitb13cc8dd588434e2aec781e6d12224e4c408ac18 (patch)
treec202a3e17b01d1db38cebd680dd7d5cdc0f641cf
parent935774cd71fe604cc8ed24adcb507d7784255672 (diff)
drm: writeback: Add out-fences for writeback connectors
Add the WRITEBACK_OUT_FENCE_PTR property to writeback connectors, to enable userspace to get a fence which will signal once the writeback is complete. It is not allowed to request an out-fence without a framebuffer attached to the connector. A timeline is added to drm_writeback_connector for use by the writeback out-fences. In the case of a commit failure or DRM_MODE_ATOMIC_TEST_ONLY, the fence is set to -1. Changes from v2: - Rebase onto Gustavo Padovan's v9 explicit sync series - Change out_fence_ptr type to s32 __user * - Set *out_fence_ptr to -1 in drm_atomic_connector_set_property - Store fence in drm_writeback_job Gustavo Padovan: - Move out_fence_ptr out of connector_state - Signal fence from drm_writeback_signal_completion instead of in driver directly Changes from v3: - Rebase onto commit 7e9081c5aac7 ("drm/fence: fix memory overwrite when setting out_fence fd") (change out_fence_ptr to s32 __user *, for real this time.) - Update documentation around WRITEBACK_OUT_FENCE_PTR Signed-off-by: Brian Starkey <brian.starkey@arm.com> [rebased and fixed conflicts] Signed-off-by: Mihail Atanassov <mihail.atanassov@arm.com> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com> Reviewed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Sean Paul <seanpaul@chromium.org> Link: https://patchwork.freedesktop.org/patch/229036/
-rw-r--r--drivers/gpu/drm/drm_atomic.c99
-rw-r--r--drivers/gpu/drm/drm_writeback.c109
-rw-r--r--include/drm/drm_atomic.h8
-rw-r--r--include/drm/drm_connector.h8
-rw-r--r--include/drm/drm_mode_config.h8
-rw-r--r--include/drm/drm_writeback.h41
6 files changed, 257 insertions, 16 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3e53d6e5c340..115719059434 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -318,6 +318,35 @@ static s32 __user *get_out_fence_for_crtc(struct drm_atomic_state *state,
318 return fence_ptr; 318 return fence_ptr;
319} 319}
320 320
321static int set_out_fence_for_connector(struct drm_atomic_state *state,
322 struct drm_connector *connector,
323 s32 __user *fence_ptr)
324{
325 unsigned int index = drm_connector_index(connector);
326
327 if (!fence_ptr)
328 return 0;
329
330 if (put_user(-1, fence_ptr))
331 return -EFAULT;
332
333 state->connectors[index].out_fence_ptr = fence_ptr;
334
335 return 0;
336}
337
338static s32 __user *get_out_fence_for_connector(struct drm_atomic_state *state,
339 struct drm_connector *connector)
340{
341 unsigned int index = drm_connector_index(connector);
342 s32 __user *fence_ptr;
343
344 fence_ptr = state->connectors[index].out_fence_ptr;
345 state->connectors[index].out_fence_ptr = NULL;
346
347 return fence_ptr;
348}
349
321/** 350/**
322 * drm_atomic_set_mode_for_crtc - set mode for CRTC 351 * drm_atomic_set_mode_for_crtc - set mode for CRTC
323 * @state: the CRTC whose incoming state to update 352 * @state: the CRTC whose incoming state to update
@@ -727,6 +756,12 @@ static int drm_atomic_connector_check(struct drm_connector *connector,
727 return -EINVAL; 756 return -EINVAL;
728 } 757 }
729 758
759 if (writeback_job->out_fence && !writeback_job->fb) {
760 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n",
761 connector->base.id, connector->name);
762 return -EINVAL;
763 }
764
730 return 0; 765 return 0;
731} 766}
732 767
@@ -1367,6 +1402,11 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
1367 if (fb) 1402 if (fb)
1368 drm_framebuffer_put(fb); 1403 drm_framebuffer_put(fb);
1369 return ret; 1404 return ret;
1405 } else if (property == config->writeback_out_fence_ptr_property) {
1406 s32 __user *fence_ptr = u64_to_user_ptr(val);
1407
1408 return set_out_fence_for_connector(state->state, connector,
1409 fence_ptr);
1370 } else if (connector->funcs->atomic_set_property) { 1410 } else if (connector->funcs->atomic_set_property) {
1371 return connector->funcs->atomic_set_property(connector, 1411 return connector->funcs->atomic_set_property(connector,
1372 state, property, val); 1412 state, property, val);
@@ -1456,6 +1496,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
1456 } else if (property == config->writeback_fb_id_property) { 1496 } else if (property == config->writeback_fb_id_property) {
1457 /* Writeback framebuffer is one-shot, write and forget */ 1497 /* Writeback framebuffer is one-shot, write and forget */
1458 *val = 0; 1498 *val = 0;
1499 } else if (property == config->writeback_out_fence_ptr_property) {
1500 *val = 0;
1459 } else if (connector->funcs->atomic_get_property) { 1501 } else if (connector->funcs->atomic_get_property) {
1460 return connector->funcs->atomic_get_property(connector, 1502 return connector->funcs->atomic_get_property(connector,
1461 state, property, val); 1503 state, property, val);
@@ -2292,7 +2334,7 @@ static int setup_out_fence(struct drm_out_fence_state *fence_state,
2292 return 0; 2334 return 0;
2293} 2335}
2294 2336
2295static int prepare_crtc_signaling(struct drm_device *dev, 2337static int prepare_signaling(struct drm_device *dev,
2296 struct drm_atomic_state *state, 2338 struct drm_atomic_state *state,
2297 struct drm_mode_atomic *arg, 2339 struct drm_mode_atomic *arg,
2298 struct drm_file *file_priv, 2340 struct drm_file *file_priv,
@@ -2301,6 +2343,8 @@ static int prepare_crtc_signaling(struct drm_device *dev,
2301{ 2343{
2302 struct drm_crtc *crtc; 2344 struct drm_crtc *crtc;
2303 struct drm_crtc_state *crtc_state; 2345 struct drm_crtc_state *crtc_state;
2346 struct drm_connector *conn;
2347 struct drm_connector_state *conn_state;
2304 int i, c = 0, ret; 2348 int i, c = 0, ret;
2305 2349
2306 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) 2350 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
@@ -2366,6 +2410,43 @@ static int prepare_crtc_signaling(struct drm_device *dev,
2366 c++; 2410 c++;
2367 } 2411 }
2368 2412
2413 for_each_new_connector_in_state(state, conn, conn_state, i) {
2414 struct drm_writeback_job *job;
2415 struct drm_out_fence_state *f;
2416 struct dma_fence *fence;
2417 s32 __user *fence_ptr;
2418
2419 fence_ptr = get_out_fence_for_connector(state, conn);
2420 if (!fence_ptr)
2421 continue;
2422
2423 job = drm_atomic_get_writeback_job(conn_state);
2424 if (!job)
2425 return -ENOMEM;
2426
2427 f = krealloc(*fence_state, sizeof(**fence_state) *
2428 (*num_fences + 1), GFP_KERNEL);
2429 if (!f)
2430 return -ENOMEM;
2431
2432 memset(&f[*num_fences], 0, sizeof(*f));
2433
2434 f[*num_fences].out_fence_ptr = fence_ptr;
2435 *fence_state = f;
2436
2437 fence = drm_writeback_get_out_fence((struct drm_writeback_connector *)conn);
2438 if (!fence)
2439 return -ENOMEM;
2440
2441 ret = setup_out_fence(&f[(*num_fences)++], fence);
2442 if (ret) {
2443 dma_fence_put(fence);
2444 return ret;
2445 }
2446
2447 job->out_fence = fence;
2448 }
2449
2369 /* 2450 /*
2370 * Having this flag means user mode pends on event which will never 2451 * Having this flag means user mode pends on event which will never
2371 * reach due to lack of at least one CRTC for signaling 2452 * reach due to lack of at least one CRTC for signaling
@@ -2376,11 +2457,11 @@ static int prepare_crtc_signaling(struct drm_device *dev,
2376 return 0; 2457 return 0;
2377} 2458}
2378 2459
2379static void complete_crtc_signaling(struct drm_device *dev, 2460static void complete_signaling(struct drm_device *dev,
2380 struct drm_atomic_state *state, 2461 struct drm_atomic_state *state,
2381 struct drm_out_fence_state *fence_state, 2462 struct drm_out_fence_state *fence_state,
2382 unsigned int num_fences, 2463 unsigned int num_fences,
2383 bool install_fds) 2464 bool install_fds)
2384{ 2465{
2385 struct drm_crtc *crtc; 2466 struct drm_crtc *crtc;
2386 struct drm_crtc_state *crtc_state; 2467 struct drm_crtc_state *crtc_state;
@@ -2550,8 +2631,8 @@ retry:
2550 drm_mode_object_put(obj); 2631 drm_mode_object_put(obj);
2551 } 2632 }
2552 2633
2553 ret = prepare_crtc_signaling(dev, state, arg, file_priv, &fence_state, 2634 ret = prepare_signaling(dev, state, arg, file_priv, &fence_state,
2554 &num_fences); 2635 &num_fences);
2555 if (ret) 2636 if (ret)
2556 goto out; 2637 goto out;
2557 2638
@@ -2567,7 +2648,7 @@ retry:
2567 } 2648 }
2568 2649
2569out: 2650out:
2570 complete_crtc_signaling(dev, state, fence_state, num_fences, !ret); 2651 complete_signaling(dev, state, fence_state, num_fences, !ret);
2571 2652
2572 if (ret == -EDEADLK) { 2653 if (ret == -EDEADLK) {
2573 drm_atomic_state_clear(state); 2654 drm_atomic_state_clear(state);
diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c
index e5b8a4b79724..827395071f0b 100644
--- a/drivers/gpu/drm/drm_writeback.c
+++ b/drivers/gpu/drm/drm_writeback.c
@@ -14,6 +14,7 @@
14#include <drm/drm_property.h> 14#include <drm/drm_property.h>
15#include <drm/drm_writeback.h> 15#include <drm/drm_writeback.h>
16#include <drm/drmP.h> 16#include <drm/drmP.h>
17#include <linux/dma-fence.h>
17 18
18/** 19/**
19 * DOC: overview 20 * DOC: overview
@@ -31,6 +32,16 @@
31 * framebuffer applies only to a single commit (see below). A framebuffer may 32 * framebuffer applies only to a single commit (see below). A framebuffer may
32 * not be attached while the CRTC is off. 33 * not be attached while the CRTC is off.
33 * 34 *
35 * Unlike with planes, when a writeback framebuffer is removed by userspace DRM
36 * makes no attempt to remove it from active use by the connector. This is
37 * because no method is provided to abort a writeback operation, and in any
38 * case making a new commit whilst a writeback is ongoing is undefined (see
39 * WRITEBACK_OUT_FENCE_PTR below). As soon as the current writeback is finished,
40 * the framebuffer will automatically no longer be in active use. As it will
41 * also have already been removed from the framebuffer list, there will be no
42 * way for any userspace application to retrieve a reference to it in the
43 * intervening period.
44 *
34 * Writeback connectors have some additional properties, which userspace 45 * Writeback connectors have some additional properties, which userspace
35 * can use to query and control them: 46 * can use to query and control them:
36 * 47 *
@@ -47,8 +58,54 @@
47 * data is an array of u32 DRM_FORMAT_* fourcc values. 58 * data is an array of u32 DRM_FORMAT_* fourcc values.
48 * Userspace can use this blob to find out what pixel formats are supported 59 * Userspace can use this blob to find out what pixel formats are supported
49 * by the connector's writeback engine. 60 * by the connector's writeback engine.
61 *
62 * "WRITEBACK_OUT_FENCE_PTR":
63 * Userspace can use this property to provide a pointer for the kernel to
64 * fill with a sync_file file descriptor, which will signal once the
65 * writeback is finished. The value should be the address of a 32-bit
66 * signed integer, cast to a u64.
67 * Userspace should wait for this fence to signal before making another
68 * commit affecting any of the same CRTCs, Planes or Connectors.
69 * **Failure to do so will result in undefined behaviour.**
70 * For this reason it is strongly recommended that all userspace
71 * applications making use of writeback connectors *always* retrieve an
72 * out-fence for the commit and use it appropriately.
73 * From userspace, this property will always read as zero.
50 */ 74 */
51 75
76#define fence_to_wb_connector(x) container_of(x->lock, \
77 struct drm_writeback_connector, \
78 fence_lock)
79
80static const char *drm_writeback_fence_get_driver_name(struct dma_fence *fence)
81{
82 struct drm_writeback_connector *wb_connector =
83 fence_to_wb_connector(fence);
84
85 return wb_connector->base.dev->driver->name;
86}
87
88static const char *
89drm_writeback_fence_get_timeline_name(struct dma_fence *fence)
90{
91 struct drm_writeback_connector *wb_connector =
92 fence_to_wb_connector(fence);
93
94 return wb_connector->timeline_name;
95}
96
97static bool drm_writeback_fence_enable_signaling(struct dma_fence *fence)
98{
99 return true;
100}
101
102static const struct dma_fence_ops drm_writeback_fence_ops = {
103 .get_driver_name = drm_writeback_fence_get_driver_name,
104 .get_timeline_name = drm_writeback_fence_get_timeline_name,
105 .enable_signaling = drm_writeback_fence_enable_signaling,
106 .wait = dma_fence_default_wait,
107};
108
52static int create_writeback_properties(struct drm_device *dev) 109static int create_writeback_properties(struct drm_device *dev)
53{ 110{
54 struct drm_property *prop; 111 struct drm_property *prop;
@@ -72,6 +129,15 @@ static int create_writeback_properties(struct drm_device *dev)
72 dev->mode_config.writeback_pixel_formats_property = prop; 129 dev->mode_config.writeback_pixel_formats_property = prop;
73 } 130 }
74 131
132 if (!dev->mode_config.writeback_out_fence_ptr_property) {
133 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
134 "WRITEBACK_OUT_FENCE_PTR", 0,
135 U64_MAX);
136 if (!prop)
137 return -ENOMEM;
138 dev->mode_config.writeback_out_fence_ptr_property = prop;
139 }
140
75 return 0; 141 return 0;
76} 142}
77 143
@@ -141,6 +207,15 @@ int drm_writeback_connector_init(struct drm_device *dev,
141 INIT_LIST_HEAD(&wb_connector->job_queue); 207 INIT_LIST_HEAD(&wb_connector->job_queue);
142 spin_lock_init(&wb_connector->job_lock); 208 spin_lock_init(&wb_connector->job_lock);
143 209
210 wb_connector->fence_context = dma_fence_context_alloc(1);
211 spin_lock_init(&wb_connector->fence_lock);
212 snprintf(wb_connector->timeline_name,
213 sizeof(wb_connector->timeline_name),
214 "CONNECTOR:%d-%s", connector->base.id, connector->name);
215
216 drm_object_attach_property(&connector->base,
217 config->writeback_out_fence_ptr_property, 0);
218
144 drm_object_attach_property(&connector->base, 219 drm_object_attach_property(&connector->base,
145 config->writeback_fb_id_property, 0); 220 config->writeback_fb_id_property, 0);
146 221
@@ -210,6 +285,7 @@ static void cleanup_work(struct work_struct *work)
210/** 285/**
211 * drm_writeback_signal_completion - Signal the completion of a writeback job 286 * drm_writeback_signal_completion - Signal the completion of a writeback job
212 * @wb_connector: The writeback connector whose job is complete 287 * @wb_connector: The writeback connector whose job is complete
288 * @status: Status code to set in the writeback out_fence (0 for success)
213 * 289 *
214 * Drivers should call this to signal the completion of a previously queued 290 * Drivers should call this to signal the completion of a previously queued
215 * writeback job. It should be called as soon as possible after the hardware 291 * writeback job. It should be called as soon as possible after the hardware
@@ -223,7 +299,8 @@ static void cleanup_work(struct work_struct *work)
223 * See also: drm_writeback_queue_job() 299 * See also: drm_writeback_queue_job()
224 */ 300 */
225void 301void
226drm_writeback_signal_completion(struct drm_writeback_connector *wb_connector) 302drm_writeback_signal_completion(struct drm_writeback_connector *wb_connector,
303 int status)
227{ 304{
228 unsigned long flags; 305 unsigned long flags;
229 struct drm_writeback_job *job; 306 struct drm_writeback_job *job;
@@ -232,8 +309,15 @@ drm_writeback_signal_completion(struct drm_writeback_connector *wb_connector)
232 job = list_first_entry_or_null(&wb_connector->job_queue, 309 job = list_first_entry_or_null(&wb_connector->job_queue,
233 struct drm_writeback_job, 310 struct drm_writeback_job,
234 list_entry); 311 list_entry);
235 if (job) 312 if (job) {
236 list_del(&job->list_entry); 313 list_del(&job->list_entry);
314 if (job->out_fence) {
315 if (status)
316 dma_fence_set_error(job->out_fence, status);
317 dma_fence_signal(job->out_fence);
318 dma_fence_put(job->out_fence);
319 }
320 }
237 spin_unlock_irqrestore(&wb_connector->job_lock, flags); 321 spin_unlock_irqrestore(&wb_connector->job_lock, flags);
238 322
239 if (WARN_ON(!job)) 323 if (WARN_ON(!job))
@@ -243,3 +327,24 @@ drm_writeback_signal_completion(struct drm_writeback_connector *wb_connector)
243 queue_work(system_long_wq, &job->cleanup_work); 327 queue_work(system_long_wq, &job->cleanup_work);
244} 328}
245EXPORT_SYMBOL(drm_writeback_signal_completion); 329EXPORT_SYMBOL(drm_writeback_signal_completion);
330
331struct dma_fence *
332drm_writeback_get_out_fence(struct drm_writeback_connector *wb_connector)
333{
334 struct dma_fence *fence;
335
336 if (WARN_ON(wb_connector->base.connector_type !=
337 DRM_MODE_CONNECTOR_WRITEBACK))
338 return NULL;
339
340 fence = kzalloc(sizeof(*fence), GFP_KERNEL);
341 if (!fence)
342 return NULL;
343
344 dma_fence_init(fence, &drm_writeback_fence_ops,
345 &wb_connector->fence_lock, wb_connector->fence_context,
346 ++wb_connector->fence_seqno);
347
348 return fence;
349}
350EXPORT_SYMBOL(drm_writeback_get_out_fence);
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 8254521b4583..da9d95a19580 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -160,6 +160,14 @@ struct __drm_crtcs_state {
160struct __drm_connnectors_state { 160struct __drm_connnectors_state {
161 struct drm_connector *ptr; 161 struct drm_connector *ptr;
162 struct drm_connector_state *state, *old_state, *new_state; 162 struct drm_connector_state *state, *old_state, *new_state;
163 /**
164 * @out_fence_ptr:
165 *
166 * User-provided pointer which the kernel uses to return a sync_file
167 * file descriptor. Used by writeback connectors to signal completion of
168 * the writeback.
169 */
170 s32 __user *out_fence_ptr;
163}; 171};
164 172
165struct drm_private_obj; 173struct drm_private_obj;
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 716c3a0e0e1d..14ab58ade87f 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -441,10 +441,10 @@ struct drm_connector_state {
441 /** 441 /**
442 * @writeback_job: Writeback job for writeback connectors 442 * @writeback_job: Writeback job for writeback connectors
443 * 443 *
444 * Holds the framebuffer for a writeback connector. As the writeback 444 * Holds the framebuffer and out-fence for a writeback connector. As
445 * completion may be asynchronous to the normal commit cycle, the 445 * the writeback completion may be asynchronous to the normal commit
446 * writeback job lifetime is managed separately from the normal atomic 446 * cycle, the writeback job lifetime is managed separately from the
447 * state by this object. 447 * normal atomic state by this object.
448 * 448 *
449 * See also: drm_writeback_queue_job() and 449 * See also: drm_writeback_queue_job() and
450 * drm_writeback_signal_completion() 450 * drm_writeback_signal_completion()
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 5f24329e6927..f4a173c8d79c 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -798,6 +798,14 @@ struct drm_mode_config {
798 * See also: drm_writeback_connector_init() 798 * See also: drm_writeback_connector_init()
799 */ 799 */
800 struct drm_property *writeback_pixel_formats_property; 800 struct drm_property *writeback_pixel_formats_property;
801 /**
802 * @writeback_out_fence_ptr_property: Property for writeback connectors,
803 * fd pointer representing the outgoing fences for a writeback
804 * connector. Userspace should provide a pointer to a value of type s32,
805 * and then cast that pointer to u64.
806 * See also: drm_writeback_connector_init()
807 */
808 struct drm_property *writeback_out_fence_ptr_property;
801 809
802 /* dumb ioctl parameters */ 810 /* dumb ioctl parameters */
803 uint32_t preferred_depth, prefer_shadow; 811 uint32_t preferred_depth, prefer_shadow;
diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h
index 17cd1feecd7e..a10fe556dfd4 100644
--- a/include/drm/drm_writeback.h
+++ b/include/drm/drm_writeback.h
@@ -50,6 +50,32 @@ struct drm_writeback_connector {
50 * drm_writeback_signal_completion() 50 * drm_writeback_signal_completion()
51 */ 51 */
52 struct list_head job_queue; 52 struct list_head job_queue;
53
54 /**
55 * @fence_context:
56 *
57 * timeline context used for fence operations.
58 */
59 unsigned int fence_context;
60 /**
61 * @fence_lock:
62 *
63 * spinlock to protect the fences in the fence_context.
64 */
65 spinlock_t fence_lock;
66 /**
67 * @fence_seqno:
68 *
69 * Seqno variable used as monotonic counter for the fences
70 * created on the connector's timeline.
71 */
72 unsigned long fence_seqno;
73 /**
74 * @timeline_name:
75 *
76 * The name of the connector's fence timeline.
77 */
78 char timeline_name[32];
53}; 79};
54 80
55struct drm_writeback_job { 81struct drm_writeback_job {
@@ -75,6 +101,13 @@ struct drm_writeback_job {
75 * directly, use drm_atomic_set_writeback_fb_for_connector() 101 * directly, use drm_atomic_set_writeback_fb_for_connector()
76 */ 102 */
77 struct drm_framebuffer *fb; 103 struct drm_framebuffer *fb;
104
105 /**
106 * @out_fence:
107 *
108 * Fence which will signal once the writeback has completed
109 */
110 struct dma_fence *out_fence;
78}; 111};
79 112
80int drm_writeback_connector_init(struct drm_device *dev, 113int drm_writeback_connector_init(struct drm_device *dev,
@@ -87,5 +120,11 @@ void drm_writeback_queue_job(struct drm_writeback_connector *wb_connector,
87 struct drm_writeback_job *job); 120 struct drm_writeback_job *job);
88 121
89void drm_writeback_cleanup_job(struct drm_writeback_job *job); 122void drm_writeback_cleanup_job(struct drm_writeback_job *job);
90void drm_writeback_signal_completion(struct drm_writeback_connector *wb_connector); 123
124void
125drm_writeback_signal_completion(struct drm_writeback_connector *wb_connector,
126 int status);
127
128struct dma_fence *
129drm_writeback_get_out_fence(struct drm_writeback_connector *wb_connector);
91#endif 130#endif