From: Pengcheng Li <lipengche...@huawei.com>

Force ETM idle acknowleghe when CPU enter WFI.
writel_relaxed(0x2, drvdata->base + TRCAUXCTLR);

Because linux kernel execute on EL1,
so we just need to open EL1 trace,close EL1 trace.
drvdata->vinst_ctrl |= BIT(20);

Because this operation exceed the range of boolean,
so we should modify q_support to unit32 bit.
drvdata->q_support = BMVAL(etmidr0, 15, 16)

Adding PM runtime operations in Coresight devices.
        -static int etmv4_suspend(struct device *dev)
        -static int etmv4_resume(struct device *dev)

Signed-off-by: Li Pengcheng <lipengche...@huawei.com>
Signed-off-by: Li Zhong <lizhon...@hisilicon.com>
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 58 +++++++++++++++++++++++++--
 drivers/hwtracing/coresight/coresight-etm4x.h |  2 +-
 drivers/hwtracing/coresight/coresight.c       | 10 +++--
 3 files changed, 62 insertions(+), 8 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
b/drivers/hwtracing/coresight/coresight-etm4x.c
index 1c59bd3..3a21409 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -33,7 +33,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/perf_event.h>
 #include <asm/sections.h>
-
+#include<linux/cpuidle.h>
 #include "coresight-etm4x.h"
 
 static int boot_enable;
@@ -111,8 +111,8 @@ static void etm4_enable_hw(void *info)
 
        writel_relaxed(drvdata->pe_sel, drvdata->base + TRCPROCSELR);
        writel_relaxed(drvdata->cfg, drvdata->base + TRCCONFIGR);
-       /* nothing specific implemented */
-       writel_relaxed(0x0, drvdata->base + TRCAUXCTLR);
+       /* Force ETM idle acknowleghe when CPU enter WFI */
+       writel_relaxed(0x2, drvdata->base + TRCAUXCTLR);
        writel_relaxed(drvdata->eventctrl0, drvdata->base + TRCEVENTCTL0R);
        writel_relaxed(drvdata->eventctrl1, drvdata->base + TRCEVENTCTL1R);
        writel_relaxed(drvdata->stall_ctrl, drvdata->base + TRCSTALLCTLR);
@@ -2491,6 +2491,8 @@ static void etm4_init_default_data(struct etmv4_drvdata 
*drvdata)
         *  started state
         */
        drvdata->vinst_ctrl |= BIT(0);
+       /* Not generate EL0-NS trace */
+       drvdata->vinst_ctrl |= BIT(20);
        /* set initial state of start-stop logic */
        if (drvdata->nr_addr_cmp)
                drvdata->vinst_ctrl |= BIT(9);
@@ -2595,6 +2597,42 @@ static struct notifier_block etm4_cpu_notifier = {
        .notifier_call = etm4_cpu_callback,
 };
 
+#ifdef CONFIG_PM
+
+static int etmv4_suspend(struct device *dev)
+{
+       int ret = 0;
+       struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
+
+       dev_info(drvdata->dev, "%s: CPU+%d\n", __func__, drvdata->cpu);
+       if (drvdata->enable) {
+               cpuidle_pause();
+               coresight_disable(drvdata->csdev);
+               cpuidle_resume();
+       }
+
+       return ret;
+}
+
+static int etmv4_resume(struct device *dev)
+{
+       int ret = 0;
+       struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
+
+       dev_info(drvdata->dev, "%s: CPU+%d\n", __func__, drvdata->cpu);
+       if (!drvdata->enable && drvdata->boot_enable) {
+               cpuidle_pause();
+               coresight_enable(drvdata->csdev);
+               cpuidle_resume();
+       }
+
+       return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(etm4x_dev_pm_ops, etmv4_suspend, etmv4_resume);
+
+#endif
+
 static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
 {
        int ret;
@@ -2673,7 +2711,9 @@ static int etm4_probe(struct amba_device *adev, const 
struct amba_id *id)
        dev_info(dev, "%s initialized\n", (char *)id->data);
 
        if (boot_enable) {
+               cpuidle_pause();
                coresight_enable(drvdata->csdev);
+               cpuidle_resume();
                drvdata->boot_enable = true;
        }
 
@@ -2698,7 +2738,17 @@ static struct amba_id etm4_ids[] = {
                .mask   = 0x000fffff,
                .data   = "ETM 4.0",
        },
-       { 0, 0},
+       {       /* ETM 4.0 - A72 board */
+               .id = 0x000bb95a,
+               .mask = 0x000fffff,
+               .data = "ETM 4.0",
+       },
+       {       /* ETM 4.0 - Atermis board */
+               .id = 0x000bb959,
+               .mask = 0x000fffff,
+               .data = "ETM 4.0",
+       },
+       {0, 0},
 };
 
 static struct amba_driver etm4x_driver = {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h 
b/drivers/hwtracing/coresight/coresight-etm4x.h
index c341002..305b29a 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -330,7 +330,7 @@ struct etmv4_drvdata {
        u32                             ccctlr;
        bool                            trcbb;
        u32                             bb_ctrl;
-       bool                            q_support;
+       u32                             q_support;
        u32                             vinst_ctrl;
        u32                             viiectlr;
        u32                             vissctlr;
diff --git a/drivers/hwtracing/coresight/coresight.c 
b/drivers/hwtracing/coresight/coresight.c
index 2ea5961..8b9fda4 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -24,6 +24,7 @@
 #include <linux/of_platform.h>
 #include <linux/delay.h>
 #include <linux/pm_runtime.h>
+#include <linux/cpuidle.h>
 
 #include "coresight-priv.h"
 
@@ -514,7 +515,7 @@ static ssize_t enable_sink_show(struct device *dev,
 {
        struct coresight_device *csdev = to_coresight_device(dev);
 
-       return scnprintf(buf, PAGE_SIZE, "%u\n", (unsigned)csdev->activated);
+       return scnprintf(buf, PAGE_SIZE, "%u\n", csdev->activated);
 }
 
 static ssize_t enable_sink_store(struct device *dev,
@@ -544,7 +545,7 @@ static ssize_t enable_source_show(struct device *dev,
 {
        struct coresight_device *csdev = to_coresight_device(dev);
 
-       return scnprintf(buf, PAGE_SIZE, "%u\n", (unsigned)csdev->enable);
+       return scnprintf(buf, PAGE_SIZE, "%u\n", csdev->enable);
 }
 
 static ssize_t enable_source_store(struct device *dev,
@@ -559,6 +560,8 @@ static ssize_t enable_source_store(struct device *dev,
        if (ret)
                return ret;
 
+       /* suspend cpuidle */
+       cpuidle_pause();
        if (val) {
                ret = coresight_enable(csdev);
                if (ret)
@@ -566,7 +569,8 @@ static ssize_t enable_source_store(struct device *dev,
        } else {
                coresight_disable(csdev);
        }
-
+       /* resume cpuidle */
+       cpuidle_resume();
        return size;
 }
 static DEVICE_ATTR_RW(enable_source);
-- 
1.8.3.2

Reply via email to