tree:
https://github.com/vsyrjala/linux.git vrr_fixes
head: b9b43deb7fc52a06855bc7d4918d704381fb2d61
commit: 0ff0a6ee139b6d7d414c0125ddc6b7ba1159ed40 [23/26] drm/i915: Fix vblank timestamps
with VRR
config: x86_64-randconfig-m001-20201215 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
smatch warnings:
drivers/gpu/drm/i915/i915_irq.c:891 i915_get_crtc_scanoutpos() warn: inconsistent
indenting
vim +891 drivers/gpu/drm/i915/i915_irq.c
828
829 static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
830 bool in_vblank_irq,
831 int *vpos, int *hpos,
832 ktime_t *stime, ktime_t *etime,
833 const struct drm_display_mode *mode)
834 {
835 struct drm_device *dev = _crtc->dev;
836 struct drm_i915_private *dev_priv = to_i915(dev);
837 struct intel_crtc *crtc = to_intel_crtc(_crtc);
838 enum pipe pipe = crtc->pipe;
839 int position;
840 int vbl_start, vbl_end, hsync_start, htotal, vtotal;
841 unsigned long irqflags;
842 bool use_scanline_counter = INTEL_GEN(dev_priv) >= 5 ||
843 IS_G4X(dev_priv) || IS_GEN(dev_priv, 2) ||
844 crtc->mode_flags & I915_MODE_FLAG_USE_SCANLINE_COUNTER;
845
846 if (drm_WARN_ON(&dev_priv->drm, !mode->crtc_clock)) {
847 drm_dbg(&dev_priv->drm,
848 "trying to get scanoutpos for disabled "
849 "pipe %c\n", pipe_name(pipe));
850 return false;
851 }
852
853 htotal = mode->crtc_htotal;
854 hsync_start = mode->crtc_hsync_start;
855 vtotal = mode->crtc_vtotal;
856 vbl_start = mode->crtc_vblank_start;
857 vbl_end = mode->crtc_vblank_end;
858
859 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
860 vbl_start = DIV_ROUND_UP(vbl_start, 2);
861 vbl_end /= 2;
862 vtotal /= 2;
863 }
864
865 /*
866 * Lock uncore.lock, as we will do multiple timing critical raw
867 * register reads, potentially with preemption disabled, so the
868 * following code must not block on uncore.lock.
869 */
870 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
871
872 /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
873
874 /* Get optional system timestamp before query. */
875 if (stime)
876 *stime = ktime_get();
877
878 if (crtc->mode_flags & I915_MODE_FLAG_VRR) {
879 int scanlines = intel_crtc_scanlines_since_frame_timestamp(crtc);
880
881 position = __intel_get_crtc_scanline(crtc);
882
883 /*
884 * Already exiting vblank? If so, shift our position
885 * so it looks like we're already apporaching the full
886 * vblank end. This should make the generated timestamp
887 * more or less match when the active portion will start.
888 */
889 if (position >= vbl_start && scanlines < position)
890 position = min(crtc->vmax_vblank_start + scanlines, vtotal - 1);
891 } if (use_scanline_counter) {
892 /* No obvious
pixelcount register. Only query vertical
893 * scanout position from Display scan line register.
894 */
895 position = __intel_get_crtc_scanline(crtc);
896 } else {
897 /* Have access to pixelcount since start of frame.
898 * We can split this into vertical and horizontal
899 * scanout position.
900 */
901 position = (intel_de_read_fw(dev_priv, PIPEFRAMEPIXEL(pipe)) &
PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;
902
903 /* convert to pixel counts */
904 vbl_start *= htotal;
905 vbl_end *= htotal;
906 vtotal *= htotal;
907
908 /*
909 * In interlaced modes, the pixel counter counts all pixels,
910 * so one field will have htotal more pixels. In order to avoid
911 * the reported position from jumping backwards when the pixel
912 * counter is beyond the length of the shorter field, just
913 * clamp the position the length of the shorter field. This
914 * matches how the scanline counter based position works since
915 * the scanline counter doesn't count the two half lines.
916 */
917 if (position >= vtotal)
918 position = vtotal - 1;
919
920 /*
921 * Start of vblank interrupt is triggered at start of hsync,
922 * just prior to the first active line of vblank. However we
923 * consider lines to start at the leading edge of horizontal
924 * active. So, should we get here before we've crossed into
925 * the horizontal active of the first line in vblank, we would
926 * not set the DRM_SCANOUTPOS_INVBL flag. In order to fix that,
927 * always add htotal-hsync_start to the current pixel position.
928 */
929 position = (position + htotal - hsync_start) % vtotal;
930 }
931
932 /* Get optional system timestamp after query. */
933 if (etime)
934 *etime = ktime_get();
935
936 /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
937
938 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
939
940 /*
941 * While in vblank, position will be negative
942 * counting up towards 0 at vbl_end. And outside
943 * vblank, position will be positive counting
944 * up since vbl_end.
945 */
946 if (position >= vbl_start)
947 position -= vbl_end;
948 else
949 position += vtotal - vbl_end;
950
951 if (use_scanline_counter) {
952 *vpos = position;
953 *hpos = 0;
954 } else {
955 *vpos = position / htotal;
956 *hpos = position - (*vpos * htotal);
957 }
958
959 return true;
960 }
961
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org