drivers/gpu/drm/imagination/pvr_job.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/imagination/pvr_job.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/imagination/pvr_job.c
Extension
.c
Size
19636 bytes
Lines
784
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct pvr_job_data {
	/** @job: Pointer to the job. */
	struct pvr_job *job;

	/** @sync_ops: Pointer to the sync_ops associated with @job. */
	struct drm_pvr_sync_op *sync_ops;

	/** @sync_op_count: Number of members of @sync_ops. */
	u32 sync_op_count;
};

/**
 * prepare_job_syncs() - Prepare all sync objects for a single job.
 * @pvr_file: PowerVR file.
 * @job_data: Precreated job and sync_ops array.
 * @signal_array: xarray to receive signal sync objects.
 *
 * Returns:
 *  * 0 on success, or
 *  * Any error code returned by pvr_sync_signal_array_collect_ops(),
 *    pvr_sync_add_deps_to_job(), drm_sched_job_add_resv_dependencies() or
 *    pvr_sync_signal_array_update_fences().
 */
static int
prepare_job_syncs(struct pvr_file *pvr_file,
		  struct pvr_job_data *job_data,
		  struct xarray *signal_array)
{
	struct dma_fence *finished_fence;
	int err = pvr_sync_signal_array_collect_ops(signal_array,
						    from_pvr_file(pvr_file),
						    job_data->sync_op_count,
						    job_data->sync_ops);

	if (err)
		return err;

	err = pvr_sync_add_deps_to_job(pvr_file, &job_data->job->base,
				       job_data->sync_op_count,
				       job_data->sync_ops, signal_array);
	if (err)
		return err;

	if (job_data->job->hwrt) {
		/* The geometry job writes the HWRT region headers, which are
		 * then read by the fragment job.
		 */
		struct drm_gem_object *obj =
			gem_from_pvr_gem(job_data->job->hwrt->fw_obj->gem);
		enum dma_resv_usage usage =
			dma_resv_usage_rw(job_data->job->type ==
					  DRM_PVR_JOB_TYPE_GEOMETRY);

		dma_resv_lock(obj->resv, NULL);
		err = drm_sched_job_add_resv_dependencies(&job_data->job->base,
							  obj->resv, usage);
		dma_resv_unlock(obj->resv);
		if (err)
			return err;
	}

	/* We need to arm the job to get the job finished fence. */
	finished_fence = pvr_queue_job_arm(job_data->job);

	err = pvr_sync_signal_array_update_fences(signal_array,
						  job_data->sync_op_count,
						  job_data->sync_ops,
						  finished_fence);
	return err;
}

/**
 * prepare_job_syncs_for_each() - Prepare all sync objects for an array of jobs.
 * @pvr_file: PowerVR file.
 * @job_data: Array of precreated jobs and their sync_ops.
 * @job_count: Number of jobs.
 * @signal_array: xarray to receive signal sync objects.
 *
 * Returns:
 *  * 0 on success, or
 *  * Any error code returned by pvr_vm_bind_job_prepare_syncs().
 */
static int
prepare_job_syncs_for_each(struct pvr_file *pvr_file,
			   struct pvr_job_data *job_data,
			   u32 *job_count,
			   struct xarray *signal_array)
{
	for (u32 i = 0; i < *job_count; i++) {
		int err = prepare_job_syncs(pvr_file, &job_data[i],

Annotation

Implementation Notes