1fa225cbcSrjs/*
2fa225cbcSrjs * Copyright © 2007 Intel Corporation
3fa225cbcSrjs *
4fa225cbcSrjs * Permission is hereby granted, free of charge, to any person obtaining a
5fa225cbcSrjs * copy of this software and associated documentation files (the "Software"),
6fa225cbcSrjs * to deal in the Software without restriction, including without limitation
7fa225cbcSrjs * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8fa225cbcSrjs * and/or sell copies of the Software, and to permit persons to whom the
9fa225cbcSrjs * Software is furnished to do so, subject to the following conditions:
10fa225cbcSrjs *
11fa225cbcSrjs * The above copyright notice and this permission notice (including the next
12fa225cbcSrjs * paragraph) shall be included in all copies or substantial portions of the
13fa225cbcSrjs * Software.
14fa225cbcSrjs *
15fa225cbcSrjs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16fa225cbcSrjs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17fa225cbcSrjs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18fa225cbcSrjs * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19fa225cbcSrjs * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20fa225cbcSrjs * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21fa225cbcSrjs * DEALINGS IN THE SOFTWARE.
22fa225cbcSrjs *
23fa225cbcSrjs * Authors:
24fa225cbcSrjs *    Eric Anholt <eric@anholt.net>
25fa225cbcSrjs *
26fa225cbcSrjs */
27fa225cbcSrjs
28fa225cbcSrjs#include <stdio.h>
29fa225cbcSrjs#include <stdlib.h>
30fa225cbcSrjs#include <string.h>
31fa225cbcSrjs#include <stdarg.h>
32fa225cbcSrjs#include <pciaccess.h>
33fa225cbcSrjs#include <err.h>
34fa225cbcSrjs#include <unistd.h>
35fa225cbcSrjs
36fa225cbcSrjs#include "reg_dumper.h"
37fa225cbcSrjs#include "../i810_reg.h"
38fa225cbcSrjs
39fa225cbcSrjsstruct idle_flags {
40fa225cbcSrjs    uint32_t instdone_flag;
41fa225cbcSrjs    char *name;
42fa225cbcSrjs    int ignore;
43fa225cbcSrjs    unsigned int count;
44fa225cbcSrjs};
45fa225cbcSrjs
46fa225cbcSrjsstruct idle_flags i915_idle_flags[] = {
47fa225cbcSrjs    {IDCT_DONE, "IDCT", 1},
48fa225cbcSrjs    {IQ_DONE, "IQ", 1},
49fa225cbcSrjs    {PR_DONE, "PR", 1},
50fa225cbcSrjs    {VLD_DONE, "VLD", 1},
51fa225cbcSrjs    {IP_DONE, "IP", 1},
52fa225cbcSrjs    {FBC_DONE, "FBC"},
53fa225cbcSrjs    {BINNER_DONE, "BINNER"},
54fa225cbcSrjs    {SF_DONE, "SF"},
55fa225cbcSrjs    {SE_DONE, "SE"},
56fa225cbcSrjs    {WM_DONE, "WM"},
57fa225cbcSrjs    {IZ_DONE, "IZ"},
58fa225cbcSrjs    {PERSPECTIVE_INTERP_DONE, "perspective interpolation"},
59fa225cbcSrjs    {DISPATCHER_DONE, "dispatcher"},
60fa225cbcSrjs    {PROJECTION_DONE, "projection and LOD"},
61fa225cbcSrjs    {DEPENDENT_ADDRESS_DONE, "dependent address calc"},
62fa225cbcSrjs    {TEXTURE_FETCH_DONE, "texture fetch"},
63fa225cbcSrjs    {TEXTURE_DECOMPRESS_DONE, "texture decompress"},
64fa225cbcSrjs    {SAMPLER_CACHE_DONE, "sampler cache"},
65fa225cbcSrjs    {FILTER_DONE, "filter"},
66fa225cbcSrjs    {BYPASS_FIFO_DONE, "bypass FIFO"},
67fa225cbcSrjs    {PS_DONE, "PS"},
68fa225cbcSrjs    {CC_DONE, "CC"},
69fa225cbcSrjs    {MAP_FILTER_DONE, "map filter"},
70fa225cbcSrjs    {MAP_L2_IDLE, "map L2", 1},
71fa225cbcSrjs    {0x80000038, "reserved bits", 1},
72fa225cbcSrjs    {0, "total"},
73fa225cbcSrjs    {0, "other"},
74fa225cbcSrjs};
75fa225cbcSrjs
76fa225cbcSrjsstruct idle_flags i965_idle_flags[] = {
77fa225cbcSrjs    {I965_SF_DONE, "SF"},
78fa225cbcSrjs    {I965_SE_DONE, "SE"},
79fa225cbcSrjs    {I965_WM_DONE, "WM"},
80fa225cbcSrjs    {I965_TEXTURE_FETCH_DONE, "texture fetch"},
81fa225cbcSrjs    {I965_SAMPLER_CACHE_DONE, "sampler cache"},
82fa225cbcSrjs    {I965_FILTER_DONE, "filter"},
83fa225cbcSrjs    {I965_PS_DONE, "PS"},
84fa225cbcSrjs    {I965_CC_DONE, "CC"},
85fa225cbcSrjs    {I965_MAP_FILTER_DONE, "map filter"},
86fa225cbcSrjs    {I965_MAP_L2_IDLE, "map L2"},
87fa225cbcSrjs    {I965_CP_DONE, "CP"},
88fa225cbcSrjs    {0, "total"},
89fa225cbcSrjs    {0, "other"},
90fa225cbcSrjs};
91fa225cbcSrjs
92fa225cbcSrjs/* Fills in the "other" and "total" fields' idle flags */
93fa225cbcSrjsstatic void
94fa225cbcSrjssetup_other_flags(I830Ptr pI830,
95fa225cbcSrjs		  struct idle_flags *idle_flags, int idle_flag_count)
96fa225cbcSrjs{
97fa225cbcSrjs    uint32_t other_idle_flags, total_idle_flags = 0;
98fa225cbcSrjs    int i;
99fa225cbcSrjs
100fa225cbcSrjs    if (IS_I965G(pI830))
101fa225cbcSrjs	other_idle_flags = ~(I965_RING_0_ENABLE);
102fa225cbcSrjs    else
103fa225cbcSrjs	other_idle_flags = ~(RING_0_ENABLE | RING_1_ENABLE | RING_2_ENABLE);
104fa225cbcSrjs
105fa225cbcSrjs    for (i = 0; i < idle_flag_count - 2; i++) {
106fa225cbcSrjs	other_idle_flags &= ~idle_flags[i].instdone_flag;
107fa225cbcSrjs	if (!idle_flags[i].ignore)
108fa225cbcSrjs	    total_idle_flags |= idle_flags[i].instdone_flag;
109fa225cbcSrjs    }
110fa225cbcSrjs    idle_flags[idle_flag_count - 2].instdone_flag = total_idle_flags;
111fa225cbcSrjs    idle_flags[idle_flag_count - 1].instdone_flag = other_idle_flags;
112fa225cbcSrjs}
113fa225cbcSrjs
114fa225cbcSrjsint main(int argc, char **argv)
115fa225cbcSrjs{
116fa225cbcSrjs    struct pci_device *dev;
117fa225cbcSrjs    I830Rec i830;
118fa225cbcSrjs    I830Ptr pI830 = &i830;
119fa225cbcSrjs    ScrnInfoRec scrn;
120fa225cbcSrjs    int err, mmio_bar;
121fa225cbcSrjs    void *mmio;
122fa225cbcSrjs    struct idle_flags *idle_flags;
123fa225cbcSrjs    int idle_flag_count;
124fa225cbcSrjs
125fa225cbcSrjs    err = pci_system_init();
126fa225cbcSrjs    if (err != 0) {
127fa225cbcSrjs	fprintf(stderr, "Couldn't initialize PCI system: %s\n", strerror(err));
128fa225cbcSrjs	exit(1);
129fa225cbcSrjs    }
130fa225cbcSrjs
131fa225cbcSrjs    /* Grab the graphics card */
132fa225cbcSrjs    dev = pci_device_find_by_slot(0, 0, 2, 0);
133fa225cbcSrjs    if (dev == NULL)
134fa225cbcSrjs	errx(1, "Couldn't find graphics card");
135fa225cbcSrjs
136fa225cbcSrjs    err = pci_device_probe(dev);
137fa225cbcSrjs    if (err != 0) {
138fa225cbcSrjs	fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err));
139fa225cbcSrjs	exit(1);
140fa225cbcSrjs    }
141fa225cbcSrjs
142fa225cbcSrjs    if (dev->vendor_id != 0x8086)
143fa225cbcSrjs	errx(1, "Graphics card is non-intel");
144fa225cbcSrjs
145fa225cbcSrjs    i830.PciInfo = dev;
146fa225cbcSrjs
147fa225cbcSrjs    mmio_bar = IS_I9XX((&i830)) ? 0 : 1;
148fa225cbcSrjs
149fa225cbcSrjs    err = pci_device_map_range (dev,
150fa225cbcSrjs				dev->regions[mmio_bar].base_addr,
151fa225cbcSrjs				dev->regions[mmio_bar].size,
152fa225cbcSrjs				PCI_DEV_MAP_FLAG_WRITABLE,
153fa225cbcSrjs				&mmio);
154fa225cbcSrjs
155fa225cbcSrjs    if (err != 0) {
156fa225cbcSrjs	fprintf(stderr, "Couldn't map MMIO region: %s\n", strerror(err));
157fa225cbcSrjs	exit(1);
158fa225cbcSrjs    }
159fa225cbcSrjs    i830.mmio = mmio;
160fa225cbcSrjs
161fa225cbcSrjs    scrn.scrnIndex = 0;
162fa225cbcSrjs    scrn.pI830 = &i830;
163fa225cbcSrjs
164fa225cbcSrjs    if (IS_I965G(pI830)) {
165fa225cbcSrjs	idle_flags = i965_idle_flags;
166fa225cbcSrjs	idle_flag_count = ARRAY_SIZE(i965_idle_flags);
167fa225cbcSrjs    } else {
168fa225cbcSrjs	idle_flags = i915_idle_flags;
169fa225cbcSrjs	idle_flag_count = ARRAY_SIZE(i915_idle_flags);
170fa225cbcSrjs    }
171fa225cbcSrjs
172fa225cbcSrjs    setup_other_flags(pI830, idle_flags, idle_flag_count);
173fa225cbcSrjs
174fa225cbcSrjs    for (;;) {
175fa225cbcSrjs	int i, j;
176fa225cbcSrjs
177fa225cbcSrjs	for (i = 0; i < 100; i++) {
178fa225cbcSrjs	    uint32_t instdone;
179fa225cbcSrjs
180fa225cbcSrjs	    if (IS_I965G(pI830))
181fa225cbcSrjs		instdone = INREG(INST_DONE_I965);
182fa225cbcSrjs	    else
183fa225cbcSrjs		instdone = INREG(INST_DONE);
184fa225cbcSrjs
185fa225cbcSrjs	    for (j = 0; j < idle_flag_count; j++) {
186fa225cbcSrjs		if ((instdone & idle_flags[j].instdone_flag) !=
187fa225cbcSrjs		    idle_flags[j].instdone_flag)
188fa225cbcSrjs		    idle_flags[j].count++;
189fa225cbcSrjs	    }
190fa225cbcSrjs
191fa225cbcSrjs	    usleep (10000);
192fa225cbcSrjs	}
193fa225cbcSrjs
194fa225cbcSrjs	for (j = 0; j < idle_flag_count; j++) {
195fa225cbcSrjs	    if (!idle_flags[j].ignore)
196fa225cbcSrjs		printf("%25s: %3d\n", idle_flags[j].name, idle_flags[j].count);
197fa225cbcSrjs	    else
198fa225cbcSrjs		printf("%25s: %3d (unreliable)\n",
199fa225cbcSrjs		       idle_flags[j].name, idle_flags[j].count);
200fa225cbcSrjs	    idle_flags[j].count = 0;
201fa225cbcSrjs	}
202fa225cbcSrjs	printf("\n");
203fa225cbcSrjs    }
204fa225cbcSrjs
205fa225cbcSrjs    return 0;
206fa225cbcSrjs}
207fa225cbcSrjs
208fa225cbcSrjsvoid xf86DrvMsg(int scrnIndex, int severity, const char *format, ...)
209fa225cbcSrjs{
210fa225cbcSrjs    va_list va;
211fa225cbcSrjs
212fa225cbcSrjs    switch (severity) {
213fa225cbcSrjs    case X_INFO:
214fa225cbcSrjs	printf("(II): ");
215fa225cbcSrjs	break;
216fa225cbcSrjs    case X_WARNING:
217fa225cbcSrjs	printf("(WW): ");
218fa225cbcSrjs	break;
219fa225cbcSrjs    case X_ERROR:
220fa225cbcSrjs	printf("(EE): ");
221fa225cbcSrjs	break;
222fa225cbcSrjs    }
223fa225cbcSrjs
224fa225cbcSrjs    va_start(va, format);
225fa225cbcSrjs    vprintf(format, va);
226fa225cbcSrjs    va_end(va);
227fa225cbcSrjs}
228