summaryrefslogtreecommitdiff
path: root/overlay
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-08-18 16:42:25 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-08-18 16:53:18 +0100
commitde2c97b27fa176deec12a6277448397fcc246e47 (patch)
tree864807fcce4ca870c2c595cb782392c864f46bfa /overlay
parent6a64ee938b90a2d27342aa42ba1d2d90da40dc7b (diff)
overlay: Add GPU frequency
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'overlay')
-rw-r--r--overlay/Makefile.am2
-rw-r--r--overlay/chart.c3
-rw-r--r--overlay/gpu-freq.c75
-rw-r--r--overlay/gpu-freq.h8
-rw-r--r--overlay/overlay.c71
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);