From: Louis Chauvet Date: Thu, 16 Oct 2025 17:56:11 +0000 (+0200) Subject: drm/vkms: Allow to attach encoders and CRTCs via configfs X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fad1138b2377aa094b1c80fad852eadbcf3a85c3;p=thirdparty%2Fkernel%2Flinux.git drm/vkms: Allow to attach encoders and CRTCs via configfs Create a default subgroup at /config/vkms/encoders/encoder/possible_crtcs that will contain symbolic links to the possible CRTCs for the encoder. Tested-by: Mark Yacoub Reviewed-by: Louis Chauvet Reviewed-by: Harry Wentland Reviewed-by: Luca Ceresoli Signed-off-by: Louis Chauvet Co-developed-by: José Expósito Signed-off-by: José Expósito Link: https://lore.kernel.org/r/20251016175618.10051-10-jose.exposito89@gmail.com Signed-off-by: Luca Ceresoli --- diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst index 622fbfa12a84c..585effe905509 100644 --- a/Documentation/gpu/vkms.rst +++ b/Documentation/gpu/vkms.rst @@ -106,6 +106,7 @@ Next, create one or more encoders:: To finish the configuration, link the different pipeline items:: sudo ln -s /config/vkms/my-vkms/crtcs/crtc0 /config/vkms/my-vkms/planes/plane0/possible_crtcs + sudo ln -s /config/vkms/my-vkms/crtcs/crtc0 /config/vkms/my-vkms/encoders/encoder0/possible_crtcs Since at least one primary plane is required, make sure to set the right type:: @@ -122,6 +123,7 @@ Finally, you can remove the VKMS instance disabling it:: And removing the top level directory and its subdirectories:: sudo rm /config/vkms/my-vkms/planes/*/possible_crtcs/* + sudo rm /config/vkms/my-vkms/encoders/*/possible_crtcs/* sudo rmdir /config/vkms/my-vkms/planes/* sudo rmdir /config/vkms/my-vkms/crtcs/* sudo rmdir /config/vkms/my-vkms/encoders/* diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c index 0df86e63570a1..7de601e39d2bc 100644 --- a/drivers/gpu/drm/vkms/vkms_configfs.c +++ b/drivers/gpu/drm/vkms/vkms_configfs.c @@ -70,11 +70,13 @@ struct vkms_configfs_crtc { * * @group: Top level configuration group that represents a encoder. * Initialized when a new directory is created under "/config/vkms/encoders" + * @possible_crtcs_group: Default subgroup of @group at "encoder/possible_crtcs" * @dev: The vkms_configfs_device this encoder belongs to * @config: Configuration of the VKMS encoder */ struct vkms_configfs_encoder { struct config_group group; + struct config_group possible_crtcs_group; struct vkms_configfs_device *dev; struct vkms_config_encoder *config; }; @@ -100,6 +102,10 @@ struct vkms_configfs_encoder { container_of(to_config_group((item)), struct vkms_configfs_encoder, \ group) +#define encoder_possible_crtcs_item_to_vkms_configfs_encoder(item) \ + container_of(to_config_group((item)), struct vkms_configfs_encoder, \ + possible_crtcs_group) + static ssize_t crtc_writeback_show(struct config_item *item, char *page) { struct vkms_configfs_crtc *crtc; @@ -364,6 +370,52 @@ static const struct config_item_type plane_group_type = { .ct_owner = THIS_MODULE, }; +static int encoder_possible_crtcs_allow_link(struct config_item *src, + struct config_item *target) +{ + struct vkms_configfs_encoder *encoder; + struct vkms_configfs_crtc *crtc; + int ret; + + if (target->ci_type != &crtc_item_type) + return -EINVAL; + + encoder = encoder_possible_crtcs_item_to_vkms_configfs_encoder(src); + crtc = crtc_item_to_vkms_configfs_crtc(target); + + scoped_guard(mutex, &encoder->dev->lock) { + if (encoder->dev->enabled) + return -EBUSY; + + ret = vkms_config_encoder_attach_crtc(encoder->config, crtc->config); + } + + return ret; +} + +static void encoder_possible_crtcs_drop_link(struct config_item *src, + struct config_item *target) +{ + struct vkms_configfs_encoder *encoder; + struct vkms_configfs_crtc *crtc; + + encoder = encoder_possible_crtcs_item_to_vkms_configfs_encoder(src); + crtc = crtc_item_to_vkms_configfs_crtc(target); + + scoped_guard(mutex, &encoder->dev->lock) + vkms_config_encoder_detach_crtc(encoder->config, crtc->config); +} + +static struct configfs_item_operations encoder_possible_crtcs_item_operations = { + .allow_link = encoder_possible_crtcs_allow_link, + .drop_link = encoder_possible_crtcs_drop_link, +}; + +static const struct config_item_type encoder_possible_crtcs_group_type = { + .ct_item_ops = &encoder_possible_crtcs_item_operations, + .ct_owner = THIS_MODULE, +}; + static void encoder_release(struct config_item *item) { struct vkms_configfs_encoder *encoder; @@ -413,6 +465,12 @@ static struct config_group *make_encoder_group(struct config_group *group, config_group_init_type_name(&encoder->group, name, &encoder_item_type); + + config_group_init_type_name(&encoder->possible_crtcs_group, + "possible_crtcs", + &encoder_possible_crtcs_group_type); + configfs_add_default_group(&encoder->possible_crtcs_group, + &encoder->group); } return &encoder->group;