1 /* 2 * Copyright 2006 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 FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Eric Anholt <eric (at) anholt.net> 25 * 26 */ 27 28 #include <inttypes.h> 29 30 #ifdef REG_DUMPER 31 #include "reg_dumper/reg_dumper.h" 32 33 #else 34 35 #ifdef HAVE_CONFIG_H 36 #include "config.h" 37 #endif 38 39 #include "xf86.h" 40 #include "i830.h" 41 #include "i830_debug.h" 42 #include <strings.h> 43 44 #endif 45 46 #include "i810_reg.h" 47 48 #define DEBUGSTRING(func) static char *func(I830Ptr pI830, int reg, \ 49 uint32_t val) 50 51 DEBUGSTRING(i830_16bit_func) 52 { 53 return XNFprintf("0x%04x", (uint16_t)val); 54 } 55 56 DEBUGSTRING(i830_debug_dcc) 57 { 58 char *addressing = NULL; 59 60 if (!IS_MOBILE(pI830)) 61 return NULL; 62 63 if (IS_I965G(pI830)) { 64 if (val & (1 << 1)) 65 addressing = "dual channel interleaved"; 66 else 67 addressing = "single or dual channel asymmetric"; 68 } else { 69 switch (val & 3) { 70 case 0: addressing = "single channel"; break; 71 case 1: addressing = "dual channel asymmetric"; break; 72 case 2: addressing = "dual channel interleaved"; break; 73 case 3: addressing = "unknown channel layout"; break; 74 } 75 } 76 77 return XNFprintf("%s, XOR randomization: %sabled, XOR bit: %d", 78 addressing, 79 (val & (1 << 10)) ? "dis" : "en", 80 (val & (1 << 9)) ? 17 : 11); 81 } 82 83 DEBUGSTRING(i830_debug_chdecmisc) 84 { 85 char *enhmodesel = NULL; 86 87 switch ((val >> 5) & 3) { 88 case 1: enhmodesel = "XOR bank/rank"; break; 89 case 2: enhmodesel = "swap bank"; break; 90 case 3: enhmodesel = "XOR bank"; break; 91 case 0: enhmodesel = "none"; break; 92 } 93 94 return XNFprintf("%s, ch2 enh %sabled, ch1 enh %sabled, ch0 enh %sabled, " 95 "flex %sabled, ep %spresent", 96 enhmodesel, 97 (val & (1 << 4)) ? "en" : "dis", 98 (val & (1 << 3)) ? "en" : "dis", 99 (val & (1 << 2)) ? "en" : "dis", 100 (val & (1 << 1)) ? "en" : "dis", 101 (val & (1 << 0)) ? "" : "not "); 102 } 103 104 DEBUGSTRING(i830_debug_xyminus1) 105 { 106 return XNFprintf("%d, %d", (val & 0xffff) + 1, 107 ((val & 0xffff0000) >> 16) + 1); 108 } 109 110 DEBUGSTRING(i830_debug_yxminus1) 111 { 112 return XNFprintf("%d, %d", ((val & 0xffff0000) >> 16) + 1, 113 (val & 0xffff) + 1); 114 } 115 116 DEBUGSTRING(i830_debug_xy) 117 { 118 return XNFprintf("%d, %d", (val & 0xffff), 119 ((val & 0xffff0000) >> 16)); 120 } 121 122 DEBUGSTRING(i830_debug_dspstride) 123 { 124 return XNFprintf("%d bytes", val); 125 } 126 127 DEBUGSTRING(i830_debug_dspcntr) 128 { 129 char *enabled = val & DISPLAY_PLANE_ENABLE ? "enabled" : "disabled"; 130 char plane = val & DISPPLANE_SEL_PIPE_B ? 'B' : 'A'; 131 if (IS_IGDNG(pI830)) 132 return XNFprintf("%s", enabled); 133 else 134 return XNFprintf("%s, pipe %c", enabled, plane); 135 } 136 137 DEBUGSTRING(i830_debug_pipeconf) 138 { 139 char *enabled = val & PIPEACONF_ENABLE ? "enabled" : "disabled"; 140 char *bit30; 141 char *bpc = NULL; 142 if (IS_I965G(pI830)) 143 bit30 = val & I965_PIPECONF_ACTIVE ? "active" : "inactive"; 144 else 145 bit30 = val & PIPEACONF_DOUBLE_WIDE ? "double-wide" : "single-wide"; 146 147 if (IS_IGDNG(pI830)) { 148 switch (val & (7<<5)) { 149 case PIPECONF_8BPP: 150 bpc = "8bpc"; 151 break; 152 case PIPECONF_10BPP: 153 bpc = "10bpc"; 154 break; 155 case PIPECONF_6BPP: 156 bpc = "6bpc"; 157 break; 158 case PIPECONF_12BPP: 159 bpc = "12bpc"; 160 break; 161 } 162 } 163 if (IS_IGDNG(pI830)) 164 return XNFprintf("%s, %s, %s", enabled, bit30, bpc); 165 else 166 return XNFprintf("%s, %s", enabled, bit30); 167 } 168 169 DEBUGSTRING(i830_debug_pipestat) 170 { 171 char *_FIFO_UNDERRUN = val & FIFO_UNDERRUN ? " FIFO_UNDERRUN" : ""; 172 char *_CRC_ERROR_ENABLE = val & CRC_ERROR_ENABLE ? " CRC_ERROR_ENABLE" : ""; 173 char *_CRC_DONE_ENABLE = val & CRC_DONE_ENABLE ? " CRC_DONE_ENABLE" : ""; 174 char *_GMBUS_EVENT_ENABLE = val & GMBUS_EVENT_ENABLE ? " GMBUS_EVENT_ENABLE" : ""; 175 char *_VSYNC_INT_ENABLE = val & VSYNC_INT_ENABLE ? " VSYNC_INT_ENABLE" : ""; 176 char *_DLINE_COMPARE_ENABLE = val & DLINE_COMPARE_ENABLE ? " DLINE_COMPARE_ENABLE" : ""; 177 char *_DPST_EVENT_ENABLE = val & DPST_EVENT_ENABLE ? " DPST_EVENT_ENABLE" : ""; 178 char *_LBLC_EVENT_ENABLE = val & LBLC_EVENT_ENABLE ? " LBLC_EVENT_ENABLE" : ""; 179 char *_OFIELD_INT_ENABLE = val & OFIELD_INT_ENABLE ? " OFIELD_INT_ENABLE" : ""; 180 char *_EFIELD_INT_ENABLE = val & EFIELD_INT_ENABLE ? " EFIELD_INT_ENABLE" : ""; 181 char *_SVBLANK_INT_ENABLE = val & SVBLANK_INT_ENABLE ? " SVBLANK_INT_ENABLE" : ""; 182 char *_VBLANK_INT_ENABLE = val & VBLANK_INT_ENABLE ? " VBLANK_INT_ENABLE" : ""; 183 char *_OREG_UPDATE_ENABLE = val & OREG_UPDATE_ENABLE ? " OREG_UPDATE_ENABLE" : ""; 184 char *_CRC_ERROR_INT_STATUS = val & CRC_ERROR_INT_STATUS ? " CRC_ERROR_INT_STATUS" : ""; 185 char *_CRC_DONE_INT_STATUS = val & CRC_DONE_INT_STATUS ? " CRC_DONE_INT_STATUS" : ""; 186 char *_GMBUS_INT_STATUS = val & GMBUS_INT_STATUS ? " GMBUS_INT_STATUS" : ""; 187 char *_VSYNC_INT_STATUS = val & VSYNC_INT_STATUS ? " VSYNC_INT_STATUS" : ""; 188 char *_DLINE_COMPARE_STATUS = val & DLINE_COMPARE_STATUS ? " DLINE_COMPARE_STATUS" : ""; 189 char *_DPST_EVENT_STATUS = val & DPST_EVENT_STATUS ? " DPST_EVENT_STATUS" : ""; 190 char *_LBLC_EVENT_STATUS = val & LBLC_EVENT_STATUS ? " LBLC_EVENT_STATUS" : ""; 191 char *_OFIELD_INT_STATUS = val & OFIELD_INT_STATUS ? " OFIELD_INT_STATUS" : ""; 192 char *_EFIELD_INT_STATUS = val & EFIELD_INT_STATUS ? " EFIELD_INT_STATUS" : ""; 193 char *_SVBLANK_INT_STATUS = val & SVBLANK_INT_STATUS ? " SVBLANK_INT_STATUS" : ""; 194 char *_VBLANK_INT_STATUS = val & VBLANK_INT_STATUS ? " VBLANK_INT_STATUS" : ""; 195 char *_OREG_UPDATE_STATUS = val & OREG_UPDATE_STATUS ? " OREG_UPDATE_STATUS" : ""; 196 return XNFprintf("status:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 197 _FIFO_UNDERRUN, 198 _CRC_ERROR_ENABLE, 199 _CRC_DONE_ENABLE, 200 _GMBUS_EVENT_ENABLE, 201 _VSYNC_INT_ENABLE, 202 _DLINE_COMPARE_ENABLE, 203 _DPST_EVENT_ENABLE, 204 _LBLC_EVENT_ENABLE, 205 _OFIELD_INT_ENABLE, 206 _EFIELD_INT_ENABLE, 207 _SVBLANK_INT_ENABLE, 208 _VBLANK_INT_ENABLE, 209 _OREG_UPDATE_ENABLE, 210 _CRC_ERROR_INT_STATUS, 211 _CRC_DONE_INT_STATUS, 212 _GMBUS_INT_STATUS, 213 _VSYNC_INT_STATUS, 214 _DLINE_COMPARE_STATUS, 215 _DPST_EVENT_STATUS, 216 _LBLC_EVENT_STATUS, 217 _OFIELD_INT_STATUS, 218 _EFIELD_INT_STATUS, 219 _SVBLANK_INT_STATUS, 220 _VBLANK_INT_STATUS, 221 _OREG_UPDATE_STATUS); 222 } 223 224 DEBUGSTRING(i830_debug_hvtotal) 225 { 226 return XNFprintf("%d active, %d total", (val & 0xffff) + 1, 227 ((val & 0xffff0000) >> 16) + 1); 228 } 229 230 DEBUGSTRING(i830_debug_hvsyncblank) 231 { 232 return XNFprintf("%d start, %d end", (val & 0xffff) + 1, 233 ((val & 0xffff0000) >> 16) + 1); 234 } 235 236 DEBUGSTRING(i830_debug_vgacntrl) 237 { 238 return XNFprintf("%s", val & VGA_DISP_DISABLE ? "disabled" : "enabled"); 239 } 240 241 DEBUGSTRING(i830_debug_fp) 242 { 243 if (IS_IGD(pI830)) { 244 return XNFprintf("n = %d, m1 = %d, m2 = %d", 245 ffs((val & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1, 246 ((val & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT), 247 ((val & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT)); 248 } 249 return XNFprintf("n = %d, m1 = %d, m2 = %d", 250 ((val & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT), 251 ((val & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT), 252 ((val & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT)); 253 } 254 255 DEBUGSTRING(i830_debug_vga_pd) 256 { 257 int vga0_p1, vga0_p2, vga1_p1, vga1_p2; 258 259 /* XXX: i9xx version */ 260 261 if (val & VGA0_PD_P1_DIV_2) 262 vga0_p1 = 2; 263 else 264 vga0_p1 = ((val & VGA0_PD_P1_MASK) >> VGA0_PD_P1_SHIFT) + 2; 265 vga0_p2 = (val & VGA0_PD_P2_DIV_4) ? 4 : 2; 266 267 if (val & VGA1_PD_P1_DIV_2) 268 vga1_p1 = 2; 269 else 270 vga1_p1 = ((val & VGA1_PD_P1_MASK) >> VGA1_PD_P1_SHIFT) + 2; 271 vga1_p2 = (val & VGA1_PD_P2_DIV_4) ? 4 : 2; 272 273 return XNFprintf("vga0 p1 = %d, p2 = %d, vga1 p1 = %d, p2 = %d", 274 vga0_p1, vga0_p2, vga1_p1, vga1_p2); 275 } 276 277 DEBUGSTRING(i830_debug_pp_status) 278 { 279 char *status = val & PP_ON ? "on" : "off"; 280 char *ready = val & PP_READY ? "ready" : "not ready"; 281 char *seq = "unknown"; 282 283 switch (val & PP_SEQUENCE_MASK) { 284 case PP_SEQUENCE_NONE: 285 seq = "idle"; 286 break; 287 case PP_SEQUENCE_ON: 288 seq = "on"; 289 break; 290 case PP_SEQUENCE_OFF: 291 seq = "off"; 292 break; 293 } 294 295 return XNFprintf("%s, %s, sequencing %s", status, ready, seq); 296 } 297 298 DEBUGSTRING(i830_debug_pp_control) 299 { 300 return XNFprintf("power target: %s", 301 val & POWER_TARGET_ON ? "on" : "off"); 302 } 303 304 DEBUGSTRING(i830_debug_dpll) 305 { 306 char *enabled = val & DPLL_VCO_ENABLE ? "enabled" : "disabled"; 307 char *dvomode = val & DPLL_DVO_HIGH_SPEED ? "dvo" : "non-dvo"; 308 char *vgamode = val & DPLL_VGA_MODE_DIS ? "" : ", VGA"; 309 char *mode = "unknown"; 310 char *clock = "unknown"; 311 char *fpextra = val & DISPLAY_RATE_SELECT_FPA1 ? ", using FPx1!" : ""; 312 char sdvoextra[20]; 313 int p1, p2 = 0; 314 315 if (IS_I9XX(pI830)) { 316 if (IS_IGD(pI830)) { 317 p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >> 318 DPLL_FPA01_P1_POST_DIV_SHIFT_IGD); 319 } else { 320 p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >> 321 DPLL_FPA01_P1_POST_DIV_SHIFT); 322 } 323 switch (val & DPLL_MODE_MASK) { 324 case DPLLB_MODE_DAC_SERIAL: 325 mode = "DAC/serial"; 326 p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; 327 break; 328 case DPLLB_MODE_LVDS: 329 mode = "LVDS"; 330 p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; 331 break; 332 } 333 } else { 334 Bool is_lvds = (INREG(LVDS) & LVDS_PORT_EN) && (reg == DPLL_B); 335 336 if (is_lvds) { 337 mode = "LVDS"; 338 p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> 339 DPLL_FPA01_P1_POST_DIV_SHIFT); 340 if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) 341 p2 = 7; 342 else 343 p2 = 14; 344 345 } else { 346 mode = "DAC/serial"; 347 if (val & PLL_P1_DIVIDE_BY_TWO) { 348 p1 = 2; 349 } else { 350 /* Map the number in the field to (3, 33) */ 351 p1 = ((val & DPLL_FPA01_P1_POST_DIV_MASK_I830) >> 352 DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; 353 } 354 if (val & PLL_P2_DIVIDE_BY_4) 355 p2 = 4; 356 else 357 p2 = 2; 358 } 359 } 360 361 switch (val & PLL_REF_INPUT_MASK) { 362 case PLL_REF_INPUT_DREFCLK: 363 clock = "default"; 364 break; 365 case PLL_REF_INPUT_TVCLKINA: 366 clock = "TV A"; 367 break; 368 case PLL_REF_INPUT_TVCLKINBC: 369 clock = "TV B/C"; 370 break; 371 case PLLB_REF_INPUT_SPREADSPECTRUMIN: 372 if (reg == DPLL_B) 373 clock = "spread spectrum"; 374 break; 375 } 376 377 if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830)) { 378 sprintf(sdvoextra, ", SDVO mult %d", 379 (int)((val & SDVO_MULTIPLIER_MASK) >> 380 SDVO_MULTIPLIER_SHIFT_HIRES) + 1); 381 } else { 382 sdvoextra[0] = '\0'; 383 } 384 385 return XNFprintf("%s, %s%s, %s clock, %s mode, p1 = %d, " 386 "p2 = %d%s%s", 387 enabled, dvomode, vgamode, clock, mode, p1, p2, 388 fpextra, sdvoextra); 389 } 390 391 DEBUGSTRING(i830_debug_dpll_test) 392 { 393 char *dpllandiv = val & DPLLA_TEST_N_BYPASS ? ", DPLLA N bypassed" : ""; 394 char *dpllamdiv = val & DPLLA_TEST_M_BYPASS ? ", DPLLA M bypassed" : ""; 395 char *dpllainput = val & DPLLA_INPUT_BUFFER_ENABLE ? 396 "" : ", DPLLA input buffer disabled"; 397 char *dpllbndiv = val & DPLLB_TEST_N_BYPASS ? ", DPLLB N bypassed" : ""; 398 char *dpllbmdiv = val & DPLLB_TEST_M_BYPASS ? ", DPLLB M bypassed" : ""; 399 char *dpllbinput = val & DPLLB_INPUT_BUFFER_ENABLE ? 400 "" : ", DPLLB input buffer disabled"; 401 402 return XNFprintf("%s%s%s%s%s%s", 403 dpllandiv, dpllamdiv, dpllainput, 404 dpllbndiv, dpllbmdiv, dpllbinput); 405 } 406 407 DEBUGSTRING(i830_debug_adpa) 408 { 409 char pipe = (val & ADPA_PIPE_B_SELECT) ? 'B' : 'A'; 410 char *enable = (val & ADPA_DAC_ENABLE) ? "enabled" : "disabled"; 411 char hsync = (val & ADPA_HSYNC_ACTIVE_HIGH) ? '+' : '-'; 412 char vsync = (val & ADPA_VSYNC_ACTIVE_HIGH) ? '+' : '-'; 413 414 if (IS_IGDNG(pI830)) 415 return XNFprintf("%s, transcoder %c, %chsync, %cvsync", 416 enable, pipe, hsync, vsync); 417 else 418 return XNFprintf("%s, pipe %c, %chsync, %cvsync", 419 enable, pipe, hsync, vsync); 420 } 421 422 DEBUGSTRING(i830_debug_lvds) 423 { 424 char pipe = val & LVDS_PIPEB_SELECT ? 'B' : 'A'; 425 char *enable = val & LVDS_PORT_EN ? "enabled" : "disabled"; 426 int depth; 427 char *channels; 428 429 if ((val & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) 430 depth = 24; 431 else 432 depth = 18; 433 if ((val & LVDS_B0B3_POWER_MASK) == LVDS_B0B3_POWER_UP) 434 channels = "2 channels"; 435 else 436 channels = "1 channel"; 437 438 439 return XNFprintf("%s, pipe %c, %d bit, %s", 440 enable, pipe, depth, channels); 441 } 442 443 DEBUGSTRING(i830_debug_dvo) 444 { 445 char *enable = val & DVO_ENABLE ? "enabled" : "disabled"; 446 char pipe = val & DVO_PIPE_B_SELECT ? 'B' : 'A'; 447 char *stall; 448 char hsync = val & DVO_HSYNC_ACTIVE_HIGH ? '+' : '-'; 449 char vsync = val & DVO_VSYNC_ACTIVE_HIGH ? '+' : '-'; 450 451 switch (val & DVO_PIPE_STALL_MASK) { 452 case DVO_PIPE_STALL_UNUSED: 453 stall = "no stall"; 454 break; 455 case DVO_PIPE_STALL: 456 stall = "stall"; 457 break; 458 case DVO_PIPE_STALL_TV: 459 stall = "TV stall"; 460 break; 461 default: 462 stall = "unknown stall"; 463 break; 464 } 465 466 return XNFprintf("%s, pipe %c, %s, %chsync, %cvsync", 467 enable, pipe, stall, hsync, vsync); 468 } 469 470 DEBUGSTRING(i830_debug_sdvo) 471 { 472 char *enable = val & SDVO_ENABLE ? "enabled" : "disabled"; 473 char pipe = val & SDVO_PIPE_B_SELECT ? 'B' : 'A'; 474 char *stall = val & SDVO_STALL_SELECT ? "enabled" : "disabled"; 475 char *detected = val & SDVO_DETECTED ? "" : "not "; 476 char *gang = val & SDVOC_GANG_MODE ? ", gang mode" : ""; 477 char sdvoextra[20]; 478 479 if (IS_I915G(pI830) || IS_I915GM(pI830)) { 480 sprintf(sdvoextra, ", SDVO mult %d", 481 (int)((val & SDVO_PORT_MULTIPLY_MASK) >> 482 SDVO_PORT_MULTIPLY_SHIFT) + 1); 483 } else { 484 sdvoextra[0] = '\0'; 485 } 486 487 return XNFprintf("%s, pipe %c, stall %s, %sdetected%s%s", 488 enable, pipe, stall, detected, sdvoextra, gang); 489 } 490 491 DEBUGSTRING(i830_debug_dspclk_gate_d) 492 { 493 char *DPUNIT_B = val & DPUNIT_B_CLOCK_GATE_DISABLE ? " DPUNIT_B" : ""; 494 char *VSUNIT = val & VSUNIT_CLOCK_GATE_DISABLE ? " VSUNIT" : ""; 495 char *VRHUNIT = val & VRHUNIT_CLOCK_GATE_DISABLE ? " VRHUNIT" : ""; 496 char *VRDUNIT = val & VRDUNIT_CLOCK_GATE_DISABLE ? " VRDUNIT" : ""; 497 char *AUDUNIT = val & AUDUNIT_CLOCK_GATE_DISABLE ? " AUDUNIT" : ""; 498 char *DPUNIT_A = val & DPUNIT_A_CLOCK_GATE_DISABLE ? " DPUNIT_A" : ""; 499 char *DPCUNIT = val & DPCUNIT_CLOCK_GATE_DISABLE ? " DPCUNIT" : ""; 500 char *TVRUNIT = val & TVRUNIT_CLOCK_GATE_DISABLE ? " TVRUNIT" : ""; 501 char *TVCUNIT = val & TVCUNIT_CLOCK_GATE_DISABLE ? " TVCUNIT" : ""; 502 char *TVFUNIT = val & TVFUNIT_CLOCK_GATE_DISABLE ? " TVFUNIT" : ""; 503 char *TVEUNIT = val & TVEUNIT_CLOCK_GATE_DISABLE ? " TVEUNIT" : ""; 504 char *DVSUNIT = val & DVSUNIT_CLOCK_GATE_DISABLE ? " DVSUNIT" : ""; 505 char *DSSUNIT = val & DSSUNIT_CLOCK_GATE_DISABLE ? " DSSUNIT" : ""; 506 char *DDBUNIT = val & DDBUNIT_CLOCK_GATE_DISABLE ? " DDBUNIT" : ""; 507 char *DPRUNIT = val & DPRUNIT_CLOCK_GATE_DISABLE ? " DPRUNIT" : ""; 508 char *DPFUNIT = val & DPFUNIT_CLOCK_GATE_DISABLE ? " DPFUNIT" : ""; 509 char *DPBMUNIT = val & DPBMUNIT_CLOCK_GATE_DISABLE ? " DPBMUNIT" : ""; 510 char *DPLSUNIT = val & DPLSUNIT_CLOCK_GATE_DISABLE ? " DPLSUNIT" : ""; 511 char *DPLUNIT = val & DPLUNIT_CLOCK_GATE_DISABLE ? " DPLUNIT" : ""; 512 char *DPOUNIT = val & DPOUNIT_CLOCK_GATE_DISABLE ? " DPOUNIT" : ""; 513 char *DPBUNIT = val & DPBUNIT_CLOCK_GATE_DISABLE ? " DPBUNIT" : ""; 514 char *DCUNIT = val & DCUNIT_CLOCK_GATE_DISABLE ? " DCUNIT" : ""; 515 char *DPUNIT = val & DPUNIT_CLOCK_GATE_DISABLE ? " DPUNIT" : ""; 516 char *VRUNIT = val & VRUNIT_CLOCK_GATE_DISABLE ? " VRUNIT" : ""; 517 char *OVHUNIT = val & OVHUNIT_CLOCK_GATE_DISABLE ? " OVHUNIT" : ""; 518 char *DPIOUNIT = val & DPIOUNIT_CLOCK_GATE_DISABLE ? " DPIOUNIT" : ""; 519 char *OVFUNIT = val & OVFUNIT_CLOCK_GATE_DISABLE ? " OVFUNIT" : ""; 520 char *OVBUNIT = val & OVBUNIT_CLOCK_GATE_DISABLE ? " OVBUNIT" : ""; 521 char *OVRUNIT = val & OVRUNIT_CLOCK_GATE_DISABLE ? " OVRUNIT" : ""; 522 char *OVCUNIT = val & OVCUNIT_CLOCK_GATE_DISABLE ? " OVCUNIT" : ""; 523 char *OVUUNIT = val & OVUUNIT_CLOCK_GATE_DISABLE ? " OVUUNIT" : ""; 524 char *OVLUNIT = val & OVLUNIT_CLOCK_GATE_DISABLE ? " OVLUNIT" : ""; 525 526 return XNFprintf ("clock gates disabled:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 527 DPUNIT_B, 528 VSUNIT, 529 VRHUNIT, 530 VRDUNIT, 531 AUDUNIT, 532 DPUNIT_A, 533 DPCUNIT, 534 TVRUNIT, 535 TVCUNIT, 536 TVFUNIT, 537 TVEUNIT, 538 DVSUNIT, 539 DSSUNIT, 540 DDBUNIT, 541 DPRUNIT, 542 DPFUNIT, 543 DPBMUNIT, 544 DPLSUNIT, 545 DPLUNIT, 546 DPOUNIT, 547 DPBUNIT, 548 DCUNIT, 549 DPUNIT, 550 VRUNIT, 551 OVHUNIT, 552 DPIOUNIT, 553 OVFUNIT, 554 OVBUNIT, 555 OVRUNIT, 556 OVCUNIT, 557 OVUUNIT, 558 OVLUNIT); 559 } 560 561 562 DEBUGSTRING(i810_debug_915_fence) 563 { 564 char *enable = (val & 1) ? " enabled" : "disabled"; 565 char format = (val & 1 << 12) ? 'Y' : 'X'; 566 int pitch = 1 << (((val & 0x70) >> 4) - 1); 567 unsigned int offset = val & 0x0ff00000; 568 int size = (1024 * 1024) << (((val & 0x700) >> 8) - 1); 569 570 if (IS_I965G(pI830) || ((IS_I915G(pI830) || IS_I915GM(pI830)) && reg >= FENCE_NEW)) 571 return NULL; 572 573 if (format == 'X') 574 pitch *= 4; 575 576 return XNFprintf("%s, %c tiled, %4d pitch, 0x%08x - 0x%08x (%dkb)", 577 enable, format, pitch, offset, offset + size, size / 1024); 578 } 579 580 DEBUGSTRING(i810_debug_965_fence_start) 581 { 582 char *enable = (val & FENCE_VALID) ? " enabled" : "disabled"; 583 char format = (val & I965_FENCE_Y_MAJOR) ? 'Y' : 'X'; 584 int pitch = ((val & 0xffc) >> 2) * 128; 585 unsigned int offset = val & 0xfffff000; 586 587 if (!IS_I965G(pI830)) 588 return NULL; 589 590 return XNFprintf("%s, %c tile walk, %4d pitch, 0x%08x start", 591 enable, format, pitch, offset); 592 } 593 594 DEBUGSTRING(i810_debug_965_fence_end) 595 { 596 unsigned int end = val & 0xfffff000; 597 598 if (!IS_I965G(pI830)) 599 return NULL; 600 601 return XNFprintf(" 0x%08x end", end); 602 } 603 604 #define DEFINEREG(reg) \ 605 { reg, #reg, NULL, 0 } 606 #define DEFINEREG_16BIT(reg) \ 607 { reg, #reg, i830_16bit_func, 0 } 608 #define DEFINEREG2(reg, func) \ 609 { reg, #reg, func, 0 } 610 611 struct i830SnapshotRec { 612 int reg; 613 char *name; 614 char *(*debug_output)(I830Ptr pI830, int reg, uint32_t val); 615 uint32_t val; 616 }; 617 618 static struct i830SnapshotRec i830_snapshot[] = { 619 DEFINEREG2(DCC, i830_debug_dcc), 620 DEFINEREG2(CHDECMISC, i830_debug_chdecmisc), 621 DEFINEREG_16BIT(C0DRB0), 622 DEFINEREG_16BIT(C0DRB1), 623 DEFINEREG_16BIT(C0DRB2), 624 DEFINEREG_16BIT(C0DRB3), 625 DEFINEREG_16BIT(C1DRB0), 626 DEFINEREG_16BIT(C1DRB1), 627 DEFINEREG_16BIT(C1DRB2), 628 DEFINEREG_16BIT(C1DRB3), 629 DEFINEREG_16BIT(C0DRA01), 630 DEFINEREG_16BIT(C0DRA23), 631 DEFINEREG_16BIT(C1DRA01), 632 DEFINEREG_16BIT(C1DRA23), 633 634 DEFINEREG(PGETBL_CTL), 635 636 DEFINEREG2(VCLK_DIVISOR_VGA0, i830_debug_fp), 637 DEFINEREG2(VCLK_DIVISOR_VGA1, i830_debug_fp), 638 DEFINEREG2(VCLK_POST_DIV, i830_debug_vga_pd), 639 DEFINEREG2(DPLL_TEST, i830_debug_dpll_test), 640 DEFINEREG(CACHE_MODE_0), 641 DEFINEREG(D_STATE), 642 DEFINEREG2(DSPCLK_GATE_D, i830_debug_dspclk_gate_d), 643 DEFINEREG(RENCLK_GATE_D1), 644 DEFINEREG(RENCLK_GATE_D2), 645 /* DEFINEREG(RAMCLK_GATE_D), CRL only */ 646 DEFINEREG2(SDVOB, i830_debug_sdvo), 647 DEFINEREG2(SDVOC, i830_debug_sdvo), 648 /* DEFINEREG(UDIB_SVB_SHB_CODES), CRL only */ 649 /* DEFINEREG(UDIB_SHA_BLANK_CODES), CRL only */ 650 DEFINEREG(SDVOUDI), 651 DEFINEREG(DSPARB), 652 DEFINEREG(DSPFW1), 653 DEFINEREG(DSPFW2), 654 DEFINEREG(DSPFW3), 655 656 DEFINEREG2(ADPA, i830_debug_adpa), 657 DEFINEREG2(LVDS, i830_debug_lvds), 658 DEFINEREG2(DVOA, i830_debug_dvo), 659 DEFINEREG2(DVOB, i830_debug_dvo), 660 DEFINEREG2(DVOC, i830_debug_dvo), 661 DEFINEREG(DVOA_SRCDIM), 662 DEFINEREG(DVOB_SRCDIM), 663 DEFINEREG(DVOC_SRCDIM), 664 665 DEFINEREG2(PP_CONTROL, i830_debug_pp_control), 666 DEFINEREG2(PP_STATUS, i830_debug_pp_status), 667 DEFINEREG(PP_ON_DELAYS), 668 DEFINEREG(PP_OFF_DELAYS), 669 DEFINEREG(PP_DIVISOR), 670 DEFINEREG(PFIT_CONTROL), 671 DEFINEREG(PFIT_PGM_RATIOS), 672 DEFINEREG(PORT_HOTPLUG_EN), 673 DEFINEREG(PORT_HOTPLUG_STAT), 674 675 DEFINEREG2(DSPACNTR, i830_debug_dspcntr), 676 DEFINEREG2(DSPASTRIDE, i830_debug_dspstride), 677 DEFINEREG2(DSPAPOS, i830_debug_xy), 678 DEFINEREG2(DSPASIZE, i830_debug_xyminus1), 679 DEFINEREG(DSPABASE), 680 DEFINEREG(DSPASURF), 681 DEFINEREG(DSPATILEOFF), 682 DEFINEREG2(PIPEACONF, i830_debug_pipeconf), 683 DEFINEREG2(PIPEASRC, i830_debug_yxminus1), 684 DEFINEREG2(PIPEASTAT, i830_debug_pipestat), 685 DEFINEREG(PIPEA_GMCH_DATA_M), 686 DEFINEREG(PIPEA_GMCH_DATA_N), 687 DEFINEREG(PIPEA_DP_LINK_M), 688 DEFINEREG(PIPEA_DP_LINK_N), 689 DEFINEREG(CURSOR_A_BASE), 690 DEFINEREG(CURSOR_A_CONTROL), 691 DEFINEREG(CURSOR_A_POSITION), 692 693 DEFINEREG2(FPA0, i830_debug_fp), 694 DEFINEREG2(FPA1, i830_debug_fp), 695 DEFINEREG2(DPLL_A, i830_debug_dpll), 696 DEFINEREG(DPLL_A_MD), 697 DEFINEREG2(HTOTAL_A, i830_debug_hvtotal), 698 DEFINEREG2(HBLANK_A, i830_debug_hvsyncblank), 699 DEFINEREG2(HSYNC_A, i830_debug_hvsyncblank), 700 DEFINEREG2(VTOTAL_A, i830_debug_hvtotal), 701 DEFINEREG2(VBLANK_A, i830_debug_hvsyncblank), 702 DEFINEREG2(VSYNC_A, i830_debug_hvsyncblank), 703 DEFINEREG(BCLRPAT_A), 704 DEFINEREG(VSYNCSHIFT_A), 705 706 DEFINEREG2(DSPBCNTR, i830_debug_dspcntr), 707 DEFINEREG2(DSPBSTRIDE, i830_debug_dspstride), 708 DEFINEREG2(DSPBPOS, i830_debug_xy), 709 DEFINEREG2(DSPBSIZE, i830_debug_xyminus1), 710 DEFINEREG(DSPBBASE), 711 DEFINEREG(DSPBSURF), 712 DEFINEREG(DSPBTILEOFF), 713 DEFINEREG2(PIPEBCONF, i830_debug_pipeconf), 714 DEFINEREG2(PIPEBSRC, i830_debug_yxminus1), 715 DEFINEREG2(PIPEBSTAT, i830_debug_pipestat), 716 DEFINEREG(PIPEB_GMCH_DATA_M), 717 DEFINEREG(PIPEB_GMCH_DATA_N), 718 DEFINEREG(PIPEB_DP_LINK_M), 719 DEFINEREG(PIPEB_DP_LINK_N), 720 DEFINEREG(CURSOR_B_BASE), 721 DEFINEREG(CURSOR_B_CONTROL), 722 DEFINEREG(CURSOR_B_POSITION), 723 724 DEFINEREG2(FPB0, i830_debug_fp), 725 DEFINEREG2(FPB1, i830_debug_fp), 726 DEFINEREG2(DPLL_B, i830_debug_dpll), 727 DEFINEREG(DPLL_B_MD), 728 DEFINEREG2(HTOTAL_B, i830_debug_hvtotal), 729 DEFINEREG2(HBLANK_B, i830_debug_hvsyncblank), 730 DEFINEREG2(HSYNC_B, i830_debug_hvsyncblank), 731 DEFINEREG2(VTOTAL_B, i830_debug_hvtotal), 732 DEFINEREG2(VBLANK_B, i830_debug_hvsyncblank), 733 DEFINEREG2(VSYNC_B, i830_debug_hvsyncblank), 734 DEFINEREG(BCLRPAT_B), 735 DEFINEREG(VSYNCSHIFT_B), 736 737 DEFINEREG(VCLK_DIVISOR_VGA0), 738 DEFINEREG(VCLK_DIVISOR_VGA1), 739 DEFINEREG(VCLK_POST_DIV), 740 DEFINEREG2(VGACNTRL, i830_debug_vgacntrl), 741 742 DEFINEREG(TV_CTL), 743 DEFINEREG(TV_DAC), 744 DEFINEREG(TV_CSC_Y), 745 DEFINEREG(TV_CSC_Y2), 746 DEFINEREG(TV_CSC_U), 747 DEFINEREG(TV_CSC_U2), 748 DEFINEREG(TV_CSC_V), 749 DEFINEREG(TV_CSC_V2), 750 DEFINEREG(TV_CLR_KNOBS), 751 DEFINEREG(TV_CLR_LEVEL), 752 DEFINEREG(TV_H_CTL_1), 753 DEFINEREG(TV_H_CTL_2), 754 DEFINEREG(TV_H_CTL_3), 755 DEFINEREG(TV_V_CTL_1), 756 DEFINEREG(TV_V_CTL_2), 757 DEFINEREG(TV_V_CTL_3), 758 DEFINEREG(TV_V_CTL_4), 759 DEFINEREG(TV_V_CTL_5), 760 DEFINEREG(TV_V_CTL_6), 761 DEFINEREG(TV_V_CTL_7), 762 DEFINEREG(TV_SC_CTL_1), 763 DEFINEREG(TV_SC_CTL_2), 764 DEFINEREG(TV_SC_CTL_3), 765 DEFINEREG(TV_WIN_POS), 766 DEFINEREG(TV_WIN_SIZE), 767 DEFINEREG(TV_FILTER_CTL_1), 768 DEFINEREG(TV_FILTER_CTL_2), 769 DEFINEREG(TV_FILTER_CTL_3), 770 DEFINEREG(TV_CC_CONTROL), 771 DEFINEREG(TV_CC_DATA), 772 DEFINEREG(TV_H_LUMA_0), 773 DEFINEREG(TV_H_LUMA_59), 774 DEFINEREG(TV_H_CHROMA_0), 775 DEFINEREG(TV_H_CHROMA_59), 776 777 DEFINEREG(FBC_CFB_BASE), 778 DEFINEREG(FBC_LL_BASE), 779 DEFINEREG(FBC_CONTROL), 780 DEFINEREG(FBC_COMMAND), 781 DEFINEREG(FBC_STATUS), 782 DEFINEREG(FBC_CONTROL2), 783 DEFINEREG(FBC_FENCE_OFF), 784 DEFINEREG(FBC_MOD_NUM), 785 786 DEFINEREG(MI_MODE), 787 /* DEFINEREG(MI_DISPLAY_POWER_DOWN), CRL only */ 788 DEFINEREG(MI_ARB_STATE), 789 DEFINEREG(MI_RDRET_STATE), 790 DEFINEREG(ECOSKPD), 791 792 DEFINEREG(DP_B), 793 DEFINEREG(DPB_AUX_CH_CTL), 794 DEFINEREG(DPB_AUX_CH_DATA1), 795 DEFINEREG(DPB_AUX_CH_DATA2), 796 DEFINEREG(DPB_AUX_CH_DATA3), 797 DEFINEREG(DPB_AUX_CH_DATA4), 798 DEFINEREG(DPB_AUX_CH_DATA5), 799 800 DEFINEREG(DP_C), 801 DEFINEREG(DPC_AUX_CH_CTL), 802 DEFINEREG(DPC_AUX_CH_DATA1), 803 DEFINEREG(DPC_AUX_CH_DATA2), 804 DEFINEREG(DPC_AUX_CH_DATA3), 805 DEFINEREG(DPC_AUX_CH_DATA4), 806 DEFINEREG(DPC_AUX_CH_DATA5), 807 808 DEFINEREG(DP_D), 809 DEFINEREG(DPD_AUX_CH_CTL), 810 DEFINEREG(DPD_AUX_CH_DATA1), 811 DEFINEREG(DPD_AUX_CH_DATA2), 812 DEFINEREG(DPD_AUX_CH_DATA3), 813 DEFINEREG(DPD_AUX_CH_DATA4), 814 DEFINEREG(DPD_AUX_CH_DATA5), 815 816 DEFINEREG(AUD_CONFIG), 817 DEFINEREG(AUD_HDMIW_STATUS), 818 DEFINEREG(AUD_CONV_CHCNT), 819 DEFINEREG(VIDEO_DIP_CTL), 820 DEFINEREG(AUD_PINW_CNTR), 821 DEFINEREG(AUD_CNTL_ST), 822 DEFINEREG(AUD_PIN_CAP), 823 DEFINEREG(AUD_PINW_CAP), 824 DEFINEREG(AUD_PINW_UNSOLRESP), 825 DEFINEREG(AUD_OUT_DIG_CNVT), 826 DEFINEREG(AUD_OUT_CWCAP), 827 DEFINEREG(AUD_GRP_CAP), 828 829 #define DEFINEFENCE_915(i) \ 830 { FENCE+i*4, "FENCE " #i, i810_debug_915_fence, 0 } 831 #define DEFINEFENCE_945(i) \ 832 { FENCE_NEW+(i - 8) * 4, "FENCE " #i, i810_debug_915_fence, 0 } 833 834 DEFINEFENCE_915(0), 835 DEFINEFENCE_915(1), 836 DEFINEFENCE_915(2), 837 DEFINEFENCE_915(3), 838 DEFINEFENCE_915(4), 839 DEFINEFENCE_915(5), 840 DEFINEFENCE_915(6), 841 DEFINEFENCE_915(7), 842 DEFINEFENCE_945(8), 843 DEFINEFENCE_945(9), 844 DEFINEFENCE_945(10), 845 DEFINEFENCE_945(11), 846 DEFINEFENCE_945(12), 847 DEFINEFENCE_945(13), 848 DEFINEFENCE_945(14), 849 DEFINEFENCE_945(15), 850 851 #define DEFINEFENCE_965(i) \ 852 { FENCE_NEW+i*8, "FENCE START " #i, i810_debug_965_fence_start, 0 }, \ 853 { FENCE_NEW+i*8+4, "FENCE END " #i, i810_debug_965_fence_end, 0 } 854 855 DEFINEFENCE_965(0), 856 DEFINEFENCE_965(1), 857 DEFINEFENCE_965(2), 858 DEFINEFENCE_965(3), 859 DEFINEFENCE_965(4), 860 DEFINEFENCE_965(5), 861 DEFINEFENCE_965(6), 862 DEFINEFENCE_965(7), 863 DEFINEFENCE_965(8), 864 DEFINEFENCE_965(9), 865 DEFINEFENCE_965(10), 866 DEFINEFENCE_965(11), 867 DEFINEFENCE_965(12), 868 DEFINEFENCE_965(13), 869 DEFINEFENCE_965(14), 870 DEFINEFENCE_965(15), 871 }; 872 #define NUM_I830_SNAPSHOTREGS (sizeof(i830_snapshot) / sizeof(i830_snapshot[0])) 873 874 DEBUGSTRING(igdng_debug_rr_hw_ctl) 875 { 876 return XNFprintf("low %d, high %d", val & RR_HW_LOW_POWER_FRAMES_MASK, 877 (val & RR_HW_HIGH_POWER_FRAMES_MASK) >> 8 ); 878 } 879 880 DEBUGSTRING(igdng_debug_m_tu) 881 { 882 return XNFprintf("TU %d, val 0x%x %d", (val >> 25) + 1, val & 0xffffff, val & 0xffffff); 883 } 884 885 DEBUGSTRING(igdng_debug_n) 886 { 887 return XNFprintf("val 0x%x %d", val & 0xffffff, val & 0xffffff); 888 } 889 890 DEBUGSTRING(igdng_debug_fdi_tx_ctl) 891 { 892 char *train = NULL, *voltage = NULL, *pre_emphasis = NULL, *portw = NULL; 893 894 switch (val & FDI_LINK_TRAIN_NONE) { 895 case FDI_LINK_TRAIN_PATTERN_1: 896 train = "pattern_1"; 897 break; 898 case FDI_LINK_TRAIN_PATTERN_2: 899 train = "pattern_2"; 900 break; 901 case FDI_LINK_TRAIN_PATTERN_IDLE: 902 train = "pattern_idle"; 903 break; 904 case FDI_LINK_TRAIN_NONE: 905 train = "not train"; 906 break; 907 } 908 909 switch (val & (7<<25)) { 910 case FDI_LINK_TRAIN_VOLTAGE_0_4V: 911 voltage = "0.4V"; 912 break; 913 case FDI_LINK_TRAIN_VOLTAGE_0_6V: 914 voltage = "0.6V"; 915 break; 916 case FDI_LINK_TRAIN_VOLTAGE_0_8V: 917 voltage = "0.8V"; 918 break; 919 case FDI_LINK_TRAIN_VOLTAGE_1_2V: 920 voltage = "1.2V"; 921 break; 922 default: 923 voltage = "reserved"; 924 } 925 926 switch (val & (7<<22)) { 927 case FDI_LINK_TRAIN_PRE_EMPHASIS_NONE: 928 pre_emphasis = "none"; 929 break; 930 case FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X: 931 pre_emphasis = "1.5x"; 932 break; 933 case FDI_LINK_TRAIN_PRE_EMPHASIS_2X: 934 pre_emphasis = "2x"; 935 break; 936 case FDI_LINK_TRAIN_PRE_EMPHASIS_3X: 937 pre_emphasis = "3x"; 938 break; 939 default: 940 pre_emphasis = "reserved"; 941 } 942 943 switch (val & (7<<19)) { 944 case FDI_DP_PORT_WIDTH_X1: 945 portw = "X1"; 946 break; 947 case FDI_DP_PORT_WIDTH_X2: 948 portw = "X2"; 949 break; 950 case FDI_DP_PORT_WIDTH_X3: 951 portw = "X3"; 952 break; 953 case FDI_DP_PORT_WIDTH_X4: 954 portw = "X4"; 955 break; 956 } 957 958 return XNFprintf("%s, train pattern %s, voltage swing %s," 959 "pre-emphasis %s, port width %s, enhanced framing %s, FDI PLL %s, scrambing %s, master mode %s", 960 val & FDI_TX_ENABLE ? "enable" : "disable", 961 train, voltage, pre_emphasis, portw, 962 val & FDI_TX_ENHANCE_FRAME_ENABLE ? "enable" : "disable", 963 val & FDI_TX_PLL_ENABLE ? "enable" : "disable", 964 val & (1 << 7) ? "disable" : "enable", 965 val & (1 << 0) ? "enable" : "disable"); 966 } 967 968 DEBUGSTRING(igdng_debug_fdi_rx_ctl) 969 { 970 char *train = NULL, *portw = NULL, *bpc = NULL; 971 972 switch (val & FDI_LINK_TRAIN_NONE) { 973 case FDI_LINK_TRAIN_PATTERN_1: 974 train = "pattern_1"; 975 break; 976 case FDI_LINK_TRAIN_PATTERN_2: 977 train = "pattern_2"; 978 break; 979 case FDI_LINK_TRAIN_PATTERN_IDLE: 980 train = "pattern_idle"; 981 break; 982 case FDI_LINK_TRAIN_NONE: 983 train = "not train"; 984 break; 985 } 986 987 switch (val & (7<<19)) { 988 case FDI_DP_PORT_WIDTH_X1: 989 portw = "X1"; 990 break; 991 case FDI_DP_PORT_WIDTH_X2: 992 portw = "X2"; 993 break; 994 case FDI_DP_PORT_WIDTH_X3: 995 portw = "X3"; 996 break; 997 case FDI_DP_PORT_WIDTH_X4: 998 portw = "X4"; 999 break; 1000 } 1001 1002 switch (val & (7<<16)) { 1003 case FDI_8BPC: 1004 bpc = "8bpc"; 1005 break; 1006 case FDI_10BPC: 1007 bpc = "10bpc"; 1008 break; 1009 case FDI_6BPC: 1010 bpc = "6bpc"; 1011 break; 1012 case FDI_12BPC: 1013 bpc = "12bpc"; 1014 break; 1015 } 1016 1017 return XNFprintf("%s, train pattern %s, port width %s, %s," 1018 "link_reverse_strap_overwrite %s, dmi_link_reverse %s, FDI PLL %s," 1019 "FS ecc %s, FE ecc %s, FS err report %s, FE err report %s," 1020 "scrambing %s, enhanced framing %s, %s", 1021 val & FDI_RX_ENABLE ? "enable" : "disable", 1022 train, portw, bpc, 1023 val & FDI_LINK_REVERSE_OVERWRITE ? "yes" : "no", 1024 val & FDI_DMI_LINK_REVERSE_MASK ? "yes" : "no", 1025 val & FDI_RX_PLL_ENABLE ? "enable" : "disable", 1026 val & FDI_FS_ERR_CORRECT_ENABLE ? "enable" : "disable", 1027 val & FDI_FE_ERR_CORRECT_ENABLE ? "enable" : "disable", 1028 val & FDI_FS_ERR_REPORT_ENABLE ? "enable" : "disable", 1029 val & FDI_FE_ERR_REPORT_ENABLE ? "enable" : "disable", 1030 val & (1 << 7) ? "disable" : "enable", 1031 val & FDI_RX_ENHANCE_FRAME_ENABLE ? "enable" : "disable", 1032 val & FDI_SEL_PCDCLK ? "PCDClk" : "RawClk"); 1033 } 1034 1035 DEBUGSTRING(igdng_debug_dspstride) 1036 { 1037 return XNFprintf("%d", val >> 6); 1038 } 1039 1040 DEBUGSTRING(igdng_debug_pch_dpll) 1041 { 1042 char *enable = val & DPLL_VCO_ENABLE ? "enable" : "disable"; 1043 char *highspeed = val & DPLL_DVO_HIGH_SPEED ? "yes" : "no"; 1044 char *mode = NULL; 1045 char *p2 = NULL; 1046 int fpa0_p1, fpa1_p1; 1047 char *refclk = NULL; 1048 int sdvo_mul; 1049 1050 if ((val & DPLLB_MODE_LVDS) == DPLLB_MODE_LVDS) { 1051 mode = "LVDS"; 1052 if (val & DPLLB_LVDS_P2_CLOCK_DIV_7) 1053 p2 = "Div 7"; 1054 else 1055 p2 = "Div 14"; 1056 } else if ((val & DPLLB_MODE_LVDS) == DPLLB_MODE_DAC_SERIAL) { 1057 mode = "Non-LVDS"; 1058 if (val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5) 1059 p2 = "Div 5"; 1060 else 1061 p2 = "Div 10"; 1062 } 1063 fpa0_p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >> 16); 1064 fpa1_p1 = ffs((val & DPLL_FPA1_P1_POST_DIV_MASK)); 1065 1066 switch (val & PLL_REF_INPUT_MASK) { 1067 case PLL_REF_INPUT_DREFCLK: 1068 refclk = "default 120Mhz"; 1069 break; 1070 case PLL_REF_INPUT_SUPER_SSC: 1071 refclk = "SuperSSC 120Mhz"; 1072 break; 1073 case PLL_REF_INPUT_TVCLKINBC: 1074 refclk = "SDVO TVClkIn"; 1075 break; 1076 case PLLB_REF_INPUT_SPREADSPECTRUMIN: 1077 refclk = "SSC"; 1078 break; 1079 case PLL_REF_INPUT_DMICLK: 1080 refclk = "DMI RefCLK"; 1081 break; 1082 } 1083 1084 sdvo_mul = ((val & PLL_REF_SDVO_HDMI_MULTIPLIER_MASK) >> 9) + 1; 1085 1086 return XNFprintf("%s, sdvo high speed %s, mode %s, p2 %s, " 1087 "FPA0 P1 %d, FPA1 P1 %d, refclk %s, sdvo/hdmi mul %d", 1088 enable, highspeed, mode, p2, fpa0_p1, fpa1_p1, refclk, sdvo_mul); 1089 } 1090 1091 DEBUGSTRING(igdng_debug_dref_ctl) 1092 { 1093 char *cpu_source; 1094 char *ssc_source = val & DREF_SSC_SOURCE_ENABLE ? "enable" : "disable"; 1095 char *nonspread_source = val & DREF_NONSPREAD_SOURCE_ENABLE ? "enable":"disable"; 1096 char *superspread_source = val & DREF_SUPERSPREAD_SOURCE_ENABLE ? "enable":"disable"; 1097 char *ssc4_mode = val & DREF_SSC4_CENTERSPREAD ? "centerspread" : "downspread"; 1098 char *ssc1 = val & DREF_SSC1_ENABLE ? "enable" : "disable"; 1099 char *ssc4 = val & DREF_SSC4_ENABLE ? "enable" : "disable"; 1100 1101 switch (val & DREF_CPU_SOURCE_OUTPUT_NONSPREAD) { 1102 case DREF_CPU_SOURCE_OUTPUT_DISABLE: 1103 cpu_source = "disable"; 1104 break; 1105 case DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD: 1106 cpu_source = "downspread"; 1107 break; 1108 case DREF_CPU_SOURCE_OUTPUT_NONSPREAD: 1109 cpu_source = "nonspread"; 1110 break; 1111 default: 1112 cpu_source = "reserved"; 1113 } 1114 return XNFprintf("cpu source %s, ssc_source %s, nonspread_source %s, " 1115 "superspread_source %s, ssc4_mode %s, ssc1 %s, ssc4 %s", 1116 cpu_source, ssc_source, nonspread_source, superspread_source, 1117 ssc4_mode, ssc1, ssc4); 1118 } 1119 1120 DEBUGSTRING(igdng_debug_rawclk_freq) 1121 { 1122 char *tp1 = NULL, *tp2 = NULL; 1123 1124 switch (val & FDL_TP1_TIMER_MASK) { 1125 case 0: 1126 tp1 = "0.5us"; 1127 break; 1128 case (1 << 12): 1129 tp1 = "1.0us"; 1130 break; 1131 case (2 << 12): 1132 tp1 = "2.0us"; 1133 break; 1134 case (3 << 12): 1135 tp1 = "4.0us"; 1136 break; 1137 } 1138 switch (val & FDL_TP2_TIMER_MASK) { 1139 case 0: 1140 tp2 = "1.5us"; 1141 break; 1142 case (1 << 10): 1143 tp2 = "3.0us"; 1144 break; 1145 case (2 << 10): 1146 tp2 = "6.0us"; 1147 break; 1148 case (3 << 10): 1149 tp2 = "12.0us"; 1150 break; 1151 } 1152 return XNFprintf("FDL_TP1 timer %s, FDL_TP2 timer %s, freq %d", 1153 tp1, tp2, val & RAWCLK_FREQ_MASK); 1154 1155 } 1156 1157 DEBUGSTRING(igdng_debug_fdi_rx_misc) 1158 { 1159 return XNFprintf("FDI Delay %d", val & ((1 << 13) - 1)); 1160 } 1161 1162 DEBUGSTRING(igdng_debug_transconf) 1163 { 1164 return XNFprintf("%s, %s", 1165 val & TRANS_ENABLE ? "enable" : "disable", 1166 val & TRANS_STATE_ENABLE ? "active" : "inactive"); 1167 } 1168 1169 DEBUGSTRING(igdng_debug_panel_fitting) 1170 { 1171 char *vadapt = NULL, *filter_sel = NULL; 1172 1173 switch (val & (3 << 25)) { 1174 case 0: 1175 vadapt = "least"; 1176 break; 1177 case (1<<25): 1178 vadapt = "moderate"; 1179 break; 1180 case (2<<25): 1181 vadapt = "reserved"; 1182 break; 1183 case (3<<25): 1184 vadapt = "most"; 1185 break; 1186 } 1187 1188 switch (val & (3 << 23)) { 1189 case 0: 1190 filter_sel = "programmed"; 1191 break; 1192 case (1<<25): 1193 filter_sel = "hardcoded"; 1194 break; 1195 case (2<<25): 1196 filter_sel = "edge_enhance"; 1197 break; 1198 case (3<<25): 1199 filter_sel = "edge_soften"; 1200 break; 1201 } 1202 1203 return XNFprintf("%s, auto_scale %s, auto_scale_cal %s, v_filter %s, vadapt %s, mode %s, filter_sel %s," 1204 "chroma pre-filter %s, vert3tap %s, v_inter_invert %s", 1205 val & PF_ENABLE ? "enable" : "disable", 1206 val & (1 << 30) ? "no" : "yes", 1207 val & (1 << 29) ? "yes" : "no", 1208 val & (1 << 28) ? "bypass" : "enable", 1209 val & (1 << 27) ? "enable" : "disable", 1210 vadapt, filter_sel, 1211 val & (1 << 22) ? "enable" : "disable", 1212 val & (1 << 21) ? "force" : "auto", 1213 val & (1 << 20) ? "field 0" : "field 1"); 1214 } 1215 1216 DEBUGSTRING(igdng_debug_pf_win) 1217 { 1218 int a, b; 1219 1220 a = (val >> 16) & 0x1fff; 1221 b = val & 0xfff; 1222 1223 return XNFprintf("%d, %d", a, b); 1224 } 1225 1226 1227 static struct i830SnapshotRec igdng_snapshot[] = { 1228 DEFINEREG2(CPU_VGACNTRL, i830_debug_vgacntrl), 1229 DEFINEREG(DIGITAL_PORT_HOTPLUG_CNTRL), 1230 1231 DEFINEREG2(RR_HW_CTL, igdng_debug_rr_hw_ctl), 1232 1233 DEFINEREG(FDI_PLL_BIOS_0), 1234 DEFINEREG(FDI_PLL_BIOS_1), 1235 DEFINEREG(FDI_PLL_BIOS_2), 1236 1237 DEFINEREG(DISPLAY_PORT_PLL_BIOS_0), 1238 DEFINEREG(DISPLAY_PORT_PLL_BIOS_1), 1239 DEFINEREG(DISPLAY_PORT_PLL_BIOS_2), 1240 1241 DEFINEREG(FDI_PLL_FREQ_CTL), 1242 1243 DEFINEREG2(PIPEACONF, i830_debug_pipeconf), 1244 1245 DEFINEREG2(HTOTAL_A, i830_debug_hvtotal), 1246 DEFINEREG2(HBLANK_A, i830_debug_hvsyncblank), 1247 DEFINEREG2(HSYNC_A, i830_debug_hvsyncblank), 1248 DEFINEREG2(VTOTAL_A, i830_debug_hvtotal), 1249 DEFINEREG2(VBLANK_A, i830_debug_hvsyncblank), 1250 DEFINEREG2(VSYNC_A, i830_debug_hvsyncblank), 1251 DEFINEREG(VSYNCSHIFT_A), 1252 DEFINEREG2(PIPEASRC, i830_debug_yxminus1), 1253 1254 DEFINEREG2(PIPEA_DATA_M1, igdng_debug_m_tu), 1255 DEFINEREG2(PIPEA_DATA_N1, igdng_debug_n), 1256 DEFINEREG2(PIPEA_DATA_M2, igdng_debug_m_tu), 1257 DEFINEREG2(PIPEA_DATA_N2, igdng_debug_n), 1258 1259 DEFINEREG2(PIPEA_LINK_M1, igdng_debug_n), 1260 DEFINEREG2(PIPEA_LINK_N1, igdng_debug_n), 1261 DEFINEREG2(PIPEA_LINK_M2, igdng_debug_n), 1262 DEFINEREG2(PIPEA_LINK_N2, igdng_debug_n), 1263 1264 DEFINEREG2(DSPACNTR, i830_debug_dspcntr), 1265 DEFINEREG(DSPABASE), 1266 DEFINEREG2(DSPASTRIDE, igdng_debug_dspstride), 1267 DEFINEREG(DSPASURF), 1268 DEFINEREG2(DSPATILEOFF, i830_debug_xy), 1269 1270 DEFINEREG2(PIPEBCONF, i830_debug_pipeconf), 1271 1272 DEFINEREG2(HTOTAL_B, i830_debug_hvtotal), 1273 DEFINEREG2(HBLANK_B, i830_debug_hvsyncblank), 1274 DEFINEREG2(HSYNC_B, i830_debug_hvsyncblank), 1275 DEFINEREG2(VTOTAL_B, i830_debug_hvtotal), 1276 DEFINEREG2(VBLANK_B, i830_debug_hvsyncblank), 1277 DEFINEREG2(VSYNC_B, i830_debug_hvsyncblank), 1278 DEFINEREG(VSYNCSHIFT_B), 1279 1280 DEFINEREG2(DSPBCNTR, i830_debug_dspcntr), 1281 DEFINEREG(DSPBBASE), 1282 DEFINEREG2(DSPBSTRIDE, igdng_debug_dspstride), 1283 DEFINEREG(DSPBSURF), 1284 DEFINEREG2(DSPBTILEOFF, i830_debug_xy), 1285 1286 DEFINEREG2(PIPEBSRC, i830_debug_yxminus1), 1287 1288 DEFINEREG2(PIPEB_DATA_M1, igdng_debug_m_tu), 1289 DEFINEREG2(PIPEB_DATA_N1, igdng_debug_n), 1290 DEFINEREG2(PIPEB_DATA_M2, igdng_debug_m_tu), 1291 DEFINEREG2(PIPEB_DATA_N2, igdng_debug_n), 1292 1293 DEFINEREG2(PIPEB_LINK_M1, igdng_debug_n), 1294 DEFINEREG2(PIPEB_LINK_N1, igdng_debug_n), 1295 DEFINEREG2(PIPEB_LINK_M2, igdng_debug_n), 1296 DEFINEREG2(PIPEB_LINK_N2, igdng_debug_n), 1297 1298 DEFINEREG2(PFA_CTL_1, igdng_debug_panel_fitting), 1299 DEFINEREG2(PFB_CTL_1, igdng_debug_panel_fitting), 1300 DEFINEREG2(PFA_WIN_POS, igdng_debug_pf_win), 1301 DEFINEREG2(PFB_WIN_POS, igdng_debug_pf_win), 1302 DEFINEREG2(PFA_WIN_SIZE, igdng_debug_pf_win), 1303 DEFINEREG2(PFB_WIN_SIZE, igdng_debug_pf_win), 1304 1305 /* PCH */ 1306 1307 DEFINEREG2(PCH_DREF_CONTROL, igdng_debug_dref_ctl), 1308 DEFINEREG2(PCH_RAWCLK_FREQ, igdng_debug_rawclk_freq), 1309 DEFINEREG(PCH_DPLL_TMR_CFG), 1310 DEFINEREG(PCH_SSC4_PARMS), 1311 DEFINEREG(PCH_SSC4_AUX_PARMS), 1312 1313 DEFINEREG2(PCH_DPLL_A, igdng_debug_pch_dpll), 1314 DEFINEREG2(PCH_DPLL_B, igdng_debug_pch_dpll), 1315 DEFINEREG2(PCH_FPA0, i830_debug_fp), 1316 DEFINEREG2(PCH_FPA1, i830_debug_fp), 1317 DEFINEREG2(PCH_FPB0, i830_debug_fp), 1318 DEFINEREG2(PCH_FPB1, i830_debug_fp), 1319 1320 DEFINEREG2(TRANS_HTOTAL_A, i830_debug_hvtotal), 1321 DEFINEREG2(TRANS_HBLANK_A, i830_debug_hvsyncblank), 1322 DEFINEREG2(TRANS_HSYNC_A, i830_debug_hvsyncblank), 1323 DEFINEREG2(TRANS_VTOTAL_A, i830_debug_hvtotal), 1324 DEFINEREG2(TRANS_VBLANK_A, i830_debug_hvsyncblank), 1325 DEFINEREG2(TRANS_VSYNC_A, i830_debug_hvsyncblank), 1326 1327 DEFINEREG2(TRANSA_DATA_M1, igdng_debug_m_tu), 1328 DEFINEREG2(TRANSA_DATA_N1, igdng_debug_n), 1329 DEFINEREG2(TRANSA_DATA_M2, igdng_debug_m_tu), 1330 DEFINEREG2(TRANSA_DATA_N2, igdng_debug_n), 1331 DEFINEREG2(TRANSA_DP_LINK_M1, igdng_debug_n), 1332 DEFINEREG2(TRANSA_DP_LINK_N1, igdng_debug_n), 1333 DEFINEREG2(TRANSA_DP_LINK_M2, igdng_debug_n), 1334 DEFINEREG2(TRANSA_DP_LINK_N2, igdng_debug_n), 1335 1336 DEFINEREG2(TRANS_HTOTAL_B, i830_debug_hvtotal), 1337 DEFINEREG2(TRANS_HBLANK_B, i830_debug_hvsyncblank), 1338 DEFINEREG2(TRANS_HSYNC_B, i830_debug_hvsyncblank), 1339 DEFINEREG2(TRANS_VTOTAL_B, i830_debug_hvtotal), 1340 DEFINEREG2(TRANS_VBLANK_B, i830_debug_hvsyncblank), 1341 DEFINEREG2(TRANS_VSYNC_B, i830_debug_hvsyncblank), 1342 1343 DEFINEREG2(TRANSB_DATA_M1, igdng_debug_m_tu), 1344 DEFINEREG2(TRANSB_DATA_N1, igdng_debug_n), 1345 DEFINEREG2(TRANSB_DATA_M2, igdng_debug_m_tu), 1346 DEFINEREG2(TRANSB_DATA_N2, igdng_debug_n), 1347 DEFINEREG2(TRANSB_DP_LINK_M1, igdng_debug_n), 1348 DEFINEREG2(TRANSB_DP_LINK_N1, igdng_debug_n), 1349 DEFINEREG2(TRANSB_DP_LINK_M2, igdng_debug_n), 1350 DEFINEREG2(TRANSB_DP_LINK_N2, igdng_debug_n), 1351 1352 DEFINEREG2(TRANSACONF, igdng_debug_transconf), 1353 DEFINEREG2(TRANSBCONF, igdng_debug_transconf), 1354 1355 DEFINEREG2(FDI_TXA_CTL, igdng_debug_fdi_tx_ctl), 1356 DEFINEREG2(FDI_TXB_CTL, igdng_debug_fdi_tx_ctl), 1357 DEFINEREG2(FDI_RXA_CTL, igdng_debug_fdi_rx_ctl), 1358 DEFINEREG2(FDI_RXB_CTL, igdng_debug_fdi_rx_ctl), 1359 1360 DEFINEREG2(FDI_RXA_MISC, igdng_debug_fdi_rx_misc), 1361 DEFINEREG2(FDI_RXB_MISC, igdng_debug_fdi_rx_misc), 1362 DEFINEREG(FDI_RXA_TUSIZE1), 1363 DEFINEREG(FDI_RXA_TUSIZE2), 1364 DEFINEREG(FDI_RXB_TUSIZE1), 1365 DEFINEREG(FDI_RXB_TUSIZE2), 1366 1367 DEFINEREG(FDI_PLL_CTL_1), 1368 DEFINEREG(FDI_PLL_CTL_2), 1369 1370 DEFINEREG(FDI_RXA_IIR), 1371 DEFINEREG(FDI_RXA_IMR), 1372 DEFINEREG(FDI_RXB_IIR), 1373 DEFINEREG(FDI_RXB_IMR), 1374 1375 DEFINEREG2(PCH_ADPA, i830_debug_adpa), 1376 DEFINEREG(HDMIB), 1377 DEFINEREG(HDMIC), 1378 DEFINEREG(HDMID), 1379 DEFINEREG2(PCH_LVDS, i830_debug_lvds), 1380 }; 1381 #define NUM_IGDNG_SNAPSHOTREGS (sizeof(igdng_snapshot) / sizeof(igdng_snapshot[0])) 1382 #undef DEFINEREG 1383 1384 #ifndef REG_DUMPER 1385 void i830TakeRegSnapshot(ScrnInfoPtr pScrn) 1386 { 1387 I830Ptr pI830 = I830PTR(pScrn); 1388 int i; 1389 1390 if (IS_IGDNG(pI830)) { 1391 for (i = 0; i < NUM_IGDNG_SNAPSHOTREGS; i++) { 1392 igdng_snapshot[i].val = INREG(igdng_snapshot[i].reg); 1393 } 1394 } else { 1395 for (i = 0; i < NUM_I830_SNAPSHOTREGS; i++) { 1396 i830_snapshot[i].val = INREG(i830_snapshot[i].reg); 1397 } 1398 } 1399 } 1400 1401 static void IGDNGCompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where) 1402 { 1403 I830Ptr pI830 = I830PTR(pScrn); 1404 int i; 1405 1406 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1407 "Comparing regs from server start up to %s\n", where); 1408 for (i = 0; i < NUM_IGDNG_SNAPSHOTREGS; i++) { 1409 uint32_t val = INREG(igdng_snapshot[i].reg); 1410 if (igdng_snapshot[i].val == val) 1411 continue; 1412 1413 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1414 "Register 0x%x (%s) changed from 0x%08x to 0x%08x\n", 1415 igdng_snapshot[i].reg, igdng_snapshot[i].name, 1416 (int)igdng_snapshot[i].val, (int)val); 1417 1418 if (igdng_snapshot[i].debug_output != NULL) { 1419 char *before, *after; 1420 1421 before = igdng_snapshot[i].debug_output(pI830, 1422 igdng_snapshot[i].reg, 1423 igdng_snapshot[i].val); 1424 after = igdng_snapshot[i].debug_output(pI830, 1425 igdng_snapshot[i].reg, 1426 val); 1427 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1428 "%s before: %s\n", igdng_snapshot[i].name, before); 1429 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1430 "%s after: %s\n", igdng_snapshot[i].name, after); 1431 1432 } 1433 } 1434 } 1435 1436 void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where) 1437 { 1438 I830Ptr pI830 = I830PTR(pScrn); 1439 int i; 1440 1441 if (IS_IGDNG(pI830)) { 1442 IGDNGCompareRegsToSnapshot(pScrn, where); 1443 return; 1444 } 1445 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1446 "Comparing regs from server start up to %s\n", where); 1447 for (i = 0; i < NUM_I830_SNAPSHOTREGS; i++) { 1448 uint32_t val = INREG(i830_snapshot[i].reg); 1449 if (i830_snapshot[i].val == val) 1450 continue; 1451 1452 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1453 "Register 0x%x (%s) changed from 0x%08x to 0x%08x\n", 1454 i830_snapshot[i].reg, i830_snapshot[i].name, 1455 (int)i830_snapshot[i].val, (int)val); 1456 1457 if (i830_snapshot[i].debug_output != NULL) { 1458 char *before, *after; 1459 1460 before = i830_snapshot[i].debug_output(pI830, 1461 i830_snapshot[i].reg, 1462 i830_snapshot[i].val); 1463 after = i830_snapshot[i].debug_output(pI830, 1464 i830_snapshot[i].reg, 1465 val); 1466 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1467 "%s before: %s\n", i830_snapshot[i].name, before); 1468 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1469 "%s after: %s\n", i830_snapshot[i].name, after); 1470 1471 } 1472 } 1473 } 1474 #endif /* !REG_DUMPER */ 1475 1476 #if 0 1477 static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int min, int max) 1478 { 1479 I830Ptr pI830 = I830PTR(pScrn); 1480 int i; 1481 1482 for (i = min; i <= max; i++) { 1483 OUTREG8 (id, i); 1484 xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%18.18s%02x: 0x%02x\n", 1485 name, i, INREG8(val)); 1486 } 1487 } 1488 1489 static void i830DumpAR(ScrnInfoPtr pScrn) 1490 { 1491 I830Ptr pI830 = I830PTR(pScrn); 1492 int i; 1493 uint16_t st01; 1494 unsigned char orig_arx, msr; 1495 1496 msr = INREG8(0x3cc); 1497 if (msr & 1) 1498 st01 = 0x3da; 1499 else 1500 st01 = 0x3ba; 1501 1502 INREG8(st01); /* make sure index/write register is in index mode */ 1503 orig_arx = INREG8(0x3c0); 1504 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%19.19sX: 0x%02x\n", 1505 "AR", orig_arx); 1506 1507 for (i = 0; i <= 0x14; i++) { 1508 INREG8(st01); 1509 OUTREG8(0x3c0, i); 1510 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%18.18s%02x: 0x%02x\n", 1511 "AR", i, INREG8(0x3c1)); 1512 } 1513 INREG8(st01); 1514 OUTREG8(0x3c0, orig_arx); 1515 INREG8(st01); /* switch back to index mode */ 1516 } 1517 #endif 1518 1519 static void IGDNGDumpRegs (ScrnInfoPtr pScrn) 1520 { 1521 I830Ptr pI830 = I830PTR(pScrn); 1522 int i; 1523 1524 xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsBegin\n"); 1525 for (i = 0; i < NUM_IGDNG_SNAPSHOTREGS; i++) { 1526 uint32_t val = INREG(igdng_snapshot[i].reg); 1527 1528 if (igdng_snapshot[i].debug_output != NULL) { 1529 char *debug = igdng_snapshot[i].debug_output(pI830, 1530 igdng_snapshot[i].reg, 1531 val); 1532 if (debug != NULL) { 1533 xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%08x (%s)\n", 1534 igdng_snapshot[i].name, (unsigned int)val, debug); 1535 xfree(debug); 1536 } 1537 } else { 1538 xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%08x\n", 1539 igdng_snapshot[i].name, (unsigned int)val); 1540 } 1541 } 1542 } 1543 1544 void i830DumpRegs (ScrnInfoPtr pScrn) 1545 { 1546 I830Ptr pI830 = I830PTR(pScrn); 1547 int i; 1548 int fp, dpll; 1549 int pipe; 1550 int n, m1, m2, m, p1, p2; 1551 int ref; 1552 int dot; 1553 int phase; 1554 #if 0 1555 int msr; 1556 int crt; 1557 #endif 1558 1559 if (IS_IGDNG(pI830)) { 1560 IGDNGDumpRegs(pScrn); 1561 return; 1562 } 1563 xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsBegin\n"); 1564 for (i = 0; i < NUM_I830_SNAPSHOTREGS; i++) { 1565 uint32_t val = INREG(i830_snapshot[i].reg); 1566 1567 if (i830_snapshot[i].debug_output != NULL) { 1568 char *debug = i830_snapshot[i].debug_output(pI830, 1569 i830_snapshot[i].reg, 1570 val); 1571 if (debug != NULL) { 1572 xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%08x (%s)\n", 1573 i830_snapshot[i].name, (unsigned int)val, debug); 1574 xfree(debug); 1575 } 1576 } else { 1577 xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%08x\n", 1578 i830_snapshot[i].name, (unsigned int)val); 1579 } 1580 } 1581 #if 0 1582 i830DumpIndexed (pScrn, "SR", 0x3c4, 0x3c5, 0, 7); 1583 msr = INREG8(0x3cc); 1584 xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%02x\n", 1585 "MSR", (unsigned int) msr); 1586 1587 i830DumpAR (pScrn); 1588 if (msr & 1) 1589 crt = 0x3d0; 1590 else 1591 crt = 0x3b0; 1592 i830DumpIndexed (pScrn, "CR", crt + 4, crt + 5, 0, 0x24); 1593 #endif 1594 for (pipe = 0; pipe <= 1; pipe++) 1595 { 1596 fp = INREG(pipe == 0 ? FPA0 : FPB0); 1597 dpll = INREG(pipe == 0 ? DPLL_A : DPLL_B); 1598 if (IS_I9XX(pI830)) 1599 { 1600 uint32_t lvds = INREG(LVDS); 1601 if ((lvds & LVDS_PORT_EN) && 1602 (lvds & LVDS_PIPEB_SELECT) == (pipe << 30)) 1603 { 1604 if ((lvds & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) 1605 p2 = 7; 1606 else 1607 p2 = 14; 1608 } 1609 else 1610 { 1611 switch ((dpll >> 24) & 0x3) { 1612 case 0: 1613 p2 = 10; 1614 break; 1615 case 1: 1616 p2 = 5; 1617 break; 1618 default: 1619 p2 = 1; 1620 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "p2 out of range\n"); 1621 break; 1622 } 1623 } 1624 if (IS_IGD(pI830)) 1625 i = (dpll >> DPLL_FPA01_P1_POST_DIV_SHIFT_IGD) & 0x1ff; 1626 else 1627 i = (dpll >> DPLL_FPA01_P1_POST_DIV_SHIFT) & 0xff; 1628 switch (i) { 1629 case 1: 1630 p1 = 1; break; 1631 case 2: 1632 p1 = 2; break; 1633 case 4: 1634 p1 = 3; break; 1635 case 8: 1636 p1 = 4; break; 1637 case 16: 1638 p1 = 5; break; 1639 case 32: 1640 p1 = 6; break; 1641 case 64: 1642 p1 = 7; break; 1643 case 128: 1644 p1 = 8; break; 1645 case 256: 1646 if (IS_IGD(pI830)) { 1647 p1 = 9; 1648 break; 1649 } /* fallback */ 1650 default: 1651 p1 = 1; 1652 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "p1 out of range\n"); 1653 break; 1654 } 1655 1656 switch ((dpll >> 13) & 0x3) { 1657 case 0: 1658 ref = 96000; 1659 break; 1660 case 3: 1661 ref = 100000; 1662 break; 1663 default: 1664 ref = 0; 1665 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "ref out of range\n"); 1666 break; 1667 } 1668 } 1669 else 1670 { 1671 uint32_t lvds = INREG(LVDS); 1672 if (IS_I85X (pI830) && 1673 (lvds & LVDS_PORT_EN) && 1674 (lvds & LVDS_PIPEB_SELECT) == (pipe << 30)) 1675 { 1676 if ((lvds & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) 1677 p2 = 7; 1678 else 1679 p2 = 14; 1680 switch ((dpll >> 16) & 0x3f) { 1681 case 0x01: p1 = 1; break; 1682 case 0x02: p1 = 2; break; 1683 case 0x04: p1 = 3; break; 1684 case 0x08: p1 = 4; break; 1685 case 0x10: p1 = 5; break; 1686 case 0x20: p1 = 6; break; 1687 default: 1688 p1 = 1; 1689 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "LVDS P1 0x%x invalid encoding\n", 1690 (dpll >> 16) & 0x3f); 1691 break; 1692 } 1693 } 1694 else 1695 { 1696 if (dpll & (1 << 23)) 1697 p2 = 4; 1698 else 1699 p2 = 2; 1700 if (dpll & PLL_P1_DIVIDE_BY_TWO) 1701 p1 = 2; 1702 else 1703 p1 = ((dpll >> 16) & 0x3f) + 2; 1704 } 1705 1706 switch ((dpll >> 13) & 0x3) { 1707 case 0: 1708 ref = 48000; 1709 break; 1710 case 3: 1711 ref = 66000; 1712 break; 1713 default: 1714 ref = 0; 1715 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "ref out of range\n"); 1716 break; 1717 } 1718 } 1719 if (IS_I965G(pI830)) { 1720 phase = (dpll >> 9) & 0xf; 1721 switch (phase) { 1722 case 6: 1723 break; 1724 default: 1725 xf86DrvMsg (pScrn->scrnIndex, X_INFO, 1726 "SDVO phase shift %d out of range -- probobly not " 1727 "an issue.\n", phase); 1728 break; 1729 } 1730 } 1731 switch ((dpll >> 8) & 1) { 1732 case 0: 1733 break; 1734 default: 1735 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, 1736 "fp select out of range\n"); 1737 break; 1738 } 1739 m1 = ((fp >> 8) & 0x3f); 1740 if (IS_IGD(pI830)) { 1741 n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1; 1742 m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT; 1743 m = m2 + 2; 1744 dot = (ref * m) / n / (p1 * p2); 1745 } else { 1746 n = ((fp >> 16) & 0x3f); 1747 m2 = ((fp >> 0) & 0x3f); 1748 m = 5 * (m1 + 2) + (m2 + 2); 1749 dot = (ref * (5 * (m1 + 2) + (m2 + 2)) / (n + 2)) / (p1 * p2); 1750 } 1751 1752 xf86DrvMsg (pScrn->scrnIndex, X_INFO, "pipe %s dot %d n %d m1 %d m2 %d p1 %d p2 %d\n", 1753 pipe == 0 ? "A" : "B", dot, n, m1, m2, p1, p2); 1754 } 1755 xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsEnd\n"); 1756 } 1757 1758 #ifndef REG_DUMPER 1759 1760 static char *mi_cmds[0x40] = { 1761 "MI_NOOP", /* 00 */ 1762 "Reserved 01", 1763 "MI_USER_INTERRUPT", 1764 "MI_WAIT_FOR_EVENT", 1765 1766 "MI_FLUSH", /* 04 */ 1767 "MI_ARB_CHECK", 1768 NULL, 1769 "MI_REPORT_HEAD", 1770 1771 NULL, /* 08 */ 1772 NULL, 1773 "MI_BATCH_BUFFER_END", 1774 NULL, 1775 1776 NULL, /* 0c */ 1777 NULL, 1778 NULL, 1779 NULL, 1780 1781 NULL, /* 10 */ 1782 "MI_OVERLAY_FLIP", 1783 "MI_LOAD_SCAN_LINES_INCL", 1784 "MI_LOAD_SCAN_LINES_EXCL", 1785 1786 "MI_DISPLAY_BUFFER_INFO", /* 14 */ 1787 NULL, 1788 NULL, 1789 NULL, 1790 1791 "MI_SET_CONTEXT", /* 18 */ 1792 NULL, 1793 NULL, 1794 NULL, 1795 1796 NULL, /* 1c */ 1797 NULL, 1798 NULL, 1799 NULL, 1800 1801 "MI_STORE_DATA_IMM", /* 20 */ 1802 "MI_STORE_DATA_INDEX", 1803 "MI_LOAD_REGISTER_IMM", 1804 NULL, 1805 1806 "MI_STORE_REGISTER_MEM", /* 24 */ 1807 NULL, 1808 NULL, 1809 NULL, 1810 1811 NULL, /* 28 */ 1812 NULL, 1813 NULL, 1814 NULL, 1815 1816 NULL, /* 2c */ 1817 NULL, 1818 NULL, 1819 NULL, 1820 1821 NULL, /* 30 */ 1822 "MI_BATCH_BUFFER_START", 1823 NULL, 1824 NULL, 1825 1826 NULL, /* 34 */ 1827 NULL, 1828 NULL, 1829 NULL, 1830 1831 NULL, /* 38 */ 1832 NULL, 1833 NULL, 1834 NULL, 1835 1836 NULL, /* 3c */ 1837 NULL, 1838 NULL, 1839 NULL, 1840 }; 1841 1842 static char *_2d_cmds[0x80] = { 1843 NULL, /* 00 */ 1844 "XY_SETUP_BLT", 1845 NULL, 1846 "XY_SETUP_CLIP_BLT", 1847 1848 NULL, /* 04 */ 1849 NULL, 1850 NULL, 1851 NULL, 1852 1853 NULL, /* 08 */ 1854 NULL, 1855 NULL, 1856 NULL, 1857 1858 NULL, /* 0c */ 1859 NULL, 1860 NULL, 1861 NULL, 1862 1863 NULL, /* 10 */ 1864 "XY_SETUP_MONO_PATTERN_SL_BLT", 1865 NULL, 1866 NULL, 1867 1868 NULL, /* 14 */ 1869 NULL, 1870 NULL, 1871 NULL, 1872 1873 NULL, /* 18 */ 1874 NULL, 1875 NULL, 1876 NULL, 1877 1878 NULL, /* 1c */ 1879 NULL, 1880 NULL, 1881 NULL, 1882 1883 NULL, /* 20 */ 1884 NULL, 1885 NULL, 1886 NULL, 1887 1888 "XY_PIXEL_BLT", /* 24 */ 1889 "XY_SCANLINE_BLT", 1890 "XY_TEXT_BLT", 1891 NULL, 1892 1893 NULL, /* 28 */ 1894 NULL, 1895 NULL, 1896 NULL, 1897 1898 NULL, /* 2c */ 1899 NULL, 1900 NULL, 1901 NULL, 1902 1903 NULL, /* 30 */ 1904 "XY_TEXT_IMMEDIATE_BLT", 1905 NULL, 1906 NULL, 1907 1908 NULL, /* 34 */ 1909 NULL, 1910 NULL, 1911 NULL, 1912 1913 NULL, /* 38 */ 1914 NULL, 1915 NULL, 1916 NULL, 1917 1918 NULL, /* 3c */ 1919 NULL, 1920 NULL, 1921 NULL, 1922 1923 "COLOR_BLT", /* 40 */ 1924 NULL, 1925 NULL, 1926 "SRC_COPY_BLT", 1927 1928 NULL, /* 44 */ 1929 NULL, 1930 NULL, 1931 NULL, 1932 1933 NULL, /* 48 */ 1934 NULL, 1935 NULL, 1936 NULL, 1937 1938 NULL, /* 4c */ 1939 NULL, 1940 NULL, 1941 NULL, 1942 1943 "XY_COLOR_BLT", /* 50 */ 1944 "XY_PAT_BLT", 1945 "XY_MONO_PAT_BLT", 1946 "XY_SRC_COPY_BLT", 1947 1948 "XY_MONO_SRC_COPY_BLT", /* 54 */ 1949 "XY_FULL_BLT", 1950 "XY_FULL_MONO_SRC_BLT", 1951 "XY_FULL_MONO_PATTERN_BLT", 1952 1953 "XY_FULL_MONO_PATTERN_MONO_SRC_BLT", /* 58 */ 1954 "XY_MONO_PAT_FIXED_BLT", 1955 NULL, 1956 NULL, 1957 1958 NULL, /* 5c */ 1959 NULL, 1960 NULL, 1961 NULL, 1962 1963 NULL, /* 60 */ 1964 NULL, 1965 NULL, 1966 NULL, 1967 1968 NULL, /* 64 */ 1969 NULL, 1970 NULL, 1971 NULL, 1972 1973 NULL, /* 68 */ 1974 NULL, 1975 NULL, 1976 NULL, 1977 1978 NULL, /* 6c */ 1979 NULL, 1980 NULL, 1981 NULL, 1982 1983 NULL, /* 70 */ 1984 "XY_MONO_SRC_COPY_IMMEDIATE_BLT", 1985 "XY_PAT_BLT_IMMEDIATE", 1986 "XY_SRC_COPY_CHROMA_BLT", 1987 1988 "XY_FULL_IMMEDIATE_PATTERN_BLT", /* 74 */ 1989 "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT", 1990 "XY_PAT_CHROMA_BLT", 1991 "XY_PAT_CHROMA_BLT_IMMEDIATE", 1992 1993 NULL, /* 78 */ 1994 NULL, 1995 NULL, 1996 NULL, 1997 1998 NULL, /* 7c */ 1999 NULL, 2000 NULL, 2001 NULL, 2002 2003 }; 2004 2005 #define _3D_ONE_WORD 1 2006 2007 static struct { 2008 char *name; 2009 int flags; 2010 } _3d_cmds[0x4][0x8][0x100] = { 2011 { /* Pipeline Type 00 (Common) */ 2012 { /* Opcode 0 */ 2013 { "URB_FENCE", 0 }, /* 00 */ 2014 { "CS_URB_STATE", 0 }, 2015 { "CONSTANT_BUFFER", 0 }, 2016 { "STATE_PREFETCH", 0 }, 2017 }, 2018 { /* Opcode 1 */ 2019 { NULL, 0 }, /* 00 */ 2020 { "STATE_BASE_ADDRESS", 0 }, 2021 { "STATE_SIP", 0 }, 2022 { NULL, 0 }, 2023 2024 { "PIPELINE_SELECT", _3D_ONE_WORD }, /* 04 */ 2025 }, 2026 }, 2027 { /* Pipeline Type 01 (Single DW) */ 2028 { /* Opcode 0 */ 2029 }, 2030 { /* Opcode 1 */ 2031 { NULL, 0 }, /* 00 */ 2032 { NULL, 0 }, 2033 { NULL, 0 }, 2034 { NULL, 0 }, 2035 2036 { "PIPELINE_SELECT", 0 }, /* 04 */ 2037 { NULL, 0 }, 2038 { NULL, 0 }, 2039 { NULL, 0 }, 2040 }, 2041 }, 2042 { /* Pipeline Type 02 (Media) */ 2043 { /* Opcode 0 */ 2044 { "MEDIA_STATE_POINTERS", 0 }, /* 00 */ 2045 }, 2046 { /* Opcode 1 */ 2047 { "MEDIA_OBJECT", 0 }, /* 00 */ 2048 { "MEDIA_OBJECT_EX", 0 }, 2049 { "MEDIA_OBJECT_PTR", 0 }, 2050 }, 2051 }, 2052 { /* Pipeline Type 03 (3D) */ 2053 { /* Opcode 0 */ 2054 { "3DSTATE_PIPELINED_POINTERS", 0 }, /* 00 */ 2055 { "3DSTATE_BINDING_TABLE_POINTERS", 0 }, 2056 { NULL, 0 }, 2057 { NULL, 0 }, 2058 2059 { NULL, 0 }, /* 04 */ 2060 { "3DSTATE_URB", 0 }, 2061 { NULL, 0 }, 2062 { NULL, 0 }, 2063 2064 { "3DSTATE_VERTEX_BUFFERS", 0 }, /* 08 */ 2065 { "3DSTATE_VERTEX_ELEMENTS", 0 }, 2066 { "3DSTATE_INDEX_BUFFER", 0 }, 2067 { "3DSTATE_VF_STATISTICS", _3D_ONE_WORD }, 2068 2069 { NULL, 0 }, /* 0c */ 2070 { "3DSTATE_VIEWPORT_STATE_POINTERS", 0 }, 2071 }, 2072 { /* Opcode 1 */ 2073 { "3DSTATE_DRAWING_RECTANGLE", 0 }, /* 00 */ 2074 { "3DSTATE_CONSTANT_COLOR", 0 }, 2075 { "3DSTATE_SAMPLER_PALETTE_LOAD0", 0 }, 2076 { NULL, 0 }, 2077 2078 { "3DSTATE_CHROMA_KEY", 0 }, /* 04 */ 2079 { "3DSTATE_DEPTH_BUFFER", 0 }, 2080 { "3DSTATE_POLY_STIPPLE_OFFSET", 0 }, 2081 { "3DSTATE_POLY_STIPPLE_PATTERN", 0 }, 2082 2083 { "3DSTATE_LINE_STIPPLE", 0 }, /* 08 */ 2084 { "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP", 0 }, 2085 }, 2086 { /* Opcode 2 */ 2087 { "PIPE_CONTROL", 0 }, /* 00 */ 2088 }, 2089 { /* Opcode 3 */ 2090 { "3DPRIMITIVE", 0 }, /* 00 */ 2091 }, 2092 }, 2093 }; 2094 2095 static int 2096 i830_valid_command (uint32_t cmd) 2097 { 2098 uint32_t type = (cmd >> 29) & 0x7; 2099 uint32_t pipeline_type; 2100 uint32_t opcode; 2101 uint32_t subopcode; 2102 uint32_t count; 2103 2104 switch (type) { 2105 case 0: /* Memory Interface */ 2106 opcode = (cmd >> 23) & 0x3f; 2107 if (opcode < 0x10) 2108 count = 1; 2109 else 2110 count = (cmd & 0x3f) + 2; 2111 if (opcode == 0x00 && cmd != 0x00000000) 2112 return -1; 2113 if (!mi_cmds[opcode]) 2114 return -1; 2115 break; 2116 case 1: 2117 return -1; 2118 case 2: /* 2D */ 2119 count = (cmd & 0x1f) + 2; 2120 opcode = (cmd >> 22) & 0x7f; 2121 if (!_2d_cmds[opcode]) 2122 return -1; 2123 break; 2124 case 3: /* 3D */ 2125 pipeline_type = (cmd >> 27) & 0x3; 2126 opcode = (cmd >> 24) & 0x7; 2127 subopcode = (cmd >> 16) & 0xff; 2128 if (_3d_cmds[pipeline_type][opcode][subopcode].flags & _3D_ONE_WORD) 2129 count = 1; 2130 else 2131 count = (cmd & 0xff) + 2; 2132 if (!_3d_cmds[pipeline_type][opcode][subopcode].name) 2133 return -1; 2134 break; 2135 default: 2136 return -1; 2137 } 2138 return count; 2139 } 2140 2141 static int 2142 i830_dump_cmd (uint32_t cmd, int count) 2143 { 2144 uint32_t type = (cmd >> 29) & 0x7; 2145 uint32_t pipeline_type; 2146 uint32_t opcode; 2147 uint32_t subopcode; 2148 int ret = 1; 2149 2150 ErrorF ("\t"); 2151 switch (type) { 2152 case 0: /* Memory Interface */ 2153 opcode = (cmd >> 23) & 0x3f; 2154 if (mi_cmds[opcode]) 2155 ErrorF ("%-40.40s %d\n", mi_cmds[opcode], count); 2156 else 2157 ErrorF ("Memory Interface Reserved\n"); 2158 break; 2159 case 1: 2160 break; 2161 case 2: /* 2D */ 2162 opcode = (cmd >> 22) & 0x7f; 2163 if (_2d_cmds[opcode]) 2164 ErrorF ("%-40.40s %d\n", _2d_cmds[opcode], count); 2165 else 2166 ErrorF ("2D Reserved\n"); 2167 break; 2168 case 3: /* 3D */ 2169 pipeline_type = (cmd >> 27) & 0x3; 2170 opcode = (cmd >> 24) & 0x7; 2171 subopcode = (cmd >> 16) & 0xff; 2172 if (_3d_cmds[pipeline_type][opcode][subopcode].name) { 2173 ErrorF ("%-40.40s %d\n", 2174 _3d_cmds[pipeline_type][opcode][subopcode].name, 2175 count); 2176 } else { 2177 ErrorF ("3D/Media Reserved (pipe %d op %d sub %d)\n", pipeline_type, opcode, subopcode); 2178 } 2179 break; 2180 default: 2181 ErrorF ("Reserved\n"); 2182 break; 2183 } 2184 return ret; 2185 } 2186 2187 static int 2188 i830_valid_chain (ScrnInfoPtr pScrn, unsigned int ring, unsigned int end) 2189 { 2190 I830Ptr pI830 = I830PTR(pScrn); 2191 unsigned int head, tail, mask; 2192 volatile unsigned char *virt; 2193 uint32_t data; 2194 int count; 2195 volatile uint32_t *ptr; 2196 2197 head = (INREG (LP_RING + RING_HEAD)) & I830_HEAD_MASK; 2198 tail = INREG (LP_RING + RING_TAIL) & I830_TAIL_MASK; 2199 mask = pI830->ring.tail_mask; 2200 2201 virt = pI830->ring.virtual_start; 2202 ErrorF ("Ring at virtual %p head 0x%x tail 0x%x count %d\n", 2203 virt, head, tail, (((tail + mask + 1) - head) & mask) >> 2); 2204 2205 for (;;) 2206 { 2207 ptr = (volatile uint32_t *) (virt + ring); 2208 data = *ptr; 2209 count = i830_valid_command (data); 2210 if (count < 0) 2211 return 0; 2212 while (count > 0 && ring != end) 2213 { 2214 ring = (ring + 4) & mask; 2215 count--; 2216 } 2217 if (ring == end) { 2218 if (count == 0) 2219 return 1; 2220 else 2221 return 0; 2222 } 2223 } 2224 } 2225 2226 static void 2227 i830_dump_cmds (ScrnInfoPtr pScrn, 2228 volatile unsigned char *virt, 2229 uint32_t start, 2230 uint32_t stop, 2231 uint32_t mask, 2232 uint32_t acthd) 2233 { 2234 I830Ptr pI830 = I830PTR(pScrn); 2235 uint32_t ring = start; 2236 uint32_t cmd = start; 2237 uint32_t data; 2238 uint32_t batch_start_mask = ((0x7 << 29) | 2239 (0x3f << 23) | 2240 (0x7ff << 12) | 2241 (1 << 11) | 2242 (1 << 7) | 2243 (1 << 6) | 2244 (0x3f << 0)); 2245 uint32_t batch_start_cmd = ((0x0 << 29) | 2246 (0x31 << 23) | 2247 (0x00 << 12) | 2248 (0 << 11) | 2249 (1 << 7) | 2250 (0 << 6) | 2251 (0 << 0)); 2252 int count; 2253 volatile uint32_t *ptr; 2254 2255 while (ring != stop) 2256 { 2257 if (ring == acthd) 2258 ErrorF ("****"); 2259 ErrorF ("\t%08x: %08x", ring, *(volatile unsigned int *) (virt + ring)); 2260 if (ring == cmd) 2261 { 2262 ptr = (volatile uint32_t *) (virt + ring); 2263 data = *ptr; 2264 count = i830_valid_command (data); 2265 i830_dump_cmd (data, count); 2266 2267 /* check for MI_BATCH_BUFFER_END */ 2268 if (data == (0x0a << 23)) 2269 stop = (ring + 4) & mask; 2270 /* check for MI_BATCH_BUFFER_START */ 2271 if ((data & batch_start_mask) == batch_start_cmd) 2272 { 2273 uint32_t batch = ptr[1] & ~3; 2274 if (batch < pI830->FbMapSize) { 2275 ErrorF ("\t%08x: %08x\n", (ring + 4) & mask, batch); 2276 ErrorF ("Batch buffer at 0x%08x {\n", batch); 2277 i830_dump_cmds (pScrn, pI830->FbBase, batch, 2278 batch + 256, 0xffffffff, acthd); 2279 ErrorF ("}\n"); 2280 ring = (ring + (count - 1) * 4) & mask; 2281 } 2282 } 2283 cmd = (cmd + count * 4) & mask; 2284 } else 2285 ErrorF ("\n"); 2286 ring = (ring + 4) & mask; 2287 } 2288 } 2289 2290 static void 2291 i830_dump_ring(ScrnInfoPtr pScrn, uint32_t acthd) 2292 { 2293 I830Ptr pI830 = I830PTR(pScrn); 2294 unsigned int head, tail, mask, cmd; 2295 volatile unsigned char *virt; 2296 2297 head = (INREG (LP_RING + RING_HEAD)) & I830_HEAD_MASK; 2298 tail = INREG (LP_RING + RING_TAIL) & I830_TAIL_MASK; 2299 mask = pI830->ring.tail_mask; 2300 2301 virt = pI830->ring.virtual_start; 2302 ErrorF ("Ring at virtual %p head 0x%x tail 0x%x count %d acthd 0x%x\n", 2303 virt, head, tail, (((tail + mask + 1) - head) & mask) >> 2, acthd); 2304 2305 /* walk back by instructions */ 2306 for (cmd = (head - 256) & mask; 2307 cmd != (head & mask); 2308 cmd = (cmd + 4) & mask) 2309 { 2310 if (i830_valid_chain (pScrn, cmd, (head & mask))) 2311 break; 2312 } 2313 2314 i830_dump_cmds (pScrn, virt, cmd, head, mask, acthd); 2315 2316 ErrorF ("Ring end\n"); 2317 } 2318 2319 /* Famous last words 2320 */ 2321 void 2322 i830_dump_error_state(ScrnInfoPtr pScrn) 2323 { 2324 I830Ptr pI830 = I830PTR(pScrn); 2325 2326 ErrorF("pgetbl_ctl: 0x%08x getbl_err: 0x%08x\n", 2327 INREG(PGETBL_CTL), INREG(PGE_ERR)); 2328 2329 ErrorF("ipeir: 0x%08x iphdr: 0x%08x\n", INREG(IPEIR), INREG(IPEHR)); 2330 2331 ErrorF("LP ring tail: 0x%08x head: 0x%08x len: 0x%08x start 0x%08x\n", 2332 INREG(LP_RING + RING_TAIL), 2333 INREG(LP_RING + RING_HEAD) & HEAD_ADDR, 2334 INREG(LP_RING + RING_LEN), 2335 INREG(LP_RING + RING_START)); 2336 2337 ErrorF("eir: 0x%04x esr: 0x%04x emr: 0x%04x\n", 2338 INREG16(EIR), INREG16(ESR), INREG16(EMR)); 2339 2340 ErrorF("instdone: 0x%04x instpm: 0x%04x\n", 2341 INREG16(INST_DONE), INREG8(INST_PM)); 2342 2343 ErrorF("memmode: 0x%08x instps: 0x%08x\n", 2344 INREG(MEMMODE), INREG(INST_PS)); 2345 2346 ErrorF("hwstam: 0x%04x ier: 0x%04x imr: 0x%04x iir: 0x%04x\n", 2347 INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR)); 2348 i830_dump_ring (pScrn, INREG(ACTHD)); 2349 } 2350 2351 void 2352 i965_dump_error_state(ScrnInfoPtr pScrn) 2353 { 2354 I830Ptr pI830 = I830PTR(pScrn); 2355 uint32_t acthd; 2356 2357 ErrorF("pgetbl_ctl: 0x%08x pgetbl_err: 0x%08x\n", 2358 INREG(PGETBL_CTL), INREG(PGE_ERR)); 2359 2360 ErrorF("ipeir: 0x%08x iphdr: 0x%08x\n", 2361 INREG(IPEIR_I965), INREG(IPEHR_I965)); 2362 2363 ErrorF("LP ring tail: 0x%08x head: %x len: 0x%08x start 0x%08x\n", 2364 INREG(LP_RING + RING_TAIL), 2365 INREG(LP_RING + RING_HEAD) & HEAD_ADDR, 2366 INREG(LP_RING + RING_LEN), 2367 INREG(LP_RING + RING_START)); 2368 2369 ErrorF("Err ID (eir): 0x%08x\n" 2370 "Err Status (esr): 0x%08x\n" 2371 "Err Mask (emr): 0x%08x\n", 2372 INREG(EIR), INREG(ESR), INREG(EMR)); 2373 2374 ErrorF("instdone: 0x%08x instdone_1: 0x%08x\n", 2375 INREG(INST_DONE_I965), INREG(INST_DONE_1)); 2376 ErrorF("instpm: 0x%08x\n", INREG(INST_PM)); 2377 2378 ErrorF("memmode: 0x%08x instps: 0x%08x\n", 2379 INREG(MEMMODE), INREG(INST_PS_I965)); 2380 2381 ErrorF("HW Status mask (hwstam): 0x%08x\nIRQ enable (ier): 0x%08x " 2382 "imr: 0x%08x iir: 0x%08x\n", 2383 INREG(HWSTAM), INREG(IER), INREG(IMR), INREG(IIR)); 2384 2385 acthd = INREG(ACTHD_I965); 2386 ErrorF("acthd: 0x%08x dma_fadd_p: 0x%08x\n", 2387 acthd, INREG(DMA_FADD_P)); 2388 ErrorF("ecoskpd: 0x%08x excc: 0x%08x\n", 2389 INREG(ECOSKPD), INREG(EXCC)); 2390 2391 ErrorF("cache_mode: 0x%08x/0x%08x\n", INREG(CACHE_MODE_0), 2392 INREG(CACHE_MODE_1)); 2393 ErrorF("mi_arb_state: 0x%08x\n", INREG(MI_ARB_STATE)); 2394 2395 ErrorF("IA_VERTICES_COUNT_QW 0x%08x/0x%08x\n", 2396 INREG(IA_VERTICES_COUNT_QW), 2397 INREG(IA_VERTICES_COUNT_QW+4)); 2398 ErrorF("IA_PRIMITIVES_COUNT_QW 0x%08x/0x%08x\n", 2399 INREG(IA_PRIMITIVES_COUNT_QW), 2400 INREG(IA_PRIMITIVES_COUNT_QW+4)); 2401 2402 ErrorF("VS_INVOCATION_COUNT_QW 0x%08x/0x%08x\n", 2403 INREG(VS_INVOCATION_COUNT_QW), 2404 INREG(VS_INVOCATION_COUNT_QW+4)); 2405 2406 ErrorF("GS_INVOCATION_COUNT_QW 0x%08x/0x%08x\n", 2407 INREG(GS_INVOCATION_COUNT_QW), 2408 INREG(GS_INVOCATION_COUNT_QW+4)); 2409 ErrorF("GS_PRIMITIVES_COUNT_QW 0x%08x/0x%08x\n", 2410 INREG(GS_PRIMITIVES_COUNT_QW), 2411 INREG(GS_PRIMITIVES_COUNT_QW+4)); 2412 2413 ErrorF("CL_INVOCATION_COUNT_QW 0x%08x/0x%08x\n", 2414 INREG(CL_INVOCATION_COUNT_QW), 2415 INREG(CL_INVOCATION_COUNT_QW+4)); 2416 ErrorF("CL_PRIMITIVES_COUNT_QW 0x%08x/0x%08x\n", 2417 INREG(CL_PRIMITIVES_COUNT_QW), 2418 INREG(CL_PRIMITIVES_COUNT_QW+4)); 2419 2420 ErrorF("PS_INVOCATION_COUNT_QW 0x%08x/0x%08x\n", 2421 INREG(PS_INVOCATION_COUNT_QW), 2422 INREG(PS_INVOCATION_COUNT_QW+4)); 2423 ErrorF("PS_DEPTH_COUNT_QW 0x%08x/0x%08x\n", 2424 INREG(PS_DEPTH_COUNT_QW), 2425 INREG(PS_DEPTH_COUNT_QW+4)); 2426 2427 ErrorF("WIZ_CTL 0x%08x\n", INREG(WIZ_CTL)); 2428 ErrorF("TS_CTL 0x%08x TS_DEBUG_DATA 0x%08x\n", INREG(TS_CTL), 2429 INREG(TS_DEBUG_DATA)); 2430 ErrorF("TD_CTL 0x%08x / 0x%08x\n", 2431 INREG(TD_CTL), INREG(TD_CTL2)); 2432 i830_dump_ring (pScrn, acthd); 2433 } 2434 2435 /** 2436 * Checks the hardware error state bits. 2437 * 2438 * \return TRUE if any errors were found. 2439 */ 2440 Bool 2441 i830_check_error_state(ScrnInfoPtr pScrn) 2442 { 2443 I830Ptr pI830 = I830PTR(pScrn); 2444 int errors = 0; 2445 unsigned long temp, head, tail; 2446 2447 temp = INREG16(ESR); 2448 if (temp != 0) { 2449 Bool vertex_max = !IS_I965G(pI830) && (temp & ERR_VERTEX_MAX); 2450 Bool pgtbl = temp & ERR_PGTBL_ERROR; 2451 Bool underrun = !IS_I965G(pI830) && 2452 (temp & ERR_DISPLAY_OVERLAY_UNDERRUN); 2453 Bool instruction = !IS_I965G(pI830) && (temp & ERR_INSTRUCTION_ERROR); 2454 2455 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2456 "ESR is 0x%08lx%s%s%s%s\n", temp, 2457 vertex_max ? ", max vertices exceeded" : "", 2458 pgtbl ? ", page table error" : "", 2459 underrun ? ", display/overlay underrun" : "", 2460 instruction ? ", instruction error" : ""); 2461 errors++; 2462 } 2463 /* Check first for page table errors */ 2464 if (!IS_I9XX(pI830)) { 2465 temp = INREG(PGE_ERR); 2466 if (temp != 0) { 2467 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2468 "PGTBL_ER is 0x%08lx\n", temp); 2469 errors++; 2470 } 2471 } else { 2472 temp = INREG(PGTBL_ER); 2473 if (temp != 0) { 2474 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2475 "PGTBL_ER is 0x%08lx" 2476 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", temp, 2477 temp & PGTBL_ERR_HOST_GTT_PTE ? ", host gtt pte" : "", 2478 temp & PGTBL_ERR_HOST_PTE_DATA ? ", host pte data" : "", 2479 temp & PGTBL_ERR_DISPA_GTT_PTE ? ", display A pte" : "", 2480 temp & PGTBL_ERR_DISPA_TILING ? 2481 ", display A tiling" : "", 2482 temp & PGTBL_ERR_DISPB_GTT_PTE ? ", display B pte" : "", 2483 temp & PGTBL_ERR_DISPB_TILING ? 2484 ", display B tiling" : "", 2485 temp & PGTBL_ERR_DISPC_GTT_PTE ? ", display C pte" : "", 2486 temp & PGTBL_ERR_DISPC_TILING ? 2487 ", display C tiling" : "", 2488 temp & PGTBL_ERR_OVERLAY_GTT_PTE ? 2489 ", overlay GTT PTE" : "", 2490 temp & PGTBL_ERR_OVERLAY_TILING ? 2491 ", overlay tiling" : "", 2492 temp & PGTBL_ERR_CS_GTT ? ", CS GTT" : "", 2493 temp & PGTBL_ERR_CS_INSTRUCTION_GTT_PTE ? 2494 ", CS instruction GTT PTE" : "", 2495 temp & PGTBL_ERR_CS_VERTEXDATA_GTT_PTE ? 2496 ", CS vertex data GTT PTE" : "", 2497 temp & PGTBL_ERR_BIN_INSTRUCTION_GTT_PTE ? 2498 ", BIN instruction GTT PTE" : "", 2499 temp & PGTBL_ERR_BIN_VERTEXDATA_GTT_PTE ? 2500 ", BIN vertex data GTT PTE" : "", 2501 temp & PGTBL_ERR_LC_GTT_PTE ? ", LC pte" : "", 2502 temp & PGTBL_ERR_LC_TILING ? ", LC tiling" : "", 2503 temp & PGTBL_ERR_MT_GTT_PTE ? ", MT pte" : "", 2504 temp & PGTBL_ERR_MT_TILING ? ", MT tiling" : ""); 2505 errors++; 2506 } 2507 } 2508 temp = INREG(PGETBL_CTL); 2509 if (!(temp & 1)) { 2510 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2511 "PGTBL_CTL (0x%08lx) indicates GTT is disabled\n", temp); 2512 errors++; 2513 } 2514 temp = INREG(LP_RING + RING_LEN); 2515 if (!pI830->have_gem && (temp & 1)) { 2516 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2517 "PRB0_CTL (0x%08lx) indicates ring buffer enabled\n", temp); 2518 errors++; 2519 } 2520 head = INREG(LP_RING + RING_HEAD); 2521 tail = INREG(LP_RING + RING_TAIL); 2522 if ((tail & I830_TAIL_MASK) != (head & I830_HEAD_MASK)) { 2523 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2524 "PRB0_HEAD (0x%08lx) and PRB0_TAIL (0x%08lx) indicate " 2525 "ring buffer not flushed\n", head, tail); 2526 errors++; 2527 } 2528 2529 #if 0 2530 if (errors) { 2531 if (IS_I965G(pI830)) 2532 i965_dump_error_state(pScrn); 2533 else 2534 i830_dump_error_state(pScrn); 2535 } 2536 #endif 2537 2538 return (errors != 0); 2539 } 2540 #endif /* !REG_DUMPER */ 2541