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

Commit 1eac5acb authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Idle the dispatcher before writing perfcounter select



The GPU must be idle before writing to the perfcounter select
registers to avoid an AHB timeout. Idle the GPU before writing
to the register.

Change-Id: Ic0dedbadf8ad3f10f78ddf68520afe6cf98880e4
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 63704274
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -317,6 +317,11 @@ static int adreno_perfcounter_start(struct adreno_device *adreno_dev)
					KGSL_PERFCOUNTER_BROKEN)
				continue;

			/*
			 * The GPU has to be idle before calling the perfcounter
			 * enable function, but since this function is called
			 * during start we already know the GPU is idle
			 */
			if (gpudev->perfcounter_enable)
				ret = gpudev->perfcounter_enable(adreno_dev, i,
					j, group->regs[j].countable);
@@ -602,6 +607,10 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev,
	if (empty == -1)
		return -EBUSY;

	ret = adreno_idle(&adreno_dev->dev);
	if (ret)
		return ret;

	/* enable the new counter */
	ret = gpudev->perfcounter_enable(adreno_dev, groupid, empty, countable);
	if (ret)
@@ -689,6 +698,11 @@ static inline void adreno_perfcounter_restore(struct adreno_device *adreno_dev)
{
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);

	/*
	 * The GPU needs to be idle before writing the perfcounter select
	 * registers. Since this function gets called during start/resume we
	 * know the GPU is already idle so we don't need to stop it
	 */
	if (gpudev->perfcounter_restore)
		gpudev->perfcounter_restore(adreno_dev);
}
@@ -1785,14 +1799,12 @@ static int _adreno_start(struct adreno_device *adreno_dev)
	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
	adreno_irqctrl(adreno_dev, 1);

	adreno_perfcounter_start(adreno_dev);

	status = adreno_ringbuffer_cold_start(&adreno_dev->ringbuffer);
	if (status)
		goto error_irq_off;

	status = adreno_perfcounter_start(adreno_dev);
	if (status)
		goto error_rb_stop;

	/* Start the dispatcher */
	adreno_dispatcher_start(device);

@@ -1802,8 +1814,6 @@ static int _adreno_start(struct adreno_device *adreno_dev)

	return 0;

error_rb_stop:
	adreno_ringbuffer_stop(&adreno_dev->ringbuffer);
error_irq_off:
	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);

+1 −0
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ struct adreno_dispatcher {

enum adreno_dispatcher_flags {
	ADRENO_DISPATCHER_POWER = 0,
	ADRENO_DISPATCHER_ACTIVE = 1,
};

struct adreno_gpudev;
+9 −2
Original line number Diff line number Diff line
@@ -324,6 +324,9 @@ static int sendcmd(struct adreno_device *adreno_dev,
	if (dispatcher->inflight == 1) {
		if (ret == 0) {
			fault_detect_read(device);

			if (!test_and_set_bit(ADRENO_DISPATCHER_ACTIVE,
				&dispatcher->priv))
				init_completion(&dispatcher->idle_gate);
		} else {
			kgsl_active_count_put(device);
@@ -1560,7 +1563,11 @@ done:
	} else {
		/* There is nothing left in the pipeline.  Shut 'er down boys */
		kgsl_mutex_lock(&device->mutex, &device->mutex_owner);

		if (test_and_clear_bit(ADRENO_DISPATCHER_ACTIVE,
			&dispatcher->priv))
			complete_all(&dispatcher->idle_gate);

		/*
		 * Stop the fault timer before decrementing the active count to
		 * avoid reading the hardware registers while we are trying to