13d0407baSopenharmony_ci/*
23d0407baSopenharmony_ci * drm_sync_helper.h: software fence and helper functions for fences and
33d0407baSopenharmony_ci * reservations used for dma buffer access synchronization between drivers.
43d0407baSopenharmony_ci *
53d0407baSopenharmony_ci * Copyright 2014 Google, Inc.
63d0407baSopenharmony_ci *
73d0407baSopenharmony_ci * This software is licensed under the terms of the GNU General Public
83d0407baSopenharmony_ci * License version 2, as published by the Free Software Foundation, and
93d0407baSopenharmony_ci * may be copied, distributed, and modified under those terms.
103d0407baSopenharmony_ci *
113d0407baSopenharmony_ci * This program is distributed in the hope that it will be useful,
123d0407baSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
133d0407baSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
143d0407baSopenharmony_ci * GNU General Public License for more details.
153d0407baSopenharmony_ci */
163d0407baSopenharmony_ci
173d0407baSopenharmony_ci#ifndef _DRM_SYNC_HELPER_H_
183d0407baSopenharmony_ci#define _DRM_SYNC_HELPER_H_
193d0407baSopenharmony_ci
203d0407baSopenharmony_ci#include <linux/fence.h>
213d0407baSopenharmony_ci#include <linux/reservation.h>
223d0407baSopenharmony_ci#include <linux/atomic.h>
233d0407baSopenharmony_ci#include <linux/workqueue.h>
243d0407baSopenharmony_ci
253d0407baSopenharmony_ci/**
263d0407baSopenharmony_ci * Create software fence
273d0407baSopenharmony_ci * @context: execution context
283d0407baSopenharmony_ci * @seqno: the sequence number of this fence inside the execution context
293d0407baSopenharmony_ci */
303d0407baSopenharmony_cistruct fence *drm_sw_fence_new(unsigned int context,
313d0407baSopenharmony_ci			unsigned seqno);
323d0407baSopenharmony_ci
333d0407baSopenharmony_ci/**
343d0407baSopenharmony_ci * Signal and decrease reference count for a fence if it exists
353d0407baSopenharmony_ci * @fence: fence to signal
363d0407baSopenharmony_ci *
373d0407baSopenharmony_ci * Utility function called when owner access to object associated with fence is
383d0407baSopenharmony_ci * finished (e.g. GPU done with rendering).
393d0407baSopenharmony_ci */
403d0407baSopenharmony_cistatic inline void drm_fence_signal_and_put(struct fence **fence)
413d0407baSopenharmony_ci{
423d0407baSopenharmony_ci	if (*fence) {
433d0407baSopenharmony_ci		fence_signal(*fence);
443d0407baSopenharmony_ci		fence_put(*fence);
453d0407baSopenharmony_ci		*fence = NULL;
463d0407baSopenharmony_ci	}
473d0407baSopenharmony_ci}
483d0407baSopenharmony_ci
493d0407baSopenharmony_cistruct drm_reservation_cb;
503d0407baSopenharmony_ci
513d0407baSopenharmony_cistruct drm_reservation_fence_cb {
523d0407baSopenharmony_ci	struct fence_cb base;
533d0407baSopenharmony_ci	struct drm_reservation_cb *parent;
543d0407baSopenharmony_ci	struct fence *fence;
553d0407baSopenharmony_ci};
563d0407baSopenharmony_ci
573d0407baSopenharmony_ci/**
583d0407baSopenharmony_ci * Callback executed when all fences in reservation callback are signaled
593d0407baSopenharmony_ci * @rcb: reservation callback structure
603d0407baSopenharmony_ci * @context: context provided by user at init time
613d0407baSopenharmony_ci */
623d0407baSopenharmony_citypedef void (*drm_reservation_cb_func_t)(struct drm_reservation_cb *rcb,
633d0407baSopenharmony_ci					  void *context);
643d0407baSopenharmony_ci
653d0407baSopenharmony_ci/**
663d0407baSopenharmony_ci * Reservation callback structure
673d0407baSopenharmony_ci * @work: work context in which func is executed
683d0407baSopenharmony_ci * @fence_cbs: fence callbacks array
693d0407baSopenharmony_ci * @num_fence_cbs: number of fence callbacks
703d0407baSopenharmony_ci * @count: count of signaled fences, when it drops to 0 func is called
713d0407baSopenharmony_ci * @func: callback to execute when all fences are signaled
723d0407baSopenharmony_ci * @context: context provided by user during initialization
733d0407baSopenharmony_ci *
743d0407baSopenharmony_ci * It is safe and expected that func will destroy this structure before
753d0407baSopenharmony_ci * returning.
763d0407baSopenharmony_ci */
773d0407baSopenharmony_cistruct drm_reservation_cb {
783d0407baSopenharmony_ci	struct work_struct work;
793d0407baSopenharmony_ci	struct drm_reservation_fence_cb **fence_cbs;
803d0407baSopenharmony_ci	unsigned num_fence_cbs;
813d0407baSopenharmony_ci	atomic_t count;
823d0407baSopenharmony_ci	void *context;
833d0407baSopenharmony_ci	drm_reservation_cb_func_t func;
843d0407baSopenharmony_ci};
853d0407baSopenharmony_ci
863d0407baSopenharmony_ci/**
873d0407baSopenharmony_ci * Initialize reservation callback
883d0407baSopenharmony_ci * @rcb: reservation callback structure to initialize
893d0407baSopenharmony_ci * @func: function to call when all fences are signaled
903d0407baSopenharmony_ci * @context: parameter to call func with
913d0407baSopenharmony_ci */
923d0407baSopenharmony_civoid drm_reservation_cb_init(struct drm_reservation_cb *rcb,
933d0407baSopenharmony_ci			     drm_reservation_cb_func_t func,
943d0407baSopenharmony_ci			     void *context);
953d0407baSopenharmony_ci
963d0407baSopenharmony_ci/**
973d0407baSopenharmony_ci * Add fences from reservation object to callback
983d0407baSopenharmony_ci * @rcb: reservation callback structure
993d0407baSopenharmony_ci * @resv: reservation object
1003d0407baSopenharmony_ci * @exclusive: (for exclusive wait) when true add all fences, otherwise only
1013d0407baSopenharmony_ci *    exclusive fence
1023d0407baSopenharmony_ci */
1033d0407baSopenharmony_ciint drm_reservation_cb_add(struct drm_reservation_cb *rcb,
1043d0407baSopenharmony_ci			   struct reservation_object *resv,
1053d0407baSopenharmony_ci			   bool exclusive);
1063d0407baSopenharmony_ci
1073d0407baSopenharmony_ci/**
1083d0407baSopenharmony_ci * Finish adding fences
1093d0407baSopenharmony_ci * @rcb: reservation callback structure
1103d0407baSopenharmony_ci *
1113d0407baSopenharmony_ci * It will trigger callback worker if all fences were signaled before.
1123d0407baSopenharmony_ci */
1133d0407baSopenharmony_civoid drm_reservation_cb_done(struct drm_reservation_cb *rcb);
1143d0407baSopenharmony_ci
1153d0407baSopenharmony_ci/**
1163d0407baSopenharmony_ci * Cleanup reservation callback structure
1173d0407baSopenharmony_ci * @rcb: reservation callback structure
1183d0407baSopenharmony_ci *
1193d0407baSopenharmony_ci * Can be called to cancel primed reservation callback.
1203d0407baSopenharmony_ci */
1213d0407baSopenharmony_civoid drm_reservation_cb_fini(struct drm_reservation_cb *rcb);
1223d0407baSopenharmony_ci
1233d0407baSopenharmony_ci/**
1243d0407baSopenharmony_ci * Add reservation to array of reservations
1253d0407baSopenharmony_ci * @resv: reservation to add
1263d0407baSopenharmony_ci * @resvs: array of reservations
1273d0407baSopenharmony_ci * @excl_resvs_bitmap: bitmap for exclusive reservations
1283d0407baSopenharmony_ci * @num_resvs: number of reservations in array
1293d0407baSopenharmony_ci * @exclusive: bool to store in excl_resvs_bitmap
1303d0407baSopenharmony_ci */
1313d0407baSopenharmony_civoid
1323d0407baSopenharmony_cidrm_add_reservation(struct reservation_object *resv,
1333d0407baSopenharmony_ci			struct reservation_object **resvs,
1343d0407baSopenharmony_ci			unsigned long *excl_resvs_bitmap,
1353d0407baSopenharmony_ci			unsigned int *num_resvs, bool exclusive);
1363d0407baSopenharmony_ci
1373d0407baSopenharmony_ci/**
1383d0407baSopenharmony_ci * Acquire ww_mutex lock on all reservations in the array
1393d0407baSopenharmony_ci * @resvs: array of reservations
1403d0407baSopenharmony_ci * @num_resvs: number of reservations in the array
1413d0407baSopenharmony_ci * @ctx: ww mutex context
1423d0407baSopenharmony_ci */
1433d0407baSopenharmony_ciint drm_lock_reservations(struct reservation_object **resvs,
1443d0407baSopenharmony_ci			unsigned int num_resvs, struct ww_acquire_ctx *ctx);
1453d0407baSopenharmony_ci
1463d0407baSopenharmony_ci/**
1473d0407baSopenharmony_ci * Release ww_mutex lock on all reservations in the array
1483d0407baSopenharmony_ci * @resvs: array of reservations
1493d0407baSopenharmony_ci * @num_resvs: number of reservations in the array
1503d0407baSopenharmony_ci * @ctx: ww mutex context
1513d0407baSopenharmony_ci */
1523d0407baSopenharmony_civoid drm_unlock_reservations(struct reservation_object **resvs,
1533d0407baSopenharmony_ci				unsigned int num_resvs,
1543d0407baSopenharmony_ci				struct ww_acquire_ctx *ctx);
1553d0407baSopenharmony_ci
1563d0407baSopenharmony_ci#endif
157