diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-08-27 11:20:43 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-08-27 12:31:13 +0100 |
commit | 1c3fd70357a57f823846010f59ba75f19e5d4af9 (patch) | |
tree | e3ef96d481a5c1d59782dab6c1b38c7e712adcd1 /overlay/power.c | |
parent | 6ec1d2c0ae631a3c0af445d4baa53561228be9a5 (diff) |
overlay: Read power from perf_events
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'overlay/power.c')
-rw-r--r-- | overlay/power.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/overlay/power.c b/overlay/power.c index 520a1099..6c5c3749 100644 --- a/overlay/power.c +++ b/overlay/power.c @@ -22,6 +22,7 @@ * */ +#include <stdint.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -30,11 +31,27 @@ #include <time.h> #include <errno.h> +#include "perf.h" #include "power.h" #include "debugfs.h" /* XXX Is this exposed through RAPL? */ +static int perf_open(void) +{ + struct perf_event_attr attr; + + memset(&attr, 0, sizeof (attr)); + + attr.type = i915_type_id(); + if (attr.type == 0) + return -ENOENT; + attr.config = I915_PERF_ENERGY; + + attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED; + return perf_event_open(&attr, -1, 0, -1, 0); +} + int power_init(struct power *power) { char buf[4096]; @@ -42,6 +59,10 @@ int power_init(struct power *power) memset(power, 0, sizeof(*power)); + power->fd = perf_open(); + if (power->fd != -1) + return 0; + sprintf(buf, "%s/i915_energy_uJ", debugfs_dri_path); fd = open(buf, 0); if (fd < 0) @@ -100,17 +121,25 @@ int power_update(struct power *power) if (power->error) return power->error; - s->energy = file_to_u64("i915_energy_uJ"); - s->timestamp = clock_ms_to_u64(); + if (power->fd != -1) { + uint64_t data[2]; + int len; + + len = read(power->fd, data, sizeof(data)); + if (len < 0) + return power->error = errno; + + s->energy = data[0]; + s->timestamp = data[1] / (1000*1000); + } else { + s->energy = file_to_u64("i915_energy_uJ"); + s->timestamp = clock_ms_to_u64(); + } + if (power->count == 1) return EAGAIN; d_time = s->timestamp - d->timestamp; - if (d_time < 900) { /* HW sample rate seems to be stable ~1Hz */ - power->count--; - return power->count <= 1 ? EAGAIN : 0; - } - power->power_mW = (s->energy - d->energy) / d_time; power->new_sample = 1; return 0; |