summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/display/intel_fb.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2021-10-20 22:51:28 +0300
committerImre Deak <imre.deak@intel.com>2021-10-21 21:44:17 +0300
commite2b8329432b880f3821f85e1253a9b6b9d714a86 (patch)
tree056f6eb1c29915b070027c0fcf767bac9d0aa8b6 /drivers/gpu/drm/i915/display/intel_fb.c
parent171c555c2c2664a250cd35680c34c31a6d233dc7 (diff)
downloadlinux-e2b8329432b880f3821f85e1253a9b6b9d714a86.tar.gz
linux-e2b8329432b880f3821f85e1253a9b6b9d714a86.tar.bz2
linux-e2b8329432b880f3821f85e1253a9b6b9d714a86.zip
drm/i915: Add a table with a descriptor for all i915 modifiers
Add a table describing all the framebuffer modifiers used by i915 at one place. This has the benefit of deduplicating the listing of supported modifiers for each platform and checking the support of these modifiers on a given plane. This also simplifies in a similar way getting some attribute for a modifier, for instance checking if the modifier is a CCS modifier type. While at it drop the cursor plane filtering from skl_plane_has_rc_ccs(), as the cursor plane is registered with DRM core elsewhere. v1: Unchanged. v2: - Keep the plane caps calculation in the plane code and pass an enum with these caps to intel_fb_get_modifiers(). (Ville) - Get the modifiers calling intel_fb_get_modifiers() in i9xx_plane.c as well. v3: - s/.id/.modifier/ (Ville) - Keep modifier_desc vs. plane_cap filter conditions consistent. (Ville) - Drop redundant cursor plane check from skl_plane_has_rc_ccs(). (Ville) - Use from, until display version fields in modifier_desc instead of a mask. (Jani) - Unexport struct intel_modifier_desc, separate its decl and init. (Jani) - Remove enum pipe, plane_id forward decls from intel_fb.h, which are not needed after v2. v4: - Reuse IS_DISPLAY_VER() instead of open-coding it. (Jani) - Preserve the current modifier order exposed to user space. (Ville) v5: Use }, { on one line to seperate the descriptor array elements. (Jani) Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com> Cc: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com> (v3) Link: https://patchwork.freedesktop.org/patch/msgid/20211020195138.1841242-2-imre.deak@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_fb.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index fa1f375e696b..d42b7a1297af 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -13,6 +13,150 @@
#define check_array_bounds(i915, a, i) drm_WARN_ON(&(i915)->drm, (i) >= ARRAY_SIZE(a))
+struct intel_modifier_desc {
+ u64 modifier;
+ struct {
+ u8 from;
+ u8 until;
+ } display_ver;
+#define DISPLAY_VER_ALL { 0, -1 }
+
+ u8 is_linear:1;
+
+ struct {
+#define INTEL_CCS_RC BIT(0)
+#define INTEL_CCS_RC_CC BIT(1)
+#define INTEL_CCS_MC BIT(2)
+
+#define INTEL_CCS_ANY (INTEL_CCS_RC | INTEL_CCS_RC_CC | INTEL_CCS_MC)
+ u8 type:3;
+ } ccs;
+};
+
+static const struct intel_modifier_desc intel_modifiers[] = {
+ {
+ .modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
+ .display_ver = { 12, 13 },
+
+ .ccs.type = INTEL_CCS_MC,
+ }, {
+ .modifier = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
+ .display_ver = { 12, 13 },
+
+ .ccs.type = INTEL_CCS_RC,
+ }, {
+ .modifier = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC,
+ .display_ver = { 12, 13 },
+
+ .ccs.type = INTEL_CCS_RC_CC,
+ }, {
+ .modifier = I915_FORMAT_MOD_Yf_TILED_CCS,
+ .display_ver = { 9, 11 },
+
+ .ccs.type = INTEL_CCS_RC,
+ }, {
+ .modifier = I915_FORMAT_MOD_Y_TILED_CCS,
+ .display_ver = { 9, 11 },
+
+ .ccs.type = INTEL_CCS_RC,
+ }, {
+ .modifier = I915_FORMAT_MOD_Yf_TILED,
+ .display_ver = { 9, 11 },
+ }, {
+ .modifier = I915_FORMAT_MOD_Y_TILED,
+ .display_ver = { 9, 13 },
+ }, {
+ .modifier = I915_FORMAT_MOD_X_TILED,
+ .display_ver = DISPLAY_VER_ALL,
+ }, {
+ .modifier = DRM_FORMAT_MOD_LINEAR,
+ .display_ver = DISPLAY_VER_ALL,
+
+ .is_linear = true,
+ },
+};
+
+static bool is_ccs_type_modifier(const struct intel_modifier_desc *md, u8 ccs_type)
+{
+ return md->ccs.type & ccs_type;
+}
+
+static bool plane_has_modifier(struct drm_i915_private *i915,
+ enum intel_plane_caps plane_caps,
+ const struct intel_modifier_desc *md)
+{
+ if (!IS_DISPLAY_VER(i915, md->display_ver.from, md->display_ver.until))
+ return false;
+
+ if (!md->is_linear &&
+ !(plane_caps & PLANE_HAS_TILING))
+ return false;
+
+ if (is_ccs_type_modifier(md, INTEL_CCS_RC | INTEL_CCS_RC_CC) &&
+ !(plane_caps & PLANE_HAS_CCS_RC))
+ return false;
+
+ if (is_ccs_type_modifier(md, INTEL_CCS_MC) &&
+ !(plane_caps & PLANE_HAS_CCS_MC))
+ return false;
+
+ return true;
+}
+
+/**
+ * intel_fb_plane_get_modifiers: Get the modifiers for the given platform and plane capabilities
+ * @i915: i915 device instance
+ * @plane_caps: capabilities for the plane the modifiers are queried for
+ *
+ * Returns:
+ * Returns the list of modifiers allowed by the @i915 platform and @plane_caps.
+ * The caller must free the returned buffer.
+ */
+u64 *intel_fb_plane_get_modifiers(struct drm_i915_private *i915,
+ enum intel_plane_caps plane_caps)
+{
+ u64 *list, *p;
+ int count = 1; /* +1 for invalid modifier terminator */
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(intel_modifiers); i++) {
+ if (plane_has_modifier(i915, plane_caps, &intel_modifiers[i]))
+ count++;
+ }
+
+ list = kmalloc_array(count, sizeof(*list), GFP_KERNEL);
+ if (drm_WARN_ON(&i915->drm, !list))
+ return NULL;
+
+ p = list;
+ for (i = 0; i < ARRAY_SIZE(intel_modifiers); i++) {
+ if (plane_has_modifier(i915, plane_caps, &intel_modifiers[i]))
+ *p++ = intel_modifiers[i].modifier;
+ }
+ *p++ = DRM_FORMAT_MOD_INVALID;
+
+ return list;
+}
+
+/**
+ * intel_fb_plane_supports_modifier: Determine if a modifier is supported by the given plane
+ * @plane: Plane to check the modifier support for
+ * @modifier: The modifier to check the support for
+ *
+ * Returns:
+ * %true if the @modifier is supported on @plane.
+ */
+bool intel_fb_plane_supports_modifier(struct intel_plane *plane, u64 modifier)
+{
+ int i;
+
+ for (i = 0; i < plane->base.modifier_count; i++)
+ if (plane->base.modifiers[i] == modifier)
+ return true;
+
+ return false;
+}
+
bool is_ccs_plane(const struct drm_framebuffer *fb, int plane)
{
if (!is_ccs_modifier(fb->modifier))