coresight: implement new tmc etr to usb flush procedure

Recommended ETR to usb flush procedure changed. This implements
the new recommended procedure.

CRs-Fixed: 443106
Change-Id: I18a6d457686905cbee75ce081ee4c6b4f6fdc62c
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c
index e734ece..4774c76 100644
--- a/drivers/coresight/coresight-csr.c
+++ b/drivers/coresight/coresight-csr.c
@@ -119,6 +119,21 @@
 }
 EXPORT_SYMBOL_GPL(msm_qdss_csr_disable_bam_to_usb);
 
+void msm_qdss_csr_disable_flush(void)
+{
+	struct csr_drvdata *drvdata = csrdrvdata;
+	uint32_t usbflshctrl;
+
+	CSR_UNLOCK(drvdata);
+
+	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
+	usbflshctrl &= ~0x2;
+	csr_writel(drvdata, usbflshctrl, CSR_USBFLSHCTRL);
+
+	CSR_LOCK(drvdata);
+}
+EXPORT_SYMBOL_GPL(msm_qdss_csr_disable_flush);
+
 static int __devinit csr_probe(struct platform_device *pdev)
 {
 	int ret;
diff --git a/drivers/coresight/coresight-priv.h b/drivers/coresight/coresight-priv.h
index 0cf2b3d..47f98f7 100644
--- a/drivers/coresight/coresight-priv.h
+++ b/drivers/coresight/coresight-priv.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -39,11 +39,13 @@
 #ifdef CONFIG_MSM_QDSS
 extern void msm_qdss_csr_enable_bam_to_usb(void);
 extern void msm_qdss_csr_disable_bam_to_usb(void);
+extern void msm_qdss_csr_disable_flush(void);
 extern unsigned int etm_readl_cp14(uint32_t off);
 extern void etm_writel_cp14(uint32_t val, uint32_t off);
 #else
 static inline void msm_qdss_csr_enable_bam_to_usb(void) {}
 static inline void msm_qdss_csr_disable_bam_to_usb(void) {}
+static inline void msm_qdss_csr_disable_flush(void) {}
 static inline unsigned int etm_readl_cp14(uint32_t off) { return 0; }
 static inline void etm_writel_cp14(uint32_t val, uint32_t off) {}
 #endif
diff --git a/drivers/coresight/coresight-tmc.c b/drivers/coresight/coresight-tmc.c
index bc77049..10eabca 100644
--- a/drivers/coresight/coresight-tmc.c
+++ b/drivers/coresight/coresight-tmc.c
@@ -155,6 +155,18 @@
 	uint32_t		trigger_cntr;
 };
 
+static void tmc_wait_for_flush(struct tmc_drvdata *drvdata)
+{
+	int count;
+
+	/* Ensure no flush is in progress */
+	for (count = TIMEOUT_US; BVAL(tmc_readl(drvdata, TMC_FFSR), 0) != 0
+				&& count > 0; count--)
+		udelay(1);
+	WARN(count == 0, "timeout while waiting for TMC flush, TMC_FFSR: %#x\n",
+	     tmc_readl(drvdata, TMC_FFSR));
+}
+
 static void tmc_wait_for_ready(struct tmc_drvdata *drvdata)
 {
 	int count;
@@ -238,7 +250,7 @@
 
 	tmc_writel(drvdata, bamdata->data_fifo.phys_base, TMC_DBALO);
 	tmc_writel(drvdata, 0x0, TMC_DBAHI);
-	tmc_writel(drvdata, 0x133, TMC_FFCR);
+	tmc_writel(drvdata, 0x103, TMC_FFCR);
 	tmc_writel(drvdata, drvdata->trigger_cntr, TMC_TRG);
 	__tmc_enable(drvdata);
 
@@ -298,14 +310,18 @@
 	if (!drvdata->enable_to_bam)
 		return;
 
+	/* Ensure periodic flush is disabled in CSR block */
+	msm_qdss_csr_disable_flush();
+
 	TMC_UNLOCK(drvdata);
 
+	tmc_wait_for_flush(drvdata);
 	tmc_flush_and_stop(drvdata);
 	__tmc_disable(drvdata);
 
 	TMC_LOCK(drvdata);
 
-	/* Disable CSR registers */
+	/* Disable CSR configuration */
 	msm_qdss_csr_disable_bam_to_usb();
 	drvdata->enable_to_bam = false;
 }