drm/i915/dsi: Enable software vblank counter
authorVandita Kulkarni <vandita.kulkarni@intel.com>
Thu, 24 Sep 2020 12:42:09 +0000 (18:12 +0530)
committerJani Nikula <jani.nikula@intel.com>
Mon, 28 Sep 2020 17:02:24 +0000 (20:02 +0300)
In case of DSI cmd mode, we get hw vblank counter updated after the TE
comes in, if we try to read the hw vblank counter in te handler we
wouldnt have the udpated vblank counter yet. This will lead to a state
where we would send the vblank event to the user space in the next te,
though the frame update would have completed in the first TE duration
itself. Hence switch to using software timestamp based vblank counter.

v2: Use mode_flags from crtc_state (Ville)

Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Vandita Kulkarni <vandita.kulkarni@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200924124209.17916-6-vandita.kulkarni@intel.com
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/i915_irq.c

index 1c6c6d7..b7ae60a 100644 (file)
@@ -1808,6 +1808,17 @@ enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc)
 static u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       u32 mode_flags = crtc->mode_flags;
+
+       /*
+        * From Gen 11, In case of dsi cmd mode, frame counter wouldnt
+        * have updated at the beginning of TE, if we want to use
+        * the hw counter, then we would find it updated in only
+        * the next TE, hence switching to sw counter.
+        */
+       if (mode_flags & (I915_MODE_FLAG_DSI_USE_TE0 | I915_MODE_FLAG_DSI_USE_TE1))
+               return 0;
 
        /*
         * On i965gm the hardware frame counter reads
index 6835b35..b753c77 100644 (file)
@@ -682,8 +682,12 @@ u32 i915_get_vblank_counter(struct drm_crtc *crtc)
 u32 g4x_get_vblank_counter(struct drm_crtc *crtc)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+       struct drm_vblank_crtc *vblank = &dev_priv->drm.vblank[drm_crtc_index(crtc)];
        enum pipe pipe = to_intel_crtc(crtc)->pipe;
 
+       if (!vblank->max_vblank_count)
+               return 0;
+
        return I915_READ(PIPE_FRMCOUNT_G4X(pipe));
 }