msm: kgsl: Implement GMU suspend
Suspend GMU in case it is not responding. So GPU hard reset
can go through.
CRs-Fixed: 2017390
Change-Id: I0793168c88519a60792cc6642b152357fa907028
Signed-off-by: Kyle Piefer <kpiefer@codeaurora.org>
Signed-off-by: George Shen <sqiao@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index fec16bd..f35f645 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -499,6 +499,7 @@
* attached and enabled
* @ADRENO_DEVICE_CACHE_FLUSH_TS_SUSPENDED - Set if a CACHE_FLUSH_TS irq storm
* is in progress
+ * @ADRENO_DEVICE_HARD_RESET - Set if soft reset fails and hard reset is needed
*/
enum adreno_device_flags {
ADRENO_DEVICE_PWRON = 0,
@@ -515,6 +516,7 @@
ADRENO_DEVICE_GPMU_INITIALIZED = 11,
ADRENO_DEVICE_ISDB_ENABLED = 12,
ADRENO_DEVICE_CACHE_FLUSH_TS_SUSPENDED = 13,
+ ADRENO_DEVICE_HARD_RESET = 14,
};
/**
@@ -1708,4 +1710,37 @@
kgsl_active_count_put(KGSL_DEVICE(adreno_dev));
}
+/**
+ * adreno_vbif_clear_pending_transactions() - Clear transactions in VBIF pipe
+ * @device: Pointer to the device whose VBIF pipe is to be cleared
+ */
+static inline int adreno_vbif_clear_pending_transactions(
+ struct kgsl_device *device)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
+ unsigned int mask = gpudev->vbif_xin_halt_ctrl0_mask;
+ unsigned int val;
+ unsigned long wait_for_vbif;
+ int ret = 0;
+
+ adreno_writereg(adreno_dev, ADRENO_REG_VBIF_XIN_HALT_CTRL0, mask);
+ /* wait for the transactions to clear */
+ wait_for_vbif = jiffies + msecs_to_jiffies(100);
+ while (1) {
+ adreno_readreg(adreno_dev,
+ ADRENO_REG_VBIF_XIN_HALT_CTRL1, &val);
+ if ((val & mask) == mask)
+ break;
+ if (time_after(jiffies, wait_for_vbif)) {
+ KGSL_DRV_ERR(device,
+ "Wait limit reached for VBIF XIN Halt\n");
+ ret = -ETIMEDOUT;
+ break;
+ }
+ }
+ adreno_writereg(adreno_dev, ADRENO_REG_VBIF_XIN_HALT_CTRL0, 0);
+ return ret;
+}
+
#endif /*__ADRENO_H */