linux-6.18: optional i915 patch enabling interlaced modes on Intel gen9 - #17
Conversation
Y/Yf tiled scanout is rejected by the display engine in IF-ID interlace mode on gen9, and userspace picks the modifier when it allocates the buffer, long before a mode is set. Every interlaced modeset therefore fails the atomic check with -EINVAL. Advertising only LINEAR/X_TILED on DISPLAY_VER 9 makes the scanout buffer interlace capable from the start. Behind a module parameter, off by default, since it costs tiling and render compression for everything else on the platform.
|
Amazing job on the patch. This looks like a great fix for the interlaced output issue with Intel graphics. |
|
Hi @amxcs, Rion here from the Batocera CRT Script project. We have already been discussing your Intel work over in your Batocera Reddit thread: First of all, thanks for following up on that discussion and submitting the Intel work here. I'm really glad to see the actual driver fix being separated from the original Batocera-specific setup and moved into the existing Linux 15kHz kernel patch project. I've now gone through the PR itself in more detail. I think making the current workaround opt-in with:
is a sensible safety measure for the patch as it exists today, because the patch itself documents that enabling it removes Y/Yf/CCS scanout on Gen9 and therefore gives up Y tiling and render compression for everything else on that platform. With the parameter defaulting to false and being limited to However, I'm not sure an opt-in switch like this should necessarily be considered the final solution. Ideally, Intel CRT support should eventually behave more like the existing AMD 15kHz support: the kernel can contain the CRT patches all the time, and the user shouldn't have to globally disable normal scanout capabilities just because they want interlaced CRT output. The difficulty here is understandable. As you've documented in the patch, userspace chooses the framebuffer modifier when the buffer is allocated, before the driver knows that the framebuffer will later be used for an interlaced modeset. That makes it difficult to simply disable Y tiling only at the moment an interlaced mode is selected. So for now the module parameter may be the most practical workaround, but I think it would still be worth investigating whether there is a cleaner way to influence framebuffer/modifier selection without globally removing Y/Yf/CCS whenever CRT support is enabled. I would also like to see These kernel patches are not specific to Batocera. They can be used by GroovyArcade or essentially any other Linux distribution, and users may switch between a CRT and a modern HDMI/DisplayPort display or use both on the same machine. It would therefore be useful to test normal progressive modes such as 720p, 1080p, 1440p and higher with the option enabled and check for any noticeable performance, acceleration, scanout or framebuffer-related regressions. The goal should be that adding CRT capabilities does not turn the kernel into a special CRT-only build. There is also another Intel limitation that is completely separate from the interlace problem: the minimum pixel/dot-clock restriction in i915. We already have a clear starting point for this one. In if (mode->clock < 10000)
return MODE_CLOCK_LOW;So DisplayPort modes below 10.000 MHz are rejected by i915 before they can proceed through the normal downstream mode validation. This is particularly relevant for native low-resolution progressive CRT modes. Fixing the Gen9 framebuffer modifier issue gives us working interlace, but it doesn't remove this separate restriction. Switchres can work around the 10 MHz floor to some extent by using super resolutions, but ideally we shouldn't need to increase the horizontal resolution simply to get around a hard-coded driver check if the Intel display hardware is actually capable of generating the requested lower pixel clock. So at the moment I see Intel CRT support as two separate driver problems:
For the second issue, I think the next step would be experimenting with lowering or bypassing that 10 MHz check and allowing the normal downstream i915/DisplayPort validation to determine whether the requested mode is actually possible. We would then need to establish what the real hardware limit is. The important question is whether there is another genuine DPLL/display hardware limitation below that point, or whether the 10 MHz value is simply a conservative driver restriction that can safely be relaxed. If the hardware can generate those lower clocks reliably, it would be interesting to find a clean way of relaxing the restriction without affecting normal Intel operation. It would also be very useful to test DisplayPort through one of the known low-pixel-clock DP-to-VGA DACs we've already tested extensively: This is important because we want to separate three different things:
Using a known external DAC that works with the low pixel clocks required for CRT use gives us a much better reference point than relying entirely on the onboard VGA conversion path. It may also help investigate the ~5–6 second resolution switching delay you mentioned on Reddit. Having both the onboard VGA output and a known external DAC available on the same Intel machine would allow us to run identical Switchres mode changes through both paths and see how much of that delay is actually coming from the Intel driver/display path, the VGA conversion hardware, or the CRT resynchronizing. If we can eventually solve both the interlace and low pixel-clock sides without sacrificing normal progressive operation, then this becomes much more than an Intel 480i workaround. We could potentially have proper Intel 15kHz support where native low-resolution progressive modes and interlaced modes both work, while the same patched kernel remains perfectly usable with modern displays. That would make the Intel patches useful not only for Batocera, but also GroovyArcade and any other Linux distribution using the Linux 15kHz kernel patches. Great work finding the original interlace issue and following through by getting it into the existing Linux 15kHz project. I think this gives us a very good starting point, and now we have a couple of interesting areas where we can hopefully take Intel CRT support further. //Rion |
|
@WeebLabs |
|
Update: patch 09 verified on a CRT, plus the progressive-display test and the dot-clock question Sorry for the long gap. Rion's review raised three things; here is where each one stands. 1. This exact patch on a CRT, with and without the parameterWhile preparing this update I found that the 480i confirmation in the description had been done with an earlier, unconditional revision of the change — not with the parameterised patch this PR actually proposes. So I rebuilt and re-tested it properly:
With the parameter set, the picture on the Trinitron is correct. Without it, the failure is exactly the one this PR describes, down to the kernel's own message. So the parameter does precisely what it says and nothing else is needed for interlace on gen9. Everything above is read back from debugfs rather than judged from the screen, including the mode the pipe is really running: X reported 640x454 as current in the failing case too, while the kernel had never applied it. 2. Progressive displays with the parameter setStock vs patched driver, same machine, an LCD over DisplayPort at 1080p. The patch removes Y/Yf/CCS from 3. The 10 MHz DisplayPort dot-clock floorMeasured — and it turned out not to need a kernel change. The check in Write-up with all the numbers and a script to reproduce it: https://github.com/amxcs/batocera-crt-15khz-intel/blob/master/docs/dp-dotclock-floor.md CompatibilityPatch 09 still applies cleanly to 6.18.45 (current in Not tested: the parameterised patch on Coffee Lake (UHD 630 was tested with the earlier revision only), an external low-pixel-clock DP→VGA DAC, and progressive modes above 1080p. |
|
Thanks for the solid implementation and the thorough follow-up testing. While the patch makes the activation dependent on a module parameter, this is completely fine for now. Since infrastructure for setting custom boot resolutions and passing kernel parameters already exists in these CRT setups, users can easily append this parameter (or an extension of it in the future) to enable Intel Gen9 interlace support. Anyone choosing to configure this will normally keep the setting static for their specific hardware layout. The earlier selection of Y-tiling by userspace drivers like Mesa is the culprit here, as it forces the allocation choice before the display engine knows the final mode. As soon as a consensus is reached on the activation routine, we can look into an automated way to disable Y-tiling dynamically. Perhaps triggering it automatically when an interlaced boot resolution is detected in conjunction with a generic userspace mode request implying an interlaced mode. The goal is to handle this entirely by patching the Linux kernel, without introducing dependencies on external projects. I'm happy to merge this into the linux-6.18 branch so we can begin wider testing. |
This adds the missing Intel piece: interlaced (480i) modes on gen9 integrated
graphics, which currently cannot work at all.
The problem
Interlace support is not missing.
intel_dp.calready setsinterlace_allowedfor
DISPLAY_VER < 12. What fails is the framebuffer modifier.The display engine rejects Y/Yf tiled scanout while a pipe runs in IF-ID
interlace mode — see the "Y/Yf tiling not supported in IF-ID mode" check in
skl_plane_check(). Userspace picks the modifier when it allocates thebuffer, long before any mode is set, and Mesa/glamor prefers Y tiling on gen9.
So every interlaced modeset fails the atomic check with -EINVAL, surfacing as
the unhelpful:
The patch
Because the modifier is chosen before the driver can know whether the buffer
will ever be scanned out interlaced, this cannot be decided per-mode. The only
thing the driver can do is not offer the modifiers that interlace cannot use.
Doing that unconditionally would cost every gen9 machine Y tiling and render
compression to serve a feature almost none of them want, so it is behind a
module parameter, off by default:
With it set, gen9 advertises only LINEAR and X_TILED for scanout. X tiling is a
first class scanout format here, so glamor acceleration keeps working — unlike
Option "AccelMethod" "none", which produces linear buffers but has no swrastfallback on builds without
swrast_dri.so.No effect on any other display generation, and none at all unless the parameter
is set.
Testing
This patch as submitted:
i915.kobuilt from vanilla 6.18.16 + patch 09 andnothing else, loaded into Batocera 43.1's 6.18.16 kernel, which carries this
folder's 15 kHz patches. HP ProDesk 400 G2 Mini, HD Graphics 530 (Skylake,
DISPLAY_VER9), VGA flex port into SCART on a Sony Trinitron. Without theparameter, every interlaced modeset is rejected with
Y/Yf tiling not supported in IF-ID mode; withi915.no_ytiled_scanout=1, real 640x454 and 720x480interlaced at 15.734 kHz, confirmed from debugfs and on the set. Details in the
comment below.
Earlier, unconditional revision of the same change: also HP ProDesk 400 G5
Mini with UHD Graphics 630 (Coffee Lake), where Switchres generated and set
interlaced modes normally, e.g.
SR-1_1280x480@59.94iat 15.67 kHz.Only tested against 6.18, so I have only added it to
linux-6.18. It alsoapplies cleanly to 6.18.45 and 7.2.5, but I have not tested those.
Written up in more detail, with the measurements, at
https://github.com/amxcs/batocera-crt-15khz-intel