diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
commit | 1f16f116b01c110db20ab808562c8b8bc3ee3d6e (patch) | |
tree | 44db563f64cf5f8d62af8f99a61e2b248c44ea3a /drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |
parent | 03724ac3d48f8f0e3caf1d30fa134f8fd96c94e2 (diff) | |
parent | f9eccf24615672896dc13251410c3f2f33a14f95 (diff) |
Merge branches 'clockevents/4.4-fixes' and 'clockevents/4.5-fixes' of http://git.linaro.org/people/daniel.lezcano/linux into timers/urgent
Pull in fixes from Daniel Lezcano:
- Fix the vt8500 timer leading to a system lock up when dealing with too
small delta (Roman Volkov)
- Select the CLKSRC_MMIO when the fsl_ftm_timer is enabled with COMPILE_TEST
(Daniel Lezcano)
- Prevent to compile timers using the 'iomem' API when the architecture has
not HAS_IOMEM set (Richard Weinberger)
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 1618e2294a16..e23843f4d877 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
@@ -611,13 +611,59 @@ void amdgpu_driver_preclose_kms(struct drm_device *dev, | |||
611 | u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) | 611 | u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) |
612 | { | 612 | { |
613 | struct amdgpu_device *adev = dev->dev_private; | 613 | struct amdgpu_device *adev = dev->dev_private; |
614 | int vpos, hpos, stat; | ||
615 | u32 count; | ||
614 | 616 | ||
615 | if (pipe >= adev->mode_info.num_crtc) { | 617 | if (pipe >= adev->mode_info.num_crtc) { |
616 | DRM_ERROR("Invalid crtc %u\n", pipe); | 618 | DRM_ERROR("Invalid crtc %u\n", pipe); |
617 | return -EINVAL; | 619 | return -EINVAL; |
618 | } | 620 | } |
619 | 621 | ||
620 | return amdgpu_display_vblank_get_counter(adev, pipe); | 622 | /* The hw increments its frame counter at start of vsync, not at start |
623 | * of vblank, as is required by DRM core vblank counter handling. | ||
624 | * Cook the hw count here to make it appear to the caller as if it | ||
625 | * incremented at start of vblank. We measure distance to start of | ||
626 | * vblank in vpos. vpos therefore will be >= 0 between start of vblank | ||
627 | * and start of vsync, so vpos >= 0 means to bump the hw frame counter | ||
628 | * result by 1 to give the proper appearance to caller. | ||
629 | */ | ||
630 | if (adev->mode_info.crtcs[pipe]) { | ||
631 | /* Repeat readout if needed to provide stable result if | ||
632 | * we cross start of vsync during the queries. | ||
633 | */ | ||
634 | do { | ||
635 | count = amdgpu_display_vblank_get_counter(adev, pipe); | ||
636 | /* Ask amdgpu_get_crtc_scanoutpos to return vpos as | ||
637 | * distance to start of vblank, instead of regular | ||
638 | * vertical scanout pos. | ||
639 | */ | ||
640 | stat = amdgpu_get_crtc_scanoutpos( | ||
641 | dev, pipe, GET_DISTANCE_TO_VBLANKSTART, | ||
642 | &vpos, &hpos, NULL, NULL, | ||
643 | &adev->mode_info.crtcs[pipe]->base.hwmode); | ||
644 | } while (count != amdgpu_display_vblank_get_counter(adev, pipe)); | ||
645 | |||
646 | if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != | ||
647 | (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) { | ||
648 | DRM_DEBUG_VBL("Query failed! stat %d\n", stat); | ||
649 | } else { | ||
650 | DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n", | ||
651 | pipe, vpos); | ||
652 | |||
653 | /* Bump counter if we are at >= leading edge of vblank, | ||
654 | * but before vsync where vpos would turn negative and | ||
655 | * the hw counter really increments. | ||
656 | */ | ||
657 | if (vpos >= 0) | ||
658 | count++; | ||
659 | } | ||
660 | } else { | ||
661 | /* Fallback to use value as is. */ | ||
662 | count = amdgpu_display_vblank_get_counter(adev, pipe); | ||
663 | DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n"); | ||
664 | } | ||
665 | |||
666 | return count; | ||
621 | } | 667 | } |
622 | 668 | ||
623 | /** | 669 | /** |