From patchwork Wed Jan 29 11:00:47 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: 13953627 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 A0130C02193 for ; Wed, 29 Jan 2025 11:01:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 112D310E7A1; Wed, 29 Jan 2025 11:01:12 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="IMGGpoPC"; 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 BC89610E7A2 for ; Wed, 29 Jan 2025 11:01:07 +0000 (UTC) Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-43624b2d453so73918505e9.2 for ; Wed, 29 Jan 2025 03:01:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148466; x=1738753266; 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=9S+7C5eQRPWzuHKFjKrS6n1FuYqDvplaGUQ2TD3AN7Y=; b=IMGGpoPCT0u5r31xPJpnjUsubmt5C8Kz9wSRP8DC6acoIxw/w+mj++l4jpCd12IU2i HFKp2dCpGkQ0zWVEJuVMJ1OlNOQkNdPPL9gdSF2WR/TbFuTPct6nHIgm9WRc2nSH9Ed7 uxN6u/2n7OnBhutLDyZak5oe2YJslvEUmR5NceqT05krKWTWRPGI/ZUsM4U4D6DDtTKS 43q7n6dwIoL1+Ss2MugsD9acan4E5OYunj3lHQR+PFxXAPC5RjelAjNCycpk/SdKp32p MkJaXvKSRiUj6Ki/xrm9Ur8RLVhZqgAl4lZN107VcIsLMEjrdeiY/nE/29hZjZUhST1q il4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148466; x=1738753266; 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=9S+7C5eQRPWzuHKFjKrS6n1FuYqDvplaGUQ2TD3AN7Y=; b=JUN9rb+d/cJUFHCewo83BSV0J6Ucyab4SlK9Aj/jyFabeTyhZQW6D4ZOzj0XlNo4Pk tIsQhY1VQwU4Xg74R0T9XERTkM0c2nJAmTbIGAAkVbXafAjV75UpAmTSyCd9+UCI9uNI cG8Jz4wC2IEHXOhJVDt29JyaIKbRMBY/nKohIE0DJu6w9eIN5kwCm7B5CCh6SoFnNuWK WxvpGSZHlU0R4RhsZIDaQVXnRemThClfP5DF6iyAfUrgP4j8dB4DtwUceg5zAzlBul5g oNn8AgeIeerPh7CslQsToW9A8HYy3h27BORD40Bsik3L8V3M4N0maeyIW2fVxTJHcYsG nBLQ== X-Forwarded-Encrypted: i=1; AJvYcCU0kvnO7Gsy8coJH58V3hE8hbo9xCmHF+ZOFhbcI7SMteH+nmjKOf4bVR/ySf+/rLrJRBz+qZDwZ1E=@lists.freedesktop.org X-Gm-Message-State: AOJu0YxW5EOa1/jwgPlELqYlJqP44qvDvH8Oz5oJhrJow7tm0L/+5iBA Hba7MWWYa6eVBV5nOxxDuzZ5bIiFz4LiZspCVvG0ePSYF+8RRWcS X-Gm-Gg: ASbGnctuVQAZ1jG54AmA6q0kJ+1T4+KKfIm1y2DpAKfdK06j8QD55KeTdFZ5NV2yd0y H+/MfpGXp5bNj5R3gUiLFTU8iKz3gdyuqndyupFdCPyUaBcJs/W9Mi+Fm7ObPlpBpAPHuD0iXj5 RUaZuVXTxElczwRC6aZqst+rJlLVMquGLEzlXS6kkT/J+nqchIFLUVSO/cSuJ62zp30nNnWOYdq SSrqOAADAchheV5v8yT5ZMtsmTg0vY489eGI2VD1o5j4kzU+KMhh6sNqVYVc5OwwrHXylGlA55C hoL9BsCKJIl4zrsK X-Google-Smtp-Source: AGHT+IGHXcYWBGVD149ms+rmsIFUA7ZyRH6Ih7lsGoiLaHzrNT56I8mZyx+mQ+eMvA8IwLloDChjhg== X-Received: by 2002:a05:600c:3b94:b0:434:ff45:cbbe with SMTP id 5b1f17b1804b1-438dc3cba35mr22656875e9.18.1738148465987; Wed, 29 Jan 2025 03:01:05 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:05 -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 01/13] drm/vkms: Extract vkms_connector header Date: Wed, 29 Jan 2025 12:00:47 +0100 Message-ID: <20250129110059.12199-2-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- drivers/gpu/drm/vkms/Makefile | 3 +- drivers/gpu/drm/vkms/vkms_connector.c | 50 +++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_connector.h | 26 ++++++++++++++ drivers/gpu/drm/vkms/vkms_output.c | 45 ++++-------------------- 4 files changed, 84 insertions(+), 40 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..ab8b52a84151 --- /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 vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev) +{ + struct drm_device *dev = &vkmsdev->drm; + 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->base, &vkms_connector_funcs, + DRM_MODE_CONNECTOR_VIRTUAL, NULL); + if (ret) + return ERR_PTR(ret); + + 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 new file mode 100644 index 000000000000..c9149c1b7af0 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_connector.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _VKMS_CONNECTOR_H_ +#define _VKMS_CONNECTOR_H_ + +#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 + * + * Returns: + * The connector or an error on failure. + */ +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 22f0d678af3a..4b5abe159add 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -1,37 +1,13 @@ // 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) { 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; @@ -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"); @@ -102,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 Wed Jan 29 11:00:48 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: 13953626 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 31533C0218D for ; Wed, 29 Jan 2025 11:01:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A78EE10E7A2; Wed, 29 Jan 2025 11:01:10 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="nFi6w3MS"; 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 487BC10E7A1 for ; Wed, 29 Jan 2025 11:01:09 +0000 (UTC) Received: by mail-wr1-f46.google.com with SMTP id ffacd0b85a97d-385e1fcb0e1so3502872f8f.2 for ; Wed, 29 Jan 2025 03:01:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148468; x=1738753268; 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=9bX+6EwizABkI0McC7gIJiE+k/hJhaZ4QvaDj5BOaFA=; b=nFi6w3MSTf0fLARM2vCACR3NF69znZpbdkwx65MlC4wcqb73rZfK+5CkPsOfu/qNNA AvR5nHOdSsNv/bZvWWZJacXwfUhextSFeFLS6hA1ya8DOkDX+se2VOSwdotO0dMgMWyV /dda8NhPl3Oa67r4QmlS1VnyUzMGwoxWYq3pItuZu2TkEwLN1y/r4PHBotnyD/DenFRA zNTmON9MqRScVLoNBjGLzO3MCrwnyNqMGMT5tim3WrGaIQcxe4Hm//pGgYAOWvjD33ul UQtjQBNod1f3o+vxWJxhS3dnoJ1shl/ld6fkbWrro0p6G42QYDSbm5Wi4Dki1q49+c8U aUNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148468; x=1738753268; 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=9bX+6EwizABkI0McC7gIJiE+k/hJhaZ4QvaDj5BOaFA=; b=vgzCT57vTWHDJafl/j3qtQEqxAEVhV99UqjgSbJSlt8yLhQyHegcdYTlyx3qSgWg6W jg2uefM5jOWWn6TtVMjlpoAPF3l74FDvwYOx4uC6wMv40BOw6LhRtLsirRGm9uycPsIv eRYIrejptGHmGb1I+avlJaNJ/rQ5zsIYkEyTjkgLVLi0k6h39+7rQqmhDuja+mcm9+YB Qyvi8qtfZFw35dFeaV6urqSXvHP4S0p23WRl7v83wlzzOx8k5hUlFq7owvTmnQ21B7Hl yYnWCm641D5WtDfAnSh4Oi+GlPXNGqymeK/JTG9dB6XIJoq7FhmCixlShNCdRGlwixrC E10A== X-Forwarded-Encrypted: i=1; AJvYcCVwOmt/VMQamUDEoAySZd6TCnX0AL8ZqOL81F6tM1Hwqj0375CPFkQR/bdp9kRr18+SxE2N9jYAL40=@lists.freedesktop.org X-Gm-Message-State: AOJu0YyhssCPqrfKzE/azPziEUQGtC/3z/3DXohHFKOnwlybdM76P05P oNJEWYFgo/FrhdDcH2mDA2Rz2vJYpvBdU+K1eHmAHBSVxtXB4vzt X-Gm-Gg: ASbGncsLmOJ7eVLwOUPX/lpIWPP0kiMJI6BUFUkpAaX3iZZnK+ryVOskEMeM6nZ+dl5 jEyUO0KLyjKSo15e5tUDW41Iw7v059PcGyel2IImaISoYdLQ71evfXyaVY/OrRVTyVaS9ue6oFd OsU6Dw9z1YINPGLLN0QyBEIgx5O+vznM3phhDPKryixzeit6YIi3CHjkIpzqUENjJZGatDPj8c9 HBg0d1WMSLniHRkakESTXioaaisBO/HIsrmzjbSVdTtSXTqj5jtstETObg4DtKDgHAb+vJ31Ek7 pb6qlRZEcFgSJUi3 X-Google-Smtp-Source: AGHT+IF0iya3LHyS6aQhAfiWBUhNrHZ30Sab7dWyXgj5JiWlbgQ4M/vCB2thWkPLBNN7BECgrimYKg== X-Received: by 2002:a05:6000:4008:b0:386:459e:655d with SMTP id ffacd0b85a97d-38c51952173mr2188558f8f.20.1738148467573; Wed, 29 Jan 2025 03:01:07 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:06 -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 02/13] drm/vkms: Add KUnit test scaffolding Date: Wed, 29 Jan 2025 12:00:48 +0100 Message-ID: <20250129110059.12199-3-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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 Signed-off-by: Arthur Grillo Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Signed-off-by: Arthur Grillo Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- 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 | 21 +++++++++++++++++++ 5 files changed, 44 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..d4665e913de7 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_TESTS + 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..45ef4b89379e 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_TESTS) += tests/ diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig b/drivers/gpu/drm/vkms/tests/.kunitconfig new file mode 100644 index 000000000000..70e378228cbd --- /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_TESTS=y diff --git a/drivers/gpu/drm/vkms/tests/Makefile b/drivers/gpu/drm/vkms/tests/Makefile new file mode 100644 index 000000000000..b78371d08aa9 --- /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_TESTS) += 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..ba93d864d57f --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include + +#include "../vkms_config.h" + +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 Wed Jan 29 11:00:49 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: 13953634 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 BA226C0218D for ; Wed, 29 Jan 2025 11:01:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 25D0810E7B3; Wed, 29 Jan 2025 11:01:33 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="c4E+0UDC"; 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 9FEA310E7A1 for ; Wed, 29 Jan 2025 11:01:10 +0000 (UTC) Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-385e1fcb0e1so3502889f8f.2 for ; Wed, 29 Jan 2025 03:01:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148469; x=1738753269; 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=6bzQMlUxW1EEe5ba9zNeNJsn9NRKOLczD9tgi8KPhh0=; b=c4E+0UDC5IfISn8Jwgt8NyttGOqATR0QK1e446jPcDyhFVyulol1C7c0bMADjve1ZO 5d62jBnyO217fo5KPka4IzdYitM8FSoQMJIHn2k5DegjzVgLzhxTxeyACN0EDqglMIbF mLHvUabi9ZWHBZNiFUIAwT40CszRqoPwY9TkZmkGfelGz0JqkvByovECdH+GRBKz0zQA SJGfDPlvEfZLRM476bc8SexdTdqGtD9ayeyEqgQ4iEyY72mlXJpj7fIG9lpf1RMaWH8T puY1Hkv95czeOUgKbVhOqcCt2UfpUFQjcUnwhf1LYmizGpGocXzS0zlSRSLlrK0GWwP5 KZlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148469; x=1738753269; 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=6bzQMlUxW1EEe5ba9zNeNJsn9NRKOLczD9tgi8KPhh0=; b=cy1WkSfV79ezYGW97Sla3R0pAWttQa6W+ZD546E/w7zdiXKXrj4BDag4LYP5IAaxve F4yUYP0qdD4/AwGII9Fz+lUaOcFuorZg+O4vA49Y54oaBeG5s1PK/mgsf/GF0ZFJqZap RgCS675jmHpKNKj/BgbWn6TmTTbFeYSk3Oug+yoJuo3th7csVcfTT/uFoWuM5082RPkC eKfeaYAK4DEbbIDvnVc7TkubusswNqMsUvZFM0WxmHjhsRqDbyTI+ZE2Hk5i20Ndc0vY jSJrTIlDLBEp3s+KFK0y8aQ4Sn3F4/hRBUjvoWbfqIg1AsNXlqaxa/tCHn3+LmTkH86Q O9JQ== X-Forwarded-Encrypted: i=1; AJvYcCVPJcVL1omziunAMhdrMWIivA7n4IqzhU2vWwaMG+RUGWISUrvVVrCZGo0l4z+ZrAOPYDvMGHKPPhs=@lists.freedesktop.org X-Gm-Message-State: AOJu0Yx3uexyUiQTYcuLeiw/lCGX4JsOs1/zOuJ1kHHS6U1rUYszgdt2 P0+RIR3pxXSuNKsvUCY41mBbJS0IqXzkn1eq22B4Jo+uTFoW/FLN X-Gm-Gg: ASbGncvyNCK9+DtPe9CM1dscW44XkPKLqNnHlWfkQXYjujIZ47Fj+jjMQwEMhVIZJkq xIeFWnCBw1x7LRBNYYJEkpJtV0ifN+xqRU2uVfnohq7UapTApaXKDJCW7/gGIz9IEAlH4F2vCiI fk5q4i8IsbqyPP7jRlddP+kmFbLWuSf1Fg1wKI/T8+lQQBIeg5tyEHph1jEI+qOAtl5+fJnHp7d lpexiYW+LsHXsySdaJr/p3duUZua1RF3q4kpTor9B3q9j3SseYdCjKbKGkm6fC+vt3yN6M54ta2 Y5T17ugXytONYNpN X-Google-Smtp-Source: AGHT+IEaD5Epnui96Ne96gVy0PYPsd828wNvu1Ty2RyBjkfQ3XZw1V5TBTPbNeiOqJZdOBbVOxUpfg== X-Received: by 2002:a05:6000:1fa4:b0:38a:673b:3738 with SMTP id ffacd0b85a97d-38c519738d2mr2325796f8f.33.1738148468729; Wed, 29 Jan 2025 03:01:08 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:08 -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 03/13] drm/vkms: Extract vkms_config header Date: Wed, 29 Jan 2025 12:00:49 +0100 Message-ID: <20250129110059.12199-4-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- drivers/gpu/drm/vkms/Makefile | 3 +- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 11 +++++ drivers/gpu/drm/vkms/vkms_config.c | 47 +++++++++++++++++++ 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, 116 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 45ef4b89379e..9bf6b8f94daf 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_TESTS) += tests/ diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index ba93d864d57f..a7060504f3dc 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -6,7 +6,18 @@ 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..152b2ecd6aef --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#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; +} + +void vkms_config_destroy(struct vkms_config *config) +{ + kfree(config); +} + +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 7c142bfc3bd9..b19f76f902b3 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); default_config = config; @@ -243,7 +223,7 @@ static int __init vkms_init(void) ret = vkms_create(config); if (ret) - kfree(config); + vkms_config_destroy(config); return ret; } @@ -272,7 +252,7 @@ static void __exit vkms_exit(void) if (default_config->dev) 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 Wed Jan 29 11:00:50 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: 13953628 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 AD04EC0218D for ; Wed, 29 Jan 2025 11:01:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2AA8510E7A9; Wed, 29 Jan 2025 11:01:17 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="l1IUm0nD"; dkim-atps=neutral Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) by gabe.freedesktop.org (Postfix) with ESMTPS id 78A0510E7A1 for ; Wed, 29 Jan 2025 11:01:11 +0000 (UTC) Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-3863703258fso342238f8f.1 for ; Wed, 29 Jan 2025 03:01:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148470; x=1738753270; 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=FjL+ZAAo0YHDYt7gQTJ/b5ubGw71F7Pu1taWojvFhk4=; b=l1IUm0nDJJ7T0/11phDNkb7nmow0ljcGuW9ynaIKZaijQEzonIWtuOxxU9DdcRa6N0 6+F6acP1r3MlEVkHEw3YpFXX5pKZlitG86XWcmNdGS0U3QEqA7AMeok5myR8tEuKtPjr ivuAxV6/sqpwtUSE0Xt8Il4P+Zy/bMLeeRIoBRMF7mUQaL6Egl5AgXAmTW02e2k6bCdI kc/YzbQFRF+z6HgRBtzzdLA7Z2U0+q1iVx6qtMVoYrbo4d1Q39Y5OUjwJ+2USJYxiDd2 FbVWxOQqV2p5gsoJwjBPyQA1HyQBVoqk/T3Gou1jlMWULrsgAJfdjlSf3XxKtAO8We26 PRAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148470; x=1738753270; 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=FjL+ZAAo0YHDYt7gQTJ/b5ubGw71F7Pu1taWojvFhk4=; b=RagGlU8972Sz3Bz0zqXl65MLeEU2+omT+xKhkUDSFBtayc1DOp/O3CO8bWOh3KQ7by lla/jo/njm1rR7oydhYewCcZhhImhYD3MDp9D3mbrYBZCSjeW0gPK3hTvMa5zACbxj9s t41ls6En4/BP/I+yWaSkCt4SlI6iWjx3z0xPikbDMGibDwd8zhRNzD80HWCQPdwrXEMv ou1yobZv+zq1VNg0zk/D5R9bLffG4qagjPyKoT+zz7C/b3B3S0lz1q/WfEHA/2M3h/az p2nuP2N5VaCJ3J9tCqSYIwDiKuO4xgDAicLto/0UIjPYh8N4OSWyVp01AvM///wkW3pi yWog== X-Forwarded-Encrypted: i=1; AJvYcCVaVQ2iDcdyFFsmSlHrZDL6SaCatKf5cLCrMHip/XBNeor43DPl7/wF4VpU2p8AigHoHF1DPS4wqDw=@lists.freedesktop.org X-Gm-Message-State: AOJu0YxZyxfNs1KctLJDrwk/Dy6utD3JQesnFDOP50z1Wuw0HMTYDBlA eAy8JrM6q0c5LNeuhd6YXek6E4UgY3Py28f5W2aRUe/hy4gtMyLR X-Gm-Gg: ASbGncuyi1BXmHCU1Vt+56sl2F2V6hn94Kk9TzChQ/Zi6ZZYdJ6mhS99k4eVXj0xlzq ZmEdsALmUuovNPJWXHYhCsmYoXaM3/gOmpK/ex7O4txyYyVxXnFjK0IhFaBBwYXaSz2FEKEtlu0 osq8soomlBP2OTWqk8+dzlYRw4BQFwfSUOl7f1+39/3cAADH7fhfbQTx/WFLGfwZ7EHfKmSo1wW J0VNJ5xyKLUwvNYOa4IT+FyqUpOigYbRofZSjFIlusiUPILmMW+jMXbTpbWrrDSK2mA+AXu/MvQ I4ubxVlgntHpqYc3 X-Google-Smtp-Source: AGHT+IGM65LZ6HAHnzroF2O3ycdsns+/7UUPzidfbU/yRI5s3eUChQJUUJRV3aYPtOLqqIewACxIzg== X-Received: by 2002:a05:6000:4011:b0:38b:ee9f:52d5 with SMTP id ffacd0b85a97d-38c50ff1713mr2361965f8f.16.1738148469669; Wed, 29 Jan 2025 03:01:09 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:09 -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 04/13] drm/vkms: Move default_config creation to its own function Date: Wed, 29 Jan 2025 12:00:50 +0100 Message-ID: <20250129110059.12199-5-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 38 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 17 +++++++++ drivers/gpu/drm/vkms/vkms_config.h | 14 +++++++ drivers/gpu/drm/vkms/vkms_drv.c | 6 +-- 4 files changed, 70 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 152b2ecd6aef..30ce4b23553f 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -18,6 +18,23 @@ struct vkms_config *vkms_config_create(void) return config; } +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; +} + 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 b19f76f902b3..700cf43389b7 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -211,16 +211,12 @@ 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); default_config = 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 Wed Jan 29 11:00:51 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: 13953629 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 3E96FC02193 for ; Wed, 29 Jan 2025 11:01:18 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8C17110E7AA; Wed, 29 Jan 2025 11:01:17 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="SegV74kU"; 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 B185F10E7A7 for ; Wed, 29 Jan 2025 11:01:12 +0000 (UTC) Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-3863c36a731so5512401f8f.1 for ; Wed, 29 Jan 2025 03:01:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148471; x=1738753271; 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=3Jdlaybe4dLW4Pxw5Cu5C4SOJCAFhex6WH7zjUJEIng=; b=SegV74kUkoBsseEdjsY95RToik2VAaYFBbG4ajlvk/eQwanf3zFjWr8G3o+itYhkE7 P0n2iZCvDZgChWPB1xhMmusz8D4bZDzpF8E4WUW/A9lRuoyn2rSss+z3GhESgQNQA5oW t+CAa4y0AJedRiCak5GQ1dlh0ua3G+auAiL8gyKBXu8KUQTULIpwaDosOtfISwnCiY0G l82A0ALZu4vg0TP8FB+/vb6efY8oGITqVcWhYnOCG917G/CRDT927y2tA+AYwbHz2JOF 6ilDHrThdznzNopfg571sY8IBwMFgB+jyh7VwCJHon6+FpRiu6XS1Pq9js7XWo8M+gB6 qhlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148471; x=1738753271; 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=3Jdlaybe4dLW4Pxw5Cu5C4SOJCAFhex6WH7zjUJEIng=; b=xJw3aG72qfvla5jsd/iCqk+2lseUtJE0a1hFJrJXwvj5jQgVN/Goh2M9B8sy9E9gMM Oa0vIg4CiqbL5nck4rrgQQcqjUQ21KKw8GOWbOVa+zLfV3FBJO1LDsKFSlkvkriELsSt EKxs2VqqaB09bzJrivIEFEEK8RxOFB1mrIEBQqxjeZKxSOI3EPYuPcrHUSVbqjLrCkXn uXphQWWhVjVLlZzjvAxdAcKjJEF7Xec7RbkUb2vPgufc3TZitjweUG43DfuVskBqhjKt Te7r+b0kU+41RC5dlv05fT2o7Gn3s2V4BPP7Hx/PtGq8XQivpqnDYl11qz+vhMIlV5/C d18w== X-Forwarded-Encrypted: i=1; AJvYcCWIu3SRDYAR291CmcKA5itk/2204Uzo3O4PvFsmbNqZNKwJ39vfiYD28i8+UO/wWu4o2NnD7wBwaXA=@lists.freedesktop.org X-Gm-Message-State: AOJu0YyVaCjBgQ/aAJofRaxjTcF6y2EjmA43utW+inPUjGWmIcYFpXdU ID2hpn64ZUpAWOQg9QbKLvz8s+Z6Cp8xuuAn+/oNmBBrjNj6fvSP X-Gm-Gg: ASbGnctmoyWdRbm9Z2udNvqU+Vf8YwZyTBSp2CUV8/eGRVImUpuUCM9UZxTVIfCrrzv C/rD0OECDaMRax2jcUpPUkcnlB5dK35PBuCcreidYK69dV6OkF8I6gbxZ2FbRexfKCdegmGBN7w LuhqNZ4ij8+ROYaVU/pwTsn1bmRVH9PZNTKcXJ1qKvBocGQlgM4P2TlGhrv7BZ7hV2Pv4maHk2I rijvKK8Cw8VjCtPKCFraxD6Fau/7J+y3NiKZNRadeE0o9Y/y2lS56v2TJztlSNyjbuver1OaMw1 CNEsMcfh8gwQakBzvqdQiGLLR2M= X-Google-Smtp-Source: AGHT+IF8ZlTcVpl9sITm6XddqK7H71VOTly30mhKNuiqqkEfAUFNz4gd4TU2PHgDJf555zpXIlbBUQ== X-Received: by 2002:a05:6000:194b:b0:38a:418e:1171 with SMTP id ffacd0b85a97d-38c52097117mr1431760f8f.37.1738148470894; Wed, 29 Jan 2025 03:01:10 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:10 -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 05/13] drm/vkms: Set device name from vkms_config Date: Wed, 29 Jan 2025 12:00:51 +0100 Message-ID: <20250129110059.12199-6-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- 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 | 15 ++++++++++++++- drivers/gpu/drm/vkms/vkms_drv.c | 4 +++- drivers/gpu/drm/vkms/vkms_drv.h | 2 ++ 5 files changed, 37 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..526800b1afb4 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 live times */ + 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 30ce4b23553f..11b0e539920b 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -7,7 +7,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; @@ -15,6 +15,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; } @@ -24,7 +30,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; @@ -37,6 +43,7 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, void vkms_config_destroy(struct vkms_config *config) { + kfree_const(config->dev_name); kfree(config); } @@ -45,7 +52,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..3e4f39cbe2e2 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,16 @@ 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 + */ +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 700cf43389b7..f23ee1a053e9 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 Wed Jan 29 11:00:52 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: 13953631 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 749D8C02193 for ; Wed, 29 Jan 2025 11:01:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BEDFF10E7AD; Wed, 29 Jan 2025 11:01:24 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Yh9weOkV"; dkim-atps=neutral Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) by gabe.freedesktop.org (Postfix) with ESMTPS id BC13710E7A7 for ; Wed, 29 Jan 2025 11:01:13 +0000 (UTC) Received: by mail-wr1-f42.google.com with SMTP id ffacd0b85a97d-385d7b4da2bso6190535f8f.1 for ; Wed, 29 Jan 2025 03:01:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148472; x=1738753272; 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=vcLgxm3SUTsLjkaczvOfL6Bm5o46S9pgFwtVrMuPL9A=; b=Yh9weOkVurmcblEl4DJAxTDRTZlUutSn3bVOrS1AqX6umdZQydGUtWW7u7Fz7uRBdw AnPDaNUvvrnhHQ1u0MjmCJhD9JC5a5zZEIG/7kS0Z86YW92gTEa/Usj5kePKGBYGPR8S xKW+kuzwb2FNzguLsapqZ8vqrD1tmYMVKvu8vlXkhGfFztuZjcPQpVC5yDGQ7EBlLfIl eUU+jkNyYMAiH8F3vuDJcAO3OIsJSGZ7oHmLDvdVahKdGJKwnYuY2AcJ06Rr2Vxcj8cn Ncqkg1d5xeBaSRJb7bO0O4I30E+KsuUBZ61Ie8wGkBxt3xqfJfLFrFVWahBm3whb40lr 2Fag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148472; x=1738753272; 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=vcLgxm3SUTsLjkaczvOfL6Bm5o46S9pgFwtVrMuPL9A=; b=JAQ3NNua/U98U+z4Ln/7+tzz/ZXLmLauyZQaxXEIH/sif7b3d8wqgZhrFaNIWKTzHE 70D/XK0vXsv6EksZ7wQfh69HnAuo6/Xwi05uN9Qpj8hkFNXh3k83dWzhJZ6PIZLpciG+ KtH4ahyH4BknRKFxORrEYrGhjeUTV+No0qNlB7vT896/mT9DXMta3iRBpw+B8OBOWSqh bUDynOgyNAm32PIZzs7WuksQqgIhpJX2gQzwyYrQLwsppFCJkbMVF/otbojNeo2gD7jc OtXGFCP9ZB+vQsJ6dIOrkoOA2xjaJksrPob8O5+ZWeH85u177PB5CHpfhW0LU4KVyltO MXkA== X-Forwarded-Encrypted: i=1; AJvYcCWh1MeGD33BtV10/Tb/TzjYeT6oskDRktG4RpFvs1e3QK8MyKHTb+BCqepJ3R0agOjpLgtdQ2WAmh4=@lists.freedesktop.org X-Gm-Message-State: AOJu0YzVuddw1fA/AaCB6Dkdy6AcXl4hBqbmvcw6cGGBPF//JoxE0pdB zYkhn4kDXMYoSAtI0IXRjVZfrchUit1/MS56HhNM1hQf2gmuxuml X-Gm-Gg: ASbGnctLK91EQCgW2h+CIVjDbC+rIWwlPe/9tgC1jq4IsowWJJZlEcCPL5xYor7WjeB qMt018s/3aXqu7qh/IRRnwDb960NXjW1pT9Y0v9XiSPHTe7VvVbtO6AMsQ1DSAqVxUxwjgbxq+j XO/Igf41kb0FsygbotlGBlFGr+1c9WGum+FUrjkQDUqYmw26ezu7XgYecWVBH0fBLspxeh89iDx LBG7xzvZoJseTBgbf8k4G4WiPQCQ6KIR3XAzEP/z9D3CC7MhwKi6mD06AyzW0EotX94MAegCGuo /i75SUC1apfwLMAv X-Google-Smtp-Source: AGHT+IGJkECaHDdVMqpyu56d/KRmlF5eI3OFpcFDGpoPoyaY9mw51GmEv0T/B7Cfz1VL8PGPqNskXA== X-Received: by 2002:a5d:6d88:0:b0:38a:418e:1179 with SMTP id ffacd0b85a97d-38c519380afmr2274027f8f.2.1738148472073; Wed, 29 Jan 2025 03:01:12 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:11 -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 06/13] drm/vkms: Add a validation function for VKMS configuration Date: Wed, 29 Jan 2025 12:00:52 +0100 Message-ID: <20250129110059.12199-7-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: José Expósito Signed-off-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Reviewed-by: Louis Chauvet --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 2 ++ drivers/gpu/drm/vkms/vkms_config.c | 5 +++++ drivers/gpu/drm/vkms/vkms_config.h | 10 ++++++++++ 3 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 526800b1afb4..66c2c6cb4a0e 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 11b0e539920b..67f71d29596e 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -47,6 +47,11 @@ void vkms_config_destroy(struct vkms_config *config) kfree(config); } +bool vkms_config_is_valid(struct vkms_config *config) +{ + return true; +} + 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 3e4f39cbe2e2..963f22b9b4bd 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -64,6 +64,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(struct vkms_config *config); + /** * vkms_config_register_debugfs() - Register a debugfs file to show the device's * configuration From patchwork Wed Jan 29 11:00:53 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: 13953630 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 91A3DC02190 for ; Wed, 29 Jan 2025 11:01:19 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DFF4510E7A8; Wed, 29 Jan 2025 11:01:17 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="KBLET8Ah"; dkim-atps=neutral Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5373410E7A7 for ; Wed, 29 Jan 2025 11:01:15 +0000 (UTC) Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-385f07cd1a4so6432545f8f.1 for ; Wed, 29 Jan 2025 03:01:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148474; x=1738753274; 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=vojZaZ8F+NK/iPnjUpn4N9qYryOnpEU70w91WMVOaic=; b=KBLET8AhlfGqD40FrgieSyBaJMoKaNQK1oXkRBHztnnaruXK1OEon1z5VHqAjQuL7U T4QknpEzP6Hf7veg53e99gsb1QFeb48Gkdsci6s3Uo5Tm2xE7B/2PrlpcgE9ZbsPbDmq /mOl8ceG4kuj4b0oqFo1+Yi8U+izR3ypE8rpH2AQXN2tTS5EfLZ0MxM3+hm19PTVFzNX SAW15ncbx2fMCHiPGg1oIuF+dW4c0bem226Ju5oRTb6t1hKFnCBr32CEkcvqcYL3QNhM Q/EmTuhfu5BDPTyu3XxBnyCKduHPxmTNzNLrEeknzrVtMfEomkJZ2+5H49gR7Bx5pR6J 3r+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148474; x=1738753274; 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=vojZaZ8F+NK/iPnjUpn4N9qYryOnpEU70w91WMVOaic=; b=Vu3MbthkUe0lfwNipq4iWIXKgfjxbDlbIqyBbEenc6M27ztHdbI89UaYUBtYDJ++Jf /9z+2qPWe+1MOgNvYOq9Xtx/bWMMQoqzq8N2joupibIU0lW6Azy0w1zMsRGTt4DO2hz9 ZJjQ8M+QGxyGqj8FKeIOu0ehZPyBcuzAe4335qjP4LOvD6AucWalWyAGXjE2qWPFLJ5F J1fpgcMXs57FEwES3kQw0UHX1tRB8wmnD7Eu7sTJPfv9l4ihBG4++hvch/Y3+5NY1Bcb dH+x1T+lXXA8cHUAVnZERKJCmTdnV6uOn/m2eec3G1LMIPDXVANYGPHQYlc7Aj+nKrGT TlGw== X-Forwarded-Encrypted: i=1; AJvYcCX3+6Rcshj61YeK2PHJcNC+hBlUfXBZajvvi7/15/pPJlcgrsTvWe89Q4x1OFMK6C59Min9+Pof5BI=@lists.freedesktop.org X-Gm-Message-State: AOJu0YyiKUzGt++yuJNwQHPXxL6mH4sPS7+faxH78ofR1KkOFAqaPEK4 wds9Bs9GRRiNiwaV2XFNS+ZlCfNwsuK1ODF1ckACRQr01GD99XMJ X-Gm-Gg: ASbGnctl6wfm3IXN+3W2FiIJCYDhJW+5B9pJWkHGdM9i00pUidpVA3kWwa2uxbfKb21 KWN7DAVzqqYRs8769ryJYLvrYS97y1jPtqZwSSgOrYjGDJgAAQt2aaOA/S44dKUqdKUxjp3dGCb Rxc39mow9NF5uJh4WmP6IJewGOblAwYbpUbukHEftfXPG4SxXie94F0vFvBbjLGE1SoqI5sbm5Q OXIFlWDWfHj0L590ECjt2+UkQgdiUG1hkEJigUK6r+2BaBWRvOXxOD+MstD9YtFQOC0JCb7SYMV vZYztwRQOTo7Ie5B X-Google-Smtp-Source: AGHT+IGlv8nmLgUmiKojqFWxzvaUL7Lfp9PLXTfmvbPvfCDgXUEhyDos5aI69wAbNCN9hEyXOrofYw== X-Received: by 2002:a5d:6c66:0:b0:38b:d7d2:12f6 with SMTP id ffacd0b85a97d-38c51932163mr2081326f8f.2.1738148473606; Wed, 29 Jan 2025 03:01:13 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:12 -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 07/13] drm/vkms: Allow to configure multiple planes Date: Wed, 29 Jan 2025 12:00:53 +0100 Message-ID: <20250129110059.12199-8-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Signed-off-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 133 +++++++++++++++- drivers/gpu/drm/vkms/vkms_config.c | 149 +++++++++++++++++- drivers/gpu/drm/vkms/vkms_config.h | 78 ++++++++- drivers/gpu/drm/vkms/vkms_output.c | 67 ++++---- 4 files changed, 386 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 66c2c6cb4a0e..7d9cb3956741 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,138 @@ 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 */ + list_for_each_entry(plane_cfg, &config->planes, link) { + 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_cfg1, *plane_cfg2; + struct vkms_config_plane **array; + size_t length; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + array = vkms_config_get_planes(config, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + plane_cfg1 = vkms_config_add_plane(config); + array = vkms_config_get_planes(config, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], plane_cfg1); + kfree(array); + + plane_cfg2 = vkms_config_add_plane(config); + array = vkms_config_get_planes(config, &length); + KUNIT_ASSERT_EQ(test, length, 2); + KUNIT_ASSERT_PTR_EQ(test, array[0], plane_cfg1); + KUNIT_ASSERT_PTR_EQ(test, array[1], plane_cfg2); + kfree(array); + + vkms_config_destroy_plane(plane_cfg1); + array = vkms_config_get_planes(config, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], plane_cfg2); + kfree(array); + + vkms_config_destroy(config); +} + +static void vkms_config_test_valid_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_add_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_add_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_add_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + plane_cfg = vkms_config_add_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_add_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + plane_cfg = vkms_config_add_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 +189,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_valid_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 67f71d29596e..a5a77612645f 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -21,6 +21,8 @@ struct vkms_config *vkms_config_create(const char *dev_name) return ERR_PTR(-ENOMEM); } + INIT_LIST_HEAD(&config->planes); + return config; } @@ -29,26 +31,139 @@ 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_add_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_add_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_add_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); } 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); } +struct vkms_config_plane **vkms_config_get_planes(const struct vkms_config *config, + size_t *out_length) +{ + struct vkms_config_plane **array; + struct vkms_config_plane *plane_cfg; + size_t length; + int n = 0; + + length = list_count_nodes((struct list_head *)&config->planes); + if (length == 0) { + *out_length = length; + return NULL; + } + + array = kmalloc_array(length, sizeof(*array), GFP_KERNEL); + if (!array) + return ERR_PTR(-ENOMEM); + + list_for_each_entry(plane_cfg, &config->planes, link) { + array[n] = plane_cfg; + n++; + } + + *out_length = length; + return array; +} + +static bool valid_plane_number(struct vkms_config *config) +{ + size_t n_planes; + + n_planes = list_count_nodes(&config->planes); + if (n_planes <= 0 || n_planes >= 32) { + pr_err("The number of planes must be between 1 and 31\n"); + return false; + } + + return true; +} + +static bool valid_plane_type(struct vkms_config *config) +{ + struct vkms_config_plane *plane_cfg; + bool has_primary_plane = false; + bool has_cursor_plane = false; + + list_for_each_entry(plane_cfg, &config->planes, link) { + enum drm_plane_type type; + + type = vkms_config_plane_get_type(plane_cfg); + + if (type == DRM_PLANE_TYPE_PRIMARY) { + if (has_primary_plane) { + pr_err("Multiple primary planes\n"); + return false; + } + + has_primary_plane = true; + } else if (type == DRM_PLANE_TYPE_CURSOR) { + if (has_cursor_plane) { + pr_err("Multiple cursor planes\n"); + return false; + } + + has_cursor_plane = true; + } + } + + if (!has_primary_plane) { + pr_err("Primary plane not found\n"); + return false; + } + + return true; +} + bool vkms_config_is_valid(struct vkms_config *config) { + if (!valid_plane_number(config)) + return false; + + if (!valid_plane_type(config)) + return false; + return true; } @@ -58,12 +173,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); + + list_for_each_entry(plane_cfg, &vkmsdev->config->planes, link) { + seq_puts(m, "plane:\n"); + seq_printf(m, "\ttype=%d\n", + vkms_config_plane_get_type(plane_cfg)); + } return 0; } @@ -77,3 +197,24 @@ 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_add_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); + + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); + + list_add_tail(&plane_cfg->link, &config->planes); + + return plane_cfg; +} + +void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg) +{ + list_del(&plane_cfg->link); + kfree(plane_cfg); +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index 963f22b9b4bd..d9aeba1762d1 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,36 @@ * * @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 + * @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; + + enum drm_plane_type type; + + /* Internal usage */ + struct vkms_plane *plane; +}; + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -64,6 +83,19 @@ vkms_config_get_device_name(struct vkms_config *config) return config->dev_name; } +/** + * vkms_config_planes() - Return the array of planes of the device + * @config: Configuration to get the planes from + * @out_length: Length of the returned array + * + * Returns: + * A list of pointers to the configurations. On success, the caller is + * responsible to free the returned array, but not its contents. On error, + * it returns an error and @out_length is invalid. + */ +struct vkms_config_plane **vkms_config_get_planes(const struct vkms_config *config, + size_t *out_length); + /** * vkms_config_is_valid() - Validate a configuration * @config: Configuration to validate @@ -81,4 +113,42 @@ bool vkms_config_is_valid(struct vkms_config *config); */ void vkms_config_register_debugfs(struct vkms_device *vkms_device); +/** + * vkms_config_add_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_add_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 068a7f87ecec..b2ae269e5827 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -11,61 +11,63 @@ 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; - int ret; + struct vkms_plane *primary = NULL, *cursor = NULL; + struct vkms_config_plane **plane_cfgs = NULL; + size_t n_planes; + int ret = 0; int writeback; unsigned int n; - /* - * 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); + plane_cfgs = vkms_config_get_planes(vkmsdev->config, &n_planes); + if (IS_ERR(plane_cfgs)) + return PTR_ERR(plane_cfgs); - if (vkmsdev->config->cursor) { - cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR); - if (IS_ERR(cursor)) - return PTR_ERR(cursor); + for (n = 0; n < n_planes; n++) { + struct vkms_config_plane *plane_cfg; + enum drm_plane_type type; + + plane_cfg = plane_cfgs[n]; + 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"); + ret = PTR_ERR(plane_cfg->plane); + goto err_free; + } + + 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, cursor ? &cursor->base : NULL); if (IS_ERR(output)) { DRM_ERROR("Failed to allocate CRTC\n"); - 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); - } + ret = PTR_ERR(output); + goto err_free; } connector = vkms_connector_init(vkmsdev); if (IS_ERR(connector)) { DRM_ERROR("Failed to init connector\n"); - return PTR_ERR(connector); + ret = PTR_ERR(connector); + goto err_free; } encoder = drmm_kzalloc(dev, sizeof(*encoder), GFP_KERNEL); if (!encoder) { DRM_ERROR("Failed to allocate encoder\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_free; } ret = drmm_encoder_init(dev, encoder, NULL, DRM_MODE_ENCODER_VIRTUAL, NULL); if (ret) { DRM_ERROR("Failed to init encoder\n"); - return ret; + goto err_free; } encoder->possible_crtcs = drm_crtc_mask(&output->crtc); @@ -73,7 +75,7 @@ int vkms_output_init(struct vkms_device *vkmsdev) ret = drm_connector_attach_encoder(&connector->base, encoder); if (ret) { DRM_ERROR("Failed to attach connector to encoder\n"); - return ret; + goto err_free; } /* Initialize the writeback component */ @@ -85,5 +87,8 @@ int vkms_output_init(struct vkms_device *vkmsdev) drm_mode_config_reset(dev); +err_free: + kfree(plane_cfgs); + return ret; } From patchwork Wed Jan 29 11:00:54 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: 13953636 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 800BAC02190 for ; Wed, 29 Jan 2025 11:01:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4E53F10E7B5; Wed, 29 Jan 2025 11:01:33 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="LgvjVGr+"; dkim-atps=neutral Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) by gabe.freedesktop.org (Postfix) with ESMTPS id E4D2B10E7A9 for ; Wed, 29 Jan 2025 11:01:16 +0000 (UTC) Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-43625c4a50dso44595075e9.0 for ; Wed, 29 Jan 2025 03:01:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148475; x=1738753275; 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=PWyhKU7rNdH8bD+VJvosWh8sByoTXBt/ga10H7y8Dnk=; b=LgvjVGr+NpzOSUEF55+00w4GuJ0tuFPMO0IOFlhfgLHARDj1+DArDwFGYa9xsYlrAZ 9yVPUPM1Jv0JaYCuI8z8OjuGPe3cbRAvEUvIivrS2waZRwLm6lmaesGKqR0vO6Dmt6Ep Dfsf2Bt/JtEfxWaSkgcZc9oSxeNA0p/pbWtBcAOY8Yh+kZ0dW8OHzqpVjR1tyNKoULz1 1QTGIPRdL1nE/uU2EUGjCUpvccKubzKkBfsK5pNE6tlWNyZID5UIpB7jgEMBod1h9jg9 OUGZQQtnHq5er5BlYJ057nSb5L3BCwFmZsPYGuYfS/Uy8gfjbhnUUUjeObeuY6piQwNo lvRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148475; x=1738753275; 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=PWyhKU7rNdH8bD+VJvosWh8sByoTXBt/ga10H7y8Dnk=; b=YUjpF0IhBMyMcA+E9Bxl+LuKQuzT5I+KrKOI1O3wgsUz3WdiQ5DYvQzk8Dp6fC4YGU loMaqj5lot19xW3Hu8XLsPVkzV4jE+MMX4VBBjouC/DmAW6qU+L7UzxK+97+mij+2f7o d6EWepNUPiXbP6bWJmDHJiehZEQ6A/WoC+XvQSE4dBpEJd5EQ+cKLE6EVzGd6wWTjKFD u4JchSoz4PygOFK6N8f2XoPtL3H7fy6jPx0ovTq/h07JphPrF2wXDI/eUxZWJSrt28cL qQi7RTbRnCLKDUR1xF4iSbZeoC6e9eYLwPpP09Nh2LQT53hxnz2Kxuxvdv/uMd7Ro1NO cRGg== X-Forwarded-Encrypted: i=1; AJvYcCVDtYI2FFzFGFc9BKhSmtXIrf+lFK034GfbQ2V5CaZZ2rc3BJ9ytFA44a0jmjet47R8bzKgoInMPaE=@lists.freedesktop.org X-Gm-Message-State: AOJu0YwH0jwLL0HGCCTOTcjEXtrE2HK+NBMUM/aQuTqVjLAx9U+HXC+e /oOYPKyrhdeW5RZGM2nUDLRK4X/8kuLnJBcO67LDUcRQrcm0TcJv X-Gm-Gg: ASbGncusDs1VyfN7Cu4t9zKHdIe+ECdqY+okaUplSm0O4h/3KRXwa6tAYfmas+weTtO STTyJnZc1THjickPLhG0RolEMcS0ej2JvllLWcgd+OBPleQ2cD3ZSR3Acr4P6V5QkO5PvSs6sNt oCbJRTSixye3niSpUo+U67WpnrsmfmNyJr3OQ0IZW9g3UjXVcGDF3bLTAP50IIs8wA3oET5csd8 jdzpJfToeamAcWiPgOBZG1I82Zc2UNcZ24SbF+hRgLmygui49abHS9aCs0LofIUfpCi9ZGoyTJY QULhTR9EN0toCL9H X-Google-Smtp-Source: AGHT+IGxI/8h+i7c/jW6fIxV1OZm8Cs90w6P/3JNhZdaD1QTZvYbrc/QvBvLcOlI+/Ue+T0wtoOzjA== X-Received: by 2002:a05:600c:458a:b0:436:ed50:4f8a with SMTP id 5b1f17b1804b1-438dc3c333cmr23449305e9.10.1738148474804; Wed, 29 Jan 2025 03:01:14 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:14 -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 08/13] drm/vkms: Allow to configure multiple CRTCs Date: Wed, 29 Jan 2025 12:00:54 +0100 Message-ID: <20250129110059.12199-9-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Signed-off-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 72 +++++++++++++++- drivers/gpu/drm/vkms/vkms_config.c | 86 ++++++++++++++++++- drivers/gpu/drm/vkms/vkms_config.h | 83 ++++++++++++++++++ drivers/gpu/drm/vkms/vkms_drv.c | 3 +- 4 files changed, 238 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 7d9cb3956741..b5907b060a5c 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 */ list_for_each_entry(plane_cfg, &config->planes, link) { 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 */ + crtc_cfg = list_first_entry(&config->crtcs, typeof(*crtc_cfg), link); + + KUNIT_EXPECT_EQ(test, list_count_nodes(&config->crtcs), 1); + 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); @@ -121,6 +128,42 @@ 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_cfg1, *crtc_cfg2; + struct vkms_config_crtc **array; + size_t length; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + array = vkms_config_get_crtcs(config, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + crtc_cfg1 = vkms_config_add_crtc(config); + array = vkms_config_get_crtcs(config, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], crtc_cfg1); + kfree(array); + + crtc_cfg2 = vkms_config_add_crtc(config); + array = vkms_config_get_crtcs(config, &length); + KUNIT_ASSERT_EQ(test, length, 2); + KUNIT_ASSERT_PTR_EQ(test, array[0], crtc_cfg1); + KUNIT_ASSERT_PTR_EQ(test, array[1], crtc_cfg2); + kfree(array); + + vkms_config_destroy_crtc(config, crtc_cfg2); + array = vkms_config_get_crtcs(config, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], crtc_cfg1); + kfree(array); + + vkms_config_destroy(config); +} + static void vkms_config_test_valid_plane_number(struct kunit *test) { struct vkms_config *config; @@ -185,13 +228,38 @@ static void vkms_config_test_valid_plane_type(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_valid_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_add_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_valid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), + KUNIT_CASE(vkms_config_test_valid_crtc_number), {} }; diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index a5a77612645f..4128892836d7 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -22,6 +22,7 @@ struct vkms_config *vkms_config_create(const char *dev_name) } INIT_LIST_HEAD(&config->planes); + INIT_LIST_HEAD(&config->crtcs); return config; } @@ -32,19 +33,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_add_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_add_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_add_plane(config); @@ -72,10 +77,14 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, 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); } @@ -107,6 +116,33 @@ struct vkms_config_plane **vkms_config_get_planes(const struct vkms_config *conf return array; } +struct vkms_config_crtc **vkms_config_get_crtcs(const struct vkms_config *config, + size_t *out_length) +{ + struct vkms_config_crtc **array; + struct vkms_config_crtc *crtc_cfg; + size_t length; + int n = 0; + + length = list_count_nodes((struct list_head *)&config->crtcs); + if (length == 0) { + *out_length = length; + return NULL; + } + + array = kmalloc_array(length, sizeof(*array), GFP_KERNEL); + if (!array) + return ERR_PTR(-ENOMEM); + + list_for_each_entry(crtc_cfg, &config->crtcs, link) { + array[n] = crtc_cfg; + n++; + } + + *out_length = length; + return array; +} + static bool valid_plane_number(struct vkms_config *config) { size_t n_planes; @@ -156,11 +192,27 @@ static bool valid_plane_type(struct vkms_config *config) return true; } +static bool valid_crtc_number(struct vkms_config *config) +{ + size_t n_crtcs; + + n_crtcs = list_count_nodes(&config->crtcs); + if (n_crtcs <= 0 || n_crtcs >= 32) { + pr_err("The number of CRTCs must be between 1 and 31\n"); + return false; + } + + return true; +} + bool vkms_config_is_valid(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; @@ -174,10 +226,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); list_for_each_entry(plane_cfg, &vkmsdev->config->planes, link) { seq_puts(m, "plane:\n"); @@ -185,6 +237,12 @@ static int vkms_config_show(struct seq_file *m, void *data) vkms_config_plane_get_type(plane_cfg)); } + list_for_each_entry(crtc_cfg, &vkmsdev->config->crtcs, link) { + seq_puts(m, "crtc:\n"); + seq_printf(m, "\twriteback=%d\n", + vkms_config_crtc_get_writeback(crtc_cfg)); + } + return 0; } @@ -218,3 +276,25 @@ void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg) list_del(&plane_cfg->link); kfree(plane_cfg); } + +struct vkms_config_crtc *vkms_config_add_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); + + vkms_config_crtc_set_writeback(crtc_cfg, false); + + list_add_tail(&crtc_cfg->link, &config->crtcs); + + return crtc_cfg; +} + +void vkms_config_destroy_crtc(struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg) +{ + list_del(&crtc_cfg->link); + kfree(crtc_cfg); +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index d9aeba1762d1..a7828fe0c4b2 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; }; @@ -43,6 +45,25 @@ struct vkms_config_plane { struct vkms_plane *plane; }; +/** + * struct vkms_config_crtc + * + * @link: Link to the others CRTCs in vkms_config + * @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; + + bool writeback; + + /* Internal usage */ + struct vkms_output *crtc; +}; + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -96,6 +117,28 @@ vkms_config_get_device_name(struct vkms_config *config) struct vkms_config_plane **vkms_config_get_planes(const struct vkms_config *config, size_t *out_length); +/** + * 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_get_crtcs() - Return the array of CRTCs of the device + * @config: Configuration to get the CRTCs from + * @out_length: Length of the returned array + * + * Returns: + * A list of pointers to the configurations. On success, the caller is + * responsible to free the returned array, but not its contents. On error, + * it returns an error and @out_length is invalid. + */ +struct vkms_config_crtc **vkms_config_get_crtcs(const struct vkms_config *config, + size_t *out_length); + /** * vkms_config_is_valid() - Validate a configuration * @config: Configuration to validate @@ -151,4 +194,44 @@ vkms_config_plane_set_type(struct vkms_config_plane *plane_cfg, plane_cfg->type = type; } +/** + * vkms_config_add_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_add_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_ */ diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index f23ee1a053e9..77f24b802849 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; From patchwork Wed Jan 29 11:00:55 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: 13953637 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 86CEAC02194 for ; Wed, 29 Jan 2025 11:01:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 861A910E7B2; Wed, 29 Jan 2025 11:01:33 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Lj3AFQ8W"; 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 8BE2B10E7A8 for ; Wed, 29 Jan 2025 11:01:17 +0000 (UTC) Received: by mail-wr1-f46.google.com with SMTP id ffacd0b85a97d-38633b5dbcfso7486221f8f.2 for ; Wed, 29 Jan 2025 03:01:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148476; x=1738753276; 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=q88yikrH24hbqKVdPbrR3EWE1tAj+IlW/np5tlv3WjE=; b=Lj3AFQ8WA5gwSoi4XKJOtxelR1YmTG67FFEZYhII1FvPehf/aruOBWjrIfgKWSia9E KN5/AJf95T/IK3lKH1SzledThh1/r/8PsFWBGE9fUaYeFvt1JyGrl4oi6SZrOWId6hXS kkXOKvKt35wwpZf8dLU+RAwa1REu6RochNedGIUyKjl5iWKhyiRxHsCfeNAz1vNF0RE0 AVziaXxJeGtl2lUW2fZcu/k8ndUY2pBZ8XoZLKn3LIobGittyInNOC7NuKZQlF6VSng6 79IKQtxVU+0Vrp5Rc7eZo3e7hWrM+Q/Kxgo4w41nFr4b2DVBUFULjiCW01sqKcPbWnsC 4jVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148476; x=1738753276; 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=q88yikrH24hbqKVdPbrR3EWE1tAj+IlW/np5tlv3WjE=; b=CHLLDcWspmulx76NH0I/E9BPdbhQ83jfMNTYsn3cOaOaeL3MzNunVn74n247ZQIwSG 6b73IceOPIzN9d0swpIUhIz5A/gDH7bT6t8WDIJJLcks4Cfccq3F3UqICLkpMpon9ydr ytk2eisqZfiXA3CsgSWGcoVJb2mbhYzHj2EPJBHSVKywyisk+lGxHFiQb+R0gvQq8X1/ iU4u7m/3lU1uz5bHE9Id79JohcY8ktEWNhbdHK6TzLLAvdWD9TbPvWwk0FaojB/idWFn wuNuLk5Jhlq6s/41LJoDLARQZ/Hq1FMdcGg4xDmCfGMGlFLzFN6uAKwqYDeyD953QDCL bhsQ== X-Forwarded-Encrypted: i=1; AJvYcCX6K43qi7AVWagn12buVUBlZdrhbQWrzylkgFBG1L6RybWqw5lJPID+ouManpXTYBzNvgc33ETweJM=@lists.freedesktop.org X-Gm-Message-State: AOJu0YwZcoPhAeO23LP1M2lFnUiyq1d4ntKStmiM339+Uij/r4KX6yO/ 31IRp3zDjhDFJBJKx8hU0JpYn6wpcFfjum7Fc5GYGYVIW5FEjh1H X-Gm-Gg: ASbGncuv0Rqxx7Xm0yaMh9ozBjKm8JK/w5O7KTUo7cBHm9m2VXpQc2sTROpyizz5TDZ h6kQOm9knkjtAzCAsVh5jxRZwOPyUcC4AB1zDaSwsNEBK9xpT0i1SFgA+/r/6baIQvO7/g1kDTg P8CWGNYQnTBBC0MerYb/uKsT42cwT7s2PykRlVCpyJR05bdmLCY3LXR6sA84wj9l0Vte8vyIhWX iNKRsBSr/N/4FUsG41TiaFpLWyYllamL3Zy8TwiqvoPlyzj+ld8KdD6gZthDoD8hNXrdvxbpa6j 76jZOn0danREwBPa X-Google-Smtp-Source: AGHT+IHDlygoZF3UMYScVhrgVjNYuMwkTq/5UtcpTgAKwbdLoTEd/tYv5i194zzG2JjgIAWcJ9vP7Q== X-Received: by 2002:adf:f943:0:b0:385:f996:1b8e with SMTP id ffacd0b85a97d-38c51951006mr2222645f8f.16.1738148475782; Wed, 29 Jan 2025 03:01:15 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:15 -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 09/13] drm/vkms: Allow to attach planes and CRTCs Date: Wed, 29 Jan 2025 12:00:55 +0100 Message-ID: <20250129110059.12199-10-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Signed-off-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 185 ++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 166 ++++++++++++++-- drivers/gpu/drm/vkms/vkms_config.h | 55 +++++- drivers/gpu/drm/vkms/vkms_output.c | 77 ++++++-- 4 files changed, 446 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index b5907b060a5c..5e698616491a 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); + list_for_each_entry(plane_cfg, &config->planes, link) { + struct vkms_config_crtc *possible_crtc; + int n_possible_crtcs = 0; + unsigned long idx = 0; + + xa_for_each(&plane_cfg->possible_crtcs, 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); @@ -191,6 +203,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); @@ -198,16 +212,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_add_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_add_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_add_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 */ @@ -217,14 +241,50 @@ static void vkms_config_test_valid_plane_type(struct kunit *test) /* Invalid: Multiple cursor planes */ plane_cfg = vkms_config_add_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_add_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_add_crtc(config); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: Second CRTC with a primary plane */ + plane_cfg = vkms_config_add_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); } @@ -251,6 +311,128 @@ static void vkms_config_test_valid_crtc_number(struct kunit *test) vkms_config_destroy(config); } +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_add_plane(config); + vkms_config_plane_set_type(overlay_cfg, DRM_PLANE_TYPE_OVERLAY); + primary_cfg = vkms_config_add_plane(config); + vkms_config_plane_set_type(primary_cfg, DRM_PLANE_TYPE_PRIMARY); + cursor_cfg = vkms_config_add_plane(config); + vkms_config_plane_set_type(cursor_cfg, DRM_PLANE_TYPE_CURSOR); + + crtc_cfg = vkms_config_add_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 **array; + size_t length; + int err; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + plane_cfg1 = vkms_config_add_plane(config); + plane_cfg2 = vkms_config_add_plane(config); + crtc_cfg1 = vkms_config_add_crtc(config); + crtc_cfg2 = vkms_config_add_crtc(config); + + /* No possible CRTCs */ + array = vkms_config_plane_get_possible_crtcs(plane_cfg1, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + array = vkms_config_plane_get_possible_crtcs(plane_cfg2, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + /* 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); + + array = vkms_config_plane_get_possible_crtcs(plane_cfg1, &length); + KUNIT_ASSERT_EQ(test, length, 2); + KUNIT_ASSERT_PTR_EQ(test, array[0], crtc_cfg1); + KUNIT_ASSERT_PTR_EQ(test, array[1], crtc_cfg2); + kfree(array); + + array = vkms_config_plane_get_possible_crtcs(plane_cfg2, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + /* Plane 1 attached to CRTC 1 and plane 2 to CRTC 2 */ + vkms_config_plane_detach_crtc(plane_cfg1, crtc_cfg2); + + array = vkms_config_plane_get_possible_crtcs(plane_cfg1, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], crtc_cfg1); + kfree(array); + + err = vkms_config_plane_attach_crtc(plane_cfg2, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + array = vkms_config_plane_get_possible_crtcs(plane_cfg2, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], crtc_cfg2); + kfree(array); + + 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, @@ -259,7 +441,10 @@ static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_get_crtcs), KUNIT_CASE(vkms_config_test_valid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), + KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), KUNIT_CASE(vkms_config_test_valid_crtc_number), + 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 4128892836d7..a2ce4905589b 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -50,13 +50,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_add_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; } } @@ -64,7 +71,11 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, plane_cfg = vkms_config_add_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; @@ -156,31 +167,39 @@ static bool valid_plane_number(struct vkms_config *config) return true; } -static bool valid_plane_type(struct vkms_config *config) +static bool valid_plane_type(struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg) { struct vkms_config_plane *plane_cfg; bool has_primary_plane = false; bool has_cursor_plane = false; list_for_each_entry(plane_cfg, &config->planes, link) { + 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) { - pr_err("Multiple primary planes\n"); - return false; - } + xa_for_each(&plane_cfg->possible_crtcs, idx, possible_crtc) { + if (possible_crtc != crtc_cfg) + continue; - has_primary_plane = true; - } else if (type == DRM_PLANE_TYPE_CURSOR) { - if (has_cursor_plane) { - pr_err("Multiple cursor planes\n"); - return false; - } + if (type == DRM_PLANE_TYPE_PRIMARY) { + if (has_primary_plane) { + pr_err("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) { + pr_err("Multiple cursor planes\n"); + return false; + } + + has_cursor_plane = true; + } } } @@ -192,6 +211,20 @@ static bool valid_plane_type(struct vkms_config *config) return true; } +static bool valid_plane_possible_crtcs(struct vkms_config *config) +{ + struct vkms_config_plane *plane_cfg; + + list_for_each_entry(plane_cfg, &config->planes, link) { + if (xa_empty(&plane_cfg->possible_crtcs)) { + pr_err("All planes must have at least one possible CRTC\n"); + return false; + } + } + + return true; +} + static bool valid_crtc_number(struct vkms_config *config) { size_t n_crtcs; @@ -207,15 +240,22 @@ static bool valid_crtc_number(struct vkms_config *config) bool vkms_config_is_valid(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; + list_for_each_entry(crtc_cfg, &config->crtcs, link) { + if (!valid_plane_type(config, crtc_cfg)) + return false; + } + return true; } @@ -265,6 +305,7 @@ struct vkms_config_plane *vkms_config_add_plane(struct vkms_config *config) return ERR_PTR(-ENOMEM); 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); @@ -273,10 +314,69 @@ struct vkms_config_plane *vkms_config_add_plane(struct vkms_config *config) 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); } +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; + + xa_for_each(&plane_cfg->possible_crtcs, idx, possible_crtc) { + if (possible_crtc == crtc_cfg) + return -EINVAL; + } + + return xa_alloc(&plane_cfg->possible_crtcs, &crtc_idx, crtc_cfg, + xa_limit_32b, GFP_KERNEL); +} + +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; + + xa_for_each(&plane_cfg->possible_crtcs, idx, possible_crtc) { + if (possible_crtc == crtc_cfg) + xa_erase(&plane_cfg->possible_crtcs, idx); + } +} + +struct vkms_config_crtc **vkms_config_plane_get_possible_crtcs(struct vkms_config_plane *plane_cfg, + size_t *out_length) +{ + struct vkms_config_crtc **array; + struct vkms_config_crtc *possible_crtc; + unsigned long idx; + size_t length = 0; + int n = 0; + + xa_for_each(&plane_cfg->possible_crtcs, idx, possible_crtc) + length++; + + if (length == 0) { + *out_length = length; + return NULL; + } + + array = kmalloc_array(length, sizeof(*array), GFP_KERNEL); + if (!array) + return ERR_PTR(-ENOMEM); + + xa_for_each(&plane_cfg->possible_crtcs, idx, possible_crtc) { + array[n] = possible_crtc; + n++; + } + + *out_length = length; + return array; +} + struct vkms_config_crtc *vkms_config_add_crtc(struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -295,6 +395,44 @@ struct vkms_config_crtc *vkms_config_add_crtc(struct vkms_config *config) void vkms_config_destroy_crtc(struct vkms_config *config, struct vkms_config_crtc *crtc_cfg) { + struct vkms_config_plane *plane_cfg; + + list_for_each_entry(plane_cfg, &config->planes, link) + vkms_config_plane_detach_crtc(plane_cfg, crtc_cfg); + list_del(&crtc_cfg->link); kfree(crtc_cfg); } + +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; + + list_for_each_entry(plane_cfg, &config->planes, link) { + current_type = vkms_config_plane_get_type(plane_cfg); + + xa_for_each(&plane_cfg->possible_crtcs, 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); +} + +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); +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index a7828fe0c4b2..1f2e6c485d08 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -12,14 +12,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; @@ -31,6 +29,7 @@ struct vkms_config { * @link: Link to the others planes in vkms_config * @type: Type of the plane. The creator of configuration needs to ensures that * at least one primary plane is present. + * @possible_crtcs: Array of CRTCs that can be used with this plane * @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 @@ -40,6 +39,7 @@ struct vkms_config_plane { struct list_head link; enum drm_plane_type type; + struct xarray possible_crtcs; /* Internal usage */ struct vkms_plane *plane; @@ -194,6 +194,35 @@ 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_attach_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_plane_get_possible_crtcs() - Return the array of possible CRTCs + * @plane_cfg: Plane to get the possible CRTCs from + * @out_length: Length of the returned array + * + * Returns: + * A list of pointers to the configurations. On success, the caller is + * responsible to free the returned array, but not its contents. On error, + * it returns an error and @out_length is invalid. + */ +struct vkms_config_crtc **vkms_config_plane_get_possible_crtcs(struct vkms_config_plane *plane_cfg, + size_t *out_length); + /** * vkms_config_add_crtc() - Add a new CRTC configuration * @config: Configuration to add the CRTC to @@ -234,4 +263,26 @@ 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 + * + * 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 + * + * 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_output.c b/drivers/gpu/drm/vkms/vkms_output.c index b2ae269e5827..427d0aad8901 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -10,18 +10,24 @@ 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_cfgs = NULL; size_t n_planes; + struct vkms_config_crtc **crtc_cfgs = NULL; + size_t n_crtcs; int ret = 0; int writeback; - unsigned int n; + unsigned int n, i; plane_cfgs = vkms_config_get_planes(vkmsdev->config, &n_planes); if (IS_ERR(plane_cfgs)) return PTR_ERR(plane_cfgs); + crtc_cfgs = vkms_config_get_crtcs(vkmsdev->config, &n_crtcs); + if (IS_ERR(crtc_cfgs)) { + ret = PTR_ERR(crtc_cfgs); + goto err_free; + } + for (n = 0; n < n_planes; n++) { struct vkms_config_plane *plane_cfg; enum drm_plane_type type; @@ -35,19 +41,54 @@ int vkms_output_init(struct vkms_device *vkmsdev) ret = PTR_ERR(plane_cfg->plane); goto err_free; } + } + + for (n = 0; n < n_crtcs; n++) { + struct vkms_config_crtc *crtc_cfg; + struct vkms_config_plane *primary, *cursor; + + crtc_cfg = crtc_cfgs[n]; + primary = vkms_config_crtc_primary_plane(vkmsdev->config, crtc_cfg); + cursor = vkms_config_crtc_cursor_plane(vkmsdev->config, crtc_cfg); + + 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"); + ret = PTR_ERR(crtc_cfg->crtc); + goto err_free; + } - if (type == DRM_PLANE_TYPE_PRIMARY) - primary = plane_cfg->plane; - else if (type == DRM_PLANE_TYPE_CURSOR) - cursor = plane_cfg->plane; + /* 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"); - ret = PTR_ERR(output); - goto err_free; + for (n = 0; n < n_planes; n++) { + struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc **possible_crtcs; + size_t n_possible_crtcs; + + plane_cfg = plane_cfgs[n]; + possible_crtcs = vkms_config_plane_get_possible_crtcs(plane_cfg, + &n_possible_crtcs); + if (IS_ERR(possible_crtcs)) { + ret = PTR_ERR(possible_crtcs); + goto err_free; + } + + for (i = 0; i < n_possible_crtcs; i++) { + struct vkms_config_crtc *possible_crtc; + + possible_crtc = possible_crtcs[i]; + plane_cfg->plane->base.possible_crtcs |= + drm_crtc_mask(&possible_crtc->crtc->crtc); + } + + kfree(possible_crtcs); } connector = vkms_connector_init(vkmsdev); @@ -69,7 +110,7 @@ int vkms_output_init(struct vkms_device *vkmsdev) DRM_ERROR("Failed to init encoder\n"); goto err_free; } - encoder->possible_crtcs = drm_crtc_mask(&output->crtc); + encoder->possible_crtcs = drm_crtc_mask(&crtc_cfgs[0]->crtc->crtc); /* Attach the encoder and the connector */ ret = drm_connector_attach_encoder(&connector->base, encoder); @@ -78,17 +119,11 @@ int vkms_output_init(struct vkms_device *vkmsdev) goto err_free; } - /* 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); err_free: kfree(plane_cfgs); + kfree(crtc_cfgs); return ret; } From patchwork Wed Jan 29 11:00:56 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: 13953635 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 E2508C02193 for ; Wed, 29 Jan 2025 11:01:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 28CBA10E7B4; Wed, 29 Jan 2025 11:01:33 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="icdm4PBF"; 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 7A20F10E7AB for ; Wed, 29 Jan 2025 11:01:18 +0000 (UTC) Received: by mail-wr1-f50.google.com with SMTP id ffacd0b85a97d-385d7f19f20so3357485f8f.1 for ; Wed, 29 Jan 2025 03:01:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148477; x=1738753277; 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=AeAv/5lTYD8GiNcnw1WJeIlZJ4ADDa5O2/fInNJ5TA0=; b=icdm4PBF/343UpPmoHC6r4aHw3aBdaOzm5pSKbnZRDP30ZIW6nlB7kuyqGA3AXndrU uojO0yQpEZw20uDMimcqD90WUzm+vLy8zVarDNZu1U+0jX8FFB4yjQWV7bdnHi5nBqJS 0H7XQkOKq9H2/KD3vyiKNWvf/ZFgS11Z7vBsb4ISHtFMCVXU3tB4KaeTEixV7BNkG4+7 eK6duxD5oTJAEGtZnJOY2R8wBy4dlvkYiMt4k7DfDJzVr5y3kRSiFPpSnORAUI2K+56O IQc1xVLC2Lj9mPV9bSS3rJuNFsOj67Ont/qrALdaCbfe6CpoCwqll+sQhGO7+ATlvzN7 V9Kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148477; x=1738753277; 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=AeAv/5lTYD8GiNcnw1WJeIlZJ4ADDa5O2/fInNJ5TA0=; b=IBOOnFcI8TydwY7yerCzayu6r6Ji9Nrx6b1RoQiXJWto+O5TOOsJlmYJibRE1rveQK 7C9bTi+cabA0q6koEUda2Jnk57mZ8B/EfUDSu5VyhwZGlrverKsY5WGh1qO3F0T1l9Vg /izBLyCTxjvHKbdpslR3scGox4FqfL8ZmKL2Y46GWLaQF5ScYGKFtydnZEjODxjS+K5K cforabOVgnILQMov/mIR85Be7hNN5xHFBm+pOFolHWM1eXkF3SBbLnvi0TH5SdUFvR3u 5UtFipEcrlfrLp1+mFILiqwd1uGx7pU+d6d7NM1sjHLgluOwRgBeSEzwOcv2euEkHdlj rX7Q== X-Forwarded-Encrypted: i=1; AJvYcCWPAgKCBJSvtbnNvu10UPQcld8HIpmz2tLuBK0vkFbcl733GOC9XttCYo43ZtzDjzlt1sbC4J6yeec=@lists.freedesktop.org X-Gm-Message-State: AOJu0YwiHEgdf7XLLYj5G02Ew+jRWKy+Duwu5BwcnMMmiK9btzSIhpYb EfUPJBMPB+2mUzCirIvBS+OUxX3YbLVj8CpygcZ076W8ud+mLTAg X-Gm-Gg: ASbGnctplAD5HmzBWNVHGN9/CB3lRMjuGTwqV8J1RXGitdB56cf+JlGBkkOMBOucr/S On7LS2tIKIqbI61zgwUr3OoKbTOGuRLHAnPMUBKZkpYtJydgjk1/xfj6ogL4MqHGRRArgBOlS/t sGV9QnUji76pM6riFNkZhUAWnjH7RijH388M+0JZVaEp5OurpUoA22/tdA572rlJtjlVh/ybcEO b+r0kQKqZQp5/HbxfsFc25zRiSKDL1OWK/rooAIYgoc86w4aKnxYqAbhpwcViqUfY9w7hFaKa65 WlNmCVYLXfKNGFQqA0rvtec94+4= X-Google-Smtp-Source: AGHT+IHHCx+npwL1T2h8TDIMwNBgX+6NeaIWD3PcUKnbkw8C0FD0i29soN8lgyZbFPebW96899TEDA== X-Received: by 2002:a5d:64a1:0:b0:385:f17b:de54 with SMTP id ffacd0b85a97d-38c5193112amr2151371f8f.5.1738148476587; Wed, 29 Jan 2025 03:01:16 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:16 -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 10/13] drm/vkms: Allow to configure multiple encoders Date: Wed, 29 Jan 2025 12:00:56 +0100 Message-ID: <20250129110059.12199-11-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Signed-off-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 65 ++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 78 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 49 ++++++++++++ 3 files changed, 192 insertions(+) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 5e698616491a..6c09363d9a96 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); @@ -176,6 +180,42 @@ 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_cfg1, *encoder_cfg2; + struct vkms_config_encoder **array; + size_t length; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + array = vkms_config_get_encoders(config, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + encoder_cfg1 = vkms_config_add_encoder(config); + array = vkms_config_get_encoders(config, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], encoder_cfg1); + kfree(array); + + encoder_cfg2 = vkms_config_add_encoder(config); + array = vkms_config_get_encoders(config, &length); + KUNIT_ASSERT_EQ(test, length, 2); + KUNIT_ASSERT_PTR_EQ(test, array[0], encoder_cfg1); + KUNIT_ASSERT_PTR_EQ(test, array[1], encoder_cfg2); + kfree(array); + + vkms_config_destroy_encoder(config, encoder_cfg2); + array = vkms_config_get_encoders(config, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], encoder_cfg1); + kfree(array); + + vkms_config_destroy(config); +} + static void vkms_config_test_valid_plane_number(struct kunit *test) { struct vkms_config *config; @@ -311,6 +351,29 @@ static void vkms_config_test_valid_crtc_number(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_valid_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_add_encoder(config); + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static void vkms_config_test_plane_attach_crtc(struct kunit *test) { struct vkms_config *config; @@ -439,10 +502,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_valid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), KUNIT_CASE(vkms_config_test_valid_crtc_number), + KUNIT_CASE(vkms_config_test_valid_encoder_number), 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 a2ce4905589b..75e72f9b5972 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); + INIT_LIST_HEAD(&config->encoders); return config; } @@ -34,6 +35,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); @@ -78,6 +80,10 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, goto err_alloc; } + encoder_cfg = vkms_config_add_encoder(config); + if (IS_ERR(encoder_cfg)) + goto err_alloc; + return config; err_alloc: @@ -89,6 +95,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); @@ -96,6 +103,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); } @@ -154,6 +164,33 @@ struct vkms_config_crtc **vkms_config_get_crtcs(const struct vkms_config *config return array; } +struct vkms_config_encoder **vkms_config_get_encoders(const struct vkms_config *config, + size_t *out_length) +{ + struct vkms_config_encoder **array; + struct vkms_config_encoder *encoder_cfg; + size_t length; + int n = 0; + + length = list_count_nodes((struct list_head *)&config->encoders); + if (length == 0) { + *out_length = length; + return NULL; + } + + array = kmalloc_array(length, sizeof(*array), GFP_KERNEL); + if (!array) + return ERR_PTR(-ENOMEM); + + list_for_each_entry(encoder_cfg, &config->encoders, link) { + array[n] = encoder_cfg; + n++; + } + + *out_length = length; + return array; +} + static bool valid_plane_number(struct vkms_config *config) { size_t n_planes; @@ -238,6 +275,19 @@ static bool valid_crtc_number(struct vkms_config *config) return true; } +static bool valid_encoder_number(struct vkms_config *config) +{ + size_t n_encoders; + + n_encoders = list_count_nodes(&config->encoders); + if (n_encoders <= 0 || n_encoders >= 32) { + pr_err("The number of encoders must be between 1 and 31\n"); + return false; + } + + return true; +} + bool vkms_config_is_valid(struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -248,6 +298,9 @@ bool vkms_config_is_valid(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; @@ -267,6 +320,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); @@ -283,6 +337,10 @@ static int vkms_config_show(struct seq_file *m, void *data) vkms_config_crtc_get_writeback(crtc_cfg)); } + list_for_each_entry(encoder_cfg, &vkmsdev->config->encoders, link) { + seq_puts(m, "encoder\n"); + } + return 0; } @@ -436,3 +494,23 @@ 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); } + +struct vkms_config_encoder *vkms_config_add_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); + + list_add_tail(&encoder_cfg->link, &config->encoders); + + return encoder_cfg; +} + +void vkms_config_destroy_encoder(struct vkms_config *config, + struct vkms_config_encoder *encoder_cfg) +{ + list_del(&encoder_cfg->link); + kfree(encoder_cfg); +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index 1f2e6c485d08..40774d0daeac 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 * @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; }; @@ -64,6 +66,22 @@ struct vkms_config_crtc { struct vkms_output *crtc; }; +/** + * struct vkms_config_encoder + * + * @link: Link to the others encoders in vkms_config + * @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; + + /* Internal usage */ + struct drm_encoder *encoder; +}; + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -139,6 +157,19 @@ static inline size_t vkms_config_get_num_crtcs(struct vkms_config *config) struct vkms_config_crtc **vkms_config_get_crtcs(const struct vkms_config *config, size_t *out_length); +/** + * vkms_config_get_encoders() - Return the array of encoders of the device + * @config: Configuration to get the encoders from + * @out_length: Length of the returned array + * + * Returns: + * A list of pointers to the configurations. On success, the caller is + * responsible to free the returned array, but not its contents. On error, + * it returns an error and @out_length is invalid. + */ +struct vkms_config_encoder **vkms_config_get_encoders(const struct vkms_config *config, + size_t *out_length); + /** * vkms_config_is_valid() - Validate a configuration * @config: Configuration to validate @@ -285,4 +316,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_add_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_add_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 Wed Jan 29 11:00:57 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: 13953632 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 3814DC0218D for ; Wed, 29 Jan 2025 11:01:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A170010E7AB; Wed, 29 Jan 2025 11:01:24 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="m9o3JefS"; 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 608C510E7AB for ; Wed, 29 Jan 2025 11:01:19 +0000 (UTC) Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-4362f61757fso70189675e9.2 for ; Wed, 29 Jan 2025 03:01:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148478; x=1738753278; 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=3ctx3bBvh7dKYn9+bYFpGOwRx0uhS4Evu/DJfS35toY=; b=m9o3JefSG5l6s0Q731eb1SCBpwbmf0a2mppRlKI2iK7l8UX7YmFx8+aEmlxJD4zNp0 wfUqtOU3IOS/l10mPHdyJ69EnU8M/wagUq3R9VrEYWKSU+HqZTG9gtGrq67MGfASK1m2 nNuhTlBHWwyN4b4pyqvo8wWT7/5YmCQvReTyRVWL4X4Gdj1/5JcVOz1RvssHoRHr4Yt4 t11qvvL4uy8osJa6yiLsLI2vOeoSaBkk1R6mcWvwskuVdU5uUal6kyWBS25WuVfjqWva a1kFACWib9sAjPkjfFCVUN1lI69x3v6vF/WQmwD4XW50zBy1Xq1CoOqRnc7Cqzo+VZMH fIRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148478; x=1738753278; 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=3ctx3bBvh7dKYn9+bYFpGOwRx0uhS4Evu/DJfS35toY=; b=FSbTCo393RhaH9artg03M7Oku2NCqkpbe42dWHbuk+Iy9CTtq36d4s22WVf31AvWfL tII3hz32jsW1Ry6YS4hZYXxBWEXEaBAzraonlUippoN33UYjsZv/5eWynkRgLBfIcCno 5s18RpI8YH8vlqhJNj2u2uOEsXSHRxo+oWBPZN268SYJzliUnfgQgOGiVd73UEiStcvp H4D8XDKapN7EAM19I8g/4Jt2XP5YHLWxmhYc5N9vK8bqVFVNS61SPRPoxDVvwCBPvlOr xK8cRh8GVRkthf/V6/POg/sJBwjMJnzWfXBfbVPtVckb9AJZ6ujbcA8jbKgLGjGLH2zL uXGg== X-Forwarded-Encrypted: i=1; AJvYcCV29blSw4xBkEUVDD3813zKVAuxfbqlnt1uBMXgvC1hD+p27Pm1JqPEoqHHlB5SUbXzZKWt8O8QQ+k=@lists.freedesktop.org X-Gm-Message-State: AOJu0Yza9rT3cJo+Cn2s6N4EUeO9hA4fWfSBPDuazB5nATOpzT4cPOg7 VssLp2MfkunIU722NHZ2E2YrDVGCaeMXvi9wbvCzhL0lnzsajbn/ X-Gm-Gg: ASbGncuJ8KK+huWEcTPCTPZzoAhIcFyG7kAU0H61IecHdsRF7UoQ6EEng4ZF8VFHU6F usEoVFHFAeOg0IgprvNSvSIHA0ANAj9Dfdv2evP61mY+9DmxzmmkhgKvrhpxAx6rTDL0PsYRKWt Mum5PVY/q9oapd2gu4MqPiw8JUzTSYTAQnnRgIZkbF9aauI37zDCdFsbT0czRcdYEV/pMQjJmrg 3sdbzIeUohhyN4alFv+nEKy5JgnJvscKPqHQmCC75QpiFvhRmYru9YzVu9KraCLIFZAlt94qbmN a4wCOSWBG0Kg8lQ9TvY8h4c72dI= X-Google-Smtp-Source: AGHT+IGwOpnYkfxSC17PNmKgDXS/E15tZQhZiHk1BMlGNoe2KSpGP7el/jfnz4r9qDPjkJ51kbuApg== X-Received: by 2002:a05:600c:1d1e:b0:434:a90b:94fe with SMTP id 5b1f17b1804b1-438dc3c2608mr23253225e9.10.1738148477437; Wed, 29 Jan 2025 03:01:17 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:17 -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 11/13] drm/vkms: Allow to attach encoders and CRTCs Date: Wed, 29 Jan 2025 12:00:57 +0100 Message-ID: <20250129110059.12199-12-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Signed-off-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 112 ++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 106 +++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 33 ++++++ drivers/gpu/drm/vkms/vkms_output.c | 64 +++++++--- 4 files changed, 299 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 6c09363d9a96..27d44315c2de 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -244,6 +244,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); @@ -297,6 +298,9 @@ static void vkms_config_test_valid_plane_type(struct kunit *test) /* Invalid: Second CRTC without primary plane */ crtc_cfg = vkms_config_add_crtc(config); + encoder_cfg = vkms_config_add_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 */ @@ -374,6 +378,51 @@ static void vkms_config_test_valid_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_add_encoder(config); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: Second CRTC with shared encoder */ + crtc_cfg2 = vkms_config_add_crtc(config); + + plane_cfg = vkms_config_add_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_plane_attach_crtc(struct kunit *test) { struct vkms_config *config; @@ -496,6 +545,67 @@ 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 **array; + size_t length; + int err; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + encoder_cfg1 = vkms_config_add_encoder(config); + encoder_cfg2 = vkms_config_add_encoder(config); + crtc_cfg1 = vkms_config_add_crtc(config); + crtc_cfg2 = vkms_config_add_crtc(config); + + /* No possible CRTCs */ + array = vkms_config_encoder_get_possible_crtcs(encoder_cfg1, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + array = vkms_config_encoder_get_possible_crtcs(encoder_cfg2, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + /* 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); + + array = vkms_config_encoder_get_possible_crtcs(encoder_cfg1, &length); + KUNIT_ASSERT_EQ(test, length, 2); + KUNIT_ASSERT_PTR_EQ(test, array[0], crtc_cfg1); + KUNIT_ASSERT_PTR_EQ(test, array[1], crtc_cfg2); + kfree(array); + + array = vkms_config_encoder_get_possible_crtcs(encoder_cfg2, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + /* Encoder 1 attached to CRTC 1 and encoder 2 to CRTC 2 */ + vkms_config_encoder_detach_crtc(encoder_cfg1, crtc_cfg2); + + array = vkms_config_encoder_get_possible_crtcs(encoder_cfg1, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], crtc_cfg1); + kfree(array); + + err = vkms_config_encoder_attach_crtc(encoder_cfg2, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + array = vkms_config_encoder_get_possible_crtcs(encoder_cfg2, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], crtc_cfg2); + kfree(array); + + 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, @@ -508,8 +618,10 @@ static struct kunit_case vkms_config_test_cases[] = { KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), KUNIT_CASE(vkms_config_test_valid_crtc_number), KUNIT_CASE(vkms_config_test_valid_encoder_number), + KUNIT_CASE(vkms_config_test_valid_encoder_possible_crtcs), 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 75e72f9b5972..437a9980e9a8 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -84,6 +84,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: @@ -288,6 +291,40 @@ static bool valid_encoder_number(struct vkms_config *config) return true; } +static bool valid_encoder_possible_crtcs(struct vkms_config *config) +{ + struct vkms_config_crtc *crtc_cfg; + struct vkms_config_encoder *encoder_cfg; + + list_for_each_entry(encoder_cfg, &config->encoders, link) { + if (xa_empty(&encoder_cfg->possible_crtcs)) { + pr_err("All encoders must have at least one possible CRTC\n"); + return false; + } + } + + list_for_each_entry(crtc_cfg, &config->crtcs, link) { + bool crtc_has_encoder = false; + + list_for_each_entry(encoder_cfg, &config->encoders, link) { + struct vkms_config_crtc *possible_crtc; + unsigned long idx = 0; + + xa_for_each(&encoder_cfg->possible_crtcs, idx, possible_crtc) { + if (possible_crtc == crtc_cfg) + crtc_has_encoder = true; + } + } + + if (!crtc_has_encoder) { + pr_err("All CRTCs must have at least one possible encoder\n"); + return false; + } + } + + return true; +} + bool vkms_config_is_valid(struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -309,6 +346,9 @@ bool vkms_config_is_valid(struct vkms_config *config) return false; } + if (!valid_encoder_possible_crtcs(config)) + return false; + return true; } @@ -454,10 +494,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; list_for_each_entry(plane_cfg, &config->planes, link) vkms_config_plane_detach_crtc(plane_cfg, crtc_cfg); + list_for_each_entry(encoder_cfg, &config->encoders, link) + vkms_config_encoder_detach_crtc(encoder_cfg, crtc_cfg); + list_del(&crtc_cfg->link); kfree(crtc_cfg); } @@ -503,6 +547,8 @@ struct vkms_config_encoder *vkms_config_add_encoder(struct vkms_config *config) if (!encoder_cfg) return ERR_PTR(-ENOMEM); + xa_init_flags(&encoder_cfg->possible_crtcs, XA_FLAGS_ALLOC); + list_add_tail(&encoder_cfg->link, &config->encoders); return encoder_cfg; @@ -511,6 +557,66 @@ struct vkms_config_encoder *vkms_config_add_encoder(struct vkms_config *config) 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); } + +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; + + xa_for_each(&encoder_cfg->possible_crtcs, idx, possible_crtc) { + if (possible_crtc == crtc_cfg) + return -EINVAL; + } + + return xa_alloc(&encoder_cfg->possible_crtcs, &crtc_idx, crtc_cfg, + xa_limit_32b, GFP_KERNEL); +} + +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; + + xa_for_each(&encoder_cfg->possible_crtcs, idx, possible_crtc) { + if (possible_crtc == crtc_cfg) + xa_erase(&encoder_cfg->possible_crtcs, idx); + } +} + +struct vkms_config_crtc ** +vkms_config_encoder_get_possible_crtcs(struct vkms_config_encoder *encoder_cfg, + size_t *out_length) +{ + struct vkms_config_crtc **array; + struct vkms_config_crtc *possible_crtc; + unsigned long idx; + size_t length = 0; + int n = 0; + + xa_for_each(&encoder_cfg->possible_crtcs, idx, possible_crtc) + length++; + + if (length == 0) { + *out_length = 0; + return NULL; + } + + array = kmalloc_array(length, sizeof(*array), GFP_KERNEL); + if (!array) + return ERR_PTR(-ENOMEM); + + xa_for_each(&encoder_cfg->possible_crtcs, idx, possible_crtc) { + array[n] = possible_crtc; + n++; + } + + *out_length = length; + return array; +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index 40774d0daeac..5f4a33e113bf 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -70,6 +70,7 @@ struct vkms_config_crtc { * struct vkms_config_encoder * * @link: Link to the others encoders in vkms_config + * @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 @@ -78,6 +79,8 @@ struct vkms_config_crtc { struct vkms_config_encoder { struct list_head link; + struct xarray possible_crtcs; + /* Internal usage */ struct drm_encoder *encoder; }; @@ -334,4 +337,34 @@ struct vkms_config_encoder *vkms_config_add_encoder(struct vkms_config *config); 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); + +/** + * vkms_config_encoder_get_possible_crtcs() - Return the array of possible CRTCs + * @encoder_cfg: Encoder to get the possible CRTCs from + * @out_length: Length of the returned array + * + * Returns: + * A list of pointers to the configurations. On success, the caller is + * responsible to free the returned array, but not its contents. On error, + * it returns an error and @out_length is invalid. + */ +struct vkms_config_crtc ** +vkms_config_encoder_get_possible_crtcs(struct vkms_config_encoder *encoder_cfg, + size_t *out_length); + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 427d0aad8901..9c3e00817add 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -9,11 +9,12 @@ 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_cfgs = NULL; size_t n_planes; struct vkms_config_crtc **crtc_cfgs = NULL; size_t n_crtcs; + struct vkms_config_encoder **encoder_cfgs = NULL; + size_t n_encoders; int ret = 0; int writeback; unsigned int n, i; @@ -28,6 +29,12 @@ int vkms_output_init(struct vkms_device *vkmsdev) goto err_free; } + encoder_cfgs = vkms_config_get_encoders(vkmsdev->config, &n_encoders); + if (IS_ERR(encoder_cfgs)) { + ret = PTR_ERR(encoder_cfgs); + goto err_free; + } + for (n = 0; n < n_planes; n++) { struct vkms_config_plane *plane_cfg; enum drm_plane_type type; @@ -91,6 +98,44 @@ int vkms_output_init(struct vkms_device *vkmsdev) kfree(possible_crtcs); } + for (n = 0; n < n_encoders; n++) { + struct vkms_config_encoder *encoder_cfg; + struct vkms_config_crtc **possible_crtcs; + size_t n_possible_crtcs; + + encoder_cfg = encoder_cfgs[n]; + + encoder_cfg->encoder = drmm_kzalloc(dev, sizeof(*encoder_cfg->encoder), GFP_KERNEL); + if (!encoder_cfg->encoder) { + DRM_ERROR("Failed to allocate encoder\n"); + ret = -ENOMEM; + goto err_free; + } + ret = drmm_encoder_init(dev, encoder_cfg->encoder, NULL, + DRM_MODE_ENCODER_VIRTUAL, NULL); + if (ret) { + DRM_ERROR("Failed to init encoder\n"); + goto err_free; + } + + possible_crtcs = vkms_config_encoder_get_possible_crtcs(encoder_cfg, + &n_possible_crtcs); + if (IS_ERR(possible_crtcs)) { + ret = PTR_ERR(possible_crtcs); + goto err_free; + } + + for (i = 0; i < n_possible_crtcs; i++) { + struct vkms_config_crtc *possible_crtc; + + possible_crtc = possible_crtcs[i]; + encoder_cfg->encoder->possible_crtcs |= + drm_crtc_mask(&possible_crtc->crtc->crtc); + } + + kfree(possible_crtcs); + } + connector = vkms_connector_init(vkmsdev); if (IS_ERR(connector)) { DRM_ERROR("Failed to init connector\n"); @@ -98,22 +143,8 @@ int vkms_output_init(struct vkms_device *vkmsdev) goto err_free; } - encoder = drmm_kzalloc(dev, sizeof(*encoder), GFP_KERNEL); - if (!encoder) { - DRM_ERROR("Failed to allocate encoder\n"); - ret = -ENOMEM; - goto err_free; - } - ret = drmm_encoder_init(dev, encoder, NULL, - DRM_MODE_ENCODER_VIRTUAL, NULL); - if (ret) { - DRM_ERROR("Failed to init encoder\n"); - goto err_free; - } - encoder->possible_crtcs = drm_crtc_mask(&crtc_cfgs[0]->crtc->crtc); - /* Attach the encoder and the connector */ - ret = drm_connector_attach_encoder(&connector->base, encoder); + ret = drm_connector_attach_encoder(&connector->base, encoder_cfgs[0]->encoder); if (ret) { DRM_ERROR("Failed to attach connector to encoder\n"); goto err_free; @@ -124,6 +155,7 @@ int vkms_output_init(struct vkms_device *vkmsdev) err_free: kfree(plane_cfgs); kfree(crtc_cfgs); + kfree(encoder_cfgs); return ret; } From patchwork Wed Jan 29 11:00:58 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: 13953638 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 A8124C0218D for ; Wed, 29 Jan 2025 11:01:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2BF6910E7A7; Wed, 29 Jan 2025 11:01:45 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="dEu6WZqz"; dkim-atps=neutral Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4C89F10E7AB for ; Wed, 29 Jan 2025 11:01:20 +0000 (UTC) Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-438a3216fc2so68179135e9.1 for ; Wed, 29 Jan 2025 03:01:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148479; x=1738753279; 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=XUpkYP/tGsoAbjn0vsUGNcgy0Vg9vALDj5dfocC1jjo=; b=dEu6WZqzFWbR8Wf7cYlZjuL6Y3A2xbpiGrvQHms+ftQ8T5lnH6nXs/BY+rIffx+DzA SHlUM3y4ZaW3I053cDJRJI4YV9rW77+ua5Do15kNBGj1pCD5CjMg4jczQmRcsqE2GAUU xRfEATgrpp56tFqtytDFAWxlt2nhENd5CB058bqGQBOcfhyPCZ78yJM4jcIfRdiwtDLZ V6iZGPqvIinHYKJeI5hu4uIw9MoYrvi2fQpaytA0jUSVRSeYBhO0ANDJRYiNTQaSbld7 CswB19tkozyfdmLIY8s+pKRPpvmnYF5+zcpRSqPwzRD8hpA+bD40Yr52sgyQyx354OiE Gbmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148479; x=1738753279; 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=XUpkYP/tGsoAbjn0vsUGNcgy0Vg9vALDj5dfocC1jjo=; b=QrqNSoXwMuPY4ld3hKJ7ZcTA5VmvzxYoa7x+muIEtjeVQuFlUoeOOfpQE4bj9/sgbW cNnIwUtTmO+sCkIsLDxkEW2E6QChXsEJYbnV8zxg4dmLWTpjuTrBQTEsoMehOZfsORyT 6FhbYdUkMZbCBu9hZ92GEV+pVYGBULWOEPht8mFOQW7ZdGGNb7Ocp9V7fQNWTxtK49rZ XRbNLLHZIrIdF+ni4z/V9+3hHzE+LiFKJvTBVSvixQ0pNfTWlgPIvALdrhzNfvfqZwrV 0dxcVS1BluwBo3oME+7Vs5whFBdDrYcxICnMhrP3xkryxXjkHRblQKWbf7431cgalWw2 AQpg== X-Forwarded-Encrypted: i=1; AJvYcCXC+zp/HtyzN6/R/sAaL9/GHIaNAp3XxSq8SLrWBTPUMZX8KGpqx9AEUmlo9QLsnYuNvfeD3k9r51c=@lists.freedesktop.org X-Gm-Message-State: AOJu0Yw0af6bvRuMqmsGldUKqHn3UUdVORA7fjC61kFD3ZBSxCWoVhky AbmpMUV2tKI/v2mErrRVFvxD/sPsN7X2FpKQ8NI9Iy3dfccxLtvg9VyYX8Kn X-Gm-Gg: ASbGncsPlMxqjWRhAv2G/NvCLlB2JkbLgP6Lml1v8a5w59JdfVXXq+euNfp9I7FcWQh MdvQbwpffet/BYPOzrtCkkpmX9060rMUeFDUDDDagoOx6jFDLb9jmNjFuqaiHluM5HwMWMForDu R/ipiqE/+hFdP7k3BJBb+xHWo2mcTHOSMQtm117GPaL4s81G/3XO9xH3V3SzZYf8axgsDs6Php2 7kxaWlCdcRYS+m20YcItRSeApa/wn7ovtWnkYy7ZvQZq+BAiKOH+1uinRD1hJGM1/wBByzVZv+L Tb8+YqrSlqcR5S66eQLsPKu9Unk= X-Google-Smtp-Source: AGHT+IEt/RU5BgHN4IuQXOAUZYIJmz+x4OCgxOMAFdg/eovjklOwz0AsxWcDE4GbtSVBFa+HrggMRA== X-Received: by 2002:a5d:5988:0:b0:385:fd07:8616 with SMTP id ffacd0b85a97d-38c5167d80bmr2164396f8f.0.1738148478451; Wed, 29 Jan 2025 03:01:18 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:17 -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 12/13] drm/vkms: Allow to configure multiple connectors Date: Wed, 29 Jan 2025 12:00:58 +0100 Message-ID: <20250129110059.12199-13-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Unlike planes, CRTCs and encoders, connectors can be added and removed once the device is created. To reflect it, add an "enabled" flag in the configuration and filter disabled connectors in the vkms_config_get_connectors() function. For the moment, changing the enabled status of the connector has no effect after the device is created, but a future patch will add this capability. 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. Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Signed-off-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 84 +++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 93 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 76 +++++++++++++++ drivers/gpu/drm/vkms/vkms_connector.c | 11 +++ 4 files changed, 264 insertions(+) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 27d44315c2de..40c385eedc1d 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)); @@ -52,6 +53,7 @@ static void vkms_config_test_default_config(struct kunit *test) struct vkms_config *config; struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; + struct vkms_config_connector *connector_cfg; int n_primaries = 0; int n_cursors = 0; int n_overlays = 0; @@ -103,6 +105,12 @@ 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); + connector_cfg = list_first_entry(&config->connectors, + typeof(*connector_cfg), link); + KUNIT_EXPECT_TRUE(test, vkms_config_connector_is_enabled(connector_cfg)); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); vkms_config_destroy(config); @@ -216,6 +224,47 @@ 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_cfg1, *connector_cfg2; + struct vkms_config_connector **array; + size_t length; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + array = vkms_config_get_connectors(config, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + connector_cfg1 = vkms_config_add_connector(config); + array = vkms_config_get_connectors(config, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + vkms_config_connector_set_enabled(connector_cfg1, true); + array = vkms_config_get_connectors(config, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], connector_cfg1); + kfree(array); + + connector_cfg2 = vkms_config_add_connector(config); + vkms_config_connector_set_enabled(connector_cfg2, true); + array = vkms_config_get_connectors(config, &length); + KUNIT_ASSERT_EQ(test, length, 2); + KUNIT_ASSERT_PTR_EQ(test, array[0], connector_cfg1); + KUNIT_ASSERT_PTR_EQ(test, array[1], connector_cfg2); + kfree(array); + + vkms_config_connector_set_enabled(connector_cfg1, false); + vkms_config_destroy_connector(connector_cfg2); + array = vkms_config_get_connectors(config, &length); + KUNIT_ASSERT_NULL(test, array); + + vkms_config_destroy(config); +} + static void vkms_config_test_valid_plane_number(struct kunit *test) { struct vkms_config *config; @@ -423,6 +472,39 @@ static void vkms_config_test_valid_encoder_possible_crtcs(struct kunit *test) vkms_config_destroy(config); } +static void vkms_config_test_valid_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); + + /* Valid: No connectors */ + connector_cfg = list_first_entry(&config->connectors, typeof(*connector_cfg), link); + vkms_config_destroy_connector(connector_cfg); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + /* Valid: Only a disabled connector */ + connector_cfg = vkms_config_add_connector(config); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + /* Valid: The connector is enabled */ + vkms_config_connector_set_enabled(connector_cfg, true); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + /* Invalid: Too many connectors */ + for (n = 0; n <= 32; n++) { + connector_cfg = vkms_config_add_connector(config); + vkms_config_connector_set_enabled(connector_cfg, true); + } + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static void vkms_config_test_plane_attach_crtc(struct kunit *test) { struct vkms_config *config; @@ -613,12 +695,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_valid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), KUNIT_CASE(vkms_config_test_valid_crtc_number), KUNIT_CASE(vkms_config_test_valid_encoder_number), KUNIT_CASE(vkms_config_test_valid_encoder_possible_crtcs), + KUNIT_CASE(vkms_config_test_valid_connector_number), 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 437a9980e9a8..e94e48fe3ad9 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); + INIT_LIST_HEAD(&config->connectors); return config; } @@ -36,6 +37,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); @@ -87,6 +89,11 @@ 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_add_connector(config); + if (IS_ERR(connector_cfg)) + goto err_alloc; + vkms_config_connector_set_enabled(connector_cfg, true); + return config; err_alloc: @@ -99,6 +106,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); @@ -109,6 +117,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); } @@ -194,6 +205,39 @@ struct vkms_config_encoder **vkms_config_get_encoders(const struct vkms_config * return array; } +struct vkms_config_connector **vkms_config_get_connectors(const struct vkms_config *config, + size_t *out_length) +{ + struct vkms_config_connector **array; + struct vkms_config_connector *connector_cfg; + size_t length = 0; + int n = 0; + + list_for_each_entry(connector_cfg, &config->connectors, link) { + if (vkms_config_connector_is_enabled(connector_cfg)) + length++; + } + + if (length == 0) { + *out_length = length; + return NULL; + } + + array = kmalloc_array(length, sizeof(*array), GFP_KERNEL); + if (!array) + return ERR_PTR(-ENOMEM); + + list_for_each_entry(connector_cfg, &config->connectors, link) { + if (vkms_config_connector_is_enabled(connector_cfg)) { + array[n] = connector_cfg; + n++; + } + } + + *out_length = length; + return array; +} + static bool valid_plane_number(struct vkms_config *config) { size_t n_planes; @@ -325,6 +369,24 @@ static bool valid_encoder_possible_crtcs(struct vkms_config *config) return true; } +static bool valid_connector_number(struct vkms_config *config) +{ + struct vkms_config_connector *connector_cfg; + size_t n_connectors = 0; + + list_for_each_entry(connector_cfg, &config->connectors, link) { + if (vkms_config_connector_is_enabled(connector_cfg)) + n_connectors++; + } + + if (n_connectors >= 32) { + pr_err("The number of connectors must be between 0 and 31\n"); + return false; + } + + return true; +} + bool vkms_config_is_valid(struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -338,6 +400,9 @@ bool vkms_config_is_valid(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; @@ -361,6 +426,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); @@ -381,6 +447,12 @@ static int vkms_config_show(struct seq_file *m, void *data) seq_puts(m, "encoder\n"); } + list_for_each_entry(connector_cfg, &vkmsdev->config->connectors, link) { + seq_puts(m, "connector:\n"); + seq_printf(m, "\tenabled=%d\n", + vkms_config_connector_is_enabled(connector_cfg)); + } + return 0; } @@ -620,3 +692,24 @@ vkms_config_encoder_get_possible_crtcs(struct vkms_config_encoder *encoder_cfg, *out_length = length; return array; } + +struct vkms_config_connector *vkms_config_add_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); + + vkms_config_connector_set_enabled(connector_cfg, false); + + list_add_tail(&connector_cfg->link, &config->connectors); + + return connector_cfg; +} + +void vkms_config_destroy_connector(struct vkms_config_connector *connector_cfg) +{ + list_del(&connector_cfg->link); + kfree(connector_cfg); +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index 5f4a33e113bf..cc32aadfda8d 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -15,6 +15,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 { @@ -22,6 +23,7 @@ struct vkms_config { struct list_head planes; struct list_head crtcs; struct list_head encoders; + struct list_head connectors; struct vkms_device *dev; }; @@ -85,6 +87,27 @@ struct vkms_config_encoder { struct drm_encoder *encoder; }; +/** + * struct vkms_config_connector + * + * @link: Link to the others connector in vkms_config + * @enabled: Connector are a different from planes, CRTCs and encoders because + * they can be added and removed once the device is created. + * This flag represents if they are part of the device or not. + * @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; + + bool enabled; + + /* Internal usage */ + struct vkms_connector *connector; +}; + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -173,6 +196,21 @@ struct vkms_config_crtc **vkms_config_get_crtcs(const struct vkms_config *config struct vkms_config_encoder **vkms_config_get_encoders(const struct vkms_config *config, size_t *out_length); +/** + * vkms_config_get_connectors() - Return the array of connectors of the device + * @config: Configuration to get the connectors from + * @out_length: Length of the returned array + * + * Note that only enabled connectors are returned. + * + * Returns: + * A list of pointers to the configurations. On success, the caller is + * responsible to free the returned array, but not its contents. On error, + * it returns an error and @out_length is invalid. + */ +struct vkms_config_connector **vkms_config_get_connectors(const struct vkms_config *config, + size_t *out_length); + /** * vkms_config_is_valid() - Validate a configuration * @config: Configuration to validate @@ -367,4 +405,42 @@ struct vkms_config_crtc ** vkms_config_encoder_get_possible_crtcs(struct vkms_config_encoder *encoder_cfg, size_t *out_length); +/** + * vkms_config_add_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_add_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); + +/** + * vkms_config_connector_is_enabled() - If the connector is part of the device + * @connector_cfg: The connector + */ +static inline bool +vkms_config_connector_is_enabled(struct vkms_config_connector *connector_cfg) +{ + return connector_cfg->enabled; +} + +/** + * vkms_config_connector_set_enabled() - If the connector is part of the device + * @crtc_cfg: Target connector + * @enabled: Add or remove the connector + */ +static inline void +vkms_config_connector_set_enabled(struct vkms_config_connector *connector_cfg, + bool enabled) +{ + connector_cfg->enabled = enabled; +} + #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 Wed Jan 29 11:00:59 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: 13953633 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 7B1C6C02190 for ; Wed, 29 Jan 2025 11:01:26 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 11C6310E7AC; Wed, 29 Jan 2025 11:01:25 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="DY2dXPci"; dkim-atps=neutral Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) by gabe.freedesktop.org (Postfix) with ESMTPS id EDCAF10E7AC for ; Wed, 29 Jan 2025 11:01:21 +0000 (UTC) Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-4361815b96cso45489535e9.1 for ; Wed, 29 Jan 2025 03:01:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738148480; x=1738753280; 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=sPKCrtDQeB9pT35xBqaZjucly7gQR5uxUbB7ZFp2HeA=; b=DY2dXPcizNm1etSHZ5jo8vLCso0mUk2KB0w8RNa9cNcpj5hqdCjZAd1umDgjXK1fB8 gQcIo4auXgwY9DpveQ3J9xF2Z+AqEqdACR79kVkERFx4utqIV70U0B81INZXHTkN72Mp 9T/o7NjfwZTyPraozfew5+7eoTx4Y6c/dSxRxM6W6spX+1W7N0N6ttO+6TylpaffkJag YgKUx9AH5wmdzPQLyQX7lsRh7rnYhYYHmnD3OsrW0rFG2zW6rUErfptfqpFvQQo1CFDI Bt9jLRiV91wFNr9qLrODqvB10pumS0Mt1U71Mao3CoJ9lGwhqpVQfxKfYdoojbBrTYXp POjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738148480; x=1738753280; 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=sPKCrtDQeB9pT35xBqaZjucly7gQR5uxUbB7ZFp2HeA=; b=kYE4Dv97chuYVEKSx79MKYIwMketxg13YJxEECnKU/qdmmYy+lfnM3COM0h0UOovXv Y6aXX0rNCUWLOB1ASH+d77AETkmiG9/I+bapxJdV+qV3WR8/uvqPeQUYof/yo0svWyNH 8T7SqYtg00azcVdUcqI1vx7A2epX11lFanoY0P08uHtJVc7h84Cx35VmdaELu9Q5ASh/ TnitFApyieLgzuCd4m6xtAtcpG8kRoHS2RrbOPNDOZ/ZC38zbwnYZRxxLZExwXd32aq0 hudhMG4C5f1nObewJN7JGJO9SGZjy+VUFZMbHp2AlmDKe0Ez03trYKbmX8IV4UX3aN+e YugQ== X-Forwarded-Encrypted: i=1; AJvYcCUH5U2jH90Pyjf7tGPhSn92vxe95inhThuYXXULQF01jxHSZhd5hR3fI9CmunEzqWVgioellQ46TpA=@lists.freedesktop.org X-Gm-Message-State: AOJu0YyYvSHKFy630MkbvOBv1NDTDpjL9iMl/190oXtBB6FPaTJ5XmEQ oQrtDDca7x14w/wJzNG/vjamMomefRtXDjRLq/FEs3Wrs4oAI5iv X-Gm-Gg: ASbGncvPxUrtDpRra6ALe2HsO8bHuDOw6FlEbG068Ht6e5O+4lTsnExNqxLgeDl8Ltx B7+xh36epYrdmwYe6la/Bju7d+d4NykNaJ90a+sRAI/oOpM6xCHBGdv70WR9IgogCTX0A9FQuhM L3HYJJt1zaSa3I9OF9Co6xNq4tp4eG/wjnRCUxDfa/Fl+jwBvWIB0V/FC2HfFMriLqu7EPrPIiL UtTydo41ZNu1JM1KbO+F3d03+JNYbLoeYAFDlxicxjxaq317fa9GJFTl6ZBllX2o1524Ddvw13E Y6yHrjjDN6SCiXs4 X-Google-Smtp-Source: AGHT+IHe873lwgBSOx12roMFUoX/pWu+ybMJMlclWGzsLsm+W6rPbHJG1LVgiHlxQhQxStQL04VdHw== X-Received: by 2002:a05:600c:3494:b0:434:a315:19c with SMTP id 5b1f17b1804b1-438dc3a85b3mr20395585e9.3.1738148480162; Wed, 29 Jan 2025 03:01:20 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176434sm16947113f8f.13.2025.01.29.03.01.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 03:01:18 -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 13/13] drm/vkms: Allow to attach connectors and encoders Date: Wed, 29 Jan 2025 12:00:59 +0100 Message-ID: <20250129110059.12199-14-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250129110059.12199-1-jose.exposito89@gmail.com> References: <20250129110059.12199-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. Signed-off-by: Louis Chauvet Signed-off-by: José Expósito Signed-off-by: Louis Chauvet Signed-off-by: José Expósito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 62 +++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 69 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 33 +++++++++ drivers/gpu/drm/vkms/vkms_output.c | 57 +++++++++++---- 4 files changed, 209 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 40c385eedc1d..d89acdc1a752 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -688,6 +688,67 @@ 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 **array; + size_t length; + int err; + + config = vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + connector_cfg1 = vkms_config_add_connector(config); + connector_cfg2 = vkms_config_add_connector(config); + encoder_cfg1 = vkms_config_add_encoder(config); + encoder_cfg2 = vkms_config_add_encoder(config); + + /* No possible encoders */ + array = vkms_config_connector_get_possible_encoders(connector_cfg1, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + array = vkms_config_connector_get_possible_encoders(connector_cfg2, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + /* 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); + + array = vkms_config_connector_get_possible_encoders(connector_cfg1, &length); + KUNIT_ASSERT_EQ(test, length, 2); + KUNIT_ASSERT_PTR_EQ(test, array[0], encoder_cfg1); + KUNIT_ASSERT_PTR_EQ(test, array[1], encoder_cfg2); + kfree(array); + + array = vkms_config_connector_get_possible_encoders(connector_cfg2, &length); + KUNIT_ASSERT_EQ(test, length, 0); + KUNIT_ASSERT_NULL(test, array); + + /* Connector 1 attached to encoder 1 and connector 2 to encoder 2 */ + vkms_config_connector_detach_encoder(connector_cfg1, encoder_cfg2); + + array = vkms_config_connector_get_possible_encoders(connector_cfg1, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], encoder_cfg1); + kfree(array); + + err = vkms_config_connector_attach_encoder(connector_cfg2, encoder_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + array = vkms_config_connector_get_possible_encoders(connector_cfg2, &length); + KUNIT_ASSERT_EQ(test, length, 1); + KUNIT_ASSERT_PTR_EQ(test, array[0], encoder_cfg2); + kfree(array); + + 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, @@ -706,6 +767,7 @@ static struct kunit_case vkms_config_test_cases[] = { 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 e94e48fe3ad9..db6e3c71fd68 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -94,6 +94,9 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, goto err_alloc; vkms_config_connector_set_enabled(connector_cfg, true); + if (vkms_config_connector_attach_encoder(connector_cfg, encoder_cfg)) + goto err_alloc; + return config; err_alloc: @@ -629,6 +632,11 @@ struct vkms_config_encoder *vkms_config_add_encoder(struct vkms_config *config) void vkms_config_destroy_encoder(struct vkms_config *config, struct vkms_config_encoder *encoder_cfg) { + struct vkms_config_connector *connector_cfg; + + list_for_each_entry(connector_cfg, &config->connectors, link) + vkms_config_connector_detach_encoder(connector_cfg, encoder_cfg); + xa_destroy(&encoder_cfg->possible_crtcs); list_del(&encoder_cfg->link); kfree(encoder_cfg); @@ -702,6 +710,7 @@ struct vkms_config_connector *vkms_config_add_connector(struct vkms_config *conf return ERR_PTR(-ENOMEM); vkms_config_connector_set_enabled(connector_cfg, false); + xa_init_flags(&connector_cfg->possible_encoders, XA_FLAGS_ALLOC); list_add_tail(&connector_cfg->link, &config->connectors); @@ -710,6 +719,66 @@ struct vkms_config_connector *vkms_config_add_connector(struct vkms_config *conf 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); } + +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; + + xa_for_each(&connector_cfg->possible_encoders, idx, possible_encoder) { + if (possible_encoder == encoder_cfg) + return -EINVAL; + } + + return xa_alloc(&connector_cfg->possible_encoders, &encoder_idx, + encoder_cfg, xa_limit_32b, GFP_KERNEL); +} + +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; + + xa_for_each(&connector_cfg->possible_encoders, idx, possible_encoder) { + if (possible_encoder == encoder_cfg) + xa_erase(&connector_cfg->possible_encoders, idx); + } +} + +struct vkms_config_encoder ** +vkms_config_connector_get_possible_encoders(struct vkms_config_connector *connector_cfg, + size_t *out_length) +{ + struct vkms_config_encoder **array; + struct vkms_config_encoder *possible_encoder; + unsigned long idx; + size_t length = 0; + int n = 0; + + xa_for_each(&connector_cfg->possible_encoders, idx, possible_encoder) + length++; + + if (length == 0) { + *out_length = length; + return NULL; + } + + array = kmalloc_array(length, sizeof(*array), GFP_KERNEL); + if (!array) + return ERR_PTR(-ENOMEM); + + xa_for_each(&connector_cfg->possible_encoders, idx, possible_encoder) { + array[n] = possible_encoder; + n++; + } + + *out_length = length; + return array; +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index cc32aadfda8d..24052de05e98 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -94,6 +94,7 @@ struct vkms_config_encoder { * @enabled: Connector are a different from planes, CRTCs and encoders because * they can be added and removed once the device is created. * This flag represents if they are part of the device or not. + * @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 @@ -103,6 +104,7 @@ struct vkms_config_connector { struct list_head link; bool enabled; + struct xarray possible_encoders; /* Internal usage */ struct vkms_connector *connector; @@ -443,4 +445,35 @@ vkms_config_connector_set_enabled(struct vkms_config_connector *connector_cfg, connector_cfg->enabled = enabled; } +/** + * 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); + +/** + * vkms_config_connector_get_possible_encoders() - Return the array of possible + * encoders + * @connector_cfg: Connector to get the possible encoders from + * @out_length: Length of the returned array + * + * Returns: + * A list of pointers to the configurations. On success, the caller is + * responsible to free the returned array, but not its contents. On error, + * it returns an error and @out_length is invalid. + */ +struct vkms_config_encoder ** +vkms_config_connector_get_possible_encoders(struct vkms_config_connector *connector_cfg, + size_t *out_length); + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 9c3e00817add..20ee8fdfa6f8 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -8,13 +8,14 @@ int vkms_output_init(struct vkms_device *vkmsdev) { struct drm_device *dev = &vkmsdev->drm; - struct vkms_connector *connector; struct vkms_config_plane **plane_cfgs = NULL; size_t n_planes; struct vkms_config_crtc **crtc_cfgs = NULL; size_t n_crtcs; struct vkms_config_encoder **encoder_cfgs = NULL; size_t n_encoders; + struct vkms_config_connector **connector_cfgs = NULL; + size_t n_connectors; int ret = 0; int writeback; unsigned int n, i; @@ -35,6 +36,13 @@ int vkms_output_init(struct vkms_device *vkmsdev) goto err_free; } + connector_cfgs = vkms_config_get_connectors(vkmsdev->config, + &n_connectors); + if (IS_ERR(connector_cfgs)) { + ret = PTR_ERR(connector_cfgs); + goto err_free; + } + for (n = 0; n < n_planes; n++) { struct vkms_config_plane *plane_cfg; enum drm_plane_type type; @@ -136,18 +144,42 @@ int vkms_output_init(struct vkms_device *vkmsdev) kfree(possible_crtcs); } - connector = vkms_connector_init(vkmsdev); - if (IS_ERR(connector)) { - DRM_ERROR("Failed to init connector\n"); - ret = PTR_ERR(connector); - goto err_free; - } + for (n = 0; n < n_connectors; n++) { + struct vkms_config_connector *connector_cfg; + struct vkms_config_encoder **possible_encoders; + size_t n_possible_encoders; - /* Attach the encoder and the connector */ - ret = drm_connector_attach_encoder(&connector->base, encoder_cfgs[0]->encoder); - if (ret) { - DRM_ERROR("Failed to attach connector to encoder\n"); - goto err_free; + connector_cfg = connector_cfgs[n]; + + connector_cfg->connector = vkms_connector_init(vkmsdev); + if (IS_ERR(connector_cfg->connector)) { + DRM_ERROR("Failed to init connector\n"); + ret = PTR_ERR(connector_cfg->connector); + goto err_free; + } + + possible_encoders = + vkms_config_connector_get_possible_encoders(connector_cfg, + &n_possible_encoders); + if (IS_ERR(possible_encoders)) { + ret = PTR_ERR(possible_encoders); + goto err_free; + } + + for (i = 0; i < n_possible_encoders; i++) { + struct vkms_config_encoder *possible_encoder; + + possible_encoder = possible_encoders[i]; + ret = drm_connector_attach_encoder(&connector_cfg->connector->base, + possible_encoder->encoder); + if (ret) { + DRM_ERROR("Failed to attach connector to encoder\n"); + kfree(possible_encoders); + goto err_free; + } + } + + kfree(possible_encoders); } drm_mode_config_reset(dev); @@ -156,6 +188,7 @@ int vkms_output_init(struct vkms_device *vkmsdev) kfree(plane_cfgs); kfree(crtc_cfgs); kfree(encoder_cfgs); + kfree(connector_cfgs); return ret; }