]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/dmc: Set DMC_EVT_CTL_ENABLE for disabled event handlers as well
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 22 Oct 2025 10:07:18 +0000 (13:07 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 22 Oct 2025 18:40:00 +0000 (21:40 +0300)
DMC_EVT_CTL_ENABLE cannot be cleared once set. So currently
any event we never enable will have DMC_EVT_CTL_ENABLE cleared,
whereas any event which has been enabled even once will have
DMC_EVT_CTL_ENABLE set. For that reason assert_dmc_loaded() has
a special case to ignore any mismatches in DMC_EVT_CTL_ENABLE.

Eliminate the special case by always configuring DMC_EVT_CTL_ENABLE
based on the original firmware event definition. Now all
event handlers will have DMC_EVT_CTL_ENABLE set, whether or
not the event has been enabled in the past.

All disabled event handlers will still have the event type set
to DMC_EVENT_FALSE so they will not actually trigger despite
DMC_EVT_CTL_ENABLE being set.

Tested-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251022100718.24803-4-ville.syrjala@linux.intel.com
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Tested-by: Imre Deak <imre.deak@intel.com>
drivers/gpu/drm/i915/display/intel_dmc.c

index 02ef0a252220892e88c314c59e3a6f521b16274d..5ba17e66d90b3897fca87a5bbc831cdc4302520e 100644 (file)
@@ -513,10 +513,16 @@ static u32 pipedmc_interrupt_mask(struct intel_display *display)
                PIPEDMC_ATS_FAULT;
 }
 
-static u32 dmc_evt_ctl_disable(void)
+static u32 dmc_evt_ctl_disable(u32 dmc_evt_ctl)
 {
-       return REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
-                             DMC_EVT_CTL_TYPE_EDGE_0_1) |
+       /*
+        * DMC_EVT_CTL_ENABLE cannot be cleared once set. Always
+        * configure it based on the original event definition to
+        * avoid mismatches in assert_dmc_loaded().
+        */
+       return (dmc_evt_ctl & DMC_EVT_CTL_ENABLE) |
+               REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
+                              DMC_EVT_CTL_TYPE_EDGE_0_1) |
                REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK,
                               DMC_EVENT_FALSE);
 }
@@ -626,7 +632,7 @@ static u32 dmc_mmiodata(struct intel_display *display,
        if (disable_dmc_evt(display, dmc_id,
                            dmc->dmc_info[dmc_id].mmioaddr[i],
                            dmc->dmc_info[dmc_id].mmiodata[i]))
-               return dmc_evt_ctl_disable();
+               return dmc_evt_ctl_disable(dmc->dmc_info[dmc_id].mmiodata[i]);
        else
                return dmc->dmc_info[dmc_id].mmiodata[i];
 }
@@ -685,12 +691,6 @@ static void assert_dmc_loaded(struct intel_display *display,
                found = intel_de_read(display, reg);
                expected = dmc_mmiodata(display, dmc, dmc_id, i);
 
-               /* once set DMC_EVT_CTL_ENABLE can't be cleared :/ */
-               if (is_dmc_evt_ctl_reg(display, dmc_id, reg)) {
-                       found &= ~DMC_EVT_CTL_ENABLE;
-                       expected &= ~DMC_EVT_CTL_ENABLE;
-               }
-
                drm_WARN(display->drm, found != expected,
                         "DMC %d mmio[%d]/0x%x incorrect (expected 0x%x, current 0x%x)\n",
                         dmc_id, i, i915_mmio_reg_offset(reg), expected, found);
@@ -843,7 +843,7 @@ static void dmc_configure_event(struct intel_display *display,
                if (!is_event_handler(display, dmc_id, event_id, reg, data))
                        continue;
 
-               intel_de_write(display, reg, enable ? data : dmc_evt_ctl_disable());
+               intel_de_write(display, reg, enable ? data : dmc_evt_ctl_disable(data));
                num_handlers++;
        }