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

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
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -203,11 +203,19 @@ int intel_guc_init(struct intel_guc *guc)
		goto err_log;
	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 */
	i915_ggtt_enable_guc(dev_priv);

	return 0;

err_ads:
	intel_guc_ads_destroy(guc);
err_log:
	intel_guc_log_destroy(&guc->log);
err_shared:
@@ -222,6 +230,10 @@ void intel_guc_fini(struct intel_guc *guc)
	struct drm_i915_private *dev_priv = guc_to_i915(guc);

	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_log_destroy(&guc->log);
	guc_shared_data_destroy(guc);
+67 −27
Original line number Diff line number Diff line
@@ -140,11 +140,6 @@ static int guc_action_deregister_ct_buffer(struct intel_guc *guc,
	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,
		     struct intel_guc_ct_channel *ctch)
{
@@ -214,25 +209,21 @@ err_out:
static void ctch_fini(struct intel_guc *guc,
		      struct intel_guc_ct_channel *ctch)
{
	GEM_BUG_ON(ctch->enabled);

	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)
{
	u32 base;
	int err;
	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->enabled);

	/* vma should be already allocated and map'ed */
	base = intel_guc_ggtt_offset(guc, ctch->vma);
@@ -255,7 +246,7 @@ static int ctch_open(struct intel_guc *guc,
					    base + PAGE_SIZE/4 * CTB_RECV,
					    INTEL_GUC_CT_BUFFER_TYPE_RECV);
	if (unlikely(err))
		goto err_fini;
		goto err_out;

	err = guc_action_register_ct_buffer(guc,
					    base + PAGE_SIZE/4 * CTB_SEND,
@@ -263,23 +254,25 @@ static int ctch_open(struct intel_guc *guc,
	if (unlikely(err))
		goto err_deregister;

	ctch->enabled = true;

	return 0;

err_deregister:
	guc_action_deregister_ct_buffer(guc,
					ctch->owner,
					INTEL_GUC_CT_BUFFER_TYPE_RECV);
err_fini:
	ctch_fini(guc, ctch);
err_out:
	DRM_ERROR("CT: can't open channel %d; err=%d\n", ctch->owner, 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)
{
	GEM_BUG_ON(!ctch_is_open(ctch));
	GEM_BUG_ON(!ctch->enabled);

	ctch->enabled = false;

	guc_action_deregister_ct_buffer(guc,
					ctch->owner,
@@ -287,7 +280,6 @@ static void ctch_close(struct intel_guc *guc,
	guc_action_deregister_ct_buffer(guc,
					ctch->owner,
					INTEL_GUC_CT_BUFFER_TYPE_RECV);
	ctch_fini(guc, 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,
	u32 fence;
	int err;

	GEM_BUG_ON(!ctch_is_open(ctch));
	GEM_BUG_ON(!ctch->enabled);
	GEM_BUG_ON(!len);
	GEM_BUG_ON(len & ~GUC_CT_MSG_LEN_MASK);
	GEM_BUG_ON(!response_buf && response_buf_size);
@@ -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 */
	int err = 0;

	if (!ctch_is_open(ctch))
	if (!ctch->enabled)
		return;

	do {
@@ -848,6 +840,51 @@ static void intel_guc_to_host_event_handler_ct(struct intel_guc *guc)
	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.
 * @ct: pointer to CT struct
@@ -865,7 +902,10 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)

	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))
		return err;

@@ -890,10 +930,10 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct)

	GEM_BUG_ON(!HAS_GUC_CT(i915));

	if (!ctch_is_open(ctch))
	if (!ctch->enabled)
		return;

	ctch_close(guc, ctch);
	ctch_disable(guc, ctch);

	/* Disable send */
	guc->send = intel_guc_send_nop;
+3 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ struct intel_guc_ct_channel {
	struct intel_guc_ct_buffer ctbs[2];
	u32 owner;
	u32 next_fence;
	bool enabled;
};

/** Holds all command transport channels.
@@ -90,6 +91,8 @@ struct intel_guc_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);
void intel_guc_ct_disable(struct intel_guc_ct *ct);