summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_dmc.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2022-07-28 11:14:40 +0300
committerImre Deak <imre.deak@intel.com>2022-07-28 16:51:27 +0300
commitfa6a4cdeafa0ab674d0f72067304c5408c89964f (patch)
tree0a00171a52869624d8b9a9eb74b84d34c5e952d5 /drivers/gpu/drm/i915/display/intel_dmc.c
parentc4cf059d9c2c4849c65b481c6853bb93c8b33f3b (diff)
drm/i915/d12+: Disable DMC handlers during loading/disabling the firmware
Disable the DMC event handlers before loading the firmware and after uninitializing the display, to make sure the firmware is inactive. This matches the Bspec "Sequences for Display C5 and C6" page for GEN12+. Add a TODO comment for doing the same on pre-GEN12 platforms. v2: - Add a macro for the number of event handlers. - Disable the event handlers only on GEN12+. - s/dev_priv/i915/ in docbook comment. Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Uma Shankar <uma.shankar@intel.com> #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20220728081440.1676857-1-imre.deak@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index ed28107cbd12..00e18a4a5a5a 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -277,6 +277,17 @@ static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv)
intel_de_posting_read(dev_priv, DC_STATE_DEBUG);
}
+static void disable_event_handler(struct drm_i915_private *i915,
+ i915_reg_t ctl_reg, i915_reg_t htp_reg)
+{
+ intel_de_write(i915, ctl_reg,
+ 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_EVT_CTL_EVENT_ID_FALSE));
+ intel_de_write(i915, htp_reg, 0);
+}
+
static void
disable_flip_queue_event(struct drm_i915_private *i915,
i915_reg_t ctl_reg, i915_reg_t htp_reg)
@@ -299,12 +310,7 @@ disable_flip_queue_event(struct drm_i915_private *i915,
return;
}
- intel_de_write(i915, ctl_reg,
- 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_EVT_CTL_EVENT_ID_FALSE));
- intel_de_write(i915, htp_reg, 0);
+ disable_event_handler(i915, ctl_reg, htp_reg);
}
static bool
@@ -356,6 +362,27 @@ disable_all_flip_queue_events(struct drm_i915_private *i915)
}
}
+static void disable_all_event_handlers(struct drm_i915_private *i915)
+{
+ int id;
+
+ /* TODO: disable the event handlers on pre-GEN12 platforms as well */
+ if (DISPLAY_VER(i915) < 12)
+ return;
+
+ for (id = DMC_FW_MAIN; id < DMC_FW_MAX; id++) {
+ int handler;
+
+ if (!has_dmc_id_fw(i915, id))
+ continue;
+
+ for (handler = 0; handler < DMC_EVENT_HANDLER_COUNT_GEN12; handler++)
+ disable_event_handler(i915,
+ DMC_EVT_CTL(i915, id, handler),
+ DMC_EVT_HTP(i915, id, handler));
+ }
+}
+
/**
* intel_dmc_load_program() - write the firmware from memory to register.
* @dev_priv: i915 drm device.
@@ -372,6 +399,8 @@ void intel_dmc_load_program(struct drm_i915_private *dev_priv)
if (!intel_dmc_has_payload(dev_priv))
return;
+ disable_all_event_handlers(dev_priv);
+
assert_rpm_wakelock_held(&dev_priv->runtime_pm);
preempt_disable();
@@ -405,6 +434,21 @@ void intel_dmc_load_program(struct drm_i915_private *dev_priv)
disable_all_flip_queue_events(dev_priv);
}
+/**
+ * intel_dmc_disable_program() - disable the firmware
+ * @i915: i915 drm device
+ *
+ * Disable all event handlers in the firmware, making sure the firmware is
+ * inactive after the display is uninitialized.
+ */
+void intel_dmc_disable_program(struct drm_i915_private *i915)
+{
+ if (!intel_dmc_has_payload(i915))
+ return;
+
+ disable_all_event_handlers(i915);
+}
+
void assert_dmc_loaded(struct drm_i915_private *i915)
{
drm_WARN_ONCE(&i915->drm,