]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/format-helper: Move drm_fb_build_fourcc_list() to sysfb helpers
authorThomas Zimmermann <tzimmermann@suse.de>
Mon, 16 Jun 2025 08:37:06 +0000 (10:37 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Wed, 18 Jun 2025 08:46:03 +0000 (10:46 +0200)
Only sysfb drivers use drm_fb_build_fourcc_list(). Move the function
to sysfb helpers and rename it accordingly. Update drivers and tests.

v3:
- update naming in tests
v2:
- select DRM_SYSFB_HELPER (kernel test robot)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: José Expósito <jose.exposito89@gmail.com>
Acked-by: Maxime Ripard <mripard@kernel.org>
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20250616083846.221396-4-tzimmermann@suse.de
drivers/gpu/drm/Kconfig.debug
drivers/gpu/drm/drm_format_helper.c
drivers/gpu/drm/sysfb/drm_sysfb_helper.h
drivers/gpu/drm/sysfb/drm_sysfb_modeset.c
drivers/gpu/drm/sysfb/efidrm.c
drivers/gpu/drm/sysfb/ofdrm.c
drivers/gpu/drm/sysfb/simpledrm.c
drivers/gpu/drm/sysfb/vesadrm.c
drivers/gpu/drm/tests/drm_sysfb_modeset_test.c
include/drm/drm_format_helper.h

index fa6ee76f4d3c51059ed1b0f52705bb683febf1e0..05dc43c0b8c5af4fe2a1a615e5c607d466758b30 100644 (file)
@@ -70,6 +70,7 @@ config DRM_KUNIT_TEST
        select DRM_GEM_SHMEM_HELPER
        select DRM_KUNIT_TEST_HELPERS
        select DRM_LIB_RANDOM
+       select DRM_SYSFB_HELPER
        select PRIME_NUMBERS
        default KUNIT_ALL_TESTS
        help
index 63dc46f9fc49e29edf691a1086bfbfbb78ecf451..99d9f7bbc261fc6525eb0711c42c2dc44b1eb0b9 100644 (file)
@@ -1339,141 +1339,3 @@ void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitc
        }
 }
 EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono);
-
-static uint32_t drm_fb_nonalpha_fourcc(uint32_t fourcc)
-{
-       /* only handle formats with depth != 0 and alpha channel */
-       switch (fourcc) {
-       case DRM_FORMAT_ARGB1555:
-               return DRM_FORMAT_XRGB1555;
-       case DRM_FORMAT_ABGR1555:
-               return DRM_FORMAT_XBGR1555;
-       case DRM_FORMAT_RGBA5551:
-               return DRM_FORMAT_RGBX5551;
-       case DRM_FORMAT_BGRA5551:
-               return DRM_FORMAT_BGRX5551;
-       case DRM_FORMAT_ARGB8888:
-               return DRM_FORMAT_XRGB8888;
-       case DRM_FORMAT_ABGR8888:
-               return DRM_FORMAT_XBGR8888;
-       case DRM_FORMAT_RGBA8888:
-               return DRM_FORMAT_RGBX8888;
-       case DRM_FORMAT_BGRA8888:
-               return DRM_FORMAT_BGRX8888;
-       case DRM_FORMAT_ARGB2101010:
-               return DRM_FORMAT_XRGB2101010;
-       case DRM_FORMAT_ABGR2101010:
-               return DRM_FORMAT_XBGR2101010;
-       case DRM_FORMAT_RGBA1010102:
-               return DRM_FORMAT_RGBX1010102;
-       case DRM_FORMAT_BGRA1010102:
-               return DRM_FORMAT_BGRX1010102;
-       }
-
-       return fourcc;
-}
-
-static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t fourcc)
-{
-       const uint32_t *fourccs_end = fourccs + nfourccs;
-
-       while (fourccs < fourccs_end) {
-               if (*fourccs == fourcc)
-                       return true;
-               ++fourccs;
-       }
-       return false;
-}
-
-/**
- * drm_fb_build_fourcc_list - Filters a list of supported color formats against
- *                            the device's native formats
- * @dev: DRM device
- * @native_fourccs: 4CC codes of natively supported color formats
- * @native_nfourccs: The number of entries in @native_fourccs
- * @fourccs_out: Returns 4CC codes of supported color formats
- * @nfourccs_out: The number of available entries in @fourccs_out
- *
- * This function create a list of supported color format from natively
- * supported formats and additional emulated formats.
- * At a minimum, most userspace programs expect at least support for
- * XRGB8888 on the primary plane. Devices that have to emulate the
- * format, and possibly others, can use drm_fb_build_fourcc_list() to
- * create a list of supported color formats. The returned list can
- * be handed over to drm_universal_plane_init() et al. Native formats
- * will go before emulated formats. Native formats with alpha channel
- * will be replaced by such without, as primary planes usually don't
- * support alpha. Other heuristics might be applied
- * to optimize the order. Formats near the beginning of the list are
- * usually preferred over formats near the end of the list.
- *
- * Returns:
- * The number of color-formats 4CC codes returned in @fourccs_out.
- */
-size_t drm_fb_build_fourcc_list(struct drm_device *dev,
-                               const u32 *native_fourccs, size_t native_nfourccs,
-                               u32 *fourccs_out, size_t nfourccs_out)
-{
-       /*
-        * XRGB8888 is the default fallback format for most of userspace
-        * and it's currently the only format that should be emulated for
-        * the primary plane. Only if there's ever another default fallback,
-        * it should be added here.
-        */
-       static const uint32_t extra_fourccs[] = {
-               DRM_FORMAT_XRGB8888,
-       };
-       static const size_t extra_nfourccs = ARRAY_SIZE(extra_fourccs);
-
-       u32 *fourccs = fourccs_out;
-       const u32 *fourccs_end = fourccs_out + nfourccs_out;
-       size_t i;
-
-       /*
-        * The device's native formats go first.
-        */
-
-       for (i = 0; i < native_nfourccs; ++i) {
-               /*
-                * Several DTs, boot loaders and firmware report native
-                * alpha formats that are non-alpha formats instead. So
-                * replace alpha formats by non-alpha formats.
-                */
-               u32 fourcc = drm_fb_nonalpha_fourcc(native_fourccs[i]);
-
-               if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) {
-                       continue; /* skip duplicate entries */
-               } else if (fourccs == fourccs_end) {
-                       drm_warn(dev, "Ignoring native format %p4cc\n", &fourcc);
-                       continue; /* end of available output buffer */
-               }
-
-               drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc);
-
-               *fourccs = fourcc;
-               ++fourccs;
-       }
-
-       /*
-        * The extra formats, emulated by the driver, go second.
-        */
-
-       for (i = 0; (i < extra_nfourccs) && (fourccs < fourccs_end); ++i) {
-               u32 fourcc = extra_fourccs[i];
-
-               if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) {
-                       continue; /* skip duplicate and native entries */
-               } else if (fourccs == fourccs_end) {
-                       drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc);
-                       continue; /* end of available output buffer */
-               }
-
-               drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc);
-
-               *fourccs = fourcc;
-               ++fourccs;
-       }
-
-       return fourccs - fourccs_out;
-}
-EXPORT_SYMBOL(drm_fb_build_fourcc_list);
index cb08a88242cc1365f774b24ca29cda8ef816892a..1424b63dde99b3d36e0e88d0a77dc306ba262885 100644 (file)
@@ -93,6 +93,10 @@ static inline struct drm_sysfb_device *to_drm_sysfb_device(struct drm_device *de
  * Plane
  */
 
+size_t drm_sysfb_build_fourcc_list(struct drm_device *dev,
+                                  const u32 *native_fourccs, size_t native_nfourccs,
+                                  u32 *fourccs_out, size_t nfourccs_out);
+
 int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane,
                                        struct drm_atomic_state *new_state);
 void drm_sysfb_plane_helper_atomic_update(struct drm_plane *plane,
index ffaa2522ab9653909814f6c132a180b615d454f1..1bcdb5ee8f093a11c4aca42b7bb75045306655ea 100644 (file)
@@ -47,6 +47,144 @@ EXPORT_SYMBOL(drm_sysfb_mode);
  * Plane
  */
 
+static u32 to_nonalpha_fourcc(u32 fourcc)
+{
+       /* only handle formats with depth != 0 and alpha channel */
+       switch (fourcc) {
+       case DRM_FORMAT_ARGB1555:
+               return DRM_FORMAT_XRGB1555;
+       case DRM_FORMAT_ABGR1555:
+               return DRM_FORMAT_XBGR1555;
+       case DRM_FORMAT_RGBA5551:
+               return DRM_FORMAT_RGBX5551;
+       case DRM_FORMAT_BGRA5551:
+               return DRM_FORMAT_BGRX5551;
+       case DRM_FORMAT_ARGB8888:
+               return DRM_FORMAT_XRGB8888;
+       case DRM_FORMAT_ABGR8888:
+               return DRM_FORMAT_XBGR8888;
+       case DRM_FORMAT_RGBA8888:
+               return DRM_FORMAT_RGBX8888;
+       case DRM_FORMAT_BGRA8888:
+               return DRM_FORMAT_BGRX8888;
+       case DRM_FORMAT_ARGB2101010:
+               return DRM_FORMAT_XRGB2101010;
+       case DRM_FORMAT_ABGR2101010:
+               return DRM_FORMAT_XBGR2101010;
+       case DRM_FORMAT_RGBA1010102:
+               return DRM_FORMAT_RGBX1010102;
+       case DRM_FORMAT_BGRA1010102:
+               return DRM_FORMAT_BGRX1010102;
+       }
+
+       return fourcc;
+}
+
+static bool is_listed_fourcc(const u32 *fourccs, size_t nfourccs, u32 fourcc)
+{
+       const u32 *fourccs_end = fourccs + nfourccs;
+
+       while (fourccs < fourccs_end) {
+               if (*fourccs == fourcc)
+                       return true;
+               ++fourccs;
+       }
+       return false;
+}
+
+/**
+ * drm_sysfb_build_fourcc_list - Filters a list of supported color formats against
+ *                               the device's native formats
+ * @dev: DRM device
+ * @native_fourccs: 4CC codes of natively supported color formats
+ * @native_nfourccs: The number of entries in @native_fourccs
+ * @fourccs_out: Returns 4CC codes of supported color formats
+ * @nfourccs_out: The number of available entries in @fourccs_out
+ *
+ * This function create a list of supported color format from natively
+ * supported formats and additional emulated formats.
+ * At a minimum, most userspace programs expect at least support for
+ * XRGB8888 on the primary plane. Sysfb devices that have to emulate
+ * the format should use drm_sysfb_build_fourcc_list() to create a list
+ * of supported color formats. The returned list can be handed over to
+ * drm_universal_plane_init() et al. Native formats will go before
+ * emulated formats. Native formats with alpha channel will be replaced
+ * by equal formats without alpha channel, as primary planes usually
+ * don't support alpha. Other heuristics might be applied to optimize
+ * the sorting order. Formats near the beginning of the list are usually
+ * preferred over formats near the end of the list.
+ *
+ * Returns:
+ * The number of color-formats 4CC codes returned in @fourccs_out.
+ */
+size_t drm_sysfb_build_fourcc_list(struct drm_device *dev,
+                                  const u32 *native_fourccs, size_t native_nfourccs,
+                                  u32 *fourccs_out, size_t nfourccs_out)
+{
+       /*
+        * XRGB8888 is the default fallback format for most of userspace
+        * and it's currently the only format that should be emulated for
+        * the primary plane. Only if there's ever another default fallback,
+        * it should be added here.
+        */
+       static const u32 extra_fourccs[] = {
+               DRM_FORMAT_XRGB8888,
+       };
+       static const size_t extra_nfourccs = ARRAY_SIZE(extra_fourccs);
+
+       u32 *fourccs = fourccs_out;
+       const u32 *fourccs_end = fourccs_out + nfourccs_out;
+       size_t i;
+
+       /*
+        * The device's native formats go first.
+        */
+
+       for (i = 0; i < native_nfourccs; ++i) {
+               /*
+                * Several DTs, boot loaders and firmware report native
+                * alpha formats that are non-alpha formats instead. So
+                * replace alpha formats by non-alpha formats.
+                */
+               u32 fourcc = to_nonalpha_fourcc(native_fourccs[i]);
+
+               if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) {
+                       continue; /* skip duplicate entries */
+               } else if (fourccs == fourccs_end) {
+                       drm_warn(dev, "Ignoring native format %p4cc\n", &fourcc);
+                       continue; /* end of available output buffer */
+               }
+
+               drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc);
+
+               *fourccs = fourcc;
+               ++fourccs;
+       }
+
+       /*
+        * The extra formats, emulated by the driver, go second.
+        */
+
+       for (i = 0; (i < extra_nfourccs) && (fourccs < fourccs_end); ++i) {
+               u32 fourcc = extra_fourccs[i];
+
+               if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) {
+                       continue; /* skip duplicate and native entries */
+               } else if (fourccs == fourccs_end) {
+                       drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc);
+                       continue; /* end of available output buffer */
+               }
+
+               drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc);
+
+               *fourccs = fourcc;
+               ++fourccs;
+       }
+
+       return fourccs - fourccs_out;
+}
+EXPORT_SYMBOL(drm_sysfb_build_fourcc_list);
+
 int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane,
                                        struct drm_atomic_state *new_state)
 {
index a8b1305b6e137a65d31f2c276cc2e159f67edf15..1883c4a8604c2feaed0843eb46199b5596d8530c 100644 (file)
@@ -271,8 +271,8 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,
 
        /* Primary plane */
 
-       nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
-                                           efi->formats, ARRAY_SIZE(efi->formats));
+       nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1,
+                                              efi->formats, ARRAY_SIZE(efi->formats));
 
        primary_plane = &efi->primary_plane;
        ret = drm_universal_plane_init(dev, primary_plane, 0, &efidrm_primary_plane_funcs,
index c9415f0cb3ed3ead08c6f7a233584a6158593096..8d8ab39c5f363a771e286720c9ede1a40b8f4efb 100644 (file)
@@ -15,7 +15,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_fbdev_shmem.h>
-#include <drm/drm_format_helper.h>
 #include <drm/drm_framebuffer.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
@@ -1015,8 +1014,8 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv,
 
        /* Primary plane */
 
-       nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
-                                           odev->formats, ARRAY_SIZE(odev->formats));
+       nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1,
+                                              odev->formats, ARRAY_SIZE(odev->formats));
 
        primary_plane = &odev->primary_plane;
        ret = drm_universal_plane_init(dev, primary_plane, 0, &ofdrm_primary_plane_funcs,
index a1c3119330deffc9e122b83941f3697e5b87f277..8530a3ef8a7aa232effa4f18771abcdcf6b55d9b 100644 (file)
@@ -18,7 +18,6 @@
 #include <drm/drm_device.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_fbdev_shmem.h>
-#include <drm/drm_format_helper.h>
 #include <drm/drm_framebuffer.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
@@ -765,8 +764,8 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
 
        /* Primary plane */
 
-       nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
-                                           sdev->formats, ARRAY_SIZE(sdev->formats));
+       nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1,
+                                              sdev->formats, ARRAY_SIZE(sdev->formats));
 
        primary_plane = &sdev->primary_plane;
        ret = drm_universal_plane_init(dev, primary_plane, 0, &simpledrm_primary_plane_funcs,
index c5216dbe21ece4669d9918716ef61e7a7c123b12..2b107958942cf909fad1ef7cb507046fe4abdca8 100644 (file)
@@ -402,8 +402,8 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv,
 
        /* Primary plane */
 
-       nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
-                                           vesa->formats, ARRAY_SIZE(vesa->formats));
+       nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1,
+                                              vesa->formats, ARRAY_SIZE(vesa->formats));
 
        primary_plane = &vesa->primary_plane;
        ret = drm_universal_plane_init(dev, primary_plane, 0, &vesadrm_primary_plane_funcs,
index 5104fb21c6bc128a80a9a313d81aa959b871c0bd..e875d876118f88617c6a4ec3adb6c5081038244b 100644 (file)
@@ -2,13 +2,14 @@
 
 #include <kunit/test.h>
 
-#include <drm/drm_format_helper.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_kunit_helpers.h>
 
+#include "../sysfb/drm_sysfb_helper.h"
+
 #define TEST_BUF_SIZE 50
 
-struct fb_build_fourcc_list_case {
+struct sysfb_build_fourcc_list_case {
        const char *name;
        u32 native_fourccs[TEST_BUF_SIZE];
        size_t native_fourccs_size;
@@ -16,7 +17,7 @@ struct fb_build_fourcc_list_case {
        size_t expected_fourccs_size;
 };
 
-static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = {
+static struct sysfb_build_fourcc_list_case sysfb_build_fourcc_list_cases[] = {
        {
                .name = "no native formats",
                .native_fourccs = { },
@@ -120,16 +121,17 @@ static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = {
        },
 };
 
-static void fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case *t, char *desc)
+static void sysfb_build_fourcc_list_case_desc(struct sysfb_build_fourcc_list_case *t, char *desc)
 {
        strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
 }
 
-KUNIT_ARRAY_PARAM(fb_build_fourcc_list, fb_build_fourcc_list_cases, fb_build_fourcc_list_case_desc);
+KUNIT_ARRAY_PARAM(sysfb_build_fourcc_list, sysfb_build_fourcc_list_cases,
+                 sysfb_build_fourcc_list_case_desc);
 
-static void drm_test_fb_build_fourcc_list(struct kunit *test)
+static void drm_test_sysfb_build_fourcc_list(struct kunit *test)
 {
-       const struct fb_build_fourcc_list_case *params = test->param_value;
+       const struct sysfb_build_fourcc_list_case *params = test->param_value;
        u32 fourccs_out[TEST_BUF_SIZE] = {0};
        size_t nfourccs_out;
        struct drm_device *drm;
@@ -141,16 +143,16 @@ static void drm_test_fb_build_fourcc_list(struct kunit *test)
        drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
 
-       nfourccs_out = drm_fb_build_fourcc_list(drm, params->native_fourccs,
-                                               params->native_fourccs_size,
-                                               fourccs_out, TEST_BUF_SIZE);
+       nfourccs_out = drm_sysfb_build_fourcc_list(drm, params->native_fourccs,
+                                                  params->native_fourccs_size,
+                                                  fourccs_out, TEST_BUF_SIZE);
 
        KUNIT_EXPECT_EQ(test, nfourccs_out, params->expected_fourccs_size);
        KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE);
 }
 
 static struct kunit_case drm_sysfb_modeset_test_cases[] = {
-       KUNIT_CASE_PARAM(drm_test_fb_build_fourcc_list, fb_build_fourcc_list_gen_params),
+       KUNIT_CASE_PARAM(drm_test_sysfb_build_fourcc_list, sysfb_build_fourcc_list_gen_params),
        {}
 };
 
index 49a2e09155d1ceae1a85d2d8af8b9b8d311d82dd..0d3ee2a1313f0d22c37f4cfaccefb0c1cbb0f110 100644 (file)
@@ -134,8 +134,4 @@ void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitc
                             const struct iosys_map *src, const struct drm_framebuffer *fb,
                             const struct drm_rect *clip, struct drm_format_conv_state *state);
 
-size_t drm_fb_build_fourcc_list(struct drm_device *dev,
-                               const u32 *native_fourccs, size_t native_nfourccs,
-                               u32 *fourccs_out, size_t nfourccs_out);
-
 #endif /* __LINUX_DRM_FORMAT_HELPER_H */