* [PATCH v5 00/38] VKMS: Introduce multiple configFS attributes
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm, José Expósito
VKMS have a wide range of options. The aim of this series is to introduce
many configfs attribute so VKMS can be used to test a wide range of
configurations.
PATCH 1-5 are to expose human readable strings from drm core
PATCH 6 is a fix for rotation value
PATCH 7 is ABI documentation
PATCH 8 added some error checks in plane configuration
PATCH 9 cleanup in plane_release
PATCH 10-12 change the display in configfs to be more readable
PATCH 13,14 plane name
PATCH 15,16 plane rotation
PATCH 17,18 plane color encoding
PATCH 19,20 plane color range
PATCH 21,22 plane format
PATCH 23 properly use zpos
PATCH 24,25 plane zpos
PATCH 26,27 connector type
PATCH 28 preparation in connector initialization
PATCH 29,30 connector supported colorspace
PATCH 31,32 connector EDID
PATCH 33-35 dynamic connectors
PATCH 36-37 PATH property
PS: Each pair of config/configfs patch are independant. I could
technically create ≈10 different series, but there will be a lot of
(trivial) conflicts between them. I will be happy to reordoer, split and
partially apply this series to help the review process.
PS2: I am currently cleaning the IGT test series to validate all that,
it should come on Monday/Tuesday
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Changes in v5:
- Fixed missing property creation for PATH
- Use the folder name instead of a new attribute for plane
- Rebased on drm-misc-next
- Link to v4: https://patch.msgid.link/20260422-vkms-all-config-v4-0-dbb52e9aadc3@bootlin.com
Changes in v4:
- Introduced a way to change the PATH property
- Reordered drm-only patches to the front of the series.
- Fixed a bug when dynamic connector are allocated/freed (drmm instead of
kzalloc)
- Properly handle errors in vkms_connector_init
- Only parse formats one by one (no more complex algorithm, you will have
to write multiple times for multiple formats)
- Use sysfs_emit instead of sprintf
- Fix rotate property default value
- Link to v3: https://lore.kernel.org/r/20251222-vkms-all-config-v3-0-ba42dc3fb9ff@bootlin.com
Changes in v3:
- Added Documentation/ABI (Thomas Petazzoni)
- PATCH 2: Clarify return value
- PATCH 6,7: Avoid passing null to printf
- PATCH 7: Restrict plane name to A-Za-z0-9
- PATCH 12: Fix missing s
- PATCH 13: Add macro to avoid repetition, fix missing s, make code
consistent, remove wrong comment, properly check bit values
- PATCH 15: Fix missing s
- PATCH 16: Fix missing s, make code consistent, remove wrong comments,
properly check value and fix default_color_range value
- PATCH 17: Create function to reduce code complexity, fix missing s
- PATCH 18: Fix parsing, rename data, reject strings > 4 chars
- PATCH 20: Remove duplicated lines, fix test comments simplify conditions,
remove useless documentation,
- PATCH 21: {Min,Max}imal -> {Min,Max}imum, simplify commit log
- PATCH 25: Fix wrong comment
- PATCH 26: Rename type to colorspaces
- PATCH 27: Improve comment, avoid useless iterations
- PATCH 28: Fix typo in commit log
- PATCH 29: Fix typo in commit log
- PATCH 30: Remove useless include and move it to proper commit
- PATCH 32: Clarify documentation
- PATCH 33: Simplify code and use better variable names
- PATCH *: Fix EINVAL/EBUSY
- Link to v2: https://lore.kernel.org/r/20251029-vkms-all-config-v2-0-be20b9bf146e@bootlin.com
Changes in v2:
- PATCH 1: reorder includes (José)
- PATCH 2: use name property instead of folder name (José)
- PATCH 3: Fix default rotations (José)
- PATCH 3,5,7,12: Add tests and extract validation for planes (José)
- PATCH 3,5: Do not create color range/encoding properties if not set
- PATCH 5,6,7,8: Set plural form for vkms_config_plane fields (José)
- PATCH 4,6,8,13: Remove checking for default in supported (José)
- PATCH 9: Add break in vkms_config_plane_add_format (José)
- PATCH 12: fix zpos_enabled typo (José)
- PATCH 13: fix documentation (José)
- Add debug display (José)
- PATCH 20: use drmm_kzalloc instead of kzalloc (José)
- PATCH 22: simplify the code (José)
- Link to v1: https://lore.kernel.org/r/20251018-vkms-all-config-v1-0-a7760755d92d@bootlin.com
To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
To: Maxime Ripard <mripard@kernel.org>
To: Thomas Zimmermann <tzimmermann@suse.de>
To: David Airlie <airlied@gmail.com>
To: Simona Vetter <simona@ffwll.ch>
To: Louis Chauvet <louis.chauvet@bootlin.com>
To: Haneen Mohammed <hamohammed.sa@gmail.com>
To: Melissa Wen <melissa.srw@gmail.com>
To: Jonathan Corbet <corbet@lwn.net>
To: Shuah Khan <skhan@linuxfoundation.org>
To: Miguel Ojeda <ojeda@kernel.org>
To: Nathan Chancellor <nathan@kernel.org>
To: Nick Desaulniers <nick.desaulniers+lkml@gmail.com>
To: Bill Wendling <morbo@google.com>
To: Justin Stitt <justinstitt@google.com>
Cc: thomas.petazzoni@bootlin.com
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: llvm@lists.linux.dev
---
Louis Chauvet (38):
drm/drm_mode_config: Add helper to get plane type name
drm/blend: Get a rotation name from it's bitfield
drm/drm_color_mgmt: Expose drm_get_color_encoding_name
drm/drm_color_mgmt: Expose drm_get_color_range_name
drm/connector: Export drm_get_colorspace_name
drm/drm_atomic_state_helper: Properly load default value for rotation
Documentation: ABI: vkms: Add current VKMS ABI documentation
drm/vkms: Add error handling in plane config creation
drm/vkms: Simplify plane_release code
drm/vkms: Explicitly display plane type
drm/vkms: Use enabled/disabled instead of 1/0 for debug
drm/vkms: Explicitly display connector status
drm/vkms: Introduce config for plane name
drm/vkms: Use plane folder name as plane name
drm/vkms: Introduce config for plane rotation
drm/vkms: Use DRM_ROTATION_FMT macros for rotation display
drm/vkms: Introduce configfs for plane rotation
drm/vkms: Introduce config for plane color encoding
drm/vkms: Introduce configfs for plane color encoding
drm/vkms: Introduce config for plane color range
drm/vkms: Introduce configfs for plane color range
drm/vkms: Introduce config for plane format
drm/vkms: Introduce configfs for plane format
drm/vkms: Properly render plane using their zpos
drm/vkms: Introduce config for plane zpos property
drm/vkms: Introduce configfs for plane zpos property
drm/vkms: Introduce config for connector type
drm/vkms: Introduce configfs for connector type
drm/vkms: Rename vkms_connector_init to vkms_connector_init_static
drm/vkms: Introduce config for connector supported colorspace
drm/vkms: Introduce configfs for connector supported colorspace
drm/vkms: Introduce config for connector EDID
drm/vkms: Introduce configfs for connector EDID
drm/vkms: Store the enabled/disabled status for connector
drm/vkms: Allow to hot-add connectors
drm/vkms: Introduce configfs for dynamic connector creation
drm/vkms: Add connector parent configuration in vkms_config
drm/vkms: Add ConfigFS interface for connector parent and port_id
.clang-format | 2 +
Documentation/ABI/testing/configfs-vkms | 250 ++++
Documentation/gpu/vkms.rst | 44 +-
drivers/gpu/drm/drm_atomic_state_helper.c | 6 +
drivers/gpu/drm/drm_blend.c | 35 +-
drivers/gpu/drm/drm_color_mgmt.c | 4 +-
drivers/gpu/drm/drm_connector.c | 1 +
drivers/gpu/drm/drm_crtc_internal.h | 6 -
drivers/gpu/drm/drm_mode_config.c | 16 +
drivers/gpu/drm/vkms/tests/Makefile | 3 +-
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 513 ++++++++-
drivers/gpu/drm/vkms/tests/vkms_configfs_test.c | 102 ++
drivers/gpu/drm/vkms/vkms_config.c | 421 ++++++-
drivers/gpu/drm/vkms/vkms_config.h | 641 ++++++++++-
drivers/gpu/drm/vkms/vkms_configfs.c | 1402 +++++++++++++++++++----
drivers/gpu/drm/vkms/vkms_configfs.h | 4 +
drivers/gpu/drm/vkms/vkms_connector.c | 268 ++++-
drivers/gpu/drm/vkms/vkms_connector.h | 48 +-
drivers/gpu/drm/vkms/vkms_crtc.c | 10 +-
drivers/gpu/drm/vkms/vkms_output.c | 15 +-
drivers/gpu/drm/vkms/vkms_plane.c | 73 +-
include/drm/drm_blend.h | 17 +
include/drm/drm_color_mgmt.h | 3 +
include/drm/drm_mode_config.h | 3 +
24 files changed, 3581 insertions(+), 306 deletions(-)
---
base-commit: 6648301c5bb2ef23f0fb15bcb01d21ff66f36799
change-id: 20251017-vkms-all-config-bd0c2a01846f
Best regards,
--
Louis Chauvet <louis.chauvet@bootlin.com>
^ permalink raw reply
* [PATCH v5 01/38] drm/drm_mode_config: Add helper to get plane type name
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm, José Expósito
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
Create and export an helper to display plane type using the
property string. This could be used to display debug
information in VKMS.
Reviewed-by: José Expósito <jose.exposito@redhat.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_mode_config.c | 16 ++++++++++++++++
include/drm/drm_mode_config.h | 3 +++
2 files changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index f432f485a914..6f8a363ec6a1 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -414,6 +414,22 @@ static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
{ DRM_PLANE_TYPE_CURSOR, "Cursor" },
};
+/**
+ * drm_get_plane_type_name - return a string for plane name
+ * @type: plane type to compute name of
+ *
+ * Returns: The name of the plane type. "(unknown)" if type is not a known
+ * plane type.
+ */
+const char *drm_get_plane_type_name(enum drm_plane_type type)
+{
+ if (type >= 0 && type < ARRAY_SIZE(drm_plane_type_enum_list))
+ return drm_plane_type_enum_list[type].name;
+ else
+ return "(unknown)";
+}
+EXPORT_SYMBOL(drm_get_plane_type_name);
+
static int drm_mode_create_standard_properties(struct drm_device *dev)
{
struct drm_property *prop;
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index d8f5b7e9673e..20aed1ae2985 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -30,6 +30,7 @@
#include <linux/llist.h>
#include <drm/drm_modeset_lock.h>
+#include <drm/drm_plane.h>
struct drm_file;
struct drm_device;
@@ -1011,4 +1012,6 @@ int drm_mode_config_create_initial_state(struct drm_device *dev);
void drm_mode_config_reset(struct drm_device *dev);
void drm_mode_config_cleanup(struct drm_device *dev);
+const char *drm_get_plane_type_name(enum drm_plane_type type);
+
#endif
--
2.54.0
^ permalink raw reply related
* [PATCH v5 02/38] drm/blend: Get a rotation name from it's bitfield
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
Having the rotation/reflection name from its value can be useful for
debugging purpose. Extract the rotation property table and implement
drm_get_rotation_name.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_blend.c | 35 ++++++++++++++++++++++++++---------
include/drm/drm_blend.h | 17 +++++++++++++++++
2 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 2f0d1ba285be..eecdaf623c1e 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -256,6 +256,31 @@ int drm_plane_create_alpha_property(struct drm_plane *plane)
}
EXPORT_SYMBOL(drm_plane_create_alpha_property);
+static const struct drm_prop_enum_list rotation_props[] = {
+ { __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" },
+ { __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" },
+ { __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
+ { __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
+ { __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
+ { __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
+};
+
+/**
+ * drm_get_rotation_name - Return the name of a rotation
+ * @rotation: The rotation mask (DRM_MODE_ROTATE_* | DRM_MODE_REFLECT_*)
+ *
+ * Returns: the name of the rotation type (unknown) if rotation is not
+ * a known rotation/reflection
+ */
+const char *drm_get_rotation_name(unsigned int rotation)
+{
+ if (rotation < ARRAY_SIZE(rotation_props))
+ return rotation_props[rotation].name;
+
+ return "(unknown)";
+}
+EXPORT_SYMBOL(drm_get_rotation_name);
+
/**
* drm_plane_create_rotation_property - create a new rotation property
* @plane: drm plane
@@ -294,14 +319,6 @@ int drm_plane_create_rotation_property(struct drm_plane *plane,
unsigned int rotation,
unsigned int supported_rotations)
{
- static const struct drm_prop_enum_list props[] = {
- { __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" },
- { __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" },
- { __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
- { __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
- { __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
- { __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
- };
struct drm_property *prop;
WARN_ON((supported_rotations & DRM_MODE_ROTATE_MASK) == 0);
@@ -309,7 +326,7 @@ int drm_plane_create_rotation_property(struct drm_plane *plane,
WARN_ON(rotation & ~supported_rotations);
prop = drm_property_create_bitmask(plane->dev, 0, "rotation",
- props, ARRAY_SIZE(props),
+ rotation_props, ARRAY_SIZE(rotation_props),
supported_rotations);
if (!prop)
return -ENOMEM;
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
index bebbb77a8f21..33329170aafe 100644
--- a/include/drm/drm_blend.h
+++ b/include/drm/drm_blend.h
@@ -43,6 +43,23 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation)
#define DRM_BLEND_ALPHA_OPAQUE 0xffff
+const char *drm_get_rotation_name(unsigned int rotation);
+
+#define DRM_ROTATION_FMT "%s%s%s%s%s%s%s%s%s%s%s%s"
+#define DRM_ROTATION_FMT_ARGS(rot) \
+ (rot) & DRM_MODE_ROTATE_0 ? drm_get_rotation_name(0) : "", \
+ (rot) & DRM_MODE_ROTATE_0 ? " " : "", \
+ (rot) & DRM_MODE_ROTATE_90 ? drm_get_rotation_name(1) : "", \
+ (rot) & DRM_MODE_ROTATE_90 ? " " : "", \
+ (rot) & DRM_MODE_ROTATE_180 ? drm_get_rotation_name(2) : "", \
+ (rot) & DRM_MODE_ROTATE_180 ? " " : "", \
+ (rot) & DRM_MODE_ROTATE_270 ? drm_get_rotation_name(3) : "", \
+ (rot) & DRM_MODE_ROTATE_270 ? " " : "", \
+ (rot) & DRM_MODE_REFLECT_X ? drm_get_rotation_name(4) : "", \
+ (rot) & DRM_MODE_REFLECT_X ? " " : "", \
+ (rot) & DRM_MODE_REFLECT_Y ? drm_get_rotation_name(5) : "", \
+ (rot) & DRM_MODE_REFLECT_Y ? " " : ""
+
int drm_plane_create_alpha_property(struct drm_plane *plane);
int drm_plane_create_rotation_property(struct drm_plane *plane,
unsigned int rotation,
--
2.54.0
^ permalink raw reply related
* [PATCH v5 03/38] drm/drm_color_mgmt: Expose drm_get_color_encoding_name
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
drm_get_color_encoding_name can be useful to display debug information
outside drm core. Export it so it could be used for VKMS
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_color_mgmt.c | 2 +-
drivers/gpu/drm/drm_crtc_internal.h | 2 --
include/drm/drm_color_mgmt.h | 2 ++
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 3bcf82cf61a7..b5635862dc91 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -496,7 +496,7 @@ const char *drm_get_color_encoding_name(enum drm_color_encoding encoding)
return color_encoding_name[encoding];
}
-EXPORT_SYMBOL_IF_KUNIT(drm_get_color_encoding_name);
+EXPORT_SYMBOL(drm_get_color_encoding_name);
/**
* drm_get_color_range_name - return a string for color range
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 83146ffef00c..bcd23eb0e531 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -38,7 +38,6 @@
#include <linux/err.h>
#include <linux/types.h>
-enum drm_color_encoding;
enum drm_color_range;
enum drm_connector_force;
enum drm_mode_status;
@@ -121,7 +120,6 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
/* drm_color_mgmt.c */
-const char *drm_get_color_encoding_name(enum drm_color_encoding encoding);
const char *drm_get_color_range_name(enum drm_color_range range);
/* IOCTLs */
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index 5140691f476a..133ca77d91c7 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -113,6 +113,8 @@ enum drm_color_range {
DRM_COLOR_RANGE_MAX,
};
+const char *drm_get_color_encoding_name(enum drm_color_encoding encoding);
+
int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
--
2.54.0
^ permalink raw reply related
* [PATCH v5 04/38] drm/drm_color_mgmt: Expose drm_get_color_range_name
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
drm_get_color_range_name can be useful to print debugging information.
Export it so it could be used from VKMS.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_color_mgmt.c | 2 +-
drivers/gpu/drm/drm_crtc_internal.h | 4 ----
include/drm/drm_color_mgmt.h | 1 +
3 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index b5635862dc91..8ec87d1c7433 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -512,7 +512,7 @@ const char *drm_get_color_range_name(enum drm_color_range range)
return color_range_name[range];
}
-EXPORT_SYMBOL_IF_KUNIT(drm_get_color_range_name);
+EXPORT_SYMBOL(drm_get_color_range_name);
/**
* drm_plane_create_color_properties - color encoding related plane properties
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index bcd23eb0e531..4bf6bc0bcb5a 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -38,7 +38,6 @@
#include <linux/err.h>
#include <linux/types.h>
-enum drm_color_range;
enum drm_connector_force;
enum drm_mode_status;
@@ -119,9 +118,6 @@ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
-/* drm_color_mgmt.c */
-const char *drm_get_color_range_name(enum drm_color_range range);
-
/* IOCTLs */
int drm_mode_gamma_get_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index 133ca77d91c7..e91f494e5a63 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -114,6 +114,7 @@ enum drm_color_range {
};
const char *drm_get_color_encoding_name(enum drm_color_encoding encoding);
+const char *drm_get_color_range_name(enum drm_color_range range);
int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
--
2.54.0
^ permalink raw reply related
* [PATCH v5 05/38] drm/connector: Export drm_get_colorspace_name
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
Export drm_get_colorspace_name so it could be used by VKMS
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_connector.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index cbb067d02cb9..4b2c7c09ba69 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1386,6 +1386,7 @@ const char *drm_get_colorspace_name(enum drm_colorspace colorspace)
else
return "(null)";
}
+EXPORT_SYMBOL(drm_get_colorspace_name);
static const u32 hdmi_colorspaces =
BIT(DRM_MODE_COLORIMETRY_SMPTE_170M_YCC) |
--
2.54.0
^ permalink raw reply related
* [PATCH v5 06/38] drm/drm_atomic_state_helper: Properly load default value for rotation
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
Currently, the default rotation is always DRM_MODE_ROTATE_0 for all planes.
Some planes may have a rotation property, and the property may specify a
different default value and supported values.
This is not an issue for "fixed" configurations, but with the introduction
of VKMS configuration, some plane may only support 90° and 180°
rotations, so the reset state of the plane was wrong (forced to 0°).
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index d90d1d7c9cf9..7fe612c4da83 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -32,6 +32,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_framebuffer.h>
+#include <drm/drm_mode_object.h>
#include <drm/drm_plane.h>
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>
@@ -276,6 +277,11 @@ void __drm_atomic_helper_plane_state_init(struct drm_plane_state *plane_state,
plane_state->plane = plane;
plane_state->rotation = DRM_MODE_ROTATE_0;
+ if (plane->rotation_property &&
+ !drm_object_property_get_default_value(&plane->base,
+ plane->rotation_property,
+ &val))
+ plane_state->rotation = val;
plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
--
2.54.0
^ permalink raw reply related
* [PATCH v5 07/38] Documentation: ABI: vkms: Add current VKMS ABI documentation
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
VKMS recently introduced a ConfigFS API to configure new devices.
Add proper ABI documentation.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/ABI/testing/configfs-vkms | 118 ++++++++++++++++++++++++++++++++
1 file changed, 118 insertions(+)
diff --git a/Documentation/ABI/testing/configfs-vkms b/Documentation/ABI/testing/configfs-vkms
new file mode 100644
index 000000000000..a1a3e186e50a
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-vkms
@@ -0,0 +1,118 @@
+What: /sys/kernel/config/vkms/
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains sub-groups corresponding to created
+ VKMS devices.
+
+What: /sys/kernel/config/vkms/<device>
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains sub-groups corresponding to the VKMS
+ device <device>.
+
+What: /sys/kernel/config/vkms/<device>/connectors
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains sub-groups corresponding to the
+ connectors of the VKMS device <device>.
+
+What: /sys/kernel/config/vkms/<device>/connectors/<connector>
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains attributes corresponding to the
+ connector <connector> of the VKMS device <device>.
+
+What: /sys/kernel/config/vkms/<device>/connectors/<connector>/status
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ Connection status of the connector. Possible values:
+ 1 - connected, 2 - disconnected, 3 - unknown.
+
+What: /sys/kernel/config/vkms/<device>/connectors/<connector>/possible_encoders
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains symbolic links to possible encoders
+ for this connector.
+
+What: /sys/kernel/config/vkms/<device>/crtcs
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains sub-groups corresponding to the
+ CRTCs of the VKMS device <device>.
+
+What: /sys/kernel/config/vkms/<device>/crtcs/<crtc>
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains attributes corresponding to the
+ CRTC <crtc> of the VKMS device <device>.
+
+What: /sys/kernel/config/vkms/<device>/crtcs/<crtc>/writeback
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ Enable or disable writeback connector support for this
+ CRTC. Value: 1 - enabled, 0 - disabled.
+
+What: /sys/kernel/config/vkms/<device>/encoders
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains sub-groups corresponding to the
+ encoders of the VKMS device <device>.
+
+What: /sys/kernel/config/vkms/<device>/encoders/<encoder>
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains attributes corresponding to the
+ encoder <encoder> of the VKMS device <device>.
+
+What: /sys/kernel/config/vkms/<device>/encoders/<encoder>/possible_crtcs
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains symbolic links to possible CRTCs
+ for this encoder.
+
+What: /sys/kernel/config/vkms/<device>/planes
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains sub-groups corresponding to the
+ planes of the VKMS device <device>.
+
+What: /sys/kernel/config/vkms/<device>/planes/<plane>
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains attributes corresponding to the
+ plane <plane> of the VKMS device <device>.
+
+What: /sys/kernel/config/vkms/<device>/planes/<plane>/type
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ Plane type. Possible values: 0 - overlay, 1 - primary,
+ 2 - cursor.
+
+What: /sys/kernel/config/vkms/<device>/planes/<plane>/possible_crtcs
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ This group contains symbolic links to possible CRTCs
+ for this plane.
+
+What: /sys/kernel/config/vkms/<device>/enabled
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ Enable or disable the VKMS device. Value: 1 - enabled,
+ 0 - disabled.
--
2.54.0
^ permalink raw reply related
* [PATCH v5 08/38] drm/vkms: Add error handling in plane config creation
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
For future patches, it is useful to properly handle errors in
vkms_config_create_plane.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 5a654d6dead8..1fd2ed1167c5 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -384,13 +384,16 @@ void vkms_config_register_debugfs(struct vkms_device *vkms_device)
ARRAY_SIZE(vkms_config_debugfs_list));
}
-struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config)
+struct vkms_config_plane __must_check *vkms_config_create_plane(struct vkms_config *config)
{
struct vkms_config_plane *plane_cfg;
+ int ret;
plane_cfg = kzalloc_obj(*plane_cfg);
- if (!plane_cfg)
- return ERR_PTR(-ENOMEM);
+ if (!plane_cfg) {
+ ret = -ENOMEM;
+ goto fail;
+ }
plane_cfg->config = config;
plane_cfg->default_pipeline = false;
@@ -400,6 +403,9 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config)
list_add_tail(&plane_cfg->link, &config->planes);
return plane_cfg;
+
+fail:
+ return ERR_PTR(ret);
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_plane);
--
2.54.0
^ permalink raw reply related
* [PATCH v5 09/38] drm/vkms: Simplify plane_release code
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
plane_release code used multiple intermediate variable, remove those in
favor of direct access.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_configfs.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index 7551b8c7766d..97f87a53d202 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -333,13 +333,9 @@ static struct configfs_attribute *plane_item_attrs[] = {
static void plane_release(struct config_item *item)
{
- struct vkms_configfs_plane *plane;
- struct mutex *lock;
-
- plane = plane_item_to_vkms_configfs_plane(item);
- lock = &plane->dev->lock;
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
- scoped_guard(mutex, lock) {
+ scoped_guard(mutex, &plane->dev->lock) {
vkms_config_destroy_plane(plane->config);
kfree(plane);
}
--
2.54.0
^ permalink raw reply related
* [PATCH v5 10/38] drm/vkms: Explicitly display plane type
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm, José Expósito
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
Debug information are mainly read by human, so use full name instead
of values.
Reviewed-by: José Expósito <jose.exposito@redhat.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 1fd2ed1167c5..469c57c6d1e8 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -352,8 +352,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
vkms_config_for_each_plane(vkmsdev->config, plane_cfg) {
seq_puts(m, "plane:\n");
- seq_printf(m, "\ttype=%d\n",
- vkms_config_plane_get_type(plane_cfg));
+ seq_printf(m, "\ttype=%s\n",
+ drm_get_plane_type_name(vkms_config_plane_get_type(plane_cfg)));
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
--
2.54.0
^ permalink raw reply related
* [PATCH v5 11/38] drm/vkms: Use enabled/disabled instead of 1/0 for debug
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm, José Expósito
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
Debug information are mainly read by human, so display human
readable values.
Reviewed-by: José Expósito <jose.exposito@redhat.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 469c57c6d1e8..4c6f3ead51d7 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
#include <linux/slab.h>
+#include <linux/string_choices.h>
#include <drm/drm_print.h>
#include <drm/drm_debugfs.h>
@@ -358,8 +359,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
seq_puts(m, "crtc:\n");
- seq_printf(m, "\twriteback=%d\n",
- vkms_config_crtc_get_writeback(crtc_cfg));
+ seq_printf(m, "\twriteback=%s\n",
+ str_enabled_disabled(vkms_config_crtc_get_writeback(crtc_cfg)));
}
vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg)
--
2.54.0
^ permalink raw reply related
* [PATCH v5 12/38] drm/vkms: Explicitly display connector status
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm, José Expósito
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
Debug information are mainly read by human, so use full name instead
of raw values for connector status.
Reviewed-by: José Expósito <jose.exposito@redhat.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 4c6f3ead51d7..9071d6864d52 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -3,6 +3,7 @@
#include <linux/slab.h>
#include <linux/string_choices.h>
+#include <drm/drm_connector.h>
#include <drm/drm_print.h>
#include <drm/drm_debugfs.h>
#include <kunit/visibility.h>
@@ -368,8 +369,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
vkms_config_for_each_connector(vkmsdev->config, connector_cfg) {
seq_puts(m, "connector:\n");
- seq_printf(m, "\tstatus=%d\n",
- vkms_config_connector_get_status(connector_cfg));
+ seq_printf(m, "\tstatus=%s\n",
+ drm_get_connector_status_name(vkms_config_connector_get_status(connector_cfg)));
}
return 0;
--
2.54.0
^ permalink raw reply related
* [PATCH v5 13/38] drm/vkms: Introduce config for plane name
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
As planes can have a name in DRM, prepare VKMS to configure it using
ConfigFS.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 11 +++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 34 ++++++++++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_plane.c | 3 ++-
3 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 9071d6864d52..54994f3c8e14 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -356,6 +356,9 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_puts(m, "plane:\n");
seq_printf(m, "\ttype=%s\n",
drm_get_plane_type_name(vkms_config_plane_get_type(plane_cfg)));
+ seq_printf(m, "\tname=%s\n",
+ vkms_config_plane_get_name(plane_cfg) ?
+ vkms_config_plane_get_name(plane_cfg) : "(null)");
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
@@ -400,12 +403,19 @@ struct vkms_config_plane __must_check *vkms_config_create_plane(struct vkms_conf
plane_cfg->config = config;
plane_cfg->default_pipeline = false;
vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY);
+
+ ret = vkms_config_plane_set_name(plane_cfg, NULL, 0);
+ if (ret)
+ goto cleanup_plane_cfg;
+
xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC);
list_add_tail(&plane_cfg->link, &config->planes);
return plane_cfg;
+cleanup_plane_cfg:
+ kfree(plane_cfg);
fail:
return ERR_PTR(ret);
}
@@ -415,6 +425,7 @@ void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg)
{
xa_destroy(&plane_cfg->possible_crtcs);
list_del(&plane_cfg->link);
+ kfree(plane_cfg->name);
kfree(plane_cfg);
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_plane);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 8f7f286a4bdd..e34f4cbfe8b8 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -3,6 +3,7 @@
#ifndef _VKMS_CONFIG_H_
#define _VKMS_CONFIG_H_
+#include <linux/string.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/xarray.h>
@@ -35,6 +36,7 @@ struct vkms_config {
*
* @link: Link to the others planes in vkms_config
* @config: The vkms_config this plane belongs to
+ * @name: Name of the plane
* @type: Type of the plane. The creator of configuration needs to ensures that
* at least one primary plane is present.
* @possible_crtcs: Array of CRTCs that can be used with this plane
@@ -47,6 +49,7 @@ struct vkms_config_plane {
struct list_head link;
struct vkms_config *config;
+ const char *name;
enum drm_plane_type type;
struct xarray possible_crtcs;
bool default_pipeline;
@@ -314,6 +317,37 @@ vkms_config_plane_set_default_pipeline(struct vkms_config_plane *plane_cfg,
plane_cfg->default_pipeline = default_pipeline;
}
+/**
+ * vkms_config_plane_set_name() - Set the plane name
+ * @plane_cfg: Plane to set the name to
+ * @name: New plane name. The name is copied.
+ *
+ * Returns: -ENOMEM if the memory allocation failed, 0 in case of success
+ */
+static inline int __must_check
+vkms_config_plane_set_name(struct vkms_config_plane *plane_cfg,
+ const char *name, size_t name_len)
+{
+ kfree(plane_cfg->name);
+
+ plane_cfg->name = kmemdup_nul(name, name_len, GFP_KERNEL);
+
+ if (name && !plane_cfg->name)
+ return -ENOMEM;
+
+ return 0;
+}
+
+/**
+ * vkms_config_plane_get_name - Get the plane name
+ * @plane_cfg: Plane to get the name from
+ */
+static inline const char *
+vkms_config_plane_get_name(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->name;
+}
+
/**
* vkms_config_plane_attach_crtc - Attach a plane to a CRTC
* @plane_cfg: Plane to attach
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 68cb2a3335e6..f35120203124 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -11,6 +11,7 @@
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_print.h>
+#include "vkms_config.h"
#include "vkms_drv.h"
#include "vkms_formats.h"
@@ -228,7 +229,7 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
&vkms_plane_funcs,
vkms_formats, ARRAY_SIZE(vkms_formats),
NULL, vkms_config_plane_get_type(plane_cfg),
- NULL);
+ vkms_config_plane_get_name(plane_cfg));
if (IS_ERR(plane))
return plane;
--
2.54.0
^ permalink raw reply related
* [PATCH v5 14/38] drm/vkms: Use plane folder name as plane name
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
The plane name is now directly derived from the configfs folder
name. When a plane directory is created under
/config/vkms/<device>/planes/, the folder name is used as the
plane name via vkms_config_plane_set_name.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_configfs.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index 97f87a53d202..0744ac40814d 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -377,6 +377,12 @@ static struct config_group *make_plane_group(struct config_group *group,
return ERR_PTR(ret);
}
+ ret = vkms_config_plane_set_name(plane->config, name, strlen(name));
+ if (ret) {
+ kfree(plane);
+ return ERR_PTR(ret);
+ }
+
config_group_init_type_name(&plane->group, name, &plane_item_type);
config_group_init_type_name(&plane->possible_crtcs_group,
--
2.54.0
^ permalink raw reply related
* [PATCH v5 15/38] drm/vkms: Introduce config for plane rotation
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
VKMS driver supports all the rotation on planes, but for testing it can be
useful to only advertise few of them. This new configuration interface
will allow configuring the rotation per planes.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 46 +++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.c | 38 +++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 59 +++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_plane.c | 5 ++-
4 files changed, 146 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index 1e4ea1863420..c33fe737678f 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
+#include <drm/drm_mode.h>
#include <kunit/test.h>
#include "../vkms_config.h"
@@ -185,6 +186,12 @@ static void vkms_config_test_default_config(struct kunit *test)
n_possible_crtcs++;
}
KUNIT_EXPECT_EQ(test, n_possible_crtcs, 1);
+ KUNIT_EXPECT_EQ(test,
+ vkms_config_plane_get_supported_rotations(plane_cfg),
+ DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
+ KUNIT_EXPECT_EQ(test,
+ vkms_config_plane_get_default_rotation(plane_cfg),
+ DRM_MODE_ROTATE_0);
}
/* Encoders */
@@ -481,6 +488,44 @@ static void vkms_config_test_valid_plane_type(struct kunit *test)
vkms_config_destroy(config);
}
+static void vkms_config_test_valid_plane_rotations(struct kunit *test)
+{
+ struct vkms_config *config;
+ struct vkms_config_plane *plane_cfg;
+
+ config = vkms_config_default_create(false, false, false, false);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config);
+
+ plane_cfg = get_first_plane(config);
+
+ /* Valid, no rotation, no reflection */
+ vkms_config_plane_set_supported_rotations(plane_cfg, DRM_MODE_ROTATE_0);
+ vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_ROTATE_0);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_rotation(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Invalid, default rotation is not supported */
+ vkms_config_plane_set_supported_rotations(plane_cfg, DRM_MODE_ROTATE_0);
+ vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_ROTATE_90);
+ KUNIT_EXPECT_FALSE(test, vkms_config_valid_plane_rotation(config, plane_cfg));
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Invalid, supported rotations must contains at least one rotation */
+ vkms_config_plane_set_supported_rotations(plane_cfg, DRM_MODE_REFLECT_MASK);
+ vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_0);
+ KUNIT_EXPECT_FALSE(test, vkms_config_valid_plane_rotation(config, plane_cfg));
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Invalid, default rotation must contains at least one rotation */
+ vkms_config_plane_set_supported_rotations(plane_cfg,
+ DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0);
+ vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_REFLECT_X);
+ KUNIT_EXPECT_FALSE(test, vkms_config_valid_plane_rotation(config, plane_cfg));
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ vkms_config_destroy(config);
+}
+
static void vkms_config_test_valid_plane_possible_crtcs(struct kunit *test)
{
struct vkms_config *config;
@@ -1003,6 +1048,7 @@ static struct kunit_case vkms_config_test_cases[] = {
KUNIT_CASE(vkms_config_test_get_connectors),
KUNIT_CASE(vkms_config_test_invalid_plane_number),
KUNIT_CASE(vkms_config_test_valid_plane_type),
+ KUNIT_CASE(vkms_config_test_valid_plane_rotations),
KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs),
KUNIT_CASE(vkms_config_test_invalid_crtc_number),
KUNIT_CASE(vkms_config_test_invalid_encoder_number),
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 54994f3c8e14..5c86eb24fedf 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -4,6 +4,7 @@
#include <linux/string_choices.h>
#include <drm/drm_connector.h>
+#include <drm/drm_mode.h>
#include <drm/drm_print.h>
#include <drm/drm_debugfs.h>
#include <kunit/visibility.h>
@@ -150,6 +151,33 @@ static bool valid_plane_number(const struct vkms_config *config)
return true;
}
+VISIBLE_IF_KUNIT
+bool vkms_config_valid_plane_rotation(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg)
+{
+ struct drm_device *dev = config->dev ? &config->dev->drm : NULL;
+
+ if ((vkms_config_plane_get_default_rotation(plane_cfg) &
+ vkms_config_plane_get_supported_rotations(plane_cfg)) !=
+ vkms_config_plane_get_default_rotation(plane_cfg)) {
+ drm_info(dev, "Configured default rotation is not supported by the plane\n");
+ return false;
+ }
+
+ if ((vkms_config_plane_get_default_rotation(plane_cfg) & DRM_MODE_ROTATE_MASK) == 0) {
+ drm_info(dev, "Configured default rotation must contains at least one possible rotation\n");
+ return false;
+ }
+
+ if ((vkms_config_plane_get_supported_rotations(plane_cfg) & DRM_MODE_ROTATE_MASK) == 0) {
+ drm_info(dev, "Configured supported rotations must contains at least one possible rotation\n");
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_rotation);
+
static bool valid_planes_for_crtc(const struct vkms_config *config,
struct vkms_config_crtc *crtc_cfg)
{
@@ -307,6 +335,12 @@ static bool valid_connector_possible_encoders(const struct vkms_config *config)
bool vkms_config_is_valid(const struct vkms_config *config)
{
struct vkms_config_crtc *crtc_cfg;
+ struct vkms_config_plane *plane_cfg;
+
+ vkms_config_for_each_plane(config, plane_cfg) {
+ if (!vkms_config_valid_plane_rotation(config, plane_cfg))
+ return false;
+ }
if (!valid_plane_number(config))
return false;
@@ -408,6 +442,10 @@ struct vkms_config_plane __must_check *vkms_config_create_plane(struct vkms_conf
if (ret)
goto cleanup_plane_cfg;
+ vkms_config_plane_set_supported_rotations(plane_cfg,
+ DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
+ vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_ROTATE_0);
+
xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC);
list_add_tail(&plane_cfg->link, &config->planes);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index e34f4cbfe8b8..b5884ac0f42f 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -40,6 +40,8 @@ struct vkms_config {
* @type: Type of the plane. The creator of configuration needs to ensures that
* at least one primary plane is present.
* @possible_crtcs: Array of CRTCs that can be used with this plane
+ * @default_rotation: Default rotation that should be used by this plane
+ * @supported_rotation: Rotation that this plane will support
* @plane: Internal usage. This pointer should never be considered as valid.
* It can be used to store a temporary reference to a VKMS plane during
* device creation. This pointer is not managed by the configuration and
@@ -51,6 +53,8 @@ struct vkms_config_plane {
const char *name;
enum drm_plane_type type;
+ unsigned int default_rotation;
+ unsigned int supported_rotations;
struct xarray possible_crtcs;
bool default_pipeline;
@@ -317,6 +321,61 @@ vkms_config_plane_set_default_pipeline(struct vkms_config_plane *plane_cfg,
plane_cfg->default_pipeline = default_pipeline;
}
+/**
+ * vkms_config_plane_get_default_rotation() - Get the default rotation for a plane
+ * @plane_cfg: Plane to get the default rotation from
+ *
+ * Returns:
+ * The default rotation for the plane.
+ */
+static inline unsigned int
+vkms_config_plane_get_default_rotation(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->default_rotation;
+}
+
+/**
+ * vkms_config_plane_set_default_rotation() - Set the default rotation for a plane
+ * @plane_cfg: Plane to set the default rotation to
+ * @default_rotation: New default rotation for the plane
+ */
+static inline void
+vkms_config_plane_set_default_rotation(struct vkms_config_plane *plane_cfg,
+ unsigned int default_rotation)
+{
+ plane_cfg->default_rotation = default_rotation;
+}
+
+/**
+ * vkms_config_plane_get_supported_rotations() - Get the supported rotations for a plane
+ * @plane_cfg: Plane to get the supported rotations from
+ *
+ * Returns:
+ * The supported rotations for the plane.
+ */
+static inline unsigned int
+vkms_config_plane_get_supported_rotations(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->supported_rotations;
+}
+
+/**
+ * vkms_config_plane_set_supported_rotations() - Set the supported rotations for a plane
+ * @plane_cfg: Plane to set the supported rotations to
+ * @supported_rotations: New supported rotations for the plane
+ */
+static inline void
+vkms_config_plane_set_supported_rotations(struct vkms_config_plane *plane_cfg,
+ unsigned int supported_rotations)
+{
+ plane_cfg->supported_rotations = supported_rotations;
+}
+
+#if IS_ENABLED(CONFIG_KUNIT)
+bool vkms_config_valid_plane_rotation(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg);
+#endif
+
/**
* vkms_config_plane_set_name() - Set the plane name
* @plane_cfg: Plane to set the name to
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index f35120203124..8a64ea41734b 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -235,8 +235,9 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
drm_plane_helper_add(&plane->base, &vkms_plane_helper_funcs);
- drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0,
- DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
+ drm_plane_create_rotation_property(&plane->base,
+ vkms_config_plane_get_default_rotation(plane_cfg),
+ vkms_config_plane_get_supported_rotations(plane_cfg));
drm_plane_create_color_properties(&plane->base,
BIT(DRM_COLOR_YCBCR_BT601) |
--
2.54.0
^ permalink raw reply related
* [PATCH v5 16/38] drm/vkms: Use DRM_ROTATION_FMT macros for rotation display
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
Replace show_bitfield calls for rotation/reflection with the new
DRM_ROTATION_FMT / DRM_ROTATION_FMT_ARGS macros for cleaner code.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 5c86eb24fedf..ca3ee3aa2c41 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -3,6 +3,7 @@
#include <linux/slab.h>
#include <linux/string_choices.h>
+#include <drm/drm_blend.h>
#include <drm/drm_connector.h>
#include <drm/drm_mode.h>
#include <drm/drm_print.h>
@@ -393,6 +394,10 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_printf(m, "\tname=%s\n",
vkms_config_plane_get_name(plane_cfg) ?
vkms_config_plane_get_name(plane_cfg) : "(null)");
+ seq_printf(m, "\tsupported rotations=" DRM_ROTATION_FMT "\n",
+ DRM_ROTATION_FMT_ARGS(vkms_config_plane_get_supported_rotations(plane_cfg)));
+ seq_printf(m, "\tdefault rotation=" DRM_ROTATION_FMT "\n",
+ DRM_ROTATION_FMT_ARGS(vkms_config_plane_get_default_rotation(plane_cfg)));
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
--
2.54.0
^ permalink raw reply related
* [PATCH v5 17/38] drm/vkms: Introduce configfs for plane rotation
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
To allows the userspace to test many hardware configurations, introduce a
new interface to configure the available rotation per planes. VKMS
supports any rotation and reflection, so the userspace can choose any
combination.
The supported rotations are configured by writing a rotation bitmask to
the file `supported_rotations` and the default rotation is chosen by
writing a rotation bitmask to `default_rotation`.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/ABI/testing/configfs-vkms | 15 ++++++
Documentation/gpu/vkms.rst | 7 ++-
drivers/gpu/drm/vkms/vkms_configfs.c | 82 +++++++++++++++++++++++++++++++++
3 files changed, 103 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/configfs-vkms b/Documentation/ABI/testing/configfs-vkms
index a1a3e186e50a..7820da8505ef 100644
--- a/Documentation/ABI/testing/configfs-vkms
+++ b/Documentation/ABI/testing/configfs-vkms
@@ -103,6 +103,21 @@ Description:
Plane type. Possible values: 0 - overlay, 1 - primary,
2 - cursor.
+What: /sys/kernel/config/vkms/<device>/planes/<plane>/supported_rotations
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ Available rotations for the plane, as a bitmask:
+ 0x01 - no rotation, 0x02 - rotate 90°, 0x04 - rotate 180°,
+ 0x08 - rotate 270°, 0x10 - reflect x, 0x20 - reflect y.
+
+What: /sys/kernel/config/vkms/<device>/planes/<plane>/default_rotation
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ Default rotation presented to userspace, same values as
+ possible_rotations.
+
What: /sys/kernel/config/vkms/<device>/planes/<plane>/possible_crtcs
Date: Nov 2025
Contact: dri-devel@lists.freedesktop.org
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 1e79e62a6bc4..610305483716 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -87,10 +87,15 @@ Start by creating one or more planes::
sudo mkdir /config/vkms/my-vkms/planes/plane0
-Planes have 1 configurable attribute:
+Planes have 3 configurable attributes:
- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
exposed by the "type" property of a plane)
+- supported_rotations: Available rotation for a plane, as a bitmask: 0x01 no rotation,
+ 0x02 rotate 90°, 0x04 rotate 180°, 0x08 rotate 270°, 0x10 reflect x, 0x20 reflect y
+ (same values as those exposed by the "rotation" property of a plane)
+- default_rotation: Default rotation presented to the userspace, same values as
+ supported_rotations.
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 0744ac40814d..47b3a4aeee8d 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -324,10 +324,92 @@ static ssize_t plane_type_store(struct config_item *item, const char *page,
return (ssize_t)count;
}
+static ssize_t plane_supported_rotations_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ unsigned int plane_supported_rotations;
+
+ scoped_guard(mutex, &plane->dev->lock)
+ plane_supported_rotations = vkms_config_plane_get_supported_rotations(plane->config);
+
+ return sprintf(page, "%u", plane_supported_rotations);
+}
+
+static ssize_t plane_supported_rotations_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 0, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~(DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK))
+ return -EINVAL;
+ /* Should at least provide one rotation */
+ if (!(val & DRM_MODE_ROTATE_MASK))
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_supported_rotations(plane->config, val);
+ }
+
+ return count;
+}
+
+static ssize_t plane_default_rotation_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ unsigned int plane_default_rotation;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ plane_default_rotation = vkms_config_plane_get_default_rotation(plane->config);
+ }
+
+ return sprintf(page, "%u", plane_default_rotation);
+}
+
+static ssize_t plane_default_rotation_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~(DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK))
+ return -EINVAL;
+
+ /* Should contain exactly one rotation */
+ if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_default_rotation(plane->config, val);
+ }
+
+ return count;
+}
+
CONFIGFS_ATTR(plane_, type);
+CONFIGFS_ATTR(plane_, supported_rotations);
+CONFIGFS_ATTR(plane_, default_rotation);
static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_type,
+ &plane_attr_supported_rotations,
+ &plane_attr_default_rotation,
NULL,
};
--
2.54.0
^ permalink raw reply related
* [PATCH v5 18/38] drm/vkms: Introduce config for plane color encoding
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
VKMS driver supports all the color encoding on planes, but for testing it
can be useful to only advertise few of them. This new configuration
interface will allow configuring the color encoding per planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 51 +++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.c | 48 ++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 64 +++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_plane.c | 15 +++----
4 files changed, 170 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index c33fe737678f..a2a3f1a106a3 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -192,6 +192,14 @@ static void vkms_config_test_default_config(struct kunit *test)
KUNIT_EXPECT_EQ(test,
vkms_config_plane_get_default_rotation(plane_cfg),
DRM_MODE_ROTATE_0);
+ KUNIT_EXPECT_EQ(test,
+ vkms_config_plane_get_supported_color_encodings(plane_cfg),
+ BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020));
+ KUNIT_EXPECT_EQ(test,
+ vkms_config_plane_get_default_color_encoding(plane_cfg),
+ DRM_COLOR_YCBCR_BT601);
}
/* Encoders */
@@ -526,6 +534,48 @@ static void vkms_config_test_valid_plane_rotations(struct kunit *test)
vkms_config_destroy(config);
}
+static void vkms_config_test_valid_plane_color_encoding(struct kunit *test)
+{
+ struct vkms_config *config;
+ struct vkms_config_plane *plane_cfg;
+
+ config = vkms_config_default_create(false, false, false, false);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config);
+
+ plane_cfg = get_first_plane(config);
+
+ /* Valid, all color encoding supported */
+ vkms_config_plane_set_supported_color_encodings(plane_cfg,
+ BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020));
+ vkms_config_plane_set_default_color_encoding(plane_cfg, DRM_COLOR_YCBCR_BT601);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_encoding(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Invalid, default color encoding is not supported */
+ vkms_config_plane_set_supported_color_encodings(plane_cfg,
+ BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT2020));
+ vkms_config_plane_set_default_color_encoding(plane_cfg, DRM_COLOR_YCBCR_BT709);
+ KUNIT_EXPECT_FALSE(test, vkms_config_valid_plane_color_encoding(config, plane_cfg));
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Valid, no supported or color encoding */
+ vkms_config_plane_set_supported_color_encodings(plane_cfg, 0);
+ vkms_config_plane_set_default_color_encoding(plane_cfg, 0);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_encoding(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Valid, if no supported color encoding, default is ignored */
+ vkms_config_plane_set_supported_color_encodings(plane_cfg, 0);
+ vkms_config_plane_set_default_color_encoding(plane_cfg, DRM_COLOR_YCBCR_BT601);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_encoding(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ vkms_config_destroy(config);
+}
+
static void vkms_config_test_valid_plane_possible_crtcs(struct kunit *test)
{
struct vkms_config *config;
@@ -1049,6 +1099,7 @@ static struct kunit_case vkms_config_test_cases[] = {
KUNIT_CASE(vkms_config_test_invalid_plane_number),
KUNIT_CASE(vkms_config_test_valid_plane_type),
KUNIT_CASE(vkms_config_test_valid_plane_rotations),
+ KUNIT_CASE(vkms_config_test_valid_plane_color_encoding),
KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs),
KUNIT_CASE(vkms_config_test_invalid_crtc_number),
KUNIT_CASE(vkms_config_test_invalid_encoder_number),
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index ca3ee3aa2c41..2fa467f5e17e 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -179,6 +179,25 @@ bool vkms_config_valid_plane_rotation(const struct vkms_config *config,
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_rotation);
+VISIBLE_IF_KUNIT
+bool vkms_config_valid_plane_color_encoding(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg)
+{
+ struct drm_device *dev = config->dev ? &config->dev->drm : NULL;
+
+ if (vkms_config_plane_get_supported_color_encodings(plane_cfg)) {
+ if ((BIT(vkms_config_plane_get_default_color_encoding(plane_cfg)) &
+ vkms_config_plane_get_supported_color_encodings(plane_cfg)) !=
+ BIT(vkms_config_plane_get_default_color_encoding(plane_cfg))) {
+ drm_info(dev, "Configured default color encoding is not supported by the plane\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_color_encoding);
+
static bool valid_planes_for_crtc(const struct vkms_config *config,
struct vkms_config_crtc *crtc_cfg)
{
@@ -341,6 +360,9 @@ bool vkms_config_is_valid(const struct vkms_config *config)
vkms_config_for_each_plane(config, plane_cfg) {
if (!vkms_config_valid_plane_rotation(config, plane_cfg))
return false;
+
+ if (!vkms_config_valid_plane_color_encoding(config, plane_cfg))
+ return false;
}
if (!valid_plane_number(config))
@@ -373,6 +395,22 @@ bool vkms_config_is_valid(const struct vkms_config *config)
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_is_valid);
+static void show_bitfield(struct seq_file *m, uint32_t value, const char *callback(unsigned int))
+{
+ u32 offset = 0;
+ bool first = true;
+
+ while (value >= BIT(offset) && offset < 32) {
+ if (value & BIT(offset)) {
+ if (!first)
+ seq_puts(m, ",");
+ seq_printf(m, callback(offset));
+ first = false;
+ }
+ offset += 1;
+ }
+}
+
static int vkms_config_show(struct seq_file *m, void *data)
{
struct drm_debugfs_entry *entry = m->private;
@@ -398,6 +436,12 @@ static int vkms_config_show(struct seq_file *m, void *data)
DRM_ROTATION_FMT_ARGS(vkms_config_plane_get_supported_rotations(plane_cfg)));
seq_printf(m, "\tdefault rotation=" DRM_ROTATION_FMT "\n",
DRM_ROTATION_FMT_ARGS(vkms_config_plane_get_default_rotation(plane_cfg)));
+ seq_puts(m, "\tsupported color encoding=");
+ show_bitfield(m, vkms_config_plane_get_supported_color_encodings(plane_cfg),
+ drm_get_color_encoding_name);
+ seq_puts(m, "\n");
+ seq_printf(m, "\tdefault color encoding=%s\n",
+ drm_get_color_encoding_name(vkms_config_plane_get_default_color_encoding(plane_cfg)));
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
@@ -450,6 +494,10 @@ struct vkms_config_plane __must_check *vkms_config_create_plane(struct vkms_conf
vkms_config_plane_set_supported_rotations(plane_cfg,
DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_ROTATE_0);
+ vkms_config_plane_set_supported_color_encodings(plane_cfg, BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020));
+ vkms_config_plane_set_default_color_encoding(plane_cfg, DRM_COLOR_YCBCR_BT601);
xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index b5884ac0f42f..31c1598ff866 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -46,6 +46,8 @@ struct vkms_config {
* It can be used to store a temporary reference to a VKMS plane during
* device creation. This pointer is not managed by the configuration and
* must be managed by other means.
+ * @default_color_encoding: Default color encoding that should be used by this plane
+ * @supported_color_encodings: Color encodings that this plane will support
*/
struct vkms_config_plane {
struct list_head link;
@@ -55,6 +57,8 @@ struct vkms_config_plane {
enum drm_plane_type type;
unsigned int default_rotation;
unsigned int supported_rotations;
+ enum drm_color_encoding default_color_encoding;
+ unsigned int supported_color_encodings;
struct xarray possible_crtcs;
bool default_pipeline;
@@ -376,6 +380,66 @@ bool vkms_config_valid_plane_rotation(const struct vkms_config *config,
const struct vkms_config_plane *plane_cfg);
#endif
+/**
+ * vkms_config_plane_get_default_color_encoding() - Get the default color encoding for a plane
+ * @plane_cfg: Plane to get the default color encoding from
+ *
+ * Returns:
+ * The default color encoding for the plane
+ */
+static inline enum drm_color_encoding
+vkms_config_plane_get_default_color_encoding(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->default_color_encoding;
+}
+
+/**
+ * vkms_config_plane_set_default_color_encoding() - Set the default color encoding for a plane
+ * @plane_cfg: Plane to set the default color encoding to
+ * @default_color_encoding: New default color encoding for the plane
+ */
+static inline void
+vkms_config_plane_set_default_color_encoding(struct vkms_config_plane *plane_cfg,
+ enum drm_color_encoding default_color_encoding)
+{
+ plane_cfg->default_color_encoding = default_color_encoding;
+}
+
+/**
+ * vkms_config_plane_get_supported_color_encodings() - Get the supported color encodings for a plane
+ * @plane_cfg: Plane to get the supported color encodings from
+ *
+ * Returns:
+ * The supported color encodings for the plane. Each set bit correspond to a value of enum
+ * drm_color_encoding: BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709) means that
+ * DRM_COLOR_YCBCR_BT601 and DRM_COLOR_YCBCR_BT709 are supported.
+ */
+static inline unsigned int
+vkms_config_plane_get_supported_color_encodings(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->supported_color_encodings;
+}
+
+/**
+ * vkms_config_plane_set_supported_color_encodings() - Set the supported color encodings for a plane
+ * @plane_cfg: Plane to set the supported color encodings to
+ * @supported_color_encodings: New supported color encodings for the plane. Each set bit corresponds
+ * to a value of enum drm_color_encoding:
+ * BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709) means that
+ * DRM_COLOR_YCBCR_BT601 and DRM_COLOR_YCBCR_BT709 are supported.
+ */
+static inline void
+vkms_config_plane_set_supported_color_encodings(struct vkms_config_plane *plane_cfg,
+ unsigned int supported_color_encodings)
+{
+ plane_cfg->supported_color_encodings = supported_color_encodings;
+}
+
+#if IS_ENABLED(CONFIG_KUNIT)
+bool vkms_config_valid_plane_color_encoding(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg);
+#endif
+
/**
* vkms_config_plane_set_name() - Set the plane name
* @plane_cfg: Plane to set the name to
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 8a64ea41734b..8d3953667f21 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -239,14 +239,13 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
vkms_config_plane_get_default_rotation(plane_cfg),
vkms_config_plane_get_supported_rotations(plane_cfg));
- drm_plane_create_color_properties(&plane->base,
- BIT(DRM_COLOR_YCBCR_BT601) |
- BIT(DRM_COLOR_YCBCR_BT709) |
- BIT(DRM_COLOR_YCBCR_BT2020),
- BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
- BIT(DRM_COLOR_YCBCR_FULL_RANGE),
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_FULL_RANGE);
+ if (vkms_config_plane_get_supported_color_encodings(plane_cfg) != 0)
+ drm_plane_create_color_properties(&plane->base,
+ vkms_config_plane_get_supported_color_encodings(plane_cfg),
+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE),
+ vkms_config_plane_get_default_color_encoding(plane_cfg),
+ DRM_COLOR_YCBCR_FULL_RANGE);
if (vkms_config_plane_get_default_pipeline(plane_cfg))
vkms_initialize_colorops(&plane->base);
--
2.54.0
^ permalink raw reply related
* [PATCH v5 19/38] drm/vkms: Introduce configfs for plane color encoding
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
To allows the userspace to test many hardware configuration, introduce a
new interface to configure the available color encoding per planes. VKMS
supports multiple color encoding, so the userspace can choose any
combination.
The supported color encoding are configured by writing a color encoding
bitmask to the file `supported_color_encoding` and the default color
encoding is chosen by writing a color encoding bitmask to
`default_color_encoding`.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/ABI/testing/configfs-vkms | 14 +++++
Documentation/gpu/vkms.rst | 8 ++-
drivers/gpu/drm/vkms/vkms_configfs.c | 92 +++++++++++++++++++++++++++++++++
3 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/configfs-vkms b/Documentation/ABI/testing/configfs-vkms
index 7820da8505ef..a9ee05fe0c66 100644
--- a/Documentation/ABI/testing/configfs-vkms
+++ b/Documentation/ABI/testing/configfs-vkms
@@ -118,6 +118,20 @@ Description:
Default rotation presented to userspace, same values as
possible_rotations.
+What: /sys/kernel/config/vkms/<device>/planes/<plane>/supported_color_encodings
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ Available color encodings for the plane, as a bitmask:
+ 0x01 - YCBCR_BT601, 0x02 - YCBCR_BT709, 0x04 - YCBCR_BT2020.
+
+What: /sys/kernel/config/vkms/<device>/planes/<plane>/default_color_encoding
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ Default color encoding presented to userspace, same
+ values as supported_color_encoding.
+
What: /sys/kernel/config/vkms/<device>/planes/<plane>/possible_crtcs
Date: Nov 2025
Contact: dri-devel@lists.freedesktop.org
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 610305483716..7206cd2b231a 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 3 configurable attributes:
+Planes have 5 configurable attributes:
- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
exposed by the "type" property of a plane)
@@ -96,6 +96,12 @@ Planes have 3 configurable attributes:
(same values as those exposed by the "rotation" property of a plane)
- default_rotation: Default rotation presented to the userspace, same values as
supported_rotations.
+- supported_color_encodings: Available encodings for a plane, as a bitmask:
+ 0x01 YCBCR_BT601, 0x02 YCBCR_BT709, 0x04 YCBCR_BT2020 (same values as those exposed
+ by the COLOR_ENCODING property of a plane). If set, supported_color_range
+ must be set too.
+- default_color_encoding: Default color encoding presented to the userspace, same
+ values as supported_color_encodings
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 47b3a4aeee8d..c1d1841b2c5a 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -9,6 +9,14 @@
#include "vkms_configfs.h"
#include "vkms_connector.h"
+/**
+ * VKMS_SUPPORTED_COLOR_ENCODINGS - Bitmask of all supported color encodings in VKMS
+ */
+#define VKMS_SUPPORTED_COLOR_ENCODINGS ( \
+ BIT(DRM_COLOR_YCBCR_BT601) | \
+ BIT(DRM_COLOR_YCBCR_BT709) | \
+ BIT(DRM_COLOR_YCBCR_BT2020))
+
/* To avoid registering configfs more than once or unregistering on error */
static bool is_configfs_registered;
@@ -402,14 +410,98 @@ static ssize_t plane_default_rotation_store(struct config_item *item,
return count;
}
+static ssize_t plane_supported_color_encodings_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ unsigned int supported_color_encodings;
+
+ scoped_guard(mutex, &plane->dev->lock)
+ supported_color_encodings = vkms_config_plane_get_supported_color_encodings(plane->config);
+
+ return sprintf(page, "%u", supported_color_encodings);
+}
+
+static ssize_t plane_supported_color_encodings_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~(VKMS_SUPPORTED_COLOR_ENCODINGS))
+ return -EINVAL;
+ /* Should at least provide one color encoding */
+ if ((val & (VKMS_SUPPORTED_COLOR_ENCODINGS)) == 0)
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_supported_color_encodings(plane->config, val);
+ }
+
+ return count;
+}
+
+static ssize_t plane_default_color_encoding_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane = plane = plane_item_to_vkms_configfs_plane(item);
+ unsigned int default_color_encoding;
+
+ scoped_guard(mutex, &plane->dev->lock)
+ default_color_encoding = BIT(vkms_config_plane_get_default_color_encoding(plane->config));
+
+ return sprintf(page, "%u", default_color_encoding);
+}
+
+static ssize_t plane_default_color_encoding_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~VKMS_SUPPORTED_COLOR_ENCODINGS)
+ return -EINVAL;
+
+ /* Ensure val is a single bit set */
+ if (!is_power_of_2(val))
+ return -EINVAL;
+
+ /* Convert bit position to the proper enum value */
+ val = __ffs(val) + DRM_COLOR_YCBCR_BT601;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_default_color_encoding(plane->config, val);
+ }
+
+ return count;
+}
+
CONFIGFS_ATTR(plane_, type);
CONFIGFS_ATTR(plane_, supported_rotations);
CONFIGFS_ATTR(plane_, default_rotation);
+CONFIGFS_ATTR(plane_, supported_color_encodings);
+CONFIGFS_ATTR(plane_, default_color_encoding);
static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_type,
&plane_attr_supported_rotations,
&plane_attr_default_rotation,
+ &plane_attr_supported_color_encodings,
+ &plane_attr_default_color_encoding,
NULL,
};
--
2.54.0
^ permalink raw reply related
* [PATCH v5 20/38] drm/vkms: Introduce config for plane color range
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
VKMS driver supports all the color range on planes, but for testing it can
be useful to only advertise few of them. This new configuration interface
will allow configuring the color range per planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 44 +++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.c | 39 ++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 35 +++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_plane.c | 8 ++---
4 files changed, 122 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index a2a3f1a106a3..a88d8b4a969e 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
+#include <drm/drm_color_mgmt.h>
#include <drm/drm_mode.h>
#include <kunit/test.h>
@@ -562,6 +563,7 @@ static void vkms_config_test_valid_plane_color_encoding(struct kunit *test)
KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
/* Valid, no supported or color encoding */
+ vkms_config_plane_set_supported_color_ranges(plane_cfg, 0);
vkms_config_plane_set_supported_color_encodings(plane_cfg, 0);
vkms_config_plane_set_default_color_encoding(plane_cfg, 0);
KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_encoding(config, plane_cfg));
@@ -576,6 +578,47 @@ static void vkms_config_test_valid_plane_color_encoding(struct kunit *test)
vkms_config_destroy(config);
}
+static void vkms_config_test_valid_plane_color_range(struct kunit *test)
+{
+ struct vkms_config *config;
+ struct vkms_config_plane *plane_cfg;
+
+ config = vkms_config_default_create(false, false, false, false);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config);
+
+ plane_cfg = get_first_plane(config);
+
+ /* Valid, all color range supported */
+ vkms_config_plane_set_supported_color_ranges(plane_cfg,
+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE));
+ vkms_config_plane_set_default_color_range(plane_cfg, DRM_COLOR_YCBCR_FULL_RANGE);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_range(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Invalid, default color range is not supported */
+ vkms_config_plane_set_supported_color_ranges(plane_cfg,
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE));
+ vkms_config_plane_set_default_color_range(plane_cfg, DRM_COLOR_YCBCR_LIMITED_RANGE);
+ KUNIT_EXPECT_FALSE(test, vkms_config_valid_plane_color_range(config, plane_cfg));
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Valid, no supported or color range */
+ vkms_config_plane_set_supported_color_encodings(plane_cfg, 0);
+ vkms_config_plane_set_supported_color_ranges(plane_cfg, 0);
+ vkms_config_plane_set_default_color_range(plane_cfg, 0);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_range(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Valid, if no supported color range, default is ignored */
+ vkms_config_plane_set_supported_color_ranges(plane_cfg, 0);
+ vkms_config_plane_set_default_color_range(plane_cfg, DRM_COLOR_YCBCR_LIMITED_RANGE);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_range(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ vkms_config_destroy(config);
+}
+
static void vkms_config_test_valid_plane_possible_crtcs(struct kunit *test)
{
struct vkms_config *config;
@@ -1100,6 +1143,7 @@ static struct kunit_case vkms_config_test_cases[] = {
KUNIT_CASE(vkms_config_test_valid_plane_type),
KUNIT_CASE(vkms_config_test_valid_plane_rotations),
KUNIT_CASE(vkms_config_test_valid_plane_color_encoding),
+ KUNIT_CASE(vkms_config_test_valid_plane_color_range),
KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs),
KUNIT_CASE(vkms_config_test_invalid_crtc_number),
KUNIT_CASE(vkms_config_test_invalid_encoder_number),
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 2fa467f5e17e..553871646761 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -198,6 +198,25 @@ bool vkms_config_valid_plane_color_encoding(const struct vkms_config *config,
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_color_encoding);
+VISIBLE_IF_KUNIT
+bool vkms_config_valid_plane_color_range(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg)
+{
+ struct drm_device *dev = config->dev ? &config->dev->drm : NULL;
+
+ if (vkms_config_plane_get_supported_color_ranges(plane_cfg)) {
+ if ((BIT(vkms_config_plane_get_default_color_range(plane_cfg)) &
+ vkms_config_plane_get_supported_color_ranges(plane_cfg)) !=
+ BIT(vkms_config_plane_get_default_color_range(plane_cfg))) {
+ drm_info(dev, "Configured default color range is not supported by the plane\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_color_range);
+
static bool valid_planes_for_crtc(const struct vkms_config *config,
struct vkms_config_crtc *crtc_cfg)
{
@@ -354,6 +373,7 @@ static bool valid_connector_possible_encoders(const struct vkms_config *config)
bool vkms_config_is_valid(const struct vkms_config *config)
{
+ struct drm_device *dev = config->dev ? &config->dev->drm : NULL;
struct vkms_config_crtc *crtc_cfg;
struct vkms_config_plane *plane_cfg;
@@ -363,6 +383,16 @@ bool vkms_config_is_valid(const struct vkms_config *config)
if (!vkms_config_valid_plane_color_encoding(config, plane_cfg))
return false;
+
+ if (!vkms_config_valid_plane_color_range(config, plane_cfg))
+ return false;
+
+ if ((vkms_config_plane_get_supported_color_encodings(plane_cfg) == 0) !=
+ (vkms_config_plane_get_supported_color_ranges(plane_cfg) == 0)) {
+ drm_info(dev,
+ "Both supported color encodings and color ranges must be set, or none\n");
+ return false;
+ }
}
if (!valid_plane_number(config))
@@ -442,6 +472,12 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_puts(m, "\n");
seq_printf(m, "\tdefault color encoding=%s\n",
drm_get_color_encoding_name(vkms_config_plane_get_default_color_encoding(plane_cfg)));
+ seq_puts(m, "\tsupported color ranges=");
+ show_bitfield(m, vkms_config_plane_get_supported_color_ranges(plane_cfg),
+ drm_get_color_range_name);
+ seq_puts(m, "\n");
+ seq_printf(m, "\tdefault color range=%s\n",
+ drm_get_color_range_name(vkms_config_plane_get_default_color_range(plane_cfg)));
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
@@ -498,6 +534,9 @@ struct vkms_config_plane __must_check *vkms_config_create_plane(struct vkms_conf
BIT(DRM_COLOR_YCBCR_BT709) |
BIT(DRM_COLOR_YCBCR_BT2020));
vkms_config_plane_set_default_color_encoding(plane_cfg, DRM_COLOR_YCBCR_BT601);
+ vkms_config_plane_set_supported_color_ranges(plane_cfg, BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE));
+ vkms_config_plane_set_default_color_range(plane_cfg, DRM_COLOR_YCBCR_FULL_RANGE);
xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 31c1598ff866..60cadb7bea5b 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -48,6 +48,8 @@ struct vkms_config {
* must be managed by other means.
* @default_color_encoding: Default color encoding that should be used by this plane
* @supported_color_encodings: Color encodings that this plane will support
+ * @default_color_range: Default color range that should be used by this plane
+ * @supported_color_ranges: Color ranges that this plane will support
*/
struct vkms_config_plane {
struct list_head link;
@@ -59,6 +61,8 @@ struct vkms_config_plane {
unsigned int supported_rotations;
enum drm_color_encoding default_color_encoding;
unsigned int supported_color_encodings;
+ enum drm_color_range default_color_range;
+ unsigned int supported_color_ranges;
struct xarray possible_crtcs;
bool default_pipeline;
@@ -440,6 +444,37 @@ bool vkms_config_valid_plane_color_encoding(const struct vkms_config *config,
const struct vkms_config_plane *plane_cfg);
#endif
+static inline enum drm_color_range
+vkms_config_plane_get_default_color_range(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->default_color_range;
+}
+
+static inline void
+vkms_config_plane_set_default_color_range(struct vkms_config_plane *plane_cfg,
+ enum drm_color_range default_color_range)
+{
+ plane_cfg->default_color_range = default_color_range;
+}
+
+static inline unsigned int
+vkms_config_plane_get_supported_color_ranges(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->supported_color_ranges;
+}
+
+static inline void
+vkms_config_plane_set_supported_color_ranges(struct vkms_config_plane *plane_cfg,
+ unsigned int supported_color_ranges)
+{
+ plane_cfg->supported_color_ranges = supported_color_ranges;
+}
+
+#if IS_ENABLED(CONFIG_KUNIT)
+bool vkms_config_valid_plane_color_range(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg);
+#endif
+
/**
* vkms_config_plane_set_name() - Set the plane name
* @plane_cfg: Plane to set the name to
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 8d3953667f21..d4ccf418198e 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -239,13 +239,13 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
vkms_config_plane_get_default_rotation(plane_cfg),
vkms_config_plane_get_supported_rotations(plane_cfg));
- if (vkms_config_plane_get_supported_color_encodings(plane_cfg) != 0)
+ if (vkms_config_plane_get_supported_color_encodings(plane_cfg) != 0 &&
+ vkms_config_plane_get_supported_color_ranges(plane_cfg) != 0)
drm_plane_create_color_properties(&plane->base,
vkms_config_plane_get_supported_color_encodings(plane_cfg),
- BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
- BIT(DRM_COLOR_YCBCR_FULL_RANGE),
+ vkms_config_plane_get_supported_color_ranges(plane_cfg),
vkms_config_plane_get_default_color_encoding(plane_cfg),
- DRM_COLOR_YCBCR_FULL_RANGE);
+ vkms_config_plane_get_default_color_range(plane_cfg));
if (vkms_config_plane_get_default_pipeline(plane_cfg))
vkms_initialize_colorops(&plane->base);
--
2.54.0
^ permalink raw reply related
* [PATCH v5 21/38] drm/vkms: Introduce configfs for plane color range
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
To allows the userspace to test many hardware configuration, introduce a
new interface to configure the available color ranges per planes. VKMS
supports multiple color ranges, so the userspace can choose any
combination.
The supported color ranges are configured by writing a color range bitmask
to the file `supported_color_ranges` and the default color range is
chosen by writing a color encoding bitmask to `default_color_range`.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/ABI/testing/configfs-vkms | 15 ++++++
Documentation/gpu/vkms.rst | 10 +++-
drivers/gpu/drm/vkms/vkms_configfs.c | 90 +++++++++++++++++++++++++++++++++
3 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/Documentation/ABI/testing/configfs-vkms b/Documentation/ABI/testing/configfs-vkms
index a9ee05fe0c66..ef0c3da6b3ca 100644
--- a/Documentation/ABI/testing/configfs-vkms
+++ b/Documentation/ABI/testing/configfs-vkms
@@ -132,6 +132,21 @@ Description:
Default color encoding presented to userspace, same
values as supported_color_encoding.
+What: /sys/kernel/config/vkms/<device>/planes/<plane>/supported_color_ranges
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ Available color ranges for the plane, as a bitmask:
+ 0x1 - DRM_COLOR_YCBCR_LIMITED_RANGE,
+ 0x2 - DRM_COLOR_YCBCR_FULL_RANGE.
+
+What: /sys/kernel/config/vkms/<device>/planes/<plane>/default_color_range
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ Default color range presented to userspace, same
+ values as supported_color_ranges.
+
What: /sys/kernel/config/vkms/<device>/planes/<plane>/possible_crtcs
Date: Nov 2025
Contact: dri-devel@lists.freedesktop.org
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 7206cd2b231a..7e8f4fe3b392 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 5 configurable attributes:
+Planes have 7 configurable attributes:
- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
exposed by the "type" property of a plane)
@@ -98,10 +98,16 @@ Planes have 5 configurable attributes:
supported_rotations.
- supported_color_encodings: Available encodings for a plane, as a bitmask:
0x01 YCBCR_BT601, 0x02 YCBCR_BT709, 0x04 YCBCR_BT2020 (same values as those exposed
- by the COLOR_ENCODING property of a plane). If set, supported_color_range
+ by the COLOR_ENCODING property of a plane). If set, supported_color_ranges
must be set too.
- default_color_encoding: Default color encoding presented to the userspace, same
values as supported_color_encodings
+- supported_color_ranges: Available color range for a plane, as a bitmask:
+ 0x1 DRM_COLOR_YCBCR_LIMITED_RANGE, 0x2 DRM_COLOR_YCBCR_FULL_RANGE (same values as
+ those exposed by the COLOR_RANGE property of a plane). If set, supported_color_encoding
+ must be set too.
+- default_color_range: Default color range presented to the userspace, same
+ values as supported_color_ranges
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 c1d1841b2c5a..56a0c542a143 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -17,6 +17,13 @@
BIT(DRM_COLOR_YCBCR_BT709) | \
BIT(DRM_COLOR_YCBCR_BT2020))
+/**
+ * VKMS_SUPPORTED_COLOR_RANGES - Bitmask of all supported color ranges in VKMS
+ */
+#define VKMS_SUPPORTED_COLOR_RANGES ( \
+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | \
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE))
+
/* To avoid registering configfs more than once or unregistering on error */
static bool is_configfs_registered;
@@ -410,6 +417,85 @@ static ssize_t plane_default_rotation_store(struct config_item *item,
return count;
}
+static ssize_t plane_supported_color_ranges_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ unsigned int supported_color_ranges;
+
+ scoped_guard(mutex, &plane->dev->lock)
+ supported_color_ranges = vkms_config_plane_get_supported_color_ranges(plane->config);
+
+ return sprintf(page, "%u", supported_color_ranges);
+}
+
+static ssize_t plane_supported_color_ranges_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~VKMS_SUPPORTED_COLOR_RANGES)
+ return -EINVAL;
+ /* Should at least provide one color range */
+ if ((val & VKMS_SUPPORTED_COLOR_RANGES) == 0)
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_supported_color_ranges(plane->config, val);
+ }
+
+ return count;
+}
+
+static ssize_t plane_default_color_range_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ unsigned int default_color_range;
+
+ scoped_guard(mutex, &plane->dev->lock)
+ default_color_range = vkms_config_plane_get_default_color_range(plane->config);
+
+ return sprintf(page, "%lu", BIT(default_color_range));
+}
+
+static ssize_t plane_default_color_range_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~VKMS_SUPPORTED_COLOR_RANGES)
+ return -EINVAL;
+
+ if (!is_power_of_2(val))
+ return -EINVAL;
+
+ /* Convert bit position to the proper enum value */
+ val = ffs(val) + DRM_COLOR_YCBCR_LIMITED_RANGE - 1;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_default_color_range(plane->config, val);
+ }
+
+ return count;
+}
+
static ssize_t plane_supported_color_encodings_show(struct config_item *item, char *page)
{
struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
@@ -493,6 +579,8 @@ static ssize_t plane_default_color_encoding_store(struct config_item *item,
CONFIGFS_ATTR(plane_, type);
CONFIGFS_ATTR(plane_, supported_rotations);
CONFIGFS_ATTR(plane_, default_rotation);
+CONFIGFS_ATTR(plane_, supported_color_ranges);
+CONFIGFS_ATTR(plane_, default_color_range);
CONFIGFS_ATTR(plane_, supported_color_encodings);
CONFIGFS_ATTR(plane_, default_color_encoding);
@@ -500,6 +588,8 @@ static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_type,
&plane_attr_supported_rotations,
&plane_attr_default_rotation,
+ &plane_attr_supported_color_ranges,
+ &plane_attr_default_color_range,
&plane_attr_supported_color_encodings,
&plane_attr_default_color_encoding,
NULL,
--
2.54.0
^ permalink raw reply related
* [PATCH v5 22/38] drm/vkms: Introduce config for plane format
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
VKMS driver supports all the pixel formats for planes, but for testing it
can be useful to only advertise few of them. This new configuration
interface will allow configuring the pixel format per planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 128 +++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 51 +++++++++++++++
drivers/gpu/drm/vkms/vkms_plane.c | 39 +----------
3 files changed, 181 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 553871646761..c7de3e307367 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -12,6 +12,42 @@
#include "vkms_config.h"
+static const u32 vkms_supported_plane_formats[] = {
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_BGR888,
+ DRM_FORMAT_XRGB16161616,
+ DRM_FORMAT_XBGR16161616,
+ DRM_FORMAT_ARGB16161616,
+ DRM_FORMAT_ABGR16161616,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_BGR565,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_NV42,
+ DRM_FORMAT_YUV420,
+ DRM_FORMAT_YUV422,
+ DRM_FORMAT_YUV444,
+ DRM_FORMAT_YVU420,
+ DRM_FORMAT_YVU422,
+ DRM_FORMAT_YVU444,
+ DRM_FORMAT_P010,
+ DRM_FORMAT_P012,
+ DRM_FORMAT_P016,
+ DRM_FORMAT_R1,
+ DRM_FORMAT_R2,
+ DRM_FORMAT_R4,
+ DRM_FORMAT_R8,
+};
+
struct vkms_config *vkms_config_create(const char *dev_name)
{
struct vkms_config *config;
@@ -441,6 +477,15 @@ static void show_bitfield(struct seq_file *m, uint32_t value, const char *callba
}
}
+static void show_formats(struct seq_file *m, u32 *formats, size_t formats_count)
+{
+ for (int i = 0; i < formats_count; i++) {
+ seq_printf(m, "%p4cc", &formats[i]);
+ if (i != formats_count - 1)
+ seq_puts(m, ", ");
+ }
+}
+
static int vkms_config_show(struct seq_file *m, void *data)
{
struct drm_debugfs_entry *entry = m->private;
@@ -478,6 +523,10 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_puts(m, "\n");
seq_printf(m, "\tdefault color range=%s\n",
drm_get_color_range_name(vkms_config_plane_get_default_color_range(plane_cfg)));
+ seq_puts(m, "\tsupported formats=");
+ show_formats(m, vkms_config_plane_get_supported_formats(plane_cfg),
+ vkms_config_plane_get_supported_formats_count(plane_cfg));
+ seq_puts(m, "\n");
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
@@ -527,6 +576,10 @@ struct vkms_config_plane __must_check *vkms_config_create_plane(struct vkms_conf
if (ret)
goto cleanup_plane_cfg;
+ ret = vkms_config_plane_add_all_formats(plane_cfg);
+ if (ret)
+ goto cleanup_plane_cfg;
+
vkms_config_plane_set_supported_rotations(plane_cfg,
DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_ROTATE_0);
@@ -554,6 +607,7 @@ EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_plane);
void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg)
{
xa_destroy(&plane_cfg->possible_crtcs);
+ kfree(plane_cfg->supported_formats);
list_del(&plane_cfg->link);
kfree(plane_cfg->name);
kfree(plane_cfg);
@@ -658,6 +712,80 @@ static struct vkms_config_plane *vkms_config_crtc_get_plane(const struct vkms_co
return NULL;
}
+int __must_check vkms_config_plane_add_all_formats(struct vkms_config_plane *plane_cfg)
+{
+ u32 *ret = krealloc_array(plane_cfg->supported_formats,
+ ARRAY_SIZE(vkms_supported_plane_formats),
+ sizeof(uint32_t), GFP_KERNEL);
+ if (!ret)
+ return -ENOMEM;
+ plane_cfg->supported_formats = ret;
+
+ memcpy(plane_cfg->supported_formats, vkms_supported_plane_formats,
+ sizeof(vkms_supported_plane_formats));
+ plane_cfg->supported_formats_count = ARRAY_SIZE(vkms_supported_plane_formats);
+ return 0;
+}
+
+static bool is_supported_format(u32 drm_format)
+{
+ for (int i = 0; i < ARRAY_SIZE(vkms_supported_plane_formats); i++) {
+ if (vkms_supported_plane_formats[i] == drm_format)
+ return true;
+ }
+
+ return false;
+}
+
+static bool vkms_config_plane_has_format(struct vkms_config_plane *plane_cfg, u32 drm_format)
+{
+ for (unsigned int i = 0; i < plane_cfg->supported_formats_count; i++) {
+ if (plane_cfg->supported_formats[i] == drm_format)
+ return true;
+ }
+ return false;
+}
+
+int __must_check vkms_config_plane_add_format(struct vkms_config_plane *plane_cfg, u32 drm_format)
+{
+ if (!is_supported_format(drm_format))
+ return -EINVAL;
+
+ if (vkms_config_plane_has_format(plane_cfg, drm_format))
+ return 0;
+
+ u32 *new_ptr = krealloc_array(plane_cfg->supported_formats,
+ plane_cfg->supported_formats_count + 1,
+ sizeof(*plane_cfg->supported_formats), GFP_KERNEL);
+ if (!new_ptr)
+ return -ENOMEM;
+
+ plane_cfg->supported_formats = new_ptr;
+ plane_cfg->supported_formats[plane_cfg->supported_formats_count] = drm_format;
+ plane_cfg->supported_formats_count++;
+
+ return 0;
+}
+
+void vkms_config_plane_remove_all_formats(struct vkms_config_plane *plane_cfg)
+{
+ plane_cfg->supported_formats_count = 0;
+ kfree(plane_cfg->supported_formats);
+ plane_cfg->supported_formats = NULL;
+}
+
+void vkms_config_plane_remove_format(struct vkms_config_plane *plane_cfg, u32 drm_format)
+{
+ for (unsigned int i = 0; i < plane_cfg->supported_formats_count; i++) {
+ if (plane_cfg->supported_formats[i] == drm_format) {
+ plane_cfg->supported_formats[i] =
+ plane_cfg->supported_formats[plane_cfg->supported_formats_count -
+ 1];
+ plane_cfg->supported_formats_count--;
+ }
+ }
+}
+
struct vkms_config_plane *vkms_config_crtc_primary_plane(const struct vkms_config *config,
struct vkms_config_crtc *crtc_cfg)
{
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 60cadb7bea5b..3de4a92af9c5 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -50,6 +50,8 @@ struct vkms_config {
* @supported_color_encodings: Color encodings that this plane will support
* @default_color_range: Default color range that should be used by this plane
* @supported_color_ranges: Color ranges that this plane will support
+ * @supported_formats: List of supported formats
+ * @supported_formats_count: Length of @supported_formats
*/
struct vkms_config_plane {
struct list_head link;
@@ -63,6 +65,8 @@ struct vkms_config_plane {
unsigned int supported_color_encodings;
enum drm_color_range default_color_range;
unsigned int supported_color_ranges;
+ u32 *supported_formats;
+ unsigned int supported_formats_count;
struct xarray possible_crtcs;
bool default_pipeline;
@@ -475,6 +479,53 @@ bool vkms_config_valid_plane_color_range(const struct vkms_config *config,
const struct vkms_config_plane *plane_cfg);
#endif
+static inline u32 *
+vkms_config_plane_get_supported_formats(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->supported_formats;
+}
+
+static inline unsigned int
+vkms_config_plane_get_supported_formats_count(struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->supported_formats_count;
+}
+
+/** vkms_config_plane_add_format - Add a format to the list of supported format of a plane
+ *
+ * The passed drm_format can already be present in the list. This may fail if the allocation of a
+ * bigger array fails.
+ *
+ * @plane_cfg: Plane to add the format to
+ * @drm_format: Format to add to this plane
+ *
+ * Returns: 0 on success, -ENOMEM if array allocation fails, -EINVAL if the format is not supported
+ * by VKMS
+ */
+int __must_check vkms_config_plane_add_format(struct vkms_config_plane *plane_cfg, u32 drm_format);
+
+/**
+ * vkms_config_plane_add_all_formats - Helper to quickly add all the supported formats
+ * @plane_cfg: Plane to add the formats to
+ *
+ * Returns: 0 on success, -ENOMEM if array allocation fails
+ * by VKMS
+ */
+int __must_check vkms_config_plane_add_all_formats(struct vkms_config_plane *plane_cfg);
+
+/**
+ * vkms_config_plane_remove_format - Remove a specific format from a plane
+ * @plane_cfg: Plane to remove the format from
+ * @drm_format: Format to remove
+ */
+void vkms_config_plane_remove_format(struct vkms_config_plane *plane_cfg, u32 drm_format);
+
+/**
+ * vkms_config_plane_remove_all_formats - Remove all formats from a plane
+ * @plane_cfg: Plane to remove the formats from
+ */
+void vkms_config_plane_remove_all_formats(struct vkms_config_plane *plane_cfg);
+
/**
* vkms_config_plane_set_name() - Set the plane name
* @plane_cfg: Plane to set the name to
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index d4ccf418198e..6e767cdf8194 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -15,42 +15,6 @@
#include "vkms_drv.h"
#include "vkms_formats.h"
-static const u32 vkms_formats[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_RGBA8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_XBGR8888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_BGR888,
- DRM_FORMAT_XRGB16161616,
- DRM_FORMAT_XBGR16161616,
- DRM_FORMAT_ARGB16161616,
- DRM_FORMAT_ABGR16161616,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_BGR565,
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV16,
- DRM_FORMAT_NV24,
- DRM_FORMAT_NV21,
- DRM_FORMAT_NV61,
- DRM_FORMAT_NV42,
- DRM_FORMAT_YUV420,
- DRM_FORMAT_YUV422,
- DRM_FORMAT_YUV444,
- DRM_FORMAT_YVU420,
- DRM_FORMAT_YVU422,
- DRM_FORMAT_YVU444,
- DRM_FORMAT_P010,
- DRM_FORMAT_P012,
- DRM_FORMAT_P016,
- DRM_FORMAT_R1,
- DRM_FORMAT_R2,
- DRM_FORMAT_R4,
- DRM_FORMAT_R8,
-};
-
static struct drm_plane_state *
vkms_plane_duplicate_state(struct drm_plane *plane)
{
@@ -227,7 +191,8 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 0,
&vkms_plane_funcs,
- vkms_formats, ARRAY_SIZE(vkms_formats),
+ vkms_config_plane_get_supported_formats(plane_cfg),
+ vkms_config_plane_get_supported_formats_count(plane_cfg),
NULL, vkms_config_plane_get_type(plane_cfg),
vkms_config_plane_get_name(plane_cfg));
if (IS_ERR(plane))
--
2.54.0
^ permalink raw reply related
* [PATCH v5 23/38] drm/vkms: Introduce configfs for plane format
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
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 <louis.chauvet@bootlin.com>
---
Documentation/ABI/testing/configfs-vkms | 9 ++
Documentation/gpu/vkms.rst | 7 +-
drivers/gpu/drm/vkms/tests/Makefile | 3 +-
drivers/gpu/drm/vkms/tests/vkms_configfs_test.c | 102 +++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_configfs.c | 113 ++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_configfs.h | 4 +
6 files changed, 236 insertions(+), 2 deletions(-)
diff --git a/Documentation/ABI/testing/configfs-vkms b/Documentation/ABI/testing/configfs-vkms
index ef0c3da6b3ca..de901ce36b2e 100644
--- a/Documentation/ABI/testing/configfs-vkms
+++ b/Documentation/ABI/testing/configfs-vkms
@@ -147,6 +147,15 @@ Description:
Default color range presented to userspace, same
values as supported_color_ranges.
+What: /sys/kernel/config/vkms/<device>/planes/<plane>/supported_formats
+Date: Nov 2025
+Contact: dri-devel@lists.freedesktop.org
+Description:
+ List of supported formats for this plane. To add a new
+ item, write its fourcc code prefixed with '+'. To remove,
+ use '-' prefix. Use '+*' to add all formats, '-*' to
+ remove all.
+
What: /sys/kernel/config/vkms/<device>/planes/<plane>/possible_crtcs
Date: Nov 2025
Contact: dri-devel@lists.freedesktop.org
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 7e8f4fe3b392..e5280a99eee8 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 attributes:
+Planes have 8 configurable attributes:
- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
exposed by the "type" property of a plane)
@@ -108,6 +108,11 @@ Planes have 7 configurable attributes:
must be set too.
- default_color_range: Default color range presented to the userspace, same
values as supported_color_ranges
+- supported_formats: List of supported formats for this plane. To add a new item in the
+ list, write it using a plus and 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/tests/Makefile b/drivers/gpu/drm/vkms/tests/Makefile
index d4d9ba8d4c54..92cfa7262ba4 100644
--- a/drivers/gpu/drm/vkms/tests/Makefile
+++ b/drivers/gpu/drm/vkms/tests/Makefile
@@ -3,6 +3,7 @@
vkms-kunit-tests-y := \
vkms_config_test.o \
vkms_format_test.o \
- vkms_color_test.o
+ vkms_color_test.o \
+ vkms_configfs_test.o \
obj-$(CONFIG_DRM_VKMS_KUNIT_TEST) += vkms-kunit-tests.o
diff --git a/drivers/gpu/drm/vkms/tests/vkms_configfs_test.c b/drivers/gpu/drm/vkms/tests/vkms_configfs_test.c
new file mode 100644
index 000000000000..8d02c2c459d9
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/vkms_configfs_test.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include "linux/printk.h"
+#include <kunit/test.h>
+
+#include "../vkms_configfs.h"
+
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
+
+/**
+ * struct vkms_configfs_parse_format_case - Store test case for format parsing
+ * @str: Contains the string to parse
+ * @str_len: str len
+ * @expected_len: expected len of the matched format
+ * @expected_offset: expected offset in the string for the parsed format
+ */
+struct vkms_configfs_parse_format_case {
+ const char *str;
+ int str_len;
+ int expected_len;
+ int expected_offset;
+};
+
+struct vkms_configfs_parse_format_case vkms_configfs_parse_format_test_cases[] = {
+ {
+ .str = "+RG24",
+ .str_len = 6,
+ .expected_len = 5,
+ .expected_offset = 0,
+ }, {
+ .str = "-RG24",
+ .str_len = 6,
+ .expected_len = 5,
+ .expected_offset = 0
+ }, {
+ .str = " -RG24",
+ .str_len = 8,
+ .expected_len = 5,
+ .expected_offset = 2
+ }, {
+ .str = "+*",
+ .str_len = 3,
+ .expected_len = 2,
+ .expected_offset = 0
+ }, {
+ .str = "-RG24+RG24",
+ .str_len = 11,
+ .expected_len = 5,
+ .expected_offset = 0
+ }, {
+ .str = "-R1+RG24",
+ .str_len = 9,
+ .expected_len = 3,
+ .expected_offset = 0
+ }, {
+ .str = "\n-R1",
+ .str_len = 5,
+ .expected_len = 3,
+ .expected_offset = 1
+ }, {
+ .str = "-R1111",
+ .str_len = 3,
+ .expected_len = 3,
+ .expected_offset = 0
+ }
+};
+
+static void vkms_configfs_test_parse_format(struct kunit *test)
+{
+ const struct vkms_configfs_parse_format_case *param = test->param_value;
+ char *out;
+ int len = vkms_configfs_parse_next_format(param->str, param->str + param->str_len, &out);
+
+ KUNIT_EXPECT_EQ(test, len, param->expected_len);
+ KUNIT_EXPECT_PTR_EQ(test, out, param->str + param->expected_offset);
+}
+
+static void vkms_configfs_test_parse_format_get_desc(struct vkms_configfs_parse_format_case *t,
+ char *desc)
+{
+ snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", t->str);
+}
+
+KUNIT_ARRAY_PARAM(vkms_configfs_test_parse_format, vkms_configfs_parse_format_test_cases,
+ vkms_configfs_test_parse_format_get_desc
+);
+
+static struct kunit_case vkms_configfs_test_cases[] = {
+ KUNIT_CASE_PARAM(vkms_configfs_test_parse_format,
+ vkms_configfs_test_parse_format_gen_params),
+ {}
+};
+
+static struct kunit_suite vkms_configfs_test_suite = {
+ .name = "vkms-configfs",
+ .test_cases = vkms_configfs_test_cases,
+};
+
+kunit_test_suite(vkms_configfs_test_suite);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Kunit test for vkms configfs utility");
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index 56a0c542a143..e6cb245b8582 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -3,6 +3,8 @@
#include <linux/configfs.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/string.h>
+#include <kunit/visibility.h>
#include "vkms_drv.h"
#include "vkms_config.h"
@@ -576,6 +578,115 @@ 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);
+}
+
+/**
+ * vkms_configfs_parse_next_format() - Parse the next format in page,
+ * skipping all non fourcc-related characters
+ * @page: page to search into
+ * @page_end: last character of the page
+ * @out: Output pointer, will point inside page
+ *
+ * Returns: size of the matched format, @out will point to the + or -
+ */
+VISIBLE_IF_KUNIT
+int vkms_configfs_parse_next_format(const char *page, const char *page_end, char **out)
+{
+ int count = page - page_end;
+ char *tmp_plus = strnchr(page, count, '+');
+ char *tmp_minus = strnchr(page, count, '-');
+
+ if (!tmp_plus && !tmp_minus)
+ return 0;
+ if (!tmp_plus)
+ *out = tmp_minus;
+ else if (!tmp_minus)
+ *out = tmp_plus;
+ else
+ *out = min(tmp_plus, tmp_minus);
+
+ char *end = *out + 1;
+
+ while (end < page_end) {
+ if (!isalnum(*end) && *end != '*')
+ break;
+ end++;
+ }
+
+ return end - *out;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_configfs_parse_next_format);
+
+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;
+
+ if (count < 2 || count > 5)
+ return -EINVAL;
+
+ if (page[0] != '+' && page[0] != '-')
+ return -EINVAL;
+
+ if (page[1] == '*' && count != 2)
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ char fmt[4] = {' ', ' ', ' ', ' '};
+
+ memcpy(fmt, &page[1], min(count - 1, 4));
+
+ if (page[0] == '+' && page[1] == '*')
+ ret = vkms_config_plane_add_all_formats(plane->config);
+ else if (page[0] == '-' && page[1] == '*')
+ vkms_config_plane_remove_all_formats(plane->config);
+ else if (page[0] == '+')
+ ret = vkms_config_plane_add_format(plane->config, *(int *)fmt);
+ else if (page[0] == '-')
+ vkms_config_plane_remove_format(plane->config, *(int *)fmt);
+
+ if (ret)
+ return ret;
+ }
+
+ return count;
+}
+
CONFIGFS_ATTR(plane_, type);
CONFIGFS_ATTR(plane_, supported_rotations);
CONFIGFS_ATTR(plane_, default_rotation);
@@ -583,6 +694,7 @@ CONFIGFS_ATTR(plane_, supported_color_ranges);
CONFIGFS_ATTR(plane_, default_color_range);
CONFIGFS_ATTR(plane_, supported_color_encodings);
CONFIGFS_ATTR(plane_, default_color_encoding);
+CONFIGFS_ATTR(plane_, supported_formats);
static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_type,
@@ -592,6 +704,7 @@ static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_default_color_range,
&plane_attr_supported_color_encodings,
&plane_attr_default_color_encoding,
+ &plane_attr_supported_formats,
NULL,
};
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.h b/drivers/gpu/drm/vkms/vkms_configfs.h
index e9020b0043db..73be660412ca 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.h
+++ b/drivers/gpu/drm/vkms/vkms_configfs.h
@@ -5,4 +5,8 @@
int vkms_configfs_register(void);
void vkms_configfs_unregister(void);
+#if IS_ENABLED(CONFIG_KUNIT)
+int vkms_configfs_parse_next_format(const char *page, const char *end_page, char **out);
+#endif
+
#endif /* _VKMS_CONFIGFS_H_ */
--
2.54.0
^ permalink raw reply related
* [PATCH v5 24/38] drm/vkms: Properly render plane using their zpos
From: Louis Chauvet @ 2026-06-27 3:30 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet, Shuah Khan, Miguel Ojeda, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: Luca Ceresoli, Kory Maincent, victoria, sebastian.wick, victoria,
airlied, thomas.petazzoni, dri-devel, linux-kernel, linux-doc,
Louis Chauvet, llvm
In-Reply-To: <20260627-vkms-all-config-v5-0-854aa0840926@bootlin.com>
Currently planes are rendered in creation order. This is not an issue, but
with the introduction of new zpos configuration, it is required to
properly render planes.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_crtc.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 079abfba427d..b9428de2d4aa 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -142,14 +142,20 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
return -ENOMEM;
vkms_state->num_active_planes = i;
- i = 0;
+ ret = drm_atomic_normalize_zpos(crtc->dev, state);
+ if (ret)
+ return ret;
+
drm_for_each_plane_mask(plane, crtc->dev, crtc_state->plane_mask) {
plane_state = drm_atomic_get_new_plane_state(crtc_state->state, plane);
if (!plane_state->visible)
continue;
- vkms_state->active_planes[i++] =
+ // Order planes according to their normalized_zpos
+ // After drm_atomic_normalize_zpos, the possible values are 0..n_planes-1
+ // so store them using this index
+ vkms_state->active_planes[plane_state->normalized_zpos] =
to_vkms_plane_state(plane_state);
}
--
2.54.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox