diff --git a/pkgbuilds/edge/linux-ptl/0019-drm-edid-populate-monitor-range-from-displayid-adaptive-sync.patch b/pkgbuilds/edge/linux-ptl/0019-drm-edid-populate-monitor-range-from-displayid-adaptive-sync.patch new file mode 100644 index 00000000..f0183452 --- /dev/null +++ b/pkgbuilds/edge/linux-ptl/0019-drm-edid-populate-monitor-range-from-displayid-adaptive-sync.patch @@ -0,0 +1,136 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spencer Bull +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); + } + diff --git a/pkgbuilds/edge/linux-ptl/PKGBUILD b/pkgbuilds/edge/linux-ptl/PKGBUILD index 5bf50c28..c0952943 100644 --- a/pkgbuilds/edge/linux-ptl/PKGBUILD +++ b/pkgbuilds/edge/linux-ptl/PKGBUILD @@ -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=( @@ -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=( @@ -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 @@ -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