Commit 30afd245 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-fixes-2026-05-20' of...

Merge tag 'drm-intel-fixes-2026-05-20' of https://gitlab.freedesktop.org/drm/i915/kernel

 into drm-fixes

- Fix joiner color pipeline selection [display] (Chaitanya Kumar Borah)
- Fix readback for target_rr in Adaptive Sync SDP [dp] (Ankit Nautiyal)
- Apply Intel DPCD workaround when SDP on prior line used [psr] (Jouni Högander)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Tvrtko Ursulin <tursulin@igalia.com>
Link: https://patch.msgid.link/ag1hKBRKwwv9JOMW@linux
parents 5b4a47dc 4703049f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -584,6 +584,7 @@ struct intel_connector {

		struct {
			u8 dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
			u8 intel_wa_dpcd;

			bool support;
			bool su_support;
+1 −1
Original line number Diff line number Diff line
@@ -5303,7 +5303,7 @@ int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
	as_sdp->length = sdp->sdp_header.HB3 & DP_ADAPTIVE_SYNC_SDP_LENGTH;
	as_sdp->mode = sdp->db[0] & DP_ADAPTIVE_SYNC_SDP_OPERATION_MODE;
	as_sdp->vtotal = (sdp->db[2] << 8) | sdp->db[1];
	as_sdp->target_rr = (u64)sdp->db[3] | ((u64)sdp->db[4] & 0x3);
	as_sdp->target_rr = ((sdp->db[4] & 0x3) << 8) | sdp->db[3];
	as_sdp->target_rr_divider = sdp->db[4] & 0x20 ? true : false;

	return 0;
+15 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: MIT */
/*
 * Copyright © 2026 Intel Corporation
 */

#ifndef __INTEL_DPCD_H__
#define __INTEL_DPCD_H__

#define INTEL_DPCD_INTEL_WA_REGISTER_CAPS					0x3f0
# define INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_EARLYSCANLINE_SDP_SUPPORT_MASK	REG_GENMASK(1, 0)
# define INTEL_DPCD_INTEL_WA_REGISTER_CAPS_FALL_BACK_TO_PSR1			0
# define INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_WITH_EARLY_SCANLINE		1
# define INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_WITHOUT_EARLY_SCANLINE		2

#endif /* __INTEL_DPCD_H__ */
+1 −1
Original line number Diff line number Diff line
@@ -373,7 +373,7 @@ intel_plane_color_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
	bool changed = false;
	int i = 0;

	iter_colorop = plane_state->uapi.color_pipeline;
	iter_colorop = from_plane_state->uapi.color_pipeline;

	while (iter_colorop) {
		for_each_new_colorop_in_state(state, colorop, new_colorop_state, i) {
+39 −5
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include "intel_display_wa.h"
#include "intel_dmc.h"
#include "intel_dp.h"
#include "intel_dpcd.h"
#include "intel_dp_aux.h"
#include "intel_dsb.h"
#include "intel_frontbuffer.h"
@@ -716,9 +717,15 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *co
			    connector->dp.psr_caps.su_support ? "" : "not ");
	}

	if (connector->dp.psr_caps.su_support)
	if (connector->dp.psr_caps.su_support) {
		ret = drm_dp_dpcd_read_byte(&intel_dp->aux,
					    INTEL_DPCD_INTEL_WA_REGISTER_CAPS,
					    &connector->dp.psr_caps.intel_wa_dpcd);
		if (ret < 0)
			return;
		_psr_compute_su_granularity(intel_dp, connector);
	}
}

void intel_psr_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector)
{
@@ -1358,9 +1365,35 @@ static bool psr2_granularity_check(struct intel_crtc_state *crtc_state,
	return true;
}

static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_dp,
							struct intel_crtc_state *crtc_state)
static bool apply_scanline_indication_wa(struct intel_crtc_state *crtc_state,
					 struct intel_connector *connector)
{
	struct intel_dp *intel_dp = intel_attached_dp(connector);
	u8 early_scanline_support = connector->dp.psr_caps.intel_wa_dpcd &
		INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_EARLYSCANLINE_SDP_SUPPORT_MASK;

	if (intel_dp->edp_dpcd[0] >= DP_EDP_15)
		return true;

	switch (early_scanline_support)	{
	case INTEL_DPCD_INTEL_WA_REGISTER_CAPS_FALL_BACK_TO_PSR1:
		crtc_state->req_psr2_sdp_prior_scanline = false;
		return false;
	case INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_WITH_EARLY_SCANLINE:
		return true;
	case INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_WITHOUT_EARLY_SCANLINE:
		crtc_state->req_psr2_sdp_prior_scanline = false;
		return true;
	default:
		MISSING_CASE(early_scanline_support);
		return false;
	}
}

static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_crtc_state *crtc_state,
							struct intel_connector *connector)
{
	struct intel_dp *intel_dp = intel_attached_dp(connector);
	struct intel_display *display = to_intel_display(intel_dp);
	const struct drm_display_mode *adjusted_mode = &crtc_state->uapi.adjusted_mode;
	u32 hblank_total, hblank_ns, req_ns;
@@ -1379,7 +1412,8 @@ static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_d
		return false;

	crtc_state->req_psr2_sdp_prior_scanline = true;
	return true;

	return apply_scanline_indication_wa(crtc_state, connector);
}

static int intel_psr_entry_setup_frames(struct intel_dp *intel_dp,
@@ -1660,7 +1694,7 @@ static bool intel_sel_update_config_valid(struct intel_crtc_state *crtc_state,
								      conn_state))
		goto unsupported;

	if (!_compute_psr2_sdp_prior_scanline_indication(intel_dp, crtc_state)) {
	if (!_compute_psr2_sdp_prior_scanline_indication(crtc_state, connector)) {
		drm_dbg_kms(display->drm,
			    "Selective update not enabled, SDP indication do not fit in hblank\n");
		goto unsupported;