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