aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c2
-rw-r--r--drivers/gpu/drm/drm_irq.c109
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c91
-rw-r--r--drivers/gpu/drm/i915/intel_display.c29
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c29
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c2
-rw-r--r--include/drm/drmP.h8
-rw-r--r--include/drm/drm_crtc.h2
12 files changed, 144 insertions, 138 deletions
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 01361aba033b..245fe4fa9c9e 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -536,7 +536,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
536 * are later needed by vblank and swap-completion 536 * are later needed by vblank and swap-completion
537 * timestamping. They are derived from true hwmode. 537 * timestamping. They are derived from true hwmode.
538 */ 538 */
539 drm_calc_timestamping_constants(crtc); 539 drm_calc_timestamping_constants(crtc, &crtc->hwmode);
540 540
541 /* FIXME: add subpixel order */ 541 /* FIXME: add subpixel order */
542done: 542done:
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index e7de2da57234..c2676b5908d9 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -436,45 +436,41 @@ int drm_control(struct drm_device *dev, void *data,
436} 436}
437 437
438/** 438/**
439 * drm_calc_timestamping_constants - Calculate and 439 * drm_calc_timestamping_constants - Calculate vblank timestamp constants
440 * store various constants which are later needed by
441 * vblank and swap-completion timestamping, e.g, by
442 * drm_calc_vbltimestamp_from_scanoutpos().
443 * They are derived from crtc's true scanout timing,
444 * so they take things like panel scaling or other
445 * adjustments into account.
446 * 440 *
447 * @crtc drm_crtc whose timestamp constants should be updated. 441 * @crtc drm_crtc whose timestamp constants should be updated.
442 * @mode display mode containing the scanout timings
448 * 443 *
444 * Calculate and store various constants which are later
445 * needed by vblank and swap-completion timestamping, e.g,
446 * by drm_calc_vbltimestamp_from_scanoutpos(). They are
447 * derived from crtc's true scanout timing, so they take
448 * things like panel scaling or other adjustments into account.
449 */ 449 */
450void drm_calc_timestamping_constants(struct drm_crtc *crtc) 450void drm_calc_timestamping_constants(struct drm_crtc *crtc,
451 const struct drm_display_mode *mode)
451{ 452{
452 s64 linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; 453 int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
453 u64 dotclock; 454 int dotclock = mode->crtc_clock;
454
455 /* Dot clock in Hz: */
456 dotclock = (u64) crtc->hwmode.clock * 1000;
457
458 /* Fields of interlaced scanout modes are only half a frame duration.
459 * Double the dotclock to get half the frame-/line-/pixelduration.
460 */
461 if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE)
462 dotclock *= 2;
463 455
464 /* Valid dotclock? */ 456 /* Valid dotclock? */
465 if (dotclock > 0) { 457 if (dotclock > 0) {
466 int frame_size; 458 int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
467 /* Convert scanline length in pixels and video dot clock to 459
468 * line duration, frame duration and pixel duration in 460 /*
469 * nanoseconds: 461 * Convert scanline length in pixels and video
462 * dot clock to line duration, frame duration
463 * and pixel duration in nanoseconds:
470 */ 464 */
471 pixeldur_ns = (s64) div64_u64(1000000000, dotclock); 465 pixeldur_ns = 1000000 / dotclock;
472 linedur_ns = (s64) div64_u64(((u64) crtc->hwmode.crtc_htotal * 466 linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
473 1000000000), dotclock); 467 framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
474 frame_size = crtc->hwmode.crtc_htotal * 468
475 crtc->hwmode.crtc_vtotal; 469 /*
476 framedur_ns = (s64) div64_u64((u64) frame_size * 1000000000, 470 * Fields of interlaced scanout modes are only half a frame duration.
477 dotclock); 471 */
472 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
473 framedur_ns /= 2;
478 } else 474 } else
479 DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n", 475 DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
480 crtc->base.id); 476 crtc->base.id);
@@ -484,11 +480,11 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc)
484 crtc->framedur_ns = framedur_ns; 480 crtc->framedur_ns = framedur_ns;
485 481
486 DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n", 482 DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
487 crtc->base.id, crtc->hwmode.crtc_htotal, 483 crtc->base.id, mode->crtc_htotal,
488 crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay); 484 mode->crtc_vtotal, mode->crtc_vdisplay);
489 DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n", 485 DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n",
490 crtc->base.id, (int) dotclock/1000, (int) framedur_ns, 486 crtc->base.id, dotclock, framedur_ns,
491 (int) linedur_ns, (int) pixeldur_ns); 487 linedur_ns, pixeldur_ns);
492} 488}
493EXPORT_SYMBOL(drm_calc_timestamping_constants); 489EXPORT_SYMBOL(drm_calc_timestamping_constants);
494 490
@@ -521,6 +517,7 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
521 * 0 = Default. 517 * 0 = Default.
522 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. 518 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler.
523 * @refcrtc: drm_crtc* of crtc which defines scanout timing. 519 * @refcrtc: drm_crtc* of crtc which defines scanout timing.
520 * @mode: mode which defines the scanout timings
524 * 521 *
525 * Returns negative value on error, failure or if not supported in current 522 * Returns negative value on error, failure or if not supported in current
526 * video mode: 523 * video mode:
@@ -540,14 +537,14 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
540 int *max_error, 537 int *max_error,
541 struct timeval *vblank_time, 538 struct timeval *vblank_time,
542 unsigned flags, 539 unsigned flags,
543 struct drm_crtc *refcrtc) 540 const struct drm_crtc *refcrtc,
541 const struct drm_display_mode *mode)
544{ 542{
545 ktime_t stime, etime, mono_time_offset; 543 ktime_t stime, etime, mono_time_offset;
546 struct timeval tv_etime; 544 struct timeval tv_etime;
547 struct drm_display_mode *mode; 545 int vbl_status;
548 int vbl_status, vtotal, vdisplay;
549 int vpos, hpos, i; 546 int vpos, hpos, i;
550 s64 framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; 547 int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns;
551 bool invbl; 548 bool invbl;
552 549
553 if (crtc < 0 || crtc >= dev->num_crtcs) { 550 if (crtc < 0 || crtc >= dev->num_crtcs) {
@@ -561,10 +558,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
561 return -EIO; 558 return -EIO;
562 } 559 }
563 560
564 mode = &refcrtc->hwmode;
565 vtotal = mode->crtc_vtotal;
566 vdisplay = mode->crtc_vdisplay;
567
568 /* Durations of frames, lines, pixels in nanoseconds. */ 561 /* Durations of frames, lines, pixels in nanoseconds. */
569 framedur_ns = refcrtc->framedur_ns; 562 framedur_ns = refcrtc->framedur_ns;
570 linedur_ns = refcrtc->linedur_ns; 563 linedur_ns = refcrtc->linedur_ns;
@@ -573,7 +566,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
573 /* If mode timing undefined, just return as no-op: 566 /* If mode timing undefined, just return as no-op:
574 * Happens during initial modesetting of a crtc. 567 * Happens during initial modesetting of a crtc.
575 */ 568 */
576 if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { 569 if (framedur_ns == 0) {
577 DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); 570 DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc);
578 return -EAGAIN; 571 return -EAGAIN;
579 } 572 }
@@ -590,7 +583,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
590 * Get vertical and horizontal scanout position vpos, hpos, 583 * Get vertical and horizontal scanout position vpos, hpos,
591 * and bounding timestamps stime, etime, pre/post query. 584 * and bounding timestamps stime, etime, pre/post query.
592 */ 585 */
593 vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, 586 vbl_status = dev->driver->get_scanout_position(dev, crtc, flags, &vpos,
594 &hpos, &stime, &etime); 587 &hpos, &stime, &etime);
595 588
596 /* 589 /*
@@ -611,18 +604,18 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
611 duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime); 604 duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime);
612 605
613 /* Accept result with < max_error nsecs timing uncertainty. */ 606 /* Accept result with < max_error nsecs timing uncertainty. */
614 if (duration_ns <= (s64) *max_error) 607 if (duration_ns <= *max_error)
615 break; 608 break;
616 } 609 }
617 610
618 /* Noisy system timing? */ 611 /* Noisy system timing? */
619 if (i == DRM_TIMESTAMP_MAXRETRIES) { 612 if (i == DRM_TIMESTAMP_MAXRETRIES) {
620 DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n", 613 DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n",
621 crtc, (int) duration_ns/1000, *max_error/1000, i); 614 crtc, duration_ns/1000, *max_error/1000, i);
622 } 615 }
623 616
624 /* Return upper bound of timestamp precision error. */ 617 /* Return upper bound of timestamp precision error. */
625 *max_error = (int) duration_ns; 618 *max_error = duration_ns;
626 619
627 /* Check if in vblank area: 620 /* Check if in vblank area:
628 * vpos is >=0 in video scanout area, but negative 621 * vpos is >=0 in video scanout area, but negative
@@ -635,25 +628,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
635 * since start of scanout at first display scanline. delta_ns 628 * since start of scanout at first display scanline. delta_ns
636 * can be negative if start of scanout hasn't happened yet. 629 * can be negative if start of scanout hasn't happened yet.
637 */ 630 */
638 delta_ns = (s64) vpos * linedur_ns + (s64) hpos * pixeldur_ns; 631 delta_ns = vpos * linedur_ns + hpos * pixeldur_ns;
639
640 /* Is vpos outside nominal vblank area, but less than
641 * 1/100 of a frame height away from start of vblank?
642 * If so, assume this isn't a massively delayed vblank
643 * interrupt, but a vblank interrupt that fired a few
644 * microseconds before true start of vblank. Compensate
645 * by adding a full frame duration to the final timestamp.
646 * Happens, e.g., on ATI R500, R600.
647 *
648 * We only do this if DRM_CALLED_FROM_VBLIRQ.
649 */
650 if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl &&
651 ((vdisplay - vpos) < vtotal / 100)) {
652 delta_ns = delta_ns - framedur_ns;
653
654 /* Signal this correction as "applied". */
655 vbl_status |= 0x8;
656 }
657 632
658 if (!drm_timestamp_monotonic) 633 if (!drm_timestamp_monotonic)
659 etime = ktime_sub(etime, mono_time_offset); 634 etime = ktime_sub(etime, mono_time_offset);
@@ -673,7 +648,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
673 crtc, (int)vbl_status, hpos, vpos, 648 crtc, (int)vbl_status, hpos, vpos,
674 (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, 649 (long)tv_etime.tv_sec, (long)tv_etime.tv_usec,
675 (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, 650 (long)vblank_time->tv_sec, (long)vblank_time->tv_usec,
676 (int)duration_ns/1000, i); 651 duration_ns/1000, i);
677 652
678 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; 653 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD;
679 if (invbl) 654 if (invbl)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 6d11e253218a..17d8fcb1b6f7 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -621,36 +621,15 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
621#define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) 621#define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__))
622#define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__)) 622#define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__))
623 623
624static bool intel_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) 624static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe)
625{ 625{
626 struct drm_i915_private *dev_priv = dev->dev_private; 626 struct drm_i915_private *dev_priv = dev->dev_private;
627 uint32_t status; 627 uint32_t status;
628 int reg;
629 628
630 if (IS_VALLEYVIEW(dev)) { 629 if (INTEL_INFO(dev)->gen < 7) {
631 status = pipe == PIPE_A ?
632 I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT :
633 I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
634
635 reg = VLV_ISR;
636 } else if (IS_GEN2(dev)) {
637 status = pipe == PIPE_A ?
638 I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT :
639 I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
640
641 reg = ISR;
642 } else if (INTEL_INFO(dev)->gen < 5) {
643 status = pipe == PIPE_A ?
644 I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT :
645 I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
646
647 reg = ISR;
648 } else if (INTEL_INFO(dev)->gen < 7) {
649 status = pipe == PIPE_A ? 630 status = pipe == PIPE_A ?
650 DE_PIPEA_VBLANK : 631 DE_PIPEA_VBLANK :
651 DE_PIPEB_VBLANK; 632 DE_PIPEB_VBLANK;
652
653 reg = DEISR;
654 } else { 633 } else {
655 switch (pipe) { 634 switch (pipe) {
656 default: 635 default:
@@ -664,18 +643,14 @@ static bool intel_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe)
664 status = DE_PIPEC_VBLANK_IVB; 643 status = DE_PIPEC_VBLANK_IVB;
665 break; 644 break;
666 } 645 }
667
668 reg = DEISR;
669 } 646 }
670 647
671 if (IS_GEN2(dev)) 648 return __raw_i915_read32(dev_priv, DEISR) & status;
672 return __raw_i915_read16(dev_priv, reg) & status;
673 else
674 return __raw_i915_read32(dev_priv, reg) & status;
675} 649}
676 650
677static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, 651static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
678 int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) 652 unsigned int flags, int *vpos, int *hpos,
653 ktime_t *stime, ktime_t *etime)
679{ 654{
680 struct drm_i915_private *dev_priv = dev->dev_private; 655 struct drm_i915_private *dev_priv = dev->dev_private;
681 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; 656 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
@@ -698,6 +673,12 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
698 vbl_start = mode->crtc_vblank_start; 673 vbl_start = mode->crtc_vblank_start;
699 vbl_end = mode->crtc_vblank_end; 674 vbl_end = mode->crtc_vblank_end;
700 675
676 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
677 vbl_start = DIV_ROUND_UP(vbl_start, 2);
678 vbl_end /= 2;
679 vtotal /= 2;
680 }
681
701 ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; 682 ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
702 683
703 /* 684 /*
@@ -722,17 +703,42 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
722 else 703 else
723 position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; 704 position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;
724 705
725 /* 706 if (HAS_PCH_SPLIT(dev)) {
726 * The scanline counter increments at the leading edge 707 /*
727 * of hsync, ie. it completely misses the active portion 708 * The scanline counter increments at the leading edge
728 * of the line. Fix up the counter at both edges of vblank 709 * of hsync, ie. it completely misses the active portion
729 * to get a more accurate picture whether we're in vblank 710 * of the line. Fix up the counter at both edges of vblank
730 * or not. 711 * to get a more accurate picture whether we're in vblank
731 */ 712 * or not.
732 in_vbl = intel_pipe_in_vblank_locked(dev, pipe); 713 */
733 if ((in_vbl && position == vbl_start - 1) || 714 in_vbl = ilk_pipe_in_vblank_locked(dev, pipe);
734 (!in_vbl && position == vbl_end - 1)) 715 if ((in_vbl && position == vbl_start - 1) ||
735 position = (position + 1) % vtotal; 716 (!in_vbl && position == vbl_end - 1))
717 position = (position + 1) % vtotal;
718 } else {
719 /*
720 * ISR vblank status bits don't work the way we'd want
721 * them to work on non-PCH platforms (for
722 * ilk_pipe_in_vblank_locked()), and there doesn't
723 * appear any other way to determine if we're currently
724 * in vblank.
725 *
726 * Instead let's assume that we're already in vblank if
727 * we got called from the vblank interrupt and the
728 * scanline counter value indicates that we're on the
729 * line just prior to vblank start. This should result
730 * in the correct answer, unless the vblank interrupt
731 * delivery really got delayed for almost exactly one
732 * full frame/field.
733 */
734 if (flags & DRM_CALLED_FROM_VBLIRQ &&
735 position == vbl_start - 1) {
736 position = (position + 1) % vtotal;
737
738 /* Signal this correction as "applied". */
739 ret |= 0x8;
740 }
741 }
736 } else { 742 } else {
737 /* Have access to pixelcount since start of frame. 743 /* Have access to pixelcount since start of frame.
738 * We can split this into vertical and horizontal 744 * We can split this into vertical and horizontal
@@ -809,7 +815,8 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
809 /* Helper routine in DRM core does all the work: */ 815 /* Helper routine in DRM core does all the work: */
810 return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, 816 return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
811 vblank_time, flags, 817 vblank_time, flags,
812 crtc); 818 crtc,
819 &to_intel_crtc(crtc)->config.adjusted_mode);
813} 820}
814 821
815static bool intel_hpd_irq_event(struct drm_device *dev, 822static bool intel_hpd_irq_event(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e77d4b8856a7..14b024becb91 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9597,21 +9597,19 @@ static int __intel_set_mode(struct drm_crtc *crtc,
9597{ 9597{
9598 struct drm_device *dev = crtc->dev; 9598 struct drm_device *dev = crtc->dev;
9599 drm_i915_private_t *dev_priv = dev->dev_private; 9599 drm_i915_private_t *dev_priv = dev->dev_private;
9600 struct drm_display_mode *saved_mode, *saved_hwmode; 9600 struct drm_display_mode *saved_mode;
9601 struct intel_crtc_config *pipe_config = NULL; 9601 struct intel_crtc_config *pipe_config = NULL;
9602 struct intel_crtc *intel_crtc; 9602 struct intel_crtc *intel_crtc;
9603 unsigned disable_pipes, prepare_pipes, modeset_pipes; 9603 unsigned disable_pipes, prepare_pipes, modeset_pipes;
9604 int ret = 0; 9604 int ret = 0;
9605 9605
9606 saved_mode = kcalloc(2, sizeof(*saved_mode), GFP_KERNEL); 9606 saved_mode = kmalloc(sizeof(*saved_mode), GFP_KERNEL);
9607 if (!saved_mode) 9607 if (!saved_mode)
9608 return -ENOMEM; 9608 return -ENOMEM;
9609 saved_hwmode = saved_mode + 1;
9610 9609
9611 intel_modeset_affected_pipes(crtc, &modeset_pipes, 9610 intel_modeset_affected_pipes(crtc, &modeset_pipes,
9612 &prepare_pipes, &disable_pipes); 9611 &prepare_pipes, &disable_pipes);
9613 9612
9614 *saved_hwmode = crtc->hwmode;
9615 *saved_mode = crtc->mode; 9613 *saved_mode = crtc->mode;
9616 9614
9617 /* Hack: Because we don't (yet) support global modeset on multiple 9615 /* Hack: Because we don't (yet) support global modeset on multiple
@@ -9662,6 +9660,14 @@ static int __intel_set_mode(struct drm_crtc *crtc,
9662 /* mode_set/enable/disable functions rely on a correct pipe 9660 /* mode_set/enable/disable functions rely on a correct pipe
9663 * config. */ 9661 * config. */
9664 to_intel_crtc(crtc)->config = *pipe_config; 9662 to_intel_crtc(crtc)->config = *pipe_config;
9663
9664 /*
9665 * Calculate and store various constants which
9666 * are later needed by vblank and swap-completion
9667 * timestamping. They are derived from true hwmode.
9668 */
9669 drm_calc_timestamping_constants(crtc,
9670 &pipe_config->adjusted_mode);
9665 } 9671 }
9666 9672
9667 /* Only after disabling all output pipelines that will be changed can we 9673 /* Only after disabling all output pipelines that will be changed can we
@@ -9685,23 +9691,10 @@ static int __intel_set_mode(struct drm_crtc *crtc,
9685 for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) 9691 for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc)
9686 dev_priv->display.crtc_enable(&intel_crtc->base); 9692 dev_priv->display.crtc_enable(&intel_crtc->base);
9687 9693
9688 if (modeset_pipes) {
9689 /* Store real post-adjustment hardware mode. */
9690 crtc->hwmode = pipe_config->adjusted_mode;
9691
9692 /* Calculate and store various constants which
9693 * are later needed by vblank and swap-completion
9694 * timestamping. They are derived from true hwmode.
9695 */
9696 drm_calc_timestamping_constants(crtc);
9697 }
9698
9699 /* FIXME: add subpixel order */ 9694 /* FIXME: add subpixel order */
9700done: 9695done:
9701 if (ret && crtc->enabled) { 9696 if (ret && crtc->enabled)
9702 crtc->hwmode = *saved_hwmode;
9703 crtc->mode = *saved_mode; 9697 crtc->mode = *saved_mode;
9704 }
9705 9698
9706out: 9699out:
9707 kfree(pipe_config); 9700 kfree(pipe_config);
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 00bca1bd5745..f48bd6dc10cd 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1799,7 +1799,8 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
1799 if (misc & ATOM_DOUBLE_CLOCK_MODE) 1799 if (misc & ATOM_DOUBLE_CLOCK_MODE)
1800 mode->flags |= DRM_MODE_FLAG_DBLSCAN; 1800 mode->flags |= DRM_MODE_FLAG_DBLSCAN;
1801 1801
1802 mode->clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; 1802 mode->crtc_clock = mode->clock =
1803 le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
1803 1804
1804 if (index == 1) { 1805 if (index == 1) {
1805 /* PAL timings appear to have wrong values for totals */ 1806 /* PAL timings appear to have wrong values for totals */
@@ -1842,7 +1843,8 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
1842 if (misc & ATOM_DOUBLE_CLOCK_MODE) 1843 if (misc & ATOM_DOUBLE_CLOCK_MODE)
1843 mode->flags |= DRM_MODE_FLAG_DBLSCAN; 1844 mode->flags |= DRM_MODE_FLAG_DBLSCAN;
1844 1845
1845 mode->clock = le16_to_cpu(dtd_timings->usPixClk) * 10; 1846 mode->crtc_clock = mode->clock =
1847 le16_to_cpu(dtd_timings->usPixClk) * 10;
1846 break; 1848 break;
1847 } 1849 }
1848 return true; 1850 return true;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 7ea647b84733..d680608f6f5b 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -306,7 +306,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
306 * to complete in this vblank? 306 * to complete in this vblank?
307 */ 307 */
308 if (update_pending && 308 if (update_pending &&
309 (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 309 (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 0,
310 &vpos, &hpos, NULL, NULL)) && 310 &vpos, &hpos, NULL, NULL)) &&
311 ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) || 311 ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
312 (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) { 312 (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
@@ -1610,6 +1610,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
1610 * 1610 *
1611 * \param dev Device to query. 1611 * \param dev Device to query.
1612 * \param crtc Crtc to query. 1612 * \param crtc Crtc to query.
1613 * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0).
1613 * \param *vpos Location where vertical scanout position should be stored. 1614 * \param *vpos Location where vertical scanout position should be stored.
1614 * \param *hpos Location where horizontal scanout position should go. 1615 * \param *hpos Location where horizontal scanout position should go.
1615 * \param *stime Target location for timestamp taken immediately before 1616 * \param *stime Target location for timestamp taken immediately before
@@ -1631,8 +1632,8 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
1631 * unknown small number of scanlines wrt. real scanout position. 1632 * unknown small number of scanlines wrt. real scanout position.
1632 * 1633 *
1633 */ 1634 */
1634int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos, 1635int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags,
1635 ktime_t *stime, ktime_t *etime) 1636 int *vpos, int *hpos, ktime_t *stime, ktime_t *etime)
1636{ 1637{
1637 u32 stat_crtc = 0, vbl = 0, position = 0; 1638 u32 stat_crtc = 0, vbl = 0, position = 0;
1638 int vbl_start, vbl_end, vtotal, ret = 0; 1639 int vbl_start, vbl_end, vtotal, ret = 0;
@@ -1774,5 +1775,27 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int
1774 if (in_vbl) 1775 if (in_vbl)
1775 ret |= DRM_SCANOUTPOS_INVBL; 1776 ret |= DRM_SCANOUTPOS_INVBL;
1776 1777
1778 /* Is vpos outside nominal vblank area, but less than
1779 * 1/100 of a frame height away from start of vblank?
1780 * If so, assume this isn't a massively delayed vblank
1781 * interrupt, but a vblank interrupt that fired a few
1782 * microseconds before true start of vblank. Compensate
1783 * by adding a full frame duration to the final timestamp.
1784 * Happens, e.g., on ATI R500, R600.
1785 *
1786 * We only do this if DRM_CALLED_FROM_VBLIRQ.
1787 */
1788 if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) {
1789 vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
1790 vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
1791
1792 if (vbl_start - *vpos < vtotal / 100) {
1793 *vpos -= vtotal;
1794
1795 /* Signal this correction as "applied". */
1796 ret |= 0x8;
1797 }
1798 }
1799
1777 return ret; 1800 return ret;
1778} 1801}
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 67fadcf4590f..1235a78fbba1 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -109,6 +109,7 @@ int radeon_gem_object_open(struct drm_gem_object *obj,
109void radeon_gem_object_close(struct drm_gem_object *obj, 109void radeon_gem_object_close(struct drm_gem_object *obj,
110 struct drm_file *file_priv); 110 struct drm_file *file_priv);
111extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, 111extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
112 unsigned int flags,
112 int *vpos, int *hpos, ktime_t *stime, 113 int *vpos, int *hpos, ktime_t *stime,
113 ktime_t *etime); 114 ktime_t *etime);
114extern const struct drm_ioctl_desc radeon_ioctls_kms[]; 115extern const struct drm_ioctl_desc radeon_ioctls_kms[];
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 9e3af24e1b05..114d1672d616 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -719,7 +719,7 @@ int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
719 /* Helper routine in DRM core does all the work: */ 719 /* Helper routine in DRM core does all the work: */
720 return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, 720 return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
721 vblank_time, flags, 721 vblank_time, flags,
722 drmcrtc); 722 drmcrtc, &drmcrtc->hwmode);
723} 723}
724 724
725#define KMS_INVALID_IOCTL(name) \ 725#define KMS_INVALID_IOCTL(name) \
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 7c53fb1cc46d..402dbe32c234 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -801,6 +801,7 @@ extern int radeon_crtc_cursor_move(struct drm_crtc *crtc,
801 int x, int y); 801 int x, int y);
802 802
803extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, 803extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
804 unsigned int flags,
804 int *vpos, int *hpos, ktime_t *stime, 805 int *vpos, int *hpos, ktime_t *stime,
805 ktime_t *etime); 806 ktime_t *etime);
806 807
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 4e7f8922ae62..8e8153e471c2 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -1486,7 +1486,7 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev)
1486 */ 1486 */
1487 for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { 1487 for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) {
1488 if (rdev->pm.active_crtcs & (1 << crtc)) { 1488 if (rdev->pm.active_crtcs & (1 << crtc)) {
1489 vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos, NULL, NULL); 1489 vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, 0, &vpos, &hpos, NULL, NULL);
1490 if ((vbl_status & DRM_SCANOUTPOS_VALID) && 1490 if ((vbl_status & DRM_SCANOUTPOS_VALID) &&
1491 !(vbl_status & DRM_SCANOUTPOS_INVBL)) 1491 !(vbl_status & DRM_SCANOUTPOS_INVBL))
1492 in_vbl = false; 1492 in_vbl = false;
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 63eab2b72ee7..04086c5be930 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -845,6 +845,7 @@ struct drm_driver {
845 * 845 *
846 * \param dev DRM device. 846 * \param dev DRM device.
847 * \param crtc Id of the crtc to query. 847 * \param crtc Id of the crtc to query.
848 * \param flags Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0).
848 * \param *vpos Target location for current vertical scanout position. 849 * \param *vpos Target location for current vertical scanout position.
849 * \param *hpos Target location for current horizontal scanout position. 850 * \param *hpos Target location for current horizontal scanout position.
850 * \param *stime Target location for timestamp taken immediately before 851 * \param *stime Target location for timestamp taken immediately before
@@ -867,6 +868,7 @@ struct drm_driver {
867 * 868 *
868 */ 869 */
869 int (*get_scanout_position) (struct drm_device *dev, int crtc, 870 int (*get_scanout_position) (struct drm_device *dev, int crtc,
871 unsigned int flags,
870 int *vpos, int *hpos, ktime_t *stime, 872 int *vpos, int *hpos, ktime_t *stime,
871 ktime_t *etime); 873 ktime_t *etime);
872 874
@@ -1401,8 +1403,10 @@ extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
1401 int crtc, int *max_error, 1403 int crtc, int *max_error,
1402 struct timeval *vblank_time, 1404 struct timeval *vblank_time,
1403 unsigned flags, 1405 unsigned flags,
1404 struct drm_crtc *refcrtc); 1406 const struct drm_crtc *refcrtc,
1405extern void drm_calc_timestamping_constants(struct drm_crtc *crtc); 1407 const struct drm_display_mode *mode);
1408extern void drm_calc_timestamping_constants(struct drm_crtc *crtc,
1409 const struct drm_display_mode *mode);
1406 1410
1407extern bool 1411extern bool
1408drm_mode_parse_command_line_for_connector(const char *mode_option, 1412drm_mode_parse_command_line_for_connector(const char *mode_option,
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index e51e8975dd6f..e963470efd39 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -449,7 +449,7 @@ struct drm_crtc {
449 uint16_t *gamma_store; 449 uint16_t *gamma_store;
450 450
451 /* Constants needed for precise vblank and swap timestamping. */ 451 /* Constants needed for precise vblank and swap timestamping. */
452 s64 framedur_ns, linedur_ns, pixeldur_ns; 452 int framedur_ns, linedur_ns, pixeldur_ns;
453 453
454 /* if you are using the helper */ 454 /* if you are using the helper */
455 void *helper_private; 455 void *helper_private;