msm: kgsl: Debugfs knob to configure wait timeout of adreno device

There are times when the adreno device is heavily loaded. Here, a
predetermined wait timeout value will not be useful. The configurability
introduced with this change will help in understanding the behaviour and
to tune the value. Will also be helpful in quickly identifying problems
that arise when the irqs don't fire.

Signed-off-by: Ranjhith Kalisamy <ranjhith@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 526c971..4207def 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -66,9 +66,6 @@
 	 | (MMU_CONFIG << MH_MMU_CONFIG__TC_R_CLNT_BEHAVIOR__SHIFT)	\
 	 | (MMU_CONFIG << MH_MMU_CONFIG__PA_W_CLNT_BEHAVIOR__SHIFT))
 
-/* max msecs to wait for gpu to finish its operation(s) */
-#define MAX_WAITGPU_SECS (HZ + HZ/2)
-
 static const struct kgsl_functable adreno_functable;
 
 static struct adreno_device device_3d0 = {
@@ -429,6 +426,8 @@
 	adreno_dev = ADRENO_DEVICE(device);
 	device->parentdev = &pdev->dev;
 
+	adreno_dev->wait_timeout = 10000; /* default value in milliseconds */
+
 	init_completion(&device->recovery_gate);
 
 	status = adreno_ringbuffer_init(device);
@@ -835,7 +834,9 @@
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
 	unsigned int rbbm_status;
-	unsigned long wait_time = jiffies + MAX_WAITGPU_SECS;
+	unsigned long wait_timeout =
+		msecs_to_jiffies(adreno_dev->wait_timeout);
+	unsigned long wait_time = jiffies + wait_timeout;
 
 	kgsl_cffdump_regpoll(device->id, REG_RBBM_STATUS << 2,
 		0x00000000, 0x80000000);
@@ -855,7 +856,7 @@
 	}
 
 	/* now, wait for the GPU to finish its operations */
-	wait_time = jiffies + MAX_WAITGPU_SECS;
+	wait_time = jiffies + wait_timeout;
 	while (time_before(jiffies, wait_time)) {
 		adreno_regread(device, REG_RBBM_STATUS, &rbbm_status);
 		if (rbbm_status == 0x110)
@@ -865,7 +866,7 @@
 err:
 	KGSL_DRV_ERR(device, "spun too long waiting for RB to idle\n");
 	if (!adreno_dump_and_recover(device)) {
-		wait_time = jiffies + MAX_WAITGPU_SECS;
+		wait_time = jiffies + wait_timeout;
 		goto retry;
 	}
 	return -ETIMEDOUT;
@@ -1073,6 +1074,10 @@
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 
+	/* Don't wait forever, set a max value for now */
+	if (msecs == -1)
+		msecs = adreno_dev->wait_timeout;
+
 	if (timestamp != adreno_dev->ringbuffer.timestamp &&
 		timestamp_cmp(timestamp,
 		adreno_dev->ringbuffer.timestamp)) {
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 94b96a1..0098045 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -64,6 +64,7 @@
 	struct adreno_ringbuffer ringbuffer;
 	unsigned int mharb;
 	struct adreno_gpudev *gpudev;
+	unsigned int wait_timeout;
 };
 
 struct adreno_gpudev {
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index b917849..c878a2c 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -421,6 +421,8 @@
 
 void adreno_debugfs_init(struct kgsl_device *device)
 {
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
 	if (!device->d_debugfs || IS_ERR(device->d_debugfs))
 		return;
 
@@ -436,6 +438,8 @@
 			    &kgsl_mh_debug_fops);
 	debugfs_create_file("cff_dump", 0644, device->d_debugfs, device,
 			    &kgsl_cff_dump_enable_fops);
+	debugfs_create_u32("wait_timeout", 0644, device->d_debugfs,
+		&adreno_dev->wait_timeout);
 
 	/* Create post mortem control files */
 
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 5d20d9b..e146ab8 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -767,10 +767,6 @@
 
 	dev_priv->device->active_cnt++;
 
-	/* Don't wait forever, set a max value for now */
-	if (param->timeout == -1)
-		param->timeout = 10 * MSEC_PER_SEC;
-
 	result = dev_priv->device->ftbl->waittimestamp(dev_priv->device,
 					param->timestamp,
 					param->timeout);
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 37ba621..a81eeaa 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -806,6 +806,11 @@
 				unsigned int msecs)
 {
 	int status = -EINVAL;
+
+	/* Don't wait forever, set a max (10 sec) value for now */
+	if (msecs == -1)
+		msecs = 10 * MSEC_PER_SEC;
+
 	mutex_unlock(&device->mutex);
 	status = z180_wait(device, timestamp, msecs);
 	mutex_lock(&device->mutex);