Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 754eebb8 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Keep the active draw context until it is switched out"

parents 3888497f 6f757d10
Loading
Loading
Loading
Loading
+9 −19
Original line number Diff line number Diff line
@@ -1376,6 +1376,8 @@ static int _adreno_start(struct adreno_device *adreno_dev)
	if (regulator_left_on)
		_soft_reset(adreno_dev);

	adreno_ringbuffer_set_global(adreno_dev, 0);

	status = kgsl_mmu_start(device);
	if (status)
		goto error_pwr_off;
@@ -1692,10 +1694,6 @@ int adreno_reset(struct kgsl_device *device, int fault)
	else
		kgsl_pwrctrl_change_state(device, KGSL_STATE_NAP);

	/* Set the page table back to the default page table */
	kgsl_mmu_set_pt(&device->mmu, device->mmu.defaultpagetable);
	adreno_ringbuffer_set_global(adreno_dev, 0);

	return ret;
}

@@ -2138,6 +2136,10 @@ static int adreno_soft_reset(struct kgsl_device *device)
	/* Reset the GPU */
	_soft_reset(adreno_dev);

	/* Set the page table back to the default page table */
	adreno_ringbuffer_set_global(adreno_dev, 0);
	kgsl_mmu_set_pt(&device->mmu, device->mmu.defaultpagetable);

	/* start of new CFF after reset */
	kgsl_cffdump_open(device);

@@ -2309,23 +2311,11 @@ static int adreno_drain(struct kgsl_device *device)
/* Caller must hold the device mutex. */
static int adreno_suspend_context(struct kgsl_device *device)
{
	int status = 0;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	/* process any profiling results that are available */
	adreno_profile_process_results(adreno_dev);

	status = adreno_idle(device);
	if (status)
		return status;
	/* set the device to default pagetable */
	kgsl_mmu_set_pt(&device->mmu, device->mmu.defaultpagetable);
	adreno_ringbuffer_set_global(adreno_dev, 0);
	adreno_profile_process_results(ADRENO_DEVICE(device));

	/* set ringbuffers to NULL ctxt */
	adreno_set_active_ctxs_null(adreno_dev);

	return status;
	/* Wait for the device to go idle */
	return adreno_idle(device);
}

/**
+18 −31
Original line number Diff line number Diff line
@@ -452,7 +452,7 @@ void adreno_drawctxt_detach(struct kgsl_context *context)
	struct adreno_device *adreno_dev;
	struct adreno_context *drawctxt;
	struct adreno_ringbuffer *rb;
	int ret = 0, count, i;
	int ret, count, i;
	struct kgsl_cmdbatch *list[ADRENO_CONTEXT_CMDQUEUE_SIZE];

	if (context == NULL)
@@ -467,33 +467,6 @@ void adreno_drawctxt_detach(struct kgsl_context *context)
	list_del_init(&drawctxt->active_node);
	spin_unlock(&adreno_dev->active_list_lock);

	/* deactivate context */
	mutex_lock(&device->mutex);
	if (rb->drawctxt_active == drawctxt) {
		if (adreno_dev->cur_rb == rb) {
			if (!kgsl_active_count_get(device)) {
				ret = adreno_drawctxt_switch(adreno_dev, rb,
					NULL, 0);
				kgsl_active_count_put(device);
			} else
				BUG();
		} else
			ret = adreno_drawctxt_switch(adreno_dev, rb, NULL, 0);

		if (ret != 0) {
			KGSL_DRV_ERR(device,
				"Unable to switch the context to NULL: %d\n",
				ret);
		}

		/*
		 * Keep going ahead if we can't switch the context - failure
		 * isn't always fatal, but sometimes it is. I like those
		 * chances!
		 */
	}
	mutex_unlock(&device->mutex);

	spin_lock(&drawctxt->lock);
	count = drawctxt_detach_cmdbatches(drawctxt, list);
	spin_unlock(&drawctxt->lock);
@@ -562,6 +535,15 @@ void adreno_drawctxt_destroy(struct kgsl_context *context)
	kfree(drawctxt);
}

static void _drawctxt_switch_wait_callback(struct kgsl_device *device,
		struct kgsl_event_group *group,
		void *priv, int result)
{
	struct adreno_context *drawctxt = (struct adreno_context *) priv;

	kgsl_context_put(&drawctxt->base);
}

/**
 * adreno_drawctxt_switch - switch the current draw context in a given RB
 * @adreno_dev - The 3D device that owns the context
@@ -613,9 +595,14 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev,
	if (ret)
		return ret;

	/* Put the old instance of the active drawctxt */
	if (rb->drawctxt_active)
	if (rb->drawctxt_active) {
		/* Wait for the timestamp to expire */
		if (kgsl_add_event(device, &rb->events, rb->timestamp,
			_drawctxt_switch_wait_callback,
			rb->drawctxt_active)) {
			kgsl_context_put(&rb->drawctxt_active->base);
		}
	}

	rb->drawctxt_active = drawctxt;
	return 0;
+10 −28
Original line number Diff line number Diff line
@@ -1449,27 +1449,27 @@ done:
	return ret;
}

static int kgsl_iommu_set_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt);

static int kgsl_iommu_start(struct kgsl_mmu *mmu)
{
	int status;
	struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
	struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];

	status = _setup_user_context(mmu);
	if (status)
		return status;

	status = _setup_secure_context(mmu);
	if (status)
	if (status) {
		_detach_context(&iommu->ctx[KGSL_IOMMU_CONTEXT_USER]);
	else {
		kgsl_iommu_enable_clk(mmu);
		KGSL_IOMMU_SET_CTX_REG(ctx, TLBIALL, 1);
		kgsl_iommu_disable_clk(mmu);
	}
		return status;
	}

	/* Make sure the hardware is programmed to the default pagetable */
	return kgsl_iommu_set_pt(mmu, mmu->defaultpagetable);
}

static int
kgsl_iommu_unmap_offset(struct kgsl_pagetable *pt,
		struct kgsl_memdesc *memdesc, uint64_t addr,
@@ -1704,23 +1704,15 @@ kgsl_iommu_get_current_ttbr0(struct kgsl_mmu *mmu)
 *
 * Return - void
 */
static int kgsl_iommu_set_pt(struct kgsl_mmu *mmu,
				struct kgsl_pagetable *pt)
static int kgsl_iommu_set_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
{
	struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
	struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
	struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
	int ret = 0;
	uint64_t ttbr0, temp;
	unsigned int contextidr;
	unsigned long wait_for_flush;

	/*
	 * If using a global pagetable, we can skip all this
	 * because the pagetable will be set up by the iommu
	 * driver and never changed at runtime.
	 */
	if (!kgsl_mmu_is_perprocess(mmu))
	if ((pt != mmu->defaultpagetable) && !kgsl_mmu_is_perprocess(mmu))
		return 0;

	kgsl_iommu_enable_clk(mmu);
@@ -1728,14 +1720,6 @@ static int kgsl_iommu_set_pt(struct kgsl_mmu *mmu,
	ttbr0 = kgsl_mmu_pagetable_get_ttbr0(pt);
	contextidr = kgsl_mmu_pagetable_get_contextidr(pt);

	/*
	 * Taking the liberty to spin idle since this codepath
	 * is invoked when we can spin safely for it to be idle
	 */
	ret = adreno_spin_idle(ADRENO_DEVICE(device), ADRENO_IDLE_TIMEOUT);
	if (ret)
		return ret;

	KGSL_IOMMU_SET_CTX_REG_Q(ctx, TTBR0, ttbr0);
	KGSL_IOMMU_SET_CTX_REG(ctx, CONTEXTIDR, contextidr);

@@ -1764,10 +1748,8 @@ static int kgsl_iommu_set_pt(struct kgsl_mmu *mmu,
		cpu_relax();
	}

	/* Disable smmu clock */
	kgsl_iommu_disable_clk(mmu);

	return ret;
	return 0;
}

/*