i915_dma.c revision 2906f0258770d3a9c4e65364df8acc904e148bbe
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"
3179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes#include "drm_crtc_helper.h"
3279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes#include "intel_drv.h"
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "i915_drm.h"
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "i915_drv.h"
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Really want an OS-independent resettable timer.  Would like to have
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * this loop run for (eg) 3 sec, but have the timer reset every time
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the head pointer changes, so that EBUSY only happens if the ring
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * actually stalls for (eg) 3 seconds.
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4184b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_wait_ring(struct drm_device * dev, int n, const char *caller)
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
447c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
46d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard	u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
47d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard	u32 last_acthd = I915_READ(acthd_reg);
48d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard	u32 acthd;
49585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
52d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard	for (i = 0; i < 100000; i++) {
53585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes		ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
54d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard		acthd = I915_READ(acthd_reg);
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ring->space = ring->head - (ring->tail + 8);
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ring->space < 0)
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ring->space += ring->Size;
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ring->space >= n)
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
617c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		if (master_priv->sarea_priv)
627c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie			master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ring->head != last_head)
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			i = 0;
66d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard		if (acthd != last_acthd)
67d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard			i = 0;
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		last_head = ring->head;
70d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard		last_acthd = acthd;
71d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard		msleep_interruptible(10);
72d3a6d4467ca44833bcb4ba1893a7aeaae939e4d5Keith Packard
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7520caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt	return -EBUSY;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
78398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard/**
79398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * Sets up the hardware status page for devices that need a physical address
80398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * in the register.
81398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard */
823043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholtstatic int i915_init_phys_hws(struct drm_device *dev)
83398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard{
84398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	drm_i915_private_t *dev_priv = dev->dev_private;
85398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	/* Program Hardware Status Page */
86398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	dev_priv->status_page_dmah =
87398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
88398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
89398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	if (!dev_priv->status_page_dmah) {
90398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		DRM_ERROR("Can not allocate hardware status page\n");
91398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		return -ENOMEM;
92398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	}
93398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
94398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
95398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
96398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
97398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
98398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
99398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	DRM_DEBUG("Enabled hardware status page\n");
100398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	return 0;
101398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard}
102398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
103398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard/**
104398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * Frees the hardware status page, whether it's a physical address or a virtual
105398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * address set up by the X Server.
106398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard */
1073043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholtstatic void i915_free_hws(struct drm_device *dev)
108398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard{
109398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	drm_i915_private_t *dev_priv = dev->dev_private;
110398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	if (dev_priv->status_page_dmah) {
111398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		drm_pci_free(dev, dev_priv->status_page_dmah);
112398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		dev_priv->status_page_dmah = NULL;
113398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	}
114398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
115398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	if (dev_priv->status_gfx_addr) {
116398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		dev_priv->status_gfx_addr = 0;
117398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		drm_core_ioremapfree(&dev_priv->hws_map, dev);
118398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	}
119398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
120398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	/* Need to rewrite hardware status page */
121398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	I915_WRITE(HWS_PGA, 0x1ffff000);
122398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard}
123398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard
12484b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlievoid i915_kernel_lost_context(struct drm_device * dev)
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
1277c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv;
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	/*
13179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	 * We should never lose context on the ring with modesetting
13279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	 * as we don't expose it to userspace
13379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	 */
13479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (drm_core_check_feature(dev, DRIVER_MODESET))
13579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		return;
13679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
137585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
138585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ring->space = ring->head - (ring->tail + 8);
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ring->space < 0)
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ring->space += ring->Size;
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1437c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (!dev->primary->master)
1447c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		return;
1457c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
1467c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master_priv = dev->primary->master->driver_priv;
1477c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (ring->head == ring->tail && master_priv->sarea_priv)
1487c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		master_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15184b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dma_cleanup(struct drm_device * dev)
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
153ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Make sure interrupts are disabled here because the uninstall ioctl
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * may not have been called from userspace and after dev_private
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * is freed, it's too late.
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
158ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	if (dev->irq_enabled)
159b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie		drm_irq_uninstall(dev);
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
161ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	if (dev_priv->ring.virtual_start) {
162ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes		drm_core_ioremapfree(&dev_priv->ring.map, dev);
1633043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholt		dev_priv->ring.virtual_start = NULL;
1643043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholt		dev_priv->ring.map.handle = NULL;
165ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes		dev_priv->ring.map.size = 0;
166ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	}
167dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
168398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	/* Clear the HWS virtual address at teardown */
169398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	if (I915_NEED_GFX_HWS(dev))
170398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		i915_free_hws(dev);
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
175ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnesstatic int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
177ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
1787c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1803a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie	master_priv->sarea = drm_getsarea(dev);
1813a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie	if (master_priv->sarea) {
1823a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie		master_priv->sarea_priv = (drm_i915_sarea_t *)
1833a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie			((u8 *)master_priv->sarea->handle + init->sarea_priv_offset);
1843a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie	} else {
1853a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie		DRM_DEBUG("sarea not found assuming DRI2 userspace\n");
1863a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie	}
1873a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie
188673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	if (init->ring_size != 0) {
189673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		if (dev_priv->ring.ring_obj != NULL) {
190673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			i915_dma_cleanup(dev);
191673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			DRM_ERROR("Client tried to initialize ringbuffer in "
192673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt				  "GEM mode\n");
193673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			return -EINVAL;
194673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		}
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
196673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.Size = init->ring_size;
197673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
199673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.map.offset = init->ring_start;
200673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.map.size = init->ring_size;
201673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.map.type = 0;
202673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.map.flags = 0;
203673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		dev_priv->ring.map.mtrr = 0;
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
205673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		drm_core_ioremap(&dev_priv->ring.map, dev);
206673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
207673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		if (dev_priv->ring.map.handle == NULL) {
208673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			i915_dma_cleanup(dev);
209673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			DRM_ERROR("can not ioremap virtual address for"
210673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt				  " ring buffer\n");
211673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt			return -ENOMEM;
212673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		}
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
217a6b54f3f5050c0cbc0c35dd48064846c6302706bMichel Dänzer	dev_priv->cpp = init->cpp;
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_priv->back_offset = init->back_offset;
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_priv->front_offset = init->front_offset;
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_priv->current_page = 0;
2217c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (master_priv->sarea_priv)
2227c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		master_priv->sarea_priv->pf_current_page = 0;
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Allow hardware batchbuffers unless told otherwise.
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_priv->allow_batchbuffer = 1;
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23184b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dma_resume(struct drm_device * dev)
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
235bf9d89295233ae2ba7b312c78ee5657307b09f4cHarvey Harrison	DRM_DEBUG("%s\n", __func__);
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev_priv->ring.map.handle == NULL) {
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("can not ioremap virtual address for"
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  " ring buffer\n");
24020caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -ENOMEM;
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Program Hardware Status Page */
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev_priv->hw_status_page) {
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("Can not find hardware status page\n");
24620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
250dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	if (dev_priv->status_gfx_addr != 0)
251585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes		I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
252dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	else
253585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes		I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DRM_DEBUG("Enabled hardware status page\n");
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
259c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_dma_init(struct drm_device *dev, void *data,
260c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			 struct drm_file *file_priv)
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
262c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_init_t *init = data;
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int retcode = 0;
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
265c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	switch (init->func) {
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_INIT_DMA:
267ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes		retcode = i915_initialize(dev, init);
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_CLEANUP_DMA:
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		retcode = i915_dma_cleanup(dev);
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_RESUME_DMA:
2730d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie		retcode = i915_dma_resume(dev);
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
27620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		retcode = -EINVAL;
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return retcode;
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Implement basically the same security restrictions as hardware does
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for MI_BATCH_NON_SECURE.  These can be made stricter at any time.
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Most of the calculations below involve calculating the size of a
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * particular instruction.  It's important to get the size right as
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that tells us where the next instruction to check is.  Any illegal
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * instruction detected will be given a size of zero, which is a
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * signal to abort the rest of the buffer.
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int do_validate_cmd(int cmd)
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (((cmd >> 29) & 0x7)) {
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x0:
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch ((cmd >> 23) & 0x3f) {
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x0:
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;	/* MI_NOOP */
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x4:
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;	/* MI_FLUSH */
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;	/* disallow everything else */
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x1:
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;	/* reserved */
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x2:
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (cmd & 0xff) + 2;	/* 2d commands */
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x3:
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (((cmd >> 24) & 0x1f) <= 0x18)
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch ((cmd >> 24) & 0x1f) {
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x1c:
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x1d:
317b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie			switch ((cmd >> 16) & 0xff) {
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 0x3:
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (cmd & 0x1f) + 2;
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 0x4:
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (cmd & 0xf) + 2;
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			default:
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (cmd & 0xffff) + 2;
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x1e:
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (cmd & (1 << 23))
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (cmd & 0xffff) + 1;
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 1;
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 0x1f:
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if ((cmd & (1 << 23)) == 0)	/* inline vertices */
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (cmd & 0x1ffff) + 2;
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else if (cmd & (1 << 17))	/* indirect random */
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if ((cmd & 0xffff) == 0)
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					return 0;	/* unknown length, too hard */
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					return (((cmd & 0xffff) + 1) / 2) + 1;
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 2;	/* indirect sequential */
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int validate_cmd(int cmd)
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret = do_validate_cmd(cmd);
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
354bc5f4523f772cc7629c5c5a46cf4f2a07a5500b8Dave Airlie/*	printk("validate_cmd( %x ): %d\n", cmd, ret); */
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
35984b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords)
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	RING_LOCALS;
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
365de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)
36620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
367de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
368c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane	BEGIN_LP_RING((dwords+1)&~1);
369de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < dwords;) {
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int cmd, sz;
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd)))
37420caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt			return -EINVAL;
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
37720caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt			return -EINVAL;
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		OUT_RING(cmd);
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (++i, --sz) {
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i],
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds							 sizeof(cmd))) {
38420caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt				return -EINVAL;
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			OUT_RING(cmd);
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
390de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	if (dwords & 1)
391de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie		OUT_RING(0);
392de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
393de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	ADVANCE_LP_RING();
394de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
398673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholtint
399673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholti915_emit_box(struct drm_device *dev,
400673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	      struct drm_clip_rect __user *boxes,
401673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	      int i, int DR1, int DR4)
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
404c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie	struct drm_clip_rect box;
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	RING_LOCALS;
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
40820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EFAULT;
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("Bad box %d,%d..%d,%d\n",
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  box.x1, box.y1, box.x2, box.y2);
41420caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
417c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane	if (IS_I965G(dev)) {
418c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		BEGIN_LP_RING(4);
419c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
420c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
42178eca43d0391f59c3b1505bb7bd38ff45b650aabAndrew Morton		OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
422c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(DR4);
423c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		ADVANCE_LP_RING();
424c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane	} else {
425c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		BEGIN_LP_RING(6);
426c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(GFX_OP_DRAWRECT_INFO);
427c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(DR1);
428c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
429c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
430c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(DR4);
431c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		OUT_RING(0);
432c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane		ADVANCE_LP_RING();
433c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane	}
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
438c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane/* XXX: Emitting the counter should really be moved to part of the IRQ
439c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane * emit. For now, do it in both places:
440c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane */
441c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane
44284b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic void i915_emit_breadcrumb(struct drm_device *dev)
443de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie{
444de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	drm_i915_private_t *dev_priv = dev->dev_private;
4457c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
446de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	RING_LOCALS;
447de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
448c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg	dev_priv->counter++;
449af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	if (dev_priv->counter > 0x7FFFFFFFUL)
450c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg		dev_priv->counter = 0;
4517c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (master_priv->sarea_priv)
4527c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		master_priv->sarea_priv->last_enqueue = dev_priv->counter;
453de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
454de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	BEGIN_LP_RING(4);
455585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	OUT_RING(MI_STORE_DWORD_INDEX);
4560baf823a10bd4131f70e9712d1f02de3c247f1dfKeith Packard	OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
457de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	OUT_RING(dev_priv->counter);
458de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	OUT_RING(0);
459de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	ADVANCE_LP_RING();
460de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie}
461de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie
46284b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dispatch_cmdbuffer(struct drm_device * dev,
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   drm_i915_cmdbuffer_t * cmd)
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int nbox = cmd->num_cliprects;
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i = 0, count, ret;
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cmd->sz & 0x3) {
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("alignment");
47020caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	i915_kernel_lost_context(dev);
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	count = nbox ? nbox : 1;
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < count; i++) {
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (i < nbox) {
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ret = i915_emit_box(dev, cmd->cliprects, i,
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					    cmd->DR1, cmd->DR4);
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ret)
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return ret;
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4);
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ret)
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return ret;
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
490de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	i915_emit_breadcrumb(dev);
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
49484b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dispatch_batchbuffer(struct drm_device * dev,
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				     drm_i915_batchbuffer_t * batch)
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
498c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie	struct drm_clip_rect __user *boxes = batch->cliprects;
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int nbox = batch->num_cliprects;
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i = 0, count;
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	RING_LOCALS;
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((batch->start | batch->used) & 0x7) {
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("alignment");
50520caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	i915_kernel_lost_context(dev);
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	count = nbox ? nbox : 1;
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < count; i++) {
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (i < nbox) {
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int ret = i915_emit_box(dev, boxes, i,
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						batch->DR1, batch->DR4);
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ret)
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return ret;
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5200790d5e148c0747499742a3c09ba5f1c07f9ed0dKeith Packard		if (!IS_I830(dev) && !IS_845G(dev)) {
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			BEGIN_LP_RING(2);
52221f16289270447673a7263ccc0b22d562fb01ecbDave Airlie			if (IS_I965G(dev)) {
52321f16289270447673a7263ccc0b22d562fb01ecbDave Airlie				OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
52421f16289270447673a7263ccc0b22d562fb01ecbDave Airlie				OUT_RING(batch->start);
52521f16289270447673a7263ccc0b22d562fb01ecbDave Airlie			} else {
52621f16289270447673a7263ccc0b22d562fb01ecbDave Airlie				OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
52721f16289270447673a7263ccc0b22d562fb01ecbDave Airlie				OUT_RING(batch->start | MI_BATCH_NON_SECURE);
52821f16289270447673a7263ccc0b22d562fb01ecbDave Airlie			}
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ADVANCE_LP_RING();
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			BEGIN_LP_RING(4);
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			OUT_RING(MI_BATCH_BUFFER);
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			OUT_RING(batch->start | MI_BATCH_NON_SECURE);
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			OUT_RING(batch->start + batch->used - 4);
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			OUT_RING(0);
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ADVANCE_LP_RING();
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
540de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie	i915_emit_breadcrumb(dev);
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
545af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airliestatic int i915_dispatch_flip(struct drm_device * dev)
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
5487c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv =
5497c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		dev->primary->master->driver_priv;
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	RING_LOCALS;
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5527c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (!master_priv->sarea_priv)
553c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg		return -EINVAL;
554c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg
555af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
55680a914dc05683ecfc98f9e1887fd6564846ffbecHarvey Harrison		  __func__,
557af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie		  dev_priv->current_page,
5587c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		  master_priv->sarea_priv->pf_current_page);
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
560af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	i915_kernel_lost_context(dev);
561af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie
562af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	BEGIN_LP_RING(2);
563585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	OUT_RING(MI_FLUSH | MI_READ_FLUSH);
564af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(0);
565af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	ADVANCE_LP_RING();
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
567af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	BEGIN_LP_RING(6);
568af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
569af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(0);
570af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	if (dev_priv->current_page == 0) {
571af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie		OUT_RING(dev_priv->back_offset);
572af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie		dev_priv->current_page = 1;
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
574af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie		OUT_RING(dev_priv->front_offset);
575af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie		dev_priv->current_page = 0;
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
577af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(0);
578af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	ADVANCE_LP_RING();
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
580af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	BEGIN_LP_RING(2);
581af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
582af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(0);
583af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	ADVANCE_LP_RING();
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5857c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master_priv->sarea_priv->last_enqueue = dev_priv->counter++;
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	BEGIN_LP_RING(4);
588585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	OUT_RING(MI_STORE_DWORD_INDEX);
5890baf823a10bd4131f70e9712d1f02de3c247f1dfKeith Packard	OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
590af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(dev_priv->counter);
591af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	OUT_RING(0);
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADVANCE_LP_RING();
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5947c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master_priv->sarea_priv->pf_current_page = dev_priv->current_page;
595af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie	return 0;
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
59884b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_quiescent(struct drm_device * dev)
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	i915_kernel_lost_context(dev);
603bf9d89295233ae2ba7b312c78ee5657307b09f4cHarvey Harrison	return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
606c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_flush_ioctl(struct drm_device *dev, void *data,
607c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			    struct drm_file *file_priv)
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
609546b0974c39657017407c86fe79811100b60700dEric Anholt	int ret;
610546b0974c39657017407c86fe79811100b60700dEric Anholt
611546b0974c39657017407c86fe79811100b60700dEric Anholt	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
613546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_lock(&dev->struct_mutex);
614546b0974c39657017407c86fe79811100b60700dEric Anholt	ret = i915_quiescent(dev);
615546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_unlock(&dev->struct_mutex);
616546b0974c39657017407c86fe79811100b60700dEric Anholt
617546b0974c39657017407c86fe79811100b60700dEric Anholt	return ret;
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
620c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_batchbuffer(struct drm_device *dev, void *data,
621c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			    struct drm_file *file_priv)
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
6247c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
6267c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	    master_priv->sarea_priv;
627c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_batchbuffer_t *batch = data;
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev_priv->allow_batchbuffer) {
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("Batchbuffer ioctl disabled\n");
63220caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n",
636c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		  batch->start, batch->used, batch->num_cliprects);
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
638546b0974c39657017407c86fe79811100b60700dEric Anholt	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
640c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
641c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt						       batch->num_cliprects *
642c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie						       sizeof(struct drm_clip_rect)))
64320caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EFAULT;
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
645546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_lock(&dev->struct_mutex);
646c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	ret = i915_dispatch_batchbuffer(dev, batch);
647546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_unlock(&dev->struct_mutex);
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
649c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg	if (sarea_priv)
6500baf823a10bd4131f70e9712d1f02de3c247f1dfKeith Packard		sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
654c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_cmdbuffer(struct drm_device *dev, void *data,
655c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			  struct drm_file *file_priv)
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
6587c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
6607c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	    master_priv->sarea_priv;
661c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_cmdbuffer_t *cmdbuf = data;
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
665c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		  cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
667546b0974c39657017407c86fe79811100b60700dEric Anholt	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
669c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	if (cmdbuf->num_cliprects &&
670c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	    DRM_VERIFYAREA_READ(cmdbuf->cliprects,
671c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt				cmdbuf->num_cliprects *
672c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie				sizeof(struct drm_clip_rect))) {
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("Fault accessing cliprects\n");
67420caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EFAULT;
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
677546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_lock(&dev->struct_mutex);
678c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
679546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_unlock(&dev->struct_mutex);
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ret) {
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ret;
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
685c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg	if (sarea_priv)
6860baf823a10bd4131f70e9712d1f02de3c247f1dfKeith Packard		sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
690c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_flip_bufs(struct drm_device *dev, void *data,
691c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			  struct drm_file *file_priv)
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
693546b0974c39657017407c86fe79811100b60700dEric Anholt	int ret;
694546b0974c39657017407c86fe79811100b60700dEric Anholt
69580a914dc05683ecfc98f9e1887fd6564846ffbecHarvey Harrison	DRM_DEBUG("%s\n", __func__);
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
697546b0974c39657017407c86fe79811100b60700dEric Anholt	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
699546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_lock(&dev->struct_mutex);
700546b0974c39657017407c86fe79811100b60700dEric Anholt	ret = i915_dispatch_flip(dev);
701546b0974c39657017407c86fe79811100b60700dEric Anholt	mutex_unlock(&dev->struct_mutex);
702546b0974c39657017407c86fe79811100b60700dEric Anholt
703546b0974c39657017407c86fe79811100b60700dEric Anholt	return ret;
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
706c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_getparam(struct drm_device *dev, void *data,
707c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			 struct drm_file *file_priv)
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
710c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_getparam_t *param = data;
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int value;
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev_priv) {
7143e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh		DRM_ERROR("called with no initialization\n");
71520caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
718c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	switch (param->param) {
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_PARAM_IRQ_ACTIVE:
7200a3e67a4caac273a3bfc4ced3da364830b1ab241Jesse Barnes		value = dev->pdev->irq ? 1 : 0;
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_PARAM_ALLOW_BATCHBUFFER:
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		value = dev_priv->allow_batchbuffer ? 1 : 0;
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7250d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie	case I915_PARAM_LAST_DISPATCH:
7260d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie		value = READ_BREADCRUMB(dev_priv);
7270d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie		break;
728ed4c9c4acf948b42b138747fcb8843ecb1a24ce4Kristian Høgsberg	case I915_PARAM_CHIPSET_ID:
729ed4c9c4acf948b42b138747fcb8843ecb1a24ce4Kristian Høgsberg		value = dev->pci_device;
730ed4c9c4acf948b42b138747fcb8843ecb1a24ce4Kristian Høgsberg		break;
731673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	case I915_PARAM_HAS_GEM:
732ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie		value = dev_priv->has_gem;
733673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		break;
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
735c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		DRM_ERROR("Unknown parameter %d\n", param->param);
73620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
739c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DRM_ERROR("DRM_COPY_TO_USER failed\n");
74120caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EFAULT;
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
747c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_setparam(struct drm_device *dev, void *data,
748c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt			 struct drm_file *file_priv)
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drm_i915_private_t *dev_priv = dev->dev_private;
751c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_setparam_t *param = data;
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev_priv) {
7543e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh		DRM_ERROR("called with no initialization\n");
75520caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
758c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	switch (param->param) {
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
762c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		dev_priv->tex_lru_log_granularity = param->value;
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case I915_SETPARAM_ALLOW_BATCHBUFFER:
765c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		dev_priv->allow_batchbuffer = param->value;
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
768c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt		DRM_ERROR("unknown parameter %d\n", param->param);
76920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
775c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_set_status_page(struct drm_device *dev, void *data,
776c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt				struct drm_file *file_priv)
777dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu{
778dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	drm_i915_private_t *dev_priv = dev->dev_private;
779c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	drm_i915_hws_addr_t *hws = data;
780b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang
781b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang	if (!I915_NEED_GFX_HWS(dev))
782b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang		return -EINVAL;
783dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
784dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	if (!dev_priv) {
7853e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh		DRM_ERROR("called with no initialization\n");
78620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -EINVAL;
787dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	}
788dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
78979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
79079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		WARN(1, "tried to set status page when mode setting active\n");
79179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		return 0;
79279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	}
79379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
794c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr);
795c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt
796c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
797dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
7988b40958032fd236194de57d29be9cf2c1f2643eeEric Anholt	dev_priv->hws_map.offset = dev->agp->base + hws->addr;
799dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	dev_priv->hws_map.size = 4*1024;
800dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	dev_priv->hws_map.type = 0;
801dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	dev_priv->hws_map.flags = 0;
802dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	dev_priv->hws_map.mtrr = 0;
803dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
804dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	drm_core_ioremap(&dev_priv->hws_map, dev);
805dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	if (dev_priv->hws_map.handle == NULL) {
806dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu		i915_dma_cleanup(dev);
807dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu		dev_priv->status_gfx_addr = 0;
808dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu		DRM_ERROR("can not ioremap virtual address for"
809dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu				" G33 hw status page\n");
81020caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt		return -ENOMEM;
811dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	}
812dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	dev_priv->hw_status_page = dev_priv->hws_map.handle;
813dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
814dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
815585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
816585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes	DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n",
817dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu			dev_priv->status_gfx_addr);
818dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
819dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu	return 0;
820dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu}
821dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu
82279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes/**
82379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * i915_probe_agp - get AGP bootup configuration
82479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * @pdev: PCI device
82579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * @aperture_size: returns AGP aperture configured size
82679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * @preallocated_size: returns size of BIOS preallocated AGP space
82779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes *
82879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * Since Intel integrated graphics are UMA, the BIOS has to set aside
82979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * some RAM for the framebuffer at early boot.  This code figures out
83079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * how much was set aside so we can use it for our own purposes.
83179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes */
832b358d0a6252d8ed16afb20caaec35b24c76074bbHannes Ederstatic int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
833b358d0a6252d8ed16afb20caaec35b24c76074bbHannes Eder			  unsigned long *preallocated_size)
83479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes{
83579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	struct pci_dev *bridge_dev;
83679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	u16 tmp = 0;
83779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	unsigned long overhead;
838241fa85b2bb655224357d713c251077dee3585ceEric Anholt	unsigned long stolen;
83979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
84079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
84179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (!bridge_dev) {
84279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		DRM_ERROR("bridge device not found\n");
84379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		return -1;
84479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	}
84579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
84679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	/* Get the fb aperture size and "stolen" memory amount. */
84779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
84879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	pci_dev_put(bridge_dev);
84979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
85079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	*aperture_size = 1024 * 1024;
85179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	*preallocated_size = 1024 * 1024;
85279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
85360fd99e3682c5acc74d58ed61dac93526d6976f7Eric Anholt	switch (dev->pdev->device) {
85479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case PCI_DEVICE_ID_INTEL_82830_CGC:
85579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case PCI_DEVICE_ID_INTEL_82845G_IG:
85679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case PCI_DEVICE_ID_INTEL_82855GM_IG:
85779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case PCI_DEVICE_ID_INTEL_82865_IG:
85879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M)
85979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes			*aperture_size *= 64;
86079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		else
86179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes			*aperture_size *= 128;
86279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		break;
86379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	default:
86479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		/* 9xx supports large sizes, just look at the length */
86560fd99e3682c5acc74d58ed61dac93526d6976f7Eric Anholt		*aperture_size = pci_resource_len(dev->pdev, 2);
86679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		break;
86779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	}
86879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
86979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	/*
87079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	 * Some of the preallocated space is taken by the GTT
87179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	 * and popup.  GTT is 1K per MB of aperture size, and popup is 4K.
87279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	 */
87360fd99e3682c5acc74d58ed61dac93526d6976f7Eric Anholt	if (IS_G4X(dev))
87460fd99e3682c5acc74d58ed61dac93526d6976f7Eric Anholt		overhead = 4096;
87560fd99e3682c5acc74d58ed61dac93526d6976f7Eric Anholt	else
87660fd99e3682c5acc74d58ed61dac93526d6976f7Eric Anholt		overhead = (*aperture_size / 1024) + 4096;
87760fd99e3682c5acc74d58ed61dac93526d6976f7Eric Anholt
878241fa85b2bb655224357d713c251077dee3585ceEric Anholt	switch (tmp & INTEL_GMCH_GMS_MASK) {
879241fa85b2bb655224357d713c251077dee3585ceEric Anholt	case INTEL_855_GMCH_GMS_DISABLED:
880241fa85b2bb655224357d713c251077dee3585ceEric Anholt		DRM_ERROR("video memory is disabled\n");
881241fa85b2bb655224357d713c251077dee3585ceEric Anholt		return -1;
88279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case INTEL_855_GMCH_GMS_STOLEN_1M:
883241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 1 * 1024 * 1024;
884241fa85b2bb655224357d713c251077dee3585ceEric Anholt		break;
88579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case INTEL_855_GMCH_GMS_STOLEN_4M:
886241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 4 * 1024 * 1024;
88779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		break;
88879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case INTEL_855_GMCH_GMS_STOLEN_8M:
889241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 8 * 1024 * 1024;
89079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		break;
89179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case INTEL_855_GMCH_GMS_STOLEN_16M:
892241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 16 * 1024 * 1024;
89379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		break;
89479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case INTEL_855_GMCH_GMS_STOLEN_32M:
895241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 32 * 1024 * 1024;
89679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		break;
89779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case INTEL_915G_GMCH_GMS_STOLEN_48M:
898241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 48 * 1024 * 1024;
89979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		break;
90079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	case INTEL_915G_GMCH_GMS_STOLEN_64M:
901241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 64 * 1024 * 1024;
902241fa85b2bb655224357d713c251077dee3585ceEric Anholt		break;
903241fa85b2bb655224357d713c251077dee3585ceEric Anholt	case INTEL_GMCH_GMS_STOLEN_128M:
904241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 128 * 1024 * 1024;
905241fa85b2bb655224357d713c251077dee3585ceEric Anholt		break;
906241fa85b2bb655224357d713c251077dee3585ceEric Anholt	case INTEL_GMCH_GMS_STOLEN_256M:
907241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 256 * 1024 * 1024;
908241fa85b2bb655224357d713c251077dee3585ceEric Anholt		break;
909241fa85b2bb655224357d713c251077dee3585ceEric Anholt	case INTEL_GMCH_GMS_STOLEN_96M:
910241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 96 * 1024 * 1024;
911241fa85b2bb655224357d713c251077dee3585ceEric Anholt		break;
912241fa85b2bb655224357d713c251077dee3585ceEric Anholt	case INTEL_GMCH_GMS_STOLEN_160M:
913241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 160 * 1024 * 1024;
914241fa85b2bb655224357d713c251077dee3585ceEric Anholt		break;
915241fa85b2bb655224357d713c251077dee3585ceEric Anholt	case INTEL_GMCH_GMS_STOLEN_224M:
916241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 224 * 1024 * 1024;
917241fa85b2bb655224357d713c251077dee3585ceEric Anholt		break;
918241fa85b2bb655224357d713c251077dee3585ceEric Anholt	case INTEL_GMCH_GMS_STOLEN_352M:
919241fa85b2bb655224357d713c251077dee3585ceEric Anholt		stolen = 352 * 1024 * 1024;
92079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		break;
92179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	default:
92279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n",
923241fa85b2bb655224357d713c251077dee3585ceEric Anholt			tmp & INTEL_GMCH_GMS_MASK);
92479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		return -1;
92579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	}
926241fa85b2bb655224357d713c251077dee3585ceEric Anholt	*preallocated_size = stolen - overhead;
92779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
92879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	return 0;
92979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes}
93079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
93179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnesstatic int i915_load_modeset_init(struct drm_device *dev)
93279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes{
93379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	struct drm_i915_private *dev_priv = dev->dev_private;
93479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	unsigned long agp_size, prealloc_size;
93579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	int fb_bar = IS_I9XX(dev) ? 2 : 0;
93679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	int ret = 0;
93779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
938aa5966296675a5092505f68d72563d5939a92353Dave Airlie	dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL);
939aa5966296675a5092505f68d72563d5939a92353Dave Airlie	if (!dev->devname) {
940aa5966296675a5092505f68d72563d5939a92353Dave Airlie		ret = -ENOMEM;
941aa5966296675a5092505f68d72563d5939a92353Dave Airlie		goto out;
942aa5966296675a5092505f68d72563d5939a92353Dave Airlie	}
943aa5966296675a5092505f68d72563d5939a92353Dave Airlie
94479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
94579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		0xff000000;
94679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
9472906f0258770d3a9c4e65364df8acc904e148bbeJesse Barnes	if (IS_MOBILE(dev) || IS_I9XX(dev))
94879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		dev_priv->cursor_needs_physical = true;
94979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	else
95079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		dev_priv->cursor_needs_physical = false;
95179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
9522906f0258770d3a9c4e65364df8acc904e148bbeJesse Barnes	if (IS_I965G(dev) || IS_G33(dev))
9532906f0258770d3a9c4e65364df8acc904e148bbeJesse Barnes		dev_priv->cursor_needs_physical = false;
9542906f0258770d3a9c4e65364df8acc904e148bbeJesse Barnes
955aa5966296675a5092505f68d72563d5939a92353Dave Airlie	ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
956aa5966296675a5092505f68d72563d5939a92353Dave Airlie	if (ret)
957aa5966296675a5092505f68d72563d5939a92353Dave Airlie		goto kfree_devname;
95879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
95979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	/* Basic memrange allocator for stolen space (aka vram) */
96079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	drm_mm_init(&dev_priv->vram, 0, prealloc_size);
96179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
96279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	/* Let GEM Manage from end of prealloc space to end of aperture */
96379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	i915_gem_do_init(dev, prealloc_size, agp_size);
96479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
96579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	ret = i915_gem_init_ringbuffer(dev);
96679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (ret)
967aa5966296675a5092505f68d72563d5939a92353Dave Airlie		goto kfree_devname;
96879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
96979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes        dev_priv->mm.gtt_mapping =
97079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		io_mapping_create_wc(dev->agp->base,
97179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes				     dev->agp->agp_info.aper_size * 1024*1024);
97279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
97379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	/* Allow hardware batchbuffers unless told otherwise.
97479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	 */
97579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	dev_priv->allow_batchbuffer = 1;
97679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
97779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	ret = intel_init_bios(dev);
97879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (ret)
97979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		DRM_INFO("failed to find VBIOS tables\n");
98079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
98179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	ret = drm_irq_install(dev);
98279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (ret)
98379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		goto destroy_ringbuffer;
98479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
98579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	/* FIXME: re-add hotplug support */
98679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes#if 0
98779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	ret = drm_hotplug_init(dev);
98879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (ret)
98979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		goto destroy_ringbuffer;
99079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes#endif
99179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
99279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	/* Always safe in the mode setting case. */
99379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	/* FIXME: do pre/post-mode set stuff in core KMS code */
99479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	dev->vblank_disable_allowed = 1;
99579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
99679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	/*
99779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	 * Initialize the hardware status page IRQ location.
99879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	 */
99979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
100079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
100179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
100279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	intel_modeset_init(dev);
100379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
100479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	drm_helper_initial_config(dev, false);
100579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
100679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	return 0;
100779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
100879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnesdestroy_ringbuffer:
100979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	i915_gem_cleanup_ringbuffer(dev);
1010aa5966296675a5092505f68d72563d5939a92353Dave Airliekfree_devname:
1011aa5966296675a5092505f68d72563d5939a92353Dave Airlie	kfree(dev->devname);
101279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnesout:
101379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	return ret;
101479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes}
101579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
10167c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlieint i915_master_create(struct drm_device *dev, struct drm_master *master)
10177c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{
10187c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv;
10197c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
10207c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER);
10217c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (!master_priv)
10227c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		return -ENOMEM;
10237c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
10247c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master->driver_priv = master_priv;
10257c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	return 0;
10267c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie}
10277c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
10287c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlievoid i915_master_destroy(struct drm_device *dev, struct drm_master *master)
10297c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{
10307c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	struct drm_i915_master_private *master_priv = master->driver_priv;
10317c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
10327c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	if (!master_priv)
10337c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie		return;
10347c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
10357c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER);
10367c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
10377c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie	master->driver_priv = NULL;
10387c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie}
10397c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie
104079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes/**
104179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * i915_driver_load - setup chip and create an initial config
104279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * @dev: DRM device
104379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * @flags: startup flags
104479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes *
104579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * The driver load routine has to do several things:
104679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes *   - drive output discovery via intel_modeset_init()
104779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes *   - initialize the memory manager
104879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes *   - allocate initial config memory
104979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes *   - setup the DRM framebuffer with the allocated memory
105079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes */
105184b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_driver_load(struct drm_device *dev, unsigned long flags)
105222eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie{
1053ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	struct drm_i915_private *dev_priv = dev->dev_private;
1054ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	unsigned long base, size;
1055ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
1056ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
105722eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	/* i915 has 4 more counters */
105822eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	dev->counters += 4;
105922eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	dev->types[6] = _DRM_STAT_IRQ;
106022eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	dev->types[7] = _DRM_STAT_PRIMARY;
106122eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	dev->types[8] = _DRM_STAT_SECONDARY;
106222eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	dev->types[9] = _DRM_STAT_DMA;
106322eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie
1064ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER);
1065ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	if (dev_priv == NULL)
1066ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes		return -ENOMEM;
1067ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
1068ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	memset(dev_priv, 0, sizeof(drm_i915_private_t));
1069ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
1070ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	dev->dev_private = (void *)dev_priv;
1071673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	dev_priv->dev = dev;
1072ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
1073ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	/* Add register map (needed for suspend/resume) */
1074ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	base = drm_get_resource_start(dev, mmio_bar);
1075ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	size = drm_get_resource_len(dev, mmio_bar);
1076ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
10773043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholt	dev_priv->regs = ioremap(base, size);
107879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (!dev_priv->regs) {
107979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		DRM_ERROR("failed to map registers\n");
108079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		ret = -EIO;
108179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		goto free_priv;
108279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	}
1083ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt
1084ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie#ifdef CONFIG_HIGHMEM64G
1085ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie	/* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */
1086ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie	dev_priv->has_gem = 0;
1087ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie#else
1088ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie	/* enable GEM by default */
1089ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie	dev_priv->has_gem = 1;
1090ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie#endif
1091ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie
1092673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	i915_gem_load(dev);
1093673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
1094398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	/* Init HWS */
1095398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	if (!I915_NEED_GFX_HWS(dev)) {
1096398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		ret = i915_init_phys_hws(dev);
1097398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard		if (ret != 0)
109879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes			goto out_rmmap;
1099398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard	}
1100ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt
1101ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	/* On the 945G/GM, the chipset reports the MSI capability on the
1102ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 * integrated graphics even though the support isn't actually there
1103ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 * according to the published specs.  It doesn't appear to function
1104ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 * correctly in testing on 945G.
1105ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 * This may be a side effect of MSI having been made available for PEG
1106ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 * and the registers being closely associated.
1107d1ed629f44b3a4108d5c445971535f05f441fce7Keith Packard	 *
1108d1ed629f44b3a4108d5c445971535f05f441fce7Keith Packard	 * According to chipset errata, on the 965GM, MSI interrupts may
1109b60678a75d44fa9d5969f79781bd856ad5858609Keith Packard	 * be lost or delayed, but we use them anyways to avoid
1110b60678a75d44fa9d5969f79781bd856ad5858609Keith Packard	 * stuck interrupts on some machines.
1111ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	 */
1112b60678a75d44fa9d5969f79781bd856ad5858609Keith Packard	if (!IS_I945G(dev) && !IS_I945GM(dev))
1113d3e74d0237b102d34979015fbf6df02ca4413074Eric Anholt		pci_enable_msi(dev->pdev);
1114ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt
11158ee1c3db9075cb3211352e737e0feb98fd733b20Matthew Garrett	intel_opregion_init(dev);
11168ee1c3db9075cb3211352e737e0feb98fd733b20Matthew Garrett
1117ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	spin_lock_init(&dev_priv->user_irq_lock);
111879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	dev_priv->user_irq_refcount = 0;
1119ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt
112052440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard	ret = drm_vblank_init(dev, I915_NUM_PIPE);
112152440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard
112252440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard	if (ret) {
112352440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard		(void) i915_driver_unload(dev);
112452440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard		return ret;
112552440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard	}
112652440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard
112779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
112879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		ret = i915_load_modeset_init(dev);
112979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		if (ret < 0) {
113079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes			DRM_ERROR("failed to init modeset\n");
113179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes			goto out_rmmap;
113279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		}
113379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	}
113479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
113579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	return 0;
113679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
113779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnesout_rmmap:
113879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	iounmap(dev_priv->regs);
113979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnesfree_priv:
114079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	drm_free(dev_priv, sizeof(struct drm_i915_private), DRM_MEM_DRIVER);
1141ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	return ret;
1142ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes}
1143ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
1144ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnesint i915_driver_unload(struct drm_device *dev)
1145ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes{
1146ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	struct drm_i915_private *dev_priv = dev->dev_private;
1147ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
114879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
114979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		io_mapping_free(dev_priv->mm.gtt_mapping);
115079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		drm_irq_uninstall(dev);
115179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	}
115279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
1153ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt	if (dev->pdev->msi_enabled)
1154ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt		pci_disable_msi(dev->pdev);
1155ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt
11563043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholt	if (dev_priv->regs != NULL)
11573043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholt		iounmap(dev_priv->regs);
1158ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
11598ee1c3db9075cb3211352e737e0feb98fd733b20Matthew Garrett	intel_opregion_free(dev);
11608ee1c3db9075cb3211352e737e0feb98fd733b20Matthew Garrett
116179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
116279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		intel_modeset_cleanup(dev);
116379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
116471acb5eb8d95b371f4cdd88a47f3c83c870d1c8fDave Airlie		i915_gem_free_all_phys_object(dev);
116571acb5eb8d95b371f4cdd88a47f3c83c870d1c8fDave Airlie
116679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		mutex_lock(&dev->struct_mutex);
116779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		i915_gem_cleanup_ringbuffer(dev);
116879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		mutex_unlock(&dev->struct_mutex);
116979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		drm_mm_takedown(&dev_priv->vram);
117079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		i915_gem_lastclose(dev);
117179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	}
117279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes
1173ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	drm_free(dev->dev_private, sizeof(drm_i915_private_t),
1174ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes		 DRM_MEM_DRIVER);
1175ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
117622eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie	return 0;
117722eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie}
117822eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie
1179673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholtint i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
1180673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt{
1181673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	struct drm_i915_file_private *i915_file_priv;
1182673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
1183673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_DEBUG("\n");
1184673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	i915_file_priv = (struct drm_i915_file_private *)
1185673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	    drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES);
1186673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
1187673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	if (!i915_file_priv)
1188673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt		return -ENOMEM;
1189673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
1190673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	file_priv->driver_priv = i915_file_priv;
1191673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
1192673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	i915_file_priv->mm.last_gem_seqno = 0;
1193673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	i915_file_priv->mm.last_gem_throttle_seqno = 0;
1194673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
1195673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	return 0;
1196673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt}
1197673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
119879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes/**
119979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * i915_driver_lastclose - clean up after all DRM clients have exited
120079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * @dev: DRM device
120179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes *
120279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * Take care of cleaning up after all DRM clients have exited.  In the
120379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * mode setting case, we want to restore the kernel's initial mode (just
120479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * in case the last client left us in a bad state).
120579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes *
120679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * Additionally, in the non-mode setting case, we'll tear down the AGP
120779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * and DMA structures, since the kernel won't be using them, and clea
120879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * up any GEM state.
120979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes */
121084b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlievoid i915_driver_lastclose(struct drm_device * dev)
12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1212ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
1213ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
121479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) {
121579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		intelfb_restore();
1216144a75fa1faa4a81530bded2e59872ef80d496b6Dave Airlie		return;
121779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	}
1218144a75fa1faa4a81530bded2e59872ef80d496b6Dave Airlie
1219673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	i915_gem_lastclose(dev);
1220673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
1221ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	if (dev_priv->agp_heap)
1222b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie		i915_mem_takedown(&(dev_priv->agp_heap));
1223ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes
1224b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie	i915_dma_cleanup(dev);
12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12276c340eac0285f3d62406d2d902d0e96fbf2a5dc0Eric Anholtvoid i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1229ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes	drm_i915_private_t *dev_priv = dev->dev_private;
123079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes	if (!drm_core_check_feature(dev, DRIVER_MODESET))
123179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes		i915_mem_release(dev, file_priv, dev_priv->agp_heap);
12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1234673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholtvoid i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
1235673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt{
1236673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
1237673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
1238673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES);
1239673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt}
1240673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt
1241c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstruct drm_ioctl_desc i915_ioctls[] = {
1242c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1243c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
1244c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH),
1245c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH),
1246c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH),
1247c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH),
1248c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH),
1249c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1250c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH),
1251c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH),
1252c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1253c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH),
1254c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP,  i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
1255c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE,  i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
1256c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE,  i915_vblank_pipe_get, DRM_AUTH ),
1257c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt	DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
12584b40893918203ee1a1f6a114316c2a19c072e9bdMatthias Hopf	DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
12592bdf00b22154023ac312481583603f4724eb1401Dave Airlie	DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1260673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
1261673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1262673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1263673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
1264673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
12652bdf00b22154023ac312481583603f4724eb1401Dave Airlie	DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
12662bdf00b22154023ac312481583603f4724eb1401Dave Airlie	DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1267673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
1268673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
1269673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
1270673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
1271de151cf67ce52ed2d88083daa5e60c7858947329Jesse Barnes	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 0),
1272673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
1273673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
1274673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
1275673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
12765a125c3c79167e78ba44efef03af7090ef28eeafEric Anholt	DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0),
1277c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie};
1278c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie
1279c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlieint i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1280cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie
1281cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie/**
1282cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * Determine if the device really is AGP or not.
1283cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie *
1284cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * All Intel graphics chipsets are treated as AGP, even if they are really
1285cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * PCI-e.
1286cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie *
1287cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * \param dev   The device to be tested.
1288cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie *
1289cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * \returns
1290cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * A value of 1 is always retured to indictate every i9x5 is AGP.
1291cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie */
129284b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_driver_device_is_agp(struct drm_device * dev)
1293cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie{
1294cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie	return 1;
1295cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie}
1296