i915_dma.c revision 80a914dc05683ecfc98f9e1887fd6564846ffbec
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 30d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie/* 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All Rights Reserved. 6bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * 7bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * Permission is hereby granted, free of charge, to any person obtaining a 8bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * copy of this software and associated documentation files (the 9bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * "Software"), to deal in the Software without restriction, including 10bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * without limitation the rights to use, copy, modify, merge, publish, 11bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * distribute, sub license, and/or sell copies of the Software, and to 12bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * permit persons to whom the Software is furnished to do so, subject to 13bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * the following conditions: 14bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * 15bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * The above copyright notice and this permission notice (including the 16bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * next paragraph) shall be included in all copies or substantial portions 17bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * of the Software. 18bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * 19bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 23bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * 270d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie */ 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "drmP.h" 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "drm.h" 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "i915_drm.h" 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "i915_drv.h" 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Really want an OS-independent resettable timer. Would like to have 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * this loop run for (eg) 3 sec, but have the timer reset every time 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the head pointer changes, so that EBUSY only happens if the ring 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * actually stalls for (eg) 3 seconds. 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3984b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_wait_ring(struct drm_device * dev, int n, const char *caller) 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 10000; i++) { 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ring->space = ring->head - (ring->tail + 8); 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ring->space < 0) 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ring->space += ring->Size; 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ring->space >= n) 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ring->head != last_head) 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = 0; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds last_head = ring->head; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6220caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EBUSY; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6584b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlievoid i915_kernel_lost_context(struct drm_device * dev) 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ring->space = ring->head - (ring->tail + 8); 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ring->space < 0) 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ring->space += ring->Size; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ring->head == ring->tail) 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8084b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dma_cleanup(struct drm_device * dev) 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 82ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_i915_private_t *dev_priv = dev->dev_private; 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make sure interrupts are disabled here because the uninstall ioctl 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * may not have been called from userspace and after dev_private 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is freed, it's too late. 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->irq) 88b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie drm_irq_uninstall(dev); 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 90ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes if (dev_priv->ring.virtual_start) { 91ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_core_ioremapfree(&dev_priv->ring.map, dev); 92ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes dev_priv->ring.virtual_start = 0; 93ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes dev_priv->ring.map.handle = 0; 94ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes dev_priv->ring.map.size = 0; 95ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes } 96dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 97ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes if (dev_priv->status_page_dmah) { 98ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_pci_free(dev, dev_priv->status_page_dmah); 99ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes dev_priv->status_page_dmah = NULL; 100ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes /* Need to rewrite hardware status page */ 101ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes I915_WRITE(0x02080, 0x1ffff000); 102ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes } 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 104ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes if (dev_priv->status_gfx_addr) { 105ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes dev_priv->status_gfx_addr = 0; 106ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_core_ioremapfree(&dev_priv->hws_map, dev); 107ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes I915_WRITE(0x2080, 0x1ffff000); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 113ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnesstatic int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 115ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_i915_private_t *dev_priv = dev->dev_private; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 117da509d7a02cb54938776439edc81f057e39f81e0Dave Airlie dev_priv->sarea = drm_getsarea(dev); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv->sarea) { 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("can not find sarea!\n"); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i915_dma_cleanup(dev); 12120caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv->mmio_map) { 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i915_dma_cleanup(dev); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("can not find mmio map!\n"); 12820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->sarea_priv = (drm_i915_sarea_t *) 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->ring.Start = init->ring_start; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->ring.End = init->ring_end; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->ring.Size = init->ring_size; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->ring.map.offset = init->ring_start; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->ring.map.size = init->ring_size; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->ring.map.type = 0; 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->ring.map.flags = 0; 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->ring.map.mtrr = 0; 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 145b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie drm_core_ioremap(&dev_priv->ring.map, dev); 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev_priv->ring.map.handle == NULL) { 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i915_dma_cleanup(dev); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("can not ioremap virtual address for" 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " ring buffer\n"); 15120caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -ENOMEM; 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->ring.virtual_start = dev_priv->ring.map.handle; 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 156a6b54f3f5050c0cbc0c35dd48064846c6302706bMichel Dänzer dev_priv->cpp = init->cpp; 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->back_offset = init->back_offset; 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->front_offset = init->front_offset; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->current_page = 0; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We are using separate values as placeholders for mechanisms for 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * private backbuffer/depthbuffer usage. 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->use_mi_batchbuffer_start = 0; 16621f16289270447673a7263ccc0b22d562fb01ecbDave Airlie if (IS_I965G(dev)) /* 965 doesn't support older method */ 16721f16289270447673a7263ccc0b22d562fb01ecbDave Airlie dev_priv->use_mi_batchbuffer_start = 1; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allow hardware batchbuffers unless told otherwise. 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->allow_batchbuffer = 1; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Program Hardware Status Page */ 174b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang if (!I915_NEED_GFX_HWS(dev)) { 175dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->status_page_dmah = 176dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); 177dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 178dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu if (!dev_priv->status_page_dmah) { 179dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu i915_dma_cleanup(dev); 180dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu DRM_ERROR("Can not allocate hardware status page\n"); 18120caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -ENOMEM; 182dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu } 183dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; 184dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 186dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 187dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu I915_WRITE(0x02080, dev_priv->dma_status_page); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_DEBUG("Enabled hardware status page\n"); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19384b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dma_resume(struct drm_device * dev) 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 197bf9d89295233ae2ba7b312c78ee5657307b09f4cHarvey Harrison DRM_DEBUG("%s\n", __func__); 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv->sarea) { 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("can not find sarea!\n"); 20120caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv->mmio_map) { 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("can not find mmio map!\n"); 20620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev_priv->ring.map.handle == NULL) { 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("can not ioremap virtual address for" 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " ring buffer\n"); 21220caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -ENOMEM; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Program Hardware Status Page */ 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv->hw_status_page) { 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("Can not find hardware status page\n"); 21820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 222dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu if (dev_priv->status_gfx_addr != 0) 223dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu I915_WRITE(0x02080, dev_priv->status_gfx_addr); 224dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu else 225dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu I915_WRITE(0x02080, dev_priv->dma_status_page); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_DEBUG("Enabled hardware status page\n"); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 231c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_dma_init(struct drm_device *dev, void *data, 232c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 234c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_init_t *init = data; 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retcode = 0; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 237c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt switch (init->func) { 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_INIT_DMA: 239ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes retcode = i915_initialize(dev, init); 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_CLEANUP_DMA: 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retcode = i915_dma_cleanup(dev); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_RESUME_DMA: 2450d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie retcode = i915_dma_resume(dev); 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 24820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt retcode = -EINVAL; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retcode; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Implement basically the same security restrictions as hardware does 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for MI_BATCH_NON_SECURE. These can be made stricter at any time. 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Most of the calculations below involve calculating the size of a 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * particular instruction. It's important to get the size right as 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that tells us where the next instruction to check is. Any illegal 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * instruction detected will be given a size of zero, which is a 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * signal to abort the rest of the buffer. 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int do_validate_cmd(int cmd) 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (((cmd >> 29) & 0x7)) { 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x0: 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch ((cmd >> 23) & 0x3f) { 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x0: 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; /* MI_NOOP */ 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x4: 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; /* MI_FLUSH */ 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; /* disallow everything else */ 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1: 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; /* reserved */ 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x2: 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0xff) + 2; /* 2d commands */ 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x3: 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((cmd >> 24) & 0x1f) <= 0x18) 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch ((cmd >> 24) & 0x1f) { 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1c: 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1d: 289b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie switch ((cmd >> 16) & 0xff) { 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x3: 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0x1f) + 2; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x4: 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0xf) + 2; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0xffff) + 2; 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1e: 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd & (1 << 23)) 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0xffff) + 1; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1f: 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cmd & (1 << 23)) == 0) /* inline vertices */ 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0x1ffff) + 2; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (cmd & (1 << 17)) /* indirect random */ 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cmd & 0xffff) == 0) 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; /* unknown length, too hard */ 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (((cmd & 0xffff) + 1) / 2) + 1; 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 2; /* indirect sequential */ 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int validate_cmd(int cmd) 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = do_validate_cmd(cmd); 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 326bc5f4523f772cc7629c5c5a46cf4f2a07a5500b8Dave Airlie/* printk("validate_cmd( %x ): %d\n", cmd, ret); */ 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33184b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords) 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds RING_LOCALS; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 337de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) 33820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 339de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 340c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane BEGIN_LP_RING((dwords+1)&~1); 341de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < dwords;) { 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cmd, sz; 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) 34620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) 34920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OUT_RING(cmd); 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (++i, --sz) { 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(cmd))) { 35620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OUT_RING(cmd); 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 362de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie if (dwords & 1) 363de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie OUT_RING(0); 364de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 365de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie ADVANCE_LP_RING(); 366de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37084b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_emit_box(struct drm_device * dev, 371c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie struct drm_clip_rect __user * boxes, 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, int DR1, int DR4) 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 375c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie struct drm_clip_rect box; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds RING_LOCALS; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { 37920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EFAULT; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("Bad box %d,%d..%d,%d\n", 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds box.x1, box.y1, box.x2, box.y2); 38520caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 388c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane if (IS_I965G(dev)) { 389c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane BEGIN_LP_RING(4); 390c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(GFX_OP_DRAWRECT_INFO_I965); 391c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); 39278eca43d0391f59c3b1505bb7bd38ff45b650aabAndrew Morton OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); 393c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(DR4); 394c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane ADVANCE_LP_RING(); 395c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane } else { 396c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane BEGIN_LP_RING(6); 397c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(GFX_OP_DRAWRECT_INFO); 398c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(DR1); 399c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); 400c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); 401c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(DR4); 402c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(0); 403c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane ADVANCE_LP_RING(); 404c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane } 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 409c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane/* XXX: Emitting the counter should really be moved to part of the IRQ 410c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane * emit. For now, do it in both places: 411c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane */ 412c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane 41384b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic void i915_emit_breadcrumb(struct drm_device *dev) 414de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie{ 415de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie drm_i915_private_t *dev_priv = dev->dev_private; 416de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie RING_LOCALS; 417de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 418af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; 419c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane 420af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie if (dev_priv->counter > 0x7FFFFFFFUL) 421af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; 422de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 423de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie BEGIN_LP_RING(4); 424de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie OUT_RING(CMD_STORE_DWORD_IDX); 425de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie OUT_RING(20); 426de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie OUT_RING(dev_priv->counter); 427de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie OUT_RING(0); 428de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie ADVANCE_LP_RING(); 429de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie} 430de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 43184b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dispatch_cmdbuffer(struct drm_device * dev, 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_cmdbuffer_t * cmd) 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int nbox = cmd->num_cliprects; 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 0, count, ret; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd->sz & 0x3) { 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("alignment"); 43920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i915_kernel_lost_context(dev); 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = nbox ? nbox : 1; 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < count; i++) { 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i < nbox) { 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = i915_emit_box(dev, cmd->cliprects, i, 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd->DR1, cmd->DR4); 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret) 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4); 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret) 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 459de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie i915_emit_breadcrumb(dev); 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46384b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dispatch_batchbuffer(struct drm_device * dev, 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_batchbuffer_t * batch) 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 467c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie struct drm_clip_rect __user *boxes = batch->cliprects; 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int nbox = batch->num_cliprects; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 0, count; 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds RING_LOCALS; 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((batch->start | batch->used) & 0x7) { 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("alignment"); 47420caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i915_kernel_lost_context(dev); 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = nbox ? nbox : 1; 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < count; i++) { 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i < nbox) { 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = i915_emit_box(dev, boxes, i, 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds batch->DR1, batch->DR4); 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret) 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev_priv->use_mi_batchbuffer_start) { 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BEGIN_LP_RING(2); 49121f16289270447673a7263ccc0b22d562fb01ecbDave Airlie if (IS_I965G(dev)) { 49221f16289270447673a7263ccc0b22d562fb01ecbDave Airlie OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); 49321f16289270447673a7263ccc0b22d562fb01ecbDave Airlie OUT_RING(batch->start); 49421f16289270447673a7263ccc0b22d562fb01ecbDave Airlie } else { 49521f16289270447673a7263ccc0b22d562fb01ecbDave Airlie OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); 49621f16289270447673a7263ccc0b22d562fb01ecbDave Airlie OUT_RING(batch->start | MI_BATCH_NON_SECURE); 49721f16289270447673a7263ccc0b22d562fb01ecbDave Airlie } 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ADVANCE_LP_RING(); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BEGIN_LP_RING(4); 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OUT_RING(MI_BATCH_BUFFER); 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OUT_RING(batch->start | MI_BATCH_NON_SECURE); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OUT_RING(batch->start + batch->used - 4); 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OUT_RING(0); 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ADVANCE_LP_RING(); 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 509de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie i915_emit_breadcrumb(dev); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 514af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airliestatic int i915_dispatch_flip(struct drm_device * dev) 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds RING_LOCALS; 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 519af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 52080a914dc05683ecfc98f9e1887fd6564846ffbecHarvey Harrison __func__, 521af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie dev_priv->current_page, 522af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie dev_priv->sarea_priv->pf_current_page); 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 524af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie i915_kernel_lost_context(dev); 525af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie 526af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie BEGIN_LP_RING(2); 527af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); 528af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(0); 529af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie ADVANCE_LP_RING(); 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie BEGIN_LP_RING(6); 532af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); 533af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(0); 534af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie if (dev_priv->current_page == 0) { 535af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(dev_priv->back_offset); 536af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie dev_priv->current_page = 1; 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 538af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(dev_priv->front_offset); 539af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie dev_priv->current_page = 0; 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 541af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(0); 542af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie ADVANCE_LP_RING(); 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 544af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie BEGIN_LP_RING(2); 545af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); 546af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(0); 547af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie ADVANCE_LP_RING(); 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 549af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BEGIN_LP_RING(4); 552af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(CMD_STORE_DWORD_IDX); 553af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(20); 554af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(dev_priv->counter); 555af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(0); 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ADVANCE_LP_RING(); 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 558af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 559af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie return 0; 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56284b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_quiescent(struct drm_device * dev) 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i915_kernel_lost_context(dev); 567bf9d89295233ae2ba7b312c78ee5657307b09f4cHarvey Harrison return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 570c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_flush_ioctl(struct drm_device *dev, void *data, 571c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5736c340eac0285f3d62406d2d902d0e96fbf2a5dc0Eric Anholt LOCK_TEST_WITH_RETURN(dev, file_priv); 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return i915_quiescent(dev); 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 578c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_batchbuffer(struct drm_device *dev, void *data, 579c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 582af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie u32 *hw_status = dev_priv->hw_status_page; 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->sarea_priv; 585c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_batchbuffer_t *batch = data; 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv->allow_batchbuffer) { 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("Batchbuffer ioctl disabled\n"); 59020caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", 594c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt batch->start, batch->used, batch->num_cliprects); 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5966c340eac0285f3d62406d2d902d0e96fbf2a5dc0Eric Anholt LOCK_TEST_WITH_RETURN(dev, file_priv); 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 598c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, 599c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt batch->num_cliprects * 600c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie sizeof(struct drm_clip_rect))) 60120caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EFAULT; 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 603c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt ret = i915_dispatch_batchbuffer(dev, batch); 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 605af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie sarea_priv->last_dispatch = (int)hw_status[5]; 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 609c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_cmdbuffer(struct drm_device *dev, void *data, 610c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 613af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie u32 *hw_status = dev_priv->hw_status_page; 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->sarea_priv; 616c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_cmdbuffer_t *cmdbuf = data; 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", 620c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6226c340eac0285f3d62406d2d902d0e96fbf2a5dc0Eric Anholt LOCK_TEST_WITH_RETURN(dev, file_priv); 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 624c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt if (cmdbuf->num_cliprects && 625c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_VERIFYAREA_READ(cmdbuf->cliprects, 626c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt cmdbuf->num_cliprects * 627c60ce623bd16137627009d05e311d877729f2ad6Dave Airlie sizeof(struct drm_clip_rect))) { 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("Fault accessing cliprects\n"); 62920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EFAULT; 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 632c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt ret = i915_dispatch_cmdbuffer(dev, cmdbuf); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret) { 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 638af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie sarea_priv->last_dispatch = (int)hw_status[5]; 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 642c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_flip_bufs(struct drm_device *dev, void *data, 643c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 64580a914dc05683ecfc98f9e1887fd6564846ffbecHarvey Harrison DRM_DEBUG("%s\n", __func__); 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6476c340eac0285f3d62406d2d902d0e96fbf2a5dc0Eric Anholt LOCK_TEST_WITH_RETURN(dev, file_priv); 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 649af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie return i915_dispatch_flip(dev); 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 652c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_getparam(struct drm_device *dev, void *data, 653c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 656c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_getparam_t *param = data; 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int value; 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv) { 6603e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh DRM_ERROR("called with no initialization\n"); 66120caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 664c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt switch (param->param) { 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_PARAM_IRQ_ACTIVE: 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = dev->irq ? 1 : 0; 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_PARAM_ALLOW_BATCHBUFFER: 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = dev_priv->allow_batchbuffer ? 1 : 0; 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6710d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie case I915_PARAM_LAST_DISPATCH: 6720d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie value = READ_BREADCRUMB(dev_priv); 6730d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie break; 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 675c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_ERROR("Unknown parameter %d\n", param->param); 67620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 679c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("DRM_COPY_TO_USER failed\n"); 68120caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EFAULT; 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 687c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_setparam(struct drm_device *dev, void *data, 688c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 691c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_setparam_t *param = data; 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv) { 6943e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh DRM_ERROR("called with no initialization\n"); 69520caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 698c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt switch (param->param) { 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_SETPARAM_USE_MI_BATCHBUFFER_START: 70021f16289270447673a7263ccc0b22d562fb01ecbDave Airlie if (!IS_I965G(dev)) 701c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt dev_priv->use_mi_batchbuffer_start = param->value; 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: 704c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt dev_priv->tex_lru_log_granularity = param->value; 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_SETPARAM_ALLOW_BATCHBUFFER: 707c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt dev_priv->allow_batchbuffer = param->value; 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 710c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_ERROR("unknown parameter %d\n", param->param); 71120caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 717c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_set_status_page(struct drm_device *dev, void *data, 718c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 719dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu{ 720dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu drm_i915_private_t *dev_priv = dev->dev_private; 721c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_hws_addr_t *hws = data; 722b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang 723b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang if (!I915_NEED_GFX_HWS(dev)) 724b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang return -EINVAL; 725dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 726dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu if (!dev_priv) { 7273e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh DRM_ERROR("called with no initialization\n"); 72820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 729dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu } 730dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 731c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr); 732c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt 733c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); 734dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 7358b40958032fd236194de57d29be9cf2c1f2643eeEric Anholt dev_priv->hws_map.offset = dev->agp->base + hws->addr; 736dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->hws_map.size = 4*1024; 737dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->hws_map.type = 0; 738dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->hws_map.flags = 0; 739dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->hws_map.mtrr = 0; 740dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 741dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu drm_core_ioremap(&dev_priv->hws_map, dev); 742dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu if (dev_priv->hws_map.handle == NULL) { 743dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu i915_dma_cleanup(dev); 744dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->status_gfx_addr = 0; 745dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu DRM_ERROR("can not ioremap virtual address for" 746dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu " G33 hw status page\n"); 74720caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -ENOMEM; 748dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu } 749dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->hw_status_page = dev_priv->hws_map.handle; 750dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 751dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 752dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu I915_WRITE(0x02080, dev_priv->status_gfx_addr); 753dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n", 754dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->status_gfx_addr); 755dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page); 756dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu return 0; 757dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu} 758dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 75984b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_driver_load(struct drm_device *dev, unsigned long flags) 76022eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie{ 761ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes struct drm_i915_private *dev_priv = dev->dev_private; 762ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes unsigned long base, size; 763ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; 764ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 76522eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie /* i915 has 4 more counters */ 76622eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie dev->counters += 4; 76722eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie dev->types[6] = _DRM_STAT_IRQ; 76822eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie dev->types[7] = _DRM_STAT_PRIMARY; 76922eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie dev->types[8] = _DRM_STAT_SECONDARY; 77022eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie dev->types[9] = _DRM_STAT_DMA; 77122eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie 772ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); 773ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes if (dev_priv == NULL) 774ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes return -ENOMEM; 775ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 776ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes memset(dev_priv, 0, sizeof(drm_i915_private_t)); 777ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 778ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes dev->dev_private = (void *)dev_priv; 779ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 780ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes /* Add register map (needed for suspend/resume) */ 781ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes base = drm_get_resource_start(dev, mmio_bar); 782ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes size = drm_get_resource_len(dev, mmio_bar); 783ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 784e3236a1173222ca209d20bb29f6c1cd3499aa845Dave Airlie ret = drm_addmap(dev, base, size, _DRM_REGISTERS, 785e3236a1173222ca209d20bb29f6c1cd3499aa845Dave Airlie _DRM_KERNEL | _DRM_DRIVER, 786ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes &dev_priv->mmio_map); 787ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes return ret; 788ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes} 789ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 790ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnesint i915_driver_unload(struct drm_device *dev) 791ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes{ 792ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes struct drm_i915_private *dev_priv = dev->dev_private; 793ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 794ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes if (dev_priv->mmio_map) 795ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_rmmap(dev, dev_priv->mmio_map); 796ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 797ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_free(dev->dev_private, sizeof(drm_i915_private_t), 798ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes DRM_MEM_DRIVER); 799ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 80022eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie return 0; 80122eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie} 80222eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie 80384b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlievoid i915_driver_lastclose(struct drm_device * dev) 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 805ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_i915_private_t *dev_priv = dev->dev_private; 806ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 807144a75fa1faa4a81530bded2e59872ef80d496b6Dave Airlie if (!dev_priv) 808144a75fa1faa4a81530bded2e59872ef80d496b6Dave Airlie return; 809144a75fa1faa4a81530bded2e59872ef80d496b6Dave Airlie 810ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes if (dev_priv->agp_heap) 811b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie i915_mem_takedown(&(dev_priv->agp_heap)); 812ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 813b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie i915_dma_cleanup(dev); 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8166c340eac0285f3d62406d2d902d0e96fbf2a5dc0Eric Anholtvoid i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 818ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_i915_private_t *dev_priv = dev->dev_private; 819ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes i915_mem_release(dev, file_priv, dev_priv->agp_heap); 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 822c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstruct drm_ioctl_desc i915_ioctls[] = { 823c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 824c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), 825c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), 826c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), 827c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), 828c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), 829c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), 830c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 831c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), 832c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), 833c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 834c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), 835c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), 836c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), 837c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), 838c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), 839c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH), 840c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie}; 841c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie 842c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlieint i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); 843cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie 844cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie/** 845cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * Determine if the device really is AGP or not. 846cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * 847cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * All Intel graphics chipsets are treated as AGP, even if they are really 848cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * PCI-e. 849cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * 850cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * \param dev The device to be tested. 851cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * 852cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * \returns 853cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * A value of 1 is always retured to indictate every i9x5 is AGP. 854cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie */ 85584b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_driver_device_is_agp(struct drm_device * dev) 856cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie{ 857cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie return 1; 858cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie} 859