From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 40F0A1E5B87 for ; Tue, 11 Feb 2025 11:09:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272161; cv=none; b=a+XT8wvznvyR0nQ2iNedvDI6ppsdYAFqosFIhBEQsbuYCXfjUR1mDeMkXArYkm6qikeiHjbBcz/0/xWc9z6aAVbaogaB57cqpA98f8bv5ZtZHN668ITlc72L7Q3Zhuox1fnPqqkmkQH4XltEU17AIvNYaG70NE/L07LNbDfZW9I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272161; c=relaxed/simple; bh=wfSWd7+rjeEbpIBLGRKWCodTxKEd6xdW/hr9jo+ucfc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gNu9/CMZJenp3qveJOeNEIPSfEh/s/5G2WIQuBMWmJI9nHlV03sUPWFJqhfugkK+KYfiY6L+DoLXJ5DLl6bxtFTcBxB9vvHYgXhmznHS1eXByWNy2v/lqmPWZxpzkVpOzxzFrif8uALGCpBPCpO1gJ/09TcBMkjqp+WWlaXb/IE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=cH6vmdQF; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="cH6vmdQF" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-43948f77f1aso10724705e9.0 for ; Tue, 11 Feb 2025 03:09:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272157; x=1739876957; darn=vger.kernel.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=wqPjNzN3hIOUqf1ihOkU/QGEBU1cO5gaJEuNeFStEvY=; b=cH6vmdQF986nUuP68S55YIcy0rWWBU/kp4Luqg1cJMLe8gMk2Jhjw8jTUbvtmX8Lzz zC5ClOmYJLzDNrMx0G2IFOmqOxkzWf5IBeZ0Fp3pe5pjpMVKR+1tksw1mIl1QRc8hyo2 0tUIVqOMUEVqkSy03l5HGnkVNV5Z26iDNitsDJ3Z5cfYVTwrfo3lLgS+oarAmcdlvCa4 BULgAFwmLV+0+VCUmsijEYU1jcjbvz9IwfUOdJRduwiCFWmI3SMhIbfXgcKjrScASIE/ Mkjdt3xUB7D5q6NSLosArAWejo2vceKtRHBGg7cpeIbTvP7KAAQvpebzUzFtb8pi5YF7 X+/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272157; x=1739876957; 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=wqPjNzN3hIOUqf1ihOkU/QGEBU1cO5gaJEuNeFStEvY=; b=qiniO2wC5fDL5muRktMCBlR3YJGe884+xNczMzzUhcc6Z3VR9MtQBfDpEvVHmlemJ9 vlwf9EkYCP1SeUpRZie7x7VHN8bdvhkwjqhG0TiL7TkYaX9LSJPWvE71W+ad7l47QoTL RsFWz4rJatOR4ABbDZx/j4hy64Jz36WNs4nsoa+c4m46iN9BUAhs2KmRRQ19dMKwr2T6 UU2IiNUDsg7yVtf8BwARpDth4BgPWX0CYgjY3k6sViK6J36Wh8TnCivBEW2bYvRHuiQO VD29iAx6I6S0O8ECULO8Bw5mNBarj06+xsR30nJOPVQ3TQnQ38OEUQif8axEANiKrXjL QA3A== X-Forwarded-Encrypted: i=1; AJvYcCXfLoJRiaf1uSFY2G8xsxBwrastOUSrvKs9JbPCSD23q8oAF1rwVa8PwTLyOGJzqcN3P2ZnqAmG91nRR1E=@vger.kernel.org X-Gm-Message-State: AOJu0YzDOtz+el+X0VRLyhEEn1pCYLH23Xkp2PUHsqMtKEZWFpHlxPSS EwuZIQZq1kK0JrBILEL0O31wcshr0LIDDfY0xLSTpRdo/4fEH/TU X-Gm-Gg: ASbGncvYnCDSvSWYr3eypb1K6dorxGQ+QHJtQs02oILBRiolupaES2uF9R3vxg4GJMb xK6sbm7WzOJBVuMUJRvYUNafhq7y2ft2CAQt6zdzxIjuUm76iu8F2CHNCwHariNEFyQ3CCsxarQ Fbephx9WLxM77LK6A3Ik0Nnm8M5EreowXfcrbTDyBcdEevOEvgMehxA58/weTo9WdXMZPCqhjxE 1qgeLTdIsg8fb5A2L2QHL8Dvug1JKrb/t5ocoJ20nPFyI7RSvSdPdGjSjtSx4HB099PG+NNFMfK Zkem+JEqqPKWqr9l X-Google-Smtp-Source: AGHT+IFlaMdG5xYT8daUity03Cn/YyaHakX4RFbJ81EYHMnPhENehZWM/3i2t+R5N2A4WjM1CP0j9w== X-Received: by 2002:a05:600c:3c8f:b0:439:3e90:c535 with SMTP id 5b1f17b1804b1-4393e90c71cmr91082515e9.0.1739272157348; Tue, 11 Feb 2025 03:09:17 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:16 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 01/15] drm/vkms: Fix use after free and double free on init error Date: Tue, 11 Feb 2025 12:08:58 +0100 Message-ID: <20250211110912.15409-2-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable If the driver initialization fails, the vkms_exit() function might access an uninitialized or freed default_config pointer and it might double free it. Fix both possible errors by initializing default_config only when the driver initialization succeeded. Reported-by: Louis Chauvet Link: https://lore.kernel.org/all/Z5uDHcCmAwiTsGte@louis-chauvet-laptop/ Fixes: 2df7af93fdad ("drm/vkms: Add vkms_config type") Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- drivers/gpu/drm/vkms/vkms_drv.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_dr= v.c index 7c142bfc3bd9..b6de91134a22 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -235,17 +235,19 @@ static int __init vkms_init(void) if (!config) return -ENOMEM; =20 - default_config =3D config; - config->cursor =3D enable_cursor; config->writeback =3D enable_writeback; config->overlay =3D enable_overlay; =20 ret =3D vkms_create(config); - if (ret) + if (ret) { kfree(config); + return ret; + } =20 - return ret; + default_config =3D config; + + return 0; } =20 static void vkms_destroy(struct vkms_config *config) @@ -269,9 +271,10 @@ static void vkms_destroy(struct vkms_config *config) =20 static void __exit vkms_exit(void) { - if (default_config->dev) - vkms_destroy(default_config); + if (!default_config) + return; =20 + vkms_destroy(default_config); kfree(default_config); } =20 --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wr1-f52.google.com (mail-wr1-f52.google.com [209.85.221.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BCB9B1F4E5F for ; Tue, 11 Feb 2025 11:09:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272162; cv=none; b=MuyPSTkbN4lGfS4Yqp83wOjSWfU9SAbfNz+4Qt7J482GosHH2lcWsdYCB1FB8h9mDaY+7cULRhp3lLyRQMledXfOv94g80lzF1gOEj5ICsOgWpeCg744JCTuf8zyPEbgPVKCWuXkNNW8BH7RFDn/8Y5SiOiceQAj9O/4ccuOKII= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272162; c=relaxed/simple; bh=sC9Zaw3ndAVo+oHrEyc64S6eUMv2Ld/tFQLViNUAGL8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=oJW29kb3CQmyLL1eQKtCRl/0BnP3eVqFuo8xwFcbKdj6dM6L67QQ4FzoiPOYtz991svkE5GNFvxWFOdglAOkxVugShVdAA5BHOMDTNa9NMmDOkQoFV9POmaazkwI4Iot6OFZ9037JH/Zle6s2MleJPKALVCdNVUYZk/vxNAm2II= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Qw6tihCX; arc=none smtp.client-ip=209.85.221.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Qw6tihCX" Received: by mail-wr1-f52.google.com with SMTP id ffacd0b85a97d-38dc8b5bb0bso2385137f8f.1 for ; Tue, 11 Feb 2025 03:09:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272159; x=1739876959; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=T6WlJ6G+D4bbUKndbktll+9YSW21OZOtswUdeB6r15c=; b=Qw6tihCXf87Tm1a9UDZJBwTZuscdFkKscpZ1fJ6UdzTHizq4jyDDffsIxcrz9cCLgk RXIH2+tN0S+S4O+ivA0gW57/SMnYPrNb6ui8xfcDFIZ5xkR+oKPXRojEdBu+QGy05/YH bSb199CLrQZN/2VOvcCn5kCdWDIUbBroWCpPivwIdk5p34fojs+9BqAsmyxZJG6OyAz5 NlYxzV0K8RGiPe8DsbXp+rcJEgDYd9YiqWrbC2Db287sP8nmF+kqGkD3JTyOOK8oYIre qMKFZ8NOgr0IZu1PZPhyP69elTZ2U0Y1gbgXQW073JymFrpGKg5IwthqonsJRvC2X0Tr Uk7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272159; x=1739876959; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=T6WlJ6G+D4bbUKndbktll+9YSW21OZOtswUdeB6r15c=; b=plfK6U/EqAJYwAxH10T/NHFW+RhcmLPZ2V41tpfOAw8BEFd+izpF1Gzcx+2gdh+B2K QSb60nf6p2I8ryYj9fGalUGuHeKwtDOCmb8CqKHLjO5ljnmDJRPKrANWibSRH7lVnA1z q6bUwMkpPeQ3yErjJeL72+n5vmkwcZ2CNGk+dubDee0XsiweEizl/Lpzex6D/dwSUykZ UVSE88KDXf8BfDlGbSAUhPVdqBG9aeRxFld6HkQbE42IrKDGEZqutcW594yG0yxidQRY 1m82a2nQhTABd/yx/8wCSElzo/fcgnd2U4zatFUsAOC3aoGpZDNJ8KgLLRnVaevi+RRW +suQ== X-Forwarded-Encrypted: i=1; AJvYcCWGgICdowB50AFSSuboDEPpltNunb8w44BBMB3aHYgN6OyqixVel3Z38k0AvaIMBVTMZV29+9G760cvAS8=@vger.kernel.org X-Gm-Message-State: AOJu0YynYuXThlaZpuHORgroz85BH/v6bOzm0fsNrganyZZMso3bgPB1 H6abVKng6kyO7hzbYZAIAWLoHszT4jRr1Q80oo2W4gLiKXKvpP87N1ivbC2F X-Gm-Gg: ASbGncvsmJ/VKybLw3jtxVjaP4PtuvfgJzQyL+v8RmtzPRjGC0Ewexn5GbSSw2keL+v mjLPm0BKlbYELV9Si1YGftrAfZWvKOC7Cw8DOAsUte+2Bba0A5zDwn6vl9WakVtmBsT40yv1MgV IyFSgUA/juwuHTg7c7Y9aa7Vh5GsNkXrIwTYMgQ5D6JkJj8QsOuGDqUC27/sP9dh0dCLy1BS/u5 I11drlEXTiu4sVjl+2L7p+66NsM7/E9bXjdhHoG2X9XSOcN7JvCplWzos/3EspYbrqfnU+HO7wt 2aSB6ttxWifcdNNB X-Google-Smtp-Source: AGHT+IEoxT9zQQpAm3Z/MPqIxGWp+fHukRONORU7zSofoG0svTWCzkqt1BkJE0/BpfPtnxCdMX09dg== X-Received: by 2002:a05:6000:1448:b0:38a:88bc:aea4 with SMTP id ffacd0b85a97d-38dc9233a6dmr12788413f8f.30.1739272158878; Tue, 11 Feb 2025 03:09:18 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:17 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 02/15] drm/vkms: Extract vkms_connector header Date: Tue, 11 Feb 2025 12:08:59 +0100 Message-ID: <20250211110912.15409-3-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Up until now, the logic to manage connectors was in vkms_output.c. Since more options will be added to connectors in the future, extract the code to its own file. Refactor, no functional changes. Reviewed-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- drivers/gpu/drm/vkms/Makefile | 3 +- drivers/gpu/drm/vkms/vkms_connector.c | 50 +++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_connector.h | 17 +++++++++ drivers/gpu/drm/vkms/vkms_output.c | 41 +++------------------- 4 files changed, 73 insertions(+), 38 deletions(-) create mode 100644 drivers/gpu/drm/vkms/vkms_connector.c create mode 100644 drivers/gpu/drm/vkms/vkms_connector.h diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index 1b28a6a32948..6b0615c424f2 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -6,6 +6,7 @@ vkms-y :=3D \ vkms_formats.o \ vkms_crtc.o \ vkms_composer.o \ - vkms_writeback.o + vkms_writeback.o \ + vkms_connector.o =20 obj-$(CONFIG_DRM_VKMS) +=3D vkms.o diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/v= kms_connector.c new file mode 100644 index 000000000000..fc97f265dea6 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_connector.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include + +#include "vkms_connector.h" + +static const struct drm_connector_funcs vkms_connector_funcs =3D { + .fill_modes =3D drm_helper_probe_single_connector_modes, + .reset =3D drm_atomic_helper_connector_reset, + .atomic_duplicate_state =3D drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state =3D 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 =3D 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 =3D { + .get_modes =3D vkms_conn_get_modes, +}; + +struct drm_connector *vkms_connector_init(struct vkms_device *vkmsdev) +{ + struct drm_device *dev =3D &vkmsdev->drm; + struct drm_connector *connector; + int ret; + + connector =3D drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL); + if (!connector) + return ERR_PTR(-ENOMEM); + + ret =3D drmm_connector_init(dev, connector, &vkms_connector_funcs, + DRM_MODE_CONNECTOR_VIRTUAL, NULL); + if (ret) + return ERR_PTR(ret); + + drm_connector_helper_add(connector, &vkms_conn_helper_funcs); + + return connector; +} diff --git a/drivers/gpu/drm/vkms/vkms_connector.h b/drivers/gpu/drm/vkms/v= kms_connector.h new file mode 100644 index 000000000000..beb5ebe09155 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_connector.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _VKMS_CONNECTOR_H_ +#define _VKMS_CONNECTOR_H_ + +#include "vkms_drv.h" + +/** + * vkms_connector_init() - Initialize a connector + * @vkmsdev: VKMS device containing the connector + * + * Returns: + * The connector or an error on failure. + */ +struct drm_connector *vkms_connector_init(struct vkms_device *vkmsdev); + +#endif /* _VKMS_CONNECTOR_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms= _output.c index 22f0d678af3a..b01c3e9289d0 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -1,32 +1,8 @@ // SPDX-License-Identifier: GPL-2.0+ =20 +#include "vkms_connector.h" #include "vkms_drv.h" -#include -#include #include -#include - -static const struct drm_connector_funcs vkms_connector_funcs =3D { - .fill_modes =3D drm_helper_probe_single_connector_modes, - .reset =3D drm_atomic_helper_connector_reset, - .atomic_duplicate_state =3D drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state =3D 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 =3D 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 =3D { - .get_modes =3D vkms_conn_get_modes, -}; =20 int vkms_output_init(struct vkms_device *vkmsdev) { @@ -73,21 +49,12 @@ int vkms_output_init(struct vkms_device *vkmsdev) } } =20 - connector =3D drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL); - if (!connector) { - DRM_ERROR("Failed to allocate connector\n"); - return -ENOMEM; - } - - ret =3D drmm_connector_init(dev, connector, &vkms_connector_funcs, - DRM_MODE_CONNECTOR_VIRTUAL, NULL); - if (ret) { + connector =3D vkms_connector_init(vkmsdev); + if (IS_ERR(connector)) { DRM_ERROR("Failed to init connector\n"); - return ret; + return PTR_ERR(connector); } =20 - drm_connector_helper_add(connector, &vkms_conn_helper_funcs); - encoder =3D drmm_kzalloc(dev, sizeof(*encoder), GFP_KERNEL); if (!encoder) { DRM_ERROR("Failed to allocate encoder\n"); --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 41FAA1F8BCB for ; Tue, 11 Feb 2025 11:09:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272164; cv=none; b=YjT8LWXtKN2/HqGmpzVXzBYtB3ucngj2oD7io+GSKHE/8vH5IHribJoPOr89ghEYNwoRkJiO3axwCXZywDr/o/NdUFn8uXEr/ZmaY1yStL4HBIqPToyb9aOtpmw+hXtXPg72bdsj0wjFXVolqCXP7FJhXV4jSZzElVZVrIku+do= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272164; c=relaxed/simple; bh=NqKUzI9Kmgs9z+WBxXu0/bcQz0rhTTeF+BXogLGULSU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZmncedR01Opsp5R/ViboXBOXGw2ros3Qwxnb5TqQLoieT4vdy0dTM97mXz7elBeNBAdvoA4GzMuQytzr7fYhDjsjbbi8j+6voi8cfKDoofdYHB7IhCbpfARlLWMWu0r4yYDcOEVS5g8LGgVV4MYlbMlB8xXcIy+KITcU15fEsDM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=J4ZiRKW2; arc=none smtp.client-ip=209.85.221.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="J4ZiRKW2" Received: by mail-wr1-f43.google.com with SMTP id ffacd0b85a97d-38dd0dc21b2so2055574f8f.2 for ; Tue, 11 Feb 2025 03:09:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272160; x=1739876960; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=prbaD9EEGSsUeJKiTeBVWVOJfwbyTxNyFRLpyPWOntc=; b=J4ZiRKW2YBoCGRBfXhO1jO6fMblrCu+p9xfZFSfU2ePUFwoah23joIx5ogqgHgapvO YJL84D7Ru+MTlVf9y2rEZ6APwVQ2BiVxStHnJEDIUY2S0sJzRMqgtBRQcvoRYLDTjLHx wD5elIc6aIh7VshpIEmnvr/pVVeP2NwokuV5ypNRv6IJGd473Pwm7xb8K19XLqFep4JY /hwHH6c75vwyQhTtrrz+ZvpHhDXL+Ejfee7vhwR9u+vqCqOeUAkp+cGUpoa0HEiXyTXe 8nyTqRgLFPz9Kta0zqWcq22MO75+hcKllGo52gRKbHGJdekUNYTKtB3teM4RUr7IpZEf YRjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272160; x=1739876960; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=prbaD9EEGSsUeJKiTeBVWVOJfwbyTxNyFRLpyPWOntc=; b=ZkQffJIBTFlERPWWYf9KyopnVCrcTJeyG3Fctqhw1Vk1hajnPYAnnmKnjfMn01z2Q/ VMmWsssi9BJG/JNtVhdQMzjcpfnhtyjyVgmyqmbIlaIDgnBLo56KfC7LBVCukrYgi8ql n6y5jX4DOIb92siGUAHv8RL3TjphdPLjLaS6gyV/zUvc+MNr3nxRghYK1Jm2NrUooAIf Kc0jrXwqo48vDafp9MbDaDIP4NQo6z7PLa97cDjJsCDOzdupJNX4pX8g5/LEKays9/QP MNuLDtn0QY25/tBv3hjJ6884g+D9QzIg9ip3GaGVyfzBbYKb6eYxgKsuIAzokCaMbTEt nLmw== X-Forwarded-Encrypted: i=1; AJvYcCViGeBWLXi/rMyB3I2UJiKpSq4jnJFGdvi/ZPymjnB//byzr94YJzsRXTzjtk62a9O7BBF/cVPrmO1bgy0=@vger.kernel.org X-Gm-Message-State: AOJu0Yy8dabhjpKX/YOFGykOqLkVMImaRFkMRFRUZdXFcI3gPZdaOPIT H+1fw5k3oIbTnuPcC1J4yVD+zsJeEaSA0Iqf/0s9WGnR9K5wRIVhSuUstMB5 X-Gm-Gg: ASbGncu7Au6APoj+BBnzR0PTGEjp1rP6DcikciLYDny+GGninmSbFGixzBJ/iwPQCEd oTvTnkypLMHmzMJ1WBFPYCK4NnuyV2OuuRl2U63kvhgHSJvD3NRB7iGhzQjlIcDsIorI/15lBmD NsmpeeB6ri/K5gAXq0S9NOdXCMkTUj3mEtwgAj/7mI7b46plfMIH/p6UKr6l+zIOy1IFFykaC0J 3PPFtsFMaeTRHRGCDbqjYe/pkcpQdn3U86WmomoVkAxjjp9tBx4AjfcwE9K8qG5r22rGZ3ATBWb d8BqmSq0GACQK23Z X-Google-Smtp-Source: AGHT+IEisoGk6NyTYRg9Nzt3NhsjvTdsTtmM67osH1eZt5tSPgY4xDQE9dG1ITKt+LUP+bKxOTSPXQ== X-Received: by 2002:a5d:6d04:0:b0:38d:e401:fd61 with SMTP id ffacd0b85a97d-38de401feb4mr3038917f8f.49.1739272160471; Tue, 11 Feb 2025 03:09:20 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:19 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 03/15] drm/vkms: Create vkms_connector struct Date: Tue, 11 Feb 2025 12:09:00 +0100 Message-ID: <20250211110912.15409-4-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Create a structure wrapping the drm_connector. Reviewed-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- drivers/gpu/drm/vkms/vkms_connector.c | 8 ++++---- drivers/gpu/drm/vkms/vkms_connector.h | 11 ++++++++++- drivers/gpu/drm/vkms/vkms_output.c | 4 ++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/v= kms_connector.c index fc97f265dea6..ab8b52a84151 100644 --- a/drivers/gpu/drm/vkms/vkms_connector.c +++ b/drivers/gpu/drm/vkms/vkms_connector.c @@ -29,22 +29,22 @@ static const struct drm_connector_helper_funcs vkms_con= n_helper_funcs =3D { .get_modes =3D vkms_conn_get_modes, }; =20 -struct drm_connector *vkms_connector_init(struct vkms_device *vkmsdev) +struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev) { struct drm_device *dev =3D &vkmsdev->drm; - struct drm_connector *connector; + struct vkms_connector *connector; int ret; =20 connector =3D drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL); if (!connector) return ERR_PTR(-ENOMEM); =20 - ret =3D drmm_connector_init(dev, connector, &vkms_connector_funcs, + ret =3D drmm_connector_init(dev, &connector->base, &vkms_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL, NULL); if (ret) return ERR_PTR(ret); =20 - drm_connector_helper_add(connector, &vkms_conn_helper_funcs); + drm_connector_helper_add(&connector->base, &vkms_conn_helper_funcs); =20 return connector; } diff --git a/drivers/gpu/drm/vkms/vkms_connector.h b/drivers/gpu/drm/vkms/v= kms_connector.h index beb5ebe09155..c9149c1b7af0 100644 --- a/drivers/gpu/drm/vkms/vkms_connector.h +++ b/drivers/gpu/drm/vkms/vkms_connector.h @@ -5,6 +5,15 @@ =20 #include "vkms_drv.h" =20 +/** + * struct vkms_connector - VKMS custom type wrapping around the DRM connec= tor + * + * @drm: Base DRM connector + */ +struct vkms_connector { + struct drm_connector base; +}; + /** * vkms_connector_init() - Initialize a connector * @vkmsdev: VKMS device containing the connector @@ -12,6 +21,6 @@ * Returns: * The connector or an error on failure. */ -struct drm_connector *vkms_connector_init(struct vkms_device *vkmsdev); +struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev); =20 #endif /* _VKMS_CONNECTOR_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms= _output.c index b01c3e9289d0..4b5abe159add 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -7,7 +7,7 @@ int vkms_output_init(struct vkms_device *vkmsdev) { struct drm_device *dev =3D &vkmsdev->drm; - struct drm_connector *connector; + struct vkms_connector *connector; struct drm_encoder *encoder; struct vkms_output *output; struct vkms_plane *primary, *overlay, *cursor =3D NULL; @@ -69,7 +69,7 @@ int vkms_output_init(struct vkms_device *vkmsdev) encoder->possible_crtcs =3D drm_crtc_mask(&output->crtc); =20 /* Attach the encoder and the connector */ - ret =3D drm_connector_attach_encoder(connector, encoder); + ret =3D drm_connector_attach_encoder(&connector->base, encoder); if (ret) { DRM_ERROR("Failed to attach connector to encoder\n"); return ret; --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4DE41FA164 for ; Tue, 11 Feb 2025 11:09:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272165; cv=none; b=Sfzmiapy/S3W6gdRIv1eOU7hwsMvDwi3pNx++oJa06V32wQl/ijU3uwcs2kakCx4G1bqB2NstkrfTCFFFvNPU0zuCGwm7vb03ZVGl3cABGPr6LdcZE2pzxnzAV0Bb0yOugWQ8l/sKPNzbwJMDLaqvKpmK6StKe55jiD+lPf50Q8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272165; c=relaxed/simple; bh=1cgEehn7yaWYfdZlUoyVzhMQP1yObaWyvnl9hlUMx3Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CoY/fsAQLtEVVgPIca1FypVOUs845paOMbaq2gOKjloqz3TrGW5CpZTj0jJEKmIP/wUcTLGsY9UPTJD6cAPiKTAqGW+VdSrJUXnbbgao78BDvzpaxzBBXrV/Bu1CRhKHDYkqdt3gfTl8H/YuXJpavD1fGsu/iyh4wBD18eIpSWI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=nGUul6jj; arc=none smtp.client-ip=209.85.128.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nGUul6jj" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-43618283dedso54115055e9.3 for ; Tue, 11 Feb 2025 03:09:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272162; x=1739876962; darn=vger.kernel.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=W0Gp3OVIpEw4+ISZmLwuTXl1/B9vTRIzRehit5QWGf8=; b=nGUul6jjD9/Br3D7USn3ZbPDar9oZVe55Pm3cTrl/3ANB2ejAHpeEAg/jUGPeYIFyU SoM1uBMovWNnlfwmTll8LMVhfe8G8Qh7zVEPNHuIoHFc6jGjaFBh0c8m1FM2rWg2ZtvH OVCj9G3csnxl5GRKOvDAA1B/eZ9g85kZMFlbLngs75ktsYj/qZpfgdKH1G+YxM0v4ov4 Q2lSAoD0nLjzjpzg62Vx/3azPo2SJXQ7I+d8yKS8/vfE2K5/YrLjbjw8PBmTxIHGmK1L fM2R42tgtIOdJYmRfhdMcrUKK7GjkMa2WhBO6p1aCSg3oimehubXju62wY4GQynBDJO9 GcfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272162; x=1739876962; 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=W0Gp3OVIpEw4+ISZmLwuTXl1/B9vTRIzRehit5QWGf8=; b=j2GXHOQ/KRO2JS6kHfhagpkYFVwxtBLNMC//MZDAUgIJc8g/2JZ4+YIEQi1LLJ5agA qZ8N6Q3TlyHFuyMWx7zqJ3akOjd2kkzdb1CLQ8qwZH5EQ//F+Guhbg5vPtAbyFW+xgVr LQszCVi551FxHZ0riG4BC72ViJ9KAzgVDh0i86uvMfdtBPSDyIP4+BFYOgh6wCMGAee9 0KVFBk+t3OH61HtGdP5jnsRwktN/SIlb+RvRWdt8/+7P9kqPgfF0NTYb4Tj25geOclrn MeCH7yYXPCtBChgitqwjoamtSzL/z+01Os8mzHbu860h1tEjw9SqcRhL9z/WYQd8Z0uq yQkw== X-Forwarded-Encrypted: i=1; AJvYcCXuc6+x6YDXLsdaHbvmhv8FaL0IBktm7mAaU9V0ON7DUVFJmDmBnRTWcp5gNNgsVKfCQtTKir7qf3YQsao=@vger.kernel.org X-Gm-Message-State: AOJu0YzqcEEJvkWXCaOG6dO5tP8LKJSqe0RvrNosCGv4v4QtxJKuCGBE Ge4Yo0PSMszxWxus5wB8Vj8rlmXHjHX4tCDNnDY21RpbXasTY+C/ X-Gm-Gg: ASbGncs5h5SdS0HJkm3z7hP/fJAZsa4afEm5x3TUpsEG+bCdXdp36dzyWS7xuvK4WdN C0BqVFF0Q5XjQnF8x3pLN4VT2mpCRIiqdPb4fORj5L5syIuzajn4B8FRLjabbTSMu18qNnS3hyU 6uMiNbTQwp/u6wxOAGgB3yiKMXq4R1p2nvy645sp4WSoMCvjmuP4nlgBr4kmaG3tf74lL6EJ+n9 n6uLRqvaRYT78BJm07ssx3+Vbp0ddE1V12Ba8/VqofwZztfUgTqH2mSj3FCQpy7unefYLq4zxaV 9RDgwagEhy15NmfR X-Google-Smtp-Source: AGHT+IHxO8sxD6ByWF8Vz/3btBqccYzxj5h/r13NKofQMWlSJ2LWLuz7YcIp8j0DEqyrs5/QM0e0gg== X-Received: by 2002:a05:6000:1f89:b0:38c:5c9a:eaca with SMTP id ffacd0b85a97d-38dc8d9b8ffmr14516579f8f.3.1739272161939; Tue, 11 Feb 2025 03:09:21 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:21 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= , Arthur Grillo Subject: [PATCH v2 04/15] drm/vkms: Add KUnit test scaffolding Date: Tue, 11 Feb 2025 12:09:01 +0100 Message-ID: <20250211110912.15409-5-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add the required boilerplate to start creating KUnit test. To run the tests: $ ./tools/testing/kunit/kunit.py run \ --kunitconfig=3Ddrivers/gpu/drm/vkms/tests Co-developed-by: Arthur Grillo Signed-off-by: Arthur Grillo Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito 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 | 19 +++++++++++++++++++ 5 files changed, 42 insertions(+) create mode 100644 drivers/gpu/drm/vkms/tests/.kunitconfig create mode 100644 drivers/gpu/drm/vkms/tests/Makefile create mode 100644 drivers/gpu/drm/vkms/tests/vkms_config_test.c diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig index 9def079f685b..d4665e913de7 100644 --- a/drivers/gpu/drm/vkms/Kconfig +++ b/drivers/gpu/drm/vkms/Kconfig @@ -14,3 +14,18 @@ config DRM_VKMS a VKMS. =20 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 :=3D \ vkms_connector.o =20 obj-$(CONFIG_DRM_VKMS) +=3D vkms.o +obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) +=3D 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=3Dy +CONFIG_DRM=3Dy +CONFIG_DRM_VKMS=3Dy +CONFIG_DRM_VKMS_KUNIT_TESTS=3Dy diff --git a/drivers/gpu/drm/vkms/tests/Makefile b/drivers/gpu/drm/vkms/tes= ts/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) +=3D vkms_config_test.o diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c new file mode 100644 index 000000000000..1177e62e19cb --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include + +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); + +static struct kunit_case vkms_config_test_cases[] =3D { + {} +}; + +static struct kunit_suite vkms_config_test_suite =3D { + .name =3D "vkms-config", + .test_cases =3D vkms_config_test_cases, +}; + +kunit_test_suite(vkms_config_test_suite); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Kunit test for vkms config utility"); --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7467A1FAC49 for ; Tue, 11 Feb 2025 11:09:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272167; cv=none; b=PgoR7MpWfbr5KmLakWu0Fb54UrPcSk/1vz1RK1EueuMW+g/+1FYGai2QnNSBnc30nC9EJX8ZifFCGxhwi5dw4BiGfxiGziDeAkfTl78beGTpnsAMTbjiR+FjM8BlehfRLKCSwFmOuomdn90M4GeCpkuMoy+Swhvv9sJMOA6Uqak= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272167; c=relaxed/simple; bh=YhwCZuO2MCiL2PquS+S4QqiD0mec7G+FOwsHL/tWxdY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lPyBtkRcv74A7zqm+pY2CsqUEf13xClneOwLyi4YWZc5wl/RJzQyoHR4/fBgtLaXwYc6XzmthPqW+rx7kJIQ8GTrr/VDMErMKDFA97M9VQGp/mRV24j/UG4oDBi5pXFd+pmuJPgkGUGciqD0Tx0RE7AIdm5klYC0Ohn191ZSKGU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lzrKtD/F; arc=none smtp.client-ip=209.85.221.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lzrKtD/F" Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-38dd93a4e8eso2092402f8f.1 for ; Tue, 11 Feb 2025 03:09:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272164; x=1739876964; darn=vger.kernel.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=w8lum8pBLYhiQh7v0U0rbZpEXVJRkT5bnyUgOR4qD6o=; b=lzrKtD/F69rhgDNq+s8oXX1HefdEV2BZjPM8F9Cq/u7Eq8grl3sztfjCj2TUK2EZqM ahvK7nTqwldHgxgeaMksvKNQ4NVV3MusmD+wIeMHWyTXWO6cQPoqVItxb1J1HyR7PEAy A04VlaB6lWVzWg5Bn9PV0+illkQHpKMwD8xBvFv3/XrDagVBnlxr3PuB4kWlhJ1U4lwe XmYS/qquKxfRePe7N19o7VEsQdvKo5oOMQQlnmJDxsywfKNjK9hG6J4kIW5uXYt4Gwf/ OBhZhjQo9T65SsC/xfbzuVqnFrbtEaC+omwohJX5uAkC9TQ/fQlRP7PQfp/fFGMu/b96 x/xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272164; x=1739876964; 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=w8lum8pBLYhiQh7v0U0rbZpEXVJRkT5bnyUgOR4qD6o=; b=FebCNacaXhmotlhZhu4DypI5ogXKec0g+VRjlXpJwQIXzFYYE/O7S6t0ECZQGaFMzi k6I105lIW2cjMa5LgpZZEhnxPWqOcjdqWX8yWjiKVSBH+TA2YoXXcOKgE8VOfHkesjNm wy9AcD1XEtrLyl6M2Fbz0hGc1kOMBH5cFXwc0ic5XPqcxM1UVs3PFGhUJvL2mcahZqQ8 tX0QIP0u/Gq1qf2+P0cYiGxTEpop1PZ2baALx4TcbaZw82g9n6Y4LyNNWa2DRSCgSDZs Apak03oMvv2YF/crX2BZS/NfDPNzUyrAmzkyJXwoAh8uTkNXtVvdcL660YORIes2nn8e 9mxw== X-Forwarded-Encrypted: i=1; AJvYcCWcxUPgLTiN6qC2ABYG8/NV+6/rk7jy8xXNs3CIt1VVb1tbsfzHHTzxSoKZgMR4YFxKRx3LB7Box/mCTCA=@vger.kernel.org X-Gm-Message-State: AOJu0Yz4KBGlqMgVG/P2jsWydVhC5cE8GV27pw+W+PfyVPOU3BVGJ4E2 JN1yf5LOWxH1kt59a3Sfgvhr0l0Sb74HdbQAbMeH81wvblv05FuJAHpHJJfg X-Gm-Gg: ASbGncuCYNx4qHIFdbLOAePwKqQ2teYT+hpRgxdxG2GuZ2izbyX5TACD6RrisuusfnL LNdilURORjBKmG3PrbuOsuSC046U9Nkd+GpwvLsDMt45UK9nTULd+49kdEH/fihMYzytmJlIT7o 2l18nLZ4xdibp2KKIyoKmucXX6KmwnZ0vMdzoOOUGd3GJr90nezjScjK7wGTsMMHNbe7s+vN89C JZgC+9gpiT6FHDQ3C4SH0Tze3NayFtIE85pPCoet5QipG/ml4WHyyWsQCEXRZmcxwCoeaMOy/w2 KdGTn7IPaLkCkvZY X-Google-Smtp-Source: AGHT+IEKnWUo5eUZtrzRBT+jHHy0k5gsRkTO/HlKIycGcSYkywT85kSZQR1n34vGrpV/GF0O9mtKGg== X-Received: by 2002:a5d:6d87:0:b0:38d:d93b:5899 with SMTP id ffacd0b85a97d-38dd93b5a82mr8411507f8f.21.1739272163582; Tue, 11 Feb 2025 03:09:23 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:22 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 05/15] drm/vkms: Extract vkms_config header Date: Tue, 11 Feb 2025 12:09:02 +0100 Message-ID: <20250211110912.15409-6-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito Reviewed-by: Louis Chauvet --- drivers/gpu/drm/vkms/Makefile | 3 +- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 13 +++++ 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, 118 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 :=3D \ vkms_crtc.o \ vkms_composer.o \ vkms_writeback.o \ - vkms_connector.o + vkms_connector.o \ + vkms_config.o =20 obj-$(CONFIG_DRM_VKMS) +=3D vkms.o obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) +=3D tests/ diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index 1177e62e19cb..a7060504f3dc 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -2,9 +2,22 @@ =20 #include =20 +#include "../vkms_config.h" + MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); =20 +static void vkms_config_test_empty_config(struct kunit *test) +{ + struct vkms_config *config; + + config =3D vkms_config_create(); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] =3D { + KUNIT_CASE(vkms_config_test_empty_config), {} }; =20 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 =3D 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 =3D m->private; + struct drm_device *dev =3D entry->dev; + struct vkms_device *vkmsdev =3D drm_device_to_vkms_device(dev); + + seq_printf(m, "writeback=3D%d\n", vkmsdev->config->writeback); + seq_printf(m, "cursor=3D%d\n", vkmsdev->config->cursor); + seq_printf(m, "overlay=3D%d\n", vkmsdev->config->overlay); + + return 0; +} + +static const struct drm_debugfs_info vkms_config_debugfs_list[] =3D { + { "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 devi= ce + * @dev: Used to store the current VKMS device. Only set when the device i= s 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 de= vice'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_dr= v.c index b6de91134a22..37de0658e6ee 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -27,11 +27,9 @@ #include #include =20 +#include "vkms_config.h" #include "vkms_drv.h" =20 -#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_st= ate *old_state) drm_atomic_helper_cleanup_planes(dev, old_state); } =20 -static int vkms_config_show(struct seq_file *m, void *data) -{ - struct drm_debugfs_entry *entry =3D m->private; - struct drm_device *dev =3D entry->dev; - struct vkms_device *vkmsdev =3D drm_device_to_vkms_device(dev); - - seq_printf(m, "writeback=3D%d\n", vkmsdev->config->writeback); - seq_printf(m, "cursor=3D%d\n", vkmsdev->config->cursor); - seq_printf(m, "overlay=3D%d\n", vkmsdev->config->overlay); - - return 0; -} - -static const struct drm_debugfs_info vkms_config_debugfs_list[] =3D { - { "vkms_config", vkms_config_show, 0 }, -}; - static const struct drm_driver vkms_driver =3D { .driver_features =3D DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM, .fops =3D &vkms_driver_fops, @@ -208,8 +189,7 @@ static int vkms_create(struct vkms_config *config) if (ret) goto out_devres; =20 - drm_debugfs_add_files(&vkms_device->drm, vkms_config_debugfs_list, - ARRAY_SIZE(vkms_config_debugfs_list)); + vkms_config_register_debugfs(vkms_device); =20 ret =3D 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; =20 - config =3D kmalloc(sizeof(*config), GFP_KERNEL); - if (!config) - return -ENOMEM; + config =3D vkms_config_create(); + if (IS_ERR(config)) + return PTR_ERR(config); =20 config->cursor =3D enable_cursor; config->writeback =3D enable_writeback; @@ -241,7 +221,7 @@ static int __init vkms_init(void) =20 ret =3D vkms_create(config); if (ret) { - kfree(config); + vkms_config_destroy(config); return ret; } =20 @@ -275,7 +255,7 @@ static void __exit vkms_exit(void) return; =20 vkms_destroy(default_config); - kfree(default_config); + vkms_config_destroy(default_config); } =20 module_init(vkms_init); diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_dr= v.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; }; =20 -/** - * struct vkms_config - General configuration for VKMS driver - * - * @writeback: If true, a writeback buffer can be attached to the CRTC - * @cursor: If true, a cursor plane is created in the VKMS device - * @overlay: If true, NUM_OVERLAY_PLANES will be created for the VKMS devi= ce - * @dev: Used to store the current VKMS device. Only set when the device i= s instantiated. - */ -struct vkms_config { - bool writeback; - bool cursor; - bool overlay; - struct vkms_device *dev; -}; +struct vkms_config; =20 /** * 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+ =20 +#include "vkms_config.h" #include "vkms_connector.h" #include "vkms_drv.h" #include --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4BED81FBE8F for ; Tue, 11 Feb 2025 11:09:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272169; cv=none; b=IzYdZ8mntYLLoVywdE1XZsIuvP1nzg0WWPAWIbI+Hmd1Tk19tl+N6w/U/R1irGrCMQoFqPzAxDwm97a7AqEYmVu0bETUdbr32whWZvESED8IuwCn2LWdjJfni/jwq/hP2Q/KdJJgfcyjR1HK4C9F4OgYPB2ztMhdXWlj46QfGa0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272169; c=relaxed/simple; bh=zcuKr1ljj0ogXVBUUWrigChcUg403Y86mqSK/R0XoCY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=s0x/ATW124Hi/Q4Pv67a86mX7KIfmRGPI1clmVvzOTounkGEAouP+2DMNray6Mz7hAdSfu603cG1YRIrlA8+aNWV+7qbuyJvuzDHKWRBKVnwjPtZhN04jaCbjfr3uECSNwx5i1QAFaU/hRgSimvCA/zLSv+4wOW8mzZ98c8nxbo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=m8ooTuZS; arc=none smtp.client-ip=209.85.221.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="m8ooTuZS" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-38dc6d55ebaso2635384f8f.1 for ; Tue, 11 Feb 2025 03:09:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272165; x=1739876965; darn=vger.kernel.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=PTakTkNWy+x7X249WP5VsfWpMi4Zx2g8PssxIcRL7RU=; b=m8ooTuZSWhDkf3h8JS3plk+fK3F1h4cyeh1dKCF2pxkrdU4rGPSk0qibkYO7sfi6jA shnUg6gRPFlKLoVb0ehPWkt9WhzPcx+QcaG+sUD9DA5yrPxDYdbCSHjqN2AzALWAWURJ AbJzLFGDYesvnwNUGf0t67jZeFgsCWxg/InXZmlqUKmrtCGZWtjpRs8TTphxqSVEvv6/ Pq/JQ3ANfNKjHp+/6phleanKE0+TfZ9zigF9zcYV4eQ9nYSdVM7zki0U0owbyI9XNB36 v39rWuw3g0fb+Ze1Ko6ooDeYMY4CE2dluYkf+Mpkb3L+7kJruwockUaPi1rAcrdtChI9 pgGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272165; x=1739876965; 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=PTakTkNWy+x7X249WP5VsfWpMi4Zx2g8PssxIcRL7RU=; b=Rg2d3dR+Hv8PoFQnSzbRSOE0nbd7zfcTm9VZ2gaO1VxAET6eMq+Z9xxH48k+R/6G2n nqlVwfYhPZiOs39n06xzM9aeV6YEiSUXVx9Uz6Y9WjYHhsp3lWis6NG7p+pQME59Mq+e b4vWrbh0p5xQNAH3Uz7WSJxpV1x7MQGgLp0p3tVLKvAuGg7rityjcO8xpWyc/gIT2N6W eLg5MQnz0OwiHZT6vJ/Sl168RCqf9L2DWl5D8gCy84OHzmax7OqDQdKyOE8pJ5IpfKnx v0daW+9eWJWeQW7wQBVGYSpgQQ+wwkIfetHWGTcCcCKH6gCvzzOIHvAKjE7hJgEfd/Wx 6k8g== X-Forwarded-Encrypted: i=1; AJvYcCVtuUU8NkXaPVD+nDanRHRYa7UHYm8wC4QXb1DZDBFHZP2ygydQ92yw8Q1bimWoZDGwmFgScN4Gw7y3DyA=@vger.kernel.org X-Gm-Message-State: AOJu0YwngnRyO8Fm3am7f4eB+EVTxoFcnnFAe0Re5bOSa6pZmRU5xOBY U9DHhFtYGC3XkzlUDKNmHr9AmhvgbRnI3J48xr1Y9HA75zdEnPRH X-Gm-Gg: ASbGncvMvWHEwwTITkwLHaZjFGtOCFRCwi7QKqLdGig74rVuaFapNKu+MJVqInS8tsu xLkjsBPeyiddKA70410+9R4chlqluoNWFba67GJphF9//PeOHINGcG6jqevVGoeeNd2NOc/GxAj PoHND8y7NHVj/EGKUtif/GdMBKjXrWjg0kW1l+vwFdENoDYINuFs2htv8XtCCyfTClCud/2ocMo +Kbrh9qWurmpZDXsJ7lYSyKaQL6ghV3NvEGlXobwNN19JqBoHlcdmOkIIRIup/ITqiFYNrnoRfh rQX6Kyv4iTzcCQz9 X-Google-Smtp-Source: AGHT+IHlC7FDVWjBn6Dv8KwLai/qeOgcEPNdtOkXbQRg/3SaHr3uTj6JQsw/jPyUom8IHnBsEk0IeA== X-Received: by 2002:a05:6000:4011:b0:38d:c73d:e52c with SMTP id ffacd0b85a97d-38de43aa6a7mr2385287f8f.14.1739272165253; Tue, 11 Feb 2025 03:09:25 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:24 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 06/15] drm/vkms: Move default_config creation to its own function Date: Tue, 11 Feb 2025 12:09:03 +0100 Message-ID: <20250211110912.15409-7-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Extract the initialization of the default configuration to a function. Refactor, no functional changes. Reviewed-by: Louis Chauvet Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- 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/dr= m/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 @@ =20 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); =20 +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); } =20 +static struct default_config_case default_config_cases[] =3D { + { 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 =3D test->param_value; + struct vkms_config *config; + + config =3D 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[] =3D { KUNIT_CASE(vkms_config_test_empty_config), + KUNIT_CASE_PARAM(vkms_config_test_default_config, + default_config_gen_params), {} }; =20 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; } =20 +struct vkms_config *vkms_config_default_create(bool enable_cursor, + bool enable_writeback, + bool enable_overlay) +{ + struct vkms_config *config; + + config =3D vkms_config_create(); + if (IS_ERR(config)) + return config; + + config->cursor =3D enable_cursor; + config->writeback =3D enable_writeback; + config->overlay =3D 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); =20 +/** + * 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_dr= v.c index 37de0658e6ee..582d5825f42b 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -211,14 +211,10 @@ static int __init vkms_init(void) int ret; struct vkms_config *config; =20 - config =3D vkms_config_create(); + config =3D vkms_config_default_create(enable_cursor, enable_writeback, en= able_overlay); if (IS_ERR(config)) return PTR_ERR(config); =20 - config->cursor =3D enable_cursor; - config->writeback =3D enable_writeback; - config->overlay =3D enable_overlay; - ret =3D vkms_create(config); if (ret) { vkms_config_destroy(config); --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wr1-f52.google.com (mail-wr1-f52.google.com [209.85.221.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 66DE61F7557 for ; Tue, 11 Feb 2025 11:09:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272170; cv=none; b=k1VU7K3plb9Sclcj2YI8WDDwiOk2opFe/GROQAJcCmiF7IlNodm4t/I8iHD/4mvybnSnJZ61pvrKg7z2JiyevP0Vvv/rTm4gcrqgBjzTj3WmolY8L794JkpuyGDuzg6tunUOOzGStdiGY4GKQmPLNHFd28zf/bBwdXz9Y3+hnqs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272170; c=relaxed/simple; bh=AjTCUuz+BkUxunMpcoHcHWR0BWaPhpL7TmZBc9bu3GA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TRmqkhzgnc0ExzZD6x49bl66fVOMVESCsdCCZ9CEthLZ+WGpQyc0/MjalVTWHlLwBHdZyZBoXw1f9SCwoMb0vlkPB93hwqrpnA41veJXnjQoux97W/P9VOs3fIdyVDRkmO54tcUE5H6XOII5yrz0lvhLU0iPPNKx65jaKf3gJC4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PjaOyEnG; arc=none smtp.client-ip=209.85.221.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PjaOyEnG" Received: by mail-wr1-f52.google.com with SMTP id ffacd0b85a97d-38dc9f3cc80so1447083f8f.0 for ; Tue, 11 Feb 2025 03:09:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272167; x=1739876967; darn=vger.kernel.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=9pIxRugrT9zIlGotEeERPrS4hzRH4JozFA5lgU8/+aE=; b=PjaOyEnGdbzof9haMobn89zHHpJB89mwMpLhrYWeZCafhM9c0atggx3R78QdFVkpRe DV7BjLfZH7rZzno9vRZSTHC9OuwGZSovFmk21pM2GpbhYW9MiPV1S0TXCWViv6ILr51G DO33z7UaCZO7wnHslYzigmCshLe8dalE/pSLuh85W94q2q/+2ct0kVVZLOsJwHJYFuhu 52gaHZKKf8lHIFC1wrAaDfewn1j4xqgvaxOz99pu1uhGcKJWhh3Kx2/eLykBj9PdziD1 QtmICD09xTWPYCTvEv9RNlrPg1w0FN5o/YBQ7IvOgI6uk5zXV629qWfcBk6hEIWCwnlf BhqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272167; x=1739876967; 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=9pIxRugrT9zIlGotEeERPrS4hzRH4JozFA5lgU8/+aE=; b=DERrcneTNO6JuWnPLoyeF8zQ71NtQ+6hkOZSq8f9nkWC+iXbXR60DdyeZlsTEAxPrE lfu16LMCahHG70ax80JlVq7l7fvDZsG7RZcrBY/gXtgww0syCntI5WpsXFsOIJflJ7xe XNegR2w2SDP95Sq224QmlluwV+slctDCSbYkDTdfv3OwcoNxBdDnz+tWjdPNZGYk7sPx eubAtyv6N42cbHh4l12DlbC4R/q2aVIfnIapaNoawJmqvrvtNnveVyr29mTeK7qYhxKV hqbqd1UKDsmn1mlE2ytIVbYK90K1bO846PKGapVrUSTwOGbZtAkWBJ89MKOA6svPfGeE uAGg== X-Forwarded-Encrypted: i=1; AJvYcCU8bhGmYVPVQuagkMTJINEhHUM47oe3dcELGScvtXl3PcaasFJrGHXlKPrtg0jU0PyxyzDRjxW6eiQDeWI=@vger.kernel.org X-Gm-Message-State: AOJu0Yw04XeINu9rH/D7PBBAK7IzKrpzV1AH0w1uReVDgVkiuDEW5pwa Vo9OiGQlhJvCV7yRiU/Odz+HNc0kArE8TQo/7xBnj2THSAaDRwwe X-Gm-Gg: ASbGncsasPhnJEUORMMjtmPhkzrX3It3OPygkLtrgN3kc+yyeUrIt4rUxfEfV8uy3oL lhRuVR04m1wr0tz4y3NoOcxCmIMtJhk+WUjeQuwxKrAz9YeGbbH+l04/4uXH3F3F8iEAs+u4gFK QzH44YWb38+XJLjwBOGwzTCua1dgkaiYxsYAe5EvKkbF8/TRZF+biyVWMKvrLWfxgRBLg3dbQUr HmPyRk3wt6Ti2Py3WSIisE/C3m6f7dsr1zo3NkjLo3s5NYTpVkvH0jUfbfYxv4X+NzXdPBBmro6 qd0JVGMGDiLyyL5C X-Google-Smtp-Source: AGHT+IHfwznOgYooE54sdnp62NB27Tm8mgqt4Q4HujPdLIkP4bQFsppMEJaJNOMzhaePFvi0XctSXw== X-Received: by 2002:a05:6000:18ab:b0:38c:5d42:1516 with SMTP id ffacd0b85a97d-38dc935dd04mr13336108f8f.34.1739272166602; Tue, 11 Feb 2025 03:09:26 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:25 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 07/15] drm/vkms: Set device name from vkms_config Date: Tue, 11 Feb 2025 12:09:04 +0100 Message-ID: <20250211110912.15409-8-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable In order to be able to create multiple devices, the device name needs to be unique. Allow to set it in the VKMS configuration. Reviewed-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 7 ++++++- drivers/gpu/drm/vkms/vkms_config.c | 14 ++++++++++++-- drivers/gpu/drm/vkms/vkms_config.h | 18 +++++++++++++++++- drivers/gpu/drm/vkms/vkms_drv.c | 4 +++- drivers/gpu/drm/vkms/vkms_drv.h | 2 ++ 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index d8644a1e3e18..92798590051b 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -15,10 +15,15 @@ struct default_config_case { static void vkms_config_test_empty_config(struct kunit *test) { struct vkms_config *config; + const char *dev_name =3D "test"; =20 - config =3D vkms_config_create(); + config =3D vkms_config_create(dev_name); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); =20 + /* The dev_name string and the config have different lifetimes */ + dev_name =3D NULL; + KUNIT_EXPECT_STREQ(test, vkms_config_get_device_name(config), "test"); + vkms_config_destroy(config); } =20 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 @@ =20 #include "vkms_config.h" =20 -struct vkms_config *vkms_config_create(void) +struct vkms_config *vkms_config_create(const char *dev_name) { struct vkms_config *config; =20 @@ -15,6 +15,12 @@ struct vkms_config *vkms_config_create(void) if (!config) return ERR_PTR(-ENOMEM); =20 + config->dev_name =3D kstrdup_const(dev_name, GFP_KERNEL); + if (!config->dev_name) { + kfree(config); + return ERR_PTR(-ENOMEM); + } + return config; } =20 @@ -24,7 +30,7 @@ struct vkms_config *vkms_config_default_create(bool enabl= e_cursor, { struct vkms_config *config; =20 - config =3D vkms_config_create(); + config =3D vkms_config_create(DEFAULT_DEVICE_NAME); if (IS_ERR(config)) return config; =20 @@ -37,6 +43,7 @@ struct vkms_config *vkms_config_default_create(bool enabl= e_cursor, =20 void vkms_config_destroy(struct vkms_config *config) { + kfree_const(config->dev_name); kfree(config); } =20 @@ -45,7 +52,10 @@ static int vkms_config_show(struct seq_file *m, void *da= ta) struct drm_debugfs_entry *entry =3D m->private; struct drm_device *dev =3D entry->dev; struct vkms_device *vkmsdev =3D drm_device_to_vkms_device(dev); + const char *dev_name; =20 + dev_name =3D vkms_config_get_device_name((struct vkms_config *)vkmsdev->c= onfig); + seq_printf(m, "dev_name=3D%s\n", dev_name); seq_printf(m, "writeback=3D%d\n", vkmsdev->config->writeback); seq_printf(m, "cursor=3D%d\n", vkmsdev->config->cursor); seq_printf(m, "overlay=3D%d\n", vkmsdev->config->overlay); diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms= _config.h index d0868750826a..fcaa909fb2e0 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -10,12 +10,14 @@ /** * struct vkms_config - General configuration for VKMS driver * + * @dev_name: Name of the device * @writeback: If true, a writeback buffer can be attached to the CRTC * @cursor: If true, a cursor plane is created in the VKMS device * @overlay: If true, NUM_OVERLAY_PLANES will be created for the VKMS devi= ce * @dev: Used to store the current VKMS device. Only set when the device i= s instantiated. */ struct vkms_config { + const char *dev_name; bool writeback; bool cursor; bool overlay; @@ -24,12 +26,13 @@ struct vkms_config { =20 /** * 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); =20 /** * vkms_config_default_create() - Create the configuration for the default= device @@ -51,6 +54,19 @@ struct vkms_config *vkms_config_default_create(bool enab= le_cursor, */ void vkms_config_destroy(struct vkms_config *config); =20 +/** + * vkms_config_get_device_name() - Return the name of the device + * @config: Configuration to get the device name from + * + * Returns: + * The device name. Only valid while @config is valid. + */ +static inline const char * +vkms_config_get_device_name(struct vkms_config *config) +{ + return config->dev_name; +} + /** * vkms_config_register_debugfs() - Register a debugfs file to show the de= vice's * configuration diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_dr= v.c index 582d5825f42b..ba977ef09b2b 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -151,8 +151,10 @@ static int vkms_create(struct vkms_config *config) int ret; struct platform_device *pdev; struct vkms_device *vkms_device; + const char *dev_name; =20 - pdev =3D platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); + dev_name =3D vkms_config_get_device_name(config); + pdev =3D platform_device_register_simple(dev_name, -1, NULL, 0); if (IS_ERR(pdev)) return PTR_ERR(pdev); =20 diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_dr= v.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 =20 +#define DEFAULT_DEVICE_NAME "vkms" + #define XRES_MIN 10 #define YRES_MIN 10 =20 --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wr1-f50.google.com (mail-wr1-f50.google.com [209.85.221.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F14A11FCFDF for ; Tue, 11 Feb 2025 11:09:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272171; cv=none; b=OVcLq/yzfUMkJhFL9dHpYHQZELXdvtUwE6SeugF7LvKR2h8ydHHnPIxwj5HGMCLh0kRKVmjnOWhUN6n+7Ke9YPkMFBP0i4JFWlj/WzDQceKm4emJEAT+1DFpylq782hNoKFE1fYZLJzP+oIjvGAHr28ZgVY42xo4siONkTfZoqc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272171; c=relaxed/simple; bh=ibI6Tffdl3D8vvHvriJzc7ymXYpxEJLtdrm7KyUcsic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MoED6C30HD+5js7u/qHBuUuWjPskqpqTYwzfRSR7j7zk1HSioa7ccqeVmNUQ8GhPqSrc7aCGw2mSgV8UBihuLx5I9qLpCvX+VhaCKH/DrN9iW7r732NTCnRGH/lc4DcYB5wQ/bVAhBkqJ3mx3oeAFiN7tPps9heHqMGgN55W5gw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=SDKRZsfA; arc=none smtp.client-ip=209.85.221.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SDKRZsfA" Received: by mail-wr1-f50.google.com with SMTP id ffacd0b85a97d-38dd935a267so2072595f8f.1 for ; Tue, 11 Feb 2025 03:09:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272168; x=1739876968; darn=vger.kernel.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=ht9ZYJCKi3pSkXQH9HmuvB26RHJWpzU2MzuZ6pZw6lg=; b=SDKRZsfABUus4u+rWbOCzAA0CSCLUpN4GYf75sG9flafccjL3v3Q6UvtyiuqudM1ek DE29DimIVEo1m+ni5yqe62+MMAZBLv1N08C20SiHJs+as1cSXB+5MbtsE/fIgyu8+aEq Z2fkWCSm3h7jfu2JvmjaaMuFkJXCYt70JmnX4tK9XhuwxfbnY6ajHJOQw21OJwRy/y7U xdAtO5q5C+tr+TuU2L3VGPgjTfmVWZGiFhUQLKNKvCencSOHX7glOoPd7G0A81SJiqvu uuSPVWtQuFiRrBEK07rqzO5c8sOf/XlBZxmWhGGaePB6E4uR+nj3y0Ax9m8WYg0nzrh+ kuNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272168; x=1739876968; 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=ht9ZYJCKi3pSkXQH9HmuvB26RHJWpzU2MzuZ6pZw6lg=; b=C4B1n4YCqIt/ZEqtaHzCNxKhgyREkiuAxbBZmcobux2Yfq/ilripgqIutrnnuGDou7 1tKPimaRCFGuY7tMamn0QxP3RhpeBsyEReJhFAl7B/LNTvuZ4qkRyX+gtzBub4V1mGQE jezAg0xm9Cl2GeeTZmSJhF/36oFa3d3M8t0QpHDv/pVYadTOl75W7s84jMErAbPrclbk 6rdS5M6ufWWnCuV2fW1kH10MLZrkAEFjyidDoliBQDZxKeC/98cAgBs0dbIdkiH2hFyq PQ/h2UsG/iuXMSDGgx46dgwcZhQQ1+ILMfiJ/Vihsb7GcewkW7Nr40zFOtFs4PJDAxIs xj3g== X-Forwarded-Encrypted: i=1; AJvYcCUIDfovwlknpFhepYILiUffY81KCVuaRsxI5EkWJo57RyWkEhj7DHu2VbGY/tFsOiVerXlYykrMmlD/PCg=@vger.kernel.org X-Gm-Message-State: AOJu0YyFeBKXnJ9cjXzLO8we5GuOw5Wh38lFgr1gg28IoYw8HXUNeiex hIgGat1xWk1UsstTocdlJU+XFeYtLGub8yb3vZfPryPMsL3hbWtr X-Gm-Gg: ASbGncuYTzcztkpGqL22uX1bR9P7jnSzc0vFy7G0UXMqGEVvciPSuGERPH1he8GUqvQ YoOuXQskvvAVzGNt/hL+++qP5mnfd2nkWk7d/UJtSCavByEm1Xnjov3hQTf5Wo8ov2uOqbwNrDz 9HWEFzdvUthtrZX/p0aoBslXMmJ3L/h1ZxxYfh37VD8Qt3w4CoN7f0sEQs4/QJuoM058wyNw7nM S7tzFulBu1S6q40S7af5hnWzI+RzU8J0JNZAQ19ZMsBauKTQHzgGsn2UahjXzcUO92VjqWfeBWF U4ACwPa1ISkvmF0R X-Google-Smtp-Source: AGHT+IE3r+36gyMVrHDbD9UHJvKxqbwN9H602g5n7dACf3knhXILuBi9Jj4prEWWCMO9MZ7h+Gndlw== X-Received: by 2002:a05:6000:186f:b0:38d:e250:d962 with SMTP id ffacd0b85a97d-38de250db12mr4478466f8f.30.1739272167690; Tue, 11 Feb 2025 03:09:27 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:27 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 08/15] drm/vkms: Add a validation function for VKMS configuration Date: Tue, 11 Feb 2025 12:09:05 +0100 Message-ID: <20250211110912.15409-9-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Louis Chauvet As the configuration will be used by userspace, add a validator to avoid creating a broken DRM device. For the moment, the function always returns true, but rules will be added in future patches. Reviewed-by: Louis Chauvet Signed-off-by: Louis Chauvet Co-developed-by: Jos=C3=A9 Exp=C3=B3sito Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- 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 ++++++++++ drivers/gpu/drm/vkms/vkms_drv.h | 2 +- drivers/gpu/drm/vkms/vkms_output.c | 3 +++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index 92798590051b..6e07139d261c 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -54,6 +54,8 @@ static void vkms_config_test_default_config(struct kunit = *test) KUNIT_EXPECT_EQ(test, config->writeback, params->enable_writeback); KUNIT_EXPECT_EQ(test, config->overlay, params->enable_overlay); =20 + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + vkms_config_destroy(config); } =20 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); } =20 +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 =3D m->private; diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms= _config.h index fcaa909fb2e0..0376dceaf6be 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -67,6 +67,16 @@ vkms_config_get_device_name(struct vkms_config *config) return config->dev_name; } =20 +/** + * 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 de= vice's * configuration diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_dr= v.h index a74a7fc3a056..95afc39ce985 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -204,7 +204,7 @@ struct vkms_config; struct vkms_device { struct drm_device drm; struct platform_device *platform; - const struct vkms_config *config; + struct vkms_config *config; }; =20 /* diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms= _output.c index 068a7f87ecec..414cc933af41 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -16,6 +16,9 @@ int vkms_output_init(struct vkms_device *vkmsdev) int writeback; unsigned int n; =20 + if (!vkms_config_is_valid(vkmsdev->config)) + return -EINVAL; + /* * Initialize used plane. One primary plane is required to perform the co= mposition. * --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 952871FCFF2 for ; Tue, 11 Feb 2025 11:09:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272173; cv=none; b=H0UWO8yR43J0O33U+3DL3MNa6XBrSvoTlDOZoYM3NIANpTEofUv2TQbrnziqd6iFYzaLn8JHwSG4zgsBb1/pmyTlDFSsd/c0GGjqT4qJroDsQcwK/rtlQ1I3aDClzBgdvAFKqWPJIs+gr8wL95QrYACyVllFAWM/3su4UqOtzUA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272173; c=relaxed/simple; bh=jQiqimLgyL3YXSrLRLX/jOpP0x47NTsxc3XafwDHLTI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZJupfS0ZbMZN9akQ5hITsfVZe1nWjERVJTI0oPL3q2xk3vTgq0ZCSeYArtik24ry4VXUInxJdkm86eKi6hls0vR+3ZhXE7OdsCgzWLkEFGEi76/HbJSE8KVJhXTocipHQuSCR31AKhoipZqupe3s0Qup9eOYUBy/haRF2tgr0Do= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IDbwiJRe; arc=none smtp.client-ip=209.85.221.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IDbwiJRe" Received: by mail-wr1-f41.google.com with SMTP id ffacd0b85a97d-38dc962f1b9so2388419f8f.3 for ; Tue, 11 Feb 2025 03:09:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272169; x=1739876969; darn=vger.kernel.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=B2kmfXhT9BzoK/pB6AuaP8lD3p6L3Xv05Wido6gdYTs=; b=IDbwiJRebXY1umnbLSwXgb/5et6OOvlZClaPc+xP5cYmtk3CtfyOvDOsep03uMb+d7 wW59rpz6pgTWzjUwbgAcUF/EbzVDOS3knmk9EwSYT42qwHD4ThCxHwNyfLA2zJ0f6Prg QGXEUcJ9Ap6tT4uccy3RHVrCRbRBbbtGyht1WEKGmLJnt+dqeRzAvM0w9NXmxdHmBT6H WFtpNJknSC8qaFsbqaMmYU+uvBXQtzeLr9XC2aX1RiXO78wVmy1FwR0lDb8kKlUAUeeI eZQnJ2X9RoDjHsSaXxa23iCZExc6TyipIrAUys9elVm1ib2lIr7hAM2uh3TnVRfMFNiz lcsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272169; x=1739876969; 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=B2kmfXhT9BzoK/pB6AuaP8lD3p6L3Xv05Wido6gdYTs=; b=wxm3MgIniTFOrUh14tP3FFIMva8tCdSc4D5+vTh3nEkDM24iB6faMC5PGYhHOJNlhL 2e1MeuxCASKEAOhMslzI5tYXK0lVNh1ZrEgNEYo7LX4HELV3inBz3eoa2bUWfYZGrgfO HpoV2DWzhp25f7VPpMF4zOQh/ZUQC5DgFdyMASXZMUMzDYpx+9ZEDCzDxXQVvUMm3elT c6GnLLotoa90gomsQTFzoWUZpmUL7ZDHm+Ngxv/c9lCSHWSWmDV4JIL28Rao7aBjZpSP 3RJiF5OTiF8v6npgrPPwLDuy63fAJQyGOHj4Be6XTWfgEB+1ri0r/cTRMkymTvXaEj4f yNNg== X-Forwarded-Encrypted: i=1; AJvYcCX+9kqbmyqFMDPq1c2M9OW1a91eA7ftpZ66IVMbHir8aLt24/REcdNtqAHqJcD6RSBYvdds2pArJ4uNx2s=@vger.kernel.org X-Gm-Message-State: AOJu0YxDYkLG0PLi6lWCvqAbXFlxs/N8nOLZzeexlmScC1pTVCuNTBBG W47imFQCh3jb+zyowtXfhLzsvgpIzyph3swQx9mGAeSnWFwPxMfs X-Gm-Gg: ASbGnctV2JOtTlDAI+Fxt9krWiR4PUzCoqOczZjvm6D8xh5e23Cm9nTofMBoIEZqshO 5+9ODjkNEZn0GomgfazmM6a9TpUWFWGw70IHlY4DwmCFwv1UztqXjGI5JC3mSHNDfj/+A4SUhde rWiUzo3GhSlHsgSrS76axwLyKw78L0UMSvSsbPBTgo1VU9iG7aj93kaHhc3FfuYCS7+vZ3Mo+Sn CITnLuk1sh0MFyetreWTrvQf8xoEAF773Ap50GBSEqS232shWE2bYJhIjEjh8C5go+yGLyfJHHP Ha1v13OkNigHTyYe X-Google-Smtp-Source: AGHT+IEzl7v9Ctoqur7uCVRnL8fUQKBIvhoP1P3h6FkEuOOmER8stFwB4z2yi1f8X0XCRNCSRLIZzQ== X-Received: by 2002:a05:6000:156f:b0:38d:d9e7:54a8 with SMTP id ffacd0b85a97d-38dd9e756f9mr7286984f8f.19.1739272168677; Tue, 11 Feb 2025 03:09:28 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:28 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 09/15] drm/vkms: Allow to configure multiple planes Date: Tue, 11 Feb 2025 12:09:06 +0100 Message-ID: <20250211110912.15409-10-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a list of planes to vkms_config and create as many planes as configured during output initialization. For backwards compatibility, add one primary plane and, if configured, one cursor plane and NUM_OVERLAY_PLANES planes to the default configuration. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 140 +++++++++++++++++- drivers/gpu/drm/vkms/vkms_config.c | 124 +++++++++++++++- drivers/gpu/drm/vkms/vkms_config.h | 73 ++++++++- drivers/gpu/drm/vkms/vkms_output.c | 42 ++---- 5 files changed, 344 insertions(+), 36 deletions(-) diff --git a/.clang-format b/.clang-format index fe1aa1a30d40..c585d2a5b395 100644 --- a/.clang-format +++ b/.clang-format @@ -690,6 +690,7 @@ ForEachMacros: - 'v4l2_m2m_for_each_src_buf' - 'v4l2_m2m_for_each_src_buf_safe' - 'virtio_device_for_each_vq' + - 'vkms_config_for_each_plane' - 'while_for_each_ftrace_op' - 'xa_for_each' - 'xa_for_each_marked' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index 6e07139d261c..38ec456d9610 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 =3D NULL; KUNIT_EXPECT_STREQ(test, vkms_config_get_device_name(config), "test"); =20 + KUNIT_EXPECT_TRUE(test, list_empty(&config->planes)); + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + vkms_config_destroy(config); } =20 @@ -44,16 +48,145 @@ static void vkms_config_test_default_config(struct kun= it *test) { const struct default_config_case *params =3D test->param_value; struct vkms_config *config; + struct vkms_config_plane *plane_cfg; + int n_primaries =3D 0; + int n_cursors =3D 0; + int n_overlays =3D 0; =20 config =3D vkms_config_default_create(params->enable_cursor, params->enable_writeback, params->enable_overlay); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); =20 - 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); =20 + /* 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_cfg; + struct vkms_config_plane *plane_cfg1, *plane_cfg2; + int n_planes =3D 0; + + config =3D vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + vkms_config_for_each_plane(config, plane_cfg) + n_planes++; + KUNIT_ASSERT_EQ(test, n_planes, 0); + + plane_cfg1 =3D vkms_config_create_plane(config); + vkms_config_for_each_plane(config, plane_cfg) { + n_planes++; + if (plane_cfg !=3D plane_cfg1) + KUNIT_FAIL(test, "Unexpected plane"); + } + KUNIT_ASSERT_EQ(test, n_planes, 1); + n_planes =3D 0; + + plane_cfg2 =3D vkms_config_create_plane(config); + vkms_config_for_each_plane(config, plane_cfg) { + n_planes++; + if (plane_cfg !=3D plane_cfg1 && plane_cfg !=3D plane_cfg2) + KUNIT_FAIL(test, "Unexpected plane"); + } + KUNIT_ASSERT_EQ(test, n_planes, 2); + n_planes =3D 0; + + vkms_config_destroy_plane(plane_cfg1); + vkms_config_for_each_plane(config, plane_cfg) { + n_planes++; + if (plane_cfg !=3D plane_cfg2) + KUNIT_FAIL(test, "Unexpected plane"); + } + KUNIT_ASSERT_EQ(test, n_planes, 1); + + vkms_config_destroy(config); +} + +static void vkms_config_test_invalid_plane_number(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_plane *plane_cfg; + int n; + + config =3D vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + /* Invalid: No planes */ + plane_cfg =3D 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 =3D 0; n <=3D 32; n++) + vkms_config_create_plane(config); + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + +static void vkms_config_test_valid_plane_type(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_plane *plane_cfg; + + config =3D vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + plane_cfg =3D list_first_entry(&config->planes, typeof(*plane_cfg), link); + vkms_config_destroy_plane(plane_cfg); + + /* Invalid: No primary plane */ + plane_cfg =3D vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Invalid: Multiple primary planes */ + plane_cfg =3D vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + plane_cfg =3D vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: One primary plane */ + vkms_config_destroy_plane(plane_cfg); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); + + /* Invalid: Multiple cursor planes */ + plane_cfg =3D vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + plane_cfg =3D vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: One primary and one cursor plane */ + vkms_config_destroy_plane(plane_cfg); KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); =20 vkms_config_destroy(config); @@ -63,6 +196,9 @@ static struct kunit_case vkms_config_test_cases[] =3D { KUNIT_CASE(vkms_config_test_empty_config), KUNIT_CASE_PARAM(vkms_config_test_default_config, default_config_gen_params), + KUNIT_CASE(vkms_config_test_get_planes), + KUNIT_CASE(vkms_config_test_invalid_plane_number), + KUNIT_CASE(vkms_config_test_valid_plane_type), {} }; =20 diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms= _config.c index 67f71d29596e..8feacfc155be 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_na= me) return ERR_PTR(-ENOMEM); } =20 + INIT_LIST_HEAD(&config->planes); + return config; } =20 @@ -29,26 +31,114 @@ struct vkms_config *vkms_config_default_create(bool en= able_cursor, bool enable_overlay) { struct vkms_config *config; + struct vkms_config_plane *plane_cfg; + int n; =20 config =3D vkms_config_create(DEFAULT_DEVICE_NAME); if (IS_ERR(config)) return config; =20 - config->cursor =3D enable_cursor; config->writeback =3D enable_writeback; - config->overlay =3D enable_overlay; + + plane_cfg =3D vkms_config_create_plane(config); + if (IS_ERR(plane_cfg)) + goto err_alloc; + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + + if (enable_overlay) { + for (n =3D 0; n < NUM_OVERLAY_PLANES; n++) { + plane_cfg =3D vkms_config_create_plane(config); + if (IS_ERR(plane_cfg)) + goto err_alloc; + vkms_config_plane_set_type(plane_cfg, + DRM_PLANE_TYPE_OVERLAY); + } + } + + if (enable_cursor) { + plane_cfg =3D vkms_config_create_plane(config); + if (IS_ERR(plane_cfg)) + goto err_alloc; + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + } =20 return config; + +err_alloc: + vkms_config_destroy(config); + return ERR_PTR(-ENOMEM); } =20 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); } =20 +static bool valid_plane_number(struct vkms_config *config) +{ + struct drm_device *dev =3D &config->dev->drm; + size_t n_planes; + + n_planes =3D list_count_nodes(&config->planes); + if (n_planes <=3D 0 || n_planes >=3D 32) { + drm_info(dev, "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 drm_device *dev =3D &config->dev->drm; + struct vkms_config_plane *plane_cfg; + bool has_primary_plane =3D false; + bool has_cursor_plane =3D false; + + vkms_config_for_each_plane(config, plane_cfg) { + enum drm_plane_type type; + + type =3D vkms_config_plane_get_type(plane_cfg); + + if (type =3D=3D DRM_PLANE_TYPE_PRIMARY) { + if (has_primary_plane) { + drm_info(dev, "Multiple primary planes\n"); + return false; + } + + has_primary_plane =3D true; + } else if (type =3D=3D DRM_PLANE_TYPE_CURSOR) { + if (has_cursor_plane) { + drm_info(dev, "Multiple cursor planes\n"); + return false; + } + + has_cursor_plane =3D true; + } + } + + if (!has_primary_plane) { + drm_info(dev, "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; } =20 @@ -58,12 +148,17 @@ static int vkms_config_show(struct seq_file *m, void *= data) struct drm_device *dev =3D entry->dev; struct vkms_device *vkmsdev =3D drm_device_to_vkms_device(dev); const char *dev_name; + struct vkms_config_plane *plane_cfg; =20 dev_name =3D vkms_config_get_device_name((struct vkms_config *)vkmsdev->c= onfig); seq_printf(m, "dev_name=3D%s\n", dev_name); seq_printf(m, "writeback=3D%d\n", vkmsdev->config->writeback); - seq_printf(m, "cursor=3D%d\n", vkmsdev->config->cursor); - seq_printf(m, "overlay=3D%d\n", vkmsdev->config->overlay); + + vkms_config_for_each_plane(vkmsdev->config, plane_cfg) { + seq_puts(m, "plane:\n"); + seq_printf(m, "\ttype=3D%d\n", + vkms_config_plane_get_type(plane_cfg)); + } =20 return 0; } @@ -77,3 +172,24 @@ void vkms_config_register_debugfs(struct vkms_device *v= kms_device) drm_debugfs_add_files(&vkms_device->drm, vkms_config_debugfs_list, ARRAY_SIZE(vkms_config_debugfs_list)); } + +struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *con= fig) +{ + struct vkms_config_plane *plane_cfg; + + plane_cfg =3D 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 0376dceaf6be..1c7ffc27f2a8 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_ =20 +#include #include =20 #include "vkms_drv.h" @@ -12,18 +13,44 @@ * * @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 devi= ce + * @planes: List of planes configured for the device * @dev: Used to store the current VKMS device. Only set when the device i= s instantiated. */ struct vkms_config { const char *dev_name; bool writeback; - bool cursor; - bool overlay; + struct list_head planes; struct vkms_device *dev; }; =20 +/** + * 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 vali= d. + * It can be used to store a temporary reference to a VKMS plane d= uring + * device creation. This pointer is not managed by the configurati= on 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_for_each_plane - Iterate over the vkms_config planes + * @config: &struct vkms_config pointer + * @plane_cfg: &struct vkms_config_plane pointer used as cursor + */ +#define vkms_config_for_each_plane(config, plane_cfg) \ + list_for_each_entry((plane_cfg), &(config)->planes, link) + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -84,4 +111,42 @@ bool vkms_config_is_valid(struct vkms_config *config); */ void vkms_config_register_debugfs(struct vkms_device *vkms_device); =20 +/** + * vkms_config_create_plane() - Add a new plane configuration + * @config: Configuration to add the plane to + * + * Returns: + * The new plane configuration or an error. Call vkms_config_destroy_plane= () to + * free the returned plane configuration. + */ +struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *con= fig); + +/** + * 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 =3D type; +} + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms= _output.c index 414cc933af41..08ea691db299 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -11,28 +11,29 @@ int vkms_output_init(struct vkms_device *vkmsdev) struct vkms_connector *connector; struct drm_encoder *encoder; struct vkms_output *output; - struct vkms_plane *primary, *overlay, *cursor =3D NULL; + struct vkms_plane *primary =3D NULL, *cursor =3D NULL; + struct vkms_config_plane *plane_cfg; int ret; int writeback; - unsigned int n; =20 if (!vkms_config_is_valid(vkmsdev->config)) return -EINVAL; =20 - /* - * Initialize used plane. One primary plane is required to perform the co= mposition. - * - * The overlay and cursor planes are not mandatory, but can be used to pe= rform complex - * composition. - */ - primary =3D vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY); - if (IS_ERR(primary)) - return PTR_ERR(primary); + vkms_config_for_each_plane(vkmsdev->config, plane_cfg) { + enum drm_plane_type type; =20 - if (vkmsdev->config->cursor) { - cursor =3D vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR); - if (IS_ERR(cursor)) - return PTR_ERR(cursor); + type =3D vkms_config_plane_get_type(plane_cfg); + + plane_cfg->plane =3D vkms_plane_init(vkmsdev, type); + if (IS_ERR(plane_cfg->plane)) { + DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n"); + return PTR_ERR(plane_cfg->plane); + } + + if (type =3D=3D DRM_PLANE_TYPE_PRIMARY) + primary =3D plane_cfg->plane; + else if (type =3D=3D DRM_PLANE_TYPE_CURSOR) + cursor =3D plane_cfg->plane; } =20 output =3D vkms_crtc_init(dev, &primary->base, @@ -42,17 +43,6 @@ int vkms_output_init(struct vkms_device *vkmsdev) return PTR_ERR(output); } =20 - if (vkmsdev->config->overlay) { - for (n =3D 0; n < NUM_OVERLAY_PLANES; n++) { - overlay =3D vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_OVERLAY); - if (IS_ERR(overlay)) { - DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n"); - return PTR_ERR(overlay); - } - overlay->base.possible_crtcs =3D drm_crtc_mask(&output->crtc); - } - } - connector =3D vkms_connector_init(vkmsdev); if (IS_ERR(connector)) { DRM_ERROR("Failed to init connector\n"); --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5E0701FF1BA for ; Tue, 11 Feb 2025 11:09:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272174; cv=none; b=k+T+pnCmBwmIplEKYxeDrtWTKlQWjF8Z6fpyxsqbkwPPL8fMCjSdCZmECLUodg7l4YOmDmOE006AuPi6tw2Q2oxPL5W4pxJG7KCHuwvyVevHmpcvIynX2XsVnyIlKSOf4iGHbU6aV1QMr+d93j01aeJd+KvJsvGAX9QdI9h0wOU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272174; c=relaxed/simple; bh=UtdSsLwNlsOpdMqCJmdovWvAqjSML4M3b3j6x5TAsmc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lOOwoF6TdQoLY0LEmwuPEoh3/DeBioPHWdF0+4J34JxU7S+ZWZjY+w0F1V4O6U+90bI4mcjn9RoOqA6YPImSY6w4gKmLDSzUaraHAal9OLajFF8cX4tllqXPMm5SDKhNP8/EanpV3HwlLCoBFQly5U6KyGoBBSCBpILpmANIErg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=QhcPNuLb; arc=none smtp.client-ip=209.85.221.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QhcPNuLb" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-38dc660b56cso4163790f8f.0 for ; Tue, 11 Feb 2025 03:09:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272171; x=1739876971; darn=vger.kernel.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=rgZhQ6dAZnQsQ/pSlZ4d6v7fEVat7OWRX1o/03NiEX0=; b=QhcPNuLb6rwVVvoeYbS/pt7wYcrQby+gEv0CbJxOqJZ67MX7taWYVkk8ty6dKPW5gU CfVRfiLMgfa3SYgg/lMqfh3DEGgynslCEmQnQDQ8qu1sy1YTpCXVCwEOxmDf/lVBcSH3 6jt8kvX5+JJxSU67YcsQG0IhFk4I8JABmDkIjgaa2TuiqLHpMmfBQD3E79hMZDRFWbXv P4xoFgtwi1R/0d6QZMVYm+FjABLWBVaIdATsFpvooIpuWG3AFjW3aWZ+330ANrqCntlK 2Qv4lop/juCFBj7dzxUrEbrmUF2bqSx+RzCUh10dYnzVr8jg5ztVf/pweN6sYc6WjWje W8Qw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272171; x=1739876971; 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=rgZhQ6dAZnQsQ/pSlZ4d6v7fEVat7OWRX1o/03NiEX0=; b=ZKNEA0szmpLBufpjpF1mRG8MiqO/KbEy6qaeWLU8gkhnox8QdmDXOT1F72xOrc1w3W ggJU1YvDYxbsPNc9BY9Znn912nZB8/HUXsh0xaNMgYERk/Zv6ouYrDNZJdDngjy1DGG/ Fvy0BGiRrlfz+rQQEAX0yKvEkOoN3ZVmFUa7tMoD3/ddqjjDSlI/NaP4VkbJmqlkl7a9 zSTEgUPzqTwz5w69upgGyBRPtzGx8lLEGXk3+/1TBAFtZ/YN/Z1EiTR5W0kt3UWUOkrj UZGUR/iimy9c+KfwqY2Sm7yN0trkeL0TodSvFeR6FnS6jAPUBkkPrcsVb5+D9E3WWbnP Jkww== X-Forwarded-Encrypted: i=1; AJvYcCWfRgLRD2MxQE44N13mab9snm11cu/UXHwef3bP8PCY0MZwmncdhOx9tgqRkDSH54zFYchE+IYVTyiDti8=@vger.kernel.org X-Gm-Message-State: AOJu0Yw4Uk76UZ7cSIfCxghYS2kPN/4tCUh7X6kT7JQw0ARlpe8rx0JO uZhuaXauFUYHTqy55qn6o/RVgt9WGG1pN9zV8dRhjnga/m9DktH6 X-Gm-Gg: ASbGnctThbG2DByVEIfPdNAr75Pph8U04NoP81Bw8wm3cVF7W5jO5bi0aWbsb89jujf deHjZ2uuRC+ylDLPqxo8dBN1OZpG2ESPidMrx1SO3Vmsta6hM/eNtA04bWZLxKG9GVMaWTe97ES ScN7/M5r7z95+KllI3i79Ak31SzFMi7DXiSh1RvvIlSDvHD/i+X1QGz9Jh0qrkNd8rHOXThip3w l64C4aOH5J9lLwNtOH8OR+/A6XwbX4J+1E2SIRCJzdyFCrQr+K2lVRkK6fs4YbhKxS99a5Gponv whV+xLSRTgHlZL2b X-Google-Smtp-Source: AGHT+IHo0BwESJDewoMMey9zJvK+1wnRQd0wPoASeUmmYx4QQnfH41fvqdbpqf8kLDCS1DoqMl7hSQ== X-Received: by 2002:a05:6000:1f81:b0:38d:e3d4:4468 with SMTP id ffacd0b85a97d-38de3d4464cmr4288184f8f.51.1739272170397; Tue, 11 Feb 2025 03:09:30 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:29 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 10/15] drm/vkms: Allow to configure multiple CRTCs Date: Tue, 11 Feb 2025 12:09:07 +0100 Message-ID: <20250211110912.15409-11-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a list of CRTCs to vkms_config and helper functions to add and remove as many CRTCs as wanted. For backwards compatibility, add one CRTC to the default configuration. A future patch will allow to attach planes and CRTCs, but for the moment there are no changes in the way the output is configured. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 73 ++++++++++++++++- drivers/gpu/drm/vkms/vkms_config.c | 60 +++++++++++++- drivers/gpu/drm/vkms/vkms_config.h | 78 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_drv.c | 3 +- 5 files changed, 209 insertions(+), 6 deletions(-) diff --git a/.clang-format b/.clang-format index c585d2a5b395..e7a901c3617d 100644 --- a/.clang-format +++ b/.clang-format @@ -690,6 +690,7 @@ ForEachMacros: - 'v4l2_m2m_for_each_src_buf' - 'v4l2_m2m_for_each_src_buf_safe' - 'virtio_device_for_each_vq' + - 'vkms_config_for_each_crtc' - 'vkms_config_for_each_plane' - 'while_for_each_ftrace_op' - 'xa_for_each' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index 38ec456d9610..59bd7baea923 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 *t= est) KUNIT_EXPECT_STREQ(test, vkms_config_get_device_name(config), "test"); =20 KUNIT_EXPECT_TRUE(test, list_empty(&config->planes)); + KUNIT_EXPECT_TRUE(test, list_empty(&config->crtcs)); =20 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); =20 @@ -49,6 +50,7 @@ static void vkms_config_test_default_config(struct kunit = *test) const struct default_config_case *params =3D test->param_value; struct vkms_config *config; struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; int n_primaries =3D 0; int n_cursors =3D 0; int n_overlays =3D 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); =20 - 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); =20 + /* CRTCs */ + crtc_cfg =3D 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)); =20 vkms_config_destroy(config); @@ -128,6 +135,43 @@ static void vkms_config_test_get_planes(struct kunit *= test) vkms_config_destroy(config); } =20 +static void vkms_config_test_get_crtcs(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_crtc *crtc_cfg; + struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; + + config =3D vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 0); + vkms_config_for_each_crtc(config, crtc_cfg) + KUNIT_FAIL(test, "Unexpected CRTC"); + + crtc_cfg1 =3D vkms_config_create_crtc(config); + KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 1); + vkms_config_for_each_crtc(config, crtc_cfg) { + if (crtc_cfg !=3D crtc_cfg1) + KUNIT_FAIL(test, "Unexpected CRTC"); + } + + crtc_cfg2 =3D vkms_config_create_crtc(config); + KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 2); + vkms_config_for_each_crtc(config, crtc_cfg) { + if (crtc_cfg !=3D crtc_cfg1 && crtc_cfg !=3D crtc_cfg2) + KUNIT_FAIL(test, "Unexpected CRTC"); + } + + vkms_config_destroy_crtc(config, crtc_cfg2); + KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 1); + vkms_config_for_each_crtc(config, crtc_cfg) { + if (crtc_cfg !=3D crtc_cfg1) + KUNIT_FAIL(test, "Unexpected CRTC"); + } + + vkms_config_destroy(config); +} + static void vkms_config_test_invalid_plane_number(struct kunit *test) { struct vkms_config *config; @@ -192,13 +236,38 @@ static void vkms_config_test_valid_plane_type(struct = kunit *test) vkms_config_destroy(config); } =20 +static void vkms_config_test_invalid_crtc_number(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_crtc *crtc_cfg; + int n; + + config =3D vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + /* Invalid: No CRTCs */ + crtc_cfg =3D 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 =3D 0; n <=3D 32; n++) + vkms_config_create_crtc(config); + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] =3D { KUNIT_CASE(vkms_config_test_empty_config), KUNIT_CASE_PARAM(vkms_config_test_default_config, default_config_gen_params), KUNIT_CASE(vkms_config_test_get_planes), + KUNIT_CASE(vkms_config_test_get_crtcs), KUNIT_CASE(vkms_config_test_invalid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), + KUNIT_CASE(vkms_config_test_invalid_crtc_number), {} }; =20 diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms= _config.c index 8feacfc155be..b08021e62c9f 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_na= me) } =20 INIT_LIST_HEAD(&config->planes); + INIT_LIST_HEAD(&config->crtcs); =20 return config; } @@ -32,19 +33,23 @@ struct vkms_config *vkms_config_default_create(bool ena= ble_cursor, { struct vkms_config *config; struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; int n; =20 config =3D vkms_config_create(DEFAULT_DEVICE_NAME); if (IS_ERR(config)) return config; =20 - config->writeback =3D enable_writeback; - plane_cfg =3D vkms_config_create_plane(config); if (IS_ERR(plane_cfg)) goto err_alloc; vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); =20 + crtc_cfg =3D vkms_config_create_crtc(config); + if (IS_ERR(crtc_cfg)) + goto err_alloc; + vkms_config_crtc_set_writeback(crtc_cfg, enable_writeback); + if (enable_overlay) { for (n =3D 0; n < NUM_OVERLAY_PLANES; n++) { plane_cfg =3D vkms_config_create_plane(config); @@ -72,10 +77,14 @@ struct vkms_config *vkms_config_default_create(bool ena= ble_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; =20 list_for_each_entry_safe(plane_cfg, plane_tmp, &config->planes, link) vkms_config_destroy_plane(plane_cfg); =20 + 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); } @@ -131,11 +140,28 @@ static bool valid_plane_type(struct vkms_config *conf= ig) return true; } =20 +static bool valid_crtc_number(struct vkms_config *config) +{ + struct drm_device *dev =3D &config->dev->drm; + size_t n_crtcs; + + n_crtcs =3D list_count_nodes(&config->crtcs); + if (n_crtcs <=3D 0 || n_crtcs >=3D 32) { + drm_info(dev, "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; =20 + if (!valid_crtc_number(config)) + return false; + if (!valid_plane_type(config)) return false; =20 @@ -149,10 +175,10 @@ static int vkms_config_show(struct seq_file *m, void = *data) struct vkms_device *vkmsdev =3D drm_device_to_vkms_device(dev); const char *dev_name; struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; =20 dev_name =3D vkms_config_get_device_name((struct vkms_config *)vkmsdev->c= onfig); seq_printf(m, "dev_name=3D%s\n", dev_name); - seq_printf(m, "writeback=3D%d\n", vkmsdev->config->writeback); =20 vkms_config_for_each_plane(vkmsdev->config, plane_cfg) { seq_puts(m, "plane:\n"); @@ -160,6 +186,12 @@ static int vkms_config_show(struct seq_file *m, void *= data) vkms_config_plane_get_type(plane_cfg)); } =20 + vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) { + seq_puts(m, "crtc:\n"); + seq_printf(m, "\twriteback=3D%d\n", + vkms_config_crtc_get_writeback(crtc_cfg)); + } + return 0; } =20 @@ -193,3 +225,25 @@ void vkms_config_destroy_plane(struct vkms_config_plan= e *plane_cfg) list_del(&plane_cfg->link); kfree(plane_cfg); } + +struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *confi= g) +{ + struct vkms_config_crtc *crtc_cfg; + + crtc_cfg =3D 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 1c7ffc27f2a8..0f5937b44948 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 i= s instantiated. */ struct vkms_config { const char *dev_name; bool writeback; struct list_head planes; + struct list_head crtcs; struct vkms_device *dev; }; =20 @@ -43,6 +45,25 @@ struct vkms_config_plane { struct vkms_plane *plane; }; =20 +/** + * 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 dur= ing + * device creation. This pointer is not managed by the configuratio= n 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_for_each_plane - Iterate over the vkms_config planes * @config: &struct vkms_config pointer @@ -51,6 +72,14 @@ struct vkms_config_plane { #define vkms_config_for_each_plane(config, plane_cfg) \ list_for_each_entry((plane_cfg), &(config)->planes, link) =20 +/** + * vkms_config_for_each_crtc - Iterate over the vkms_config CRTCs + * @config: &struct vkms_config pointer + * @crtc_cfg: &struct vkms_config_crtc pointer used as cursor + */ +#define vkms_config_for_each_crtc(config, crtc_cfg) \ + list_for_each_entry((crtc_cfg), &(config)->crtcs, link) + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -94,6 +123,15 @@ vkms_config_get_device_name(struct vkms_config *config) return config->dev_name; } =20 +/** + * vkms_config_get_num_crtcs() - Return the number of CRTCs in the configu= ration + * @config: Configuration to get the number of CRTCs from + */ +static inline size_t vkms_config_get_num_crtcs(struct vkms_config *config) +{ + return list_count_nodes(&config->crtcs); +} + /** * vkms_config_is_valid() - Validate a configuration * @config: Configuration to validate @@ -149,4 +187,44 @@ vkms_config_plane_set_type(struct vkms_config_plane *p= lane_cfg, plane_cfg->type =3D type; } =20 +/** + * vkms_config_create_crtc() - Add a new CRTC configuration + * @config: Configuration to add the CRTC to + * + * Returns: + * The new CRTC configuration or an error. Call vkms_config_destroy_crtc()= to + * free the returned CRTC configuration. + */ +struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *confi= g); + +/** + * 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 cre= ated + * @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 cre= ated + * @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 =3D writeback; +} + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_dr= v.c index ba977ef09b2b..a24d1655f7b8 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -181,7 +181,8 @@ static int vkms_create(struct vkms_config *config) goto out_devres; } =20 - ret =3D drm_vblank_init(&vkms_device->drm, 1); + ret =3D drm_vblank_init(&vkms_device->drm, + vkms_config_get_num_crtcs(config)); if (ret) { DRM_ERROR("Failed to vblank\n"); goto out_devres; --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 46105211472 for ; Tue, 11 Feb 2025 11:09:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272176; cv=none; b=Lj6npzyKQOCTqUgvBkV+w73cm4V4J4DYsDUhdGY0oWDGNlOByWz7YAy1v/MJ/sQTvRwnW72e+PrFmJc6v5DqUk8On9x5rJAG336yt/68KeGNIZ8xK2c/jgDKwldLZRgHAWRpFwazxV4ge0n5NcqUYgJX37BzScFon7v0MQ9HrNI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272176; c=relaxed/simple; bh=GOPu3z+1Nckku4odiaZ6fSKuOlCJkl3Rt7VV0rDsa+M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=h2uUOBKA/Dz/e+//RvmcIQ17XtzjPycbTui6/auD7ZrldqQLQR93T/VIomaWlQi+ToS+s+LDdGVC1HLr1TPzvnKGdXm4n9qXWsHEnPHXJCHIvHx1GzBeO+n+ZffglFjcBi/RrGQ2gAzJ4jZAlp9DpY6nn1iT+spjTZsI69jLWcM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=CYWLk5gB; arc=none smtp.client-ip=209.85.128.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CYWLk5gB" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-43956e3863eso92235e9.2 for ; Tue, 11 Feb 2025 03:09:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272172; x=1739876972; darn=vger.kernel.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=gz0YRk3ughu7e2CD68H5VgQs97KOCSbfd1nCJLxiUJ0=; b=CYWLk5gBUSnnNqpRH7HwDgOatiwu+wDYV6uAo3MqLaAzl9I9e39MBQUrXhDtztlkQM 5iluPXWsDiZqAZ4in8u1qHZgGPXXaY53zs55e7pUpFgPhpFOZjuxL1ELA7cEAe3WIEAA HnLrs0jzx4q1Pab418yR7/vFeRFkmzup8HHYWpeAkFrsE+nZxEdSHgX/Wdb6dN/IpbFX uxiXs82M1mSuHNa/hh4IFfjBq5CWaPHXJPcm4eK02rhZfTnPyzNImVoUdTloKl6ADwIN jMknnOycY8TE6fSqx/HpWqWpqw1C8CT3bCC+qytDz/Ls4wEYXC4KwPRX7xUfGPTI8Enr mNKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272172; x=1739876972; 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=gz0YRk3ughu7e2CD68H5VgQs97KOCSbfd1nCJLxiUJ0=; b=k3IrBfpMFEJ7uInT+V4g5HyymAstg9W/LjyRi7Zco1D0h4A0gCeqbqWOIGOW2hdXo3 Bv6xHkf2lfuq1/Tq7GWPMwCdxfU+pcakMF5EyZSvwwjnhsjldsW5WbO9NoC9OJCMv64i ZPvzIpyX5oBTdHO9l3J7lnyY55kzY5VC+5a/Xzboj6s6jW7nNPADKBHoW/uqGNaz95d5 kE8OP4+467s4quERlDVxqHHr6zrIzi5M0FFfbycrhlFfsjg5pLzoNNpCuzFtsVGMW6CP 6nZc2PWzjKeZFYRmabGgkc0WYeJ8cGxbbMgN1wP1TMNsjfGZUgccldfVzW99jO2eU8jo JuKA== X-Forwarded-Encrypted: i=1; AJvYcCVRiO3mLQQR8n8IFlnKDMj9/2mYgKki+gzLAwHEeT6Zm6C6K5CKHNcOehjRh0lAvsnhx+m6e7ePDyiA3iA=@vger.kernel.org X-Gm-Message-State: AOJu0Yxa0VDNrp8c5oR0910auuMB4iRJONZDws+4qRpfPQ+6WFd+rHft klH9FKWqOEDFQ8YULAIMxa879U9pTmcRkK1hfnUmXg5Cfnq/qd9j X-Gm-Gg: ASbGnctRNuHIjmNXJgqmlZjShX9KVRiI3nNopeARL90w+jH8UFo8wvViT+Im3fSRMZY /whsR47ZCPbAG6/FursA1Vm03Y9/NU/nCG5eonZtFo8aMyj8WLEUkMsrKDt5uqS3LoaA549D5yi aGSKOEHvVFPHYRJfHGkn6954iP5JwysNdUAhkCiYO+VlblRq8rC9SAU3wiyc3NLKVS4jQjPqLG5 Fww1eoyw+ijJMVJjN7m1F+Hn8oAn/y2ualfeMfahks9m+VXloCLnh6/++3q+xfg9GNvnjAB66Vk RL9Z02o3vOAPuwuO X-Google-Smtp-Source: AGHT+IFYyO9xkH4y9QLRvN5380Sr4o2mE2mFu7BIqe31z9dyETfPETCYymIayfCMHUazfsKp2PlPrw== X-Received: by 2002:a05:600c:4f8e:b0:434:a7e3:db5c with SMTP id 5b1f17b1804b1-43924989dbbmr183832195e9.11.1739272172196; Tue, 11 Feb 2025 03:09:32 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:31 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 11/15] drm/vkms: Allow to attach planes and CRTCs Date: Tue, 11 Feb 2025 12:09:08 +0100 Message-ID: <20250211110912.15409-12-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a list of possible CRTCs to the plane configuration and helpers to attach, detach and get the primary and cursor planes attached to a CRTC. Now that the default configuration has its planes and CRTC correctly attached, configure the output following the configuration. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 188 ++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 147 ++++++++++++-- drivers/gpu/drm/vkms/vkms_config.h | 59 +++++- drivers/gpu/drm/vkms/vkms_output.c | 51 +++-- 5 files changed, 411 insertions(+), 35 deletions(-) diff --git a/.clang-format b/.clang-format index e7a901c3617d..6f944fa39841 100644 --- a/.clang-format +++ b/.clang-format @@ -692,6 +692,7 @@ ForEachMacros: - 'virtio_device_for_each_vq' - 'vkms_config_for_each_crtc' - 'vkms_config_for_each_plane' + - 'vkms_config_plane_for_each_possible_crtc' - 'while_for_each_ftrace_op' - 'xa_for_each' - 'xa_for_each_marked' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index 59bd7baea923..505eebb07a52 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); =20 + list_for_each_entry(plane_cfg, &config->planes, link) { + struct vkms_config_crtc *possible_crtc; + int n_possible_crtcs =3D 0; + unsigned long idx =3D 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)); =20 vkms_config_destroy(config); @@ -199,6 +211,8 @@ static void vkms_config_test_valid_plane_type(struct ku= nit *test) { struct vkms_config *config; struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; + int err; =20 config =3D vkms_config_default_create(false, false, false); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); @@ -206,16 +220,26 @@ static void vkms_config_test_valid_plane_type(struct = kunit *test) plane_cfg =3D list_first_entry(&config->planes, typeof(*plane_cfg), link); vkms_config_destroy_plane(plane_cfg); =20 + crtc_cfg =3D list_first_entry(&config->crtcs, typeof(*crtc_cfg), link); + /* Invalid: No primary plane */ plane_cfg =3D vkms_config_create_plane(config); vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); + err =3D vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); =20 /* Invalid: Multiple primary planes */ plane_cfg =3D vkms_config_create_plane(config); vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + err =3D vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + plane_cfg =3D vkms_config_create_plane(config); vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + err =3D vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); =20 /* Valid: One primary plane */ @@ -225,14 +249,50 @@ static void vkms_config_test_valid_plane_type(struct = kunit *test) /* Invalid: Multiple cursor planes */ plane_cfg =3D vkms_config_create_plane(config); vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + err =3D vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + plane_cfg =3D vkms_config_create_plane(config); vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + err =3D vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); =20 /* Valid: One primary and one cursor plane */ vkms_config_destroy_plane(plane_cfg); KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); =20 + /* Invalid: Second CRTC without primary plane */ + crtc_cfg =3D vkms_config_create_crtc(config); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: Second CRTC with a primary plane */ + plane_cfg =3D vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + err =3D 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 =3D vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + plane_cfg =3D list_first_entry(&config->planes, typeof(*plane_cfg), link); + crtc_cfg =3D 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); } =20 @@ -259,6 +319,131 @@ static void vkms_config_test_invalid_crtc_number(stru= ct kunit *test) vkms_config_destroy(config); } =20 +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 =3D vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + overlay_cfg =3D vkms_config_create_plane(config); + vkms_config_plane_set_type(overlay_cfg, DRM_PLANE_TYPE_OVERLAY); + primary_cfg =3D vkms_config_create_plane(config); + vkms_config_plane_set_type(primary_cfg, DRM_PLANE_TYPE_PRIMARY); + cursor_cfg =3D vkms_config_create_plane(config); + vkms_config_plane_set_type(cursor_cfg, DRM_PLANE_TYPE_CURSOR); + + crtc_cfg =3D vkms_config_create_crtc(config); + + /* No primary or cursor planes */ + KUNIT_EXPECT_NULL(test, vkms_config_crtc_primary_plane(config, crtc_cfg)); + KUNIT_EXPECT_NULL(test, vkms_config_crtc_cursor_plane(config, crtc_cfg)); + + /* Overlay plane, but no primary or cursor planes */ + err =3D 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 =3D vkms_config_plane_attach_crtc(primary_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + err =3D 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 =3D vkms_config_plane_attach_crtc(cursor_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); + KUNIT_EXPECT_PTR_EQ(test, + vkms_config_crtc_primary_plane(config, crtc_cfg), + primary_cfg); + KUNIT_EXPECT_PTR_EQ(test, + vkms_config_crtc_cursor_plane(config, crtc_cfg), + cursor_cfg); + + /* Detach primary and destroy cursor plane */ + vkms_config_plane_detach_crtc(overlay_cfg, crtc_cfg); + vkms_config_plane_detach_crtc(primary_cfg, crtc_cfg); + vkms_config_destroy_plane(cursor_cfg); + KUNIT_EXPECT_NULL(test, vkms_config_crtc_primary_plane(config, crtc_cfg)); + KUNIT_EXPECT_NULL(test, vkms_config_crtc_cursor_plane(config, crtc_cfg)); + + vkms_config_destroy(config); +} + +static void vkms_config_test_plane_get_possible_crtcs(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_plane *plane_cfg1, *plane_cfg2; + struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; + struct vkms_config_crtc *possible_crtc; + unsigned long idx =3D 0; + int n_crtcs =3D 0; + int err; + + config =3D vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + plane_cfg1 =3D vkms_config_create_plane(config); + plane_cfg2 =3D vkms_config_create_plane(config); + crtc_cfg1 =3D vkms_config_create_crtc(config); + crtc_cfg2 =3D vkms_config_create_crtc(config); + + /* No possible CRTCs */ + vkms_config_plane_for_each_possible_crtc(plane_cfg1, idx, possible_crtc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + vkms_config_plane_for_each_possible_crtc(plane_cfg2, idx, possible_crtc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + /* Plane 1 attached to CRTC 1 and 2 */ + err =3D vkms_config_plane_attach_crtc(plane_cfg1, crtc_cfg1); + KUNIT_EXPECT_EQ(test, err, 0); + err =3D vkms_config_plane_attach_crtc(plane_cfg1, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + vkms_config_plane_for_each_possible_crtc(plane_cfg1, idx, possible_crtc) { + n_crtcs++; + if (possible_crtc !=3D crtc_cfg1 && possible_crtc !=3D crtc_cfg2) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 2); + n_crtcs =3D 0; + + vkms_config_plane_for_each_possible_crtc(plane_cfg2, idx, possible_crtc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + /* Plane 1 attached to CRTC 1 and plane 2 to CRTC 2 */ + vkms_config_plane_detach_crtc(plane_cfg1, crtc_cfg2); + vkms_config_plane_for_each_possible_crtc(plane_cfg1, idx, possible_crtc) { + n_crtcs++; + if (possible_crtc !=3D crtc_cfg1) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 1); + n_crtcs =3D 0; + + err =3D vkms_config_plane_attach_crtc(plane_cfg2, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + vkms_config_plane_for_each_possible_crtc(plane_cfg2, idx, possible_crtc) { + n_crtcs++; + if (possible_crtc !=3D crtc_cfg2) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 1); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] =3D { KUNIT_CASE(vkms_config_test_empty_config), KUNIT_CASE_PARAM(vkms_config_test_default_config, @@ -267,7 +452,10 @@ static struct kunit_case vkms_config_test_cases[] =3D { KUNIT_CASE(vkms_config_test_get_crtcs), KUNIT_CASE(vkms_config_test_invalid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), + KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), KUNIT_CASE(vkms_config_test_invalid_crtc_number), + KUNIT_CASE(vkms_config_test_plane_attach_crtc), + KUNIT_CASE(vkms_config_test_plane_get_possible_crtcs), {} }; =20 diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms= _config.c index b08021e62c9f..d96f9e5f9b72 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 ena= ble_cursor, goto err_alloc; vkms_config_crtc_set_writeback(crtc_cfg, enable_writeback); =20 + if (vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg)) + goto err_alloc; + if (enable_overlay) { for (n =3D 0; n < NUM_OVERLAY_PLANES; n++) { plane_cfg =3D vkms_config_create_plane(config); if (IS_ERR(plane_cfg)) goto err_alloc; + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); + + if (vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg)) + goto err_alloc; } } =20 @@ -64,7 +71,11 @@ struct vkms_config *vkms_config_default_create(bool enab= le_cursor, plane_cfg =3D vkms_config_create_plane(config); if (IS_ERR(plane_cfg)) goto err_alloc; + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); + + if (vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg)) + goto err_alloc; } =20 return config; @@ -103,7 +114,8 @@ static bool valid_plane_number(struct vkms_config *conf= ig) return true; } =20 -static bool valid_plane_type(struct vkms_config *config) +static bool valid_planes_for_crtc(struct vkms_config *config, + struct vkms_config_crtc *crtc_cfg) { struct drm_device *dev =3D &config->dev->drm; struct vkms_config_plane *plane_cfg; @@ -111,24 +123,31 @@ static bool valid_plane_type(struct vkms_config *conf= ig) bool has_cursor_plane =3D false; =20 vkms_config_for_each_plane(config, plane_cfg) { + struct vkms_config_crtc *possible_crtc; + unsigned long idx =3D 0; enum drm_plane_type type; =20 type =3D vkms_config_plane_get_type(plane_cfg); =20 - if (type =3D=3D DRM_PLANE_TYPE_PRIMARY) { - if (has_primary_plane) { - drm_info(dev, "Multiple primary planes\n"); - return false; - } + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + if (possible_crtc !=3D crtc_cfg) + continue; =20 - has_primary_plane =3D true; - } else if (type =3D=3D DRM_PLANE_TYPE_CURSOR) { - if (has_cursor_plane) { - drm_info(dev, "Multiple cursor planes\n"); - return false; - } + if (type =3D=3D DRM_PLANE_TYPE_PRIMARY) { + if (has_primary_plane) { + drm_info(dev, "Multiple primary planes\n"); + return false; + } =20 - has_cursor_plane =3D true; + has_primary_plane =3D true; + } else if (type =3D=3D DRM_PLANE_TYPE_CURSOR) { + if (has_cursor_plane) { + drm_info(dev, "Multiple cursor planes\n"); + return false; + } + + has_cursor_plane =3D true; + } } } =20 @@ -140,6 +159,21 @@ static bool valid_plane_type(struct vkms_config *confi= g) return true; } =20 +static bool valid_plane_possible_crtcs(struct vkms_config *config) +{ + struct drm_device *dev =3D &config->dev->drm; + struct vkms_config_plane *plane_cfg; + + vkms_config_for_each_plane(config, plane_cfg) { + if (xa_empty(&plane_cfg->possible_crtcs)) { + drm_info(dev, "All planes must have at least one possible CRTC\n"); + return false; + } + } + + return true; +} + static bool valid_crtc_number(struct vkms_config *config) { struct drm_device *dev =3D &config->dev->drm; @@ -156,15 +190,22 @@ static bool valid_crtc_number(struct vkms_config *con= fig) =20 bool vkms_config_is_valid(struct vkms_config *config) { + struct vkms_config_crtc *crtc_cfg; + if (!valid_plane_number(config)) return false; =20 if (!valid_crtc_number(config)) return false; =20 - if (!valid_plane_type(config)) + if (!valid_plane_possible_crtcs(config)) return false; =20 + vkms_config_for_each_crtc(config, crtc_cfg) { + if (!valid_planes_for_crtc(config, crtc_cfg)) + return false; + } + return true; } =20 @@ -214,6 +255,7 @@ struct vkms_config_plane *vkms_config_create_plane(stru= ct vkms_config *config) return ERR_PTR(-ENOMEM); =20 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); + xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC); =20 list_add_tail(&plane_cfg->link, &config->planes); =20 @@ -222,10 +264,39 @@ struct vkms_config_plane *vkms_config_create_plane(st= ruct vkms_config *config) =20 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); } =20 +int __must_check vkms_config_plane_attach_crtc(struct vkms_config_plane *p= lane_cfg, + struct vkms_config_crtc *crtc_cfg) +{ + struct vkms_config_crtc *possible_crtc; + unsigned long idx =3D 0; + u32 crtc_idx =3D 0; + + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + if (possible_crtc =3D=3D 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 =3D 0; + + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + if (possible_crtc =3D=3D crtc_cfg) + xa_erase(&plane_cfg->possible_crtcs, idx); + } +} + struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *confi= g) { struct vkms_config_crtc *crtc_cfg; @@ -244,6 +315,54 @@ struct vkms_config_crtc *vkms_config_create_crtc(struc= t vkms_config *config) void vkms_config_destroy_crtc(struct vkms_config *config, struct vkms_config_crtc *crtc_cfg) { + struct vkms_config_plane *plane_cfg; + + vkms_config_for_each_plane(config, plane_cfg) + vkms_config_plane_detach_crtc(plane_cfg, crtc_cfg); + list_del(&crtc_cfg->link); kfree(crtc_cfg); } + +/** + * vkms_config_crtc_get_plane() - Return the first attached plane to a CRT= C with + * the specific type + * @config: Configuration containing the CRTC and the plane + * @crtc_cfg: Only find planes attached to this CRTC + * @type: Plane type to search + * + * Returns: + * The first plane found attached to @crtc_cfg with the type @type. + */ +static struct vkms_config_plane *vkms_config_crtc_get_plane(const struct v= kms_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 =3D 0; + + vkms_config_for_each_plane(config, plane_cfg) { + current_type =3D vkms_config_plane_get_type(plane_cfg); + + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + if (possible_crtc =3D=3D crtc_cfg && current_type =3D=3D 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_PRIMAR= Y); +} + +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 0f5937b44948..0fe0ded1d8e4 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -5,6 +5,7 @@ =20 #include #include +#include =20 #include "vkms_drv.h" =20 @@ -12,14 +13,12 @@ * struct vkms_config - General configuration for VKMS driver * * @dev_name: Name of the device - * @writeback: If true, a writeback buffer can be attached to the CRTC * @planes: List of planes configured for the device * @crtcs: List of CRTCs configured for the device * @dev: Used to store the current VKMS device. Only set when the device i= s instantiated. */ struct vkms_config { const char *dev_name; - bool writeback; struct list_head planes; struct list_head crtcs; struct vkms_device *dev; @@ -31,6 +30,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 vali= d. * It can be used to store a temporary reference to a VKMS plane d= uring * device creation. This pointer is not managed by the configurati= on and @@ -40,6 +40,7 @@ struct vkms_config_plane { struct list_head link; =20 enum drm_plane_type type; + struct xarray possible_crtcs; =20 /* Internal usage */ struct vkms_plane *plane; @@ -80,6 +81,16 @@ struct vkms_config_crtc { #define vkms_config_for_each_crtc(config, crtc_cfg) \ list_for_each_entry((crtc_cfg), &(config)->crtcs, link) =20 +/** + * vkms_config_plane_for_each_possible_crtc - Iterate over the vkms_config= _plane + * possible CRTCs + * @plane_cfg: &struct vkms_config_plane pointer + * @idx: Index of the cursor + * @possible_crtc: &struct vkms_config_crtc pointer used as cursor + */ +#define vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_= crtc) \ + xa_for_each(&(plane_cfg)->possible_crtcs, idx, (possible_crtc)) + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -187,6 +198,22 @@ vkms_config_plane_set_type(struct vkms_config_plane *p= lane_cfg, plane_cfg->type =3D type; } =20 +/** + * 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 *p= lane_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_create_crtc() - Add a new CRTC configuration * @config: Configuration to add the CRTC to @@ -227,4 +254,32 @@ vkms_config_crtc_set_writeback(struct vkms_config_crtc= *crtc_cfg, crtc_cfg->writeback =3D writeback; } =20 +/** + * vkms_config_crtc_primary_plane() - Return the primary plane for a CRTC + * @config: Configuration containing the CRTC + * @crtc_config: Target CRTC + * + * Note that, if multiple primary planes are found, the first one is retur= ned. + * In this case, the configuration will be invalid. See vkms_config_is_val= id(). + * + * Returns: + * The primary plane or NULL if none is assigned yet. + */ +struct vkms_config_plane *vkms_config_crtc_primary_plane(const struct vkms= _config *config, + struct vkms_config_crtc *crtc_cfg); + +/** + * vkms_config_crtc_cursor_plane() - Return the cursor plane for a CRTC + * @config: Configuration containing the CRTC + * @crtc_config: Target CRTC + * + * Note that, if multiple cursor planes are found, the first one is return= ed. + * In this case, the configuration will be invalid. See vkms_config_is_val= id(). + * + * 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 08ea691db299..f63bc8e3014b 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -10,9 +10,8 @@ int vkms_output_init(struct vkms_device *vkmsdev) struct drm_device *dev =3D &vkmsdev->drm; struct vkms_connector *connector; struct drm_encoder *encoder; - struct vkms_output *output; - struct vkms_plane *primary =3D NULL, *cursor =3D NULL; struct vkms_config_plane *plane_cfg; + struct vkms_config_crtc *crtc_cfg; int ret; int writeback; =20 @@ -29,18 +28,37 @@ int vkms_output_init(struct vkms_device *vkmsdev) DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n"); return PTR_ERR(plane_cfg->plane); } + } + + vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) { + struct vkms_config_plane *primary, *cursor; + + primary =3D vkms_config_crtc_primary_plane(vkmsdev->config, crtc_cfg); + cursor =3D vkms_config_crtc_cursor_plane(vkmsdev->config, crtc_cfg); =20 - if (type =3D=3D DRM_PLANE_TYPE_PRIMARY) - primary =3D plane_cfg->plane; - else if (type =3D=3D DRM_PLANE_TYPE_CURSOR) - cursor =3D plane_cfg->plane; + crtc_cfg->crtc =3D vkms_crtc_init(dev, &primary->plane->base, + cursor ? &cursor->plane->base : NULL); + if (IS_ERR(crtc_cfg->crtc)) { + DRM_ERROR("Failed to allocate CRTC\n"); + return PTR_ERR(crtc_cfg->crtc); + } + + /* Initialize the writeback component */ + if (vkms_config_crtc_get_writeback(crtc_cfg)) { + writeback =3D vkms_enable_writeback_connector(vkmsdev, crtc_cfg->crtc); + if (writeback) + DRM_ERROR("Failed to init writeback connector\n"); + } } =20 - output =3D vkms_crtc_init(dev, &primary->base, - cursor ? &cursor->base : NULL); - if (IS_ERR(output)) { - DRM_ERROR("Failed to allocate CRTC\n"); - return PTR_ERR(output); + vkms_config_for_each_plane(vkmsdev->config, plane_cfg) { + struct vkms_config_crtc *possible_crtc; + unsigned long idx =3D 0; + + vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { + plane_cfg->plane->base.possible_crtcs |=3D + drm_crtc_mask(&possible_crtc->crtc->crtc); + } } =20 connector =3D vkms_connector_init(vkmsdev); @@ -60,7 +78,9 @@ int vkms_output_init(struct vkms_device *vkmsdev) DRM_ERROR("Failed to init encoder\n"); return ret; } - encoder->possible_crtcs =3D drm_crtc_mask(&output->crtc); + + vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) + encoder->possible_crtcs =3D drm_crtc_mask(&crtc_cfg->crtc->crtc); =20 /* Attach the encoder and the connector */ ret =3D drm_connector_attach_encoder(&connector->base, encoder); @@ -69,13 +89,6 @@ int vkms_output_init(struct vkms_device *vkmsdev) return ret; } =20 - /* Initialize the writeback component */ - if (vkmsdev->config->writeback) { - writeback =3D vkms_enable_writeback_connector(vkmsdev, output); - if (writeback) - DRM_ERROR("Failed to init writeback connector\n"); - } - drm_mode_config_reset(dev); =20 return ret; --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F30221480E for ; Tue, 11 Feb 2025 11:09:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272177; cv=none; b=uqdKUjwIM5U6Ame8fwoCZts79E7sXdNwH8L+ZxWEuJX11jmMZXkpJXs+sKCfoth3tcq/E53oRx8qLZvcW2LPbYrtLYLppPo7uyUPsbN97Zpp+RnyXbQwBHOhlav9+4L733U3qFMn3ItICio1ktDt4G58GfTYQPQiBv27xVY1rI4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272177; c=relaxed/simple; bh=PVEPm1kY/idMTDrE0VEvdUMBe89RNDz0ttex8bvxbys=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=J1/IdGGeL9VZFWKkMt2EOKIfq8QE5DjKP167x14M9B7zj9g7AOBoiWBta0hT3npP6p8yKIAtys2KT3jiWlos+Ys91Hjf91OyqAdz8nshPHFE071mT9jcj1JUUXrBHxZI2oyNKV1BM0TTaQ+zTOu0TNq3qXAbLSnE67HWyzL+rsE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=nCZs64Hn; arc=none smtp.client-ip=209.85.128.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nCZs64Hn" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-439473da55aso11899065e9.2 for ; Tue, 11 Feb 2025 03:09:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272174; x=1739876974; darn=vger.kernel.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=XRXCP6F4bBplXevntCwP41QU632J1UrvDIWVEgZMPA0=; b=nCZs64Hnns0oElFmu5dC+CTqNoxzBQSoSZ9h9Qq/abNH2J7QbIYhAHgPmZ9ZmnZb/E GYLhH++lSW/buIb4d9J6m+pJwf0Jw8lTuxbx/wnGLb8RGp6WFxidWTSputreR/4/KT8g ygLlP9awSGMARULVa2TwlmZ2Rv/4f2Olegv8dn2NuQKYiI09U7hMCGCJ1Fm4MIwvNV7r aMu34G3D14GdtoIkCYgNc+ivoEqQVlOTIMyTJaCOQLm0O0D8jzUZxHGHULoih08TAjSW Pm/813U2y3eai01NDbreFXTz/PRp4+lCxEZgH58fPWuFUhCRKDMt4CC5Ggo0tiXraee+ gjUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272174; x=1739876974; 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=XRXCP6F4bBplXevntCwP41QU632J1UrvDIWVEgZMPA0=; b=AW4jr4FLYeM1w5d2VT2o6O85uVk/ma7rINM9JeOzid7dVL/vWgApfHFkUBp7yFgxoB KyXaHOeglB03XzjKGpc6mrOcMJCScKuyjaIWQIUhfkn6LE5Mjt9Ob227YJJPBS7ipIGT LGW4CkOrXv0Xjju0HSXVCeizIdf76kUv1b4KzItmaNX01pT12AxX8MnGVYcwrzQzpg6g 9pvtQDiTUizmKzCFcpmQcjblIg1n/3CWzCqUty0arS6RGmPInS4jfQPnOWI1hkUO/VeW enKLpHTaAqMN3UWGbyOvBu+eQNfHMquJ4n6mzRX7GTd//0WS/EvAdtiJOfw+Jbl7hqoK vrsA== X-Forwarded-Encrypted: i=1; AJvYcCWLbl2gHTIz/VfHupG9v3lF3p9FizUW183KMixVESFGvu1fuGHY8mx3qew/YReqaEPl4xZn7UKw7cCppQY=@vger.kernel.org X-Gm-Message-State: AOJu0YyDKVfLjBKp5LMs/LHG663lWLeBOV8qgYqhYVCCFHp2Ta2sHLd3 hr1gGwpZXKrLOPN24zdyO/ZDEjuqiYBVB2RBU3U5A365iwdJ1DLfr8DE+siS X-Gm-Gg: ASbGncvE6ddpnUM6mm4NQA5goulAq0GxeQaBWNOO9EUT+9xjGZ+KrSMHtr5nEBCaCzB YRdBQ2+X06Y2MNkFBxB026hNyHR0v7xXsaRoBPdQLBC7yPp07rTjH7aM/Sqm3Vx3dEMwQqTKU40 +RFqM7n2wepKGsSJ2GFGr56hF7D2jfXnuhMkAqsANklxpNiLBIavwSHkpKnSCWUu76S3xnh1Ltv zX+i2JRBI1R5E5ZlO2HC86N8edYnrmT+gscc7DaVL1mP+u3P8BfpFSt6w8NKRQWi+EeQE67Cl98 5+7BU8m5vxwCx6J9 X-Google-Smtp-Source: AGHT+IHaEHjzly/enWLmlI6mFAusxfeBe2nWWZ8jB4NpsboW241fvKEcbn9nV3lJGEXBPuSeAXgNhA== X-Received: by 2002:a05:600c:a45:b0:434:a923:9310 with SMTP id 5b1f17b1804b1-439249913a5mr152047525e9.15.1739272173514; Tue, 11 Feb 2025 03:09:33 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:32 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 12/15] drm/vkms: Allow to configure multiple encoders Date: Tue, 11 Feb 2025 12:09:09 +0100 Message-ID: <20250211110912.15409-13-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a list of encoders to vkms_config and helper functions to add and remove as many encoders as wanted. For backwards compatibility, add one encoder to the default configuration. A future patch will allow to attach encoders and CRTCs, but for the moment there are no changes in the way the output is configured. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 73 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 51 +++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 44 +++++++++++ 4 files changed, 169 insertions(+) diff --git a/.clang-format b/.clang-format index 6f944fa39841..c355a2f58eed 100644 --- a/.clang-format +++ b/.clang-format @@ -691,6 +691,7 @@ ForEachMacros: - 'v4l2_m2m_for_each_src_buf_safe' - 'virtio_device_for_each_vq' - 'vkms_config_for_each_crtc' + - 'vkms_config_for_each_encoder' - 'vkms_config_for_each_plane' - 'vkms_config_plane_for_each_possible_crtc' - 'while_for_each_ftrace_op' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index 505eebb07a52..0bb76a1e6c79 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 *t= est) =20 KUNIT_EXPECT_TRUE(test, list_empty(&config->planes)); KUNIT_EXPECT_TRUE(test, list_empty(&config->crtcs)); + KUNIT_EXPECT_TRUE(test, list_empty(&config->encoders)); =20 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); =20 @@ -99,6 +100,9 @@ static void vkms_config_test_default_config(struct kunit= *test) KUNIT_EXPECT_EQ(test, n_possible_crtcs, 1); } =20 + /* Encoders */ + KUNIT_EXPECT_EQ(test, list_count_nodes(&config->encoders), 1); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); =20 vkms_config_destroy(config); @@ -184,6 +188,50 @@ static void vkms_config_test_get_crtcs(struct kunit *t= est) vkms_config_destroy(config); } =20 +static void vkms_config_test_get_encoders(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_encoder *encoder_cfg; + struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; + int n_encoders =3D 0; + + config =3D vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + vkms_config_for_each_encoder(config, encoder_cfg) + n_encoders++; + KUNIT_ASSERT_EQ(test, n_encoders, 0); + + encoder_cfg1 =3D vkms_config_create_encoder(config); + vkms_config_for_each_encoder(config, encoder_cfg) { + n_encoders++; + if (encoder_cfg !=3D encoder_cfg1) + KUNIT_FAIL(test, "Unexpected encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 1); + n_encoders =3D 0; + + encoder_cfg2 =3D vkms_config_create_encoder(config); + vkms_config_for_each_encoder(config, encoder_cfg) { + n_encoders++; + if (encoder_cfg !=3D encoder_cfg1 && encoder_cfg !=3D encoder_cfg2) + KUNIT_FAIL(test, "Unexpected encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 2); + n_encoders =3D 0; + + vkms_config_destroy_encoder(config, encoder_cfg2); + vkms_config_for_each_encoder(config, encoder_cfg) { + n_encoders++; + if (encoder_cfg !=3D encoder_cfg1) + KUNIT_FAIL(test, "Unexpected encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 1); + n_encoders =3D 0; + + vkms_config_destroy(config); +} + static void vkms_config_test_invalid_plane_number(struct kunit *test) { struct vkms_config *config; @@ -319,6 +367,29 @@ static void vkms_config_test_invalid_crtc_number(struc= t kunit *test) vkms_config_destroy(config); } =20 +static void vkms_config_test_invalid_encoder_number(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_encoder *encoder_cfg; + int n; + + config =3D vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + /* Invalid: No encoders */ + encoder_cfg =3D 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 =3D 0; n <=3D 32; n++) + vkms_config_create_encoder(config); + + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static void vkms_config_test_plane_attach_crtc(struct kunit *test) { struct vkms_config *config; @@ -450,10 +521,12 @@ static struct kunit_case vkms_config_test_cases[] =3D= { default_config_gen_params), KUNIT_CASE(vkms_config_test_get_planes), KUNIT_CASE(vkms_config_test_get_crtcs), + KUNIT_CASE(vkms_config_test_get_encoders), KUNIT_CASE(vkms_config_test_invalid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), KUNIT_CASE(vkms_config_test_invalid_crtc_number), + KUNIT_CASE(vkms_config_test_invalid_encoder_number), KUNIT_CASE(vkms_config_test_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 d96f9e5f9b72..0cf6105fe743 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_na= me) =20 INIT_LIST_HEAD(&config->planes); INIT_LIST_HEAD(&config->crtcs); + INIT_LIST_HEAD(&config->encoders); =20 return config; } @@ -34,6 +35,7 @@ struct vkms_config *vkms_config_default_create(bool enabl= e_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; =20 config =3D vkms_config_create(DEFAULT_DEVICE_NAME); @@ -78,6 +80,10 @@ struct vkms_config *vkms_config_default_create(bool enab= le_cursor, goto err_alloc; } =20 + encoder_cfg =3D vkms_config_create_encoder(config); + if (IS_ERR(encoder_cfg)) + goto err_alloc; + return config; =20 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; =20 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); =20 + list_for_each_entry_safe(encoder_cfg, encoder_tmp, &config->encoders, lin= k) + vkms_config_destroy_encoder(config, encoder_cfg); + kfree_const(config->dev_name); kfree(config); } @@ -188,6 +198,20 @@ static bool valid_crtc_number(struct vkms_config *conf= ig) return true; } =20 +static bool valid_encoder_number(struct vkms_config *config) +{ + struct drm_device *dev =3D &config->dev->drm; + size_t n_encoders; + + n_encoders =3D list_count_nodes(&config->encoders); + if (n_encoders <=3D 0 || n_encoders >=3D 32) { + drm_info(dev, "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; @@ -198,6 +222,9 @@ bool vkms_config_is_valid(struct vkms_config *config) if (!valid_crtc_number(config)) return false; =20 + if (!valid_encoder_number(config)) + return false; + if (!valid_plane_possible_crtcs(config)) return false; =20 @@ -217,6 +244,7 @@ static int vkms_config_show(struct seq_file *m, void *d= ata) const char *dev_name; struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; + struct vkms_config_encoder *encoder_cfg; =20 dev_name =3D vkms_config_get_device_name((struct vkms_config *)vkmsdev->c= onfig); seq_printf(m, "dev_name=3D%s\n", dev_name); @@ -233,6 +261,9 @@ static int vkms_config_show(struct seq_file *m, void *d= ata) vkms_config_crtc_get_writeback(crtc_cfg)); } =20 + vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) + seq_puts(m, "encoder\n"); + return 0; } =20 @@ -366,3 +397,23 @@ struct vkms_config_plane *vkms_config_crtc_cursor_plan= e(const struct vkms_config { return vkms_config_crtc_get_plane(config, crtc_cfg, DRM_PLANE_TYPE_CURSOR= ); } + +struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config = *config) +{ + struct vkms_config_encoder *encoder_cfg; + + encoder_cfg =3D 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 0fe0ded1d8e4..2ba80c4c9ce5 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -15,12 +15,14 @@ * @dev_name: Name of the device * @planes: List of planes configured for the device * @crtcs: List of CRTCs configured for the device + * @encoders: List of encoders configured for the device * @dev: Used to store the current VKMS device. Only set when the device i= s instantiated. */ struct vkms_config { const char *dev_name; struct list_head planes; struct list_head crtcs; + struct list_head encoders; struct vkms_device *dev; }; =20 @@ -65,6 +67,22 @@ struct vkms_config_crtc { struct vkms_output *crtc; }; =20 +/** + * struct vkms_config_encoder + * + * @link: Link to the others encoders in vkms_config + * @encoder: Internal usage. This pointer should never be considered as va= lid. + * It can be used to store a temporary reference to a VKMS encod= er + * 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_for_each_plane - Iterate over the vkms_config planes * @config: &struct vkms_config pointer @@ -81,6 +99,14 @@ struct vkms_config_crtc { #define vkms_config_for_each_crtc(config, crtc_cfg) \ list_for_each_entry((crtc_cfg), &(config)->crtcs, link) =20 +/** + * vkms_config_for_each_encoder - Iterate over the vkms_config encoders + * @config: &struct vkms_config pointer + * @encoder_cfg: &struct vkms_config_encoder pointer used as cursor + */ +#define vkms_config_for_each_encoder(config, encoder_cfg) \ + list_for_each_entry((encoder_cfg), &(config)->encoders, link) + /** * vkms_config_plane_for_each_possible_crtc - Iterate over the vkms_config= _plane * possible CRTCs @@ -282,4 +308,22 @@ struct vkms_config_plane *vkms_config_crtc_primary_pla= ne(const struct vkms_confi struct vkms_config_plane *vkms_config_crtc_cursor_plane(const struct vkms_= config *config, struct vkms_config_crtc *crtc_cfg); =20 +/** + * vkms_config_create_encoder() - Add a new encoder configuration + * @config: Configuration to add the encoder to + * + * Returns: + * The new encoder configuration or an error. Call vkms_config_destroy_enc= oder() + * to free the returned encoder configuration. + */ +struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config = *config); + +/** + * vkms_config_destroy_encoder() - Remove and free a encoder configuration + * @config: Configuration to remove the encoder from + * @encoder_cfg: Encoder configuration to destroy + */ +void vkms_config_destroy_encoder(struct vkms_config *config, + struct vkms_config_encoder *encoder_cfg); + #endif /* _VKMS_CONFIG_H_ */ --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3912D215177 for ; Tue, 11 Feb 2025 11:09:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272179; cv=none; b=UCplEBLn64KCH4DbdPrzY1w9gKZ3LYOMpP5F8f+nhSxLl8DO+GX+gMwf/PUMkUBrFOfppGfENOxS810ch9Tw30uEdTpW5OJO+aorOUXaB4DAMDP1c2FIjnly+bA3DbAlMnUNsc7iyqKg2trdZApEOTvjfcr9KlsiwqNOK8OfDjI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272179; c=relaxed/simple; bh=oeo4bG+/eJ7XtJBvRaAecKqlmOofWXLDt07i5UsHrCk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=oSXjUU7u7BBx+x0AHU8KktfFb9vnAowltYRVrx1qaXUEuAQrWrDkAeMkzG8aRP2tJ/z1eEzVuLZXEmLU8+0JI1qbz5l+2a7ufF8MDQaOwhjvA5HzBHgoxb8+ZcR4eIeRynGl9qh1S0yn7zEsleTavJrpG2G5DrKsQ5rWltRmqEU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kc+v9fR4; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kc+v9fR4" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-4394345e4d5so14992745e9.0 for ; Tue, 11 Feb 2025 03:09:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272175; x=1739876975; darn=vger.kernel.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=cBb49MDgu+iAkUP/6QQB0E1tqf2rFoHfPXGl3p4Zkas=; b=kc+v9fR4fiUiC0uJz7BW4eGcHq2dEyr5LeuNv2tSbLIT4OcYoTepP7B5OecL2uL30w FCXIHY4v/rhMaDKyPj0QF4Y7weDI9jhs3lxd90xhN0Sf945Yjz6zG7gF8vOhoizXsVEN cbBLRUa+RBH30ejdz+YhD7XS9SwxkPF2J0VoPxgUKsyRsVIDN1BELoYLCQGIvyNEGOf5 5TM212U6oLTitBDg0FWTwqVsDmDbCEHjb+NkHf/LBuU9Gd1n0vu8d8jw7l316FoUdL1D iV4Ezsy5i6dUWgUZRUAOVEa3NVwXCNUSHUrygXjQBBX4B38ndG8a2dd4WDI+ji/QBAyG bZHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272175; x=1739876975; 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=cBb49MDgu+iAkUP/6QQB0E1tqf2rFoHfPXGl3p4Zkas=; b=oE7gjao5x2h5nsfFQOFBQPB74jcfXr6mItMYOPlY/hbd3/OMuvu9EzDrt+AULXK/t0 oONXFOUpcLa/wq1B1R4VZXQ1FZFxnHljT8RclLlDgQkGHMOyanV1rg+FjfSaWSH05RRv ibILDVHWe2OVdgYcgdmGEc7lhTxicDijzehfQsIItSvY5mmgrsdkOeXEXQksEm6Ww1tq g/0prrsK1CKRiQIyQVae5xXW5y8z6HEpH9Lt7B0jnL61tFJqNtI6+aQyHhcw2det6bQc Jou03p/3hzi31h1n1hfS0wt/gjDLpqOBEISrjiEMU9LvT2OQQXwPcmTcDilqKDJIqe2p 9Y5Q== X-Forwarded-Encrypted: i=1; AJvYcCVYPxc4oyEMDvpPSBUbPzgXQETxxckagaAQLIXoEIBClOCvZIkrCdh1YzJv/dW6wJmVtjDgzQnmnqMAt6M=@vger.kernel.org X-Gm-Message-State: AOJu0Yx74CULZPckekuhHgoKNgnx3oCB9ExLUP6OvLcHCX6wWvsSiT+S Nl7mwp03N3P68HJOr4Yt9tJYRwPljBLNimtPz0gT+KMGqDyKeENc X-Gm-Gg: ASbGncuRldePQYF1NOsKY3Sewu3+HaUQqgwOhm+maLGUMTmGmNbblYnvyz3PtW4nrnE 17xmk1MtvIZTE7W8//giN8s2CP0v6OzO78eBjvKxpi1SSFPmsE/oVY/cRDMIibDzxT5f86HijkT JpXrfqzDaVpaptNou0W71ZPOLqM2DqOq6knoZceA1yDRuon5+oy12i0pe1a0E2z9s3cjzlQxMPT SMhFwmYg3jsOg3wZVwDSLymCiOtMinC7r7uGjaakMe6BoYygt7gFt7egXdSprvHD04JKCLnGpgh PcgdiSuwsJNbLWyS X-Google-Smtp-Source: AGHT+IHQk/Fn1ZUrMEagdpMTyL2U3IoU4CkvypqpCJ0kXIm/qhhmQ+g6UNzGxOSySShebpsPgP1VuQ== X-Received: by 2002:a5d:64a6:0:b0:38d:ddf2:aff5 with SMTP id ffacd0b85a97d-38dddf2b2dbmr7971886f8f.3.1739272175222; Tue, 11 Feb 2025 03:09:35 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:34 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 13/15] drm/vkms: Allow to attach encoders and CRTCs Date: Tue, 11 Feb 2025 12:09:10 +0100 Message-ID: <20250211110912.15409-14-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a list of possible CRTCs to the encoder configuration and helpers to attach and detach them. Now that the default configuration has its encoder and CRTC correctly attached, configure the output following the configuration. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 115 ++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 77 ++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 29 +++++ drivers/gpu/drm/vkms/vkms_output.c | 49 +++++--- 5 files changed, 251 insertions(+), 20 deletions(-) diff --git a/.clang-format b/.clang-format index c355a2f58eed..5d21c0e4edbd 100644 --- a/.clang-format +++ b/.clang-format @@ -693,6 +693,7 @@ ForEachMacros: - 'vkms_config_for_each_crtc' - 'vkms_config_for_each_encoder' - 'vkms_config_for_each_plane' + - 'vkms_config_encoder_for_each_possible_crtc' - 'vkms_config_plane_for_each_possible_crtc' - 'while_for_each_ftrace_op' - 'xa_for_each' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index 0bb76a1e6c79..7458d175acb6 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -260,6 +260,7 @@ static void vkms_config_test_valid_plane_type(struct ku= nit *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; =20 config =3D vkms_config_default_create(false, false, false); @@ -313,6 +314,9 @@ static void vkms_config_test_valid_plane_type(struct ku= nit *test) =20 /* Invalid: Second CRTC without primary plane */ crtc_cfg =3D vkms_config_create_crtc(config); + encoder_cfg =3D vkms_config_create_encoder(config); + err =3D vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg); + KUNIT_EXPECT_EQ(test, err, 0); KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); =20 /* Valid: Second CRTC with a primary plane */ @@ -390,6 +394,51 @@ static void vkms_config_test_invalid_encoder_number(st= ruct kunit *test) vkms_config_destroy(config); } =20 +static void vkms_config_test_valid_encoder_possible_crtcs(struct kunit *te= st) +{ + 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 =3D vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + crtc_cfg1 =3D list_first_entry(&config->crtcs, typeof(*crtc_cfg1), link); + + /* Invalid: Encoder without a possible CRTC */ + encoder_cfg =3D vkms_config_create_encoder(config); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Valid: Second CRTC with shared encoder */ + crtc_cfg2 =3D vkms_config_create_crtc(config); + + plane_cfg =3D vkms_config_create_plane(config); + vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); + err =3D vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + err =3D vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg1); + KUNIT_EXPECT_EQ(test, err, 0); + + err =3D 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; @@ -515,6 +564,70 @@ static void vkms_config_test_plane_get_possible_crtcs(= struct kunit *test) vkms_config_destroy(config); } =20 +static void vkms_config_test_encoder_get_possible_crtcs(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; + struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; + struct vkms_config_crtc *possible_crtc; + unsigned long idx =3D 0; + int n_crtcs =3D 0; + int err; + + config =3D vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + encoder_cfg1 =3D vkms_config_create_encoder(config); + encoder_cfg2 =3D vkms_config_create_encoder(config); + crtc_cfg1 =3D vkms_config_create_crtc(config); + crtc_cfg2 =3D vkms_config_create_crtc(config); + + /* No possible CRTCs */ + vkms_config_encoder_for_each_possible_crtc(encoder_cfg1, idx, possible_cr= tc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg2, idx, possible_cr= tc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + /* Encoder 1 attached to CRTC 1 and 2 */ + err =3D vkms_config_encoder_attach_crtc(encoder_cfg1, crtc_cfg1); + KUNIT_EXPECT_EQ(test, err, 0); + err =3D vkms_config_encoder_attach_crtc(encoder_cfg1, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg1, idx, possible_cr= tc) { + n_crtcs++; + if (possible_crtc !=3D crtc_cfg1 && possible_crtc !=3D crtc_cfg2) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 2); + n_crtcs =3D 0; + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg2, idx, possible_cr= tc) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + + /* Encoder 1 attached to CRTC 1 and encoder 2 to CRTC 2 */ + vkms_config_encoder_detach_crtc(encoder_cfg1, crtc_cfg2); + vkms_config_encoder_for_each_possible_crtc(encoder_cfg1, idx, possible_cr= tc) { + n_crtcs++; + if (possible_crtc !=3D crtc_cfg1) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 1); + n_crtcs =3D 0; + + err =3D vkms_config_encoder_attach_crtc(encoder_cfg2, crtc_cfg2); + KUNIT_EXPECT_EQ(test, err, 0); + vkms_config_encoder_for_each_possible_crtc(encoder_cfg2, idx, possible_cr= tc) { + n_crtcs++; + if (possible_crtc !=3D crtc_cfg2) + KUNIT_FAIL(test, "Unexpected possible CRTC"); + } + KUNIT_ASSERT_EQ(test, n_crtcs, 1); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] =3D { KUNIT_CASE(vkms_config_test_empty_config), KUNIT_CASE_PARAM(vkms_config_test_default_config, @@ -527,8 +640,10 @@ static struct kunit_case vkms_config_test_cases[] =3D { KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), KUNIT_CASE(vkms_config_test_invalid_crtc_number), KUNIT_CASE(vkms_config_test_invalid_encoder_number), + KUNIT_CASE(vkms_config_test_valid_encoder_possible_crtcs), KUNIT_CASE(vkms_config_test_plane_attach_crtc), KUNIT_CASE(vkms_config_test_plane_get_possible_crtcs), + KUNIT_CASE(vkms_config_test_encoder_get_possible_crtcs), {} }; =20 diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms= _config.c index 0cf6105fe743..f727c0009489 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 enabl= e_cursor, if (IS_ERR(encoder_cfg)) goto err_alloc; =20 + if (vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg)) + goto err_alloc; + return config; =20 err_alloc: @@ -212,6 +215,42 @@ static bool valid_encoder_number(struct vkms_config *c= onfig) return true; } =20 +static bool valid_encoder_possible_crtcs(struct vkms_config *config) +{ + struct drm_device *dev =3D &config->dev->drm; + struct vkms_config_crtc *crtc_cfg; + struct vkms_config_encoder *encoder_cfg; + + vkms_config_for_each_encoder(config, encoder_cfg) { + if (xa_empty(&encoder_cfg->possible_crtcs)) { + drm_info(dev, "All encoders must have at least one possible CRTC\n"); + return false; + } + } + + vkms_config_for_each_crtc(config, crtc_cfg) { + bool crtc_has_encoder =3D false; + + vkms_config_for_each_encoder(config, encoder_cfg) { + struct vkms_config_crtc *possible_crtc; + unsigned long idx =3D 0; + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg, + idx, possible_crtc) { + if (possible_crtc =3D=3D crtc_cfg) + crtc_has_encoder =3D true; + } + } + + if (!crtc_has_encoder) { + drm_info(dev, "All CRTCs must have at least one possible encoder\n"); + return false; + } + } + + return true; +} + bool vkms_config_is_valid(struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -233,6 +272,9 @@ bool vkms_config_is_valid(struct vkms_config *config) return false; } =20 + if (!valid_encoder_possible_crtcs(config)) + return false; + return true; } =20 @@ -347,10 +389,14 @@ void vkms_config_destroy_crtc(struct vkms_config *con= fig, struct vkms_config_crtc *crtc_cfg) { struct vkms_config_plane *plane_cfg; + struct vkms_config_encoder *encoder_cfg; =20 vkms_config_for_each_plane(config, plane_cfg) vkms_config_plane_detach_crtc(plane_cfg, crtc_cfg); =20 + vkms_config_for_each_encoder(config, encoder_cfg) + vkms_config_encoder_detach_crtc(encoder_cfg, crtc_cfg); + list_del(&crtc_cfg->link); kfree(crtc_cfg); } @@ -406,6 +452,8 @@ struct vkms_config_encoder *vkms_config_create_encoder(= struct vkms_config *confi if (!encoder_cfg) return ERR_PTR(-ENOMEM); =20 + xa_init_flags(&encoder_cfg->possible_crtcs, XA_FLAGS_ALLOC); + list_add_tail(&encoder_cfg->link, &config->encoders); =20 return encoder_cfg; @@ -414,6 +462,35 @@ struct vkms_config_encoder *vkms_config_create_encoder= (struct vkms_config *confi void vkms_config_destroy_encoder(struct vkms_config *config, struct vkms_config_encoder *encoder_cfg) { + 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_encode= r *encoder_cfg, + struct vkms_config_crtc *crtc_cfg) +{ + struct vkms_config_crtc *possible_crtc; + unsigned long idx =3D 0; + u32 crtc_idx =3D 0; + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possible_crt= c) { + if (possible_crtc =3D=3D 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_c= fg, + struct vkms_config_crtc *crtc_cfg) +{ + struct vkms_config_crtc *possible_crtc; + unsigned long idx =3D 0; + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possible_crt= c) { + if (possible_crtc =3D=3D crtc_cfg) + xa_erase(&encoder_cfg->possible_crtcs, idx); + } +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms= _config.h index 2ba80c4c9ce5..28c24afebe1e 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -71,6 +71,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 va= lid. * It can be used to store a temporary reference to a VKMS encod= er * during device creation. This pointer is not managed by the @@ -79,6 +80,8 @@ struct vkms_config_crtc { struct vkms_config_encoder { struct list_head link; =20 + struct xarray possible_crtcs; + /* Internal usage */ struct drm_encoder *encoder; }; @@ -117,6 +120,16 @@ struct vkms_config_encoder { #define vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_= crtc) \ xa_for_each(&(plane_cfg)->possible_crtcs, idx, (possible_crtc)) =20 +/** + * vkms_config_encoder_for_each_possible_crtc - Iterate over the + * vkms_config_encoder possible CRTCs + * @encoder_cfg: &struct vkms_config_encoder pointer + * @idx: Index of the cursor + * @possible_crtc: &struct vkms_config_crtc pointer used as cursor + */ +#define vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possi= ble_crtc) \ + xa_for_each(&(encoder_cfg)->possible_crtcs, idx, (possible_crtc)) + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -326,4 +339,20 @@ struct vkms_config_encoder *vkms_config_create_encoder= (struct vkms_config *confi void vkms_config_destroy_encoder(struct vkms_config *config, struct vkms_config_encoder *encoder_cfg); =20 +/** + * 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_encode= r *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_c= fg, + struct vkms_config_crtc *crtc_cfg); + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms= _output.c index f63bc8e3014b..8920d6b5d105 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -9,9 +9,9 @@ int vkms_output_init(struct vkms_device *vkmsdev) { struct drm_device *dev =3D &vkmsdev->drm; struct vkms_connector *connector; - struct drm_encoder *encoder; struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; + struct vkms_config_encoder *encoder_cfg; int ret; int writeback; =20 @@ -61,32 +61,41 @@ int vkms_output_init(struct vkms_device *vkmsdev) } } =20 + vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) { + struct vkms_config_crtc *possible_crtc; + unsigned long idx =3D 0; + + encoder_cfg->encoder =3D drmm_kzalloc(dev, sizeof(*encoder_cfg->encoder)= , GFP_KERNEL); + if (!encoder_cfg->encoder) { + DRM_ERROR("Failed to allocate encoder\n"); + return -ENOMEM; + } + ret =3D drmm_encoder_init(dev, encoder_cfg->encoder, NULL, + DRM_MODE_ENCODER_VIRTUAL, NULL); + if (ret) { + DRM_ERROR("Failed to init encoder\n"); + return ret; + } + + vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possible_cr= tc) { + encoder_cfg->encoder->possible_crtcs |=3D + drm_crtc_mask(&possible_crtc->crtc->crtc); + } + } + connector =3D vkms_connector_init(vkmsdev); if (IS_ERR(connector)) { DRM_ERROR("Failed to init connector\n"); return PTR_ERR(connector); } =20 - encoder =3D drmm_kzalloc(dev, sizeof(*encoder), GFP_KERNEL); - if (!encoder) { - DRM_ERROR("Failed to allocate encoder\n"); - return -ENOMEM; - } - ret =3D drmm_encoder_init(dev, encoder, NULL, - DRM_MODE_ENCODER_VIRTUAL, NULL); - if (ret) { - DRM_ERROR("Failed to init encoder\n"); - return ret; - } - - vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) - encoder->possible_crtcs =3D drm_crtc_mask(&crtc_cfg->crtc->crtc); - /* Attach the encoder and the connector */ - ret =3D drm_connector_attach_encoder(&connector->base, encoder); - if (ret) { - DRM_ERROR("Failed to attach connector to encoder\n"); - return ret; + vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) { + ret =3D drm_connector_attach_encoder(&connector->base, encoder_cfg->enco= der); + if (ret) { + DRM_ERROR("Failed to attach connector to encoder\n"); + return ret; + } } =20 drm_mode_config_reset(dev); --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5FD2D217677 for ; Tue, 11 Feb 2025 11:09:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272180; cv=none; b=MjN3KpJeOtqc0qQ+SMshbLrEkQJKyvTLxpmeEapl0FZyzXvJnpcOyQiNBUSAZSNud5PuITrqJrp79cEmaq0EBxq2HdT7vOxRVEqKUPCGAde3I+I6jCuoIHCtRcGgRL5g/YGMMJmvlLG9kqtpo2jY/xBekiALXqijtXZDpeeu2jY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272180; c=relaxed/simple; bh=B5t9U8KSNdoPYgKokhj86dSak3eka1GRDfhbDfSNVSs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rH9pgf7oCCJ0pe3+6wZvK2DUXIeLE8uO7wbxkNCRx33cLnoid3zRgoIFC6i3k4uTkPIAAJjQSR8Oz++Xq8ctCF078tTXk0qEJtw7hP5C1pXBc+bpDsCiUMHdkwoMK1p3jN0ddtlLVBEPDEU/0frIdiG8pTbgRAsXw4NfrZ4+/HU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=i2clpO3r; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="i2clpO3r" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-43944c51e41so20643875e9.0 for ; Tue, 11 Feb 2025 03:09:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272177; x=1739876977; darn=vger.kernel.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=rBA7ggfA28/uYGXwmpLDfBK8mT199rEz14cjtJoLIxE=; b=i2clpO3rwfO19hFId8q1HHjyKCR0wX8BURcqx1y1OfBi0QjFUhTy9jsA/ickeT1A1e mrWgs0HQbsrF5lVP5g9WmLo9h6RyIpy0tccYmvFo6LN2Rxde3ExSBPxuAEDseVy9y99m 1oJf9NC8IFGiM5nKnArs8jErxPr5i9zr/VuZgoleIr5o4XRwJDBtbrzLLWfBxsEVsIRc 2Njs+Fe508J7xByDqx48u5V1dEOwIYhNvvX/4XP40yy0tCs3ta3AiBIyBGo8hS0SrXb9 RNH/0mIfNDIUuc6lhoJoYUGfp4kShBzdQSA830BYGCIlq2PxFDQ6coQa2xnxyVlVYufa 0ZcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272177; x=1739876977; 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=rBA7ggfA28/uYGXwmpLDfBK8mT199rEz14cjtJoLIxE=; b=M642jldRws8YVyjJtQDeyPzmSvGzhHsErj5obMMi9VDEzTQth1Vg/xt/HBYwlb28Zg ub5OxyXXLzpZ5Mp3bhjGz10dOWzgvn6KuXzzMlMcgwCxqd4c0CBVIy/o4G5mjdGzygTH Cz6GNrERRhJu6RFAjf3rk8VCHhOWw+F7DQ22mAopFF0qu6tTzj+Z4RnvqJ8rPljxovlU ZZBi/0b8D4v5Hz1ILuH08Ow2fekau4Ha3M4Evym2m+gN4Totd+0e1BBLxIY5uuTFho3O 7KH2Gf+zp1tGjtl+gE0kAUVzlpV5fB9CWgCEhbCDqDNfYPmevrt1FqIF4TDseQFtJmIM epSA== X-Forwarded-Encrypted: i=1; AJvYcCVHIvQwB0PhFg2PeOGVjypT5Dr0G9KQsDR0Vth/8jwuBOh6YrOzf7LjZSyC07SmxChJvlHVBjLnQ7yi/ls=@vger.kernel.org X-Gm-Message-State: AOJu0YwyOWhvUq5Y5yjKSVdHI9eoKUuKPWWBkJX0jo0bpombny46tzSW INwPfn6wXdEuyyiRz32CcMCRz3gLNhvUEIovq1Joysetdx6hOj5H X-Gm-Gg: ASbGncspR2/Z4mo7845J4TYLKIgiEuZk3fEm3a+v4kzMMtyx2PgOJMKpzU+nPA6+k1O kPMY7eIeh9BN2rOZHcnCo3JjYhUmh8sZfPCdgSkSdE0z95BSMyF5QBe+ilYG13aiajuhOU0BjT9 epgUlNVx1KpJImSFcX/1inS5rBMFNZa4oCoxHg1dylATtoWaLjaEI/LaoqAsL3/Y4VMZIwtA83w zunLikH0cAU3y5j0FUa1ssaZvTszAEj3N+VZeR+p7WQc4Ut4g3lwIHoqicYOPn3jDV1yIOtI5iP iPARtpiiEJ06LtkT X-Google-Smtp-Source: AGHT+IG6uIK5sMReW8rmpfJ2cFHMTPBO6ZtT186CMnf1Lse58U69fHbGtfmXj/UJuW94AjncP1IpdQ== X-Received: by 2002:a05:600c:1c92:b0:439:4589:1abc with SMTP id 5b1f17b1804b1-43945891eaemr64620595e9.14.1739272176501; Tue, 11 Feb 2025 03:09:36 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:35 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 14/15] drm/vkms: Allow to configure multiple connectors Date: Tue, 11 Feb 2025 12:09:11 +0100 Message-ID: <20250211110912.15409-15-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a list of connectors to vkms_config and helper functions to add and remove as many connectors as wanted. For backwards compatibility, add one enabled connector to the default configuration. A future patch will allow to attach connectors and encoders, but for the moment there are no changes in the way the output is configured. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 74 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 50 +++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 42 +++++++++++ drivers/gpu/drm/vkms/vkms_connector.c | 11 +++ 5 files changed, 178 insertions(+) diff --git a/.clang-format b/.clang-format index 5d21c0e4edbd..ca49832993c5 100644 --- a/.clang-format +++ b/.clang-format @@ -690,6 +690,7 @@ ForEachMacros: - 'v4l2_m2m_for_each_src_buf' - 'v4l2_m2m_for_each_src_buf_safe' - 'virtio_device_for_each_vq' + - 'vkms_config_for_each_connector' - 'vkms_config_for_each_crtc' - 'vkms_config_for_each_encoder' - 'vkms_config_for_each_plane' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index 7458d175acb6..cba7e9d2fcad 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 *t= est) 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)); =20 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); =20 @@ -103,6 +104,9 @@ static void vkms_config_test_default_config(struct kuni= t *test) /* Encoders */ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->encoders), 1); =20 + /* Connectors */ + KUNIT_EXPECT_EQ(test, list_count_nodes(&config->connectors), 1); + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); =20 vkms_config_destroy(config); @@ -232,6 +236,51 @@ static void vkms_config_test_get_encoders(struct kunit= *test) vkms_config_destroy(config); } =20 +static void vkms_config_test_get_connectors(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_connector *connector_cfg; + struct vkms_config_connector *connector_cfg1, *connector_cfg2; + int n_connectors =3D 0; + + config =3D vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + vkms_config_for_each_connector(config, connector_cfg) + n_connectors++; + KUNIT_ASSERT_EQ(test, n_connectors, 0); + + connector_cfg1 =3D vkms_config_create_connector(config); + vkms_config_for_each_connector(config, connector_cfg) { + n_connectors++; + if (connector_cfg !=3D connector_cfg1) + KUNIT_FAIL(test, "Unexpected connector"); + } + KUNIT_ASSERT_EQ(test, n_connectors, 1); + n_connectors =3D 0; + + connector_cfg2 =3D vkms_config_create_connector(config); + vkms_config_for_each_connector(config, connector_cfg) { + n_connectors++; + if (connector_cfg !=3D connector_cfg1 && + connector_cfg !=3D connector_cfg2) + KUNIT_FAIL(test, "Unexpected connector"); + } + KUNIT_ASSERT_EQ(test, n_connectors, 2); + n_connectors =3D 0; + + vkms_config_destroy_connector(connector_cfg2); + vkms_config_for_each_connector(config, connector_cfg) { + n_connectors++; + if (connector_cfg !=3D connector_cfg1) + KUNIT_FAIL(test, "Unexpected connector"); + } + KUNIT_ASSERT_EQ(test, n_connectors, 1); + n_connectors =3D 0; + + vkms_config_destroy(config); +} + static void vkms_config_test_invalid_plane_number(struct kunit *test) { struct vkms_config *config; @@ -439,6 +488,29 @@ static void vkms_config_test_valid_encoder_possible_cr= tcs(struct kunit *test) vkms_config_destroy(config); } =20 +static void vkms_config_test_invalid_connector_number(struct kunit *test) +{ + struct vkms_config *config; + struct vkms_config_connector *connector_cfg; + int n; + + config =3D vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + /* Invalid: No connectors */ + connector_cfg =3D list_first_entry(&config->connectors, typeof(*connector= _cfg), link); + vkms_config_destroy_connector(connector_cfg); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + /* Invalid: Too many connectors */ + for (n =3D 0; n <=3D 32; n++) + connector_cfg =3D vkms_config_create_connector(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; @@ -635,12 +707,14 @@ static struct kunit_case vkms_config_test_cases[] =3D= { KUNIT_CASE(vkms_config_test_get_planes), KUNIT_CASE(vkms_config_test_get_crtcs), KUNIT_CASE(vkms_config_test_get_encoders), + KUNIT_CASE(vkms_config_test_get_connectors), KUNIT_CASE(vkms_config_test_invalid_plane_number), KUNIT_CASE(vkms_config_test_valid_plane_type), KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), KUNIT_CASE(vkms_config_test_invalid_crtc_number), KUNIT_CASE(vkms_config_test_invalid_encoder_number), KUNIT_CASE(vkms_config_test_valid_encoder_possible_crtcs), + KUNIT_CASE(vkms_config_test_invalid_connector_number), KUNIT_CASE(vkms_config_test_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 f727c0009489..d52280d3bbee 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_na= me) INIT_LIST_HEAD(&config->planes); INIT_LIST_HEAD(&config->crtcs); INIT_LIST_HEAD(&config->encoders); + INIT_LIST_HEAD(&config->connectors); =20 return config; } @@ -36,6 +37,7 @@ struct vkms_config *vkms_config_default_create(bool enabl= e_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; =20 config =3D vkms_config_create(DEFAULT_DEVICE_NAME); @@ -87,6 +89,10 @@ struct vkms_config *vkms_config_default_create(bool enab= le_cursor, if (vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg)) goto err_alloc; =20 + connector_cfg =3D vkms_config_create_connector(config); + if (IS_ERR(connector_cfg)) + goto err_alloc; + return config; =20 err_alloc: @@ -99,6 +105,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; =20 list_for_each_entry_safe(plane_cfg, plane_tmp, &config->planes, link) vkms_config_destroy_plane(plane_cfg); @@ -109,6 +116,9 @@ void vkms_config_destroy(struct vkms_config *config) list_for_each_entry_safe(encoder_cfg, encoder_tmp, &config->encoders, lin= k) vkms_config_destroy_encoder(config, encoder_cfg); =20 + list_for_each_entry_safe(connector_cfg, connector_tmp, &config->connector= s, link) + vkms_config_destroy_connector(connector_cfg); + kfree_const(config->dev_name); kfree(config); } @@ -251,6 +261,20 @@ static bool valid_encoder_possible_crtcs(struct vkms_c= onfig *config) return true; } =20 +static bool valid_connector_number(struct vkms_config *config) +{ + struct drm_device *dev =3D &config->dev->drm; + size_t n_connectors; + + n_connectors =3D list_count_nodes(&config->connectors); + if (n_connectors <=3D 0 || n_connectors >=3D 32) { + drm_info(dev, "The number of connectors 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; @@ -264,6 +288,9 @@ bool vkms_config_is_valid(struct vkms_config *config) if (!valid_encoder_number(config)) return false; =20 + if (!valid_connector_number(config)) + return false; + if (!valid_plane_possible_crtcs(config)) return false; =20 @@ -287,6 +314,7 @@ static int vkms_config_show(struct seq_file *m, void *d= ata) struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; struct vkms_config_encoder *encoder_cfg; + struct vkms_config_connector *connector_cfg; =20 dev_name =3D vkms_config_get_device_name((struct vkms_config *)vkmsdev->c= onfig); seq_printf(m, "dev_name=3D%s\n", dev_name); @@ -306,6 +334,9 @@ static int vkms_config_show(struct seq_file *m, void *d= ata) vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) seq_puts(m, "encoder\n"); =20 + vkms_config_for_each_connector(vkmsdev->config, connector_cfg) + seq_puts(m, "connector\n"); + return 0; } =20 @@ -494,3 +525,22 @@ void vkms_config_encoder_detach_crtc(struct vkms_confi= g_encoder *encoder_cfg, xa_erase(&encoder_cfg->possible_crtcs, idx); } } + +struct vkms_config_connector *vkms_config_create_connector(struct vkms_con= fig *config) +{ + struct vkms_config_connector *connector_cfg; + + connector_cfg =3D kzalloc(sizeof(*connector_cfg), GFP_KERNEL); + if (!connector_cfg) + return ERR_PTR(-ENOMEM); + + 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 28c24afebe1e..8451c2f127b6 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -16,6 +16,7 @@ * @planes: List of planes configured for the device * @crtcs: List of CRTCs configured for the device * @encoders: List of encoders configured for the device + * @connectors: List of connectors configured for the device * @dev: Used to store the current VKMS device. Only set when the device i= s instantiated. */ struct vkms_config { @@ -23,6 +24,7 @@ struct vkms_config { struct list_head planes; struct list_head crtcs; struct list_head encoders; + struct list_head connectors; struct vkms_device *dev; }; =20 @@ -86,6 +88,22 @@ struct vkms_config_encoder { struct drm_encoder *encoder; }; =20 +/** + * struct vkms_config_connector + * + * @link: Link to the others connector in vkms_config + * @connector: Internal usage. This pointer should never be considered as = valid. + * It can be used to store a temporary reference to a VKMS con= nector + * 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; + + /* Internal usage */ + struct vkms_connector *connector; +}; + /** * vkms_config_for_each_plane - Iterate over the vkms_config planes * @config: &struct vkms_config pointer @@ -110,6 +128,14 @@ struct vkms_config_encoder { #define vkms_config_for_each_encoder(config, encoder_cfg) \ list_for_each_entry((encoder_cfg), &(config)->encoders, link) =20 +/** + * vkms_config_for_each_connector - Iterate over the vkms_config connectors + * @config: &struct vkms_config pointer + * @connector_cfg: &struct vkms_config_connector pointer used as cursor + */ +#define vkms_config_for_each_connector(config, connector_cfg) \ + list_for_each_entry((connector_cfg), &(config)->connectors, link) + /** * vkms_config_plane_for_each_possible_crtc - Iterate over the vkms_config= _plane * possible CRTCs @@ -355,4 +381,20 @@ int __must_check vkms_config_encoder_attach_crtc(struc= t vkms_config_encoder *enc void vkms_config_encoder_detach_crtc(struct vkms_config_encoder *encoder_c= fg, struct vkms_config_crtc *crtc_cfg); =20 +/** + * vkms_config_create_connector() - Add a new connector configuration + * @config: Configuration to add the connector to + * + * Returns: + * The new connector configuration or an error. Call + * vkms_config_destroy_connector() to free the returned connector configur= ation. + */ +struct vkms_config_connector *vkms_config_create_connector(struct vkms_con= fig *config); + +/** + * vkms_config_destroy_connector() - Remove and free a connector configura= tion + * @connector_cfg: Connector configuration to destroy + */ +void vkms_config_destroy_connector(struct vkms_config_connector *connector= _cfg); + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/v= kms_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 *con= nector) return count; } =20 +static struct drm_encoder *vkms_conn_best_encoder(struct drm_connector *co= nnector) +{ + 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 =3D { .get_modes =3D vkms_conn_get_modes, + .best_encoder =3D vkms_conn_best_encoder, }; =20 struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev) --=20 2.48.1 From nobody Wed Dec 17 04:54:50 2025 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D85EF21D00B for ; Tue, 11 Feb 2025 11:09:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272182; cv=none; b=tMP7rz03cHHTSbhetLb6YMkPlzPTFs5Hm8TFqX7cQejrRKjE2lnDYeTjQ9vq2Ui8btToEZ1mpMv1smhLtAVb6YleY3oZaYtZSVtHjGS6UiiuTNtSS9DVKIZf1eM1zLe29HeHOUTUEyO8FJ5FHb9uN9vaWJAFcp77kS1qrrwaE+g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739272182; c=relaxed/simple; bh=ZTj9POfW0r2v891dVioEm/LvxgBX96ByWwuDI/SqhRc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OIrtRAhx7SIU5t5Snt6F0EYokmj6giihRflRY4TDYVKm2T0qb616gzKlgYh0Ili7UkNhwS2x3wAXNBRe/ogbUhn2h+/+QbPCM3ImPPlPXsd2EZMMC/cH8VznUGvVCy6x5Fdle6Zgz/2EJ7iM9kPVrVA9n0eigHcqsLBVi0j1n0A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=P3hZy0SF; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="P3hZy0SF" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-4394829ef0fso10152635e9.0 for ; Tue, 11 Feb 2025 03:09:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739272178; x=1739876978; darn=vger.kernel.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=uGUdgw2ywsEOYDg6PxJGKHCOLJS2s2ya/ph3EyRFJVM=; b=P3hZy0SFInf12gWHqCoUoOwpATfNupSAUqCBxEroTyuorqTJNhMdqzbjsqo0drrBbB sF8U2dVlU1rqpAvMrqfZiRkXbrZHF0u3oTysrIPbHdIsfmnxvyfPMl16Hs5DdaAi9z/T pQYVKr7tGPisb36kN39JY1YJy/J2Mk10e+iSkOrEWXAaBWYawAHISKpk+FDe3n8vhkv1 zmbpZ79Kphv7mTbion+bqb77bnrSqq90+yJd5DUjGNnCotCXEBNNDkV5e9u+KBmx45L0 zCoQHZ5cNckbEMFS/2Nl3XbV8xRBlbRJFLwqmVjhrRMHyD4pQJyzUeyqev2dRrwTjGwo 9dAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739272178; x=1739876978; 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=uGUdgw2ywsEOYDg6PxJGKHCOLJS2s2ya/ph3EyRFJVM=; b=w0ySUMejzOPoxxj4+LgtMcGu/gXZ1OY3qsjp/f0R2tUR848OFXT1mY9fxS1mTu+OAn Vo4xtkDnNcnlVgJOj56npmK/Wr9Y5qhNU+CKzAcuWB/ZmTeD431qlbCFZZbClZD3GqkY ByBjPugnAfWcJd/JflQi4tHZTo+FZcPBysc4oDeRRF70kVUzAlS2O2CQc22emD889IEt CPGMAkLs4cj0H+kR6EIeT9cC5+5rGaQSmbfblnH+MJZ8vojVfbBBdz0g2w8tTiRogleo DSZsTWRYYqj8rpS9nnV3YICLes4uUHTD8LyWK6WnGQQCMtc7taxEg4RjXUcxMDAVi0nB HC0w== X-Forwarded-Encrypted: i=1; AJvYcCUky2fXIPTcbkGof4EcvGBmGQKnhf+pFU+C2hB9NWA4uoIhho7KDwPbQ6TjhOdnea9HRzHrsKd9Al5wFIs=@vger.kernel.org X-Gm-Message-State: AOJu0YzdR4A9To7v3vR6d3IJgWEek2fVyCmrIah/ynH4p9LYaMTJagFw GwXRTg0wVLSo32Owcb6MovcOcR6hhzE20uqYQZJHKcqsovdrtbjm X-Gm-Gg: ASbGncuG9iZf10XfhvKOxWCPEAtiKKjQy25Ax/qZYFrl4s5yEgYu/F+Clz4JXjp0K7k ylhtr+32X8x0KCsl13g+ZniVh5FgkCxypzt1e2/cTCyEsaJ7ZJxQDnPLYsP0YCrTwixJ+PYddW7 de/YHyKHnhmHzP96TP/HvX545t5ZMT9KmxtaTfJNdN16EgWnWdTsqT2oteFFeO4VSPI3s2HVm2s HoqFbsk63Ogp8HwlupPrWQsZZo7c7ZjNabt5cZw7n+y8B8biwuGWlie6Oyrfp5YO49gJQxVoI5/ b9ktuIXYcCxshY6C X-Google-Smtp-Source: AGHT+IEBywQtzeAfqxQNya+FLykWVeF9GchkmCoUu0KPaur3KfXxA5e/gms8QC9wUmsE7b8h69zDmQ== X-Received: by 2002:a5d:64c4:0:b0:38d:c0c0:b3da with SMTP id ffacd0b85a97d-38de438e603mr2334406f8f.2.1739272178153; Tue, 11 Feb 2025 03:09:38 -0800 (PST) Received: from fedora.. ([94.73.37.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38dcb55b7a5sm11814417f8f.14.2025.02.11.03.09.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Feb 2025 03:09:37 -0800 (PST) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= 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?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v2 15/15] drm/vkms: Allow to attach connectors and encoders Date: Tue, 11 Feb 2025 12:09:12 +0100 Message-ID: <20250211110912.15409-16-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250211110912.15409-1-jose.exposito89@gmail.com> References: <20250211110912.15409-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a list of possible encoders to the connector configuration and helpers to attach and detach them. Now that the default configuration has its connector and encoder correctly, configure the output following the configuration. Co-developed-by: Louis Chauvet Signed-off-by: Louis Chauvet Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- .clang-format | 1 + drivers/gpu/drm/vkms/tests/vkms_config_test.c | 94 +++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.c | 60 ++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 29 ++++++ drivers/gpu/drm/vkms/vkms_output.c | 33 ++++--- 5 files changed, 204 insertions(+), 13 deletions(-) diff --git a/.clang-format b/.clang-format index ca49832993c5..7630990aa07a 100644 --- a/.clang-format +++ b/.clang-format @@ -694,6 +694,7 @@ ForEachMacros: - 'vkms_config_for_each_crtc' - 'vkms_config_for_each_encoder' - 'vkms_config_for_each_plane' + - 'vkms_config_connector_for_each_possible_encoder' - 'vkms_config_encoder_for_each_possible_crtc' - 'vkms_config_plane_for_each_possible_crtc' - 'while_for_each_ftrace_op' diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/dr= m/vkms/tests/vkms_config_test.c index cba7e9d2fcad..2d104ecfde3b 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -511,6 +511,27 @@ static void vkms_config_test_invalid_connector_number(= struct kunit *test) vkms_config_destroy(config); } =20 +static void vkms_config_test_valid_connector_possible_encoders(struct kuni= t *test) +{ + struct vkms_config *config; + struct vkms_config_encoder *encoder_cfg; + struct vkms_config_connector *connector_cfg; + + config =3D vkms_config_default_create(false, false, false); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + encoder_cfg =3D list_first_entry(&config->encoders, + typeof(*encoder_cfg), link); + connector_cfg =3D list_first_entry(&config->connectors, + typeof(*connector_cfg), link); + + /* Invalid: Connector without a possible encoder */ + vkms_config_connector_detach_encoder(connector_cfg, encoder_cfg); + KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); + + vkms_config_destroy(config); +} + static void vkms_config_test_plane_attach_crtc(struct kunit *test) { struct vkms_config *config; @@ -700,6 +721,77 @@ static void vkms_config_test_encoder_get_possible_crtc= s(struct kunit *test) vkms_config_destroy(config); } =20 +static void vkms_config_test_connector_get_possible_encoders(struct kunit = *test) +{ + struct vkms_config *config; + struct vkms_config_connector *connector_cfg1, *connector_cfg2; + struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; + struct vkms_config_encoder *possible_encoder; + unsigned long idx =3D 0; + int n_encoders =3D 0; + int err; + + config =3D vkms_config_create("test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); + + connector_cfg1 =3D vkms_config_create_connector(config); + connector_cfg2 =3D vkms_config_create_connector(config); + encoder_cfg1 =3D vkms_config_create_encoder(config); + encoder_cfg2 =3D vkms_config_create_encoder(config); + + /* No possible encoders */ + vkms_config_connector_for_each_possible_encoder(connector_cfg1, idx, + possible_encoder) + KUNIT_FAIL(test, "Unexpected possible encoder"); + + vkms_config_connector_for_each_possible_encoder(connector_cfg2, idx, + possible_encoder) + KUNIT_FAIL(test, "Unexpected possible encoder"); + + /* Connector 1 attached to encoders 1 and 2 */ + err =3D vkms_config_connector_attach_encoder(connector_cfg1, encoder_cfg1= ); + KUNIT_EXPECT_EQ(test, err, 0); + err =3D vkms_config_connector_attach_encoder(connector_cfg1, encoder_cfg2= ); + KUNIT_EXPECT_EQ(test, err, 0); + + vkms_config_connector_for_each_possible_encoder(connector_cfg1, idx, + possible_encoder) { + n_encoders++; + if (possible_encoder !=3D encoder_cfg1 && + possible_encoder !=3D encoder_cfg2) + KUNIT_FAIL(test, "Unexpected possible encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 2); + n_encoders =3D 0; + + vkms_config_connector_for_each_possible_encoder(connector_cfg2, idx, + possible_encoder) + KUNIT_FAIL(test, "Unexpected possible encoder"); + + /* Connector 1 attached to encoder 1 and connector 2 to encoder 2 */ + vkms_config_connector_detach_encoder(connector_cfg1, encoder_cfg2); + vkms_config_connector_for_each_possible_encoder(connector_cfg1, idx, + possible_encoder) { + n_encoders++; + if (possible_encoder !=3D encoder_cfg1) + KUNIT_FAIL(test, "Unexpected possible encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 1); + n_encoders =3D 0; + + err =3D vkms_config_connector_attach_encoder(connector_cfg2, encoder_cfg2= ); + KUNIT_EXPECT_EQ(test, err, 0); + vkms_config_connector_for_each_possible_encoder(connector_cfg2, idx, + possible_encoder) { + n_encoders++; + if (possible_encoder !=3D encoder_cfg2) + KUNIT_FAIL(test, "Unexpected possible encoder"); + } + KUNIT_ASSERT_EQ(test, n_encoders, 1); + + vkms_config_destroy(config); +} + static struct kunit_case vkms_config_test_cases[] =3D { KUNIT_CASE(vkms_config_test_empty_config), KUNIT_CASE_PARAM(vkms_config_test_default_config, @@ -715,9 +807,11 @@ static struct kunit_case vkms_config_test_cases[] =3D { KUNIT_CASE(vkms_config_test_invalid_encoder_number), KUNIT_CASE(vkms_config_test_valid_encoder_possible_crtcs), KUNIT_CASE(vkms_config_test_invalid_connector_number), + KUNIT_CASE(vkms_config_test_valid_connector_possible_encoders), KUNIT_CASE(vkms_config_test_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), {} }; =20 diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms= _config.c index d52280d3bbee..3d95dc713151 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -93,6 +93,9 @@ struct vkms_config *vkms_config_default_create(bool enabl= e_cursor, if (IS_ERR(connector_cfg)) goto err_alloc; =20 + if (vkms_config_connector_attach_encoder(connector_cfg, encoder_cfg)) + goto err_alloc; + return config; =20 err_alloc: @@ -275,6 +278,22 @@ static bool valid_connector_number(struct vkms_config = *config) return true; } =20 +static bool valid_connector_possible_encoders(struct vkms_config *config) +{ + struct drm_device *dev =3D &config->dev->drm; + struct vkms_config_connector *connector_cfg; + + vkms_config_for_each_connector(config, connector_cfg) { + if (xa_empty(&connector_cfg->possible_encoders)) { + drm_info(dev, + "All connectors must have at least one possible encoder\n"); + return false; + } + } + + return true; +} + bool vkms_config_is_valid(struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; @@ -302,6 +321,9 @@ bool vkms_config_is_valid(struct vkms_config *config) if (!valid_encoder_possible_crtcs(config)) return false; =20 + if (!valid_connector_possible_encoders(config)) + return false; + return true; } =20 @@ -493,6 +515,11 @@ struct vkms_config_encoder *vkms_config_create_encoder= (struct vkms_config *confi void vkms_config_destroy_encoder(struct vkms_config *config, struct vkms_config_encoder *encoder_cfg) { + struct vkms_config_connector *connector_cfg; + + vkms_config_for_each_connector(config, connector_cfg) + vkms_config_connector_detach_encoder(connector_cfg, encoder_cfg); + xa_destroy(&encoder_cfg->possible_crtcs); list_del(&encoder_cfg->link); kfree(encoder_cfg); @@ -534,6 +561,8 @@ struct vkms_config_connector *vkms_config_create_connec= tor(struct vkms_config *c if (!connector_cfg) return ERR_PTR(-ENOMEM); =20 + xa_init_flags(&connector_cfg->possible_encoders, XA_FLAGS_ALLOC); + list_add_tail(&connector_cfg->link, &config->connectors); =20 return connector_cfg; @@ -541,6 +570,37 @@ struct vkms_config_connector *vkms_config_create_conne= ctor(struct vkms_config *c =20 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_c= onnector *connector_cfg, + struct vkms_config_encoder *encoder_cfg) +{ + struct vkms_config_encoder *possible_encoder; + unsigned long idx =3D 0; + u32 encoder_idx =3D 0; + + vkms_config_connector_for_each_possible_encoder(connector_cfg, idx, + possible_encoder) { + if (possible_encoder =3D=3D 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 *co= nnector_cfg, + struct vkms_config_encoder *encoder_cfg) +{ + struct vkms_config_encoder *possible_encoder; + unsigned long idx =3D 0; + + vkms_config_connector_for_each_possible_encoder(connector_cfg, idx, + possible_encoder) { + if (possible_encoder =3D=3D encoder_cfg) + xa_erase(&connector_cfg->possible_encoders, idx); + } +} diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms= _config.h index 8451c2f127b6..c87513d174f2 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -92,6 +92,7 @@ struct vkms_config_encoder { * struct vkms_config_connector * * @link: Link to the others connector in vkms_config + * @possible_encoders: Array of encoders that can be used with this connec= tor * @connector: Internal usage. This pointer should never be considered as = valid. * It can be used to store a temporary reference to a VKMS con= nector * during device creation. This pointer is not managed by the @@ -100,6 +101,8 @@ struct vkms_config_encoder { struct vkms_config_connector { struct list_head link; =20 + struct xarray possible_encoders; + /* Internal usage */ struct vkms_connector *connector; }; @@ -156,6 +159,16 @@ struct vkms_config_connector { #define vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possi= ble_crtc) \ xa_for_each(&(encoder_cfg)->possible_crtcs, idx, (possible_crtc)) =20 +/** + * vkms_config_connector_for_each_possible_encoder - Iterate over the + * vkms_config_connector possible encoders + * @connector_cfg: &struct vkms_config_connector pointer + * @idx: Index of the cursor + * @possible_encoder: &struct vkms_config_encoder pointer used as cursor + */ +#define vkms_config_connector_for_each_possible_encoder(connector_cfg, idx= , possible_encoder) \ + xa_for_each(&(connector_cfg)->possible_encoders, idx, (possible_encoder)) + /** * vkms_config_create() - Create a new VKMS configuration * @dev_name: Name of the device @@ -397,4 +410,20 @@ struct vkms_config_connector *vkms_config_create_conne= ctor(struct vkms_config *c */ void vkms_config_destroy_connector(struct vkms_config_connector *connector= _cfg); =20 +/** + * 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_c= onnector *connector_cfg, + struct vkms_config_encoder *encoder_cfg); + +/** + * vkms_config_connector_detach_encoder - Detach a connector from an encod= er + * @connector_cfg: Connector to detach + * @encoder_cfg: Encoder to detach @connector_cfg from + */ +void vkms_config_connector_detach_encoder(struct vkms_config_connector *co= nnector_cfg, + struct vkms_config_encoder *encoder_cfg); + #endif /* _VKMS_CONFIG_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms= _output.c index 8920d6b5d105..8d7ca0cdd79f 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -8,10 +8,10 @@ int vkms_output_init(struct vkms_device *vkmsdev) { struct drm_device *dev =3D &vkmsdev->drm; - struct vkms_connector *connector; struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; struct vkms_config_encoder *encoder_cfg; + struct vkms_config_connector *connector_cfg; int ret; int writeback; =20 @@ -83,22 +83,29 @@ int vkms_output_init(struct vkms_device *vkmsdev) } } =20 - connector =3D vkms_connector_init(vkmsdev); - if (IS_ERR(connector)) { - DRM_ERROR("Failed to init connector\n"); - return PTR_ERR(connector); - } + vkms_config_for_each_connector(vkmsdev->config, connector_cfg) { + struct vkms_config_encoder *possible_encoder; + unsigned long idx =3D 0; =20 - /* Attach the encoder and the connector */ - vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg) { - ret =3D drm_connector_attach_encoder(&connector->base, encoder_cfg->enco= der); - if (ret) { - DRM_ERROR("Failed to attach connector to encoder\n"); - return ret; + connector_cfg->connector =3D vkms_connector_init(vkmsdev); + if (IS_ERR(connector_cfg->connector)) { + DRM_ERROR("Failed to init connector\n"); + return PTR_ERR(connector_cfg->connector); + } + + vkms_config_connector_for_each_possible_encoder(connector_cfg, + idx, + possible_encoder) { + ret =3D drm_connector_attach_encoder(&connector_cfg->connector->base, + possible_encoder->encoder); + if (ret) { + DRM_ERROR("Failed to attach connector to encoder\n"); + return ret; + } } } =20 drm_mode_config_reset(dev); =20 - return ret; + return 0; } --=20 2.48.1