diff options
author | Arve Hjønnevåg <arve@android.com> | 2012-04-02 17:20:32 -0700 |
---|---|---|
committer | Arve Hjønnevåg <arve@android.com> | 2013-07-01 13:40:41 -0700 |
commit | bbba6b086dd3463da400ff5b87e6868d2a63f54c (patch) | |
tree | 8c52d2c097918861a4a0fee9f6986b492dbd3bd4 /arch | |
parent | e91914cc72cf1d15ae4c3e0a5cf4d6700634d1f2 (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.h | 7 | ||||
-rw-r--r-- | arch/arm/kernel/etm.c | 44 |
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 684107f444a..5de545626df 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 fc254563ae0..2cd9be36670 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c @@ -116,6 +116,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); @@ -647,6 +650,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", ×tamp) != 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) @@ -726,6 +759,7 @@ static int 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); @@ -766,6 +800,8 @@ static int 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); @@ -785,6 +821,14 @@ static int 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"); |