Skip to content

HDMI modeswitch to 1080p fails on atomic path (primary plane keeps old framebuffer size) #268

Description

@robertogogoni

So I've been trying to get my LG TV (LG Electronics LG TV, serial 0x01010101) working at 1080p over HDMI for a while now. Internal laptop display is a 1366x768 AU Optronics panel (eDP-1), and the TV clearly supports 1920x1080 -- hyprctl monitors lists it right there in availableModes (yes, this output is from after I got the workaround working, so the irony of it happily showing 1080p while I'm here filing a bug about not being able to get 1080p is not lost on me):

Monitor HDMI-A-1 (ID 1):
	1920x1080@60.00000 at -1920x0
	description: LG Electronics LG TV 0x01010101
	make: LG Electronics
	model: LG TV
	physical size (mm): 1600x900
	serial: 0x01010101
	availableModes: 1360x768@60.02Hz 1920x1080@60.00Hz 1920x1080@59.94Hz 1920x1080@50.00Hz 1920x1080@30.00Hz 1920x1080@29.97Hz 1920x1080@25.00Hz 1920x1080@24.00Hz 1920x1080@23.98Hz 1152x864@59.97Hz 1280x720@60.00Hz ...

But every time I set monitor=HDMI-A-1,1920x1080@60,auto-left,1 in monitors.conf and boot, it just... doesn't switch. No error on the Hyprland side, it silently stays at 1360x768.

I ended up enabling i915 DRM debug tracing and found something pretty clear. When aquamarine sends the atomic test-commit to switch pipe B to 1920x1080, it's still attaching a framebuffer sized for the old mode:

i915: [drm:drm_atomic_set_fb_for_plane] Set [FB:190] for [PLANE:50:primary B]
i915: [drm:intel_plane_check_clipping] [PLANE:50:primary B] plane (1360x768+0+0) must cover entire CRTC (1920x1080+0+0)
i915: [drm:intel_plane_atomic_check] [PLANE:50:primary B] atomic driver check failed
i915: [drm:intel_crtc_state_dump] [PLANE:50:primary B] fb: [FB:190] 1360x768 format = XR24 little-endian (0x34325258) modifier = 0x0
i915: [drm:drm_atomic_check_only] atomic driver check for 00000000d07c1cf0 failed: -22

Basically the kernel wants the primary plane to cover the whole CRTC, sees a 1360x768 buffer trying to back a 1920x1080 mode, and rejects it. The CRTC state dump confirms the mode itself is totally fine:

requested mode: "1920x1080": 60 148500 1920 2008 2052 2200 1080 1084 1089 1125
adjusted mode: "1920x1080": 60 148500 1920 2008 2052 2200 1080 1084 1089 1125
port clock: 148500, pipe src: 1920x1080+0+0, pixel rate 148500

148.5 MHz clock, well within what Haswell can push (max 300 MHz TMDS) and what the TV sink accepts (max 150 MHz per EDID). The commit just never includes a buffer at the right size.

This isn't intermittent either. I watched it fail continuously for like 20 minutes, cycling through different framebuffer IDs (190, 195, 218, 254, 260, 266, 278, 296, 302, 310) but every single one was still 1360x768. It never allocates at the target resolution before test-committing.

Setting AQ_NO_ATOMIC=1 fixed it immediately since the legacy path doesn't do the test-commit:

aquamarine: drm: AQ_NO_ATOMIC enabled, using the legacy drm iface
aquamarine: drm: Connector HDMI-A-1 connected
aquamarine: drm: Connecting connector HDMI-A-1, CRTC ID 66
aquamarine: drm: Mode 0: 1360x768@60.02Hz  (preferred)
aquamarine: drm: Mode 1: 1920x1080@60.00Hz
aquamarine: drm: Modesetting HDMI-A-1 with 1920x1080@60.00Hz

TV is at 1080p now, been stable since.

My setup:

  • Hyprland 0.54.3 (commit 521ece46), aquamarine 0.10.0 (rebuilt from main, includes the backend: fix use-after-free of logger during teardown #244 UAF fix)
  • Kernel 6.19.11-arch1-1
  • Intel Haswell-ULT HD 4400 (i915), i7-4510U, Samsung laptop
  • eDP-1 (AU Optronics 0x22EC) at 1366x768 on pipe A, works fine
  • HDMI-A-1 (LG Electronics LG TV 0x01010101, 1600x900mm physical) on pipe B

Repro: basically any dual-monitor i915 setup where the external monitor needs a higher resolution than whatever was previously active on that CRTC. Configure it in monitors.conf, boot without AQ_NO_ATOMIC, check dmesg for plane (WxH) must cover entire CRTC.

I think this is the same underlying issue as #59, and probably what was happening in hyprwm/Hyprland#6953 and hyprwm/Hyprland#8758 too (both had atomic failures with EINVAL but no kernel traces to confirm). Happy to test patches or grab more logs if that helps.

Full logs: kernel DRM trace + Hyprland log (working boot with AQ_NO_ATOMIC)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions