summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorArve Hjønnevåg <arve@android.com>2012-04-02 17:20:32 -0700
committerFrank Li <Frank.Li@freescale.com>2012-09-26 13:24:57 +0800
commit86a7393665c7d6fb5fed84de15f50d394d55c8d8 (patch)
tree4f1fc82975faf9457ba39c09e69e32f8107b586e /arch
parent8449220d6931f572f20f62a20b745949c65d1a7b (diff)
ARM: etm: Add sysfs entry to enable timestamps if supported
Change-Id: Iff964ba2f6236ed81863e02ec7b3ec9fbc48044a Signed-off-by: Arve Hjønnevåg <arve@android.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/include/asm/hardware/coresight.h7
-rw-r--r--arch/arm/kernel/etm.c44
2 files changed, 51 insertions, 0 deletions
diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
index 0fad8f8aed7d..42059d36f3aa 100644
--- a/arch/arm/include/asm/hardware/coresight.h
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -18,10 +18,12 @@
#define TRACER_RUNNING_BIT 1
#define TRACER_CYCLE_ACC_BIT 2
#define TRACER_TRACE_DATA_BIT 3
+#define TRACER_TIMESTAMP_BIT 4
#define TRACER_ACCESSED BIT(TRACER_ACCESSED_BIT)
#define TRACER_RUNNING BIT(TRACER_RUNNING_BIT)
#define TRACER_CYCLE_ACC BIT(TRACER_CYCLE_ACC_BIT)
#define TRACER_TRACE_DATA BIT(TRACER_TRACE_DATA_BIT)
+#define TRACER_TIMESTAMP BIT(TRACER_TIMESTAMP_BIT)
#define TRACER_TIMEOUT 10000
@@ -57,6 +59,7 @@
#define ETMCTRL_DATA_DO_BOTH (ETMCTRL_DATA_DO_DATA | ETMCTRL_DATA_DO_ADDR)
#define ETMCTRL_BRANCH_OUTPUT (1 << 8)
#define ETMCTRL_CYCLEACCURATE (1 << 12)
+#define ETMCTRL_TIMESTAMP_EN (1 << 28)
/* ETM configuration code register */
#define ETMR_CONFCODE (0x04)
@@ -129,8 +132,12 @@
#define ETMR_ID 0x1e4
#define ETMIDR_VERSION(x) (((x) >> 4) & 0xff)
+#define ETMIDR_VERSION_3_1 0x21
#define ETMIDR_VERSION_PFT_1_0 0x30
+#define ETMR_CCE 0x1e8
+#define ETMCCER_TIMESTAMPING_IMPLEMENTED BIT(22)
+
#define ETMR_TRACEIDR 0x200
/* ETM management registers, "ETM Architecture", 3.5.24 */
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 9cdbb6d2a4e1..d83ba792dced 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -115,6 +115,9 @@ static int trace_start_etm(struct tracectx *t, int id)
if (t->flags & TRACER_TRACE_DATA)
v |= ETMCTRL_DATA_DO_ADDR;
+ if (t->flags & TRACER_TIMESTAMP)
+ v |= ETMCTRL_TIMESTAMP_EN;
+
etm_unlock(t, id);
etm_writel(t, id, v, ETMR_CTRL);
@@ -646,6 +649,36 @@ static ssize_t trace_mode_store(struct kobject *kobj,
static struct kobj_attribute trace_mode_attr =
__ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
+static ssize_t trace_timestamp_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_TIMESTAMP));
+}
+
+static ssize_t trace_timestamp_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int timestamp;
+
+ if (sscanf(buf, "%u", &timestamp) != 1)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ if (timestamp)
+ tracer.flags |= TRACER_TIMESTAMP;
+ else
+ tracer.flags &= ~TRACER_TIMESTAMP;
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+static struct kobj_attribute trace_timestamp_attr =
+ __ATTR(trace_timestamp, 0644,
+ trace_timestamp_show, trace_timestamp_store);
+
static ssize_t trace_range_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
@@ -725,6 +758,7 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
int new_count;
u32 etmccr;
u32 etmidr;
+ u32 etmccer = 0;
u8 etm_version = 0;
mutex_lock(&t->mutex);
@@ -765,6 +799,8 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
if (etmccr & ETMCCR_ETMIDR_PRESENT) {
etmidr = etm_readl(t, t->etm_regs_count, ETMR_ID);
etm_version = ETMIDR_VERSION(etmidr);
+ if (etm_version >= ETMIDR_VERSION_3_1)
+ etmccer = etm_readl(t, t->etm_regs_count, ETMR_CCE);
}
etm_writel(t, t->etm_regs_count, 0x441, ETMR_CTRL);
etm_writel(t, t->etm_regs_count, new_count, ETMR_TRACEIDR);
@@ -784,6 +820,14 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
if (ret)
dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
+ if (etmccer & ETMCCER_TIMESTAMPING_IMPLEMENTED) {
+ ret = sysfs_create_file(&dev->dev.kobj,
+ &trace_timestamp_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev,
+ "Failed to create trace_timestamp in sysfs\n");
+ }
+
ret = sysfs_create_file(&dev->dev.kobj, &trace_range_attr.attr);
if (ret)
dev_dbg(&dev->dev, "Failed to create trace_range in sysfs\n");