]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/gpu/drm/i915/intel_ringbuffer.c
drm/i915: introduce intel_ring_buffer structure (V2)
[net-next-2.6.git] / drivers / gpu / drm / i915 / intel_ringbuffer.c
CommitLineData
62fdfeaf
EA
1/*
2 * Copyright © 2008-2010 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 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 * Zou Nan hai <nanhai.zou@intel.com>
26 * Xiang Hai hao<haihao.xiang@intel.com>
27 *
28 */
29
30#include "drmP.h"
31#include "drm.h"
62fdfeaf 32#include "i915_drv.h"
8187a2b7 33#include "i915_drm.h"
62fdfeaf 34#include "i915_trace.h"
62fdfeaf 35
8187a2b7
ZN
36static void
37render_ring_flush(struct drm_device *dev,
38 struct intel_ring_buffer *ring,
39 u32 invalidate_domains,
40 u32 flush_domains)
62fdfeaf 41{
62fdfeaf
EA
42#if WATCH_EXEC
43 DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
44 invalidate_domains, flush_domains);
45#endif
8187a2b7
ZN
46 u32 cmd;
47 trace_i915_gem_request_flush(dev, ring->next_seqno,
62fdfeaf
EA
48 invalidate_domains, flush_domains);
49
62fdfeaf
EA
50 if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) {
51 /*
52 * read/write caches:
53 *
54 * I915_GEM_DOMAIN_RENDER is always invalidated, but is
55 * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
56 * also flushed at 2d versus 3d pipeline switches.
57 *
58 * read-only caches:
59 *
60 * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
61 * MI_READ_FLUSH is set, and is always flushed on 965.
62 *
63 * I915_GEM_DOMAIN_COMMAND may not exist?
64 *
65 * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
66 * invalidated when MI_EXE_FLUSH is set.
67 *
68 * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
69 * invalidated with every MI_FLUSH.
70 *
71 * TLBs:
72 *
73 * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
74 * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
75 * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
76 * are flushed at any MI_FLUSH.
77 */
78
79 cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
80 if ((invalidate_domains|flush_domains) &
81 I915_GEM_DOMAIN_RENDER)
82 cmd &= ~MI_NO_WRITE_FLUSH;
83 if (!IS_I965G(dev)) {
84 /*
85 * On the 965, the sampler cache always gets flushed
86 * and this bit is reserved.
87 */
88 if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
89 cmd |= MI_READ_FLUSH;
90 }
91 if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
92 cmd |= MI_EXE_FLUSH;
93
94#if WATCH_EXEC
95 DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
96#endif
8187a2b7
ZN
97 intel_ring_begin(dev, ring, 8);
98 intel_ring_emit(dev, ring, cmd);
99 intel_ring_emit(dev, ring, MI_NOOP);
100 intel_ring_advance(dev, ring);
62fdfeaf 101 }
8187a2b7
ZN
102}
103
104static unsigned int render_ring_get_head(struct drm_device *dev,
105 struct intel_ring_buffer *ring)
106{
107 drm_i915_private_t *dev_priv = dev->dev_private;
108 return I915_READ(PRB0_HEAD) & HEAD_ADDR;
109}
62fdfeaf 110
8187a2b7
ZN
111static unsigned int render_ring_get_tail(struct drm_device *dev,
112 struct intel_ring_buffer *ring)
113{
114 drm_i915_private_t *dev_priv = dev->dev_private;
115 return I915_READ(PRB0_TAIL) & TAIL_ADDR;
62fdfeaf 116}
8187a2b7
ZN
117
118static unsigned int render_ring_get_active_head(struct drm_device *dev,
119 struct intel_ring_buffer *ring)
120{
121 drm_i915_private_t *dev_priv = dev->dev_private;
122 u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
123
124 return I915_READ(acthd_reg);
125}
126
127static void render_ring_advance_ring(struct drm_device *dev,
128 struct intel_ring_buffer *ring)
129{
130 drm_i915_private_t *dev_priv = dev->dev_private;
131 I915_WRITE(PRB0_TAIL, ring->tail);
132}
133
134static int init_ring_common(struct drm_device *dev,
135 struct intel_ring_buffer *ring)
136{
137 u32 head;
138 drm_i915_private_t *dev_priv = dev->dev_private;
139 struct drm_i915_gem_object *obj_priv;
140 obj_priv = to_intel_bo(ring->gem_object);
141
142 /* Stop the ring if it's running. */
143 I915_WRITE(ring->regs.ctl, 0);
144 I915_WRITE(ring->regs.head, 0);
145 I915_WRITE(ring->regs.tail, 0);
146
147 /* Initialize the ring. */
148 I915_WRITE(ring->regs.start, obj_priv->gtt_offset);
149 head = ring->get_head(dev, ring);
150
151 /* G45 ring initialization fails to reset head to zero */
152 if (head != 0) {
153 DRM_ERROR("%s head not reset to zero "
154 "ctl %08x head %08x tail %08x start %08x\n",
155 ring->name,
156 I915_READ(ring->regs.ctl),
157 I915_READ(ring->regs.head),
158 I915_READ(ring->regs.tail),
159 I915_READ(ring->regs.start));
160
161 I915_WRITE(ring->regs.head, 0);
162
163 DRM_ERROR("%s head forced to zero "
164 "ctl %08x head %08x tail %08x start %08x\n",
165 ring->name,
166 I915_READ(ring->regs.ctl),
167 I915_READ(ring->regs.head),
168 I915_READ(ring->regs.tail),
169 I915_READ(ring->regs.start));
170 }
171
172 I915_WRITE(ring->regs.ctl,
173 ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES)
174 | RING_NO_REPORT | RING_VALID);
175
176 head = I915_READ(ring->regs.head) & HEAD_ADDR;
177 /* If the head is still not zero, the ring is dead */
178 if (head != 0) {
179 DRM_ERROR("%s initialization failed "
180 "ctl %08x head %08x tail %08x start %08x\n",
181 ring->name,
182 I915_READ(ring->regs.ctl),
183 I915_READ(ring->regs.head),
184 I915_READ(ring->regs.tail),
185 I915_READ(ring->regs.start));
186 return -EIO;
187 }
188
189 if (!drm_core_check_feature(dev, DRIVER_MODESET))
190 i915_kernel_lost_context(dev);
191 else {
192 ring->head = ring->get_head(dev, ring);
193 ring->tail = ring->get_tail(dev, ring);
194 ring->space = ring->head - (ring->tail + 8);
195 if (ring->space < 0)
196 ring->space += ring->size;
197 }
198 return 0;
199}
200
201static int init_render_ring(struct drm_device *dev,
202 struct intel_ring_buffer *ring)
203{
204 drm_i915_private_t *dev_priv = dev->dev_private;
205 int ret = init_ring_common(dev, ring);
206 if (IS_I9XX(dev) && !IS_GEN3(dev)) {
207 I915_WRITE(MI_MODE,
208 (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH);
209 }
210 return ret;
211}
212
62fdfeaf 213#define PIPE_CONTROL_FLUSH(addr) \
8187a2b7 214do { \
62fdfeaf
EA
215 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \
216 PIPE_CONTROL_DEPTH_STALL); \
217 OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \
218 OUT_RING(0); \
219 OUT_RING(0); \
8187a2b7 220} while (0)
62fdfeaf
EA
221
222/**
223 * Creates a new sequence number, emitting a write of it to the status page
224 * plus an interrupt, which will trigger i915_user_interrupt_handler.
225 *
226 * Must be called with struct_lock held.
227 *
228 * Returned sequence numbers are nonzero on success.
229 */
8187a2b7
ZN
230static u32
231render_ring_add_request(struct drm_device *dev,
232 struct intel_ring_buffer *ring,
233 struct drm_file *file_priv,
234 u32 flush_domains)
62fdfeaf 235{
8187a2b7 236 u32 seqno;
62fdfeaf 237 drm_i915_private_t *dev_priv = dev->dev_private;
8187a2b7 238 seqno = intel_ring_get_seqno(dev, ring);
62fdfeaf
EA
239 if (HAS_PIPE_CONTROL(dev)) {
240 u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
241
242 /*
243 * Workaround qword write incoherence by flushing the
244 * PIPE_NOTIFY buffers out to memory before requesting
245 * an interrupt.
246 */
247 BEGIN_LP_RING(32);
248 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
249 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
250 OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
251 OUT_RING(seqno);
252 OUT_RING(0);
253 PIPE_CONTROL_FLUSH(scratch_addr);
254 scratch_addr += 128; /* write to separate cachelines */
255 PIPE_CONTROL_FLUSH(scratch_addr);
256 scratch_addr += 128;
257 PIPE_CONTROL_FLUSH(scratch_addr);
258 scratch_addr += 128;
259 PIPE_CONTROL_FLUSH(scratch_addr);
260 scratch_addr += 128;
261 PIPE_CONTROL_FLUSH(scratch_addr);
262 scratch_addr += 128;
263 PIPE_CONTROL_FLUSH(scratch_addr);
264 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
265 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
266 PIPE_CONTROL_NOTIFY);
267 OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
268 OUT_RING(seqno);
269 OUT_RING(0);
270 ADVANCE_LP_RING();
271 } else {
272 BEGIN_LP_RING(4);
273 OUT_RING(MI_STORE_DWORD_INDEX);
274 OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
275 OUT_RING(seqno);
276
277 OUT_RING(MI_USER_INTERRUPT);
278 ADVANCE_LP_RING();
279 }
280 return seqno;
281}
282
8187a2b7
ZN
283static u32
284render_ring_get_gem_seqno(struct drm_device *dev,
285 struct intel_ring_buffer *ring)
286{
287 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
288 if (HAS_PIPE_CONTROL(dev))
289 return ((volatile u32 *)(dev_priv->seqno_page))[0];
290 else
291 return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
292}
293
294static void
295render_ring_get_user_irq(struct drm_device *dev,
296 struct intel_ring_buffer *ring)
62fdfeaf
EA
297{
298 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
299 unsigned long irqflags;
300
301 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
8187a2b7 302 if (dev->irq_enabled && (++ring->user_irq_refcount == 1)) {
62fdfeaf
EA
303 if (HAS_PCH_SPLIT(dev))
304 ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
305 else
306 i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
307 }
308 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
309}
310
8187a2b7
ZN
311static void
312render_ring_put_user_irq(struct drm_device *dev,
313 struct intel_ring_buffer *ring)
62fdfeaf
EA
314{
315 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
316 unsigned long irqflags;
317
318 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
8187a2b7
ZN
319 BUG_ON(dev->irq_enabled && ring->user_irq_refcount <= 0);
320 if (dev->irq_enabled && (--ring->user_irq_refcount == 0)) {
62fdfeaf
EA
321 if (HAS_PCH_SPLIT(dev))
322 ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
323 else
324 i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
325 }
326 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
327}
328
8187a2b7
ZN
329static void render_setup_status_page(struct drm_device *dev,
330 struct intel_ring_buffer *ring)
331{
332 drm_i915_private_t *dev_priv = dev->dev_private;
333 if (IS_GEN6(dev)) {
334 I915_WRITE(HWS_PGA_GEN6, ring->status_page.gfx_addr);
335 I915_READ(HWS_PGA_GEN6); /* posting read */
336 } else {
337 I915_WRITE(HWS_PGA, ring->status_page.gfx_addr);
338 I915_READ(HWS_PGA); /* posting read */
339 }
340
341}
342
343static int
344render_ring_dispatch_gem_execbuffer(struct drm_device *dev,
345 struct intel_ring_buffer *ring,
346 struct drm_i915_gem_execbuffer2 *exec,
347 struct drm_clip_rect *cliprects,
348 uint64_t exec_offset)
62fdfeaf
EA
349{
350 drm_i915_private_t *dev_priv = dev->dev_private;
351 int nbox = exec->num_cliprects;
352 int i = 0, count;
353 uint32_t exec_start, exec_len;
62fdfeaf
EA
354 exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
355 exec_len = (uint32_t) exec->batch_len;
356
357 trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1);
358
359 count = nbox ? nbox : 1;
360
361 for (i = 0; i < count; i++) {
362 if (i < nbox) {
363 int ret = i915_emit_box(dev, cliprects, i,
364 exec->DR1, exec->DR4);
365 if (ret)
366 return ret;
367 }
368
369 if (IS_I830(dev) || IS_845G(dev)) {
8187a2b7
ZN
370 intel_ring_begin(dev, ring, 4);
371 intel_ring_emit(dev, ring, MI_BATCH_BUFFER);
372 intel_ring_emit(dev, ring,
373 exec_start | MI_BATCH_NON_SECURE);
374 intel_ring_emit(dev, ring, exec_start + exec_len - 4);
375 intel_ring_emit(dev, ring, 0);
62fdfeaf 376 } else {
8187a2b7 377 intel_ring_begin(dev, ring, 4);
62fdfeaf 378 if (IS_I965G(dev)) {
8187a2b7
ZN
379 intel_ring_emit(dev, ring,
380 MI_BATCH_BUFFER_START | (2 << 6)
381 | MI_BATCH_NON_SECURE_I965);
382 intel_ring_emit(dev, ring, exec_start);
62fdfeaf 383 } else {
8187a2b7
ZN
384 intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START
385 | (2 << 6));
386 intel_ring_emit(dev, ring, exec_start |
387 MI_BATCH_NON_SECURE);
62fdfeaf 388 }
62fdfeaf 389 }
8187a2b7 390 intel_ring_advance(dev, ring);
62fdfeaf
EA
391 }
392
393 /* XXX breadcrumb */
394 return 0;
395}
396
8187a2b7
ZN
397static void cleanup_status_page(struct drm_device *dev,
398 struct intel_ring_buffer *ring)
62fdfeaf
EA
399{
400 drm_i915_private_t *dev_priv = dev->dev_private;
401 struct drm_gem_object *obj;
402 struct drm_i915_gem_object *obj_priv;
403
8187a2b7
ZN
404 obj = ring->status_page.obj;
405 if (obj == NULL)
62fdfeaf 406 return;
62fdfeaf
EA
407 obj_priv = to_intel_bo(obj);
408
409 kunmap(obj_priv->pages[0]);
410 i915_gem_object_unpin(obj);
411 drm_gem_object_unreference(obj);
8187a2b7 412 ring->status_page.obj = NULL;
62fdfeaf
EA
413
414 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
62fdfeaf
EA
415}
416
8187a2b7
ZN
417static int init_status_page(struct drm_device *dev,
418 struct intel_ring_buffer *ring)
62fdfeaf
EA
419{
420 drm_i915_private_t *dev_priv = dev->dev_private;
421 struct drm_gem_object *obj;
422 struct drm_i915_gem_object *obj_priv;
423 int ret;
424
62fdfeaf
EA
425 obj = i915_gem_alloc_object(dev, 4096);
426 if (obj == NULL) {
427 DRM_ERROR("Failed to allocate status page\n");
428 ret = -ENOMEM;
429 goto err;
430 }
431 obj_priv = to_intel_bo(obj);
432 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
433
434 ret = i915_gem_object_pin(obj, 4096);
435 if (ret != 0) {
62fdfeaf
EA
436 goto err_unref;
437 }
438
8187a2b7
ZN
439 ring->status_page.gfx_addr = obj_priv->gtt_offset;
440 ring->status_page.page_addr = kmap(obj_priv->pages[0]);
441 if (ring->status_page.page_addr == NULL) {
62fdfeaf 442 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
62fdfeaf
EA
443 goto err_unpin;
444 }
8187a2b7
ZN
445 ring->status_page.obj = obj;
446 memset(ring->status_page.page_addr, 0, PAGE_SIZE);
62fdfeaf 447
8187a2b7
ZN
448 ring->setup_status_page(dev, ring);
449 DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
450 ring->name, ring->status_page.gfx_addr);
62fdfeaf
EA
451
452 return 0;
453
454err_unpin:
455 i915_gem_object_unpin(obj);
456err_unref:
457 drm_gem_object_unreference(obj);
458err:
8187a2b7 459 return ret;
62fdfeaf
EA
460}
461
8187a2b7
ZN
462
463int intel_init_ring_buffer(struct drm_device *dev,
464 struct intel_ring_buffer *ring)
62fdfeaf 465{
62fdfeaf 466 int ret;
8187a2b7
ZN
467 struct drm_i915_gem_object *obj_priv;
468 struct drm_gem_object *obj;
469 ring->dev = dev;
62fdfeaf 470
8187a2b7
ZN
471 if (I915_NEED_GFX_HWS(dev)) {
472 ret = init_status_page(dev, ring);
473 if (ret)
474 return ret;
475 }
62fdfeaf 476
8187a2b7 477 obj = i915_gem_alloc_object(dev, ring->size);
62fdfeaf
EA
478 if (obj == NULL) {
479 DRM_ERROR("Failed to allocate ringbuffer\n");
8187a2b7
ZN
480 ret = -ENOMEM;
481 goto cleanup;
62fdfeaf 482 }
62fdfeaf 483
8187a2b7
ZN
484 ring->gem_object = obj;
485
486 ret = i915_gem_object_pin(obj, ring->alignment);
62fdfeaf
EA
487 if (ret != 0) {
488 drm_gem_object_unreference(obj);
8187a2b7 489 goto cleanup;
62fdfeaf
EA
490 }
491
8187a2b7
ZN
492 obj_priv = to_intel_bo(obj);
493 ring->map.size = ring->size;
62fdfeaf 494 ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
62fdfeaf
EA
495 ring->map.type = 0;
496 ring->map.flags = 0;
497 ring->map.mtrr = 0;
498
499 drm_core_ioremap_wc(&ring->map, dev);
500 if (ring->map.handle == NULL) {
501 DRM_ERROR("Failed to map ringbuffer.\n");
62fdfeaf
EA
502 i915_gem_object_unpin(obj);
503 drm_gem_object_unreference(obj);
8187a2b7
ZN
504 ret = -EINVAL;
505 goto cleanup;
62fdfeaf
EA
506 }
507
8187a2b7
ZN
508 ring->virtual_start = ring->map.handle;
509 ret = ring->init(dev, ring);
510 if (ret != 0) {
511 intel_cleanup_ring_buffer(dev, ring);
512 return ret;
62fdfeaf
EA
513 }
514
62fdfeaf
EA
515 if (!drm_core_check_feature(dev, DRIVER_MODESET))
516 i915_kernel_lost_context(dev);
517 else {
8187a2b7
ZN
518 ring->head = ring->get_head(dev, ring);
519 ring->tail = ring->get_tail(dev, ring);
62fdfeaf
EA
520 ring->space = ring->head - (ring->tail + 8);
521 if (ring->space < 0)
8187a2b7 522 ring->space += ring->size;
62fdfeaf 523 }
8187a2b7
ZN
524 INIT_LIST_HEAD(&ring->active_list);
525 INIT_LIST_HEAD(&ring->request_list);
526 return ret;
527cleanup:
528 cleanup_status_page(dev, ring);
529 return ret;
62fdfeaf
EA
530}
531
8187a2b7
ZN
532void intel_cleanup_ring_buffer(struct drm_device *dev,
533 struct intel_ring_buffer *ring)
62fdfeaf 534{
8187a2b7 535 if (ring->gem_object == NULL)
62fdfeaf
EA
536 return;
537
8187a2b7 538 drm_core_ioremapfree(&ring->map, dev);
62fdfeaf 539
8187a2b7
ZN
540 i915_gem_object_unpin(ring->gem_object);
541 drm_gem_object_unreference(ring->gem_object);
542 ring->gem_object = NULL;
543 cleanup_status_page(dev, ring);
62fdfeaf
EA
544}
545
8187a2b7
ZN
546int intel_wrap_ring_buffer(struct drm_device *dev,
547 struct intel_ring_buffer *ring)
62fdfeaf 548{
8187a2b7 549 unsigned int *virt;
62fdfeaf 550 int rem;
8187a2b7 551 rem = ring->size - ring->tail;
62fdfeaf 552
8187a2b7
ZN
553 if (ring->space < rem) {
554 int ret = intel_wait_ring_buffer(dev, ring, rem);
62fdfeaf
EA
555 if (ret)
556 return ret;
557 }
62fdfeaf 558
8187a2b7 559 virt = (unsigned int *)(ring->virtual_start + ring->tail);
62fdfeaf
EA
560 rem /= 4;
561 while (rem--)
562 *virt++ = MI_NOOP;
563
8187a2b7 564 ring->tail = 0;
62fdfeaf
EA
565
566 return 0;
567}
568
8187a2b7
ZN
569int intel_wait_ring_buffer(struct drm_device *dev,
570 struct intel_ring_buffer *ring, int n)
62fdfeaf 571{
8187a2b7 572 unsigned long end;
62fdfeaf
EA
573
574 trace_i915_ring_wait_begin (dev);
8187a2b7
ZN
575 end = jiffies + 3 * HZ;
576 do {
577 ring->head = ring->get_head(dev, ring);
62fdfeaf
EA
578 ring->space = ring->head - (ring->tail + 8);
579 if (ring->space < 0)
8187a2b7 580 ring->space += ring->size;
62fdfeaf
EA
581 if (ring->space >= n) {
582 trace_i915_ring_wait_end (dev);
583 return 0;
584 }
585
586 if (dev->primary->master) {
587 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
588 if (master_priv->sarea_priv)
589 master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
590 }
8187a2b7
ZN
591 yield();
592 } while (!time_after(jiffies, end));
593 trace_i915_ring_wait_end (dev);
594 return -EBUSY;
595}
62fdfeaf 596
8187a2b7
ZN
597void intel_ring_begin(struct drm_device *dev,
598 struct intel_ring_buffer *ring, int n)
599{
600 if (unlikely(ring->tail + n > ring->size))
601 intel_wrap_ring_buffer(dev, ring);
602 if (unlikely(ring->space < n))
603 intel_wait_ring_buffer(dev, ring, n);
604}
62fdfeaf 605
8187a2b7
ZN
606void intel_ring_emit(struct drm_device *dev,
607 struct intel_ring_buffer *ring, unsigned int data)
608{
609 unsigned int *virt = ring->virtual_start + ring->tail;
610 *virt = data;
611 ring->tail += 4;
612 ring->tail &= ring->size - 1;
613 ring->space -= 4;
614}
62fdfeaf 615
8187a2b7
ZN
616void intel_ring_advance(struct drm_device *dev,
617 struct intel_ring_buffer *ring)
618{
619 ring->advance_ring(dev, ring);
620}
62fdfeaf 621
8187a2b7
ZN
622void intel_fill_struct(struct drm_device *dev,
623 struct intel_ring_buffer *ring,
624 void *data,
625 unsigned int len)
626{
627 unsigned int *virt = ring->virtual_start + ring->tail;
628 BUG_ON((len&~(4-1)) != 0);
629 intel_ring_begin(dev, ring, len);
630 memcpy(virt, data, len);
631 ring->tail += len;
632 ring->tail &= ring->size - 1;
633 ring->space -= len;
634 intel_ring_advance(dev, ring);
635}
62fdfeaf 636
8187a2b7
ZN
637u32 intel_ring_get_seqno(struct drm_device *dev,
638 struct intel_ring_buffer *ring)
639{
640 u32 seqno;
641 seqno = ring->next_seqno;
642
643 /* reserve 0 for non-seqno */
644 if (++ring->next_seqno == 0)
645 ring->next_seqno = 1;
646 return seqno;
62fdfeaf 647}
8187a2b7
ZN
648
649struct intel_ring_buffer render_ring = {
650 .name = "render ring",
651 .regs = {
652 .ctl = PRB0_CTL,
653 .head = PRB0_HEAD,
654 .tail = PRB0_TAIL,
655 .start = PRB0_START
656 },
657 .ring_flag = I915_EXEC_RENDER,
658 .size = 32 * PAGE_SIZE,
659 .alignment = PAGE_SIZE,
660 .virtual_start = NULL,
661 .dev = NULL,
662 .gem_object = NULL,
663 .head = 0,
664 .tail = 0,
665 .space = 0,
666 .next_seqno = 1,
667 .user_irq_refcount = 0,
668 .irq_gem_seqno = 0,
669 .waiting_gem_seqno = 0,
670 .setup_status_page = render_setup_status_page,
671 .init = init_render_ring,
672 .get_head = render_ring_get_head,
673 .get_tail = render_ring_get_tail,
674 .get_active_head = render_ring_get_active_head,
675 .advance_ring = render_ring_advance_ring,
676 .flush = render_ring_flush,
677 .add_request = render_ring_add_request,
678 .get_gem_seqno = render_ring_get_gem_seqno,
679 .user_irq_get = render_ring_get_user_irq,
680 .user_irq_put = render_ring_put_user_irq,
681 .dispatch_gem_execbuffer = render_ring_dispatch_gem_execbuffer,
682 .status_page = {NULL, 0, NULL},
683 .map = {0,}
684};