In LNL onwards, FBC can be associated to the first three planes.
The FBC will be enabled for first FBC capable visible plane
until the userspace can select one of these FBC capable plane
explicitly

Bspec: 69560
Signed-off-by: Vinod Govindapillai <vinod.govindapil...@intel.com>
---
 drivers/gpu/drm/i915/display/intel_fbc.c      | 29 +++++++++++++++++++
 .../drm/i915/display/skl_universal_plane.c    |  5 +++-
 drivers/gpu/drm/i915/i915_reg.h               |  4 +++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c 
b/drivers/gpu/drm/i915/display/intel_fbc.c
index 45e205a0f740..62f59630d410 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -649,6 +649,21 @@ static void skl_fbc_program_cfb_stride(struct intel_fbc 
*fbc)
                     CHICKEN_FBC_STRIDE_MASK, val);
 }
 
+static u32 lnl_plane_binding(struct intel_fbc *fbc)
+{
+       switch (fbc->state.plane->id) {
+       default:
+               MISSING_CASE(fbc->state.plane->id);
+               fallthrough;
+       case 0:
+               return DPFC_CTL_PLANE_BINDING_1;
+       case 1:
+               return DPFC_CTL_PLANE_BINDING_2;
+       case 2:
+               return DPFC_CTL_PLANE_BINDING_3;
+       }
+}
+
 static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)
 {
        const struct intel_fbc_state *fbc_state = &fbc->state;
@@ -660,6 +675,9 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)
        if (IS_IVYBRIDGE(i915))
                dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane);
 
+       if (DISPLAY_VER(i915) >= 20)
+               dpfc_ctl |= lnl_plane_binding(fbc);
+
        if (fbc_state->fence_id >= 0)
                dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB;
 
@@ -1250,6 +1268,17 @@ static int intel_fbc_check_plane(struct 
intel_atomic_state *state,
                }
        }
 
+       /*
+        * From LNL, FBC can be assigned on any plane. Until a provision is
+        * provided for the userspace to select a plane for FBC, lets select
+        * the first visible plane that is FBC capable.
+        */
+       if (DISPLAY_VER(i915) >= 20 && fbc->state.plane &&
+           fbc->state.plane != plane) {
+               plane_state->no_fbc_reason = "fbc enabled on another plane";
+               return 0;
+       }
+
        plane_state->no_fbc_reason = NULL;
 
        return 0;
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 4d01c7ae4485..1291351c9941 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1962,7 +1962,10 @@ static bool skl_plane_has_fbc(struct drm_i915_private 
*dev_priv,
        if ((DISPLAY_RUNTIME_INFO(dev_priv)->fbc_mask & BIT(fbc_id)) == 0)
                return false;
 
-       return plane_id == PLANE_PRIMARY;
+       if (DISPLAY_VER(dev_priv) >= 20)
+               return plane_id <= PLANE_SPRITE1;
+       else
+               return plane_id == PLANE_PRIMARY;
 }
 
 static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index aefad14ab27a..b207774f3c33 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1327,6 +1327,10 @@
 #define   DPFC_CTL_PLANE_IVB(i9xx_plane)       
REG_FIELD_PREP(DPFC_CTL_PLANE_MASK_IVB, (i9xx_plane))
 #define   DPFC_CTL_FENCE_EN_IVB                        REG_BIT(28) /* ivb+ */
 #define   DPFC_CTL_PERSISTENT_MODE             REG_BIT(25) /* g4x-snb */
+#define   DPFC_CTL_PLANE_BINDING_MASK          REG_GENMASK(12, 11) /* XE */
+#define   DPFC_CTL_PLANE_BINDING_1             
REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, 0) /* XE */
+#define   DPFC_CTL_PLANE_BINDING_2             
REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, 1) /* XE */
+#define   DPFC_CTL_PLANE_BINDING_3             
REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, 2) /* XE */
 #define   DPFC_CTL_FALSE_COLOR                 REG_BIT(10) /* ivb+ */
 #define   DPFC_CTL_SR_EN                       REG_BIT(10) /* g4x only */
 #define   DPFC_CTL_SR_EXIT_DIS                 REG_BIT(9) /* g4x only */
-- 
2.34.1

Reply via email to