@@ -6,6 +6,14 @@
#include "vkms_config.h"
#include "vkms_drv.h"
+static const u32 vkms_supported_plane_formats[] = {
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XRGB16161616,
+ DRM_FORMAT_ARGB16161616,
+ DRM_FORMAT_RGB565,
+};
+
struct vkms_config *vkms_config_create(void)
{
struct vkms_config *config;
@@ -120,6 +128,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;
@@ -186,6 +201,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)
{
@@ -206,6 +280,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);
}
@@ -90,6 +90,8 @@ struct vkms_config_plane {
enum drm_plane_type type;
unsigned int default_rotation;
unsigned int supported_rotations;
+ u32 *supported_formats;
+ unsigned int supported_formats_count;
struct xarray possible_crtcs;
/* Internal usage */
@@ -136,6 +138,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);
/**
@@ -13,14 +13,6 @@
#include "vkms_formats.h"
#include "vkms_config.h"
-static const u32 vkms_formats[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_XRGB16161616,
- DRM_FORMAT_ARGB16161616,
- DRM_FORMAT_RGB565
-};
-
static struct drm_plane_state *
vkms_plane_duplicate_state(struct drm_plane *plane)
{
@@ -195,8 +187,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;
VKMS driver supports all the pixel formats for planes, but for testing it can be useful to only advertise few of them. This new configuration interface will allow configuring the pixel format per planes. Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com> --- drivers/gpu/drm/vkms/vkms_config.c | 75 ++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 19 ++++++++++ drivers/gpu/drm/vkms/vkms_plane.c | 13 ++----- 3 files changed, 97 insertions(+), 10 deletions(-)