xref: /titanic_50/usr/src/uts/intel/io/drm/i915_dma.c (revision 6b5764c36d253d178caa447fa2a6d7e0c7dfd6e6)
1 /* BEGIN CSTYLED */
2 
3 /* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
4  */
5 /*
6  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
7  * All Rights Reserved.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the
11  * "Software"), to deal in the Software without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sub license, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice (including the
18  * next paragraph) shall be included in all copies or substantial portions
19  * of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
25  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28  *
29  */
30 
31 /*
32  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
33  * Use is subject to license terms.
34  */
35 
36 #include "drmP.h"
37 #include "drm.h"
38 #include "i915_drm.h"
39 #include "i915_drv.h"
40 
41 
42 
43 /* Really want an OS-independent resettable timer.  Would like to have
44  * this loop run for (eg) 3 sec, but have the timer reset every time
45  * the head pointer changes, so that EBUSY only happens if the ring
46  * actually stalls for (eg) 3 seconds.
47  */
48 /*ARGSUSED*/
49 int i915_wait_ring(drm_device_t * dev, int n, const char *caller)
50 {
51 	drm_i915_private_t *dev_priv = dev->dev_private;
52 	drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
53 	u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
54 	u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
55 	u32 last_acthd = I915_READ(acthd_reg);
56 	u32 acthd;
57 	int i;
58 
59 	for (i = 0; i < 100000; i++) {
60 		ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
61 		acthd = I915_READ(acthd_reg);
62 		ring->space = ring->head - (ring->tail + 8);
63 		if (ring->space < 0)
64 			ring->space += ring->Size;
65 		if (ring->space >= n)
66 			return 0;
67 
68 		if (ring->head != last_head)
69 			i = 0;
70 
71 		if (acthd != last_acthd)
72 			i = 0;
73 
74 		last_head = ring->head;
75 		last_acthd = acthd;
76 		DRM_UDELAY(10);
77 	}
78 
79 	return (EBUSY);
80 }
81 
82 int i915_init_hardware_status(drm_device_t *dev)
83 {
84        drm_i915_private_t *dev_priv = dev->dev_private;
85        drm_dma_handle_t *dmah;
86 
87        /* Program Hardware Status Page */
88        dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff,1);
89 
90        if (!dmah) {
91                DRM_ERROR("Can not allocate hardware status page\n");
92                return -ENOMEM;
93        }
94 
95        dev_priv->status_page_dmah = dmah;
96        dev_priv->hw_status_page = (void *)dmah->vaddr;
97        dev_priv->dma_status_page = dmah->paddr;
98 
99        (void) memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
100 
101        I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
102        DRM_DEBUG("Enabled hardware status page\n");
103        return 0;
104 }
105 
106 void i915_free_hardware_status(drm_device_t *dev)
107 {
108        drm_i915_private_t *dev_priv = dev->dev_private;
109 	if (!I915_NEED_GFX_HWS(dev)) {
110 		if (dev_priv->status_page_dmah) {
111 			drm_pci_free(dev, dev_priv->status_page_dmah);
112 			dev_priv->status_page_dmah = NULL;
113 			/* Need to rewrite hardware status page */
114 			I915_WRITE(HWS_PGA, 0x1ffff000);
115 		}
116        	} else {
117 		if (dev_priv->status_gfx_addr) {
118 			dev_priv->status_gfx_addr = 0;
119 			drm_core_ioremapfree(&dev_priv->hws_map, dev);
120 			I915_WRITE(HWS_PGA, 0x1ffff000);
121 		}
122 	}
123 }
124 
125 #if I915_RING_VALIDATE
126 /**
127  * Validate the cached ring tail value
128  *
129  * If the X server writes to the ring and DRM doesn't
130  * reload the head and tail pointers, it will end up writing
131  * data to the wrong place in the ring, causing havoc.
132  */
133 void i915_ring_validate(struct drm_device *dev, const char *func, int line)
134 {
135        drm_i915_private_t *dev_priv = dev->dev_private;
136        drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
137        u32     tail = I915_READ(PRB0_TAIL) & HEAD_ADDR;
138        u32     head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
139 
140        if (tail != ring->tail) {
141                DRM_ERROR("%s:%d head sw %x, hw %x. tail sw %x hw %x\n",
142                          func, line,
143                          ring->head, head, ring->tail, tail);
144        }
145 }
146 #endif
147 
148 void i915_kernel_lost_context(drm_device_t * dev)
149 {
150 	drm_i915_private_t *dev_priv = dev->dev_private;
151 	drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
152 
153        ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
154        ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
155 	ring->space = ring->head - (ring->tail + 8);
156 	if (ring->space < 0)
157 		ring->space += ring->Size;
158 
159 }
160 
161 static int i915_dma_cleanup(drm_device_t * dev)
162 {
163 	drm_i915_private_t *dev_priv =
164 		    (drm_i915_private_t *) dev->dev_private;
165 
166 	/* Make sure interrupts are disabled here because the uninstall ioctl
167 	 * may not have been called from userspace and after dev_private
168 	 * is freed, it's too late.
169 	 */
170 	if (dev->irq_enabled)
171 		(void) drm_irq_uninstall(dev);
172 
173 	if (dev_priv->ring.virtual_start) {
174 		drm_core_ioremapfree(&dev_priv->ring.map, dev);
175 		dev_priv->ring.virtual_start = 0;
176 		dev_priv->ring.map.handle = 0;
177 		dev_priv->ring.map.size = 0;
178 	}
179 
180 	i915_free_hardware_status(dev);
181 
182 	dev_priv->sarea = NULL;
183 	dev_priv->sarea_priv = NULL;
184 
185 	return 0;
186 }
187 
188 static int i915_initialize(drm_device_t * dev,
189 			   drm_i915_init_t * init)
190 {
191 	drm_i915_private_t *dev_priv =
192 	    (drm_i915_private_t *)dev->dev_private;
193 
194 	DRM_GETSAREA();
195 	if (!dev_priv->sarea) {
196 		DRM_ERROR("can not find sarea!\n");
197 		dev->dev_private = (void *)dev_priv;
198 		(void) i915_dma_cleanup(dev);
199 		return (EINVAL);
200 	}
201 
202 	/*
203 	 * mmio_map will be destoried after DMA clean up.  We should not
204 	 * access mmio_map in suspend or resume process.
205 	 */
206 
207  	dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
208 
209 	 if (!dev_priv->mmio_map) {
210 			dev->dev_private = (void *)dev_priv;
211 			(void) i915_dma_cleanup(dev);
212 			DRM_ERROR("can not find mmio map!\n");
213 			return (EINVAL);
214 	 }
215 
216        if (init->sarea_priv_offset)
217                dev_priv->sarea_priv = (drm_i915_sarea_t *)
218                        ((unsigned long) dev_priv->sarea->handle +
219                         init->sarea_priv_offset);
220        else {
221                /* No sarea_priv for you! */
222                dev_priv->sarea_priv = NULL;
223         }
224 
225 	if (init->ring_size != 0) {
226 		dev_priv->ring.Size = init->ring_size;
227 		dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
228 
229 		dev_priv->ring.map.offset = (u_offset_t)init->ring_start;
230 		dev_priv->ring.map.size = init->ring_size;
231 		dev_priv->ring.map.type = 0;
232 		dev_priv->ring.map.flags = 0;
233 		dev_priv->ring.map.mtrr = 0;
234 
235 		drm_core_ioremap(&dev_priv->ring.map, dev);
236 
237 		if (dev_priv->ring.map.handle == NULL) {
238 			(void) i915_dma_cleanup(dev);
239 			DRM_ERROR("can not ioremap virtual address for"
240 			  " ring buffer\n");
241 			return (ENOMEM);
242 		}
243 
244 		dev_priv->ring.virtual_start = (u8 *)dev_priv->ring.map.dev_addr;
245 	}
246 
247 	dev_priv->cpp = init->cpp;
248 
249 	if (dev_priv->sarea_priv)
250 		dev_priv->sarea_priv->pf_current_page = 0;
251 
252 	/* We are using separate values as placeholders for mechanisms for
253 	 * private backbuffer/depthbuffer usage.
254 	 */
255 
256 	/* Allow hardware batchbuffers unless told otherwise.
257 	 */
258 	dev_priv->allow_batchbuffer = 1;
259 
260 	/* Init HWS */
261 	if (!I915_NEED_GFX_HWS(dev)) {
262 		(void) i915_init_hardware_status(dev);
263 	}
264 
265 	/* Enable vblank on pipe A for older X servers
266 	*/
267 	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
268 
269 #ifdef I915_HAVE_BUFFER
270 	drm_bo_driver_init(dev);
271 #endif
272 	return 0;
273 }
274 
275 static int i915_dma_resume(drm_device_t * dev)
276 {
277 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
278 
279 	DRM_DEBUG("i915_dma_resume\n");
280 
281 	if (!dev_priv->sarea) {
282 		DRM_ERROR("can not find sarea!\n");
283 		return (EINVAL);
284 	}
285 
286 	if (dev_priv->ring.map.handle == NULL) {
287 		DRM_ERROR("can not ioremap virtual address for"
288 			  " ring buffer\n");
289 		return (ENOMEM);
290 	}
291 
292 	/* Program Hardware Status Page */
293 	if (!dev_priv->hw_status_page) {
294 		DRM_ERROR("Can not find hardware status page\n");
295 		return (EINVAL);
296 	}
297 	DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
298 
299 	if (!I915_NEED_GFX_HWS(dev))
300 		I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
301 	else
302 		I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
303 	DRM_DEBUG("Enabled hardware status page\n");
304 
305 	return 0;
306 }
307 
308 /*ARGSUSED*/
309 static int i915_dma_init(DRM_IOCTL_ARGS)
310 {
311 	DRM_DEVICE;
312 	drm_i915_init_t init;
313 	int retcode = 0;
314 
315 	DRM_COPYFROM_WITH_RETURN(&init, (drm_i915_init_t *)data, sizeof(init));
316 
317 	switch (init.func) {
318 	case I915_INIT_DMA:
319 		retcode = i915_initialize(dev, &init);
320 		break;
321 	case I915_CLEANUP_DMA:
322 		retcode = i915_dma_cleanup(dev);
323 		break;
324 	case I915_RESUME_DMA:
325 		retcode = i915_dma_resume(dev);
326 		break;
327 	default:
328 		retcode = EINVAL;
329 		break;
330 	}
331 
332 	return retcode;
333 }
334 
335 /* Implement basically the same security restrictions as hardware does
336  * for MI_BATCH_NON_SECURE.  These can be made stricter at any time.
337  *
338  * Most of the calculations below involve calculating the size of a
339  * particular instruction.  It's important to get the size right as
340  * that tells us where the next instruction to check is.  Any illegal
341  * instruction detected will be given a size of zero, which is a
342  * signal to abort the rest of the buffer.
343  */
344 static int do_validate_cmd(int cmd)
345 {
346 	switch (((cmd >> 29) & 0x7)) {
347 	case 0x0:
348 		switch ((cmd >> 23) & 0x3f) {
349 		case 0x0:
350 			return 1;	/* MI_NOOP */
351 		case 0x4:
352 			return 1;	/* MI_FLUSH */
353 		default:
354 			return 0;	/* disallow everything else */
355 		}
356 #ifndef __SUNPRO_C
357 		break;
358 #endif
359 	case 0x1:
360 		return 0;	/* reserved */
361 	case 0x2:
362 		return (cmd & 0xff) + 2;	/* 2d commands */
363 	case 0x3:
364 		if (((cmd >> 24) & 0x1f) <= 0x18)
365 			return 1;
366 
367 		switch ((cmd >> 24) & 0x1f) {
368 		case 0x1c:
369 			return 1;
370 		case 0x1d:
371 			switch ((cmd >> 16) & 0xff) {
372 			case 0x3:
373 				return (cmd & 0x1f) + 2;
374 			case 0x4:
375 				return (cmd & 0xf) + 2;
376 			default:
377 				return (cmd & 0xffff) + 2;
378 			}
379 		case 0x1e:
380 			if (cmd & (1 << 23))
381 				return (cmd & 0xffff) + 1;
382 			else
383 				return 1;
384 		case 0x1f:
385 			if ((cmd & (1 << 23)) == 0)	/* inline vertices */
386 				return (cmd & 0x1ffff) + 2;
387 			else if (cmd & (1 << 17))	/* indirect random */
388 				if ((cmd & 0xffff) == 0)
389 					return 0;	/* unknown length, too hard */
390 				else
391 					return (((cmd & 0xffff) + 1) / 2) + 1;
392 			else
393 				return 2;	/* indirect sequential */
394 		default:
395 			return 0;
396 		}
397 	default:
398 		return 0;
399 	}
400 
401 #ifndef __SUNPRO_C
402 	return 0;
403 #endif
404 }
405 
406 static int validate_cmd(int cmd)
407 {
408 	int ret = do_validate_cmd(cmd);
409 
410 /* 	printk("validate_cmd( %x ): %d\n", cmd, ret); */
411 
412 	return ret;
413 }
414 
415 static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)
416 {
417 	drm_i915_private_t *dev_priv = dev->dev_private;
418 	int i;
419 	RING_LOCALS;
420 
421 	if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)
422 		return (EINVAL);
423 
424 	BEGIN_LP_RING((dwords+1)&~1);
425 
426 	for (i = 0; i < dwords;) {
427 		int cmd, sz;
428 
429 		if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd)))
430 			return (EINVAL);
431 
432 
433 		if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
434 			return (EINVAL);
435 
436 		OUT_RING(cmd);
437 
438 		while (++i, --sz) {
439 			if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i],
440 							 sizeof(cmd))) {
441 				return (EINVAL);
442 			}
443 			OUT_RING(cmd);
444 		}
445 	}
446 
447 	if (dwords & 1)
448 		OUT_RING(0);
449 
450 	ADVANCE_LP_RING();
451 
452 	return 0;
453 }
454 
455 int i915_emit_box(drm_device_t * dev,
456 			 drm_clip_rect_t __user * boxes,
457 			 int i, int DR1, int DR4)
458 {
459 	drm_i915_private_t *dev_priv = dev->dev_private;
460 	drm_clip_rect_t box;
461 	RING_LOCALS;
462 
463 	if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
464 		return (EFAULT);
465 	}
466 
467 	if (box.y2 <= box.y1 || box.x2 <= box.x1) {
468 		DRM_ERROR("Bad box %d,%d..%d,%d\n",
469 			  box.x1, box.y1, box.x2, box.y2);
470 		return (EINVAL);
471 	}
472 
473 	if (IS_I965G(dev)) {
474 		BEGIN_LP_RING(4);
475 		OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
476 		OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
477 		OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
478 		OUT_RING(DR4);
479 		ADVANCE_LP_RING();
480 	} else {
481 		BEGIN_LP_RING(6);
482 		OUT_RING(GFX_OP_DRAWRECT_INFO);
483 		OUT_RING(DR1);
484 		OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
485 		OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
486 		OUT_RING(DR4);
487 		OUT_RING(0);
488 		ADVANCE_LP_RING();
489 	}
490 
491 	return 0;
492 }
493 
494 /* XXX: Emitting the counter should really be moved to part of the IRQ
495  * emit.  For now, do it in both places:
496  */
497 
498 void i915_emit_breadcrumb(drm_device_t *dev)
499 {
500 	drm_i915_private_t *dev_priv = dev->dev_private;
501 	RING_LOCALS;
502 
503 	if (++dev_priv->counter > BREADCRUMB_MASK) {
504 		 dev_priv->counter = 1;
505 		 DRM_DEBUG("Breadcrumb counter wrapped around\n");
506 	}
507 
508 	if (dev_priv->sarea_priv)
509 		dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
510 
511 
512 	BEGIN_LP_RING(4);
513 	OUT_RING(MI_STORE_DWORD_INDEX);
514 	OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
515 	OUT_RING(dev_priv->counter);
516 	OUT_RING(0);
517 	ADVANCE_LP_RING();
518 
519 }
520 
521 
522 void i915_emit_mi_flush(drm_device_t *dev, uint32_t flush)
523 {
524 	drm_i915_private_t *dev_priv = dev->dev_private;
525 	uint32_t flush_cmd = MI_FLUSH;
526 	RING_LOCALS;
527 
528 	flush_cmd |= flush;
529 
530 	i915_kernel_lost_context(dev);
531 
532 	BEGIN_LP_RING(4);
533 	OUT_RING(flush_cmd);
534 	OUT_RING(0);
535 	OUT_RING(0);
536 	OUT_RING(0);
537 	ADVANCE_LP_RING();
538 }
539 
540 static int i915_dispatch_cmdbuffer(drm_device_t * dev,
541 				   drm_i915_cmdbuffer_t * cmd)
542 {
543 #ifdef I915_HAVE_FENCE
544 	drm_i915_private_t *dev_priv = dev->dev_private;
545 #endif
546 	int nbox = cmd->num_cliprects;
547 	int i = 0, count, ret;
548 
549 	if (cmd->sz & 0x3) {
550 		DRM_ERROR("alignment");
551 		return (EINVAL);
552 	}
553 
554 	i915_kernel_lost_context(dev);
555 
556 	count = nbox ? nbox : 1;
557 
558 	for (i = 0; i < count; i++) {
559 		if (i < nbox) {
560 			ret = i915_emit_box(dev, cmd->cliprects, i,
561 					    cmd->DR1, cmd->DR4);
562 			if (ret)
563 				return ret;
564 		}
565 
566 		ret = i915_emit_cmds(dev, (int __user *)(void *)cmd->buf, cmd->sz / 4);
567 		if (ret)
568 			return ret;
569 	}
570 
571 	i915_emit_breadcrumb( dev );
572 #ifdef I915_HAVE_FENCE
573 	if (unlikely((dev_priv->counter & 0xFF) == 0))
574 		drm_fence_flush_old(dev, 0, dev_priv->counter);
575 #endif
576 	return 0;
577 }
578 
579 static int i915_dispatch_batchbuffer(drm_device_t * dev,
580 				     drm_i915_batchbuffer_t * batch)
581 {
582 	drm_i915_private_t *dev_priv = dev->dev_private;
583 	drm_clip_rect_t __user *boxes = batch->cliprects;
584 	int nbox = batch->num_cliprects;
585 	int i = 0, count;
586 	RING_LOCALS;
587 
588 	if ((batch->start | batch->used) & 0x7) {
589 		DRM_ERROR("alignment");
590 		return (EINVAL);
591 	}
592 
593 	i915_kernel_lost_context(dev);
594 
595 	count = nbox ? nbox : 1;
596 
597 	for (i = 0; i < count; i++) {
598 		if (i < nbox) {
599 			int ret = i915_emit_box(dev, boxes, i,
600 						batch->DR1, batch->DR4);
601 			if (ret)
602 				return ret;
603 		}
604 
605 		if (IS_I830(dev) || IS_845G(dev)) {
606 			BEGIN_LP_RING(4);
607 			OUT_RING(MI_BATCH_BUFFER);
608 			OUT_RING(batch->start | MI_BATCH_NON_SECURE);
609 			OUT_RING(batch->start + batch->used - 4);
610 			OUT_RING(0);
611 			ADVANCE_LP_RING();
612 		} else {
613 			BEGIN_LP_RING(2);
614 			if (IS_I965G(dev)) {
615 				OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
616 				OUT_RING(batch->start);
617 			} else {
618 				OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
619 				OUT_RING(batch->start | MI_BATCH_NON_SECURE);
620 			}
621 			ADVANCE_LP_RING();
622 		}
623 	}
624 
625 	i915_emit_breadcrumb( dev );
626 
627 	return 0;
628 }
629 
630 static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)
631 {
632 	drm_i915_private_t *dev_priv = dev->dev_private;
633 	u32 num_pages, current_page, next_page, dspbase;
634 	int shift = 2 * plane, x, y;
635 	RING_LOCALS;
636 
637 	/* Calculate display base offset */
638 	num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
639 	current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3;
640 	next_page = (current_page + 1) % num_pages;
641 
642 	switch (next_page) {
643 	default:
644 	case 0:
645 		dspbase = dev_priv->sarea_priv->front_offset;
646 		break;
647 	case 1:
648 		dspbase = dev_priv->sarea_priv->back_offset;
649 		break;
650 	case 2:
651 		dspbase = dev_priv->sarea_priv->third_offset;
652 		break;
653 	}
654 
655 	if (plane == 0) {
656 		x = dev_priv->sarea_priv->planeA_x;
657 		y = dev_priv->sarea_priv->planeA_y;
658 	} else {
659 		x = dev_priv->sarea_priv->planeB_x;
660 		y = dev_priv->sarea_priv->planeB_y;
661 	}
662 
663 	dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp;
664 
665 
666 	DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page, dspbase);
667 
668 	BEGIN_LP_RING(4);
669 	OUT_RING(sync ? 0 :
670 		(MI_WAIT_FOR_EVENT | (plane ? MI_WAIT_FOR_PLANE_B_FLIP :
671 					MI_WAIT_FOR_PLANE_A_FLIP)));
672 	OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) |
673 		(plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A));
674 	OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp);
675 	OUT_RING(dspbase);
676 	ADVANCE_LP_RING();
677 
678 	dev_priv->sarea_priv->pf_current_page &= ~(0x3 << shift);
679 	dev_priv->sarea_priv->pf_current_page |= next_page << shift;
680 }
681 
682 void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
683 {
684 	drm_i915_private_t *dev_priv = dev->dev_private;
685 	int i;
686 
687 	DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n",
688 		planes, dev_priv->sarea_priv->pf_current_page);
689 
690 	i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH);
691 
692 	for (i = 0; i < 2; i++)
693 		if (planes & (1 << i))
694 			i915_do_dispatch_flip(dev, i, sync);
695 
696 	i915_emit_breadcrumb(dev);
697 #ifdef I915_HAVE_FENCE
698 	if (unlikely(!sync && ((dev_priv->counter & 0xFF) == 0)))
699 		drm_fence_flush_old(dev, 0, dev_priv->counter);
700 #endif
701 
702 }
703 
704 static int i915_quiescent(drm_device_t * dev)
705 {
706 	drm_i915_private_t *dev_priv = dev->dev_private;
707 	int ret;
708 	i915_kernel_lost_context(dev);
709 	ret = i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
710 
711 	if (ret)
712 	{
713 		i915_kernel_lost_context (dev);
714 		DRM_ERROR ("not quiescent head %08x tail %08x space %08x\n",
715 			   dev_priv->ring.head,
716 			   dev_priv->ring.tail,
717 			   dev_priv->ring.space);
718 	}
719 	return ret;
720 }
721 
722 /*ARGSUSED*/
723 static int i915_flush_ioctl(DRM_IOCTL_ARGS)
724 {
725 	DRM_DEVICE;
726 
727 	LOCK_TEST_WITH_RETURN(dev, fpriv);
728 
729 	return i915_quiescent(dev);
730 }
731 
732 /*ARGSUSED*/
733 static int i915_batchbuffer(DRM_IOCTL_ARGS)
734 {
735 	DRM_DEVICE;
736 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
737 	drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
738 	    dev_priv->sarea_priv;
739 	drm_i915_batchbuffer_t batch;
740 	int ret;
741 
742 	if (!dev_priv->allow_batchbuffer) {
743 		DRM_ERROR("Batchbuffer ioctl disabled\n");
744 		return (EINVAL);
745 	}
746 
747 	if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
748 		drm_i915_batchbuffer32_t batchbuffer32_t;
749 
750 		DRM_COPYFROM_WITH_RETURN(&batchbuffer32_t,
751 			(void *) data, sizeof (batchbuffer32_t));
752 
753 		batch.start = batchbuffer32_t.start;
754 		batch.used = batchbuffer32_t.used;
755 		batch.DR1 = batchbuffer32_t.DR1;
756 		batch.DR4 = batchbuffer32_t.DR4;
757 		batch.num_cliprects = batchbuffer32_t.num_cliprects;
758 		batch.cliprects = (drm_clip_rect_t __user *)
759 			(uintptr_t)batchbuffer32_t.cliprects;
760 	} else
761 		DRM_COPYFROM_WITH_RETURN(&batch, (void *) data,
762 			sizeof(batch));
763 
764 
765 	DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d, counter %d\n",
766 		  batch.start, batch.used, batch.num_cliprects, dev_priv->counter);
767 
768 	LOCK_TEST_WITH_RETURN(dev, fpriv);
769 
770 /*
771 	if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects,
772 						       batch.num_cliprects *
773 						       sizeof(drm_clip_rect_t)))
774 		return (EFAULT);
775 */
776 
777 
778 	ret = i915_dispatch_batchbuffer(dev, &batch);
779 	sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
780 
781 	return ret;
782 }
783 
784 /*ARGSUSED*/
785 static int i915_cmdbuffer(DRM_IOCTL_ARGS)
786 {
787 	DRM_DEVICE;
788 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
789 	drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
790 	    dev_priv->sarea_priv;
791 	drm_i915_cmdbuffer_t cmdbuf;
792 	int ret;
793 
794 	if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
795 		drm_i915_cmdbuffer32_t cmdbuffer32_t;
796 
797 		DRM_COPYFROM_WITH_RETURN(&cmdbuffer32_t,
798 			(drm_i915_cmdbuffer32_t __user *) data,
799 			sizeof (drm_i915_cmdbuffer32_t));
800 
801 		cmdbuf.buf = (char __user *)(uintptr_t)cmdbuffer32_t.buf;
802 		cmdbuf.sz = cmdbuffer32_t.sz;
803 		cmdbuf.DR1 = cmdbuffer32_t.DR1;
804 		cmdbuf.DR4 = cmdbuffer32_t.DR4;
805 		cmdbuf.num_cliprects = cmdbuffer32_t.num_cliprects;
806 		cmdbuf.cliprects = (drm_clip_rect_t __user *)
807 			(uintptr_t)cmdbuffer32_t.cliprects;
808 	} else
809 		DRM_COPYFROM_WITH_RETURN(&cmdbuf, (void *) data,
810 			sizeof(cmdbuf));
811 
812 	DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
813 		  cmdbuf.buf, cmdbuf.sz, cmdbuf.num_cliprects);
814 
815 	LOCK_TEST_WITH_RETURN(dev, fpriv);
816 
817 /*
818 	if (cmdbuf.num_cliprects &&
819 	    DRM_VERIFYAREA_READ(cmdbuf.cliprects,
820 				cmdbuf.num_cliprects *
821 				sizeof(drm_clip_rect_t))) {
822 		DRM_ERROR("Fault accessing cliprects\n");
823 		return (EFAULT);
824 	}
825 */
826 
827 	ret = i915_dispatch_cmdbuffer(dev, &cmdbuf);
828 	if (ret) {
829 		DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
830 		return ret;
831 	}
832 
833 	sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
834 	return 0;
835 }
836 
837 static void i915_do_cleanup_pageflip(drm_device_t * dev)
838 {
839 	drm_i915_private_t *dev_priv = dev->dev_private;
840 	int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
841 
842 	DRM_DEBUG("i915_do_cleanup_pageflip\n");
843 
844 	for (i = 0, planes = 0; i < 2; i++)
845 		if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {
846 			dev_priv->sarea_priv->pf_current_page =
847 				(dev_priv->sarea_priv->pf_current_page &
848 				 ~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i));
849 
850 			planes |= 1 << i;
851 		}
852 
853 	if (planes)
854 		i915_dispatch_flip(dev, planes, 0);
855 
856 }
857 
858 /*ARGSUSED*/
859 static int i915_flip_bufs(DRM_IOCTL_ARGS)
860 {
861 	DRM_DEVICE;
862 	drm_i915_flip_t param;
863         DRM_COPYFROM_WITH_RETURN(&param, (drm_i915_flip_t *) data,
864                                  sizeof(param));
865 
866 	DRM_DEBUG("i915_flip_bufs\n");
867 
868 	LOCK_TEST_WITH_RETURN(dev, fpriv);
869 	/* This is really planes */
870 	if (param.pipes & ~0x3) {
871 		DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n",
872 			  param.pipes);
873 		return -EINVAL;
874 	}
875 	i915_dispatch_flip(dev, param.pipes, 0);
876 	return 0;
877 }
878 
879 /*ARGSUSED*/
880 static int i915_getparam(DRM_IOCTL_ARGS)
881 {
882 	DRM_DEVICE;
883 	drm_i915_private_t *dev_priv = dev->dev_private;
884 	drm_i915_getparam_t param;
885 	int value;
886 
887 	if (!dev_priv) {
888 		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
889 		return (EINVAL);
890 	}
891 
892 	if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
893 		drm_i915_getparam32_t getparam32_t;
894 
895 		DRM_COPYFROM_WITH_RETURN(&getparam32_t,
896 			(drm_i915_getparam32_t __user *) data,
897 			sizeof (drm_i915_getparam32_t));
898 
899 		param.param = getparam32_t.param;
900 		param.value = (int __user *)(uintptr_t)getparam32_t.value;
901 	} else
902 		DRM_COPYFROM_WITH_RETURN(&param,
903 		    (drm_i915_getparam_t *) data, sizeof(param));
904 
905 	switch (param.param) {
906 	case I915_PARAM_IRQ_ACTIVE:
907 		value = dev->irq_enabled ? 1 : 0;
908 		break;
909 	case I915_PARAM_ALLOW_BATCHBUFFER:
910 		value = dev_priv->allow_batchbuffer ? 1 : 0;
911 		break;
912 	case I915_PARAM_LAST_DISPATCH:
913 		value = READ_BREADCRUMB(dev_priv);
914 		break;
915 	case I915_PARAM_CHIPSET_ID:
916 		value = dev->pci_device;
917 		break;
918 	default:
919 		DRM_ERROR("Unknown parameter %d\n", param.param);
920 		return (EINVAL);
921 	}
922 
923 	if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) {
924 		DRM_ERROR("i915_getparam failed\n");
925 		return (EFAULT);
926 	}
927 	return 0;
928 }
929 
930 /*ARGSUSED*/
931 static int i915_setparam(DRM_IOCTL_ARGS)
932 {
933 	DRM_DEVICE;
934 	drm_i915_private_t *dev_priv = dev->dev_private;
935 	drm_i915_setparam_t param;
936 
937 	if (!dev_priv) {
938 		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
939 		return (EINVAL);
940 	}
941 
942 	DRM_COPYFROM_WITH_RETURN(&param, (drm_i915_setparam_t *) data,
943 				 sizeof(param));
944 
945 	switch (param.param) {
946 	case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
947 		break;
948 	case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
949 		dev_priv->tex_lru_log_granularity = param.value;
950 		break;
951 	case I915_SETPARAM_ALLOW_BATCHBUFFER:
952 		dev_priv->allow_batchbuffer = param.value;
953 		break;
954 	default:
955 		DRM_ERROR("unknown parameter %d\n", param.param);
956 		return (EINVAL);
957 	}
958 
959 	return 0;
960 }
961 
962 /*ARGSUSED*/
963 static int i915_set_status_page(DRM_IOCTL_ARGS)
964 {
965 	DRM_DEVICE;
966 	drm_i915_private_t *dev_priv = dev->dev_private;
967 	drm_i915_hws_addr_t hws;
968 
969 	if (!I915_NEED_GFX_HWS(dev))
970 		return (EINVAL);
971 
972 	if (!dev_priv) {
973 		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
974 		return (EINVAL);
975 	}
976 	DRM_COPYFROM_WITH_RETURN(&hws, (drm_i915_hws_addr_t __user *) data,
977 			sizeof(hws));
978 	DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws.addr);
979 
980 	dev_priv->status_gfx_addr = hws.addr & (0x1ffff<<12);
981 	DRM_DEBUG("set gfx_addr 0x%08x\n", dev_priv->status_gfx_addr);
982 
983 	dev_priv->hws_map.offset =
984 	    (u_offset_t)dev->agp->agp_info.agpi_aperbase + hws.addr;
985 	dev_priv->hws_map.size = 4 * 1024; /* 4K pages */
986 	dev_priv->hws_map.type = 0;
987 	dev_priv->hws_map.flags = 0;
988 	dev_priv->hws_map.mtrr = 0;
989 
990 	DRM_DEBUG("set status page: i915_set_status_page: mapoffset 0x%llx\n",
991 	    dev_priv->hws_map.offset);
992 	drm_core_ioremap(&dev_priv->hws_map, dev);
993 	if (dev_priv->hws_map.handle == NULL) {
994 		dev->dev_private = (void *)dev_priv;
995 		(void) i915_dma_cleanup(dev);
996 		dev_priv->status_gfx_addr = 0;
997 		DRM_ERROR("can not ioremap virtual address for"
998 				" G33 hw status page\n");
999 		return (ENOMEM);
1000 	}
1001 	dev_priv->hw_status_page = dev_priv->hws_map.dev_addr;
1002 
1003 	(void) memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
1004 	I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
1005 	DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
1006 			dev_priv->status_gfx_addr);
1007 	DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
1008 	return 0;
1009 }
1010 
1011 /*ARGSUSED*/
1012 int i915_driver_load(drm_device_t *dev, unsigned long flags)
1013 {
1014 	struct drm_i915_private *dev_priv;
1015 	int ret = 0;
1016 
1017 	/* i915 has 4 more counters */
1018 	dev->counters += 4;
1019 	dev->types[6] = _DRM_STAT_IRQ;
1020 	dev->types[7] = _DRM_STAT_PRIMARY;
1021 	dev->types[8] = _DRM_STAT_SECONDARY;
1022 	dev->types[9] = _DRM_STAT_DMA;
1023 
1024 	dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER);
1025 	if (dev_priv == NULL)
1026 		return ENOMEM;
1027 
1028 	(void) memset(dev_priv, 0, sizeof(drm_i915_private_t));
1029 	dev->dev_private = (void *)dev_priv;
1030 	dev_priv->dev = dev;
1031 
1032 	mutex_init(&dev_priv->swaps_lock, "swap", MUTEX_DRIVER, NULL);
1033 	mutex_init(&dev_priv->user_irq_lock, "userirq", MUTEX_DRIVER, NULL);
1034 
1035 	return ret;
1036 }
1037 
1038 int i915_driver_unload(struct drm_device *dev)
1039 {
1040        drm_i915_private_t *dev_priv = dev->dev_private;
1041 
1042        i915_free_hardware_status(dev);
1043 
1044 	DRM_FINI_WAITQUEUE(&dev_priv->irq_queue);
1045         mutex_destroy(&dev_priv->swaps_lock);
1046         mutex_destroy(&dev_priv->user_irq_lock);
1047 
1048 	drm_free(dev->dev_private, sizeof(drm_i915_private_t),
1049 	    DRM_MEM_DRIVER);
1050 	dev->dev_private = NULL;
1051 
1052 	return 0;
1053 }
1054 
1055 
1056 void i915_driver_lastclose(drm_device_t * dev)
1057 {
1058 	drm_i915_private_t *dev_priv = dev->dev_private;
1059 
1060 	/* agp off can use this to get called before dev_priv */
1061 	if (!dev_priv)
1062 		return;
1063 
1064 #ifdef I915_HAVE_BUFFER
1065 	if (dev_priv->val_bufs) {
1066 		vfree(dev_priv->val_bufs);
1067 		dev_priv->val_bufs = NULL;
1068 	}
1069 #endif
1070 
1071 
1072 	DRM_GETSAREA();
1073 	if (dev_priv->sarea_priv)
1074 		i915_do_cleanup_pageflip(dev);
1075 	if (dev_priv->agp_heap)
1076 		i915_mem_takedown(&(dev_priv->agp_heap));
1077 #if defined(I915_HAVE_BUFFER)
1078 	if (dev_priv->sarea_kmap.virtual) {
1079 		drm_bo_kunmap(&dev_priv->sarea_kmap);
1080 		dev_priv->sarea_kmap.virtual = NULL;
1081 		dev->lock.hw_lock = NULL;
1082 		dev->sigdata.lock = NULL;
1083 	}
1084 
1085 	if (dev_priv->sarea_bo) {
1086 		mutex_lock(&dev->struct_mutex);
1087 		drm_bo_usage_deref_locked(&dev_priv->sarea_bo);
1088 		mutex_unlock(&dev->struct_mutex);
1089 		dev_priv->sarea_bo = NULL;
1090 	}
1091 #endif
1092 	(void) i915_dma_cleanup(dev);
1093 }
1094 
1095 void i915_driver_preclose(drm_device_t * dev, drm_file_t *fpriv)
1096 {
1097 	if (dev->dev_private) {
1098 		drm_i915_private_t *dev_priv = dev->dev_private;
1099 		i915_mem_release(dev, fpriv, dev_priv->agp_heap);
1100 	}
1101 }
1102 
1103 drm_ioctl_desc_t i915_ioctls[] = {
1104 	[DRM_IOCTL_NR(DRM_I915_INIT)] =
1105 	    {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1106 	[DRM_IOCTL_NR(DRM_I915_FLUSH)] =
1107 	    {i915_flush_ioctl, DRM_AUTH},
1108 	[DRM_IOCTL_NR(DRM_I915_FLIP)] =
1109 	    {i915_flip_bufs, DRM_AUTH},
1110 	[DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] =
1111 	    {i915_batchbuffer, DRM_AUTH},
1112 	[DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] =
1113 	    {i915_irq_emit, DRM_AUTH},
1114 	[DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] =
1115 	    {i915_irq_wait, DRM_AUTH},
1116 	[DRM_IOCTL_NR(DRM_I915_GETPARAM)] =
1117 	    {i915_getparam, DRM_AUTH},
1118 	[DRM_IOCTL_NR(DRM_I915_SETPARAM)] =
1119 	    {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1120 	[DRM_IOCTL_NR(DRM_I915_ALLOC)] =
1121 	    {i915_mem_alloc, DRM_AUTH},
1122 	[DRM_IOCTL_NR(DRM_I915_FREE)] =
1123 	    {i915_mem_free, DRM_AUTH},
1124 	[DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] =
1125 	    {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1126 	[DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] =
1127 	    {i915_cmdbuffer, DRM_AUTH},
1128 	[DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] =
1129 	    {i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1130 	[DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] =
1131 	    {i915_vblank_pipe_set, DRM_AUTH},
1132 	[DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] =
1133 	    {i915_vblank_pipe_get, DRM_AUTH},
1134 	[DRM_IOCTL_NR(DRM_I915_VBLANK_SWAP)] =
1135 	    {i915_vblank_swap, DRM_AUTH},
1136 	[DRM_IOCTL_NR(DRM_I915_HWS_ADDR)] =
1137 	    {i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1138 };
1139 
1140 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1141 
1142 /**
1143  * Determine if the device really is AGP or not.
1144  *
1145  * All Intel graphics chipsets are treated as AGP, even if they are really
1146  * PCI-e.
1147  *
1148  * \param dev   The device to be tested.
1149  *
1150  * \returns
1151  * A value of 1 is always retured to indictate every i9x5 is AGP.
1152  */
1153 /*ARGSUSED*/
1154 int i915_driver_device_is_agp(drm_device_t * dev)
1155 {
1156 	return 1;
1157 }
1158 
1159 /*ARGSUSED*/
1160 int i915_driver_firstopen(struct drm_device *dev)
1161 {
1162 #ifdef I915_HAVE_BUFFER
1163 	drm_bo_driver_init(dev);
1164 #endif
1165 	return 0;
1166 }
1167 
1168