Critical workarounds/fixes for suspend/resume & screen flickering on XPS 9550 running Arch Linux
EDIT (12/1/2016): Dell has released BIOS version 1.2.16, and it appears to remedy the black screen on resume from suspend!
After getting my first display replaced under warranty due to dead/stuck pixels, I still had issues with screen brightness and random flickering. I updated to the latest BIOS (which was, at the time of this writing, version 01.2.10), which promised to “Fix LCD flickering when in lowest brightness”. Unfortunately, it did not reduce, much less fix, the flickering on my system… and it actually introduced a new problem: upon resuming from a suspend, the screen’s backlight would not come on, unless the brightness was turned up all the way. Anything less than maximum, and the backlight would turn off. Annoying.
This is easy: just downgrade to the previous BIOS until Dell pushes an update that doesn’t cause more problems than it solves. You can download the previous version (01.2.00) HERE
Fixing screen flickering
11/20/2016 UPDATE: According to Luca’s comment below, this screen-flickering fix should also work for the Dell Precision 5510!
Thankfully, the screen flickering I’ve experienced can be remedied in software. The fix is even easier than downgrading the bios: just add
i915.edp_vswing=2 to your kernel command line and reboot.
This adjusts the “voltage swing” tables used to adjust the brightness of the screen – in this case, locking it to 400mV (which, I presume, is higher than the default voltage swing table). If you’re not familiar with how LED brightness works, this is a good read. This is probably an over-simplification (due to my incomplete understanding based on a few minutes of reading), but here’s what I think is going on: the backlight’s brightness is based on pulse-width modulation (PWM). I’d imagine there are pre-set PWM duty-cycle levels (i.e. 50%, 60%, 70%, etc.), and the duty-cycle is chosen based on the voltage being delivered. But because the voltage being delivered varies slightly, a swing “window” is needed to specify the tolerance allowed within a duty-cycle level. If that window is too small, voltage variances will cause undesired jumps between duty-cycle levels – i.e. flickering.
I’m not really much of an electronics guy, and this is all speculation based off not-enough-reading, so I’m probably pretty far off on the why. Thankfully, the how (
i915.edp_vswing=2) seems to completely eliminate screen flickering for me. Anyway, if you want to read more, check out the Sources below.