Skip to content

Commit 1a45ef0

Browse files
author
Thomas Zimmermann
committed
drm/format-helper: Move drm_fb_build_fourcc_list() to sysfb helpers
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 <[email protected]> Reviewed-by: José Expósito <[email protected]> Acked-by: Maxime Ripard <[email protected]> Acked-by: Javier Martinez Canillas <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 4f522a4 commit 1a45ef0

File tree

10 files changed

+164
-163
lines changed

10 files changed

+164
-163
lines changed

drivers/gpu/drm/Kconfig.debug

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ config DRM_KUNIT_TEST
7070
select DRM_GEM_SHMEM_HELPER
7171
select DRM_KUNIT_TEST_HELPERS
7272
select DRM_LIB_RANDOM
73+
select DRM_SYSFB_HELPER
7374
select PRIME_NUMBERS
7475
default KUNIT_ALL_TESTS
7576
help

drivers/gpu/drm/drm_format_helper.c

Lines changed: 0 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,141 +1339,3 @@ void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitc
13391339
}
13401340
}
13411341
EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono);
1342-
1343-
static uint32_t drm_fb_nonalpha_fourcc(uint32_t fourcc)
1344-
{
1345-
/* only handle formats with depth != 0 and alpha channel */
1346-
switch (fourcc) {
1347-
case DRM_FORMAT_ARGB1555:
1348-
return DRM_FORMAT_XRGB1555;
1349-
case DRM_FORMAT_ABGR1555:
1350-
return DRM_FORMAT_XBGR1555;
1351-
case DRM_FORMAT_RGBA5551:
1352-
return DRM_FORMAT_RGBX5551;
1353-
case DRM_FORMAT_BGRA5551:
1354-
return DRM_FORMAT_BGRX5551;
1355-
case DRM_FORMAT_ARGB8888:
1356-
return DRM_FORMAT_XRGB8888;
1357-
case DRM_FORMAT_ABGR8888:
1358-
return DRM_FORMAT_XBGR8888;
1359-
case DRM_FORMAT_RGBA8888:
1360-
return DRM_FORMAT_RGBX8888;
1361-
case DRM_FORMAT_BGRA8888:
1362-
return DRM_FORMAT_BGRX8888;
1363-
case DRM_FORMAT_ARGB2101010:
1364-
return DRM_FORMAT_XRGB2101010;
1365-
case DRM_FORMAT_ABGR2101010:
1366-
return DRM_FORMAT_XBGR2101010;
1367-
case DRM_FORMAT_RGBA1010102:
1368-
return DRM_FORMAT_RGBX1010102;
1369-
case DRM_FORMAT_BGRA1010102:
1370-
return DRM_FORMAT_BGRX1010102;
1371-
}
1372-
1373-
return fourcc;
1374-
}
1375-
1376-
static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t fourcc)
1377-
{
1378-
const uint32_t *fourccs_end = fourccs + nfourccs;
1379-
1380-
while (fourccs < fourccs_end) {
1381-
if (*fourccs == fourcc)
1382-
return true;
1383-
++fourccs;
1384-
}
1385-
return false;
1386-
}
1387-
1388-
/**
1389-
* drm_fb_build_fourcc_list - Filters a list of supported color formats against
1390-
* the device's native formats
1391-
* @dev: DRM device
1392-
* @native_fourccs: 4CC codes of natively supported color formats
1393-
* @native_nfourccs: The number of entries in @native_fourccs
1394-
* @fourccs_out: Returns 4CC codes of supported color formats
1395-
* @nfourccs_out: The number of available entries in @fourccs_out
1396-
*
1397-
* This function create a list of supported color format from natively
1398-
* supported formats and additional emulated formats.
1399-
* At a minimum, most userspace programs expect at least support for
1400-
* XRGB8888 on the primary plane. Devices that have to emulate the
1401-
* format, and possibly others, can use drm_fb_build_fourcc_list() to
1402-
* create a list of supported color formats. The returned list can
1403-
* be handed over to drm_universal_plane_init() et al. Native formats
1404-
* will go before emulated formats. Native formats with alpha channel
1405-
* will be replaced by such without, as primary planes usually don't
1406-
* support alpha. Other heuristics might be applied
1407-
* to optimize the order. Formats near the beginning of the list are
1408-
* usually preferred over formats near the end of the list.
1409-
*
1410-
* Returns:
1411-
* The number of color-formats 4CC codes returned in @fourccs_out.
1412-
*/
1413-
size_t drm_fb_build_fourcc_list(struct drm_device *dev,
1414-
const u32 *native_fourccs, size_t native_nfourccs,
1415-
u32 *fourccs_out, size_t nfourccs_out)
1416-
{
1417-
/*
1418-
* XRGB8888 is the default fallback format for most of userspace
1419-
* and it's currently the only format that should be emulated for
1420-
* the primary plane. Only if there's ever another default fallback,
1421-
* it should be added here.
1422-
*/
1423-
static const uint32_t extra_fourccs[] = {
1424-
DRM_FORMAT_XRGB8888,
1425-
};
1426-
static const size_t extra_nfourccs = ARRAY_SIZE(extra_fourccs);
1427-
1428-
u32 *fourccs = fourccs_out;
1429-
const u32 *fourccs_end = fourccs_out + nfourccs_out;
1430-
size_t i;
1431-
1432-
/*
1433-
* The device's native formats go first.
1434-
*/
1435-
1436-
for (i = 0; i < native_nfourccs; ++i) {
1437-
/*
1438-
* Several DTs, boot loaders and firmware report native
1439-
* alpha formats that are non-alpha formats instead. So
1440-
* replace alpha formats by non-alpha formats.
1441-
*/
1442-
u32 fourcc = drm_fb_nonalpha_fourcc(native_fourccs[i]);
1443-
1444-
if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) {
1445-
continue; /* skip duplicate entries */
1446-
} else if (fourccs == fourccs_end) {
1447-
drm_warn(dev, "Ignoring native format %p4cc\n", &fourcc);
1448-
continue; /* end of available output buffer */
1449-
}
1450-
1451-
drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc);
1452-
1453-
*fourccs = fourcc;
1454-
++fourccs;
1455-
}
1456-
1457-
/*
1458-
* The extra formats, emulated by the driver, go second.
1459-
*/
1460-
1461-
for (i = 0; (i < extra_nfourccs) && (fourccs < fourccs_end); ++i) {
1462-
u32 fourcc = extra_fourccs[i];
1463-
1464-
if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) {
1465-
continue; /* skip duplicate and native entries */
1466-
} else if (fourccs == fourccs_end) {
1467-
drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc);
1468-
continue; /* end of available output buffer */
1469-
}
1470-
1471-
drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc);
1472-
1473-
*fourccs = fourcc;
1474-
++fourccs;
1475-
}
1476-
1477-
return fourccs - fourccs_out;
1478-
}
1479-
EXPORT_SYMBOL(drm_fb_build_fourcc_list);

drivers/gpu/drm/sysfb/drm_sysfb_helper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ static inline struct drm_sysfb_device *to_drm_sysfb_device(struct drm_device *de
9393
* Plane
9494
*/
9595

96+
size_t drm_sysfb_build_fourcc_list(struct drm_device *dev,
97+
const u32 *native_fourccs, size_t native_nfourccs,
98+
u32 *fourccs_out, size_t nfourccs_out);
99+
96100
int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane,
97101
struct drm_atomic_state *new_state);
98102
void drm_sysfb_plane_helper_atomic_update(struct drm_plane *plane,

drivers/gpu/drm/sysfb/drm_sysfb_modeset.c

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,144 @@ EXPORT_SYMBOL(drm_sysfb_mode);
4747
* Plane
4848
*/
4949

50+
static u32 to_nonalpha_fourcc(u32 fourcc)
51+
{
52+
/* only handle formats with depth != 0 and alpha channel */
53+
switch (fourcc) {
54+
case DRM_FORMAT_ARGB1555:
55+
return DRM_FORMAT_XRGB1555;
56+
case DRM_FORMAT_ABGR1555:
57+
return DRM_FORMAT_XBGR1555;
58+
case DRM_FORMAT_RGBA5551:
59+
return DRM_FORMAT_RGBX5551;
60+
case DRM_FORMAT_BGRA5551:
61+
return DRM_FORMAT_BGRX5551;
62+
case DRM_FORMAT_ARGB8888:
63+
return DRM_FORMAT_XRGB8888;
64+
case DRM_FORMAT_ABGR8888:
65+
return DRM_FORMAT_XBGR8888;
66+
case DRM_FORMAT_RGBA8888:
67+
return DRM_FORMAT_RGBX8888;
68+
case DRM_FORMAT_BGRA8888:
69+
return DRM_FORMAT_BGRX8888;
70+
case DRM_FORMAT_ARGB2101010:
71+
return DRM_FORMAT_XRGB2101010;
72+
case DRM_FORMAT_ABGR2101010:
73+
return DRM_FORMAT_XBGR2101010;
74+
case DRM_FORMAT_RGBA1010102:
75+
return DRM_FORMAT_RGBX1010102;
76+
case DRM_FORMAT_BGRA1010102:
77+
return DRM_FORMAT_BGRX1010102;
78+
}
79+
80+
return fourcc;
81+
}
82+
83+
static bool is_listed_fourcc(const u32 *fourccs, size_t nfourccs, u32 fourcc)
84+
{
85+
const u32 *fourccs_end = fourccs + nfourccs;
86+
87+
while (fourccs < fourccs_end) {
88+
if (*fourccs == fourcc)
89+
return true;
90+
++fourccs;
91+
}
92+
return false;
93+
}
94+
95+
/**
96+
* drm_sysfb_build_fourcc_list - Filters a list of supported color formats against
97+
* the device's native formats
98+
* @dev: DRM device
99+
* @native_fourccs: 4CC codes of natively supported color formats
100+
* @native_nfourccs: The number of entries in @native_fourccs
101+
* @fourccs_out: Returns 4CC codes of supported color formats
102+
* @nfourccs_out: The number of available entries in @fourccs_out
103+
*
104+
* This function create a list of supported color format from natively
105+
* supported formats and additional emulated formats.
106+
* At a minimum, most userspace programs expect at least support for
107+
* XRGB8888 on the primary plane. Sysfb devices that have to emulate
108+
* the format should use drm_sysfb_build_fourcc_list() to create a list
109+
* of supported color formats. The returned list can be handed over to
110+
* drm_universal_plane_init() et al. Native formats will go before
111+
* emulated formats. Native formats with alpha channel will be replaced
112+
* by equal formats without alpha channel, as primary planes usually
113+
* don't support alpha. Other heuristics might be applied to optimize
114+
* the sorting order. Formats near the beginning of the list are usually
115+
* preferred over formats near the end of the list.
116+
*
117+
* Returns:
118+
* The number of color-formats 4CC codes returned in @fourccs_out.
119+
*/
120+
size_t drm_sysfb_build_fourcc_list(struct drm_device *dev,
121+
const u32 *native_fourccs, size_t native_nfourccs,
122+
u32 *fourccs_out, size_t nfourccs_out)
123+
{
124+
/*
125+
* XRGB8888 is the default fallback format for most of userspace
126+
* and it's currently the only format that should be emulated for
127+
* the primary plane. Only if there's ever another default fallback,
128+
* it should be added here.
129+
*/
130+
static const u32 extra_fourccs[] = {
131+
DRM_FORMAT_XRGB8888,
132+
};
133+
static const size_t extra_nfourccs = ARRAY_SIZE(extra_fourccs);
134+
135+
u32 *fourccs = fourccs_out;
136+
const u32 *fourccs_end = fourccs_out + nfourccs_out;
137+
size_t i;
138+
139+
/*
140+
* The device's native formats go first.
141+
*/
142+
143+
for (i = 0; i < native_nfourccs; ++i) {
144+
/*
145+
* Several DTs, boot loaders and firmware report native
146+
* alpha formats that are non-alpha formats instead. So
147+
* replace alpha formats by non-alpha formats.
148+
*/
149+
u32 fourcc = to_nonalpha_fourcc(native_fourccs[i]);
150+
151+
if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) {
152+
continue; /* skip duplicate entries */
153+
} else if (fourccs == fourccs_end) {
154+
drm_warn(dev, "Ignoring native format %p4cc\n", &fourcc);
155+
continue; /* end of available output buffer */
156+
}
157+
158+
drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc);
159+
160+
*fourccs = fourcc;
161+
++fourccs;
162+
}
163+
164+
/*
165+
* The extra formats, emulated by the driver, go second.
166+
*/
167+
168+
for (i = 0; (i < extra_nfourccs) && (fourccs < fourccs_end); ++i) {
169+
u32 fourcc = extra_fourccs[i];
170+
171+
if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) {
172+
continue; /* skip duplicate and native entries */
173+
} else if (fourccs == fourccs_end) {
174+
drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc);
175+
continue; /* end of available output buffer */
176+
}
177+
178+
drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc);
179+
180+
*fourccs = fourcc;
181+
++fourccs;
182+
}
183+
184+
return fourccs - fourccs_out;
185+
}
186+
EXPORT_SYMBOL(drm_sysfb_build_fourcc_list);
187+
50188
int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane,
51189
struct drm_atomic_state *new_state)
52190
{

drivers/gpu/drm/sysfb/efidrm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,8 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,
271271

272272
/* Primary plane */
273273

274-
nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
275-
efi->formats, ARRAY_SIZE(efi->formats));
274+
nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1,
275+
efi->formats, ARRAY_SIZE(efi->formats));
276276

277277
primary_plane = &efi->primary_plane;
278278
ret = drm_universal_plane_init(dev, primary_plane, 0, &efidrm_primary_plane_funcs,

drivers/gpu/drm/sysfb/ofdrm.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <drm/drm_drv.h>
1616
#include <drm/drm_edid.h>
1717
#include <drm/drm_fbdev_shmem.h>
18-
#include <drm/drm_format_helper.h>
1918
#include <drm/drm_framebuffer.h>
2019
#include <drm/drm_gem_atomic_helper.h>
2120
#include <drm/drm_gem_framebuffer_helper.h>
@@ -1015,8 +1014,8 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv,
10151014

10161015
/* Primary plane */
10171016

1018-
nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
1019-
odev->formats, ARRAY_SIZE(odev->formats));
1017+
nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1,
1018+
odev->formats, ARRAY_SIZE(odev->formats));
10201019

10211020
primary_plane = &odev->primary_plane;
10221021
ret = drm_universal_plane_init(dev, primary_plane, 0, &ofdrm_primary_plane_funcs,

drivers/gpu/drm/sysfb/simpledrm.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <drm/drm_device.h>
1919
#include <drm/drm_drv.h>
2020
#include <drm/drm_fbdev_shmem.h>
21-
#include <drm/drm_format_helper.h>
2221
#include <drm/drm_framebuffer.h>
2322
#include <drm/drm_gem_atomic_helper.h>
2423
#include <drm/drm_gem_framebuffer_helper.h>
@@ -765,8 +764,8 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
765764

766765
/* Primary plane */
767766

768-
nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
769-
sdev->formats, ARRAY_SIZE(sdev->formats));
767+
nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1,
768+
sdev->formats, ARRAY_SIZE(sdev->formats));
770769

771770
primary_plane = &sdev->primary_plane;
772771
ret = drm_universal_plane_init(dev, primary_plane, 0, &simpledrm_primary_plane_funcs,

drivers/gpu/drm/sysfb/vesadrm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,8 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv,
402402

403403
/* Primary plane */
404404

405-
nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
406-
vesa->formats, ARRAY_SIZE(vesa->formats));
405+
nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1,
406+
vesa->formats, ARRAY_SIZE(vesa->formats));
407407

408408
primary_plane = &vesa->primary_plane;
409409
ret = drm_universal_plane_init(dev, primary_plane, 0, &vesadrm_primary_plane_funcs,

0 commit comments

Comments
 (0)