* [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration
@ 2024-11-22 17:20 Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 01/18] drm/vkms: Extract vkms_config header Louis Chauvet
` (17 more replies)
0 siblings, 18 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet, José Expósito
The current code is not flexible to configure the VKMS device. In
preparation for ConfigFS interface introduce few structure that can be
used to configure the device creation: `vkms_config`.
This part is splitted from the ConfigFS implementation itself to avoid
mixing two complex interfaces.
The vkms_config structure will allows the configuration of:
- planes
- name
- possible_crtcs
- supported_color_encodings
- supported_rotations
- supported_color_ranges
- default_rotation
- default_color_range
- default_color_encoding
- type
- format
- crtcs
- name
- possible_planes [automatically filled by helpers]
- possible_encoders [automatically filled by helpers]
- encoders
- name
- type
- possible_crtcs
- connectors:
- type
- status
- EDID
This series depends on:
https://lore.kernel.org/all/20241122-google-vkms-managed-v5-0-1ab60403e960@bootlin.com
https://lore.kernel.org/all/20241122-b4-vkms-allocated-v2-0-ff7bddbf0bfb@bootlin.com
https://lore.kernel.org/all/20241122-b4-new-color-formats-v3-0-23f7776197c9@bootlin.com
https://lore.kernel.org/all/20241122-writeback_line_by_line-v3-0-085d5810f6e3@bootlin.com
As there are some conflicts, you can find a working branch here:
https://gitlab.freedesktop.org/louischauvet/kernel/-/tree/b4/vkms-config
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Changes in v2:
- Rebased on drm-misc-next
- Added support for many new configuration
- Link to v1: https://lore.kernel.org/r/20240814-google-remove-crtc-index-from-parameter-v1-0-6e179abf9fd4@bootlin.com
---
Louis Chauvet (18):
drm/vkms: Extract vkms_config header
drm/vkms: Add a validation function for vkms configuration
drm/vkms: Move default_config creation to its own function
drm/vkms: Introduce config for plane
drm/vkms: Introduce config for plane name
drm/vkms: Introduce config for plane rotation
drm/vkms: Introduce config for plane color encoding
drm/vkms: Introduce config for plane color range
drm/vkms: Introduce config for CRTCs and encoders
drm/vkms: Introduce config for encoder name
drm/vkms: Introduce config for CRTC name
drm/vkms: Add test for config structure
drm/vkms: Introduce config for connector
drm/vkms: Introduce config for connector type
drm/vkms: Introduce config for plane format
drm/vkms: Introduce config for connector status
drm/vkms: Introduce config for connector EDID
drm/vkms: Introduce config for encoder type
drivers/gpu/drm/vkms/Makefile | 3 +-
drivers/gpu/drm/vkms/tests/Makefile | 1 +
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 137 ++++++
drivers/gpu/drm/vkms/vkms_config.c | 613 ++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 245 ++++++++++
drivers/gpu/drm/vkms/vkms_crtc.c | 16 +-
drivers/gpu/drm/vkms/vkms_drv.c | 42 +-
drivers/gpu/drm/vkms/vkms_drv.h | 25 +-
drivers/gpu/drm/vkms/vkms_output.c | 183 +++++---
drivers/gpu/drm/vkms/vkms_plane.c | 62 +--
10 files changed, 1152 insertions(+), 175 deletions(-)
---
base-commit: 98efdd02e220fea84c1491012d7292749a71faeb
change-id: 20240521-google-remove-crtc-index-from-parameter-f9afb21c7a85
prerequisite-message-id: 20241122-google-vkms-managed-v5-0-1ab60403e960@bootlin.com
prerequisite-patch-id: b608594ad493a41000ee703792eac4b23f9e35dc
prerequisite-patch-id: 5697aa87c44bbf3eda8a1ba424465dc792545d4c
prerequisite-patch-id: 223d59c407ce28dacf3f563b5c0148d2398303f1
prerequisite-patch-id: 720b75b21d06ce3d3f060fb9238f7903834da0e1
prerequisite-patch-id: 30a1e033fa43241ca6a43006fd4f29f8e9217224
prerequisite-message-id: 20241122-b4-vkms-allocated-v2-0-ff7bddbf0bfb@bootlin.com
prerequisite-patch-id: 9741873a5f0a7a3cf117dec7837354c3ad38ac3a
prerequisite-patch-id: 1a383d1494e4f2142b62822f2ba482a3b813563a
prerequisite-patch-id: 7d3f49fee4d3553d52fc075b7868da9dea9209cd
prerequisite-patch-id: 57f5aeff2a9e8f2b6f47569e44dcd8fa587ed4bf
prerequisite-message-id: 20241122-b4-new-color-formats-v3-0-23f7776197c9@bootlin.com
prerequisite-patch-id: e6717b75d79ae5cfb0815bab88d722082107dc0e
prerequisite-patch-id: 4b3b1ea5ad2e3ba1922cd4b3d3d46214b27c8c2d
prerequisite-patch-id: 060874d5a7433cc8cc654bc63e0b411036727ebb
prerequisite-patch-id: 43115d21842e508d9d8b0468e15f67d442bffe3c
prerequisite-patch-id: 627d0970e76d4154c982d0d4172e7a0c4dfb9a4c
prerequisite-patch-id: 582445144ac0ab11175ef96262060b08a5e1467e
prerequisite-patch-id: a98fac5a2c60fe23fbc6a455e9a4ab8b0f187ee8
prerequisite-patch-id: 62c8d109a22b9978f755255b67f13fe74fb7008d
prerequisite-message-id: 20241122-writeback_line_by_line-v3-0-085d5810f6e3@bootlin.com
prerequisite-patch-id: 07868dd9c7bbb1ed96d675c689de86f0cf293248
prerequisite-patch-id: 736638b76050ef7a99cfad2c1560f7af114d5fbd
prerequisite-patch-id: 20d8823f9c1d372ab2b88f969f5110f77e49c7f9
Best regards,
--
Louis Chauvet <louis.chauvet@bootlin.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH RFC v2 01/18] drm/vkms: Extract vkms_config header
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 02/18] drm/vkms: Add a validation function for vkms configuration Louis Chauvet
` (16 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet, José Expósito
Creating a new vkms_config structure will be more complex once we
start adding more options.
Extract the vkms_config structure to its own header and source files
and add functions to create and delete a vkms_config and to initialize
debugfs.
Refactor, no functional changes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
[Changes: Cherry picked and conflict solve]
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
---
drivers/gpu/drm/vkms/Makefile | 3 ++-
drivers/gpu/drm/vkms/vkms_config.c | 48 ++++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 32 +++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_drv.c | 41 +++++++++-----------------------
drivers/gpu/drm/vkms/vkms_drv.h | 15 +-----------
drivers/gpu/drm/vkms/vkms_output.c | 1 +
6 files changed, 95 insertions(+), 45 deletions(-)
diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
index 8d3e46dde6350558a0aab4254df0dfe863f9c6ce..2b6db5870b977f6e5013982af89a48aec6c11983 100644
--- a/drivers/gpu/drm/vkms/Makefile
+++ b/drivers/gpu/drm/vkms/Makefile
@@ -6,7 +6,8 @@ vkms-y := \
vkms_formats.o \
vkms_crtc.o \
vkms_composer.o \
- vkms_writeback.o
+ vkms_writeback.o \
+ vkms_config.o
obj-$(CONFIG_DRM_VKMS) += vkms.o
obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += tests/
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
new file mode 100644
index 0000000000000000000000000000000000000000..76355174a6ca54b880218c2bd458c8339a3dabaa
--- /dev/null
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <kunit/visibility.h>
+#include <drm/drm_debugfs.h>
+
+#include "vkms_config.h"
+#include "vkms_drv.h"
+
+struct vkms_config *vkms_config_create(void)
+{
+ struct vkms_config *config;
+
+ config = kzalloc(sizeof(*config), GFP_KERNEL);
+ if (!config)
+ return ERR_PTR(-ENOMEM);
+
+ return config;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_create);
+
+void vkms_config_destroy(struct vkms_config *config)
+{
+ kfree(config);
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy);
+
+static int vkms_config_show(struct seq_file *m, void *data)
+{
+ struct drm_debugfs_entry *entry = m->private;
+ struct drm_device *dev = entry->dev;
+ struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
+
+ seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback);
+ seq_printf(m, "cursor=%d\n", vkmsdev->config->cursor);
+ seq_printf(m, "overlay=%d\n", vkmsdev->config->overlay);
+
+ return 0;
+}
+
+static const struct drm_debugfs_info vkms_config_debugfs_list[] = {
+ { "vkms_config", vkms_config_show, 0 },
+};
+
+void vkms_config_register_debugfs(struct vkms_device *vkms_device)
+{
+ drm_debugfs_add_files(&vkms_device->drm, vkms_config_debugfs_list,
+ ARRAY_SIZE(vkms_config_debugfs_list));
+}
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..b284831738743f6d7c452be03f917a7d3975d173
--- /dev/null
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _VKMS_CONFIG_H
+#define _VKMS_CONFIG_H
+
+#include <linux/types.h>
+#include "vkms_drv.h"
+
+/**
+ * struct vkms_config - General configuration for VKMS driver
+ *
+ * @writeback: If true, a writeback buffer can be attached to the CRTC
+ * @cursor: If true, a cursor plane is created in the VKMS device
+ * @overlay: If true, NUM_OVERLAY_PLANES will be created for the VKMS device
+ * @dev: Used to store the current vkms device. Only set when the device is instancied.
+ */
+struct vkms_config {
+ bool writeback;
+ bool cursor;
+ bool overlay;
+ struct vkms_device *dev;
+};
+
+/**
+ * vkms_config_register_debugfs() - Register the debugfs file to display current configuration
+ */
+void vkms_config_register_debugfs(struct vkms_device *vkms_device);
+
+struct vkms_config *vkms_config_create(void);
+void vkms_config_destroy(struct vkms_config *config);
+
+#endif //_VKMS_CONFIG_H
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index c54504e590a18ae8af07cc1cc48179c38c4e6c0f..e399566a5b5d6a6cf92a41c72910e857fc4e743f 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -28,6 +28,7 @@
#include <drm/drm_vblank.h>
#include "vkms_drv.h"
+#include "vkms_config.h"
#include <drm/drm_print.h>
#include <drm/drm_debugfs.h>
@@ -82,22 +83,6 @@ static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state)
drm_atomic_helper_cleanup_planes(dev, old_state);
}
-static int vkms_config_show(struct seq_file *m, void *data)
-{
- struct drm_debugfs_entry *entry = m->private;
- struct drm_device *dev = entry->dev;
- struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
-
- seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback);
- seq_printf(m, "cursor=%d\n", vkmsdev->config->cursor);
- seq_printf(m, "overlay=%d\n", vkmsdev->config->overlay);
-
- return 0;
-}
-
-static const struct drm_debugfs_info vkms_config_debugfs_list[] = {
- { "vkms_config", vkms_config_show, 0 },
-};
static const struct drm_driver vkms_driver = {
.driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM,
@@ -210,8 +195,7 @@ static int vkms_create(struct vkms_config *config)
if (ret)
goto out_devres;
- drm_debugfs_add_files(&vkms_device->drm, vkms_config_debugfs_list,
- ARRAY_SIZE(vkms_config_debugfs_list));
+ vkms_config_register_debugfs(vkms_device);
ret = drm_dev_register(&vkms_device->drm, 0);
if (ret)
@@ -231,21 +215,18 @@ static int vkms_create(struct vkms_config *config)
static int __init vkms_init(void)
{
int ret;
- struct vkms_config *config;
-
- config = kmalloc(sizeof(*config), GFP_KERNEL);
- if (!config)
- return -ENOMEM;
- default_config = config;
+ default_config = vkms_config_create();
+ if (IS_ERR(default_config))
+ return PTR_ERR(default_config);
- config->cursor = enable_cursor;
- config->writeback = enable_writeback;
- config->overlay = enable_overlay;
+ default_config->cursor = enable_cursor;
+ default_config->writeback = enable_writeback;
+ default_config->overlay = enable_overlay;
- ret = vkms_create(config);
+ ret = vkms_create(default_config);
if (ret)
- kfree(config);
+ vkms_config_destroy(default_config);
return ret;
}
@@ -274,7 +255,7 @@ static void __exit vkms_exit(void)
if (default_config->dev)
vkms_destroy(default_config);
- kfree(default_config);
+ vkms_config_destroy(default_config);
}
module_init(vkms_init);
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index ddb6bf94514d9364521ff7c38a04d9aa69fc09dc..6dde780d0515394faf2a4763f9bb7447a28d1472 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -212,20 +212,7 @@ struct vkms_crtc {
spinlock_t composer_lock;
};
-/**
- * struct vkms_config - General configuration for VKMS driver
- *
- * @writeback: If true, a writeback buffer can be attached to the CRTC
- * @cursor: If true, a cursor plane is created in the VKMS device
- * @overlay: If true, NUM_OVERLAY_PLANES will be created for the VKMS device
- * @dev: Used to store the current VKMS device. Only set when the device is instantiated.
- */
-struct vkms_config {
- bool writeback;
- bool cursor;
- bool overlay;
- struct vkms_device *dev;
-};
+struct vkms_config;
/**
* struct vkms_device - Description of a VKMS device
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 1c6d41856e317eb7b9b79f56fdf7473d0a339250..34b6e761bce8a1f2153e1e47c795bad1a52a3454 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
#include "vkms_drv.h"
+#include "vkms_config.h"
#include <drm/drm_atomic_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_managed.h>
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 02/18] drm/vkms: Add a validation function for vkms configuration
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 01/18] drm/vkms: Extract vkms_config header Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 03/18] drm/vkms: Move default_config creation to its own function Louis Chauvet
` (15 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
As the configuration will be used by userspace, add a validator to avoid
creating a broken DRM device
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 6 ++++++
drivers/gpu/drm/vkms/vkms_config.h | 13 +++++++++++++
2 files changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 76355174a6ca54b880218c2bd458c8339a3dabaa..8d5c1429e6e196ef46c95c6ae73330bc4be2be39 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -24,6 +24,12 @@ void vkms_config_destroy(struct vkms_config *config)
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy);
+bool vkms_config_is_valid(struct vkms_config *config)
+{
+ return true;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_is_valid);
+
static int vkms_config_show(struct seq_file *m, void *data)
{
struct drm_debugfs_entry *entry = m->private;
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index b284831738743f6d7c452be03f917a7d3975d173..df571dd67352ca90fb47bd937fb9f11ceb95fcb2 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -29,4 +29,17 @@ void vkms_config_register_debugfs(struct vkms_device *vkms_device);
struct vkms_config *vkms_config_create(void);
void vkms_config_destroy(struct vkms_config *config);
+/**
+ * vkms_config_is_valid() - Validate a configuration
+ *
+ * Check if all the property defined in the configuration are valids. This will return false for
+ * example if:
+ * - no or many primary planes are present;
+ * - the default rotation of a plane is not in its supported rotation;
+ * - a CRTC don't have any encoder...
+ *
+ * @vkms_config: Configuration to validate
+ */
+bool vkms_config_is_valid(struct vkms_config *vkms_config);
+
#endif //_VKMS_CONFIG_H
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 03/18] drm/vkms: Move default_config creation to its own function
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 01/18] drm/vkms: Extract vkms_config header Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 02/18] drm/vkms: Add a validation function for vkms configuration Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 04/18] drm/vkms: Introduce config for plane Louis Chauvet
` (14 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet, José Expósito
Extract the initialization of the default configuration to a function.
Refactor, no functional changes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
[Changes: Cherry pick and solve conflicts]
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 16 ++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 9 +++++++++
drivers/gpu/drm/vkms/vkms_drv.c | 7 +------
3 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 8d5c1429e6e196ef46c95c6ae73330bc4be2be39..f7e0d39952ac73ea49c710b49becd391b5aaa66a 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -18,6 +18,22 @@ struct vkms_config *vkms_config_create(void)
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_create);
+struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable_overlay,
+ bool enable_cursor)
+{
+ struct vkms_config *vkms_config = vkms_config_create();
+
+ if (IS_ERR(vkms_config))
+ return vkms_config;
+
+ vkms_config->writeback = enable_writeback;
+ vkms_config->overlay = enable_overlay;
+ vkms_config->cursor = enable_cursor;
+
+ return vkms_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 df571dd67352ca90fb47bd937fb9f11ceb95fcb2..2afb795586c6924a46dd4ba777bf22a4f51cddda 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -42,4 +42,13 @@ void vkms_config_destroy(struct vkms_config *config);
*/
bool vkms_config_is_valid(struct vkms_config *vkms_config);
+/**
+ * vkms_config_alloc_default() - Allocate the configuration for the default device
+ * @enable_writeback: Enable the writeback connector for this configuration
+ * @enable_overlay: Create some overlay planes
+ * @enable_cursor: Create a cursor plane
+ */
+struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable_overlay,
+ bool enable_cursor);
+
#endif //_VKMS_CONFIG_H
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index e399566a5b5d6a6cf92a41c72910e857fc4e743f..61ae2986568093ab0df7174a0a4678a75f9aad0c 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -215,15 +215,10 @@ static int vkms_create(struct vkms_config *config)
static int __init vkms_init(void)
{
int ret;
-
- default_config = vkms_config_create();
+ default_config = vkms_config_alloc_default(enable_writeback, enable_overlay, enable_cursor);
if (IS_ERR(default_config))
return PTR_ERR(default_config);
- default_config->cursor = enable_cursor;
- default_config->writeback = enable_writeback;
- default_config->overlay = enable_overlay;
-
ret = vkms_create(default_config);
if (ret)
vkms_config_destroy(default_config);
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 04/18] drm/vkms: Introduce config for plane
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (2 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 03/18] drm/vkms: Move default_config creation to its own function Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 05/18] drm/vkms: Introduce config for plane name Louis Chauvet
` (13 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
The current vkms driver only allows the usage of one primary, eight
overlays and one cursor plane. This new configuration structure aims to
make the configuration more flexible.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 91 ++++++++++++++++++++++++++++++++++++--
drivers/gpu/drm/vkms/vkms_config.h | 43 +++++++++++++++++-
drivers/gpu/drm/vkms/vkms_drv.h | 3 +-
drivers/gpu/drm/vkms/vkms_output.c | 37 +++++-----------
drivers/gpu/drm/vkms/vkms_plane.c | 5 ++-
5 files changed, 144 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index f7e0d39952ac73ea49c710b49becd391b5aaa66a..31981dce2c2ed3ef8fc52e227e301d5f8d5338e6 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -14,6 +14,8 @@ struct vkms_config *vkms_config_create(void)
if (!config)
return ERR_PTR(-ENOMEM);
+ INIT_LIST_HEAD(&config->planes);
+
return config;
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_create);
@@ -21,27 +23,105 @@ EXPORT_SYMBOL_IF_KUNIT(vkms_config_create);
struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable_overlay,
bool enable_cursor)
{
+ struct vkms_config_plane *plane;
struct vkms_config *vkms_config = vkms_config_create();
if (IS_ERR(vkms_config))
return vkms_config;
vkms_config->writeback = enable_writeback;
- vkms_config->overlay = enable_overlay;
- vkms_config->cursor = enable_cursor;
+ plane = vkms_config_create_plane(vkms_config);
+ if (!plane)
+ goto err_alloc;
+
+ plane->type = DRM_PLANE_TYPE_PRIMARY;
+
+ if (enable_overlay) {
+ for (int i = 0; i < NUM_OVERLAY_PLANES; i++) {
+ plane = vkms_config_create_plane(vkms_config);
+ if (!plane)
+ goto err_alloc;
+ plane->type = DRM_PLANE_TYPE_OVERLAY;
+ }
+ }
+ if (enable_cursor) {
+ plane = vkms_config_create_plane(vkms_config);
+ if (!plane)
+ goto err_alloc;
+ plane->type = DRM_PLANE_TYPE_CURSOR;
+ }
return vkms_config;
+
+err_alloc:
+ vkms_config_destroy(vkms_config);
+ return ERR_PTR(-ENOMEM);
}
+struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_config)
+{
+ if (!vkms_config)
+ return NULL;
+
+ struct vkms_config_plane *vkms_config_overlay = kzalloc(sizeof(*vkms_config),
+ GFP_KERNEL);
+
+ if (!vkms_config_overlay)
+ return NULL;
+
+ vkms_config_overlay->type = DRM_PLANE_TYPE_OVERLAY;
+
+ list_add(&vkms_config_overlay->link, &vkms_config->planes);
+
+ return vkms_config_overlay;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_plane);
+
+void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_overlay)
+{
+ if (!vkms_config_overlay)
+ return;
+ list_del(&vkms_config_overlay->link);
+ kfree(vkms_config_overlay);
+}
void vkms_config_destroy(struct vkms_config *config)
{
+ struct vkms_config_plane *vkms_config_plane, *tmp_plane;
+
+ list_for_each_entry_safe(vkms_config_plane, tmp_plane, &config->planes, link) {
+ vkms_config_delete_plane(vkms_config_plane);
+ }
+
kfree(config);
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy);
bool vkms_config_is_valid(struct vkms_config *config)
{
+ struct vkms_config_plane *config_plane;
+
+ bool has_cursor = false;
+ bool has_primary = false;
+
+ list_for_each_entry(config_plane, &config->planes, link) {
+ if (config_plane->type == DRM_PLANE_TYPE_PRIMARY) {
+ // Multiple primary planes for only one CRTC
+ if (has_primary)
+ return false;
+ has_primary = true;
+ }
+ if (config_plane->type == DRM_PLANE_TYPE_CURSOR) {
+ // Multiple cursor planes for only one CRTC
+ if (has_cursor)
+ return false;
+ has_cursor = true;
+ }
+ }
+
+ if (!has_primary)
+ return false;
+
return true;
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_is_valid);
@@ -51,10 +131,13 @@ static int vkms_config_show(struct seq_file *m, void *data)
struct drm_debugfs_entry *entry = m->private;
struct drm_device *dev = entry->dev;
struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
+ struct vkms_config_plane *config_plane;
seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback);
- seq_printf(m, "cursor=%d\n", vkmsdev->config->cursor);
- seq_printf(m, "overlay=%d\n", vkmsdev->config->overlay);
+ list_for_each_entry(config_plane, &vkmsdev->config->planes, link) {
+ seq_puts(m, "plane:\n");
+ seq_printf(m, "\ttype: %d\n", config_plane->type);
+ }
return 0;
}
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 2afb795586c6924a46dd4ba777bf22a4f51cddda..ac99f1df6d9a17bd7040a1e7a6acce14cd8fd9d0 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -10,8 +10,8 @@
* struct vkms_config - General configuration for VKMS driver
*
* @writeback: If true, a writeback buffer can be attached to the CRTC
- * @cursor: If true, a cursor plane is created in the VKMS device
- * @overlay: If true, NUM_OVERLAY_PLANES will be created for the VKMS device
+ * @planes: List of planes configured for this device. They are created by the function
+ * vkms_config_create_plane().
* @dev: Used to store the current vkms device. Only set when the device is instancied.
*/
struct vkms_config {
@@ -19,6 +19,27 @@ struct vkms_config {
bool cursor;
bool overlay;
struct vkms_device *dev;
+
+ struct list_head planes;
+};
+
+/**
+ * struct vkms_config_plane
+ *
+ * @link: Link to the others planes
+ * @type: Type of the plane. The creator of configuration needs to ensures that at least one
+ * plane is primary.
+ * @plane: Internal usage. This pointer should never be considered as valid. It can be used to
+ * store a temporary reference to a vkms plane during device creation. This pointer is
+ * not managed by the configuration and must be managed by other means.
+ */
+struct vkms_config_plane {
+ struct list_head link;
+
+ enum drm_plane_type type;
+
+ /* Internal usage */
+ struct vkms_plane *plane;
};
/**
@@ -42,6 +63,24 @@ void vkms_config_destroy(struct vkms_config *config);
*/
bool vkms_config_is_valid(struct vkms_config *vkms_config);
+/**
+ * vkms_config_create_plane() - Create a plane configuration
+ *
+ * This will allocate and add a new plane to @vkms_config. This plane will have by default the
+ * maximum supported values.
+ * @vkms_config: Configuration where to insert new plane
+ */
+struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_config);
+
+/**
+ * vkms_config_delete_plane() - Remove a plane configuration and frees its memory
+ *
+ * This will delete a plane configuration from the parent configuration. This will NOT
+ * cleanup and frees the vkms_plane that can be stored in @vkms_config_plane.
+ * @vkms_config_plane: Plane configuration to cleanup
+ */
+void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_plane);
+
/**
* vkms_config_alloc_default() - Allocate the configuration for the default device
* @enable_writeback: Enable the writeback connector for this configuration
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 6dde780d0515394faf2a4763f9bb7447a28d1472..acb0258d1ff18f97bde3630b3d2f3b8fcc511e67 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -213,6 +213,7 @@ struct vkms_crtc {
};
struct vkms_config;
+struct vkms_config_plane;
/**
* struct vkms_device - Description of a VKMS device
@@ -269,7 +270,7 @@ int vkms_output_init(struct vkms_device *vkmsdev);
* @type: type of plane to initialize
*/
struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
- enum drm_plane_type type);
+ struct vkms_config_plane *config);
/* CRC Support */
const char *const *vkms_get_crc_sources(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 34b6e761bce8a1f2153e1e47c795bad1a52a3454..20bd39f06f433b5b9cee2b0e4fa2176999ed85aa 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -31,30 +31,14 @@ static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = {
int vkms_output_init(struct vkms_device *vkmsdev)
{
+ struct vkms_config_plane *config_plane;
struct drm_device *dev = &vkmsdev->drm;
struct drm_connector *connector;
struct drm_encoder *encoder;
struct vkms_crtc *vkms_crtc;
- struct vkms_plane *primary, *overlay, *cursor = NULL;
+ struct vkms_plane *primary, *cursor = NULL;
int ret;
int writeback;
- unsigned int n;
-
- /*
- * Initialize used plane. One primary plane is required to perform the composition.
- *
- * The overlay and cursor planes are not mandatory, but can be used to perform complex
- * composition.
- */
- primary = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY);
- if (IS_ERR(primary))
- return PTR_ERR(primary);
-
- if (vkmsdev->config->cursor) {
- cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR);
- if (IS_ERR(cursor))
- return PTR_ERR(cursor);
- }
vkms_crtc = vkms_crtc_init(dev, &primary->base,
cursor ? &cursor->base : NULL);
@@ -63,15 +47,16 @@ int vkms_output_init(struct vkms_device *vkmsdev)
return PTR_ERR(vkms_crtc);
}
- if (vkmsdev->config->overlay) {
- for (n = 0; n < NUM_OVERLAY_PLANES; n++) {
- overlay = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_OVERLAY);
- if (IS_ERR(overlay)) {
- DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n");
- return PTR_ERR(overlay);
- }
- overlay->base.possible_crtcs = drm_crtc_mask(&vkms_crtc->base);
+ list_for_each_entry(config_plane, &vkmsdev->config->planes, link) {
+ config_plane->plane = vkms_plane_init(vkmsdev, config_plane);
+ if (IS_ERR(config_plane->plane)) {
+ ret = PTR_ERR(config_plane->plane);
+ return ret;
}
+ if (config_plane->type == DRM_PLANE_TYPE_PRIMARY)
+ primary = config_plane->plane;
+ else if (config_plane->type == DRM_PLANE_TYPE_CURSOR)
+ cursor = config_plane->plane;
}
connector = drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 4ab0fab4dd09f4be14308afb2f52bc6465f6396d..3d742e47e0fcd647225251f53a73b6ac0e669868 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -11,6 +11,7 @@
#include "vkms_drv.h"
#include "vkms_formats.h"
+#include "vkms_config.h"
static const u32 vkms_formats[] = {
DRM_FORMAT_ARGB8888,
@@ -219,7 +220,7 @@ static const struct drm_plane_helper_funcs vkms_plane_helper_funcs = {
};
struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
- enum drm_plane_type type)
+ struct vkms_config_plane *config)
{
struct drm_device *dev = &vkmsdev->drm;
struct vkms_plane *plane;
@@ -227,7 +228,7 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 0,
&vkms_plane_funcs,
vkms_formats, ARRAY_SIZE(vkms_formats),
- NULL, type, NULL);
+ NULL, config->type, NULL);
if (IS_ERR(plane))
return plane;
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 05/18] drm/vkms: Introduce config for plane name
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (3 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 04/18] drm/vkms: Introduce config for plane Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 06/18] drm/vkms: Introduce config for plane rotation Louis Chauvet
` (12 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
As a plane will be a folder in ConfigFS, add name configuration for plane
so it will reflect the folder name.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 14 ++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 2 ++
drivers/gpu/drm/vkms/vkms_plane.c | 2 +-
3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 31981dce2c2ed3ef8fc52e227e301d5f8d5338e6..8af7b80d1fea201102f45f8ee49fd88ce26733e3 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -36,6 +36,10 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
goto err_alloc;
plane->type = DRM_PLANE_TYPE_PRIMARY;
+ plane->name = kzalloc(sizeof("primary"), GFP_KERNEL);
+ if (!plane->name)
+ goto err_alloc;
+ sprintf(plane->name, "primary");
if (enable_overlay) {
for (int i = 0; i < NUM_OVERLAY_PLANES; i++) {
@@ -43,6 +47,10 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
if (!plane)
goto err_alloc;
plane->type = DRM_PLANE_TYPE_OVERLAY;
+ plane->name = kzalloc(10, GFP_KERNEL);
+ if (!plane->name)
+ goto err_alloc;
+ snprintf(plane->name, 10, "plane-%d", i);
}
}
if (enable_cursor) {
@@ -50,6 +58,10 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
if (!plane)
goto err_alloc;
plane->type = DRM_PLANE_TYPE_CURSOR;
+ plane->name = kzalloc(sizeof("cursor"), GFP_KERNEL);
+ if (!plane->name)
+ goto err_alloc;
+ sprintf(plane->name, "cursor");
}
return vkms_config;
@@ -82,6 +94,7 @@ void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_overlay)
if (!vkms_config_overlay)
return;
list_del(&vkms_config_overlay->link);
+ kfree(vkms_config_overlay->name);
kfree(vkms_config_overlay);
}
@@ -136,6 +149,7 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback);
list_for_each_entry(config_plane, &vkmsdev->config->planes, link) {
seq_puts(m, "plane:\n");
+ seq_printf(m, "\tname: %s\n", config_plane->name);
seq_printf(m, "\ttype: %d\n", config_plane->type);
}
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index ac99f1df6d9a17bd7040a1e7a6acce14cd8fd9d0..3e70bce8d4f7b06f44ec79b3a3d8e6897f9a44c7 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -27,6 +27,7 @@ struct vkms_config {
* struct vkms_config_plane
*
* @link: Link to the others planes
+ * @name: Name of the plane
* @type: Type of the plane. The creator of configuration needs to ensures that at least one
* plane is primary.
* @plane: Internal usage. This pointer should never be considered as valid. It can be used to
@@ -36,6 +37,7 @@ struct vkms_config {
struct vkms_config_plane {
struct list_head link;
+ char *name;
enum drm_plane_type type;
/* Internal usage */
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 3d742e47e0fcd647225251f53a73b6ac0e669868..56725f243382d75668ab2bf23423a69c75cb366b 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -228,7 +228,7 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 0,
&vkms_plane_funcs,
vkms_formats, ARRAY_SIZE(vkms_formats),
- NULL, config->type, NULL);
+ NULL, config->type, config->name);
if (IS_ERR(plane))
return plane;
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 06/18] drm/vkms: Introduce config for plane rotation
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (4 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 05/18] drm/vkms: Introduce config for plane name Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 07/18] drm/vkms: Introduce config for plane color encoding Louis Chauvet
` (11 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
VKMS driver supports all the rotation on planes, but for testing it can be
useful to only advertise few of them. This new configuration interface
will allow configuring the rotation per planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 9 +++++++++
drivers/gpu/drm/vkms/vkms_config.h | 4 ++++
drivers/gpu/drm/vkms/vkms_plane.c | 5 +++--
3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 8af7b80d1fea201102f45f8ee49fd88ce26733e3..6a2e5f0c580a348effc12b474a7f87dcd4e36642 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -82,6 +82,8 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_conf
return NULL;
vkms_config_overlay->type = DRM_PLANE_TYPE_OVERLAY;
+ vkms_config_overlay->supported_rotations = DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK;
+ vkms_config_overlay->default_rotation = DRM_MODE_ROTATE_0;
list_add(&vkms_config_overlay->link, &vkms_config->planes);
@@ -118,6 +120,11 @@ bool vkms_config_is_valid(struct vkms_config *config)
bool has_primary = false;
list_for_each_entry(config_plane, &config->planes, link) {
+ // Default rotation not in supported rotations
+ if ((config_plane->default_rotation & config_plane->supported_rotations) !=
+ config_plane->default_rotation)
+ return false;
+
if (config_plane->type == DRM_PLANE_TYPE_PRIMARY) {
// Multiple primary planes for only one CRTC
if (has_primary)
@@ -151,6 +158,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_puts(m, "plane:\n");
seq_printf(m, "\tname: %s\n", config_plane->name);
seq_printf(m, "\ttype: %d\n", config_plane->type);
+ seq_printf(m, "\tsupported rotations: 0x%x\n", config_plane->supported_rotations);
+ seq_printf(m, "\tdefault rotation: 0x%x\n", config_plane->default_rotation);
}
return 0;
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 3e70bce8d4f7b06f44ec79b3a3d8e6897f9a44c7..fd5e0df11647f145d53e71a1b6a244951af3ec0d 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -30,6 +30,8 @@ struct vkms_config {
* @name: Name of the plane
* @type: Type of the plane. The creator of configuration needs to ensures that at least one
* plane is primary.
+ * @default_rotation: Default rotation that should be used by this plane
+ * @supported_rotation: Rotation that this plane will support
* @plane: Internal usage. This pointer should never be considered as valid. It can be used to
* store a temporary reference to a vkms plane during device creation. This pointer is
* not managed by the configuration and must be managed by other means.
@@ -39,6 +41,8 @@ struct vkms_config_plane {
char *name;
enum drm_plane_type type;
+ unsigned int default_rotation;
+ unsigned int supported_rotations;
/* Internal usage */
struct vkms_plane *plane;
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 56725f243382d75668ab2bf23423a69c75cb366b..306af498543cbc39b8af3e5b5879f8b3972d5a4a 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -234,8 +234,9 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
drm_plane_helper_add(&plane->base, &vkms_plane_helper_funcs);
- drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0,
- DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
+ drm_plane_create_rotation_property(&plane->base,
+ config->default_rotation,
+ config->supported_rotations);
drm_plane_create_color_properties(&plane->base,
BIT(DRM_COLOR_YCBCR_BT601) |
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 07/18] drm/vkms: Introduce config for plane color encoding
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (5 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 06/18] drm/vkms: Introduce config for plane rotation Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 08/18] drm/vkms: Introduce config for plane color range Louis Chauvet
` (10 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
VKMS driver supports all the color encoding on planes, but for testing it
can be useful to only advertise few of them. This new configuration
interface will allow configuring the color encoding per planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 15 +++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 4 ++++
drivers/gpu/drm/vkms/vkms_plane.c | 6 ++----
3 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 6a2e5f0c580a348effc12b474a7f87dcd4e36642..9f9ebe674f6cbe03ac15e5380e4584c40a8bdea7 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -84,6 +84,11 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_conf
vkms_config_overlay->type = DRM_PLANE_TYPE_OVERLAY;
vkms_config_overlay->supported_rotations = DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK;
vkms_config_overlay->default_rotation = DRM_MODE_ROTATE_0;
+ vkms_config_overlay->supported_color_encoding = BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020);
+ vkms_config_overlay->default_color_encoding = DRM_COLOR_YCBCR_BT601;
+
list_add(&vkms_config_overlay->link, &vkms_config->planes);
@@ -125,6 +130,12 @@ bool vkms_config_is_valid(struct vkms_config *config)
config_plane->default_rotation)
return false;
+ // Default color range not in supported color range
+ if ((BIT(config_plane->default_color_encoding) &
+ config_plane->supported_color_encoding) !=
+ BIT(config_plane->default_color_encoding))
+ return false;
+
if (config_plane->type == DRM_PLANE_TYPE_PRIMARY) {
// Multiple primary planes for only one CRTC
if (has_primary)
@@ -160,6 +171,10 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_printf(m, "\ttype: %d\n", config_plane->type);
seq_printf(m, "\tsupported rotations: 0x%x\n", config_plane->supported_rotations);
seq_printf(m, "\tdefault rotation: 0x%x\n", config_plane->default_rotation);
+ seq_printf(m, "\tsupported color encoding: 0x%x\n",
+ config_plane->supported_color_encoding);
+ seq_printf(m, "\tdefault color encoding: %d\n",
+ config_plane->default_color_encoding);
}
return 0;
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index fd5e0df11647f145d53e71a1b6a244951af3ec0d..6cc9b89a996fe26c04951981cfeff7b603c6aec4 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -32,6 +32,8 @@ struct vkms_config {
* plane is primary.
* @default_rotation: Default rotation that should be used by this plane
* @supported_rotation: Rotation that this plane will support
+ * @default_color_encoding: Default color encoding that should be used by this plane
+ * @supported_color_encoding: Color encoding that this plane will support
* @plane: Internal usage. This pointer should never be considered as valid. It can be used to
* store a temporary reference to a vkms plane during device creation. This pointer is
* not managed by the configuration and must be managed by other means.
@@ -43,6 +45,8 @@ struct vkms_config_plane {
enum drm_plane_type type;
unsigned int default_rotation;
unsigned int supported_rotations;
+ enum drm_color_encoding default_color_encoding;
+ unsigned int supported_color_encoding;
/* Internal usage */
struct vkms_plane *plane;
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 306af498543cbc39b8af3e5b5879f8b3972d5a4a..77704ee2d49d2ce1551f67cab6308dc69b329ef5 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -239,12 +239,10 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
config->supported_rotations);
drm_plane_create_color_properties(&plane->base,
- BIT(DRM_COLOR_YCBCR_BT601) |
- BIT(DRM_COLOR_YCBCR_BT709) |
- BIT(DRM_COLOR_YCBCR_BT2020),
+ config->supported_color_encoding,
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
BIT(DRM_COLOR_YCBCR_FULL_RANGE),
- DRM_COLOR_YCBCR_BT601,
+ config->default_color_encoding,
DRM_COLOR_YCBCR_FULL_RANGE);
return plane;
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 08/18] drm/vkms: Introduce config for plane color range
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (6 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 07/18] drm/vkms: Introduce config for plane color encoding Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 09/18] drm/vkms: Introduce config for CRTCs and encoders Louis Chauvet
` (9 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
VKMS driver supports all the color range on planes, but for testing it can
be useful to only advertise few of them. This new configuration interface
will allow configuring the color range per planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 14 +++++++++++++-
drivers/gpu/drm/vkms/vkms_config.h | 4 ++++
drivers/gpu/drm/vkms/vkms_plane.c | 5 ++---
3 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 9f9ebe674f6cbe03ac15e5380e4584c40a8bdea7..10fef173fba921e9abacb5e6dfd292b396694815 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -88,7 +88,9 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_conf
BIT(DRM_COLOR_YCBCR_BT709) |
BIT(DRM_COLOR_YCBCR_BT2020);
vkms_config_overlay->default_color_encoding = DRM_COLOR_YCBCR_BT601;
-
+ vkms_config_overlay->supported_color_range = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE);
+ vkms_config_overlay->default_color_range = DRM_COLOR_YCBCR_FULL_RANGE;
list_add(&vkms_config_overlay->link, &vkms_config->planes);
@@ -136,6 +138,12 @@ bool vkms_config_is_valid(struct vkms_config *config)
BIT(config_plane->default_color_encoding))
return false;
+ // Default color range not in supported color range
+ if ((BIT(config_plane->default_color_range) &
+ config_plane->supported_color_range) !=
+ BIT(config_plane->default_color_range))
+ return false;
+
if (config_plane->type == DRM_PLANE_TYPE_PRIMARY) {
// Multiple primary planes for only one CRTC
if (has_primary)
@@ -175,6 +183,10 @@ static int vkms_config_show(struct seq_file *m, void *data)
config_plane->supported_color_encoding);
seq_printf(m, "\tdefault color encoding: %d\n",
config_plane->default_color_encoding);
+ seq_printf(m, "\tsupported color range: 0x%x\n",
+ config_plane->supported_color_range);
+ seq_printf(m, "\tdefault color range: %d\n",
+ config_plane->default_color_range);
}
return 0;
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 6cc9b89a996fe26c04951981cfeff7b603c6aec4..8a58c633f9d4649308ce0c536acfcffb03c0617f 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -34,6 +34,8 @@ struct vkms_config {
* @supported_rotation: Rotation that this plane will support
* @default_color_encoding: Default color encoding that should be used by this plane
* @supported_color_encoding: Color encoding that this plane will support
+ * @default_color_range: Default color range that should be used by this plane
+ * @supported_color_range: Color range that this plane will support
* @plane: Internal usage. This pointer should never be considered as valid. It can be used to
* store a temporary reference to a vkms plane during device creation. This pointer is
* not managed by the configuration and must be managed by other means.
@@ -47,6 +49,8 @@ struct vkms_config_plane {
unsigned int supported_rotations;
enum drm_color_encoding default_color_encoding;
unsigned int supported_color_encoding;
+ enum drm_color_range default_color_range;
+ unsigned int supported_color_range;
/* Internal usage */
struct vkms_plane *plane;
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 77704ee2d49d2ce1551f67cab6308dc69b329ef5..90a5946481e47ab7cff9b9dc4942720b6bbcbe3f 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -240,10 +240,9 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
drm_plane_create_color_properties(&plane->base,
config->supported_color_encoding,
- BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
- BIT(DRM_COLOR_YCBCR_FULL_RANGE),
+ config->supported_color_range,
config->default_color_encoding,
- DRM_COLOR_YCBCR_FULL_RANGE);
+ config->default_color_range);
return plane;
}
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 09/18] drm/vkms: Introduce config for CRTCs and encoders
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (7 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 08/18] drm/vkms: Introduce config for plane color range Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 10/18] drm/vkms: Introduce config for encoder name Louis Chauvet
` (8 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
The current VKMS driver can only uses one CRTC and one encoder. This patch
introduce in the same time CRTC and encoders as they are tighly linked.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 269 +++++++++++++++++++++++++++++++++----
drivers/gpu/drm/vkms/vkms_config.h | 104 +++++++++++++-
drivers/gpu/drm/vkms/vkms_crtc.c | 14 +-
drivers/gpu/drm/vkms/vkms_drv.h | 7 +-
drivers/gpu/drm/vkms/vkms_output.c | 86 ++++++------
5 files changed, 405 insertions(+), 75 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 10fef173fba921e9abacb5e6dfd292b396694815..e44ed904cefb97b8b6ab8fc27623e315397e0106 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -15,6 +15,8 @@ struct vkms_config *vkms_config_create(void)
return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&config->planes);
+ INIT_LIST_HEAD(&config->crtcs);
+ INIT_LIST_HEAD(&config->encoders);
return config;
}
@@ -24,12 +26,24 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
bool enable_cursor)
{
struct vkms_config_plane *plane;
+ struct vkms_config_encoder *encoder;
+ struct vkms_config_crtc *crtc;
struct vkms_config *vkms_config = vkms_config_create();
if (IS_ERR(vkms_config))
return vkms_config;
- vkms_config->writeback = enable_writeback;
+ crtc = vkms_config_create_crtc(vkms_config);
+ if (!crtc)
+ goto err_alloc;
+ crtc->writeback = enable_writeback;
+
+ encoder = vkms_config_create_encoder(vkms_config);
+ if (!encoder)
+ goto err_alloc;
+
+ if (vkms_config_encoder_attach_crtc(encoder, crtc))
+ goto err_alloc;
plane = vkms_config_create_plane(vkms_config);
if (!plane)
@@ -41,6 +55,9 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
goto err_alloc;
sprintf(plane->name, "primary");
+ if (vkms_config_plane_attach_crtc(plane, crtc))
+ goto err_alloc;
+
if (enable_overlay) {
for (int i = 0; i < NUM_OVERLAY_PLANES; i++) {
plane = vkms_config_create_plane(vkms_config);
@@ -51,6 +68,9 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
if (!plane->name)
goto err_alloc;
snprintf(plane->name, 10, "plane-%d", i);
+
+ if (vkms_config_plane_attach_crtc(plane, crtc))
+ goto err_alloc;
}
}
if (enable_cursor) {
@@ -62,6 +82,9 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
if (!plane->name)
goto err_alloc;
sprintf(plane->name, "cursor");
+
+ if (vkms_config_plane_attach_crtc(plane, crtc))
+ goto err_alloc;
}
return vkms_config;
@@ -91,6 +114,7 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_conf
vkms_config_overlay->supported_color_range = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
BIT(DRM_COLOR_YCBCR_FULL_RANGE);
vkms_config_overlay->default_color_range = DRM_COLOR_YCBCR_FULL_RANGE;
+ xa_init_flags(&vkms_config_overlay->possible_crtcs, XA_FLAGS_ALLOC);
list_add(&vkms_config_overlay->link, &vkms_config->planes);
@@ -98,33 +122,195 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_conf
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_plane);
-void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_overlay)
+struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *vkms_config)
{
- if (!vkms_config_overlay)
+ if (!vkms_config)
+ return NULL;
+
+ struct vkms_config_crtc *vkms_config_crtc = kzalloc(sizeof(*vkms_config_crtc),
+ GFP_KERNEL);
+
+ if (!vkms_config_crtc)
+ return NULL;
+
+ list_add(&vkms_config_crtc->link, &vkms_config->crtcs);
+ xa_init_flags(&vkms_config_crtc->possible_planes, XA_FLAGS_ALLOC);
+ xa_init_flags(&vkms_config_crtc->possible_encoders, XA_FLAGS_ALLOC);
+
+ return vkms_config_crtc;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_crtc);
+
+struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *vkms_config)
+{
+ if (!vkms_config)
+ return NULL;
+
+ struct vkms_config_encoder *vkms_config_encoder = kzalloc(sizeof(*vkms_config_encoder),
+ GFP_KERNEL);
+
+ if (!vkms_config_encoder)
+ return NULL;
+
+ list_add(&vkms_config_encoder->link, &vkms_config->encoders);
+ xa_init_flags(&vkms_config_encoder->possible_crtcs, XA_FLAGS_ALLOC);
+
+ return vkms_config_encoder;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_encoder);
+
+void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_plane,
+ struct vkms_config *vkms_config)
+{
+ struct vkms_config_crtc *crtc_config;
+ struct vkms_config_plane *plane;
+
+ if (!vkms_config_plane)
+ return;
+ list_del(&vkms_config_plane->link);
+ xa_destroy(&vkms_config_plane->possible_crtcs);
+
+ list_for_each_entry(crtc_config, &vkms_config->crtcs, link) {
+ unsigned long idx = 0;
+
+ xa_for_each(&crtc_config->possible_planes, idx, plane) {
+ if (plane == vkms_config_plane)
+ xa_erase(&crtc_config->possible_planes, idx);
+ }
+ }
+
+ kfree(vkms_config_plane->name);
+ kfree(vkms_config_plane);
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_delete_plane);
+
+void vkms_config_delete_crtc(struct vkms_config_crtc *vkms_config_crtc,
+ struct vkms_config *vkms_config)
+{
+ struct vkms_config_crtc *crtc_config;
+ struct vkms_config_plane *plane_config;
+ struct vkms_config_encoder *encoder_config;
+
+ if (!vkms_config_crtc)
+ return;
+ list_del(&vkms_config_crtc->link);
+ xa_destroy(&vkms_config_crtc->possible_planes);
+ xa_destroy(&vkms_config_crtc->possible_encoders);
+
+ list_for_each_entry(plane_config, &vkms_config->planes, link) {
+ unsigned long idx = 0;
+
+ xa_for_each(&plane_config->possible_crtcs, idx, crtc_config) {
+ if (crtc_config == vkms_config_crtc)
+ xa_erase(&plane_config->possible_crtcs, idx);
+ }
+ }
+
+ list_for_each_entry(encoder_config, &vkms_config->encoders, link) {
+ unsigned long idx = 0;
+
+ xa_for_each(&encoder_config->possible_crtcs, idx, crtc_config) {
+ if (crtc_config == vkms_config_crtc)
+ xa_erase(&encoder_config->possible_crtcs, idx);
+ }
+ }
+
+ kfree(vkms_config_crtc);
+}
+
+void vkms_config_delete_encoder(struct vkms_config_encoder *vkms_config_encoder,
+ struct vkms_config *vkms_config)
+{
+ if (!vkms_config_encoder)
return;
- list_del(&vkms_config_overlay->link);
- kfree(vkms_config_overlay->name);
- kfree(vkms_config_overlay);
+ list_del(&vkms_config_encoder->link);
+ xa_destroy(&vkms_config_encoder->possible_crtcs);
+
+ struct vkms_config_crtc *crtc_config;
+ struct vkms_config_encoder *encoder;
+
+ list_for_each_entry(crtc_config, &vkms_config->crtcs, link) {
+ unsigned long idx = 0;
+
+ xa_for_each(&crtc_config->possible_encoders, idx, encoder) {
+ if (encoder == vkms_config_encoder)
+ xa_erase(&crtc_config->possible_encoders, idx);
+ }
+ }
+
+ kfree(vkms_config_encoder);
}
void vkms_config_destroy(struct vkms_config *config)
{
struct vkms_config_plane *vkms_config_plane, *tmp_plane;
+ struct vkms_config_encoder *vkms_config_encoder, *tmp_encoder;
+ struct vkms_config_crtc *vkms_config_crtc, *tmp_crtc;
list_for_each_entry_safe(vkms_config_plane, tmp_plane, &config->planes, link) {
- vkms_config_delete_plane(vkms_config_plane);
+ vkms_config_delete_plane(vkms_config_plane, config);
+ }
+ list_for_each_entry_safe(vkms_config_encoder, tmp_encoder, &config->encoders, link) {
+ vkms_config_delete_encoder(vkms_config_encoder, config);
+ }
+ list_for_each_entry_safe(vkms_config_crtc, tmp_crtc, &config->crtcs, link) {
+ vkms_config_delete_crtc(vkms_config_crtc, config);
}
kfree(config);
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy);
+int __must_check vkms_config_plane_attach_crtc(struct vkms_config_plane *vkms_config_plane,
+ struct vkms_config_crtc *vkms_config_crtc)
+{
+ u32 crtc_idx, encoder_idx;
+ int ret;
+
+ ret = xa_alloc(&vkms_config_plane->possible_crtcs, &crtc_idx, vkms_config_crtc,
+ xa_limit_32b, GFP_KERNEL);
+ if (ret)
+ return ret;
+
+ ret = xa_alloc(&vkms_config_crtc->possible_planes, &encoder_idx, vkms_config_plane,
+ xa_limit_32b, GFP_KERNEL);
+ if (ret) {
+ xa_erase(&vkms_config_plane->possible_crtcs, crtc_idx);
+ return ret;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_plane_attach_crtc);
+
+int __must_check vkms_config_encoder_attach_crtc(struct vkms_config_encoder *vkms_config_encoder,
+ struct vkms_config_crtc *vkms_config_crtc)
+{
+ u32 crtc_idx, encoder_idx;
+ int ret;
+
+ ret = xa_alloc(&vkms_config_encoder->possible_crtcs, &crtc_idx, vkms_config_crtc,
+ xa_limit_32b, GFP_KERNEL);
+ if (ret)
+ return ret;
+
+ ret = xa_alloc(&vkms_config_crtc->possible_encoders, &encoder_idx, vkms_config_encoder,
+ xa_limit_32b, GFP_KERNEL);
+ if (ret) {
+ xa_erase(&vkms_config_encoder->possible_crtcs, crtc_idx);
+ return ret;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_encoder_attach_crtc);
+
bool vkms_config_is_valid(struct vkms_config *config)
{
struct vkms_config_plane *config_plane;
- bool has_cursor = false;
- bool has_primary = false;
+ struct vkms_config_crtc *config_crtc;
+ struct vkms_config_encoder *config_encoder;
list_for_each_entry(config_plane, &config->planes, link) {
// Default rotation not in supported rotations
@@ -144,22 +330,47 @@ bool vkms_config_is_valid(struct vkms_config *config)
BIT(config_plane->default_color_range))
return false;
- if (config_plane->type == DRM_PLANE_TYPE_PRIMARY) {
- // Multiple primary planes for only one CRTC
- if (has_primary)
- return false;
- has_primary = true;
- }
- if (config_plane->type == DRM_PLANE_TYPE_CURSOR) {
- // Multiple cursor planes for only one CRTC
- if (has_cursor)
- return false;
- has_cursor = true;
- }
+ // No CRTC linked to this plane
+ if (xa_empty(&config_plane->possible_crtcs))
+ return false;
+ }
+
+ list_for_each_entry(config_encoder, &config->encoders, link) {
+ // No CRTC linked to this encoder
+ if (xa_empty(&config_encoder->possible_crtcs))
+ return false;
}
- if (!has_primary)
- return false;
+ list_for_each_entry(config_crtc, &config->crtcs, link) {
+ bool has_primary = false;
+ bool has_cursor = false;
+ unsigned long idx = 0;
+
+ // No encoder attached to this CRTC
+ if (xa_empty(&config_crtc->possible_encoders))
+ return false;
+
+ xa_for_each(&config_crtc->possible_planes, idx, config_plane) {
+ if (config_plane->type == DRM_PLANE_TYPE_PRIMARY) {
+ // Multiple primary planes for only one CRTC
+ if (has_primary)
+ return false;
+
+ has_primary = true;
+ }
+ if (config_plane->type == DRM_PLANE_TYPE_CURSOR) {
+ // Multiple cursor planes for only one CRTC
+ if (has_cursor)
+ return false;
+
+ has_cursor = true;
+ }
+ }
+
+ // No primary plane for this CRTC
+ if (!has_primary)
+ return false;
+ }
return true;
}
@@ -171,8 +382,9 @@ static int vkms_config_show(struct seq_file *m, void *data)
struct drm_device *dev = entry->dev;
struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
struct vkms_config_plane *config_plane;
+ struct vkms_config_crtc *config_crtc;
+ struct vkms_config_encoder *config_encoder;
- seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback);
list_for_each_entry(config_plane, &vkmsdev->config->planes, link) {
seq_puts(m, "plane:\n");
seq_printf(m, "\tname: %s\n", config_plane->name);
@@ -189,6 +401,15 @@ static int vkms_config_show(struct seq_file *m, void *data)
config_plane->default_color_range);
}
+ list_for_each_entry(config_encoder, &vkmsdev->config->encoders, link) {
+ seq_puts(m, "encoder:\n");
+ }
+
+ list_for_each_entry(config_crtc, &vkmsdev->config->crtcs, link) {
+ seq_puts(m, "crtc:\n");
+ seq_printf(m, "\twriteback: %d\n", config_crtc->writeback);
+ }
+
return 0;
}
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 8a58c633f9d4649308ce0c536acfcffb03c0617f..8f247fc09373fb2c8145e83be05c6afec1ffac1c 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -9,18 +9,59 @@
/**
* struct vkms_config - General configuration for VKMS driver
*
- * @writeback: If true, a writeback buffer can be attached to the CRTC
* @planes: List of planes configured for this device. They are created by the function
* vkms_config_create_plane().
+ * @crtcs: List of crtcs configured for this device. They are created by the function
+ * vkms_config_create_crtc().
+ * @encoders: List of encoders configured for this device. They are created by the function
+ * vkms_config_create_encoder().
* @dev: Used to store the current vkms device. Only set when the device is instancied.
*/
struct vkms_config {
- bool writeback;
- bool cursor;
- bool overlay;
struct vkms_device *dev;
struct list_head planes;
+ struct list_head crtcs;
+ struct list_head encoders;
+};
+
+/**
+ * struct vkms_config_crtc
+ *
+ * @link: Link to the others CRTCs
+ * @possible_planes: List of planes that can be used with this CRTC
+ * @possible_encoders: List of encoders that can be used with this CRTC
+ * @crtc: Internal usage. This pointer should never be considered as valid. It can be used to
+ * store a temporary reference to a vkms crtc during device creation. This pointer is
+ * not managed by the configuration and must be managed by other means.
+ */
+struct vkms_config_crtc {
+ struct list_head link;
+
+ bool writeback;
+ struct xarray possible_planes;
+ struct xarray possible_encoders;
+
+ /* Internal usage */
+ struct vkms_crtc *crtc;
+};
+
+/**
+ * struct vkms_config_encoder
+ *
+ * @link: Link to the others encoders
+ * @possible_crtcs: List of CRTC that can be used with this encoder
+ * @encoder: Internal usage. This pointer should never be considered as valid. It can be used to
+ * store a temporary reference to a vkms encoder during device creation. This pointer is
+ * not managed by the configuration and must be managed by other means.
+ */
+struct vkms_config_encoder {
+ struct list_head link;
+
+ struct xarray possible_crtcs;
+
+ /* Internal usage */
+ struct drm_encoder *encoder;
};
/**
@@ -36,6 +77,7 @@ struct vkms_config {
* @supported_color_encoding: Color encoding that this plane will support
* @default_color_range: Default color range that should be used by this plane
* @supported_color_range: Color range that this plane will support
+ * @possible_crtcs: List of CRTC that can be used with this plane.
* @plane: Internal usage. This pointer should never be considered as valid. It can be used to
* store a temporary reference to a vkms plane during device creation. This pointer is
* not managed by the configuration and must be managed by other means.
@@ -52,6 +94,7 @@ struct vkms_config_plane {
enum drm_color_range default_color_range;
unsigned int supported_color_range;
+ struct xarray possible_crtcs;
/* Internal usage */
struct vkms_plane *plane;
};
@@ -86,14 +129,63 @@ bool vkms_config_is_valid(struct vkms_config *vkms_config);
*/
struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_config);
+/**
+ * vkms_config_create_crtc() - Create a crtc configuration
+ *
+ * This will allocate and add a new crtc configuration to @vkms_config.
+ * @vkms_config: Configuration where to insert new crtc configuration
+ */
+struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *vkms_config);
+
+/**
+ * vkms_config_create_encoder() - Create an encoder configuration
+ *
+ * This will allocate and add a new encoder configuration to @vkms_config.
+ * @vkms_config: Configuration where to insert new encoder configuration
+ */
+struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *vkms_config);
+
+int __must_check vkms_config_plane_attach_crtc(struct vkms_config_plane *vkms_config_plane,
+ struct vkms_config_crtc *vkms_config_crtc);
+int __must_check vkms_config_encoder_attach_crtc(struct vkms_config_encoder *vkms_config_encoder,
+ struct vkms_config_crtc *vkms_config_crtc);
+
/**
* vkms_config_delete_plane() - Remove a plane configuration and frees its memory
*
* This will delete a plane configuration from the parent configuration. This will NOT
- * cleanup and frees the vkms_plane that can be stored in @vkms_config_plane.
+ * cleanup and frees the vkms_plane that can be stored in @vkms_config_plane. It will also remove
+ * any reference to this plane in @vkms_config.
+ *
* @vkms_config_plane: Plane configuration to cleanup
+ * @vkms_config: Parent configuration
+ */
+void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_plane,
+ struct vkms_config *vkms_config);
+/**
+ * vkms_config_delete_crtc() - Remove a CRTC configuration and frees its memory
+ *
+ * This will delete a CRTC configuration from the parent configuration. This will NOT
+ * cleanup and frees the vkms_crtc that can be stored in @vkms_config_crtc. It will also remove
+ * any reference to this CRTC in @vkms_config.
+ *
+ * @vkms_config_crtc: Plane configuration to cleanup
+ * @vkms_config: Parent configuration
+ */
+void vkms_config_delete_crtc(struct vkms_config_crtc *vkms_config_crtc,
+ struct vkms_config *vkms_config);
+/**
+ * vkms_config_delete_encoder() - Remove an encoder configuration and frees its memory
+ *
+ * This will delete an encoder configuration from the parent configuration. This will NOT
+ * cleanup and frees the vkms_encoder that can be stored in @vkms_config_encoder. It will also
+ * remove any reference to this CRTC in @vkms_config.
+ *
+ * @vkms_config_encoder: Plane configuration to cleanup
+ * @vkms_config: Parent configuration
*/
-void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_plane);
+void vkms_config_delete_encoder(struct vkms_config_encoder *vkms_config_encoder,
+ struct vkms_config *vkms_config);
/**
* vkms_config_alloc_default() - Allocate the configuration for the default device
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 7851bcf335b7aa9a95848b3af8900812115b2189..3825fba57c012f84cbe67114e053dcd7fcfa283d 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -9,6 +9,7 @@
#include <drm/drm_managed.h>
#include "vkms_drv.h"
+#include "vkms_config.h"
static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
{
@@ -279,9 +280,12 @@ static void vkms_crtc_destroy_workqueue(struct drm_device *dev,
destroy_workqueue(vkms_crtc->composer_workq);
}
-struct vkms_crtc *vkms_crtc_init(struct drm_device *dev, struct drm_plane *primary,
- struct drm_plane *cursor)
+struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkms_device,
+ struct drm_plane *primary,
+ struct drm_plane *cursor,
+ struct vkms_config_crtc *config)
{
+ struct drm_device *dev = &vkms_device->drm;
struct vkms_crtc *vkms_crtc;
struct drm_crtc *crtc;
int ret;
@@ -318,5 +322,11 @@ struct vkms_crtc *vkms_crtc_init(struct drm_device *dev, struct drm_plane *prima
if (ret)
return ERR_PTR(ret);
+ if (config->writeback) {
+ ret = vkms_enable_writeback_connector(vkms_device, vkms_crtc);
+ if (ret)
+ return ERR_PTR(ret);
+ }
+
return vkms_crtc;
}
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index acb0258d1ff18f97bde3630b3d2f3b8fcc511e67..a772bf4168e11730c6ee2e3c79abce3a6351203f 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -214,6 +214,8 @@ struct vkms_crtc {
struct vkms_config;
struct vkms_config_plane;
+struct vkms_config_crtc;
+struct vkms_config_encoder;
/**
* struct vkms_device - Description of a VKMS device
@@ -252,9 +254,10 @@ struct vkms_device {
* @primary: primary plane to attach to the CRTC
* @cursor: plane to attach to the CRTC
*/
-struct vkms_crtc *vkms_crtc_init(struct drm_device *dev,
+struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkms_device,
struct drm_plane *primary,
- struct drm_plane *cursor);
+ struct drm_plane *cursor,
+ struct vkms_config_crtc *config);
/**
* vkms_output_init() - Initialize all sub-components needed for a VKMS device.
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 20bd39f06f433b5b9cee2b0e4fa2176999ed85aa..03498a20d78dd8a66f9fc66b360c5ea57fc48d88 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -31,21 +31,13 @@ static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = {
int vkms_output_init(struct vkms_device *vkmsdev)
{
- struct vkms_config_plane *config_plane;
+ struct vkms_config_encoder *config_encoder;
struct drm_device *dev = &vkmsdev->drm;
+ struct vkms_config_plane *config_plane;
+ struct vkms_config_crtc *config_crtc;
struct drm_connector *connector;
- struct drm_encoder *encoder;
- struct vkms_crtc *vkms_crtc;
- struct vkms_plane *primary, *cursor = NULL;
+ unsigned long idx;
int ret;
- int writeback;
-
- vkms_crtc = vkms_crtc_init(dev, &primary->base,
- cursor ? &cursor->base : NULL);
- if (IS_ERR(vkms_crtc)) {
- DRM_ERROR("Failed to allocate CRTC\n");
- return PTR_ERR(vkms_crtc);
- }
list_for_each_entry(config_plane, &vkmsdev->config->planes, link) {
config_plane->plane = vkms_plane_init(vkmsdev, config_plane);
@@ -53,10 +45,30 @@ int vkms_output_init(struct vkms_device *vkmsdev)
ret = PTR_ERR(config_plane->plane);
return ret;
}
- if (config_plane->type == DRM_PLANE_TYPE_PRIMARY)
- primary = config_plane->plane;
- else if (config_plane->type == DRM_PLANE_TYPE_CURSOR)
- cursor = config_plane->plane;
+ }
+
+ list_for_each_entry(config_crtc, &vkmsdev->config->crtcs, link) {
+ struct drm_plane *primary = NULL, *cursor = NULL;
+
+ xa_for_each(&config_crtc->possible_planes, idx, config_plane) {
+ if (config_plane->type == DRM_PLANE_TYPE_PRIMARY)
+ primary = &config_plane->plane->base;
+ else if (config_plane->type == DRM_PLANE_TYPE_CURSOR)
+ cursor = &config_plane->plane->base;
+ }
+
+ config_crtc->crtc = vkms_crtc_init(vkmsdev, primary, cursor, config_crtc);
+
+ if (IS_ERR(config_crtc->crtc)) {
+ ret = PTR_ERR(config_crtc->crtc);
+ return ret;
+ }
+ }
+
+ list_for_each_entry(config_crtc, &vkmsdev->config->crtcs, link) {
+ xa_for_each(&config_crtc->possible_planes, idx, config_plane) {
+ config_plane->plane->base.possible_crtcs |= drm_crtc_mask(&config_crtc->crtc->base);
+ }
}
connector = drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
@@ -74,33 +86,25 @@ int vkms_output_init(struct vkms_device *vkmsdev)
drm_connector_helper_add(connector, &vkms_conn_helper_funcs);
- encoder = drmm_kzalloc(dev, sizeof(*encoder), GFP_KERNEL);
- if (!encoder) {
- DRM_ERROR("Failed to allocate encoder\n");
- return -ENOMEM;
- }
- ret = drmm_encoder_init(dev, encoder, NULL,
- DRM_MODE_ENCODER_VIRTUAL, NULL);
- if (ret) {
- DRM_ERROR("Failed to init encoder\n");
- return ret;
- }
- encoder->possible_crtcs = drm_crtc_mask(&vkms_crtc->base);
-
- /* Attach the encoder and the connector */
- ret = drm_connector_attach_encoder(connector, encoder);
- if (ret) {
- DRM_ERROR("Failed to attach connector to encoder\n");
- return ret;
- }
-
- /* Initialize the writeback component */
- if (vkmsdev->config->writeback) {
- writeback = vkms_enable_writeback_connector(vkmsdev, vkms_crtc);
- if (writeback) {
- DRM_ERROR("Failed to init writeback connector\n");
+ list_for_each_entry(config_encoder, &vkmsdev->config->encoders, link) {
+ config_encoder->encoder = drmm_kzalloc(dev, sizeof(*config_encoder->encoder),
+ GFP_KERNEL);
+ if (!config_encoder->encoder)
+ return -ENOMEM;
+ ret = drmm_encoder_init(dev, config_encoder->encoder, NULL,
+ DRM_MODE_ENCODER_VIRTUAL, NULL);
+ if (ret) {
+ DRM_ERROR("Failed to init encoder\n");
return ret;
}
+ xa_for_each(&config_encoder->possible_crtcs, idx, config_crtc) {
+ config_encoder->encoder->possible_crtcs |= drm_crtc_mask(&config_crtc->crtc->base);
+ }
+ if (IS_ERR(config_encoder->encoder))
+ return PTR_ERR(config_encoder->encoder);
+ ret = drm_connector_attach_encoder(connector, config_encoder->encoder);
+ if (ret)
+ return ret;
}
drm_mode_config_reset(dev);
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 10/18] drm/vkms: Introduce config for encoder name
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (8 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 09/18] drm/vkms: Introduce config for CRTCs and encoders Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-25 9:28 ` Jani Nikula
2024-11-22 17:20 ` [PATCH RFC v2 11/18] drm/vkms: Introduce config for CRTC name Louis Chauvet
` (7 subsequent siblings)
17 siblings, 1 reply; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
As an encoder will be a directory in ConfigFS, add the configuration for
encoder name so we will be able to reflect the configfs directory name in
the drm name.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 6 ++++++
drivers/gpu/drm/vkms/vkms_config.h | 2 ++
drivers/gpu/drm/vkms/vkms_output.c | 2 +-
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index e44ed904cefb97b8b6ab8fc27623e315397e0106..a2539fb56b602569b75748fdf9c4784f104b0bff 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -41,6 +41,10 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
encoder = vkms_config_create_encoder(vkms_config);
if (!encoder)
goto err_alloc;
+ encoder->name = kzalloc(sizeof("Main Encoder"), GFP_KERNEL);
+ if (!encoder->name)
+ goto err_alloc;
+ sprintf(encoder->name, "Main Encoder");
if (vkms_config_encoder_attach_crtc(encoder, crtc))
goto err_alloc;
@@ -238,6 +242,7 @@ void vkms_config_delete_encoder(struct vkms_config_encoder *vkms_config_encoder,
}
}
+ kfree(vkms_config_encoder->name);
kfree(vkms_config_encoder);
}
@@ -403,6 +408,7 @@ static int vkms_config_show(struct seq_file *m, void *data)
list_for_each_entry(config_encoder, &vkmsdev->config->encoders, link) {
seq_puts(m, "encoder:\n");
+ seq_printf(m, "\tname: %s\n", config_encoder->name);
}
list_for_each_entry(config_crtc, &vkmsdev->config->crtcs, link) {
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 8f247fc09373fb2c8145e83be05c6afec1ffac1c..4223edd94ec270915dd658c0b5efd489554d33a5 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -50,6 +50,7 @@ struct vkms_config_crtc {
* struct vkms_config_encoder
*
* @link: Link to the others encoders
+ * @name: Name of the encoder
* @possible_crtcs: List of CRTC that can be used with this encoder
* @encoder: Internal usage. This pointer should never be considered as valid. It can be used to
* store a temporary reference to a vkms encoder during device creation. This pointer is
@@ -58,6 +59,7 @@ struct vkms_config_crtc {
struct vkms_config_encoder {
struct list_head link;
+ char *name;
struct xarray possible_crtcs;
/* Internal usage */
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 03498a20d78dd8a66f9fc66b360c5ea57fc48d88..6277ad72fdd476d1eff52ad037389bdb1a254f5e 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -92,7 +92,7 @@ int vkms_output_init(struct vkms_device *vkmsdev)
if (!config_encoder->encoder)
return -ENOMEM;
ret = drmm_encoder_init(dev, config_encoder->encoder, NULL,
- DRM_MODE_ENCODER_VIRTUAL, NULL);
+ DRM_MODE_ENCODER_VIRTUAL, config_encoder->name);
if (ret) {
DRM_ERROR("Failed to init encoder\n");
return ret;
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 11/18] drm/vkms: Introduce config for CRTC name
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (9 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 10/18] drm/vkms: Introduce config for encoder name Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-25 9:29 ` Jani Nikula
2024-11-22 17:20 ` [PATCH RFC v2 12/18] drm/vkms: Add test for config structure Louis Chauvet
` (6 subsequent siblings)
17 siblings, 1 reply; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
As a CRTC will be a directory in ConfigFS, add the name configuration for
CRTC name so we will be able to reflect the configfs directory name in the
drm name.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 5 +++++
drivers/gpu/drm/vkms/vkms_config.h | 2 ++
drivers/gpu/drm/vkms/vkms_crtc.c | 2 +-
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index a2539fb56b602569b75748fdf9c4784f104b0bff..3252f657ce515c0193a8c0e709bfe861feba0aca 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -37,6 +37,10 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
if (!crtc)
goto err_alloc;
crtc->writeback = enable_writeback;
+ crtc->name = kzalloc(sizeof("Main CRTC"), GFP_KERNEL);
+ if (!crtc->name)
+ goto err_alloc;
+ sprintf(crtc->name, "Main CRTC");
encoder = vkms_config_create_encoder(vkms_config);
if (!encoder)
@@ -219,6 +223,7 @@ void vkms_config_delete_crtc(struct vkms_config_crtc *vkms_config_crtc,
}
}
+ kfree(vkms_config_crtc->name);
kfree(vkms_config_crtc);
}
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 4223edd94ec270915dd658c0b5efd489554d33a5..4a4c16dea7855cf36060986ef247be698974fafc 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -29,6 +29,7 @@ struct vkms_config {
* struct vkms_config_crtc
*
* @link: Link to the others CRTCs
+ * @name: Name of the CRTC
* @possible_planes: List of planes that can be used with this CRTC
* @possible_encoders: List of encoders that can be used with this CRTC
* @crtc: Internal usage. This pointer should never be considered as valid. It can be used to
@@ -38,6 +39,7 @@ struct vkms_config {
struct vkms_config_crtc {
struct list_head link;
+ char *name;
bool writeback;
struct xarray possible_planes;
struct xarray possible_encoders;
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 3825fba57c012f84cbe67114e053dcd7fcfa283d..25a3d97a362afd0d40f3e023d9cce985d447a880 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -292,7 +292,7 @@ struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkms_device,
vkms_crtc = drmm_crtc_alloc_with_planes(dev, struct vkms_crtc, base,
primary, cursor,
- &vkms_crtc_funcs, NULL);
+ &vkms_crtc_funcs, config->name);
if (IS_ERR(vkms_crtc)) {
DRM_DEV_ERROR(dev->dev, "Failed to init CRTC\n");
return vkms_crtc;
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 12/18] drm/vkms: Add test for config structure
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (10 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 11/18] drm/vkms: Introduce config for CRTC name Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 13/18] drm/vkms: Introduce config for connector Louis Chauvet
` (5 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
The config structure is a bit complex in term of memory management. Add
basic test to avoid breaking it in the future.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/Makefile | 1 +
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 137 ++++++++++++++++++++++++++
2 files changed, 138 insertions(+)
diff --git a/drivers/gpu/drm/vkms/tests/Makefile b/drivers/gpu/drm/vkms/tests/Makefile
index 2d1df668569e4f243ed9a06c1e16e595c131c4f6..ec71b5fe7f9d957eeeabd233bb75c4c250789ff4 100644
--- a/drivers/gpu/drm/vkms/tests/Makefile
+++ b/drivers/gpu/drm/vkms/tests/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += vkms_format_test.o
+obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += vkms_config_test.o
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..12b845bc358aaa44434c6b66184cf17d19656596
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <kunit/test.h>
+
+#include "../vkms_config.h"
+
+MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING);
+
+static void vkms_config_test_basic_allocation(struct kunit *test)
+{
+ struct vkms_config *config = vkms_config_create();
+
+ KUNIT_EXPECT_TRUE_MSG(test, list_empty(&config->encoders),
+ "Encoder list is not empty after allocation");
+ KUNIT_EXPECT_TRUE_MSG(test, list_empty(&config->crtcs),
+ "CRTC list is not empty after allocation");
+ KUNIT_EXPECT_TRUE_MSG(test, list_empty(&config->planes),
+ "Plane list is not empty after allocation");
+
+ vkms_config_destroy(config);
+}
+
+static void vkms_config_test_simple_config(struct kunit *test)
+{
+ struct vkms_config *config = vkms_config_create();
+
+ struct vkms_config_plane *plane_1 = vkms_config_create_plane(config);
+ struct vkms_config_plane *plane_2 = vkms_config_create_plane(config);
+ struct vkms_config_crtc *crtc = vkms_config_create_crtc(config);
+ struct vkms_config_encoder *encoder = vkms_config_create_encoder(config);
+
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->planes), 2);
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->crtcs), 1);
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->encoders), 1);
+
+ plane_1->type = DRM_PLANE_TYPE_PRIMARY;
+ plane_2->type = DRM_PLANE_TYPE_CURSOR;
+
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_1, crtc), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_2, crtc), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_encoder_attach_crtc(encoder, crtc), 0);
+
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ vkms_config_delete_plane(plane_1, config);
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->planes), 1);
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->crtcs), 1);
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->encoders), 1);
+
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ plane_2->type = DRM_PLANE_TYPE_PRIMARY;
+
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ vkms_config_destroy(config);
+}
+
+static void vkms_config_test_complex_config(struct kunit *test)
+{
+ struct vkms_config *config = vkms_config_create();
+
+ struct vkms_config_plane *plane_1 = vkms_config_create_plane(config);
+ struct vkms_config_plane *plane_2 = vkms_config_create_plane(config);
+ struct vkms_config_plane *plane_3 = vkms_config_create_plane(config);
+ struct vkms_config_plane *plane_4 = vkms_config_create_plane(config);
+ struct vkms_config_plane *plane_5 = vkms_config_create_plane(config);
+ struct vkms_config_plane *plane_6 = vkms_config_create_plane(config);
+ struct vkms_config_plane *plane_7 = vkms_config_create_plane(config);
+ struct vkms_config_plane *plane_8 = vkms_config_create_plane(config);
+ struct vkms_config_crtc *crtc_1 = vkms_config_create_crtc(config);
+ struct vkms_config_crtc *crtc_2 = vkms_config_create_crtc(config);
+ struct vkms_config_encoder *encoder_1 = vkms_config_create_encoder(config);
+ struct vkms_config_encoder *encoder_2 = vkms_config_create_encoder(config);
+ struct vkms_config_encoder *encoder_3 = vkms_config_create_encoder(config);
+ struct vkms_config_encoder *encoder_4 = vkms_config_create_encoder(config);
+
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->planes), 8);
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->crtcs), 2);
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->encoders), 4);
+
+ plane_1->type = DRM_PLANE_TYPE_PRIMARY;
+ plane_2->type = DRM_PLANE_TYPE_CURSOR;
+ plane_3->type = DRM_PLANE_TYPE_OVERLAY;
+ plane_4->type = DRM_PLANE_TYPE_OVERLAY;
+ plane_5->type = DRM_PLANE_TYPE_PRIMARY;
+ plane_6->type = DRM_PLANE_TYPE_CURSOR;
+ plane_7->type = DRM_PLANE_TYPE_OVERLAY;
+ plane_8->type = DRM_PLANE_TYPE_OVERLAY;
+
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_1, crtc_1), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_2, crtc_1), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_3, crtc_1), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_4, crtc_1), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_5, crtc_2), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_6, crtc_2), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_7, crtc_2), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_8, crtc_2), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_3, crtc_2), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_attach_crtc(plane_4, crtc_2), 0);
+
+ KUNIT_EXPECT_EQ(test, vkms_config_encoder_attach_crtc(encoder_1, crtc_1), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_encoder_attach_crtc(encoder_2, crtc_1), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_encoder_attach_crtc(encoder_3, crtc_1), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_encoder_attach_crtc(encoder_3, crtc_2), 0);
+ KUNIT_EXPECT_EQ(test, vkms_config_encoder_attach_crtc(encoder_4, crtc_2), 0);
+
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ vkms_config_delete_plane(plane_4, config);
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->planes), 7);
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->crtcs), 2);
+ KUNIT_EXPECT_EQ(test, list_count_nodes(&config->encoders), 4);
+
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ vkms_config_destroy(config);
+}
+
+static struct kunit_case vkms_config_test_cases[] = {
+ KUNIT_CASE(vkms_config_test_basic_allocation),
+ KUNIT_CASE(vkms_config_test_simple_config),
+ KUNIT_CASE(vkms_config_test_complex_config),
+ {}
+};
+
+static struct kunit_suite vkms_config_test_suite = {
+ .name = "vkms-config",
+ .test_cases = vkms_config_test_cases,
+};
+
+kunit_test_suite(vkms_config_test_suite);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Kunit test for vkms config utility");
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 13/18] drm/vkms: Introduce config for connector
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (11 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 12/18] drm/vkms: Add test for config structure Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 14/18] drm/vkms: Introduce config for connector type Louis Chauvet
` (4 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 62 +++++++++++++++++++++++++++++++++++++-
drivers/gpu/drm/vkms/vkms_config.h | 18 +++++++++--
drivers/gpu/drm/vkms/vkms_drv.c | 2 +-
drivers/gpu/drm/vkms/vkms_output.c | 37 ++++++++++++-----------
4 files changed, 98 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 3252f657ce515c0193a8c0e709bfe861feba0aca..998bdc50405116507e9cefd72a7b472c4c17e36d 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -17,6 +17,7 @@ struct vkms_config *vkms_config_create(void)
INIT_LIST_HEAD(&config->planes);
INIT_LIST_HEAD(&config->crtcs);
INIT_LIST_HEAD(&config->encoders);
+ INIT_LIST_HEAD(&config->connectors);
return config;
}
@@ -28,6 +29,7 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
struct vkms_config_plane *plane;
struct vkms_config_encoder *encoder;
struct vkms_config_crtc *crtc;
+ struct vkms_config_connector *connector;
struct vkms_config *vkms_config = vkms_config_create();
if (IS_ERR(vkms_config))
@@ -53,6 +55,12 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
if (vkms_config_encoder_attach_crtc(encoder, crtc))
goto err_alloc;
+ connector = vkms_config_create_connector(vkms_config);
+ if (!connector)
+ goto err_alloc;
+ if (vkms_config_connector_attach_encoder(connector, encoder))
+ goto err_alloc;
+
plane = vkms_config_create_plane(vkms_config);
if (!plane)
goto err_alloc;
@@ -130,6 +138,23 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_conf
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_plane);
+struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *vkms_config)
+{
+ if (!vkms_config)
+ return NULL;
+
+ struct vkms_config_connector *vkms_config_connector =
+ kzalloc(sizeof(*vkms_config_connector), GFP_KERNEL);
+
+ if (!vkms_config_connector)
+ return NULL;
+
+ list_add(&vkms_config_connector->link, &vkms_config->connectors);
+ xa_init_flags(&vkms_config_connector->possible_encoders, XA_FLAGS_ALLOC);
+
+ return vkms_config_connector;
+}
+
struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *vkms_config)
{
if (!vkms_config)
@@ -227,6 +252,15 @@ void vkms_config_delete_crtc(struct vkms_config_crtc *vkms_config_crtc,
kfree(vkms_config_crtc);
}
+void vkms_config_delete_connector(struct vkms_config_connector *vkms_config_conector)
+{
+ if (!vkms_config_conector)
+ return;
+ list_del(&vkms_config_conector->link);
+
+ kfree(vkms_config_conector);
+}
+
void vkms_config_delete_encoder(struct vkms_config_encoder *vkms_config_encoder,
struct vkms_config *vkms_config)
{
@@ -247,6 +281,17 @@ void vkms_config_delete_encoder(struct vkms_config_encoder *vkms_config_encoder,
}
}
+ struct vkms_config_connector *connector_config;
+
+ list_for_each_entry(connector_config, &vkms_config->connectors, link) {
+ unsigned long idx = 0;
+
+ xa_for_each(&connector_config->possible_encoders, idx, encoder) {
+ if (encoder == vkms_config_encoder)
+ xa_erase(&connector_config->possible_encoders, idx);
+ }
+ }
+
kfree(vkms_config_encoder->name);
kfree(vkms_config_encoder);
}
@@ -256,7 +301,7 @@ void vkms_config_destroy(struct vkms_config *config)
struct vkms_config_plane *vkms_config_plane, *tmp_plane;
struct vkms_config_encoder *vkms_config_encoder, *tmp_encoder;
struct vkms_config_crtc *vkms_config_crtc, *tmp_crtc;
-
+ struct vkms_config_connector *vkms_config_connector, *tmp_connector;
list_for_each_entry_safe(vkms_config_plane, tmp_plane, &config->planes, link) {
vkms_config_delete_plane(vkms_config_plane, config);
}
@@ -266,6 +311,9 @@ void vkms_config_destroy(struct vkms_config *config)
list_for_each_entry_safe(vkms_config_crtc, tmp_crtc, &config->crtcs, link) {
vkms_config_delete_crtc(vkms_config_crtc, config);
}
+ list_for_each_entry_safe(vkms_config_connector, tmp_connector, &config->connectors, link) {
+ vkms_config_delete_connector(vkms_config_connector);
+ }
kfree(config);
}
@@ -315,6 +363,18 @@ int __must_check vkms_config_encoder_attach_crtc(struct vkms_config_encoder *vkm
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_encoder_attach_crtc);
+int __must_check
+vkms_config_connector_attach_encoder(struct vkms_config_connector *vkms_config_connector,
+ struct vkms_config_encoder *vkms_config_encoder)
+{
+ u32 encoder_idx;
+ int ret;
+
+ ret = xa_alloc(&vkms_config_connector->possible_encoders, &encoder_idx, vkms_config_encoder,
+ xa_limit_32b, GFP_KERNEL);
+ return ret;
+}
+
bool vkms_config_is_valid(struct vkms_config *config)
{
struct vkms_config_plane *config_plane;
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 4a4c16dea7855cf36060986ef247be698974fafc..d64024e6682d217f7d9265f436ff2e6135860260 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -23,6 +23,7 @@ struct vkms_config {
struct list_head planes;
struct list_head crtcs;
struct list_head encoders;
+ struct list_head connectors;
};
/**
@@ -103,6 +104,15 @@ struct vkms_config_plane {
struct vkms_plane *plane;
};
+struct vkms_config_connector {
+ struct list_head link;
+
+ struct xarray possible_encoders;
+
+ /* Internal usage */
+ struct drm_connector *connector;
+};
+
/**
* vkms_config_register_debugfs() - Register the debugfs file to display current configuration
*/
@@ -133,6 +143,8 @@ bool vkms_config_is_valid(struct vkms_config *vkms_config);
*/
struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_config);
+struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *vkms_config);
+
/**
* vkms_config_create_crtc() - Create a crtc configuration
*
@@ -153,7 +165,9 @@ int __must_check vkms_config_plane_attach_crtc(struct vkms_config_plane *vkms_co
struct vkms_config_crtc *vkms_config_crtc);
int __must_check vkms_config_encoder_attach_crtc(struct vkms_config_encoder *vkms_config_encoder,
struct vkms_config_crtc *vkms_config_crtc);
-
+int __must_check
+vkms_config_connector_attach_encoder(struct vkms_config_connector *vkms_config_connector,
+ struct vkms_config_encoder *vkms_config_encoder);
/**
* vkms_config_delete_plane() - Remove a plane configuration and frees its memory
*
@@ -190,7 +204,7 @@ void vkms_config_delete_crtc(struct vkms_config_crtc *vkms_config_crtc,
*/
void vkms_config_delete_encoder(struct vkms_config_encoder *vkms_config_encoder,
struct vkms_config *vkms_config);
-
+void vkms_config_delete_connector(struct vkms_config_connector *vkms_config_conector);
/**
* vkms_config_alloc_default() - Allocate the configuration for the default device
* @enable_writeback: Enable the writeback connector for this configuration
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 61ae2986568093ab0df7174a0a4678a75f9aad0c..eb6fd570b4549639f6818ff63fb334f2a461b23d 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -185,7 +185,7 @@ static int vkms_create(struct vkms_config *config)
goto out_devres;
}
- ret = drm_vblank_init(&vkms_device->drm, 1);
+ ret = drm_vblank_init(&vkms_device->drm, list_count_nodes(&config->crtcs));
if (ret) {
DRM_ERROR("Failed to vblank\n");
goto out_devres;
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 6277ad72fdd476d1eff52ad037389bdb1a254f5e..90c0fa8eba53bef4ca80c374b40d69b0de155144 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -35,7 +35,7 @@ int vkms_output_init(struct vkms_device *vkmsdev)
struct drm_device *dev = &vkmsdev->drm;
struct vkms_config_plane *config_plane;
struct vkms_config_crtc *config_crtc;
- struct drm_connector *connector;
+ struct vkms_config_connector *config_connector;
unsigned long idx;
int ret;
@@ -71,21 +71,6 @@ int vkms_output_init(struct vkms_device *vkmsdev)
}
}
- connector = drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
- if (!connector) {
- DRM_ERROR("Failed to allocate connector\n");
- return -ENOMEM;
- }
-
- ret = drmm_connector_init(dev, connector, &vkms_connector_funcs,
- DRM_MODE_CONNECTOR_VIRTUAL, NULL);
- if (ret) {
- DRM_ERROR("Failed to init connector\n");
- return ret;
- }
-
- drm_connector_helper_add(connector, &vkms_conn_helper_funcs);
-
list_for_each_entry(config_encoder, &vkmsdev->config->encoders, link) {
config_encoder->encoder = drmm_kzalloc(dev, sizeof(*config_encoder->encoder),
GFP_KERNEL);
@@ -97,14 +82,32 @@ int vkms_output_init(struct vkms_device *vkmsdev)
DRM_ERROR("Failed to init encoder\n");
return ret;
}
+
xa_for_each(&config_encoder->possible_crtcs, idx, config_crtc) {
config_encoder->encoder->possible_crtcs |= drm_crtc_mask(&config_crtc->crtc->base);
}
if (IS_ERR(config_encoder->encoder))
return PTR_ERR(config_encoder->encoder);
- ret = drm_connector_attach_encoder(connector, config_encoder->encoder);
+ }
+
+ list_for_each_entry(config_connector, &vkmsdev->config->connectors, link) {
+ config_connector->connector = drmm_kzalloc(&vkmsdev->drm,
+ sizeof(*config_connector->connector),
+ GFP_KERNEL);
+ if (!config_connector->connector)
+ return -ENOMEM;
+ ret = drmm_connector_init(&vkmsdev->drm, config_connector->connector,
+ &vkms_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL, NULL);
if (ret)
return ret;
+ drm_connector_helper_add(config_connector->connector, &vkms_conn_helper_funcs);
+
+ xa_for_each(&config_connector->possible_encoders, idx, config_encoder) {
+ ret = drm_connector_attach_encoder(config_connector->connector,
+ config_encoder->encoder);
+ if (ret)
+ return ret;
+ }
}
drm_mode_config_reset(dev);
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 14/18] drm/vkms: Introduce config for connector type
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (12 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 13/18] drm/vkms: Introduce config for connector Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 15/18] drm/vkms: Introduce config for plane format Louis Chauvet
` (3 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
To allow emulation of different kind of connector, make the connector type
configurable.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 1 +
drivers/gpu/drm/vkms/vkms_config.h | 1 +
drivers/gpu/drm/vkms/vkms_output.c | 2 +-
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 998bdc50405116507e9cefd72a7b472c4c17e36d..c3334d3d808e5fc8cd6d855e9e1395f94f157ffb 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -151,6 +151,7 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *v
list_add(&vkms_config_connector->link, &vkms_config->connectors);
xa_init_flags(&vkms_config_connector->possible_encoders, XA_FLAGS_ALLOC);
+ vkms_config_connector->type = DRM_MODE_CONNECTOR_VIRTUAL;
return vkms_config_connector;
}
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index d64024e6682d217f7d9265f436ff2e6135860260..c44bcafc3b34e1997f29631fda42af05e1c0c2ba 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -108,6 +108,7 @@ struct vkms_config_connector {
struct list_head link;
struct xarray possible_encoders;
+ int type;
/* Internal usage */
struct drm_connector *connector;
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 90c0fa8eba53bef4ca80c374b40d69b0de155144..aea6366fd9a662483ed5a255d02d5025a30297f7 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -97,7 +97,7 @@ int vkms_output_init(struct vkms_device *vkmsdev)
if (!config_connector->connector)
return -ENOMEM;
ret = drmm_connector_init(&vkmsdev->drm, config_connector->connector,
- &vkms_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL, NULL);
+ &vkms_connector_funcs, config_connector->type, NULL);
if (ret)
return ret;
drm_connector_helper_add(config_connector->connector, &vkms_conn_helper_funcs);
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 15/18] drm/vkms: Introduce config for plane format
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (13 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 14/18] drm/vkms: Introduce config for connector type Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 16/18] drm/vkms: Introduce config for connector status Louis Chauvet
` (2 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 105 +++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 19 +++++++
drivers/gpu/drm/vkms/vkms_plane.c | 43 ++-------------
3 files changed, 127 insertions(+), 40 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index c3334d3d808e5fc8cd6d855e9e1395f94f157ffb..4726929c2b54b2e670f9ef53b05ec009ca495e08 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -6,6 +6,44 @@
#include "vkms_config.h"
#include "vkms_drv.h"
+static const u32 vkms_supported_plane_formats[] = {
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_BGRX8888,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_BGR888,
+ DRM_FORMAT_XRGB16161616,
+ DRM_FORMAT_XBGR16161616,
+ DRM_FORMAT_ARGB16161616,
+ DRM_FORMAT_ABGR16161616,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_BGR565,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_NV42,
+ DRM_FORMAT_YUV420,
+ DRM_FORMAT_YUV422,
+ DRM_FORMAT_YUV444,
+ DRM_FORMAT_YVU420,
+ DRM_FORMAT_YVU422,
+ DRM_FORMAT_YVU444,
+ DRM_FORMAT_P010,
+ DRM_FORMAT_P012,
+ DRM_FORMAT_P016,
+ DRM_FORMAT_R1,
+ DRM_FORMAT_R2,
+ DRM_FORMAT_R4,
+ DRM_FORMAT_R8,
+};
+
struct vkms_config *vkms_config_create(void)
{
struct vkms_config *config;
@@ -120,6 +158,13 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_conf
if (!vkms_config_overlay)
return NULL;
+ vkms_config_overlay->supported_formats = NULL;
+
+ if (vkms_config_plane_add_all_formats(vkms_config_overlay)) {
+ kfree(vkms_config_overlay);
+ return NULL;
+ }
+
vkms_config_overlay->type = DRM_PLANE_TYPE_OVERLAY;
vkms_config_overlay->supported_rotations = DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK;
vkms_config_overlay->default_rotation = DRM_MODE_ROTATE_0;
@@ -193,6 +238,65 @@ struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *vkms_
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_encoder);
+int __must_check vkms_config_plane_add_all_formats(struct vkms_config_plane *vkms_config_plane)
+{
+ u32 *ret = krealloc_array(vkms_config_plane->supported_formats,
+ ARRAY_SIZE(vkms_supported_plane_formats),
+ sizeof(uint32_t), GFP_KERNEL);
+ if (!ret)
+ return -ENOMEM;
+ vkms_config_plane->supported_formats = ret;
+
+ memcpy(vkms_config_plane->supported_formats, vkms_supported_plane_formats,
+ sizeof(vkms_supported_plane_formats));
+ vkms_config_plane->supported_formats_count = ARRAY_SIZE(vkms_supported_plane_formats);
+ return 0;
+}
+
+int __must_check vkms_config_plane_add_format(struct vkms_config_plane *vkms_config_plane,
+ u32 drm_format)
+{
+ bool found = false;
+
+ for (int i = 0; i < ARRAY_SIZE(vkms_supported_plane_formats); i++) {
+ if (vkms_supported_plane_formats[i] == drm_format)
+ found = true;
+ }
+
+ if (!found)
+ return -EINVAL;
+ for (unsigned int i = 0; i < vkms_config_plane->supported_formats_count; i++) {
+ if (vkms_config_plane->supported_formats[i] == drm_format)
+ return 0;
+ }
+ u32 *new_ptr = krealloc_array(vkms_config_plane->supported_formats,
+ vkms_config_plane->supported_formats_count + 1,
+ sizeof(*vkms_config_plane->supported_formats), GFP_KERNEL);
+ if (!new_ptr)
+ return -ENOMEM;
+
+ vkms_config_plane->supported_formats = new_ptr;
+ vkms_config_plane->supported_formats[vkms_config_plane->supported_formats_count] = drm_format;
+ vkms_config_plane->supported_formats_count++;
+
+ return 0;
+}
+
+void vkms_config_plane_remove_all_formats(struct vkms_config_plane *vkms_config_plane)
+{
+ vkms_config_plane->supported_formats_count = 0;
+}
+
+void vkms_config_plane_remove_format(struct vkms_config_plane *vkms_config_plane, u32 drm_format)
+{
+ for (unsigned int i = 0; i < vkms_config_plane->supported_formats_count; i++) {
+ if (vkms_config_plane->supported_formats[i] == drm_format) {
+ vkms_config_plane->supported_formats[i] = vkms_config_plane->supported_formats[vkms_config_plane->supported_formats_count - 1];
+ vkms_config_plane->supported_formats_count--;
+ }
+ }
+}
+
void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_plane,
struct vkms_config *vkms_config)
{
@@ -213,6 +317,7 @@ void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_plane,
}
}
+ kfree(vkms_config_plane->supported_formats);
kfree(vkms_config_plane->name);
kfree(vkms_config_plane);
}
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index c44bcafc3b34e1997f29631fda42af05e1c0c2ba..5487e0140da0e111c36f9a22d4e783a20c880a1d 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -98,6 +98,8 @@ struct vkms_config_plane {
unsigned int supported_color_encoding;
enum drm_color_range default_color_range;
unsigned int supported_color_range;
+ u32 *supported_formats;
+ unsigned int supported_formats_count;
struct xarray possible_crtcs;
/* Internal usage */
@@ -144,6 +146,23 @@ bool vkms_config_is_valid(struct vkms_config *vkms_config);
*/
struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_config);
+/** vkms_config_plane_add_format - Add a format to the list of supported format of a plane
+ *
+ * The passed drm_format can already be present in the list. This may fail if the allocation of a
+ * bigger array fails.
+ *
+ * @vkms_config_plane: Plane to add the format to
+ * @drm_format: Format to add to this plane
+ *
+ * Returns: 0 on success, -ENOMEM if array allocation fails, -EINVAL if the format is not supported
+ * by VKMS
+ */
+int __must_check vkms_config_plane_add_format(struct vkms_config_plane *vkms_config_plane,
+ u32 drm_format);
+int __must_check vkms_config_plane_add_all_formats(struct vkms_config_plane *vkms_config_plane);
+void vkms_config_plane_remove_format(struct vkms_config_plane *vkms_config_plane, u32 drm_format);
+void vkms_config_plane_remove_all_formats(struct vkms_config_plane *vkms_config_plane);
+
struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *vkms_config);
/**
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 90a5946481e47ab7cff9b9dc4942720b6bbcbe3f..b858c8ba00d97e461d70b5cc274ab4e7a3e1bb78 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -13,44 +13,6 @@
#include "vkms_formats.h"
#include "vkms_config.h"
-static const u32 vkms_formats[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_RGBA8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_XBGR8888,
- DRM_FORMAT_RGBX8888,
- DRM_FORMAT_BGRX8888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_BGR888,
- DRM_FORMAT_XRGB16161616,
- DRM_FORMAT_XBGR16161616,
- DRM_FORMAT_ARGB16161616,
- DRM_FORMAT_ABGR16161616,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_BGR565,
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV16,
- DRM_FORMAT_NV24,
- DRM_FORMAT_NV21,
- DRM_FORMAT_NV61,
- DRM_FORMAT_NV42,
- DRM_FORMAT_YUV420,
- DRM_FORMAT_YUV422,
- DRM_FORMAT_YUV444,
- DRM_FORMAT_YVU420,
- DRM_FORMAT_YVU422,
- DRM_FORMAT_YVU444,
- DRM_FORMAT_P010,
- DRM_FORMAT_P012,
- DRM_FORMAT_P016,
- DRM_FORMAT_R1,
- DRM_FORMAT_R2,
- DRM_FORMAT_R4,
- DRM_FORMAT_R8,
-};
-
static struct drm_plane_state *
vkms_plane_duplicate_state(struct drm_plane *plane)
{
@@ -227,8 +189,9 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 0,
&vkms_plane_funcs,
- vkms_formats, ARRAY_SIZE(vkms_formats),
- NULL, config->type, config->name);
+ config->supported_formats,
+ config->supported_formats_count, NULL, config->type,
+ config->name);
if (IS_ERR(plane))
return plane;
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 16/18] drm/vkms: Introduce config for connector status
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (14 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 15/18] drm/vkms: Introduce config for plane format Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 17/18] drm/vkms: Introduce config for connector EDID Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 18/18] drm/vkms: Introduce config for encoder type Louis Chauvet
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet, José Expósito
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
[adpated it for my implementation]
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 10 ++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 4 ++++
drivers/gpu/drm/vkms/vkms_output.c | 17 +++++++++++++++++
3 files changed, 31 insertions(+)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 4726929c2b54b2e670f9ef53b05ec009ca495e08..ac1a9658c5075c118d59da965ca3392355ccb2b2 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -2,6 +2,7 @@
#include <kunit/visibility.h>
#include <drm/drm_debugfs.h>
+#include <drm/drm_probe_helper.h>
#include "vkms_config.h"
#include "vkms_drv.h"
@@ -197,10 +198,19 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *v
list_add(&vkms_config_connector->link, &vkms_config->connectors);
xa_init_flags(&vkms_config_connector->possible_encoders, XA_FLAGS_ALLOC);
vkms_config_connector->type = DRM_MODE_CONNECTOR_VIRTUAL;
+ vkms_config_connector->status = connector_status_unknown;
return vkms_config_connector;
}
+void vkms_config_connector_update_status(struct vkms_config_connector *vkms_config_connector,
+ enum drm_connector_status status)
+{
+ vkms_config_connector->status = status;
+ if (vkms_config_connector->connector)
+ drm_kms_helper_hotplug_event(vkms_config_connector->connector->dev);
+}
+
struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *vkms_config)
{
if (!vkms_config)
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 5487e0140da0e111c36f9a22d4e783a20c880a1d..bba56c9d8aeceac97a4339ef42ab663c5dc54e65 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -111,11 +111,15 @@ struct vkms_config_connector {
struct xarray possible_encoders;
int type;
+ enum drm_connector_status status;
/* Internal usage */
struct drm_connector *connector;
};
+void vkms_config_connector_update_status(struct vkms_config_connector *vkms_config_connector,
+ enum drm_connector_status status);
+
/**
* vkms_config_register_debugfs() - Register the debugfs file to display current configuration
*/
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index aea6366fd9a662483ed5a255d02d5025a30297f7..fc6a0cdade0739b94820ed4e0924cf355137fe79 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -7,9 +7,26 @@
#include <drm/drm_managed.h>
#include <drm/drm_probe_helper.h>
+static enum drm_connector_status vkms_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct vkms_device *vkmsdev = drm_device_to_vkms_device(connector->dev);
+ enum drm_connector_status status = connector->status;
+ struct vkms_config_connector *connector_cfg;
+
+ list_for_each_entry(connector_cfg, &vkmsdev->config->connectors, link) {
+ if (connector_cfg->connector == connector) {
+ status = connector_cfg->status;
+ break;
+ }
+ }
+
+ return status;
+}
+
static const struct drm_connector_funcs vkms_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.reset = drm_atomic_helper_connector_reset,
+ .detect = vkms_connector_detect,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 17/18] drm/vkms: Introduce config for connector EDID
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (15 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 16/18] drm/vkms: Introduce config for connector status Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
2024-11-22 21:28 ` Ian Forbes
2024-11-25 9:45 ` Jani Nikula
2024-11-22 17:20 ` [PATCH RFC v2 18/18] drm/vkms: Introduce config for encoder type Louis Chauvet
17 siblings, 2 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
To properly test the EDID reading without using the DRM override, add an
option to configure the EDID for a connector.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 1 +
drivers/gpu/drm/vkms/vkms_config.h | 2 ++
drivers/gpu/drm/vkms/vkms_output.c | 37 ++++++++++++++++++++++++++++++++++---
3 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index ac1a9658c5075c118d59da965ca3392355ccb2b2..1a1234d4f10fa8e5ea6bd649139ecc10c991f875 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -199,6 +199,7 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *v
xa_init_flags(&vkms_config_connector->possible_encoders, XA_FLAGS_ALLOC);
vkms_config_connector->type = DRM_MODE_CONNECTOR_VIRTUAL;
vkms_config_connector->status = connector_status_unknown;
+ vkms_config_connector->edid_blob_len = 0;
return vkms_config_connector;
}
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index bba56c9d8aeceac97a4339ef42ab663c5dc54e65..1220b16f6c98d1ebb0ae55d662a84fe25e1a6a02 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -112,6 +112,8 @@ struct vkms_config_connector {
struct xarray possible_encoders;
int type;
enum drm_connector_status status;
+ char edid_blob[PAGE_SIZE];
+ int edid_blob_len;
/* Internal usage */
struct drm_connector *connector;
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index fc6a0cdade0739b94820ed4e0924cf355137fe79..56590afb33d75465971d10a282040690840cdbee 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -31,13 +31,44 @@ static const struct drm_connector_funcs vkms_connector_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
+static int vkms_connector_read_block(void *context, u8 *buf, unsigned int block, size_t len)
+{
+ struct vkms_config_connector *config = context;
+
+ if (block * len + len > config->edid_blob_len)
+ return 1;
+ memcpy(buf, &config->edid_blob[block * len], len);
+ return 0;
+}
+
static int vkms_conn_get_modes(struct drm_connector *connector)
{
+ const struct drm_edid *drm_edid = NULL;
int count;
+ struct vkms_config_connector *connector_cfg;
+ struct vkms_device *vkmsdev = drm_device_to_vkms_device(connector->dev);
+ struct vkms_config_connector *context = NULL;
+
+ list_for_each_entry(connector_cfg, &vkmsdev->config->connectors, link) {
+ if (connector_cfg->connector == connector) {
+ context = connector_cfg;
+ break;
+ }
+ }
+ if (context)
+ drm_edid = drm_edid_read_custom(connector, vkms_connector_read_block, context);
+
+ /*
+ * Unconditionally update the connector. If the EDID was read
+ * successfully, fill in the connector information derived from the
+ * EDID. Otherwise, if the EDID is NULL, clear the connector
+ * information.
+ */
+ drm_edid_connector_update(connector, drm_edid);
+
+ count = drm_edid_connector_add_modes(connector);
- /* Use the default modes list from DRM */
- count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
- drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
+ drm_edid_free(drm_edid);
return count;
}
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH RFC v2 18/18] drm/vkms: Introduce config for encoder type
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
` (16 preceding siblings ...)
2024-11-22 17:20 ` [PATCH RFC v2 17/18] drm/vkms: Introduce config for connector EDID Louis Chauvet
@ 2024-11-22 17:20 ` Louis Chauvet
17 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-22 17:20 UTC (permalink / raw)
To: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 1 +
drivers/gpu/drm/vkms/vkms_config.h | 2 ++
drivers/gpu/drm/vkms/vkms_output.c | 2 +-
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 1a1234d4f10fa8e5ea6bd649139ecc10c991f875..26280ad223208a978c44ef9c6c6eaadf1756818d 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -242,6 +242,7 @@ struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *vkms_
if (!vkms_config_encoder)
return NULL;
+ vkms_config_encoder->type = DRM_MODE_ENCODER_VIRTUAL;
list_add(&vkms_config_encoder->link, &vkms_config->encoders);
xa_init_flags(&vkms_config_encoder->possible_crtcs, XA_FLAGS_ALLOC);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 1220b16f6c98d1ebb0ae55d662a84fe25e1a6a02..c6fe0573abd899e4b44b5ad390ff72e12664973f 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -55,6 +55,7 @@ struct vkms_config_crtc {
* @link: Link to the others encoders
* @name: Name of the encoder
* @possible_crtcs: List of CRTC that can be used with this encoder
+ * @type: Type of encoder, see drm_mode.h, DRM_MODE_ENCODER_*
* @encoder: Internal usage. This pointer should never be considered as valid. It can be used to
* store a temporary reference to a vkms encoder during device creation. This pointer is
* not managed by the configuration and must be managed by other means.
@@ -64,6 +65,7 @@ struct vkms_config_encoder {
char *name;
struct xarray possible_crtcs;
+ char type;
/* Internal usage */
struct drm_encoder *encoder;
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 56590afb33d75465971d10a282040690840cdbee..7c87da5757529b9a8dae880cd32272be7dd46a27 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -125,7 +125,7 @@ int vkms_output_init(struct vkms_device *vkmsdev)
if (!config_encoder->encoder)
return -ENOMEM;
ret = drmm_encoder_init(dev, config_encoder->encoder, NULL,
- DRM_MODE_ENCODER_VIRTUAL, config_encoder->name);
+ config_encoder->type, config_encoder->name);
if (ret) {
DRM_ERROR("Failed to init encoder\n");
return ret;
--
2.47.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH RFC v2 17/18] drm/vkms: Introduce config for connector EDID
2024-11-22 17:20 ` [PATCH RFC v2 17/18] drm/vkms: Introduce config for connector EDID Louis Chauvet
@ 2024-11-22 21:28 ` Ian Forbes
2024-11-23 10:45 ` Louis Chauvet
2024-11-25 9:45 ` Jani Nikula
1 sibling, 1 reply; 26+ messages in thread
From: Ian Forbes @ 2024-11-22 21:28 UTC (permalink / raw)
To: Louis Chauvet
Cc: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel
I didn't see a `drm_connector_attach_edid_property` call in this
series. Did you forget this? Virtual connectors don't have this
property by default.
Ian,
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH RFC v2 17/18] drm/vkms: Introduce config for connector EDID
2024-11-22 21:28 ` Ian Forbes
@ 2024-11-23 10:45 ` Louis Chauvet
0 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-23 10:45 UTC (permalink / raw)
To: dri-devel, Ian Forbes
Cc: Maíra Canal, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel
Le 22 novembre 2024 21:28:00 UTC, Ian Forbes <ian.forbes@broadcom.com> a écrit :
>I didn't see a `drm_connector_attach_edid_property` call in this
>series. Did you forget this? Virtual connectors don't have this
>property by default.
Hello Ian,
You are right; I did not call this function. As mainly tested with the DP connector type, I never had any issue. I need to check if calling `drm_edid_connector_update` fails if the EDID property does not exist.
Thanks,
Louis Chauvet
>Ian,
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH RFC v2 10/18] drm/vkms: Introduce config for encoder name
2024-11-22 17:20 ` [PATCH RFC v2 10/18] drm/vkms: Introduce config for encoder name Louis Chauvet
@ 2024-11-25 9:28 ` Jani Nikula
2024-11-25 9:50 ` Louis Chauvet
0 siblings, 1 reply; 26+ messages in thread
From: Jani Nikula @ 2024-11-25 9:28 UTC (permalink / raw)
To: Louis Chauvet, Maíra Canal, Haneen Mohammed, Simona Vetter,
Melissa Wen, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
On Fri, 22 Nov 2024, Louis Chauvet <louis.chauvet@bootlin.com> wrote:
> As an encoder will be a directory in ConfigFS, add the configuration for
> encoder name so we will be able to reflect the configfs directory name in
> the drm name.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/vkms_config.c | 6 ++++++
> drivers/gpu/drm/vkms/vkms_config.h | 2 ++
> drivers/gpu/drm/vkms/vkms_output.c | 2 +-
> 3 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
> index e44ed904cefb97b8b6ab8fc27623e315397e0106..a2539fb56b602569b75748fdf9c4784f104b0bff 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.c
> +++ b/drivers/gpu/drm/vkms/vkms_config.c
> @@ -41,6 +41,10 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
> encoder = vkms_config_create_encoder(vkms_config);
> if (!encoder)
> goto err_alloc;
> + encoder->name = kzalloc(sizeof("Main Encoder"), GFP_KERNEL);
> + if (!encoder->name)
> + goto err_alloc;
> + sprintf(encoder->name, "Main Encoder");
Drive-by comment, maybe kstrdup()?
>
> if (vkms_config_encoder_attach_crtc(encoder, crtc))
> goto err_alloc;
> @@ -238,6 +242,7 @@ void vkms_config_delete_encoder(struct vkms_config_encoder *vkms_config_encoder,
> }
> }
>
> + kfree(vkms_config_encoder->name);
> kfree(vkms_config_encoder);
> }
>
> @@ -403,6 +408,7 @@ static int vkms_config_show(struct seq_file *m, void *data)
>
> list_for_each_entry(config_encoder, &vkmsdev->config->encoders, link) {
> seq_puts(m, "encoder:\n");
> + seq_printf(m, "\tname: %s\n", config_encoder->name);
> }
>
> list_for_each_entry(config_crtc, &vkmsdev->config->crtcs, link) {
> diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
> index 8f247fc09373fb2c8145e83be05c6afec1ffac1c..4223edd94ec270915dd658c0b5efd489554d33a5 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> @@ -50,6 +50,7 @@ struct vkms_config_crtc {
> * struct vkms_config_encoder
> *
> * @link: Link to the others encoders
> + * @name: Name of the encoder
> * @possible_crtcs: List of CRTC that can be used with this encoder
> * @encoder: Internal usage. This pointer should never be considered as valid. It can be used to
> * store a temporary reference to a vkms encoder during device creation. This pointer is
> @@ -58,6 +59,7 @@ struct vkms_config_crtc {
> struct vkms_config_encoder {
> struct list_head link;
>
> + char *name;
> struct xarray possible_crtcs;
>
> /* Internal usage */
> diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
> index 03498a20d78dd8a66f9fc66b360c5ea57fc48d88..6277ad72fdd476d1eff52ad037389bdb1a254f5e 100644
> --- a/drivers/gpu/drm/vkms/vkms_output.c
> +++ b/drivers/gpu/drm/vkms/vkms_output.c
> @@ -92,7 +92,7 @@ int vkms_output_init(struct vkms_device *vkmsdev)
> if (!config_encoder->encoder)
> return -ENOMEM;
> ret = drmm_encoder_init(dev, config_encoder->encoder, NULL,
> - DRM_MODE_ENCODER_VIRTUAL, NULL);
> + DRM_MODE_ENCODER_VIRTUAL, config_encoder->name);
> if (ret) {
> DRM_ERROR("Failed to init encoder\n");
> return ret;
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH RFC v2 11/18] drm/vkms: Introduce config for CRTC name
2024-11-22 17:20 ` [PATCH RFC v2 11/18] drm/vkms: Introduce config for CRTC name Louis Chauvet
@ 2024-11-25 9:29 ` Jani Nikula
0 siblings, 0 replies; 26+ messages in thread
From: Jani Nikula @ 2024-11-25 9:29 UTC (permalink / raw)
To: Louis Chauvet, Maíra Canal, Haneen Mohammed, Simona Vetter,
Melissa Wen, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
On Fri, 22 Nov 2024, Louis Chauvet <louis.chauvet@bootlin.com> wrote:
> As a CRTC will be a directory in ConfigFS, add the name configuration for
> CRTC name so we will be able to reflect the configfs directory name in the
> drm name.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/vkms_config.c | 5 +++++
> drivers/gpu/drm/vkms/vkms_config.h | 2 ++
> drivers/gpu/drm/vkms/vkms_crtc.c | 2 +-
> 3 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
> index a2539fb56b602569b75748fdf9c4784f104b0bff..3252f657ce515c0193a8c0e709bfe861feba0aca 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.c
> +++ b/drivers/gpu/drm/vkms/vkms_config.c
> @@ -37,6 +37,10 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
> if (!crtc)
> goto err_alloc;
> crtc->writeback = enable_writeback;
> + crtc->name = kzalloc(sizeof("Main CRTC"), GFP_KERNEL);
> + if (!crtc->name)
> + goto err_alloc;
> + sprintf(crtc->name, "Main CRTC");
Ditto, kstrdup()
>
> encoder = vkms_config_create_encoder(vkms_config);
> if (!encoder)
> @@ -219,6 +223,7 @@ void vkms_config_delete_crtc(struct vkms_config_crtc *vkms_config_crtc,
> }
> }
>
> + kfree(vkms_config_crtc->name);
> kfree(vkms_config_crtc);
> }
>
> diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
> index 4223edd94ec270915dd658c0b5efd489554d33a5..4a4c16dea7855cf36060986ef247be698974fafc 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> @@ -29,6 +29,7 @@ struct vkms_config {
> * struct vkms_config_crtc
> *
> * @link: Link to the others CRTCs
> + * @name: Name of the CRTC
> * @possible_planes: List of planes that can be used with this CRTC
> * @possible_encoders: List of encoders that can be used with this CRTC
> * @crtc: Internal usage. This pointer should never be considered as valid. It can be used to
> @@ -38,6 +39,7 @@ struct vkms_config {
> struct vkms_config_crtc {
> struct list_head link;
>
> + char *name;
> bool writeback;
> struct xarray possible_planes;
> struct xarray possible_encoders;
> diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
> index 3825fba57c012f84cbe67114e053dcd7fcfa283d..25a3d97a362afd0d40f3e023d9cce985d447a880 100644
> --- a/drivers/gpu/drm/vkms/vkms_crtc.c
> +++ b/drivers/gpu/drm/vkms/vkms_crtc.c
> @@ -292,7 +292,7 @@ struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkms_device,
>
> vkms_crtc = drmm_crtc_alloc_with_planes(dev, struct vkms_crtc, base,
> primary, cursor,
> - &vkms_crtc_funcs, NULL);
> + &vkms_crtc_funcs, config->name);
> if (IS_ERR(vkms_crtc)) {
> DRM_DEV_ERROR(dev->dev, "Failed to init CRTC\n");
> return vkms_crtc;
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH RFC v2 17/18] drm/vkms: Introduce config for connector EDID
2024-11-22 17:20 ` [PATCH RFC v2 17/18] drm/vkms: Introduce config for connector EDID Louis Chauvet
2024-11-22 21:28 ` Ian Forbes
@ 2024-11-25 9:45 ` Jani Nikula
2024-11-25 10:19 ` Louis Chauvet
1 sibling, 1 reply; 26+ messages in thread
From: Jani Nikula @ 2024-11-25 9:45 UTC (permalink / raw)
To: Louis Chauvet, Maíra Canal, Haneen Mohammed, Simona Vetter,
Melissa Wen, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel,
dri-devel, Louis Chauvet
On Fri, 22 Nov 2024, Louis Chauvet <louis.chauvet@bootlin.com> wrote:
> To properly test the EDID reading without using the DRM override, add an
> option to configure the EDID for a connector.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/vkms_config.c | 1 +
> drivers/gpu/drm/vkms/vkms_config.h | 2 ++
> drivers/gpu/drm/vkms/vkms_output.c | 37 ++++++++++++++++++++++++++++++++++---
> 3 files changed, 37 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
> index ac1a9658c5075c118d59da965ca3392355ccb2b2..1a1234d4f10fa8e5ea6bd649139ecc10c991f875 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.c
> +++ b/drivers/gpu/drm/vkms/vkms_config.c
> @@ -199,6 +199,7 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *v
> xa_init_flags(&vkms_config_connector->possible_encoders, XA_FLAGS_ALLOC);
> vkms_config_connector->type = DRM_MODE_CONNECTOR_VIRTUAL;
> vkms_config_connector->status = connector_status_unknown;
> + vkms_config_connector->edid_blob_len = 0;
>
> return vkms_config_connector;
> }
> diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
> index bba56c9d8aeceac97a4339ef42ab663c5dc54e65..1220b16f6c98d1ebb0ae55d662a84fe25e1a6a02 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> @@ -112,6 +112,8 @@ struct vkms_config_connector {
> struct xarray possible_encoders;
> int type;
> enum drm_connector_status status;
> + char edid_blob[PAGE_SIZE];
> + int edid_blob_len;
>
> /* Internal usage */
> struct drm_connector *connector;
> diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
> index fc6a0cdade0739b94820ed4e0924cf355137fe79..56590afb33d75465971d10a282040690840cdbee 100644
> --- a/drivers/gpu/drm/vkms/vkms_output.c
> +++ b/drivers/gpu/drm/vkms/vkms_output.c
> @@ -31,13 +31,44 @@ static const struct drm_connector_funcs vkms_connector_funcs = {
> .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> };
>
> +static int vkms_connector_read_block(void *context, u8 *buf, unsigned int block, size_t len)
> +{
> + struct vkms_config_connector *config = context;
> +
> + if (block * len + len > config->edid_blob_len)
The parameters to the read block function are a bit weird for historical
reasons. The start offset is indicated by block number, length by
len. The start byte offset is thus block * EDID_LENGTH! There's no
smaller granularity for start offset. However len can be < EDID_LENGTH!
So the above should be (block * EDID_LENGTH + len > edid_blob_len)
> + return 1;
> + memcpy(buf, &config->edid_blob[block * len], len);
And this should be &config->edid_blob[block * EDID_LENGTH].
(Your patch would work, but just by coincidence due to the way the read
block function is currently called.)
> + return 0;
> +}
> +
> static int vkms_conn_get_modes(struct drm_connector *connector)
> {
> + const struct drm_edid *drm_edid = NULL;
> int count;
> + struct vkms_config_connector *connector_cfg;
> + struct vkms_device *vkmsdev = drm_device_to_vkms_device(connector->dev);
> + struct vkms_config_connector *context = NULL;
> +
> + list_for_each_entry(connector_cfg, &vkmsdev->config->connectors, link) {
> + if (connector_cfg->connector == connector) {
> + context = connector_cfg;
> + break;
> + }
> + }
> + if (context)
> + drm_edid = drm_edid_read_custom(connector, vkms_connector_read_block, context);
Thanks for using drm_edid_read_custom() for this btw!
> +
> + /*
> + * Unconditionally update the connector. If the EDID was read
> + * successfully, fill in the connector information derived from the
> + * EDID. Otherwise, if the EDID is NULL, clear the connector
> + * information.
> + */
> + drm_edid_connector_update(connector, drm_edid);
> +
> + count = drm_edid_connector_add_modes(connector);
>
> - /* Use the default modes list from DRM */
> - count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
> - drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
I don't really know anything about your use case, but don't you want to
fall back to the above for drm_edid == NULL? *shrug*
BR,
Jani.
> + drm_edid_free(drm_edid);
>
> return count;
> }
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH RFC v2 10/18] drm/vkms: Introduce config for encoder name
2024-11-25 9:28 ` Jani Nikula
@ 2024-11-25 9:50 ` Louis Chauvet
0 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-25 9:50 UTC (permalink / raw)
To: dri-devel, Jani Nikula, Maíra Canal, Haneen Mohammed,
Simona Vetter, Melissa Wen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel
Le 25 novembre 2024 09:28:44 UTC, Jani Nikula <jani.nikula@linux.intel.com> a écrit :
>On Fri, 22 Nov 2024, Louis Chauvet <louis.chauvet@bootlin.com> wrote:
>> As an encoder will be a directory in ConfigFS, add the configuration for
>> encoder name so we will be able to reflect the configfs directory name in
>> the drm name.
>>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>> ---
>> drivers/gpu/drm/vkms/vkms_config.c | 6 ++++++
>> drivers/gpu/drm/vkms/vkms_config.h | 2 ++
>> drivers/gpu/drm/vkms/vkms_output.c | 2 +-
>> 3 files changed, 9 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
>> index e44ed904cefb97b8b6ab8fc27623e315397e0106..a2539fb56b602569b75748fdf9c4784f104b0bff 100644
>> --- a/drivers/gpu/drm/vkms/vkms_config.c
>> +++ b/drivers/gpu/drm/vkms/vkms_config.c
>> @@ -41,6 +41,10 @@ struct vkms_config *vkms_config_alloc_default(bool enable_writeback, bool enable
>> encoder = vkms_config_create_encoder(vkms_config);
>> if (!encoder)
>> goto err_alloc;
>> + encoder->name = kzalloc(sizeof("Main Encoder"), GFP_KERNEL);
>> + if (!encoder->name)
>> + goto err_alloc;
>> + sprintf(encoder->name, "Main Encoder");
>
>Drive-by comment, maybe kstrdup()?
Nice catch, thank you!
I will update for next version.
Thanks,
Louis Chauvet
>>
>> if (vkms_config_encoder_attach_crtc(encoder, crtc))
>> goto err_alloc;
>> @@ -238,6 +242,7 @@ void vkms_config_delete_encoder(struct vkms_config_encoder *vkms_config_encoder,
>> }
>> }
>>
>> + kfree(vkms_config_encoder->name);
>> kfree(vkms_config_encoder);
>> }
>>
>> @@ -403,6 +408,7 @@ static int vkms_config_show(struct seq_file *m, void *data)
>>
>> list_for_each_entry(config_encoder, &vkmsdev->config->encoders, link) {
>> seq_puts(m, "encoder:\n");
>> + seq_printf(m, "\tname: %s\n", config_encoder->name);
>> }
>>
>> list_for_each_entry(config_crtc, &vkmsdev->config->crtcs, link) {
>> diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
>> index 8f247fc09373fb2c8145e83be05c6afec1ffac1c..4223edd94ec270915dd658c0b5efd489554d33a5 100644
>> --- a/drivers/gpu/drm/vkms/vkms_config.h
>> +++ b/drivers/gpu/drm/vkms/vkms_config.h
>> @@ -50,6 +50,7 @@ struct vkms_config_crtc {
>> * struct vkms_config_encoder
>> *
>> * @link: Link to the others encoders
>> + * @name: Name of the encoder
>> * @possible_crtcs: List of CRTC that can be used with this encoder
>> * @encoder: Internal usage. This pointer should never be considered as valid. It can be used to
>> * store a temporary reference to a vkms encoder during device creation. This pointer is
>> @@ -58,6 +59,7 @@ struct vkms_config_crtc {
>> struct vkms_config_encoder {
>> struct list_head link;
>>
>> + char *name;
>> struct xarray possible_crtcs;
>>
>> /* Internal usage */
>> diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
>> index 03498a20d78dd8a66f9fc66b360c5ea57fc48d88..6277ad72fdd476d1eff52ad037389bdb1a254f5e 100644
>> --- a/drivers/gpu/drm/vkms/vkms_output.c
>> +++ b/drivers/gpu/drm/vkms/vkms_output.c
>> @@ -92,7 +92,7 @@ int vkms_output_init(struct vkms_device *vkmsdev)
>> if (!config_encoder->encoder)
>> return -ENOMEM;
>> ret = drmm_encoder_init(dev, config_encoder->encoder, NULL,
>> - DRM_MODE_ENCODER_VIRTUAL, NULL);
>> + DRM_MODE_ENCODER_VIRTUAL, config_encoder->name);
>> if (ret) {
>> DRM_ERROR("Failed to init encoder\n");
>> return ret;
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH RFC v2 17/18] drm/vkms: Introduce config for connector EDID
2024-11-25 9:45 ` Jani Nikula
@ 2024-11-25 10:19 ` Louis Chauvet
0 siblings, 0 replies; 26+ messages in thread
From: Louis Chauvet @ 2024-11-25 10:19 UTC (permalink / raw)
To: dri-devel, Jani Nikula, Maíra Canal, Haneen Mohammed,
Simona Vetter, Melissa Wen, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie
Cc: arthurgrillo, jeremie.dautheribes, miquel.raynal,
thomas.petazzoni, seanpaul, nicolejadeyee, linux-kernel
Le 25 novembre 2024 09:45:04 UTC, Jani Nikula <jani.nikula@linux.intel.com> a écrit :
>On Fri, 22 Nov 2024, Louis Chauvet <louis.chauvet@bootlin.com> wrote:
>> To properly test the EDID reading without using the DRM override, add an
>> option to configure the EDID for a connector.
>>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>> ---
>> drivers/gpu/drm/vkms/vkms_config.c | 1 +
>> drivers/gpu/drm/vkms/vkms_config.h | 2 ++
>> drivers/gpu/drm/vkms/vkms_output.c | 37 ++++++++++++++++++++++++++++++++++---
>> 3 files changed, 37 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
>> index ac1a9658c5075c118d59da965ca3392355ccb2b2..1a1234d4f10fa8e5ea6bd649139ecc10c991f875 100644
>> --- a/drivers/gpu/drm/vkms/vkms_config.c
>> +++ b/drivers/gpu/drm/vkms/vkms_config.c
>> @@ -199,6 +199,7 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *v
>> xa_init_flags(&vkms_config_connector->possible_encoders, XA_FLAGS_ALLOC);
>> vkms_config_connector->type = DRM_MODE_CONNECTOR_VIRTUAL;
>> vkms_config_connector->status = connector_status_unknown;
>> + vkms_config_connector->edid_blob_len = 0;
>>
>> return vkms_config_connector;
>> }
>> diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
>> index bba56c9d8aeceac97a4339ef42ab663c5dc54e65..1220b16f6c98d1ebb0ae55d662a84fe25e1a6a02 100644
>> --- a/drivers/gpu/drm/vkms/vkms_config.h
>> +++ b/drivers/gpu/drm/vkms/vkms_config.h
>> @@ -112,6 +112,8 @@ struct vkms_config_connector {
>> struct xarray possible_encoders;
>> int type;
>> enum drm_connector_status status;
>> + char edid_blob[PAGE_SIZE];
>> + int edid_blob_len;
>>
>> /* Internal usage */
>> struct drm_connector *connector;
>> diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
>> index fc6a0cdade0739b94820ed4e0924cf355137fe79..56590afb33d75465971d10a282040690840cdbee 100644
>> --- a/drivers/gpu/drm/vkms/vkms_output.c
>> +++ b/drivers/gpu/drm/vkms/vkms_output.c
>> @@ -31,13 +31,44 @@ static const struct drm_connector_funcs vkms_connector_funcs = {
>> .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
>> };
>>
>> +static int vkms_connector_read_block(void *context, u8 *buf, unsigned int block, size_t len)
>> +{
>> + struct vkms_config_connector *config = context;
>> +
>> + if (block * len + len > config->edid_blob_len)
>
>The parameters to the read block function are a bit weird for historical
>reasons. The start offset is indicated by block number, length by
>len. The start byte offset is thus block * EDID_LENGTH! There's no
>smaller granularity for start offset. However len can be < EDID_LENGTH!
>
>So the above should be (block * EDID_LENGTH + len > edid_blob_len)
>
>> + return 1;
>> + memcpy(buf, &config->edid_blob[block * len], len);
>
>And this should be &config->edid_blob[block * EDID_LENGTH].
>
>(Your patch would work, but just by coincidence due to the way the read
>block function is currently called.)
Thanks for those clarifications!
>> + return 0;
>> +}
>> +
>> static int vkms_conn_get_modes(struct drm_connector *connector)
>> {
>> + const struct drm_edid *drm_edid = NULL;
>> int count;
>> + struct vkms_config_connector *connector_cfg;
>> + struct vkms_device *vkmsdev = drm_device_to_vkms_device(connector->dev);
>> + struct vkms_config_connector *context = NULL;
>> +
>> + list_for_each_entry(connector_cfg, &vkmsdev->config->connectors, link) {
>> + if (connector_cfg->connector == connector) {
>> + context = connector_cfg;
>> + break;
>> + }
>> + }
>> + if (context)
>> + drm_edid = drm_edid_read_custom(connector, vkms_connector_read_block, context);
>
>Thanks for using drm_edid_read_custom() for this btw!
>
>> +
>> + /*
>> + * Unconditionally update the connector. If the EDID was read
>> + * successfully, fill in the connector information derived from the
>> + * EDID. Otherwise, if the EDID is NULL, clear the connector
>> + * information.
>> + */
>> + drm_edid_connector_update(connector, drm_edid);
>> +
>> + count = drm_edid_connector_add_modes(connector);
>>
>> - /* Use the default modes list from DRM */
>> - count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
>> - drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
>
>I don't really know anything about your use case, but don't you want to
>fall back to the above for drm_edid == NULL? *shrug*
You are right, I will probably fallback to noedid version, at least for VIRTUAL connectors.
Or maybe I will add something in VKMS configuration to use "empty edid", "default modes_noedid" or "custom_edid".
This way you will be able to test all the scenarios for your userspace.
Thanks for your review,
Louis Chauvet
>BR,
>Jani.
>
>> + drm_edid_free(drm_edid);
>>
>> return count;
>> }
>
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2024-11-25 10:25 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-22 17:20 [PATCH RFC v2 00/18] drm/vkms: Introduce detailed configuration Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 01/18] drm/vkms: Extract vkms_config header Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 02/18] drm/vkms: Add a validation function for vkms configuration Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 03/18] drm/vkms: Move default_config creation to its own function Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 04/18] drm/vkms: Introduce config for plane Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 05/18] drm/vkms: Introduce config for plane name Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 06/18] drm/vkms: Introduce config for plane rotation Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 07/18] drm/vkms: Introduce config for plane color encoding Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 08/18] drm/vkms: Introduce config for plane color range Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 09/18] drm/vkms: Introduce config for CRTCs and encoders Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 10/18] drm/vkms: Introduce config for encoder name Louis Chauvet
2024-11-25 9:28 ` Jani Nikula
2024-11-25 9:50 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 11/18] drm/vkms: Introduce config for CRTC name Louis Chauvet
2024-11-25 9:29 ` Jani Nikula
2024-11-22 17:20 ` [PATCH RFC v2 12/18] drm/vkms: Add test for config structure Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 13/18] drm/vkms: Introduce config for connector Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 14/18] drm/vkms: Introduce config for connector type Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 15/18] drm/vkms: Introduce config for plane format Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 16/18] drm/vkms: Introduce config for connector status Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 17/18] drm/vkms: Introduce config for connector EDID Louis Chauvet
2024-11-22 21:28 ` Ian Forbes
2024-11-23 10:45 ` Louis Chauvet
2024-11-25 9:45 ` Jani Nikula
2024-11-25 10:19 ` Louis Chauvet
2024-11-22 17:20 ` [PATCH RFC v2 18/18] drm/vkms: Introduce config for encoder type Louis Chauvet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox