Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ /* Copyright (c) 2023 Imagination Technologies Ltd. */ #ifndef PVR_QUEUE_H #define PVR_QUEUE_H #include <drm/gpu_scheduler.h> #include "pvr_cccb.h" #include "pvr_device.h" struct pvr_context; struct pvr_queue; /** * struct pvr_queue_fence_ctx - Queue fence context * * Used to implement dma_fence_ops for pvr_job::{done,cccb}_fence. */ struct pvr_queue_fence_ctx { /** @id: Fence context ID allocated with dma_fence_context_alloc(). */ u64 id; /** @seqno: Sequence number incremented each time a fence is created. */ atomic_t seqno; /** @lock: Lock used to synchronize access to fences allocated by this context. */ spinlock_t lock; }; /** * struct pvr_queue_cccb_fence_ctx - CCCB fence context * * Context used to manage fences controlling access to the CCCB. No fences are * issued if there's enough space in the CCCB to push job commands. */ struct pvr_queue_cccb_fence_ctx { /** @base: Base queue fence context. */ struct pvr_queue_fence_ctx base; /** * @job: Job waiting for CCCB space. * * Thanks to the serializationg done at the drm_sched_entity level, * there's no more than one job waiting for CCCB at a given time. * * This field is NULL if no jobs are currently waiting for CCCB space. * * Must be accessed with @job_lock held. */ struct pvr_job *job; /** @job_lock: Lock protecting access to the job object. */ struct mutex job_lock; }; /** * struct pvr_queue_fence - Queue fence object */ struct pvr_queue_fence { /** @base: Base dma_fence. */ struct dma_fence base; /** @queue: Queue that created this fence. */ struct pvr_queue *queue; }; /** * struct pvr_queue - Job queue * * Used to queue and track execution of pvr_job objects. */ struct pvr_queue { /** @scheduler: Single entity scheduler use to push jobs to this queue. */ struct drm_gpu_scheduler scheduler; /** @entity: Scheduling entity backing this queue. */ struct drm_sched_entity entity; /** @type: Type of jobs queued to this queue. */ enum drm_pvr_job_type type; /** @ctx: Context object this queue is bound to. */ struct pvr_context *ctx; /** @node: Used to add the queue to the active/idle queue list. */ struct list_head node; /** * @in_flight_job_count: Number of jobs submitted to the CCCB that * have not been processed yet. */ atomic_t in_flight_job_count; /** * @cccb_fence_ctx: CCCB fence context. * * Used to control access to the CCCB is full, such that we don't * end up trying to push commands to the CCCB if there's not enough * space to receive all commands needed for a job to complete. */ struct pvr_queue_cccb_fence_ctx cccb_fence_ctx; /** @job_fence_ctx: Job fence context object. */ struct pvr_queue_fence_ctx job_fence_ctx; /** @timeline_ufo: Timeline UFO for the context queue. */ struct { /** @fw_obj: FW object representing the UFO value. */ struct pvr_fw_object *fw_obj; /** @value: CPU mapping of the UFO value. */ u32 *value; } timeline_ufo; /** * @last_queued_job_scheduled_fence: The scheduled fence of the last * job queued to this queue. * * We use it to insert frag -> geom dependencies when issuing combined * geom+frag jobs, to guarantee that the fragment job that's part of * the combined operation comes after all fragment jobs that were queued * before it. */ struct dma_fence *last_queued_job_scheduled_fence; /** @cccb: Client Circular Command Buffer. */ struct pvr_cccb cccb; /** @reg_state_obj: FW object representing the register state of this queue. */ struct pvr_fw_object *reg_state_obj; /** @ctx_offset: Offset of the queue context in the FW context object. */ u32 ctx_offset; /** @callstack_addr: Initial call stack address for register state object. */ u64 callstack_addr; }; bool pvr_queue_fence_is_ufo_backed(struct dma_fence *f); int pvr_queue_job_init(struct pvr_job *job); void pvr_queue_job_cleanup(struct pvr_job *job); void pvr_queue_job_push(struct pvr_job *job); struct dma_fence *pvr_queue_job_arm(struct pvr_job *job); struct pvr_queue *pvr_queue_create(struct pvr_context *ctx, enum drm_pvr_job_type type, struct drm_pvr_ioctl_create_context_args *args, void *fw_ctx_map); void pvr_queue_kill(struct pvr_queue *queue); void pvr_queue_destroy(struct pvr_queue *queue); void pvr_queue_process(struct pvr_queue *queue); void pvr_queue_device_pre_reset(struct pvr_device *pvr_dev); void pvr_queue_device_post_reset(struct pvr_device *pvr_dev); int pvr_queue_device_init(struct pvr_device *pvr_dev); void pvr_queue_device_fini(struct pvr_device *pvr_dev); #endif /* PVR_QUEUE_H */ |