public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] drm/i915/dmc: Clear HRR EVT_CTL/HTP to zero on ADL-S
       [not found] <20251022100718.24803-1-ville.syrjala@linux.intel.com>
@ 2025-10-22 10:07 ` Ville Syrjala
  2025-10-22 11:21   ` Petr Vorel
  0 siblings, 1 reply; 2+ messages in thread
From: Ville Syrjala @ 2025-10-22 10:07 UTC (permalink / raw)
  To: intel-gfx; +Cc: intel-xe, stable, Petr Vorel

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

On ADL-S the main DMC HRR event DMC_EVT_CTL/HTP are never
restored to their previous values during DC6 exit. This
angers assert_dmc_loaded(), and basically makes the HRR
handler unusable because we don't rewrite EVT_HTP when
enabling DMC events.

Let's just clear the HRR EVT_CTL/HTP to zero from the
beginnning so that the expected value matches the post-DC6
reality.

I suppose if we ever had actual use for HRR we'd have to both,
reject HRR+PSR, and reprogram EVT_HTP when enabling the event.
But for now we don't care about HRR so keeping both registers
zeroed is fine.

Cc: stable@vger.kernel.org
Tested-by: Petr Vorel <pvorel@suse.cz>
Fixes: 43175c92d403 ("drm/i915/dmc: Assert DMC is loaded harder")
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15153
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dmc.c | 55 +++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index be6d37ea1139..5ba531e3bc36 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -550,6 +550,36 @@ static bool is_event_handler(struct intel_display *display,
 		REG_FIELD_GET(DMC_EVT_CTL_EVENT_ID_MASK, data) == event_id;
 }
 
+static bool fixup_dmc_evt(struct intel_display *display,
+			  enum intel_dmc_id dmc_id,
+			  i915_reg_t reg_ctl, u32 *data_ctl,
+			  i915_reg_t reg_htp, u32 *data_htp)
+{
+	if (!is_dmc_evt_ctl_reg(display, dmc_id, reg_ctl))
+		return false;
+
+	if (!is_dmc_evt_htp_reg(display, dmc_id, reg_htp))
+		return false;
+
+	/* make sure reg_ctl and reg_htp are for the same event */
+	if (i915_mmio_reg_offset(reg_ctl) - i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, 0)) !=
+	    i915_mmio_reg_offset(reg_htp) - i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, 0)))
+		return false;
+
+	/*
+	 * On ADL-S the HRR event handler is not restored after DC6.
+	 * Clear it to zero from the beginning to avoid mismatches later.
+	 */
+	if (display->platform.alderlake_s && dmc_id == DMC_FW_MAIN &&
+	    is_event_handler(display, dmc_id, MAINDMC_EVENT_VBLANK_A, reg_ctl, *data_ctl)) {
+		*data_ctl = 0;
+		*data_htp = 0;
+		return true;
+	}
+
+	return false;
+}
+
 static bool disable_dmc_evt(struct intel_display *display,
 			    enum intel_dmc_id dmc_id,
 			    i915_reg_t reg, u32 data)
@@ -1068,9 +1098,32 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
 	for (i = 0; i < mmio_count; i++) {
 		dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]);
 		dmc_info->mmiodata[i] = mmiodata[i];
+	}
 
+	for (i = 0; i < mmio_count - 1; i++) {
+		u32 orig_mmiodata[2] = {
+			dmc_info->mmiodata[i],
+			dmc_info->mmiodata[i+1],
+		};
+
+		if (!fixup_dmc_evt(display, dmc_id,
+				   dmc_info->mmioaddr[i], &dmc_info->mmiodata[i],
+				   dmc_info->mmioaddr[i+1], &dmc_info->mmiodata[i+1]))
+			continue;
+
+		drm_dbg_kms(display->drm,
+			    " mmio[%d]: 0x%x = 0x%x->0x%x (EVT_CTL)\n",
+			    i, i915_mmio_reg_offset(dmc_info->mmioaddr[i]),
+			    orig_mmiodata[0], dmc_info->mmiodata[i]);
+		drm_dbg_kms(display->drm,
+			    " mmio[%d]: 0x%x = 0x%x->0x%x (EVT_HTP)\n",
+			    i+1, i915_mmio_reg_offset(dmc_info->mmioaddr[i+1]),
+			    orig_mmiodata[1], dmc_info->mmiodata[i+1]);
+	}
+
+	for (i = 0; i < mmio_count; i++) {
 		drm_dbg_kms(display->drm, " mmio[%d]: 0x%x = 0x%x%s%s\n",
-			    i, mmioaddr[i], mmiodata[i],
+			    i, i915_mmio_reg_offset(dmc_info->mmioaddr[i]), dmc_info->mmiodata[i],
 			    is_dmc_evt_ctl_reg(display, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_CTL)" :
 			    is_dmc_evt_htp_reg(display, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_HTP)" : "",
 			    disable_dmc_evt(display, dmc_id, dmc_info->mmioaddr[i],
-- 
2.49.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH 1/3] drm/i915/dmc: Clear HRR EVT_CTL/HTP to zero on ADL-S
  2025-10-22 10:07 ` [PATCH 1/3] drm/i915/dmc: Clear HRR EVT_CTL/HTP to zero on ADL-S Ville Syrjala
@ 2025-10-22 11:21   ` Petr Vorel
  0 siblings, 0 replies; 2+ messages in thread
From: Petr Vorel @ 2025-10-22 11:21 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx, intel-xe, stable

Hi Ville,

> On ADL-S the main DMC HRR event DMC_EVT_CTL/HTP are never
> restored to their previous values during DC6 exit. This
> angers assert_dmc_loaded(), and basically makes the HRR
> handler unusable because we don't rewrite EVT_HTP when
> enabling DMC events.

> Let's just clear the HRR EVT_CTL/HTP to zero from the
> beginnning so that the expected value matches the post-DC6
> reality.

> I suppose if we ever had actual use for HRR we'd have to both,
> reject HRR+PSR, and reprogram EVT_HTP when enabling the event.
> But for now we don't care about HRR so keeping both registers
> zeroed is fine.
...

LGTM.

Reviewed-by: Petr Vorel <pvorel@suse.cz>

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-10-22 11:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20251022100718.24803-1-ville.syrjala@linux.intel.com>
2025-10-22 10:07 ` [PATCH 1/3] drm/i915/dmc: Clear HRR EVT_CTL/HTP to zero on ADL-S Ville Syrjala
2025-10-22 11:21   ` Petr Vorel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox