Commit e0ad3c64 authored by Sujaritha Sundaresan's avatar Sujaritha Sundaresan Committed by Chris Wilson

drm/i915/guc: Splitting CT channel open/close functions

The aim of this patch is to allow enabling and disabling
of CTB without requiring the mutex lock.

v2: Phasing out ctch_is_enabled function and replacing it with
    ctch->enabled (Daniele)

Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Signed-off-by: default avatarSujaritha Sundaresan <sujaritha.sundaresan@intel.com>
Reviewed-by: default avatarDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20190220013927.9488-2-sujaritha.sundaresan@intel.com
parent 9ce25e72
...@@ -203,11 +203,19 @@ int intel_guc_init(struct intel_guc *guc) ...@@ -203,11 +203,19 @@ int intel_guc_init(struct intel_guc *guc)
goto err_log; goto err_log;
GEM_BUG_ON(!guc->ads_vma); GEM_BUG_ON(!guc->ads_vma);
if (HAS_GUC_CT(dev_priv)) {
ret = intel_guc_ct_init(&guc->ct);
if (ret)
goto err_ads;
}
/* We need to notify the guc whenever we change the GGTT */ /* We need to notify the guc whenever we change the GGTT */
i915_ggtt_enable_guc(dev_priv); i915_ggtt_enable_guc(dev_priv);
return 0; return 0;
err_ads:
intel_guc_ads_destroy(guc);
err_log: err_log:
intel_guc_log_destroy(&guc->log); intel_guc_log_destroy(&guc->log);
err_shared: err_shared:
...@@ -222,6 +230,10 @@ void intel_guc_fini(struct intel_guc *guc) ...@@ -222,6 +230,10 @@ void intel_guc_fini(struct intel_guc *guc)
struct drm_i915_private *dev_priv = guc_to_i915(guc); struct drm_i915_private *dev_priv = guc_to_i915(guc);
i915_ggtt_disable_guc(dev_priv); i915_ggtt_disable_guc(dev_priv);
if (HAS_GUC_CT(dev_priv))
intel_guc_ct_fini(&guc->ct);
intel_guc_ads_destroy(guc); intel_guc_ads_destroy(guc);
intel_guc_log_destroy(&guc->log); intel_guc_log_destroy(&guc->log);
guc_shared_data_destroy(guc); guc_shared_data_destroy(guc);
......
...@@ -140,11 +140,6 @@ static int guc_action_deregister_ct_buffer(struct intel_guc *guc, ...@@ -140,11 +140,6 @@ static int guc_action_deregister_ct_buffer(struct intel_guc *guc,
return err; return err;
} }
static bool ctch_is_open(struct intel_guc_ct_channel *ctch)
{
return ctch->vma != NULL;
}
static int ctch_init(struct intel_guc *guc, static int ctch_init(struct intel_guc *guc,
struct intel_guc_ct_channel *ctch) struct intel_guc_ct_channel *ctch)
{ {
...@@ -214,25 +209,21 @@ static int ctch_init(struct intel_guc *guc, ...@@ -214,25 +209,21 @@ static int ctch_init(struct intel_guc *guc,
static void ctch_fini(struct intel_guc *guc, static void ctch_fini(struct intel_guc *guc,
struct intel_guc_ct_channel *ctch) struct intel_guc_ct_channel *ctch)
{ {
GEM_BUG_ON(ctch->enabled);
i915_vma_unpin_and_release(&ctch->vma, I915_VMA_RELEASE_MAP); i915_vma_unpin_and_release(&ctch->vma, I915_VMA_RELEASE_MAP);
} }
static int ctch_open(struct intel_guc *guc, static int ctch_enable(struct intel_guc *guc,
struct intel_guc_ct_channel *ctch) struct intel_guc_ct_channel *ctch)
{ {
u32 base; u32 base;
int err; int err;
int i; int i;
CT_DEBUG_DRIVER("CT: channel %d reopen=%s\n",
ctch->owner, yesno(ctch_is_open(ctch)));
if (!ctch->vma) {
err = ctch_init(guc, ctch);
if (unlikely(err))
goto err_out;
GEM_BUG_ON(!ctch->vma); GEM_BUG_ON(!ctch->vma);
}
GEM_BUG_ON(ctch->enabled);
/* vma should be already allocated and map'ed */ /* vma should be already allocated and map'ed */
base = intel_guc_ggtt_offset(guc, ctch->vma); base = intel_guc_ggtt_offset(guc, ctch->vma);
...@@ -255,7 +246,7 @@ static int ctch_open(struct intel_guc *guc, ...@@ -255,7 +246,7 @@ static int ctch_open(struct intel_guc *guc,
base + PAGE_SIZE/4 * CTB_RECV, base + PAGE_SIZE/4 * CTB_RECV,
INTEL_GUC_CT_BUFFER_TYPE_RECV); INTEL_GUC_CT_BUFFER_TYPE_RECV);
if (unlikely(err)) if (unlikely(err))
goto err_fini; goto err_out;
err = guc_action_register_ct_buffer(guc, err = guc_action_register_ct_buffer(guc,
base + PAGE_SIZE/4 * CTB_SEND, base + PAGE_SIZE/4 * CTB_SEND,
...@@ -263,23 +254,25 @@ static int ctch_open(struct intel_guc *guc, ...@@ -263,23 +254,25 @@ static int ctch_open(struct intel_guc *guc,
if (unlikely(err)) if (unlikely(err))
goto err_deregister; goto err_deregister;
ctch->enabled = true;
return 0; return 0;
err_deregister: err_deregister:
guc_action_deregister_ct_buffer(guc, guc_action_deregister_ct_buffer(guc,
ctch->owner, ctch->owner,
INTEL_GUC_CT_BUFFER_TYPE_RECV); INTEL_GUC_CT_BUFFER_TYPE_RECV);
err_fini:
ctch_fini(guc, ctch);
err_out: err_out:
DRM_ERROR("CT: can't open channel %d; err=%d\n", ctch->owner, err); DRM_ERROR("CT: can't open channel %d; err=%d\n", ctch->owner, err);
return err; return err;
} }
static void ctch_close(struct intel_guc *guc, static void ctch_disable(struct intel_guc *guc,
struct intel_guc_ct_channel *ctch) struct intel_guc_ct_channel *ctch)
{ {
GEM_BUG_ON(!ctch_is_open(ctch)); GEM_BUG_ON(!ctch->enabled);
ctch->enabled = false;
guc_action_deregister_ct_buffer(guc, guc_action_deregister_ct_buffer(guc,
ctch->owner, ctch->owner,
...@@ -287,7 +280,6 @@ static void ctch_close(struct intel_guc *guc, ...@@ -287,7 +280,6 @@ static void ctch_close(struct intel_guc *guc,
guc_action_deregister_ct_buffer(guc, guc_action_deregister_ct_buffer(guc,
ctch->owner, ctch->owner,
INTEL_GUC_CT_BUFFER_TYPE_RECV); INTEL_GUC_CT_BUFFER_TYPE_RECV);
ctch_fini(guc, ctch);
} }
static u32 ctch_get_next_fence(struct intel_guc_ct_channel *ctch) static u32 ctch_get_next_fence(struct intel_guc_ct_channel *ctch)
...@@ -481,7 +473,7 @@ static int ctch_send(struct intel_guc_ct *ct, ...@@ -481,7 +473,7 @@ static int ctch_send(struct intel_guc_ct *ct,
u32 fence; u32 fence;
int err; int err;
GEM_BUG_ON(!ctch_is_open(ctch)); GEM_BUG_ON(!ctch->enabled);
GEM_BUG_ON(!len); GEM_BUG_ON(!len);
GEM_BUG_ON(len & ~GUC_CT_MSG_LEN_MASK); GEM_BUG_ON(len & ~GUC_CT_MSG_LEN_MASK);
GEM_BUG_ON(!response_buf && response_buf_size); GEM_BUG_ON(!response_buf && response_buf_size);
...@@ -817,7 +809,7 @@ static void ct_process_host_channel(struct intel_guc_ct *ct) ...@@ -817,7 +809,7 @@ static void ct_process_host_channel(struct intel_guc_ct *ct)
u32 msg[GUC_CT_MSG_LEN_MASK + 1]; /* one extra dw for the header */ u32 msg[GUC_CT_MSG_LEN_MASK + 1]; /* one extra dw for the header */
int err = 0; int err = 0;
if (!ctch_is_open(ctch)) if (!ctch->enabled)
return; return;
do { do {
...@@ -848,6 +840,51 @@ static void intel_guc_to_host_event_handler_ct(struct intel_guc *guc) ...@@ -848,6 +840,51 @@ static void intel_guc_to_host_event_handler_ct(struct intel_guc *guc)
ct_process_host_channel(ct); ct_process_host_channel(ct);
} }
/**
* intel_guc_ct_init - Init CT communication
* @ct: pointer to CT struct
*
* Allocate memory required for communication via
* the CT channel.
*
* Shall only be called for platforms with HAS_GUC_CT.
*
* Return: 0 on success, a negative errno code on failure.
*/
int intel_guc_ct_init(struct intel_guc_ct *ct)
{
struct intel_guc *guc = ct_to_guc(ct);
struct intel_guc_ct_channel *ctch = &ct->host_channel;
int err;
err = ctch_init(guc, ctch);
if (unlikely(err)) {
DRM_ERROR("CT: can't open channel %d; err=%d\n",
ctch->owner, err);
return err;
}
GEM_BUG_ON(!ctch->vma);
return 0;
}
/**
* intel_guc_ct_fini - Fini CT communication
* @ct: pointer to CT struct
*
* Deallocate memory required for communication via
* the CT channel.
*
* Shall only be called for platforms with HAS_GUC_CT.
*/
void intel_guc_ct_fini(struct intel_guc_ct *ct)
{
struct intel_guc *guc = ct_to_guc(ct);
struct intel_guc_ct_channel *ctch = &ct->host_channel;
ctch_fini(guc, ctch);
}
/** /**
* intel_guc_ct_enable - Enable buffer based command transport. * intel_guc_ct_enable - Enable buffer based command transport.
* @ct: pointer to CT struct * @ct: pointer to CT struct
...@@ -865,7 +902,10 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct) ...@@ -865,7 +902,10 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)
GEM_BUG_ON(!HAS_GUC_CT(i915)); GEM_BUG_ON(!HAS_GUC_CT(i915));
err = ctch_open(guc, ctch); if (ctch->enabled)
return 0;
err = ctch_enable(guc, ctch);
if (unlikely(err)) if (unlikely(err))
return err; return err;
...@@ -890,10 +930,10 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct) ...@@ -890,10 +930,10 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct)
GEM_BUG_ON(!HAS_GUC_CT(i915)); GEM_BUG_ON(!HAS_GUC_CT(i915));
if (!ctch_is_open(ctch)) if (!ctch->enabled)
return; return;
ctch_close(guc, ctch); ctch_disable(guc, ctch);
/* Disable send */ /* Disable send */
guc->send = intel_guc_send_nop; guc->send = intel_guc_send_nop;
......
...@@ -66,6 +66,7 @@ struct intel_guc_ct_channel { ...@@ -66,6 +66,7 @@ struct intel_guc_ct_channel {
struct intel_guc_ct_buffer ctbs[2]; struct intel_guc_ct_buffer ctbs[2];
u32 owner; u32 owner;
u32 next_fence; u32 next_fence;
bool enabled;
}; };
/** Holds all command transport channels. /** Holds all command transport channels.
...@@ -90,6 +91,8 @@ struct intel_guc_ct { ...@@ -90,6 +91,8 @@ struct intel_guc_ct {
}; };
void intel_guc_ct_init_early(struct intel_guc_ct *ct); void intel_guc_ct_init_early(struct intel_guc_ct *ct);
int intel_guc_ct_init(struct intel_guc_ct *ct);
void intel_guc_ct_fini(struct intel_guc_ct *ct);
int intel_guc_ct_enable(struct intel_guc_ct *ct); int intel_guc_ct_enable(struct intel_guc_ct *ct);
void intel_guc_ct_disable(struct intel_guc_ct *ct); void intel_guc_ct_disable(struct intel_guc_ct *ct);
......
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