linux/drivers/gpu/drm/v3d/v3d_gem.c
/**
 * v3d_submit_cl_ioctl() - Submits a job (frame) to the V3D.
 * @dev: DRM device
 * @data: ioctl argument
 * @file_priv: DRM file for this fd
 *
 * This is the main entrypoint for userspace to submit a 3D frame to
 * the GPU.  Userspace provides the binner command list (if
 * applicable), and the kernel sets up the render command list to draw
 * to the framebuffer described in the ioctl, using the command lists
 * that the 3D engine's binner will produce.
 */
Submits a job (frame) to the V3D.
@dev: DRM device
@data: ioctl argument
@file_priv: DRM file for this fd

This is the main entrypoint for userspace to submit a 3D frame to
the GPU.  Userspace provides the binner command list (if
applicable), and the kernel sets up the render command list to draw
to the framebuffer described in the ioctl, using the command lists
that the 3D engine's binner will produce.
Submits a job ( frame ) to the V3D . @dev : DRM device @data : ioctl argument @file_priv : DRM file for this fd This is the main entrypoint for userspace to submit a 3D frame to the GPU . Userspace provides the binner command list ( if applicable ) and the kernel sets up the render command list to draw to the framebuffer described in the ioctl using the command lists that the 3D engine ' s binner will produce .
int
v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
		    struct drm_file *file_priv)
{
	struct v3d_dev *v3d = to_v3d_dev(dev);
	struct v3d_file_priv *v3d_priv = file_priv->driver_priv;
	struct drm_v3d_submit_cl *args = data;
	struct v3d_exec_info *exec;
	struct ww_acquire_ctx acquire_ctx;
	struct drm_syncobj *sync_out;
	int ret = 0;
	if (args->pad != 0) {
		DRM_INFO("pad must be zero: %d\n", args->pad);
		return -EINVAL;
	}
	exec = kcalloc(1, sizeof(*exec), GFP_KERNEL);
	if (!exec)
		return -ENOMEM;
	ret = pm_runtime_get_sync(v3d->dev);
	if (ret < 0) {
		kfree(exec);
		return ret;
	}
	kref_init(&exec->refcount);
	ret = drm_syncobj_find_fence(file_priv, args->in_sync_bcl,
				     &exec->bin.in_fence);
	if (ret == -EINVAL)
		goto fail;
	ret = drm_syncobj_find_fence(file_priv, args->in_sync_rcl,
				     &exec->render.in_fence);
	if (ret == -EINVAL)
		goto fail;
	exec->qma = args->qma;
	exec->qms = args->qms;
	exec->qts = args->qts;
	exec->bin.exec = exec;
	exec->bin.start = args->bcl_start;
	exec->bin.end = args->bcl_end;
	exec->render.exec = exec;
	exec->render.start = args->rcl_start;
	exec->render.end = args->rcl_end;
	exec->v3d = v3d;
	INIT_LIST_HEAD(&exec->unref_list);
	ret = v3d_cl_lookup_bos(dev, file_priv, args, exec);
	if (ret)
		goto fail;
	ret = v3d_lock_bo_reservations(dev, exec, &acquire_ctx);
	if (ret)
		goto fail;
	mutex_lock(&v3d->sched_lock);
	if (exec->bin.start != exec->bin.end) {
		ret = drm_sched_job_init(&exec->bin.base,
					 &v3d_priv->sched_entity[V3D_BIN],
					 v3d_priv);
		if (ret)
			goto fail_unreserve;
		exec->bin_done_fence =
			dma_fence_get(&exec->bin.base.s_fence->finished);
		kref_get(&exec->refcount); 
		drm_sched_entity_push_job(&exec->bin.base,
					  &v3d_priv->sched_entity[V3D_BIN]);
	}
	ret = drm_sched_job_init(&exec->render.base,
				 &v3d_priv->sched_entity[V3D_RENDER],
				 v3d_priv);
	if (ret)
		goto fail_unreserve;
	kref_get(&exec->refcount); 
	drm_sched_entity_push_job(&exec->render.base,
				  &v3d_priv->sched_entity[V3D_RENDER]);
	mutex_unlock(&v3d->sched_lock);
	v3d_attach_object_fences(exec);
	v3d_unlock_bo_reservations(dev, exec, &acquire_ctx);
	sync_out = drm_syncobj_find(file_priv, args->out_sync);
	if (sync_out) {
		drm_syncobj_replace_fence(sync_out,
					  &exec->render.base.s_fence->finished);
		drm_syncobj_put(sync_out);
	}
	v3d_exec_put(exec);
	return 0;
fail_unreserve:
	mutex_unlock(&v3d->sched_lock);
	v3d_unlock_bo_reservations(dev, exec, &acquire_ctx);
fail:
	v3d_exec_put(exec);
	return ret;
}
int v3d_submit_cl_ioctl ( struct drm_device * dev , void * data , struct drm_file * file_priv ) { struct v3d_dev * v3d = to_v3d_dev ( dev ) ; struct v3d_file_priv * v3d_priv = file_priv -> driver_priv ; struct drm_v3d_submit_cl * args = data ; struct v3d_exec_info * exec ; struct ww_acquire_ctx acquire_ctx ; struct drm_syncobj * sync_out ; int ret = 0 ; if ( args -> pad != 0 ) { DRM_INFO ( " \n " , args -> pad ) ; return - EINVAL ; } exec = kcalloc ( 1 , sizeof ( * exec ) , GFP_KERNEL ) ; if ( ! exec ) return - ENOMEM ; ret = pm_runtime_get_sync ( v3d -> dev ) ; if ( ret < 0 ) { kfree ( exec ) ; return ret ; } kref_init ( & exec -> refcount ) ; ret = drm_syncobj_find_fence ( file_priv , args -> in_sync_bcl , & exec -> bin . in_fence ) ; if ( ret == - EINVAL ) goto fail ; ret = drm_syncobj_find_fence ( file_priv , args -> in_sync_rcl , & exec -> render . in_fence ) ; if ( ret == - EINVAL ) goto fail ; exec -> qma = args -> qma ; exec -> qms = args -> qms ; exec -> qts = args -> qts ; exec -> bin . exec = exec ; exec -> bin . start = args -> bcl_start ; exec -> bin . end = args -> bcl_end ; exec -> render . exec = exec ; exec -> render . start = args -> rcl_start ; exec -> render . end = args -> rcl_end ; exec -> v3d = v3d ; INIT_LIST_HEAD ( & exec -> unref_list ) ; ret = v3d_cl_lookup_bos ( dev , file_priv , args , exec ) ; if ( ret ) goto fail ; ret = v3d_lock_bo_reservations ( dev , exec , & acquire_ctx ) ; if ( ret ) goto fail ; mutex_lock ( & v3d -> sched_lock ) ; if ( exec -> bin . start != exec -> bin . end ) { ret = drm_sched_job_init ( & exec -> bin . base , & v3d_priv -> sched_entity [ V3D_BIN ] , v3d_priv ) ; if ( ret ) goto fail_unreserve ; exec -> bin_done_fence = dma_fence_get ( & exec -> bin . base . s_fence -> finished ) ; kref_get ( & exec -> refcount ) ; drm_sched_entity_push_job ( & exec -> bin . base , & v3d_priv -> sched_entity [ V3D_BIN ] ) ; } ret = drm_sched_job_init ( & exec -> render . base , & v3d_priv -> sched_entity [ V3D_RENDER ] , v3d_priv ) ; if ( ret ) goto fail_unreserve ; kref_get ( & exec -> refcount ) ; drm_sched_entity_push_job ( & exec -> render . base , & v3d_priv -> sched_entity [ V3D_RENDER ] ) ; mutex_unlock ( & v3d -> sched_lock ) ; v3d_attach_object_fences ( exec ) ; v3d_unlock_bo_reservations ( dev , exec , & acquire_ctx ) ; sync_out = drm_syncobj_find ( file_priv , args -> out_sync ) ; if ( sync_out ) { drm_syncobj_replace_fence ( sync_out , & exec -> render . base . s_fence -> finished ) ; drm_syncobj_put ( sync_out ) ; } v3d_exec_put ( exec ) ; return 0 ; fail_unreserve : mutex_unlock ( & v3d -> sched_lock ) ; v3d_unlock_bo_reservations ( dev , exec , & acquire_ctx ) ; fail : v3d_exec_put ( exec ) ; return ret ; }
v3d_submit_cl_ioctl() - Submits a job (frame) to the V3D.
v3d_submit_cl_ioctl () - Submits a job ( frame ) to the V3D .
/* put by scheduler job completion */ /* put by scheduler job completion */ /* Update the return sync object for the */