drm/i915/guc: reorder enable/disable communication steps

Make sure we always have CT buffers enabled when the interrupts are
enabled, so we can always handle interrupts from GuC. Also move the
setting of the guc->send and guc->handler functions to the GuC
communication control functions for consistency.

The reorder also fixes the onion unwinding of intel_uc_init_hw, because
guc_enable_communication would've left interrupts enabled when failing
to enable CTB.

v2: always retunr the result of ctch_enable() in
    intel_guc_ct_enable() (Michal)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110943
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20190621182123.31368-1-daniele.ceraolospurio@intel.com
This commit is contained in:
Daniele Ceraolo Spurio 2019-06-21 11:21:22 -07:00 committed by Chris Wilson
parent 80fc1c1991
commit e29cc1d7e8
3 changed files with 24 additions and 21 deletions

View File

@ -529,8 +529,8 @@ unlink:
/* /*
* Command Transport (CT) buffer based GuC send function. * Command Transport (CT) buffer based GuC send function.
*/ */
static int intel_guc_send_ct(struct intel_guc *guc, const u32 *action, u32 len, int intel_guc_send_ct(struct intel_guc *guc, const u32 *action, u32 len,
u32 *response_buf, u32 response_buf_size) u32 *response_buf, u32 response_buf_size)
{ {
struct intel_guc_ct *ct = &guc->ct; struct intel_guc_ct *ct = &guc->ct;
struct intel_guc_ct_channel *ctch = &ct->host_channel; struct intel_guc_ct_channel *ctch = &ct->host_channel;
@ -834,7 +834,7 @@ static void ct_process_host_channel(struct intel_guc_ct *ct)
* When we're communicating with the GuC over CT, GuC uses events * When we're communicating with the GuC over CT, GuC uses events
* to notify us about new messages being posted on the RECV buffer. * to notify us about new messages being posted on the RECV buffer.
*/ */
static void intel_guc_to_host_event_handler_ct(struct intel_guc *guc) void intel_guc_to_host_event_handler_ct(struct intel_guc *guc)
{ {
struct intel_guc_ct *ct = &guc->ct; struct intel_guc_ct *ct = &guc->ct;
@ -892,20 +892,11 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)
{ {
struct intel_guc *guc = ct_to_guc(ct); struct intel_guc *guc = ct_to_guc(ct);
struct intel_guc_ct_channel *ctch = &ct->host_channel; struct intel_guc_ct_channel *ctch = &ct->host_channel;
int err;
if (ctch->enabled) if (ctch->enabled)
return 0; return 0;
err = ctch_enable(guc, ctch); return ctch_enable(guc, ctch);
if (unlikely(err))
return err;
/* Switch into cmd transport buffer based send() */
guc->send = intel_guc_send_ct;
guc->handler = intel_guc_to_host_event_handler_ct;
DRM_INFO("CT: %s\n", enableddisabled(true));
return 0;
} }
/** /**
@ -921,9 +912,4 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct)
return; return;
ctch_disable(guc, ctch); ctch_disable(guc, ctch);
/* Disable send */
guc->send = intel_guc_send_nop;
guc->handler = intel_guc_to_host_event_handler_nop;
DRM_INFO("CT: %s\n", enableddisabled(false));
} }

View File

@ -101,4 +101,8 @@ static inline void intel_guc_ct_stop(struct intel_guc_ct *ct)
ct->host_channel.enabled = false; ct->host_channel.enabled = false;
} }
int intel_guc_send_ct(struct intel_guc *guc, const u32 *action, u32 len,
u32 *response_buf, u32 response_buf_size);
void intel_guc_to_host_event_handler_ct(struct intel_guc *guc);
#endif /* _INTEL_GUC_CT_H_ */ #endif /* _INTEL_GUC_CT_H_ */

View File

@ -235,9 +235,20 @@ static void guc_disable_interrupts(struct intel_guc *guc)
static int guc_enable_communication(struct intel_guc *guc) static int guc_enable_communication(struct intel_guc *guc)
{ {
int ret;
ret = intel_guc_ct_enable(&guc->ct);
if (ret)
return ret;
guc->send = intel_guc_send_ct;
guc->handler = intel_guc_to_host_event_handler_ct;
guc_enable_interrupts(guc); guc_enable_interrupts(guc);
return intel_guc_ct_enable(&guc->ct); DRM_INFO("GuC communication enabled\n");
return 0;
} }
static void guc_stop_communication(struct intel_guc *guc) static void guc_stop_communication(struct intel_guc *guc)
@ -250,12 +261,14 @@ static void guc_stop_communication(struct intel_guc *guc)
static void guc_disable_communication(struct intel_guc *guc) static void guc_disable_communication(struct intel_guc *guc)
{ {
intel_guc_ct_disable(&guc->ct);
guc_disable_interrupts(guc); guc_disable_interrupts(guc);
guc->send = intel_guc_send_nop; guc->send = intel_guc_send_nop;
guc->handler = intel_guc_to_host_event_handler_nop; guc->handler = intel_guc_to_host_event_handler_nop;
intel_guc_ct_disable(&guc->ct);
DRM_INFO("GuC communication disabled\n");
} }
int intel_uc_init_misc(struct drm_i915_private *i915) int intel_uc_init_misc(struct drm_i915_private *i915)