Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Tvrtko Ursulin and committed by
Ard Biesheuvel
c7c7eb5e 7f2f1fd6

+47
+47
drivers/firmware/efi/sysfb_efi.c
··· 242 242 return 1; 243 243 } 244 244 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 + 245 272 /* 246 273 * Some devices have a portrait LCD but advertise a landscape resolution (and 247 274 * pitch). We simply swap width and height for these devices so that we can ··· 323 296 DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), 324 297 }, 325 298 .callback = efifb_swap_width_height, 299 + }, 300 + { 301 + /* Valve Steam Deck (Jupiter) */ 302 + .matches = { 303 + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), 304 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"), 305 + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), 306 + }, 307 + .callback = efifb_check_and_swap_width_height, 308 + .driver_data = (void *)&efifb_steamdeck_mode_fixup, 309 + }, 310 + { 311 + /* Valve Steam Deck (Galileo) */ 312 + .matches = { 313 + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), 314 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galileo"), 315 + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), 316 + }, 317 + .callback = efifb_check_and_swap_width_height, 318 + .driver_data = (void *)&efifb_steamdeck_mode_fixup, 326 319 }, 327 320 {}, 328 321 };