Pixel normalizer is enabled with normalization factor as 1.0 for
FP16 formats in order to support FBC for those formats in xe3p_lpd.
Previously pixel normalizer gets disabled during the plane disable
routine. But there could be plane format settings without explicitly
calling the plane disable in-between and we could endup keeping the
pixel normalizer enabled for formats which we don't require that.
This is causing crc mismatches in yuv formats and FIFO underruns in
planar formats like NV12. Fix this by updating the pixel normalizer
configuration based on the pixel formats explicitly during the plane
settings arm calls itself - enable it for FP16 and disable it for other
formats in HDR capable planes.
Fixes: 5298eea7ed20 ("drm/i915/xe3p_lpd: use pixel normalizer for fp16 formats
for FBC")
Signed-off-by: Vinod Govindapillai <[email protected]>
---
.../drm/i915/display/intel_display_device.h | 1 +
.../drm/i915/display/skl_universal_plane.c | 51 +++++++++++++------
2 files changed, 36 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h
b/drivers/gpu/drm/i915/display/intel_display_device.h
index 6c74d6b0cc48..126aa1eeeb6d 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -175,6 +175,7 @@ struct intel_display_platforms {
#define HAS_DSC_MST(__display) (DISPLAY_VER(__display) >= 12 &&
HAS_DSC(__display))
#define HAS_FBC(__display)
(DISPLAY_RUNTIME_INFO(__display)->fbc_mask != 0)
#define HAS_FBC_DIRTY_RECT(__display) (DISPLAY_VER(__display) >= 30)
+#define HAS_FBC_FP16_FORMATS(__display) (DISPLAY_VER(__display) >= 35)
#define HAS_FBC_SYS_CACHE(__display) (DISPLAY_VER(__display) >= 35 &&
!(__display)->platform.dgfx)
#define HAS_FPGA_DBG_UNCLAIMED(__display)
(DISPLAY_INFO(__display)->has_fpga_dbg)
#define HAS_FW_BLC(__display) (DISPLAY_VER(__display) >= 3)
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index b3d41705448a..724d5d25d3d0 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -891,20 +891,46 @@ static void icl_plane_disable_sel_fetch_arm(struct
intel_dsb *dsb,
intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id),
0);
}
-static void x3p_lpd_plane_update_pixel_normalizer(struct intel_dsb *dsb,
- struct intel_plane *plane,
- bool enable)
+static void xe3p_lpd_plane_disable_pixel_normalizer(struct intel_dsb *dsb,
+ struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(plane->pipe);
- u32 val;
- /* Only HDR planes have pixel normalizer and don't matter if no FBC */
+ if (!HAS_FBC_FP16_FORMATS(display))
+ return;
+
+ /* Only HDR planes have pixel normalizer and don't matter if FBC is
fused off */
+ if (!skl_plane_has_fbc(display, fbc_id, plane->id))
+ return;
+
+ intel_de_write_dsb(display, dsb,
+ PLANE_PIXEL_NORMALIZE(plane->pipe, plane->id), 0);
+}
+
+static void xe3p_lpd_plane_update_pixel_normalizer(struct intel_dsb *dsb,
+ struct intel_plane *plane)
+{
+ struct intel_display *display = to_intel_display(plane);
+ enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(plane->pipe);
+ const struct intel_plane_state *plane_state =
+ to_intel_plane_state(plane->base.state);
+ u32 val = 0;
+
+ if (!HAS_FBC_FP16_FORMATS(display))
+ return;
+
if (!skl_plane_has_fbc(display, fbc_id, plane->id))
return;
- val = enable ?
PLANE_PIXEL_NORMALIZE_NORM_FACTOR(PLANE_PIXEL_NORMALIZE_NORM_FACTOR_1_0) |
- PLANE_PIXEL_NORMALIZE_ENABLE : 0;
+ /*
+ * In order to have FBC for fp16 formats pixel normalizer block must be
+ * active. Check if pixel normalizer block need to be enabled for FBC.
+ * If needed, use normalization factor as 1.0 and enable the block.
+ */
+ if (intel_fbc_is_enable_pixel_normalizer(plane_state))
+ val =
PLANE_PIXEL_NORMALIZE_NORM_FACTOR(PLANE_PIXEL_NORMALIZE_NORM_FACTOR_1_0) |
+ PLANE_PIXEL_NORMALIZE_ENABLE;
intel_de_write_dsb(display, dsb,
PLANE_PIXEL_NORMALIZE(plane->pipe, plane->id), val);
@@ -926,8 +952,7 @@ icl_plane_disable_arm(struct intel_dsb *dsb,
icl_plane_disable_sel_fetch_arm(dsb, plane, crtc_state);
- if (DISPLAY_VER(display) >= 35)
- x3p_lpd_plane_update_pixel_normalizer(dsb, plane, false);
+ xe3p_lpd_plane_disable_pixel_normalizer(dsb, plane);
intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id), 0);
intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id), 0);
@@ -1674,13 +1699,7 @@ icl_plane_update_arm(struct intel_dsb *dsb,
intel_color_plane_commit_arm(dsb, plane_state);
- /*
- * In order to have FBC for fp16 formats pixel normalizer block must be
- * active. Check if pixel normalizer block need to be enabled for FBC.
- * If needed, use normalization factor as 1.0 and enable the block.
- */
- if (intel_fbc_is_enable_pixel_normalizer(plane_state))
- x3p_lpd_plane_update_pixel_normalizer(dsb, plane, true);
+ xe3p_lpd_plane_update_pixel_normalizer(dsb, plane);
/*
* The control register self-arms if the plane was previously
--
2.43.0