Xe3p_LPD added registers and bits to provide debug information at the
time a FIFO underrun happens.  We have already handled most of them,
with FBC being left out.  Let's handle it now.

For FBC, a bit was added to FBC_DEBUG_STATUS that indicates that the
respective FBC was decompressing when a FIFO underrun happened.  Add the
logic log that info.

Bspec: 69561
Cc: Matt Roper <[email protected]>
Cc: Ville Syrjälä <[email protected]>
Signed-off-by: Gustavo Sousa <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_fbc.c           | 45 ++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_fbc.h           |  2 +
 drivers/gpu/drm/i915/display/intel_fbc_regs.h      |  2 +
 drivers/gpu/drm/i915/display/intel_fifo_underrun.c |  1 +
 4 files changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c 
b/drivers/gpu/drm/i915/display/intel_fbc.c
index a1e3083022ee..24b72951ea3c 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -129,6 +129,11 @@ struct intel_fbc {
        const char *no_fbc_reason;
 };
 
+static char fbc_name(enum intel_fbc_id fbc_id)
+{
+       return 'A' + fbc_id;
+}
+
 /* plane stride in pixels */
 static unsigned int intel_fbc_plane_stride(const struct intel_plane_state 
*plane_state)
 {
@@ -2119,6 +2124,46 @@ void intel_fbc_handle_fifo_underrun_irq(struct 
intel_display *display)
                __intel_fbc_handle_fifo_underrun_irq(fbc);
 }
 
+static unsigned int pipe_to_fbc_mask(struct intel_display *display, enum pipe 
pipe)
+{
+       struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
+       struct intel_plane *plane;
+       unsigned int mask = 0;
+
+       for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
+               if (plane->fbc)
+                       mask |= BIT(plane->fbc->id);
+       }
+
+       return mask;
+}
+
+static void __intel_fbc_log_fifo_underrun(struct intel_fbc *fbc, enum pipe 
pipe)
+{
+       struct intel_display *display = fbc->display;
+       u32 val;
+
+       val = intel_de_read(display, FBC_DEBUG_STATUS(fbc->id));
+       if (val & FBC_UNDERRUN_DECMPR) {
+               intel_de_write(display, FBC_DEBUG_STATUS(fbc->id), 
FBC_UNDERRUN_DECMPR);
+               drm_err(display->drm, "Pipe %c FIFO underrun info: FBC %c 
decompressing\n",
+                       pipe_name(pipe), fbc_name(fbc->id));
+       }
+}
+
+void intel_fbc_log_fifo_underrun(struct intel_display *display, enum pipe pipe)
+{
+       struct intel_fbc *fbc;
+       enum intel_fbc_id fbc_id;
+       unsigned int fbc_mask;
+
+       fbc_mask = pipe_to_fbc_mask(display, pipe);
+
+       for_each_intel_fbc(display, fbc, fbc_id)
+               if (fbc_mask & BIT(fbc_id))
+                       __intel_fbc_log_fifo_underrun(fbc, pipe);
+}
+
 /*
  * The DDX driver changes its behavior depending on the value it reads from
  * i915.enable_fbc, so sanitize it by translating the default value into either
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h 
b/drivers/gpu/drm/i915/display/intel_fbc.h
index 91424563206a..d34282cbe971 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.h
+++ b/drivers/gpu/drm/i915/display/intel_fbc.h
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 
 enum fb_op_origin;
+enum pipe;
 struct intel_atomic_state;
 struct intel_crtc;
 struct intel_crtc_state;
@@ -46,6 +47,7 @@ void intel_fbc_flush(struct intel_display *display,
                     unsigned int frontbuffer_bits, enum fb_op_origin origin);
 void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane);
 void intel_fbc_handle_fifo_underrun_irq(struct intel_display *display);
+void intel_fbc_log_fifo_underrun(struct intel_display *display, enum pipe 
pipe);
 void intel_fbc_reset_underrun(struct intel_display *display);
 void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc);
 void intel_fbc_debugfs_register(struct intel_display *display);
diff --git a/drivers/gpu/drm/i915/display/intel_fbc_regs.h 
b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
index b1d0161a3196..77d8321c4fb3 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
@@ -88,6 +88,8 @@
 #define DPFC_FENCE_YOFF                        _MMIO(0x3218)
 #define ILK_DPFC_FENCE_YOFF(fbc_id)    _MMIO_PIPE((fbc_id), 0x43218, 0x43258)
 #define DPFC_CHICKEN                   _MMIO(0x3224)
+#define FBC_DEBUG_STATUS(fbc_id)       _MMIO_PIPE((fbc_id), 0x43220, 0x43260)
+#define   FBC_UNDERRUN_DECMPR                  REG_BIT(27)
 #define ILK_DPFC_CHICKEN(fbc_id)       _MMIO_PIPE((fbc_id), 0x43224, 0x43264)
 #define   DPFC_HT_MODIFY                       REG_BIT(31) /* pre-ivb */
 #define   DPFC_NUKE_ON_ANY_MODIFICATION                REG_BIT(23) /* bdw+ */
diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c 
b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
index 1da90c99f93f..d0dbc4faa3f4 100644
--- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
+++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
@@ -403,6 +403,7 @@ static void xe3p_lpd_log_underrun(struct intel_display 
*display,
        u32 val;
 
        process_underrun_dbg1(display, pipe);
+       intel_fbc_log_fifo_underrun(display, pipe);
 
        val = intel_de_read(display, UNDERRUN_DBG2(pipe));
        if (val & UNDERRUN_FRAME_LINE_COUNTERS_FROZEN) {

-- 
2.51.0

Reply via email to