Hacker News new | past | comments | ask | show | jobs | submit login
Hacking the LG Monitor's EDID (gist.github.com)
323 points by kj800x on Aug 30, 2023 | hide | past | favorite | 142 comments



An EDID override like this would be helpful for macOS as well, where the monitors swapping around after standby is a real annoyance [0] [1]

EDID rewrites are 99% of the time blocked by the monitor firmware: https://notes.alinpanaitiu.com/Decoding-monitor-EDID-on-macO...

By the way, one helpful tool that helped me navigate the EDID dump was Kaitai Struct [2]. It shows a side by side view with the hex view and the EDID structure, and it highlights the hex values in real time as you navigate the structure. Unfortunately [3] it doesn't support the extension blocks that the author needs.

[0] https://notes.alinpanaitiu.com/Weird-monitor-bugs

[1] https://forums.macrumors.com/threads/external-displays-swapp...

[2] https://kaitai.io/

[3] https://github.com/kaitai-io/edid.ksy


I had a problem with the monitor where the EDID gets constantly erased if the HDMI cable is unplugged in certain conditions. Usually there's a service menu hidden somewhere you can enable so that the EDID EEPROM becomes writable. That doesn't seem to work in my case, so I ended up opening the monitor and hard wired the write enable pin. This happens so often (it's an old monitor I got for free) I drilled a hole and put a switch on the pin lol.


Why doesn't macOS use the ports that monitors are connected to, to determine their layout (only treating a monitor as having moved if its port's EDID doesn't match the EDID in that port from before sleeping)?


Ports are not a good monitor identifier, as they can be dynamic and seemingly non-deterministic when you start to involve hubs, docks and muxes, and having a monitor change identifier because you used USB port 1 instead of port 3 for your dock is not particularly helpful.

In the Linux world, stable identifiers are made from a combination of product name and serial number.


Almost certainly the most common use case for multiple screens on Macs at this point is notebooks connected to an external monitor, some of the time. On modern Macbooks it's mostly all just Thunderbolt ports too, which are supposed to be interchangeable, people can plug in whatever wherever without thinking about. People may also run a monitor via a TB dock, which again may plug in wherever. Though even with desktops in general, tying meatspace spatial information to port plugin fundamentally seems like a bad idea. Physical screens are much less likely to be moved then a cable, and the number of people who'd prefer to be able to treat the same type of port as functionally identical vs those who want that mental overhead seems low.


That's a poor excuse for shuffling screens that, like rather many (so not a rare bug), don't have unique serial numbers in their EDIDs, just because the user folded the laptop to sleep, and unfolded it the next day after breakfast to continue working/using.

Resolving assignments of cloned screens in the absence of physical-plugging-involving hotplug (that thus only comes from the monitor(s) also turning off when the laptop goes to sleep) by random instead of remembering physical ports/paths to them, across sometime as tame as a suspend-to-RAM, is frankly terrible UX.

Trying to use uniqueness features to be sticky across port swaps is good.... but I'd not be surprised if my grandparents would actually assume the way to swap them is by swapping the ports they are plugged into. Especially I'd expect them to be confused/surprised by swapping the plugs _not_ resulting in swapped content.


Docks with numbered ports make me want to have all things aligned. First monitor left to right needs to connect to port 1 and have number 1 in the system. I know this is not required but feels untidy if not done.


> An EDID override like this would be helpful for macOS as well, where the monitors swapping around after standby is a real annoyance [0] [1]

Are you sure this is still true? I had this problem for a very long time but it seems to have been fixed with a recent macOS update. It must have been one of the Ventura point releases.


Some people report having it fixed with 13.5.1. Some still have the problem because their monitors are missing the Alphanumeric Serial Number field.


I recently went down this rabbit hole and assumed the duplicated serial number in the EDID was playing a role in triggering it but even after switching to different monitors later on MacOS would still do this all the time. Just recently I moved my keyboard and mouse to the primary display that's connected over USB C and so far the problem has not reoccurred. No idea if having them on the secondary display was triggering the bug or if moving to the primary is just a way to mitigate it but FWIW, unless I've hit a string of good luck, it seems that for displays that also have USB combined MacOS takes the HIDs connected into account when deciding to flip your displays around every two seconds.


Apparently there are $5-15 EDID "emulator" devices that are just an HDMI passthrough adapter with a fake EDID ROM that always reports common modes as 4K60/2K60/VGA. Apparent purpose is to get PS5 to work with quirky 4K TVs. A similar device called HDMI "dummy plug" allows GPU acceleration on quirky PCs without having a display, but the latter has no passthrough port at the back.

If that's all the author needs, that might be the path of least resistance.


My favorite use case is Looking Glass.

Want to play video games that only run in Windows, but don't want to leave Linux? You can run Windows in a virtual machine and "passthrough" your GPU's PCIe slot. The advantage is that Windows can get the full performance of your GPU. The disadvantage is that it took the whole GPU away from your Linux host, along with whatever display it's attached to. You can use a second GPU for your Linux host (i.e. your integrated CPU one), but that needs its own physical display.

You can use Looking Glass to copy the framebuffer from your Windows guest so that you can redraw it on your Linux host. That way you can have your Windows guest in a window, and never have to leave your Linux desktop again. The big caveat is that your Windows guest needs a valid display connected, or it will never draw any frames to begin with. You can plug in a spare monitor that you never actually look at, or you can spoof one.


I'll add that this setup works great, ran it for a good couple of years before finally dropping it (not for any looking glass reasons, eventually just didn't need it anymore with proton).

Also loved that it integrated so well into OBS directly to stream from!


Wow this is so cool… might have to try it!! The real hacker news is in the comments!


So this is what those non-pass through "displayport edid emulators" are for!


Can you commit that to the looking glass readme.md - having skimmed their GitHub, it was unclear what it actually did.

Out of curiosity, what is the performance like? Presumably good for desktop use, but how about fps sensitive games?


Latency is like a couple milliseconds i believe. Looking glass uses shared memory between the host and guest for the framebuffer.


I'd expect vsync-to-host to be the default, though something more like triple buffering should also work (with the host atomically grabbing the latest completed buffer to compose just-in-time for composing to finish before the RAMDAC starts the first line... so roughly grabbing at the start of blank, spending vblank compositing, and no tearing after vblank).

So in total, on the order of a millisecond additional latency if you pass vsync timing alignment down, and no variable refresh rate.

But the latter is barely compatible with compositing in general. All techniques for handling a VFR video stream in a window should also apply to the uncompressed/shared memory looking glass stream.


It's pretty cool, of course the need for this kind of setup has become pretty rare as proton runs pretty much everything nowadays (apart from those pesky anti-cheat games).


Genuine question, but are multiple inputs on the monitor not a consideration for your scenario? Or are multiple inputs on a single monitor unsuitable for this purpose?


Multiple inputs works fine with gpu pass through, but regularly switching monitor inputs is honestly a pain depending on your monitor. Its like a 10 second process for my monitor.

Also people running a setup like this are using the Linux host as their main desktop. If you only have one monitor and are switching inputs you lose your whole workflow on Linux host when using the vm. It’s better with dual monitors but I’d still prefer looking glass.


The switching process can be disrupting depending on how it works, I agree. But even so far as to include grabbing a spare monitor "you never actually look at" or spoofing one? For that, I admit I can't see why just using one of the inputs on the monitor you already have isn't an option.

Unless of course the monitor doesn't have additional inputs (but it was never specified the hypothetical monitor is ancient) or they are all already used (again wasn't specified).


For Looking Glass, probably not: the guest OS will probably notice the monitor switching away from its connected input, and will stop drawing frames accordingly.


These devices are also used among home theater enthusiasts as a hack to enable LLDV (Low Latency Dolby Vision) which causes the source device to perform tone mapping.

http://videoprocessor.org/lldv

https://www.avsforum.com/threads/alternative-devices-for-ena...

https://blog.semtech.com/demystifying-dolby-vision-for-pro-a...


The added benefit is you don't get a chance to brick your TV with a bad write.


No need to write to eeprom. On Linux, just load your custom EDID.

I returned OP's model display for a similar reason - except there was no HDR possible on Windows, even with the LG custom drivers. I also can't unsee the parallax on those models. It's pretty atrocious for the price.


Yeah, we still have loads of "EDID minders" left over from the RGB/VGA days. Little in-line boxes with DIP switches to set a given resolution and refresh so display hardware always reported the same spec to any laptop/desktop/device plugged in.

Not surprised there are similar for HDMI.


Indeed they are for Hdmi. I even saw some claiming to support hdmi 2.0 (4k @60Hz), but I have never seen one for Hdmi 2.1.

Unfortunately despite huge progress with resolutions, refresh rates and ability to use one cable for lots of stuff (usb-c) we went significantly backwards in KVMs. If all your devices speak hdmi 2.1 there are one or two 4way devices that claim 8K-hdmi 2.1 (made by easycoo?), but if you have usb-c or newer displayport devices that don't support passive hdmi dongles your out of luck.

As far as I know there is one device on the market (made by delock) that claims to support DP1.4 (4k@60hz),but it has no edid emulation and there are no pass through edid emulators for displayport 1.4... So every time you switch kvm your displays will act as if they're disconnected/reconnected. If you do actual work on two pcs and you switch a lot that's horrible.

So the tldr is: great modes, but why did nobody think of the kvm users when making those standards (by for example making monitor hot plug detect being able to be disabled from monitor menu?).


1. This is impressive debugging work by the author. No individual step is rocket science - especially when the story is the success path and not the forking paths of possible failures - but they kept their eyes on the prize and figured it out.

2. This reminds me why I no longer use linux on the desktop


> 2. This reminds me why I no longer use linux on the desktop

Lest anyone read this and nodded along: This was a defect in the LG monitor the OP worked around, not anything to do with Linux.


This is mostly true* and beyond irrelevant to the point GP was making (that they no longer use Linux on the desktop because of annoyances like this).

From the original article "It works great on both Mac and Windows, but on Linux it displays just a black panel" and, amusingly, after the fix: "One issue is that now my second monitor isn't displaying anything. When I go into Display Settings, it seems like my computer thinks that both monitors are sending this EDID so it's put the second monitor into the wrong mode."

Seems like 2023 isn't the Year of the Linux Desktop either.

* I say "mostly" because to 99+% of the people, telling them "this monitor works great on both Mac and Windows and shows nothing but a black screen on Linux, but don't worry; it has nothing to do with Linux" will get you some pretty quizzical looks.


If you tell Linux to replace the EDID firmware with a custom binary, without telling it which output to override, I'm not surprised Linux acts the way it does. I can confirm on my machine that overriding EDID for a specific connector works as expected. https://wiki.archlinux.org/title/kernel_mode_setting#Forcing... says that you can do it for multiple connectors using commas to separate values, though I have not tried. Though one gotcha is that on my RX 570, `ls -ld /sys/class/drm/*/edid` prints HDMI-A-1 and -2, which is also the name of the display outputs on Wayland, but on X11 xrandr identifies these outputs as HDMI-1 and HDMI-2. (I think you have to use HDMI-A-1 in the kernel command line, but I have not tried.)


Yep, as much as we want hardware and software to be conformant to whatever standards exist, in practice an important part of the job of a production OS is to work around the myriad quirks of hw/sw users will likely encounter. Standards are the input, experience is the output, and users judge on output. Related is yesterday's post about ensuring DOS app compatibility in Win95 [1]

[1]: https://news.ycombinator.com/item?id=37311508


Linux contains lots of code to work around a myriad of EDID quirks (and loads of other HW quirks), too:

https://github.com/torvalds/linux/blob/master/drivers/gpu/dr...

There certainly isn't any big philosophical point to make here, Linux doesn't take a hard stance of expecting correct HW.

Ultimately this is a symptom of (1) bugs happen (here, at LG) and (2) Linux has a lower market share and therefore sees less testing. It's certainly fine to say "then I will use Windows to run into statistically fewer problems", so long as you're aware the same argument applies to any entrenched incumbent. As mentioned earlier, it'd have applied to MSIE in 2005 as well.


> As mentioned earlier, it'd have applied to MSIE in 2005 as well.

What's funny is, I was around in 2005 and had already adopted Firefox well before it was called Firefox. (I was also around for the release of IE 4, and spent half a day downloading it on our 56k modem on release day! Exciting times.)

That's because the web is what I work on, and I am OK taking on buggy/beta stuff in the web domain because I learn useful things.

In the OS space, I was a linux user for a decade before I realized that I was wasting tremendous amounts of time and energy debugging stuff very like this monitor issue, and getting no transferable benefit out of it.

I switched to mac at the time, and have experienced vastly less of this sort of configuration nightmare since.

I love linux and I root for it, and occasionally I still try to switch again, before I end up having to figure out this sort of issue that just empirically doesn't exist on my mac, then I get sad and switch back.


I think that's fine and a respectable choice. I think it's even OK to argue that Windows has a value prop as a paid product because MS spends more effort on HW-specific quirks handling, or arguments along those lines.

Still, I think it does matter what's technically going on and where the fault lies. I also think that just like browser diversity, OS diversity is a net positive for the enforcement of good standards that makes things work better for users overall.

For example, I'm willing to bet (and it's because I know cases of it :-) that many PC peripherals work better on Macs because Linux existing has made HW-manufacturers more standards-conscious than a Windows-only world would have, especially since so many HW/embedded engineers run it.

> I was wasting tremendous amounts of time and energy debugging stuff very like this monitor issue, and getting no transferable benefit out of it

You got me there - in my case it lead to a career of making cars, phones, game consoles and other stuff running Linux, so I guess the over-under on the direct utility shakes out a bit differently here :-)

That said, it's been a very long time since I've done any fiddling/debugging to make any HW work privately. Ironically, I've had a lot more issues making HW work correctly on the M1 Mac I also have, e.g. my (quirky) Bluetooth earbuds work a lot better on PipeWire than macOS ...


Linux* actually does have a tendency towards more hardline stances, simply because it's not answerable to market forces in quite the same way. For example, say 0.5% of monitors out there have dodgy edid values like this. For a commercial OS, that's a lot of unhappy people, many of whom have social media accounts, so "When displaying a new resolution, always start at max(60Hz, lowest available refresh rate) so if something's wrong people can at least see what's going on" might be a good rule of thumb for a commercial OS.

For Linux, however, the equivalent might be "report the bug so an exception can be made for this specific monitor". In other words, it's less important that everybody be immediately happy, as long as bugs can be reported and eventually fixed.

* Shorthand for any OSS kernel and its associated ecosystem


I’ve seen many more monitor compatibility issues under MacOS than Linux, and have plenty of older hardware that works with reverse engineered Linux drivers, but no longer works with Windows.

I think the common case is that vendors test with the current version of Windows, MacOS and/or Linux (in decreasing priority order), then hope that it the hardware is EOL’ed before the drivers bit rot.


This reminds me of a recent complaint about some software which didn't work properly with a certain sync service, and the developer response was that the third-party service was buggy so it wasn't their problem.

Ok, but personally quite a lot of my job involves working around the bugs and quirks of old unmaintained Windows OSes. The customer rightly doesn't care, they just want your software to work. It is almost always possible to at least mitigate the problems of whatever buggy garbage hardware/software you have to deal with.


It would be nice to figure out why Windows and MacOS evidently didn't have the problem. If there's some additional probing that they're doing to catch the monitor out on its lies, Linux could do that too.


Good question indeed.

One thing I could imagine is that Linux is giving preference to using the values in the DisplayID block as it's the newer standard, and since EDID/DisplayID compliance has improved over time the logic may be "the newer one is more likely to be correct". In the meantime perhaps Win/Mac continue to look at the classic EDID data, and if they do, it likely gets less test coverage from manufacturers.

Pure speculation.

Edit: From https://learn.microsoft.com/en-us/windows-hardware/design/co...

> Windows does not support DisplayID 1.x blocks, and always ignores them.

No explanation is given.

The LG display sends a DisplayID 1.2 block.


That's odd, I was definitely able to add a DisplayID 1.3 extension block (128 extra bytes appended) to a CRT monitor's 128-byte EDID data using CRU, then have Windows 11 see those extra resolutions (when the CRT was plugged into a DP-to-VGA adapter). Though I ended up switching to CTA-861 (HDMI extension blocks) with all the HDMI YCbCr/audio nonsense turned off, because 010Editor and edid2json could understand CTA-861 but not DisplayID (though I learned from this article that git://linuxtv.org/edid-decode.git, or https://git.linuxtv.org/edid-decode.git, has better support for EDID standards than the other tools).

Another oddity is that when I run edid-decode on the DisplayID 1.3 file created by CRU, edid-decode reports the block as "Version: 1.2" instead. Wonder what's up with that.


If that's also true of MacOS, that would mean LG made the effort of adding extra data that their tested systems didn't actually use and then got it wrong anyway, which would be funny.


Random anecdote:

I work in the automotive industry, where we often use fancy unusual screen hardware a couple of years before it turns up in home consumer electronics or phones. For example special multi-axis curved stuff, dynamic angular privacy filters, or haptic feedback using electrostatic modulation of resistance instead of vibration motors (that allows you to make the screen feel rough and scaly or glidy, give UI elements a feel-able shape, etc.).

One time, we were told to use earplugs at work for a few days, because of a pre-release firmware bug that could in theory, if other safety mechanisms also failed, cause the haptics to potentially emit an ear-piercing low-frequency tone ...

Temporary EDID bugs, otoh, I've seen so many times. :)


> One time, we were told to use earplugs at work for a few days, because of a pre-release firmware bug that could in theory, if other safety mechanisms also failed, cause the haptics to potentially emit an ear-piercing low-frequency tone ...

Wow, on-demand tinnitus is one hell of a failure mode.


What I imagine is that the engineers assigned to it started off from an EDID from some other display they have, made changes to it, tested on Mac and Windows, never tested on Linux.


Mere speculation on my part, since I have no familiarity with the HDMI or DisplayPort protocols:

1. Windows/macOS might have a "quirks table" that hardcodes fixes for spec-violating devices.

2. Windows/macOS might ignore some reported EDID values and derive their own when they determine that the display behaves differently from what is reported (e.g. by recording response packet timings).


> (e.g. by recording response packet timings)

Even modern packetized display interfaces like DisplayPort are still fundamentally a one-way firehose for the pixel data. There's no provision for acknowledging or retransmitting data packets, and forward error correction is optional. The bidirectional sideband channels used for stuff like EDID are not timing-sensitive like the pixel data stream.


It could be the failure mode is identifiable on the OS and Linux didn't add detection and fallback support.

Honestly though it could also be workarounds. Windows is king at making stuff like this work by hard coding overrides. E.g. a custom driver for this display.


A defect that was not in evidence for MacOs or Windows.


I ran into the same problem as TFA in 2017 with an AOC g2460pf monitor. The display port would advertise binary garbage for the EDID that wouldn't checksum, so no OS would try and use it. AOC registered some "drivers" with Windows, so it would automatically download and apply a patch that would make that port usable, but they also included a CD with the stuff on it.

However they patched this on the Windows side was quite fragile, because it kept breaking after OS updates. After I could no longer get it working with the reinstall and pray method, I switched to Linux because of this issue. I fixed it once with an EDID in the initramfs, and haven't had any issues for the last 6 years.


You could try applying the same EDID patch using CRU on Windows, at least if Windows recognizes the monitor in the first place.


Sure, but this is exactly equivalent to saying "This is why I stopped using Firefox for web browsing" in 2005 and sticking to MSIE 4/5 and its take on standards, because the websites always work.

Reasonable and practical, but which direction did get us more progress for the web?

EDID exists for a reason and is a good thing; monitors providing reliable, useful EDID data is something to strive for.

It's gotten a lot better over the years as the result of operating systems using and enforcing it more. Monitors with bogus/garbage EDID used to be a lot more common 10+ years ago.


It's not at all hard to find EDID bugs that affect Windows and macOS, especially where variable refresh rate or HDR or 10-bit color or DSC are involved. And in those situations, working around the monitor bug tends to be just as hard (Windows) or impossible (Mac).


Indeed my Dell is treated with some absurd sharpen filters because EDID says its a TV and macOS wants to "help". IIRC, there was a similar story posted to HN about it, involving debugging EDID and applying an override


Basically, they tested it on these 2 and then shipped it. If it would fail on win or osx, LG would not ship it.

At first, this seems a reason not to use Linux, but a future upgrade of win/osx will break your hardware. Tons of hardware gets obsoleted this way. Meanwhile, Linux will just keep on working.


> Basically, they tested it on these 2 and then shipped it. If it would fail on win or osx, LG would not ship it.

Yep. I first and foremost look fir Linux support explicitly called out in the system requirements. If I can't find it, I look for reviews mentioning Linux.

But explicitly supported is always the best, ideally backed by reviews that confirm it.


Light googling reveals examples of Windows and MacOS users experiencing issues with LG ULTRAGEAR monitors too.


We don't know that though. The fact that it presumably works everywhere except Linux makes me think there's still a bug in that `edid-decode` path.

And as far as I can tell from the article, OP just assumed the display supported 60hz because it happened to show an image when they set it to that.


I don’t think that’s actually correct either. The monitor is advertising Freesync/GSync variable refresh rate. The Ultragear monitors are high end gaming monitors so they come with 48-240Hz VRR on some monitors. That’s the 48-144hz extension in the EDID of this monitor.

Based on debugging some issues I was having in macOS, I discovered from various Reddit and forums that Linux doesn’t handle that well depending on your driver stack/how you connect. If you’re on very modern hardware, kernels, and the OEM drivers it’s a better situation. macOS also has partially broken support for Freesync (or ProMotion as Apple brands it) at the moment on Intel machines.

I have an Asus GSync monitor with 48-144hz compatibility. This works over DisplayPort on my M2 Pro MacBook. On my RX6800 equipped Intel Mac I get 100Hz over DisplayPort 1.4 and 120Hz over HDMI 2.0 due to a DSC bug affecting Intel Macs. Even without that bug, 120Hz sometimes presents the OP’s issues between startup and login so I use 100Hz. The betas for the next macOS apparently fix this.

Either way, it’s a fun patch


Huh. This reminds me of why the world so needs Linux. That they could just take off the shelf tools & plug around for a bit, learning & understanding a complex situation with crude & fast debugging, knowing only a little of the internals, and in the end improve their own situation clearly. And then they could share that knowledge with others in such a clear manner.

Nothing else in computing is like this. We just cannot help ourselves & each other in most realms of computing: we must be content with what we are given, as it is.

In almost all probability the linux system either doesn't have a GPU capable of running this high pixel clock or the cable/connector can't handle it. I'd love to know what the Mac & windows machines do; do they run 60Hz too or are they pushing all 144Hz here successfully? This seems very likely to be a cable issue, one I don't expect windows nor Mac deal with particularly excellently.


I have experienced pixel clock errors on Linux, but can't say in this case if the monitor, cable, or GPU is unable to handle full resolution at 144hz. The CTA-861 (HDMI metadata) block contains a mode "3440x1440 99.990 Hz", or 1440p100 with a pixel clock of 543.5 MHz. I don't know if this 100hz mode functions on Windows or not. The DIsplayID block instead contains a 144hz mode with a pixel clock of 799.750 MHz. Both of these modes may be within DisplayPort bandwidth limits or not, depending on the link rate and bits per pixel (this EDID says "Bits per primary color channel: 10"), and may also be supported by the display or not.

I do know that Linux X11 (amdgpu kernel driver, modesetting X11 driver) tends to drive my DVI 1080p display with too high of a pixel clock (too large blanking intervals) when connected over a HDMI-to-DVI cable from my GPU. I believe this is because there's actually a duplication of mode selection logic between the amdgpu kernel driver and X11. I've reported another (system hang) amdgpu/X11 resolution bug at https://gitlab.freedesktop.org/xorg/driver/xf86-video-amdgpu... with no progress towards being resolved so far. Neither bug appears on Wayland, but mainstream Wayland desktop environments (KDE/GNOME) do not allow adding custom resolutions through xrandr without overriding EDID files and either rebooting for the kernel to see it, or touching files in /proc/ (untested).


Not sure about Mac, but you can do the same on Windows. It's a bit different world and sometimes overly complicated, but works. https://learn.microsoft.com/en-us/windows-hardware/drivers/d...


Funny... I am trying to learn how to patch my own debian stable kernel with an (incomplete) kernel patch submitted for adjusting the backlight on an Apple Studio Display. The monitor - to my surprise - works really great with my Debian 12 workstation via a displayport->usb-c converter cable. But (in typical Apple fashion) there is not a single button on the display to adjust brightness and the kernel doesn't support this monitor.

The patch is quite simple: https://lore.kernel.org/lkml/20230701120806.11812-1-julius@z...

But I haven't been able to make the time to sit down and 1. respond to the feedback (original author hasn't yet) and 2. try and apply it to the otherwise standard Debian kernel.

Aside from this issue linux on the desktop has been quite pleasant, and of course this issue is not the fault of Linux per say. Deb12/KDE/Wayland/AMDGPU


> and the kernel doesn't support this monitor

I find it so immensely "WTF!?" that a kernel needs to know about a monitor, to change its brightness.


The kernel doesn't necessarily need to know about every monitor specifically, there's lots of standards that divide this space into broad categories. But some hardware does custom things that need individual drivers, e.g. use the USB channels to announce a custom device with its own proprietary protocol.

Sometimes this may be intentional design to lower compatibility and cause these problems intentionally, but often it is just bad engineering, not malice.


    > The Apple Studio Display does not have any physical buttons and the only
    > way to get or set the brightness is by sending USB control transfers to a
    > HID device exposed by the display.


It's hardware, and usually userspace can't talk directly to hardware.


Sounds like an abstraction is appropriate. We could call it a "device driver". Is there a reason so many things get baked into the kernel, rather than using, say, kernel modules?


Pretty sure this is what DDC is supposed to solve. https://en.wikipedia.org/wiki/Display_Data_Channel which is why this EDID post reminded me of this problem.

Problem is, regular DDC utils don't know how to communicate with this particular display.

Joke is on me, I shouldn't have spent $1,500 on a display that is pretty much exclusively designed to be connected to a Mac. But I was using it with a Mac for a while before building this new Linux box.


Relatively few things need to actually be baked into the kernel. Most features in the kernel codebase can be built as a module at will, especially drivers.

But it's the codebase that you patch, so "patching the kernel" doesn't mean the OP ruled out building it as a module in the end. Even though they may well be able to just build it against kernel headers and even load it at runtime.


The latest version of that patch is here: https://lore.kernel.org/lkml/20230820094118.20521-2-julius@z...

Also it should be trivial to run this as an out-of-tree module until it's merged. With DKMS or put hid_bl.c into an empty directory and add the following makefile:

``` ifneq ($(KERNELRELEASE),) # kbuild part of makefile obj-m := hid_bl.o

else # normal makefile KDIR ?= /lib/modules/`uname -r`/build

modules:

%: $(MAKE) -C $(KDIR) M=$$PWD $@

endif ```


this is really helpful - thanks!


>original author hasn't yet

Julius has responded to comments as recently as a week ago and is now working on a (hopefully mergable) v4.

You will probably see it in 6.7 and probably backported to stable kernels in a few months.

It will support any monitor which uses this USB control scheme (presumably a few other apple monitors).

So don't worry about making the time to address the comments. The author seems to be on top of it. Two to three months for a medium sized driver patch (such as this) to be merged seems about right to me.


ah nice - i hadn't seen any additional activity so was gonna try and run with it on my own but thanks for the info


If you’re on a Mac and using a Dell monitor (I know it does it for the Dell Ultrasharp, not sure if it’s for all Dells), check your monitor settings to see if the computer is actually sending RGB to the monitor. Chances are, even over HDMI, it’s using YPbPr. Every mac I’ve ever used (20 or more over the past 10 years), and every Dell monitor (at least 5), the mac is sending the the display signal as YPbPr instead of RGB. Just Google, “Macos Dell YPbPr” and you can find complaints going back 10+ years.

I get a lot of computers to use for a brief period of time (consultant), and fixing that on Macbooks every couple months is non-trivial. Sometimes it’s impossible if it’s an older version of MacOS because older versions required overriding system files and booting into single-user mode.


This debuging and hacking kind of remind me of Windows, and dealing with various versions of drivers, service packs, and so on.

Normal sane Linux user would just force resolution into bootloader, and create global xorg.conf. There are like 10 far easier ways to solve this problem.


Point is - I don't want to do any of this on my personal computer after work. I just want to plug a monitor in and... It works. Don't care why, don't care if windows/Mac has some quirks table. I debug enough stuff at work.


Well… this monitor and its EDID are actually correct.

The monitor supports 3440x1440 @ 144hz and in the EDID it’s setting that mode as preferred. I checked online and LG market the monitor with those specs, so it’s not an error.

It would probably have been easier to flip the bit in the EDID that says the 60hz rate is preferred rather than messing about with the timings - since there is a perfectly good 60hz timing in the EDID.

To me (without any other evidence presented or investigation on my part) this is more an issue with the graphics card driver on Linux than an issue with LG.


It's the same reason I have to patch the Radeon drivers on Linux. They just pick the highest mode available without regards whether it will work at all. E.g. if the EDID shows the monitor supports 10bpc, they will pick it even if there's not enough bandwidth to suppport it (e.g. bad cable or already daisy chaning something else), resulting in an empty screen.

They will also pick 10bpc even if it results in power consumption increasing by 30W (hello stupid AMD GPUs idle power consumption heuristics).

I have the impression (untested) that Windows seem to be less excited to select modes outside of the common ones, even if they are advertised in the EDID.


I agree, from memory windows will prefer a 60hz rate at the highest resolution until the user (or “monitor .inf file) overrides it.

I kind of feel MacaOS does the same - indeed a quick test shows my monitor at 60hz even though there is a free sync range from 40-90 in the refresh rate. But of course this is a weird situation since it’s a free sync thing too, so I couldn’t apply it to everything.

So on that note, I go back to my original theory that it’s the graphics driver (or xrand or one of those x-things) screwing the timings up.


I have this monochrome hi-res LCD with an HDMI controller for some lithography project.

The EDID advertises YCBR colors. But in reality it only accepts RGB.

The amdgpu driver in my AMD laptop is the only machine I own that actually sends YCBR, and I had to add an EDID override for it. It's a pain to do. It's confusing. And then the HDMI port is now only capable this specific screen.

Thankfully the amdgpu driver has now be fitted with few knobs allowing you to override some of the settings at runtime.


> The monitor supports 3440x1440 @ 144hz and in the EDID it’s setting that mode as preferred. I checked online and LG market the monitor with those specs, so it’s not an error.

… so did I. There's several models all under the same "brand" name, or whatever hardware manufacturers call the idiocy of sell 8 products under the same name.

Some of them have max refresh rates of 120 Hz. Some can do higher. But the OP never states (unless I am missing it) what model monitor he has.

(There is a model number in the EDID dump but it doesn't seem to correspond in format to LG's model numbers…)


my guess is the connection they used has insufficient bandwidth / spec version and this could have all been avoided.


That part confused me too. I think I have the same ultra wide monitor and it indeed runs 144 on windows. The article ever explained why it is "unsupported" under Linux


Couldn’t this just be that the software isn’t capable of handling the maximum setting since the graphics card drivers aren’t loaded yet? And of course windows and macOS boot up with more conservative display settings knowing this? Essentially the other OSes are doing just what you’re describing.


This makes more sense to me. LG screens tend to have proper modes set and is one reason I recently purchased an LG Ultragear a couple of weeks ago.


Agreed I've never had a problem with LG monitors. Samsung, on the other hand, have been a grab bag of razors and needles.

I even went as far as to buy one of those "weird" [0] LG screens that have 4096 horizontal resolution all the timings and such worked perfectly.

[0] https://www.lg.com/us/business/download/resources/BT00001837...


I'm wondering if the real issue is the user doesn't have a DisplayPort 1.4 supporting cable or equipment. The speeds, color (10bit) and the resolution suggest to me that could be the real problem. I doubt the monitor would intentionally ship with such out of spec edid, especially since the monitor claims support from 48Hz to 144hz, likely for variable refresh rate.


I was wondering that, too. I couldn't find the actual model of the monitor anywhere on the page. But LG has several monitors in its UltraGear line that do 3440x1440 at 144Hz: https://www.lg.com/us/gaming-monitors Presumably he's got one of them?

In that case it's not so much the EDID that's wrong but something else in his setup that won't work with those capabilities, and either Windows and Apple just don't default to maxing out the refresh rate, or they do but are able to detect that it's the wrong cable. Or it's a graphics driver issue?


Thought exactly the same.

I wouldn't be surprised if MacOS and Windows simply default to 60Hz unless manually selected otherwise, just to reduce customer service tickets.

Debugging this issue on linux is maybe an exciting journey, debugging it over the phone with a end-user who only has one cable and one monitor is just a PITA.


I'd consider it a Linux bug if the kernel drivers don't transparently hide high color depths and refresh rates that aren't supported by the display/cable/GPU's maximum supported DP data rate.


DisplayPort cables don't have identification chips inside them. The only way for the machine to know if the cable is capable of running at DP1.4 speed is to try to bring up the link at that speed. The software does correctly hide modes that the endpoints say they cannot support, though that won't help when one endpoint lies.


I saw this was noted online as a potential issue so I did try two different cables first and neither of them worked. It's completely possible that neither of those cables were up to spec either, so I've ordered one that is VESA Certified to support DisplayPort 1.4 and I'll have to check and see if they work without the hack when they come in. I'm on my Mac now and it just lists 85 and 50 Hz in the display settings which seems odd.


LG's firmwares are pretty bad in my experience. I have two LG monitors and they both have weird quirks.

On the first one (a 34" ultrawide), all of its inputs lose connection for a moment whenever it wakes from standby (including the USB ports, making them useless for external drives). This also has the effect of causing my computer to occasionally lock up on resume from hibernation unless I tap the power button on the monitor before I wake the system. Additionally, at refresh rates above 60Hz the gamma gets progressively lower making the image darker the higher you go, even though the gamma setting in its menu is exactly the same, and black frame insertion and game mode are both off. Others online have reported the same thing.

The other monitor I got second-hand and it mostly works. It has a horrid HDR implemenation however that just washes out everything. I also tried to use brightness and input control via DDC/CI, which is a fairly well known standard, but this causes it to shut off abruptly and I have to unplug the power cord it to get it back.


> This also has the effect of causing my computer to occasionally lock up on resume from hibernation unless I tap the power button on the monitor before I wake the system.

Wow you just off-handedly resolved an issue I’ve been dealing with for months on my Linux desktop. I lost an hour of Baldur’s Gate progress the other night after this happened after I hadn’t saved the game. Thank you!

Your fix also resolves a similar issue I have on the Mac side when using my work laptop. If I tap the keyboard to resume from sleep, my LG monitor wakes up but doesn’t display an image. I have to wait for it to go through the motions until it finally displays “no input” before tapping on my keyboard to make it display the lock screen. Meanwhile, my second monitor works from the get go.

I somehow never thought to hit the power button first. I wish there were a way to make the LG monitor work like my other one and not have to do that.


> Wow you just off-handedly resolved an issue I’ve been dealing with for months

Awesome! Glad I could help.

> I wish there were a way to make the LG monitor work like my other one and not have to do that

Yeah unfortunately that would be on LG to release a firmware update. And from what I can tell, they'd rather you just buy the new revised model.


I was expecting a tale of how the author managed to overwrite whatever part of the monitor's firmware was responsible for spitting out the EDID. While interesting, the title is a bit misleading: it's an ugly but effective hack to inject a custom EDID.


I wouldn't really call it "an ugly hack" since the kernel has had this procedure (to load EDID overrides from /lib/firmware) since forever. Introduced in 2012 by https://github.com/torvalds/linux/commit/da0df92b57311aa1b26... , current doc is in https://github.com/torvalds/linux/blob/872459663c52f5e8a28c0...


Haha, I'm happy to agree to disagree here. In my book doing hex editing on a binary file and overriding what my system thinks the monitor is reporting to ultimately solve the problem feels enough like a hack (http://catb.org/jargon/html/meaning-of-hack.html).

As someone else noted, I'm considering overwriting the EEPROM in the monitor but I'd like to be 100% certain that's correct before I try it (one of the reasons I posted to HN was to see if folks thought I was going down the wrong path). I'm actually going to try a completely new cable first in case it's a bandwidth issue.


In the last paragraph: "One last thing I might consider doing at some point would be to try to overwrite the EDID on the monitor itself."


And the author downloaded the monitor's edid & bitwrenched it around to make their hack.

I definitely had the same expectation, & was most way through reading, expecting my expectation wasnt going to be mentioned, but I was far from upset. I was quite happy to hear there's kernel workarounds for exactly this kind of thing.

The main shortcoming I feel right now is that this only works if you only have one specific monitor you want to hack, or you are ok rebooting. If the kernel had some way to dynamically override the edid that would be excellent. Maybe a eBPF filter?


On some monitors (more typically the older ones), the EDID is just stored in an I2C EEPROM. So it may be possible to just re-program it. I don't know what they do on newer monitors, it could just be something listening to the I2C in the HDMI connector and pretending to be an EEPROM.


I have two identical ASUS 1920x1200 monitors. The EDID on one of them got corrupted.

Dumped the EDID from the other monitor, put in a file in /usr/lib/firmware/edid, and added this to the grub command:

   drm.edid_firmware=DVI-D-2:edid/asus-1920x1200.bin
DVI-D-2 is the moniker for the broken monitor.

Long Live Linux!


Related, I have to use BetterDisplay to force a custom EDID since my xiaomi gaming monitor goes into YCbCr colour space and blacks become gray when connected to macOS. (Ironically the fix I was using before finding out about EDID patching and the cause of the problem, which I thought was bad calibration on my end, was to switch input source back and forth which somehow fixed the issue until the monitor was shut down)


I have similar issue on Dell S2722QC - when macOS picks YCbCr instead of RGB, the display is flickering (every other frame is dark). Both Windows and Linux always pick RGB, but macOS seems to pick at random. Very annoying, but technically the manufacturer only promises that the monitor works with Windows. I just unplug and replug monitor until it works, but will try BetterDisplay, thanks.


I too use betterdisplay on macOS after something in an OS update made my laptop decide that my second monitor can only support 30Hz instead of 144.


Sounds exactly like the things that made me switch from Linux to MacOS 13 years ago. There's value in things just working and not having to learn about how my hardware actually works. Learned a lot though!


This has nothing to do with "Linux". The monitor is exposing a bad ID in its configuration block. Monitor says "I support 140Hz at 4k", so Linux (strictly the kernel framebuffer driver in use) says "OK then, that's the best one, give me that". And it doesn't work, because the Monitor lied.

And the reason it works on Windows or (sometimes) MacOS is just that those systems have arbitrarily different default choices (e.g. "see if it has 60 Hz and use that"). And it happens to work with Windows because the monitor manufacturer bothered to test with windows (and, sometimes, MacOS), where they didn't with Linux.

This happens everywhere in the tech industry. No one does QA to the standards. It's 100% routine to see devices with PCI capabilities advertised that don't work, to see phantom ACPI entries for hardware that doesn't exist, to see EFI BIOSes exposing function tables for capabilities that never worked and weren't tested, USB devices which advertise a standard class but which only work with a proprietary driver, etc...

And the only reason anything works anywhere is that, at the end of the day, they plug it in and test. And on Linux they don't.


OP is using an LG Ultragear gaming monitor which support the preferred resolution reported in the EDID "3440x1440 143.923 Hz", so this definitely has something to do with linux doing something different than windows/macos.


We don't know that. OP never states what monitor he has, and "LG Ultragear" isn't a model. There's a range of models under that moniker, and if you look at LG's website, the max refresh tops out at 240Hz on some of them … and at 120 Hz on others.


I completely agree with you in principle. It's rarely an actual fault of anything in Linux. However the outside effect to me as a user is that I need to debug my monitor's EDID to get it to work correctly. Inconveniently for me (as much as I love digging into things like that) I really want to just plug in a conference room projector into my laptop and have other people already put in place out those workarounds for me sometimes.


> I really want to just plug in a conference room projector into my laptop and have other people already put in place out those workarounds for me sometimes.

Then you should definitely use Linux more, and buy hardware that explicitly supports Linux.


Ever had use hardware that you didn't buy yourself? I don't have a choice to select Linux friendly projectors at conferences. I still wanted to have the same experience of just plugging a cable into my computer and everything working as MacOS users have.


> Ever had use hardware that you didn't buy yourself?

Yes, of course. The point wasn't that I would buy a device for my own use (though that is kind of appealing these days), but rather that your choices influence what the market provides.

If you want display devices to support Linux, you need to preferentially buy devices that explicitly support Linux, and make that fact known to vendors as well as you can.


Funnily enough, stuff not working on my m1 over the past year or so is precisely why I stick with Ubuntu on my thinkpad for all of my tasks except the ones that require macos! I don't think I've ever needed to debug any of my thinkpads with integrated gpus.


FYI, if anyone is interested in "hacking" their EDID but doesn't want to go to these lengths, I've had success using a combination of BetterDisplay [1] and AW EDID Editor [2]. See this discussion for some tips on how to use it [3]. Obviously with BetterDisplay this solution is specific to MacOS, but it works, and you don't have to dive into hex code.

You can use it to force RGB mode, force 4K60hz, etc.

[1] https://github.com/waydabber/BetterDisplay

[2] https://www.analogway.com/emea/products/software-tools/aw-ed...

[3] https://github.com/waydabber/BetterDisplay/discussions/1473


I've recently went down this rabbit hole myself as well and found Custom Resolution Utility (CRU) [1] to be an efficient EDID editor.

[1] https://www.monitortests.com/forum/Thread-Custom-Resolution-...


Is there any program to override EDID on macOS that doesn't cost money? CRU is free (and open-source if you can compile Embarcadero C++) on Windows, and xrandr and kernel command lines are free and open-source on Linux.


>Actually, the start of the function isn't that bad, but scroll down halfway and you'll find this: [...] Oh no, there's no way I'm going to be able to figure out all this byte manipulation in my head.

I know the author says later that they don't do C development, but note that most of this code is just reading two consecutive bytes as a 16-bit integer, except for x[9] and x[17] where the high bit has a special meaning.


Now that you've mentioned that, that section is a lot more readable to me. Cheers! My C skills are inversely correlated to my body's uptime and it was probably around 1:30AM when I reached that part of the story


OP's approach looks cool but a bit baroque. I'm also hacking around EDID issues and it turns out there's a nice GUI program to decode and (lightly) patch it: https://packages.debian.org/unstable/utils/wxedid

I have to do more involved full EDID reconstruction surgery tho since I need to add DTD entries rather than just change existing ones. So I'm looking at [edid-generator] together with [cvt12]. The latter can calculate xrandr modelines for VESA standard timings that all seem to work with my TV. cvt12 adds the option to calculate NTSC (1/1.001) timings over regular cvt which is already in Debian.

[cvt12]: https://github.com/kevinlekiller/cvt_modeline_calculator_12

[edid-generator]: https://github.com/akatrevorjay/edid-generator (thanks Kodi wiki)


I genuinely take the baroque comment as a complement. There's many paths to a solution and this was a fun one that ended up working for me.

Thanks for the pointers for those programs. Someone else pointed out Kaitai Struct could help me do the hex editing which I'm planning on taking a look at later


I tried wxedid from the AUR on Arch Linux, but unfortunately it segfaults in Wx code on startup. I haven't tried building it manually and debugging.


LG monitors get firmware updates, I wonder if one of them contained this fix.


I noticed this problem with Dell displays on macOS. The first script I used, and would still use if DisplayPort over USB-C got it wrong[0]. The particular thing that I was correcting wasn't resolution/refresh but rather the color mode to use RGB rather than YPbPr which can be blurry on lower-than-retina displays.

[0] https://gist.github.com/adaugherity/7435890


Lack of ability to configure a monitors behaviour has long been a pet hate.

- automatic display switching when an input is off (bad if you’re attempting to troubleshoot a non posting machine)

- LED flashing when the monitor is soft-powered off, barely noticeable during the day but blinding in a dark room - good luck sleeping

- OSD behaviour where it disappears to quickly, particularly in a soft-off status - no ability to know what the firmware behaviour is until you buy it and test for yourself


Very interesting report. I'm not sure I understand what the root cause of the issue is though - is it a Linux bug or a problem with the monitor itself?


The monitor reports an EDID resolution/refresh value to the system that is incorrect for the actual monitor's capabilities. Linux happens to be choosing to use that invalid EDID resolution/refresh value and the default result is no picture on the monitor.

The bug is with the EDID values LG programmed into the monitor.


There are many cases where hardware is not up to spec and other operating systems ignore it more or less but Linux can be a stickler.

Windows is generally most forgiving, then Mac, finally Linux.


More like: Linux is most likely to try to use the features a device claims to support. Windows will often only try to use a narrower subset of those features, and that subset is what actually got tested before the product shipped. Case in point: NVMe APST, which has been a perennial source of trouble on Linux, but Windows largely ignores (at the expense of worse power management behavior).


I sort of expect that Windows and Mac have more testing and overrides applied to fix buggy firmware. The find and override process just happens during pre-ship QA instead of post-launch support issues debugged over the internet.


> I don't do much C or C++ development, but I've used gdb in the past for schoolwork and a really great capture the flag I did once. I probably can remember enough about it to get some useful info out.

This brought a tear to my eye. What a beautiful attitude, kj800x! Don’t ever lose it; that spirit will take you far.


I had similar issues with EDID on an old monitor. I pulled the cover off the back and found the I2C EEPROM that stored the EDID data. I soldered a jumper to disable the write protect on the EEPROM and was able to reprogram it using the Linux i2c-dev device.


OT but blog posts like this make me think that I'm nowhere near in the capabilities, energy, skills and problem solving attitude of some other engineers out there.


For my LG monitor also do an EDID-hack. If I use it with DP it works fine but with HDMI it gets super bright and high contrast. In windows it works fine.


EDID is such an ugly mess. I wish we had something cleaner.


EDID, CTA-861, and DisplayID are the result of decades of piling layers of cruft on top of each other (CRTs, then LCDs, then variable refresh rates), with different data formats from competing standards committees (HDMI vs. VESA/DisplayPort) with different sets of needs (like HDMI/CTA-861 supporting audio codecs and YPbPr/chroma subsampling originally for home theater applications), sometimes coexisting on the same display (this LG monitor has both CTA-861 and DisplayID blocks).


(the things we do for ~love~ linux)


What's with LG in general? It seems they often have problems with EDIDs.


Fun read! Definitely reminded me of this xkcd https://xkcd.com/196/


Glad you liked it and great XKCD. I end up reaching for xdotool more often than I'd expect when something isn't easily scriptable elsewise




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: