Skip to content

Commit c7c7eb5

Browse files
Tvrtko Ursulinardbiesheuvel
authored andcommitted
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 <tvrtko.ursulin@igalia.com> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Melissa Wen <mwen@igalia.com> Cc: linux-efi@vger.kernel.org Tested-by: Melissa Wen <mwen@igalia.com> # v3 Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> [ardb: use local var to refer to screen_info] Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent 7f2f1fd commit c7c7eb5

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

drivers/firmware/efi/sysfb_efi.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,33 @@ static int __init efifb_swap_width_height(const struct dmi_system_id *id)
242242
return 1;
243243
}
244244

245+
struct efifb_mode_fixup {
246+
unsigned int width;
247+
unsigned int height;
248+
unsigned int linelength;
249+
};
250+
251+
static int __init
252+
efifb_check_and_swap_width_height(const struct dmi_system_id *id)
253+
{
254+
const struct efifb_mode_fixup *data = id->driver_data;
255+
struct screen_info *si = &screen_info;
256+
257+
if (data->width == si->lfb_width && data->height == si->lfb_height) {
258+
swap(si->lfb_width, si->lfb_height);
259+
si->lfb_linelength = data->linelength;
260+
si->lfb_size = data->linelength * data->width;
261+
}
262+
263+
return 1;
264+
}
265+
266+
static const struct efifb_mode_fixup efifb_steamdeck_mode_fixup __initconst = {
267+
.width = 1280,
268+
.height = 800,
269+
.linelength = 3328,
270+
};
271+
245272
/*
246273
* Some devices have a portrait LCD but advertise a landscape resolution (and
247274
* 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 = {
297324
},
298325
.callback = efifb_swap_width_height,
299326
},
327+
{
328+
/* Valve Steam Deck (Jupiter) */
329+
.matches = {
330+
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"),
331+
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"),
332+
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"),
333+
},
334+
.callback = efifb_check_and_swap_width_height,
335+
.driver_data = (void *)&efifb_steamdeck_mode_fixup,
336+
},
337+
{
338+
/* Valve Steam Deck (Galileo) */
339+
.matches = {
340+
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"),
341+
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galileo"),
342+
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"),
343+
},
344+
.callback = efifb_check_and_swap_width_height,
345+
.driver_data = (void *)&efifb_steamdeck_mode_fixup,
346+
},
300347
{},
301348
};
302349

0 commit comments

Comments
 (0)