diff options
author | Dave Airlie <airlied@redhat.com> | 2023-01-16 08:33:22 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2023-01-16 08:33:28 +0300 |
commit | c37ea39c1fa880da0d7fd2c719e5c96be19f0fc5 (patch) | |
tree | 1d4bd8a5ab631cd54ebb326fc39160a2be84e969 /drivers/firmware | |
parent | 1f1c24dee225fc82472627986997ba6aef309fc2 (diff) | |
parent | 6e41acd2e5353c5362e0d5c2f5ba495c54ff555e (diff) | |
download | linux-c37ea39c1fa880da0d7fd2c719e5c96be19f0fc5.tar.xz |
Merge tag 'drm-misc-next-2023-01-12' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v6.3:
UAPI Changes:
* fourcc: Document Open Source user waiver
Cross-subsystem Changes:
* firmware: fix color-format selection for system framebuffers
Core Changes:
* format-helper: Add conversion from XRGB8888 to various sysfb formats;
Make XRGB8888 the only driver-emulated legacy format
* fb-helper: Avoid blank consoles from selecting an incorrect color format
* probe-helper: Enable/disable HPD on connectors plus driver updates
* Use drm_dbg_ helpers in several places
* docs: Document defaults for CRTC backgrounds; Document use of drm_minor
Driver Changes:
* arm/hdlcd: Use new debugfs helpers
* gud: Use new debugfs helpers
* panel: Support Visionox VTDR6130 AMOLED DSI; Support Himax HX8394; Convert
many drivers to common generic DSI write-sequence helper
* v3d: Do not opencode drm_gem_object_lookup()
* vc4: Various HVS an CRTC fixes
* vkms: Fix SEGFAULT from incorrect GEM-buffer mapping
* Convert various drivers to i2c probe_new()
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/Y8ADeSzZDj+tpibF@linux-uq9g
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/sysfb_simplefb.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/drivers/firmware/sysfb_simplefb.c b/drivers/firmware/sysfb_simplefb.c index a353e27f83f5..ce9c007ed66f 100644 --- a/drivers/firmware/sysfb_simplefb.c +++ b/drivers/firmware/sysfb_simplefb.c @@ -27,25 +27,56 @@ static const struct simplefb_format formats[] = SIMPLEFB_FORMATS; __init bool sysfb_parse_mode(const struct screen_info *si, struct simplefb_platform_data *mode) { - const struct simplefb_format *f; __u8 type; + u32 bits_per_pixel; unsigned int i; type = si->orig_video_isVGA; if (type != VIDEO_TYPE_VLFB && type != VIDEO_TYPE_EFI) return false; + /* + * The meaning of depth and bpp for direct-color formats is + * inconsistent: + * + * - DRM format info specifies depth as the number of color + * bits; including alpha, but not including filler bits. + * - Linux' EFI platform code computes lfb_depth from the + * individual color channels, including the reserved bits. + * - VBE 1.1 defines lfb_depth for XRGB1555 as 16, but later + * versions use 15. + * - On the kernel command line, 'bpp' of 32 is usually + * XRGB8888 including the filler bits, but 15 is XRGB1555 + * not including the filler bit. + * + * It's not easily possible to fix this in struct screen_info, + * as this could break UAPI. The best solution is to compute + * bits_per_pixel here and ignore lfb_depth. In the loop below, + * ignore simplefb formats with alpha bits, as EFI and VESA + * don't specify alpha channels. + */ + if (si->lfb_depth > 8) { + bits_per_pixel = max(max3(si->red_size + si->red_pos, + si->green_size + si->green_pos, + si->blue_size + si->blue_pos), + si->rsvd_size + si->rsvd_pos); + } else { + bits_per_pixel = si->lfb_depth; + } + for (i = 0; i < ARRAY_SIZE(formats); ++i) { - f = &formats[i]; - if (si->lfb_depth == f->bits_per_pixel && + const struct simplefb_format *f = &formats[i]; + + if (f->transp.length) + continue; /* transparent formats are unsupported by VESA/EFI */ + + if (bits_per_pixel == f->bits_per_pixel && si->red_size == f->red.length && si->red_pos == f->red.offset && si->green_size == f->green.length && si->green_pos == f->green.offset && si->blue_size == f->blue.length && - si->blue_pos == f->blue.offset && - si->rsvd_size == f->transp.length && - si->rsvd_pos == f->transp.offset) { + si->blue_pos == f->blue.offset) { mode->format = f->name; mode->width = si->lfb_width; mode->height = si->lfb_height; |