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