]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/psr: Add intel_psr_needs_block_dc_vblank for blocking dc entry
authorJouni Högander <jouni.hogander@intel.com>
Fri, 20 Sep 2024 06:23:39 +0000 (09:23 +0300)
committerJouni Högander <jouni.hogander@intel.com>
Mon, 23 Sep 2024 04:07:14 +0000 (07:07 +0300)
We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't
prevent it in case of Panel Replay. Panel Replay switches main link off on
DC entry. This means vblank interrupts are not fired and is a problem if
user-space is polling for vblank events. For this purpose add new function
to query need for dc entry blocking on.

Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240920062340.1333777-2-jouni.hogander@intel.com
drivers/gpu/drm/i915/display/intel_psr.c
drivers/gpu/drm/i915/display/intel_psr.h

index 5b355d0a356529c6dd0baac33296eed2edb61af5..e3357f3b5c705f5c457cc8cbe546af50d63ba629 100644 (file)
@@ -35,6 +35,7 @@
 #include "intel_cursor_regs.h"
 #include "intel_ddi.h"
 #include "intel_de.h"
+#include "intel_display_irq.h"
 #include "intel_display_types.h"
 #include "intel_dp.h"
 #include "intel_dp_aux.h"
@@ -2229,6 +2230,36 @@ unlock:
        mutex_unlock(&psr->lock);
 }
 
+/**
+ * intel_psr_needs_block_dc_vblank - Check if block dc entry is needed
+ * @crtc_state: CRTC status
+ *
+ * We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't
+ * prevent it in case of Panel Replay. Panel Replay switches main link off on
+ * DC entry. This means vblank interrupts are not fired and is a problem if
+ * user-space is polling for vblank events.
+ */
+bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state)
+{
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       struct intel_encoder *encoder;
+
+       for_each_encoder_on_crtc(crtc->base.dev, &crtc->base, encoder) {
+               struct intel_dp *intel_dp;
+
+               if (!intel_encoder_is_dp(encoder))
+                       continue;
+
+               intel_dp = enc_to_intel_dp(encoder);
+
+               if (intel_dp_is_edp(intel_dp) &&
+                   CAN_PANEL_REPLAY(intel_dp))
+                       return true;
+       }
+
+       return false;
+}
+
 static u32 man_trk_ctl_enable_bit_get(struct intel_display *display)
 {
        struct drm_i915_private *dev_priv = to_i915(display->drm);
index 6eb5f15f674faa4d9a75dd23aaa852a0ce076e51..5f26f61f82aa945cb80202b102946367089c8e30 100644 (file)
@@ -58,6 +58,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
 void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state);
 void intel_psr_pause(struct intel_dp *intel_dp);
 void intel_psr_resume(struct intel_dp *intel_dp);
+bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state);
 
 void intel_psr_lock(const struct intel_crtc_state *crtc_state);
 void intel_psr_unlock(const struct intel_crtc_state *crtc_state);