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

Commit c3c3b9b5 authored by Lucille Sylvester's avatar Lucille Sylvester
Browse files

msm: kgsl: Remove the busy waiting loop from idle_check



Previously there were issues with extra long GPU sequences
running during the idle_check NAP attempt thwarting the
transition to NAP.  With the dispatcher architecture this
is much less likely to occur.  In addition the dispatcher
increases chances of a very short pause between a command
coming in and being submitted increasing the occurence of
"micro-NAPs" being caught by this loop.  These extremely
short NAP periods are actually a power loss on the CX rail.
Given that hw clock gating will take care of any long GPU
command tails remove the busy wait loop for power savings.

Change-Id: I4efc6215689c42ab03d4e478ad97839208d04004
Signed-off-by: default avatarLucille Sylvester <lsylvest@codeaurora.org>
parent a888b526
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -863,7 +863,6 @@ void a3xx_cp_callback(struct adreno_device *adreno_dev, int irq)
{
	struct kgsl_device *device = &adreno_dev->dev;

	device->pwrctrl.irq_last = 1;
	queue_work(device->work_queue, &device->event_work);
	adreno_dispatcher_schedule(device);
}
+0 −1
Original line number Diff line number Diff line
@@ -1288,7 +1288,6 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
	kgsl_cff_core_idle(device);

done:
	device->pwrctrl.irq_last = 0;
	trace_kgsl_issueibcmds(device, context->id, cmdbatch,
		cmdbatch->timestamp, cmdbatch->flags, ret,
		drawctxt->type);
+2 −27
Original line number Diff line number Diff line
@@ -1195,8 +1195,6 @@ void kgsl_pwrctrl_close(struct kgsl_device *device)
 */
void kgsl_idle_check(struct work_struct *work)
{
	int delay = INIT_UDELAY;
	int requested_state;
	struct kgsl_device *device = container_of(work, struct kgsl_device,
							idle_check_ws);
	WARN_ON(device == NULL);
@@ -1209,30 +1207,9 @@ void kgsl_idle_check(struct work_struct *work)

	if (device->state == KGSL_STATE_ACTIVE
		   || device->state ==  KGSL_STATE_NAP) {
		/*
		 * If no user is explicitly trying to use the GPU
		 * (active_cnt is zero), then loop with increasing delay,
		 * waiting for the GPU to become idle.
		 */
		while (!atomic_read(&device->active_cnt) &&
			(delay < MAX_UDELAY)) {
			requested_state = device->requested_state;
			if (!kgsl_pwrctrl_sleep(device))
				break;
			/*
			 * If no new commands have been issued since the
			 * last interrupt, stay in this loop waiting for
			 * the GPU to become idle.
			 */
			if (!device->pwrctrl.irq_last)
				break;
			kgsl_pwrctrl_request_state(device, requested_state);
			mutex_unlock(&device->mutex);
			udelay(delay);
			delay *= 2;
			mutex_lock(&device->mutex);
		}

		if (!atomic_read(&device->active_cnt))
			kgsl_pwrctrl_sleep(device);

		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
		if (device->state == KGSL_STATE_ACTIVE) {
@@ -1249,8 +1226,6 @@ void kgsl_idle_check(struct work_struct *work)
				kgsl_pwrctrl_busy_time(device, true);
				device->pwrctrl.clk_stats.no_nap_cnt = 0;
			}
		} else {
			device->pwrctrl.irq_last = 0;
		}
	}

+0 −1
Original line number Diff line number Diff line
@@ -106,7 +106,6 @@ struct kgsl_pwrctrl {
	struct kgsl_clk_stats clk_stats;
	struct pm_qos_request pm_qos_req_dma;
	unsigned int pm_qos_latency;
	unsigned int irq_last;
	bool bus_control;
	int bus_mod;
	unsigned int bus_index[KGSL_MAX_PWRLEVELS];