From patchwork Mon Feb 17 10:01:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977430 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 99584C021A0 for ; Mon, 17 Feb 2025 10:01:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DDA7F10E3C9; Mon, 17 Feb 2025 10:01:27 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="SAs0CLS6"; dkim-atps=neutral Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) by gabe.freedesktop.org (Postfix) with ESMTPS id 02A2610E3C2 for ; Mon, 17 Feb 2025 10:01:26 +0000 (UTC) Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-43948021a45so43125365e9.1 for ; Mon, 17 Feb 2025 02:01:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786485; x=1740391285; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=T6WlJ6G+D4bbUKndbktll+9YSW21OZOtswUdeB6r15c=; b=SAs0CLS6aBgPnacETSQpFwLx9iwNusATSKGE6pTk79HFDeV/5roX5iSwEQANesSxdw iBLqwy6s4n6z3aZumbt7D2exFO2046FBDJI3l8djfbNKpk8Ecxe2DukpngOdBcI9inNH 1IFseQ+pJgNoXOEMerJ926eNds38d6HwQ+mmlQTdikd8/eWXrQIP37Mq2ljZD40fNnAa 09dPrIgGvkS9Mj+dl8e/2wlooNGRPG7kPZeaD6/FmJY74hXxD3/IFN57wiycyHuVwXRM RvsBfzBaWNrnfUI0Xn2WnlcKr15+AWUcQmaJCrnidoxPHZekypFyXul9R9b6jwPdtJVl c8cQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786485; x=1740391285; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=T6WlJ6G+D4bbUKndbktll+9YSW21OZOtswUdeB6r15c=; b=N68fM2V5+rhJHt3x8fFN0XtBRMKqxuYgRp9M+l18QUhh0dtfCKmD8/40j+lNAq5qr/ M9DUX3JvKCxdY92LKTHXxb5qWIn8aQGqtQD/hU0/FxUMVKEmaiVKmKX4JVgH8cFxv838 r1udYo2tTE4y8gWsbJaOriEKwtPB+QSKgwFLV8JKGeJ5Dav8cCQTj7goYaA68svU0rpx SVBP5m7FOCC9M5wa9SyaHhGXFsa4kPoSvU1vxCLKSt8UQLcVuO5yn6u3qHGGwkLPKFkc /6B7ksdG4vemhmIclRusXhKkNHlV3j+iKgEjTnt5a7chP54k8k7BrnkFkGKdhO/SU7Qk iMEA== X-Forwarded-Encrypted: i=1; AJvYcCU6J9vMuVzq8GCRsrYgwJqoSgjUWi0OdyyTj1CKxFT8LoOU6Uq1e8bcKKRrV4F4Q9OS0Ao9FMc+Yac=@lists.freedesktop.org X-Gm-Message-State: AOJu0Ywb2WUuLASRAv9wmsT6RRcaeyaViAaG7MEuBbIu3RXhisgDiL4E w9+09enUeQf5qDRNAXJGhwiG3rBw/rujMea1+K8KvRensJT1EYi8 X-Gm-Gg: ASbGncvpxzml+jbD/F75+xQgDQwMhc++Y2MjU+HXdzQm16cFdsXDr4yq13RHC3gYhHe Tlhn1BU7M7wj3b8QZ7SIW/g0p5c1nzg962MKeLYRpnIK59xPhDepzlvSg0JT8heCRDhCBraRs88 kIQ2VLl89JZhM6UjEvO31fAhFhxuWlYYh5Q748Q2cBPlhJiJRjDFBb1P2rD4fRz5Nb/8obqwGRV iID2gNNiCZzSp7+EWyseRsAYfcTBAqdDmvx9tUZfJgZ9L15UTTGAlBjYe2q4qW7GsV9fPwPWSTI PRpdlmSmN0d5kl9BaQ== X-Google-Smtp-Source: AGHT+IHR0ivBkP8DqlKn6j8a9rbDoM73t+/snjkd1dg3bV48JUhvsPQ/BQ9hOo9BodTzfQDHc3wwJw== X-Received: by 2002:a5d:47a3:0:b0:38f:3914:c624 with SMTP id ffacd0b85a97d-38f3914cacfmr6018411f8f.7.1739786485181; Mon, 17 Feb 2025 02:01:25 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:24 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 01/14] drm/vkms: Extract vkms_connector header Date: Mon, 17 Feb 2025 11:01:07 +0100 Message-ID: <20250217100120.7620-2-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Up until now, the logic to manage connectors was in vkms_output.c. Since more options will be added to connectors in the future, extract the code to its own file. Refactor, no functional changes. Reviewed-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/Makefile | 3 +- drivers/gpu/drm/vkms/vkms_connector.c | 50 +++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_connector.h | 17 +++++++++ drivers/gpu/drm/vkms/vkms_output.c | 41 +++------------------- 4 files changed, 73 insertions(+), 38 deletions(-) create mode 100644 drivers/gpu/drm/vkms/vkms_connector.c create mode 100644 drivers/gpu/drm/vkms/vkms_connector.h diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index 1b28a6a32948..6b0615c424f2 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -6,6 +6,7 @@ vkms-y := \ vkms_formats.o \ vkms_crtc.o \ vkms_composer.o \ - vkms_writeback.o + vkms_writeback.o \ + vkms_connector.o obj-$(CONFIG_DRM_VKMS) += vkms.o diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/vkms_connector.c new file mode 100644 index 000000000000..fc97f265dea6 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_connector.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include + +#include "vkms_connector.h" + +static const struct drm_connector_funcs vkms_connector_funcs = { + .fill_modes = drm_helper_probe_single_connector_modes, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int vkms_conn_get_modes(struct drm_connector *connector) +{ + int count; + + /* Use the default modes list from DRM */ + count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX); + drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF); + + return count; +} + +static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = { + .get_modes = vkms_conn_get_modes, +}; + +struct drm_connector *vkms_connector_init(struct vkms_device *vkmsdev) +{ + struct drm_device *dev = &vkmsdev->drm; + struct drm_connector *connector; + int ret; + + connector = drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL); + if (!connector) + return ERR_PTR(-ENOMEM); + + ret = drmm_connector_init(dev, connector, &vkms_connector_funcs, + DRM_MODE_CONNECTOR_VIRTUAL, NULL); + if (ret) + return ERR_PTR(ret); + + drm_connector_helper_add(connector, &vkms_conn_helper_funcs); + + return connector; +} diff --git a/drivers/gpu/drm/vkms/vkms_connector.h b/drivers/gpu/drm/vkms/vkms_connector.h new file mode 100644 index 000000000000..beb5ebe09155 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_connector.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _VKMS_CONNECTOR_H_ +#define _VKMS_CONNECTOR_H_ + +#include "vkms_drv.h" + +/** + * vkms_connector_init() - Initialize a connector + * @vkmsdev: VKMS device containing the connector + * + * Returns: + * The connector or an error on failure. + */ +struct drm_connector *vkms_connector_init(struct vkms_device *vkmsdev); + +#endif /* _VKMS_CONNECTOR_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 22f0d678af3a..b01c3e9289d0 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -1,32 +1,8 @@ // SPDX-License-Identifier: GPL-2.0+ +#include "vkms_connector.h" #include "vkms_drv.h" -#include -#include #include -#include - -static const struct drm_connector_funcs vkms_connector_funcs = { - .fill_modes = drm_helper_probe_single_connector_modes, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static int vkms_conn_get_modes(struct drm_connector *connector) -{ - int count; - - /* Use the default modes list from DRM */ - count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX); - drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF); - - return count; -} - -static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = { - .get_modes = vkms_conn_get_modes, -}; int vkms_output_init(struct vkms_device *vkmsdev) { @@ -73,21 +49,12 @@ int vkms_output_init(struct vkms_device *vkmsdev) } } - connector = drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL); - if (!connector) { - DRM_ERROR("Failed to allocate connector\n"); - return -ENOMEM; - } - - ret = drmm_connector_init(dev, connector, &vkms_connector_funcs, - DRM_MODE_CONNECTOR_VIRTUAL, NULL); - if (ret) { + connector = vkms_connector_init(vkmsdev); + if (IS_ERR(connector)) { DRM_ERROR("Failed to init connector\n"); - return ret; + return PTR_ERR(connector); } - drm_connector_helper_add(connector, &vkms_conn_helper_funcs); - encoder = drmm_kzalloc(dev, sizeof(*encoder), GFP_KERNEL); if (!encoder) { DRM_ERROR("Failed to allocate encoder\n"); From patchwork Mon Feb 17 10:01:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977432 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 76C45C021A7 for ; Mon, 17 Feb 2025 10:01:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E845610E3D0; Mon, 17 Feb 2025 10:01:34 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="MJ77jEsY"; dkim-atps=neutral Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.54]) by gabe.freedesktop.org (Postfix) with ESMTPS id CEED610E3C2 for ; Mon, 17 Feb 2025 10:01:27 +0000 (UTC) Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-38f3ac22948so613759f8f.0 for ; Mon, 17 Feb 2025 02:01:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786486; x=1740391286; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=prbaD9EEGSsUeJKiTeBVWVOJfwbyTxNyFRLpyPWOntc=; b=MJ77jEsYkiIQzIFwH1tfgPVUe5E8ikv6BammqNf1nF3Ib7DI89qTTf+eVTA0hRatYc Bl4WiScHNMwmcK3CyRoFhEDQWgc4XGxOmirSqSmN/yayDzMMNmI5Gam/LRrgypk0UZRZ L8zrpI9o0V1WMCVdK0qyFipSuGLfTxX5purpyV2cFQQDx3lCnDfiyUtehY92z4CeZjxz MOnUQNAPcepUAqkuGZPiCpkBS1cuOffUVqXj6vbhD2HKkiSvYAzd5sWPS9FDaqlcYPHE OMwHzAwuM8LpVtehWPkL2Xf5HTNVyXJOYYzRQ6Fc5UZMFljgWMTevQ6R7La2avdrh9as NV6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786486; x=1740391286; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=prbaD9EEGSsUeJKiTeBVWVOJfwbyTxNyFRLpyPWOntc=; b=PE45ZUfsmVh78plV157C9lOa1K6Zf3XnswNZ5fr5FvBZWaZh9LcvWpwkcBvXq2is+3 GHP9HGPTnMbefiufD4OYtyE03LLNQ603w8ReTuTLevEGVmFYSHLLjjOzU+A6KvVxfUhe MQXjLK1QbJphJcBuBdR0WCkBA4lINdo/RDzA+4qzBYNWJVd6sCfAjUr+xk9RK+sqJ5L0 L/31njfB7uoJDoNZIp8ZT8qJXB3z3m+Sdh1cbvfeW6P0xH1Fq6msldhRrSD9TM/hYGae /vv4ip4GXfuBxqRjvVX/Nu6IBMzMzJ9x7BQsNOCESzMyYi3ypaodMCDEhqv6Jsa8EVqv XG4w== X-Forwarded-Encrypted: i=1; AJvYcCWjRRwY7tumybgOSLunmZ6q1SGWmdshAbGeLmrqUyxsaKRLbrRgkJJ/mZbfvf+DbfMTOhkoJIbe6tw=@lists.freedesktop.org X-Gm-Message-State: AOJu0YyAnSExaszvp+YhB+7JkfDxcQGBPv9P5drAQDx2UgE/eEjUQW3V n0Vxh9cf+bzrOX9MhEXWlAsqcbSPo+cmkaLqs+COtrN4sc8oJ9uW X-Gm-Gg: ASbGncvDGJ6fPmv9l061eqOc70Mm0n4TlOGdxNVNbjfBQM7hAfik3hupvKc9Sovs0XN LxkD6WaYdRI8ARK6mrCqG84uikBnuNlUco8k5wvGuve0+ZqqSw+64an2LP46ZFyS4JrPm/+DQCa psXqunP7zrANKfbW24FsxyubYUF34jU7RW2r8IYZdkry3xdJc8gLw91SjV8VWhAMwDtTOzdVH6K KgSZLIMg72MomvkplcPNeh6SJqthbS8q5JKhaiSOpObPbhYhodf+mjJ07xz+KUL+aO270YOoGL4 ApAgSfiCnMUsXpocmA== X-Google-Smtp-Source: AGHT+IEdub1ENivcRK+0XnYHr4w7hyC6AU7B2PacCu2x37x4fKN/+Z9glwiYOFaDq7cRKGtz5fNHfw== X-Received: by 2002:a5d:6d06:0:b0:38f:4cdc:5d36 with SMTP id ffacd0b85a97d-38f4cdc605bmr768718f8f.43.1739786486004; Mon, 17 Feb 2025 02:01:26 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:25 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 02/14] drm/vkms: Create vkms_connector struct Date: Mon, 17 Feb 2025 11:01:08 +0100 Message-ID: <20250217100120.7620-3-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Create a structure wrapping the drm_connector. Reviewed-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/vkms_connector.c | 8 ++++---- drivers/gpu/drm/vkms/vkms_connector.h | 11 ++++++++++- drivers/gpu/drm/vkms/vkms_output.c | 4 ++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/vkms_connector.c index fc97f265dea6..ab8b52a84151 100644 --- a/drivers/gpu/drm/vkms/vkms_connector.c +++ b/drivers/gpu/drm/vkms/vkms_connector.c @@ -29,22 +29,22 @@ static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = { .get_modes = vkms_conn_get_modes, }; -struct drm_connector *vkms_connector_init(struct vkms_device *vkmsdev) +struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev) { struct drm_device *dev = &vkmsdev->drm; - struct drm_connector *connector; + struct vkms_connector *connector; int ret; connector = drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL); if (!connector) return ERR_PTR(-ENOMEM); - ret = drmm_connector_init(dev, connector, &vkms_connector_funcs, + ret = drmm_connector_init(dev, &connector->base, &vkms_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL, NULL); if (ret) return ERR_PTR(ret); - drm_connector_helper_add(connector, &vkms_conn_helper_funcs); + drm_connector_helper_add(&connector->base, &vkms_conn_helper_funcs); return connector; } diff --git a/drivers/gpu/drm/vkms/vkms_connector.h b/drivers/gpu/drm/vkms/vkms_connector.h index beb5ebe09155..c9149c1b7af0 100644 --- a/drivers/gpu/drm/vkms/vkms_connector.h +++ b/drivers/gpu/drm/vkms/vkms_connector.h @@ -5,6 +5,15 @@ #include "vkms_drv.h" +/** + * struct vkms_connector - VKMS custom type wrapping around the DRM connector + * + * @drm: Base DRM connector + */ +struct vkms_connector { + struct drm_connector base; +}; + /** * vkms_connector_init() - Initialize a connector * @vkmsdev: VKMS device containing the connector @@ -12,6 +21,6 @@ * Returns: * The connector or an error on failure. */ -struct drm_connector *vkms_connector_init(struct vkms_device *vkmsdev); +struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev); #endif /* _VKMS_CONNECTOR_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index b01c3e9289d0..4b5abe159add 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -7,7 +7,7 @@ int vkms_output_init(struct vkms_device *vkmsdev) { struct drm_device *dev = &vkmsdev->drm; - struct drm_connector *connector; + struct vkms_connector *connector; struct drm_encoder *encoder; struct vkms_output *output; struct vkms_plane *primary, *overlay, *cursor = NULL; @@ -69,7 +69,7 @@ int vkms_output_init(struct vkms_device *vkmsdev) encoder->possible_crtcs = drm_crtc_mask(&output->crtc); /* Attach the encoder and the connector */ - ret = drm_connector_attach_encoder(connector, encoder); + ret = drm_connector_attach_encoder(&connector->base, encoder); if (ret) { DRM_ERROR("Failed to attach connector to encoder\n"); return ret; From patchwork Mon Feb 17 10:01:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977433 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 17D3BC0219E for ; Mon, 17 Feb 2025 10:01:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2F5FB10E3D6; Mon, 17 Feb 2025 10:01:35 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="T4FdGYiC"; dkim-atps=neutral Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4193C10E3C2 for ; Mon, 17 Feb 2025 10:01:29 +0000 (UTC) Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-38f31f7731fso1201245f8f.0 for ; Mon, 17 Feb 2025 02:01:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786488; x=1740391288; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XyJ4zhCFR8HQ/P+sh2alNxUJOEd+yUChQD9LZjyxME0=; b=T4FdGYiCc+ddcub9Bzz5o8OiJ/rVZq0bmKDJgUEumplC/6Bc23NSaEG54R2PnIi7yz AhlhS8syzXsZaAaxVbjU7rthczUwq2H5CpIzlxIVP0RXgRbSLY0aas6hkbgzuB93RbPZ fGBNOEnKWWasvtrGN7A3PzWOyzqWpa3cmvk42YaP/hnDMP6vtjqhDhonZlJVHxwHzdwX R/3XTYcdbHA8vqojS8rODGTMTNTcPd/iFspwR0BF7s2R4hKptthALIGs29Y7a9eFPHlJ 2G0jyIN85mbJ/wrw0o6YhElvo2Tq0K4iysk82SZuUnqM/PfysiOjvN/VsutdfBK1NSpk Fzlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786488; x=1740391288; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XyJ4zhCFR8HQ/P+sh2alNxUJOEd+yUChQD9LZjyxME0=; b=DckG3e8GLI21v+GB2d3dpHy34LqrLGmeTesnU45gZLHi167oavnZoqsu5/H/YfWQdY 3i7SD7Id86EWCeLacyV/AUY1sta7isT9YwYh+nQRiuXtHKfj6HzflKkioUgXFnhcBUrW tTssMMF5aoR0Lh5HsfYFpKjxsjEGaXC9+iVfB37j7hSyfi+iX6GPwl/RpXT/jmte0+j9 Gv0akh5i9F/52utsJ3S8cFxiauaVwHka2KB7OdqUZ6eLsItADqHVUockB/sq5fNvLKCL Aoo9S6/hDqWAYEa6160RN4qRJQhOYB54eiH+0+S0c+D21RRJgUegxzc/vxxspRbcZ2wH KfkA== X-Forwarded-Encrypted: i=1; AJvYcCWmiMyfX3G7Iqpr4Uz+7x11KbSjWkh+qep55cxSvwrWYHhyo3QyOBz88wUeO0yHEHw/70mBIKSdwXs=@lists.freedesktop.org X-Gm-Message-State: AOJu0YzS9/X+/v3GZdJuHfddQ2GC55xbn3AC2cpI9DaPFX4TbFbfmftR ap2RbNj/jgWFeY1osl/No4PUBUgBEjm+Y5MiZF7+WIScPtrG4QMv X-Gm-Gg: ASbGncsh2j7xCGX6Ebs0+B9yAIaG630R5Ldl8tdh+3nkdJpCYSk+Gb5yk48ZBT2vUoH Z/calaj71wvDqgVyt739uLBWa/OZvkUQOFBKZ8P03n/H61FPehuUCZspwp6/L8M5UCNydsaoUzl wqji0et3eq323NQIoltxV5cQr6ksUv/MpciJ2r5u2YziJPHe3VClh2dDak5Gx5ZGAMeQpwgVqpL WFtfkeKeAPFTCVkF3MRurr27M/qarnpjhbBZd08Cfkq/Suom4icY8pMvOaG6VvsDOjwq3m2nqmf YDFW9iElmT12wMYxvQ== X-Google-Smtp-Source: AGHT+IEgChZS1TM0yOWscdOUtGj2+t/pNHUL4Ncpoj0PJEzTn8rZEI3vhQLyexaVQtcmkHYF3tLn/w== X-Received: by 2002:a05:6000:18a9:b0:38f:2193:f8c2 with SMTP id ffacd0b85a97d-38f33f34e32mr8698968f8f.31.1739786487650; Mon, 17 Feb 2025 02:01:27 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:26 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= , Arthur Grillo Subject: [PATCH v3 03/14] drm/vkms: Add KUnit test scaffolding Date: Mon, 17 Feb 2025 11:01:09 +0100 Message-ID: <20250217100120.7620-4-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add the required boilerplate to start creating KUnit test. To run the tests: $ ./tools/testing/kunit/kunit.py run \ --kunitconfig=drivers/gpu/drm/vkms/tests Reviewed-by: Louis Chauvet Co-developed-by: Arthur Grillo Signed-off-by: Arthur Grillo Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/Kconfig | 15 +++++++++++++++ drivers/gpu/drm/vkms/Makefile | 1 + drivers/gpu/drm/vkms/tests/.kunitconfig | 4 ++++ drivers/gpu/drm/vkms/tests/Makefile | 3 +++ drivers/gpu/drm/vkms/tests/vkms_config_test.c | 19 +++++++++++++++++++ 5 files changed, 42 insertions(+) create mode 100644 drivers/gpu/drm/vkms/tests/.kunitconfig create mode 100644 drivers/gpu/drm/vkms/tests/Makefile create mode 100644 drivers/gpu/drm/vkms/tests/vkms_config_test.c diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig index 9def079f685b..3c02f928ffe6 100644 --- a/drivers/gpu/drm/vkms/Kconfig +++ b/drivers/gpu/drm/vkms/Kconfig @@ -14,3 +14,18 @@ config DRM_VKMS a VKMS. If M is selected the module will be called vkms. + +config DRM_VKMS_KUNIT_TEST + tristate "KUnit tests for VKMS" if !KUNIT_ALL_TESTS + depends on DRM_VKMS && KUNIT + default KUNIT_ALL_TESTS + help + This builds unit tests for VKMS. This option is not useful for + distributions or general kernels, but only for kernel + developers working on VKMS. + + For more information on KUnit and unit tests in general, + please refer to the KUnit documentation in + Documentation/dev-tools/kunit/. + + If in doubt, say "N". diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index 6b0615c424f2..c23eee2f3df4 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -10,3 +10,4 @@ vkms-y := \ vkms_connector.o obj-$(CONFIG_DRM_VKMS) += vkms.o +obj-$(CONFIG_DRM_VKMS_KUNIT_TEST) += tests/ diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig b/drivers/gpu/drm/vkms/tests/.kunitconfig new file mode 100644 index 000000000000..6a2d87068edc --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/.kunitconfig @@ -0,0 +1,4 @@ +CONFIG_KUNIT=y +CONFIG_DRM=y +CONFIG_DRM_VKMS=y +CONFIG_DRM_VKMS_KUNIT_TEST=y diff --git a/drivers/gpu/drm/vkms/tests/Makefile b/drivers/gpu/drm/vkms/tests/Makefile new file mode 100644 index 000000000000..9ded37b67a46 --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_DRM_VKMS_KUNIT_TEST) += vkms_config_test.o diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c new file mode 100644 index 000000000000..1177e62e19cb --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include + +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); + +static struct kunit_case vkms_config_test_cases[] = { + {} +}; + +static struct kunit_suite vkms_config_test_suite = { + .name = "vkms-config", + .test_cases = vkms_config_test_cases, +}; + +kunit_test_suite(vkms_config_test_suite); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Kunit test for vkms config utility"); From patchwork Mon Feb 17 10:01:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977431 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5318AC0219E for ; Mon, 17 Feb 2025 10:01:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AE52810E3E0; Mon, 17 Feb 2025 10:01:32 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hHOlVkRH"; dkim-atps=neutral Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) by gabe.freedesktop.org (Postfix) with ESMTPS id D180510E3C2 for ; Mon, 17 Feb 2025 10:01:30 +0000 (UTC) Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-38f2c4382d1so1522951f8f.0 for ; Mon, 17 Feb 2025 02:01:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786489; x=1740391289; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LmDfaEOjc70HjJgnj7sLGaZRyHuUKTvYVGnXm2VRbiY=; b=hHOlVkRHIyZWBEASiOOlZ82JpH27/TbsTH61bTAlXimFC/CPvewTTzqbn84IdjmiHe /JLonYmjNo7Dz1kSr1erE6F56c/55d3HZpUEH1osUSGaRC9sBSSM9UndcuCUacYic/jR bNDRHdIEX/g7dcE2M8KORMq4Ke/6Tc2Iez1UTCzaj7DYRmNPyOMB6VfdIvs3BihFBrYo AKeV3b+7WKVktYHxdgfq114SM2uqr9U5ZhRj6iLW2qgtK0yJoUFqr+pV9UcHRuesnmui rrVwMQi+oRqnMqfQDdwijjcDEbOnvt11TTfZpdxNLh1tjE3Xfmc/JVcF+hjO6ArbDu9q B+Bw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786489; x=1740391289; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LmDfaEOjc70HjJgnj7sLGaZRyHuUKTvYVGnXm2VRbiY=; b=I2H1K9szUs+uai0g18Z1pIJ0FiRNyUaXzurKiNLk2iCd+NfdMr9eds9rzZ4p+TJot/ yXQbz/johW7o41Xwa601l3kMM68DanEM5ukompE7+N5jhu9NPA4N60Q3nkjKcR5K+k2U /uKuTuccbrglWLfTG3WxpaotdGq9YBj8n+ktvyEVp0VV0Og+fQu0Z2McFZDO5nRC9wXE J50tHozDUFPRsAM9I/vx0Bbd7yrdaMMNiay/pTqugrZcukFm3SK0/hpAM7IMoSqe/03l w/6WwxcCoQIxritHweWZSKAS3F5ojWNh9Bme/uqnEzC3OkDPBNNKjxLC1pm94ChKXAjk GvaQ== X-Forwarded-Encrypted: i=1; AJvYcCX912D0vlsjjBHv5yAtfPzYdSIyKXd1FZ9sndSFNEcbYgaIrz475PEpJU/EAgVqMV9xt6KxNBa62w4=@lists.freedesktop.org X-Gm-Message-State: AOJu0YwxZmKPTW4vI1Xxo+Wm0b+jIIp2guPWRDcFUIZNqJyCEU8+GO5+ 7zCdjuwIdRfwjysfys2ogrBoJoNxo3S6qxx7dz57t7P5S8MTJ1Zu X-Gm-Gg: ASbGnctshSvAg/Q14Y0PQVq3bqtXm9dEyp8C7Jzfkv4xYe0YK0FGCwVz7cEbnq4G2JR ilk3ntt0qe+gBCqEFQT5KMYsn0v3jOzhV9q085cfKm2+pLs9GJoqTNIj/ZbR0HyUZbsDezkBwxx Vg851o26+ev/QEDFLyoeLVoQXvqA959dTajF5oU/jo5PMPJOB6zI19ZOv19qSAjp+ge85phIW4w bB137gv9DctD8O1VrxXRAvVktfqSGp3Dl+OV02oqyvkNLpiU9ngDZA8LMH7AoMMnogsnOiMyX/8 +kThkcTCRHxTE8RR+A== X-Google-Smtp-Source: AGHT+IHstdjpSigFhN2igJJ+uFQJmFbHjahhv3wT/oTulr2cNaKb5gAC3MJK+5fY4aO6oDo3PD9wcQ== X-Received: by 2002:a05:6000:154b:b0:38d:a695:6daf with SMTP id ffacd0b85a97d-38f33c20c39mr9565959f8f.19.1739786488810; Mon, 17 Feb 2025 02:01:28 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:28 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 04/14] drm/vkms: Extract vkms_config header Date: Mon, 17 Feb 2025 11:01:10 +0100 Message-ID: <20250217100120.7620-5-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Creating a new vkms_config structure will be more complex once we start adding more options. Extract the vkms_config structure to its own header and source files and add functions to create and delete a vkms_config and to initialize debugfs. Refactor, no functional changes. Reviewed-by: Louis Chauvet Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/Makefile | 3 +- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 13 +++++ drivers/gpu/drm/vkms/vkms_config.c | 50 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 47 +++++++++++++++++ drivers/gpu/drm/vkms/vkms_drv.c | 34 +++---------- drivers/gpu/drm/vkms/vkms_drv.h | 15 +----- drivers/gpu/drm/vkms/vkms_output.c | 1 + 7 files changed, 121 insertions(+), 42 deletions(-) create mode 100644 drivers/gpu/drm/vkms/vkms_config.c create mode 100644 drivers/gpu/drm/vkms/vkms_config.h diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index c23eee2f3df4..d657865e573f 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -7,7 +7,8 @@ vkms-y := \ vkms_crtc.o \ vkms_composer.o \ vkms_writeback.o \ - vkms_connector.o + vkms_connector.o \ + vkms_config.o obj-$(CONFIG_DRM_VKMS) += vkms.o obj-$(CONFIG_DRM_VKMS_KUNIT_TEST) += tests/ diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 1177e62e19cb..a7060504f3dc 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -2,9 +2,22 @@ #include +#include "../vkms_config.h" + MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); +static void vkms_config_test_empty_config(struct kunit *test) +{ + struct vkms_config *config; + + config = vkms_config_create(); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] = { + KUNIT_CASE(vkms_config_test_empty_config), {} }; diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c new file mode 100644 index 000000000000..42caa421876e --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include + +#include +#include +#include + +#include "vkms_config.h" + +struct vkms_config *vkms_config_create(void) +{ + struct vkms_config *config; + + config = kzalloc(sizeof(*config), GFP_KERNEL); + if (!config) + return ERR_PTR(-ENOMEM); + + return config; +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_create); + +void vkms_config_destroy(struct vkms_config *config) +{ + kfree(config); +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy); + +static int vkms_config_show(struct seq_file *m, void *data) +{ + struct drm_debugfs_entry *entry = m->private; + struct drm_device *dev = entry->dev; + struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev); + + seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback); + seq_printf(m, "cursor=%d\n", vkmsdev->config->cursor); + seq_printf(m, "overlay=%d\n", vkmsdev->config->overlay); + + return 0; +} + +static const struct drm_debugfs_info vkms_config_debugfs_list[] = { + { "vkms_config", vkms_config_show, 0 }, +}; + +void vkms_config_register_debugfs(struct vkms_device *vkms_device) +{ + drm_debugfs_add_files(&vkms_device->drm, vkms_config_debugfs_list, + ARRAY_SIZE(vkms_config_debugfs_list)); +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h new file mode 100644 index 000000000000..ced10f56a812 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _VKMS_CONFIG_H_ +#define _VKMS_CONFIG_H_ + +#include + +#include "vkms_drv.h" + +/** + * 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 device + * @dev: Used to store the current VKMS device. Only set when the device is instantiated. + */ +struct vkms_config { + bool writeback; + bool cursor; + bool overlay; + struct vkms_device *dev; +}; + +/** + * vkms_config_create() - Create a new VKMS configuration + * + * Returns: + * The new vkms_config or an error. Call vkms_config_destroy() to free the + * returned configuration. + */ +struct vkms_config *vkms_config_create(void); + +/** + * vkms_config_destroy() - Free a VKMS configuration + * @config: vkms_config to free + */ +void vkms_config_destroy(struct vkms_config *config); + +/** + * vkms_config_register_debugfs() - Register a debugfs file to show the device's + * configuration + * @vkms_device: Device to register + */ +void vkms_config_register_debugfs(struct vkms_device *vkms_device); + +#endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index b6de91134a22..37de0658e6ee 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -27,11 +27,9 @@ #include #include +#include "vkms_config.h" #include "vkms_drv.h" -#include -#include - #define DRIVER_NAME "vkms" #define DRIVER_DESC "Virtual Kernel Mode Setting" #define DRIVER_MAJOR 1 @@ -81,23 +79,6 @@ static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state) drm_atomic_helper_cleanup_planes(dev, old_state); } -static int vkms_config_show(struct seq_file *m, void *data) -{ - struct drm_debugfs_entry *entry = m->private; - struct drm_device *dev = entry->dev; - struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev); - - seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback); - seq_printf(m, "cursor=%d\n", vkmsdev->config->cursor); - seq_printf(m, "overlay=%d\n", vkmsdev->config->overlay); - - return 0; -} - -static const struct drm_debugfs_info vkms_config_debugfs_list[] = { - { "vkms_config", vkms_config_show, 0 }, -}; - static const struct drm_driver vkms_driver = { .driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM, .fops = &vkms_driver_fops, @@ -208,8 +189,7 @@ static int vkms_create(struct vkms_config *config) if (ret) goto out_devres; - drm_debugfs_add_files(&vkms_device->drm, vkms_config_debugfs_list, - ARRAY_SIZE(vkms_config_debugfs_list)); + vkms_config_register_debugfs(vkms_device); ret = drm_dev_register(&vkms_device->drm, 0); if (ret) @@ -231,9 +211,9 @@ static int __init vkms_init(void) int ret; struct vkms_config *config; - config = kmalloc(sizeof(*config), GFP_KERNEL); - if (!config) - return -ENOMEM; + config = vkms_config_create(); + if (IS_ERR(config)) + return PTR_ERR(config); config->cursor = enable_cursor; config->writeback = enable_writeback; @@ -241,7 +221,7 @@ static int __init vkms_init(void) ret = vkms_create(config); if (ret) { - kfree(config); + vkms_config_destroy(config); return ret; } @@ -275,7 +255,7 @@ static void __exit vkms_exit(void) return; vkms_destroy(default_config); - kfree(default_config); + vkms_config_destroy(default_config); } module_init(vkms_init); diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index abbb652be2b5..af7081c940d6 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -189,20 +189,7 @@ struct vkms_output { spinlock_t composer_lock; }; -/** - * 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 device - * @dev: Used to store the current VKMS device. Only set when the device is instantiated. - */ -struct vkms_config { - bool writeback; - bool cursor; - bool overlay; - struct vkms_device *dev; -}; +struct vkms_config; /** * struct vkms_device - Description of a VKMS device diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 4b5abe159add..068a7f87ecec 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ +#include "vkms_config.h" #include "vkms_connector.h" #include "vkms_drv.h" #include From patchwork Mon Feb 17 10:01:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977434 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 609F8C021A1 for ; Mon, 17 Feb 2025 10:01:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5EE5E10E3E3; Mon, 17 Feb 2025 10:01:35 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="XQTEPKY3"; dkim-atps=neutral Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) by gabe.freedesktop.org (Postfix) with ESMTPS id A3C8B10E3C2 for ; Mon, 17 Feb 2025 10:01:31 +0000 (UTC) Received: by mail-wr1-f46.google.com with SMTP id ffacd0b85a97d-38f24fc466aso2962212f8f.2 for ; Mon, 17 Feb 2025 02:01:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786490; x=1740391290; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=an4ZlObHhfs530zfnSQ9jtNvfBOIXbJcmgdk2xLIJkM=; b=XQTEPKY3jvscGyvsI6wmog46FHPzOfj7VM/CxucV/kxgTP9bZp0B/wGL2rtdN1676Y H1mosfuY1vjrP/uVUNI3yF+Tb2+TOgclWdpz7kl5zyZDx+rWThqnj5TWTqLSHT6lj3KL iP2ySc2cdsbmnj525WhA8n0DE1XRtBAu7Kq2EagxlsXhs9xRqat5hvuCmDy6P1YI84uG bBRUoci83nxYnN18QtAX0ahaeVJb8whhhrtKBGXX271sua6NkBM5V4kvqH0vSeWlR8Tr kci9jkGMBpOm29SU+2IQ3eNojXoT547sNhP868aFCHQ12Hnd6oeCHAYsL5Y+eRt5cKvT kUPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786490; x=1740391290; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=an4ZlObHhfs530zfnSQ9jtNvfBOIXbJcmgdk2xLIJkM=; b=j19AOTYQXiK74GLxbI8cAHdmD4Tr9peV1yjqI93dnuYTZPqEFvAfAu0qS+Tgr5PjUa W9d9c+05lQhUVH9W0ec8QzXAirW0qEbhVnf0g0dlAMwU5MKnLB2Pj686I4MAw27ApA6p w0lQd3IL1ClsPmEc0R0uLFJhTzL00T71TjovfmKt2iWnPkCswJbNBVhUQU0L1UZV9wql 1EirhpyQhPsfLRRxHv528vLip7XtBmh/oZf+bZP/BnSAw8KY2XlEqeFKxDAANj0e9EB3 hXC1sXvmu/5j3XYLUw6HCqYEzxjfYs/IKXR+dUvX3H+WAGaPC8DeEHf679uWhiagrAhM N/BQ== X-Forwarded-Encrypted: i=1; AJvYcCVyQeJe5B8AVwUfKt5kHen+xCgQJUKIRGAT2eVsUAsYiHyPz737TivR8gmAjOJ/4BjU7OPlV0eiU3k=@lists.freedesktop.org X-Gm-Message-State: AOJu0Yy0zcdKj2k4LL7Oo2snRQbBDViX5ycj2E/6O3Fi8O8Po84m8pi9 PmCQtaJFO1/csAoSArwHxUSc9IKnl6Evhj7eWZt13Gts8NaBj4vw X-Gm-Gg: ASbGncvyCna7NS8lnfGrXCTW4sUz4OPljMRpKH42jj/nWh12FtxRE74qposCxlbzNSj hnIfA6wYzgtcwZN7i/wVjd8+i3+aevI5bMhPibzilst09PYrmvx2J5GrzHhGHVcsc5PR9pqPJlT +iunAOLVK6jJ0bk/XTLv47WFM7jdauXvl4h3TOjwL4WWWq06JTR4q0VdiHHTVLsKQlCdLQRvOZf K4SbzEwEzm7r5wP4UKhvRwU2lC5tr/Cs1aHRQe0gAMmh+XAfG71SB5X2vZiG+MrLCGZP17wMOHf dyPmQ+b2q7TMepI/Tg== X-Google-Smtp-Source: AGHT+IH4CwihIwVZG7tSArR4NUMsOT3lALCUrNrAZruadVHeYFhmux5YvQbpgfyRoPVEoAAf3qpcFg== X-Received: by 2002:a5d:5f4e:0:b0:38f:329a:270f with SMTP id ffacd0b85a97d-38f3406787cmr9234492f8f.39.1739786489831; Mon, 17 Feb 2025 02:01:29 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:29 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 05/14] drm/vkms: Move default_config creation to its own function Date: Mon, 17 Feb 2025 11:01:11 +0100 Message-ID: <20250217100120.7620-6-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Extract the initialization of the default configuration to a function. Refactor, no functional changes. Reviewed-by: Louis Chauvet Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 38 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 18 +++++++++ drivers/gpu/drm/vkms/vkms_config.h | 14 +++++++ drivers/gpu/drm/vkms/vkms_drv.c | 6 +-- 4 files changed, 71 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index a7060504f3dc..d8644a1e3e18 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -6,6 +6,12 @@ MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); +struct default_config_case { + bool enable_cursor; + bool enable_writeback; + bool enable_overlay; +}; + static void vkms_config_test_empty_config(struct kunit *test) { struct vkms_config *config; @@ -16,8 +22,40 @@ static void vkms_config_test_empty_config(struct kunit *test) vkms_config_destroy(config); } +static struct default_config_case default_config_cases[] = { + { false, false, false }, + { true, false, false }, + { true, true, false }, + { true, false, true }, + { false, true, false }, + { false, true, true }, + { false, false, true }, + { true, true, true }, +}; + +KUNIT_ARRAY_PARAM(default_config, default_config_cases, NULL); + +static void vkms_config_test_default_config(struct kunit *test) +{ + const struct default_config_case *params = test->param_value; + struct vkms_config *config; + + config = vkms_config_default_create(params->enable_cursor, + params->enable_writeback, + params->enable_overlay); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + KUNIT_EXPECT_EQ(test, config->cursor, params->enable_cursor); + KUNIT_EXPECT_EQ(test, config->writeback, params->enable_writeback); + KUNIT_EXPECT_EQ(test, config->overlay, params->enable_overlay); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_empty_config), + KUNIT_CASE_PARAM(vkms_config_test_default_config, + default_config_gen_params), {} }; diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index 42caa421876e..0af8e6dc0a01 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -20,6 +20,24 @@ struct vkms_config *vkms_config_create(void) } EXPORT_SYMBOL_IF_KUNIT(vkms_config_create); +struct vkms_config *vkms_config_default_create(bool enable_cursor, + bool enable_writeback, + bool enable_overlay) +{ + struct vkms_config *config; + + config = vkms_config_create(); + if (IS_ERR(config)) + return config; + + config->cursor = enable_cursor; + config->writeback = enable_writeback; + config->overlay = enable_overlay; + + return config; +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_default_create); + void vkms_config_destroy(struct vkms_config *config) { kfree(config); diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index ced10f56a812..d0868750826a 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -31,6 +31,20 @@ struct vkms_config { */ struct vkms_config *vkms_config_create(void); +/** + * vkms_config_default_create() - Create the configuration for the default device + * @enable_cursor: Create or not a cursor plane + * @enable_writeback: Create or not a writeback connector + * @enable_overlay: Create or not overlay planes + * + * Returns: + * The default vkms_config or an error. Call vkms_config_destroy() to free the + * returned configuration. + */ +struct vkms_config *vkms_config_default_create(bool enable_cursor, + bool enable_writeback, + bool enable_overlay); + /** * vkms_config_destroy() - Free a VKMS configuration * @config: vkms_config to free diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 37de0658e6ee..582d5825f42b 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -211,14 +211,10 @@ static int __init vkms_init(void) int ret; struct vkms_config *config; - config = vkms_config_create(); + config = vkms_config_default_create(enable_cursor, enable_writeback, enable_overlay); if (IS_ERR(config)) return PTR_ERR(config); - config->cursor = enable_cursor; - config->writeback = enable_writeback; - config->overlay = enable_overlay; - ret = vkms_create(config); if (ret) { vkms_config_destroy(config); From patchwork Mon Feb 17 10:01:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977435 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 65920C021A9 for ; Mon, 17 Feb 2025 10:01:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 060B810E3E8; Mon, 17 Feb 2025 10:01:36 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="kfBiTJ2u"; dkim-atps=neutral Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) by gabe.freedesktop.org (Postfix) with ESMTPS id A920410E3D6 for ; Mon, 17 Feb 2025 10:01:32 +0000 (UTC) Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-38f1e8efe82so4545441f8f.0 for ; Mon, 17 Feb 2025 02:01:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786491; x=1740391291; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TJKka9BGXo5aWskaWZaSFDrSIvgDMiHYo6XxF9H8dkw=; b=kfBiTJ2uGQpFtxe7AmAGOdn/JBWNBB97QNwDN0lGr4xRvj1cAR2pPMp4phazCDd6CC s7hiWNGQ1QxhQhTs8cE4Wa2vSttLfrCNEpFNEp3doEjKnlvUQhNy15JoVcEkfMADG5Qt mG395B75oVfUwiiH4N2oAjECSiFXWB4cxRD75yo/coiGfoLPCnZ5l4FGLDwxvbE0Loj+ XslttuaHeLmg2FVes7MSEIHUIRFVu75YxaM0kHwPOgvxJrcJRBylE/8lsEynhiEp4e1L ypItkpdXwnlY2LNemHmq1jp5iR4x4yyTgb5px8RQoSmQXzcNX6Y+JW+JlsxnCfwh48RU dRUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786491; x=1740391291; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TJKka9BGXo5aWskaWZaSFDrSIvgDMiHYo6XxF9H8dkw=; b=sXvsGPQpZs7v803booTe9q7KtFU2smM18PdnnjrnxE/4AzF027H9v6U+VxjM9KxKae d5gzM9xw8VsfH4jEaEpS2bpUXbrUXFYivwMigKE+33VqpQGqdx8nbYJ5drhiMuXw4I/X U15ufIYmmSmww0V1LwD0EhdoAg4iKrsq9I53INJWAYi2HCkuZXdGSevA9UiqLzqEdvlZ UEmgM1ic9Dtt5LxhT5zyK8foJz2MyvPOsN42OqQvHwRdty671M9xPTP1DdrELJmiz0nP CdHcA1i+UWaNEUY+cTCYC8gz82OSk26KKPy8VLIHWUB9mrl4/5bIkWXSXCkuopd/lpsY aeEg== X-Forwarded-Encrypted: i=1; AJvYcCUZt2s/inGAvLBEttOKP/NI9HGjbpOl03doPYlW//Bg8kZ9Fx29tYn0MouJ5LVMQ6KxrAwHUfpXDIQ=@lists.freedesktop.org X-Gm-Message-State: AOJu0YyRrfPnY7NEE8U2+sjYNx3Y4+Vxc2LgVxR/WfRlC5fWFZQtouiE 1hdvVoNW28HNjxxlt2J1mYk15C6I6MB2niBpQnw7tvdluyYvipNE X-Gm-Gg: ASbGncv9rnlGlloWOZqVqV+2QvuTqBn3UGFF/78ABbuAJNEJ6/spJWUA/mOK391JOKk SExuc7Nc8AXpFH7Q22d+QjsXyWNgSH3sR/cSgyaLUSdTZnLkusV9e3gq7brTnU/MH+rh2zND5db Skfib/XjsAfkAUpYTI3Y2bBbfwHl4R8qjC5gk3Bu3o4uScK35+6I5LnvjESh77NqW+DHI6CxoVR 9bHHxsc//aP3OobPCJKgcRrEs/pqYYIJrdgSxyOnvWDEa8kM3JfGVvmDDHMovjciRheTQmEq1Us R2w3d5VBnEimqUgoyA== X-Google-Smtp-Source: AGHT+IEvXRu7nQr9abk46p9Flqt3U0L5kaXWVWty1aavdlHs6R4PCjETBRhWfdtHHenUEDLZusXffQ== X-Received: by 2002:a5d:438c:0:b0:38f:2856:7dc4 with SMTP id ffacd0b85a97d-38f33f62c72mr7168453f8f.55.1739786491049; Mon, 17 Feb 2025 02:01:31 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:30 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 06/14] drm/vkms: Set device name from vkms_config Date: Mon, 17 Feb 2025 11:01:12 +0100 Message-ID: <20250217100120.7620-7-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" In order to be able to create multiple devices, the device name needs to be unique. Allow to set it in the VKMS configuration. Reviewed-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 7 ++++++- drivers/gpu/drm/vkms/vkms_config.c | 14 ++++++++++++-- drivers/gpu/drm/vkms/vkms_config.h | 18 +++++++++++++++++- drivers/gpu/drm/vkms/vkms_drv.c | 4 +++- drivers/gpu/drm/vkms/vkms_drv.h | 2 ++ 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index d8644a1e3e18..92798590051b 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -15,10 +15,15 @@ struct default_config_case { static void vkms_config_test_empty_config(struct kunit *test) { struct vkms_config *config; + const char *dev_name = "test"; - config = vkms_config_create(); + config = vkms_config_create(dev_name); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + /* The dev_name string and the config have different lifetimes */ + dev_name = NULL; + KUNIT_EXPECT_STREQ(test, vkms_config_get_device_name(config), "test"); + vkms_config_destroy(config); } diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index 0af8e6dc0a01..9fb08d94a351 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -8,7 +8,7 @@ #include "vkms_config.h" -struct vkms_config *vkms_config_create(void) +struct vkms_config *vkms_config_create(const char *dev_name) { struct vkms_config *config; @@ -16,6 +16,12 @@ struct vkms_config *vkms_config_create(void) if (!config) return ERR_PTR(-ENOMEM); + config->dev_name = kstrdup_const(dev_name, GFP_KERNEL); + if (!config->dev_name) { + kfree(config); + return ERR_PTR(-ENOMEM); + } + return config; } EXPORT_SYMBOL_IF_KUNIT(vkms_config_create); @@ -26,7 +32,7 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, { struct vkms_config *config; - config = vkms_config_create(); + config = vkms_config_create(DEFAULT_DEVICE_NAME); if (IS_ERR(config)) return config; @@ -40,6 +46,7 @@ EXPORT_SYMBOL_IF_KUNIT(vkms_config_default_create); void vkms_config_destroy(struct vkms_config *config) { + kfree_const(config->dev_name); kfree(config); } EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy); @@ -49,7 +56,10 @@ static int vkms_config_show(struct seq_file *m, void *data) struct drm_debugfs_entry *entry = m->private; struct drm_device *dev = entry->dev; struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev); + const char *dev_name; + dev_name = vkms_config_get_device_name((struct vkms_config *)vkmsdev->config); + seq_printf(m, "dev_name=%s\n", dev_name); seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback); seq_printf(m, "cursor=%d\n", vkmsdev->config->cursor); seq_printf(m, "overlay=%d\n", vkmsdev->config->overlay); diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index d0868750826a..fcaa909fb2e0 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -10,12 +10,14 @@ /** * struct vkms_config - General configuration for VKMS driver * + * @dev_name: Name of the device * @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 device * @dev: Used to store the current VKMS device. Only set when the device is instantiated. */ struct vkms_config { + const char *dev_name; bool writeback; bool cursor; bool overlay; @@ -24,12 +26,13 @@ struct vkms_config { /** * vkms_config_create() - Create a new VKMS configuration + * @dev_name: Name of the device * * Returns: * The new vkms_config or an error. Call vkms_config_destroy() to free the * returned configuration. */ -struct vkms_config *vkms_config_create(void); +struct vkms_config *vkms_config_create(const char *dev_name); /** * vkms_config_default_create() - Create the configuration for the default device @@ -51,6 +54,19 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, */ void vkms_config_destroy(struct vkms_config *config); +/** + * vkms_config_get_device_name() - Return the name of the device + * @config: Configuration to get the device name from + * + * Returns: + * The device name. Only valid while @config is valid. + */ +static inline const char * +vkms_config_get_device_name(struct vkms_config *config) +{ + return config->dev_name; +} + /** * vkms_config_register_debugfs() - Register a debugfs file to show the device's * configuration diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 582d5825f42b..ba977ef09b2b 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -151,8 +151,10 @@ static int vkms_create(struct vkms_config *config) int ret; struct platform_device *pdev; struct vkms_device *vkms_device; + const char *dev_name; - pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); + dev_name = vkms_config_get_device_name(config); + pdev = platform_device_register_simple(dev_name, -1, NULL, 0); if (IS_ERR(pdev)) return PTR_ERR(pdev); diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index af7081c940d6..a74a7fc3a056 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -12,6 +12,8 @@ #include #include +#define DEFAULT_DEVICE_NAME "vkms" + #define XRES_MIN 10 #define YRES_MIN 10 From patchwork Mon Feb 17 10:01:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977436 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 96635C0219E for ; Mon, 17 Feb 2025 10:01:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 046BA10E3FC; Mon, 17 Feb 2025 10:01:43 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="H62TYoIZ"; dkim-atps=neutral Received: from mail-wr1-f50.google.com (mail-wr1-f50.google.com [209.85.221.50]) by gabe.freedesktop.org (Postfix) with ESMTPS id 026F510E3D6 for ; Mon, 17 Feb 2025 10:01:34 +0000 (UTC) Received: by mail-wr1-f50.google.com with SMTP id ffacd0b85a97d-38f378498c9so1388608f8f.1 for ; Mon, 17 Feb 2025 02:01:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786493; x=1740391293; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vG84qkV7BJECjcnd+fwOr4EF0zkS6sxDafqd+tmcLZs=; b=H62TYoIZUkmBms4xjplWgx75yXKFLlQLCjr+7m5Fiv2McYnhsIw7/Jc/xvW1QUx9Xq 8VPVZsJGp5tR74tQ1iAjwl6XpdZMno7n7Nzm99lppeBPe+DB9uPFBH+zgBmJvRZNomRW jH8BO14S9YYJe0aDJwa5v1OxJfmAYljKdta8ZBkG6h2kJRb0Q4A58v4F7htXrL+ARSgv E3AYbzkkPEdGG2sZDETcQfyElNdrxPvFeZUX1XrUU3vSTGVCdR9JSAUQlwOzTr8s8Dca IcH2xhiEJFhIxD21knisFI59f5PIuvOZZhwTAJBINam4YTW/hO3LpT/wrg9DTOw/XrL7 37wg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786493; x=1740391293; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vG84qkV7BJECjcnd+fwOr4EF0zkS6sxDafqd+tmcLZs=; b=EXrcQFfu3tSDBvc9inuOamYXU+uHh6EtP5+Y+nM3NUjf9ZWyQ5xDs99+eRB/BFKpNl sX4A9qbb/Kwg6z9d8kl4btei8QEu4Dc8tLfHmuLvn2aF3KDmkX13wjp/ODTjOz3CSwgV 8xFCskcLV0ldNbzBK0rJ9qWfRphOodVviB5DQRLDfW6f2VKsVn/Bz8mrxVrdor62CeiC 5xihEFh5m+bzhHJyG6OelK/vXJ1ThWrNlgGjd5pUwl/GjfeXSGtasCUCP6O9CG7RyEgU fBa4SFd493sq8C3wRrHgFCM22uV1c9ShN8pBsnocSE3u15fC577YNU+dFS4nMWOD4Qp8 gYDA== X-Forwarded-Encrypted: i=1; AJvYcCW75XIAi4mamwwxRIV1L+1L9LsUHgoaHrNG68y8l7bECFw3X8B9B2a107ocEl5PUGe5X9NKNBDGd80=@lists.freedesktop.org X-Gm-Message-State: AOJu0YxGgKIs8bOGPfqzScssIMw6T5ZzBeMR4nYx1zCNydJF3wWCVTKV 7r8NsWBTc0mUm4ZLPwH5/bqamNO2wXl6PGz/C0ldVHhUClzU1E+V X-Gm-Gg: ASbGncucNVeEDQeGoFxfYHPelIMdDdOMrUFnCn6CsBaay8zNtDeYNTGHDw5U31N3Cuz DgDosppBRnD5EJaGXKPHEqrxFFo5lFpLL03AIkOw1Vp02ht7SjRSUd5XYKEPExsybq3cpvsK3/B tQJ4HocEcu/+Xif9VVXPFqx0WDPT/feceqhBla5M1feGOpAFx/0UbX4zlEHNHCmebu238wjVSF2 KfBCMIa07IxpQfgqOSn5Xja/27Z7E24J76qnLEi0DEJKuLwaDZJtzI3lDF7Dn5BJgIW+UHuRavO 8xYdbkSCsf2W6Ou6eg== X-Google-Smtp-Source: AGHT+IFGNiAYm97F/rvajIu8CyZRnvNveqnN8T22WAtQI5gMJGrMZ9dUcF45LtAZOYQGxLfI+woL/w== X-Received: by 2002:a05:6000:1f87:b0:38d:d8fb:e91a with SMTP id ffacd0b85a97d-38f33f35862mr8662918f8f.27.1739786492575; Mon, 17 Feb 2025 02:01:32 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:31 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 07/14] drm/vkms: Add a validation function for VKMS configuration Date: Mon, 17 Feb 2025 11:01:13 +0100 Message-ID: <20250217100120.7620-8-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Louis Chauvet As the configuration will be used by userspace, add a validator to avoid creating a broken DRM device. For the moment, the function always returns true, but rules will be added in future patches. Reviewed-by: Louis Chauvet Signed-off-by: Louis Chauvet Co-developed-by: José Expósito Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 2 ++ drivers/gpu/drm/vkms/vkms_config.c | 6 ++++++ drivers/gpu/drm/vkms/vkms_config.h | 10 ++++++++++ drivers/gpu/drm/vkms/vkms_output.c | 3 +++ 4 files changed, 21 insertions(+) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 92798590051b..6e07139d261c 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -54,6 +54,8 @@ static void vkms_config_test_default_config(struct kunit *test) KUNIT_EXPECT_EQ(test, config->writeback, params->enable_writeback); KUNIT_EXPECT_EQ(test, config->overlay, params->enable_overlay); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + vkms_config_destroy(config); } diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index 9fb08d94a351..d1947537834c 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -51,6 +51,12 @@ void vkms_config_destroy(struct vkms_config *config) } EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy); +bool vkms_config_is_valid(const struct vkms_config *config) +{ + return true; +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_is_valid); + static int vkms_config_show(struct seq_file *m, void *data) { struct drm_debugfs_entry *entry = m->private; diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index fcaa909fb2e0..31c758631c37 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -67,6 +67,16 @@ vkms_config_get_device_name(struct vkms_config *config) return config->dev_name; } +/** + * vkms_config_is_valid() - Validate a configuration + * @config: Configuration to validate + * + * Returns: + * Whether the configuration is valid or not. + * For example, a configuration without primary planes is not valid. + */ +bool vkms_config_is_valid(const struct vkms_config *config); + /** * vkms_config_register_debugfs() - Register a debugfs file to show the device's * configuration diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 068a7f87ecec..414cc933af41 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -16,6 +16,9 @@ int vkms_output_init(struct vkms_device *vkmsdev) int writeback; unsigned int n; + if (!vkms_config_is_valid(vkmsdev->config)) + return -EINVAL; + /* * Initialize used plane. One primary plane is required to perform the composition. * From patchwork Mon Feb 17 10:01:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977442 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7C57DC021A1 for ; Mon, 17 Feb 2025 10:01:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E8DFD10E405; Mon, 17 Feb 2025 10:01:56 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hyOfJE8V"; dkim-atps=neutral Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6289410E3E8 for ; Mon, 17 Feb 2025 10:01:35 +0000 (UTC) Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-4396a24118dso26415815e9.0 for ; Mon, 17 Feb 2025 02:01:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786494; x=1740391294; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vSrfW4vID/ZAsmlpyoSMJry7zJ9YdWQKmVlp2hDaPt4=; b=hyOfJE8VQdg0Q1Dab1YxPZU2GLcF2HGQ9tmOFYW420Jniwz/p9U6PvZXGGE2eDQ3It 7c309zBmLUMqdHaoCHhRURUc9kyXb4k5nfB9Wul0e5U3TPbDizFBQ/ZLMC2PbrUI46a8 eeGb56p1GuCgfJxkBAILGHF7/nKgbmXyrKDWOokKoBWkwIXeMFNSufXjqBYQ3Y53RTDw AXpyRaZDSjNPgZR16CJEbRyg59iy6HJLMFBBmDnon35758AVmVSj9I6Hqrtca7AzpktA InzfHQ9pjD2INLysXVHGcXHDcdBrzDifHVLW6xGkblRzQDYUdQSGQUKccKIXAEqPPv7f +Yxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786494; x=1740391294; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vSrfW4vID/ZAsmlpyoSMJry7zJ9YdWQKmVlp2hDaPt4=; b=sd1GmGtIVW/kjjBEtk7SBd8GAMYjPY1vDLiitw3Reb0+DmEnCBn0lrav193RB3EwcI 1delcK4tSRnzogaXR8HvM/gxLH03m/8yhmmK+tBmt8E6utcSyVJP1Erf8E55oznenEUk kSn02U8Y/Doj5yuKkmfTNZ8Zp8rH6Th87QHXHYRKIkKxA/tMCuIGgQw/XVd9Wj5hgUC6 rOhf/6vfo0wfArTBceDsv6EN8kFH0JhOpmAi+Apfk/iyaBIxdRgeeKAlBHn9Zfn6DEBR wVutbNwr2u6W0Zn++dYl6hPyoHTQPrK/GbiGa2K6rHT/0QJdb0qYxFeZe45fMpnBaezp ZRnQ== X-Forwarded-Encrypted: i=1; AJvYcCU/5ZQNhtGWrUIpHpre4R+ukuhs8suhSKveX/7faXvW4iXpggQHdyIb+zpS0zsBozRHfrvkbglGyew=@lists.freedesktop.org X-Gm-Message-State: AOJu0YwT5xOKi5Cd4yFT6dodY5ZdBcuSzypx2w472Nw5Kz6epSk7Tfqx 64PZHMbUZBRvSenxB92cCOl1Z4Yv3rj/V+lqd5tCrByepMw7xr8u X-Gm-Gg: ASbGncsHtFtb0dTs2LHjtXNklDRDQLZ6/d5DKU6xDa2C4uU5JE13q4tLh+5bUQnymPx /QuiVltdLuzQB+Wg7XcUxW2KHtIfCcrmfVeYVW9Lyo588qqMHYvdJyKsCFw7dQK1c+Wt+3Kz/p+ 7/XhT/8ffud1VwPOfTk6UnLSt39Ok0Dhbv1Gv0x2Y/NTSlvK8HodbJ1nTh/JIsxSLRP6HXr9Lpf tQX/BNsZu4NdZWMgYecu+ahNaNKYb3yeCReRCI2Nh+7cLN+t0tGLZA+5Xn/kBGJAihR/0duPb3V EPA+Hfvdp6SIG94mKg== X-Google-Smtp-Source: AGHT+IE4VXLne6sIG307xQsNtrMPLrSZtXRSPD2+s47ILm99USQ8Tj9BzGbdQDRZCI621/kHUhRIhA== X-Received: by 2002:a05:6000:1ac5:b0:38f:32ac:7e55 with SMTP id ffacd0b85a97d-38f33f53f34mr9012471f8f.48.1739786493628; Mon, 17 Feb 2025 02:01:33 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:33 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 08/14] drm/vkms: Allow to configure multiple planes Date: Mon, 17 Feb 2025 11:01:14 +0100 Message-ID: <20250217100120.7620-9-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add a list of planes to vkms_config and create as many planes as configured during output initialization. For backwards compatibility, add one primary plane and, if configured, one cursor plane and NUM_OVERLAY_PLANES planes to the default configuration. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 140 +++++++++++++++++- drivers/gpu/drm/vkms/vkms_config.c | 127 +++++++++++++++- drivers/gpu/drm/vkms/vkms_config.h | 75 +++++++++- drivers/gpu/drm/vkms/vkms_output.c | 42 ++---- 5 files changed, 349 insertions(+), 36 deletions(-) diff --git a/.clang-format b/.clang-format index fe1aa1a30d40..c585d2a5b395 100644 --- a/.clang-format +++ b/.clang-format @@ -690,6 +690,7 @@ ForEachMacros: - 'v4l2_m2m_for_each_src_buf' - 'v4l2_m2m_for_each_src_buf_safe' - 'virtio_device_for_each_vq' + - 'vkms_config_for_each_plane' - 'while_for_each_ftrace_op' - 'xa_for_each' - 'xa_for_each_marked' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 6e07139d261c..fe6f079902fd 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -24,6 +24,10 @@ static void vkms_config_test_empty_config(struct kunit *test) dev_name = NULL; KUNIT_EXPECT_STREQ(test, vkms_config_get_device_name(config), "test"); + KUNIT_EXPECT_TRUE(test, list_empty(&config->planes)); + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + vkms_config_destroy(config); } @@ -44,16 +48,145 @@ static void vkms_config_test_default_config(struct kunit *test) { const struct default_config_case *params = test->param_value; struct vkms_config *config; + struct vkms_config_plane *plane_cfg; + int n_primaries = 0; + int n_cursors = 0; + int n_overlays = 0; config = vkms_config_default_create(params->enable_cursor, params->enable_writeback, params->enable_overlay); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); - KUNIT_EXPECT_EQ(test, config->cursor, params->enable_cursor); KUNIT_EXPECT_EQ(test, config->writeback, params->enable_writeback); - KUNIT_EXPECT_EQ(test, config->overlay, params->enable_overlay); + /* Planes */ + vkms_config_for_each_plane(config, plane_cfg) { + switch (vkms_config_plane_get_type(plane_cfg)) { + case DRM_PLANE_TYPE_PRIMARY: + n_primaries++; + break; + case DRM_PLANE_TYPE_CURSOR: + n_cursors++; + break; + case DRM_PLANE_TYPE_OVERLAY: + n_overlays++; + break; + default: + KUNIT_FAIL_AND_ABORT(test, "Unknown plane type"); + } + } + KUNIT_EXPECT_EQ(test, n_primaries, 1); + KUNIT_EXPECT_EQ(test, n_cursors, params->enable_cursor ? 1 : 0); + KUNIT_EXPECT_EQ(test, n_overlays, params->enable_overlay ? 8 : 0); + + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + +static void vkms_config_test_get_planes(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_plane *plane_cfg; + struct vkms_config_plane *plane_cfg1, *plane_cfg2; + int n_planes = 0; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + vkms_config_for_each_plane(config, plane_cfg) + n_planes++; + KUNIT_ASSERT_EQ(test, n_planes, 0); + + plane_cfg1 = vkms_config_create_plane(config); + vkms_config_for_each_plane(config, plane_cfg) { + n_planes++; + if (plane_cfg != plane_cfg1) + KUNIT_FAIL(test, "Unexpected plane"); + } + KUNIT_ASSERT_EQ(test, n_planes, 1); + n_planes = 0; + + plane_cfg2 = vkms_config_create_plane(config); + vkms_config_for_each_plane(config, plane_cfg) { + n_planes++; + if (plane_cfg != plane_cfg1 && plane_cfg != plane_cfg2) + KUNIT_FAIL(test, "Unexpected plane"); + } + KUNIT_ASSERT_EQ(test, n_planes, 2); + n_planes = 0; + + vkms_config_destroy_plane(plane_cfg1); + vkms_config_for_each_plane(config, plane_cfg) { + n_planes++; + if (plane_cfg != plane_cfg2) + KUNIT_FAIL(test, "Unexpected plane"); + } + KUNIT_ASSERT_EQ(test, n_planes, 1); + + vkms_config_destroy(config); +} + +static void vkms_config_test_invalid_plane_number(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_plane *plane_cfg; + int n; + + config = vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + /* Invalid: No planes */ + plane_cfg = list_first_entry(&config->planes, typeof(*plane_cfg), link); + vkms_config_destroy_plane(plane_cfg); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Invalid: Too many planes */ + for (n = 0; n <= 32; n++) + vkms_config_create_plane(config); + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + +static void vkms_config_test_valid_plane_type(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_plane *plane_cfg; + + config = vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + plane_cfg = list_first_entry(&config->planes, typeof(*plane_cfg), link); + vkms_config_destroy_plane(plane_cfg); + + /* Invalid: No primary plane */ + plane_cfg = vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Invalid: Multiple primary planes */ + plane_cfg = vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + plane_cfg = vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: One primary plane */ + vkms_config_destroy_plane(plane_cfg); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + /* Invalid: Multiple cursor planes */ + plane_cfg = vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + plane_cfg = vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: One primary and one cursor plane */ + vkms_config_destroy_plane(plane_cfg); KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); vkms_config_destroy(config); @@ -63,6 +196,9 @@ static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_empty_config), KUNIT_CASE_PARAM(vkms_config_test_default_config, default_config_gen_params), + KUNIT_CASE(vkms_config_test_get_planes), + KUNIT_CASE(vkms_config_test_invalid_plane_number), + KUNIT_CASE(vkms_config_test_valid_plane_type), {} }; diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index d1947537834c..3c3f5cf79058 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -22,6 +22,8 @@ struct vkms_config *vkms_config_create(const char *dev_name) return ERR_PTR(-ENOMEM); } + INIT_LIST_HEAD(&config->planes); + return config; } EXPORT_SYMBOL_IF_KUNIT(vkms_config_create); @@ -31,28 +33,116 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, bool enable_overlay) { struct vkms_config *config; + struct vkms_config_plane *plane_cfg; + int n; config = vkms_config_create(DEFAULT_DEVICE_NAME); if (IS_ERR(config)) return config; - config->cursor = enable_cursor; config->writeback = enable_writeback; - config->overlay = enable_overlay; + + plane_cfg = vkms_config_create_plane(config); + if (IS_ERR(plane_cfg)) + goto err_alloc; + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + + if (enable_overlay) { + for (n = 0; n < NUM_OVERLAY_PLANES; n++) { + plane_cfg = vkms_config_create_plane(config); + if (IS_ERR(plane_cfg)) + goto err_alloc; + vkms_config_plane_set_type(plane_cfg, + DRM_PLANE_TYPE_OVERLAY); + } + } + + if (enable_cursor) { + plane_cfg = vkms_config_create_plane(config); + if (IS_ERR(plane_cfg)) + goto err_alloc; + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + } return config; + +err_alloc: + vkms_config_destroy(config); + return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL_IF_KUNIT(vkms_config_default_create); void vkms_config_destroy(struct vkms_config *config) { + struct vkms_config_plane *plane_cfg, *plane_tmp; + + list_for_each_entry_safe(plane_cfg, plane_tmp, &config->planes, link) + vkms_config_destroy_plane(plane_cfg); + kfree_const(config->dev_name); kfree(config); } EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy); +static bool valid_plane_number(const struct vkms_config *config) +{ + struct drm_device *dev = config->dev ? &config->dev->drm : NULL; + size_t n_planes; + + n_planes = list_count_nodes((struct list_head *)&config->planes); + if (n_planes <= 0 || n_planes >= 32) { + drm_info(dev, "The number of planes must be between 1 and 31\n"); + return false; + } + + return true; +} + +static bool valid_plane_type(const struct vkms_config *config) +{ + struct drm_device *dev = config->dev ? &config->dev->drm : NULL; + struct vkms_config_plane *plane_cfg; + bool has_primary_plane = false; + bool has_cursor_plane = false; + + vkms_config_for_each_plane(config, plane_cfg) { + enum drm_plane_type type; + + type = vkms_config_plane_get_type(plane_cfg); + + if (type == DRM_PLANE_TYPE_PRIMARY) { + if (has_primary_plane) { + drm_info(dev, "Multiple primary planes\n"); + return false; + } + + has_primary_plane = true; + } else if (type == DRM_PLANE_TYPE_CURSOR) { + if (has_cursor_plane) { + drm_info(dev, "Multiple cursor planes\n"); + return false; + } + + has_cursor_plane = true; + } + } + + if (!has_primary_plane) { + drm_info(dev, "Primary plane not found\n"); + return false; + } + + return true; +} + bool vkms_config_is_valid(const struct vkms_config *config) { + if (!valid_plane_number(config)) + return false; + + if (!valid_plane_type(config)) + return false; + return true; } EXPORT_SYMBOL_IF_KUNIT(vkms_config_is_valid); @@ -63,12 +153,17 @@ static int vkms_config_show(struct seq_file *m, void *data) struct drm_device *dev = entry->dev; struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev); const char *dev_name; + struct vkms_config_plane *plane_cfg; dev_name = vkms_config_get_device_name((struct vkms_config *)vkmsdev->config); seq_printf(m, "dev_name=%s\n", dev_name); seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback); - seq_printf(m, "cursor=%d\n", vkmsdev->config->cursor); - seq_printf(m, "overlay=%d\n", vkmsdev->config->overlay); + + 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)); + } return 0; } @@ -82,3 +177,27 @@ void vkms_config_register_debugfs(struct vkms_device *vkms_device) drm_debugfs_add_files(&vkms_device->drm, vkms_config_debugfs_list, ARRAY_SIZE(vkms_config_debugfs_list)); } + +struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config) +{ + struct vkms_config_plane *plane_cfg; + + plane_cfg = kzalloc(sizeof(*plane_cfg), GFP_KERNEL); + if (!plane_cfg) + return ERR_PTR(-ENOMEM); + + plane_cfg->config = config; + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); + + list_add_tail(&plane_cfg->link, &config->planes); + + return plane_cfg; +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_plane); + +void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg) +{ + list_del(&plane_cfg->link); + 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 31c758631c37..613e98760640 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 #include #include "vkms_drv.h" @@ -12,18 +13,46 @@ * * @dev_name: Name of the device * @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 device + * @planes: List of planes configured for the device * @dev: Used to store the current VKMS device. Only set when the device is instantiated. */ struct vkms_config { const char *dev_name; bool writeback; - bool cursor; - bool overlay; + struct list_head planes; struct vkms_device *dev; }; +/** + * struct vkms_config_plane + * + * @link: Link to the others planes in vkms_config + * @config: The vkms_config this plane belongs to + * @type: Type of the plane. The creator of configuration needs to ensures that + * at least one primary plane is present. + * @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 + * must be managed by other means. + */ +struct vkms_config_plane { + struct list_head link; + struct vkms_config *config; + + enum drm_plane_type type; + + /* Internal usage */ + struct vkms_plane *plane; +}; + +/** + * vkms_config_for_each_plane - Iterate over the vkms_config planes + * @config: &struct vkms_config pointer + * @plane_cfg: &struct vkms_config_plane pointer used as cursor + */ +#define vkms_config_for_each_plane(config, plane_cfg) \ + list_for_each_entry((plane_cfg), &(config)->planes, link) + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -84,4 +113,42 @@ bool vkms_config_is_valid(const struct vkms_config *config); */ void vkms_config_register_debugfs(struct vkms_device *vkms_device); +/** + * vkms_config_create_plane() - Add a new plane configuration + * @config: Configuration to add the plane to + * + * Returns: + * The new plane configuration or an error. Call vkms_config_destroy_plane() to + * free the returned plane configuration. + */ +struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config); + +/** + * vkms_config_destroy_plane() - Remove and free a plane configuration + * @plane_cfg: Plane configuration to destroy + */ +void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg); + +/** + * vkms_config_plane_type() - Return the plane type + * @plane_cfg: Plane to get the type from + */ +static inline enum drm_plane_type +vkms_config_plane_get_type(struct vkms_config_plane *plane_cfg) +{ + return plane_cfg->type; +} + +/** + * vkms_config_plane_set_type() - Set the plane type + * @plane_cfg: Plane to set the type to + * @type: New plane type + */ +static inline void +vkms_config_plane_set_type(struct vkms_config_plane *plane_cfg, + enum drm_plane_type type) +{ + plane_cfg->type = type; +} + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 414cc933af41..08ea691db299 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -11,28 +11,29 @@ int vkms_output_init(struct vkms_device *vkmsdev) struct vkms_connector *connector; struct drm_encoder *encoder; struct vkms_output *output; - struct vkms_plane *primary, *overlay, *cursor = NULL; + struct vkms_plane *primary = NULL, *cursor = NULL; + struct vkms_config_plane *plane_cfg; int ret; int writeback; - unsigned int n; if (!vkms_config_is_valid(vkmsdev->config)) return -EINVAL; - /* - * Initialize used plane. One primary plane is required to perform the composition. - * - * The overlay and cursor planes are not mandatory, but can be used to perform complex - * composition. - */ - primary = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY); - if (IS_ERR(primary)) - return PTR_ERR(primary); + vkms_config_for_each_plane(vkmsdev->config, plane_cfg) { + enum drm_plane_type type; - if (vkmsdev->config->cursor) { - cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR); - if (IS_ERR(cursor)) - return PTR_ERR(cursor); + type = vkms_config_plane_get_type(plane_cfg); + + plane_cfg->plane = vkms_plane_init(vkmsdev, type); + if (IS_ERR(plane_cfg->plane)) { + DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n"); + return PTR_ERR(plane_cfg->plane); + } + + if (type == DRM_PLANE_TYPE_PRIMARY) + primary = plane_cfg->plane; + else if (type == DRM_PLANE_TYPE_CURSOR) + cursor = plane_cfg->plane; } output = vkms_crtc_init(dev, &primary->base, @@ -42,17 +43,6 @@ int vkms_output_init(struct vkms_device *vkmsdev) return PTR_ERR(output); } - if (vkmsdev->config->overlay) { - for (n = 0; n < NUM_OVERLAY_PLANES; n++) { - overlay = 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 = drm_crtc_mask(&output->crtc); - } - } - connector = vkms_connector_init(vkmsdev); if (IS_ERR(connector)) { DRM_ERROR("Failed to init connector\n"); From patchwork Mon Feb 17 10:01:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977437 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C8D7DC021A1 for ; Mon, 17 Feb 2025 10:01:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0452A10E3ED; Mon, 17 Feb 2025 10:01:43 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="h7BJeqRz"; dkim-atps=neutral Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9AA3D10E3ED for ; Mon, 17 Feb 2025 10:01:36 +0000 (UTC) Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-4396a4d5e3bso26187175e9.3 for ; Mon, 17 Feb 2025 02:01:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786495; x=1740391295; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6ard8F/ImBapjiK3Qgw2K+5KYKoFmpd/b+fCrH1E+pw=; b=h7BJeqRzd/BGrk1ithdrB1ILhRVL04NvahJk5rZV/VuNqAzurd3ip2pIjwuIGhPYQS WxJ0SGJEu8GiiY654BICrCcEX/DnXYuBBjPyn5L1WH7AzqZw0ukWIakzpu0mhVSj04ut K0GGNdu6Iif/nUwlYOY/QBaHjbwQwgQ+8ZqslbGEt4uGumtPUHAUumFsjJV3bp988iLz 7kDdEouMCCWj1ZD88OT1qX5s2JxcGfoqMH+nAUgkVKRqi0T3zUhNjRxIvGdcg6D2Z517 d12hiuAdyif8sLcRfhxjo63WxE+gYdJOPqHBNOKfMe8e1Ul30EJ+4HhPFlZaxzxfBTlk i9dA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786495; x=1740391295; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6ard8F/ImBapjiK3Qgw2K+5KYKoFmpd/b+fCrH1E+pw=; b=VJsoyBv+IlPnGNpoI7VVkfoSIgxvrWWjvB6myZOuBjgQHQa29qDzSv0LXR/X/ZSC1Q jRRCJZcCuQCQEfqO5upiI75wx3D2Ho+MAqX1noXTQhQUD0dcUJv+bOB2pAiZx3Ze255b fYZw8FtbmuIGj1IYQ9aZTLx3Dqra1KFkHZoOXeJPyqlMKH3bGo7Ej1LgtVNOJ2mzp0pT EYM+kVOXBPteQwkXOzJYDlNQr8DLyAG7KzQTtVN6o0I9W+wIkCtlecVqTjX3/9A6ud0X wCobCjyDMxXCn1OosiVyBRbXaSLvXYBc71155hIOmQYueuprhvWdlpDaxjs35/ptavzY DA/w== X-Forwarded-Encrypted: i=1; AJvYcCVMt+d5NWdU1Kiob9K9zlZhnFgUD7cK8hG2E56j4Y3Ccd0kYk7d1gpf0kaytbaS7mDnG5aztgXMRJ4=@lists.freedesktop.org X-Gm-Message-State: AOJu0YxLNlw8PSIf9fd6qZjXixF6Mf7VjMgOuNuBK/hw0DB6X2Letcz2 zse24ji9w4WWmeD16mEvm0NK9mcTqEZohyyMfkQqGEy+8yXaVoqb X-Gm-Gg: ASbGnctD7EVTdvR+iG+jke3YJWPDiDGKiY3NRZMroHEzoXvyw5WYjhOtYlI5jp/1SMn vdQtJ/MLVUks8Ajb8AUl7CMH49pzcaAicKpo2Fyez8O8YtQDTWavIkkBDJVhAObyrlvQvqvs4ph DpN4OSz4VHDeU8ib6y+anw8eVrT3uGO4yD1Y7xroT7ia4NlFrcgI+Qt5cbsp7N93gpo4GxTIjka RDJQRm1UoznBr0y32nW63HBTg4J2/QOny7a3B9gBpRbLWje0Pff91YotptLZ450M7+tT5rAH8eN AqT9zZYsThwjRfMImQ== X-Google-Smtp-Source: AGHT+IFK8DpkcwyuRSHeqcTmKovdePAaotiW5JS+D7k7nGvwuuRMowAPsCf0v9vYyLbrWDrjMjHx0Q== X-Received: by 2002:a5d:648f:0:b0:38f:2856:7d9a with SMTP id ffacd0b85a97d-38f33f14a27mr8637339f8f.3.1739786494843; Mon, 17 Feb 2025 02:01:34 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:34 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 09/14] drm/vkms: Allow to configure multiple CRTCs Date: Mon, 17 Feb 2025 11:01:15 +0100 Message-ID: <20250217100120.7620-10-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add a list of CRTCs to vkms_config and helper functions to add and remove as many CRTCs as wanted. For backwards compatibility, add one CRTC to the default configuration. A future patch will allow to attach planes and CRTCs, but for the moment there are no changes in the way the output is configured. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 73 ++++++++++++++++- drivers/gpu/drm/vkms/vkms_config.c | 63 ++++++++++++++- drivers/gpu/drm/vkms/vkms_config.h | 80 +++++++++++++++++++ 4 files changed, 212 insertions(+), 5 deletions(-) diff --git a/.clang-format b/.clang-format index c585d2a5b395..e7a901c3617d 100644 --- a/.clang-format +++ b/.clang-format @@ -690,6 +690,7 @@ ForEachMacros: - 'v4l2_m2m_for_each_src_buf' - 'v4l2_m2m_for_each_src_buf_safe' - 'virtio_device_for_each_vq' + - 'vkms_config_for_each_crtc' - 'vkms_config_for_each_plane' - 'while_for_each_ftrace_op' - 'xa_for_each' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index fe6f079902fd..6a89361601a0 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -25,6 +25,7 @@ static void vkms_config_test_empty_config(struct kunit *test) KUNIT_EXPECT_STREQ(test, vkms_config_get_device_name(config), "test"); KUNIT_EXPECT_TRUE(test, list_empty(&config->planes)); + KUNIT_EXPECT_TRUE(test, list_empty(&config->crtcs)); KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); @@ -49,6 +50,7 @@ static void vkms_config_test_default_config(struct kunit *test) const struct default_config_case *params = test->param_value; struct vkms_config *config; struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; int n_primaries = 0; int n_cursors = 0; int n_overlays = 0; @@ -58,8 +60,6 @@ static void vkms_config_test_default_config(struct kunit *test) params->enable_overlay); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); - KUNIT_EXPECT_EQ(test, config->writeback, params->enable_writeback); - /* Planes */ vkms_config_for_each_plane(config, plane_cfg) { switch (vkms_config_plane_get_type(plane_cfg)) { @@ -80,6 +80,13 @@ static void vkms_config_test_default_config(struct kunit *test) KUNIT_EXPECT_EQ(test, n_cursors, params->enable_cursor ? 1 : 0); KUNIT_EXPECT_EQ(test, n_overlays, params->enable_overlay ? 8 : 0); + /* CRTCs */ + KUNIT_EXPECT_EQ(test, list_count_nodes(&config->crtcs), 1); + + crtc_cfg = list_first_entry(&config->crtcs, typeof(*crtc_cfg), link); + KUNIT_EXPECT_EQ(test, vkms_config_crtc_get_writeback(crtc_cfg), + params->enable_writeback); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); vkms_config_destroy(config); @@ -128,6 +135,43 @@ static void vkms_config_test_get_planes(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_get_crtcs(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_crtc *crtc_cfg; + struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 0); + vkms_config_for_each_crtc(config, crtc_cfg) + KUNIT_FAIL(test, "Unexpected CRTC"); + + crtc_cfg1 = vkms_config_create_crtc(config); + KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 1); + vkms_config_for_each_crtc(config, crtc_cfg) { + if (crtc_cfg != crtc_cfg1) + KUNIT_FAIL(test, "Unexpected CRTC"); + } + + crtc_cfg2 = vkms_config_create_crtc(config); + KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 2); + vkms_config_for_each_crtc(config, crtc_cfg) { + if (crtc_cfg != crtc_cfg1 && crtc_cfg != crtc_cfg2) + KUNIT_FAIL(test, "Unexpected CRTC"); + } + + vkms_config_destroy_crtc(config, crtc_cfg2); + KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 1); + vkms_config_for_each_crtc(config, crtc_cfg) { + if (crtc_cfg != crtc_cfg1) + KUNIT_FAIL(test, "Unexpected CRTC"); + } + + vkms_config_destroy(config); +} + static void vkms_config_test_invalid_plane_number(struct kunit *test) { struct vkms_config *config; @@ -192,13 +236,38 @@ static void vkms_config_test_valid_plane_type(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_invalid_crtc_number(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_crtc *crtc_cfg; + int n; + + config = vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + /* Invalid: No CRTCs */ + crtc_cfg = list_first_entry(&config->crtcs, typeof(*crtc_cfg), link); + vkms_config_destroy_crtc(config, crtc_cfg); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Invalid: Too many CRTCs */ + for (n = 0; n <= 32; n++) + vkms_config_create_crtc(config); + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_empty_config), KUNIT_CASE_PARAM(vkms_config_test_default_config, default_config_gen_params), KUNIT_CASE(vkms_config_test_get_planes), + KUNIT_CASE(vkms_config_test_get_crtcs), KUNIT_CASE(vkms_config_test_invalid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), + KUNIT_CASE(vkms_config_test_invalid_crtc_number), {} }; diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index 3c3f5cf79058..d195db770fae 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -23,6 +23,7 @@ struct vkms_config *vkms_config_create(const char *dev_name) } INIT_LIST_HEAD(&config->planes); + INIT_LIST_HEAD(&config->crtcs); return config; } @@ -34,19 +35,23 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, { struct vkms_config *config; struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; int n; config = vkms_config_create(DEFAULT_DEVICE_NAME); if (IS_ERR(config)) return config; - config->writeback = enable_writeback; - plane_cfg = vkms_config_create_plane(config); if (IS_ERR(plane_cfg)) goto err_alloc; vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + crtc_cfg = vkms_config_create_crtc(config); + if (IS_ERR(crtc_cfg)) + goto err_alloc; + vkms_config_crtc_set_writeback(crtc_cfg, enable_writeback); + if (enable_overlay) { for (n = 0; n < NUM_OVERLAY_PLANES; n++) { plane_cfg = vkms_config_create_plane(config); @@ -75,10 +80,14 @@ EXPORT_SYMBOL_IF_KUNIT(vkms_config_default_create); void vkms_config_destroy(struct vkms_config *config) { struct vkms_config_plane *plane_cfg, *plane_tmp; + struct vkms_config_crtc *crtc_cfg, *crtc_tmp; list_for_each_entry_safe(plane_cfg, plane_tmp, &config->planes, link) vkms_config_destroy_plane(plane_cfg); + list_for_each_entry_safe(crtc_cfg, crtc_tmp, &config->crtcs, link) + vkms_config_destroy_crtc(config, crtc_cfg); + kfree_const(config->dev_name); kfree(config); } @@ -135,11 +144,28 @@ static bool valid_plane_type(const struct vkms_config *config) return true; } +static bool valid_crtc_number(const struct vkms_config *config) +{ + struct drm_device *dev = config->dev ? &config->dev->drm : NULL; + size_t n_crtcs; + + n_crtcs = list_count_nodes((struct list_head *)&config->crtcs); + if (n_crtcs <= 0 || n_crtcs >= 32) { + drm_info(dev, "The number of CRTCs must be between 1 and 31\n"); + return false; + } + + return true; +} + bool vkms_config_is_valid(const struct vkms_config *config) { if (!valid_plane_number(config)) return false; + if (!valid_crtc_number(config)) + return false; + if (!valid_plane_type(config)) return false; @@ -154,10 +180,10 @@ static int vkms_config_show(struct seq_file *m, void *data) struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev); const char *dev_name; struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; dev_name = vkms_config_get_device_name((struct vkms_config *)vkmsdev->config); seq_printf(m, "dev_name=%s\n", dev_name); - seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback); vkms_config_for_each_plane(vkmsdev->config, plane_cfg) { seq_puts(m, "plane:\n"); @@ -165,6 +191,12 @@ static int vkms_config_show(struct seq_file *m, void *data) vkms_config_plane_get_type(plane_cfg)); } + 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)); + } + return 0; } @@ -201,3 +233,28 @@ void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg) kfree(plane_cfg); } EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_plane); + +struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *config) +{ + struct vkms_config_crtc *crtc_cfg; + + crtc_cfg = kzalloc(sizeof(*crtc_cfg), GFP_KERNEL); + if (!crtc_cfg) + return ERR_PTR(-ENOMEM); + + crtc_cfg->config = config; + vkms_config_crtc_set_writeback(crtc_cfg, false); + + list_add_tail(&crtc_cfg->link, &config->crtcs); + + return crtc_cfg; +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_crtc); + +void vkms_config_destroy_crtc(struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg) +{ + list_del(&crtc_cfg->link); + kfree(crtc_cfg); +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_crtc); diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index 613e98760640..978418db84b9 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -14,12 +14,14 @@ * @dev_name: Name of the device * @writeback: If true, a writeback buffer can be attached to the CRTC * @planes: List of planes configured for the device + * @crtcs: List of CRTCs configured for the device * @dev: Used to store the current VKMS device. Only set when the device is instantiated. */ struct vkms_config { const char *dev_name; bool writeback; struct list_head planes; + struct list_head crtcs; struct vkms_device *dev; }; @@ -45,6 +47,27 @@ struct vkms_config_plane { struct vkms_plane *plane; }; +/** + * struct vkms_config_crtc + * + * @link: Link to the others CRTCs in vkms_config + * @config: The vkms_config this CRTC belongs to + * @writeback: If true, a writeback buffer can be attached to the CRTC + * @crtc: Internal usage. This pointer should never be considered as valid. + * It can be used to store a temporary reference to a VKMS CRTC during + * device creation. This pointer is not managed by the configuration and + * must be managed by other means. + */ +struct vkms_config_crtc { + struct list_head link; + struct vkms_config *config; + + bool writeback; + + /* Internal usage */ + struct vkms_output *crtc; +}; + /** * vkms_config_for_each_plane - Iterate over the vkms_config planes * @config: &struct vkms_config pointer @@ -53,6 +76,14 @@ struct vkms_config_plane { #define vkms_config_for_each_plane(config, plane_cfg) \ list_for_each_entry((plane_cfg), &(config)->planes, link) +/** + * vkms_config_for_each_crtc - Iterate over the vkms_config CRTCs + * @config: &struct vkms_config pointer + * @crtc_cfg: &struct vkms_config_crtc pointer used as cursor + */ +#define vkms_config_for_each_crtc(config, crtc_cfg) \ + list_for_each_entry((crtc_cfg), &(config)->crtcs, link) + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -96,6 +127,15 @@ vkms_config_get_device_name(struct vkms_config *config) return config->dev_name; } +/** + * vkms_config_get_num_crtcs() - Return the number of CRTCs in the configuration + * @config: Configuration to get the number of CRTCs from + */ +static inline size_t vkms_config_get_num_crtcs(struct vkms_config *config) +{ + return list_count_nodes(&config->crtcs); +} + /** * vkms_config_is_valid() - Validate a configuration * @config: Configuration to validate @@ -151,4 +191,44 @@ vkms_config_plane_set_type(struct vkms_config_plane *plane_cfg, plane_cfg->type = type; } +/** + * vkms_config_create_crtc() - Add a new CRTC configuration + * @config: Configuration to add the CRTC to + * + * Returns: + * The new CRTC configuration or an error. Call vkms_config_destroy_crtc() to + * free the returned CRTC configuration. + */ +struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *config); + +/** + * vkms_config_destroy_crtc() - Remove and free a CRTC configuration + * @config: Configuration to remove the CRTC from + * @crtc_cfg: CRTC configuration to destroy + */ +void vkms_config_destroy_crtc(struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg); + +/** + * vkms_config_crtc_get_writeback() - If a writeback connector will be created + * @crtc_cfg: CRTC with or without a writeback connector + */ +static inline bool +vkms_config_crtc_get_writeback(struct vkms_config_crtc *crtc_cfg) +{ + return crtc_cfg->writeback; +} + +/** + * vkms_config_crtc_set_writeback() - If a writeback connector will be created + * @crtc_cfg: Target CRTC + * @writeback: Enable or disable the writeback connector + */ +static inline void +vkms_config_crtc_set_writeback(struct vkms_config_crtc *crtc_cfg, + bool writeback) +{ + crtc_cfg->writeback = writeback; +} + #endif /* _VKMS_CONFIG_H_ */ From patchwork Mon Feb 17 10:01:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977439 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7EDA7C021A7 for ; Mon, 17 Feb 2025 10:01:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6E3E010E3A7; Mon, 17 Feb 2025 10:01:43 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="gkL0MJ7Q"; dkim-atps=neutral Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1432710E3ED for ; Mon, 17 Feb 2025 10:01:38 +0000 (UTC) Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-436ce2ab251so28033905e9.1 for ; Mon, 17 Feb 2025 02:01:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786496; x=1740391296; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dj7UdgqKRsR/J7Evr6WiSgrN4y9r4lOHfFFfgOEYKbo=; b=gkL0MJ7QNgVaKY3q7qisdgxLa1sAt+fkAhpOGdZXCVn42gq513r5h6AlO/t4AQLCnN eLWZwwonLed1x3zkQs0jIMfTOvPEvZSkvMLVjA4waHD3cHiV8LQsZD7dVp4FkSpuBc2G ou0l9uyIggxzkOgXadfF/Z+69schQZ+aDfWE4+BvH/lts6Th9gOt5K+52H9yRQNAfBai QUeBW5G/A50TmRANIzKAjaDfjThzCOtuwqMjBbKWwgG56oPea5pW6wTIjNG0qXU4oQvX IWzv8OLGKulN4AT0+nfAtSI56IoreW9nqkGzqRQdsEKnitM4p45+8kn1sCd4WPKeFsFe +6yQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786496; x=1740391296; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dj7UdgqKRsR/J7Evr6WiSgrN4y9r4lOHfFFfgOEYKbo=; b=rh/ZT7nIfXCOqh3R9zHj7/3Z3GaMvaWzddh+bL1b2NTyxEQajKQynftqeDVSzSa+O+ aGZB70SOBcvloWsGxEVtpUxSp9NsbjBT/fyBVsk/0jOtTtRtkfn1LDiyq/zkDYucW4R/ sChEnCMAfZdv0vvcObvndXZNHVAeuc+H9vVjZasAMXhX9EgyeS8CPmP0yQZeh8RCcecH NJrV5Re1ktPXwT3C82whbAEZDblQKbtdhBD8xUzUFQnwgsC+dsMGrRKWlqUt4elo6kFa vMm9jp89q98tOYpbSjFJN9Y6tboQddX6C41rzvU8Zmgc6YAXeKr4zmx+JsibVXxD/3br sDnw== X-Forwarded-Encrypted: i=1; AJvYcCUO2CHXXydulADtr4wjIkXJ7flhCJK8qgtY+LPnzlUNlGY0HErZvTWfu02dVi6Q7TU0KFhEeeq13po=@lists.freedesktop.org X-Gm-Message-State: AOJu0Yyfdl2sk+mBISfyT/zxtsxa+mJo1al7+DfpRgf5GG5tUSF6H4Mz eRZljf6X1yzNvIO9fgStzQ6Q4nq6H1sjNhGEUO0HXvPQTmIstzag X-Gm-Gg: ASbGnctUngs4cGVziKcyYG20CumLSzbPIbMnqrN0DXjykjF1HtRoUi4ViALboJscnLk ZGw373E6yzmbxtxpXpsl2+InL1xScNn6dhM9EHyDJV5+eqoF7Zd6suWQftApnOCtsoJmnPTq54B yuuHeqCt4RqbPQnd6JM0kHyhIVJtIt+5eXRJUKUR4IuMM53MAQ37minTA0lmkIQp+bUvJkc+lyw c+b3ANkzjdvigAp5VZ0gItGCTs06Y4v1Gme/QE9YqaLeI4y98HUQLgM1FwM+bxxE1S7zckoE6wA +nCO2WXdJljJJknGCw== X-Google-Smtp-Source: AGHT+IH1KccrzaQoF+WebCKzmT5TTQsy0uAxPCpxUtjM+62wg2qG+bggbeG8iaMiJutP1r+mA3xVTA== X-Received: by 2002:a05:6000:18ad:b0:385:f249:c336 with SMTP id ffacd0b85a97d-38f33f4e4eamr8180401f8f.45.1739786496100; Mon, 17 Feb 2025 02:01:36 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:35 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 10/14] drm/vkms: Allow to attach planes and CRTCs Date: Mon, 17 Feb 2025 11:01:16 +0100 Message-ID: <20250217100120.7620-11-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add a list of possible CRTCs to the plane configuration and helpers to attach, detach and get the primary and cursor planes attached to a CRTC. Now that the default configuration has its planes and CRTC correctly attached, configure the output following the configuration. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 222 ++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 154 ++++++++++-- drivers/gpu/drm/vkms/vkms_config.h | 59 ++++- drivers/gpu/drm/vkms/vkms_drv.c | 3 +- drivers/gpu/drm/vkms/vkms_output.c | 51 ++-- 6 files changed, 454 insertions(+), 36 deletions(-) diff --git a/.clang-format b/.clang-format index e7a901c3617d..6f944fa39841 100644 --- a/.clang-format +++ b/.clang-format @@ -692,6 +692,7 @@ ForEachMacros: - 'virtio_device_for_each_vq' - 'vkms_config_for_each_crtc' - 'vkms_config_for_each_plane' + - 'vkms_config_plane_for_each_possible_crtc' - 'while_for_each_ftrace_op' - 'xa_for_each' - 'xa_for_each_marked' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 6a89361601a0..b7a0a8202819 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -87,6 +87,18 @@ static void vkms_config_test_default_config(struct kunit *test) KUNIT_EXPECT_EQ(test, vkms_config_crtc_get_writeback(crtc_cfg), params->enable_writeback); + vkms_config_for_each_plane(config, plane_cfg) { + struct vkms_config_crtc *possible_crtc; + int n_possible_crtcs = 0; + unsigned long idx = 0; + + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + KUNIT_EXPECT_PTR_EQ(test, crtc_cfg, possible_crtc); + n_possible_crtcs++; + } + KUNIT_EXPECT_EQ(test, n_possible_crtcs, 1); + } + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); vkms_config_destroy(config); @@ -199,6 +211,8 @@ static void vkms_config_test_valid_plane_type(struct kunit *test) { struct vkms_config *config; struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; + int err; config = vkms_config_default_create(false, false, false); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); @@ -206,16 +220,26 @@ static void vkms_config_test_valid_plane_type(struct kunit *test) plane_cfg = list_first_entry(&config->planes, typeof(*plane_cfg), link); vkms_config_destroy_plane(plane_cfg); + crtc_cfg = list_first_entry(&config->crtcs, typeof(*crtc_cfg), link); + /* Invalid: No primary plane */ plane_cfg = vkms_config_create_plane(config); vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); + err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); /* Invalid: Multiple primary planes */ plane_cfg = vkms_config_create_plane(config); vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + plane_cfg = vkms_config_create_plane(config); vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); /* Valid: One primary plane */ @@ -225,14 +249,50 @@ static void vkms_config_test_valid_plane_type(struct kunit *test) /* Invalid: Multiple cursor planes */ plane_cfg = vkms_config_create_plane(config); vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + plane_cfg = vkms_config_create_plane(config); vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); /* Valid: One primary and one cursor plane */ vkms_config_destroy_plane(plane_cfg); KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + /* Invalid: Second CRTC without primary plane */ + crtc_cfg = vkms_config_create_crtc(config); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: Second CRTC with a primary plane */ + plane_cfg = vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + 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; + struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; + + config = vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + plane_cfg = list_first_entry(&config->planes, typeof(*plane_cfg), link); + crtc_cfg = list_first_entry(&config->crtcs, typeof(*crtc_cfg), link); + + /* Invalid: Primary plane without a possible CRTC */ + vkms_config_plane_detach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + vkms_config_destroy(config); } @@ -259,6 +319,164 @@ static void vkms_config_test_invalid_crtc_number(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_attach_different_configs(struct kunit *test) +{ + struct vkms_config *config1, *config2; + struct vkms_config_plane *plane_cfg1, *plane_cfg2; + struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; + int err; + + config1 = vkms_config_create("test1"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config1); + + config2 = vkms_config_create("test2"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config2); + + plane_cfg1 = vkms_config_create_plane(config1); + crtc_cfg1 = vkms_config_create_crtc(config1); + + plane_cfg2 = vkms_config_create_plane(config2); + crtc_cfg2 = vkms_config_create_crtc(config2); + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg1); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg2); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg1); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); + + err = vkms_config_plane_attach_crtc(plane_cfg1, crtc_cfg2); + KUNIT_EXPECT_NE(test, err, 0); + err = vkms_config_plane_attach_crtc(plane_cfg2, crtc_cfg1); + KUNIT_EXPECT_NE(test, err, 0); + + vkms_config_destroy(config1); + vkms_config_destroy(config2); +} + +static void vkms_config_test_plane_attach_crtc(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_plane *overlay_cfg; + struct vkms_config_plane *primary_cfg; + struct vkms_config_plane *cursor_cfg; + struct vkms_config_crtc *crtc_cfg; + int err; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + overlay_cfg = vkms_config_create_plane(config); + vkms_config_plane_set_type(overlay_cfg, DRM_PLANE_TYPE_OVERLAY); + primary_cfg = vkms_config_create_plane(config); + vkms_config_plane_set_type(primary_cfg, DRM_PLANE_TYPE_PRIMARY); + cursor_cfg = vkms_config_create_plane(config); + vkms_config_plane_set_type(cursor_cfg, DRM_PLANE_TYPE_CURSOR); + + crtc_cfg = vkms_config_create_crtc(config); + + /* No primary or cursor planes */ + KUNIT_EXPECT_NULL(test, vkms_config_crtc_primary_plane(config, crtc_cfg)); + KUNIT_EXPECT_NULL(test, vkms_config_crtc_cursor_plane(config, crtc_cfg)); + + /* Overlay plane, but no primary or cursor planes */ + err = vkms_config_plane_attach_crtc(overlay_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + KUNIT_EXPECT_NULL(test, vkms_config_crtc_primary_plane(config, crtc_cfg)); + KUNIT_EXPECT_NULL(test, vkms_config_crtc_cursor_plane(config, crtc_cfg)); + + /* Primary plane, attaching it twice must fail */ + err = vkms_config_plane_attach_crtc(primary_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + err = vkms_config_plane_attach_crtc(primary_cfg, crtc_cfg); + KUNIT_EXPECT_NE(test, err, 0); + KUNIT_EXPECT_PTR_EQ(test, + vkms_config_crtc_primary_plane(config, crtc_cfg), + primary_cfg); + KUNIT_EXPECT_NULL(test, vkms_config_crtc_cursor_plane(config, crtc_cfg)); + + /* Primary and cursor planes */ + err = vkms_config_plane_attach_crtc(cursor_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + KUNIT_EXPECT_PTR_EQ(test, + vkms_config_crtc_primary_plane(config, crtc_cfg), + primary_cfg); + KUNIT_EXPECT_PTR_EQ(test, + vkms_config_crtc_cursor_plane(config, crtc_cfg), + cursor_cfg); + + /* Detach primary and destroy cursor plane */ + vkms_config_plane_detach_crtc(overlay_cfg, crtc_cfg); + vkms_config_plane_detach_crtc(primary_cfg, crtc_cfg); + vkms_config_destroy_plane(cursor_cfg); + KUNIT_EXPECT_NULL(test, vkms_config_crtc_primary_plane(config, crtc_cfg)); + KUNIT_EXPECT_NULL(test, vkms_config_crtc_cursor_plane(config, crtc_cfg)); + + vkms_config_destroy(config); +} + +static void vkms_config_test_plane_get_possible_crtcs(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_plane *plane_cfg1, *plane_cfg2; + struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; + int n_crtcs = 0; + int err; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + plane_cfg1 = vkms_config_create_plane(config); + plane_cfg2 = vkms_config_create_plane(config); + crtc_cfg1 = vkms_config_create_crtc(config); + crtc_cfg2 = vkms_config_create_crtc(config); + + /* No possible CRTCs */ + vkms_config_plane_for_each_possible_crtc(plane_cfg1, idx, possible_crtc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + vkms_config_plane_for_each_possible_crtc(plane_cfg2, idx, possible_crtc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + /* Plane 1 attached to CRTC 1 and 2 */ + err = vkms_config_plane_attach_crtc(plane_cfg1, crtc_cfg1); + KUNIT_EXPECT_EQ(test, err, 0); + err = vkms_config_plane_attach_crtc(plane_cfg1, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + vkms_config_plane_for_each_possible_crtc(plane_cfg1, idx, possible_crtc) { + n_crtcs++; + if (possible_crtc != crtc_cfg1 && possible_crtc != crtc_cfg2) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 2); + n_crtcs = 0; + + vkms_config_plane_for_each_possible_crtc(plane_cfg2, idx, possible_crtc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + /* Plane 1 attached to CRTC 1 and plane 2 to CRTC 2 */ + vkms_config_plane_detach_crtc(plane_cfg1, crtc_cfg2); + vkms_config_plane_for_each_possible_crtc(plane_cfg1, idx, possible_crtc) { + n_crtcs++; + if (possible_crtc != crtc_cfg1) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 1); + n_crtcs = 0; + + err = vkms_config_plane_attach_crtc(plane_cfg2, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + vkms_config_plane_for_each_possible_crtc(plane_cfg2, idx, possible_crtc) { + n_crtcs++; + if (possible_crtc != crtc_cfg2) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 1); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_empty_config), KUNIT_CASE_PARAM(vkms_config_test_default_config, @@ -267,7 +485,11 @@ static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_get_crtcs), KUNIT_CASE(vkms_config_test_invalid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), + KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), KUNIT_CASE(vkms_config_test_invalid_crtc_number), + KUNIT_CASE(vkms_config_test_attach_different_configs), + KUNIT_CASE(vkms_config_test_plane_attach_crtc), + KUNIT_CASE(vkms_config_test_plane_get_possible_crtcs), {} }; diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index d195db770fae..458385413648 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -52,13 +52,20 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, goto err_alloc; vkms_config_crtc_set_writeback(crtc_cfg, enable_writeback); + if (vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg)) + goto err_alloc; + if (enable_overlay) { for (n = 0; n < NUM_OVERLAY_PLANES; n++) { plane_cfg = vkms_config_create_plane(config); if (IS_ERR(plane_cfg)) goto err_alloc; + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); + + if (vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg)) + goto err_alloc; } } @@ -66,7 +73,11 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, plane_cfg = vkms_config_create_plane(config); if (IS_ERR(plane_cfg)) goto err_alloc; + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + + if (vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg)) + goto err_alloc; } return config; @@ -107,7 +118,8 @@ static bool valid_plane_number(const struct vkms_config *config) return true; } -static bool valid_plane_type(const struct vkms_config *config) +static bool valid_planes_for_crtc(const struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg) { struct drm_device *dev = config->dev ? &config->dev->drm : NULL; struct vkms_config_plane *plane_cfg; @@ -115,24 +127,31 @@ static bool valid_plane_type(const struct vkms_config *config) bool has_cursor_plane = false; vkms_config_for_each_plane(config, plane_cfg) { + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; enum drm_plane_type type; type = vkms_config_plane_get_type(plane_cfg); - if (type == DRM_PLANE_TYPE_PRIMARY) { - if (has_primary_plane) { - drm_info(dev, "Multiple primary planes\n"); - return false; - } + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + if (possible_crtc != crtc_cfg) + continue; - has_primary_plane = true; - } else if (type == DRM_PLANE_TYPE_CURSOR) { - if (has_cursor_plane) { - drm_info(dev, "Multiple cursor planes\n"); - return false; - } + if (type == DRM_PLANE_TYPE_PRIMARY) { + if (has_primary_plane) { + drm_info(dev, "Multiple primary planes\n"); + return false; + } - has_cursor_plane = true; + has_primary_plane = true; + } else if (type == DRM_PLANE_TYPE_CURSOR) { + if (has_cursor_plane) { + drm_info(dev, "Multiple cursor planes\n"); + return false; + } + + has_cursor_plane = true; + } } } @@ -144,6 +163,21 @@ static bool valid_plane_type(const struct vkms_config *config) return true; } +static bool valid_plane_possible_crtcs(const struct vkms_config *config) +{ + struct drm_device *dev = config->dev ? &config->dev->drm : NULL; + struct vkms_config_plane *plane_cfg; + + vkms_config_for_each_plane(config, plane_cfg) { + if (xa_empty(&plane_cfg->possible_crtcs)) { + drm_info(dev, "All planes must have at least one possible CRTC\n"); + return false; + } + } + + return true; +} + static bool valid_crtc_number(const struct vkms_config *config) { struct drm_device *dev = config->dev ? &config->dev->drm : NULL; @@ -160,15 +194,22 @@ static bool valid_crtc_number(const struct vkms_config *config) bool vkms_config_is_valid(const struct vkms_config *config) { + struct vkms_config_crtc *crtc_cfg; + if (!valid_plane_number(config)) return false; if (!valid_crtc_number(config)) return false; - if (!valid_plane_type(config)) + if (!valid_plane_possible_crtcs(config)) return false; + vkms_config_for_each_crtc(config, crtc_cfg) { + if (!valid_planes_for_crtc(config, crtc_cfg)) + return false; + } + return true; } EXPORT_SYMBOL_IF_KUNIT(vkms_config_is_valid); @@ -220,6 +261,7 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config) plane_cfg->config = config; vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); + xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC); list_add_tail(&plane_cfg->link, &config->planes); @@ -229,11 +271,45 @@ 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); list_del(&plane_cfg->link); kfree(plane_cfg); } EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_plane); +int __must_check vkms_config_plane_attach_crtc(struct vkms_config_plane *plane_cfg, + struct vkms_config_crtc *crtc_cfg) +{ + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; + u32 crtc_idx = 0; + + if (plane_cfg->config != crtc_cfg->config) + return -EINVAL; + + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + if (possible_crtc == crtc_cfg) + return -EEXIST; + } + + return xa_alloc(&plane_cfg->possible_crtcs, &crtc_idx, crtc_cfg, + xa_limit_32b, GFP_KERNEL); +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_plane_attach_crtc); + +void vkms_config_plane_detach_crtc(struct vkms_config_plane *plane_cfg, + struct vkms_config_crtc *crtc_cfg) +{ + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; + + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + if (possible_crtc == crtc_cfg) + xa_erase(&plane_cfg->possible_crtcs, idx); + } +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_plane_detach_crtc); + struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -254,7 +330,57 @@ EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_crtc); void vkms_config_destroy_crtc(struct vkms_config *config, struct vkms_config_crtc *crtc_cfg) { + struct vkms_config_plane *plane_cfg; + + vkms_config_for_each_plane(config, plane_cfg) + vkms_config_plane_detach_crtc(plane_cfg, crtc_cfg); + list_del(&crtc_cfg->link); kfree(crtc_cfg); } EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_crtc); + +/** + * vkms_config_crtc_get_plane() - Return the first attached plane to a CRTC with + * the specific type + * @config: Configuration containing the CRTC and the plane + * @crtc_cfg: Only find planes attached to this CRTC + * @type: Plane type to search + * + * Returns: + * The first plane found attached to @crtc_cfg with the type @type. + */ +static struct vkms_config_plane *vkms_config_crtc_get_plane(const struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg, + enum drm_plane_type type) +{ + struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *possible_crtc; + enum drm_plane_type current_type; + unsigned long idx = 0; + + vkms_config_for_each_plane(config, plane_cfg) { + current_type = vkms_config_plane_get_type(plane_cfg); + + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + if (possible_crtc == crtc_cfg && current_type == type) + return plane_cfg; + } + } + + return NULL; +} + +struct vkms_config_plane *vkms_config_crtc_primary_plane(const struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg) +{ + return vkms_config_crtc_get_plane(config, crtc_cfg, DRM_PLANE_TYPE_PRIMARY); +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_crtc_primary_plane); + +struct vkms_config_plane *vkms_config_crtc_cursor_plane(const struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg) +{ + return vkms_config_crtc_get_plane(config, crtc_cfg, DRM_PLANE_TYPE_CURSOR); +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_crtc_cursor_plane); diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index 978418db84b9..ad303b34ee03 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -5,6 +5,7 @@ #include #include +#include #include "vkms_drv.h" @@ -12,14 +13,12 @@ * struct vkms_config - General configuration for VKMS driver * * @dev_name: Name of the device - * @writeback: If true, a writeback buffer can be attached to the CRTC * @planes: List of planes configured for the device * @crtcs: List of CRTCs configured for the device * @dev: Used to store the current VKMS device. Only set when the device is instantiated. */ struct vkms_config { const char *dev_name; - bool writeback; struct list_head planes; struct list_head crtcs; struct vkms_device *dev; @@ -32,6 +31,7 @@ struct vkms_config { * @config: The vkms_config this plane belongs to * @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 * @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 @@ -42,6 +42,7 @@ struct vkms_config_plane { struct vkms_config *config; enum drm_plane_type type; + struct xarray possible_crtcs; /* Internal usage */ struct vkms_plane *plane; @@ -84,6 +85,16 @@ struct vkms_config_crtc { #define vkms_config_for_each_crtc(config, crtc_cfg) \ list_for_each_entry((crtc_cfg), &(config)->crtcs, link) +/** + * vkms_config_plane_for_each_possible_crtc - Iterate over the vkms_config_plane + * possible CRTCs + * @plane_cfg: &struct vkms_config_plane pointer + * @idx: Index of the cursor + * @possible_crtc: &struct vkms_config_crtc pointer used as cursor + */ +#define vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) \ + xa_for_each(&(plane_cfg)->possible_crtcs, idx, (possible_crtc)) + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -191,6 +202,22 @@ vkms_config_plane_set_type(struct vkms_config_plane *plane_cfg, plane_cfg->type = type; } +/** + * vkms_config_plane_attach_crtc - Attach a plane to a CRTC + * @plane_cfg: Plane to attach + * @crtc_cfg: CRTC to attach @plane_cfg to + */ +int __must_check vkms_config_plane_attach_crtc(struct vkms_config_plane *plane_cfg, + struct vkms_config_crtc *crtc_cfg); + +/** + * vkms_config_plane_detach_crtc - Detach a plane from a CRTC + * @plane_cfg: Plane to detach + * @crtc_cfg: CRTC to detach @plane_cfg from + */ +void vkms_config_plane_detach_crtc(struct vkms_config_plane *plane_cfg, + struct vkms_config_crtc *crtc_cfg); + /** * vkms_config_create_crtc() - Add a new CRTC configuration * @config: Configuration to add the CRTC to @@ -231,4 +258,32 @@ vkms_config_crtc_set_writeback(struct vkms_config_crtc *crtc_cfg, crtc_cfg->writeback = writeback; } +/** + * vkms_config_crtc_primary_plane() - Return the primary plane for a CRTC + * @config: Configuration containing the CRTC + * @crtc_config: Target CRTC + * + * Note that, if multiple primary planes are found, the first one is returned. + * In this case, the configuration will be invalid. See vkms_config_is_valid(). + * + * Returns: + * The primary plane or NULL if none is assigned yet. + */ +struct vkms_config_plane *vkms_config_crtc_primary_plane(const struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg); + +/** + * vkms_config_crtc_cursor_plane() - Return the cursor plane for a CRTC + * @config: Configuration containing the CRTC + * @crtc_config: Target CRTC + * + * Note that, if multiple cursor planes are found, the first one is returned. + * In this case, the configuration will be invalid. See vkms_config_is_valid(). + * + * Returns: + * The cursor plane or NULL if none is assigned yet. + */ +struct vkms_config_plane *vkms_config_crtc_cursor_plane(const struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg); + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index ba977ef09b2b..a24d1655f7b8 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -181,7 +181,8 @@ static int vkms_create(struct vkms_config *config) goto out_devres; } - ret = drm_vblank_init(&vkms_device->drm, 1); + ret = drm_vblank_init(&vkms_device->drm, + vkms_config_get_num_crtcs(config)); if (ret) { DRM_ERROR("Failed to vblank\n"); goto out_devres; diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 08ea691db299..f63bc8e3014b 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -10,9 +10,8 @@ int vkms_output_init(struct vkms_device *vkmsdev) struct drm_device *dev = &vkmsdev->drm; struct vkms_connector *connector; struct drm_encoder *encoder; - struct vkms_output *output; - struct vkms_plane *primary = NULL, *cursor = NULL; struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; int ret; int writeback; @@ -29,18 +28,37 @@ int vkms_output_init(struct vkms_device *vkmsdev) DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n"); return PTR_ERR(plane_cfg->plane); } + } + + vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) { + struct vkms_config_plane *primary, *cursor; + + primary = vkms_config_crtc_primary_plane(vkmsdev->config, crtc_cfg); + cursor = vkms_config_crtc_cursor_plane(vkmsdev->config, crtc_cfg); - if (type == DRM_PLANE_TYPE_PRIMARY) - primary = plane_cfg->plane; - else if (type == DRM_PLANE_TYPE_CURSOR) - cursor = plane_cfg->plane; + crtc_cfg->crtc = vkms_crtc_init(dev, &primary->plane->base, + cursor ? &cursor->plane->base : NULL); + if (IS_ERR(crtc_cfg->crtc)) { + DRM_ERROR("Failed to allocate CRTC\n"); + return PTR_ERR(crtc_cfg->crtc); + } + + /* Initialize the writeback component */ + if (vkms_config_crtc_get_writeback(crtc_cfg)) { + writeback = vkms_enable_writeback_connector(vkmsdev, crtc_cfg->crtc); + if (writeback) + DRM_ERROR("Failed to init writeback connector\n"); + } } - output = vkms_crtc_init(dev, &primary->base, - cursor ? &cursor->base : NULL); - if (IS_ERR(output)) { - DRM_ERROR("Failed to allocate CRTC\n"); - return PTR_ERR(output); + vkms_config_for_each_plane(vkmsdev->config, plane_cfg) { + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; + + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + plane_cfg->plane->base.possible_crtcs |= + drm_crtc_mask(&possible_crtc->crtc->crtc); + } } connector = vkms_connector_init(vkmsdev); @@ -60,7 +78,9 @@ int vkms_output_init(struct vkms_device *vkmsdev) DRM_ERROR("Failed to init encoder\n"); return ret; } - encoder->possible_crtcs = drm_crtc_mask(&output->crtc); + + vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) + encoder->possible_crtcs = drm_crtc_mask(&crtc_cfg->crtc->crtc); /* Attach the encoder and the connector */ ret = drm_connector_attach_encoder(&connector->base, encoder); @@ -69,13 +89,6 @@ int vkms_output_init(struct vkms_device *vkmsdev) return ret; } - /* Initialize the writeback component */ - if (vkmsdev->config->writeback) { - writeback = vkms_enable_writeback_connector(vkmsdev, output); - if (writeback) - DRM_ERROR("Failed to init writeback connector\n"); - } - drm_mode_config_reset(dev); return ret; From patchwork Mon Feb 17 10:01:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977443 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CE82EC021A0 for ; Mon, 17 Feb 2025 10:01:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1E69610E408; Mon, 17 Feb 2025 10:01:57 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZqVl3Vqp"; dkim-atps=neutral Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5230710E3ED for ; Mon, 17 Feb 2025 10:01:39 +0000 (UTC) Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-38f378498c9so1388707f8f.1 for ; Mon, 17 Feb 2025 02:01:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786498; x=1740391298; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QE/hUz6GYbvwIk0/ln/IOlUTy13vdrYGmRx1J7/N6cw=; b=ZqVl3VqpZjKNQHr3FabbK5NIFnTcZjZsOh3D4pLklpz8Vsw0g3UMgLATBGL4NEEtqt AY+wXSu9orudIIFjuF+dnW5zD4lsVsdRSxMHv/yNLFBYu6OIamR0y85W+N+/u9tCpaqR LA/rqtCvcsbP39fw77y7e6NGQKmSWegjL7uv53s81HZXOJss8hxxCRO6OVQR5pQeJA5r RQ794qKJTuIYepLRgMVTub8Bv8GzFBNTIymynvPN/ci2KPTeDQDxQU4xTV16ywkV/FVJ cMBMb0TJk1vQXqI4AqomryNWcVivI+cE3ECrzFBeb7fdmRqVrv6ZDGFaoYgdMOcDiXqP zBBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786498; x=1740391298; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QE/hUz6GYbvwIk0/ln/IOlUTy13vdrYGmRx1J7/N6cw=; b=sGMIiPlhdVQGYSIEtVPlUYYW24KVPgW8VamlLasUsLUBGWuP06Br3nUkQBCFV5/LiI PgbKmEWmGRL7+4pttcjVPVVR/UTZFEG0uJ9ao+Wj7iOFvuw12Rgzxy5BFdf5LANvuvIF R2OwY1crMQWZWGgMRUqxMq1NdRyfCDQdrpkha4yEj1uxJc+Qr4ZNcga0j+N+LTzVcWWJ Ntu4R04OdaYL6Q1HPpuaK3bbrge59qiC0Rl6NoKBrqcYNh0NWziuqDdFpYrEHGlPo9MM q5kN0+Rou+tFDYp2khU1OUB3znp/l6Xzf5reCmWoeJxwQBDrm0WYaD0sksjPzu8fuikE K48Q== X-Forwarded-Encrypted: i=1; AJvYcCX9+1JZdjyznjfD/5dWLAfzJ8H63RkRvw/hdmF186BmV4opiV8yiwLzOUlf6n3B8g4vPJ8zVJ5EeZI=@lists.freedesktop.org X-Gm-Message-State: AOJu0YwIFkhKHoTS7f6n0B2UYXt1MaNv3UH/QrhCacI6+BEzN0qK0vrx 6P7YXgh8utjsGzKEYfWsv7HF8ww3K9leGKRVbhZco2fJDH4dR/G0 X-Gm-Gg: ASbGncsBzE7LbGIxdro7dVQSElg0fHcM6VuRkJtghleAGLOTrO+dIoRkQsza18PLg3T eSwt5wruZDaNd3uHWX2q3SSSaT+hT3k7ViJgl7Cy+poMemyr+x6UykbjKqIxocG9LuF5UQlmYSm RdHmo5EhGLfojZVoqP0naRYur22yNN2zlnNcyjFitVDsCB75xX1LkDO2EfwZXygWAFYIqKTVFbW Ch5XwXIN5xtb+61a7Slu9yKOV0XtDVOSRa6wVVqny0bdqVMLk8YJY/35oDPewck3witIIiy83Sn QqHglJY0IoOg7mSNjw== X-Google-Smtp-Source: AGHT+IGyqqXdCDlpGFfiHEQ2LUXkFawndXkHby5XB87IbcBSHCsBW62ArJ64y5Rm2Ma51E8LAMaxFw== X-Received: by 2002:a05:6000:18a9:b0:38f:2990:c091 with SMTP id ffacd0b85a97d-38f33f1224bmr8086177f8f.6.1739786496997; Mon, 17 Feb 2025 02:01:36 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:36 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 11/14] drm/vkms: Allow to configure multiple encoders Date: Mon, 17 Feb 2025 11:01:17 +0100 Message-ID: <20250217100120.7620-12-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add a list of encoders to vkms_config and helper functions to add and remove as many encoders as wanted. For backwards compatibility, add one encoder to the default configuration. A future patch will allow to attach encoders and CRTCs, but for the moment there are no changes in the way the output is configured. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 73 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 54 ++++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 46 ++++++++++++ 4 files changed, 174 insertions(+) diff --git a/.clang-format b/.clang-format index 6f944fa39841..c355a2f58eed 100644 --- a/.clang-format +++ b/.clang-format @@ -691,6 +691,7 @@ ForEachMacros: - 'v4l2_m2m_for_each_src_buf_safe' - 'virtio_device_for_each_vq' - 'vkms_config_for_each_crtc' + - 'vkms_config_for_each_encoder' - 'vkms_config_for_each_plane' - 'vkms_config_plane_for_each_possible_crtc' - 'while_for_each_ftrace_op' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index b7a0a8202819..92926972c64c 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -26,6 +26,7 @@ static void vkms_config_test_empty_config(struct kunit *test) KUNIT_EXPECT_TRUE(test, list_empty(&config->planes)); KUNIT_EXPECT_TRUE(test, list_empty(&config->crtcs)); + KUNIT_EXPECT_TRUE(test, list_empty(&config->encoders)); KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); @@ -99,6 +100,9 @@ static void vkms_config_test_default_config(struct kunit *test) KUNIT_EXPECT_EQ(test, n_possible_crtcs, 1); } + /* Encoders */ + KUNIT_EXPECT_EQ(test, list_count_nodes(&config->encoders), 1); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); vkms_config_destroy(config); @@ -184,6 +188,50 @@ static void vkms_config_test_get_crtcs(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_get_encoders(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_encoder *encoder_cfg; + struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; + int n_encoders = 0; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + vkms_config_for_each_encoder(config, encoder_cfg) + n_encoders++; + KUNIT_ASSERT_EQ(test, n_encoders, 0); + + encoder_cfg1 = vkms_config_create_encoder(config); + vkms_config_for_each_encoder(config, encoder_cfg) { + n_encoders++; + if (encoder_cfg != encoder_cfg1) + KUNIT_FAIL(test, "Unexpected encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 1); + n_encoders = 0; + + encoder_cfg2 = vkms_config_create_encoder(config); + vkms_config_for_each_encoder(config, encoder_cfg) { + n_encoders++; + if (encoder_cfg != encoder_cfg1 && encoder_cfg != encoder_cfg2) + KUNIT_FAIL(test, "Unexpected encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 2); + n_encoders = 0; + + vkms_config_destroy_encoder(config, encoder_cfg2); + vkms_config_for_each_encoder(config, encoder_cfg) { + n_encoders++; + if (encoder_cfg != encoder_cfg1) + KUNIT_FAIL(test, "Unexpected encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 1); + n_encoders = 0; + + vkms_config_destroy(config); +} + static void vkms_config_test_invalid_plane_number(struct kunit *test) { struct vkms_config *config; @@ -319,6 +367,29 @@ static void vkms_config_test_invalid_crtc_number(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_invalid_encoder_number(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_encoder *encoder_cfg; + int n; + + config = vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + /* Invalid: No encoders */ + encoder_cfg = list_first_entry(&config->encoders, typeof(*encoder_cfg), link); + vkms_config_destroy_encoder(config, encoder_cfg); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Invalid: Too many encoders */ + for (n = 0; n <= 32; n++) + vkms_config_create_encoder(config); + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static void vkms_config_test_attach_different_configs(struct kunit *test) { struct vkms_config *config1, *config2; @@ -483,10 +554,12 @@ static struct kunit_case vkms_config_test_cases[] = { default_config_gen_params), KUNIT_CASE(vkms_config_test_get_planes), KUNIT_CASE(vkms_config_test_get_crtcs), + KUNIT_CASE(vkms_config_test_get_encoders), KUNIT_CASE(vkms_config_test_invalid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), 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), KUNIT_CASE(vkms_config_test_attach_different_configs), KUNIT_CASE(vkms_config_test_plane_attach_crtc), KUNIT_CASE(vkms_config_test_plane_get_possible_crtcs), diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index 458385413648..db8be054f6f4 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -24,6 +24,7 @@ struct vkms_config *vkms_config_create(const char *dev_name) INIT_LIST_HEAD(&config->planes); INIT_LIST_HEAD(&config->crtcs); + INIT_LIST_HEAD(&config->encoders); return config; } @@ -36,6 +37,7 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, struct vkms_config *config; struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; + struct vkms_config_encoder *encoder_cfg; int n; config = vkms_config_create(DEFAULT_DEVICE_NAME); @@ -80,6 +82,10 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, goto err_alloc; } + encoder_cfg = vkms_config_create_encoder(config); + if (IS_ERR(encoder_cfg)) + goto err_alloc; + return config; err_alloc: @@ -92,6 +98,7 @@ void vkms_config_destroy(struct vkms_config *config) { struct vkms_config_plane *plane_cfg, *plane_tmp; struct vkms_config_crtc *crtc_cfg, *crtc_tmp; + struct vkms_config_encoder *encoder_cfg, *encoder_tmp; list_for_each_entry_safe(plane_cfg, plane_tmp, &config->planes, link) vkms_config_destroy_plane(plane_cfg); @@ -99,6 +106,9 @@ void vkms_config_destroy(struct vkms_config *config) list_for_each_entry_safe(crtc_cfg, crtc_tmp, &config->crtcs, link) vkms_config_destroy_crtc(config, crtc_cfg); + list_for_each_entry_safe(encoder_cfg, encoder_tmp, &config->encoders, link) + vkms_config_destroy_encoder(config, encoder_cfg); + kfree_const(config->dev_name); kfree(config); } @@ -192,6 +202,20 @@ static bool valid_crtc_number(const struct vkms_config *config) return true; } +static bool valid_encoder_number(const struct vkms_config *config) +{ + struct drm_device *dev = config->dev ? &config->dev->drm : NULL; + size_t n_encoders; + + n_encoders = list_count_nodes((struct list_head *)&config->encoders); + if (n_encoders <= 0 || n_encoders >= 32) { + drm_info(dev, "The number of encoders must be between 1 and 31\n"); + return false; + } + + return true; +} + bool vkms_config_is_valid(const struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -202,6 +226,9 @@ bool vkms_config_is_valid(const struct vkms_config *config) if (!valid_crtc_number(config)) return false; + if (!valid_encoder_number(config)) + return false; + if (!valid_plane_possible_crtcs(config)) return false; @@ -222,6 +249,7 @@ static int vkms_config_show(struct seq_file *m, void *data) const char *dev_name; struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; + struct vkms_config_encoder *encoder_cfg; dev_name = vkms_config_get_device_name((struct vkms_config *)vkmsdev->config); seq_printf(m, "dev_name=%s\n", dev_name); @@ -238,6 +266,9 @@ static int vkms_config_show(struct seq_file *m, void *data) vkms_config_crtc_get_writeback(crtc_cfg)); } + vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) + seq_puts(m, "encoder\n"); + return 0; } @@ -384,3 +415,26 @@ struct vkms_config_plane *vkms_config_crtc_cursor_plane(const struct vkms_config return vkms_config_crtc_get_plane(config, crtc_cfg, DRM_PLANE_TYPE_CURSOR); } EXPORT_SYMBOL_IF_KUNIT(vkms_config_crtc_cursor_plane); + +struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *config) +{ + struct vkms_config_encoder *encoder_cfg; + + encoder_cfg = kzalloc(sizeof(*encoder_cfg), GFP_KERNEL); + if (!encoder_cfg) + return ERR_PTR(-ENOMEM); + + encoder_cfg->config = config; + list_add_tail(&encoder_cfg->link, &config->encoders); + + return encoder_cfg; +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_encoder); + +void vkms_config_destroy_encoder(struct vkms_config *config, + struct vkms_config_encoder *encoder_cfg) +{ + list_del(&encoder_cfg->link); + kfree(encoder_cfg); +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_encoder); diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index ad303b34ee03..024cbed0e439 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -15,12 +15,14 @@ * @dev_name: Name of the device * @planes: List of planes configured for the device * @crtcs: List of CRTCs configured for the device + * @encoders: List of encoders configured for the device * @dev: Used to store the current VKMS device. Only set when the device is instantiated. */ struct vkms_config { const char *dev_name; struct list_head planes; struct list_head crtcs; + struct list_head encoders; struct vkms_device *dev; }; @@ -69,6 +71,24 @@ struct vkms_config_crtc { struct vkms_output *crtc; }; +/** + * struct vkms_config_encoder + * + * @link: Link to the others encoders in vkms_config + * @config: The vkms_config this CRTC belongs to + * @encoder: Internal usage. This pointer should never be considered as valid. + * It can be used to store a temporary reference to a VKMS encoder + * during device creation. This pointer is not managed by the + * configuration and must be managed by other means. + */ +struct vkms_config_encoder { + struct list_head link; + struct vkms_config *config; + + /* Internal usage */ + struct drm_encoder *encoder; +}; + /** * vkms_config_for_each_plane - Iterate over the vkms_config planes * @config: &struct vkms_config pointer @@ -85,6 +105,14 @@ struct vkms_config_crtc { #define vkms_config_for_each_crtc(config, crtc_cfg) \ list_for_each_entry((crtc_cfg), &(config)->crtcs, link) +/** + * vkms_config_for_each_encoder - Iterate over the vkms_config encoders + * @config: &struct vkms_config pointer + * @encoder_cfg: &struct vkms_config_encoder pointer used as cursor + */ +#define vkms_config_for_each_encoder(config, encoder_cfg) \ + list_for_each_entry((encoder_cfg), &(config)->encoders, link) + /** * vkms_config_plane_for_each_possible_crtc - Iterate over the vkms_config_plane * possible CRTCs @@ -286,4 +314,22 @@ struct vkms_config_plane *vkms_config_crtc_primary_plane(const struct vkms_confi struct vkms_config_plane *vkms_config_crtc_cursor_plane(const struct vkms_config *config, struct vkms_config_crtc *crtc_cfg); +/** + * vkms_config_create_encoder() - Add a new encoder configuration + * @config: Configuration to add the encoder to + * + * Returns: + * The new encoder configuration or an error. Call vkms_config_destroy_encoder() + * to free the returned encoder configuration. + */ +struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *config); + +/** + * vkms_config_destroy_encoder() - Remove and free a encoder configuration + * @config: Configuration to remove the encoder from + * @encoder_cfg: Encoder configuration to destroy + */ +void vkms_config_destroy_encoder(struct vkms_config *config, + struct vkms_config_encoder *encoder_cfg); + #endif /* _VKMS_CONFIG_H_ */ From patchwork Mon Feb 17 10:01:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977441 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7672CC0219E for ; Mon, 17 Feb 2025 10:01:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DD56410E3C2; Mon, 17 Feb 2025 10:01:54 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="TFV9sYhf"; dkim-atps=neutral Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id ACA4D10E3ED for ; Mon, 17 Feb 2025 10:01:39 +0000 (UTC) Received: by mail-wr1-f43.google.com with SMTP id ffacd0b85a97d-38f2f748128so1215396f8f.1 for ; Mon, 17 Feb 2025 02:01:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786498; x=1740391298; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cQlaDUo4DM2CfG9+Vwr7FXGbsG9nzlidtjF2Ge79JFI=; b=TFV9sYhfokHqI9VGYK4x0n8eH7pN0aCUNbIwIWy3zwX2TjU1HH4PmSD0gXQ49Vyh7a 1Nl927bs1ou8Yz97DxEJHB+dY66fXLJJEMGjBPXSJZygeayacQ1ZVVHjjGX91fqVu65D 5k+ylBZAt4WcCo60FrnIAUHWb79WWKWvmmrjn0JHPWJrUvVVm3L9zI6xMo7ZF7XaJ4dy TSkw3UOphvsGa4XvbWwzQi2I0pDxQgsuHfdYYiOIAySM1zEEKNeHX4UIX3ft049n8zx/ cIMQ3fJEo0WwsXwBr5/HurBaLjGkjvglsWubc3Ghxyxi19OovLMmTmLFT2A4l3Pi8Dqu QM5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786498; x=1740391298; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cQlaDUo4DM2CfG9+Vwr7FXGbsG9nzlidtjF2Ge79JFI=; b=lLsH+zwTHQfz7fDXN2CRpSc+JsoL9lGZi+69Sn3PbF0+KT4Rsuks/aq8LIGOqsHpZO bOspkfhN6ikIZ0nq2d4wDhozn8YqhEo+dp/+3XEDRL3hH4w8RhqRcdqbYd2V88tZ6EV8 s48oLIznN8d0WJYw2JDZ4BdyTK8n9ervOS+wXDqqo9UUt5C8eegTA913vPJoYOqKhhVl pUPRI5/SXGjn0CEnF2Oj9EziXCRcpAnd171MSio6E3hMjswqvikXuFX5dcxVBHayviVi 1xuMHQKDNsMa0Wthr9XoraV7ICfgMBcgeSKzIh6t6Mc0VOGaN4YuIq6srl+lfUbF7P4t FNEg== X-Forwarded-Encrypted: i=1; AJvYcCW1NgooDO81JxH9l+USHApAvuM3ASM1gC8bLQ3+y7uyzprnSFNBsUxLmCrhWUkdY1XQBzkA/dujDss=@lists.freedesktop.org X-Gm-Message-State: AOJu0YypwbVjVkrz3NNg+nu5qX62qBTrenPzqmDL6AymWzxZOXhzUN4L NycH6ck42FIhWVdMW6D8M7ONtju20ZqXApl3knacf93we51WvQIW X-Gm-Gg: ASbGnctD5ZYz4HhLQy6gxIi93j4Oth02TVcqikjX93J65EMlEtU8JNE1rnTdf+emtd8 Q4XQemqAEyp/IQ8/K+2A4VdqK4uzSvB+/Yz6+OJmjrZEXITgk+xYWshHn1VO98iQHx6Aq4Ix9VN 2NXT08FBcTHUNRc2FpbpcLR3DxwQ6fPhoY/1ZUG34HlWs/EWf/2W5/fFug/KxT/IwonCbkB4x1D saF7bjpSDvdkyns76thwmkBT2+Lfff3241nx6sOdIry5n1R1b5kQ7lLzQc/OjN0HAS86w01GRgM tIXJqrdFGs8DEgXYTg== X-Google-Smtp-Source: AGHT+IERgf4vCWOYJpiPaChwre4D7Jf7Oj+yRx0VaKhY3mB+GYSaJMeKEQKY6m15DvRWOPQHqCbCQw== X-Received: by 2002:a05:6000:1568:b0:38f:43c8:f751 with SMTP id ffacd0b85a97d-38f43c8fa82mr4178871f8f.35.1739786497932; Mon, 17 Feb 2025 02:01:37 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:37 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 12/14] drm/vkms: Allow to attach encoders and CRTCs Date: Mon, 17 Feb 2025 11:01:18 +0100 Message-ID: <20250217100120.7620-13-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add a list of possible CRTCs to the encoder configuration and helpers to attach and detach them. Now that the default configuration has its encoder and CRTC correctly attached, configure the output following the configuration. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 125 ++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 82 ++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 29 ++++ drivers/gpu/drm/vkms/vkms_output.c | 49 ++++--- 5 files changed, 266 insertions(+), 20 deletions(-) diff --git a/.clang-format b/.clang-format index c355a2f58eed..5d21c0e4edbd 100644 --- a/.clang-format +++ b/.clang-format @@ -693,6 +693,7 @@ ForEachMacros: - 'vkms_config_for_each_crtc' - 'vkms_config_for_each_encoder' - 'vkms_config_for_each_plane' + - 'vkms_config_encoder_for_each_possible_crtc' - 'vkms_config_plane_for_each_possible_crtc' - 'while_for_each_ftrace_op' - 'xa_for_each' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 92926972c64c..62fbcba4520f 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -260,6 +260,7 @@ static void vkms_config_test_valid_plane_type(struct kunit *test) struct vkms_config *config; struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; + struct vkms_config_encoder *encoder_cfg; int err; config = vkms_config_default_create(false, false, false); @@ -313,6 +314,9 @@ static void vkms_config_test_valid_plane_type(struct kunit *test) /* Invalid: Second CRTC without primary plane */ crtc_cfg = vkms_config_create_crtc(config); + encoder_cfg = vkms_config_create_encoder(config); + err = vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); /* Valid: Second CRTC with a primary plane */ @@ -390,11 +394,57 @@ static void vkms_config_test_invalid_encoder_number(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_valid_encoder_possible_crtcs(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; + struct vkms_config_encoder *encoder_cfg; + int err; + + config = vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + crtc_cfg1 = list_first_entry(&config->crtcs, typeof(*crtc_cfg1), link); + + /* Invalid: Encoder without a possible CRTC */ + encoder_cfg = vkms_config_create_encoder(config); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: Second CRTC with shared encoder */ + crtc_cfg2 = vkms_config_create_crtc(config); + + plane_cfg = vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + err = vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg1); + KUNIT_EXPECT_EQ(test, err, 0); + + err = vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + /* Invalid: Second CRTC without encoders */ + vkms_config_encoder_detach_crtc(encoder_cfg, crtc_cfg2); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: First CRTC with 2 possible encoder */ + vkms_config_destroy_plane(plane_cfg); + vkms_config_destroy_crtc(config, crtc_cfg2); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static void vkms_config_test_attach_different_configs(struct kunit *test) { struct vkms_config *config1, *config2; struct vkms_config_plane *plane_cfg1, *plane_cfg2; struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; + struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; int err; config1 = vkms_config_create("test1"); @@ -405,20 +455,29 @@ static void vkms_config_test_attach_different_configs(struct kunit *test) plane_cfg1 = vkms_config_create_plane(config1); crtc_cfg1 = vkms_config_create_crtc(config1); + encoder_cfg1 = vkms_config_create_encoder(config1); plane_cfg2 = vkms_config_create_plane(config2); crtc_cfg2 = vkms_config_create_crtc(config2); + encoder_cfg2 = vkms_config_create_encoder(config2); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg1); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg2); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg1); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg1); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg2); err = vkms_config_plane_attach_crtc(plane_cfg1, crtc_cfg2); KUNIT_EXPECT_NE(test, err, 0); err = vkms_config_plane_attach_crtc(plane_cfg2, crtc_cfg1); KUNIT_EXPECT_NE(test, err, 0); + err = vkms_config_encoder_attach_crtc(encoder_cfg1, crtc_cfg2); + KUNIT_EXPECT_NE(test, err, 0); + err = vkms_config_encoder_attach_crtc(encoder_cfg2, crtc_cfg1); + KUNIT_EXPECT_NE(test, err, 0); + vkms_config_destroy(config1); vkms_config_destroy(config2); } @@ -548,6 +607,70 @@ static void vkms_config_test_plane_get_possible_crtcs(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_encoder_get_possible_crtcs(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; + struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; + int n_crtcs = 0; + int err; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + encoder_cfg1 = vkms_config_create_encoder(config); + encoder_cfg2 = vkms_config_create_encoder(config); + crtc_cfg1 = vkms_config_create_crtc(config); + crtc_cfg2 = vkms_config_create_crtc(config); + + /* No possible CRTCs */ + vkms_config_encoder_for_each_possible_crtc(encoder_cfg1, idx, possible_crtc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg2, idx, possible_crtc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + /* Encoder 1 attached to CRTC 1 and 2 */ + err = vkms_config_encoder_attach_crtc(encoder_cfg1, crtc_cfg1); + KUNIT_EXPECT_EQ(test, err, 0); + err = vkms_config_encoder_attach_crtc(encoder_cfg1, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg1, idx, possible_crtc) { + n_crtcs++; + if (possible_crtc != crtc_cfg1 && possible_crtc != crtc_cfg2) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 2); + n_crtcs = 0; + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg2, idx, possible_crtc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + /* Encoder 1 attached to CRTC 1 and encoder 2 to CRTC 2 */ + vkms_config_encoder_detach_crtc(encoder_cfg1, crtc_cfg2); + vkms_config_encoder_for_each_possible_crtc(encoder_cfg1, idx, possible_crtc) { + n_crtcs++; + if (possible_crtc != crtc_cfg1) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 1); + n_crtcs = 0; + + err = vkms_config_encoder_attach_crtc(encoder_cfg2, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + vkms_config_encoder_for_each_possible_crtc(encoder_cfg2, idx, possible_crtc) { + n_crtcs++; + if (possible_crtc != crtc_cfg2) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 1); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_empty_config), KUNIT_CASE_PARAM(vkms_config_test_default_config, @@ -560,9 +683,11 @@ static struct kunit_case vkms_config_test_cases[] = { 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), + KUNIT_CASE(vkms_config_test_valid_encoder_possible_crtcs), KUNIT_CASE(vkms_config_test_attach_different_configs), KUNIT_CASE(vkms_config_test_plane_attach_crtc), KUNIT_CASE(vkms_config_test_plane_get_possible_crtcs), + KUNIT_CASE(vkms_config_test_encoder_get_possible_crtcs), {} }; diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index db8be054f6f4..17262a9c2567 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -86,6 +86,9 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, if (IS_ERR(encoder_cfg)) goto err_alloc; + if (vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg)) + goto err_alloc; + return config; err_alloc: @@ -216,6 +219,42 @@ static bool valid_encoder_number(const struct vkms_config *config) return true; } +static bool valid_encoder_possible_crtcs(const struct vkms_config *config) +{ + struct drm_device *dev = config->dev ? &config->dev->drm : NULL; + struct vkms_config_crtc *crtc_cfg; + struct vkms_config_encoder *encoder_cfg; + + vkms_config_for_each_encoder(config, encoder_cfg) { + if (xa_empty(&encoder_cfg->possible_crtcs)) { + drm_info(dev, "All encoders must have at least one possible CRTC\n"); + return false; + } + } + + vkms_config_for_each_crtc(config, crtc_cfg) { + bool crtc_has_encoder = false; + + vkms_config_for_each_encoder(config, encoder_cfg) { + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg, + idx, possible_crtc) { + if (possible_crtc == crtc_cfg) + crtc_has_encoder = true; + } + } + + if (!crtc_has_encoder) { + drm_info(dev, "All CRTCs must have at least one possible encoder\n"); + return false; + } + } + + return true; +} + bool vkms_config_is_valid(const struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -237,6 +276,9 @@ bool vkms_config_is_valid(const struct vkms_config *config) return false; } + if (!valid_encoder_possible_crtcs(config)) + return false; + return true; } EXPORT_SYMBOL_IF_KUNIT(vkms_config_is_valid); @@ -362,10 +404,14 @@ void vkms_config_destroy_crtc(struct vkms_config *config, struct vkms_config_crtc *crtc_cfg) { struct vkms_config_plane *plane_cfg; + struct vkms_config_encoder *encoder_cfg; vkms_config_for_each_plane(config, plane_cfg) vkms_config_plane_detach_crtc(plane_cfg, crtc_cfg); + vkms_config_for_each_encoder(config, encoder_cfg) + vkms_config_encoder_detach_crtc(encoder_cfg, crtc_cfg); + list_del(&crtc_cfg->link); kfree(crtc_cfg); } @@ -425,6 +471,8 @@ struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *confi return ERR_PTR(-ENOMEM); encoder_cfg->config = config; + xa_init_flags(&encoder_cfg->possible_crtcs, XA_FLAGS_ALLOC); + list_add_tail(&encoder_cfg->link, &config->encoders); return encoder_cfg; @@ -434,7 +482,41 @@ EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_encoder); void vkms_config_destroy_encoder(struct vkms_config *config, struct vkms_config_encoder *encoder_cfg) { + xa_destroy(&encoder_cfg->possible_crtcs); list_del(&encoder_cfg->link); kfree(encoder_cfg); } EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_encoder); + +int __must_check vkms_config_encoder_attach_crtc(struct vkms_config_encoder *encoder_cfg, + struct vkms_config_crtc *crtc_cfg) +{ + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; + u32 crtc_idx = 0; + + if (encoder_cfg->config != crtc_cfg->config) + return -EINVAL; + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possible_crtc) { + if (possible_crtc == crtc_cfg) + return -EEXIST; + } + + return xa_alloc(&encoder_cfg->possible_crtcs, &crtc_idx, crtc_cfg, + xa_limit_32b, GFP_KERNEL); +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_encoder_attach_crtc); + +void vkms_config_encoder_detach_crtc(struct vkms_config_encoder *encoder_cfg, + struct vkms_config_crtc *crtc_cfg) +{ + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possible_crtc) { + if (possible_crtc == crtc_cfg) + xa_erase(&encoder_cfg->possible_crtcs, idx); + } +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_encoder_detach_crtc); diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index 024cbed0e439..3e5b2e407378 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -76,6 +76,7 @@ struct vkms_config_crtc { * * @link: Link to the others encoders in vkms_config * @config: The vkms_config this CRTC belongs to + * @possible_crtcs: Array of CRTCs that can be used with this encoder * @encoder: Internal usage. This pointer should never be considered as valid. * It can be used to store a temporary reference to a VKMS encoder * during device creation. This pointer is not managed by the @@ -85,6 +86,8 @@ struct vkms_config_encoder { struct list_head link; struct vkms_config *config; + struct xarray possible_crtcs; + /* Internal usage */ struct drm_encoder *encoder; }; @@ -123,6 +126,16 @@ struct vkms_config_encoder { #define vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) \ xa_for_each(&(plane_cfg)->possible_crtcs, idx, (possible_crtc)) +/** + * vkms_config_encoder_for_each_possible_crtc - Iterate over the + * vkms_config_encoder possible CRTCs + * @encoder_cfg: &struct vkms_config_encoder pointer + * @idx: Index of the cursor + * @possible_crtc: &struct vkms_config_crtc pointer used as cursor + */ +#define vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possible_crtc) \ + xa_for_each(&(encoder_cfg)->possible_crtcs, idx, (possible_crtc)) + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -332,4 +345,20 @@ struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *confi void vkms_config_destroy_encoder(struct vkms_config *config, struct vkms_config_encoder *encoder_cfg); +/** + * vkms_config_encoder_attach_crtc - Attach a encoder to a CRTC + * @encoder_cfg: Encoder to attach + * @crtc_cfg: CRTC to attach @encoder_cfg to + */ +int __must_check vkms_config_encoder_attach_crtc(struct vkms_config_encoder *encoder_cfg, + struct vkms_config_crtc *crtc_cfg); + +/** + * vkms_config_encoder_detach_crtc - Detach a encoder from a CRTC + * @encoder_cfg: Encoder to detach + * @crtc_cfg: CRTC to detach @encoder_cfg from + */ +void vkms_config_encoder_detach_crtc(struct vkms_config_encoder *encoder_cfg, + struct vkms_config_crtc *crtc_cfg); + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index f63bc8e3014b..8920d6b5d105 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -9,9 +9,9 @@ int vkms_output_init(struct vkms_device *vkmsdev) { struct drm_device *dev = &vkmsdev->drm; struct vkms_connector *connector; - struct drm_encoder *encoder; struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; + struct vkms_config_encoder *encoder_cfg; int ret; int writeback; @@ -61,32 +61,41 @@ int vkms_output_init(struct vkms_device *vkmsdev) } } + vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) { + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; + + encoder_cfg->encoder = drmm_kzalloc(dev, sizeof(*encoder_cfg->encoder), GFP_KERNEL); + if (!encoder_cfg->encoder) { + DRM_ERROR("Failed to allocate encoder\n"); + return -ENOMEM; + } + ret = drmm_encoder_init(dev, encoder_cfg->encoder, NULL, + DRM_MODE_ENCODER_VIRTUAL, NULL); + if (ret) { + DRM_ERROR("Failed to init encoder\n"); + return ret; + } + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possible_crtc) { + encoder_cfg->encoder->possible_crtcs |= + drm_crtc_mask(&possible_crtc->crtc->crtc); + } + } + connector = vkms_connector_init(vkmsdev); if (IS_ERR(connector)) { DRM_ERROR("Failed to init connector\n"); return PTR_ERR(connector); } - encoder = drmm_kzalloc(dev, sizeof(*encoder), GFP_KERNEL); - if (!encoder) { - DRM_ERROR("Failed to allocate encoder\n"); - return -ENOMEM; - } - ret = drmm_encoder_init(dev, encoder, NULL, - DRM_MODE_ENCODER_VIRTUAL, NULL); - if (ret) { - DRM_ERROR("Failed to init encoder\n"); - return ret; - } - - vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) - encoder->possible_crtcs = drm_crtc_mask(&crtc_cfg->crtc->crtc); - /* Attach the encoder and the connector */ - ret = drm_connector_attach_encoder(&connector->base, encoder); - if (ret) { - DRM_ERROR("Failed to attach connector to encoder\n"); - return ret; + vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) { + ret = drm_connector_attach_encoder(&connector->base, encoder_cfg->encoder); + if (ret) { + DRM_ERROR("Failed to attach connector to encoder\n"); + return ret; + } } drm_mode_config_reset(dev); From patchwork Mon Feb 17 10:01:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977438 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4A9F9C021A0 for ; Mon, 17 Feb 2025 10:01:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 22AEB10E3FE; Mon, 17 Feb 2025 10:01:43 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="O7+2Mr/O"; dkim-atps=neutral Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) by gabe.freedesktop.org (Postfix) with ESMTPS id 54B0C10E3ED for ; Mon, 17 Feb 2025 10:01:41 +0000 (UTC) Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-4396e9ee133so9136215e9.0 for ; Mon, 17 Feb 2025 02:01:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786500; x=1740391300; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TsH5GoAFJ5tlGQR+a6vIGy2HGR87dyc91TICMzNL7FI=; b=O7+2Mr/OgD9a0HIevcZbBPUcQ9tMYy/50waNG25/Cc6iStf/uwpExlldQS1URdhfXl oeYTaQRiqbEi0XAG34FQzzdVQ0lxucFZ94ISEcLtt+OTrbeKV4OEfKVh3DoXlCtEsJd2 5MLprQiFZ7kVdWc3mtQXbTwIN++zj0Q3JELUqABLYnb6i4Ss3wPmBuCQSTJWovmaVC6x EnqZ+W5RckINr65XD5Vkjv5bLyO6xchf2dRafyt23t0wkQ6PWay3c89MQPFDnicVKFRn 2YEz139kfI1Z+lz3KW3f6TAetHh9sBHYAqWW1PcQ3S8aWTYRnsGkyaa6//jr/efEj3sy PAIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786500; x=1740391300; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TsH5GoAFJ5tlGQR+a6vIGy2HGR87dyc91TICMzNL7FI=; b=cY0dtJrBC+N2bIyeedGN24jEHA1yNz6LuCLYne8Rl5PGAarZW7FrzvODeUY7wDn0wd c1XK1sBpBpAGDq5Bvp5/oc9/VVOAAy5/q+eWpDMql+IpT8ZWDEF5IFsbc4gGopHzfg93 eeKeohuNR5CA3uL4ENdF4tcg3OugG4RIu8NhVkhhb0/JwP5pEGb3768alWPKG+X2dj60 tSTf+fDC7G0+SC5i5sJtcprd2CQ7L30c4OF3Zf3bRMx5QE2ks5XoAvPwYl4eDzY8AECA t9SLvoFbesVPCbZ0lrrUzyiAvBqA5FWUbFoa7jDh2pzSC7KCsbgBIToHBayjiJFV8SP7 iGKA== X-Forwarded-Encrypted: i=1; AJvYcCUmcX1dP8XeCeZYP72DO1yWgm56BU4WMPbKmGflJXqeOeLbiw4xHeiK/7PKcoiZxP0tz8I5IPZBC+A=@lists.freedesktop.org X-Gm-Message-State: AOJu0YwLvUFvhCrctjFemAojxQ1JYYLdexjydu/OBXyOyb8TPUQAK32G ufkMDfKLMRBYOnogfBZkjVaVuuJzZPm57eSxguZ7Gpsa/XUS091/ X-Gm-Gg: ASbGncuCbnqnCSdMkOjS1N3q6FN2K5SxCGuU8vADkNxw5LtcRwMG/quF03ATH+VV8yE is4vGK8g5rfLcMLS1vxAbzNGoI6kXHQsvndGYlvkUofi3uBVFXKVic6Kogm50AcdgpBCTNPBYsC SJPWbrLJN6qPjrHLclWCgAm3iYV4tAMQl4JoT7g9Cj7V8SnrCncOLcMOVNmtn8JnEMqWiVEXEkU S+FDRdPT0svw54YxDRF6QHqr3G++DliJV5MBezoR1egh8eWgFy0A+R+VzOXiUnSg2txHy7NWFKf RcKgPpmJRDFkh2L/oA== X-Google-Smtp-Source: AGHT+IGvvz63U2R7Sm/K+Fh1GHthSY6kpflYYWVJY+5MjqkmhdnWe3kpM+KUCZ7rjWTrdlnvhQ8JCw== X-Received: by 2002:a5d:47a5:0:b0:38d:b12f:60d1 with SMTP id ffacd0b85a97d-38f33c2892emr8878815f8f.26.1739786499537; Mon, 17 Feb 2025 02:01:39 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:38 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 13/14] drm/vkms: Allow to configure multiple connectors Date: Mon, 17 Feb 2025 11:01:19 +0100 Message-ID: <20250217100120.7620-14-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add a list of connectors to vkms_config and helper functions to add and remove as many connectors as wanted. For backwards compatibility, add one enabled connector to the default configuration. A future patch will allow to attach connectors and encoders, but for the moment there are no changes in the way the output is configured. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 74 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 54 ++++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 44 +++++++++++ drivers/gpu/drm/vkms/vkms_connector.c | 11 +++ 5 files changed, 184 insertions(+) diff --git a/.clang-format b/.clang-format index 5d21c0e4edbd..ca49832993c5 100644 --- a/.clang-format +++ b/.clang-format @@ -690,6 +690,7 @@ ForEachMacros: - 'v4l2_m2m_for_each_src_buf' - 'v4l2_m2m_for_each_src_buf_safe' - 'virtio_device_for_each_vq' + - 'vkms_config_for_each_connector' - 'vkms_config_for_each_crtc' - 'vkms_config_for_each_encoder' - 'vkms_config_for_each_plane' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 62fbcba4520f..0034f922713e 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -27,6 +27,7 @@ static void vkms_config_test_empty_config(struct kunit *test) KUNIT_EXPECT_TRUE(test, list_empty(&config->planes)); KUNIT_EXPECT_TRUE(test, list_empty(&config->crtcs)); KUNIT_EXPECT_TRUE(test, list_empty(&config->encoders)); + KUNIT_EXPECT_TRUE(test, list_empty(&config->connectors)); KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); @@ -103,6 +104,9 @@ static void vkms_config_test_default_config(struct kunit *test) /* Encoders */ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->encoders), 1); + /* Connectors */ + KUNIT_EXPECT_EQ(test, list_count_nodes(&config->connectors), 1); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); vkms_config_destroy(config); @@ -232,6 +236,51 @@ static void vkms_config_test_get_encoders(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_get_connectors(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_connector *connector_cfg; + struct vkms_config_connector *connector_cfg1, *connector_cfg2; + int n_connectors = 0; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + vkms_config_for_each_connector(config, connector_cfg) + n_connectors++; + KUNIT_ASSERT_EQ(test, n_connectors, 0); + + connector_cfg1 = vkms_config_create_connector(config); + vkms_config_for_each_connector(config, connector_cfg) { + n_connectors++; + if (connector_cfg != connector_cfg1) + KUNIT_FAIL(test, "Unexpected connector"); + } + KUNIT_ASSERT_EQ(test, n_connectors, 1); + n_connectors = 0; + + connector_cfg2 = vkms_config_create_connector(config); + vkms_config_for_each_connector(config, connector_cfg) { + n_connectors++; + if (connector_cfg != connector_cfg1 && + connector_cfg != connector_cfg2) + KUNIT_FAIL(test, "Unexpected connector"); + } + KUNIT_ASSERT_EQ(test, n_connectors, 2); + n_connectors = 0; + + vkms_config_destroy_connector(connector_cfg2); + vkms_config_for_each_connector(config, connector_cfg) { + n_connectors++; + if (connector_cfg != connector_cfg1) + KUNIT_FAIL(test, "Unexpected connector"); + } + KUNIT_ASSERT_EQ(test, n_connectors, 1); + n_connectors = 0; + + vkms_config_destroy(config); +} + static void vkms_config_test_invalid_plane_number(struct kunit *test) { struct vkms_config *config; @@ -439,6 +488,29 @@ static void vkms_config_test_valid_encoder_possible_crtcs(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_invalid_connector_number(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_connector *connector_cfg; + int n; + + config = vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + /* Invalid: No connectors */ + connector_cfg = list_first_entry(&config->connectors, typeof(*connector_cfg), link); + vkms_config_destroy_connector(connector_cfg); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Invalid: Too many connectors */ + for (n = 0; n <= 32; n++) + connector_cfg = vkms_config_create_connector(config); + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static void vkms_config_test_attach_different_configs(struct kunit *test) { struct vkms_config *config1, *config2; @@ -678,12 +750,14 @@ static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_get_planes), KUNIT_CASE(vkms_config_test_get_crtcs), KUNIT_CASE(vkms_config_test_get_encoders), + 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_possible_crtcs), KUNIT_CASE(vkms_config_test_invalid_crtc_number), KUNIT_CASE(vkms_config_test_invalid_encoder_number), KUNIT_CASE(vkms_config_test_valid_encoder_possible_crtcs), + KUNIT_CASE(vkms_config_test_invalid_connector_number), KUNIT_CASE(vkms_config_test_attach_different_configs), KUNIT_CASE(vkms_config_test_plane_attach_crtc), KUNIT_CASE(vkms_config_test_plane_get_possible_crtcs), diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index 17262a9c2567..fbbdee6068ce 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -25,6 +25,7 @@ struct vkms_config *vkms_config_create(const char *dev_name) INIT_LIST_HEAD(&config->planes); INIT_LIST_HEAD(&config->crtcs); INIT_LIST_HEAD(&config->encoders); + INIT_LIST_HEAD(&config->connectors); return config; } @@ -38,6 +39,7 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; struct vkms_config_encoder *encoder_cfg; + struct vkms_config_connector *connector_cfg; int n; config = vkms_config_create(DEFAULT_DEVICE_NAME); @@ -89,6 +91,10 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, if (vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg)) goto err_alloc; + connector_cfg = vkms_config_create_connector(config); + if (IS_ERR(connector_cfg)) + goto err_alloc; + return config; err_alloc: @@ -102,6 +108,7 @@ void vkms_config_destroy(struct vkms_config *config) struct vkms_config_plane *plane_cfg, *plane_tmp; struct vkms_config_crtc *crtc_cfg, *crtc_tmp; struct vkms_config_encoder *encoder_cfg, *encoder_tmp; + struct vkms_config_connector *connector_cfg, *connector_tmp; list_for_each_entry_safe(plane_cfg, plane_tmp, &config->planes, link) vkms_config_destroy_plane(plane_cfg); @@ -112,6 +119,9 @@ void vkms_config_destroy(struct vkms_config *config) list_for_each_entry_safe(encoder_cfg, encoder_tmp, &config->encoders, link) vkms_config_destroy_encoder(config, encoder_cfg); + list_for_each_entry_safe(connector_cfg, connector_tmp, &config->connectors, link) + vkms_config_destroy_connector(connector_cfg); + kfree_const(config->dev_name); kfree(config); } @@ -255,6 +265,20 @@ static bool valid_encoder_possible_crtcs(const struct vkms_config *config) return true; } +static bool valid_connector_number(const struct vkms_config *config) +{ + struct drm_device *dev = config->dev ? &config->dev->drm : NULL; + size_t n_connectors; + + n_connectors = list_count_nodes((struct list_head *)&config->connectors); + if (n_connectors <= 0 || n_connectors >= 32) { + drm_info(dev, "The number of connectors must be between 1 and 31\n"); + return false; + } + + return true; +} + bool vkms_config_is_valid(const struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -268,6 +292,9 @@ bool vkms_config_is_valid(const struct vkms_config *config) if (!valid_encoder_number(config)) return false; + if (!valid_connector_number(config)) + return false; + if (!valid_plane_possible_crtcs(config)) return false; @@ -292,6 +319,7 @@ static int vkms_config_show(struct seq_file *m, void *data) struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; struct vkms_config_encoder *encoder_cfg; + struct vkms_config_connector *connector_cfg; dev_name = vkms_config_get_device_name((struct vkms_config *)vkmsdev->config); seq_printf(m, "dev_name=%s\n", dev_name); @@ -311,6 +339,9 @@ static int vkms_config_show(struct seq_file *m, void *data) vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) seq_puts(m, "encoder\n"); + vkms_config_for_each_connector(vkmsdev->config, connector_cfg) + seq_puts(m, "connector\n"); + return 0; } @@ -520,3 +551,26 @@ void vkms_config_encoder_detach_crtc(struct vkms_config_encoder *encoder_cfg, } } EXPORT_SYMBOL_IF_KUNIT(vkms_config_encoder_detach_crtc); + +struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *config) +{ + struct vkms_config_connector *connector_cfg; + + connector_cfg = kzalloc(sizeof(*connector_cfg), GFP_KERNEL); + if (!connector_cfg) + return ERR_PTR(-ENOMEM); + + connector_cfg->config = config; + + list_add_tail(&connector_cfg->link, &config->connectors); + + return connector_cfg; +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_connector); + +void vkms_config_destroy_connector(struct vkms_config_connector *connector_cfg) +{ + list_del(&connector_cfg->link); + kfree(connector_cfg); +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_connector); diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index 3e5b2e407378..73562c894102 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -16,6 +16,7 @@ * @planes: List of planes configured for the device * @crtcs: List of CRTCs configured for the device * @encoders: List of encoders configured for the device + * @connectors: List of connectors configured for the device * @dev: Used to store the current VKMS device. Only set when the device is instantiated. */ struct vkms_config { @@ -23,6 +24,7 @@ struct vkms_config { struct list_head planes; struct list_head crtcs; struct list_head encoders; + struct list_head connectors; struct vkms_device *dev; }; @@ -92,6 +94,24 @@ struct vkms_config_encoder { struct drm_encoder *encoder; }; +/** + * struct vkms_config_connector + * + * @link: Link to the others connector in vkms_config + * @config: The vkms_config this connector belongs to + * @connector: Internal usage. This pointer should never be considered as valid. + * It can be used to store a temporary reference to a VKMS connector + * during device creation. This pointer is not managed by the + * configuration and must be managed by other means. + */ +struct vkms_config_connector { + struct list_head link; + struct vkms_config *config; + + /* Internal usage */ + struct vkms_connector *connector; +}; + /** * vkms_config_for_each_plane - Iterate over the vkms_config planes * @config: &struct vkms_config pointer @@ -116,6 +136,14 @@ struct vkms_config_encoder { #define vkms_config_for_each_encoder(config, encoder_cfg) \ list_for_each_entry((encoder_cfg), &(config)->encoders, link) +/** + * vkms_config_for_each_connector - Iterate over the vkms_config connectors + * @config: &struct vkms_config pointer + * @connector_cfg: &struct vkms_config_connector pointer used as cursor + */ +#define vkms_config_for_each_connector(config, connector_cfg) \ + list_for_each_entry((connector_cfg), &(config)->connectors, link) + /** * vkms_config_plane_for_each_possible_crtc - Iterate over the vkms_config_plane * possible CRTCs @@ -361,4 +389,20 @@ int __must_check vkms_config_encoder_attach_crtc(struct vkms_config_encoder *enc void vkms_config_encoder_detach_crtc(struct vkms_config_encoder *encoder_cfg, struct vkms_config_crtc *crtc_cfg); +/** + * vkms_config_create_connector() - Add a new connector configuration + * @config: Configuration to add the connector to + * + * Returns: + * The new connector configuration or an error. Call + * vkms_config_destroy_connector() to free the returned connector configuration. + */ +struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *config); + +/** + * vkms_config_destroy_connector() - Remove and free a connector configuration + * @connector_cfg: Connector configuration to destroy + */ +void vkms_config_destroy_connector(struct vkms_config_connector *connector_cfg); + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/vkms_connector.c index ab8b52a84151..48b10cba322a 100644 --- a/drivers/gpu/drm/vkms/vkms_connector.c +++ b/drivers/gpu/drm/vkms/vkms_connector.c @@ -25,8 +25,19 @@ static int vkms_conn_get_modes(struct drm_connector *connector) return count; } +static struct drm_encoder *vkms_conn_best_encoder(struct drm_connector *connector) +{ + struct drm_encoder *encoder; + + drm_connector_for_each_possible_encoder(connector, encoder) + return encoder; + + return NULL; +} + static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = { .get_modes = vkms_conn_get_modes, + .best_encoder = vkms_conn_best_encoder, }; struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev) From patchwork Mon Feb 17 10:01:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Patchwork-Id: 13977440 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 412AFC0219E for ; Mon, 17 Feb 2025 10:01:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CC74310E401; Mon, 17 Feb 2025 10:01:43 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="UoecvJ2T"; dkim-atps=neutral Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) by gabe.freedesktop.org (Postfix) with ESMTPS id 276F010E3ED for ; Mon, 17 Feb 2025 10:01:42 +0000 (UTC) Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-4398c8c8b2cso2332975e9.2 for ; Mon, 17 Feb 2025 02:01:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739786501; x=1740391301; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=V2z90w2fCLpTI8+G020nwpC9EGaGHD873RtNRgO7sTs=; b=UoecvJ2TrlOvav3PwqhKGQ53aHGLHZVzQxDrdfhBwT4htR3+zymLf5zm2GuHFx+/Dr XZmrSDb0+otJzzOEKIoDvQ6mdkl+tCvmeNG17lkjH2DJbvWRg10COMddeAqf7YEbZyO+ t2HxBGurp/1PNTGd8V2fhq5jw5waft+Go0qy2GrOLGoF/JRwe26n1HsYAHgIwIpjpFB8 nk+uNa7U7W8GxYhvE9SR/CwlAq82zEO7hlTEi56TqnMEvQ03/YMDNDHjYMkAbUPhBM5B wKonefAYu4hnmyOWSutpKQg5D6kHoenrPuQo+5l0L+1nnkiZ1oTnnTM/hVUxq1qVUcCx wsNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739786501; x=1740391301; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=V2z90w2fCLpTI8+G020nwpC9EGaGHD873RtNRgO7sTs=; b=m45G+CvEfNHOlzLGzUOBQTRuThPvKwnXNMDp5BaqP4iwhMQacK7bXcUW8/LpZGZHe2 NGYpP88N2PFCeH5CEn7tO320E8TvTOmG/VQvg9PH9ZFJT+K9HTq5U2Dl7B21Jha4Zr4i PKCVmpDmX2naHc7wLakQBU0559jmWQztaJLcy+PeNXLJyEDi2otaaIQnG779A6Lf6BbX C1/hok4glJPCQ64vwZ2HSlrI+PvL5qJMMBnAxWyV+kLblT7DSu/HrMUWb50zH0k29/I3 LZLMNBJboYiFp1qLkCJkZ+dd1g5ykRjG9HKG675g5YKYFnUscuz2t0gl5wLXKWU7CvQt pqOQ== X-Forwarded-Encrypted: i=1; AJvYcCWkOyyANTzw1qJSNoSqAjRH7yo+c0LgY2TTP3b/5lVdT1vzmu9EFqJ8RuqVDKlY7kH9rOfUByzkVg8=@lists.freedesktop.org X-Gm-Message-State: AOJu0YwQ4Y58GTNebqXxsgqPWD+9LGpuGo5BITYVO4ICVtcYQYOeJzjX yHoT/SBzSgX5qSuJ1CKh+nFCra83ybl54INpeLqJ1ICxhfdaF4Gv X-Gm-Gg: ASbGnctzcS+uweCHsCmotrrMiwkT9vLLj2qxSaKCl6Y9I7gAj7WsyCKrwxvgpq8KcUA +nDlcEiXGrPX37GajOGN1xRJxaGMgDZcGAwjm272VhaPncuZcPxQWaILj7tNriEkF+y1nREgLUN W/nCxCesUZJIJEtUwIEgmrqvtsjW3TyewP45hi3IzkDt0ShOda0Xe5O1AntjshpLeNmvHJl5hta UzjJzlAkzfE4hdePkBcGwS7Up3/H/Jf0MKiA/L9fym5kdNNG2KB8gMnzZIFhNZ5QrzoKbfYVGYr fZhPiYNV+TnBuZ5nrg== X-Google-Smtp-Source: AGHT+IF+Qm5zq9bzDlKVIp6rJDOjwCR2Kk0QNvXvDTzENRvNaSBvN02UJtyivFoTKFswNi0sfHXdtg== X-Received: by 2002:a05:600c:19c7:b0:439:4c86:9c32 with SMTP id 5b1f17b1804b1-4396e6aa021mr81717905e9.8.1739786500440; Mon, 17 Feb 2025 02:01:40 -0800 (PST) Received: from fedora.. ([213.94.27.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38f259f7fe6sm11591901f8f.86.2025.02.17.02.01.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 02:01:40 -0800 (PST) From: =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= Subject: [PATCH v3 14/14] drm/vkms: Allow to attach connectors and encoders Date: Mon, 17 Feb 2025 11:01:20 +0100 Message-ID: <20250217100120.7620-15-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250217100120.7620-1-jose.exposito89@gmail.com> References: <20250217100120.7620-1-jose.exposito89@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add a list of possible encoders to the connector configuration and helpers to attach and detach them. Now that the default configuration has its connector and encoder correctly, configure the output following the configuration. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 104 ++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 64 +++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 29 +++++ drivers/gpu/drm/vkms/vkms_output.c | 33 +++--- 5 files changed, 218 insertions(+), 13 deletions(-) diff --git a/.clang-format b/.clang-format index ca49832993c5..7630990aa07a 100644 --- a/.clang-format +++ b/.clang-format @@ -694,6 +694,7 @@ ForEachMacros: - 'vkms_config_for_each_crtc' - 'vkms_config_for_each_encoder' - 'vkms_config_for_each_plane' + - 'vkms_config_connector_for_each_possible_encoder' - 'vkms_config_encoder_for_each_possible_crtc' - 'vkms_config_plane_for_each_possible_crtc' - 'while_for_each_ftrace_op' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 0034f922713e..a5d63e00cc1f 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -511,12 +511,34 @@ static void vkms_config_test_invalid_connector_number(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_valid_connector_possible_encoders(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_encoder *encoder_cfg; + struct vkms_config_connector *connector_cfg; + + config = vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + encoder_cfg = list_first_entry(&config->encoders, + typeof(*encoder_cfg), link); + connector_cfg = list_first_entry(&config->connectors, + typeof(*connector_cfg), link); + + /* Invalid: Connector without a possible encoder */ + vkms_config_connector_detach_encoder(connector_cfg, encoder_cfg); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static void vkms_config_test_attach_different_configs(struct kunit *test) { struct vkms_config *config1, *config2; struct vkms_config_plane *plane_cfg1, *plane_cfg2; struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; + struct vkms_config_connector *connector_cfg1, *connector_cfg2; int err; config1 = vkms_config_create("test1"); @@ -528,10 +550,12 @@ static void vkms_config_test_attach_different_configs(struct kunit *test) plane_cfg1 = vkms_config_create_plane(config1); crtc_cfg1 = vkms_config_create_crtc(config1); encoder_cfg1 = vkms_config_create_encoder(config1); + connector_cfg1 = vkms_config_create_connector(config1); plane_cfg2 = vkms_config_create_plane(config2); crtc_cfg2 = vkms_config_create_crtc(config2); encoder_cfg2 = vkms_config_create_encoder(config2); + connector_cfg2 = vkms_config_create_connector(config2); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg1); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg2); @@ -539,6 +563,8 @@ static void vkms_config_test_attach_different_configs(struct kunit *test) KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg1); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg2); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg1); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg2); err = vkms_config_plane_attach_crtc(plane_cfg1, crtc_cfg2); KUNIT_EXPECT_NE(test, err, 0); @@ -550,6 +576,11 @@ static void vkms_config_test_attach_different_configs(struct kunit *test) err = vkms_config_encoder_attach_crtc(encoder_cfg2, crtc_cfg1); KUNIT_EXPECT_NE(test, err, 0); + err = vkms_config_connector_attach_encoder(connector_cfg1, encoder_cfg2); + KUNIT_EXPECT_NE(test, err, 0); + err = vkms_config_connector_attach_encoder(connector_cfg2, encoder_cfg1); + KUNIT_EXPECT_NE(test, err, 0); + vkms_config_destroy(config1); vkms_config_destroy(config2); } @@ -743,6 +774,77 @@ static void vkms_config_test_encoder_get_possible_crtcs(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_connector_get_possible_encoders(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_connector *connector_cfg1, *connector_cfg2; + struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; + struct vkms_config_encoder *possible_encoder; + unsigned long idx = 0; + int n_encoders = 0; + int err; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + connector_cfg1 = vkms_config_create_connector(config); + connector_cfg2 = vkms_config_create_connector(config); + encoder_cfg1 = vkms_config_create_encoder(config); + encoder_cfg2 = vkms_config_create_encoder(config); + + /* No possible encoders */ + vkms_config_connector_for_each_possible_encoder(connector_cfg1, idx, + possible_encoder) + KUNIT_FAIL(test, "Unexpected possible encoder"); + + vkms_config_connector_for_each_possible_encoder(connector_cfg2, idx, + possible_encoder) + KUNIT_FAIL(test, "Unexpected possible encoder"); + + /* Connector 1 attached to encoders 1 and 2 */ + err = vkms_config_connector_attach_encoder(connector_cfg1, encoder_cfg1); + KUNIT_EXPECT_EQ(test, err, 0); + err = vkms_config_connector_attach_encoder(connector_cfg1, encoder_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + vkms_config_connector_for_each_possible_encoder(connector_cfg1, idx, + possible_encoder) { + n_encoders++; + if (possible_encoder != encoder_cfg1 && + possible_encoder != encoder_cfg2) + KUNIT_FAIL(test, "Unexpected possible encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 2); + n_encoders = 0; + + vkms_config_connector_for_each_possible_encoder(connector_cfg2, idx, + possible_encoder) + KUNIT_FAIL(test, "Unexpected possible encoder"); + + /* Connector 1 attached to encoder 1 and connector 2 to encoder 2 */ + vkms_config_connector_detach_encoder(connector_cfg1, encoder_cfg2); + vkms_config_connector_for_each_possible_encoder(connector_cfg1, idx, + possible_encoder) { + n_encoders++; + if (possible_encoder != encoder_cfg1) + KUNIT_FAIL(test, "Unexpected possible encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 1); + n_encoders = 0; + + err = vkms_config_connector_attach_encoder(connector_cfg2, encoder_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + vkms_config_connector_for_each_possible_encoder(connector_cfg2, idx, + possible_encoder) { + n_encoders++; + if (possible_encoder != encoder_cfg2) + KUNIT_FAIL(test, "Unexpected possible encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 1); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_empty_config), KUNIT_CASE_PARAM(vkms_config_test_default_config, @@ -758,10 +860,12 @@ static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_invalid_encoder_number), KUNIT_CASE(vkms_config_test_valid_encoder_possible_crtcs), KUNIT_CASE(vkms_config_test_invalid_connector_number), + KUNIT_CASE(vkms_config_test_valid_connector_possible_encoders), KUNIT_CASE(vkms_config_test_attach_different_configs), KUNIT_CASE(vkms_config_test_plane_attach_crtc), KUNIT_CASE(vkms_config_test_plane_get_possible_crtcs), KUNIT_CASE(vkms_config_test_encoder_get_possible_crtcs), + KUNIT_CASE(vkms_config_test_connector_get_possible_encoders), {} }; diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index fbbdee6068ce..a1df5659b0fb 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -95,6 +95,9 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, if (IS_ERR(connector_cfg)) goto err_alloc; + if (vkms_config_connector_attach_encoder(connector_cfg, encoder_cfg)) + goto err_alloc; + return config; err_alloc: @@ -279,6 +282,22 @@ static bool valid_connector_number(const struct vkms_config *config) return true; } +static bool valid_connector_possible_encoders(const struct vkms_config *config) +{ + struct drm_device *dev = config->dev ? &config->dev->drm : NULL; + struct vkms_config_connector *connector_cfg; + + vkms_config_for_each_connector(config, connector_cfg) { + if (xa_empty(&connector_cfg->possible_encoders)) { + drm_info(dev, + "All connectors must have at least one possible encoder\n"); + return false; + } + } + + return true; +} + bool vkms_config_is_valid(const struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -306,6 +325,9 @@ bool vkms_config_is_valid(const struct vkms_config *config) if (!valid_encoder_possible_crtcs(config)) return false; + if (!valid_connector_possible_encoders(config)) + return false; + return true; } EXPORT_SYMBOL_IF_KUNIT(vkms_config_is_valid); @@ -513,6 +535,11 @@ EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_encoder); void vkms_config_destroy_encoder(struct vkms_config *config, struct vkms_config_encoder *encoder_cfg) { + struct vkms_config_connector *connector_cfg; + + vkms_config_for_each_connector(config, connector_cfg) + vkms_config_connector_detach_encoder(connector_cfg, encoder_cfg); + xa_destroy(&encoder_cfg->possible_crtcs); list_del(&encoder_cfg->link); kfree(encoder_cfg); @@ -561,6 +588,7 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *c return ERR_PTR(-ENOMEM); connector_cfg->config = config; + xa_init_flags(&connector_cfg->possible_encoders, XA_FLAGS_ALLOC); list_add_tail(&connector_cfg->link, &config->connectors); @@ -570,7 +598,43 @@ EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_connector); void vkms_config_destroy_connector(struct vkms_config_connector *connector_cfg) { + xa_destroy(&connector_cfg->possible_encoders); list_del(&connector_cfg->link); kfree(connector_cfg); } EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_connector); + +int __must_check vkms_config_connector_attach_encoder(struct vkms_config_connector *connector_cfg, + struct vkms_config_encoder *encoder_cfg) +{ + struct vkms_config_encoder *possible_encoder; + unsigned long idx = 0; + u32 encoder_idx = 0; + + if (connector_cfg->config != encoder_cfg->config) + return -EINVAL; + + vkms_config_connector_for_each_possible_encoder(connector_cfg, idx, + possible_encoder) { + if (possible_encoder == encoder_cfg) + return -EEXIST; + } + + return xa_alloc(&connector_cfg->possible_encoders, &encoder_idx, + encoder_cfg, xa_limit_32b, GFP_KERNEL); +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_connector_attach_encoder); + +void vkms_config_connector_detach_encoder(struct vkms_config_connector *connector_cfg, + struct vkms_config_encoder *encoder_cfg) +{ + struct vkms_config_encoder *possible_encoder; + unsigned long idx = 0; + + vkms_config_connector_for_each_possible_encoder(connector_cfg, idx, + possible_encoder) { + if (possible_encoder == encoder_cfg) + xa_erase(&connector_cfg->possible_encoders, idx); + } +} +EXPORT_SYMBOL_IF_KUNIT(vkms_config_connector_detach_encoder); diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index 73562c894102..0118e3f99706 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -99,6 +99,7 @@ struct vkms_config_encoder { * * @link: Link to the others connector in vkms_config * @config: The vkms_config this connector belongs to + * @possible_encoders: Array of encoders that can be used with this connector * @connector: Internal usage. This pointer should never be considered as valid. * It can be used to store a temporary reference to a VKMS connector * during device creation. This pointer is not managed by the @@ -108,6 +109,8 @@ struct vkms_config_connector { struct list_head link; struct vkms_config *config; + struct xarray possible_encoders; + /* Internal usage */ struct vkms_connector *connector; }; @@ -164,6 +167,16 @@ struct vkms_config_connector { #define vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possible_crtc) \ xa_for_each(&(encoder_cfg)->possible_crtcs, idx, (possible_crtc)) +/** + * vkms_config_connector_for_each_possible_encoder - Iterate over the + * vkms_config_connector possible encoders + * @connector_cfg: &struct vkms_config_connector pointer + * @idx: Index of the cursor + * @possible_encoder: &struct vkms_config_encoder pointer used as cursor + */ +#define vkms_config_connector_for_each_possible_encoder(connector_cfg, idx, possible_encoder) \ + xa_for_each(&(connector_cfg)->possible_encoders, idx, (possible_encoder)) + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -405,4 +418,20 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *c */ void vkms_config_destroy_connector(struct vkms_config_connector *connector_cfg); +/** + * vkms_config_connector_attach_encoder - Attach a connector to an encoder + * @connector_cfg: Connector to attach + * @encoder_cfg: Encoder to attach @connector_cfg to + */ +int __must_check vkms_config_connector_attach_encoder(struct vkms_config_connector *connector_cfg, + struct vkms_config_encoder *encoder_cfg); + +/** + * vkms_config_connector_detach_encoder - Detach a connector from an encoder + * @connector_cfg: Connector to detach + * @encoder_cfg: Encoder to detach @connector_cfg from + */ +void vkms_config_connector_detach_encoder(struct vkms_config_connector *connector_cfg, + struct vkms_config_encoder *encoder_cfg); + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 8920d6b5d105..8d7ca0cdd79f 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -8,10 +8,10 @@ int vkms_output_init(struct vkms_device *vkmsdev) { struct drm_device *dev = &vkmsdev->drm; - struct vkms_connector *connector; struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; struct vkms_config_encoder *encoder_cfg; + struct vkms_config_connector *connector_cfg; int ret; int writeback; @@ -83,22 +83,29 @@ int vkms_output_init(struct vkms_device *vkmsdev) } } - connector = vkms_connector_init(vkmsdev); - if (IS_ERR(connector)) { - DRM_ERROR("Failed to init connector\n"); - return PTR_ERR(connector); - } + vkms_config_for_each_connector(vkmsdev->config, connector_cfg) { + struct vkms_config_encoder *possible_encoder; + unsigned long idx = 0; - /* Attach the encoder and the connector */ - vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) { - ret = drm_connector_attach_encoder(&connector->base, encoder_cfg->encoder); - if (ret) { - DRM_ERROR("Failed to attach connector to encoder\n"); - return ret; + connector_cfg->connector = vkms_connector_init(vkmsdev); + if (IS_ERR(connector_cfg->connector)) { + DRM_ERROR("Failed to init connector\n"); + return PTR_ERR(connector_cfg->connector); + } + + vkms_config_connector_for_each_possible_encoder(connector_cfg, + idx, + possible_encoder) { + ret = drm_connector_attach_encoder(&connector_cfg->connector->base, + possible_encoder->encoder); + if (ret) { + DRM_ERROR("Failed to attach connector to encoder\n"); + return ret; + } } } drm_mode_config_reset(dev); - return ret; + return 0; }