* [PATCH 1/2] drm/edid: populate monitor_range from DisplayID Adaptive Sync block
2026-04-15 13:06 [PATCH 0/2] drm: Enable eDP VRR for panels with DisplayID Adaptive Sync Jake S
@ 2026-04-15 13:06 ` Jake S
2026-04-15 13:06 ` [PATCH 2/2] drm/i915/display: allow eDP VRR when EDID has adaptive sync range Jake S
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Jake S @ 2026-04-15 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel, jani.nikula, ville.syrjala, rodrigo.vivi, Jake S
The DRM EDID parser only reads monitor range (min/max vfreq) from the
base EDID Display Range Limits descriptor (tag 0xFD). Many modern eDP
OLED panels ship with a DisplayID v2.0 extension containing an Adaptive
Sync Data Block (tag 0x2B) that declares the VRR range, but no base
EDID range limits descriptor at all.
This leaves info->monitor_range zeroed on Intel/Nouveau/etc, while
amdgpu has a private workaround (parse_edid_displayid_vrr). Add generic
drm_get_monitor_range_displayid() so all drivers benefit.
Handles both tag 0x2B (Adaptive Sync, CTA-861.6) and tag 0x25 (Dynamic
Video Timing Range Limits, DisplayID v2.0 section 4.5).
Only fills in monitor_range as a fallback when the base EDID parsing
found nothing, preserving existing behavior for panels with proper Range
Limits descriptors.
Tested on Dell XPS 2026 (Intel Panther Lake, LG Display OLED eDP,
3200x2000, VRR 20-120Hz via DisplayID tag 0x2B).
Signed-off-by: Jake S <j@metarealtyinc.ca>
---
gpu/drm/drm_edid.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/gpu/drm/drm_edid.c b/gpu/drm/drm_edid.c
index 68390e7..ebefd18 100644
--- a/gpu/drm/drm_edid.c
+++ b/gpu/drm/drm_edid.c
@@ -6567,6 +6567,57 @@ static void drm_get_monitor_range(struct drm_connector *connector,
info->monitor_range.min_vfreq, info->monitor_range.max_vfreq);
}
+/*
+ * Parse DisplayID v2.0 Adaptive Sync Data Block (tag 0x2B) as a fallback
+ * when the base EDID has no Range Limits descriptor. Many modern eDP OLED
+ * panels only advertise their VRR range via DisplayID, not base EDID.
+ *
+ * Also handles tag 0x25 (Dynamic Video Timing Range Limits).
+ */
+static void drm_get_monitor_range_displayid(struct drm_connector *connector,
+ const struct drm_edid *drm_edid)
+{
+ struct drm_display_info *info = &connector->display_info;
+ const struct displayid_block *block;
+ struct displayid_iter iter;
+
+ if (info->monitor_range.min_vfreq && info->monitor_range.max_vfreq)
+ return;
+
+ displayid_iter_edid_begin(drm_edid, &iter);
+ displayid_iter_for_each(block, &iter) {
+ const u8 *data = (const u8 *)block + sizeof(*block);
+ int len = block->num_bytes;
+ u16 min_vfreq, max_vfreq;
+
+ if (block->tag == 0x2b && len >= 6) {
+ /* Adaptive Sync Data Block (CTA-861.6) */
+ min_vfreq = data[2];
+ max_vfreq = data[3] | ((u16)(data[4] & 0x3) << 8);
+ } else if (block->tag == DATA_BLOCK_2_DYNAMIC_VIDEO_TIMING &&
+ len >= 6) {
+ /* Dynamic Video Timing Range Limits (DisplayID v2.0) */
+ int offset = ((data[0] >> 3) & 0x3) ? 5 : 3;
+
+ if (len < offset + 3)
+ continue;
+ min_vfreq = data[offset];
+ max_vfreq = data[offset + 1] |
+ ((u16)(data[offset + 2] & 0x3) << 8);
+ } else {
+ continue;
+ }
+
+ if (max_vfreq && min_vfreq && max_vfreq > min_vfreq) {
+ info->monitor_range.min_vfreq = min_vfreq;
+ info->monitor_range.max_vfreq = max_vfreq;
+ break;
+ }
+ }
+ displayid_iter_end(&iter);
+}
+
+
static void drm_parse_vesa_specific_block(struct drm_connector *connector,
const struct displayid_block *block)
{
@@ -6756,6 +6807,8 @@ static void update_display_info(struct drm_connector *connector,
drm_get_monitor_range(connector, drm_edid);
+ drm_get_monitor_range_displayid(connector, drm_edid);
+
if (edid->revision < 3)
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/2] drm/i915/display: allow eDP VRR when EDID has adaptive sync range
2026-04-15 13:06 [PATCH 0/2] drm: Enable eDP VRR for panels with DisplayID Adaptive Sync Jake S
2026-04-15 13:06 ` [PATCH 1/2] drm/edid: populate monitor_range from DisplayID Adaptive Sync block Jake S
@ 2026-04-15 13:06 ` Jake S
2026-04-15 14:01 ` Ville Syrjälä
` (2 more replies)
2026-04-15 14:05 ` [PATCH 0/2] drm: Enable eDP VRR for panels with DisplayID Adaptive Sync Ville Syrjälä
` (2 subsequent siblings)
4 siblings, 3 replies; 10+ messages in thread
From: Jake S @ 2026-04-15 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel, jani.nikula, ville.syrjala, rodrigo.vivi, Jake S
intel_vrr_is_capable() currently hard-gates eDP VRR on the VBT (Video
BIOS Table) vrr flag. Many OEMs ship laptops with VRR-capable eDP OLED
panels but do not set the VRR flag in the VBT, making VRR impossible
on Linux even though the hardware supports it and works on Windows.
Relax the eDP check: if the VBT flag is not set but the EDID provides
a valid monitor range with delta > 10Hz (now also populated from
DisplayID Adaptive Sync blocks by the previous patch), allow VRR. The
existing checks for DPCD Ignore MSA and monitor range delta still apply.
This mirrors the approach taken by amdgpu, which has its own EDID-based
VRR fallback (parse_edid_displayid_vrr) for exactly this class of panel.
Tested on Dell XPS 2026 (Intel Panther Lake / xe driver, LG Display
OLED eDP, 3200x2000, VRR 20-120Hz confirmed via vblank event tracing).
Signed-off-by: Jake S <j@metarealtyinc.ca>
---
gpu/drm/i915/display/intel_vrr.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/gpu/drm/i915/display/intel_vrr.c b/gpu/drm/i915/display/intel_vrr.c
index bea0057..f527471 100644
--- a/gpu/drm/i915/display/intel_vrr.c
+++ b/gpu/drm/i915/display/intel_vrr.c
@@ -47,7 +47,12 @@ bool intel_vrr_is_capable(struct intel_connector *connector)
*/
switch (connector->base.connector_type) {
case DRM_MODE_CONNECTOR_eDP:
- if (!connector->panel.vbt.vrr)
+ /*
+ * Prefer VBT flag, but fall back to EDID monitor range
+ * for panels where OEM firmware omits the VBT VRR flag.
+ */
+ if (!connector->panel.vbt.vrr &&
+ !(info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10))
return false;
fallthrough;
case DRM_MODE_CONNECTOR_DisplayPort:
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 2/2] drm/i915/display: allow eDP VRR when EDID has adaptive sync range
2026-04-15 13:06 ` [PATCH 2/2] drm/i915/display: allow eDP VRR when EDID has adaptive sync range Jake S
@ 2026-04-15 14:01 ` Ville Syrjälä
2026-04-15 19:08 ` Jake S
2026-04-15 19:39 ` Jake S
2 siblings, 0 replies; 10+ messages in thread
From: Ville Syrjälä @ 2026-04-15 14:01 UTC (permalink / raw)
To: Jake S; +Cc: intel-gfx, dri-devel, jani.nikula, rodrigo.vivi
On Wed, Apr 15, 2026 at 09:06:26AM -0400, Jake S wrote:
> intel_vrr_is_capable() currently hard-gates eDP VRR on the VBT (Video
> BIOS Table) vrr flag. Many OEMs ship laptops with VRR-capable eDP OLED
> panels but do not set the VRR flag in the VBT, making VRR impossible
> on Linux even though the hardware supports it and works on Windows.
>
> Relax the eDP check: if the VBT flag is not set but the EDID provides
> a valid monitor range with delta > 10Hz (now also populated from
> DisplayID Adaptive Sync blocks by the previous patch), allow VRR. The
> existing checks for DPCD Ignore MSA and monitor range delta still apply.
AFAICS the Windows driver does respect that VBT bit. So we should too.
>
> This mirrors the approach taken by amdgpu, which has its own EDID-based
> VRR fallback (parse_edid_displayid_vrr) for exactly this class of panel.
>
> Tested on Dell XPS 2026 (Intel Panther Lake / xe driver, LG Display
> OLED eDP, 3200x2000, VRR 20-120Hz confirmed via vblank event tracing).
>
> Signed-off-by: Jake S <j@metarealtyinc.ca>
> ---
> gpu/drm/i915/display/intel_vrr.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/gpu/drm/i915/display/intel_vrr.c b/gpu/drm/i915/display/intel_vrr.c
> index bea0057..f527471 100644
> --- a/gpu/drm/i915/display/intel_vrr.c
> +++ b/gpu/drm/i915/display/intel_vrr.c
> @@ -47,7 +47,12 @@ bool intel_vrr_is_capable(struct intel_connector *connector)
> */
> switch (connector->base.connector_type) {
> case DRM_MODE_CONNECTOR_eDP:
> - if (!connector->panel.vbt.vrr)
> + /*
> + * Prefer VBT flag, but fall back to EDID monitor range
> + * for panels where OEM firmware omits the VBT VRR flag.
> + */
> + if (!connector->panel.vbt.vrr &&
> + !(info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10))
> return false;
> fallthrough;
> case DRM_MODE_CONNECTOR_DisplayPort:
> --
> 2.53.0
--
Ville Syrjälä
Intel
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 2/2] drm/i915/display: allow eDP VRR when EDID has adaptive sync range
2026-04-15 13:06 ` [PATCH 2/2] drm/i915/display: allow eDP VRR when EDID has adaptive sync range Jake S
2026-04-15 14:01 ` Ville Syrjälä
@ 2026-04-15 19:08 ` Jake S
2026-04-15 19:16 ` Ville Syrjälä
2026-04-15 19:39 ` Jake S
2 siblings, 1 reply; 10+ messages in thread
From: Jake S @ 2026-04-15 19:08 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel, ville.syrjala
Hi Ville,
> AFAICS the Windows driver does respect that VBT bit. So we should too.
That's fair -- I don't have visibility into the Windows driver
internals so I can't say definitively whether it checks VBT or not.
What I can confirm is the end-user result: on this Dell XPS 2026
(Panther Lake), VRR 20-120Hz works on Windows but not on Linux with
the same firmware. The VBT does not contain a VRR flag for this panel
at all -- intel_vbt_decode shows no VRR-related fields in the child
device block.
So either Windows has a fallback path when VBT doesn't declare VRR,
or Dell's Intel DCH driver ships with a driver-side override. Either
way, the panel clearly supports VRR (the EDID's DisplayID extension
explicitly declares Adaptive Sync 20-120Hz), and it works in practice
on this hardware.
Framework laptop users have reported the same class of issue with
their BOE panels.
If respecting VBT is important (and I understand the reasoning --
OEM validation), would something like a quirk table or a module
parameter be an acceptable alternative? I'd rather have any path to
making this work than no path.
Thanks for the review.
Jake
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] drm/i915/display: allow eDP VRR when EDID has adaptive sync range
2026-04-15 19:08 ` Jake S
@ 2026-04-15 19:16 ` Ville Syrjälä
0 siblings, 0 replies; 10+ messages in thread
From: Ville Syrjälä @ 2026-04-15 19:16 UTC (permalink / raw)
To: Jake S; +Cc: intel-gfx, dri-devel
On Wed, Apr 15, 2026 at 07:08:30PM +0000, Jake S wrote:
> Hi Ville,
>
> > AFAICS the Windows driver does respect that VBT bit. So we should too.
>
> That's fair -- I don't have visibility into the Windows driver
> internals so I can't say definitively whether it checks VBT or not.
>
> What I can confirm is the end-user result: on this Dell XPS 2026
> (Panther Lake), VRR 20-120Hz works on Windows but not on Linux with
> the same firmware. The VBT does not contain a VRR flag for this panel
> at all -- intel_vbt_decode shows no VRR-related fields in the child
> device block.
It's in the LFP power block (44).
>
> So either Windows has a fallback path when VBT doesn't declare VRR,
> or Dell's Intel DCH driver ships with a driver-side override.
My cursory glance didn't spot any registry key stuff in there
either. That I think is the usual "screw proper design and just
hack it" approach for the Windows driver.
> Either
> way, the panel clearly supports VRR (the EDID's DisplayID extension
> explicitly declares Adaptive Sync 20-120Hz), and it works in practice
> on this hardware.
>
> Framework laptop users have reported the same class of issue with
> their BOE panels.
>
> If respecting VBT is important (and I understand the reasoning --
> OEM validation), would something like a quirk table or a module
> parameter be an acceptable alternative? I'd rather have any path to
> making this work than no path.
One can always hack up the VBT and use the firmware loader
to override it.
--
Ville Syrjälä
Intel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] drm/i915/display: allow eDP VRR when EDID has adaptive sync range
2026-04-15 13:06 ` [PATCH 2/2] drm/i915/display: allow eDP VRR when EDID has adaptive sync range Jake S
2026-04-15 14:01 ` Ville Syrjälä
2026-04-15 19:08 ` Jake S
@ 2026-04-15 19:39 ` Jake S
2 siblings, 0 replies; 10+ messages in thread
From: Jake S @ 2026-04-15 19:39 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel, ville.syrjala
Hi Ville,
> It's in the LFP power block (44).
You're right -- I checked and intel_vbt_decode shows:
BDB block 44 - LFP power conservation features block:
Variable Refresh Rate (VRR): yes
And looking at the code, panel->vbt.vrr defaults to true at line
1370 of intel_bios.c anyway. So the VBT gate was never the problem.
The actual issue is the final check in intel_vrr_is_capable():
return info->monitor_range.max_vfreq - min_vfreq > 10;
monitor_range is 0/0 because this panel's EDID has no base block
Range Limits descriptor (tag 0xFD). The VRR range is only in the
DisplayID v2.0 Adaptive Sync block (tag 0x2B), which drm_edid.c
doesn't parse into monitor_range.
So patch 2/2 (the VBT relaxation) is unnecessary and I'll drop it.
Only patch 1/2 (parsing DisplayID tag 0x2B into monitor_range) is
needed. I'll send a v2 with just that patch.
Sorry for the noise on the VBT front -- should have traced the
actual failure path more carefully before assuming.
Thanks,
Jake
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] drm: Enable eDP VRR for panels with DisplayID Adaptive Sync
2026-04-15 13:06 [PATCH 0/2] drm: Enable eDP VRR for panels with DisplayID Adaptive Sync Jake S
2026-04-15 13:06 ` [PATCH 1/2] drm/edid: populate monitor_range from DisplayID Adaptive Sync block Jake S
2026-04-15 13:06 ` [PATCH 2/2] drm/i915/display: allow eDP VRR when EDID has adaptive sync range Jake S
@ 2026-04-15 14:05 ` Ville Syrjälä
2026-04-15 19:08 ` Jake S
2026-04-16 13:21 ` ✗ LGCI.VerificationFailed: failure for " Patchwork
4 siblings, 0 replies; 10+ messages in thread
From: Ville Syrjälä @ 2026-04-15 14:05 UTC (permalink / raw)
To: Jake S; +Cc: intel-gfx, dri-devel, jani.nikula, rodrigo.vivi
On Wed, Apr 15, 2026 at 09:06:24AM -0400, Jake S wrote:
> Many 2025-2026 laptops (Dell XPS, Framework, etc.) ship with OLED eDP
> panels that support VRR 20-120Hz. These panels advertise their VRR
> capability through a DisplayID v2.0 Adaptive Sync Data Block (tag 0x2B)
> in their EDID. VRR works fine on Windows.
>
> On Linux, VRR is broken due to two issues:
>
> 1. The DRM EDID parser (drm_edid.c) only reads monitor range from the
> base EDID Display Range Limits descriptor (tag 0xFD). It does not
> parse the DisplayID Adaptive Sync block. This leaves monitor_range
> zeroed. AMD's driver has a private workaround; the generic DRM
> layer does not.
>
> 2. The Intel display driver (intel_vrr.c) gates eDP VRR on a VBT
> (Video BIOS Table) firmware flag. Most OEMs don't set this flag
> because the Windows driver doesn't need it. This blocks VRR even
> when the EDID clearly declares support.
>
> This series fixes both issues:
> - Patch 1 adds generic DisplayID Adaptive Sync parsing to drm_edid.c,
> benefiting all DRM drivers.
> - Patch 2 relaxes the Intel eDP VRR gate to also accept EDID-based
> capability when the VBT flag is absent.
>
> Tested on Dell XPS 2026 (Intel Panther Lake, xe driver, LG Display
> OLED 3200x2000). VRR 20-120Hz confirmed via kernel vblank event
> tracing -- display dynamically varies between 32Hz (idle) and 120Hz
> (active rendering).
>
> Related work: Adriano Vero posted a similar DisplayID range parsing
> patch to LKML (2026-03-28) which has not yet been merged.
Why did you post a different version?
>
> GitHub: https://github.com/jibsta210/edp-vrr-linux
>
> Jake S (2):
> drm/edid: populate monitor_range from DisplayID Adaptive Sync block
> drm/i915/display: allow eDP VRR when EDID has adaptive sync range
>
> gpu/drm/drm_edid.c | 53 ++++++++++++++++++++++++++++++++
> gpu/drm/i915/display/intel_vrr.c | 7 ++++-
> 2 files changed, 59 insertions(+), 1 deletion(-)
>
> --
> 2.53.0
--
Ville Syrjälä
Intel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] drm: Enable eDP VRR for panels with DisplayID Adaptive Sync
2026-04-15 13:06 [PATCH 0/2] drm: Enable eDP VRR for panels with DisplayID Adaptive Sync Jake S
` (2 preceding siblings ...)
2026-04-15 14:05 ` [PATCH 0/2] drm: Enable eDP VRR for panels with DisplayID Adaptive Sync Ville Syrjälä
@ 2026-04-15 19:08 ` Jake S
2026-04-16 13:21 ` ✗ LGCI.VerificationFailed: failure for " Patchwork
4 siblings, 0 replies; 10+ messages in thread
From: Jake S @ 2026-04-15 19:08 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel, ville.syrjala
Hi Ville,
> Why did you post a different version?
Sorry for the confusion -- I wasn't building on Adriano Vero's
March 28 patch. I did the investigation independently and only found
his work afterwards. I referenced it in the cover letter but should
have been clearer.
The key difference: Adriano's patch handles tag 0x25 (Dynamic Video
Timing Range Limits). My panel (LG Display VNFT2 in a Dell XPS 2026)
only has tag 0x2B (Adaptive Sync Data Block), so his patch alone
wouldn't have helped here. My patch handles both 0x2B and 0x25.
Happy to coordinate with Adriano and fold the 0x2B handling into a
v2 of his series if that's preferred.
Thanks,
Jake
^ permalink raw reply [flat|nested] 10+ messages in thread* ✗ LGCI.VerificationFailed: failure for drm: Enable eDP VRR for panels with DisplayID Adaptive Sync
2026-04-15 13:06 [PATCH 0/2] drm: Enable eDP VRR for panels with DisplayID Adaptive Sync Jake S
` (3 preceding siblings ...)
2026-04-15 19:08 ` Jake S
@ 2026-04-16 13:21 ` Patchwork
4 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2026-04-16 13:21 UTC (permalink / raw)
To: Jake S; +Cc: intel-gfx
== Series Details ==
Series: drm: Enable eDP VRR for panels with DisplayID Adaptive Sync
URL : https://patchwork.freedesktop.org/series/165000/
State : failure
== Summary ==
Address 'j@metarealtyinc.ca' is not on the allowlist, which prevents CI from being triggered for this patch.
If you want Intel GFX CI to accept this address, please contact the script maintainers at i915-ci-infra@lists.freedesktop.org.
Exception occurred during validation, bailing out!
^ permalink raw reply [flat|nested] 10+ messages in thread