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

Commit a8002ec2 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt
Browse files

msm: kgsl: Add context unregister HFI



This is a special sequence because we don't want to wait for
the ack back while holding the device mutex. This means, we
have to define a new sequence of unlocking the device mutex
before we begin our wait for ack.

Change-Id: I3ea27bdccd66cdaafd8cff6cc1366848c1a4bea6
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent 019b8504
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -806,7 +806,7 @@ struct adreno_gpudev {
	int (*preemption_init)(struct adreno_device *adreno_dev);
	void (*preemption_schedule)(struct adreno_device *adreno_dev);
	int (*preemption_context_init)(struct kgsl_context *context);
	void (*preemption_context_destroy)(struct kgsl_context *context);
	void (*context_detach)(struct adreno_context *drawctxt);
	void (*clk_set_options)(struct adreno_device *adreno_dev,
				const char *name, struct clk *clk, bool on);
	void (*pre_reset)(struct adreno_device *adreno_dev);
+1 −6
Original line number Diff line number Diff line
@@ -2801,7 +2801,6 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
	.preemption_schedule = a6xx_preemption_schedule,
	.set_marker = a6xx_set_marker,
	.preemption_context_init = a6xx_preemption_context_init,
	.preemption_context_destroy = a6xx_preemption_context_destroy,
	.sptprac_is_on = a6xx_sptprac_is_on,
	.ccu_invalidate = a6xx_ccu_invalidate,
	.perfcounter_update = a6xx_perfcounter_update,
@@ -2824,7 +2823,7 @@ struct adreno_gpudev adreno_a6xx_hwsched_gpudev = {
	.read_throttling_counters = a6xx_read_throttling_counters,
	.iommu_fault_block = a6xx_iommu_fault_block,
	.preemption_context_init = a6xx_preemption_context_init,
	.preemption_context_destroy = a6xx_preemption_context_destroy,
	.context_detach = a6xx_hwsched_context_detach,
	.perfcounter_update = a6xx_perfcounter_update,
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
	.coresight = {&a6xx_coresight, &a6xx_coresight_cx},
@@ -2856,7 +2855,6 @@ struct adreno_gpudev adreno_a6xx_gmu_gpudev = {
	.preemption_schedule = a6xx_preemption_schedule,
	.set_marker = a6xx_set_marker,
	.preemption_context_init = a6xx_preemption_context_init,
	.preemption_context_destroy = a6xx_preemption_context_destroy,
	.sptprac_is_on = a6xx_sptprac_is_on,
	.ccu_invalidate = a6xx_ccu_invalidate,
	.perfcounter_update = a6xx_perfcounter_update,
@@ -2890,7 +2888,6 @@ struct adreno_gpudev adreno_a6xx_rgmu_gpudev = {
	.preemption_schedule = a6xx_preemption_schedule,
	.set_marker = a6xx_set_marker,
	.preemption_context_init = a6xx_preemption_context_init,
	.preemption_context_destroy = a6xx_preemption_context_destroy,
	.sptprac_is_on = a6xx_sptprac_is_on,
	.ccu_invalidate = a6xx_ccu_invalidate,
	.perfcounter_update = a6xx_perfcounter_update,
@@ -2924,7 +2921,6 @@ struct adreno_gpudev adreno_a619_holi_gpudev = {
	.preemption_schedule = a6xx_preemption_schedule,
	.set_marker = a6xx_set_marker,
	.preemption_context_init = a6xx_preemption_context_init,
	.preemption_context_destroy = a6xx_preemption_context_destroy,
	.sptprac_is_on = a6xx_sptprac_is_on,
	.ccu_invalidate = a6xx_ccu_invalidate,
	.perfcounter_update = a6xx_perfcounter_update,
@@ -2961,7 +2957,6 @@ struct adreno_gpudev adreno_a630_gpudev = {
	.preemption_schedule = a6xx_preemption_schedule,
	.set_marker = a6xx_set_marker,
	.preemption_context_init = a6xx_preemption_context_init,
	.preemption_context_destroy = a6xx_preemption_context_destroy,
	.sptprac_is_on = a6xx_sptprac_is_on,
	.ccu_invalidate = a6xx_ccu_invalidate,
	.perfcounter_update = a6xx_perfcounter_update,
+25 −2
Original line number Diff line number Diff line
@@ -177,6 +177,21 @@ static void a6xx_hwsched_active_count_put(struct adreno_device *adreno_dev)
	wake_up(&device->active_cnt_wq);
}

static int unregister_context_hwsched(int id, void *ptr, void *data)
{
	struct kgsl_context *context = ptr;

	/*
	 * We don't need to send the unregister hfi packet because
	 * we are anyway going to lose the gmu state of registered
	 * contexts. So just reset the flag so that the context
	 * registers with gmu on its first submission post slumber.
	 */
	context->gmu_registered = false;

	return 0;
}

static int a6xx_hwsched_notify_slumber(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
@@ -477,6 +492,10 @@ static int a6xx_hwsched_power_off(struct adreno_device *adreno_dev)

	a6xx_hwsched_gmu_power_off(adreno_dev);

	read_lock(&device->context_lock);
	idr_for_each(&device->context_idr, unregister_context_hwsched, NULL);
	read_unlock(&device->context_lock);

	if (!IS_ERR_OR_NULL(adreno_dev->gpu_llc_slice))
		llcc_slice_deactivate(adreno_dev->gpu_llc_slice);

@@ -695,8 +714,12 @@ static int a6xx_hwsched_bind(struct device *dev, struct device *master,

	ret = a6xx_hwsched_hfi_probe(ADRENO_DEVICE(device));

	if (!ret) {
		set_bit(GMU_DISPATCH, &device->gmu_core.flags);
		return 0;
	}

error:
	if (ret)
	a6xx_gmu_remove(device);

	return ret;
+81 −0
Original line number Diff line number Diff line
@@ -911,3 +911,84 @@ int a6xx_hwsched_submit_cmdobj(struct adreno_device *adreno_dev, u32 flags,

	return ret;
}

static int send_context_unregister_hfi(struct adreno_device *adreno_dev,
	u32 ctxt_id, u32 ts)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
	struct a6xx_hwsched_hfi *hfi = to_a6xx_hwsched_hfi(adreno_dev);
	struct pending_cmd pending_ack;
	struct hfi_unregister_ctxt_cmd cmd;
	u32 seqnum;
	int rc;

	cmd.hdr = CMD_MSG_HDR(H2F_MSG_UNREGISTER_CONTEXT, sizeof(cmd));
	cmd.ctxt_id = ctxt_id,
	cmd.ts = ts,

	seqnum = atomic_inc_return(&gmu->hfi.seqnum);
	cmd.hdr = MSG_HDR_SET_SEQNUM(cmd.hdr, seqnum);

	add_waiter(hfi, cmd.hdr, &pending_ack);

	rc = a6xx_hfi_cmdq_write(adreno_dev, (u32 *)&cmd);
	if (rc)
		goto done;

	mutex_unlock(&device->mutex);

	rc = wait_for_completion_timeout(&pending_ack.complete,
			msecs_to_jiffies(30 * 1000));
	if (!rc) {
		dev_err(&gmu->pdev->dev,
			"Ack timeout for context unregister seq: %d ctx: %d ts: %d\n",
			MSG_HDR_GET_SEQNUM(pending_ack.sent_hdr),
			ctxt_id, ts);
		rc = -ETIMEDOUT;
		mutex_lock(&device->mutex);
		gmu_fault_snapshot(device);
		goto done;
	}

	mutex_lock(&device->mutex);

	rc = check_ack_failure(adreno_dev, &pending_ack);
done:
	del_waiter(hfi, &pending_ack);

	return rc;
}

void a6xx_hwsched_context_detach(struct adreno_context *drawctxt)
{
	struct kgsl_context *context = &drawctxt->base;
	struct kgsl_device *device = context->device;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
	int ret = 0;

	mutex_lock(&device->mutex);

	/* Only send HFI if device is not in SLUMBER */
	if (context->gmu_registered &&
		test_bit(GMU_PRIV_GPU_STARTED, &gmu->flags))
		ret = send_context_unregister_hfi(adreno_dev, context->id,
			drawctxt->internal_timestamp);

	if (!ret) {
		kgsl_sharedmem_writel(device->memstore,
			KGSL_MEMSTORE_OFFSET(context->id, soptimestamp),
			drawctxt->timestamp);

		kgsl_sharedmem_writel(device->memstore,
			KGSL_MEMSTORE_OFFSET(context->id, eoptimestamp),
			drawctxt->timestamp);

		adreno_profile_process_results(adreno_dev);
	}

	context->gmu_registered = false;

	mutex_unlock(&device->mutex);
}
+9 −0
Original line number Diff line number Diff line
@@ -191,4 +191,13 @@ int a6xx_hfi_send_cmd_async(struct adreno_device *adreno_dev, void *data);
 */
int a6xx_hwsched_submit_cmdobj(struct adreno_device *adreno_dev, u32 flags,
	struct kgsl_drawobj_cmd *cmdobj);

/**
 * a6xx_hwsched_context_detach - Unregister a context with GMU
 * @drawctxt: Pointer to the adreno context
 *
 * This function sends context unregister HFI and waits for the ack
 * to ensure all submissions from this context have retired
 */
void a6xx_hwsched_context_detach(struct adreno_context *drawctxt);
#endif
Loading