The GuC log contains a separate space used for crash dump.
We even get a separate notification for it. While we're not handling
crash differently yet, it makes sense to decouple the two right now to
simplify the following patches.

v2: Move guc_log_flush_irq_disable up to avoid movement in following
    patches (Sagar).

Signed-off-by: Michał Winiarski <michal.winiar...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospu...@intel.com>
Cc: Sagar Arun Kamble <sagar.a.kam...@intel.com>
Cc: Michal Wajdeczko <michal.wajdec...@intel.com>
Reviewed-by: Sagar Arun Kamble <sagar.a.kam...@intel.com>
---
 drivers/gpu/drm/i915/intel_guc.c     | 25 ++++++++++---------------
 drivers/gpu/drm/i915/intel_guc.h     |  2 ++
 drivers/gpu/drm/i915/intel_guc_log.c | 30 +++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_uc.c      | 14 +++++---------
 4 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
index 25f92291fd40..0d92caf6a83f 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -67,6 +67,7 @@ void intel_guc_init_early(struct intel_guc *guc)
        intel_guc_log_init_early(guc);
 
        mutex_init(&guc->send_mutex);
+       spin_lock_init(&guc->irq_lock);
        guc->send = intel_guc_send_nop;
        guc->notify = gen8_guc_raise_irq;
 }
@@ -367,7 +368,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*action, u32 len)
 void intel_guc_to_host_event_handler(struct intel_guc *guc)
 {
        struct drm_i915_private *dev_priv = guc_to_i915(guc);
-       u32 msg, flush;
+       u32 msg, val;
 
        /*
         * Sample the log buffer flush related bits & clear them out now
@@ -380,24 +381,18 @@ void intel_guc_to_host_event_handler(struct intel_guc 
*guc)
         * could happen that GuC sets the bit for 2nd interrupt but Host
         * clears out the bit on handling the 1st interrupt.
         */
-
-       msg = I915_READ(SOFT_SCRATCH(15));
-       flush = msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED |
-                      INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER);
-       if (flush) {
-               /* Clear the message bits that are handled */
-               I915_WRITE(SOFT_SCRATCH(15), msg & ~flush);
-
-               /* Handle flush interrupt in bottom half */
+       spin_lock(&guc->irq_lock);
+       val = I915_READ(SOFT_SCRATCH(15));
+       msg = val & guc->msg_enabled_mask;
+       I915_WRITE(SOFT_SCRATCH(15), val & ~msg);
+       spin_unlock(&guc->irq_lock);
+
+       if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
+                  INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)) {
                queue_work(guc->log.runtime.flush_wq,
                           &guc->log.runtime.flush_work);
 
                guc->log.flush_interrupt_count++;
-       } else {
-               /*
-                * Not clearing of unhandled event bits won't result in
-                * re-triggering of the interrupt.
-                */
        }
 }
 
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 6d5aebe55039..78d9840cd309 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -53,7 +53,9 @@ struct intel_guc {
        struct drm_i915_gem_object *load_err_log;
 
        /* intel_guc_recv interrupt related state */
+       spinlock_t irq_lock;
        bool interrupts_enabled;
+       unsigned int msg_enabled_mask;
 
        struct i915_vma *ads_vma;
        struct i915_vma *stage_desc_pool;
diff --git a/drivers/gpu/drm/i915/intel_guc_log.c 
b/drivers/gpu/drm/i915/intel_guc_log.c
index 90b395f34808..89cb3939467f 100644
--- a/drivers/gpu/drm/i915/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/intel_guc_log.c
@@ -592,6 +592,22 @@ int intel_guc_log_create(struct intel_guc *guc)
        return ret;
 }
 
+static void guc_log_flush_irq_enable(struct intel_guc *guc)
+{
+       spin_lock_irq(&guc->irq_lock);
+       guc->msg_enabled_mask |= INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
+                                INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED;
+       spin_unlock_irq(&guc->irq_lock);
+}
+
+static void guc_log_flush_irq_disable(struct intel_guc *guc)
+{
+       spin_lock_irq(&guc->irq_lock);
+       guc->msg_enabled_mask &= ~(INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
+                                  INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
+       spin_unlock_irq(&guc->irq_lock);
+}
+
 void intel_guc_log_destroy(struct intel_guc *guc)
 {
        guc_log_runtime_destroy(guc);
@@ -696,12 +712,7 @@ int intel_guc_log_register(struct intel_guc *guc)
        if (ret)
                goto err_runtime;
 
-       /* GuC logging is currently the only user of Guc2Host interrupts */
-       mutex_lock(&i915->drm.struct_mutex);
-       intel_runtime_pm_get(i915);
-       gen9_enable_guc_interrupts(i915);
-       intel_runtime_pm_put(i915);
-       mutex_unlock(&i915->drm.struct_mutex);
+       guc_log_flush_irq_enable(guc);
 
        return 0;
 
@@ -719,6 +730,8 @@ void intel_guc_log_unregister(struct intel_guc *guc)
 {
        struct drm_i915_private *i915 = guc_to_i915(guc);
 
+       guc_log_flush_irq_disable(guc);
+
        /*
         * Once logging is disabled, GuC won't generate logs & send an
         * interrupt. But there could be some data in the log buffer
@@ -728,11 +741,6 @@ void intel_guc_log_unregister(struct intel_guc *guc)
        guc_flush_logs(guc);
 
        mutex_lock(&i915->drm.struct_mutex);
-       /* GuC logging is currently the only user of Guc2Host interrupts */
-       intel_runtime_pm_get(i915);
-       gen9_disable_guc_interrupts(i915);
-       intel_runtime_pm_put(i915);
-
        guc_log_runtime_destroy(guc);
        mutex_unlock(&i915->drm.struct_mutex);
 
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index 1c1a00df010b..90d2f38e22c9 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -245,6 +245,8 @@ static int guc_enable_communication(struct intel_guc *guc)
 {
        struct drm_i915_private *dev_priv = guc_to_i915(guc);
 
+       gen9_enable_guc_interrupts(dev_priv);
+
        if (HAS_GUC_CT(dev_priv))
                return intel_guc_enable_ct(guc);
 
@@ -259,6 +261,8 @@ static void guc_disable_communication(struct intel_guc *guc)
        if (HAS_GUC_CT(dev_priv))
                intel_guc_disable_ct(guc);
 
+       gen9_disable_guc_interrupts(dev_priv);
+
        guc->send = intel_guc_send_nop;
 }
 
@@ -397,12 +401,9 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
        }
 
        if (USES_GUC_SUBMISSION(dev_priv)) {
-               if (i915_modparams.guc_log_level)
-                       gen9_enable_guc_interrupts(dev_priv);
-
                ret = intel_guc_submission_enable(guc);
                if (ret)
-                       goto err_interrupts;
+                       goto err_communication;
        }
 
        dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n",
@@ -417,8 +418,6 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
        /*
         * We've failed to load the firmware :(
         */
-err_interrupts:
-       gen9_disable_guc_interrupts(dev_priv);
 err_communication:
        guc_disable_communication(guc);
 err_log_capture:
@@ -448,9 +447,6 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
                intel_guc_submission_disable(guc);
 
        guc_disable_communication(guc);
-
-       if (USES_GUC_SUBMISSION(dev_priv))
-               gen9_disable_guc_interrupts(dev_priv);
 }
 
 int intel_uc_suspend(struct drm_i915_private *i915)
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to