Commit eacd8391 authored by Michał Winiarski's avatar Michał Winiarski Committed by Chris Wilson

drm/i915/guc: Keep GuC interrupts enabled when using GuC

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).
v3: s/guc_log_flush_irq_*/guc_flush_log_msg_*, rebase after mass rename
Signed-off-by: default avatarMichał Winiarski <michal.winiarski@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com> (v2)
Reviewed-by: default avatarSagar Arun Kamble <sagar.a.kamble@intel.com>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20180319095348.9716-1-michal.winiarski@intel.com
parent ad260ab3
...@@ -67,6 +67,7 @@ void intel_guc_init_early(struct intel_guc *guc) ...@@ -67,6 +67,7 @@ void intel_guc_init_early(struct intel_guc *guc)
intel_guc_log_init_early(&guc->log); intel_guc_log_init_early(&guc->log);
mutex_init(&guc->send_mutex); mutex_init(&guc->send_mutex);
spin_lock_init(&guc->irq_lock);
guc->send = intel_guc_send_nop; guc->send = intel_guc_send_nop;
guc->notify = gen8_guc_raise_irq; guc->notify = gen8_guc_raise_irq;
} }
...@@ -368,7 +369,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len) ...@@ -368,7 +369,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) void intel_guc_to_host_event_handler(struct intel_guc *guc)
{ {
struct drm_i915_private *dev_priv = guc_to_i915(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 * Sample the log buffer flush related bits & clear them out now
...@@ -381,24 +382,18 @@ void intel_guc_to_host_event_handler(struct intel_guc *guc) ...@@ -381,24 +382,18 @@ void intel_guc_to_host_event_handler(struct intel_guc *guc)
* could happen that GuC sets the bit for 2nd interrupt but Host * could happen that GuC sets the bit for 2nd interrupt but Host
* clears out the bit on handling the 1st interrupt. * clears out the bit on handling the 1st interrupt.
*/ */
spin_lock(&guc->irq_lock);
msg = I915_READ(SOFT_SCRATCH(15)); val = I915_READ(SOFT_SCRATCH(15));
flush = msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED | msg = val & guc->msg_enabled_mask;
INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER); I915_WRITE(SOFT_SCRATCH(15), val & ~msg);
if (flush) { spin_unlock(&guc->irq_lock);
/* Clear the message bits that are handled */
I915_WRITE(SOFT_SCRATCH(15), msg & ~flush); if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)) {
/* Handle flush interrupt in bottom half */
queue_work(guc->log.runtime.flush_wq, queue_work(guc->log.runtime.flush_wq,
&guc->log.runtime.flush_work); &guc->log.runtime.flush_work);
guc->log.flush_interrupt_count++; guc->log.flush_interrupt_count++;
} else {
/*
* Not clearing of unhandled event bits won't result in
* re-triggering of the interrupt.
*/
} }
} }
......
...@@ -56,7 +56,9 @@ struct intel_guc { ...@@ -56,7 +56,9 @@ struct intel_guc {
struct drm_i915_gem_object *load_err_log; struct drm_i915_gem_object *load_err_log;
/* intel_guc_recv interrupt related state */ /* intel_guc_recv interrupt related state */
spinlock_t irq_lock;
bool interrupts_enabled; bool interrupts_enabled;
unsigned int msg_enabled_mask;
struct i915_vma *ads_vma; struct i915_vma *ads_vma;
struct i915_vma *stage_desc_pool; struct i915_vma *stage_desc_pool;
......
...@@ -73,6 +73,22 @@ static int guc_log_control(struct intel_guc *guc, bool enable, u32 verbosity) ...@@ -73,6 +73,22 @@ static int guc_log_control(struct intel_guc *guc, bool enable, u32 verbosity)
return intel_guc_send(guc, action, ARRAY_SIZE(action)); return intel_guc_send(guc, action, ARRAY_SIZE(action));
} }
static void guc_flush_log_msg_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_flush_log_msg_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);
}
static inline struct intel_guc *log_to_guc(struct intel_guc_log *log) static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
{ {
return container_of(log, struct intel_guc, log); return container_of(log, struct intel_guc, log);
...@@ -709,12 +725,7 @@ int intel_guc_log_register(struct intel_guc_log *log) ...@@ -709,12 +725,7 @@ int intel_guc_log_register(struct intel_guc_log *log)
if (ret) if (ret)
goto err_runtime; goto err_runtime;
/* GuC logging is currently the only user of Guc2Host interrupts */ guc_flush_log_msg_enable(guc);
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);
return 0; return 0;
...@@ -733,6 +744,8 @@ void intel_guc_log_unregister(struct intel_guc_log *log) ...@@ -733,6 +744,8 @@ void intel_guc_log_unregister(struct intel_guc_log *log)
struct intel_guc *guc = log_to_guc(log); struct intel_guc *guc = log_to_guc(log);
struct drm_i915_private *i915 = guc_to_i915(guc); struct drm_i915_private *i915 = guc_to_i915(guc);
guc_flush_log_msg_disable(guc);
/* /*
* Once logging is disabled, GuC won't generate logs & send an * Once logging is disabled, GuC won't generate logs & send an
* interrupt. But there could be some data in the log buffer * interrupt. But there could be some data in the log buffer
...@@ -742,12 +755,6 @@ void intel_guc_log_unregister(struct intel_guc_log *log) ...@@ -742,12 +755,6 @@ void intel_guc_log_unregister(struct intel_guc_log *log)
guc_flush_logs(log); guc_flush_logs(log);
mutex_lock(&i915->drm.struct_mutex); 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(log); guc_log_runtime_destroy(log);
mutex_unlock(&i915->drm.struct_mutex); mutex_unlock(&i915->drm.struct_mutex);
......
...@@ -247,6 +247,8 @@ static int guc_enable_communication(struct intel_guc *guc) ...@@ -247,6 +247,8 @@ static int guc_enable_communication(struct intel_guc *guc)
{ {
struct drm_i915_private *dev_priv = guc_to_i915(guc); struct drm_i915_private *dev_priv = guc_to_i915(guc);
gen9_enable_guc_interrupts(dev_priv);
if (HAS_GUC_CT(dev_priv)) if (HAS_GUC_CT(dev_priv))
return intel_guc_enable_ct(guc); return intel_guc_enable_ct(guc);
...@@ -261,6 +263,8 @@ static void guc_disable_communication(struct intel_guc *guc) ...@@ -261,6 +263,8 @@ static void guc_disable_communication(struct intel_guc *guc)
if (HAS_GUC_CT(dev_priv)) if (HAS_GUC_CT(dev_priv))
intel_guc_disable_ct(guc); intel_guc_disable_ct(guc);
gen9_disable_guc_interrupts(dev_priv);
guc->send = intel_guc_send_nop; guc->send = intel_guc_send_nop;
} }
...@@ -413,12 +417,9 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) ...@@ -413,12 +417,9 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
} }
if (USES_GUC_SUBMISSION(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); ret = intel_guc_submission_enable(guc);
if (ret) if (ret)
goto err_interrupts; goto err_communication;
} }
dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n", dev_info(dev_priv->drm.dev, "GuC firmware version %u.%u\n",
...@@ -433,8 +434,6 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) ...@@ -433,8 +434,6 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
/* /*
* We've failed to load the firmware :( * We've failed to load the firmware :(
*/ */
err_interrupts:
gen9_disable_guc_interrupts(dev_priv);
err_communication: err_communication:
guc_disable_communication(guc); guc_disable_communication(guc);
err_log_capture: err_log_capture:
...@@ -464,9 +463,6 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv) ...@@ -464,9 +463,6 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
intel_guc_submission_disable(guc); intel_guc_submission_disable(guc);
guc_disable_communication(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) int intel_uc_suspend(struct drm_i915_private *i915)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment