Commit d6d05e2a authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

video: screen_info: Add pixel-format helper for linear framebuffers



Add screen_info_pixel_format(), which converts a screen_info's
information about the color format to struct pixel_format. The encoding
within the screen_info structure is complex and therefore prone to
errors. Later patches will convert callers to use the pixel format.

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20250714151513.309475-3-tzimmermann@suse.de
parent cff5fb82
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@
#include <linux/screen_info.h>
#include <linux/string.h>

#include <video/pixel_format.h>

static void resource_init_named(struct resource *r,
				resource_size_t start, resource_size_t size,
				const char *name, unsigned int flags)
@@ -180,3 +182,56 @@ u32 __screen_info_lfb_bits_per_pixel(const struct screen_info *si)
	return bits_per_pixel;
}
EXPORT_SYMBOL(__screen_info_lfb_bits_per_pixel);

static int __screen_info_lfb_pixel_format(const struct screen_info *si, struct pixel_format *f)
{
	u32 bits_per_pixel = __screen_info_lfb_bits_per_pixel(si);

	if (bits_per_pixel > U8_MAX)
		return -EINVAL;

	f->bits_per_pixel = bits_per_pixel;

	if (si->lfb_depth > 8) {
		f->indexed = false;
		f->alpha.offset = 0;
		f->alpha.length = 0;
		f->red.offset = si->red_pos;
		f->red.length = si->red_size;
		f->green.offset = si->green_pos;
		f->green.length = si->green_size;
		f->blue.offset = si->blue_pos;
		f->blue.length = si->blue_size;
	} else {
		f->indexed = true;
		f->index.offset = 0;
		f->index.length = si->lfb_depth;
	}

	return 0;
}

/**
 * screen_info_pixel_format - Returns the screen-info format as pixel-format description
 *
 * @si: the screen_info
 * @f: pointer to return pixel-format description
 *
 * Returns:
 * 0 on success, or a negative errno code otherwise.
 */
int screen_info_pixel_format(const struct screen_info *si, struct pixel_format *f)
{
	unsigned int type = screen_info_video_type(si);

	/* TODO: Add support for additional types as needed. */
	switch (type) {
	case VIDEO_TYPE_VLFB:
	case VIDEO_TYPE_EFI:
		return __screen_info_lfb_pixel_format(si, f);
	}

	/* not supported */
	return -EINVAL;
}
EXPORT_SYMBOL(screen_info_pixel_format);
+2 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#define SCREEN_INFO_MAX_RESOURCES	3

struct pci_dev;
struct pixel_format;
struct resource;

static inline bool __screen_info_has_lfb(unsigned int type)
@@ -136,6 +137,7 @@ static inline u32 __screen_info_vesapm_info_base(const struct screen_info *si)
ssize_t screen_info_resources(const struct screen_info *si, struct resource *r, size_t num);

u32 __screen_info_lfb_bits_per_pixel(const struct screen_info *si);
int screen_info_pixel_format(const struct screen_info *si, struct pixel_format *f);

#if defined(CONFIG_PCI)
void screen_info_apply_fixups(void);