1 /* BEGIN CSTYLED */ 2 3 /* i915_dma.c -- DMA support for the I915 -*- linux-c -*- 4 */ 5 /* 6 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 7 * All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the 11 * "Software"), to deal in the Software without restriction, including 12 * without limitation the rights to use, copy, modify, merge, publish, 13 * distribute, sub license, and/or sell copies of the Software, and to 14 * permit persons to whom the Software is furnished to do so, subject to 15 * the following conditions: 16 * 17 * The above copyright notice and this permission notice (including the 18 * next paragraph) shall be included in all copies or substantial portions 19 * of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 24 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 25 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 26 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 27 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 * 29 */ 30 31 /* 32 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 33 * Use is subject to license terms. 34 */ 35 36 #pragma ident "%Z%%M% %I% %E% SMI" 37 38 #include "drmP.h" 39 #include "drm.h" 40 #include "i915_drm.h" 41 #include "i915_drv.h" 42 43 #define IS_I965G(dev) (dev->pci_device == 0x2972 || \ 44 dev->pci_device == 0x2982 || \ 45 dev->pci_device == 0x2992 || \ 46 dev->pci_device == 0x29A2 || \ 47 dev->pci_device == 0x2A02 || \ 48 dev->pci_device == 0x2A12) 49 50 51 /* Really want an OS-independent resettable timer. Would like to have 52 * this loop run for (eg) 3 sec, but have the timer reset every time 53 * the head pointer changes, so that EBUSY only happens if the ring 54 * actually stalls for (eg) 3 seconds. 55 */ 56 /*ARGSUSED*/ 57 int i915_wait_ring(drm_device_t * dev, int n, const char *caller) 58 { 59 drm_i915_private_t *dev_priv = dev->dev_private; 60 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 61 u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 62 int i; 63 64 for (i = 0; i < 10000; i++) { 65 ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 66 ring->space = ring->head - (ring->tail + 8); 67 if (ring->space < 0) 68 ring->space += ring->Size; 69 if (ring->space >= n) 70 return 0; 71 72 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; 73 74 if (ring->head != last_head) 75 i = 0; 76 77 last_head = ring->head; 78 DRM_UDELAY(1); 79 } 80 81 return (EBUSY); 82 } 83 84 void i915_kernel_lost_context(drm_device_t * dev) 85 { 86 drm_i915_private_t *dev_priv = dev->dev_private; 87 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 88 89 ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 90 ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; 91 ring->space = ring->head - (ring->tail + 8); 92 if (ring->space < 0) 93 ring->space += ring->Size; 94 95 if (ring->head == ring->tail) 96 dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; 97 } 98 99 static int i915_dma_cleanup(drm_device_t * dev) 100 { 101 /* Make sure interrupts are disabled here because the uninstall ioctl 102 * may not have been called from userspace and after dev_private 103 * is freed, it's too late. 104 */ 105 if (dev->irq) 106 (void) drm_irq_uninstall(dev); 107 108 if (dev->dev_private) { 109 drm_i915_private_t *dev_priv = 110 (drm_i915_private_t *) dev->dev_private; 111 112 if (dev_priv->ring.virtual_start) { 113 drm_core_ioremapfree(&dev_priv->ring.map, dev); 114 } 115 116 if (dev_priv->status_page_dmah) { 117 drm_pci_free(dev, dev_priv->status_page_dmah); 118 119 /* Need to rewrite hardware status page */ 120 I915_WRITE(0x02080, 0x1ffff000); 121 } 122 123 drm_free(dev->dev_private, sizeof(drm_i915_private_t), 124 DRM_MEM_DRIVER); 125 126 dev->dev_private = NULL; 127 } 128 129 return 0; 130 } 131 132 static int i915_initialize(drm_device_t * dev, 133 drm_i915_private_t * dev_priv, 134 drm_i915_init_t * init) 135 { 136 (void) memset(dev_priv, 0, sizeof(drm_i915_private_t)); 137 138 DRM_GETSAREA(); 139 if (!dev_priv->sarea) { 140 DRM_ERROR("can not find sarea!\n"); 141 dev->dev_private = (void *)dev_priv; 142 (void) i915_dma_cleanup(dev); 143 return (EINVAL); 144 } 145 146 dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); 147 if (!dev_priv->mmio_map) { 148 dev->dev_private = (void *)dev_priv; 149 (void) i915_dma_cleanup(dev); 150 DRM_ERROR("can not find mmio map!\n"); 151 return (EINVAL); 152 } 153 154 dev_priv->sarea_priv = (drm_i915_sarea_t *) 155 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); 156 157 dev_priv->ring.Start = init->ring_start; 158 dev_priv->ring.End = init->ring_end; 159 dev_priv->ring.Size = init->ring_size; 160 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; 161 162 dev_priv->ring.map.offset = (u_offset_t)init->ring_start; 163 dev_priv->ring.map.size = init->ring_size; 164 dev_priv->ring.map.type = 0; 165 dev_priv->ring.map.flags = 0; 166 dev_priv->ring.map.mtrr = 0; 167 168 drm_core_ioremap(&dev_priv->ring.map, dev); 169 170 if (dev_priv->ring.map.handle == NULL) { 171 dev->dev_private = (void *)dev_priv; 172 (void) i915_dma_cleanup(dev); 173 DRM_ERROR("can not ioremap virtual address for" 174 " ring buffer\n"); 175 return (ENOMEM); 176 } 177 178 dev_priv->ring.virtual_start = (u8 *)dev_priv->ring.map.dev_addr; 179 180 dev_priv->cpp = init->cpp; 181 dev_priv->back_offset = init->back_offset; 182 dev_priv->front_offset = init->front_offset; 183 dev_priv->current_page = 0; 184 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 185 186 /* We are using separate values as placeholders for mechanisms for 187 * private backbuffer/depthbuffer usage. 188 */ 189 dev_priv->use_mi_batchbuffer_start = 0; 190 191 /* Allow hardware batchbuffers unless told otherwise. 192 */ 193 dev_priv->allow_batchbuffer = 1; 194 195 /* Program Hardware Status Page */ 196 dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 197 0xffffffff, 1); 198 199 if (!dev_priv->status_page_dmah) { 200 dev->dev_private = (void *)dev_priv; 201 (void) i915_dma_cleanup(dev); 202 DRM_ERROR("Can not allocate hardware status page\n"); 203 return (ENOMEM); 204 } 205 206 dev_priv->hw_status_page = (void *)dev_priv->status_page_dmah->vaddr; 207 dev_priv->dma_status_page = dev_priv->status_page_dmah->paddr; 208 (void) memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 209 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 210 211 I915_WRITE(0x02080, dev_priv->dma_status_page); 212 DRM_DEBUG("Enabled hardware status page\n"); 213 214 dev->dev_private = (void *)dev_priv; 215 216 #ifdef I915_HAVE_BUFFER 217 drm_bo_driver_init(dev); 218 #endif 219 return 0; 220 } 221 222 static int i915_dma_resume(drm_device_t * dev) 223 { 224 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 225 226 DRM_DEBUG("%s\n", __FUNCTION__); 227 228 if (!dev_priv->sarea) { 229 DRM_ERROR("can not find sarea!\n"); 230 return (EINVAL); 231 } 232 233 if (!dev_priv->mmio_map) { 234 DRM_ERROR("can not find mmio map!\n"); 235 return (EINVAL); 236 } 237 238 if (dev_priv->ring.map.handle == NULL) { 239 DRM_ERROR("can not ioremap virtual address for" 240 " ring buffer\n"); 241 return (ENOMEM); 242 } 243 244 /* Program Hardware Status Page */ 245 if (!dev_priv->hw_status_page) { 246 DRM_ERROR("Can not find hardware status page\n"); 247 return (EINVAL); 248 } 249 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 250 251 I915_WRITE(0x02080, dev_priv->dma_status_page); 252 DRM_DEBUG("Enabled hardware status page\n"); 253 254 return 0; 255 } 256 257 /*ARGSUSED*/ 258 static int i915_dma_init(DRM_IOCTL_ARGS) 259 { 260 DRM_DEVICE; 261 drm_i915_private_t *dev_priv; 262 drm_i915_init_t init; 263 int retcode = 0; 264 265 DRM_COPYFROM_WITH_RETURN(&init, (drm_i915_init_t *)data, sizeof(init)); 266 267 switch (init.func) { 268 case I915_INIT_DMA: 269 dev_priv = drm_alloc(sizeof(drm_i915_private_t), 270 DRM_MEM_DRIVER); 271 if (dev_priv == NULL) 272 return (ENOMEM); 273 retcode = i915_initialize(dev, dev_priv, &init); 274 break; 275 case I915_CLEANUP_DMA: 276 retcode = i915_dma_cleanup(dev); 277 break; 278 case I915_RESUME_DMA: 279 retcode = i915_dma_resume(dev); 280 break; 281 default: 282 retcode = EINVAL; 283 break; 284 } 285 286 return retcode; 287 } 288 289 /* Implement basically the same security restrictions as hardware does 290 * for MI_BATCH_NON_SECURE. These can be made stricter at any time. 291 * 292 * Most of the calculations below involve calculating the size of a 293 * particular instruction. It's important to get the size right as 294 * that tells us where the next instruction to check is. Any illegal 295 * instruction detected will be given a size of zero, which is a 296 * signal to abort the rest of the buffer. 297 */ 298 static int do_validate_cmd(int cmd) 299 { 300 switch (((cmd >> 29) & 0x7)) { 301 case 0x0: 302 switch ((cmd >> 23) & 0x3f) { 303 case 0x0: 304 return 1; /* MI_NOOP */ 305 case 0x4: 306 return 1; /* MI_FLUSH */ 307 default: 308 return 0; /* disallow everything else */ 309 } 310 #ifndef __SUNPRO_C 311 break; 312 #endif 313 case 0x1: 314 return 0; /* reserved */ 315 case 0x2: 316 return (cmd & 0xff) + 2; /* 2d commands */ 317 case 0x3: 318 if (((cmd >> 24) & 0x1f) <= 0x18) 319 return 1; 320 321 switch ((cmd >> 24) & 0x1f) { 322 case 0x1c: 323 return 1; 324 case 0x1d: 325 switch ((cmd >> 16) & 0xff) { 326 case 0x3: 327 return (cmd & 0x1f) + 2; 328 case 0x4: 329 return (cmd & 0xf) + 2; 330 default: 331 return (cmd & 0xffff) + 2; 332 } 333 case 0x1e: 334 if (cmd & (1 << 23)) 335 return (cmd & 0xffff) + 1; 336 else 337 return 1; 338 case 0x1f: 339 if ((cmd & (1 << 23)) == 0) /* inline vertices */ 340 return (cmd & 0x1ffff) + 2; 341 else if (cmd & (1 << 17)) /* indirect random */ 342 if ((cmd & 0xffff) == 0) 343 return 0; /* unknown length, too hard */ 344 else 345 return (((cmd & 0xffff) + 1) / 2) + 1; 346 else 347 return 2; /* indirect sequential */ 348 default: 349 return 0; 350 } 351 default: 352 return 0; 353 } 354 355 #ifndef __SUNPRO_C 356 return 0; 357 #endif 358 } 359 360 static int validate_cmd(int cmd) 361 { 362 int ret = do_validate_cmd(cmd); 363 364 /* printk("validate_cmd( %x ): %d\n", cmd, ret); */ 365 366 return ret; 367 } 368 369 static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) 370 { 371 drm_i915_private_t *dev_priv = dev->dev_private; 372 int i; 373 RING_LOCALS; 374 375 if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) 376 return (EINVAL); 377 378 BEGIN_LP_RING((dwords+1)&~1); 379 380 for (i = 0; i < dwords;) { 381 int cmd, sz; 382 383 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) 384 return (EINVAL); 385 386 387 if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) 388 return (EINVAL); 389 390 OUT_RING(cmd); 391 392 while (++i, --sz) { 393 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], 394 sizeof(cmd))) { 395 return (EINVAL); 396 } 397 OUT_RING(cmd); 398 } 399 } 400 401 if (dwords & 1) 402 OUT_RING(0); 403 404 ADVANCE_LP_RING(); 405 406 return 0; 407 } 408 409 static int i915_emit_box(drm_device_t * dev, 410 drm_clip_rect_t __user * boxes, 411 int i, int DR1, int DR4) 412 { 413 drm_i915_private_t *dev_priv = dev->dev_private; 414 drm_clip_rect_t box; 415 RING_LOCALS; 416 417 if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { 418 return (EFAULT); 419 } 420 421 if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { 422 DRM_ERROR("Bad box %d,%d..%d,%d\n", 423 box.x1, box.y1, box.x2, box.y2); 424 return (EINVAL); 425 } 426 427 if (IS_I965G(dev)) { 428 BEGIN_LP_RING(4); 429 OUT_RING(GFX_OP_DRAWRECT_INFO_I965); 430 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); 431 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); 432 OUT_RING(DR4); 433 ADVANCE_LP_RING(); 434 } else { 435 BEGIN_LP_RING(6); 436 OUT_RING(GFX_OP_DRAWRECT_INFO); 437 OUT_RING(DR1); 438 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); 439 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); 440 OUT_RING(DR4); 441 OUT_RING(0); 442 ADVANCE_LP_RING(); 443 } 444 445 return 0; 446 } 447 448 /* XXX: Emitting the counter should really be moved to part of the IRQ 449 * emit. For now, do it in both places: 450 */ 451 452 static void i915_emit_breadcrumb(drm_device_t *dev) 453 { 454 drm_i915_private_t *dev_priv = dev->dev_private; 455 RING_LOCALS; 456 457 dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; 458 459 BEGIN_LP_RING(4); 460 OUT_RING(CMD_STORE_DWORD_IDX); 461 OUT_RING(20); 462 OUT_RING(dev_priv->counter); 463 OUT_RING(0); 464 ADVANCE_LP_RING(); 465 #ifdef I915_HAVE_FENCE 466 drm_fence_flush_old(dev, 0, dev_priv->counter); 467 #endif 468 } 469 470 471 int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush) 472 { 473 drm_i915_private_t *dev_priv = dev->dev_private; 474 uint32_t flush_cmd = CMD_MI_FLUSH; 475 RING_LOCALS; 476 477 flush_cmd |= flush; 478 479 i915_kernel_lost_context(dev); 480 481 BEGIN_LP_RING(4); 482 OUT_RING(flush_cmd); 483 OUT_RING(0); 484 OUT_RING(0); 485 OUT_RING(0); 486 ADVANCE_LP_RING(); 487 488 return 0; 489 } 490 491 static int i915_dispatch_cmdbuffer(drm_device_t * dev, 492 drm_i915_cmdbuffer_t * cmd) 493 { 494 int nbox = cmd->num_cliprects; 495 int i = 0, count, ret; 496 497 if (cmd->sz & 0x3) { 498 DRM_ERROR("alignment"); 499 return (EINVAL); 500 } 501 502 i915_kernel_lost_context(dev); 503 504 count = nbox ? nbox : 1; 505 506 for (i = 0; i < count; i++) { 507 if (i < nbox) { 508 ret = i915_emit_box(dev, cmd->cliprects, i, 509 cmd->DR1, cmd->DR4); 510 if (ret) 511 return ret; 512 } 513 514 ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4); 515 if (ret) 516 return ret; 517 } 518 519 i915_emit_breadcrumb( dev ); 520 return 0; 521 } 522 523 static int i915_dispatch_batchbuffer(drm_device_t * dev, 524 drm_i915_batchbuffer_t * batch) 525 { 526 drm_i915_private_t *dev_priv = dev->dev_private; 527 drm_clip_rect_t __user *boxes = batch->cliprects; 528 int nbox = batch->num_cliprects; 529 int i = 0, count; 530 RING_LOCALS; 531 532 if ((batch->start | batch->used) & 0x7) { 533 DRM_ERROR("alignment"); 534 return (EINVAL); 535 } 536 537 i915_kernel_lost_context(dev); 538 539 count = nbox ? nbox : 1; 540 541 for (i = 0; i < count; i++) { 542 if (i < nbox) { 543 int ret = i915_emit_box(dev, boxes, i, 544 batch->DR1, batch->DR4); 545 if (ret) 546 return ret; 547 } 548 549 if (dev_priv->use_mi_batchbuffer_start) { 550 BEGIN_LP_RING(2); 551 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); 552 OUT_RING(batch->start | MI_BATCH_NON_SECURE); 553 ADVANCE_LP_RING(); 554 } else { 555 BEGIN_LP_RING(4); 556 OUT_RING(MI_BATCH_BUFFER); 557 OUT_RING(batch->start | MI_BATCH_NON_SECURE); 558 OUT_RING(batch->start + batch->used - 4); 559 OUT_RING(0); 560 ADVANCE_LP_RING(); 561 } 562 } 563 564 i915_emit_breadcrumb( dev ); 565 566 return 0; 567 } 568 569 static int i915_dispatch_flip(drm_device_t * dev) 570 { 571 drm_i915_private_t *dev_priv = dev->dev_private; 572 RING_LOCALS; 573 574 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 575 __FUNCTION__, 576 dev_priv->current_page, 577 dev_priv->sarea_priv->pf_current_page); 578 579 i915_kernel_lost_context(dev); 580 581 BEGIN_LP_RING(2); 582 OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); 583 OUT_RING(0); 584 ADVANCE_LP_RING(); 585 586 BEGIN_LP_RING(6); 587 OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); 588 OUT_RING(0); 589 if (dev_priv->current_page == 0) { 590 OUT_RING(dev_priv->back_offset); 591 dev_priv->current_page = 1; 592 } else { 593 OUT_RING(dev_priv->front_offset); 594 dev_priv->current_page = 0; 595 } 596 OUT_RING(0); 597 ADVANCE_LP_RING(); 598 599 BEGIN_LP_RING(2); 600 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); 601 OUT_RING(0); 602 ADVANCE_LP_RING(); 603 604 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; 605 606 BEGIN_LP_RING(4); 607 OUT_RING(CMD_STORE_DWORD_IDX); 608 OUT_RING(20); 609 OUT_RING(dev_priv->counter); 610 OUT_RING(0); 611 ADVANCE_LP_RING(); 612 #ifdef I915_HAVE_FENCE 613 drm_fence_flush_old(dev, 0, dev_priv->counter); 614 #endif 615 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 616 return 0; 617 } 618 619 static int i915_quiescent(drm_device_t * dev) 620 { 621 drm_i915_private_t *dev_priv = dev->dev_private; 622 623 i915_kernel_lost_context(dev); 624 return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); 625 } 626 627 /*ARGSUSED*/ 628 static int i915_flush_ioctl(DRM_IOCTL_ARGS) 629 { 630 DRM_DEVICE; 631 632 LOCK_TEST_WITH_RETURN(dev, fpriv); 633 634 return i915_quiescent(dev); 635 } 636 637 /*ARGSUSED*/ 638 static int i915_batchbuffer(DRM_IOCTL_ARGS) 639 { 640 DRM_DEVICE; 641 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 642 u32 *hw_status = dev_priv->hw_status_page; 643 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 644 dev_priv->sarea_priv; 645 drm_i915_batchbuffer_t batch; 646 int ret; 647 648 if (!dev_priv->allow_batchbuffer) { 649 DRM_ERROR("Batchbuffer ioctl disabled\n"); 650 return (EINVAL); 651 } 652 653 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { 654 drm_i915_batchbuffer32_t batchbuffer32_t; 655 656 DRM_COPYFROM_WITH_RETURN(&batchbuffer32_t, 657 (void *) data, sizeof (batchbuffer32_t)); 658 659 batch.start = batchbuffer32_t.start; 660 batch.used = batchbuffer32_t.used; 661 batch.DR1 = batchbuffer32_t.DR1; 662 batch.DR4 = batchbuffer32_t.DR4; 663 batch.num_cliprects = batchbuffer32_t.num_cliprects; 664 batch.cliprects = (drm_clip_rect_t __user *) 665 (uintptr_t)batchbuffer32_t.cliprects; 666 } else 667 DRM_COPYFROM_WITH_RETURN(&batch, (void *) data, 668 sizeof(batch)); 669 670 DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", 671 batch.start, batch.used, batch.num_cliprects); 672 673 LOCK_TEST_WITH_RETURN(dev, fpriv); 674 /* 675 676 if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects, 677 batch.num_cliprects * 678 sizeof(drm_clip_rect_t))) 679 return (EFAULT); 680 */ 681 682 ret = i915_dispatch_batchbuffer(dev, &batch); 683 684 sarea_priv->last_dispatch = (int)hw_status[5]; 685 return ret; 686 } 687 688 /*ARGSUSED*/ 689 static int i915_cmdbuffer(DRM_IOCTL_ARGS) 690 { 691 DRM_DEVICE; 692 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 693 u32 *hw_status = dev_priv->hw_status_page; 694 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 695 dev_priv->sarea_priv; 696 drm_i915_cmdbuffer_t cmdbuf; 697 int ret; 698 699 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { 700 drm_i915_cmdbuffer32_t cmdbuffer32_t; 701 702 DRM_COPYFROM_WITH_RETURN(&cmdbuffer32_t, 703 (drm_i915_cmdbuffer32_t __user *) data, 704 sizeof (drm_i915_cmdbuffer32_t)); 705 706 cmdbuf.buf = (char __user *)(uintptr_t)cmdbuffer32_t.buf; 707 cmdbuf.sz = cmdbuffer32_t.sz; 708 cmdbuf.DR1 = cmdbuffer32_t.DR1; 709 cmdbuf.DR4 = cmdbuffer32_t.DR4; 710 cmdbuf.num_cliprects = cmdbuffer32_t.num_cliprects; 711 cmdbuf.cliprects = (drm_clip_rect_t __user *) 712 (uintptr_t)cmdbuffer32_t.cliprects; 713 } else 714 DRM_COPYFROM_WITH_RETURN(&cmdbuf, (void *) data, 715 sizeof(cmdbuf)); 716 717 DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", 718 cmdbuf.buf, cmdbuf.sz, cmdbuf.num_cliprects); 719 720 LOCK_TEST_WITH_RETURN(dev, fpriv); 721 /* 722 723 if (cmdbuf.num_cliprects && 724 DRM_VERIFYAREA_READ(cmdbuf.cliprects, 725 cmdbuf.num_cliprects * 726 sizeof(drm_clip_rect_t))) { 727 DRM_ERROR("Fault accessing cliprects\n"); 728 return (EFAULT); 729 } 730 */ 731 732 ret = i915_dispatch_cmdbuffer(dev, &cmdbuf); 733 if (ret) { 734 DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); 735 return ret; 736 } 737 738 sarea_priv->last_dispatch = (int)hw_status[5]; 739 return 0; 740 } 741 742 static int i915_do_cleanup_pageflip(drm_device_t * dev) 743 { 744 drm_i915_private_t *dev_priv = dev->dev_private; 745 746 DRM_DEBUG("%s\n", __FUNCTION__); 747 if (dev_priv->current_page != 0) 748 (void) i915_dispatch_flip(dev); 749 750 return 0; 751 } 752 753 /*ARGSUSED*/ 754 static int i915_flip_bufs(DRM_IOCTL_ARGS) 755 { 756 DRM_DEVICE; 757 758 DRM_DEBUG("%s\n", __FUNCTION__); 759 760 LOCK_TEST_WITH_RETURN(dev, fpriv); 761 762 return i915_dispatch_flip(dev); 763 } 764 765 /*ARGSUSED*/ 766 static int i915_getparam(DRM_IOCTL_ARGS) 767 { 768 DRM_DEVICE; 769 drm_i915_private_t *dev_priv = dev->dev_private; 770 drm_i915_getparam_t param; 771 int value; 772 773 if (!dev_priv) { 774 DRM_ERROR("%s called with no initialization\n", __FUNCTION__); 775 return (EINVAL); 776 } 777 778 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { 779 drm_i915_getparam32_t getparam32_t; 780 781 DRM_COPYFROM_WITH_RETURN(&getparam32_t, 782 (drm_i915_getparam32_t __user *) data, 783 sizeof (drm_i915_getparam32_t)); 784 785 param.param = getparam32_t.param; 786 param.value = (int __user *)(uintptr_t)getparam32_t.value; 787 } else 788 DRM_COPYFROM_WITH_RETURN(¶m, 789 (drm_i915_getparam_t *) data, sizeof(param)); 790 791 switch (param.param) { 792 case I915_PARAM_IRQ_ACTIVE: 793 value = dev->irq ? 1 : 0; 794 break; 795 case I915_PARAM_ALLOW_BATCHBUFFER: 796 value = dev_priv->allow_batchbuffer ? 1 : 0; 797 break; 798 case I915_PARAM_LAST_DISPATCH: 799 value = READ_BREADCRUMB(dev_priv); 800 break; 801 default: 802 DRM_ERROR("Unknown parameter %d\n", param.param); 803 return (EINVAL); 804 } 805 806 if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { 807 DRM_ERROR("i915_getparam failed\n"); 808 return (EFAULT); 809 } 810 return 0; 811 } 812 813 /*ARGSUSED*/ 814 static int i915_setparam(DRM_IOCTL_ARGS) 815 { 816 DRM_DEVICE; 817 drm_i915_private_t *dev_priv = dev->dev_private; 818 drm_i915_setparam_t param; 819 820 if (!dev_priv) { 821 DRM_ERROR("%s called with no initialization\n", __FUNCTION__); 822 return (EINVAL); 823 } 824 825 DRM_COPYFROM_WITH_RETURN(¶m, (drm_i915_setparam_t *) data, 826 sizeof(param)); 827 828 switch (param.param) { 829 case I915_SETPARAM_USE_MI_BATCHBUFFER_START: 830 dev_priv->use_mi_batchbuffer_start = param.value; 831 break; 832 case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: 833 dev_priv->tex_lru_log_granularity = param.value; 834 break; 835 case I915_SETPARAM_ALLOW_BATCHBUFFER: 836 dev_priv->allow_batchbuffer = param.value; 837 break; 838 default: 839 DRM_ERROR("unknown parameter %d\n", param.param); 840 return (EINVAL); 841 } 842 843 return 0; 844 } 845 846 /*ARGSUSED*/ 847 int i915_driver_load(drm_device_t *dev, unsigned long flags) 848 { 849 /* i915 has 4 more counters */ 850 dev->counters += 4; 851 dev->types[6] = _DRM_STAT_IRQ; 852 dev->types[7] = _DRM_STAT_PRIMARY; 853 dev->types[8] = _DRM_STAT_SECONDARY; 854 dev->types[9] = _DRM_STAT_DMA; 855 856 return 0; 857 } 858 859 void i915_driver_lastclose(drm_device_t * dev) 860 { 861 if (dev->dev_private) { 862 drm_i915_private_t *dev_priv = dev->dev_private; 863 i915_mem_takedown(&(dev_priv->agp_heap)); 864 } 865 (void) i915_dma_cleanup(dev); 866 } 867 868 void i915_driver_preclose(drm_device_t * dev, drm_file_t *fpriv) 869 { 870 if (dev->dev_private) { 871 drm_i915_private_t *dev_priv = dev->dev_private; 872 if (dev_priv->page_flipping) { 873 (void) i915_do_cleanup_pageflip(dev); 874 } 875 i915_mem_release(dev, fpriv, dev_priv->agp_heap); 876 } 877 } 878 879 extern drm_ioctl_desc_t i915_ioctls[]; 880 881 void i915_set_ioctl_desc(int n, drm_ioctl_t * func, 882 int auth_needed, int root_only, char *desc) 883 { 884 i915_ioctls[n].func = func; 885 i915_ioctls[n].auth_needed = auth_needed; 886 i915_ioctls[n].root_only = root_only; 887 i915_ioctls[n].desc = desc; 888 } 889 void 890 i915_init_ioctl_arrays(void) 891 { 892 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_INIT), 893 i915_dma_init, 1, 1, "i915_dma_init"); 894 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_FLUSH), 895 i915_flush_ioctl, 1, 0, "i915_flush_ioctl"); 896 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_FLIP), 897 i915_flip_bufs, 1, 0, "i915_flip_bufs"); 898 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_BATCHBUFFER), 899 i915_batchbuffer, 1, 0, "i915_batchbuffer"); 900 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_IRQ_EMIT), 901 i915_irq_emit, 1, 0, " i915_irq_emit"); 902 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_IRQ_WAIT), 903 i915_irq_wait, 1, 0, "i915_irq_wait"); 904 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_GETPARAM), 905 i915_getparam, 1, 0, "i915_getparam"); 906 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_SETPARAM), 907 i915_setparam, 1, 1, "i915_setparam"); 908 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_ALLOC), 909 i915_mem_alloc, 1, 0, "i915_mem_alloc"); 910 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_FREE), 911 i915_mem_free, 1, 0, "i915_mem_free"); 912 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_INIT_HEAP), 913 i915_mem_init_heap, 1, 1, "i915_mem_init_heap"); 914 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_CMDBUFFER), 915 i915_cmdbuffer, 1, 0, "i915_cmdbuffer"); 916 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP), 917 i915_mem_destroy_heap, 1, 1, "i915_mem_destroy_heap"); 918 } 919 /** 920 * Determine if the device really is AGP or not. 921 * 922 * All Intel graphics chipsets are treated as AGP, even if they are really 923 * PCI-e. 924 * 925 * \param dev The device to be tested. 926 * 927 * \returns 928 * A value of 1 is always retured to indictate every i9x5 is AGP. 929 */ 930 /*ARGSUSED*/ 931 int i915_driver_device_is_agp(drm_device_t * dev) 932 { 933 return 1; 934 } 935