intel_gpu_top: Wake the GT power well to read gen6 ring registers
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 7 Jan 2011 19:42:29 +0000 (19:42 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 7 Jan 2011 19:58:55 +0000 (19:58 +0000)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
tools/intel_gpu_top.c

index fb2cd4a..a70d7a0 100644 (file)
@@ -33,6 +33,9 @@
 #include "intel_gpu_tools.h"
 #include "instdone.h"
 
+#define  FORCEWAKE         0xA18C
+#define  FORCEWAKE_ACK     0x130090
+
 #define SAMPLES_PER_SEC             10000
 #define SAMPLES_TO_PERCENT_RATIO    (SAMPLES_PER_SEC / 100)
 
@@ -47,6 +50,7 @@ struct top_bit {
 struct top_bit *top_bits_sorted[MAX_NUM_TOP_BITS];
 
 static uint32_t instdone, instdone1;
+static uint32_t devid;
 
 static const char *bars[] = {
        " ",
@@ -293,9 +297,43 @@ struct ring {
        int idle;
 };
 
+static void gen6_force_wake_get(void)
+{
+       int count;
+
+       if (!IS_GEN6(devid))
+               return;
+
+       /* This will probably have undesirable side-effects upon the system. */
+       count = 0;
+       while (count++ < 50 && (INREG(FORCEWAKE_ACK) & 1))
+               usleep(10);
+
+       OUTREG(FORCEWAKE, 1);
+
+       count = 0;
+       while (count++ < 50 && (INREG(FORCEWAKE_ACK) & 1) == 0)
+               usleep(10);
+}
+
+static void gen6_force_wake_put(void)
+{
+       if (!IS_GEN6(devid))
+               return;
+
+       OUTREG(FORCEWAKE, 0);
+}
+
+static uint32_t ring_read(struct ring *ring, uint32_t reg)
+{
+       return INREG(ring->mmio + reg);
+}
+
 static void ring_init(struct ring *ring)
 {
-       ring->size = ((INREG(ring->mmio + RING_LEN) & RING_NR_PAGES) >> 12) * 4096;
+       gen6_force_wake_get();
+       ring->size = ((ring_read(ring, RING_LEN) & RING_NR_PAGES) >> 12) * 4096;
+       gen6_force_wake_put();
 }
 
 static void ring_reset(struct ring *ring)
@@ -310,8 +348,10 @@ static void ring_sample(struct ring *ring)
        if (!ring->size)
                return;
 
-       ring->head = INREG(ring->mmio + RING_HEAD) & HEAD_ADDR;
-       ring->tail = INREG(ring->mmio + RING_TAIL) & TAIL_ADDR;
+       gen6_force_wake_get();
+       ring->head = ring_read(ring, RING_HEAD) & HEAD_ADDR;
+       ring->tail = ring_read(ring, RING_TAIL) & TAIL_ADDR;
+       gen6_force_wake_put();
 
        if (ring->tail == ring->head)
                ring->idle++;
@@ -352,7 +392,6 @@ int main(int argc, char **argv)
                .name = "bitstream",
                .mmio = 0x12030,
        };
-       uint32_t devid;
        int i;
 
        pci_dev = intel_get_pci_device();