From: Tvrtko Ursulin Date: Mon, 8 Dec 2025 19:39:25 +0000 (+0100) Subject: efi: sysfb_efi: Fix efidrmfb and simpledrmfb on Valve Steam Deck X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7c7eb5ed5a3896e57019f7b33e3b7dcb4ab73b4;p=thirdparty%2Flinux.git efi: sysfb_efi: Fix efidrmfb and simpledrmfb on Valve Steam Deck Valve Steam Deck has a 800x1280 portrait screen installed in a landscape orientation. The firmware offers a software-rotated 1280x800 mode, which GRUB can be made to switch to when displaying a boot menu. If this mode was selected frame buffer drivers will see this fake mode and fbcon rendering will be corrupted. Let us therefore add a selective quirk inside the current "swap with and height" handling, which will detect this exact mode and fix it up back to the native one. This will allow the DRM-based framebuffer drivers to detect the correct mode, apply the existing panel orientation quirk, and render the console in landscape mode with no corruption. Signed-off-by: Tvrtko Ursulin Cc: Thomas Zimmermann Cc: Ard Biesheuvel Cc: Melissa Wen Cc: linux-efi@vger.kernel.org Tested-by: Melissa Wen # v3 Reviewed-by: Thomas Zimmermann [ardb: use local var to refer to screen_info] Signed-off-by: Ard Biesheuvel --- diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c index dc4d70b7737c4..aea94a75b575e 100644 --- a/drivers/firmware/efi/sysfb_efi.c +++ b/drivers/firmware/efi/sysfb_efi.c @@ -242,6 +242,33 @@ static int __init efifb_swap_width_height(const struct dmi_system_id *id) return 1; } +struct efifb_mode_fixup { + unsigned int width; + unsigned int height; + unsigned int linelength; +}; + +static int __init +efifb_check_and_swap_width_height(const struct dmi_system_id *id) +{ + const struct efifb_mode_fixup *data = id->driver_data; + struct screen_info *si = &screen_info; + + if (data->width == si->lfb_width && data->height == si->lfb_height) { + swap(si->lfb_width, si->lfb_height); + si->lfb_linelength = data->linelength; + si->lfb_size = data->linelength * data->width; + } + + return 1; +} + +static const struct efifb_mode_fixup efifb_steamdeck_mode_fixup __initconst = { + .width = 1280, + .height = 800, + .linelength = 3328, +}; + /* * Some devices have a portrait LCD but advertise a landscape resolution (and * pitch). We simply swap width and height for these devices so that we can @@ -297,6 +324,26 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { }, .callback = efifb_swap_width_height, }, + { + /* Valve Steam Deck (Jupiter) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), + }, + .callback = efifb_check_and_swap_width_height, + .driver_data = (void *)&efifb_steamdeck_mode_fixup, + }, + { + /* Valve Steam Deck (Galileo) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galileo"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), + }, + .callback = efifb_check_and_swap_width_height, + .driver_data = (void *)&efifb_steamdeck_mode_fixup, + }, {}, };