msm: kgsl: Count a percentage of _io time

Count different percentages based upon GPU frequency.

Change-Id: Ia579f6705ff9858263f507bd4f3ba0f84b772554
Signed-off-by: Lucille Sylvester <lsylvest@codeaurora.org>
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 2d2f104..b737b116 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1969,18 +1969,22 @@
 			{
 				.gpu_freq = 400000000,
 				.bus_freq = 4,
+				.io_fraction = 0,
 			},
 			{
 				.gpu_freq = 300000000,
 				.bus_freq = 3,
+				.io_fraction = 33,
 			},
 			{
 				.gpu_freq = 200000000,
 				.bus_freq = 2,
+				.io_fraction = 100,
 			},
 			{
 				.gpu_freq = 128000000,
 				.bus_freq = 1,
+				.io_fraction = 100,
 			},
 			{
 				.gpu_freq = 27000000,
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index def2558..4458adf 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -657,18 +657,22 @@
 			{
 				.gpu_freq = 266667000,
 				.bus_freq = 4,
+				.io_fraction = 0,
 			},
 			{
 				.gpu_freq = 228571000,
 				.bus_freq = 3,
+				.io_fraction = 33,
 			},
 			{
 				.gpu_freq = 200000000,
 				.bus_freq = 2,
+				.io_fraction = 100,
 			},
 			{
 				.gpu_freq = 177778000,
-				.bus_freq = 1
+				.bus_freq = 1,
+				.io_fraction = 100,
 			},
 			{
 				.gpu_freq = 27000000,
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index b13190d..0693f46 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1080,6 +1080,7 @@
 {
 	long status = 0;
 	uint io = 1;
+	static uint io_cnt;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 
@@ -1097,12 +1098,9 @@
 		goto done;
 	}
 	if (!kgsl_check_timestamp(device, timestamp)) {
-		if (pwr->active_pwrlevel) {
-			int low_pwrlevel = pwr->num_pwrlevels -
-					KGSL_PWRLEVEL_LOW_OFFSET;
-			if (pwr->active_pwrlevel == low_pwrlevel)
-				io = 0;
-		}
+		io_cnt = (io_cnt + 1) % 100;
+		if (io_cnt < pwr->pwrlevels[pwr->active_pwrlevel].io_fraction)
+			io = 0;
 		mutex_unlock(&device->mutex);
 		/* We need to make sure that the process is placed in wait-q
 		 * before its condition is called */
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 2aff1ff..64397e0 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -479,6 +479,8 @@
 					   gpu_freq) : 0;
 		pwr->pwrlevels[i].bus_freq =
 			pdata_pwr->pwrlevel[i].bus_freq;
+		pwr->pwrlevels[i].io_fraction =
+			pdata_pwr->pwrlevel[i].io_fraction;
 	}
 	/* Do not set_rate for targets in sync with AXI */
 	if (pwr->pwrlevels[0].gpu_freq > 0)
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 17dab76..6258a9b 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -21,7 +21,6 @@
 
 #define KGSL_PWRLEVEL_TURBO 0
 #define KGSL_PWRLEVEL_NOMINAL 1
-#define KGSL_PWRLEVEL_LOW_OFFSET 2
 
 #define KGSL_MAX_CLKS 5
 
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 84e8564..9db6bc6 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -111,6 +111,7 @@
 struct kgsl_pwrlevel {
 	unsigned int gpu_freq;
 	unsigned int bus_freq;
+	unsigned int io_fraction;
 };
 
 struct kgsl_version {