]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/xe3p_lpd: use pixel normalizer for fp16 formats for FBC
authorVinod Govindapillai <vinod.govindapillai@intel.com>
Mon, 27 Oct 2025 13:40:01 +0000 (15:40 +0200)
committerVinod Govindapillai <vinod.govindapillai@intel.com>
Fri, 31 Oct 2025 11:32:16 +0000 (13:32 +0200)
There is a hw restriction that we could enable the FBC for FP16
formats only if the pixel normalization block is enabled. Hence
enable the pixel normalizer block with normalzation factor as
1.0 for the supported FP16 formats to get the FBC enabled. Two
existing helper function definitions are moved up to avoid the
forward declarations as part of this patch as well.

v2: sw/hw state differentiation on handling pixel normalizer (Jani)

Bspec: 69863, 68881
Cc: Shekhar Chauhan <shekhar.chauhan@intel.com>
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Link: https://patch.msgid.link/20251027134001.325064-5-vinod.govindapillai@intel.com
drivers/gpu/drm/i915/display/intel_fbc.c
drivers/gpu/drm/i915/display/intel_fbc.h
drivers/gpu/drm/i915/display/skl_universal_plane.c
drivers/gpu/drm/i915/display/skl_universal_plane_regs.h

index 0f697c7b1d466673bd50ebdebcf3c9f5daf87bd6..54b23116ea3c37388e0abe7a4218884e68d05971 100644 (file)
@@ -1119,6 +1119,15 @@ static bool xe3p_lpd_fbc_pixel_format_is_valid(const struct intel_plane_state *p
        }
 }
 
+bool
+intel_fbc_is_enable_pixel_normalizer(const struct intel_plane_state *plane_state)
+{
+       struct intel_display *display = to_intel_display(plane_state);
+
+       return DISPLAY_VER(display) >= 35 &&
+              xe3p_lpd_fbc_fp16_format_is_valid(plane_state);
+}
+
 static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
 {
        struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
index c86562404a00160925034f0aa7ac466b1c6e9425..91424563206a31e279bc6b9c498e19efebe191c5 100644 (file)
@@ -53,5 +53,7 @@ void intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state,
                                  struct intel_crtc *crtc);
 void intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb,
                                       struct intel_plane *plane);
+bool
+intel_fbc_is_enable_pixel_normalizer(const struct intel_plane_state *plane_state);
 
 #endif /* __INTEL_FBC_H__ */
index d24070d61c0e1d73203f1fa2ce9f2e6f65284cba..ba1bf0bd4c55f992d88644619f684572f898b223 100644 (file)
@@ -439,6 +439,23 @@ static int skl_plane_max_height(const struct drm_framebuffer *fb,
        return 4096;
 }
 
+static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
+{
+       return pipe - PIPE_A + INTEL_FBC_A;
+}
+
+static bool skl_plane_has_fbc(struct intel_display *display,
+                             enum intel_fbc_id fbc_id, enum plane_id plane_id)
+{
+       if ((DISPLAY_RUNTIME_INFO(display)->fbc_mask & BIT(fbc_id)) == 0)
+               return false;
+
+       if (DISPLAY_VER(display) >= 20)
+               return icl_is_hdr_plane(display, plane_id);
+       else
+               return plane_id == PLANE_1;
+}
+
 static int icl_plane_max_height(const struct drm_framebuffer *fb,
                                int color_plane,
                                unsigned int rotation)
@@ -874,6 +891,25 @@ 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)
+{
+       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 (!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;
+
+       intel_de_write_dsb(display, dsb,
+                          PLANE_PIXEL_NORMALIZE(plane->pipe, plane->id), val);
+}
+
 static void
 icl_plane_disable_arm(struct intel_dsb *dsb,
                      struct intel_plane *plane,
@@ -889,6 +925,10 @@ icl_plane_disable_arm(struct intel_dsb *dsb,
        skl_write_plane_wm(dsb, plane, crtc_state);
 
        icl_plane_disable_sel_fetch_arm(dsb, plane, crtc_state);
+
+       if (DISPLAY_VER(display) >= 35)
+               x3p_lpd_plane_update_pixel_normalizer(dsb, plane, false);
+
        intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id), 0);
        intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id), 0);
 }
@@ -1618,6 +1658,14 @@ icl_plane_update_arm(struct intel_dsb *dsb,
 
        icl_plane_update_sel_fetch_arm(dsb, plane, crtc_state, 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);
+
        /*
         * The control register self-arms if the plane was previously
         * disabled. Try to make the plane enable atomic by writing
@@ -2390,23 +2438,6 @@ void icl_link_nv12_planes(struct intel_plane_state *uv_plane_state,
        }
 }
 
-static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
-{
-       return pipe - PIPE_A + INTEL_FBC_A;
-}
-
-static bool skl_plane_has_fbc(struct intel_display *display,
-                             enum intel_fbc_id fbc_id, enum plane_id plane_id)
-{
-       if ((DISPLAY_RUNTIME_INFO(display)->fbc_mask & BIT(fbc_id)) == 0)
-               return false;
-
-       if (DISPLAY_VER(display) >= 20)
-               return icl_is_hdr_plane(display, plane_id);
-       else
-               return plane_id == PLANE_1;
-}
-
 static struct intel_fbc *skl_plane_fbc(struct intel_display *display,
                                       enum pipe pipe, enum plane_id plane_id)
 {
index ca9fdfbbe57cfcf0a7e04f233f8c21bf5585bb9e..7c944d3ca85550fcd53af1798607ac8b3e3c538b 100644 (file)
                                                                _SEL_FETCH_PLANE_OFFSET_5_A, _SEL_FETCH_PLANE_OFFSET_5_B, \
                                                                _SEL_FETCH_PLANE_OFFSET_6_A, _SEL_FETCH_PLANE_OFFSET_6_B)
 
+#define _PLANE_PIXEL_NORMALIZE_1_A             0x701a8
+#define _PLANE_PIXEL_NORMALIZE_2_A             0x702a8
+#define _PLANE_PIXEL_NORMALIZE_1_B             0x711a8
+#define _PLANE_PIXEL_NORMALIZE_2_B             0x712a8
+#define PLANE_PIXEL_NORMALIZE(pipe, plane)     _MMIO_SKL_PLANE((pipe), (plane), \
+                                                               _PLANE_PIXEL_NORMALIZE_1_A, _PLANE_PIXEL_NORMALIZE_1_B, \
+                                                               _PLANE_PIXEL_NORMALIZE_2_A, _PLANE_PIXEL_NORMALIZE_2_B)
+#define   PLANE_PIXEL_NORMALIZE_ENABLE                 REG_BIT(31)
+#define   PLANE_PIXEL_NORMALIZE_NORM_FACTOR_MASK       REG_GENMASK(15, 0)
+#define   PLANE_PIXEL_NORMALIZE_NORM_FACTOR(val)       REG_FIELD_PREP(PLANE_PIXEL_NORMALIZE_NORM_FACTOR_MASK, (val))
+#define   PLANE_PIXEL_NORMALIZE_NORM_FACTOR_1_0                0x3c00
+
 #endif /* __SKL_UNIVERSAL_PLANE_REGS_H__ */