From 3f44acf69ea43952ca600ccbbb97e4988c13daea Mon Sep 17 00:00:00 2001
From: Oleg Perelet <operelet@codeaurora.org>
Date: Thu, 18 Aug 2016 13:50:54 -0700
Subject: [PATCH] msm: kgsl: Change sequencing for GPU hardware clock gating

Disable GPU SP clock before programing hardware clock gating registers.

CRs-Fixed: 1056488
Change-Id: I2c91e8ae6a30facefd5dd3d4a4e4c33ffc792fe1
Signed-off-by: Oleg Perelet <operelet@codeaurora.org>
---
 drivers/gpu/msm/a5xx_reg.h    |  1 +
 drivers/gpu/msm/adreno_a5xx.c | 15 ++++++++++++---
 drivers/gpu/msm/adreno_a5xx.h |  3 +++
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/msm/a5xx_reg.h b/drivers/gpu/msm/a5xx_reg.h
index c6dc9032c0bc..cedd02987002 100644
--- a/drivers/gpu/msm/a5xx_reg.h
+++ b/drivers/gpu/msm/a5xx_reg.h
@@ -858,6 +858,7 @@
 #define A5XX_GPMU_ALWAYS_ON_COUNTER_RESET	0xA87B
 #define A5XX_GPMU_POWER_COUNTER_SELECT_0	0xA87C
 #define A5XX_GPMU_POWER_COUNTER_SELECT_1	0xA87D
+#define A5XX_GPMU_GPMU_SP_CLOCK_CONTROL		0xA880
 
 #define A5XX_GPMU_CLOCK_THROTTLE_CTRL		0xA8A3
 #define A5XX_GPMU_THROTTLE_UNMASK_FORCE_CTRL	0xA8A8
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 61d27ac8061f..3252bfb764f2 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -437,8 +437,10 @@ static int a5xx_regulator_enable(struct adreno_device *adreno_dev)
 {
 	unsigned int ret;
 	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
-	if (!(adreno_is_a530(adreno_dev) || adreno_is_a540(adreno_dev)))
+	if (!(adreno_is_a530(adreno_dev) || adreno_is_a540(adreno_dev))) {
+		a5xx_hwcg_set(adreno_dev, true);
 		return 0;
+	}
 
 	/*
 	 * Turn on smaller power domain first to reduce voltage droop.
@@ -460,6 +462,15 @@ static int a5xx_regulator_enable(struct adreno_device *adreno_dev)
 		return ret;
 	}
 
+	/* Disable SP clock */
+	kgsl_regrmw(device, A5XX_GPMU_GPMU_SP_CLOCK_CONTROL,
+		CNTL_IP_CLK_ENABLE, 0);
+	/* Enable hardware clockgating */
+	a5xx_hwcg_set(adreno_dev, true);
+	/* Enable SP clock */
+	kgsl_regrmw(device, A5XX_GPMU_GPMU_SP_CLOCK_CONTROL,
+		CNTL_IP_CLK_ENABLE, 1);
+
 	return 0;
 }
 
@@ -1875,8 +1886,6 @@ static void a5xx_start(struct adreno_device *adreno_dev)
 	} else {
 		/* if not in ISDB mode enable ME/PFP split notification */
 		kgsl_regwrite(device, A5XX_RBBM_AHB_CNTL1, 0xA6FFFFFF);
-		/* enable HWCG */
-		a5xx_hwcg_set(adreno_dev, true);
 	}
 
 	kgsl_regwrite(device, A5XX_RBBM_AHB_CNTL2, 0x0000003F);
diff --git a/drivers/gpu/msm/adreno_a5xx.h b/drivers/gpu/msm/adreno_a5xx.h
index 27d5a4b31c71..e424e7a9f228 100644
--- a/drivers/gpu/msm/adreno_a5xx.h
+++ b/drivers/gpu/msm/adreno_a5xx.h
@@ -177,6 +177,9 @@ void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on);
 
 /* A5XX_GPMU_GPMU_PWR_THRESHOLD */
 #define PWR_THRESHOLD_VALID		0x80000000
+
+/* A5XX_GPMU_GPMU_SP_CLOCK_CONTROL */
+#define CNTL_IP_CLK_ENABLE		BIT(0)
 /* AGC */
 #define AGC_INIT_BASE			A5XX_GPMU_DATA_RAM_BASE
 #define AGC_INIT_MSG_MAGIC		(AGC_INIT_BASE + 5)