Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spencer Bull <spencer.bull@dell.com>
Date: Mon, 30 Mar 2026 23:30:00 +0000
Subject: [PATCH] drm/edid: populate monitor range from DisplayID adaptive sync

Some eDP OLED panels advertise a VRR range only via the DisplayID 2.x
Adaptive Sync data block. In that case `display_info.monitor_range`
stays at 0/0 because DRM currently only fills it from the legacy EDID
monitor range descriptor.

Intel's VRR capability path consumes `display_info.monitor_range`
directly, so the connector ends up with `vrr_capable=0` despite EDID
advertising Adaptive Sync.

Backfill `monitor_range` from the DisplayID 2.x Adaptive Sync data
block when the legacy descriptor did not provide a range.
---
drivers/gpu/drm/drm_displayid_internal.h | 1 +
drivers/gpu/drm/drm_edid.c | 50 ++++++++++++++++++++++++++++++++++------
2 files changed, 43 insertions(+), 8 deletions(-)

--- a/drivers/gpu/drm/drm_displayid_internal.h
+++ b/drivers/gpu/drm/drm_displayid_internal.h
@@ -67,6 +67,7 @@
#define DATA_BLOCK_2_TILED_DISPLAY_TOPOLOGY 0x28
#define DATA_BLOCK_2_CONTAINER_ID 0x29
#define DATA_BLOCK_2_TYPE_10_FORMULA_TIMING 0x2a
+#define DATA_BLOCK_2_ADAPTIVE_SYNC 0x2b
#define DATA_BLOCK_2_VENDOR_SPECIFIC 0x7e
#define DATA_BLOCK_2_CTA_DISPLAY_ID 0x81

--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -6527,6 +6527,46 @@
info->monitor_range.min_vfreq, info->monitor_range.max_vfreq);
}

+#define DISPLAYID_ADAPTIVE_SYNC_DESC_SIZE 6
+
+static void drm_update_displayid_adaptive_sync_range(struct drm_connector *connector,
+ const struct displayid_block *block)
+{
+ struct drm_monitor_range_info *range = &connector->display_info.monitor_range;
+ const u8 *data = (const u8 *)(block + 1);
+ u16 best_min = 0, best_max = 0;
+ unsigned int best_span = 0;
+ int i;
+
+ if (block->rev != 0 || block->num_bytes < DISPLAYID_ADAPTIVE_SYNC_DESC_SIZE ||
+ block->num_bytes % DISPLAYID_ADAPTIVE_SYNC_DESC_SIZE)
+ return;
+
+ for (i = 0; i < block->num_bytes; i += DISPLAYID_ADAPTIVE_SYNC_DESC_SIZE) {
+ const u8 *desc = &data[i];
+ u16 min_vfreq = desc[2];
+ u16 max_vfreq = ((((u16)desc[4]) & 0x3) << 8) | desc[3];
+ unsigned int span;
+
+ max_vfreq += 1;
+ if (!min_vfreq || max_vfreq <= min_vfreq)
+ continue;
+
+ span = max_vfreq - min_vfreq;
+ if (span <= best_span)
+ continue;
+
+ best_min = min_vfreq;
+ best_max = max_vfreq;
+ best_span = span;
+ }
+
+ if (best_span) {
+ range->min_vfreq = best_min;
+ range->max_vfreq = best_max;
+ }
+}
+
static void drm_parse_vesa_mso_data(struct drm_connector *connector,
const struct displayid_block *block)
{
@@ -6648,26 +6688,41 @@
{
struct drm_display_info *info = &connector->display_info;
const struct displayid_block *block;
+ bool displayid_base_logged = false;
struct displayid_iter iter;

displayid_iter_edid_begin(drm_edid, &iter);
displayid_iter_for_each(block, &iter) {
+ /*
+ * Primary use is a DisplayID base section property, but later
+ * blocks may still carry useful metadata like adaptive sync ranges.
+ */
+ if (!displayid_base_logged) {
+ drm_dbg_kms(connector->dev,
+ "[CONNECTOR:%d:%s] DisplayID extension version 0x%02x, primary use 0x%02x\n",
+ connector->base.id, connector->name,
+ displayid_version(&iter),
+ displayid_primary_use(&iter));
+ if (displayid_version(&iter) == DISPLAY_ID_STRUCTURE_VER_20 &&
+ (displayid_primary_use(&iter) == PRIMARY_USE_HEAD_MOUNTED_VR ||
+ displayid_primary_use(&iter) == PRIMARY_USE_HEAD_MOUNTED_AR))
+ info->non_desktop = true;
+
+ displayid_base_logged = true;
+ }
+
+ if (!info->monitor_range.min_vfreq && !info->monitor_range.max_vfreq &&
+ block->tag == DATA_BLOCK_2_ADAPTIVE_SYNC)
+ drm_update_displayid_adaptive_sync_range(connector, block);
+ }
+
+ if (info->monitor_range.min_vfreq && info->monitor_range.max_vfreq)
drm_dbg_kms(connector->dev,
- "[CONNECTOR:%d:%s] DisplayID extension version 0x%02x, primary use 0x%02x\n",
+ "[CONNECTOR:%d:%s] DisplayID adaptive sync refresh rate range is %d Hz - %d Hz\n",
connector->base.id, connector->name,
- displayid_version(&iter),
- displayid_primary_use(&iter));
- if (displayid_version(&iter) == DISPLAY_ID_STRUCTURE_VER_20 &&
- (displayid_primary_use(&iter) == PRIMARY_USE_HEAD_MOUNTED_VR ||
- displayid_primary_use(&iter) == PRIMARY_USE_HEAD_MOUNTED_AR))
- info->non_desktop = true;
-
- /*
- * We're only interested in the base section here, no need to
- * iterate further.
- */
- break;
- }
+ info->monitor_range.min_vfreq,
+ info->monitor_range.max_vfreq);
+
displayid_iter_end(&iter);
}

7 changes: 4 additions & 3 deletions pkgbuilds/edge/linux-ptl/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

pkgbase=linux-ptl
pkgver=6.19.10.arch1
pkgrel=1
pkgrel=2
pkgdesc='Linux with Panther Lake hardware backports (SDCA audio, WiFi 7)'
url='https://github.com/archlinux/linux'
arch=(
Expand Down Expand Up @@ -43,6 +43,7 @@ source=(
0014-ASoC-SDCA-Limit-values-user-can-write-to-Selected-Mo.patch
0017-ASoC-SDCA-Fix-NULL-pointer-dereference-in-sdca_jack_.patch
0018-wifi-iwlwifi-mld-correctly-set-wifi-generation-data.patch
0019-drm-edid-populate-monitor-range-from-displayid-adaptive-sync.patch
)
source_x86_64=(config.x86_64)
validpgpkeys=(
Expand All @@ -55,7 +56,7 @@ b2sums=('f91cdd0b8727ce50ba286b321e85f394ff7e2eff27cde6e6e85e8abfc627b2b069bb567
'9632ace64efb38ee784d731ea85aeb285f0c3db486112122c17059c359c490a54c6ef7cd9d1d1cdecc8ae1d43df94536890b83a6671c1166a6b2148308f1baf3'
'SKIP'
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP'
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
b2sums_x86_64=('0fe195286246b83f0859f79dd2f6c633f5370057aa6afad4525309822ade855f7f6ebcfb01109786313c9331ad61d667b0257ecc7b7f239d2f962c9d34f0b10d')

# https://www.kernel.org/pub/linux/kernel/v6.x/sha256sums.asc
Expand All @@ -64,7 +65,7 @@ sha256sums=('466d441a0ea5e04b7023618b7b201bfd60effab225f806fd41ce663484395a1c'
'96410b474e9b3efc2e03e5bb8e3819f41313e943f2157c215094668200cb069d'
'SKIP'
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP'
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')

export KBUILD_BUILD_HOST=archlinux
export KBUILD_BUILD_USER=$pkgbase
Expand Down