There exists a property IN_FORMATS which exposes the plane supported
modifiers/formats to the user. In some platforms when asynchronous flip
are used all of modifiers/formats mentioned in IN_FORMATS are not
supported. This patch adds a new plane property IN_FORMATS_ASYNC to
expose the async flip supported modifiers/formats so that user can use
this information ahead and do flip with unsupported
formats/modifiers. This will save flip failures.
Add a new function pointer similar to format_mod_supported specifically
for asynchronous flip.

v2: Remove async variable from drm_plane (Ville)
v3: Add new function pointer for async (Ville)
v5: Typo corrected in commit message & some correction in the kernel
documentation. (Chaitanya)
v7: Place IN_FORMATS_ASYNC next to IN_FORMATS (Ville)
v8: replace uint32_t with u32 and uint64_t with u64 (Chaitanya)

Signed-off-by: Arun R Murthy <arun.r.mur...@intel.com>
Tested-by: Naveen Kumar <naveen1.ku...@intel.com>
---
 drivers/gpu/drm/drm_mode_config.c |  7 +++++++
 drivers/gpu/drm/drm_plane.c       | 12 ++++++++++--
 include/drm/drm_mode_config.h     |  6 ++++++
 include/drm/drm_plane.h           | 17 +++++++++++++++++
 4 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_mode_config.c 
b/drivers/gpu/drm/drm_mode_config.c
index 
8642a2fb25a90116dab975aa0ab6b51deafb4b96..b4239fd04e9da4d4b5cfccdef1d3dde9556f322d
 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -381,6 +381,13 @@ static int drm_mode_create_standard_properties(struct 
drm_device *dev)
                return -ENOMEM;
        dev->mode_config.modifiers_property = prop;
 
+       prop = drm_property_create(dev,
+                                  DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
+                                  "IN_FORMATS_ASYNC", 0);
+       if (!prop)
+               return -ENOMEM;
+       dev->mode_config.async_modifiers_property = prop;
+
        prop = drm_property_create(dev,
                                   DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
                                   "SIZE_HINTS", 0);
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 
a28b22fdd7a41aca82d097d42237851da9a0a79b..110838c3e5920835e0875e57e6e479bcab7c8733
 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -141,6 +141,14 @@
  *     various bugs in this area with inconsistencies between the capability
  *     flag and per-plane properties.
  *
+ * IN_FORMATS_ASYNC:
+ *     Blob property which contains the set of buffer format and modifier
+ *     pairs supported by this plane for asynchronous flips. The blob is a 
struct
+ *     drm_format_modifier_blob. Userspace cannot change this property. This 
is an
+ *     optional property and if not present then user should expect a failure 
in
+ *     atomic ioctl when the modifier/format is not supported by that plane 
under
+ *     asynchronous flip.
+ *
  * SIZE_HINTS:
  *     Blob property which contains the set of recommended plane size
  *     which can used for simple "cursor like" use cases (eg. no scaling).
@@ -197,7 +205,7 @@ static int create_in_format_blob(struct drm_device *dev, 
struct drm_plane *plane
        formats_size = sizeof(__u32) * plane->format_count;
        if (WARN_ON(!formats_size)) {
                /* 0 formats are never expected */
-               return 0;
+               return ERR_PTR(0);
        }
 
        modifiers_size =
@@ -213,7 +221,7 @@ static int create_in_format_blob(struct drm_device *dev, 
struct drm_plane *plane
 
        blob = drm_property_create_blob(dev, blob_size, NULL);
        if (IS_ERR(blob))
-               return -1;
+               return ERR_PTR(-1);
 
        blob_data = blob->data;
        blob_data->version = FORMAT_BLOB_CURRENT;
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 
271765e2e9f2da62aaf0d258828ef4196e14822e..0c116d6dfd277262b1a4c0f097fce2d719f43844
 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -936,6 +936,12 @@ struct drm_mode_config {
         */
        struct drm_property *modifiers_property;
 
+       /**
+        * @async_modifiers_property: Plane property to list support 
modifier/format
+        * combination for asynchronous flips.
+        */
+       struct drm_property *async_modifiers_property;
+
        /**
         * @size_hints_property: Plane SIZE_HINTS property.
         */
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 
dd718c62ac31bf16606f3ee9f025a5b171cd1e67..01479dd94e76a8389a0c9e9d6744400aa2291064
 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -549,6 +549,23 @@ struct drm_plane_funcs {
         */
        bool (*format_mod_supported)(struct drm_plane *plane, uint32_t format,
                                     uint64_t modifier);
+       /**
+        * @format_mod_supported_async:
+        *
+        * This optional hook is used for the DRM to determine if for
+        * asynchronous flip the given format/modifier combination is valid for
+        * the plane. This allows the DRM to generate the correct format
+        * bitmask (which formats apply to which modifier), and to validate
+        * modifiers at atomic_check time.
+        *
+        * Returns:
+        *
+        * True if the given modifier is valid for that format on the plane.
+        * False otherwise.
+        */
+       bool (*format_mod_supported_async)(struct drm_plane *plane,
+                                          u32 format, u64 modifier);
+
 };
 
 /**

-- 
2.25.1

Reply via email to