i915_dma.c revision de151cf67ce52ed2d88083daa5e60c7858947329
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
30d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie/*
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All Rights Reserved.
6bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie *
7bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * Permission is hereby granted, free of charge, to any person obtaining a
8bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * copy of this software and associated documentation files (the
9bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * "Software"), to deal in the Software without restriction, including
10bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * without limitation the rights to use, copy, modify, merge, publish,
11bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * distribute, sub license, and/or sell copies of the Software, and to
12bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * permit persons to whom the Software is furnished to do so, subject to
13bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * the following conditions:
14bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie *
15bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * The above copyright notice and this permission notice (including the
16bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * next paragraph) shall be included in all copies or substantial portions
17bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * of the Software.
18bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie *
19bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie *
270d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie */
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "drmP.h"
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "drm.h"
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "i915_drm.h"
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "i915_drv.h"
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Really want an OS-independent resettable timer.  Would like to have
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * this loop run for (eg) 3 sec, but have the timer reset every time
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the head pointer changes, so that EBUSY only happens if the ring
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * actually stalls for (eg) 3 seconds.
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3984b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_wait_ring(struct drm_device * dev, int n, const char *caller)
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
427c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
44d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard	u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
45d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard	u32 last_acthd = I915_READ(acthd_reg);
46d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard	u32 acthd;
47585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
50d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard	for (i = 0; i < 100000; i++) {
51585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes		ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
52d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard		acthd = I915_READ(acthd_reg);
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ring->space = ring->head - (ring->tail + 8);
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ring->space < 0)
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ring->space += ring->Size;
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ring->space >= n)
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
597c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		if (master_priv->sarea_priv)
607c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie			master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ring->head != last_head)
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			i = 0;
64d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard		if (acthd != last_acthd)
65d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard			i = 0;
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		last_head = ring->head;
68d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard		last_acthd = acthd;
69d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard		msleep_interruptible(10);
70d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7320caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt	return -EBUSY;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
76398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard/**
77398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * Sets up the hardware status page for devices that need a physical address
78398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * in the register.
79398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard */
803043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholtstatic int i915_init_phys_hws(struct drm_device *dev)
81398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard{
82398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	drm_i915_private_t *dev_priv = dev->dev_private;
83398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	/* Program Hardware Status Page */
84398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	dev_priv->status_page_dmah =
85398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
86398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
87398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	if (!dev_priv->status_page_dmah) {
88398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		DRM_ERROR("Can not allocate hardware status page\n");
89398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		return -ENOMEM;
90398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	}
91398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
92398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
93398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
94398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
95398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
96398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
97398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	DRM_DEBUG("Enabled hardware status page\n");
98398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	return 0;
99398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard}
100398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
101398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard/**
102398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * Frees the hardware status page, whether it's a physical address or a virtual
103398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * address set up by the X Server.
104398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard */
1053043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholtstatic void i915_free_hws(struct drm_device *dev)
106398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard{
107398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	drm_i915_private_t *dev_priv = dev->dev_private;
108398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	if (dev_priv->status_page_dmah) {
109398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		drm_pci_free(dev, dev_priv->status_page_dmah);
110398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		dev_priv->status_page_dmah = NULL;
111398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	}
112398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
113398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	if (dev_priv->status_gfx_addr) {
114398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		dev_priv->status_gfx_addr = 0;
115398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		drm_core_ioremapfree(&dev_priv->hws_map, dev);
116398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	}
117398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
118398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	/* Need to rewrite hardware status page */
119398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	I915_WRITE(HWS_PGA, 0x1ffff000);
120398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard}
121398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
12284b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlievoid i915_kernel_lost_context(struct drm_device * dev)
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
1257c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
128585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
129585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ring->space = ring->head - (ring->tail + 8);
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ring->space < 0)
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ring->space += ring->Size;
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1347c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (!dev->primary->master)
1357c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		return;
1367c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
1377c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master_priv = dev->primary->master->driver_priv;
1387c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (ring->head == ring->tail && master_priv->sarea_priv)
1397c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		master_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14284b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dma_cleanup(struct drm_device * dev)
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
144ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Make sure interrupts are disabled here because the uninstall ioctl
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * may not have been called from userspace and after dev_private
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * is freed, it's too late.
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
149ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	if (dev->irq_enabled)
150b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie		drm_irq_uninstall(dev);
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
152ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	if (dev_priv->ring.virtual_start) {
153ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes		drm_core_ioremapfree(&dev_priv->ring.map, dev);
1543043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholt		dev_priv->ring.virtual_start = NULL;
1553043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholt		dev_priv->ring.map.handle = NULL;
156ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes		dev_priv->ring.map.size = 0;
157ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	}
158dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
159398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	/* Clear the HWS virtual address at teardown */
160398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	if (I915_NEED_GFX_HWS(dev))
161398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		i915_free_hws(dev);
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
166ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnesstatic int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
168ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
1697c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
171673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	if (init->ring_size != 0) {
172673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		if (dev_priv->ring.ring_obj != NULL) {
173673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			i915_dma_cleanup(dev);
174673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			DRM_ERROR("Client tried to initialize ringbuffer in "
175673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt				  "GEM mode\n");
176673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			return -EINVAL;
177673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		}
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
179673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.Size = init->ring_size;
180673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
182673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.map.offset = init->ring_start;
183673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.map.size = init->ring_size;
184673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.map.type = 0;
185673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.map.flags = 0;
186673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.map.mtrr = 0;
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
188673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		drm_core_ioremap(&dev_priv->ring.map, dev);
189673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
190673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		if (dev_priv->ring.map.handle == NULL) {
191673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			i915_dma_cleanup(dev);
192673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			DRM_ERROR("can not ioremap virtual address for"
193673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt				  " ring buffer\n");
194673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			return -ENOMEM;
195673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		}
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
200a6b54f3f5050c0cbc0c35dd48064846c6302706bMichel Dänzer	dev_priv->cpp = init->cpp;
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_priv->back_offset = init->back_offset;
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_priv->front_offset = init->front_offset;
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_priv->current_page = 0;
2047c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (master_priv->sarea_priv)
2057c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		master_priv->sarea_priv->pf_current_page = 0;
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Allow hardware batchbuffers unless told otherwise.
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_priv->allow_batchbuffer = 1;
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21484b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dma_resume(struct drm_device * dev)
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
218bf9d89295233ae2ba7b312c78ee5657307b09f4cHarvey Harrison	DRM_DEBUG("%s\n", __func__);
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev_priv->ring.map.handle == NULL) {
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("can not ioremap virtual address for"
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  " ring buffer\n");
22320caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -ENOMEM;
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Program Hardware Status Page */
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev_priv->hw_status_page) {
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("Can not find hardware status page\n");
22920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
233dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	if (dev_priv->status_gfx_addr != 0)
234585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes		I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
235dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	else
236585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes		I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DRM_DEBUG("Enabled hardware status page\n");
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
242c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_dma_init(struct drm_device *dev, void *data,
243c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			 struct drm_file *file_priv)
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
245c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_init_t *init = data;
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int retcode = 0;
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
248c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	switch (init->func) {
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_INIT_DMA:
250ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes		retcode = i915_initialize(dev, init);
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_CLEANUP_DMA:
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		retcode = i915_dma_cleanup(dev);
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_RESUME_DMA:
2560d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie		retcode = i915_dma_resume(dev);
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
25920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		retcode = -EINVAL;
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return retcode;
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Implement basically the same security restrictions as hardware does
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for MI_BATCH_NON_SECURE.  These can be made stricter at any time.
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Most of the calculations below involve calculating the size of a
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * particular instruction.  It's important to get the size right as
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that tells us where the next instruction to check is.  Any illegal
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * instruction detected will be given a size of zero, which is a
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * signal to abort the rest of the buffer.
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int do_validate_cmd(int cmd)
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (((cmd >> 29) & 0x7)) {
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x0:
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch ((cmd >> 23) & 0x3f) {
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x0:
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;	/* MI_NOOP */
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x4:
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;	/* MI_FLUSH */
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;	/* disallow everything else */
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x1:
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;	/* reserved */
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x2:
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (cmd & 0xff) + 2;	/* 2d commands */
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x3:
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (((cmd >> 24) & 0x1f) <= 0x18)
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch ((cmd >> 24) & 0x1f) {
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x1c:
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x1d:
300b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie			switch ((cmd >> 16) & 0xff) {
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 0x3:
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (cmd & 0x1f) + 2;
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 0x4:
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (cmd & 0xf) + 2;
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			default:
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (cmd & 0xffff) + 2;
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x1e:
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (cmd & (1 << 23))
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (cmd & 0xffff) + 1;
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 1;
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x1f:
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if ((cmd & (1 << 23)) == 0)	/* inline vertices */
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (cmd & 0x1ffff) + 2;
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else if (cmd & (1 << 17))	/* indirect random */
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if ((cmd & 0xffff) == 0)
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					return 0;	/* unknown length, too hard */
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					return (((cmd & 0xffff) + 1) / 2) + 1;
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 2;	/* indirect sequential */
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int validate_cmd(int cmd)
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret = do_validate_cmd(cmd);
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
337bc5f4523f772cc7629c5c5a46cf4f2a07a5500b8Dave Airlie/*	printk("validate_cmd( %x ): %d\n", cmd, ret); */
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
34284b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords)
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	RING_LOCALS;
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
348de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)
34920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
350de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
351c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane	BEGIN_LP_RING((dwords+1)&~1);
352de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < dwords;) {
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int cmd, sz;
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd)))
35720caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt			return -EINVAL;
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
36020caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt			return -EINVAL;
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		OUT_RING(cmd);
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (++i, --sz) {
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i],
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds							 sizeof(cmd))) {
36720caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt				return -EINVAL;
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			OUT_RING(cmd);
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
373de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	if (dwords & 1)
374de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie		OUT_RING(0);
375de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
376de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	ADVANCE_LP_RING();
377de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholtint
382673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholti915_emit_box(struct drm_device *dev,
383673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	      struct drm_clip_rect __user *boxes,
384673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	      int i, int DR1, int DR4)
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
387c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie	struct drm_clip_rect box;
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	RING_LOCALS;
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
39120caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EFAULT;
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("Bad box %d,%d..%d,%d\n",
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  box.x1, box.y1, box.x2, box.y2);
39720caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
400c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane	if (IS_I965G(dev)) {
401c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		BEGIN_LP_RING(4);
402c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
403c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
40478eca43d0391f59c3b1505bb7bd38ff45b650aabAndrew Morton		OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
405c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(DR4);
406c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		ADVANCE_LP_RING();
407c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane	} else {
408c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		BEGIN_LP_RING(6);
409c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(GFX_OP_DRAWRECT_INFO);
410c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(DR1);
411c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
412c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
413c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(DR4);
414c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(0);
415c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		ADVANCE_LP_RING();
416c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane	}
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
421c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane/* XXX: Emitting the counter should really be moved to part of the IRQ
422c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane * emit. For now, do it in both places:
423c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane */
424c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane
42584b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic void i915_emit_breadcrumb(struct drm_device *dev)
426de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie{
427de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	drm_i915_private_t *dev_priv = dev->dev_private;
4287c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
429de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	RING_LOCALS;
430de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
431c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg	dev_priv->counter++;
432af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	if (dev_priv->counter > 0x7FFFFFFFUL)
433c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg		dev_priv->counter = 0;
4347c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (master_priv->sarea_priv)
4357c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		master_priv->sarea_priv->last_enqueue = dev_priv->counter;
436de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
437de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	BEGIN_LP_RING(4);
438585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	OUT_RING(MI_STORE_DWORD_INDEX);
4390baf823a10bd4131f70e9712d1f02de3c247f1dfKeith Packard	OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
440de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	OUT_RING(dev_priv->counter);
441de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	OUT_RING(0);
442de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	ADVANCE_LP_RING();
443de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie}
444de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
44584b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dispatch_cmdbuffer(struct drm_device * dev,
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   drm_i915_cmdbuffer_t * cmd)
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int nbox = cmd->num_cliprects;
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i = 0, count, ret;
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cmd->sz & 0x3) {
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("alignment");
45320caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	i915_kernel_lost_context(dev);
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	count = nbox ? nbox : 1;
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < count; i++) {
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (i < nbox) {
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ret = i915_emit_box(dev, cmd->cliprects, i,
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					    cmd->DR1, cmd->DR4);
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ret)
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return ret;
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4);
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ret)
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return ret;
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
473de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	i915_emit_breadcrumb(dev);
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
47784b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dispatch_batchbuffer(struct drm_device * dev,
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				     drm_i915_batchbuffer_t * batch)
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
481c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie	struct drm_clip_rect __user *boxes = batch->cliprects;
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int nbox = batch->num_cliprects;
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i = 0, count;
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	RING_LOCALS;
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((batch->start | batch->used) & 0x7) {
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("alignment");
48820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	i915_kernel_lost_context(dev);
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	count = nbox ? nbox : 1;
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < count; i++) {
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (i < nbox) {
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int ret = i915_emit_box(dev, boxes, i,
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						batch->DR1, batch->DR4);
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ret)
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return ret;
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5030790d5e148c0747499742a3c09ba5f1c07f9ed0dKeith Packard		if (!IS_I830(dev) && !IS_845G(dev)) {
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			BEGIN_LP_RING(2);
50521f16289270447673a7263ccc0b22d562fb01ecbDave Airlie			if (IS_I965G(dev)) {
50621f16289270447673a7263ccc0b22d562fb01ecbDave Airlie				OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
50721f16289270447673a7263ccc0b22d562fb01ecbDave Airlie				OUT_RING(batch->start);
50821f16289270447673a7263ccc0b22d562fb01ecbDave Airlie			} else {
50921f16289270447673a7263ccc0b22d562fb01ecbDave Airlie				OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
51021f16289270447673a7263ccc0b22d562fb01ecbDave Airlie				OUT_RING(batch->start | MI_BATCH_NON_SECURE);
51121f16289270447673a7263ccc0b22d562fb01ecbDave Airlie			}
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ADVANCE_LP_RING();
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			BEGIN_LP_RING(4);
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			OUT_RING(MI_BATCH_BUFFER);
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			OUT_RING(batch->start | MI_BATCH_NON_SECURE);
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			OUT_RING(batch->start + batch->used - 4);
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			OUT_RING(0);
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ADVANCE_LP_RING();
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
523de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	i915_emit_breadcrumb(dev);
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
528af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airliestatic int i915_dispatch_flip(struct drm_device * dev)
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
5317c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv =
5327c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		dev->primary->master->driver_priv;
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	RING_LOCALS;
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5357c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (!master_priv->sarea_priv)
536c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg		return -EINVAL;
537c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg
538af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
53980a914dc05683ecfc98f9e1887fd6564846ffbecHarvey Harrison		  __func__,
540af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie		  dev_priv->current_page,
5417c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		  master_priv->sarea_priv->pf_current_page);
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
543af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	i915_kernel_lost_context(dev);
544af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie
545af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	BEGIN_LP_RING(2);
546585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	OUT_RING(MI_FLUSH | MI_READ_FLUSH);
547af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(0);
548af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	ADVANCE_LP_RING();
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
550af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	BEGIN_LP_RING(6);
551af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
552af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(0);
553af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	if (dev_priv->current_page == 0) {
554af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie		OUT_RING(dev_priv->back_offset);
555af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie		dev_priv->current_page = 1;
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
557af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie		OUT_RING(dev_priv->front_offset);
558af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie		dev_priv->current_page = 0;
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
560af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(0);
561af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	ADVANCE_LP_RING();
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
563af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	BEGIN_LP_RING(2);
564af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
565af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(0);
566af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	ADVANCE_LP_RING();
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5687c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master_priv->sarea_priv->last_enqueue = dev_priv->counter++;
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	BEGIN_LP_RING(4);
571585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	OUT_RING(MI_STORE_DWORD_INDEX);
5720baf823a10bd4131f70e9712d1f02de3c247f1dfKeith Packard	OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
573af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(dev_priv->counter);
574af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(0);
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADVANCE_LP_RING();
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5777c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master_priv->sarea_priv->pf_current_page = dev_priv->current_page;
578af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	return 0;
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
58184b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_quiescent(struct drm_device * dev)
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	i915_kernel_lost_context(dev);
586bf9d89295233ae2ba7b312c78ee5657307b09f4cHarvey Harrison	return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
589c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_flush_ioctl(struct drm_device *dev, void *data,
590c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			    struct drm_file *file_priv)
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
592546b0974c39657017407c86fe79811100b60700dEric Anholt	int ret;
593546b0974c39657017407c86fe79811100b60700dEric Anholt
594546b0974c39657017407c86fe79811100b60700dEric Anholt	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
596546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_lock(&dev->struct_mutex);
597546b0974c39657017407c86fe79811100b60700dEric Anholt	ret = i915_quiescent(dev);
598546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_unlock(&dev->struct_mutex);
599546b0974c39657017407c86fe79811100b60700dEric Anholt
600546b0974c39657017407c86fe79811100b60700dEric Anholt	return ret;
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
603c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_batchbuffer(struct drm_device *dev, void *data,
604c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			    struct drm_file *file_priv)
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
6077c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
6097c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	    master_priv->sarea_priv;
610c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_batchbuffer_t *batch = data;
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev_priv->allow_batchbuffer) {
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("Batchbuffer ioctl disabled\n");
61520caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n",
619c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		  batch->start, batch->used, batch->num_cliprects);
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
621546b0974c39657017407c86fe79811100b60700dEric Anholt	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
623c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
624c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt						       batch->num_cliprects *
625c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie						       sizeof(struct drm_clip_rect)))
62620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EFAULT;
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
628546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_lock(&dev->struct_mutex);
629c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	ret = i915_dispatch_batchbuffer(dev, batch);
630546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_unlock(&dev->struct_mutex);
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
632c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg	if (sarea_priv)
6330baf823a10bd4131f70e9712d1f02de3c247f1dfKeith Packard		sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
637c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_cmdbuffer(struct drm_device *dev, void *data,
638c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			  struct drm_file *file_priv)
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
6417c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
6437c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	    master_priv->sarea_priv;
644c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_cmdbuffer_t *cmdbuf = data;
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
648c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		  cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
650546b0974c39657017407c86fe79811100b60700dEric Anholt	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
652c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	if (cmdbuf->num_cliprects &&
653c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	    DRM_VERIFYAREA_READ(cmdbuf->cliprects,
654c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt				cmdbuf->num_cliprects *
655c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie				sizeof(struct drm_clip_rect))) {
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("Fault accessing cliprects\n");
65720caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EFAULT;
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
660546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_lock(&dev->struct_mutex);
661c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
662546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_unlock(&dev->struct_mutex);
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ret) {
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ret;
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
668c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg	if (sarea_priv)
6690baf823a10bd4131f70e9712d1f02de3c247f1dfKeith Packard		sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
673c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_flip_bufs(struct drm_device *dev, void *data,
674c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			  struct drm_file *file_priv)
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
676546b0974c39657017407c86fe79811100b60700dEric Anholt	int ret;
677546b0974c39657017407c86fe79811100b60700dEric Anholt
67880a914dc05683ecfc98f9e1887fd6564846ffbecHarvey Harrison	DRM_DEBUG("%s\n", __func__);
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
680546b0974c39657017407c86fe79811100b60700dEric Anholt	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
682546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_lock(&dev->struct_mutex);
683546b0974c39657017407c86fe79811100b60700dEric Anholt	ret = i915_dispatch_flip(dev);
684546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_unlock(&dev->struct_mutex);
685546b0974c39657017407c86fe79811100b60700dEric Anholt
686546b0974c39657017407c86fe79811100b60700dEric Anholt	return ret;
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
689c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_getparam(struct drm_device *dev, void *data,
690c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			 struct drm_file *file_priv)
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
693c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_getparam_t *param = data;
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int value;
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev_priv) {
6973e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh		DRM_ERROR("called with no initialization\n");
69820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	switch (param->param) {
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_PARAM_IRQ_ACTIVE:
7030a3e67a4caac273a3bfc4ced3da364830b1ab241Jesse Barnes		value = dev->pdev->irq ? 1 : 0;
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_PARAM_ALLOW_BATCHBUFFER:
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		value = dev_priv->allow_batchbuffer ? 1 : 0;
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7080d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie	case I915_PARAM_LAST_DISPATCH:
7090d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie		value = READ_BREADCRUMB(dev_priv);
7100d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie		break;
711ed4c9c4acf948b42b138747fcb8843ecb1a24ce4Kristian Høgsberg	case I915_PARAM_CHIPSET_ID:
712ed4c9c4acf948b42b138747fcb8843ecb1a24ce4Kristian Høgsberg		value = dev->pci_device;
713ed4c9c4acf948b42b138747fcb8843ecb1a24ce4Kristian Høgsberg		break;
714673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	case I915_PARAM_HAS_GEM:
715ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie		value = dev_priv->has_gem;
716673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		break;
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
718c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		DRM_ERROR("Unknown parameter %d\n", param->param);
71920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
722c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("DRM_COPY_TO_USER failed\n");
72420caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EFAULT;
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
730c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_setparam(struct drm_device *dev, void *data,
731c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			 struct drm_file *file_priv)
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
734c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_setparam_t *param = data;
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev_priv) {
7373e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh		DRM_ERROR("called with no initialization\n");
73820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
741c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	switch (param->param) {
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
745c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		dev_priv->tex_lru_log_granularity = param->value;
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_SETPARAM_ALLOW_BATCHBUFFER:
748c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		dev_priv->allow_batchbuffer = param->value;
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
751c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		DRM_ERROR("unknown parameter %d\n", param->param);
75220caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
758c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_set_status_page(struct drm_device *dev, void *data,
759c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt				struct drm_file *file_priv)
760dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu{
761dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	drm_i915_private_t *dev_priv = dev->dev_private;
762c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_hws_addr_t *hws = data;
763b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang
764b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang	if (!I915_NEED_GFX_HWS(dev))
765b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang		return -EINVAL;
766dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
767dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	if (!dev_priv) {
7683e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh		DRM_ERROR("called with no initialization\n");
76920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
770dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	}
771dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
772c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr);
773c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt
774c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
775dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
7768b40958032fd236194de57d29be9cf2c1f2643eeEric Anholt	dev_priv->hws_map.offset = dev->agp->base + hws->addr;
777dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	dev_priv->hws_map.size = 4*1024;
778dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	dev_priv->hws_map.type = 0;
779dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	dev_priv->hws_map.flags = 0;
780dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	dev_priv->hws_map.mtrr = 0;
781dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
782dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	drm_core_ioremap(&dev_priv->hws_map, dev);
783dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	if (dev_priv->hws_map.handle == NULL) {
784dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu		i915_dma_cleanup(dev);
785dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu		dev_priv->status_gfx_addr = 0;
786dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu		DRM_ERROR("can not ioremap virtual address for"
787dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu				" G33 hw status page\n");
78820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -ENOMEM;
789dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	}
790dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	dev_priv->hw_status_page = dev_priv->hws_map.handle;
791dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
792dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
793585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
794585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n",
795dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu			dev_priv->status_gfx_addr);
796dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
797dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	return 0;
798dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu}
799dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
8007c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlieint i915_master_create(struct drm_device *dev, struct drm_master *master)
8017c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{
8027c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv;
8037c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
8047c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER);
8057c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (!master_priv)
8067c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		return -ENOMEM;
8077c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
8087c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master->driver_priv = master_priv;
8097c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	return 0;
8107c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie}
8117c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
8127c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlievoid i915_master_destroy(struct drm_device *dev, struct drm_master *master)
8137c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{
8147c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = master->driver_priv;
8157c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
8167c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (!master_priv)
8177c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		return;
8187c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
8197c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER);
8207c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
8217c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master->driver_priv = NULL;
8227c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie}
8237c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
82484b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_driver_load(struct drm_device *dev, unsigned long flags)
82522eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie{
826ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	struct drm_i915_private *dev_priv = dev->dev_private;
827ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	unsigned long base, size;
828ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
829ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
83022eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	/* i915 has 4 more counters */
83122eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	dev->counters += 4;
83222eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	dev->types[6] = _DRM_STAT_IRQ;
83322eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	dev->types[7] = _DRM_STAT_PRIMARY;
83422eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	dev->types[8] = _DRM_STAT_SECONDARY;
83522eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	dev->types[9] = _DRM_STAT_DMA;
83622eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie
837ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER);
838ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	if (dev_priv == NULL)
839ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes		return -ENOMEM;
840ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
841ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	memset(dev_priv, 0, sizeof(drm_i915_private_t));
842ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
843ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	dev->dev_private = (void *)dev_priv;
844673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	dev_priv->dev = dev;
845ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
846ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	/* Add register map (needed for suspend/resume) */
847ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	base = drm_get_resource_start(dev, mmio_bar);
848ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	size = drm_get_resource_len(dev, mmio_bar);
849ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
8503043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholt	dev_priv->regs = ioremap(base, size);
851ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt
852ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie#ifdef CONFIG_HIGHMEM64G
853ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie	/* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */
854ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie	dev_priv->has_gem = 0;
855ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie#else
856ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie	/* enable GEM by default */
857ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie	dev_priv->has_gem = 1;
858ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie#endif
859ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie
860673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	i915_gem_load(dev);
861673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
862398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	/* Init HWS */
863398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	if (!I915_NEED_GFX_HWS(dev)) {
864398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		ret = i915_init_phys_hws(dev);
865398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		if (ret != 0)
866398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard			return ret;
867398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	}
868ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt
869ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	/* On the 945G/GM, the chipset reports the MSI capability on the
870ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 * integrated graphics even though the support isn't actually there
871ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 * according to the published specs.  It doesn't appear to function
872ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 * correctly in testing on 945G.
873ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 * This may be a side effect of MSI having been made available for PEG
874ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 * and the registers being closely associated.
875d1ed629f44b3a4108d5c445971535f05f441fce7Keith Packard	 *
876d1ed629f44b3a4108d5c445971535f05f441fce7Keith Packard	 * According to chipset errata, on the 965GM, MSI interrupts may
877b60678a75d44fa9d5969f79781bd856ad5858609Keith Packard	 * be lost or delayed, but we use them anyways to avoid
878b60678a75d44fa9d5969f79781bd856ad5858609Keith Packard	 * stuck interrupts on some machines.
879ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 */
880b60678a75d44fa9d5969f79781bd856ad5858609Keith Packard	if (!IS_I945G(dev) && !IS_I945GM(dev))
881d3e74d0237b102d34979015fbf6df02ca4413074Eric Anholt		pci_enable_msi(dev->pdev);
882ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt
8838ee1c3db9075cb3211352e737e0feb98fd733b20Matthew Garrett	intel_opregion_init(dev);
8848ee1c3db9075cb3211352e737e0feb98fd733b20Matthew Garrett
885ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	spin_lock_init(&dev_priv->user_irq_lock);
886ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt
88752440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard	ret = drm_vblank_init(dev, I915_NUM_PIPE);
88852440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard
88952440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard	if (ret) {
89052440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard		(void) i915_driver_unload(dev);
89152440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard		return ret;
89252440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard	}
89352440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard
894ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	return ret;
895ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes}
896ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
897ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnesint i915_driver_unload(struct drm_device *dev)
898ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes{
899ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	struct drm_i915_private *dev_priv = dev->dev_private;
900ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
901ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	if (dev->pdev->msi_enabled)
902ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt		pci_disable_msi(dev->pdev);
903ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt
904398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	i915_free_hws(dev);
905398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
9063043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholt	if (dev_priv->regs != NULL)
9073043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholt		iounmap(dev_priv->regs);
908ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
9098ee1c3db9075cb3211352e737e0feb98fd733b20Matthew Garrett	intel_opregion_free(dev);
9108ee1c3db9075cb3211352e737e0feb98fd733b20Matthew Garrett
911ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	drm_free(dev->dev_private, sizeof(drm_i915_private_t),
912ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes		 DRM_MEM_DRIVER);
913ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
91422eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	return 0;
91522eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie}
91622eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie
917673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholtint i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
918673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt{
919673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	struct drm_i915_file_private *i915_file_priv;
920673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
921673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_DEBUG("\n");
922673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	i915_file_priv = (struct drm_i915_file_private *)
923673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	    drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES);
924673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
925673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	if (!i915_file_priv)
926673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		return -ENOMEM;
927673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
928673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	file_priv->driver_priv = i915_file_priv;
929673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
930673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	i915_file_priv->mm.last_gem_seqno = 0;
931673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	i915_file_priv->mm.last_gem_throttle_seqno = 0;
932673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
933673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	return 0;
934673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt}
935673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
93684b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlievoid i915_driver_lastclose(struct drm_device * dev)
9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
938ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
939ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
940144a75fa1faa4a81530bded2e59872ef80d496b6Dave Airlie	if (!dev_priv)
941144a75fa1faa4a81530bded2e59872ef80d496b6Dave Airlie		return;
942144a75fa1faa4a81530bded2e59872ef80d496b6Dave Airlie
943673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	i915_gem_lastclose(dev);
944673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
945ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	if (dev_priv->agp_heap)
946b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie		i915_mem_takedown(&(dev_priv->agp_heap));
947ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
948b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie	i915_dma_cleanup(dev);
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9516c340eac0285f3d62406d2d902d0e96fbf2a5dc0Eric Anholtvoid i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
953ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
954ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	i915_mem_release(dev, file_priv, dev_priv->agp_heap);
9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
957673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholtvoid i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
958673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt{
959673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
960673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
961673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES);
962673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt}
963673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
964c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstruct drm_ioctl_desc i915_ioctls[] = {
965c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
966c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
967c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH),
968c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH),
969c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH),
970c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH),
971c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH),
972c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
973c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH),
974c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH),
975c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
976c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH),
977c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP,  i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
978c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE,  i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
979c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE,  i915_vblank_pipe_get, DRM_AUTH ),
980c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
9814b40893918203ee1a1f6a114316c2a19c072e9bdMatthias Hopf	DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
9822bdf00b22154023ac312481583603f4724eb1401Dave Airlie	DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
983673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
984673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
985673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
986673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
987673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
9882bdf00b22154023ac312481583603f4724eb1401Dave Airlie	DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
9892bdf00b22154023ac312481583603f4724eb1401Dave Airlie	DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
990673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
991673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
992673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
993673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
994de151cf67ce52ed2d88083daa5e60c7858947329Jesse Barnes	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 0),
995673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
996673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
997673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
998673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
9995a125c3c79167e78ba44efef03af7090ef28eeafEric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0),
1000c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie};
1001c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie
1002c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlieint i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1003cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie
1004cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie/**
1005cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * Determine if the device really is AGP or not.
1006cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie *
1007cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * All Intel graphics chipsets are treated as AGP, even if they are really
1008cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * PCI-e.
1009cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie *
1010cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * \param dev   The device to be tested.
1011cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie *
1012cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * \returns
1013cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * A value of 1 is always retured to indictate every i9x5 is AGP.
1014cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie */
101584b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_driver_device_is_agp(struct drm_device * dev)
1016cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie{
1017cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie	return 1;
1018cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie}
1019