From: Tvrtko Ursulin <[email protected]> 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 <[email protected]> Cc: Thomas Zimmermann <[email protected]> Cc: Ard Biesheuvel <[email protected]> Cc: Melissa Wen <[email protected]> Cc: [email protected] Tested-by: Melissa Wen <[email protected]> # v3 Reviewed-by: Thomas Zimmermann <[email protected]> --- drivers/firmware/efi/sysfb_efi.c | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c index 85f6399d5e1f..88e4fd4b0a3f 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; + + if (data->width == screen_info.lfb_width && + data->height == screen_info.lfb_height) { + swap(screen_info.lfb_width, screen_info.lfb_height); + screen_info.lfb_linelength = data->linelength; + screen_info.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, + }, {}, }; -- 2.52.0
