diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-08-18 16:42:25 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-08-18 16:53:18 +0100 |
commit | de2c97b27fa176deec12a6277448397fcc246e47 (patch) | |
tree | 864807fcce4ca870c2c595cb782392c864f46bfa /overlay | |
parent | 6a64ee938b90a2d27342aa42ba1d2d90da40dc7b (diff) |
overlay: Add GPU frequency
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'overlay')
-rw-r--r-- | overlay/Makefile.am | 2 | ||||
-rw-r--r-- | overlay/chart.c | 3 | ||||
-rw-r--r-- | overlay/gpu-freq.c | 75 | ||||
-rw-r--r-- | overlay/gpu-freq.h | 8 | ||||
-rw-r--r-- | overlay/overlay.c | 71 |
5 files changed, 158 insertions, 1 deletions
diff --git a/overlay/Makefile.am b/overlay/Makefile.am index 294181e0..ee34fb31 100644 --- a/overlay/Makefile.am +++ b/overlay/Makefile.am @@ -19,6 +19,8 @@ intel_gpu_overlay_SOURCES = \ gpu-top.h \ gpu-top.c \ gpu-perf.c \ + gpu-freq.h \ + gpu-freq.c \ igfx.h \ igfx.c \ x11/dri2.c \ diff --git a/overlay/chart.c b/overlay/chart.c index 8b46cadb..bc0489cd 100644 --- a/overlay/chart.c +++ b/overlay/chart.c @@ -134,6 +134,9 @@ void chart_draw(struct chart *chart, cairo_t *cr) if (chart->range_automatic) chart_update_range(chart); + if (chart->range[1] <= chart->range[0]) + return; + cairo_save(cr); cairo_translate(cr, chart->x, chart->y + chart->h); diff --git a/overlay/gpu-freq.c b/overlay/gpu-freq.c new file mode 100644 index 00000000..f0285a5f --- /dev/null +++ b/overlay/gpu-freq.c @@ -0,0 +1,75 @@ +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <stdio.h> + +#include "gpu-freq.h" + +int gpu_freq_init(struct gpu_freq *gf) +{ + char buf[4096], *s; + int fd, len = -1; + + memset(gf, 0, sizeof(*gf)); + + fd = open("/sys/kernel/debug/dri/0/i915_cur_delayinfo", 0); + if (fd < 0) + return errno; + + len = read(fd, buf, sizeof(buf)-1); + close(fd); + if (len < 0) + return EIO; + + buf[len] = '\0'; + + s = strstr(buf, "(RPN)"); + if (s == NULL) + return EIO; + sscanf(s, "(RPN) frequency: %dMHz", &gf->rpn); + + s = strstr(s, "(RP1)"); + if (s == NULL) + return EIO; + sscanf(s, "(RP1) frequency: %dMHz", &gf->rp1); + + s = strstr(s, "(RP0)"); + if (s == NULL) + return EIO; + sscanf(s, "(RP0) frequency: %dMHz", &gf->rp0); + + s = strstr(s, "Max"); + if (s == NULL) + return EIO; + sscanf(s, "Max overclocked frequency: %dMHz", &gf->max); + + return 0; +} + +int gpu_freq_update(struct gpu_freq *gf) +{ + char buf[4096], *s; + int fd, len = -1; + + fd = open("/sys/kernel/debug/dri/0/i915_cur_delayinfo", 0); + if (fd < 0) + return errno; + + len = read(fd, buf, sizeof(buf)-1); + close(fd); + if (len < 0) + return EIO; + + buf[len] = '\0'; + + s = strstr(buf, "RPNSWREQ:"); + if (s) + sscanf(s, "RPNSWREQ: %dMHz", &gf->request); + + s = strstr(buf, "CAGF:"); + if (s) + sscanf(s, "CAGF: %dMHz", &gf->current); + + return 0; +} diff --git a/overlay/gpu-freq.h b/overlay/gpu-freq.h new file mode 100644 index 00000000..a704f6be --- /dev/null +++ b/overlay/gpu-freq.h @@ -0,0 +1,8 @@ +struct gpu_freq { + int rpn, rp1, rp0, max; + int request; + int current; +}; + +int gpu_freq_init(struct gpu_freq *gf); +int gpu_freq_update(struct gpu_freq *gf); diff --git a/overlay/overlay.c b/overlay/overlay.c index 71d20b0f..b8889627 100644 --- a/overlay/overlay.c +++ b/overlay/overlay.c @@ -11,9 +11,10 @@ #include "overlay.h" #include "cpu-top.h" +#include "gem-objects.h" +#include "gpu-freq.h" #include "gpu-top.h" #include "gpu-perf.h" -#include "gem-objects.h" #include "chart.h" const cairo_user_data_key_t overlay_key; @@ -369,6 +370,71 @@ static void show_gpu_perf(struct overlay_context *ctx, struct overlay_gpu_perf * ctx->last_y += 118; } +struct overlay_gpu_freq { + struct gpu_freq gpu_freq; + struct chart current; + struct chart request; + int error; +}; + +static void init_gpu_freq(struct overlay_gpu_freq *gf, + cairo_surface_t *surface) +{ + gf->error = gpu_freq_init(&gf->gpu_freq); + if (gf->error) + return; + + chart_init(&gf->current, "current", 120); + chart_set_size(&gf->current, + cairo_image_surface_get_width(surface)-24, + 100); + chart_set_stroke_rgba(&gf->current, 0.75, 0.25, 0.50, 1.); + chart_set_mode(&gf->current, CHART_STROKE); + chart_set_range(&gf->current, 0, gf->gpu_freq.max); + + chart_init(&gf->request, "request", 120); + chart_set_size(&gf->request, + cairo_image_surface_get_width(surface)-24, + 100); + chart_set_fill_rgba(&gf->request, 0.25, 0.75, 0.50, 1.); + chart_set_mode(&gf->request, CHART_FILL); + chart_set_range(&gf->request, 0, gf->gpu_freq.max); +} + +static void show_gpu_freq(struct overlay_context *ctx, struct overlay_gpu_freq *gf) +{ + char buf[160]; + int y, len; + + if (gf->error == 0) + gf->error = gpu_freq_update(&gf->gpu_freq); + if (gf->error) + return; + + if (gf->gpu_freq.current) + chart_add_sample(&gf->current, gf->gpu_freq.current); + if (gf->gpu_freq.request) + chart_add_sample(&gf->request, gf->gpu_freq.request); + + y = ctx->last_y + 6; + + chart_set_position(&gf->current, 12, y); + chart_set_position(&gf->request, 12, y); + + chart_draw(&gf->request, ctx->cr); + chart_draw(&gf->current, ctx->cr); + + len = sprintf(buf, "Frequency: %dMHz", gf->gpu_freq.current); + if (gf->gpu_freq.request) + sprintf(buf + len, " (requested %dMHz)", gf->gpu_freq.request); + cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1); + cairo_move_to(ctx->cr, 12, y); + cairo_show_text(ctx->cr, buf); + y += 14; + + ctx->last_y += 112; +} + static void show_gem_objects(struct overlay_context *ctx) { char gem_objects[1024], *s, *t, *end; @@ -403,6 +469,7 @@ int main(int argc, char **argv) cairo_surface_t *surface; struct overlay_gpu_top gpu_top; struct overlay_gpu_perf gpu_perf; + struct overlay_gpu_freq gpu_freq; int i = 0; if (argc > 1) { @@ -416,6 +483,7 @@ int main(int argc, char **argv) init_gpu_top(&gpu_top, surface); init_gpu_perf(&gpu_perf, surface); + init_gpu_freq(&gpu_freq, surface); while (1) { struct overlay_context ctx; @@ -442,6 +510,7 @@ int main(int argc, char **argv) show_gpu_top(&ctx, &gpu_top); show_gpu_perf(&ctx, &gpu_perf); + show_gpu_freq(&ctx, &gpu_freq); show_gem_objects(&ctx); cairo_destroy(ctx.cr); |