From nobody Mon Dec 15 22:04:33 2025 Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9060F1F1306 for ; Tue, 21 Jan 2025 10:55:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.194 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737456947; cv=none; b=FhB1uMlKMIBwUntEPU0StPQFLixnyirTzv3h+QqE3vYgoQw1rAT9KM2EzY6QITL4S5hLLAMmGCNNQOAE9ctYWxCTBV32UQkF2AO5Rnf41NEMmfoWo++1Hxtrma9Aehhe2rF7rYKc+KX23oR00fClL7cW2yJJQGHT0osFzaijJ2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737456947; c=relaxed/simple; bh=EkmyO2LSexOkTJzOOyicuZnPgcN7tBbD7ESxmkXrUAk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hr8HjrETAry0Z73oK716Fo6Hf4fZg0Lii3RGQYPIajLa0lZSt8S+XTcGnAyP2akCPoVojriC32gCZioV1u19zUUCcVearRrJUJM3MBNB5z0OKr7sGZ53p0D99NXmnLGVeUNdFxi3MUTf81uM5/mfj1xXGp1+roHJsw/NqEfO7Ro= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=GxZwv7SR; arc=none smtp.client-ip=217.70.183.194 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="GxZwv7SR" Received: by mail.gandi.net (Postfix) with ESMTPSA id B7CD54000B; Tue, 21 Jan 2025 10:55:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1737456938; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EZ4+dULwJeZLEDWGar2fFPRnYCtGxTs/GQ44jM9HSvo=; b=GxZwv7SRqMSlSIBidrGEocrNihB8C4kI706FuM/CdIM5z3611VCKNpxo823q3JPE+26jCP qD4pbQTJxL9fY2IZzjyTp2wU16IBMbeUaROHSJ84HFqPGBrEmV9+x/zUOvBAMQxIzgDUA5 SDJQvL4TfAeZtszNG8Y5zhsJ+vMxcluibp4a5nypkytSJtgjPG/g2NCfjp1RTfWDr2UExL BsTs7HSnL6XbYxQywV36S2Pyqvyrp4QYZNEMlXTutDWbRnGMcUQ8GKu+O0GK04ciuwhrtV VEeuG/rjhVIV5JevoETrPUROarkE7zaQ6pmXeuaP3HhtPlkLE8fqp0kEwP9kzQ== From: Louis Chauvet Date: Tue, 21 Jan 2025 11:55:28 +0100 Subject: [PATCH v3 04/16] drm/vkms: Introduce config for plane Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250121-google-remove-crtc-index-from-parameter-v3-4-cac00a3c3544@bootlin.com> References: <20250121-google-remove-crtc-index-from-parameter-v3-0-cac00a3c3544@bootlin.com> In-Reply-To: <20250121-google-remove-crtc-index-from-parameter-v3-0-cac00a3c3544@bootlin.com> To: =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Simona Vetter , Melissa Wen , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie Cc: arthurgrillo@riseup.net, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, nicolejadeyee@google.com, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Louis Chauvet X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=11421; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=EkmyO2LSexOkTJzOOyicuZnPgcN7tBbD7ESxmkXrUAk=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnj30hAYAZBrKZVxfxqvE8/lqtyPJZy0eqpQ0Pa r2pggxNh/iJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZ499IQAKCRAgrS7GWxAs 4kQ6D/9LuRl2K7ZAxkclQV2nJOhZC3bg7/SVcHEXPMUceIerO9ksRyrYOHgZMc4AQavNMPZoxvr +nVDeorKPnvaPWzBOSLxB5v9RGcY/JAqqYJJGS1S9+tpa83yxhE7bZSkAGNBvoOBxBO/UM10V3O DpCAxnvFxxITPBdLXpA6fAQ6GGMdjRaFItIC/vnc/oRsIkybnggx2h3hUELVfORO0L/ywraZogS XnFVhwqqf1ZY0midG8nsdeYvADVozyiHhFZe4WB3tXfHR/RAHTxvxwWiDbRTOAF+XkPtyQb01MY EDxRWLFf5H/KqXSsna8itVQ+54wk+aMYWFeDwyRkR81e4gzvRJNkfKuDPlDJ62qwrM5C8rE0YXq c8d9l7+ymxLi9VRX8N38AYeAOYE4nZRCnFX0kvbwvsEchqNyc0ZH/hkAafVROI0BEcAVFXLBZpR 9Szh1ldEzdC0tKbKqUOAUdp1n0zRTEYO3GC6gvbZaPXxq7MIyCk26HeLIBcILjGLItc9dYRipM3 ggsLsPa00eBEzLJSe3mdrxTBppHp8a/YumwXgn79lNYHIrbM49jVz5G9wo9B21ghaqB4qpMNbl6 60a8WZdKGXKp0/rgH/g7tel7UV11rFJoWJKwnE7+mNC0FDTQ0m8PWdbqSujosLzKssgCqxi5fBf vil4LzCe6X2YP+A== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com The current vkms driver only allows the usage of one primary, eight overlays and one cursor plane. This new configuration structure aims to make the configuration more flexible. Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_config.c | 92 ++++++++++++++++++++++++++++++++++= ++-- drivers/gpu/drm/vkms/vkms_config.h | 43 +++++++++++++++++- drivers/gpu/drm/vkms/vkms_drv.h | 3 +- drivers/gpu/drm/vkms/vkms_output.c | 37 +++++---------- drivers/gpu/drm/vkms/vkms_plane.c | 5 ++- 5 files changed, 145 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms= _config.c index e7c7f46303e8ce4c9de68878668b855ac0fc5d2e..495056ce988ab32738701f00c94= c709457aefbd3 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -14,6 +14,8 @@ struct vkms_config *vkms_config_create(void) if (!config) return ERR_PTR(-ENOMEM); =20 + INIT_LIST_HEAD(&config->planes); + return config; } EXPORT_SYMBOL_IF_KUNIT(vkms_config_create); @@ -21,26 +23,105 @@ EXPORT_SYMBOL_IF_KUNIT(vkms_config_create); struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool = enable_overlay, bool enable_cursor) { + struct vkms_config_plane *plane; struct vkms_config *vkms_config =3D vkms_config_create(); =20 if (IS_ERR(vkms_config)) return vkms_config; =20 vkms_config->writeback =3D enable_writeback; - vkms_config->overlay =3D enable_overlay; - vkms_config->cursor =3D enable_cursor; =20 + plane =3D vkms_config_create_plane(vkms_config); + if (!plane) + goto err_alloc; + + plane->type =3D DRM_PLANE_TYPE_PRIMARY; + + if (enable_overlay) { + for (int i =3D 0; i < NUM_OVERLAY_PLANES; i++) { + plane =3D vkms_config_create_plane(vkms_config); + if (!plane) + goto err_alloc; + plane->type =3D DRM_PLANE_TYPE_OVERLAY; + } + } + if (enable_cursor) { + plane =3D vkms_config_create_plane(vkms_config); + if (!plane) + goto err_alloc; + plane->type =3D DRM_PLANE_TYPE_CURSOR; + } return vkms_config; + +err_alloc: + vkms_config_destroy(vkms_config); + return ERR_PTR(-ENOMEM); +} + +struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkm= s_config) +{ + if (!vkms_config) + return NULL; + + struct vkms_config_plane *vkms_config_overlay =3D kzalloc(sizeof(*vkms_co= nfig_overlay), + GFP_KERNEL); + + if (!vkms_config_overlay) + return NULL; + + vkms_config_overlay->type =3D DRM_PLANE_TYPE_OVERLAY; + + list_add(&vkms_config_overlay->link, &vkms_config->planes); + + return vkms_config_overlay; +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_plane); + +void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_overla= y) +{ + if (!vkms_config_overlay) + return; + list_del(&vkms_config_overlay->link); + kfree(vkms_config_overlay); } =20 void vkms_config_destroy(struct vkms_config *config) { + struct vkms_config_plane *vkms_config_plane, *tmp_plane; + + list_for_each_entry_safe(vkms_config_plane, tmp_plane, &config->planes, l= ink) { + vkms_config_delete_plane(vkms_config_plane); + } + kfree(config); } EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy); =20 bool vkms_config_is_valid(struct vkms_config *config) { + struct vkms_config_plane *config_plane; + + bool has_cursor =3D false; + bool has_primary =3D false; + + list_for_each_entry(config_plane, &config->planes, link) { + if (config_plane->type =3D=3D DRM_PLANE_TYPE_PRIMARY) { + // Multiple primary planes for only one CRTC + if (has_primary) + return false; + has_primary =3D true; + } + if (config_plane->type =3D=3D DRM_PLANE_TYPE_CURSOR) { + // Multiple cursor planes for only one CRTC + if (has_cursor) + return false; + has_cursor =3D true; + } + } + + if (!has_primary) + return false; + return true; } EXPORT_SYMBOL_IF_KUNIT(vkms_config_is_valid); @@ -50,10 +131,13 @@ static int vkms_config_show(struct seq_file *m, void *= data) struct drm_debugfs_entry *entry =3D m->private; struct drm_device *dev =3D entry->dev; struct vkms_device *vkmsdev =3D drm_device_to_vkms_device(dev); + struct vkms_config_plane *config_plane; =20 seq_printf(m, "writeback=3D%d\n", vkmsdev->config->writeback); - seq_printf(m, "cursor=3D%d\n", vkmsdev->config->cursor); - seq_printf(m, "overlay=3D%d\n", vkmsdev->config->overlay); + list_for_each_entry(config_plane, &vkmsdev->config->planes, link) { + seq_puts(m, "plane:\n"); + seq_printf(m, "\ttype: %d\n", config_plane->type); + } =20 return 0; } diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms= _config.h index 2afb795586c6924a46dd4ba777bf22a4f51cddda..ac99f1df6d9a17bd7040a1e7a6a= cce14cd8fd9d0 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -10,8 +10,8 @@ * struct vkms_config - General configuration for VKMS driver * * @writeback: If true, a writeback buffer can be attached to the CRTC - * @cursor: If true, a cursor plane is created in the VKMS device - * @overlay: If true, NUM_OVERLAY_PLANES will be created for the VKMS devi= ce + * @planes: List of planes configured for this device. They are created by= the function + * vkms_config_create_plane(). * @dev: Used to store the current vkms device. Only set when the device i= s instancied. */ struct vkms_config { @@ -19,6 +19,27 @@ struct vkms_config { bool cursor; bool overlay; struct vkms_device *dev; + + struct list_head planes; +}; + +/** + * struct vkms_config_plane + * + * @link: Link to the others planes + * @type: Type of the plane. The creator of configuration needs to ensures= that at least one + * plane is primary. + * @plane: Internal usage. This pointer should never be considered as vali= d. It can be used to + * store a temporary reference to a vkms plane during device creat= ion. This pointer is + * not managed by the configuration and must be managed by other m= eans. + */ +struct vkms_config_plane { + struct list_head link; + + enum drm_plane_type type; + + /* Internal usage */ + struct vkms_plane *plane; }; =20 /** @@ -42,6 +63,24 @@ void vkms_config_destroy(struct vkms_config *config); */ bool vkms_config_is_valid(struct vkms_config *vkms_config); =20 +/** + * vkms_config_create_plane() - Create a plane configuration + * + * This will allocate and add a new plane to @vkms_config. This plane will= have by default the + * maximum supported values. + * @vkms_config: Configuration where to insert new plane + */ +struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkm= s_config); + +/** + * vkms_config_delete_plane() - Remove a plane configuration and frees its= memory + * + * This will delete a plane configuration from the parent configuration. T= his will NOT + * cleanup and frees the vkms_plane that can be stored in @vkms_config_pla= ne. + * @vkms_config_plane: Plane configuration to cleanup + */ +void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_plane); + /** * vkms_config_alloc_default() - Allocate the configuration for the defaul= t device * @enable_writeback: Enable the writeback connector for this configuration diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_dr= v.h index af7081c940d6c074dc01cf8180556a3d902e386d..1b5add9536f503fe224425b924c= 14a5217bb09b1 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -190,6 +190,7 @@ struct vkms_output { }; =20 struct vkms_config; +struct vkms_config_plane; =20 /** * struct vkms_device - Description of a VKMS device @@ -246,7 +247,7 @@ int vkms_output_init(struct vkms_device *vkmsdev); * @type: type of plane to initialize */ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev, - enum drm_plane_type type); + struct vkms_config_plane *config); =20 /* CRC Support */ const char *const *vkms_get_crc_sources(struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms= _output.c index 78e389d832c16e4dbaccda34fbf3215f34adeadf..cf385f676ef7f45633b4ed69a80= 47c87fad95dbd 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -31,30 +31,14 @@ static const struct drm_connector_helper_funcs vkms_con= n_helper_funcs =3D { =20 int vkms_output_init(struct vkms_device *vkmsdev) { + struct vkms_config_plane *config_plane; struct drm_device *dev =3D &vkmsdev->drm; struct drm_connector *connector; struct drm_encoder *encoder; struct vkms_output *output; - struct vkms_plane *primary, *overlay, *cursor =3D NULL; + struct vkms_plane *primary, *cursor =3D NULL; int ret; int writeback; - unsigned int n; - - /* - * Initialize used plane. One primary plane is required to perform the co= mposition. - * - * The overlay and cursor planes are not mandatory, but can be used to pe= rform complex - * composition. - */ - primary =3D vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY); - if (IS_ERR(primary)) - return PTR_ERR(primary); - - if (vkmsdev->config->cursor) { - cursor =3D vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR); - if (IS_ERR(cursor)) - return PTR_ERR(cursor); - } =20 output =3D vkms_crtc_init(dev, &primary->base, cursor ? &cursor->base : NULL); @@ -63,15 +47,16 @@ int vkms_output_init(struct vkms_device *vkmsdev) return PTR_ERR(output); } =20 - if (vkmsdev->config->overlay) { - for (n =3D 0; n < NUM_OVERLAY_PLANES; n++) { - overlay =3D vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_OVERLAY); - if (IS_ERR(overlay)) { - DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n"); - return PTR_ERR(overlay); - } - overlay->base.possible_crtcs =3D drm_crtc_mask(&output->crtc); + list_for_each_entry(config_plane, &vkmsdev->config->planes, link) { + config_plane->plane =3D vkms_plane_init(vkmsdev, config_plane); + if (IS_ERR(config_plane->plane)) { + ret =3D PTR_ERR(config_plane->plane); + return ret; } + if (config_plane->type =3D=3D DRM_PLANE_TYPE_PRIMARY) + primary =3D config_plane->plane; + else if (config_plane->type =3D=3D DRM_PLANE_TYPE_CURSOR) + cursor =3D config_plane->plane; } =20 connector =3D drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL); diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_= plane.c index e2fce471870f1899f2ccb66b339ce8c4332cc287..4663002c9c54030ff6243631a2a= 1cff26415e7a3 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -11,6 +11,7 @@ =20 #include "vkms_drv.h" #include "vkms_formats.h" +#include "vkms_config.h" =20 static const u32 vkms_formats[] =3D { DRM_FORMAT_ARGB8888, @@ -187,7 +188,7 @@ static const struct drm_plane_helper_funcs vkms_plane_h= elper_funcs =3D { }; =20 struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev, - enum drm_plane_type type) + struct vkms_config_plane *config) { struct drm_device *dev =3D &vkmsdev->drm; struct vkms_plane *plane; @@ -195,7 +196,7 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *= vkmsdev, plane =3D drmm_universal_plane_alloc(dev, struct vkms_plane, base, 0, &vkms_plane_funcs, vkms_formats, ARRAY_SIZE(vkms_formats), - NULL, type, NULL); + NULL, config->type, NULL); if (IS_ERR(plane)) return plane; =20 --=20 2.47.1