i810_dma.c 35.7 KB
Newer Older
L
Linus Torvalds 已提交
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
/* i810_dma.c -- DMA support for the i810 -*- linux-c -*-
 * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
 *
 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
 *	    Jeff Hartmann <jhartmann@valinux.com>
 *          Keith Whitwell <keith@tungstengraphics.com>
 *
 */

#include "drmP.h"
#include "drm.h"
#include "i810_drm.h"
#include "i810_drv.h"
#include <linux/interrupt.h>	/* For task queue support */
#include <linux/delay.h>
#include <linux/pagemap.h>

#define I810_BUF_FREE		2
#define I810_BUF_CLIENT		1
#define I810_BUF_HARDWARE      	0

#define I810_BUF_UNMAPPED 0
#define I810_BUF_MAPPED   1

D
Dave Airlie 已提交
48
static drm_buf_t *i810_freelist_get(drm_device_t * dev)
L
Linus Torvalds 已提交
49
{
D
Dave Airlie 已提交
50 51 52
	drm_device_dma_t *dma = dev->dma;
	int i;
	int used;
L
Linus Torvalds 已提交
53 54 55

	/* Linear search might not be the best solution */

D
Dave Airlie 已提交
56 57 58
	for (i = 0; i < dma->buf_count; i++) {
		drm_buf_t *buf = dma->buflist[i];
		drm_i810_buf_priv_t *buf_priv = buf->dev_private;
L
Linus Torvalds 已提交
59
		/* In use is already a pointer */
D
Dave Airlie 已提交
60
		used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
L
Linus Torvalds 已提交
61 62 63 64 65
			       I810_BUF_CLIENT);
		if (used == I810_BUF_FREE) {
			return buf;
		}
	}
D
Dave Airlie 已提交
66
	return NULL;
L
Linus Torvalds 已提交
67 68 69 70 71 72
}

/* This should only be called if the buffer is not sent to the hardware
 * yet, the hardware updates in use for us once its on the ring buffer.
 */

D
Dave Airlie 已提交
73
static int i810_freelist_put(drm_device_t * dev, drm_buf_t * buf)
L
Linus Torvalds 已提交
74
{
D
Dave Airlie 已提交
75 76
	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
	int used;
L
Linus Torvalds 已提交
77

D
Dave Airlie 已提交
78 79
	/* In use is already a pointer */
	used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE);
L
Linus Torvalds 已提交
80
	if (used != I810_BUF_CLIENT) {
D
Dave Airlie 已提交
81 82
		DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
		return -EINVAL;
L
Linus Torvalds 已提交
83 84
	}

D
Dave Airlie 已提交
85
	return 0;
L
Linus Torvalds 已提交
86 87
}

D
Dave Airlie 已提交
88
static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
L
Linus Torvalds 已提交
89
{
D
Dave Airlie 已提交
90 91 92 93
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev;
	drm_i810_private_t *dev_priv;
	drm_buf_t *buf;
L
Linus Torvalds 已提交
94 95 96
	drm_i810_buf_priv_t *buf_priv;

	lock_kernel();
D
Dave Airlie 已提交
97
	dev = priv->head->dev;
L
Linus Torvalds 已提交
98
	dev_priv = dev->dev_private;
D
Dave Airlie 已提交
99
	buf = dev_priv->mmap_buffer;
L
Linus Torvalds 已提交
100 101 102 103 104
	buf_priv = buf->dev_private;

	vma->vm_flags |= (VM_IO | VM_DONTCOPY);
	vma->vm_file = filp;

D
Dave Airlie 已提交
105
	buf_priv->currently_mapped = I810_BUF_MAPPED;
L
Linus Torvalds 已提交
106 107 108
	unlock_kernel();

	if (io_remap_pfn_range(vma, vma->vm_start,
D
Dave Airlie 已提交
109 110 111
			       VM_OFFSET(vma) >> PAGE_SHIFT,
			       vma->vm_end - vma->vm_start, vma->vm_page_prot))
		return -EAGAIN;
L
Linus Torvalds 已提交
112 113 114
	return 0;
}

D
Dave Airlie 已提交
115
static struct file_operations i810_buffer_fops = {
D
Dave Airlie 已提交
116 117
	.open = drm_open,
	.flush = drm_flush,
D
Dave Airlie 已提交
118
	.release = drm_release,
D
Dave Airlie 已提交
119 120 121
	.ioctl = drm_ioctl,
	.mmap = i810_mmap_buffers,
	.fasync = drm_fasync,
D
Dave Airlie 已提交
122 123
};

D
Dave Airlie 已提交
124
static int i810_map_buffer(drm_buf_t * buf, struct file *filp)
L
Linus Torvalds 已提交
125
{
D
Dave Airlie 已提交
126 127
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
L
Linus Torvalds 已提交
128
	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
D
Dave Airlie 已提交
129 130
	drm_i810_private_t *dev_priv = dev->dev_private;
	struct file_operations *old_fops;
L
Linus Torvalds 已提交
131 132
	int retcode = 0;

D
Dave Airlie 已提交
133
	if (buf_priv->currently_mapped == I810_BUF_MAPPED)
L
Linus Torvalds 已提交
134 135
		return -EINVAL;

D
Dave Airlie 已提交
136
	down_write(&current->mm->mmap_sem);
L
Linus Torvalds 已提交
137 138 139 140
	old_fops = filp->f_op;
	filp->f_op = &i810_buffer_fops;
	dev_priv->mmap_buffer = buf;
	buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
D
Dave Airlie 已提交
141 142
					    PROT_READ | PROT_WRITE,
					    MAP_SHARED, buf->bus_address);
L
Linus Torvalds 已提交
143 144 145 146 147 148 149 150
	dev_priv->mmap_buffer = NULL;
	filp->f_op = old_fops;
	if ((unsigned long)buf_priv->virtual > -1024UL) {
		/* Real error */
		DRM_ERROR("mmap error\n");
		retcode = (signed int)buf_priv->virtual;
		buf_priv->virtual = NULL;
	}
D
Dave Airlie 已提交
151
	up_write(&current->mm->mmap_sem);
L
Linus Torvalds 已提交
152 153 154 155

	return retcode;
}

D
Dave Airlie 已提交
156
static int i810_unmap_buffer(drm_buf_t * buf)
L
Linus Torvalds 已提交
157 158 159 160 161 162 163 164 165 166 167 168 169
{
	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
	int retcode = 0;

	if (buf_priv->currently_mapped != I810_BUF_MAPPED)
		return -EINVAL;

	down_write(&current->mm->mmap_sem);
	retcode = do_munmap(current->mm,
			    (unsigned long)buf_priv->virtual,
			    (size_t) buf->total);
	up_write(&current->mm->mmap_sem);

D
Dave Airlie 已提交
170 171
	buf_priv->currently_mapped = I810_BUF_UNMAPPED;
	buf_priv->virtual = NULL;
L
Linus Torvalds 已提交
172 173 174 175

	return retcode;
}

D
Dave Airlie 已提交
176
static int i810_dma_get_buffer(drm_device_t * dev, drm_i810_dma_t * d,
L
Linus Torvalds 已提交
177 178
			       struct file *filp)
{
D
Dave Airlie 已提交
179
	drm_buf_t *buf;
L
Linus Torvalds 已提交
180 181 182 183 184 185
	drm_i810_buf_priv_t *buf_priv;
	int retcode = 0;

	buf = i810_freelist_get(dev);
	if (!buf) {
		retcode = -ENOMEM;
D
Dave Airlie 已提交
186
		DRM_DEBUG("retcode=%d\n", retcode);
L
Linus Torvalds 已提交
187 188 189 190 191 192
		return retcode;
	}

	retcode = i810_map_buffer(buf, filp);
	if (retcode) {
		i810_freelist_put(dev, buf);
D
Dave Airlie 已提交
193
		DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
L
Linus Torvalds 已提交
194 195 196 197 198
		return retcode;
	}
	buf->filp = filp;
	buf_priv = buf->dev_private;
	d->granted = 1;
D
Dave Airlie 已提交
199 200 201
	d->request_idx = buf->idx;
	d->request_size = buf->total;
	d->virtual = buf_priv->virtual;
L
Linus Torvalds 已提交
202 203 204 205

	return retcode;
}

D
Dave Airlie 已提交
206
static int i810_dma_cleanup(drm_device_t * dev)
L
Linus Torvalds 已提交
207 208 209 210 211 212 213 214 215 216 217 218
{
	drm_device_dma_t *dma = dev->dma;

	/* Make sure interrupts are disabled here because the uninstall ioctl
	 * may not have been called from userspace and after dev_private
	 * is freed, it's too late.
	 */
	if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ) && dev->irq_enabled)
		drm_irq_uninstall(dev);

	if (dev->dev_private) {
		int i;
D
Dave Airlie 已提交
219 220
		drm_i810_private_t *dev_priv =
		    (drm_i810_private_t *) dev->dev_private;
L
Linus Torvalds 已提交
221 222

		if (dev_priv->ring.virtual_start) {
D
Dave Airlie 已提交
223 224
			drm_ioremapfree((void *)dev_priv->ring.virtual_start,
					dev_priv->ring.Size, dev);
L
Linus Torvalds 已提交
225
		}
D
Dave Airlie 已提交
226 227
		if (dev_priv->hw_status_page) {
			pci_free_consistent(dev->pdev, PAGE_SIZE,
L
Linus Torvalds 已提交
228 229
					    dev_priv->hw_status_page,
					    dev_priv->dma_status_page);
D
Dave Airlie 已提交
230 231
			/* Need to rewrite hardware status page */
			I810_WRITE(0x02080, 0x1ffff000);
L
Linus Torvalds 已提交
232
		}
D
Dave Airlie 已提交
233
		drm_free(dev->dev_private, sizeof(drm_i810_private_t),
L
Linus Torvalds 已提交
234
			 DRM_MEM_DRIVER);
D
Dave Airlie 已提交
235
		dev->dev_private = NULL;
L
Linus Torvalds 已提交
236 237

		for (i = 0; i < dma->buf_count; i++) {
D
Dave Airlie 已提交
238
			drm_buf_t *buf = dma->buflist[i];
L
Linus Torvalds 已提交
239
			drm_i810_buf_priv_t *buf_priv = buf->dev_private;
D
Dave Airlie 已提交
240 241 242
			if (buf_priv->kernel_virtual && buf->total)
				drm_ioremapfree(buf_priv->kernel_virtual,
						buf->total, dev);
L
Linus Torvalds 已提交
243 244
		}
	}
D
Dave Airlie 已提交
245
	return 0;
L
Linus Torvalds 已提交
246 247
}

D
Dave Airlie 已提交
248
static int i810_wait_ring(drm_device_t * dev, int n)
L
Linus Torvalds 已提交
249
{
D
Dave Airlie 已提交
250 251 252 253
	drm_i810_private_t *dev_priv = dev->dev_private;
	drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
	int iters = 0;
	unsigned long end;
L
Linus Torvalds 已提交
254 255
	unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;

D
Dave Airlie 已提交
256 257 258 259 260 261 262
	end = jiffies + (HZ * 3);
	while (ring->space < n) {
		ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
		ring->space = ring->head - (ring->tail + 8);
		if (ring->space < 0)
			ring->space += ring->Size;

L
Linus Torvalds 已提交
263
		if (ring->head != last_head) {
D
Dave Airlie 已提交
264
			end = jiffies + (HZ * 3);
L
Linus Torvalds 已提交
265 266
			last_head = ring->head;
		}
D
Dave Airlie 已提交
267 268

		iters++;
L
Linus Torvalds 已提交
269
		if (time_before(end, jiffies)) {
D
Dave Airlie 已提交
270 271 272
			DRM_ERROR("space: %d wanted %d\n", ring->space, n);
			DRM_ERROR("lockup\n");
			goto out_wait_ring;
L
Linus Torvalds 已提交
273 274 275 276
		}
		udelay(1);
	}

D
Dave Airlie 已提交
277 278
      out_wait_ring:
	return iters;
L
Linus Torvalds 已提交
279 280
}

D
Dave Airlie 已提交
281
static void i810_kernel_lost_context(drm_device_t * dev)
L
Linus Torvalds 已提交
282
{
D
Dave Airlie 已提交
283 284
	drm_i810_private_t *dev_priv = dev->dev_private;
	drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
L
Linus Torvalds 已提交
285

D
Dave Airlie 已提交
286 287 288 289 290
	ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
	ring->tail = I810_READ(LP_RING + RING_TAIL);
	ring->space = ring->head - (ring->tail + 8);
	if (ring->space < 0)
		ring->space += ring->Size;
L
Linus Torvalds 已提交
291 292
}

D
Dave Airlie 已提交
293
static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv)
L
Linus Torvalds 已提交
294
{
D
Dave Airlie 已提交
295 296 297 298
	drm_device_dma_t *dma = dev->dma;
	int my_idx = 24;
	u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx);
	int i;
L
Linus Torvalds 已提交
299 300

	if (dma->buf_count > 1019) {
D
Dave Airlie 已提交
301 302
		/* Not enough space in the status page for the freelist */
		return -EINVAL;
L
Linus Torvalds 已提交
303 304
	}

D
Dave Airlie 已提交
305 306 307
	for (i = 0; i < dma->buf_count; i++) {
		drm_buf_t *buf = dma->buflist[i];
		drm_i810_buf_priv_t *buf_priv = buf->dev_private;
L
Linus Torvalds 已提交
308

D
Dave Airlie 已提交
309 310 311
		buf_priv->in_use = hw_status++;
		buf_priv->my_use_idx = my_idx;
		my_idx += 4;
L
Linus Torvalds 已提交
312

D
Dave Airlie 已提交
313
		*buf_priv->in_use = I810_BUF_FREE;
L
Linus Torvalds 已提交
314 315

		buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
D
Dave Airlie 已提交
316
						       buf->total, dev);
L
Linus Torvalds 已提交
317 318 319 320
	}
	return 0;
}

D
Dave Airlie 已提交
321 322 323
static int i810_dma_initialize(drm_device_t * dev,
			       drm_i810_private_t * dev_priv,
			       drm_i810_init_t * init)
L
Linus Torvalds 已提交
324 325 326
{
	struct list_head *list;

D
Dave Airlie 已提交
327
	memset(dev_priv, 0, sizeof(drm_i810_private_t));
L
Linus Torvalds 已提交
328 329 330 331 332

	list_for_each(list, &dev->maplist->head) {
		drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
		if (r_list->map &&
		    r_list->map->type == _DRM_SHM &&
D
Dave Airlie 已提交
333
		    r_list->map->flags & _DRM_CONTAINS_LOCK) {
L
Linus Torvalds 已提交
334
			dev_priv->sarea_map = r_list->map;
D
Dave Airlie 已提交
335 336 337
			break;
		}
	}
L
Linus Torvalds 已提交
338 339
	if (!dev_priv->sarea_map) {
		dev->dev_private = (void *)dev_priv;
D
Dave Airlie 已提交
340 341 342
		i810_dma_cleanup(dev);
		DRM_ERROR("can not find sarea!\n");
		return -EINVAL;
L
Linus Torvalds 已提交
343 344 345 346
	}
	dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
	if (!dev_priv->mmio_map) {
		dev->dev_private = (void *)dev_priv;
D
Dave Airlie 已提交
347 348 349
		i810_dma_cleanup(dev);
		DRM_ERROR("can not find mmio map!\n");
		return -EINVAL;
L
Linus Torvalds 已提交
350
	}
351
	dev->agp_buffer_token = init->buffers_offset;
L
Linus Torvalds 已提交
352 353 354
	dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
	if (!dev->agp_buffer_map) {
		dev->dev_private = (void *)dev_priv;
D
Dave Airlie 已提交
355 356 357
		i810_dma_cleanup(dev);
		DRM_ERROR("can not find dma buffer map!\n");
		return -EINVAL;
L
Linus Torvalds 已提交
358 359 360
	}

	dev_priv->sarea_priv = (drm_i810_sarea_t *)
D
Dave Airlie 已提交
361
	    ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset);
L
Linus Torvalds 已提交
362

D
Dave Airlie 已提交
363 364 365
	dev_priv->ring.Start = init->ring_start;
	dev_priv->ring.End = init->ring_end;
	dev_priv->ring.Size = init->ring_size;
L
Linus Torvalds 已提交
366

D
Dave Airlie 已提交
367 368 369
	dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
						   init->ring_start,
						   init->ring_size, dev);
L
Linus Torvalds 已提交
370

D
Dave Airlie 已提交
371 372 373 374
	if (dev_priv->ring.virtual_start == NULL) {
		dev->dev_private = (void *)dev_priv;
		i810_dma_cleanup(dev);
		DRM_ERROR("can not ioremap virtual address for"
L
Linus Torvalds 已提交
375
			  " ring buffer\n");
D
Dave Airlie 已提交
376
		return -ENOMEM;
L
Linus Torvalds 已提交
377 378
	}

D
Dave Airlie 已提交
379
	dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
L
Linus Torvalds 已提交
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394

	dev_priv->w = init->w;
	dev_priv->h = init->h;
	dev_priv->pitch = init->pitch;
	dev_priv->back_offset = init->back_offset;
	dev_priv->depth_offset = init->depth_offset;
	dev_priv->front_offset = init->front_offset;

	dev_priv->overlay_offset = init->overlay_offset;
	dev_priv->overlay_physical = init->overlay_physical;

	dev_priv->front_di1 = init->front_offset | init->pitch_bits;
	dev_priv->back_di1 = init->back_offset | init->pitch_bits;
	dev_priv->zi1 = init->depth_offset | init->pitch_bits;

D
Dave Airlie 已提交
395 396 397 398 399
	/* Program Hardware Status Page */
	dev_priv->hw_status_page =
	    pci_alloc_consistent(dev->pdev, PAGE_SIZE,
				 &dev_priv->dma_status_page);
	if (!dev_priv->hw_status_page) {
L
Linus Torvalds 已提交
400 401 402 403 404
		dev->dev_private = (void *)dev_priv;
		i810_dma_cleanup(dev);
		DRM_ERROR("Can not allocate hardware status page\n");
		return -ENOMEM;
	}
D
Dave Airlie 已提交
405 406
	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
	DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
L
Linus Torvalds 已提交
407 408

	I810_WRITE(0x02080, dev_priv->dma_status_page);
D
Dave Airlie 已提交
409
	DRM_DEBUG("Enabled hardware status page\n");
L
Linus Torvalds 已提交
410

D
Dave Airlie 已提交
411
	/* Now we need to init our freelist */
L
Linus Torvalds 已提交
412 413
	if (i810_freelist_init(dev, dev_priv) != 0) {
		dev->dev_private = (void *)dev_priv;
D
Dave Airlie 已提交
414 415
		i810_dma_cleanup(dev);
		DRM_ERROR("Not enough space in the status page for"
L
Linus Torvalds 已提交
416
			  " the freelist\n");
D
Dave Airlie 已提交
417
		return -ENOMEM;
L
Linus Torvalds 已提交
418 419 420
	}
	dev->dev_private = (void *)dev_priv;

D
Dave Airlie 已提交
421
	return 0;
L
Linus Torvalds 已提交
422 423 424 425 426 427 428 429 430 431 432 433 434
}

/* i810 DRM version 1.1 used a smaller init structure with different
 * ordering of values than is currently used (drm >= 1.2). There is
 * no defined way to detect the XFree version to correct this problem,
 * however by checking using this procedure we can detect the correct
 * thing to do.
 *
 * #1 Read the Smaller init structure from user-space
 * #2 Verify the overlay_physical is a valid physical address, or NULL
 *    If it isn't then we have a v1.1 client. Fix up params.
 *    If it is, then we have a 1.2 client... get the rest of the data.
 */
D
Dave Airlie 已提交
435
static int i810_dma_init_compat(drm_i810_init_t * init, unsigned long arg)
L
Linus Torvalds 已提交
436 437 438
{

	/* Get v1.1 init data */
D
Dave Airlie 已提交
439 440
	if (copy_from_user(init, (drm_i810_pre12_init_t __user *) arg,
			   sizeof(drm_i810_pre12_init_t))) {
L
Linus Torvalds 已提交
441 442 443 444 445 446 447
		return -EFAULT;
	}

	if ((!init->overlay_physical) || (init->overlay_physical > 4096)) {

		/* This is a v1.2 client, just get the v1.2 init data */
		DRM_INFO("Using POST v1.2 init.\n");
D
Dave Airlie 已提交
448
		if (copy_from_user(init, (drm_i810_init_t __user *) arg,
L
Linus Torvalds 已提交
449 450 451 452 453 454 455
				   sizeof(drm_i810_init_t))) {
			return -EFAULT;
		}
	} else {

		/* This is a v1.1 client, fix the params */
		DRM_INFO("Using PRE v1.2 init.\n");
D
Dave Airlie 已提交
456 457 458 459 460 461
		init->pitch_bits = init->h;
		init->pitch = init->w;
		init->h = init->overlay_physical;
		init->w = init->overlay_offset;
		init->overlay_physical = 0;
		init->overlay_offset = 0;
L
Linus Torvalds 已提交
462 463 464 465 466 467
	}

	return 0;
}

static int i810_dma_init(struct inode *inode, struct file *filp,
D
Dave Airlie 已提交
468
			 unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
469
{
D
Dave Airlie 已提交
470 471 472 473 474
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
	drm_i810_private_t *dev_priv;
	drm_i810_init_t init;
	int retcode = 0;
L
Linus Torvalds 已提交
475 476

	/* Get only the init func */
D
Dave Airlie 已提交
477 478
	if (copy_from_user
	    (&init, (void __user *)arg, sizeof(drm_i810_init_func_t)))
L
Linus Torvalds 已提交
479 480
		return -EFAULT;

D
Dave Airlie 已提交
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
	switch (init.func) {
	case I810_INIT_DMA:
		/* This case is for backward compatibility. It
		 * handles XFree 4.1.0 and 4.2.0, and has to
		 * do some parameter checking as described below.
		 * It will someday go away.
		 */
		retcode = i810_dma_init_compat(&init, arg);
		if (retcode)
			return retcode;

		dev_priv = drm_alloc(sizeof(drm_i810_private_t),
				     DRM_MEM_DRIVER);
		if (dev_priv == NULL)
			return -ENOMEM;
		retcode = i810_dma_initialize(dev, dev_priv, &init);
		break;

	default:
	case I810_INIT_DMA_1_4:
		DRM_INFO("Using v1.4 init.\n");
		if (copy_from_user(&init, (drm_i810_init_t __user *) arg,
				   sizeof(drm_i810_init_t))) {
			return -EFAULT;
		}
		dev_priv = drm_alloc(sizeof(drm_i810_private_t),
				     DRM_MEM_DRIVER);
		if (dev_priv == NULL)
			return -ENOMEM;
		retcode = i810_dma_initialize(dev, dev_priv, &init);
		break;

	case I810_CLEANUP_DMA:
		DRM_INFO("DMA Cleanup\n");
		retcode = i810_dma_cleanup(dev);
		break;
L
Linus Torvalds 已提交
517 518
	}

D
Dave Airlie 已提交
519
	return retcode;
L
Linus Torvalds 已提交
520 521 522 523 524 525 526 527
}

/* Most efficient way to verify state for the i810 is as it is
 * emitted.  Non-conformant state is silently dropped.
 *
 * Use 'volatile' & local var tmp to force the emitted values to be
 * identical to the verified ones.
 */
D
Dave Airlie 已提交
528 529
static void i810EmitContextVerified(drm_device_t * dev,
				    volatile unsigned int *code)
L
Linus Torvalds 已提交
530
{
D
Dave Airlie 已提交
531
	drm_i810_private_t *dev_priv = dev->dev_private;
L
Linus Torvalds 已提交
532 533 534 535
	int i, j = 0;
	unsigned int tmp;
	RING_LOCALS;

D
Dave Airlie 已提交
536
	BEGIN_LP_RING(I810_CTX_SETUP_SIZE);
L
Linus Torvalds 已提交
537

D
Dave Airlie 已提交
538 539
	OUT_RING(GFX_OP_COLOR_FACTOR);
	OUT_RING(code[I810_CTXREG_CF1]);
L
Linus Torvalds 已提交
540

D
Dave Airlie 已提交
541 542
	OUT_RING(GFX_OP_STIPPLE);
	OUT_RING(code[I810_CTXREG_ST1]);
L
Linus Torvalds 已提交
543

D
Dave Airlie 已提交
544
	for (i = 4; i < I810_CTX_SETUP_SIZE; i++) {
L
Linus Torvalds 已提交
545 546
		tmp = code[i];

D
Dave Airlie 已提交
547 548 549
		if ((tmp & (7 << 29)) == (3 << 29) &&
		    (tmp & (0x1f << 24)) < (0x1d << 24)) {
			OUT_RING(tmp);
L
Linus Torvalds 已提交
550
			j++;
D
Dave Airlie 已提交
551 552
		} else
			printk("constext state dropped!!!\n");
L
Linus Torvalds 已提交
553 554 555
	}

	if (j & 1)
D
Dave Airlie 已提交
556
		OUT_RING(0);
L
Linus Torvalds 已提交
557 558 559 560

	ADVANCE_LP_RING();
}

D
Dave Airlie 已提交
561
static void i810EmitTexVerified(drm_device_t * dev, volatile unsigned int *code)
L
Linus Torvalds 已提交
562
{
D
Dave Airlie 已提交
563
	drm_i810_private_t *dev_priv = dev->dev_private;
L
Linus Torvalds 已提交
564 565 566 567
	int i, j = 0;
	unsigned int tmp;
	RING_LOCALS;

D
Dave Airlie 已提交
568
	BEGIN_LP_RING(I810_TEX_SETUP_SIZE);
L
Linus Torvalds 已提交
569

D
Dave Airlie 已提交
570 571 572 573
	OUT_RING(GFX_OP_MAP_INFO);
	OUT_RING(code[I810_TEXREG_MI1]);
	OUT_RING(code[I810_TEXREG_MI2]);
	OUT_RING(code[I810_TEXREG_MI3]);
L
Linus Torvalds 已提交
574

D
Dave Airlie 已提交
575
	for (i = 4; i < I810_TEX_SETUP_SIZE; i++) {
L
Linus Torvalds 已提交
576 577
		tmp = code[i];

D
Dave Airlie 已提交
578 579 580
		if ((tmp & (7 << 29)) == (3 << 29) &&
		    (tmp & (0x1f << 24)) < (0x1d << 24)) {
			OUT_RING(tmp);
L
Linus Torvalds 已提交
581
			j++;
D
Dave Airlie 已提交
582 583
		} else
			printk("texture state dropped!!!\n");
L
Linus Torvalds 已提交
584 585 586
	}

	if (j & 1)
D
Dave Airlie 已提交
587
		OUT_RING(0);
L
Linus Torvalds 已提交
588 589 590 591 592 593

	ADVANCE_LP_RING();
}

/* Need to do some additional checking when setting the dest buffer.
 */
D
Dave Airlie 已提交
594 595
static void i810EmitDestVerified(drm_device_t * dev,
				 volatile unsigned int *code)
L
Linus Torvalds 已提交
596
{
D
Dave Airlie 已提交
597
	drm_i810_private_t *dev_priv = dev->dev_private;
L
Linus Torvalds 已提交
598 599 600
	unsigned int tmp;
	RING_LOCALS;

D
Dave Airlie 已提交
601
	BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2);
L
Linus Torvalds 已提交
602 603 604

	tmp = code[I810_DESTREG_DI1];
	if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
D
Dave Airlie 已提交
605 606
		OUT_RING(CMD_OP_DESTBUFFER_INFO);
		OUT_RING(tmp);
L
Linus Torvalds 已提交
607
	} else
D
Dave Airlie 已提交
608 609
		DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
			  tmp, dev_priv->front_di1, dev_priv->back_di1);
L
Linus Torvalds 已提交
610 611 612

	/* invarient:
	 */
D
Dave Airlie 已提交
613 614
	OUT_RING(CMD_OP_Z_BUFFER_INFO);
	OUT_RING(dev_priv->zi1);
L
Linus Torvalds 已提交
615

D
Dave Airlie 已提交
616 617
	OUT_RING(GFX_OP_DESTBUFFER_VARS);
	OUT_RING(code[I810_DESTREG_DV1]);
L
Linus Torvalds 已提交
618

D
Dave Airlie 已提交
619 620 621 622 623 624
	OUT_RING(GFX_OP_DRAWRECT_INFO);
	OUT_RING(code[I810_DESTREG_DR1]);
	OUT_RING(code[I810_DESTREG_DR2]);
	OUT_RING(code[I810_DESTREG_DR3]);
	OUT_RING(code[I810_DESTREG_DR4]);
	OUT_RING(0);
L
Linus Torvalds 已提交
625 626 627 628

	ADVANCE_LP_RING();
}

D
Dave Airlie 已提交
629
static void i810EmitState(drm_device_t * dev)
L
Linus Torvalds 已提交
630
{
D
Dave Airlie 已提交
631 632
	drm_i810_private_t *dev_priv = dev->dev_private;
	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
L
Linus Torvalds 已提交
633
	unsigned int dirty = sarea_priv->dirty;
D
Dave Airlie 已提交
634

L
Linus Torvalds 已提交
635 636 637
	DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);

	if (dirty & I810_UPLOAD_BUFFERS) {
D
Dave Airlie 已提交
638
		i810EmitDestVerified(dev, sarea_priv->BufferState);
L
Linus Torvalds 已提交
639 640 641 642
		sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS;
	}

	if (dirty & I810_UPLOAD_CTX) {
D
Dave Airlie 已提交
643
		i810EmitContextVerified(dev, sarea_priv->ContextState);
L
Linus Torvalds 已提交
644 645 646 647
		sarea_priv->dirty &= ~I810_UPLOAD_CTX;
	}

	if (dirty & I810_UPLOAD_TEX0) {
D
Dave Airlie 已提交
648
		i810EmitTexVerified(dev, sarea_priv->TexState[0]);
L
Linus Torvalds 已提交
649 650 651 652
		sarea_priv->dirty &= ~I810_UPLOAD_TEX0;
	}

	if (dirty & I810_UPLOAD_TEX1) {
D
Dave Airlie 已提交
653
		i810EmitTexVerified(dev, sarea_priv->TexState[1]);
L
Linus Torvalds 已提交
654 655 656 657 658 659
		sarea_priv->dirty &= ~I810_UPLOAD_TEX1;
	}
}

/* need to verify
 */
D
Dave Airlie 已提交
660 661 662
static void i810_dma_dispatch_clear(drm_device_t * dev, int flags,
				    unsigned int clear_color,
				    unsigned int clear_zval)
L
Linus Torvalds 已提交
663
{
D
Dave Airlie 已提交
664 665
	drm_i810_private_t *dev_priv = dev->dev_private;
	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
L
Linus Torvalds 已提交
666 667 668 669 670 671
	int nbox = sarea_priv->nbox;
	drm_clip_rect_t *pbox = sarea_priv->boxes;
	int pitch = dev_priv->pitch;
	int cpp = 2;
	int i;
	RING_LOCALS;
D
Dave Airlie 已提交
672 673 674 675

	if (dev_priv->current_page == 1) {
		unsigned int tmp = flags;

L
Linus Torvalds 已提交
676
		flags &= ~(I810_FRONT | I810_BACK);
D
Dave Airlie 已提交
677 678 679 680
		if (tmp & I810_FRONT)
			flags |= I810_BACK;
		if (tmp & I810_BACK)
			flags |= I810_FRONT;
L
Linus Torvalds 已提交
681 682
	}

D
Dave Airlie 已提交
683
	i810_kernel_lost_context(dev);
L
Linus Torvalds 已提交
684

D
Dave Airlie 已提交
685 686
	if (nbox > I810_NR_SAREA_CLIPRECTS)
		nbox = I810_NR_SAREA_CLIPRECTS;
L
Linus Torvalds 已提交
687

D
Dave Airlie 已提交
688
	for (i = 0; i < nbox; i++, pbox++) {
L
Linus Torvalds 已提交
689 690 691 692 693 694 695 696
		unsigned int x = pbox->x1;
		unsigned int y = pbox->y1;
		unsigned int width = (pbox->x2 - x) * cpp;
		unsigned int height = pbox->y2 - y;
		unsigned int start = y * pitch + x * cpp;

		if (pbox->x1 > pbox->x2 ||
		    pbox->y1 > pbox->y2 ||
D
Dave Airlie 已提交
697
		    pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
L
Linus Torvalds 已提交
698 699
			continue;

D
Dave Airlie 已提交
700 701 702 703 704 705 706 707
		if (flags & I810_FRONT) {
			BEGIN_LP_RING(6);
			OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
			OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
			OUT_RING((height << 16) | width);
			OUT_RING(start);
			OUT_RING(clear_color);
			OUT_RING(0);
L
Linus Torvalds 已提交
708 709 710
			ADVANCE_LP_RING();
		}

D
Dave Airlie 已提交
711 712 713 714 715 716 717 718
		if (flags & I810_BACK) {
			BEGIN_LP_RING(6);
			OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
			OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
			OUT_RING((height << 16) | width);
			OUT_RING(dev_priv->back_offset + start);
			OUT_RING(clear_color);
			OUT_RING(0);
L
Linus Torvalds 已提交
719 720 721
			ADVANCE_LP_RING();
		}

D
Dave Airlie 已提交
722 723 724 725 726 727 728 729
		if (flags & I810_DEPTH) {
			BEGIN_LP_RING(6);
			OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
			OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
			OUT_RING((height << 16) | width);
			OUT_RING(dev_priv->depth_offset + start);
			OUT_RING(clear_zval);
			OUT_RING(0);
L
Linus Torvalds 已提交
730 731 732 733 734
			ADVANCE_LP_RING();
		}
	}
}

D
Dave Airlie 已提交
735
static void i810_dma_dispatch_swap(drm_device_t * dev)
L
Linus Torvalds 已提交
736
{
D
Dave Airlie 已提交
737 738
	drm_i810_private_t *dev_priv = dev->dev_private;
	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
L
Linus Torvalds 已提交
739 740 741 742 743 744 745 746 747
	int nbox = sarea_priv->nbox;
	drm_clip_rect_t *pbox = sarea_priv->boxes;
	int pitch = dev_priv->pitch;
	int cpp = 2;
	int i;
	RING_LOCALS;

	DRM_DEBUG("swapbuffers\n");

D
Dave Airlie 已提交
748
	i810_kernel_lost_context(dev);
L
Linus Torvalds 已提交
749

D
Dave Airlie 已提交
750 751
	if (nbox > I810_NR_SAREA_CLIPRECTS)
		nbox = I810_NR_SAREA_CLIPRECTS;
L
Linus Torvalds 已提交
752

D
Dave Airlie 已提交
753
	for (i = 0; i < nbox; i++, pbox++) {
L
Linus Torvalds 已提交
754 755
		unsigned int w = pbox->x2 - pbox->x1;
		unsigned int h = pbox->y2 - pbox->y1;
D
Dave Airlie 已提交
756
		unsigned int dst = pbox->x1 * cpp + pbox->y1 * pitch;
L
Linus Torvalds 已提交
757 758 759 760
		unsigned int start = dst;

		if (pbox->x1 > pbox->x2 ||
		    pbox->y1 > pbox->y2 ||
D
Dave Airlie 已提交
761
		    pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
L
Linus Torvalds 已提交
762 763
			continue;

D
Dave Airlie 已提交
764 765 766 767
		BEGIN_LP_RING(6);
		OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4);
		OUT_RING(pitch | (0xCC << 16));
		OUT_RING((h << 16) | (w * cpp));
L
Linus Torvalds 已提交
768
		if (dev_priv->current_page == 0)
D
Dave Airlie 已提交
769
			OUT_RING(dev_priv->front_offset + start);
L
Linus Torvalds 已提交
770
		else
D
Dave Airlie 已提交
771 772
			OUT_RING(dev_priv->back_offset + start);
		OUT_RING(pitch);
L
Linus Torvalds 已提交
773
		if (dev_priv->current_page == 0)
D
Dave Airlie 已提交
774
			OUT_RING(dev_priv->back_offset + start);
L
Linus Torvalds 已提交
775
		else
D
Dave Airlie 已提交
776
			OUT_RING(dev_priv->front_offset + start);
L
Linus Torvalds 已提交
777 778 779 780
		ADVANCE_LP_RING();
	}
}

D
Dave Airlie 已提交
781 782
static void i810_dma_dispatch_vertex(drm_device_t * dev,
				     drm_buf_t * buf, int discard, int used)
L
Linus Torvalds 已提交
783
{
D
Dave Airlie 已提交
784
	drm_i810_private_t *dev_priv = dev->dev_private;
L
Linus Torvalds 已提交
785
	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
D
Dave Airlie 已提交
786 787 788
	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
	drm_clip_rect_t *box = sarea_priv->boxes;
	int nbox = sarea_priv->nbox;
L
Linus Torvalds 已提交
789 790 791
	unsigned long address = (unsigned long)buf->bus_address;
	unsigned long start = address - dev->agp->base;
	int i = 0;
D
Dave Airlie 已提交
792
	RING_LOCALS;
L
Linus Torvalds 已提交
793

D
Dave Airlie 已提交
794
	i810_kernel_lost_context(dev);
L
Linus Torvalds 已提交
795

D
Dave Airlie 已提交
796
	if (nbox > I810_NR_SAREA_CLIPRECTS)
L
Linus Torvalds 已提交
797 798
		nbox = I810_NR_SAREA_CLIPRECTS;

D
Dave Airlie 已提交
799
	if (used > 4 * 1024)
L
Linus Torvalds 已提交
800 801 802
		used = 0;

	if (sarea_priv->dirty)
D
Dave Airlie 已提交
803
		i810EmitState(dev);
L
Linus Torvalds 已提交
804 805 806 807

	if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
		unsigned int prim = (sarea_priv->vertex_prim & PR_MASK);

D
Dave Airlie 已提交
808 809
		*(u32 *) buf_priv->kernel_virtual =
		    ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2)));
L
Linus Torvalds 已提交
810 811

		if (used & 4) {
D
Dave Airlie 已提交
812
			*(u32 *) ((u32) buf_priv->kernel_virtual + used) = 0;
L
Linus Torvalds 已提交
813 814 815 816 817 818 819 820 821 822
			used += 4;
		}

		i810_unmap_buffer(buf);
	}

	if (used) {
		do {
			if (i < nbox) {
				BEGIN_LP_RING(4);
D
Dave Airlie 已提交
823 824 825 826 827 828
				OUT_RING(GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
					 SC_ENABLE);
				OUT_RING(GFX_OP_SCISSOR_INFO);
				OUT_RING(box[i].x1 | (box[i].y1 << 16));
				OUT_RING((box[i].x2 -
					  1) | ((box[i].y2 - 1) << 16));
L
Linus Torvalds 已提交
829 830 831 832
				ADVANCE_LP_RING();
			}

			BEGIN_LP_RING(4);
D
Dave Airlie 已提交
833 834 835 836
			OUT_RING(CMD_OP_BATCH_BUFFER);
			OUT_RING(start | BB1_PROTECTED);
			OUT_RING(start + used - 4);
			OUT_RING(0);
L
Linus Torvalds 已提交
837 838 839 840 841 842 843 844
			ADVANCE_LP_RING();

		} while (++i < nbox);
	}

	if (discard) {
		dev_priv->counter++;

D
Dave Airlie 已提交
845 846
		(void)cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
			      I810_BUF_HARDWARE);
L
Linus Torvalds 已提交
847 848

		BEGIN_LP_RING(8);
D
Dave Airlie 已提交
849 850 851 852 853 854 855 856
		OUT_RING(CMD_STORE_DWORD_IDX);
		OUT_RING(20);
		OUT_RING(dev_priv->counter);
		OUT_RING(CMD_STORE_DWORD_IDX);
		OUT_RING(buf_priv->my_use_idx);
		OUT_RING(I810_BUF_FREE);
		OUT_RING(CMD_REPORT_HEAD);
		OUT_RING(0);
L
Linus Torvalds 已提交
857 858 859 860
		ADVANCE_LP_RING();
	}
}

D
Dave Airlie 已提交
861
static void i810_dma_dispatch_flip(drm_device_t * dev)
L
Linus Torvalds 已提交
862
{
D
Dave Airlie 已提交
863
	drm_i810_private_t *dev_priv = dev->dev_private;
L
Linus Torvalds 已提交
864 865 866
	int pitch = dev_priv->pitch;
	RING_LOCALS;

D
Dave Airlie 已提交
867 868 869 870 871 872
	DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
		  __FUNCTION__,
		  dev_priv->current_page,
		  dev_priv->sarea_priv->pf_current_page);

	i810_kernel_lost_context(dev);
L
Linus Torvalds 已提交
873

D
Dave Airlie 已提交
874 875 876
	BEGIN_LP_RING(2);
	OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
	OUT_RING(0);
L
Linus Torvalds 已提交
877 878
	ADVANCE_LP_RING();

D
Dave Airlie 已提交
879
	BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2);
L
Linus Torvalds 已提交
880 881 882 883
	/* On i815 at least ASYNC is buggy */
	/* pitch<<5 is from 11.2.8 p158,
	   its the pitch / 8 then left shifted 8,
	   so (pitch >> 3) << 8 */
D
Dave Airlie 已提交
884 885 886
	OUT_RING(CMD_OP_FRONTBUFFER_INFO | (pitch << 5) /*| ASYNC_FLIP */ );
	if (dev_priv->current_page == 0) {
		OUT_RING(dev_priv->back_offset);
L
Linus Torvalds 已提交
887 888
		dev_priv->current_page = 1;
	} else {
D
Dave Airlie 已提交
889
		OUT_RING(dev_priv->front_offset);
L
Linus Torvalds 已提交
890 891 892 893 894 895
		dev_priv->current_page = 0;
	}
	OUT_RING(0);
	ADVANCE_LP_RING();

	BEGIN_LP_RING(2);
D
Dave Airlie 已提交
896 897
	OUT_RING(CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP);
	OUT_RING(0);
L
Linus Torvalds 已提交
898 899 900 901 902 903 904 905 906 907
	ADVANCE_LP_RING();

	/* Increment the frame counter.  The client-side 3D driver must
	 * throttle the framerate by waiting for this value before
	 * performing the swapbuffer ioctl.
	 */
	dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;

}

D
Dave Airlie 已提交
908
static void i810_dma_quiescent(drm_device_t * dev)
L
Linus Torvalds 已提交
909
{
D
Dave Airlie 已提交
910 911
	drm_i810_private_t *dev_priv = dev->dev_private;
	RING_LOCALS;
L
Linus Torvalds 已提交
912 913 914

/*  	printk("%s\n", __FUNCTION__); */

D
Dave Airlie 已提交
915
	i810_kernel_lost_context(dev);
L
Linus Torvalds 已提交
916

D
Dave Airlie 已提交
917 918 919 920 921 922
	BEGIN_LP_RING(4);
	OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
	OUT_RING(CMD_REPORT_HEAD);
	OUT_RING(0);
	OUT_RING(0);
	ADVANCE_LP_RING();
L
Linus Torvalds 已提交
923

D
Dave Airlie 已提交
924
	i810_wait_ring(dev, dev_priv->ring.Size - 8);
L
Linus Torvalds 已提交
925 926
}

D
Dave Airlie 已提交
927
static int i810_flush_queue(drm_device_t * dev)
L
Linus Torvalds 已提交
928
{
D
Dave Airlie 已提交
929
	drm_i810_private_t *dev_priv = dev->dev_private;
L
Linus Torvalds 已提交
930
	drm_device_dma_t *dma = dev->dma;
D
Dave Airlie 已提交
931 932 933
	int i, ret = 0;
	RING_LOCALS;

L
Linus Torvalds 已提交
934 935
/*  	printk("%s\n", __FUNCTION__); */

D
Dave Airlie 已提交
936
	i810_kernel_lost_context(dev);
L
Linus Torvalds 已提交
937

D
Dave Airlie 已提交
938 939 940 941
	BEGIN_LP_RING(2);
	OUT_RING(CMD_REPORT_HEAD);
	OUT_RING(0);
	ADVANCE_LP_RING();
L
Linus Torvalds 已提交
942

D
Dave Airlie 已提交
943
	i810_wait_ring(dev, dev_priv->ring.Size - 8);
L
Linus Torvalds 已提交
944

D
Dave Airlie 已提交
945 946 947
	for (i = 0; i < dma->buf_count; i++) {
		drm_buf_t *buf = dma->buflist[i];
		drm_i810_buf_priv_t *buf_priv = buf->dev_private;
L
Linus Torvalds 已提交
948 949 950 951 952 953 954 955 956 957

		int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE,
				   I810_BUF_FREE);

		if (used == I810_BUF_HARDWARE)
			DRM_DEBUG("reclaimed from HARDWARE\n");
		if (used == I810_BUF_CLIENT)
			DRM_DEBUG("still on client\n");
	}

D
Dave Airlie 已提交
958
	return ret;
L
Linus Torvalds 已提交
959 960 961
}

/* Must be called with the lock held */
D
Dave Airlie 已提交
962
void i810_reclaim_buffers(drm_device_t * dev, struct file *filp)
L
Linus Torvalds 已提交
963 964
{
	drm_device_dma_t *dma = dev->dma;
D
Dave Airlie 已提交
965
	int i;
L
Linus Torvalds 已提交
966

D
Dave Airlie 已提交
967 968 969 970 971 972
	if (!dma)
		return;
	if (!dev->dev_private)
		return;
	if (!dma->buflist)
		return;
L
Linus Torvalds 已提交
973

D
Dave Airlie 已提交
974
	i810_flush_queue(dev);
L
Linus Torvalds 已提交
975 976

	for (i = 0; i < dma->buf_count; i++) {
D
Dave Airlie 已提交
977 978
		drm_buf_t *buf = dma->buflist[i];
		drm_i810_buf_priv_t *buf_priv = buf->dev_private;
L
Linus Torvalds 已提交
979 980 981 982 983 984 985 986

		if (buf->filp == filp && buf_priv) {
			int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
					   I810_BUF_FREE);

			if (used == I810_BUF_CLIENT)
				DRM_DEBUG("reclaimed from client\n");
			if (buf_priv->currently_mapped == I810_BUF_MAPPED)
D
Dave Airlie 已提交
987
				buf_priv->currently_mapped = I810_BUF_UNMAPPED;
L
Linus Torvalds 已提交
988 989 990 991
		}
	}
}

D
Dave Airlie 已提交
992 993
static int i810_flush_ioctl(struct inode *inode, struct file *filp,
			    unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
994
{
D
Dave Airlie 已提交
995 996
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
L
Linus Torvalds 已提交
997 998 999

	LOCK_TEST_WITH_RETURN(dev, filp);

D
Dave Airlie 已提交
1000 1001
	i810_flush_queue(dev);
	return 0;
L
Linus Torvalds 已提交
1002 1003 1004
}

static int i810_dma_vertex(struct inode *inode, struct file *filp,
D
Dave Airlie 已提交
1005
			   unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
1006 1007 1008 1009
{
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
	drm_device_dma_t *dma = dev->dma;
D
Dave Airlie 已提交
1010 1011 1012 1013
	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
	u32 *hw_status = dev_priv->hw_status_page;
	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
	    dev_priv->sarea_priv;
L
Linus Torvalds 已提交
1014 1015
	drm_i810_vertex_t vertex;

D
Dave Airlie 已提交
1016 1017
	if (copy_from_user
	    (&vertex, (drm_i810_vertex_t __user *) arg, sizeof(vertex)))
L
Linus Torvalds 已提交
1018 1019 1020 1021 1022 1023 1024
		return -EFAULT;

	LOCK_TEST_WITH_RETURN(dev, filp);

	DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
		  vertex.idx, vertex.used, vertex.discard);

D
Dave Airlie 已提交
1025
	if (vertex.idx < 0 || vertex.idx > dma->buf_count)
L
Linus Torvalds 已提交
1026 1027
		return -EINVAL;

D
Dave Airlie 已提交
1028 1029 1030
	i810_dma_dispatch_vertex(dev,
				 dma->buflist[vertex.idx],
				 vertex.discard, vertex.used);
L
Linus Torvalds 已提交
1031

D
Dave Airlie 已提交
1032
	atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]);
L
Linus Torvalds 已提交
1033
	atomic_inc(&dev->counts[_DRM_STAT_DMA]);
D
Dave Airlie 已提交
1034 1035
	sarea_priv->last_enqueue = dev_priv->counter - 1;
	sarea_priv->last_dispatch = (int)hw_status[5];
L
Linus Torvalds 已提交
1036 1037 1038 1039 1040

	return 0;
}

static int i810_clear_bufs(struct inode *inode, struct file *filp,
D
Dave Airlie 已提交
1041
			   unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
1042 1043 1044 1045 1046
{
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
	drm_i810_clear_t clear;

D
Dave Airlie 已提交
1047 1048
	if (copy_from_user
	    (&clear, (drm_i810_clear_t __user *) arg, sizeof(clear)))
L
Linus Torvalds 已提交
1049 1050 1051 1052
		return -EFAULT;

	LOCK_TEST_WITH_RETURN(dev, filp);

D
Dave Airlie 已提交
1053 1054 1055 1056
	/* GH: Someone's doing nasty things... */
	if (!dev->dev_private) {
		return -EINVAL;
	}
L
Linus Torvalds 已提交
1057

D
Dave Airlie 已提交
1058 1059 1060
	i810_dma_dispatch_clear(dev, clear.flags,
				clear.clear_color, clear.clear_depth);
	return 0;
L
Linus Torvalds 已提交
1061 1062 1063
}

static int i810_swap_bufs(struct inode *inode, struct file *filp,
D
Dave Airlie 已提交
1064
			  unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
1065 1066 1067 1068 1069 1070 1071 1072
{
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;

	DRM_DEBUG("i810_swap_bufs\n");

	LOCK_TEST_WITH_RETURN(dev, filp);

D
Dave Airlie 已提交
1073 1074
	i810_dma_dispatch_swap(dev);
	return 0;
L
Linus Torvalds 已提交
1075 1076 1077
}

static int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
D
Dave Airlie 已提交
1078
		       unsigned long arg)
L
Linus Torvalds 已提交
1079
{
D
Dave Airlie 已提交
1080 1081 1082 1083 1084 1085 1086 1087
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
	u32 *hw_status = dev_priv->hw_status_page;
	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
	    dev_priv->sarea_priv;

	sarea_priv->last_dispatch = (int)hw_status[5];
L
Linus Torvalds 已提交
1088 1089 1090 1091
	return 0;
}

static int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
D
Dave Airlie 已提交
1092
		       unsigned long arg)
L
Linus Torvalds 已提交
1093
{
D
Dave Airlie 已提交
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
	int retcode = 0;
	drm_i810_dma_t d;
	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
	u32 *hw_status = dev_priv->hw_status_page;
	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
	    dev_priv->sarea_priv;

	if (copy_from_user(&d, (drm_i810_dma_t __user *) arg, sizeof(d)))
L
Linus Torvalds 已提交
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
		return -EFAULT;

	LOCK_TEST_WITH_RETURN(dev, filp);

	d.granted = 0;

	retcode = i810_dma_get_buffer(dev, &d, filp);

	DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
		  current->pid, retcode, d.granted);

D
Dave Airlie 已提交
1115
	if (copy_to_user((drm_dma_t __user *) arg, &d, sizeof(d)))
L
Linus Torvalds 已提交
1116
		return -EFAULT;
D
Dave Airlie 已提交
1117
	sarea_priv->last_dispatch = (int)hw_status[5];
L
Linus Torvalds 已提交
1118 1119 1120 1121 1122

	return retcode;
}

static int i810_copybuf(struct inode *inode,
D
Dave Airlie 已提交
1123
			struct file *filp, unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
1124 1125 1126 1127 1128 1129
{
	/* Never copy - 2.4.x doesn't need it */
	return 0;
}

static int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
D
Dave Airlie 已提交
1130
		       unsigned long arg)
L
Linus Torvalds 已提交
1131 1132 1133 1134 1135
{
	/* Never copy - 2.4.x doesn't need it */
	return 0;
}

D
Dave Airlie 已提交
1136 1137
static void i810_dma_dispatch_mc(drm_device_t * dev, drm_buf_t * buf, int used,
				 unsigned int last_render)
L
Linus Torvalds 已提交
1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
{
	drm_i810_private_t *dev_priv = dev->dev_private;
	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
	unsigned long address = (unsigned long)buf->bus_address;
	unsigned long start = address - dev->agp->base;
	int u;
	RING_LOCALS;

	i810_kernel_lost_context(dev);

D
Dave Airlie 已提交
1149
	u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE);
L
Linus Torvalds 已提交
1150 1151 1152 1153
	if (u != I810_BUF_CLIENT) {
		DRM_DEBUG("MC found buffer that isn't mine!\n");
	}

D
Dave Airlie 已提交
1154
	if (used > 4 * 1024)
L
Linus Torvalds 已提交
1155 1156 1157 1158
		used = 0;

	sarea_priv->dirty = 0x7f;

D
Dave Airlie 已提交
1159
	DRM_DEBUG("dispatch mc addr 0x%lx, used 0x%x\n", address, used);
L
Linus Torvalds 已提交
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169

	dev_priv->counter++;
	DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter);
	DRM_DEBUG("i810_dma_dispatch_mc\n");
	DRM_DEBUG("start : %lx\n", start);
	DRM_DEBUG("used : %d\n", used);
	DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4);

	if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
		if (used & 4) {
D
Dave Airlie 已提交
1170
			*(u32 *) ((u32) buf_priv->virtual + used) = 0;
L
Linus Torvalds 已提交
1171 1172 1173 1174 1175 1176
			used += 4;
		}

		i810_unmap_buffer(buf);
	}
	BEGIN_LP_RING(4);
D
Dave Airlie 已提交
1177 1178 1179 1180
	OUT_RING(CMD_OP_BATCH_BUFFER);
	OUT_RING(start | BB1_PROTECTED);
	OUT_RING(start + used - 4);
	OUT_RING(0);
L
Linus Torvalds 已提交
1181 1182 1183
	ADVANCE_LP_RING();

	BEGIN_LP_RING(8);
D
Dave Airlie 已提交
1184 1185 1186 1187 1188 1189 1190 1191 1192
	OUT_RING(CMD_STORE_DWORD_IDX);
	OUT_RING(buf_priv->my_use_idx);
	OUT_RING(I810_BUF_FREE);
	OUT_RING(0);

	OUT_RING(CMD_STORE_DWORD_IDX);
	OUT_RING(16);
	OUT_RING(last_render);
	OUT_RING(0);
L
Linus Torvalds 已提交
1193 1194 1195 1196
	ADVANCE_LP_RING();
}

static int i810_dma_mc(struct inode *inode, struct file *filp,
D
Dave Airlie 已提交
1197
		       unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
1198 1199 1200 1201
{
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
	drm_device_dma_t *dma = dev->dma;
D
Dave Airlie 已提交
1202
	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
L
Linus Torvalds 已提交
1203 1204
	u32 *hw_status = dev_priv->hw_status_page;
	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
D
Dave Airlie 已提交
1205
	    dev_priv->sarea_priv;
L
Linus Torvalds 已提交
1206 1207
	drm_i810_mc_t mc;

D
Dave Airlie 已提交
1208
	if (copy_from_user(&mc, (drm_i810_mc_t __user *) arg, sizeof(mc)))
L
Linus Torvalds 已提交
1209 1210 1211 1212 1213 1214 1215 1216
		return -EFAULT;

	LOCK_TEST_WITH_RETURN(dev, filp);

	if (mc.idx >= dma->buf_count || mc.idx < 0)
		return -EINVAL;

	i810_dma_dispatch_mc(dev, dma->buflist[mc.idx], mc.used,
D
Dave Airlie 已提交
1217
			     mc.last_render);
L
Linus Torvalds 已提交
1218 1219 1220

	atomic_add(mc.used, &dev->counts[_DRM_STAT_SECONDARY]);
	atomic_inc(&dev->counts[_DRM_STAT_DMA]);
D
Dave Airlie 已提交
1221 1222
	sarea_priv->last_enqueue = dev_priv->counter - 1;
	sarea_priv->last_dispatch = (int)hw_status[5];
L
Linus Torvalds 已提交
1223 1224 1225 1226 1227 1228 1229 1230 1231

	return 0;
}

static int i810_rstatus(struct inode *inode, struct file *filp,
			unsigned int cmd, unsigned long arg)
{
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
D
Dave Airlie 已提交
1232
	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
L
Linus Torvalds 已提交
1233

D
Dave Airlie 已提交
1234
	return (int)(((u32 *) (dev_priv->hw_status_page))[4]);
L
Linus Torvalds 已提交
1235 1236 1237
}

static int i810_ov0_info(struct inode *inode, struct file *filp,
D
Dave Airlie 已提交
1238
			 unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
1239 1240 1241
{
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
D
Dave Airlie 已提交
1242
	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
L
Linus Torvalds 已提交
1243 1244 1245 1246
	drm_i810_overlay_t data;

	data.offset = dev_priv->overlay_offset;
	data.physical = dev_priv->overlay_physical;
D
Dave Airlie 已提交
1247 1248
	if (copy_to_user
	    ((drm_i810_overlay_t __user *) arg, &data, sizeof(data)))
L
Linus Torvalds 已提交
1249 1250 1251 1252 1253 1254 1255 1256 1257
		return -EFAULT;
	return 0;
}

static int i810_fstatus(struct inode *inode, struct file *filp,
			unsigned int cmd, unsigned long arg)
{
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
D
Dave Airlie 已提交
1258
	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
L
Linus Torvalds 已提交
1259 1260 1261 1262 1263 1264 1265

	LOCK_TEST_WITH_RETURN(dev, filp);

	return I810_READ(0x30008);
}

static int i810_ov0_flip(struct inode *inode, struct file *filp,
D
Dave Airlie 已提交
1266
			 unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
1267 1268 1269
{
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
D
Dave Airlie 已提交
1270
	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
L
Linus Torvalds 已提交
1271 1272 1273 1274

	LOCK_TEST_WITH_RETURN(dev, filp);

	//Tell the overlay to update
D
Dave Airlie 已提交
1275
	I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000);
L
Linus Torvalds 已提交
1276 1277 1278 1279 1280

	return 0;
}

/* Not sure why this isn't set all the time:
D
Dave Airlie 已提交
1281 1282
 */
static void i810_do_init_pageflip(drm_device_t * dev)
L
Linus Torvalds 已提交
1283 1284
{
	drm_i810_private_t *dev_priv = dev->dev_private;
D
Dave Airlie 已提交
1285

L
Linus Torvalds 已提交
1286 1287 1288 1289 1290 1291
	DRM_DEBUG("%s\n", __FUNCTION__);
	dev_priv->page_flipping = 1;
	dev_priv->current_page = 0;
	dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
}

D
Dave Airlie 已提交
1292
static int i810_do_cleanup_pageflip(drm_device_t * dev)
L
Linus Torvalds 已提交
1293 1294 1295 1296 1297
{
	drm_i810_private_t *dev_priv = dev->dev_private;

	DRM_DEBUG("%s\n", __FUNCTION__);
	if (dev_priv->current_page != 0)
D
Dave Airlie 已提交
1298
		i810_dma_dispatch_flip(dev);
L
Linus Torvalds 已提交
1299 1300 1301 1302 1303 1304

	dev_priv->page_flipping = 0;
	return 0;
}

static int i810_flip_bufs(struct inode *inode, struct file *filp,
D
Dave Airlie 已提交
1305
			  unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
1306 1307 1308 1309 1310 1311 1312 1313 1314
{
	drm_file_t *priv = filp->private_data;
	drm_device_t *dev = priv->head->dev;
	drm_i810_private_t *dev_priv = dev->dev_private;

	DRM_DEBUG("%s\n", __FUNCTION__);

	LOCK_TEST_WITH_RETURN(dev, filp);

D
Dave Airlie 已提交
1315 1316
	if (!dev_priv->page_flipping)
		i810_do_init_pageflip(dev);
L
Linus Torvalds 已提交
1317

D
Dave Airlie 已提交
1318 1319
	i810_dma_dispatch_flip(dev);
	return 0;
L
Linus Torvalds 已提交
1320 1321
}

D
Dave Airlie 已提交
1322
void i810_driver_pretakedown(drm_device_t * dev)
L
Linus Torvalds 已提交
1323
{
D
Dave Airlie 已提交
1324
	i810_dma_cleanup(dev);
L
Linus Torvalds 已提交
1325 1326
}

D
Dave Airlie 已提交
1327
void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp)
L
Linus Torvalds 已提交
1328 1329 1330 1331 1332 1333 1334 1335 1336
{
	if (dev->dev_private) {
		drm_i810_private_t *dev_priv = dev->dev_private;
		if (dev_priv->page_flipping) {
			i810_do_cleanup_pageflip(dev);
		}
	}
}

D
Dave Airlie 已提交
1337
void i810_driver_release(drm_device_t * dev, struct file *filp)
L
Linus Torvalds 已提交
1338 1339 1340 1341
{
	i810_reclaim_buffers(dev, filp);
}

D
Dave Airlie 已提交
1342
int i810_driver_dma_quiescent(drm_device_t * dev)
L
Linus Torvalds 已提交
1343
{
D
Dave Airlie 已提交
1344
	i810_dma_quiescent(dev);
L
Linus Torvalds 已提交
1345 1346 1347 1348
	return 0;
}

drm_ioctl_desc_t i810_ioctls[] = {
D
Dave Airlie 已提交
1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362
	[DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, 1, 1},
	[DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, 1, 0},
	[DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, 1, 1},
	[DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, 1, 0},
D
Dave Airlie 已提交
1363
	[DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, 1, 0}
L
Linus Torvalds 已提交
1364 1365 1366
};

int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382

/**
 * Determine if the device really is AGP or not.
 *
 * All Intel graphics chipsets are treated as AGP, even if they are really
 * PCI-e.
 *
 * \param dev   The device to be tested.
 *
 * \returns
 * A value of 1 is always retured to indictate every i810 is AGP.
 */
int i810_driver_device_is_agp(drm_device_t * dev)
{
	return 1;
}