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

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

Merge "Revert "msm: kgsl: Use IDLE interrupt to switch to NAP state""

parents dab7cce4 2be44f7c
Loading
Loading
Loading
Loading
+3 −17
Original line number Diff line number Diff line
@@ -3263,20 +3263,6 @@ void a3xx_fatal_err_callback(struct adreno_device *adreno_dev, int bit)
	adreno_dispatcher_irq_fault(device);
}

void a3xx_gpu_idle_callback(struct adreno_device *adreno_dev,
					int irq)
{
	struct kgsl_device *device = &adreno_dev->dev;

	if (device->requested_state == KGSL_STATE_NONE) {
		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
		queue_work(device->work_queue, &device->idle_check_ws);
	}

	mod_timer_pending(&device->idle_timer,
		jiffies + device->pwrctrl.interval_timeout);
}

/*
 * a3xx_cp_callback() - CP interrupt handler
 * @adreno_dev: Adreno device pointer
@@ -3289,6 +3275,7 @@ 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->ts_expired_ws);
	adreno_dispatcher_schedule(device);
}
@@ -3740,8 +3727,7 @@ static void a3xx_perfcounter_restore(struct adreno_device *adreno_dev)
}

#define A3XX_INT_MASK \
	((1 << A3XX_INT_RBBM_GPU_IDLE) |         \
	 (1 << A3XX_INT_RBBM_AHB_ERROR) |        \
	((1 << A3XX_INT_RBBM_AHB_ERROR) |        \
	 (1 << A3XX_INT_RBBM_ATB_BUS_OVERFLOW) | \
	 (1 << A3XX_INT_CP_T0_PACKET_IN_IB) |    \
	 (1 << A3XX_INT_CP_OPCODE_ERROR) |       \
@@ -3755,7 +3741,7 @@ static void a3xx_perfcounter_restore(struct adreno_device *adreno_dev)
	 (1 << A3XX_INT_UCHE_OOB_ACCESS))

static struct adreno_irq_funcs a3xx_irq_funcs[] = {
	ADRENO_IRQ_CALLBACK(a3xx_gpu_idle_callback), /* 0 - RBBM_GPU_IDLE */
	ADRENO_IRQ_CALLBACK(NULL),                    /* 0 - RBBM_GPU_IDLE */
	ADRENO_IRQ_CALLBACK(a3xx_a4xx_err_callback),  /* 1 - RBBM_AHB_ERROR */
	ADRENO_IRQ_CALLBACK(a3xx_a4xx_err_callback),  /* 2 - RBBM_REG_TIMEOUT */
	/* * 3 - RBBM_ME_MS_TIMEOUT */
+2 −3
Original line number Diff line number Diff line
@@ -957,8 +957,7 @@ static struct adreno_coresight a4xx_coresight = {
};

#define A4XX_INT_MASK \
	((1 << A3XX_INT_RBBM_GPU_IDLE) |		\
	 (1 << A3XX_INT_RBBM_AHB_ERROR) |		\
	((1 << A3XX_INT_RBBM_AHB_ERROR) |		\
	 (1 << A3XX_INT_RBBM_REG_TIMEOUT) |		\
	 (1 << A3XX_INT_RBBM_ME_MS_TIMEOUT) |		\
	 (1 << A3XX_INT_RBBM_PFP_MS_TIMEOUT) |		\
@@ -980,7 +979,7 @@ static struct adreno_coresight a4xx_coresight = {
	 (1 << A4XX_INT_RBBM_DPM_THERMAL_RED_ERR))

static struct adreno_irq_funcs a4xx_irq_funcs[] = {
	ADRENO_IRQ_CALLBACK(a3xx_gpu_idle_callback), /* 0 - RBBM_GPU_IDLE */
	ADRENO_IRQ_CALLBACK(NULL),                   /* 0 - RBBM_GPU_IDLE */
	ADRENO_IRQ_CALLBACK(a3xx_a4xx_err_callback), /* 1 - RBBM_AHB_ERROR */
	ADRENO_IRQ_CALLBACK(a3xx_a4xx_err_callback), /* 2 - RBBM_REG_TIMEOUT */
	/* 3 - RBBM_ME_MS_TIMEOUT */
+1 −0
Original line number Diff line number Diff line
@@ -1237,6 +1237,7 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
	kgsl_cff_core_idle(device);

done:
	device->pwrctrl.irq_last = 0;
	kgsl_trace_issueibcmds(device, context->id, cmdbatch,
		cmdbatch->timestamp, cmdbatch->flags, ret,
		drawctxt->type);
+38 −5
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <mach/msm_iomap.h>
#include <mach/msm_bus.h>
#include <linux/ktime.h>
#include <linux/delay.h>

#include "kgsl.h"
#include "kgsl_pwrscale.h"
@@ -33,6 +34,16 @@
#define UPDATE_BUSY_VAL		1000000
#define UPDATE_BUSY		50

/*
 * Expected delay for post-interrupt processing on A3xx.
 * The delay may be longer, gradually increase the delay
 * to compensate.  If the GPU isn't done by max delay,
 * it's working on something other than just the final
 * command sequence so stop waiting for it to be idle.
 */
#define INIT_UDELAY		200
#define MAX_UDELAY		2000

struct clk_pair {
	const char *name;
	uint map;
@@ -1149,6 +1160,8 @@ 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);
@@ -1162,11 +1175,29 @@ 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,
		 * try to sleep.
		 * 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 (!atomic_read(&device->active_cnt))
			kgsl_pwrctrl_sleep(device);
			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);
		}


		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
		if (device->state == KGSL_STATE_ACTIVE) {
@@ -1183,6 +1214,8 @@ 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;
		}
	}

+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ struct kgsl_pwrctrl {
	struct pm_qos_request pm_qos_req_dma;
	unsigned int pm_qos_latency;
	unsigned int step_mul;
	unsigned int irq_last;
};

void kgsl_pwrctrl_irq(struct kgsl_device *device, int state);