To allow the userspace to test many hardware configuration, introduce a
new interface to configure the available formats per planes. VKMS supports
multiple formats, so the userspace can choose any combination.

The supported formats are configured by writing the fourcc code in
supported_formats:
 # enable AR24 format
  echo '+AR24' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
 # disable AR24 format
  echo '-AR24' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
 # enable all format supported by VKMS
  echo '+*' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
 # disable all formats
  echo '-*' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats

Signed-off-by: Louis Chauvet <[email protected]>
---
 Documentation/gpu/vkms.rst           |  7 ++-
 drivers/gpu/drm/vkms/vkms_configfs.c | 82 ++++++++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 979f8a545498..deb14e7c48ea 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -87,7 +87,7 @@ Start by creating one or more planes::
 
   sudo mkdir /config/vkms/my-vkms/planes/plane0
 
-Planes have 7 configurable attribute:
+Planes have 8 configurable attribute:
 
 - type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
   exposed by the "type" property of a plane)
@@ -106,6 +106,11 @@ Planes have 7 configurable attribute:
   those exposed by the COLOR_RANGE property of a plane)
 - default_color_range: Default color range presented to the userspace, same
   values as supported_color_range
+- supported_formats: List of supported formats for this plane. To add a new 
item in the
+  list, write it using a plus its fourcc code: +XR24
+  To remove a format, use a minus and its fourcc: -XR24
+  To add all formats use +*
+  To remove all formats, use -*
 
 Continue by creating one or more CRTCs::
 
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c 
b/drivers/gpu/drm/vkms/vkms_configfs.c
index 0b280c73b0cc..528f22fa2df1 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -599,6 +599,86 @@ static ssize_t plane_default_color_encoding_store(struct 
config_item *item,
        return count;
 }
 
+static ssize_t plane_supported_formats_show(struct config_item *item, char 
*page)
+{
+       struct vkms_configfs_plane *plane;
+
+       plane = plane_item_to_vkms_configfs_plane(item);
+
+       page[0] = '\0';
+
+       scoped_guard(mutex, &plane->dev->lock)
+       {
+               u32 *formats = 
vkms_config_plane_get_supported_formats(plane->config);
+
+               for (int i = 0;
+                    i < 
vkms_config_plane_get_supported_formats_count(plane->config);
+                    i++) {
+                       char tmp[6] = { 0 };
+                       const ssize_t ret = snprintf(tmp, ARRAY_SIZE(tmp), 
"%.*s\n",
+                                              (int)sizeof(*formats),
+                                              (char *)&formats[i]);
+                       if (ret < 0)
+                               return ret;
+                       /*
+                        * Limitation of ConfigFS attributes, an attribute 
can't be bigger
+                        * than PAGE_SIZE. This will crop the result if this 
plane support
+                        * more than ≈1000 formats.
+                        */
+                       if (ret + strlen(page) > PAGE_SIZE - 1)
+                               return -ENOMEM;
+                       strncat(page, tmp, ARRAY_SIZE(tmp));
+               }
+       }
+
+       return strlen(page);
+}
+
+static ssize_t plane_supported_formats_store(struct config_item *item,
+                                            const char *page, size_t count)
+{
+       struct vkms_configfs_plane *plane;
+
+       plane = plane_item_to_vkms_configfs_plane(item);
+       int ret = 0;
+       int ptr = 0;
+
+       scoped_guard(mutex, &plane->dev->lock)
+       {
+               while (ptr < count) {
+                       char tmp[4] = { ' ', ' ', ' ', ' ' };
+
+                       memcpy(tmp, &page[ptr + 1], min(sizeof(tmp), count - 
(ptr + 1)));
+                       if (page[ptr] == '+') {
+                               if (tmp[0] == '*') {
+                                       ret = 
vkms_config_plane_add_all_formats(plane->config);
+                                       if (ret)
+                                               return ret;
+                                       ptr += 1;
+                               } else {
+                                       ret = 
vkms_config_plane_add_format(plane->config,
+                                                                          
*(int *)tmp);
+                                       if (ret)
+                                               return ret;
+                                       ptr += 4;
+                               }
+                       } else if (page[ptr] == '-') {
+                               if (tmp[0] == '*') {
+                                       
vkms_config_plane_remove_all_formats(plane->config);
+                                       ptr += 1;
+                               } else {
+                                       
vkms_config_plane_remove_format(plane->config, *(int *)tmp);
+                                       ptr += 4;
+                               }
+                       }
+                       /* Skip anything that is not a + or a - */
+                       ptr += 1;
+               }
+       }
+
+       return count;
+}
+
 CONFIGFS_ATTR(plane_, type);
 CONFIGFS_ATTR(plane_, supported_rotations);
 CONFIGFS_ATTR(plane_, default_rotation);
@@ -606,6 +686,7 @@ CONFIGFS_ATTR(plane_, supported_color_range);
 CONFIGFS_ATTR(plane_, default_color_range);
 CONFIGFS_ATTR(plane_, supported_color_encoding);
 CONFIGFS_ATTR(plane_, default_color_encoding);
+CONFIGFS_ATTR(plane_, supported_formats);
 
 static struct configfs_attribute *plane_item_attrs[] = {
        &plane_attr_type,
@@ -615,6 +696,7 @@ static struct configfs_attribute *plane_item_attrs[] = {
        &plane_attr_default_color_range,
        &plane_attr_supported_color_encoding,
        &plane_attr_default_color_encoding,
+       &plane_attr_supported_formats,
        NULL,
 };
 

-- 
2.51.0

Reply via email to