diff options
| author | Thomas Zimmermann <tzimmermann@suse.de> | 2025-07-14 17:13:02 +0200 |
|---|---|---|
| committer | Thomas Zimmermann <tzimmermann@suse.de> | 2025-08-26 09:54:16 +0200 |
| commit | d6d05e2af796ca25094f80a73d8841505d54368b (patch) | |
| tree | 62c6032c52a53ee48f24cb13a52798c14e228065 | |
| parent | cff5fb82733c4f1acda458ffd2bb5c948fb59bd6 (diff) | |
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: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20250714151513.309475-3-tzimmermann@suse.de
| -rw-r--r-- | drivers/video/screen_info_generic.c | 55 | ||||
| -rw-r--r-- | include/linux/screen_info.h | 2 |
2 files changed, 57 insertions, 0 deletions
diff --git a/drivers/video/screen_info_generic.c b/drivers/video/screen_info_generic.c index 900e9386eceb..763adbba71cb 100644 --- a/drivers/video/screen_info_generic.c +++ b/drivers/video/screen_info_generic.c @@ -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); diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h index 923d68e07679..1690706206e8 100644 --- a/include/linux/screen_info.h +++ b/include/linux/screen_info.h @@ -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); |
