drm/i915: Move GEM request routines to i915_gem_request.c
[deliverable/linux.git] / drivers / gpu / drm / i915 / i915_gem_request.h
CommitLineData
05235c53
CW
1/*
2 * Copyright © 2008-2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25#ifndef I915_GEM_REQUEST_H
26#define I915_GEM_REQUEST_H
27
28/**
29 * Request queue structure.
30 *
31 * The request queue allows us to note sequence numbers that have been emitted
32 * and may be associated with active buffers to be retired.
33 *
34 * By keeping this list, we can avoid having to do questionable sequence
35 * number comparisons on buffer last_read|write_seqno. It also allows an
36 * emission time to be associated with the request for tracking how far ahead
37 * of the GPU the submission is.
38 *
39 * The requests are reference counted, so upon creation they should have an
40 * initial reference taken using kref_init
41 */
42struct drm_i915_gem_request {
43 struct kref ref;
44
45 /** On Which ring this request was generated */
46 struct drm_i915_private *i915;
47
48 /**
49 * Context and ring buffer related to this request
50 * Contexts are refcounted, so when this request is associated with a
51 * context, we must increment the context's refcount, to guarantee that
52 * it persists while any request is linked to it. Requests themselves
53 * are also refcounted, so the request will only be freed when the last
54 * reference to it is dismissed, and the code in
55 * i915_gem_request_free() will then decrement the refcount on the
56 * context.
57 */
58 struct i915_gem_context *ctx;
59 struct intel_engine_cs *engine;
60 struct intel_ringbuffer *ringbuf;
61 struct intel_signal_node signaling;
62
63 /** GEM sequence number associated with the previous request,
64 * when the HWS breadcrumb is equal to this the GPU is processing
65 * this request.
66 */
67 u32 previous_seqno;
68
69 /** GEM sequence number associated with this request,
70 * when the HWS breadcrumb is equal or greater than this the GPU
71 * has finished processing this request.
72 */
73 u32 seqno;
74
75 /** Position in the ringbuffer of the start of the request */
76 u32 head;
77
78 /**
79 * Position in the ringbuffer of the start of the postfix.
80 * This is required to calculate the maximum available ringbuffer
81 * space without overwriting the postfix.
82 */
83 u32 postfix;
84
85 /** Position in the ringbuffer of the end of the whole request */
86 u32 tail;
87
88 /** Preallocate space in the ringbuffer for the emitting the request */
89 u32 reserved_space;
90
91 /**
92 * Context related to the previous request.
93 * As the contexts are accessed by the hardware until the switch is
94 * completed to a new context, the hardware may still be writing
95 * to the context object after the breadcrumb is visible. We must
96 * not unpin/unbind/prune that object whilst still active and so
97 * we keep the previous context pinned until the following (this)
98 * request is retired.
99 */
100 struct i915_gem_context *previous_context;
101
102 /** Batch buffer related to this request if any (used for
103 * error state dump only).
104 */
105 struct drm_i915_gem_object *batch_obj;
106
107 /** Time at which this request was emitted, in jiffies. */
108 unsigned long emitted_jiffies;
109
110 /** global list entry for this request */
111 struct list_head list;
112
113 struct drm_i915_file_private *file_priv;
114 /** file_priv list entry for this request */
115 struct list_head client_list;
116
117 /** process identifier submitting this request */
118 struct pid *pid;
119
120 /**
121 * The ELSP only accepts two elements at a time, so we queue
122 * context/tail pairs on a given queue (ring->execlist_queue) until the
123 * hardware is available. The queue serves a double purpose: we also use
124 * it to keep track of the up to 2 contexts currently in the hardware
125 * (usually one in execution and the other queued up by the GPU): We
126 * only remove elements from the head of the queue when the hardware
127 * informs us that an element has been completed.
128 *
129 * All accesses to the queue are mediated by a spinlock
130 * (ring->execlist_lock).
131 */
132
133 /** Execlist link in the submission queue.*/
134 struct list_head execlist_link;
135
136 /** Execlists no. of times this request has been sent to the ELSP */
137 int elsp_submitted;
138
139 /** Execlists context hardware id. */
140 unsigned int ctx_hw_id;
141};
142
143struct drm_i915_gem_request * __must_check
144i915_gem_request_alloc(struct intel_engine_cs *engine,
145 struct i915_gem_context *ctx);
146void i915_gem_request_free(struct kref *req_ref);
147int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
148 struct drm_file *file);
149void i915_gem_request_retire_upto(struct drm_i915_gem_request *req);
150
151static inline u32
152i915_gem_request_get_seqno(struct drm_i915_gem_request *req)
153{
154 return req ? req->seqno : 0;
155}
156
157static inline struct intel_engine_cs *
158i915_gem_request_get_engine(struct drm_i915_gem_request *req)
159{
160 return req ? req->engine : NULL;
161}
162
163static inline struct drm_i915_gem_request *
164i915_gem_request_reference(struct drm_i915_gem_request *req)
165{
166 if (req)
167 kref_get(&req->ref);
168 return req;
169}
170
171static inline void
172i915_gem_request_unreference(struct drm_i915_gem_request *req)
173{
174 kref_put(&req->ref, i915_gem_request_free);
175}
176
177static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
178 struct drm_i915_gem_request *src)
179{
180 if (src)
181 i915_gem_request_reference(src);
182
183 if (*pdst)
184 i915_gem_request_unreference(*pdst);
185
186 *pdst = src;
187}
188
189void __i915_add_request(struct drm_i915_gem_request *req,
190 struct drm_i915_gem_object *batch_obj,
191 bool flush_caches);
192#define i915_add_request(req) \
193 __i915_add_request(req, NULL, true)
194#define i915_add_request_no_flush(req) \
195 __i915_add_request(req, NULL, false)
196
197struct intel_rps_client;
198
199int __i915_wait_request(struct drm_i915_gem_request *req,
200 bool interruptible,
201 s64 *timeout,
202 struct intel_rps_client *rps);
203int __must_check i915_wait_request(struct drm_i915_gem_request *req);
204
205static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine);
206
207/**
208 * Returns true if seq1 is later than seq2.
209 */
210static inline bool i915_seqno_passed(u32 seq1, u32 seq2)
211{
212 return (s32)(seq1 - seq2) >= 0;
213}
214
215static inline bool
216i915_gem_request_started(const struct drm_i915_gem_request *req)
217{
218 return i915_seqno_passed(intel_engine_get_seqno(req->engine),
219 req->previous_seqno);
220}
221
222static inline bool
223i915_gem_request_completed(const struct drm_i915_gem_request *req)
224{
225 return i915_seqno_passed(intel_engine_get_seqno(req->engine),
226 req->seqno);
227}
228
229bool __i915_spin_request(const struct drm_i915_gem_request *request,
230 int state, unsigned long timeout_us);
231static inline bool i915_spin_request(const struct drm_i915_gem_request *request,
232 int state, unsigned long timeout_us)
233{
234 return (i915_gem_request_started(request) &&
235 __i915_spin_request(request, state, timeout_us));
236}
237
238#endif /* I915_GEM_REQUEST_H */
This page took 0.032809 seconds and 5 git commands to generate.