aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_irq.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2013-10-28 15:22:52 -0400
committerVille Syrjälä <ville.syrjala@linux.intel.com>2014-01-20 05:21:35 -0500
commit8072bfa6045a264d3913102a35fab125b06603a2 (patch)
treef08bac82c992480223540c77608e0aa26d9af148 /drivers/gpu/drm/drm_irq.c
parentabca9e45449876ca4e66f7e31c850753cde344a5 (diff)
drm/radeon: Move the early vblank IRQ fixup to radeon_get_crtc_scanoutpos()
i915 doesn't need this kludge for most platforms. Although we do appear to need something similar on certain platforms, but we can be more accurate when we apply the adjustment since we know exactly why the scanline counter doesn't always quite match the vblank status. Also the current code doesn't handle interlaced modes correctly, and we already deal with interlaced modes in i915 code. So let's just move the current code to radeon_get_crtc_scanoutpos() since that's why it was added. For i915 we'll add a more finely targeted variant. v2: Fix vpos vs. *vpos bug (Mario) Reviewed-by: mario.kleiner.de@gmail.com Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r--drivers/gpu/drm/drm_irq.c25
1 files changed, 2 insertions, 23 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index e55619f49671..c2676b5908d9 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -542,7 +542,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
542{ 542{
543 ktime_t stime, etime, mono_time_offset; 543 ktime_t stime, etime, mono_time_offset;
544 struct timeval tv_etime; 544 struct timeval tv_etime;
545 int vbl_status, vtotal, vdisplay; 545 int vbl_status;
546 int vpos, hpos, i; 546 int vpos, hpos, i;
547 int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; 547 int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns;
548 bool invbl; 548 bool invbl;
@@ -558,9 +558,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
558 return -EIO; 558 return -EIO;
559 } 559 }
560 560
561 vtotal = mode->crtc_vtotal;
562 vdisplay = mode->crtc_vdisplay;
563
564 /* Durations of frames, lines, pixels in nanoseconds. */ 561 /* Durations of frames, lines, pixels in nanoseconds. */
565 framedur_ns = refcrtc->framedur_ns; 562 framedur_ns = refcrtc->framedur_ns;
566 linedur_ns = refcrtc->linedur_ns; 563 linedur_ns = refcrtc->linedur_ns;
@@ -569,7 +566,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
569 /* If mode timing undefined, just return as no-op: 566 /* If mode timing undefined, just return as no-op:
570 * Happens during initial modesetting of a crtc. 567 * Happens during initial modesetting of a crtc.
571 */ 568 */
572 if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { 569 if (framedur_ns == 0) {
573 DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); 570 DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc);
574 return -EAGAIN; 571 return -EAGAIN;
575 } 572 }
@@ -633,24 +630,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
633 */ 630 */
634 delta_ns = vpos * linedur_ns + hpos * pixeldur_ns; 631 delta_ns = vpos * linedur_ns + hpos * pixeldur_ns;
635 632
636 /* Is vpos outside nominal vblank area, but less than
637 * 1/100 of a frame height away from start of vblank?
638 * If so, assume this isn't a massively delayed vblank
639 * interrupt, but a vblank interrupt that fired a few
640 * microseconds before true start of vblank. Compensate
641 * by adding a full frame duration to the final timestamp.
642 * Happens, e.g., on ATI R500, R600.
643 *
644 * We only do this if DRM_CALLED_FROM_VBLIRQ.
645 */
646 if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl &&
647 ((vdisplay - vpos) < vtotal / 100)) {
648 delta_ns = delta_ns - framedur_ns;
649
650 /* Signal this correction as "applied". */
651 vbl_status |= 0x8;
652 }
653
654 if (!drm_timestamp_monotonic) 633 if (!drm_timestamp_monotonic)
655 etime = ktime_sub(etime, mono_time_offset); 634 etime = ktime_sub(etime, mono_time_offset);
656 635