We are currently handling Panel Replay and PSR both in
intel_psr_short_pulse. As own logic for error handling is needed for Panel
Replay let's split it now. Keep functionality as it is.

Signed-off-by: Jouni Högander <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 94 +++++++++++++++++-------
 1 file changed, 66 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c 
b/drivers/gpu/drm/i915/display/intel_psr.c
index e138982dc91f6..99d357bfd84b7 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -3899,46 +3899,67 @@ static void psr_capability_changed_check(struct 
intel_dp *intel_dp)
        }
 }
 
-/*
- * On common bits:
- * DP_PSR_RFB_STORAGE_ERROR == DP_PANEL_REPLAY_RFB_STORAGE_ERROR
- * DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR == 
DP_PANEL_REPLAY_VSC_SDP_UNCORRECTABLE_ERROR
- * DP_PSR_LINK_CRC_ERROR == DP_PANEL_REPLAY_LINK_CRC_ERROR
- * this function is relying on PSR definitions
- */
-void intel_psr_short_pulse(struct intel_dp *intel_dp)
+static void _panel_replay_short_pulse(struct intel_dp *intel_dp)
 {
        struct intel_display *display = to_intel_display(intel_dp);
        struct intel_psr *psr = &intel_dp->psr;
-       u8 status, error_status;
-       const u8 errors = DP_PSR_RFB_STORAGE_ERROR |
-                         DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR |
-                         DP_PSR_LINK_CRC_ERROR;
+       int ret;
+       u8 error_status;
+       const u8 errors = DP_PANEL_REPLAY_LINK_CRC_ERROR |
+                         DP_PANEL_REPLAY_RFB_STORAGE_ERROR |
+                         DP_PANEL_REPLAY_VSC_SDP_UNCORRECTABLE_ERROR;
 
-       if (!CAN_PSR(intel_dp) && !CAN_PANEL_REPLAY(intel_dp))
+       ret = drm_dp_dpcd_read_byte(&intel_dp->aux, 
DP_PANEL_REPLAY_ERROR_STATUS,
+                                   &error_status);
+       if (ret < 0)
                return;
 
-       mutex_lock(&psr->lock);
+       if (error_status & errors) {
+               intel_psr_disable_locked(intel_dp);
+               psr->sink_not_reliable = true;
+       }
 
-       psr->link_ok = false;
+       if (error_status & DP_PANEL_REPLAY_RFB_STORAGE_ERROR)
+               drm_dbg_kms(display->drm,
+                           "Panel Replay RFB storage error\n");
+       if (error_status & DP_PANEL_REPLAY_VSC_SDP_UNCORRECTABLE_ERROR)
+               drm_dbg_kms(display->drm,
+                           "Panel Replay VSC SDP uncorrectable error\n");
+       if (error_status & DP_PANEL_REPLAY_LINK_CRC_ERROR)
+               drm_dbg_kms(display->drm,
+                           "Panel Replay Link CRC error\n");
 
-       if (!psr->enabled)
-               goto exit;
+       if (error_status & ~errors)
+               drm_err(display->drm,
+                       "PANEL_REPLAY_ERROR_STATUS unhandled errors %x\n",
+                       error_status & ~errors);
+
+       /* clear status register */
+       drm_dp_dpcd_write_byte(&intel_dp->aux, DP_PANEL_REPLAY_ERROR_STATUS,
+                              error_status);
+}
+
+static void _psr_short_pulse(struct intel_dp *intel_dp)
+{
+       struct intel_display *display = to_intel_display(intel_dp);
+       struct intel_psr *psr = &intel_dp->psr;
+       u8 status, error_status;
+       const u8 errors = DP_PSR_RFB_STORAGE_ERROR |
+                         DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR |
+                         DP_PSR_LINK_CRC_ERROR;
 
        if (psr_get_status_and_error_status(intel_dp, &status, &error_status)) {
                drm_err(display->drm,
                        "Error reading PSR status or error status\n");
-               goto exit;
+               return;
        }
 
-       if ((!psr->panel_replay_enabled && status == 
DP_PSR_SINK_INTERNAL_ERROR) ||
-           (error_status & errors)) {
+       if (status == DP_PSR_SINK_INTERNAL_ERROR || (error_status & errors)) {
                intel_psr_disable_locked(intel_dp);
                psr->sink_not_reliable = true;
        }
 
-       if (!psr->panel_replay_enabled && status == DP_PSR_SINK_INTERNAL_ERROR 
&&
-           !error_status)
+       if (status == DP_PSR_SINK_INTERNAL_ERROR && !error_status)
                drm_dbg_kms(display->drm,
                            "PSR sink internal error, disabling PSR\n");
        if (error_status & DP_PSR_RFB_STORAGE_ERROR)
@@ -3955,16 +3976,33 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp)
                drm_err(display->drm,
                        "PSR_ERROR_STATUS unhandled errors %x\n",
                        error_status & ~errors);
+
        /* clear status register */
-       drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_ERROR_STATUS, error_status);
+       drm_dp_dpcd_write_byte(&intel_dp->aux, DP_PSR_ERROR_STATUS, 
error_status);
 
-       if (!psr->panel_replay_enabled) {
-               psr_alpm_check(intel_dp);
-               psr_capability_changed_check(intel_dp);
-       }
+       psr_alpm_check(intel_dp);
+       psr_capability_changed_check(intel_dp);
+}
+
+void intel_psr_short_pulse(struct intel_dp *intel_dp)
+{
+       if (!CAN_PSR(intel_dp) && !CAN_PANEL_REPLAY(intel_dp))
+               return;
+
+       mutex_lock(&intel_dp->psr.lock);
+
+       if (!intel_dp->psr.enabled)
+               goto exit;
+
+       intel_dp->psr.link_ok = false;
+
+       if (intel_dp->psr.panel_replay_enabled)
+               _panel_replay_short_pulse(intel_dp);
+       else
+               _psr_short_pulse(intel_dp);
 
 exit:
-       mutex_unlock(&psr->lock);
+       mutex_unlock(&intel_dp->psr.lock);
 }
 
 bool intel_psr_enabled(struct intel_dp *intel_dp)
-- 
2.43.0

Reply via email to