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 44 45 /* Really want an OS-independent resettable timer. Would like to have 46 * this loop run for (eg) 3 sec, but have the timer reset every time 47 * the head pointer changes, so that EBUSY only happens if the ring 48 * actually stalls for (eg) 3 seconds. 49 */ 50 /*ARGSUSED*/ 51 int i915_wait_ring(drm_device_t * dev, int n, const char *caller) 52 { 53 drm_i915_private_t *dev_priv = dev->dev_private; 54 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 55 u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 56 int i; 57 58 for (i = 0; i < 10000; i++) { 59 ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 60 ring->space = ring->head - (ring->tail + 8); 61 if (ring->space < 0) 62 ring->space += ring->Size; 63 if (ring->space >= n) 64 return 0; 65 66 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; 67 68 if (ring->head != last_head) 69 i = 0; 70 71 last_head = ring->head; 72 DRM_UDELAY(1); 73 } 74 75 return (EBUSY); 76 } 77 78 void i915_kernel_lost_context(drm_device_t * dev) 79 { 80 drm_i915_private_t *dev_priv = dev->dev_private; 81 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 82 83 ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 84 ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; 85 ring->space = ring->head - (ring->tail + 8); 86 if (ring->space < 0) 87 ring->space += ring->Size; 88 89 if (ring->head == ring->tail) 90 dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; 91 } 92 93 static int i915_dma_cleanup(drm_device_t * dev) 94 { 95 drm_i915_private_t *dev_priv = 96 (drm_i915_private_t *) dev->dev_private; 97 98 /* Make sure interrupts are disabled here because the uninstall ioctl 99 * may not have been called from userspace and after dev_private 100 * is freed, it's too late. 101 */ 102 if (dev->irq) 103 (void) drm_irq_uninstall(dev); 104 105 if (dev_priv->ring.virtual_start) { 106 drm_core_ioremapfree(&dev_priv->ring.map, dev); 107 dev_priv->ring.virtual_start = 0; 108 dev_priv->ring.map.handle = 0; 109 dev_priv->ring.map.size = 0; 110 } 111 112 if (dev_priv->status_page_dmah) { 113 drm_pci_free(dev, dev_priv->status_page_dmah); 114 dev_priv->status_page_dmah = NULL; 115 116 /* Need to rewrite hardware status page */ 117 I915_WRITE(0x02080, 0x1ffff000); 118 } 119 120 if (dev_priv->status_gfx_addr) { 121 dev_priv->status_gfx_addr = 0; 122 drm_core_ioremapfree(&dev_priv->hws_map, dev); 123 I915_WRITE(0x2080, 0x1ffff000); 124 } 125 126 return 0; 127 } 128 129 static int i915_initialize(drm_device_t * dev, 130 drm_i915_init_t * init) 131 { 132 drm_i915_private_t *dev_priv = 133 (drm_i915_private_t *)dev->dev_private; 134 135 DRM_GETSAREA(); 136 if (!dev_priv->sarea) { 137 DRM_ERROR("can not find sarea!\n"); 138 dev->dev_private = (void *)dev_priv; 139 (void) i915_dma_cleanup(dev); 140 return (EINVAL); 141 } 142 143 /* 144 * mmio_map will be destoried after DMA clean up. We should not 145 * access mmio_map in suspend or resume process. 146 */ 147 dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); 148 if (!dev_priv->mmio_map) { 149 dev->dev_private = (void *)dev_priv; 150 (void) i915_dma_cleanup(dev); 151 DRM_ERROR("can not find mmio map!\n"); 152 return (EINVAL); 153 } 154 155 dev_priv->sarea_priv = (drm_i915_sarea_t *)(void *) 156 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); 157 158 dev_priv->ring.Start = init->ring_start; 159 dev_priv->ring.End = init->ring_end; 160 dev_priv->ring.Size = init->ring_size; 161 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; 162 163 dev_priv->ring.map.offset = (u_offset_t)init->ring_start; 164 dev_priv->ring.map.size = init->ring_size; 165 dev_priv->ring.map.type = 0; 166 dev_priv->ring.map.flags = 0; 167 dev_priv->ring.map.mtrr = 0; 168 169 drm_core_ioremap(&dev_priv->ring.map, dev); 170 171 if (dev_priv->ring.map.handle == NULL) { 172 dev->dev_private = (void *)dev_priv; 173 (void) i915_dma_cleanup(dev); 174 DRM_ERROR("can not ioremap virtual address for" 175 " ring buffer\n"); 176 return (ENOMEM); 177 } 178 179 dev_priv->ring.virtual_start = (u8 *)dev_priv->ring.map.dev_addr; 180 181 dev_priv->cpp = init->cpp; 182 dev_priv->back_offset = init->back_offset; 183 dev_priv->front_offset = init->front_offset; 184 dev_priv->current_page = 0; 185 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 186 187 /* We are using separate values as placeholders for mechanisms for 188 * private backbuffer/depthbuffer usage. 189 */ 190 dev_priv->use_mi_batchbuffer_start = 0; 191 192 /* Allow hardware batchbuffers unless told otherwise. 193 */ 194 dev_priv->allow_batchbuffer = 1; 195 196 197 if (!IS_G33(dev)) { 198 /* Program Hardware Status Page */ 199 dev_priv->status_page_dmah = 200 drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 201 0xffffffff, 1); 202 203 if (!dev_priv->status_page_dmah) { 204 dev->dev_private = (void *)dev_priv; 205 (void) i915_dma_cleanup(dev); 206 DRM_ERROR("Can not allocate hardware status page\n"); 207 return (ENOMEM); 208 } 209 210 dev_priv->hw_status_page = 211 (void *)dev_priv->status_page_dmah->vaddr; 212 dev_priv->dma_status_page = dev_priv->status_page_dmah->paddr; 213 (void) memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 214 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 215 216 I915_WRITE(0x02080, dev_priv->dma_status_page); 217 } 218 DRM_DEBUG("Enabled hardware status page\n"); 219 220 221 #ifdef I915_HAVE_BUFFER 222 drm_bo_driver_init(dev); 223 #endif 224 return 0; 225 } 226 227 static int i915_dma_resume(drm_device_t * dev) 228 { 229 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 230 231 DRM_DEBUG("%s\n", __FUNCTION__); 232 233 if (!dev_priv->sarea) { 234 DRM_ERROR("can not find sarea!\n"); 235 return (EINVAL); 236 } 237 238 if (!dev_priv->mmio_map) { 239 DRM_ERROR("can not find mmio map!\n"); 240 return (EINVAL); 241 } 242 243 if (dev_priv->ring.map.handle == NULL) { 244 DRM_ERROR("can not ioremap virtual address for" 245 " ring buffer\n"); 246 return (ENOMEM); 247 } 248 249 /* Program Hardware Status Page */ 250 if (!dev_priv->hw_status_page) { 251 DRM_ERROR("Can not find hardware status page\n"); 252 return (EINVAL); 253 } 254 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 255 256 I915_WRITE(0x02080, dev_priv->dma_status_page); 257 DRM_DEBUG("Enabled hardware status page\n"); 258 259 return 0; 260 } 261 262 /*ARGSUSED*/ 263 static int i915_dma_init(DRM_IOCTL_ARGS) 264 { 265 DRM_DEVICE; 266 drm_i915_init_t init; 267 int retcode = 0; 268 269 DRM_COPYFROM_WITH_RETURN(&init, (drm_i915_init_t *)data, sizeof(init)); 270 271 switch (init.func) { 272 case I915_INIT_DMA: 273 retcode = i915_initialize(dev, &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) { 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 *)(void *)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 static int i915_set_status_page(DRM_IOCTL_ARGS) 848 { 849 DRM_DEVICE; 850 drm_i915_private_t *dev_priv = dev->dev_private; 851 drm_i915_hws_addr_t hws; 852 853 if (!dev_priv) { 854 DRM_ERROR("%s called with no initialization\n", __FUNCTION__); 855 return (EINVAL); 856 } 857 DRM_COPYFROM_WITH_RETURN(&hws, (drm_i915_hws_addr_t __user *) data, 858 sizeof(hws)); 859 DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws.addr); 860 861 dev_priv->status_gfx_addr = hws.addr & (0x1ffff<<12); 862 DRM_DEBUG("set gfx_addr 0x%08x\n", dev_priv->status_gfx_addr); 863 864 dev_priv->hws_map.offset = 865 (u_offset_t)dev->agp->agp_info.agpi_aperbase + hws.addr; 866 dev_priv->hws_map.size = PAGE_SIZE; /* 4K pages */ 867 dev_priv->hws_map.type = _DRM_REGISTERS; 868 dev_priv->hws_map.flags = 0; 869 dev_priv->hws_map.mtrr = 0; 870 871 DRM_DEBUG("set status page: i915_set_status_page: mapoffset 0x%llx\n", 872 dev_priv->hws_map.offset); 873 drm_core_ioremap(&dev_priv->hws_map, dev); 874 if (dev_priv->hws_map.handle == NULL) { 875 dev->dev_private = (void *)dev_priv; 876 (void) i915_dma_cleanup(dev); 877 dev_priv->status_gfx_addr = 0; 878 DRM_ERROR("can not ioremap virtual address for" 879 " G33 hw status page\n"); 880 return (ENOMEM); 881 } 882 dev_priv->hw_status_page = dev_priv->hws_map.dev_addr; 883 884 (void) memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 885 I915_WRITE(0x02080, dev_priv->status_gfx_addr); 886 DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n", 887 dev_priv->status_gfx_addr); 888 DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page); 889 return 0; 890 } 891 892 /*ARGSUSED*/ 893 int i915_driver_load(drm_device_t *dev, unsigned long flags) 894 { 895 struct drm_i915_private *dev_priv; 896 897 /* i915 has 4 more counters */ 898 dev->counters += 4; 899 dev->types[6] = _DRM_STAT_IRQ; 900 dev->types[7] = _DRM_STAT_PRIMARY; 901 dev->types[8] = _DRM_STAT_SECONDARY; 902 dev->types[9] = _DRM_STAT_DMA; 903 904 dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); 905 if (dev_priv == NULL) 906 return ENOMEM; 907 908 (void) memset(dev_priv, 0, sizeof(drm_i915_private_t)); 909 dev->dev_private = (void *)dev_priv; 910 911 return 0; 912 } 913 914 int i915_driver_unload(struct drm_device *dev) 915 { 916 drm_free(dev->dev_private, sizeof(drm_i915_private_t), 917 DRM_MEM_DRIVER); 918 919 return 0; 920 } 921 922 923 void i915_driver_lastclose(drm_device_t * dev) 924 { 925 if (dev->dev_private) { 926 drm_i915_private_t *dev_priv = dev->dev_private; 927 i915_mem_takedown(&(dev_priv->agp_heap)); 928 } 929 (void) i915_dma_cleanup(dev); 930 } 931 932 void i915_driver_preclose(drm_device_t * dev, drm_file_t *fpriv) 933 { 934 if (dev->dev_private) { 935 drm_i915_private_t *dev_priv = dev->dev_private; 936 if (dev_priv->page_flipping) { 937 (void) i915_do_cleanup_pageflip(dev); 938 } 939 i915_mem_release(dev, fpriv, dev_priv->agp_heap); 940 } 941 } 942 943 extern drm_ioctl_desc_t i915_ioctls[]; 944 945 void i915_set_ioctl_desc(int n, drm_ioctl_t * func, 946 int auth_needed, int root_only, char *desc) 947 { 948 i915_ioctls[n].func = func; 949 i915_ioctls[n].auth_needed = auth_needed; 950 i915_ioctls[n].root_only = root_only; 951 i915_ioctls[n].desc = desc; 952 } 953 void 954 i915_init_ioctl_arrays(void) 955 { 956 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_INIT), 957 i915_dma_init, 1, 1, "i915_dma_init"); 958 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_FLUSH), 959 i915_flush_ioctl, 1, 0, "i915_flush_ioctl"); 960 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_FLIP), 961 i915_flip_bufs, 1, 0, "i915_flip_bufs"); 962 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_BATCHBUFFER), 963 i915_batchbuffer, 1, 0, "i915_batchbuffer"); 964 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_IRQ_EMIT), 965 i915_irq_emit, 1, 0, " i915_irq_emit"); 966 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_IRQ_WAIT), 967 i915_irq_wait, 1, 0, "i915_irq_wait"); 968 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_GETPARAM), 969 i915_getparam, 1, 0, "i915_getparam"); 970 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_SETPARAM), 971 i915_setparam, 1, 1, "i915_setparam"); 972 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_ALLOC), 973 i915_mem_alloc, 1, 0, "i915_mem_alloc"); 974 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_FREE), 975 i915_mem_free, 1, 0, "i915_mem_free"); 976 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_INIT_HEAP), 977 i915_mem_init_heap, 1, 1, "i915_mem_init_heap"); 978 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_CMDBUFFER), 979 i915_cmdbuffer, 1, 0, "i915_cmdbuffer"); 980 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP), 981 i915_mem_destroy_heap, 1, 1, "i915_mem_destroy_heap"); 982 i915_set_ioctl_desc(DRM_IOCTL_NR(DRM_I915_HWS_ADDR), 983 i915_set_status_page, 1, 0, "i915_set_status_page"); 984 } 985 /** 986 * Determine if the device really is AGP or not. 987 * 988 * All Intel graphics chipsets are treated as AGP, even if they are really 989 * PCI-e. 990 * 991 * \param dev The device to be tested. 992 * 993 * \returns 994 * A value of 1 is always retured to indictate every i9x5 is AGP. 995 */ 996 /*ARGSUSED*/ 997 int i915_driver_device_is_agp(drm_device_t * dev) 998 { 999 return 1; 1000 } 1001