1 /* BEGIN CSTYLED */ 2 3 /* i915_irq.c -- IRQ 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 2009 Sun Microsystems, Inc. All rights reserved. 33 * Use is subject to license terms. 34 */ 35 36 #include "drmP.h" 37 #include "drm.h" 38 #include "i915_drm.h" 39 #include "i915_drv.h" 40 41 42 #define MAX_NOPID ((u32)~0) 43 44 /* 45 * These are the interrupts used by the driver 46 */ 47 #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \ 48 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ 49 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) 50 51 static inline void 52 i915_enable_irq(drm_i915_private_t *dev_priv, uint32_t mask) 53 { 54 if ((dev_priv->irq_mask_reg & mask) != 0) { 55 dev_priv->irq_mask_reg &= ~mask; 56 I915_WRITE(IMR, dev_priv->irq_mask_reg); 57 (void) I915_READ(IMR); 58 } 59 } 60 61 static inline void 62 i915_disable_irq(drm_i915_private_t *dev_priv, uint32_t mask) 63 { 64 if ((dev_priv->irq_mask_reg & mask) != mask) { 65 dev_priv->irq_mask_reg |= mask; 66 I915_WRITE(IMR, dev_priv->irq_mask_reg); 67 (void) I915_READ(IMR); 68 } 69 } 70 /** 71 * i915_get_pipe - return the the pipe associated with a given plane 72 * @dev: DRM device 73 * @plane: plane to look for 74 * 75 * The Intel Mesa & 2D drivers call the vblank routines with a plane number 76 * rather than a pipe number, since they may not always be equal. This routine 77 * maps the given @plane back to a pipe number. 78 */ 79 static int 80 i915_get_pipe(struct drm_device *dev, int plane) 81 { 82 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 83 u32 dspcntr; 84 85 dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR); 86 87 return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0; 88 } 89 90 /** 91 * i915_get_plane - return the the plane associated with a given pipe 92 * @dev: DRM device 93 * @pipe: pipe to look for 94 * 95 * The Intel Mesa & 2D drivers call the vblank routines with a plane number 96 * rather than a plane number, since they may not always be equal. This routine 97 * maps the given @pipe back to a plane number. 98 */ 99 static int 100 i915_get_plane(struct drm_device *dev, int pipe) 101 { 102 if (i915_get_pipe(dev, 0) == pipe) 103 return 0; 104 return 1; 105 } 106 107 /** 108 * i915_pipe_enabled - check if a pipe is enabled 109 * @dev: DRM device 110 * @pipe: pipe to check 111 * 112 * Reading certain registers when the pipe is disabled can hang the chip. 113 * Use this routine to make sure the PLL is running and the pipe is active 114 * before reading such registers if unsure. 115 */ 116 static int 117 i915_pipe_enabled(struct drm_device *dev, int pipe) 118 { 119 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 120 unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF; 121 122 if (I915_READ(pipeconf) & PIPEACONF_ENABLE) 123 return 1; 124 125 return 0; 126 } 127 128 /** 129 * Emit a synchronous flip. 130 * 131 * This function must be called with the drawable spinlock held. 132 */ 133 static void 134 i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, 135 int plane) 136 { 137 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 138 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; 139 u16 x1, y1, x2, y2; 140 int pf_planes = 1 << plane; 141 142 DRM_SPINLOCK_ASSERT(&dev->drw_lock); 143 144 /* If the window is visible on the other plane, we have to flip on that 145 * plane as well. 146 */ 147 if (plane == 1) { 148 x1 = sarea_priv->planeA_x; 149 y1 = sarea_priv->planeA_y; 150 x2 = x1 + sarea_priv->planeA_w; 151 y2 = y1 + sarea_priv->planeA_h; 152 } else { 153 x1 = sarea_priv->planeB_x; 154 y1 = sarea_priv->planeB_y; 155 x2 = x1 + sarea_priv->planeB_w; 156 y2 = y1 + sarea_priv->planeB_h; 157 } 158 159 if (x2 > 0 && y2 > 0) { 160 int i, num_rects = drw->num_rects; 161 struct drm_clip_rect *rect = drw->rects; 162 163 for (i = 0; i < num_rects; i++) 164 if (!(rect[i].x1 >= x2 || rect[i].y1 >= y2 || 165 rect[i].x2 <= x1 || rect[i].y2 <= y1)) { 166 pf_planes = 0x3; 167 168 break; 169 } 170 } 171 172 i915_dispatch_flip(dev, pf_planes, 1); 173 } 174 175 /** 176 * Emit blits for scheduled buffer swaps. 177 * 178 * This function will be called with the HW lock held. 179 */ 180 static void i915_vblank_tasklet(drm_device_t *dev) 181 { 182 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 183 struct list_head *list, *tmp, hits, *hit; 184 int nhits, slice[2], upper[2], lower[2], i, num_pages; 185 unsigned counter[2]; 186 struct drm_drawable_info *drw; 187 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; 188 u32 cpp = dev_priv->cpp, offsets[3]; 189 u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | 190 XY_SRC_COPY_BLT_WRITE_ALPHA | 191 XY_SRC_COPY_BLT_WRITE_RGB) 192 : XY_SRC_COPY_BLT_CMD; 193 u32 src_pitch = sarea_priv->pitch * cpp; 194 u32 dst_pitch = sarea_priv->pitch * cpp; 195 /* COPY rop (0xcc), map cpp to magic color depth constants */ 196 u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24); 197 RING_LOCALS; 198 199 if (IS_I965G(dev) && sarea_priv->front_tiled) { 200 cmd |= XY_SRC_COPY_BLT_DST_TILED; 201 dst_pitch >>= 2; 202 } 203 if (IS_I965G(dev) && sarea_priv->back_tiled) { 204 cmd |= XY_SRC_COPY_BLT_SRC_TILED; 205 src_pitch >>= 2; 206 } 207 208 counter[0] = drm_vblank_count(dev, 0); 209 counter[1] = drm_vblank_count(dev, 1); 210 211 INIT_LIST_HEAD(&hits); 212 213 nhits = 0; 214 215 /* No irqsave/restore necessary. This tasklet may be run in an 216 * interrupt context or normal context, but we don't have to worry 217 * about getting interrupted by something acquiring the lock, because 218 * we are the interrupt context thing that acquires the lock. 219 */ 220 DRM_SPINLOCK(&dev_priv->swaps_lock); 221 222 /* Find buffer swaps scheduled for this vertical blank */ 223 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { 224 drm_i915_vbl_swap_t *vbl_swap = 225 list_entry(list, drm_i915_vbl_swap_t, head); 226 int pipe = i915_get_pipe(dev, vbl_swap->plane); 227 228 if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) 229 continue; 230 231 list_del(list); 232 dev_priv->swaps_pending--; 233 drm_vblank_put(dev, pipe); 234 235 DRM_SPINUNLOCK(&dev_priv->swaps_lock); 236 DRM_SPINLOCK(&dev->drw_lock); 237 238 drw = drm_get_drawable_info(dev, vbl_swap->drw_id); 239 240 if (!drw) { 241 DRM_SPINUNLOCK(&dev->drw_lock); 242 drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); 243 DRM_SPINLOCK(&dev_priv->swaps_lock); 244 continue; 245 } 246 247 list_for_each(hit, &hits) { 248 drm_i915_vbl_swap_t *swap_cmp = 249 list_entry(hit, drm_i915_vbl_swap_t, head); 250 struct drm_drawable_info *drw_cmp = 251 drm_get_drawable_info(dev, swap_cmp->drw_id); 252 253 if (drw_cmp && 254 drw_cmp->rects[0].y1 > drw->rects[0].y1) { 255 list_add_tail(list, hit); 256 break; 257 } 258 } 259 260 DRM_SPINUNLOCK(&dev->drw_lock); 261 262 /* List of hits was empty, or we reached the end of it */ 263 if (hit == &hits) 264 list_add_tail(list, hits.prev); 265 266 nhits++; 267 268 DRM_SPINLOCK(&dev_priv->swaps_lock); 269 } 270 271 DRM_SPINUNLOCK(&dev_priv->swaps_lock); 272 273 if (nhits == 0) { 274 return; 275 } 276 277 i915_kernel_lost_context(dev); 278 279 upper[0] = upper[1] = 0; 280 slice[0] = max(sarea_priv->planeA_h / nhits, 1); 281 slice[1] = max(sarea_priv->planeB_h / nhits, 1); 282 lower[0] = sarea_priv->planeA_y + slice[0]; 283 lower[1] = sarea_priv->planeB_y + slice[0]; 284 285 offsets[0] = sarea_priv->front_offset; 286 offsets[1] = sarea_priv->back_offset; 287 offsets[2] = sarea_priv->third_offset; 288 num_pages = sarea_priv->third_handle ? 3 : 2; 289 290 DRM_SPINLOCK(&dev->drw_lock); 291 292 /* Emit blits for buffer swaps, partitioning both outputs into as many 293 * slices as there are buffer swaps scheduled in order to avoid tearing 294 * (based on the assumption that a single buffer swap would always 295 * complete before scanout starts). 296 */ 297 for (i = 0; i++ < nhits; 298 upper[0] = lower[0], lower[0] += slice[0], 299 upper[1] = lower[1], lower[1] += slice[1]) { 300 int init_drawrect = 1; 301 302 if (i == nhits) 303 lower[0] = lower[1] = sarea_priv->height; 304 305 list_for_each(hit, &hits) { 306 drm_i915_vbl_swap_t *swap_hit = 307 list_entry(hit, drm_i915_vbl_swap_t, head); 308 struct drm_clip_rect *rect; 309 int num_rects, plane, front, back; 310 unsigned short top, bottom; 311 312 drw = drm_get_drawable_info(dev, swap_hit->drw_id); 313 314 if (!drw) 315 continue; 316 317 plane = swap_hit->plane; 318 319 if (swap_hit->flip) { 320 i915_dispatch_vsync_flip(dev, drw, plane); 321 continue; 322 } 323 324 if (init_drawrect) { 325 int width = sarea_priv->width; 326 int height = sarea_priv->height; 327 if (IS_I965G(dev)) { 328 BEGIN_LP_RING(4); 329 OUT_RING(GFX_OP_DRAWRECT_INFO_I965); 330 OUT_RING(0); 331 OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16)); 332 OUT_RING(0); 333 ADVANCE_LP_RING(); 334 } else { 335 BEGIN_LP_RING(6); 336 OUT_RING(GFX_OP_DRAWRECT_INFO); 337 OUT_RING(0); 338 OUT_RING(0); 339 OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16)); 340 OUT_RING(0); 341 OUT_RING(0); 342 ADVANCE_LP_RING(); 343 } 344 345 sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; 346 347 init_drawrect = 0; 348 } 349 350 rect = drw->rects; 351 top = upper[plane]; 352 bottom = lower[plane]; 353 354 front = (dev_priv->sarea_priv->pf_current_page >> 355 (2 * plane)) & 0x3; 356 back = (front + 1) % num_pages; 357 358 for (num_rects = drw->num_rects; num_rects--; rect++) { 359 int y1 = max(rect->y1, top); 360 int y2 = min(rect->y2, bottom); 361 362 if (y1 >= y2) 363 continue; 364 365 BEGIN_LP_RING(8); 366 OUT_RING(cmd); 367 OUT_RING(ropcpp | dst_pitch); 368 OUT_RING((y1 << 16) | rect->x1); 369 OUT_RING((y2 << 16) | rect->x2); 370 OUT_RING(offsets[front]); 371 OUT_RING((y1 << 16) | rect->x1); 372 OUT_RING(src_pitch); 373 OUT_RING(offsets[back]); 374 ADVANCE_LP_RING(); 375 } 376 } 377 } 378 379 DRM_SPINUNLOCK(&dev->drw_lock); 380 381 list_for_each_safe(hit, tmp, &hits) { 382 drm_i915_vbl_swap_t *swap_hit = 383 list_entry(hit, drm_i915_vbl_swap_t, head); 384 385 list_del(hit); 386 387 drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER); 388 } 389 } 390 391 u32 i915_get_vblank_counter(struct drm_device *dev, int plane) 392 { 393 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 394 unsigned long high_frame; 395 unsigned long low_frame; 396 u32 high1, high2, low, count; 397 int pipe; 398 399 pipe = i915_get_pipe(dev, plane); 400 high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; 401 low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; 402 403 if (!i915_pipe_enabled(dev, pipe)) { 404 DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); 405 return 0; 406 } 407 408 /* 409 * High & low register fields aren't synchronized, so make sure 410 * we get a low value that's stable across two reads of the high 411 * register. 412 */ 413 do { 414 high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> 415 PIPE_FRAME_HIGH_SHIFT); 416 low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> 417 PIPE_FRAME_LOW_SHIFT); 418 high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> 419 PIPE_FRAME_HIGH_SHIFT); 420 } while (high1 != high2); 421 422 count = (high1 << 8) | low; 423 424 /* count may be reset by other driver(e.g. 2D driver), 425 we have no way to know if it is wrapped or resetted 426 when count is zero. do a rough guess. 427 */ 428 if (count < dev->last_vblank[pipe] && dev->last_vblank[pipe] < dev->max_vblank_count/2) 429 dev->last_vblank[pipe]=0; 430 return count; 431 } 432 433 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) 434 { 435 drm_device_t *dev = (drm_device_t *) (void *) arg; 436 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 437 u32 iir; 438 u32 pipea_stats = 0, pipeb_stats = 0; 439 int vblank = 0; 440 iir = I915_READ(IIR); 441 442 atomic_inc(&dev_priv->irq_received); 443 444 if (iir == 0) { 445 return IRQ_NONE; 446 } 447 448 if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { 449 pipea_stats = I915_READ(PIPEASTAT); 450 451 /* The vblank interrupt gets enabled even if we didn't ask for 452 it, so make sure it's shut down again */ 453 if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)) 454 pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | 455 PIPE_VBLANK_INTERRUPT_ENABLE); 456 else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| 457 PIPE_VBLANK_INTERRUPT_STATUS)) 458 { 459 vblank++; 460 drm_handle_vblank(dev, i915_get_plane(dev, 0)); 461 } 462 463 I915_WRITE(PIPEASTAT, pipea_stats); 464 } 465 if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) { 466 pipeb_stats = I915_READ(PIPEBSTAT); 467 468 /* The vblank interrupt gets enabled even if we didn't ask for 469 it, so make sure it's shut down again */ 470 if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)) 471 pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | 472 PIPE_VBLANK_INTERRUPT_ENABLE); 473 else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| 474 PIPE_VBLANK_INTERRUPT_STATUS)) 475 { 476 vblank++; 477 drm_handle_vblank(dev, i915_get_plane(dev, 1)); 478 } 479 480 I915_WRITE(PIPEBSTAT, pipeb_stats); 481 } 482 483 if (dev_priv->sarea_priv) 484 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 485 486 I915_WRITE(IIR, iir); 487 488 (void) I915_READ(IIR); /* Flush posted writes */ 489 490 if (iir & I915_USER_INTERRUPT) { 491 DRM_WAKEUP(&dev_priv->irq_queue); 492 #ifdef I915_HAVE_FENCE 493 i915_fence_handler(dev); 494 #endif 495 } 496 497 if (vblank) { 498 if (dev_priv->swaps_pending > 0) 499 drm_locked_tasklet(dev, i915_vblank_tasklet); 500 } 501 502 return IRQ_HANDLED; 503 504 } 505 506 int i915_emit_irq(drm_device_t * dev) 507 { 508 509 drm_i915_private_t *dev_priv = dev->dev_private; 510 RING_LOCALS; 511 512 i915_kernel_lost_context(dev); 513 514 i915_emit_breadcrumb(dev); 515 516 BEGIN_LP_RING(2); 517 OUT_RING(0); 518 OUT_RING(MI_USER_INTERRUPT); 519 ADVANCE_LP_RING(); 520 521 return dev_priv->counter; 522 } 523 524 void i915_user_irq_on(drm_i915_private_t *dev_priv) 525 { 526 spin_lock(&dev_priv->user_irq_lock); 527 if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){ 528 i915_enable_irq(dev_priv, I915_USER_INTERRUPT); 529 } 530 spin_unlock(&dev_priv->user_irq_lock); 531 532 } 533 534 void i915_user_irq_off(drm_i915_private_t *dev_priv) 535 { 536 spin_lock(&dev_priv->user_irq_lock); 537 if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { 538 i915_disable_irq(dev_priv, I915_USER_INTERRUPT); 539 } 540 spin_unlock(&dev_priv->user_irq_lock); 541 } 542 543 544 static int i915_wait_irq(drm_device_t * dev, int irq_nr) 545 { 546 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 547 int ret = 0; 548 549 550 551 if (!dev_priv) { 552 DRM_ERROR("called with no initialization\n"); 553 return -EINVAL; 554 } 555 556 557 558 559 if (READ_BREADCRUMB(dev_priv) >= irq_nr) { 560 if (dev_priv->sarea_priv) 561 dev_priv->sarea_priv->last_dispatch = 562 READ_BREADCRUMB(dev_priv); 563 return 0; 564 } 565 566 DRM_DEBUG("i915_wait_irq: irq_nr=%d breadcrumb=%d\n", irq_nr, READ_BREADCRUMB(dev_priv)); 567 i915_user_irq_on(dev_priv); 568 DRM_WAIT_ON(ret, &dev_priv->irq_queue, 3 * DRM_HZ, 569 READ_BREADCRUMB(dev_priv) >= irq_nr); 570 i915_user_irq_off(dev_priv); 571 572 if (ret == EBUSY || ret == EINTR) { 573 DRM_DEBUG("%d: EBUSY -- rec: %d emitted: %d\n", 574 ret, 575 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); 576 } 577 578 if (dev_priv->sarea_priv) 579 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 580 581 return ret; 582 } 583 584 585 /* Needs the lock as it touches the ring. 586 */ 587 /*ARGSUSED*/ 588 int i915_irq_emit(DRM_IOCTL_ARGS) 589 { 590 DRM_DEVICE; 591 drm_i915_private_t *dev_priv = dev->dev_private; 592 drm_i915_irq_emit_t emit; 593 int result; 594 595 LOCK_TEST_WITH_RETURN(dev, fpriv); 596 597 if (!dev_priv) { 598 DRM_ERROR("%s called with no initialization\n", __FUNCTION__); 599 return (EINVAL); 600 } 601 602 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { 603 drm_i915_irq_emit32_t irq_emit32; 604 605 DRM_COPYFROM_WITH_RETURN(&irq_emit32, 606 (drm_i915_irq_emit32_t __user *) data, 607 sizeof (drm_i915_irq_emit32_t)); 608 emit.irq_seq = (int __user *)(uintptr_t)irq_emit32.irq_seq; 609 } else 610 DRM_COPYFROM_WITH_RETURN(&emit, 611 (drm_i915_irq_emit_t __user *) data, sizeof(emit)); 612 613 result = i915_emit_irq(dev); 614 615 if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) { 616 DRM_ERROR("copy_to_user\n"); 617 return (EFAULT); 618 } 619 620 return 0; 621 } 622 623 /* Doesn't need the hardware lock. 624 */ 625 /*ARGSUSED*/ 626 int i915_irq_wait(DRM_IOCTL_ARGS) 627 { 628 DRM_DEVICE; 629 drm_i915_private_t *dev_priv = dev->dev_private; 630 drm_i915_irq_wait_t irqwait; 631 632 if (!dev_priv) { 633 DRM_ERROR("%s called with no initialization\n", __FUNCTION__); 634 return (EINVAL); 635 } 636 637 DRM_COPYFROM_WITH_RETURN(&irqwait, 638 (drm_i915_irq_wait_t __user *) data, sizeof(irqwait)); 639 640 return i915_wait_irq(dev, irqwait.irq_seq); 641 } 642 643 int i915_enable_vblank(struct drm_device *dev, int plane) 644 { 645 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 646 int pipe = i915_get_pipe(dev, plane); 647 u32 pipestat_reg = 0; 648 u32 mask_reg = 0; 649 u32 pipestat; 650 651 switch (pipe) { 652 case 0: 653 pipestat_reg = PIPEASTAT; 654 mask_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; 655 break; 656 case 1: 657 pipestat_reg = PIPEBSTAT; 658 mask_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; 659 break; 660 default: 661 DRM_ERROR("tried to enable vblank on non-existent pipe %d\n", 662 pipe); 663 break; 664 } 665 666 if (pipestat_reg) 667 { 668 pipestat = I915_READ (pipestat_reg); 669 /* 670 * Older chips didn't have the start vblank interrupt, 671 * but 672 */ 673 if (IS_I965G (dev)) 674 pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; 675 else 676 pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE; 677 /* 678 * Clear any pending status 679 */ 680 pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | 681 PIPE_VBLANK_INTERRUPT_STATUS); 682 I915_WRITE(pipestat_reg, pipestat); 683 } 684 DRM_SPINLOCK(&dev_priv->user_irq_lock); 685 i915_enable_irq(dev_priv, mask_reg); 686 DRM_SPINUNLOCK(&dev_priv->user_irq_lock); 687 688 return 0; 689 } 690 691 void i915_disable_vblank(struct drm_device *dev, int plane) 692 { 693 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 694 int pipe = i915_get_pipe(dev, plane); 695 u32 pipestat_reg = 0; 696 u32 mask_reg = 0; 697 u32 pipestat; 698 699 switch (pipe) { 700 case 0: 701 pipestat_reg = PIPEASTAT; 702 mask_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; 703 break; 704 case 1: 705 pipestat_reg = PIPEBSTAT; 706 mask_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; 707 break; 708 default: 709 DRM_ERROR("tried to disable vblank on non-existent pipe %d\n", 710 pipe); 711 break; 712 } 713 714 DRM_SPINLOCK(&dev_priv->user_irq_lock); 715 i915_disable_irq(dev_priv, mask_reg); 716 DRM_SPINUNLOCK(&dev_priv->user_irq_lock); 717 718 if (pipestat_reg) 719 { 720 pipestat = I915_READ (pipestat_reg); 721 pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | 722 PIPE_VBLANK_INTERRUPT_ENABLE); 723 /* 724 * Clear any pending status 725 */ 726 pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | 727 PIPE_VBLANK_INTERRUPT_STATUS); 728 I915_WRITE(pipestat_reg, pipestat); 729 (void) I915_READ(pipestat_reg); 730 } 731 } 732 733 734 static void i915_enable_interrupt (drm_device_t *dev) 735 { 736 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 737 738 dev_priv->irq_mask_reg = 0xffffffff; 739 I915_WRITE(IMR, dev_priv->irq_mask_reg); 740 I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); 741 (void) I915_READ (IER); 742 743 dev_priv->irq_enabled = 1; 744 } 745 746 /* Set the vblank monitor pipe 747 */ 748 /*ARGSUSED*/ 749 int i915_vblank_pipe_set(DRM_IOCTL_ARGS) 750 { 751 DRM_DEVICE; 752 drm_i915_private_t *dev_priv = dev->dev_private; 753 754 if (!dev_priv) { 755 DRM_ERROR("called with no initialization\n"); 756 return (-EINVAL); 757 } 758 759 return (0); 760 } 761 762 /*ARGSUSED*/ 763 int i915_vblank_pipe_get(DRM_IOCTL_ARGS) 764 { 765 DRM_DEVICE; 766 drm_i915_private_t *dev_priv = dev->dev_private; 767 drm_i915_vblank_pipe_t pipe; 768 769 if (!dev_priv) { 770 DRM_ERROR("called with no initialization\n"); 771 return -EINVAL; 772 } 773 774 775 DRM_COPYFROM_WITH_RETURN(&pipe, (drm_i915_vblank_pipe_t __user *)data, sizeof (pipe)); 776 777 pipe.pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; 778 779 return 0; 780 } 781 782 /** 783 * Schedule buffer swap at given vertical blank. 784 */ 785 /*ARGSUSED*/ 786 int i915_vblank_swap(DRM_IOCTL_ARGS) 787 { 788 DRM_DEVICE; 789 drm_i915_private_t *dev_priv = dev->dev_private; 790 drm_i915_vblank_swap_t *swap; 791 drm_i915_vbl_swap_t *vbl_swap; 792 unsigned int pipe, seqtype, curseq, plane; 793 struct list_head *list; 794 int ret; 795 796 if (!dev_priv) { 797 DRM_ERROR("%s called with no initialization\n", __func__); 798 return -EINVAL; 799 } 800 801 if (!dev_priv->sarea_priv || dev_priv->sarea_priv->rotation) { 802 DRM_DEBUG("Rotation not supported\n"); 803 return -EINVAL; 804 } 805 806 DRM_COPYFROM_WITH_RETURN(&swap, (drm_i915_vblank_swap_t __user *)data, sizeof (swap)); 807 808 if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | 809 _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS | 810 _DRM_VBLANK_FLIP)) { 811 DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); 812 return -EINVAL; 813 } 814 815 plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; 816 pipe = i915_get_pipe(dev, plane); 817 818 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); 819 820 if (!(dev_priv->vblank_pipe & (1 << pipe))) { 821 DRM_ERROR("Invalid pipe %d\n", pipe); 822 return -EINVAL; 823 } 824 825 spin_lock_irqsave(&dev->drw_lock, irqflags); 826 827 /* It makes no sense to schedule a swap for a drawable that doesn't have 828 * valid information at this point. E.g. this could mean that the X 829 * server is too old to push drawable information to the DRM, in which 830 * case all such swaps would become ineffective. 831 */ 832 if (!drm_get_drawable_info(dev, swap->drawable)) { 833 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 834 DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); 835 return -EINVAL; 836 } 837 838 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 839 840 /* 841 * We take the ref here and put it when the swap actually completes 842 * in the tasklet. 843 */ 844 ret = drm_vblank_get(dev, pipe); 845 if (ret) 846 return ret; 847 curseq = drm_vblank_count(dev, pipe); 848 849 if (seqtype == _DRM_VBLANK_RELATIVE) 850 swap->sequence += curseq; 851 852 if ((curseq - swap->sequence) <= (1<<23)) { 853 if (swap->seqtype & _DRM_VBLANK_NEXTONMISS) { 854 swap->sequence = curseq + 1; 855 } else { 856 DRM_DEBUG("Missed target sequence\n"); 857 drm_vblank_put(dev, pipe); 858 return -EINVAL; 859 } 860 } 861 862 if (swap->seqtype & _DRM_VBLANK_FLIP) { 863 swap->sequence--; 864 865 if ((curseq - swap->sequence) <= (1<<23)) { 866 struct drm_drawable_info *drw; 867 868 LOCK_TEST_WITH_RETURN(dev, fpriv); 869 870 spin_lock_irqsave(&dev->drw_lock, irqflags); 871 872 drw = drm_get_drawable_info(dev, swap->drawable); 873 874 if (!drw) { 875 spin_unlock_irqrestore(&dev->drw_lock, 876 irqflags); 877 DRM_DEBUG("Invalid drawable ID %d\n", 878 swap->drawable); 879 drm_vblank_put(dev, pipe); 880 return -EINVAL; 881 } 882 883 i915_dispatch_vsync_flip(dev, drw, plane); 884 885 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 886 887 drm_vblank_put(dev, pipe); 888 return 0; 889 } 890 } 891 892 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); 893 894 list_for_each(list, &dev_priv->vbl_swaps.head) { 895 vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); 896 897 if (vbl_swap->drw_id == swap->drawable && 898 vbl_swap->plane == plane && 899 vbl_swap->sequence == swap->sequence) { 900 vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); 901 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); 902 DRM_DEBUG("Already scheduled\n"); 903 return 0; 904 } 905 } 906 907 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); 908 909 if (dev_priv->swaps_pending >= 100) { 910 DRM_DEBUG("Too many swaps queued\n"); 911 drm_vblank_put(dev, pipe); 912 return -EBUSY; 913 } 914 915 vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER); 916 917 if (!vbl_swap) { 918 DRM_ERROR("Failed to allocate memory to queue swap\n"); 919 drm_vblank_put(dev, pipe); 920 return -ENOMEM; 921 } 922 923 DRM_DEBUG("vbl_swap\n"); 924 925 vbl_swap->drw_id = swap->drawable; 926 vbl_swap->plane = plane; 927 vbl_swap->sequence = swap->sequence; 928 vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); 929 930 if (vbl_swap->flip) 931 swap->sequence++; 932 933 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); 934 935 list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head); 936 dev_priv->swaps_pending++; 937 938 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); 939 940 return 0; 941 } 942 943 /* drm_dma.h hooks 944 */ 945 void i915_driver_irq_preinstall(drm_device_t * dev) 946 { 947 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 948 949 I915_WRITE(HWSTAM, 0xeffe); 950 I915_WRITE(IMR, 0xffffffff); 951 I915_WRITE(IER, 0x0); 952 } 953 954 void i915_driver_irq_postinstall(drm_device_t * dev) 955 { 956 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 957 int ret, num_pipes=2; 958 959 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); 960 dev_priv->swaps_pending = 0; 961 962 dev_priv->user_irq_refcount = 0; 963 dev_priv->irq_mask_reg = 0xffffffff; 964 965 ret = drm_vblank_init(dev, num_pipes); 966 if (ret) 967 return; 968 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; 969 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ 970 971 i915_enable_interrupt(dev); 972 973 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue, DRM_INTR_PRI(dev)); 974 975 /* 976 * Initialize the hardware status page IRQ location. 977 */ 978 979 I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); 980 return; 981 } 982 983 void i915_driver_irq_uninstall(drm_device_t * dev) 984 { 985 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 986 u32 temp; 987 if (!dev_priv) 988 return; 989 990 dev_priv->vblank_pipe = 0; 991 dev_priv->irq_enabled = 0; 992 993 I915_WRITE(HWSTAM, 0xffffffff); 994 I915_WRITE(IMR, 0xffffffff); 995 I915_WRITE(IER, 0x0); 996 997 temp = I915_READ(PIPEASTAT); 998 I915_WRITE(PIPEASTAT, temp); 999 temp = I915_READ(PIPEBSTAT); 1000 I915_WRITE(PIPEBSTAT, temp); 1001 temp = I915_READ(IIR); 1002 I915_WRITE(IIR, temp); 1003 1004 } 1005