Archlinux Sway with a 4K display

Posted by Alex D'Andrea on 20 December 2023

I usually work with 2 different systems: a Lenovo Thinkpad Yoga Gen 3 and an Intel NUC - both run mostly identical Linux setups. While on NUC the external display is fine, yoga’s setup falls behind in certain situations: when connected via an HDMI cable the monitor only delivers 30Hz, while the NUC runs as 60Hz. This difference really matters, 30Hz just are not enough for a seamless UI feedback for user input. It feels off in a subtle way.

The display is not detected in a suitable mode:

$ swaymsg -t get_outputs
Output HDMI-A-1 'LG Electronics LG HDR 4K 0x000006C1' (focused)
  Current mode: 3840x2160 @ 30.000 Hz
  Scale factor: 2.000000
  Scale filter: nearest
  Subpixel hinting: unknown
  Transform: normal
  Max render time: off
  Adaptive sync: disabled
  Available modes:
    3840x2160 @ 30.000 Hz
    3840x2160 @ 29.970 Hz
    3840x2160 @ 25.000 Hz
    3840x2160 @ 24.000 Hz
    3840x2160 @ 23.976 Hz
    2560x1440 @ 59.951 Hz
  [...]

The same monitor with the same cable does work on the NUC. Most people seems to recommend using HDMI cables that are rated for the required throughput. Since the cable does work on the NUC, I think this is misleading.

I owned a Thinkpad 450s before that had a Mini-DisplayPort socket and when using a Mini-DisplayPort-to-DisplayPort it was able to achieve 60Hz - but only then. HDMI via the docking station did not work. The Yoga does not have this connector, but USB-C, so I cannot use the cable. Unfortunately I do not have a USB-C to DisplayPort (or HDMI?) cable at this time.

I searched a bit for users with similar problems and software stack and found https://github.com/swaywm/sway/issues/7367:

I am on an Arch Linux system and just ran a full system update. After a reboot, my external monitor now only runs with 30Hz, not with 60Hz anymore like it used to.

That report lets one suspect a software problem, and there are some mentions of it in that bug report that claim to fix the bug. In backend/drm: set “max bpc” property based on pixel format, Sway developer Simon Ser (@emersion) writes:

Since 1d581656 (“backend/drm: set “max bpc” to the max”) we set the “max bpc” property to the maximum value. The kernel driver is supposed to clamp this value depending on hardware capabilities.
All kernel drivers lower the value depending on the GPU capabilities. However, none of the drivers lower the value depending on the DP-MST link capabilities. Thus, enabling a 4k@60Hz mode can fail on some DP-MST setups due to the “max bpc” property.

The associated merge request was merged, however, it was already included in the 0.16.2 release of wlroots (that sway is using), so logically either my problem is different or this fix wasn’t the right one.

Just to be sure I installed Sway from AUR, so I had a pretty recent version - there was no improvement, unfortunately. Actually my system got worse, since now kanshi stopped working, probably because it strictly depended on an older version of wlroots that got updated when I installed the most recent sway.

Since I was going down rabbit holes, anyways, I decided to try shikane - a kanshi replacement.

Back in the days in a former job we used to make a joke about the developers that ran Linux: when they’d need to make a presentation, there were often problems with secondary displays and refresh rates and that stuff. So we joked that “they just need to recompile the kernel to connect a secondary monitor” - this one reminds me a bit of that as well :-)

At least it is holiday season and I had something to blog about.