i915_dma.c revision 189049
1145132Sanholt/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- 2145132Sanholt */ 3152909Sanholt/*- 4145132Sanholt * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 5145132Sanholt * All Rights Reserved. 6182080Srnoland * 7152909Sanholt * Permission is hereby granted, free of charge, to any person obtaining a 8152909Sanholt * copy of this software and associated documentation files (the 9152909Sanholt * "Software"), to deal in the Software without restriction, including 10152909Sanholt * without limitation the rights to use, copy, modify, merge, publish, 11152909Sanholt * distribute, sub license, and/or sell copies of the Software, and to 12152909Sanholt * permit persons to whom the Software is furnished to do so, subject to 13152909Sanholt * the following conditions: 14182080Srnoland * 15152909Sanholt * The above copyright notice and this permission notice (including the 16152909Sanholt * next paragraph) shall be included in all copies or substantial portions 17152909Sanholt * of the Software. 18182080Srnoland * 19152909Sanholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20152909Sanholt * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21152909Sanholt * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22152909Sanholt * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 23152909Sanholt * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24152909Sanholt * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25152909Sanholt * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26182080Srnoland * 27152909Sanholt */ 28145132Sanholt 29152909Sanholt#include <sys/cdefs.h> 30152909Sanholt__FBSDID("$FreeBSD: head/sys/dev/drm/i915_dma.c 189049 2009-02-25 18:44:50Z rnoland $"); 31145132Sanholt 32152909Sanholt#include "dev/drm/drmP.h" 33152909Sanholt#include "dev/drm/drm.h" 34152909Sanholt#include "dev/drm/i915_drm.h" 35152909Sanholt#include "dev/drm/i915_drv.h" 36152909Sanholt 37145132Sanholt/* Really want an OS-independent resettable timer. Would like to have 38145132Sanholt * this loop run for (eg) 3 sec, but have the timer reset every time 39145132Sanholt * the head pointer changes, so that EBUSY only happens if the ring 40145132Sanholt * actually stalls for (eg) 3 seconds. 41145132Sanholt */ 42182080Srnolandint i915_wait_ring(struct drm_device * dev, int n, const char *caller) 43145132Sanholt{ 44145132Sanholt drm_i915_private_t *dev_priv = dev->dev_private; 45145132Sanholt drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 46182080Srnoland u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR; 47183573Srnoland u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; 48183573Srnoland u32 last_acthd = I915_READ(acthd_reg); 49183573Srnoland u32 acthd; 50145132Sanholt int i; 51145132Sanholt 52183573Srnoland for (i = 0; i < 100000; i++) { 53182080Srnoland ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; 54183573Srnoland acthd = I915_READ(acthd_reg); 55145132Sanholt ring->space = ring->head - (ring->tail + 8); 56145132Sanholt if (ring->space < 0) 57145132Sanholt ring->space += ring->Size; 58145132Sanholt if (ring->space >= n) 59145132Sanholt return 0; 60145132Sanholt 61189049Srnoland if (dev_priv->sarea_priv) 62189049Srnoland dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; 63189049Srnoland 64145132Sanholt if (ring->head != last_head) 65145132Sanholt i = 0; 66145132Sanholt 67183573Srnoland if (acthd != last_acthd) 68183573Srnoland i = 0; 69183573Srnoland 70145132Sanholt last_head = ring->head; 71183573Srnoland last_acthd = acthd; 72183573Srnoland DRM_UDELAY(10 * 1000); 73145132Sanholt } 74145132Sanholt 75182080Srnoland return -EBUSY; 76145132Sanholt} 77145132Sanholt 78189049Srnoland/** 79189049Srnoland * Sets up the hardware status page for devices that need a physical address 80189049Srnoland * in the register. 81189049Srnoland */ 82189049Srnolandstatic int i915_init_phys_hws(struct drm_device *dev) 83183573Srnoland{ 84183573Srnoland drm_i915_private_t *dev_priv = dev->dev_private; 85183573Srnoland 86183573Srnoland /* Program Hardware Status Page */ 87183573Srnoland DRM_UNLOCK(); 88189049Srnoland dev_priv->status_page_dmah = 89189049Srnoland drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); 90183573Srnoland DRM_LOCK(); 91189049Srnoland if (!dev_priv->status_page_dmah) { 92183573Srnoland DRM_ERROR("Can not allocate hardware status page\n"); 93183573Srnoland return -ENOMEM; 94183573Srnoland } 95189049Srnoland dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; 96189049Srnoland dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; 97183573Srnoland 98183573Srnoland memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 99183573Srnoland 100189049Srnoland I915_WRITE(HWS_PGA, dev_priv->dma_status_page); 101183573Srnoland DRM_DEBUG("Enabled hardware status page\n"); 102183573Srnoland return 0; 103183573Srnoland} 104183573Srnoland 105189049Srnoland/** 106189049Srnoland * Frees the hardware status page, whether it's a physical address or a virtual 107189049Srnoland * address set up by the X Server. 108189049Srnoland */ 109189049Srnolandstatic void i915_free_hws(struct drm_device *dev) 110183573Srnoland{ 111183573Srnoland drm_i915_private_t *dev_priv = dev->dev_private; 112183573Srnoland if (dev_priv->status_page_dmah) { 113183573Srnoland drm_pci_free(dev, dev_priv->status_page_dmah); 114183573Srnoland dev_priv->status_page_dmah = NULL; 115183573Srnoland } 116183573Srnoland 117183573Srnoland if (dev_priv->status_gfx_addr) { 118183573Srnoland dev_priv->status_gfx_addr = 0; 119183573Srnoland drm_core_ioremapfree(&dev_priv->hws_map, dev); 120183573Srnoland } 121183573Srnoland 122189049Srnoland /* Need to rewrite hardware status page */ 123189049Srnoland I915_WRITE(HWS_PGA, 0x1ffff000); 124183573Srnoland} 125183573Srnoland 126182080Srnolandvoid i915_kernel_lost_context(struct drm_device * dev) 127145132Sanholt{ 128145132Sanholt drm_i915_private_t *dev_priv = dev->dev_private; 129145132Sanholt drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 130145132Sanholt 131182080Srnoland ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; 132182080Srnoland ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; 133145132Sanholt ring->space = ring->head - (ring->tail + 8); 134145132Sanholt if (ring->space < 0) 135145132Sanholt ring->space += ring->Size; 136189049Srnoland 137189049Srnoland if (ring->head == ring->tail && dev_priv->sarea_priv) 138189049Srnoland dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; 139145132Sanholt} 140145132Sanholt 141182080Srnolandstatic int i915_dma_cleanup(struct drm_device * dev) 142145132Sanholt{ 143182080Srnoland drm_i915_private_t *dev_priv = dev->dev_private; 144145132Sanholt /* Make sure interrupts are disabled here because the uninstall ioctl 145145132Sanholt * may not have been called from userspace and after dev_private 146145132Sanholt * is freed, it's too late. 147145132Sanholt */ 148183573Srnoland if (dev->irq_enabled) 149145132Sanholt drm_irq_uninstall(dev); 150145132Sanholt 151182080Srnoland if (dev_priv->ring.virtual_start) { 152182080Srnoland drm_core_ioremapfree(&dev_priv->ring.map, dev); 153189049Srnoland dev_priv->ring.virtual_start = NULL; 154189049Srnoland dev_priv->ring.map.handle = NULL; 155182080Srnoland dev_priv->ring.map.size = 0; 156182080Srnoland } 157145132Sanholt 158189049Srnoland /* Clear the HWS virtual address at teardown */ 159183573Srnoland if (I915_NEED_GFX_HWS(dev)) 160189049Srnoland i915_free_hws(dev); 161145132Sanholt 162145132Sanholt return 0; 163145132Sanholt} 164145132Sanholt 165189049Srnolandstatic int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) 166145132Sanholt{ 167182080Srnoland drm_i915_private_t *dev_priv = dev->dev_private; 168171394Skib 169182080Srnoland dev_priv->sarea = drm_getsarea(dev); 170145132Sanholt if (!dev_priv->sarea) { 171145132Sanholt DRM_ERROR("can not find sarea!\n"); 172145132Sanholt i915_dma_cleanup(dev); 173182080Srnoland return -EINVAL; 174145132Sanholt } 175145132Sanholt 176189049Srnoland dev_priv->sarea_priv = (drm_i915_sarea_t *) 177189049Srnoland ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); 178145132Sanholt 179189049Srnoland if (init->ring_size != 0) { 180189049Srnoland if (dev_priv->ring.ring_obj != NULL) { 181189049Srnoland i915_dma_cleanup(dev); 182189049Srnoland DRM_ERROR("Client tried to initialize ringbuffer in " 183189049Srnoland "GEM mode\n"); 184189049Srnoland return -EINVAL; 185189049Srnoland } 186182080Srnoland 187183573Srnoland dev_priv->ring.Size = init->ring_size; 188183573Srnoland dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; 189145132Sanholt 190183573Srnoland dev_priv->ring.map.offset = init->ring_start; 191183573Srnoland dev_priv->ring.map.size = init->ring_size; 192183573Srnoland dev_priv->ring.map.type = 0; 193183573Srnoland dev_priv->ring.map.flags = 0; 194183573Srnoland dev_priv->ring.map.mtrr = 0; 195145132Sanholt 196183573Srnoland drm_core_ioremap(&dev_priv->ring.map, dev); 197145132Sanholt 198183573Srnoland if (dev_priv->ring.map.handle == NULL) { 199183573Srnoland i915_dma_cleanup(dev); 200183573Srnoland DRM_ERROR("can not ioremap virtual address for" 201183573Srnoland " ring buffer\n"); 202183573Srnoland return -ENOMEM; 203183573Srnoland } 204145132Sanholt } 205145132Sanholt 206189049Srnoland dev_priv->ring.virtual_start = dev_priv->ring.map.handle; 207189049Srnoland 208182080Srnoland dev_priv->cpp = init->cpp; 209189049Srnoland dev_priv->back_offset = init->back_offset; 210189049Srnoland dev_priv->front_offset = init->front_offset; 211189049Srnoland dev_priv->current_page = 0; 212189049Srnoland dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 213145132Sanholt 214145132Sanholt /* Allow hardware batchbuffers unless told otherwise. 215145132Sanholt */ 216145132Sanholt dev_priv->allow_batchbuffer = 1; 217145132Sanholt 218145132Sanholt return 0; 219145132Sanholt} 220145132Sanholt 221182080Srnolandstatic int i915_dma_resume(struct drm_device * dev) 222145132Sanholt{ 223145132Sanholt drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 224145132Sanholt 225182080Srnoland DRM_DEBUG("\n"); 226145132Sanholt 227145132Sanholt if (!dev_priv->sarea) { 228145132Sanholt DRM_ERROR("can not find sarea!\n"); 229182080Srnoland return -EINVAL; 230145132Sanholt } 231145132Sanholt 232145132Sanholt if (dev_priv->ring.map.handle == NULL) { 233145132Sanholt DRM_ERROR("can not ioremap virtual address for" 234145132Sanholt " ring buffer\n"); 235182080Srnoland return -ENOMEM; 236145132Sanholt } 237145132Sanholt 238145132Sanholt /* Program Hardware Status Page */ 239145132Sanholt if (!dev_priv->hw_status_page) { 240145132Sanholt DRM_ERROR("Can not find hardware status page\n"); 241182080Srnoland return -EINVAL; 242145132Sanholt } 243145132Sanholt DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 244145132Sanholt 245182080Srnoland if (dev_priv->status_gfx_addr != 0) 246189049Srnoland I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); 247182080Srnoland else 248189049Srnoland I915_WRITE(HWS_PGA, dev_priv->dma_status_page); 249145132Sanholt DRM_DEBUG("Enabled hardware status page\n"); 250145132Sanholt 251145132Sanholt return 0; 252145132Sanholt} 253145132Sanholt 254182080Srnolandstatic int i915_dma_init(struct drm_device *dev, void *data, 255182080Srnoland struct drm_file *file_priv) 256145132Sanholt{ 257182080Srnoland drm_i915_init_t *init = data; 258145132Sanholt int retcode = 0; 259145132Sanholt 260182080Srnoland switch (init->func) { 261145132Sanholt case I915_INIT_DMA: 262189049Srnoland retcode = i915_initialize(dev, init); 263145132Sanholt break; 264145132Sanholt case I915_CLEANUP_DMA: 265145132Sanholt retcode = i915_dma_cleanup(dev); 266145132Sanholt break; 267145132Sanholt case I915_RESUME_DMA: 268145132Sanholt retcode = i915_dma_resume(dev); 269145132Sanholt break; 270145132Sanholt default: 271145132Sanholt retcode = -EINVAL; 272145132Sanholt break; 273145132Sanholt } 274145132Sanholt 275145132Sanholt return retcode; 276145132Sanholt} 277145132Sanholt 278145132Sanholt/* Implement basically the same security restrictions as hardware does 279145132Sanholt * for MI_BATCH_NON_SECURE. These can be made stricter at any time. 280145132Sanholt * 281145132Sanholt * Most of the calculations below involve calculating the size of a 282145132Sanholt * particular instruction. It's important to get the size right as 283145132Sanholt * that tells us where the next instruction to check is. Any illegal 284145132Sanholt * instruction detected will be given a size of zero, which is a 285145132Sanholt * signal to abort the rest of the buffer. 286145132Sanholt */ 287145132Sanholtstatic int do_validate_cmd(int cmd) 288145132Sanholt{ 289145132Sanholt switch (((cmd >> 29) & 0x7)) { 290145132Sanholt case 0x0: 291145132Sanholt switch ((cmd >> 23) & 0x3f) { 292145132Sanholt case 0x0: 293145132Sanholt return 1; /* MI_NOOP */ 294145132Sanholt case 0x4: 295145132Sanholt return 1; /* MI_FLUSH */ 296145132Sanholt default: 297145132Sanholt return 0; /* disallow everything else */ 298145132Sanholt } 299145132Sanholt break; 300145132Sanholt case 0x1: 301145132Sanholt return 0; /* reserved */ 302145132Sanholt case 0x2: 303145132Sanholt return (cmd & 0xff) + 2; /* 2d commands */ 304145132Sanholt case 0x3: 305145132Sanholt if (((cmd >> 24) & 0x1f) <= 0x18) 306145132Sanholt return 1; 307145132Sanholt 308145132Sanholt switch ((cmd >> 24) & 0x1f) { 309145132Sanholt case 0x1c: 310145132Sanholt return 1; 311145132Sanholt case 0x1d: 312145132Sanholt switch ((cmd >> 16) & 0xff) { 313145132Sanholt case 0x3: 314145132Sanholt return (cmd & 0x1f) + 2; 315145132Sanholt case 0x4: 316145132Sanholt return (cmd & 0xf) + 2; 317145132Sanholt default: 318145132Sanholt return (cmd & 0xffff) + 2; 319145132Sanholt } 320145132Sanholt case 0x1e: 321145132Sanholt if (cmd & (1 << 23)) 322145132Sanholt return (cmd & 0xffff) + 1; 323145132Sanholt else 324145132Sanholt return 1; 325145132Sanholt case 0x1f: 326145132Sanholt if ((cmd & (1 << 23)) == 0) /* inline vertices */ 327145132Sanholt return (cmd & 0x1ffff) + 2; 328145132Sanholt else if (cmd & (1 << 17)) /* indirect random */ 329145132Sanholt if ((cmd & 0xffff) == 0) 330145132Sanholt return 0; /* unknown length, too hard */ 331145132Sanholt else 332145132Sanholt return (((cmd & 0xffff) + 1) / 2) + 1; 333145132Sanholt else 334145132Sanholt return 2; /* indirect sequential */ 335145132Sanholt default: 336145132Sanholt return 0; 337145132Sanholt } 338145132Sanholt default: 339145132Sanholt return 0; 340145132Sanholt } 341145132Sanholt 342145132Sanholt return 0; 343145132Sanholt} 344145132Sanholt 345145132Sanholtstatic int validate_cmd(int cmd) 346145132Sanholt{ 347145132Sanholt int ret = do_validate_cmd(cmd); 348145132Sanholt 349182080Srnoland/* printk("validate_cmd( %x ): %d\n", cmd, ret); */ 350145132Sanholt 351145132Sanholt return ret; 352145132Sanholt} 353145132Sanholt 354182080Srnolandstatic int i915_emit_cmds(struct drm_device *dev, int __user *buffer, 355182080Srnoland int dwords) 356145132Sanholt{ 357145132Sanholt drm_i915_private_t *dev_priv = dev->dev_private; 358145132Sanholt int i; 359145132Sanholt RING_LOCALS; 360145132Sanholt 361157617Sanholt if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) 362182080Srnoland return -EINVAL; 363157617Sanholt 364162132Sanholt BEGIN_LP_RING((dwords+1)&~1); 365157617Sanholt 366145132Sanholt for (i = 0; i < dwords;) { 367145132Sanholt int cmd, sz; 368145132Sanholt 369183573Srnoland if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) 370183573Srnoland return -EINVAL; 371183573Srnoland 372145132Sanholt if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) 373182080Srnoland return -EINVAL; 374145132Sanholt 375145132Sanholt OUT_RING(cmd); 376145132Sanholt 377145132Sanholt while (++i, --sz) { 378183573Srnoland if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], 379183573Srnoland sizeof(cmd))) { 380183573Srnoland return -EINVAL; 381183573Srnoland } 382145132Sanholt OUT_RING(cmd); 383145132Sanholt } 384145132Sanholt } 385182080Srnoland 386157617Sanholt if (dwords & 1) 387157617Sanholt OUT_RING(0); 388145132Sanholt 389157617Sanholt ADVANCE_LP_RING(); 390182080Srnoland 391145132Sanholt return 0; 392145132Sanholt} 393145132Sanholt 394183573Srnolandint i915_emit_box(struct drm_device * dev, 395183573Srnoland struct drm_clip_rect __user * boxes, 396183573Srnoland int i, int DR1, int DR4) 397145132Sanholt{ 398145132Sanholt drm_i915_private_t *dev_priv = dev->dev_private; 399182080Srnoland struct drm_clip_rect box; 400145132Sanholt RING_LOCALS; 401145132Sanholt 402183573Srnoland if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { 403183573Srnoland return -EFAULT; 404183573Srnoland } 405183573Srnoland 406145132Sanholt if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { 407145132Sanholt DRM_ERROR("Bad box %d,%d..%d,%d\n", 408145132Sanholt box.x1, box.y1, box.x2, box.y2); 409182080Srnoland return -EINVAL; 410145132Sanholt } 411145132Sanholt 412162132Sanholt if (IS_I965G(dev)) { 413162132Sanholt BEGIN_LP_RING(4); 414162132Sanholt OUT_RING(GFX_OP_DRAWRECT_INFO_I965); 415162132Sanholt OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); 416162132Sanholt OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); 417162132Sanholt OUT_RING(DR4); 418162132Sanholt ADVANCE_LP_RING(); 419162132Sanholt } else { 420162132Sanholt BEGIN_LP_RING(6); 421162132Sanholt OUT_RING(GFX_OP_DRAWRECT_INFO); 422162132Sanholt OUT_RING(DR1); 423162132Sanholt OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); 424162132Sanholt OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); 425162132Sanholt OUT_RING(DR4); 426162132Sanholt OUT_RING(0); 427162132Sanholt ADVANCE_LP_RING(); 428162132Sanholt } 429145132Sanholt 430145132Sanholt return 0; 431145132Sanholt} 432145132Sanholt 433162132Sanholt/* XXX: Emitting the counter should really be moved to part of the IRQ 434182080Srnoland * emit. For now, do it in both places: 435162132Sanholt */ 436157617Sanholt 437189049Srnolandstatic void i915_emit_breadcrumb(struct drm_device *dev) 438157617Sanholt{ 439157617Sanholt drm_i915_private_t *dev_priv = dev->dev_private; 440157617Sanholt RING_LOCALS; 441157617Sanholt 442189049Srnoland dev_priv->counter++; 443189049Srnoland if (dev_priv->counter > 0x7FFFFFFFUL) 444189049Srnoland dev_priv->counter = 0; 445182080Srnoland if (dev_priv->sarea_priv) 446182080Srnoland dev_priv->sarea_priv->last_enqueue = dev_priv->counter; 447162132Sanholt 448157617Sanholt BEGIN_LP_RING(4); 449182080Srnoland OUT_RING(MI_STORE_DWORD_INDEX); 450189049Srnoland OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); 451157617Sanholt OUT_RING(dev_priv->counter); 452157617Sanholt OUT_RING(0); 453157617Sanholt ADVANCE_LP_RING(); 454157617Sanholt} 455157617Sanholt 456182080Srnolandstatic int i915_dispatch_cmdbuffer(struct drm_device * dev, 457145132Sanholt drm_i915_cmdbuffer_t * cmd) 458145132Sanholt{ 459145132Sanholt int nbox = cmd->num_cliprects; 460145132Sanholt int i = 0, count, ret; 461145132Sanholt 462145132Sanholt if (cmd->sz & 0x3) { 463182080Srnoland DRM_ERROR("alignment\n"); 464182080Srnoland return -EINVAL; 465145132Sanholt } 466145132Sanholt 467145132Sanholt i915_kernel_lost_context(dev); 468145132Sanholt 469145132Sanholt count = nbox ? nbox : 1; 470145132Sanholt 471145132Sanholt for (i = 0; i < count; i++) { 472145132Sanholt if (i < nbox) { 473145132Sanholt ret = i915_emit_box(dev, cmd->cliprects, i, 474145132Sanholt cmd->DR1, cmd->DR4); 475145132Sanholt if (ret) 476145132Sanholt return ret; 477145132Sanholt } 478145132Sanholt 479145132Sanholt ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4); 480145132Sanholt if (ret) 481145132Sanholt return ret; 482145132Sanholt } 483145132Sanholt 484182080Srnoland i915_emit_breadcrumb(dev); 485145132Sanholt return 0; 486145132Sanholt} 487145132Sanholt 488189049Srnolandstatic int i915_dispatch_batchbuffer(struct drm_device * dev, 489189049Srnoland drm_i915_batchbuffer_t * batch) 490145132Sanholt{ 491145132Sanholt drm_i915_private_t *dev_priv = dev->dev_private; 492182080Srnoland struct drm_clip_rect __user *boxes = batch->cliprects; 493145132Sanholt int nbox = batch->num_cliprects; 494145132Sanholt int i = 0, count; 495145132Sanholt RING_LOCALS; 496145132Sanholt 497145132Sanholt if ((batch->start | batch->used) & 0x7) { 498182080Srnoland DRM_ERROR("alignment\n"); 499182080Srnoland return -EINVAL; 500145132Sanholt } 501145132Sanholt 502145132Sanholt i915_kernel_lost_context(dev); 503145132Sanholt 504145132Sanholt count = nbox ? nbox : 1; 505145132Sanholt 506145132Sanholt for (i = 0; i < count; i++) { 507145132Sanholt if (i < nbox) { 508145132Sanholt int ret = i915_emit_box(dev, boxes, i, 509145132Sanholt batch->DR1, batch->DR4); 510145132Sanholt if (ret) 511145132Sanholt return ret; 512145132Sanholt } 513145132Sanholt 514189049Srnoland if (!IS_I830(dev) && !IS_845G(dev)) { 515145132Sanholt BEGIN_LP_RING(2); 516182080Srnoland if (IS_I965G(dev)) { 517182080Srnoland OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); 518182080Srnoland OUT_RING(batch->start); 519182080Srnoland } else { 520182080Srnoland OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); 521182080Srnoland OUT_RING(batch->start | MI_BATCH_NON_SECURE); 522182080Srnoland } 523145132Sanholt ADVANCE_LP_RING(); 524189049Srnoland } else { 525189049Srnoland BEGIN_LP_RING(4); 526189049Srnoland OUT_RING(MI_BATCH_BUFFER); 527189049Srnoland OUT_RING(batch->start | MI_BATCH_NON_SECURE); 528189049Srnoland OUT_RING(batch->start + batch->used - 4); 529189049Srnoland OUT_RING(0); 530189049Srnoland ADVANCE_LP_RING(); 531145132Sanholt } 532145132Sanholt } 533145132Sanholt 534182080Srnoland i915_emit_breadcrumb(dev); 535189049Srnoland 536145132Sanholt return 0; 537145132Sanholt} 538145132Sanholt 539189049Srnolandstatic int i915_dispatch_flip(struct drm_device * dev) 540145132Sanholt{ 541145132Sanholt drm_i915_private_t *dev_priv = dev->dev_private; 542145132Sanholt RING_LOCALS; 543145132Sanholt 544189049Srnoland if (!dev_priv->sarea_priv) 545189049Srnoland return -EINVAL; 546145132Sanholt 547189049Srnoland DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 548189049Srnoland __func__, 549189049Srnoland dev_priv->current_page, 550189049Srnoland dev_priv->sarea_priv->pf_current_page); 551145132Sanholt 552189049Srnoland i915_kernel_lost_context(dev); 553189049Srnoland 554189049Srnoland BEGIN_LP_RING(2); 555189049Srnoland OUT_RING(MI_FLUSH | MI_READ_FLUSH); 556189049Srnoland OUT_RING(0); 557189049Srnoland ADVANCE_LP_RING(); 558189049Srnoland 559189049Srnoland BEGIN_LP_RING(6); 560189049Srnoland OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); 561189049Srnoland OUT_RING(0); 562189049Srnoland if (dev_priv->current_page == 0) { 563189049Srnoland OUT_RING(dev_priv->back_offset); 564189049Srnoland dev_priv->current_page = 1; 565145132Sanholt } else { 566189049Srnoland OUT_RING(dev_priv->front_offset); 567189049Srnoland dev_priv->current_page = 0; 568145132Sanholt } 569189049Srnoland OUT_RING(0); 570189049Srnoland ADVANCE_LP_RING(); 571145132Sanholt 572189049Srnoland BEGIN_LP_RING(2); 573189049Srnoland OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); 574189049Srnoland OUT_RING(0); 575189049Srnoland ADVANCE_LP_RING(); 576145132Sanholt 577189049Srnoland dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; 578145132Sanholt 579145132Sanholt BEGIN_LP_RING(4); 580189049Srnoland OUT_RING(MI_STORE_DWORD_INDEX); 581189049Srnoland OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); 582189049Srnoland OUT_RING(dev_priv->counter); 583189049Srnoland OUT_RING(0); 584145132Sanholt ADVANCE_LP_RING(); 585145132Sanholt 586189049Srnoland dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 587189049Srnoland return 0; 588145132Sanholt} 589145132Sanholt 590189049Srnolandstatic int i915_quiescent(struct drm_device * dev) 591145132Sanholt{ 592145132Sanholt drm_i915_private_t *dev_priv = dev->dev_private; 593145132Sanholt 594145132Sanholt i915_kernel_lost_context(dev); 595189049Srnoland return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__); 596145132Sanholt} 597145132Sanholt 598182080Srnolandstatic int i915_flush_ioctl(struct drm_device *dev, void *data, 599182080Srnoland struct drm_file *file_priv) 600145132Sanholt{ 601189049Srnoland int ret; 602145132Sanholt 603189049Srnoland RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 604145132Sanholt 605189049Srnoland ret = i915_quiescent(dev); 606189049Srnoland 607189049Srnoland return ret; 608145132Sanholt} 609145132Sanholt 610182080Srnolandstatic int i915_batchbuffer(struct drm_device *dev, void *data, 611182080Srnoland struct drm_file *file_priv) 612145132Sanholt{ 613145132Sanholt drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 614145132Sanholt drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 615145132Sanholt dev_priv->sarea_priv; 616182080Srnoland drm_i915_batchbuffer_t *batch = data; 617189049Srnoland size_t cliplen; 618145132Sanholt int ret; 619145132Sanholt 620145132Sanholt if (!dev_priv->allow_batchbuffer) { 621145132Sanholt DRM_ERROR("Batchbuffer ioctl disabled\n"); 622182080Srnoland return -EINVAL; 623145132Sanholt } 624145132Sanholt 625145132Sanholt DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", 626182080Srnoland batch->start, batch->used, batch->num_cliprects); 627145132Sanholt 628189049Srnoland RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 629145132Sanholt 630189049Srnoland DRM_UNLOCK(); 631189049Srnoland cliplen = batch->num_cliprects * sizeof(struct drm_clip_rect); 632182080Srnoland if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, 633189049Srnoland cliplen)) { 634189049Srnoland DRM_LOCK(); 635182080Srnoland return -EFAULT; 636189049Srnoland } 637189049Srnoland if (batch->num_cliprects) { 638189049Srnoland ret = vslock(batch->cliprects, cliplen); 639189049Srnoland if (ret) { 640189049Srnoland DRM_ERROR("Fault wiring cliprects\n"); 641189049Srnoland DRM_LOCK(); 642189049Srnoland return -EFAULT; 643189049Srnoland } 644189049Srnoland } 645189049Srnoland DRM_LOCK(); 646183573Srnoland 647182080Srnoland ret = i915_dispatch_batchbuffer(dev, batch); 648145132Sanholt 649189049Srnoland if (sarea_priv) 650189049Srnoland sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 651189049Srnoland 652189049Srnoland DRM_UNLOCK(); 653189049Srnoland if (batch->num_cliprects) 654189049Srnoland vsunlock(batch->cliprects, cliplen); 655189049Srnoland DRM_LOCK(); 656189049Srnoland 657145132Sanholt return ret; 658145132Sanholt} 659145132Sanholt 660182080Srnolandstatic int i915_cmdbuffer(struct drm_device *dev, void *data, 661182080Srnoland struct drm_file *file_priv) 662145132Sanholt{ 663145132Sanholt drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 664145132Sanholt drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 665145132Sanholt dev_priv->sarea_priv; 666182080Srnoland drm_i915_cmdbuffer_t *cmdbuf = data; 667189049Srnoland size_t cliplen; 668145132Sanholt int ret; 669145132Sanholt 670145132Sanholt DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", 671182080Srnoland cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); 672145132Sanholt 673189049Srnoland RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 674145132Sanholt 675189049Srnoland DRM_UNLOCK(); 676189049Srnoland cliplen = cmdbuf->num_cliprects * sizeof(struct drm_clip_rect); 677189049Srnoland if (cmdbuf->num_cliprects && DRM_VERIFYAREA_READ(cmdbuf->cliprects, 678189049Srnoland cliplen)) { 679145132Sanholt DRM_ERROR("Fault accessing cliprects\n"); 680189049Srnoland DRM_LOCK(); 681182080Srnoland return -EFAULT; 682145132Sanholt } 683189049Srnoland if (cmdbuf->num_cliprects) { 684189049Srnoland ret = vslock(cmdbuf->cliprects, cliplen); 685189049Srnoland if (ret) { 686189049Srnoland DRM_ERROR("Fault wiring cliprects\n"); 687189049Srnoland DRM_LOCK(); 688189049Srnoland return -EFAULT; 689189049Srnoland } 690189049Srnoland ret = vslock(cmdbuf->buf, cmdbuf->sz); 691189049Srnoland if (ret) { 692189049Srnoland vsunlock(cmdbuf->cliprects, cliplen); 693189049Srnoland DRM_ERROR("Fault wiring cmds\n"); 694189049Srnoland DRM_LOCK(); 695189049Srnoland return -EFAULT; 696189049Srnoland } 697189049Srnoland } 698189049Srnoland DRM_LOCK(); 699183573Srnoland 700182080Srnoland ret = i915_dispatch_cmdbuffer(dev, cmdbuf); 701189049Srnoland DRM_UNLOCK(); 702189049Srnoland if (cmdbuf->num_cliprects) { 703189049Srnoland vsunlock(cmdbuf->buf, cmdbuf->sz); 704189049Srnoland vsunlock(cmdbuf->cliprects, cliplen); 705189049Srnoland } 706189049Srnoland DRM_LOCK(); 707183573Srnoland if (ret) { 708145132Sanholt DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); 709183573Srnoland return ret; 710145132Sanholt } 711183573Srnoland 712189049Srnoland if (sarea_priv) 713189049Srnoland sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 714183573Srnoland return 0; 715145132Sanholt} 716145132Sanholt 717189049Srnolandstatic int i915_flip_bufs(struct drm_device *dev, void *data, 718189049Srnoland struct drm_file *file_priv) 719145132Sanholt{ 720189049Srnoland int ret; 721145132Sanholt 722189049Srnoland DRM_DEBUG("%s\n", __func__); 723145132Sanholt 724182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 725145132Sanholt 726189049Srnoland ret = i915_dispatch_flip(dev); 727182080Srnoland 728189049Srnoland return ret; 729145132Sanholt} 730145132Sanholt 731182080Srnolandstatic int i915_getparam(struct drm_device *dev, void *data, 732182080Srnoland struct drm_file *file_priv) 733145132Sanholt{ 734145132Sanholt drm_i915_private_t *dev_priv = dev->dev_private; 735182080Srnoland drm_i915_getparam_t *param = data; 736145132Sanholt int value; 737145132Sanholt 738145132Sanholt if (!dev_priv) { 739182080Srnoland DRM_ERROR("called with no initialization\n"); 740182080Srnoland return -EINVAL; 741145132Sanholt } 742145132Sanholt 743182080Srnoland switch (param->param) { 744145132Sanholt case I915_PARAM_IRQ_ACTIVE: 745183573Srnoland value = dev->irq_enabled ? 1 : 0; 746145132Sanholt break; 747145132Sanholt case I915_PARAM_ALLOW_BATCHBUFFER: 748145132Sanholt value = dev_priv->allow_batchbuffer ? 1 : 0; 749145132Sanholt break; 750157617Sanholt case I915_PARAM_LAST_DISPATCH: 751157617Sanholt value = READ_BREADCRUMB(dev_priv); 752157617Sanholt break; 753182080Srnoland case I915_PARAM_CHIPSET_ID: 754182080Srnoland value = dev->pci_device; 755182080Srnoland break; 756183573Srnoland case I915_PARAM_HAS_GEM: 757184373Srnoland /* We need to reset this to 1 once we have GEM */ 758184373Srnoland value = 0; 759183573Srnoland break; 760145132Sanholt default: 761182080Srnoland DRM_ERROR("Unknown parameter %d\n", param->param); 762182080Srnoland return -EINVAL; 763145132Sanholt } 764145132Sanholt 765182080Srnoland if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { 766145132Sanholt DRM_ERROR("DRM_COPY_TO_USER failed\n"); 767182080Srnoland return -EFAULT; 768145132Sanholt } 769145132Sanholt 770145132Sanholt return 0; 771145132Sanholt} 772145132Sanholt 773182080Srnolandstatic int i915_setparam(struct drm_device *dev, void *data, 774182080Srnoland struct drm_file *file_priv) 775145132Sanholt{ 776145132Sanholt drm_i915_private_t *dev_priv = dev->dev_private; 777182080Srnoland drm_i915_setparam_t *param = data; 778145132Sanholt 779145132Sanholt if (!dev_priv) { 780182080Srnoland DRM_ERROR("called with no initialization\n"); 781182080Srnoland return -EINVAL; 782145132Sanholt } 783145132Sanholt 784182080Srnoland switch (param->param) { 785145132Sanholt case I915_SETPARAM_USE_MI_BATCHBUFFER_START: 786145132Sanholt break; 787145132Sanholt case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: 788182080Srnoland dev_priv->tex_lru_log_granularity = param->value; 789145132Sanholt break; 790145132Sanholt case I915_SETPARAM_ALLOW_BATCHBUFFER: 791182080Srnoland dev_priv->allow_batchbuffer = param->value; 792145132Sanholt break; 793145132Sanholt default: 794182080Srnoland DRM_ERROR("unknown parameter %d\n", param->param); 795182080Srnoland return -EINVAL; 796145132Sanholt } 797145132Sanholt 798145132Sanholt return 0; 799145132Sanholt} 800145132Sanholt 801182080Srnolandstatic int i915_set_status_page(struct drm_device *dev, void *data, 802182080Srnoland struct drm_file *file_priv) 803182080Srnoland{ 804182080Srnoland drm_i915_private_t *dev_priv = dev->dev_private; 805182080Srnoland drm_i915_hws_addr_t *hws = data; 806182080Srnoland 807182080Srnoland if (!I915_NEED_GFX_HWS(dev)) 808182080Srnoland return -EINVAL; 809182080Srnoland 810182080Srnoland if (!dev_priv) { 811182080Srnoland DRM_ERROR("called with no initialization\n"); 812182080Srnoland return -EINVAL; 813182080Srnoland } 814189049Srnoland 815182080Srnoland DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); 816182080Srnoland 817182080Srnoland dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); 818182080Srnoland 819182080Srnoland dev_priv->hws_map.offset = dev->agp->base + hws->addr; 820182080Srnoland dev_priv->hws_map.size = 4*1024; 821182080Srnoland dev_priv->hws_map.type = 0; 822182080Srnoland dev_priv->hws_map.flags = 0; 823182080Srnoland dev_priv->hws_map.mtrr = 0; 824182080Srnoland 825182080Srnoland drm_core_ioremap(&dev_priv->hws_map, dev); 826182080Srnoland if (dev_priv->hws_map.handle == NULL) { 827182080Srnoland i915_dma_cleanup(dev); 828182080Srnoland dev_priv->status_gfx_addr = 0; 829182080Srnoland DRM_ERROR("can not ioremap virtual address for" 830182080Srnoland " G33 hw status page\n"); 831182080Srnoland return -ENOMEM; 832182080Srnoland } 833182080Srnoland dev_priv->hw_status_page = dev_priv->hws_map.handle; 834182080Srnoland 835182080Srnoland memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 836182080Srnoland I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); 837189049Srnoland DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n", 838182080Srnoland dev_priv->status_gfx_addr); 839182080Srnoland DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page); 840182080Srnoland return 0; 841182080Srnoland} 842182080Srnoland 843182080Srnolandint i915_driver_load(struct drm_device *dev, unsigned long flags) 844182080Srnoland{ 845189049Srnoland struct drm_i915_private *dev_priv = dev->dev_private; 846182080Srnoland unsigned long base, size; 847182080Srnoland int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; 848182080Srnoland 849152909Sanholt /* i915 has 4 more counters */ 850152909Sanholt dev->counters += 4; 851152909Sanholt dev->types[6] = _DRM_STAT_IRQ; 852152909Sanholt dev->types[7] = _DRM_STAT_PRIMARY; 853152909Sanholt dev->types[8] = _DRM_STAT_SECONDARY; 854152909Sanholt dev->types[9] = _DRM_STAT_DMA; 855152909Sanholt 856182080Srnoland dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); 857182080Srnoland if (dev_priv == NULL) 858182080Srnoland return -ENOMEM; 859182080Srnoland 860182080Srnoland memset(dev_priv, 0, sizeof(drm_i915_private_t)); 861182080Srnoland 862182080Srnoland dev->dev_private = (void *)dev_priv; 863183573Srnoland dev_priv->dev = dev; 864182080Srnoland 865182080Srnoland /* Add register map (needed for suspend/resume) */ 866182080Srnoland base = drm_get_resource_start(dev, mmio_bar); 867182080Srnoland size = drm_get_resource_len(dev, mmio_bar); 868182080Srnoland 869182080Srnoland ret = drm_addmap(dev, base, size, _DRM_REGISTERS, 870189049Srnoland _DRM_KERNEL | _DRM_DRIVER, &dev_priv->mmio_map); 871183573Srnoland#ifdef I915_HAVE_GEM 872183573Srnoland i915_gem_load(dev); 873183573Srnoland#endif 874183573Srnoland /* Init HWS */ 875183573Srnoland if (!I915_NEED_GFX_HWS(dev)) { 876189049Srnoland ret = i915_init_phys_hws(dev); 877189049Srnoland if (ret != 0) 878183573Srnoland return ret; 879183573Srnoland } 880189049Srnoland#ifdef __linux__ 881189049Srnoland /* On the 945G/GM, the chipset reports the MSI capability on the 882189049Srnoland * integrated graphics even though the support isn't actually there 883189049Srnoland * according to the published specs. It doesn't appear to function 884189049Srnoland * correctly in testing on 945G. 885189049Srnoland * This may be a side effect of MSI having been made available for PEG 886189049Srnoland * and the registers being closely associated. 887189049Srnoland * 888189049Srnoland * According to chipset errata, on the 965GM, MSI interrupts may 889189049Srnoland * be lost or delayed 890189049Srnoland */ 891189049Srnoland if (!IS_I945G(dev) && !IS_I945GM(dev) && !IS_I965GM(dev)) 892189049Srnoland if (pci_enable_msi(dev->pdev)) 893189049Srnoland DRM_ERROR("failed to enable MSI\n"); 894183573Srnoland 895189049Srnoland intel_opregion_init(dev); 896189049Srnoland#endif 897189049Srnoland DRM_SPININIT(&dev_priv->user_irq_lock, "userirq"); 898189049Srnoland 899182080Srnoland return ret; 900182080Srnoland} 901182080Srnoland 902182080Srnolandint i915_driver_unload(struct drm_device *dev) 903182080Srnoland{ 904182080Srnoland struct drm_i915_private *dev_priv = dev->dev_private; 905182080Srnoland 906189049Srnoland i915_free_hws(dev); 907182080Srnoland 908189049Srnoland drm_rmmap(dev, dev_priv->mmio_map); 909182080Srnoland#ifdef __linux__ 910182080Srnoland intel_opregion_free(dev); 911182080Srnoland#endif 912189049Srnoland DRM_SPINUNINIT(&dev_priv->user_irq_lock); 913182080Srnoland 914182080Srnoland drm_free(dev->dev_private, sizeof(drm_i915_private_t), 915182080Srnoland DRM_MEM_DRIVER); 916182080Srnoland 917152909Sanholt return 0; 918152909Sanholt} 919152909Sanholt 920183573Srnolandint i915_driver_open(struct drm_device *dev, struct drm_file *file_priv) 921183573Srnoland{ 922183573Srnoland struct drm_i915_file_private *i915_file_priv; 923183573Srnoland 924183573Srnoland DRM_DEBUG("\n"); 925183573Srnoland i915_file_priv = (struct drm_i915_file_private *) 926183573Srnoland drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES); 927183573Srnoland 928183573Srnoland if (!i915_file_priv) 929183573Srnoland return -ENOMEM; 930183573Srnoland 931183573Srnoland file_priv->driver_priv = i915_file_priv; 932183573Srnoland 933183573Srnoland i915_file_priv->mm.last_gem_seqno = 0; 934183573Srnoland i915_file_priv->mm.last_gem_throttle_seqno = 0; 935183573Srnoland 936183573Srnoland return 0; 937183573Srnoland} 938183573Srnoland 939189049Srnolandvoid i915_driver_lastclose(struct drm_device * dev) 940189049Srnoland{ 941189049Srnoland drm_i915_private_t *dev_priv = dev->dev_private; 942189049Srnoland 943189049Srnoland if (!dev_priv) 944189049Srnoland return; 945189049Srnoland#ifdef I915_HAVE_GEM 946189049Srnoland i915_gem_lastclose(dev); 947189049Srnoland#endif 948189049Srnoland if (dev_priv->agp_heap) 949189049Srnoland i915_mem_takedown(&(dev_priv->agp_heap)); 950189049Srnoland 951189049Srnoland i915_dma_cleanup(dev); 952189049Srnoland} 953189049Srnoland 954182080Srnolandvoid i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) 955145132Sanholt{ 956182080Srnoland drm_i915_private_t *dev_priv = dev->dev_private; 957182080Srnoland i915_mem_release(dev, file_priv, dev_priv->agp_heap); 958145132Sanholt} 959145132Sanholt 960183573Srnolandvoid i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) 961183573Srnoland{ 962183573Srnoland struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; 963183573Srnoland 964183573Srnoland drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES); 965183573Srnoland} 966183573Srnoland 967182080Srnolandstruct drm_ioctl_desc i915_ioctls[] = { 968182080Srnoland DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 969182080Srnoland DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), 970182080Srnoland DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), 971182080Srnoland DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), 972182080Srnoland DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), 973182080Srnoland DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), 974182080Srnoland DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), 975182080Srnoland DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 976182080Srnoland DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), 977182080Srnoland DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), 978182080Srnoland DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 979182080Srnoland DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), 980182080Srnoland DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), 981182080Srnoland DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), 982182080Srnoland DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), 983182080Srnoland DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), 984184263Srnoland DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 985183573Srnoland#ifdef I915_HAVE_GEM 986189049Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 987183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH), 988183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), 989183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), 990183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH), 991183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH), 992189049Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 993189049Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 994183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0), 995183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0), 996183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0), 997183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0), 998183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0), 999183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0), 1000183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0), 1001183573Srnoland DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), 1002183573Srnoland#endif 1003145132Sanholt}; 1004145132Sanholt 1005145132Sanholtint i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); 1006152909Sanholt 1007152909Sanholt/** 1008152909Sanholt * Determine if the device really is AGP or not. 1009152909Sanholt * 1010152909Sanholt * All Intel graphics chipsets are treated as AGP, even if they are really 1011152909Sanholt * PCI-e. 1012152909Sanholt * 1013152909Sanholt * \param dev The device to be tested. 1014152909Sanholt * 1015152909Sanholt * \returns 1016152909Sanholt * A value of 1 is always retured to indictate every i9x5 is AGP. 1017152909Sanholt */ 1018182080Srnolandint i915_driver_device_is_agp(struct drm_device * dev) 1019152909Sanholt{ 1020152909Sanholt return 1; 1021152909Sanholt} 1022