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