mirror of
https://github.com/torvalds/linux.git
synced 2026-04-30 20:42:33 -04:00
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 <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
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user