coresight: implement crash dumping support

Add support to allow debug image to be able to dump ETF content
and ETM, TMC regsiters in case of apps proc bite or system hang
causing secure watchdog reset.

This will enable host parsing scripts to extract ETF and
ETR-memory trace data contents from RAM dumps.

Change-Id: Ie6f03bef7b4ccda7ea8d7709ee0c4808424c5b92
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
diff --git a/drivers/coresight/coresight-etm.c b/drivers/coresight/coresight-etm.c
index 182e50c..71298ef 100644
--- a/drivers/coresight/coresight-etm.c
+++ b/drivers/coresight/coresight-etm.c
@@ -31,6 +31,7 @@
 #include <linux/coresight.h>
 #include <asm/sections.h>
 #include <mach/socinfo.h>
+#include <mach/msm_memory_dump.h>
 
 #include "coresight-priv.h"
 
@@ -131,6 +132,9 @@
 
 #define ETM_SEQ_STATE_MAX_VAL	(0x2)
 
+#define ETM_REG_DUMP_VER_OFF	(4)
+#define ETM_REG_DUMP_VER	(1)
+
 enum etm_addr_type {
 	ETM_ADDR_TYPE_NONE,
 	ETM_ADDR_TYPE_SINGLE,
@@ -1517,7 +1521,10 @@
 	struct coresight_platform_data *pdata;
 	struct etm_drvdata *drvdata;
 	struct resource *res;
-	static int etm_count;
+	uint32_t reg_size;
+	static int count;
+	void *baddr;
+	struct msm_client_dump dump;
 	struct coresight_desc *desc;
 
 	/* Fail probe for Krait pass3 until supported */
@@ -1542,6 +1549,7 @@
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
+	reg_size = resource_size(res);
 
 	drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
 	if (!drvdata->base)
@@ -1560,7 +1568,7 @@
 	if (ret)
 		goto err0;
 
-	drvdata->cpu = etm_count++;
+	drvdata->cpu = count++;
 
 	ret = clk_prepare_enable(drvdata->clk);
 	if (ret)
@@ -1584,6 +1592,21 @@
 
 	clk_disable_unprepare(drvdata->clk);
 
+	baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL);
+	if (baddr) {
+		*(uint32_t *)(baddr + ETM_REG_DUMP_VER_OFF) = ETM_REG_DUMP_VER;
+		dump.id = MSM_ETM0_REG + drvdata->cpu;
+		dump.start_addr = virt_to_phys(baddr);
+		dump.end_addr = dump.start_addr + PAGE_SIZE + reg_size;
+		ret = msm_dump_table_register(&dump);
+		if (ret) {
+			devm_kfree(dev, baddr);
+			dev_err(dev, "ETM REG dump setup failed\n");
+		}
+	} else {
+		dev_err(dev, "ETM REG dump space allocation failed\n");
+	}
+
 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc) {
 		ret = -ENOMEM;