diff options
Diffstat (limited to 'drivers/gpu/drm')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 41 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_irq.c | 43 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 52 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 45 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 38 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.h | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_kms.c | 37 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_crtc.c | 34 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.h | 11 |
16 files changed, 102 insertions, 253 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 0ce8292d97c0..9de615bb0c2e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -1910,10 +1910,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); | |||
| 1910 | u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); | 1910 | u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); |
| 1911 | int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); | 1911 | int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); |
| 1912 | void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); | 1912 | void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); |
| 1913 | bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, | ||
| 1914 | int *max_error, | ||
| 1915 | struct timeval *vblank_time, | ||
| 1916 | bool in_vblank_irq); | ||
| 1917 | long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, | 1913 | long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, |
| 1918 | unsigned long arg); | 1914 | unsigned long arg); |
| 1919 | 1915 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 4e0f7d2d87f1..73e982cd6136 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |||
| @@ -711,6 +711,16 @@ static const struct file_operations amdgpu_driver_kms_fops = { | |||
| 711 | #endif | 711 | #endif |
| 712 | }; | 712 | }; |
| 713 | 713 | ||
| 714 | static bool | ||
| 715 | amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, | ||
| 716 | bool in_vblank_irq, int *vpos, int *hpos, | ||
| 717 | ktime_t *stime, ktime_t *etime, | ||
| 718 | const struct drm_display_mode *mode) | ||
| 719 | { | ||
| 720 | return amdgpu_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, | ||
| 721 | stime, etime, mode); | ||
| 722 | } | ||
| 723 | |||
| 714 | static struct drm_driver kms_driver = { | 724 | static struct drm_driver kms_driver = { |
| 715 | .driver_features = | 725 | .driver_features = |
| 716 | DRIVER_USE_AGP | | 726 | DRIVER_USE_AGP | |
| @@ -725,8 +735,8 @@ static struct drm_driver kms_driver = { | |||
| 725 | .get_vblank_counter = amdgpu_get_vblank_counter_kms, | 735 | .get_vblank_counter = amdgpu_get_vblank_counter_kms, |
| 726 | .enable_vblank = amdgpu_enable_vblank_kms, | 736 | .enable_vblank = amdgpu_enable_vblank_kms, |
| 727 | .disable_vblank = amdgpu_disable_vblank_kms, | 737 | .disable_vblank = amdgpu_disable_vblank_kms, |
| 728 | .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms, | 738 | .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, |
| 729 | .get_scanout_position = amdgpu_get_crtc_scanoutpos, | 739 | .get_scanout_position = amdgpu_get_crtc_scanout_position, |
| 730 | #if defined(CONFIG_DEBUG_FS) | 740 | #if defined(CONFIG_DEBUG_FS) |
| 731 | .debugfs_init = amdgpu_debugfs_init, | 741 | .debugfs_init = amdgpu_debugfs_init, |
| 732 | #endif | 742 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index babd969a63d1..40f45ba71b86 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
| @@ -934,47 +934,6 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) | |||
| 934 | amdgpu_irq_put(adev, &adev->crtc_irq, idx); | 934 | amdgpu_irq_put(adev, &adev->crtc_irq, idx); |
| 935 | } | 935 | } |
| 936 | 936 | ||
| 937 | /** | ||
| 938 | * amdgpu_get_vblank_timestamp_kms - get vblank timestamp | ||
| 939 | * | ||
| 940 | * @dev: drm dev pointer | ||
| 941 | * @crtc: crtc to get the timestamp for | ||
| 942 | * @max_error: max error | ||
| 943 | * @vblank_time: time value | ||
| 944 | * @in_vblank_irq: called from drm_handle_vblank() | ||
| 945 | * | ||
| 946 | * Gets the timestamp on the requested crtc based on the | ||
| 947 | * scanout position. (all asics). | ||
| 948 | * Returns true on success, false on failure. | ||
| 949 | */ | ||
| 950 | bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, | ||
| 951 | int *max_error, | ||
| 952 | struct timeval *vblank_time, | ||
| 953 | bool in_vblank_irq) | ||
| 954 | { | ||
| 955 | struct drm_crtc *crtc; | ||
| 956 | struct amdgpu_device *adev = dev->dev_private; | ||
| 957 | |||
| 958 | if (pipe >= dev->num_crtcs) { | ||
| 959 | DRM_ERROR("Invalid crtc %u\n", pipe); | ||
| 960 | return false; | ||
| 961 | } | ||
| 962 | |||
| 963 | /* Get associated drm_crtc: */ | ||
| 964 | crtc = &adev->mode_info.crtcs[pipe]->base; | ||
| 965 | if (!crtc) { | ||
| 966 | /* This can occur on driver load if some component fails to | ||
| 967 | * initialize completely and driver is unloaded */ | ||
| 968 | DRM_ERROR("Uninitialized crtc %d\n", pipe); | ||
| 969 | return false; | ||
| 970 | } | ||
| 971 | |||
| 972 | /* Helper routine in DRM core does all the work: */ | ||
| 973 | return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, | ||
| 974 | vblank_time, in_vblank_irq, | ||
| 975 | &crtc->hwmode); | ||
| 976 | } | ||
| 977 | |||
| 978 | const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { | 937 | const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { |
| 979 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 938 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
| 980 | DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 939 | DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index db8f8dda209c..20d6522fd7b4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | |||
| @@ -534,6 +534,9 @@ struct amdgpu_framebuffer { | |||
| 534 | ((em) == ATOM_ENCODER_MODE_DP_MST)) | 534 | ((em) == ATOM_ENCODER_MODE_DP_MST)) |
| 535 | 535 | ||
| 536 | /* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ | 536 | /* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ |
| 537 | #define DRM_SCANOUTPOS_VALID (1 << 0) | ||
| 538 | #define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) | ||
| 539 | #define DRM_SCANOUTPOS_ACCURATE (1 << 2) | ||
| 537 | #define USE_REAL_VBLANKSTART (1 << 30) | 540 | #define USE_REAL_VBLANKSTART (1 << 30) |
| 538 | #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) | 541 | #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) |
| 539 | 542 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index fba6a842f4cd..89f0928b042a 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -684,6 +684,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc, | |||
| 684 | 684 | ||
| 685 | vblank->linedur_ns = linedur_ns; | 685 | vblank->linedur_ns = linedur_ns; |
| 686 | vblank->framedur_ns = framedur_ns; | 686 | vblank->framedur_ns = framedur_ns; |
| 687 | vblank->hwmode = *mode; | ||
| 687 | 688 | ||
| 688 | DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", | 689 | DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", |
| 689 | crtc->base.id, mode->crtc_htotal, | 690 | crtc->base.id, mode->crtc_htotal, |
| @@ -704,7 +705,6 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); | |||
| 704 | * True when called from drm_crtc_handle_vblank(). Some drivers | 705 | * True when called from drm_crtc_handle_vblank(). Some drivers |
| 705 | * need to apply some workarounds for gpu-specific vblank irq quirks | 706 | * need to apply some workarounds for gpu-specific vblank irq quirks |
| 706 | * if flag is set. | 707 | * if flag is set. |
| 707 | * @mode: mode which defines the scanout timings | ||
| 708 | * | 708 | * |
| 709 | * Implements calculation of exact vblank timestamps from given drm_display_mode | 709 | * Implements calculation of exact vblank timestamps from given drm_display_mode |
| 710 | * timings and current video scanout position of a CRTC. This can be called from | 710 | * timings and current video scanout position of a CRTC. This can be called from |
| @@ -724,6 +724,13 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); | |||
| 724 | * returns as no operation if a doublescan or interlaced video mode is | 724 | * returns as no operation if a doublescan or interlaced video mode is |
| 725 | * active. Higher level code is expected to handle this. | 725 | * active. Higher level code is expected to handle this. |
| 726 | * | 726 | * |
| 727 | * This function can be used to implement the &drm_driver.get_vblank_timestamp | ||
| 728 | * directly, if the driver implements the &drm_driver.get_scanout_position hook. | ||
| 729 | * | ||
| 730 | * Note that atomic drivers must call drm_calc_timestamping_constants() before | ||
| 731 | * enabling a CRTC. The atomic helpers already take care of that in | ||
| 732 | * drm_atomic_helper_update_legacy_modeset_state(). | ||
| 733 | * | ||
| 727 | * Returns: | 734 | * Returns: |
| 728 | * | 735 | * |
| 729 | * Returns true on success, and false on failure, i.e. when no accurate | 736 | * Returns true on success, and false on failure, i.e. when no accurate |
| @@ -733,17 +740,23 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, | |||
| 733 | unsigned int pipe, | 740 | unsigned int pipe, |
| 734 | int *max_error, | 741 | int *max_error, |
| 735 | struct timeval *vblank_time, | 742 | struct timeval *vblank_time, |
| 736 | bool in_vblank_irq, | 743 | bool in_vblank_irq) |
| 737 | const struct drm_display_mode *mode) | ||
| 738 | { | 744 | { |
| 739 | struct timeval tv_etime; | 745 | struct timeval tv_etime; |
| 740 | ktime_t stime, etime; | 746 | ktime_t stime, etime; |
| 741 | unsigned int vbl_status; | 747 | bool vbl_status; |
| 748 | struct drm_crtc *crtc; | ||
| 749 | const struct drm_display_mode *mode; | ||
| 750 | struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; | ||
| 742 | int vpos, hpos, i; | 751 | int vpos, hpos, i; |
| 743 | int delta_ns, duration_ns; | 752 | int delta_ns, duration_ns; |
| 744 | unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0; | ||
| 745 | 753 | ||
| 746 | if (pipe >= dev->num_crtcs) { | 754 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 755 | return false; | ||
| 756 | |||
| 757 | crtc = drm_crtc_from_index(dev, pipe); | ||
| 758 | |||
| 759 | if (pipe >= dev->num_crtcs || !crtc) { | ||
| 747 | DRM_ERROR("Invalid crtc %u\n", pipe); | 760 | DRM_ERROR("Invalid crtc %u\n", pipe); |
| 748 | return false; | 761 | return false; |
| 749 | } | 762 | } |
| @@ -754,6 +767,11 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, | |||
| 754 | return false; | 767 | return false; |
| 755 | } | 768 | } |
| 756 | 769 | ||
| 770 | if (drm_drv_uses_atomic_modeset(dev)) | ||
| 771 | mode = &vblank->hwmode; | ||
| 772 | else | ||
| 773 | mode = &crtc->hwmode; | ||
| 774 | |||
| 757 | /* If mode timing undefined, just return as no-op: | 775 | /* If mode timing undefined, just return as no-op: |
| 758 | * Happens during initial modesetting of a crtc. | 776 | * Happens during initial modesetting of a crtc. |
| 759 | */ | 777 | */ |
| @@ -774,15 +792,16 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, | |||
| 774 | * Get vertical and horizontal scanout position vpos, hpos, | 792 | * Get vertical and horizontal scanout position vpos, hpos, |
| 775 | * and bounding timestamps stime, etime, pre/post query. | 793 | * and bounding timestamps stime, etime, pre/post query. |
| 776 | */ | 794 | */ |
| 777 | vbl_status = dev->driver->get_scanout_position(dev, pipe, flags, | 795 | vbl_status = dev->driver->get_scanout_position(dev, pipe, |
| 796 | in_vblank_irq, | ||
| 778 | &vpos, &hpos, | 797 | &vpos, &hpos, |
| 779 | &stime, &etime, | 798 | &stime, &etime, |
| 780 | mode); | 799 | mode); |
| 781 | 800 | ||
| 782 | /* Return as no-op if scanout query unsupported or failed. */ | 801 | /* Return as no-op if scanout query unsupported or failed. */ |
| 783 | if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { | 802 | if (!vbl_status) { |
| 784 | DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", | 803 | DRM_DEBUG("crtc %u : scanoutpos query failed.\n", |
| 785 | pipe, vbl_status); | 804 | pipe); |
| 786 | return false; | 805 | return false; |
| 787 | } | 806 | } |
| 788 | 807 | ||
| @@ -821,8 +840,8 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, | |||
| 821 | etime = ktime_sub_ns(etime, delta_ns); | 840 | etime = ktime_sub_ns(etime, delta_ns); |
| 822 | *vblank_time = ktime_to_timeval(etime); | 841 | *vblank_time = ktime_to_timeval(etime); |
| 823 | 842 | ||
| 824 | DRM_DEBUG_VBL("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", | 843 | DRM_DEBUG_VBL("crtc %u : v p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", |
| 825 | pipe, vbl_status, hpos, vpos, | 844 | pipe, hpos, vpos, |
| 826 | (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, | 845 | (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, |
| 827 | (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, | 846 | (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, |
| 828 | duration_ns/1000, i); | 847 | duration_ns/1000, i); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ae09c29662a1..dccb7c2560fe 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -827,10 +827,10 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) | |||
| 827 | return (position + crtc->scanline_offset) % vtotal; | 827 | return (position + crtc->scanline_offset) % vtotal; |
| 828 | } | 828 | } |
| 829 | 829 | ||
| 830 | static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, | 830 | static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, |
| 831 | unsigned int flags, int *vpos, int *hpos, | 831 | bool in_vblank_irq, int *vpos, int *hpos, |
| 832 | ktime_t *stime, ktime_t *etime, | 832 | ktime_t *stime, ktime_t *etime, |
| 833 | const struct drm_display_mode *mode) | 833 | const struct drm_display_mode *mode) |
| 834 | { | 834 | { |
| 835 | struct drm_i915_private *dev_priv = to_i915(dev); | 835 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 836 | struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, | 836 | struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, |
| @@ -838,13 +838,12 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 838 | int position; | 838 | int position; |
| 839 | int vbl_start, vbl_end, hsync_start, htotal, vtotal; | 839 | int vbl_start, vbl_end, hsync_start, htotal, vtotal; |
| 840 | bool in_vbl = true; | 840 | bool in_vbl = true; |
| 841 | int ret = 0; | ||
| 842 | unsigned long irqflags; | 841 | unsigned long irqflags; |
| 843 | 842 | ||
| 844 | if (WARN_ON(!mode->crtc_clock)) { | 843 | if (WARN_ON(!mode->crtc_clock)) { |
| 845 | DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " | 844 | DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " |
| 846 | "pipe %c\n", pipe_name(pipe)); | 845 | "pipe %c\n", pipe_name(pipe)); |
| 847 | return 0; | 846 | return false; |
| 848 | } | 847 | } |
| 849 | 848 | ||
| 850 | htotal = mode->crtc_htotal; | 849 | htotal = mode->crtc_htotal; |
| @@ -859,8 +858,6 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 859 | vtotal /= 2; | 858 | vtotal /= 2; |
| 860 | } | 859 | } |
| 861 | 860 | ||
| 862 | ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; | ||
| 863 | |||
| 864 | /* | 861 | /* |
| 865 | * Lock uncore.lock, as we will do multiple timing critical raw | 862 | * Lock uncore.lock, as we will do multiple timing critical raw |
| 866 | * register reads, potentially with preemption disabled, so the | 863 | * register reads, potentially with preemption disabled, so the |
| @@ -944,11 +941,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 944 | *hpos = position - (*vpos * htotal); | 941 | *hpos = position - (*vpos * htotal); |
| 945 | } | 942 | } |
| 946 | 943 | ||
| 947 | /* In vblank? */ | 944 | return true; |
| 948 | if (in_vbl) | ||
| 949 | ret |= DRM_SCANOUTPOS_IN_VBLANK; | ||
| 950 | |||
| 951 | return ret; | ||
| 952 | } | 945 | } |
| 953 | 946 | ||
| 954 | int intel_get_crtc_scanline(struct intel_crtc *crtc) | 947 | int intel_get_crtc_scanline(struct intel_crtc *crtc) |
| @@ -964,37 +957,6 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) | |||
| 964 | return position; | 957 | return position; |
| 965 | } | 958 | } |
| 966 | 959 | ||
| 967 | static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, | ||
| 968 | int *max_error, | ||
| 969 | struct timeval *vblank_time, | ||
| 970 | bool in_vblank_irq) | ||
| 971 | { | ||
| 972 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 973 | struct intel_crtc *crtc; | ||
| 974 | |||
| 975 | if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { | ||
| 976 | DRM_ERROR("Invalid crtc %u\n", pipe); | ||
| 977 | return false; | ||
| 978 | } | ||
| 979 | |||
| 980 | /* Get drm_crtc to timestamp: */ | ||
| 981 | crtc = intel_get_crtc_for_pipe(dev_priv, pipe); | ||
| 982 | if (crtc == NULL) { | ||
| 983 | DRM_ERROR("Invalid crtc %u\n", pipe); | ||
| 984 | return false; | ||
| 985 | } | ||
| 986 | |||
| 987 | if (!crtc->base.hwmode.crtc_clock) { | ||
| 988 | DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); | ||
| 989 | return false; | ||
| 990 | } | ||
| 991 | |||
| 992 | /* Helper routine in DRM core does all the work: */ | ||
| 993 | return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, | ||
| 994 | vblank_time, in_vblank_irq, | ||
| 995 | &crtc->base.hwmode); | ||
| 996 | } | ||
| 997 | |||
| 998 | static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) | 960 | static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) |
| 999 | { | 961 | { |
| 1000 | u32 busy_up, busy_down, max_avg, min_avg; | 962 | u32 busy_up, busy_down, max_avg, min_avg; |
| @@ -4294,7 +4256,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) | |||
| 4294 | 4256 | ||
| 4295 | dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD; | 4257 | dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD; |
| 4296 | 4258 | ||
| 4297 | dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; | 4259 | dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; |
| 4298 | dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; | 4260 | dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; |
| 4299 | 4261 | ||
| 4300 | if (IS_CHERRYVIEW(dev_priv)) { | 4262 | if (IS_CHERRYVIEW(dev_priv)) { |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 07e2b1335f65..e2b3346ead48 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | |||
| @@ -527,31 +527,28 @@ static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) | |||
| 527 | return NULL; | 527 | return NULL; |
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, | 530 | static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, |
| 531 | unsigned int flags, int *vpos, int *hpos, | 531 | bool in_vblank_irq, int *vpos, int *hpos, |
| 532 | ktime_t *stime, ktime_t *etime, | 532 | ktime_t *stime, ktime_t *etime, |
| 533 | const struct drm_display_mode *mode) | 533 | const struct drm_display_mode *mode) |
| 534 | { | 534 | { |
| 535 | struct msm_drm_private *priv = dev->dev_private; | 535 | struct msm_drm_private *priv = dev->dev_private; |
| 536 | struct drm_crtc *crtc; | 536 | struct drm_crtc *crtc; |
| 537 | struct drm_encoder *encoder; | 537 | struct drm_encoder *encoder; |
| 538 | int line, vsw, vbp, vactive_start, vactive_end, vfp_end; | 538 | int line, vsw, vbp, vactive_start, vactive_end, vfp_end; |
| 539 | int ret = 0; | ||
| 540 | 539 | ||
| 541 | crtc = priv->crtcs[pipe]; | 540 | crtc = priv->crtcs[pipe]; |
| 542 | if (!crtc) { | 541 | if (!crtc) { |
| 543 | DRM_ERROR("Invalid crtc %d\n", pipe); | 542 | DRM_ERROR("Invalid crtc %d\n", pipe); |
| 544 | return 0; | 543 | return false; |
| 545 | } | 544 | } |
| 546 | 545 | ||
| 547 | encoder = get_encoder_from_crtc(crtc); | 546 | encoder = get_encoder_from_crtc(crtc); |
| 548 | if (!encoder) { | 547 | if (!encoder) { |
| 549 | DRM_ERROR("no encoder found for crtc %d\n", pipe); | 548 | DRM_ERROR("no encoder found for crtc %d\n", pipe); |
| 550 | return 0; | 549 | return false; |
| 551 | } | 550 | } |
| 552 | 551 | ||
| 553 | ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; | ||
| 554 | |||
| 555 | vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; | 552 | vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; |
| 556 | vbp = mode->crtc_vtotal - mode->crtc_vsync_end; | 553 | vbp = mode->crtc_vtotal - mode->crtc_vsync_end; |
| 557 | 554 | ||
| @@ -575,10 +572,8 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 575 | 572 | ||
| 576 | if (line < vactive_start) { | 573 | if (line < vactive_start) { |
| 577 | line -= vactive_start; | 574 | line -= vactive_start; |
| 578 | ret |= DRM_SCANOUTPOS_IN_VBLANK; | ||
| 579 | } else if (line > vactive_end) { | 575 | } else if (line > vactive_end) { |
| 580 | line = line - vfp_end - vactive_start; | 576 | line = line - vfp_end - vactive_start; |
| 581 | ret |= DRM_SCANOUTPOS_IN_VBLANK; | ||
| 582 | } else { | 577 | } else { |
| 583 | line -= vactive_start; | 578 | line -= vactive_start; |
| 584 | } | 579 | } |
| @@ -589,31 +584,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 589 | if (etime) | 584 | if (etime) |
| 590 | *etime = ktime_get(); | 585 | *etime = ktime_get(); |
| 591 | 586 | ||
| 592 | return ret; | 587 | return true; |
| 593 | } | ||
| 594 | |||
| 595 | static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, | ||
| 596 | int *max_error, | ||
| 597 | struct timeval *vblank_time, | ||
| 598 | bool in_vblank_irq) | ||
| 599 | { | ||
| 600 | struct msm_drm_private *priv = dev->dev_private; | ||
| 601 | struct drm_crtc *crtc; | ||
| 602 | |||
| 603 | if (pipe < 0 || pipe >= priv->num_crtcs) { | ||
| 604 | DRM_ERROR("Invalid crtc %d\n", pipe); | ||
| 605 | return false; | ||
| 606 | } | ||
| 607 | |||
| 608 | crtc = priv->crtcs[pipe]; | ||
| 609 | if (!crtc) { | ||
| 610 | DRM_ERROR("Invalid crtc %d\n", pipe); | ||
| 611 | return false; | ||
| 612 | } | ||
| 613 | |||
| 614 | return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, | ||
| 615 | vblank_time, in_vblank_irq, | ||
| 616 | &crtc->mode); | ||
| 617 | } | 588 | } |
| 618 | 589 | ||
| 619 | static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) | 590 | static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) |
| @@ -725,7 +696,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) | |||
| 725 | dev->mode_config.max_width = 0xffff; | 696 | dev->mode_config.max_width = 0xffff; |
| 726 | dev->mode_config.max_height = 0xffff; | 697 | dev->mode_config.max_height = 0xffff; |
| 727 | 698 | ||
| 728 | dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp; | 699 | dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; |
| 729 | dev->driver->get_scanout_position = mdp5_get_scanoutpos; | 700 | dev->driver->get_scanout_position = mdp5_get_scanoutpos; |
| 730 | dev->driver->get_vblank_counter = mdp5_get_vblank_counter; | 701 | dev->driver->get_vblank_counter = mdp5_get_vblank_counter; |
| 731 | dev->max_vblank_count = 0xffffffff; | 702 | dev->max_vblank_count = 0xffffffff; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 2d28ef57f2bf..6718c84fb862 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
| @@ -98,7 +98,7 @@ calc(int blanks, int blanke, int total, int line) | |||
| 98 | return line; | 98 | return line; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static int | 101 | static bool |
| 102 | nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, | 102 | nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, |
| 103 | ktime_t *stime, ktime_t *etime) | 103 | ktime_t *stime, ktime_t *etime) |
| 104 | { | 104 | { |
| @@ -111,16 +111,16 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, | |||
| 111 | }; | 111 | }; |
| 112 | struct nouveau_display *disp = nouveau_display(crtc->dev); | 112 | struct nouveau_display *disp = nouveau_display(crtc->dev); |
| 113 | struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)]; | 113 | struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)]; |
| 114 | int ret, retry = 20; | 114 | int retry = 20; |
| 115 | bool ret = false; | ||
| 115 | 116 | ||
| 116 | do { | 117 | do { |
| 117 | ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); | 118 | ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); |
| 118 | if (ret != 0) | 119 | if (ret != 0) |
| 119 | return 0; | 120 | return false; |
| 120 | 121 | ||
| 121 | if (args.scan.vline) { | 122 | if (args.scan.vline) { |
| 122 | ret |= DRM_SCANOUTPOS_ACCURATE; | 123 | ret = true; |
| 123 | ret |= DRM_SCANOUTPOS_VALID; | ||
| 124 | break; | 124 | break; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| @@ -133,14 +133,12 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, | |||
| 133 | if (stime) *stime = ns_to_ktime(args.scan.time[0]); | 133 | if (stime) *stime = ns_to_ktime(args.scan.time[0]); |
| 134 | if (etime) *etime = ns_to_ktime(args.scan.time[1]); | 134 | if (etime) *etime = ns_to_ktime(args.scan.time[1]); |
| 135 | 135 | ||
| 136 | if (*vpos < 0) | ||
| 137 | ret |= DRM_SCANOUTPOS_IN_VBLANK; | ||
| 138 | return ret; | 136 | return ret; |
| 139 | } | 137 | } |
| 140 | 138 | ||
| 141 | int | 139 | bool |
| 142 | nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, | 140 | nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, |
| 143 | unsigned int flags, int *vpos, int *hpos, | 141 | bool in_vblank_irq, int *vpos, int *hpos, |
| 144 | ktime_t *stime, ktime_t *etime, | 142 | ktime_t *stime, ktime_t *etime, |
| 145 | const struct drm_display_mode *mode) | 143 | const struct drm_display_mode *mode) |
| 146 | { | 144 | { |
| @@ -153,28 +151,6 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 153 | } | 151 | } |
| 154 | } | 152 | } |
| 155 | 153 | ||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | bool | ||
| 160 | nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, | ||
| 161 | int *max_error, struct timeval *time, bool in_vblank_irq) | ||
| 162 | { | ||
| 163 | struct drm_crtc *crtc; | ||
| 164 | |||
| 165 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
| 166 | if (nouveau_crtc(crtc)->index == pipe) { | ||
| 167 | struct drm_display_mode *mode; | ||
| 168 | if (drm_drv_uses_atomic_modeset(dev)) | ||
| 169 | mode = &crtc->state->adjusted_mode; | ||
| 170 | else | ||
| 171 | mode = &crtc->hwmode; | ||
| 172 | return drm_calc_vbltimestamp_from_scanoutpos(dev, | ||
| 173 | pipe, max_error, time, in_vblank_irq, | ||
| 174 | mode); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | return false; | 154 | return false; |
| 179 | } | 155 | } |
| 180 | 156 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 8ec86259c5ac..201aec2ea5b8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h | |||
| @@ -68,11 +68,9 @@ int nouveau_display_suspend(struct drm_device *dev, bool runtime); | |||
| 68 | void nouveau_display_resume(struct drm_device *dev, bool runtime); | 68 | void nouveau_display_resume(struct drm_device *dev, bool runtime); |
| 69 | int nouveau_display_vblank_enable(struct drm_device *, unsigned int); | 69 | int nouveau_display_vblank_enable(struct drm_device *, unsigned int); |
| 70 | void nouveau_display_vblank_disable(struct drm_device *, unsigned int); | 70 | void nouveau_display_vblank_disable(struct drm_device *, unsigned int); |
| 71 | int nouveau_display_scanoutpos(struct drm_device *, unsigned int, | 71 | bool nouveau_display_scanoutpos(struct drm_device *, unsigned int, |
| 72 | unsigned int, int *, int *, ktime_t *, | 72 | bool, int *, int *, ktime_t *, |
| 73 | ktime_t *, const struct drm_display_mode *); | 73 | ktime_t *, const struct drm_display_mode *); |
| 74 | bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, | ||
| 75 | struct timeval *, bool); | ||
| 76 | 74 | ||
| 77 | int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, | 75 | int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
| 78 | struct drm_pending_vblank_event *event, | 76 | struct drm_pending_vblank_event *event, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ec719df619a6..1f751a3f570c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
| @@ -978,7 +978,7 @@ driver_stub = { | |||
| 978 | .enable_vblank = nouveau_display_vblank_enable, | 978 | .enable_vblank = nouveau_display_vblank_enable, |
| 979 | .disable_vblank = nouveau_display_vblank_disable, | 979 | .disable_vblank = nouveau_display_vblank_disable, |
| 980 | .get_scanout_position = nouveau_display_scanoutpos, | 980 | .get_scanout_position = nouveau_display_scanoutpos, |
| 981 | .get_vblank_timestamp = nouveau_display_vblstamp, | 981 | .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, |
| 982 | 982 | ||
| 983 | .ioctls = nouveau_ioctls, | 983 | .ioctls = nouveau_ioctls, |
| 984 | .num_ioctls = ARRAY_SIZE(nouveau_ioctls), | 984 | .num_ioctls = ARRAY_SIZE(nouveau_ioctls), |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 88fc791ec8fb..ef8a75940980 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
| @@ -115,10 +115,6 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); | |||
| 115 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); | 115 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); |
| 116 | int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); | 116 | int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); |
| 117 | void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); | 117 | void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); |
| 118 | bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, | ||
| 119 | int *max_error, | ||
| 120 | struct timeval *vblank_time, | ||
| 121 | bool in_vblank_irq); | ||
| 122 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev); | 118 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev); |
| 123 | int radeon_driver_irq_postinstall_kms(struct drm_device *dev); | 119 | int radeon_driver_irq_postinstall_kms(struct drm_device *dev); |
| 124 | void radeon_driver_irq_uninstall_kms(struct drm_device *dev); | 120 | void radeon_driver_irq_uninstall_kms(struct drm_device *dev); |
| @@ -530,6 +526,16 @@ static const struct file_operations radeon_driver_kms_fops = { | |||
| 530 | #endif | 526 | #endif |
| 531 | }; | 527 | }; |
| 532 | 528 | ||
| 529 | static bool | ||
| 530 | radeon_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, | ||
| 531 | bool in_vblank_irq, int *vpos, int *hpos, | ||
| 532 | ktime_t *stime, ktime_t *etime, | ||
| 533 | const struct drm_display_mode *mode) | ||
| 534 | { | ||
| 535 | return radeon_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, | ||
| 536 | stime, etime, mode); | ||
| 537 | } | ||
| 538 | |||
| 533 | static struct drm_driver kms_driver = { | 539 | static struct drm_driver kms_driver = { |
| 534 | .driver_features = | 540 | .driver_features = |
| 535 | DRIVER_USE_AGP | | 541 | DRIVER_USE_AGP | |
| @@ -544,8 +550,8 @@ static struct drm_driver kms_driver = { | |||
| 544 | .get_vblank_counter = radeon_get_vblank_counter_kms, | 550 | .get_vblank_counter = radeon_get_vblank_counter_kms, |
| 545 | .enable_vblank = radeon_enable_vblank_kms, | 551 | .enable_vblank = radeon_enable_vblank_kms, |
| 546 | .disable_vblank = radeon_disable_vblank_kms, | 552 | .disable_vblank = radeon_disable_vblank_kms, |
| 547 | .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, | 553 | .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, |
| 548 | .get_scanout_position = radeon_get_crtc_scanoutpos, | 554 | .get_scanout_position = radeon_get_crtc_scanout_position, |
| 549 | .irq_preinstall = radeon_driver_irq_preinstall_kms, | 555 | .irq_preinstall = radeon_driver_irq_preinstall_kms, |
| 550 | .irq_postinstall = radeon_driver_irq_postinstall_kms, | 556 | .irq_postinstall = radeon_driver_irq_postinstall_kms, |
| 551 | .irq_uninstall = radeon_driver_irq_uninstall_kms, | 557 | .irq_uninstall = radeon_driver_irq_uninstall_kms, |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 5bccdeae0773..6a68d440bc44 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -858,43 +858,6 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) | |||
| 858 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | 858 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
| 859 | } | 859 | } |
| 860 | 860 | ||
| 861 | /** | ||
| 862 | * radeon_get_vblank_timestamp_kms - get vblank timestamp | ||
| 863 | * | ||
| 864 | * @dev: drm dev pointer | ||
| 865 | * @crtc: crtc to get the timestamp for | ||
| 866 | * @max_error: max error | ||
| 867 | * @vblank_time: time value | ||
| 868 | * @flags: flags passed to the driver | ||
| 869 | * | ||
| 870 | * Gets the timestamp on the requested crtc based on the | ||
| 871 | * scanout position. (all asics). | ||
| 872 | * Returns true on success, false on failure. | ||
| 873 | */ | ||
| 874 | bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, | ||
| 875 | int *max_error, | ||
| 876 | struct timeval *vblank_time, | ||
| 877 | bool in_vblank_irq) | ||
| 878 | { | ||
| 879 | struct drm_crtc *drmcrtc; | ||
| 880 | struct radeon_device *rdev = dev->dev_private; | ||
| 881 | |||
| 882 | if (crtc < 0 || crtc >= dev->num_crtcs) { | ||
| 883 | DRM_ERROR("Invalid crtc %d\n", crtc); | ||
| 884 | return false; | ||
| 885 | } | ||
| 886 | |||
| 887 | /* Get associated drm_crtc: */ | ||
| 888 | drmcrtc = &rdev->mode_info.crtcs[crtc]->base; | ||
| 889 | if (!drmcrtc) | ||
| 890 | return false; | ||
| 891 | |||
| 892 | /* Helper routine in DRM core does all the work: */ | ||
| 893 | return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, | ||
| 894 | vblank_time, in_vblank_irq, | ||
| 895 | &drmcrtc->hwmode); | ||
| 896 | } | ||
| 897 | |||
| 898 | const struct drm_ioctl_desc radeon_ioctls_kms[] = { | 861 | const struct drm_ioctl_desc radeon_ioctls_kms[] = { |
| 899 | DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 862 | DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 900 | DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 863 | DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ad282648fc8b..00f5ec5c12c7 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -691,6 +691,9 @@ struct atom_voltage_table | |||
| 691 | }; | 691 | }; |
| 692 | 692 | ||
| 693 | /* Driver internal use only flags of radeon_get_crtc_scanoutpos() */ | 693 | /* Driver internal use only flags of radeon_get_crtc_scanoutpos() */ |
| 694 | #define DRM_SCANOUTPOS_VALID (1 << 0) | ||
| 695 | #define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) | ||
| 696 | #define DRM_SCANOUTPOS_ACCURATE (1 << 2) | ||
| 694 | #define USE_REAL_VBLANKSTART (1 << 30) | 697 | #define USE_REAL_VBLANKSTART (1 << 30) |
| 695 | #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) | 698 | #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) |
| 696 | 699 | ||
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 6ed53d2867c4..1b4dbe9e1c6d 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c | |||
| @@ -151,10 +151,10 @@ int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused) | |||
| 151 | } | 151 | } |
| 152 | #endif | 152 | #endif |
| 153 | 153 | ||
| 154 | int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | 154 | bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, |
| 155 | unsigned int flags, int *vpos, int *hpos, | 155 | bool in_vblank_irq, int *vpos, int *hpos, |
| 156 | ktime_t *stime, ktime_t *etime, | 156 | ktime_t *stime, ktime_t *etime, |
| 157 | const struct drm_display_mode *mode) | 157 | const struct drm_display_mode *mode) |
| 158 | { | 158 | { |
| 159 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 159 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 160 | struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); | 160 | struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); |
| @@ -162,7 +162,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | |||
| 162 | u32 val; | 162 | u32 val; |
| 163 | int fifo_lines; | 163 | int fifo_lines; |
| 164 | int vblank_lines; | 164 | int vblank_lines; |
| 165 | int ret = 0; | 165 | bool ret = false; |
| 166 | 166 | ||
| 167 | /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ | 167 | /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ |
| 168 | 168 | ||
| @@ -198,7 +198,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | |||
| 198 | fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay; | 198 | fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay; |
| 199 | 199 | ||
| 200 | if (fifo_lines > 0) | 200 | if (fifo_lines > 0) |
| 201 | ret |= DRM_SCANOUTPOS_VALID; | 201 | ret = true; |
| 202 | 202 | ||
| 203 | /* HVS more than fifo_lines into frame for compositing? */ | 203 | /* HVS more than fifo_lines into frame for compositing? */ |
| 204 | if (*vpos > fifo_lines) { | 204 | if (*vpos > fifo_lines) { |
| @@ -216,7 +216,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | |||
| 216 | */ | 216 | */ |
| 217 | *vpos -= fifo_lines + 1; | 217 | *vpos -= fifo_lines + 1; |
| 218 | 218 | ||
| 219 | ret |= DRM_SCANOUTPOS_ACCURATE; | ||
| 220 | return ret; | 219 | return ret; |
| 221 | } | 220 | } |
| 222 | 221 | ||
| @@ -229,10 +228,9 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | |||
| 229 | * We can't get meaningful readings wrt. scanline position of the PV | 228 | * We can't get meaningful readings wrt. scanline position of the PV |
| 230 | * and need to make things up in a approximative but consistent way. | 229 | * and need to make things up in a approximative but consistent way. |
| 231 | */ | 230 | */ |
| 232 | ret |= DRM_SCANOUTPOS_IN_VBLANK; | ||
| 233 | vblank_lines = mode->vtotal - mode->vdisplay; | 231 | vblank_lines = mode->vtotal - mode->vdisplay; |
| 234 | 232 | ||
| 235 | if (flags & DRM_CALLED_FROM_VBLIRQ) { | 233 | if (in_vblank_irq) { |
| 236 | /* | 234 | /* |
| 237 | * Assume the irq handler got called close to first | 235 | * Assume the irq handler got called close to first |
| 238 | * line of vblank, so PV has about a full vblank | 236 | * line of vblank, so PV has about a full vblank |
| @@ -254,9 +252,10 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | |||
| 254 | * we are at the very beginning of vblank, as the hvs just | 252 | * we are at the very beginning of vblank, as the hvs just |
| 255 | * started refilling, and the stime and etime timestamps | 253 | * started refilling, and the stime and etime timestamps |
| 256 | * truly correspond to start of vblank. | 254 | * truly correspond to start of vblank. |
| 255 | * | ||
| 256 | * Unfortunately there's no way to report this to upper levels | ||
| 257 | * and make it more useful. | ||
| 257 | */ | 258 | */ |
| 258 | if ((val & SCALER_DISPSTATX_FULL) != SCALER_DISPSTATX_FULL) | ||
| 259 | ret |= DRM_SCANOUTPOS_ACCURATE; | ||
| 260 | } else { | 259 | } else { |
| 261 | /* | 260 | /* |
| 262 | * No clue where we are inside vblank. Return a vpos of zero, | 261 | * No clue where we are inside vblank. Return a vpos of zero, |
| @@ -270,19 +269,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | |||
| 270 | return ret; | 269 | return ret; |
| 271 | } | 270 | } |
| 272 | 271 | ||
| 273 | bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, | ||
| 274 | int *max_error, struct timeval *vblank_time, | ||
| 275 | bool in_vblank_irq) | ||
| 276 | { | ||
| 277 | struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); | ||
| 278 | struct drm_crtc_state *state = crtc->state; | ||
| 279 | |||
| 280 | /* Helper routine in DRM core does all the work: */ | ||
| 281 | return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error, | ||
| 282 | vblank_time, in_vblank_irq, | ||
| 283 | &state->adjusted_mode); | ||
| 284 | } | ||
| 285 | |||
| 286 | static void vc4_crtc_destroy(struct drm_crtc *crtc) | 272 | static void vc4_crtc_destroy(struct drm_crtc *crtc) |
| 287 | { | 273 | { |
| 288 | drm_crtc_cleanup(crtc); | 274 | drm_crtc_cleanup(crtc); |
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 754ce76d4b98..863974942c66 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c | |||
| @@ -154,7 +154,7 @@ static struct drm_driver vc4_drm_driver = { | |||
| 154 | .irq_uninstall = vc4_irq_uninstall, | 154 | .irq_uninstall = vc4_irq_uninstall, |
| 155 | 155 | ||
| 156 | .get_scanout_position = vc4_crtc_get_scanoutpos, | 156 | .get_scanout_position = vc4_crtc_get_scanoutpos, |
| 157 | .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp, | 157 | .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, |
| 158 | 158 | ||
| 159 | #if defined(CONFIG_DEBUG_FS) | 159 | #if defined(CONFIG_DEBUG_FS) |
| 160 | .debugfs_init = vc4_debugfs_init, | 160 | .debugfs_init = vc4_debugfs_init, |
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index d192f7e5c1eb..5ba281361fb7 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h | |||
| @@ -489,13 +489,10 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); | |||
| 489 | extern struct platform_driver vc4_crtc_driver; | 489 | extern struct platform_driver vc4_crtc_driver; |
| 490 | bool vc4_event_pending(struct drm_crtc *crtc); | 490 | bool vc4_event_pending(struct drm_crtc *crtc); |
| 491 | int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); | 491 | int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); |
| 492 | int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | 492 | bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, |
| 493 | unsigned int flags, int *vpos, int *hpos, | 493 | bool in_vblank_irq, int *vpos, int *hpos, |
| 494 | ktime_t *stime, ktime_t *etime, | 494 | ktime_t *stime, ktime_t *etime, |
| 495 | const struct drm_display_mode *mode); | 495 | const struct drm_display_mode *mode); |
| 496 | bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, | ||
| 497 | int *max_error, struct timeval *vblank_time, | ||
| 498 | bool in_vblank_irq); | ||
| 499 | 496 | ||
| 500 | /* vc4_debugfs.c */ | 497 | /* vc4_debugfs.c */ |
| 501 | int vc4_debugfs_init(struct drm_minor *minor); | 498 | int vc4_debugfs_init(struct drm_minor *minor); |
