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 | /** |
