hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/gpu/drm/drm_writeback.c
....@@ -9,12 +9,14 @@
99 * of such GNU licence.
1010 */
1111
12
+#include <linux/dma-fence.h>
13
+
1214 #include <drm/drm_crtc.h>
15
+#include <drm/drm_device.h>
16
+#include <drm/drm_drv.h>
1317 #include <drm/drm_modeset_helper_vtables.h>
1418 #include <drm/drm_property.h>
1519 #include <drm/drm_writeback.h>
16
-#include <drm/drmP.h>
17
-#include <linux/dma-fence.h>
1820
1921 /**
2022 * DOC: overview
....@@ -106,7 +108,6 @@
106108 .get_driver_name = drm_writeback_fence_get_driver_name,
107109 .get_timeline_name = drm_writeback_fence_get_timeline_name,
108110 .enable_signaling = drm_writeback_fence_enable_signaling,
109
- .wait = dma_fence_default_wait,
110111 };
111112
112113 static int create_writeback_properties(struct drm_device *dev)
....@@ -239,14 +240,52 @@
239240 }
240241 EXPORT_SYMBOL(drm_writeback_connector_init);
241242
243
+int drm_writeback_set_fb(struct drm_connector_state *conn_state,
244
+ struct drm_framebuffer *fb)
245
+{
246
+ WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK);
247
+
248
+ if (!conn_state->writeback_job) {
249
+ conn_state->writeback_job =
250
+ kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL);
251
+ if (!conn_state->writeback_job)
252
+ return -ENOMEM;
253
+
254
+ conn_state->writeback_job->connector =
255
+ drm_connector_to_writeback(conn_state->connector);
256
+ }
257
+
258
+ drm_framebuffer_assign(&conn_state->writeback_job->fb, fb);
259
+ return 0;
260
+}
261
+
262
+int drm_writeback_prepare_job(struct drm_writeback_job *job)
263
+{
264
+ struct drm_writeback_connector *connector = job->connector;
265
+ const struct drm_connector_helper_funcs *funcs =
266
+ connector->base.helper_private;
267
+ int ret;
268
+
269
+ if (funcs->prepare_writeback_job) {
270
+ ret = funcs->prepare_writeback_job(connector, job);
271
+ if (ret < 0)
272
+ return ret;
273
+ }
274
+
275
+ job->prepared = true;
276
+ return 0;
277
+}
278
+EXPORT_SYMBOL(drm_writeback_prepare_job);
279
+
242280 /**
243281 * drm_writeback_queue_job - Queue a writeback job for later signalling
244282 * @wb_connector: The writeback connector to queue a job on
245
- * @job: The job to queue
283
+ * @conn_state: The connector state containing the job to queue
246284 *
247
- * This function adds a job to the job_queue for a writeback connector. It
248
- * should be considered to take ownership of the writeback job, and so any other
249
- * references to the job must be cleared after calling this function.
285
+ * This function adds the job contained in @conn_state to the job_queue for a
286
+ * writeback connector. It takes ownership of the writeback job and sets the
287
+ * @conn_state->writeback_job to NULL, and so no access to the job may be
288
+ * performed by the caller after this function returns.
250289 *
251290 * Drivers must ensure that for a given writeback connector, jobs are queued in
252291 * exactly the same order as they will be completed by the hardware (and
....@@ -258,15 +297,38 @@
258297 * See also: drm_writeback_signal_completion()
259298 */
260299 void drm_writeback_queue_job(struct drm_writeback_connector *wb_connector,
261
- struct drm_writeback_job *job)
300
+ struct drm_connector_state *conn_state)
262301 {
302
+ struct drm_writeback_job *job;
263303 unsigned long flags;
304
+
305
+ job = conn_state->writeback_job;
306
+ conn_state->writeback_job = NULL;
264307
265308 spin_lock_irqsave(&wb_connector->job_lock, flags);
266309 list_add_tail(&job->list_entry, &wb_connector->job_queue);
267310 spin_unlock_irqrestore(&wb_connector->job_lock, flags);
268311 }
269312 EXPORT_SYMBOL(drm_writeback_queue_job);
313
+
314
+void drm_writeback_cleanup_job(struct drm_writeback_job *job)
315
+{
316
+ struct drm_writeback_connector *connector = job->connector;
317
+ const struct drm_connector_helper_funcs *funcs =
318
+ connector->base.helper_private;
319
+
320
+ if (job->prepared && funcs->cleanup_writeback_job)
321
+ funcs->cleanup_writeback_job(connector, job);
322
+
323
+ if (job->fb)
324
+ drm_framebuffer_put(job->fb);
325
+
326
+ if (job->out_fence)
327
+ dma_fence_put(job->out_fence);
328
+
329
+ kfree(job);
330
+}
331
+EXPORT_SYMBOL(drm_writeback_cleanup_job);
270332
271333 /*
272334 * @cleanup_work: deferred cleanup of a writeback job
....@@ -280,10 +342,9 @@
280342 struct drm_writeback_job *job = container_of(work,
281343 struct drm_writeback_job,
282344 cleanup_work);
283
- drm_framebuffer_put(job->fb);
284
- kfree(job);
285
-}
286345
346
+ drm_writeback_cleanup_job(job);
347
+}
287348
288349 /**
289350 * drm_writeback_signal_completion - Signal the completion of a writeback job
....@@ -307,25 +368,29 @@
307368 {
308369 unsigned long flags;
309370 struct drm_writeback_job *job;
371
+ struct dma_fence *out_fence;
310372
311373 spin_lock_irqsave(&wb_connector->job_lock, flags);
312374 job = list_first_entry_or_null(&wb_connector->job_queue,
313375 struct drm_writeback_job,
314376 list_entry);
315
- if (job) {
377
+ if (job)
316378 list_del(&job->list_entry);
317
- if (job->out_fence) {
318
- if (status)
319
- dma_fence_set_error(job->out_fence, status);
320
- dma_fence_signal(job->out_fence);
321
- dma_fence_put(job->out_fence);
322
- }
323
- }
379
+
324380 spin_unlock_irqrestore(&wb_connector->job_lock, flags);
325381
326382 if (WARN_ON(!job))
327383 return;
328384
385
+ out_fence = job->out_fence;
386
+ if (out_fence) {
387
+ if (status)
388
+ dma_fence_set_error(out_fence, status);
389
+ dma_fence_signal(out_fence);
390
+ dma_fence_put(out_fence);
391
+ job->out_fence = NULL;
392
+ }
393
+
329394 INIT_WORK(&job->cleanup_work, cleanup_work);
330395 queue_work(system_long_wq, &job->cleanup_work);
331396 }