pvr_job.h 3.7 KB

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