1 /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ 2 /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 4 #ifndef PVR_JOB_H 5 #define PVR_JOB_H 6 7 #include <uapi/drm/pvr_drm.h> 8 9 #include <linux/kref.h> 10 #include <linux/types.h> 11 12 #include <drm/drm_gem.h> 13 #include <drm/gpu_scheduler.h> 14 15 #include "pvr_power.h" 16 17 /* Forward declaration from "pvr_context.h". */ 18 struct pvr_context; 19 20 /* Forward declarations from "pvr_device.h". */ 21 struct pvr_device; 22 struct pvr_file; 23 24 /* Forward declarations from "pvr_hwrt.h". */ 25 struct pvr_hwrt_data; 26 27 /* Forward declaration from "pvr_queue.h". */ 28 struct pvr_queue; 29 30 struct pvr_job { 31 /** @base: drm_sched_job object. */ 32 struct drm_sched_job base; 33 34 /** @ref_count: Refcount for job. */ 35 struct kref ref_count; 36 37 /** @type: Type of job. */ 38 enum drm_pvr_job_type type; 39 40 /** @id: Job ID number. */ 41 u32 id; 42 43 /** 44 * @paired_job: Job paired to this job. 45 * 46 * This field is only meaningful for geometry and fragment jobs. 47 * 48 * Paired jobs are executed on the same context, and need to be submitted 49 * atomically to the FW, to make sure the partial render logic has a 50 * fragment job to execute when the Parameter Manager runs out of memory. 51 * 52 * The geometry job should point to the fragment job it's paired with, 53 * and the fragment job should point to the geometry job it's paired with. 54 */ 55 struct pvr_job *paired_job; 56 57 /** @cccb_fence: Fence used to wait for CCCB space. */ 58 struct dma_fence *cccb_fence; 59 60 /** @kccb_fence: Fence used to wait for KCCB space. */ 61 struct dma_fence *kccb_fence; 62 63 /** @done_fence: Fence to signal when the job is done. */ 64 struct dma_fence *done_fence; 65 66 /** @pvr_dev: Device pointer. */ 67 struct pvr_device *pvr_dev; 68 69 /** @ctx: Pointer to owning context. */ 70 struct pvr_context *ctx; 71 72 /** @cmd: Command data. Format depends on @type. */ 73 void *cmd; 74 75 /** @cmd_len: Length of command data, in bytes. */ 76 u32 cmd_len; 77 78 /** 79 * @fw_ccb_cmd_type: Firmware CCB command type. Must be one of %ROGUE_FWIF_CCB_CMD_TYPE_*. 80 */ 81 u32 fw_ccb_cmd_type; 82 83 /** @hwrt: HWRT object. Will be NULL for compute and transfer jobs. */ 84 struct pvr_hwrt_data *hwrt; 85 86 /** 87 * @has_pm_ref: True if the job has a power ref, thus forcing the GPU to stay on until 88 * the job is done. 89 */ 90 bool has_pm_ref; 91 }; 92 93 /** 94 * pvr_job_get() - Take additional reference on job. 95 * @job: Job pointer. 96 * 97 * Call pvr_job_put() to release. 98 * 99 * Returns: 100 * * The requested job on success, or 101 * * %NULL if no job pointer passed. 102 */ 103 static __always_inline struct pvr_job * 104 pvr_job_get(struct pvr_job *job) 105 { 106 if (job) 107 kref_get(&job->ref_count); 108 109 return job; 110 } 111 112 void pvr_job_put(struct pvr_job *job); 113 114 /** 115 * pvr_job_release_pm_ref() - Release the PM ref if the job acquired it. 116 * @job: The job to release the PM ref on. 117 */ 118 static __always_inline void 119 pvr_job_release_pm_ref(struct pvr_job *job) 120 { 121 if (job->has_pm_ref) { 122 pvr_power_put(job->pvr_dev); 123 job->has_pm_ref = false; 124 } 125 } 126 127 /** 128 * pvr_job_get_pm_ref() - Get a PM ref and attach it to the job. 129 * @job: The job to attach the PM ref to. 130 * 131 * Return: 132 * * 0 on success, or 133 * * Any error returned by pvr_power_get() otherwise. 134 */ 135 static __always_inline int 136 pvr_job_get_pm_ref(struct pvr_job *job) 137 { 138 int err; 139 140 if (job->has_pm_ref) 141 return 0; 142 143 err = pvr_power_get(job->pvr_dev); 144 if (!err) 145 job->has_pm_ref = true; 146 147 return err; 148 } 149 150 int pvr_job_wait_first_non_signaled_native_dep(struct pvr_job *job); 151 152 bool pvr_job_non_native_deps_done(struct pvr_job *job); 153 154 int pvr_job_fits_in_cccb(struct pvr_job *job, unsigned long native_dep_count); 155 156 void pvr_job_submit(struct pvr_job *job); 157 158 int pvr_submit_jobs(struct pvr_device *pvr_dev, struct pvr_file *pvr_file, 159 struct drm_pvr_ioctl_submit_jobs_args *args); 160 161 #endif /* PVR_JOB_H */ 162