1/************************************************************************** 2 3Copyright 2001 VA Linux Systems Inc., Fremont, California. 4Copyright © 2002 by David Dawes 5 6All Rights Reserved. 7 8Permission is hereby granted, free of charge, to any person obtaining a 9copy of this software and associated documentation files (the "Software"), 10to deal in the Software without restriction, including without limitation 11on the rights to use, copy, modify, merge, publish, distribute, sub 12license, and/or sell copies of the Software, and to permit persons to whom 13the Software is furnished to do so, subject to the following conditions: 14 15The above copyright notice and this permission notice (including the next 16paragraph) shall be included in all copies or substantial portions of the 17Software. 18 19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 23DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 25USE OR OTHER DEALINGS IN THE SOFTWARE. 26 27**************************************************************************/ 28 29/* 30 * Authors: Jeff Hartmann <jhartmann@valinux.com> 31 * Abraham van der Merwe <abraham@2d3d.co.za> 32 * David Dawes <dawes@xfree86.org> 33 * Alan Hourihane <alanh@tungstengraphics.com> 34 */ 35 36#ifdef HAVE_CONFIG_H 37#include "config.h" 38#endif 39 40#ifndef PRINT_MODE_INFO 41#define PRINT_MODE_INFO 0 42#endif 43 44#include <assert.h> 45#include <string.h> 46#include <stdio.h> 47#include <unistd.h> 48#include <stdlib.h> 49#include <stdio.h> 50#include <errno.h> 51 52#include "xf86.h" 53#include "xf86_OSproc.h" 54#include "xf86Priv.h" 55#include "xf86cmap.h" 56#include "compiler.h" 57#include "vgaHW.h" 58#include "mipointer.h" 59#include "micmap.h" 60#include "shadowfb.h" 61#include <X11/extensions/randr.h> 62#include "fb.h" 63#include "miscstruct.h" 64#include "dixstruct.h" 65#include "xf86xv.h" 66#include <X11/extensions/Xv.h> 67#include "shadow.h" 68#include "i830.h" 69#include "i830_display.h" 70#include "i830_debug.h" 71#include "i830_bios.h" 72#include "i830_video.h" 73#if HAVE_SYS_MMAN_H && HAVE_MPROTECT 74#include <sys/mman.h> 75#endif 76 77#ifdef INTEL_XVMC 78#define _INTEL_XVMC_SERVER_ 79#include "i830_hwmc.h" 80#endif 81 82#include <sys/ioctl.h> 83#include "i915_drm.h" 84#include <xf86drmMode.h> 85 86#define BIT(x) (1 << (x)) 87#define MAX(a,b) ((a) > (b) ? (a) : (b)) 88#define NB_OF(x) (sizeof (x) / sizeof (*x)) 89 90/* *INDENT-OFF* */ 91static SymTabRec I830Chipsets[] = { 92 {PCI_CHIP_I830_M, "i830"}, 93 {PCI_CHIP_845_G, "845G"}, 94 {PCI_CHIP_I855_GM, "852GM/855GM"}, 95 {PCI_CHIP_I865_G, "865G"}, 96 {PCI_CHIP_I915_G, "915G"}, 97 {PCI_CHIP_E7221_G, "E7221 (i915)"}, 98 {PCI_CHIP_I915_GM, "915GM"}, 99 {PCI_CHIP_I945_G, "945G"}, 100 {PCI_CHIP_I945_GM, "945GM"}, 101 {PCI_CHIP_I945_GME, "945GME"}, 102 {PCI_CHIP_IGD_GM, "Pineview GM"}, 103 {PCI_CHIP_IGD_G, "Pineview G"}, 104 {PCI_CHIP_I965_G, "965G"}, 105 {PCI_CHIP_G35_G, "G35"}, 106 {PCI_CHIP_I965_Q, "965Q"}, 107 {PCI_CHIP_I946_GZ, "946GZ"}, 108 {PCI_CHIP_I965_GM, "965GM"}, 109 {PCI_CHIP_I965_GME, "965GME/GLE"}, 110 {PCI_CHIP_G33_G, "G33"}, 111 {PCI_CHIP_Q35_G, "Q35"}, 112 {PCI_CHIP_Q33_G, "Q33"}, 113 {PCI_CHIP_GM45_GM, "GM45"}, 114 {PCI_CHIP_IGD_E_G, "4 Series"}, 115 {PCI_CHIP_G45_G, "G45/G43"}, 116 {PCI_CHIP_Q45_G, "Q45/Q43"}, 117 {PCI_CHIP_G41_G, "G41"}, 118 {PCI_CHIP_B43_G, "B43"}, 119 {PCI_CHIP_IGDNG_D_G, "Clarkdale"}, 120 {PCI_CHIP_IGDNG_M_G, "Arrandale"}, 121 {-1, NULL} 122}; 123 124static PciChipsets I830PciChipsets[] = { 125 {PCI_CHIP_I830_M, PCI_CHIP_I830_M, NULL}, 126 {PCI_CHIP_845_G, PCI_CHIP_845_G, NULL}, 127 {PCI_CHIP_I855_GM, PCI_CHIP_I855_GM, NULL}, 128 {PCI_CHIP_I865_G, PCI_CHIP_I865_G, NULL}, 129 {PCI_CHIP_I915_G, PCI_CHIP_I915_G, NULL}, 130 {PCI_CHIP_E7221_G, PCI_CHIP_E7221_G, NULL}, 131 {PCI_CHIP_I915_GM, PCI_CHIP_I915_GM, NULL}, 132 {PCI_CHIP_I945_G, PCI_CHIP_I945_G, NULL}, 133 {PCI_CHIP_I945_GM, PCI_CHIP_I945_GM, NULL}, 134 {PCI_CHIP_I945_GME, PCI_CHIP_I945_GME, NULL}, 135 {PCI_CHIP_IGD_GM, PCI_CHIP_IGD_GM, NULL}, 136 {PCI_CHIP_IGD_G, PCI_CHIP_IGD_G, NULL}, 137 {PCI_CHIP_I965_G, PCI_CHIP_I965_G, NULL}, 138 {PCI_CHIP_G35_G, PCI_CHIP_G35_G, NULL}, 139 {PCI_CHIP_I965_Q, PCI_CHIP_I965_Q, NULL}, 140 {PCI_CHIP_I946_GZ, PCI_CHIP_I946_GZ, NULL}, 141 {PCI_CHIP_I965_GM, PCI_CHIP_I965_GM, NULL}, 142 {PCI_CHIP_I965_GME, PCI_CHIP_I965_GME, NULL}, 143 {PCI_CHIP_G33_G, PCI_CHIP_G33_G, NULL}, 144 {PCI_CHIP_Q35_G, PCI_CHIP_Q35_G, NULL}, 145 {PCI_CHIP_Q33_G, PCI_CHIP_Q33_G, NULL}, 146 {PCI_CHIP_GM45_GM, PCI_CHIP_GM45_GM, NULL}, 147 {PCI_CHIP_IGD_E_G, PCI_CHIP_IGD_E_G, NULL}, 148 {PCI_CHIP_G45_G, PCI_CHIP_G45_G, NULL}, 149 {PCI_CHIP_Q45_G, PCI_CHIP_Q45_G, NULL}, 150 {PCI_CHIP_G41_G, PCI_CHIP_G41_G, NULL}, 151 {PCI_CHIP_B43_G, PCI_CHIP_B43_G, NULL}, 152 {PCI_CHIP_IGDNG_D_G, PCI_CHIP_IGDNG_D_G, NULL}, 153 {PCI_CHIP_IGDNG_M_G, PCI_CHIP_IGDNG_M_G, NULL}, 154 {-1, -1, NULL} 155}; 156 157/* 158 * Note: "ColorKey" is provided for compatibility with the i810 driver. 159 * However, the correct option name is "VideoKey". "ColorKey" usually 160 * refers to the tranparency key for 8+24 overlays, not for video overlays. 161 */ 162 163typedef enum { 164 OPTION_DRI, 165 OPTION_VIDEO_KEY, 166 OPTION_COLOR_KEY, 167 OPTION_MODEDEBUG, 168 OPTION_FALLBACKDEBUG, 169 OPTION_LVDS24BITMODE, 170 OPTION_FBC, 171 OPTION_TILING, 172 OPTION_SWAPBUFFERS_WAIT, 173 OPTION_LVDSFIXEDMODE, 174 OPTION_FORCEENABLEPIPEA, 175#ifdef INTEL_XVMC 176 OPTION_XVMC, 177#endif 178 OPTION_PREFER_OVERLAY, 179} I830Opts; 180 181static OptionInfoRec I830Options[] = { 182 {OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, TRUE}, 183 {OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, 184 {OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE}, 185 {OPTION_MODEDEBUG, "ModeDebug", OPTV_BOOLEAN, {0}, FALSE}, 186 {OPTION_FALLBACKDEBUG, "FallbackDebug", OPTV_BOOLEAN, {0}, FALSE}, 187 {OPTION_LVDS24BITMODE, "LVDS24Bit", OPTV_BOOLEAN, {0}, FALSE}, 188 {OPTION_FBC, "FramebufferCompression", OPTV_BOOLEAN, {0}, TRUE}, 189 {OPTION_TILING, "Tiling", OPTV_BOOLEAN, {0}, TRUE}, 190 {OPTION_SWAPBUFFERS_WAIT, "SwapbuffersWait", OPTV_BOOLEAN, {0}, TRUE}, 191 {OPTION_LVDSFIXEDMODE, "LVDSFixedMode", OPTV_BOOLEAN, {0}, FALSE}, 192 {OPTION_FORCEENABLEPIPEA, "ForceEnablePipeA", OPTV_BOOLEAN, {0}, FALSE}, 193#ifdef INTEL_XVMC 194 {OPTION_XVMC, "XvMC", OPTV_BOOLEAN, {0}, TRUE}, 195#endif 196 {OPTION_PREFER_OVERLAY, "XvPreferOverlay", OPTV_BOOLEAN, {0}, FALSE}, 197 {-1, NULL, OPTV_NONE, {0}, FALSE} 198}; 199/* *INDENT-ON* */ 200 201static void i830AdjustFrame(int scrnIndex, int x, int y, int flags); 202static Bool I830CloseScreen(int scrnIndex, ScreenPtr pScreen); 203static Bool I830EnterVT(int scrnIndex, int flags); 204static Bool SaveHWState(ScrnInfoPtr pScrn); 205static Bool RestoreHWState(ScrnInfoPtr pScrn); 206 207/* temporary */ 208extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y); 209 210#ifdef I830DEBUG 211void 212I830DPRINTF(const char *filename, int line, const char *function, 213 const char *fmt, ...) 214{ 215 va_list ap; 216 217 ErrorF("\n##############################################\n" 218 "*** In function %s, on line %d, in file %s ***\n", 219 function, line, filename); 220 va_start(ap, fmt); 221 VErrorF(fmt, ap); 222 va_end(ap); 223 ErrorF("##############################################\n\n"); 224} 225#endif /* #ifdef I830DEBUG */ 226 227/* Export I830 options to i830 driver where necessary */ 228const OptionInfoRec * 229I830AvailableOptions(int chipid, int busid) 230{ 231 int i; 232 233 for (i = 0; I830PciChipsets[i].PCIid > 0; i++) { 234 if (chipid == I830PciChipsets[i].PCIid) 235 return I830Options; 236 } 237 return NULL; 238} 239 240static Bool 241I830GetRec(ScrnInfoPtr pScrn) 242{ 243 I830Ptr pI830; 244 245 if (pScrn->driverPrivate) 246 return TRUE; 247 pI830 = pScrn->driverPrivate = xnfcalloc(sizeof(I830Rec), 1); 248 return TRUE; 249} 250 251static void 252I830FreeRec(ScrnInfoPtr pScrn) 253{ 254 I830Ptr pI830; 255 256 if (!pScrn) 257 return; 258 if (!pScrn->driverPrivate) 259 return; 260 261 pI830 = I830PTR(pScrn); 262 263 xfree(pScrn->driverPrivate); 264 pScrn->driverPrivate = NULL; 265} 266 267static int 268I830DetectMemory(ScrnInfoPtr pScrn) 269{ 270 I830Ptr pI830 = I830PTR(pScrn); 271 uint16_t gmch_ctrl; 272 int memsize = 0, gtt_size; 273 int range; 274 struct pci_device *bridge = intel_host_bridge (); 275 pci_device_cfg_read_u16(bridge, & gmch_ctrl, I830_GMCH_CTRL); 276 277 if (IS_I965G(pI830)) { 278 /* The 965 may have a GTT that is actually larger than is necessary 279 * to cover the aperture, so check the hardware's reporting of the 280 * GTT size. 281 */ 282 switch (INREG(PGETBL_CTL) & PGETBL_SIZE_MASK) { 283 case PGETBL_SIZE_512KB: 284 gtt_size = 512; 285 break; 286 case PGETBL_SIZE_256KB: 287 gtt_size = 256; 288 break; 289 case PGETBL_SIZE_128KB: 290 gtt_size = 128; 291 break; 292 case PGETBL_SIZE_1MB: 293 gtt_size = 1024; 294 break; 295 case PGETBL_SIZE_2MB: 296 gtt_size = 2048; 297 break; 298 case PGETBL_SIZE_1_5MB: 299 gtt_size = 1024 + 512; 300 break; 301 default: 302 FatalError("Unknown GTT size value: %08x\n", (int)INREG(PGETBL_CTL)); 303 } 304 } else if (IS_G33CLASS(pI830)) { 305 /* G33's GTT size is detect in GMCH_CTRL */ 306 switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { 307 case G33_PGETBL_SIZE_1M: 308 gtt_size = 1024; 309 break; 310 case G33_PGETBL_SIZE_2M: 311 gtt_size = 2048; 312 break; 313 default: 314 FatalError("Unknown GTT size value: %08x\n", 315 (int)(gmch_ctrl & G33_PGETBL_SIZE_MASK)); 316 } 317 } else { 318 /* Older chipsets only had GTT appropriately sized for the aperture. */ 319 gtt_size = pI830->FbMapSize / (1024*1024); 320 } 321 322 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "detected %d kB GTT.\n", gtt_size); 323 324 /* The stolen memory has the GTT at the top, and the 4KB popup below that. 325 * Everything else can be freely used by the graphics driver. 326 */ 327 range = gtt_size + 4; 328 329 /* new 4 series hardware has seperate GTT stolen with GFX stolen */ 330 if (IS_G4X(pI830) || IS_IGD(pI830) || IS_IGDNG(pI830)) 331 range = 4; 332 333 if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { 334 switch (gmch_ctrl & I855_GMCH_GMS_MASK) { 335 case I855_GMCH_GMS_STOLEN_1M: 336 memsize = MB(1) - KB(range); 337 break; 338 case I855_GMCH_GMS_STOLEN_4M: 339 memsize = MB(4) - KB(range); 340 break; 341 case I855_GMCH_GMS_STOLEN_8M: 342 memsize = MB(8) - KB(range); 343 break; 344 case I855_GMCH_GMS_STOLEN_16M: 345 memsize = MB(16) - KB(range); 346 break; 347 case I855_GMCH_GMS_STOLEN_32M: 348 memsize = MB(32) - KB(range); 349 break; 350 case I915G_GMCH_GMS_STOLEN_48M: 351 if (IS_I9XX(pI830)) 352 memsize = MB(48) - KB(range); 353 break; 354 case I915G_GMCH_GMS_STOLEN_64M: 355 if (IS_I9XX(pI830)) 356 memsize = MB(64) - KB(range); 357 break; 358 case G33_GMCH_GMS_STOLEN_128M: 359 if (IS_I9XX(pI830)) 360 memsize = MB(128) - KB(range); 361 break; 362 case G33_GMCH_GMS_STOLEN_256M: 363 if (IS_I9XX(pI830)) 364 memsize = MB(256) - KB(range); 365 break; 366 case INTEL_GMCH_GMS_STOLEN_96M: 367 if (IS_I9XX(pI830)) 368 memsize = MB(96) - KB(range); 369 break; 370 case INTEL_GMCH_GMS_STOLEN_160M: 371 if (IS_I9XX(pI830)) 372 memsize = MB(160) - KB(range); 373 break; 374 case INTEL_GMCH_GMS_STOLEN_224M: 375 if (IS_I9XX(pI830)) 376 memsize = MB(224) - KB(range); 377 break; 378 case INTEL_GMCH_GMS_STOLEN_352M: 379 if (IS_I9XX(pI830)) 380 memsize = MB(352) - KB(range); 381 break; 382 } 383 } else { 384 switch (gmch_ctrl & I830_GMCH_GMS_MASK) { 385 case I830_GMCH_GMS_STOLEN_512: 386 memsize = KB(512) - KB(range); 387 break; 388 case I830_GMCH_GMS_STOLEN_1024: 389 memsize = MB(1) - KB(range); 390 break; 391 case I830_GMCH_GMS_STOLEN_8192: 392 memsize = MB(8) - KB(range); 393 break; 394 case I830_GMCH_GMS_LOCAL: 395 memsize = 0; 396 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 397 "Local memory found, but won't be used.\n"); 398 break; 399 } 400 } 401 402#if 0 403 /* And 64KB page aligned */ 404 memsize &= ~0xFFFF; 405#endif 406 407 if (memsize > 0) { 408 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 409 "detected %d kB stolen memory.\n", memsize / 1024); 410 } else { 411 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no video memory detected.\n"); 412 } 413 414 return memsize; 415} 416 417static Bool 418I830MapMMIO(ScrnInfoPtr pScrn) 419{ 420 int err; 421 struct pci_device *device; 422 I830Ptr pI830 = I830PTR(pScrn); 423 424 device = pI830->PciInfo; 425 err = pci_device_map_range (device, 426 pI830->MMIOAddr, 427 pI830->MMIOSize, 428 PCI_DEV_MAP_FLAG_WRITABLE, 429 (void **) &pI830->MMIOBase); 430 if (err) 431 { 432 xf86DrvMsg (pScrn->scrnIndex, X_ERROR, 433 "Unable to map mmio range. %s (%d)\n", 434 strerror (err), err); 435 return FALSE; 436 } 437 438 /* Set up the GTT mapping for the various places it has been moved over 439 * time. 440 */ 441 if (IS_I9XX(pI830)) { 442 uint32_t gttaddr; 443 444 if (IS_I965G(pI830)) 445 { 446 if (IS_G4X(pI830) || IS_IGDNG(pI830)) { 447 gttaddr = pI830->MMIOAddr + MB(2); 448 pI830->GTTMapSize = MB(2); 449 } else { 450 gttaddr = pI830->MMIOAddr + KB(512); 451 pI830->GTTMapSize = KB(512); 452 } 453 } 454 else 455 { 456 gttaddr = I810_MEMBASE(pI830->PciInfo, 3) & 0xFFFFFF00; 457 pI830->GTTMapSize = pI830->FbMapSize / 1024; 458 } 459 err = pci_device_map_range (device, 460 gttaddr, pI830->GTTMapSize, 461 PCI_DEV_MAP_FLAG_WRITABLE, 462 (void **) &pI830->GTTBase); 463 if (err) 464 { 465 xf86DrvMsg (pScrn->scrnIndex, X_ERROR, 466 "Unable to map GTT range. %s (%d)\n", 467 strerror (err), err); 468 return FALSE; 469 } 470 } else { 471 /* The GTT aperture on i830 is write-only. We could probably map the 472 * actual physical pages that back it, but leave it alone for now. 473 */ 474 pI830->GTTBase = NULL; 475 pI830->GTTMapSize = 0; 476 } 477 478 return TRUE; 479} 480 481static Bool 482I830MapMem(ScrnInfoPtr pScrn) 483{ 484 I830Ptr pI830 = I830PTR(pScrn); 485 long i; 486 struct pci_device *const device = pI830->PciInfo; 487 int err; 488 489 for (i = 2; i < pI830->FbMapSize; i <<= 1) ; 490 pI830->FbMapSize = i; 491 492 err = pci_device_map_range (device, pI830->LinearAddr, pI830->FbMapSize, 493 PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE, 494 (void **) &pI830->FbBase); 495 if (err) 496 return FALSE; 497 498 if (pI830->ring.mem != NULL) { 499 pI830->ring.virtual_start = pI830->FbBase + pI830->ring.mem->offset; 500 } 501 502 return TRUE; 503} 504 505static void 506I830UnmapMMIO(ScrnInfoPtr pScrn) 507{ 508 I830Ptr pI830 = I830PTR(pScrn); 509 510 pci_device_unmap_range (pI830->PciInfo, pI830->MMIOBase, pI830->MMIOSize); 511 pI830->MMIOBase = NULL; 512 513 if (IS_I9XX(pI830)) { 514 pci_device_unmap_range (pI830->PciInfo, pI830->GTTBase, pI830->GTTMapSize); 515 pI830->GTTBase = NULL; 516 } 517} 518 519static Bool 520I830UnmapMem(ScrnInfoPtr pScrn) 521{ 522 I830Ptr pI830 = I830PTR(pScrn); 523 524 pci_device_unmap_range (pI830->PciInfo, pI830->FbBase, pI830->FbMapSize); 525 pI830->FbBase = NULL; 526 I830UnmapMMIO(pScrn); 527 return TRUE; 528} 529 530static void 531I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 532 LOCO * colors, VisualPtr pVisual) 533{ 534 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 535 int i,j, index; 536 int p; 537 uint16_t lut_r[256], lut_g[256], lut_b[256]; 538 539 DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors); 540 541 for(p = 0; p < xf86_config->num_crtc; p++) { 542 xf86CrtcPtr crtc = xf86_config->crtc[p]; 543 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 544 545 /* Initialize to the old lookup table values. */ 546 for (i = 0; i < 256; i++) { 547 lut_r[i] = intel_crtc->lut_r[i] << 8; 548 lut_g[i] = intel_crtc->lut_g[i] << 8; 549 lut_b[i] = intel_crtc->lut_b[i] << 8; 550 } 551 552 switch(pScrn->depth) { 553 case 15: 554 for (i = 0; i < numColors; i++) { 555 index = indices[i]; 556 for (j = 0; j < 8; j++) { 557 lut_r[index * 8 + j] = colors[index].red << 8; 558 lut_g[index * 8 + j] = colors[index].green << 8; 559 lut_b[index * 8 + j] = colors[index].blue << 8; 560 } 561 } 562 break; 563 case 16: 564 for (i = 0; i < numColors; i++) { 565 index = indices[i]; 566 567 if (index <= 31) { 568 for (j = 0; j < 8; j++) { 569 lut_r[index * 8 + j] = colors[index].red << 8; 570 lut_b[index * 8 + j] = colors[index].blue << 8; 571 } 572 } 573 574 for (j = 0; j < 4; j++) { 575 lut_g[index * 4 + j] = colors[index].green << 8; 576 } 577 } 578 break; 579 default: 580 for (i = 0; i < numColors; i++) { 581 index = indices[i]; 582 lut_r[index] = colors[index].red << 8; 583 lut_g[index] = colors[index].green << 8; 584 lut_b[index] = colors[index].blue << 8; 585 } 586 break; 587 } 588 589 /* Make the change through RandR */ 590#ifdef RANDR_12_INTERFACE 591 RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); 592#else 593 crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); 594#endif 595 } 596} 597 598/** 599 * Adjust the screen pixmap for the current location of the front buffer. 600 * This is done at EnterVT when buffers are bound as long as the resources 601 * have already been created, but the first EnterVT happens before 602 * CreateScreenResources. 603 */ 604static Bool 605i830CreateScreenResources(ScreenPtr pScreen) 606{ 607 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 608 I830Ptr pI830 = I830PTR(pScrn); 609 610 pScreen->CreateScreenResources = pI830->CreateScreenResources; 611 if (!(*pScreen->CreateScreenResources)(pScreen)) 612 return FALSE; 613 614 i830_uxa_create_screen_resources(pScreen); 615 616 return TRUE; 617} 618 619static int 620i830_output_clones (ScrnInfoPtr pScrn, int type_mask) 621{ 622 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); 623 int o; 624 int index_mask = 0; 625 626 for (o = 0; o < config->num_output; o++) 627 { 628 xf86OutputPtr output = config->output[o]; 629 I830OutputPrivatePtr intel_output = output->driver_private; 630 if (type_mask & (1 << intel_output->type)) 631 index_mask |= (1 << o); 632 } 633 return index_mask; 634} 635 636/** 637 * Set up the outputs according to what type of chip we are. 638 * 639 * Some outputs may not initialize, due to allocation failure or because a 640 * controller chip isn't found. 641 */ 642static void 643I830SetupOutputs(ScrnInfoPtr pScrn) 644{ 645 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); 646 I830Ptr pI830 = I830PTR(pScrn); 647 int o, c; 648 Bool lvds_detected = FALSE; 649 650 /* everyone has at least a single analog output */ 651 i830_crt_init(pScrn); 652 653 /* Set up integrated LVDS */ 654 if (IS_MOBILE(pI830) && !IS_I830(pI830)) 655 i830_lvds_init(pScrn); 656 657 if (IS_I9XX(pI830)) { 658 Bool found = FALSE; 659 if ((INREG(SDVOB) & SDVO_DETECTED)) { 660 found = i830_sdvo_init(pScrn, SDVOB); 661 662 if (!found && SUPPORTS_INTEGRATED_HDMI(pI830)) 663 i830_hdmi_init(pScrn, SDVOB); 664 } 665 666 if ((INREG(SDVOB) & SDVO_DETECTED)) 667 found = i830_sdvo_init(pScrn, SDVOC); 668 669 if ((INREG(SDVOC) & SDVO_DETECTED) && 670 !found && SUPPORTS_INTEGRATED_HDMI(pI830)) 671 i830_hdmi_init(pScrn, SDVOC); 672 673 } else { 674 i830_dvo_init(pScrn); 675 } 676 if (IS_I9XX(pI830) && IS_MOBILE(pI830)) 677 i830_tv_init(pScrn); 678 679 for (o = 0; o < config->num_output; o++) 680 { 681 xf86OutputPtr output = config->output[o]; 682 I830OutputPrivatePtr intel_output = output->driver_private; 683 int crtc_mask; 684 685 if (intel_output->type == I830_OUTPUT_LVDS) 686 lvds_detected = TRUE; 687 688 crtc_mask = 0; 689 for (c = 0; c < config->num_crtc; c++) 690 { 691 xf86CrtcPtr crtc = config->crtc[c]; 692 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 693 694 if (intel_output->pipe_mask & (1 << intel_crtc->pipe)) 695 crtc_mask |= (1 << c); 696 } 697 output->possible_crtcs = crtc_mask; 698 output->possible_clones = i830_output_clones (pScrn, intel_output->clone_mask); 699 } 700} 701 702static void 703i830_init_clock_gating(ScrnInfoPtr pScrn) 704{ 705 I830Ptr pI830 = I830PTR(pScrn); 706 707 /* Disable clock gating reported to work incorrectly according to the specs. 708 */ 709 if (IS_G4X(pI830)) { 710 uint32_t dspclk_gate; 711 OUTREG(RENCLK_GATE_D1, 0); 712 OUTREG(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | 713 GS_UNIT_CLOCK_GATE_DISABLE | 714 CL_UNIT_CLOCK_GATE_DISABLE); 715 OUTREG(RAMCLK_GATE_D, 0); 716 dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | 717 OVRUNIT_CLOCK_GATE_DISABLE | 718 OVCUNIT_CLOCK_GATE_DISABLE; 719 if (IS_GM45(pI830)) 720 dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; 721 OUTREG(DSPCLK_GATE_D, dspclk_gate); 722 } else if (IS_I965GM(pI830)) { 723 OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); 724 OUTREG(RENCLK_GATE_D2, 0); 725 OUTREG(DSPCLK_GATE_D, 0); 726 OUTREG(RAMCLK_GATE_D, 0); 727 OUTREG16(DEUC, 0); 728 } else if (IS_I965G(pI830)) { 729 OUTREG(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | 730 I965_RCC_CLOCK_GATE_DISABLE | 731 I965_RCPB_CLOCK_GATE_DISABLE | 732 I965_ISC_CLOCK_GATE_DISABLE | 733 I965_FBC_CLOCK_GATE_DISABLE); 734 OUTREG(RENCLK_GATE_D2, 0); 735 } else if (IS_I855(pI830) || IS_I865G(pI830)) { 736 OUTREG(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); 737 } else if (IS_I830(pI830)) { 738 OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); 739 } 740} 741 742static void 743i830_init_bios_control(ScrnInfoPtr pScrn) 744{ 745 I830Ptr pI830 = I830PTR(pScrn); 746 747 /* Set "extended desktop" */ 748 OUTREG(SWF0, INREG(SWF0) | (1 << 21)); 749 750 /* Set "driver loaded", "OS unknown", "APM 1.2" */ 751 OUTREG(SWF4, (INREG(SWF4) & ~((3 << 19) | (7 << 16))) | 752 (1 << 23) | (2 << 16)); 753} 754 755static int 756I830LVDSPresent(ScrnInfoPtr pScrn) 757{ 758 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); 759 int o, lvds_detected = FALSE; 760 761 for (o = 0; o < config->num_output; o++) { 762 xf86OutputPtr output = config->output[o]; 763 I830OutputPrivatePtr intel_output = output->driver_private; 764 765 if (intel_output->type == I830_OUTPUT_LVDS) 766 lvds_detected = TRUE; 767 } 768 769 return lvds_detected; 770} 771/** 772 * Setup the CRTCs 773 */ 774 775 776static void 777I830PreInitDDC(ScrnInfoPtr pScrn) 778{ 779 I830Ptr pI830 = I830PTR(pScrn); 780 781 if (!xf86LoadSubModule(pScrn, "ddc")) { 782 pI830->ddc2 = FALSE; 783 } else { 784 pI830->ddc2 = TRUE; 785 } 786 787 /* DDC can use I2C bus */ 788 /* Load I2C if we have the code to use it */ 789 if (pI830->ddc2) { 790 if (xf86LoadSubModule(pScrn, "i2c")) { 791 pI830->ddc2 = TRUE; 792 } else { 793 pI830->ddc2 = FALSE; 794 } 795 } 796} 797 798static void 799PreInitCleanup(ScrnInfoPtr pScrn) 800{ 801 I830Ptr pI830 = I830PTR(pScrn); 802 803 if (pI830->MMIOBase) 804 I830UnmapMMIO(pScrn); 805 I830FreeRec(pScrn); 806} 807 808/* 809 * Adjust *width to allow for tiling if possible 810 */ 811Bool 812i830_tiled_width(I830Ptr i830, int *width, int cpp) 813{ 814 Bool tiled = FALSE; 815 816 /* 817 * Adjust the display width to allow for front buffer tiling if possible 818 */ 819 if (i830->tiling) { 820 if (IS_I965G(i830)) { 821 int tile_pixels = 512 / cpp; 822 *width = (*width + tile_pixels - 1) & 823 ~(tile_pixels - 1); 824 tiled = TRUE; 825 } else { 826 /* Good pitches to allow tiling. Don't care about pitches < 1024 827 * pixels. 828 */ 829 static const int pitches[] = { 830 1024, 831 2048, 832 4096, 833 8192, 834 0 835 }; 836 int i; 837 838 for (i = 0; pitches[i] != 0; i++) { 839 if (pitches[i] >= *width) { 840 *width = pitches[i]; 841 tiled = TRUE; 842 break; 843 } 844 } 845 } 846 } 847 return tiled; 848} 849 850/* 851 * Pad to accelerator requirement 852 */ 853int 854i830_pad_drawable_width(int width, int cpp) 855{ 856 return (width + 63) & ~63; 857} 858 859static Bool 860i830_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) 861{ 862#ifdef DRI2 863 I830Ptr i830 = I830PTR(scrn); 864 int old_width = scrn->displayWidth; 865#endif 866 int old_x = scrn->virtualX; 867 int old_y = scrn->virtualY; 868 869 if (old_x == width && old_y == height) 870 return TRUE; 871 872 scrn->virtualX = width; 873 scrn->virtualY = height; 874#ifdef DRI2 875 if (i830->front_buffer) 876 { 877 i830_memory *new_front, *old_front; 878 Bool tiled; 879 ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; 880 881 scrn->displayWidth = i830_pad_drawable_width(width, i830->cpp); 882 tiled = i830_tiled_width(i830, &scrn->displayWidth, i830->cpp); 883 xf86DrvMsg(scrn->scrnIndex, X_INFO, "Allocate new frame buffer %dx%d stride %d\n", 884 width, height, scrn->displayWidth); 885 I830Sync(scrn); 886 i830WaitForVblank(scrn); 887 new_front = i830_allocate_framebuffer(scrn); 888 if (!new_front) { 889 scrn->virtualX = old_x; 890 scrn->virtualY = old_y; 891 scrn->displayWidth = old_width; 892 return FALSE; 893 } 894 old_front = i830->front_buffer; 895 i830->front_buffer = new_front; 896 i830_set_pixmap_bo(screen->GetScreenPixmap(screen), 897 new_front->bo); 898 scrn->fbOffset = i830->front_buffer->offset; 899 900 screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen), 901 width, height, -1, -1, scrn->displayWidth * i830->cpp, 902 i830->FbBase + scrn->fbOffset); 903 904 xf86DrvMsg(scrn->scrnIndex, X_INFO, "New front buffer at 0x%lx\n", 905 i830->front_buffer->offset); 906 i830_set_new_crtc_bo(scrn); 907 I830Sync(scrn); 908 i830WaitForVblank(scrn); 909 i830_free_memory(scrn, old_front); 910 } 911#endif 912 return TRUE; 913} 914 915static const xf86CrtcConfigFuncsRec i830_xf86crtc_config_funcs = { 916 i830_xf86crtc_resize 917}; 918 919#define HOTKEY_BIOS_SWITCH 0 920#define HOTKEY_DRIVER_NOTIFY 1 921 922/** 923 * Controls the BIOS's behavior on hotkey switch. 924 * 925 * If the mode is HOTKEY_BIOS_SWITCH, the BIOS will be set to do a mode switch 926 * on its own and update the state in the scratch register. 927 * If the mode is HOTKEY_DRIVER_NOTIFY, the BIOS won't do a mode switch and 928 * will just update the state to represent what it would have been switched to. 929 */ 930static void 931i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) 932{ 933 I830Ptr pI830 = I830PTR(pScrn); 934 uint8_t gr18; 935 936 /* Don't mess with kernel settings... */ 937 if (pI830->use_drm_mode) 938 return; 939 940 gr18 = pI830->readControl(pI830, GRX, 0x18); 941 if (mode == HOTKEY_BIOS_SWITCH) 942 gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK; 943 else 944 gr18 |= HOTKEY_VBIOS_SWITCH_BLOCK; 945 pI830->writeControl(pI830, GRX, 0x18, gr18); 946} 947 948/* 949 * DRM mode setting Linux only at this point... later on we could 950 * add a wrapper here. 951 */ 952static Bool i830_kernel_mode_enabled(ScrnInfoPtr pScrn) 953{ 954 struct pci_device *PciInfo; 955 EntityInfoPtr pEnt; 956 char *busIdString; 957 int ret; 958 959 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 960 PciInfo = xf86GetPciInfoForEntity(pEnt->index); 961 962 if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) 963 return FALSE; 964 965 busIdString = DRICreatePCIBusID(PciInfo); 966 967 ret = drmCheckModesettingSupported(busIdString); 968 if (ret) { 969 if (xf86LoadKernelModule("i915")) 970 ret = drmCheckModesettingSupported(busIdString); 971 } 972 /* Be nice to the user and load fbcon too */ 973 if (!ret) 974 (void) xf86LoadKernelModule("fbcon"); 975 xfree(busIdString); 976 if (ret) 977 return FALSE; 978 979 return TRUE; 980} 981 982static Bool 983i830_detect_chipset(ScrnInfoPtr pScrn) 984{ 985 I830Ptr pI830 = I830PTR(pScrn); 986 MessageType from = X_PROBED; 987 const char *chipname; 988 uint32_t capid; 989 int fb_bar, mmio_bar; 990 991 992 /* We have to use PIO to probe, because we haven't mapped yet. */ 993 if (!pI830->use_drm_mode) 994 I830SetPIOAccess(pI830); 995 996 switch (DEVICE_ID(pI830->PciInfo)) { 997 case PCI_CHIP_I830_M: 998 chipname = "830M"; 999 break; 1000 case PCI_CHIP_845_G: 1001 chipname = "845G"; 1002 break; 1003 case PCI_CHIP_I855_GM: 1004 /* Check capid register to find the chipset variant */ 1005 pci_device_cfg_read_u32 (pI830->PciInfo, &capid, I85X_CAPID); 1006 pI830->variant = (capid >> I85X_VARIANT_SHIFT) & I85X_VARIANT_MASK; 1007 switch (pI830->variant) { 1008 case I855_GM: 1009 chipname = "855GM"; 1010 break; 1011 case I855_GME: 1012 chipname = "855GME"; 1013 break; 1014 case I852_GM: 1015 chipname = "852GM"; 1016 break; 1017 case I852_GME: 1018 chipname = "852GME"; 1019 break; 1020 default: 1021 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1022 "Unknown 852GM/855GM variant: 0x%x)\n", pI830->variant); 1023 chipname = "852GM/855GM (unknown variant)"; 1024 break; 1025 } 1026 break; 1027 case PCI_CHIP_I865_G: 1028 chipname = "865G"; 1029 break; 1030 case PCI_CHIP_I915_G: 1031 chipname = "915G"; 1032 break; 1033 case PCI_CHIP_E7221_G: 1034 chipname = "E7221 (i915)"; 1035 break; 1036 case PCI_CHIP_I915_GM: 1037 chipname = "915GM"; 1038 break; 1039 case PCI_CHIP_I945_G: 1040 chipname = "945G"; 1041 break; 1042 case PCI_CHIP_I945_GM: 1043 chipname = "945GM"; 1044 break; 1045 case PCI_CHIP_I945_GME: 1046 chipname = "945GME"; 1047 break; 1048 case PCI_CHIP_IGD_GM: 1049 chipname = "Pineview GM"; 1050 break; 1051 case PCI_CHIP_IGD_G: 1052 chipname = "Pineview G"; 1053 break; 1054 case PCI_CHIP_I965_G: 1055 chipname = "965G"; 1056 break; 1057 case PCI_CHIP_G35_G: 1058 chipname = "G35"; 1059 break; 1060 case PCI_CHIP_I965_Q: 1061 chipname = "965Q"; 1062 break; 1063 case PCI_CHIP_I946_GZ: 1064 chipname = "946GZ"; 1065 break; 1066 case PCI_CHIP_I965_GM: 1067 chipname = "965GM"; 1068 break; 1069 case PCI_CHIP_I965_GME: 1070 chipname = "965GME/GLE"; 1071 break; 1072 case PCI_CHIP_G33_G: 1073 chipname = "G33"; 1074 break; 1075 case PCI_CHIP_Q35_G: 1076 chipname = "Q35"; 1077 break; 1078 case PCI_CHIP_Q33_G: 1079 chipname = "Q33"; 1080 break; 1081 case PCI_CHIP_GM45_GM: 1082 chipname = "GM45"; 1083 break; 1084 case PCI_CHIP_IGD_E_G: 1085 chipname = "4 Series"; 1086 break; 1087 case PCI_CHIP_G45_G: 1088 chipname = "G45/G43"; 1089 break; 1090 case PCI_CHIP_Q45_G: 1091 chipname = "Q45/Q43"; 1092 break; 1093 case PCI_CHIP_G41_G: 1094 chipname = "G41"; 1095 break; 1096 case PCI_CHIP_B43_G: 1097 chipname = "B43"; 1098 break; 1099 case PCI_CHIP_IGDNG_D_G: 1100 chipname = "Clarkdale"; 1101 break; 1102 case PCI_CHIP_IGDNG_M_G: 1103 chipname = "Arrandale"; 1104 break; 1105 default: 1106 chipname = "unknown chipset"; 1107 break; 1108 } 1109 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1110 "Integrated Graphics Chipset: Intel(R) %s\n", chipname); 1111 1112 /* Set the Chipset and ChipRev, allowing config file entries to override. */ 1113 if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) { 1114 pScrn->chipset = pI830->pEnt->device->chipset; 1115 from = X_CONFIG; 1116 } else if (pI830->pEnt->device->chipID >= 0) { 1117 pScrn->chipset = (char *)xf86TokenToString(I830Chipsets, 1118 pI830->pEnt->device->chipID); 1119 from = X_CONFIG; 1120 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 1121 pI830->pEnt->device->chipID); 1122 DEVICE_ID(pI830->PciInfo) = pI830->pEnt->device->chipID; 1123 } else { 1124 from = X_PROBED; 1125 pScrn->chipset = (char *)xf86TokenToString(I830Chipsets, 1126 DEVICE_ID(pI830->PciInfo)); 1127 } 1128 1129 if (pI830->pEnt->device->chipRev >= 0) { 1130 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 1131 pI830->pEnt->device->chipRev); 1132 } 1133 1134 xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", 1135 (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx"); 1136 1137 /* Check if the HW cursor needs physical address. */ 1138 if (IS_MOBILE(pI830) || IS_I9XX(pI830)) 1139 pI830->CursorNeedsPhysical = TRUE; 1140 else 1141 pI830->CursorNeedsPhysical = FALSE; 1142 1143 if (IS_I965G(pI830) || IS_G33CLASS(pI830)) 1144 pI830->CursorNeedsPhysical = FALSE; 1145 1146 /* Skip the rest if the kernel is taking care of things */ 1147 if (pI830->use_drm_mode) 1148 return TRUE; 1149 1150 /* Now that we know the chipset, figure out the resource base addrs */ 1151 if (IS_I9XX(pI830)) { 1152 fb_bar = 2; 1153 mmio_bar = 0; 1154 } else { 1155 fb_bar = 0; 1156 mmio_bar = 1; 1157 } 1158 1159 if (pI830->pEnt->device->MemBase != 0) { 1160 pI830->LinearAddr = pI830->pEnt->device->MemBase; 1161 from = X_CONFIG; 1162 } else { 1163 pI830->LinearAddr = I810_MEMBASE (pI830->PciInfo, fb_bar); 1164 if (pI830->LinearAddr == 0) { 1165 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1166 "No valid FB address in PCI config space\n"); 1167 PreInitCleanup(pScrn); 1168 return FALSE; 1169 } 1170 } 1171 1172 xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", 1173 (unsigned long)pI830->LinearAddr); 1174 1175 if (pI830->pEnt->device->IOBase != 0) { 1176 pI830->MMIOAddr = pI830->pEnt->device->IOBase; 1177 from = X_CONFIG; 1178 pI830->MMIOSize = I810_REG_SIZE; 1179 } else { 1180 pI830->MMIOAddr = I810_MEMBASE (pI830->PciInfo, mmio_bar); 1181 if (pI830->MMIOAddr == 0) { 1182 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1183 "No valid MMIO address in PCI config space\n"); 1184 PreInitCleanup(pScrn); 1185 return FALSE; 1186 } 1187 pI830->MMIOSize = pI830->PciInfo->regions[mmio_bar].size; 1188 } 1189 1190 xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX size %u\n", 1191 (unsigned long)pI830->MMIOAddr, pI830->MMIOSize); 1192 1193 /* Now figure out mapsize on 8xx chips */ 1194 if (IS_I830(pI830) || IS_845G(pI830)) { 1195 uint16_t gmch_ctrl; 1196 struct pci_device *bridge; 1197 1198 bridge = intel_host_bridge (); 1199 pci_device_cfg_read_u16 (bridge, &gmch_ctrl, I830_GMCH_CTRL); 1200 if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { 1201 pI830->FbMapSize = 0x8000000; 1202 } else { 1203 pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */ 1204 } 1205 } else { 1206 if (IS_I9XX(pI830)) { 1207 pI830->FbMapSize = pI830->PciInfo->regions[fb_bar].size; 1208 } else { 1209 /* 128MB aperture for later i8xx series. */ 1210 pI830->FbMapSize = 0x8000000; 1211 } 1212 } 1213 1214 return TRUE; 1215} 1216 1217static Bool 1218I830LoadSyms(ScrnInfoPtr pScrn) 1219{ 1220 I830Ptr pI830 = I830PTR(pScrn); 1221 1222 if (pI830->use_drm_mode) 1223 return TRUE; 1224 1225 /* The vgahw module should be loaded here when needed */ 1226 if (!xf86LoadSubModule(pScrn, "vgahw")) 1227 return FALSE; 1228 1229 if (!xf86LoadSubModule(pScrn, "ramdac")) 1230 return FALSE; 1231 1232 return TRUE; 1233} 1234 1235static Bool 1236I830GetEarlyOptions(ScrnInfoPtr pScrn) 1237{ 1238 I830Ptr pI830 = I830PTR(pScrn); 1239 1240 /* Process the options */ 1241 xf86CollectOptions(pScrn, NULL); 1242 if (!(pI830->Options = xalloc(sizeof(I830Options)))) 1243 return FALSE; 1244 memcpy(pI830->Options, I830Options, sizeof(I830Options)); 1245 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options); 1246 1247 pI830->fallback_debug = xf86ReturnOptValBool(pI830->Options, 1248 OPTION_FALLBACKDEBUG, FALSE); 1249 1250 if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) { 1251 pI830->debug_modes = TRUE; 1252 } else { 1253 pI830->debug_modes = FALSE; 1254 } 1255 1256 if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) { 1257 pI830->lvds_24_bit_mode = TRUE; 1258 } else { 1259 pI830->lvds_24_bit_mode = FALSE; 1260 } 1261 1262 if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) { 1263 pI830->skip_panel_detect = FALSE; 1264 } else { 1265 pI830->skip_panel_detect = TRUE; 1266 } 1267 1268 if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) 1269 pI830->quirk_flag |= QUIRK_PIPEA_FORCE; 1270 1271 return TRUE; 1272} 1273 1274static void 1275I830PreInitCrtcConfig(ScrnInfoPtr pScrn) 1276{ 1277 xf86CrtcConfigPtr xf86_config; 1278 I830Ptr pI830 = I830PTR(pScrn); 1279 int max_width, max_height; 1280 1281 /* check quirks */ 1282 i830_fixup_devices(pScrn); 1283 1284 /* Allocate an xf86CrtcConfig */ 1285 xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); 1286 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1287 1288 /* See i830_exa.c comments for why we limit the framebuffer size like this. 1289 */ 1290 if (IS_I965G(pI830)) { 1291 max_height = max_width = min(16384 / pI830->cpp, 8192); 1292 } else { 1293 max_width = 2048; 1294 max_height = 2048; 1295 } 1296 xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height); 1297} 1298 1299static void 1300i830_check_dri_option(ScrnInfoPtr pScrn) 1301{ 1302 I830Ptr pI830 = I830PTR(pScrn); 1303 pI830->directRenderingType = DRI_NONE; 1304 if (!xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE)) 1305 pI830->directRenderingType = DRI_DISABLED; 1306 1307 if (pScrn->depth != 16 && pScrn->depth != 24) { 1308 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " 1309 "runs only at depths 16 and 24.\n"); 1310 pI830->directRenderingType = DRI_DISABLED; 1311 } 1312} 1313 1314static Bool 1315i830_user_modesetting_init(ScrnInfoPtr pScrn) 1316{ 1317 I830Ptr pI830 = I830PTR(pScrn); 1318 int i, num_pipe; 1319 1320 I830MapMMIO(pScrn); 1321 1322 if (pI830->debug_modes) { 1323 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1324 "Hardware state on X startup:\n"); 1325 i830DumpRegs (pScrn); 1326 } 1327 1328 i830TakeRegSnapshot(pScrn); 1329 1330 if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G) 1331 num_pipe = 1; 1332 else 1333 if (IS_MOBILE(pI830) || IS_I9XX(pI830)) 1334 num_pipe = 2; 1335 else 1336 num_pipe = 1; 1337 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", 1338 num_pipe, num_pipe > 1 ? "s" : ""); 1339 1340 I830PreInitDDC(pScrn); 1341 for (i = 0; i < num_pipe; i++) { 1342 i830_crtc_init(pScrn, i); 1343 } 1344 I830SetupOutputs(pScrn); 1345 1346 SaveHWState(pScrn); 1347 1348 if (!xf86InitialConfiguration (pScrn, TRUE)) 1349 { 1350 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); 1351 RestoreHWState(pScrn); 1352 PreInitCleanup(pScrn); 1353 return FALSE; 1354 } 1355 RestoreHWState(pScrn); 1356 1357 pI830->stolen_size = I830DetectMemory(pScrn); 1358 1359 return TRUE; 1360} 1361 1362static Bool 1363i830_open_drm_master(ScrnInfoPtr scrn) 1364{ 1365 I830Ptr i830 = I830PTR(scrn); 1366 struct pci_device *dev = i830->PciInfo; 1367 char *busid; 1368 drmSetVersion sv; 1369 struct drm_i915_getparam gp; 1370 int err, has_gem; 1371 1372 /* We wish we had asprintf, but all we get is XNFprintf. */ 1373 busid = XNFprintf("pci:%04x:%02x:%02x.%d", 1374 dev->domain, dev->bus, dev->dev, dev->func); 1375 1376 i830->drmSubFD = drmOpen("i915", busid); 1377 if (i830->drmSubFD == -1) { 1378 xfree(busid); 1379 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 1380 "[drm] Failed to open DRM device for %s: %s\n", busid, 1381 strerror(errno)); 1382 return FALSE; 1383 } 1384 1385 xfree(busid); 1386 1387 /* Check that what we opened was a master or a master-capable FD, 1388 * by setting the version of the interface we'll use to talk to it. 1389 * (see DRIOpenDRMMaster() in DRI1) 1390 */ 1391 sv.drm_di_major = 1; 1392 sv.drm_di_minor = 1; 1393 sv.drm_dd_major = -1; 1394 sv.drm_dd_minor = -1; 1395 err = drmSetInterfaceVersion(i830->drmSubFD, &sv); 1396 if (err != 0) { 1397 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 1398 "[drm] failed to set drm interface version.\n"); 1399 drmClose(i830->drmSubFD); 1400 i830->drmSubFD = -1; 1401 return FALSE; 1402 } 1403 1404 has_gem = FALSE; 1405 gp.param = I915_PARAM_HAS_GEM; 1406 gp.value = &has_gem; 1407 (void)drmCommandWriteRead(i830->drmSubFD, DRM_I915_GETPARAM, 1408 &gp, sizeof(gp)); 1409 if (!has_gem) { 1410 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 1411 "[drm] Failed to detect GEM. Kernel 2.6.28 required.\n"); 1412 drmClose(i830->drmSubFD); 1413 i830->drmSubFD = -1; 1414 return FALSE; 1415 } 1416 1417 return TRUE; 1418} 1419 1420static void 1421i830_close_drm_master(ScrnInfoPtr scrn) 1422{ 1423 I830Ptr i830 = I830PTR(scrn); 1424 if (i830 && i830->drmSubFD > 0) { 1425 drmClose(i830->drmSubFD); 1426 i830->drmSubFD = -1; 1427 } 1428} 1429 1430static Bool 1431I830DrmModeInit(ScrnInfoPtr pScrn) 1432{ 1433 I830Ptr pI830 = I830PTR(pScrn); 1434 1435 if (drmmode_pre_init(pScrn, pI830->drmSubFD, pI830->cpp) == FALSE) { 1436 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1437 "Kernel modesetting setup failed\n"); 1438 PreInitCleanup(pScrn); 1439 return FALSE; 1440 } 1441 1442 pI830->have_gem = TRUE; 1443 1444 i830_init_bufmgr(pScrn); 1445 1446 return TRUE; 1447} 1448 1449static void 1450I830XvInit(ScrnInfoPtr pScrn) 1451{ 1452 I830Ptr pI830 = I830PTR(pScrn); 1453 MessageType from = X_PROBED; 1454 1455 pI830->XvPreferOverlay = xf86ReturnOptValBool(pI830->Options, OPTION_PREFER_OVERLAY, FALSE); 1456 1457 if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY, 1458 &(pI830->colorKey))) { 1459 from = X_CONFIG; 1460 } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY, 1461 &(pI830->colorKey))) { 1462 from = X_CONFIG; 1463 } else { 1464 pI830->colorKey = 1465 (1 << pScrn->offset.red) | (1 << pScrn->offset.green) | 1466 (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << 1467 pScrn->offset.blue); 1468 from = X_DEFAULT; 1469 } 1470 xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n", 1471 pI830->colorKey); 1472} 1473 1474/** 1475 * This is called before ScreenInit to do any require probing of screen 1476 * configuration. 1477 * 1478 * This code generally covers probing, module loading, option handling 1479 * card mapping, and RandR setup. 1480 * 1481 * Since xf86InitialConfiguration ends up requiring that we set video modes 1482 * in order to detect configuration, we end up having to do a lot of driver 1483 * setup (talking to the DRM, mapping the device, etc.) in this function. 1484 * As a result, we want to set up that server initialization once rather 1485 * that doing it per generation. 1486 */ 1487static Bool 1488I830PreInit(ScrnInfoPtr pScrn, int flags) 1489{ 1490 vgaHWPtr hwp; 1491 I830Ptr pI830; 1492 rgb defaultWeight = { 0, 0, 0 }; 1493 EntityInfoPtr pEnt; 1494 int flags24; 1495 Gamma zeros = { 0.0, 0.0, 0.0 }; 1496 int drm_mode_setting; 1497 1498 if (pScrn->numEntities != 1) 1499 return FALSE; 1500 1501 drm_mode_setting = i830_kernel_mode_enabled(pScrn); 1502 1503 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 1504 1505 if (flags & PROBE_DETECT) 1506 return TRUE; 1507 1508 /* Allocate driverPrivate */ 1509 if (!I830GetRec(pScrn)) 1510 return FALSE; 1511 1512 pI830 = I830PTR(pScrn); 1513 pI830->SaveGeneration = -1; 1514 pI830->pEnt = pEnt; 1515 pI830->use_drm_mode = drm_mode_setting; 1516 pI830->kernel_exec_fencing = pI830->use_drm_mode; 1517 1518 if (!I830LoadSyms(pScrn)) 1519 return FALSE; 1520 1521 if (!drm_mode_setting) { 1522 /* Allocate a vgaHWRec */ 1523 if (!vgaHWGetHWRec(pScrn)) 1524 return FALSE; 1525 hwp = VGAHWPTR(pScrn); 1526 } 1527 1528 pScrn->displayWidth = 640; /* default it */ 1529 1530 if (pI830->pEnt->location.type != BUS_PCI) 1531 return FALSE; 1532 1533 pI830->PciInfo = xf86GetPciInfoForEntity(pI830->pEnt->index); 1534 1535 if (!i830_open_drm_master(pScrn)) 1536 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to become DRM master.\n"); 1537 1538 pScrn->monitor = pScrn->confScreen->monitor; 1539 pScrn->progClock = TRUE; 1540 pScrn->rgbBits = 8; 1541 1542 flags24 = Support32bppFb | PreferConvert24to32 | SupportConvert24to32; 1543 1544 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) 1545 return FALSE; 1546 1547 switch (pScrn->depth) { 1548 case 8: 1549 case 15: 1550 case 16: 1551 case 24: 1552 break; 1553 default: 1554 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1555 "Given depth (%d) is not supported by I830 driver\n", 1556 pScrn->depth); 1557 return FALSE; 1558 } 1559 xf86PrintDepthBpp(pScrn); 1560 1561 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) 1562 return FALSE; 1563 if (!xf86SetDefaultVisual(pScrn, -1)) 1564 return FALSE; 1565 1566 if (!pI830->use_drm_mode) 1567 hwp = VGAHWPTR(pScrn); 1568 1569 pI830->cpp = pScrn->bitsPerPixel / 8; 1570 1571 pI830->preinit = TRUE; 1572 1573 if (!I830GetEarlyOptions(pScrn)) 1574 return FALSE; 1575 1576 if (!i830_detect_chipset(pScrn)) 1577 return FALSE; 1578 1579 i830_check_dri_option(pScrn); 1580 1581 if (pI830->use_drm_mode) { 1582 if (!I830DrmModeInit(pScrn)) 1583 return FALSE; 1584 } else { 1585 if (i830_bios_init(pScrn)) 1586 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1587 "VBIOS initialization failed.\n"); 1588 I830PreInitCrtcConfig(pScrn); 1589 if (!i830_user_modesetting_init(pScrn)) 1590 return FALSE; 1591 } 1592 1593 I830XvInit(pScrn); 1594 1595 if (!xf86SetGamma(pScrn, zeros)) { 1596 PreInitCleanup(pScrn); 1597 return FALSE; 1598 } 1599 1600 if (pScrn->modes == NULL) { 1601 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); 1602 PreInitCleanup(pScrn); 1603 return FALSE; 1604 } 1605 pScrn->currentMode = pScrn->modes; 1606 1607 /* Set display resolution */ 1608 xf86SetDpi(pScrn, 0, 0); 1609 1610 /* Load the required sub modules */ 1611 if (!xf86LoadSubModule(pScrn, "fb")) { 1612 PreInitCleanup(pScrn); 1613 return FALSE; 1614 } 1615 1616 if (!pI830->use_drm_mode) { 1617 i830CompareRegsToSnapshot(pScrn, "After PreInit"); 1618 1619 I830UnmapMMIO(pScrn); 1620 1621 /* We won't be using the VGA access after the probe. */ 1622 I830SetMMIOAccess(pI830); 1623 } 1624 1625 /* Load the dri2 module if requested. */ 1626 if (xf86ReturnOptValBool(pI830->Options, OPTION_DRI, FALSE) && 1627 pI830->directRenderingType != DRI_DISABLED) { 1628 xf86LoadSubModule(pScrn, "dri2"); 1629 } 1630 1631 pI830->preinit = FALSE; 1632 1633 return TRUE; 1634} 1635 1636/* 1637 * Reset registers that it doesn't make sense to save/restore to a sane state. 1638 * This is basically the ring buffer and fence registers. Restoring these 1639 * doesn't make sense without restoring GTT mappings. This is something that 1640 * whoever gets control next should do. 1641 */ 1642static void 1643i830_stop_ring(ScrnInfoPtr pScrn, Bool flush) 1644{ 1645 I830Ptr pI830 = I830PTR(pScrn); 1646 unsigned long temp; 1647 1648 DPRINTF(PFX, "ResetState: flush is %s\n", BOOLTOSTRING(flush)); 1649 1650 /* Flush the ring buffer, then disable it. */ 1651 temp = INREG(LP_RING + RING_LEN); 1652 if (temp & RING_VALID) { 1653 i830_refresh_ring(pScrn); 1654 i830_wait_ring_idle(pScrn); 1655 } 1656 1657 OUTREG(LP_RING + RING_LEN, 0); 1658 OUTREG(LP_RING + RING_HEAD, 0); 1659 OUTREG(LP_RING + RING_TAIL, 0); 1660 OUTREG(LP_RING + RING_START, 0); 1661} 1662 1663static void 1664i830_start_ring(ScrnInfoPtr pScrn) 1665{ 1666 I830Ptr pI830 = I830PTR(pScrn); 1667 unsigned int itemp; 1668 1669 DPRINTF(PFX, "SetRingRegs\n"); 1670 1671 OUTREG(LP_RING + RING_LEN, 0); 1672 OUTREG(LP_RING + RING_TAIL, 0); 1673 OUTREG(LP_RING + RING_HEAD, 0); 1674 1675 assert((pI830->ring.mem->offset & I830_RING_START_MASK) == 1676 pI830->ring.mem->offset); 1677 1678 /* Don't care about the old value. Reserved bits must be zero anyway. */ 1679 itemp = pI830->ring.mem->offset; 1680 OUTREG(LP_RING + RING_START, itemp); 1681 1682 if (((pI830->ring.mem->size - 4096) & I830_RING_NR_PAGES) != 1683 pI830->ring.mem->size - 4096) { 1684 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1685 "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " 1686 "mask (%x)\n", pI830->ring.mem->size - 4096, 1687 I830_RING_NR_PAGES); 1688 } 1689 /* Don't care about the old value. Reserved bits must be zero anyway. */ 1690 itemp = (pI830->ring.mem->size - 4096) & I830_RING_NR_PAGES; 1691 itemp |= (RING_NO_REPORT | RING_VALID); 1692 OUTREG(LP_RING + RING_LEN, itemp); 1693 i830_refresh_ring(pScrn); 1694} 1695 1696void 1697i830_refresh_ring(ScrnInfoPtr pScrn) 1698{ 1699 I830Ptr pI830 = I830PTR(pScrn); 1700 1701 /* If we're reaching RefreshRing as a result of grabbing the DRI lock 1702 * before we've set up the ringbuffer, don't bother. 1703 */ 1704 if (pI830->ring.mem == NULL) 1705 return; 1706 1707 pI830->ring.head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; 1708 pI830->ring.tail = INREG(LP_RING + RING_TAIL); 1709 pI830->ring.space = pI830->ring.head - (pI830->ring.tail + 8); 1710 if (pI830->ring.space < 0) 1711 pI830->ring.space += pI830->ring.mem->size; 1712} 1713 1714enum pipe { 1715 PIPE_A = 0, 1716 PIPE_B, 1717}; 1718 1719static Bool 1720i830_pipe_enabled(I830Ptr pI830, enum pipe pipe) 1721{ 1722 if (pipe == PIPE_A) 1723 return (INREG(PIPEACONF) & PIPEACONF_ENABLE); 1724 else 1725 return (INREG(PIPEBCONF) & PIPEBCONF_ENABLE); 1726} 1727 1728static void 1729i830_save_palette(I830Ptr pI830, enum pipe pipe) 1730{ 1731 int i; 1732 1733 if (!i830_pipe_enabled(pI830, pipe)) 1734 return; 1735 1736 for(i= 0; i < 256; i++) { 1737 if (pipe == PIPE_A) 1738 pI830->savePaletteA[i] = INREG(PALETTE_A + (i << 2)); 1739 else 1740 pI830->savePaletteB[i] = INREG(PALETTE_B + (i << 2)); 1741 } 1742} 1743 1744static void 1745i830_restore_palette(I830Ptr pI830, enum pipe pipe) 1746{ 1747 int i; 1748 1749 if (!i830_pipe_enabled(pI830, pipe)) 1750 return; 1751 1752 for(i= 0; i < 256; i++) { 1753 if (pipe == PIPE_A) 1754 OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]); 1755 else 1756 OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]); 1757 } 1758} 1759 1760static Bool 1761SaveHWState(ScrnInfoPtr pScrn) 1762{ 1763 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1764 I830Ptr pI830 = I830PTR(pScrn); 1765 vgaHWPtr hwp = VGAHWPTR(pScrn); 1766 vgaRegPtr vgaReg = &hwp->SavedReg; 1767 int i; 1768 1769 if (pI830->fb_compression) { 1770 pI830->saveFBC_CFB_BASE = INREG(FBC_CFB_BASE); 1771 pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE); 1772 pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2); 1773 pI830->saveFBC_CONTROL = INREG(FBC_CONTROL); 1774 pI830->saveFBC_FENCE_OFF = INREG(FBC_FENCE_OFF); 1775 } 1776 1777 /* Save video mode information for native mode-setting. */ 1778 if (!DSPARB_HWCONTROL(pI830)) 1779 pI830->saveDSPARB = INREG(DSPARB); 1780 1781 pI830->saveDSPACNTR = INREG(DSPACNTR); 1782 pI830->savePIPEACONF = INREG(PIPEACONF); 1783 pI830->savePIPEASRC = INREG(PIPEASRC); 1784 pI830->saveFPA0 = INREG(FPA0); 1785 pI830->saveFPA1 = INREG(FPA1); 1786 pI830->saveDPLL_A = INREG(DPLL_A); 1787 if (IS_I965G(pI830)) 1788 pI830->saveDPLL_A_MD = INREG(DPLL_A_MD); 1789 pI830->saveHTOTAL_A = INREG(HTOTAL_A); 1790 pI830->saveHBLANK_A = INREG(HBLANK_A); 1791 pI830->saveHSYNC_A = INREG(HSYNC_A); 1792 pI830->saveVTOTAL_A = INREG(VTOTAL_A); 1793 pI830->saveVBLANK_A = INREG(VBLANK_A); 1794 pI830->saveVSYNC_A = INREG(VSYNC_A); 1795 pI830->saveBCLRPAT_A = INREG(BCLRPAT_A); 1796 pI830->saveDSPASTRIDE = INREG(DSPASTRIDE); 1797 pI830->saveDSPASIZE = INREG(DSPASIZE); 1798 pI830->saveDSPAPOS = INREG(DSPAPOS); 1799 pI830->saveDSPABASE = INREG(DSPABASE); 1800 1801 i830_save_palette(pI830, PIPE_A); 1802 1803 if(xf86_config->num_crtc == 2) { 1804 pI830->savePIPEBCONF = INREG(PIPEBCONF); 1805 pI830->savePIPEBSRC = INREG(PIPEBSRC); 1806 pI830->saveDSPBCNTR = INREG(DSPBCNTR); 1807 pI830->saveFPB0 = INREG(FPB0); 1808 pI830->saveFPB1 = INREG(FPB1); 1809 pI830->saveDPLL_B = INREG(DPLL_B); 1810 if (IS_I965G(pI830)) 1811 pI830->saveDPLL_B_MD = INREG(DPLL_B_MD); 1812 pI830->saveHTOTAL_B = INREG(HTOTAL_B); 1813 pI830->saveHBLANK_B = INREG(HBLANK_B); 1814 pI830->saveHSYNC_B = INREG(HSYNC_B); 1815 pI830->saveVTOTAL_B = INREG(VTOTAL_B); 1816 pI830->saveVBLANK_B = INREG(VBLANK_B); 1817 pI830->saveVSYNC_B = INREG(VSYNC_B); 1818 pI830->saveBCLRPAT_B = INREG(BCLRPAT_B); 1819 pI830->saveDSPBSTRIDE = INREG(DSPBSTRIDE); 1820 pI830->saveDSPBSIZE = INREG(DSPBSIZE); 1821 pI830->saveDSPBPOS = INREG(DSPBPOS); 1822 pI830->saveDSPBBASE = INREG(DSPBBASE); 1823 1824 i830_save_palette(pI830, PIPE_B); 1825 } 1826 1827 if (IS_I965G(pI830)) { 1828 pI830->saveDSPASURF = INREG(DSPASURF); 1829 pI830->saveDSPBSURF = INREG(DSPBSURF); 1830 pI830->saveDSPATILEOFF = INREG(DSPATILEOFF); 1831 pI830->saveDSPBTILEOFF = INREG(DSPBTILEOFF); 1832 } 1833 1834 pI830->saveVCLK_DIVISOR_VGA0 = INREG(VCLK_DIVISOR_VGA0); 1835 pI830->saveVCLK_DIVISOR_VGA1 = INREG(VCLK_DIVISOR_VGA1); 1836 pI830->saveVCLK_POST_DIV = INREG(VCLK_POST_DIV); 1837 pI830->saveVGACNTRL = INREG(VGACNTRL); 1838 1839 pI830->saveCURSOR_A_CONTROL = INREG(CURSOR_A_CONTROL); 1840 pI830->saveCURSOR_A_POSITION = INREG(CURSOR_A_POSITION); 1841 pI830->saveCURSOR_A_BASE = INREG(CURSOR_A_BASE); 1842 pI830->saveCURSOR_B_CONTROL = INREG(CURSOR_B_CONTROL); 1843 pI830->saveCURSOR_B_POSITION = INREG(CURSOR_B_POSITION); 1844 pI830->saveCURSOR_B_BASE = INREG(CURSOR_B_BASE); 1845 1846 for(i = 0; i < 7; i++) { 1847 pI830->saveSWF[i] = INREG(SWF0 + (i << 2)); 1848 pI830->saveSWF[i+7] = INREG(SWF00 + (i << 2)); 1849 } 1850 pI830->saveSWF[14] = INREG(SWF30); 1851 pI830->saveSWF[15] = INREG(SWF31); 1852 pI830->saveSWF[16] = INREG(SWF32); 1853 1854 pI830->saveDSPCLK_GATE_D = INREG(DSPCLK_GATE_D); 1855 pI830->saveRENCLK_GATE_D1 = INREG(RENCLK_GATE_D1); 1856 1857 if (IS_I965G(pI830)) { 1858 pI830->saveRENCLK_GATE_D2 = INREG(RENCLK_GATE_D2); 1859 pI830->saveRAMCLK_GATE_D = INREG(RAMCLK_GATE_D); 1860 } 1861 1862 if (IS_I965GM(pI830) || IS_GM45(pI830)) 1863 pI830->savePWRCTXA = INREG(PWRCTXA); 1864 1865 if (IS_MOBILE(pI830) && !IS_I830(pI830)) 1866 pI830->saveLVDS = INREG(LVDS); 1867 pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL); 1868 1869 for (i = 0; i < xf86_config->num_output; i++) { 1870 xf86OutputPtr output = xf86_config->output[i]; 1871 if (output->funcs->save) 1872 (*output->funcs->save) (output); 1873 } 1874 1875 vgaHWUnlock(hwp); 1876 vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS); 1877 1878 return TRUE; 1879} 1880 1881/* Wait for the PLL to settle down after programming */ 1882static void 1883i830_dpll_settle(void) 1884{ 1885 usleep(10000); /* 10 ms *should* be plenty */ 1886} 1887 1888static Bool 1889RestoreHWState(ScrnInfoPtr pScrn) 1890{ 1891 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1892 I830Ptr pI830 = I830PTR(pScrn); 1893 vgaHWPtr hwp = VGAHWPTR(pScrn); 1894 vgaRegPtr vgaReg = &hwp->SavedReg; 1895 int i; 1896 1897 DPRINTF(PFX, "RestoreHWState\n"); 1898 1899 /* Disable outputs */ 1900 for (i = 0; i < xf86_config->num_output; i++) { 1901 xf86OutputPtr output = xf86_config->output[i]; 1902 output->funcs->dpms(output, DPMSModeOff); 1903 } 1904 i830WaitForVblank(pScrn); 1905 1906 /* Disable pipes */ 1907 for (i = 0; i < xf86_config->num_crtc; i++) { 1908 xf86CrtcPtr crtc = xf86_config->crtc[i]; 1909 i830_crtc_disable(crtc, TRUE); 1910 } 1911 i830WaitForVblank(pScrn); 1912 1913 if (IS_MOBILE(pI830) && !IS_I830(pI830)) 1914 OUTREG(LVDS, pI830->saveLVDS); 1915 1916 if (!IS_I830(pI830) && !IS_845G(pI830)) 1917 OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL); 1918 1919 if (!DSPARB_HWCONTROL(pI830)) 1920 OUTREG(DSPARB, pI830->saveDSPARB); 1921 1922 OUTREG(DSPCLK_GATE_D, pI830->saveDSPCLK_GATE_D); 1923 OUTREG(RENCLK_GATE_D1, pI830->saveRENCLK_GATE_D1); 1924 1925 if (IS_I965G(pI830)) { 1926 OUTREG(RENCLK_GATE_D2, pI830->saveRENCLK_GATE_D2); 1927 OUTREG(RAMCLK_GATE_D, pI830->saveRAMCLK_GATE_D); 1928 } 1929 1930 if (IS_I965GM(pI830) || IS_GM45(pI830)) 1931 OUTREG(PWRCTXA, pI830->savePWRCTXA); 1932 1933 /* 1934 * Pipe regs 1935 * To restore the saved state, we first need to program the PLL regs, 1936 * followed by the pipe configuration and finally the display plane 1937 * configuration. The VGA registers can program one, both or neither 1938 * of the PLL regs, depending on their VGA_MOD_DIS bit value. 1939 */ 1940 1941 /* 1942 * Since either or both pipes may use the VGA clocks, make sure the 1943 * regs are valid. 1944 */ 1945 OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0); 1946 OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1); 1947 OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV); 1948 1949 /* If the pipe A PLL is active, we can restore the pipe & plane config */ 1950 if (pI830->saveDPLL_A & DPLL_VCO_ENABLE) 1951 { 1952 OUTREG(FPA0, pI830->saveFPA0); 1953 OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE); 1954 POSTING_READ(DPLL_A); 1955 usleep(150); 1956 } 1957 OUTREG(FPA0, pI830->saveFPA0); 1958 OUTREG(FPA1, pI830->saveFPA1); 1959 OUTREG(DPLL_A, pI830->saveDPLL_A); 1960 POSTING_READ(DPLL_A); 1961 i830_dpll_settle(); 1962 if (IS_I965G(pI830)) 1963 OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD); 1964 else 1965 OUTREG(DPLL_A, pI830->saveDPLL_A); 1966 POSTING_READ(DPLL_A); 1967 i830_dpll_settle(); 1968 1969 /* Restore mode config */ 1970 OUTREG(HTOTAL_A, pI830->saveHTOTAL_A); 1971 OUTREG(HBLANK_A, pI830->saveHBLANK_A); 1972 OUTREG(HSYNC_A, pI830->saveHSYNC_A); 1973 OUTREG(VTOTAL_A, pI830->saveVTOTAL_A); 1974 OUTREG(VBLANK_A, pI830->saveVBLANK_A); 1975 OUTREG(VSYNC_A, pI830->saveVSYNC_A); 1976 OUTREG(BCLRPAT_A, pI830->saveBCLRPAT_A); 1977 1978 OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE); 1979 OUTREG(DSPASIZE, pI830->saveDSPASIZE); 1980 OUTREG(DSPAPOS, pI830->saveDSPAPOS); 1981 OUTREG(PIPEASRC, pI830->savePIPEASRC); 1982 OUTREG(DSPABASE, pI830->saveDSPABASE); 1983 if (IS_I965G(pI830)) 1984 { 1985 OUTREG(DSPASURF, pI830->saveDSPASURF); 1986 OUTREG(DSPATILEOFF, pI830->saveDSPATILEOFF); 1987 } 1988 1989 OUTREG(PIPEACONF, pI830->savePIPEACONF); 1990 POSTING_READ(PIPEACONF); 1991 i830WaitForVblank(pScrn); 1992 1993 /* 1994 * Program Pipe A's plane 1995 * The corresponding display plane may be disabled, and should only be 1996 * enabled if pipe A is actually on (otherwise we have a bug in the initial 1997 * state). 1998 */ 1999 if ((pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_MASK) == 2000 DISPPLANE_SEL_PIPE_A) { 2001 OUTREG(DSPACNTR, pI830->saveDSPACNTR); 2002 OUTREG(DSPABASE, INREG(DSPABASE)); 2003 POSTING_READ(DSPABASE); 2004 i830WaitForVblank(pScrn); 2005 } 2006 if ((pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_MASK) == 2007 DISPPLANE_SEL_PIPE_A) { 2008 OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); 2009 OUTREG(DSPBBASE, INREG(DSPBBASE)); 2010 POSTING_READ(DSPBBASE); 2011 i830WaitForVblank(pScrn); 2012 } 2013 2014 /* See note about pipe programming above */ 2015 if(xf86_config->num_crtc == 2) 2016 { 2017 /* If the pipe B PLL is active, we can restore the pipe & plane config */ 2018 if (pI830->saveDPLL_B & DPLL_VCO_ENABLE) 2019 { 2020 OUTREG(FPB0, pI830->saveFPB0); 2021 OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE); 2022 POSTING_READ(DPLL_B); 2023 usleep(150); 2024 } 2025 OUTREG(FPB0, pI830->saveFPB0); 2026 OUTREG(FPB1, pI830->saveFPB1); 2027 OUTREG(DPLL_B, pI830->saveDPLL_B); 2028 POSTING_READ(DPLL_B); 2029 i830_dpll_settle(); 2030 if (IS_I965G(pI830)) 2031 OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD); 2032 else 2033 OUTREG(DPLL_B, pI830->saveDPLL_B); 2034 POSTING_READ(DPLL_B); 2035 i830_dpll_settle(); 2036 2037 /* Restore mode config */ 2038 OUTREG(HTOTAL_B, pI830->saveHTOTAL_B); 2039 OUTREG(HBLANK_B, pI830->saveHBLANK_B); 2040 OUTREG(HSYNC_B, pI830->saveHSYNC_B); 2041 OUTREG(VTOTAL_B, pI830->saveVTOTAL_B); 2042 OUTREG(VBLANK_B, pI830->saveVBLANK_B); 2043 OUTREG(VSYNC_B, pI830->saveVSYNC_B); 2044 OUTREG(BCLRPAT_B, pI830->saveBCLRPAT_B); 2045 OUTREG(DSPBSTRIDE, pI830->saveDSPBSTRIDE); 2046 OUTREG(DSPBSIZE, pI830->saveDSPBSIZE); 2047 OUTREG(DSPBPOS, pI830->saveDSPBPOS); 2048 OUTREG(PIPEBSRC, pI830->savePIPEBSRC); 2049 OUTREG(DSPBBASE, pI830->saveDSPBBASE); 2050 if (IS_I965G(pI830)) 2051 { 2052 OUTREG(DSPBSURF, pI830->saveDSPBSURF); 2053 OUTREG(DSPBTILEOFF, pI830->saveDSPBTILEOFF); 2054 } 2055 2056 OUTREG(PIPEBCONF, pI830->savePIPEBCONF); 2057 POSTING_READ(PIPEBCONF); 2058 i830WaitForVblank(pScrn); 2059 2060 /* 2061 * Program Pipe B's plane 2062 * Note that pipe B may be disabled, and in that case, the plane 2063 * should also be disabled or we must have had a bad initial state. 2064 */ 2065 if ((pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_MASK) == 2066 DISPPLANE_SEL_PIPE_B) { 2067 OUTREG(DSPACNTR, pI830->saveDSPACNTR); 2068 OUTREG(DSPABASE, INREG(DSPABASE)); 2069 i830WaitForVblank(pScrn); 2070 } 2071 if ((pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_MASK) == 2072 DISPPLANE_SEL_PIPE_B) { 2073 OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); 2074 OUTREG(DSPBBASE, INREG(DSPBBASE)); 2075 i830WaitForVblank(pScrn); 2076 } 2077 } 2078 2079 OUTREG(VGACNTRL, pI830->saveVGACNTRL); 2080 2081 /* 2082 * Restore cursors 2083 * Even though the X cursor is hidden before we restore the hw state, 2084 * we probably only disabled one cursor plane. If we're going from 2085 * e.g. plane b to plane a here in RestoreHWState, we need to restore 2086 * both cursor plane settings. 2087 */ 2088 OUTREG(CURSOR_A_POSITION, pI830->saveCURSOR_A_POSITION); 2089 OUTREG(CURSOR_A_BASE, pI830->saveCURSOR_A_BASE); 2090 OUTREG(CURSOR_A_CONTROL, pI830->saveCURSOR_A_CONTROL); 2091 OUTREG(CURSOR_B_POSITION, pI830->saveCURSOR_B_POSITION); 2092 OUTREG(CURSOR_B_BASE, pI830->saveCURSOR_B_BASE); 2093 OUTREG(CURSOR_B_CONTROL, pI830->saveCURSOR_B_CONTROL); 2094 2095 /* Restore outputs */ 2096 for (i = 0; i < xf86_config->num_output; i++) { 2097 xf86OutputPtr output = xf86_config->output[i]; 2098 if (output->funcs->restore) 2099 output->funcs->restore(output); 2100 } 2101 2102 i830_restore_palette(pI830, PIPE_A); 2103 i830_restore_palette(pI830, PIPE_B); 2104 2105 for(i = 0; i < 7; i++) { 2106 OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]); 2107 OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]); 2108 } 2109 2110 OUTREG(SWF30, pI830->saveSWF[14]); 2111 OUTREG(SWF31, pI830->saveSWF[15]); 2112 OUTREG(SWF32, pI830->saveSWF[16]); 2113 2114 if (pI830->fb_compression) { 2115 OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE); 2116 OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE); 2117 OUTREG(FBC_FENCE_OFF, pI830->saveFBC_FENCE_OFF); 2118 OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2); 2119 OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL); 2120 } 2121 2122 vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS); 2123 vgaHWLock(hwp); 2124 2125 return TRUE; 2126} 2127 2128/** 2129 * Intialiazes the hardware for the 3D pipeline use in the 2D driver. 2130 * 2131 * Some state caching is performed to avoid redundant state emits. This 2132 * function is also responsible for marking the state as clobbered for DRI 2133 * clients. 2134 */ 2135void 2136IntelEmitInvarientState(ScrnInfoPtr pScrn) 2137{ 2138 I830Ptr pI830 = I830PTR(pScrn); 2139 2140 /* If we've emitted our state since the last clobber by another client, 2141 * skip it. 2142 */ 2143 if (pI830->last_3d != LAST_3D_OTHER) 2144 return; 2145 2146 if (!IS_I965G(pI830)) 2147 { 2148 if (IS_I9XX(pI830)) 2149 I915EmitInvarientState(pScrn); 2150 else 2151 I830EmitInvarientState(pScrn); 2152 } 2153} 2154 2155static void 2156I830BlockHandler(int i, 2157 pointer blockData, pointer pTimeout, pointer pReadmask) 2158{ 2159 ScreenPtr pScreen = screenInfo.screens[i]; 2160 ScrnInfoPtr pScrn = xf86Screens[i]; 2161 I830Ptr pI830 = I830PTR(pScrn); 2162 2163 pScreen->BlockHandler = pI830->BlockHandler; 2164 2165 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 2166 2167 pI830->BlockHandler = pScreen->BlockHandler; 2168 pScreen->BlockHandler = I830BlockHandler; 2169 2170 if (pScrn->vtSema) { 2171 Bool flushed = FALSE; 2172 /* Emit a flush of the rendering cache, or on the 965 and beyond 2173 * rendering results may not hit the framebuffer until significantly 2174 * later. 2175 */ 2176 if (pI830->need_mi_flush || pI830->batch_used) 2177 { 2178 flushed = TRUE; 2179 I830EmitFlush(pScrn); 2180 } 2181 2182 /* Flush the batch, so that any rendering is executed in a timely 2183 * fashion. 2184 */ 2185 intel_batch_flush(pScrn, flushed); 2186 if (pI830->have_gem) 2187 drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_THROTTLE); 2188 2189 pI830->need_mi_flush = FALSE; 2190 } 2191 2192 i830_uxa_block_handler (pScreen); 2193 2194 I830VideoBlockHandler(i, blockData, pTimeout, pReadmask); 2195} 2196 2197static void 2198i830_fixup_mtrrs(ScrnInfoPtr pScrn) 2199{ 2200#ifdef HAS_MTRR_SUPPORT 2201 I830Ptr pI830 = I830PTR(pScrn); 2202 int fd; 2203 struct mtrr_gentry gentry; 2204 struct mtrr_sentry sentry; 2205 2206 if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) != -1 ) { 2207 for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0; 2208 ++gentry.regnum) { 2209 2210 if (gentry.size < 1) { 2211 /* DISABLED */ 2212 continue; 2213 } 2214 2215 /* Check the MTRR range is one we like and if not - remove it. 2216 * The Xserver common layer will then setup the right range 2217 * for us. 2218 */ 2219 if (gentry.base == pI830->LinearAddr && 2220 gentry.size < pI830->FbMapSize) { 2221 2222 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2223 "Removing bad MTRR range (base 0x%lx, size 0x%x)\n", 2224 gentry.base, gentry.size); 2225 2226 sentry.base = gentry.base; 2227 sentry.size = gentry.size; 2228 sentry.type = gentry.type; 2229 2230 if (ioctl (fd, MTRRIOC_DEL_ENTRY, &sentry) == -1) { 2231 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2232 "Failed to remove bad MTRR range\n"); 2233 } 2234 } 2235 } 2236 close(fd); 2237 } 2238#endif 2239} 2240 2241static Bool 2242i830_try_memory_allocation(ScrnInfoPtr pScrn) 2243{ 2244 I830Ptr pI830 = I830PTR(pScrn); 2245 Bool tiled = pI830->tiling; 2246 2247 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2248 "Attempting memory allocation with %stiled buffers.\n", 2249 tiled ? "" : "un"); 2250 2251 if (!i830_allocate_2d_memory(pScrn)) 2252 goto failed; 2253 2254 if (IS_I965GM(pI830) || IS_GM45(pI830)) 2255 if (!i830_allocate_pwrctx(pScrn)) 2256 goto failed; 2257 2258 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%siled allocation successful.\n", 2259 tiled ? "T" : "Unt"); 2260 return TRUE; 2261 2262failed: 2263 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%siled allocation failed.\n", 2264 tiled ? "T" : "Unt"); 2265 return FALSE; 2266} 2267/* 2268 * Try to allocate memory in several ways: 2269 * 1) If direct rendering is enabled, try to allocate enough memory for tiled 2270 * surfaces by rounding up the display width to a tileable one. 2271 * 2) If that fails or the allocations themselves fail, try again with untiled 2272 * allocations (if this works DRI will stay enabled). 2273 * 3) And if all else fails, disable DRI and try just 2D allocations. 2274 * 4) Give up and fail ScreenInit. 2275 */ 2276static Bool 2277i830_memory_init(ScrnInfoPtr pScrn) 2278{ 2279 I830Ptr pI830 = I830PTR(pScrn); 2280 int savedDisplayWidth = pScrn->displayWidth; 2281 Bool tiled = FALSE; 2282 2283 tiled = i830_tiled_width(pI830, &pScrn->displayWidth, pI830->cpp); 2284 /* Set up our video memory allocator for the chosen videoRam */ 2285 if (!i830_allocator_init(pScrn, pScrn->videoRam * KB(1))) { 2286 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2287 "Couldn't initialize video memory allocator\n"); 2288 PreInitCleanup(pScrn); 2289 return FALSE; 2290 } 2291 2292 xf86DrvMsg(pScrn->scrnIndex, 2293 pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, 2294 "VideoRam: %d KB\n", pScrn->videoRam); 2295 2296 /* Tiled first if we got a good displayWidth */ 2297 if (tiled) { 2298 if (i830_try_memory_allocation(pScrn)) 2299 return TRUE; 2300 else { 2301 i830_reset_allocations(pScrn); 2302 pI830->tiling = FALSE; 2303 } 2304 } 2305 2306 /* If tiling fails we have to disable FBC */ 2307 pScrn->displayWidth = savedDisplayWidth; 2308 if (pI830->fb_compression) 2309 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2310 "Couldn't allocate tiled memory, fb compression " 2311 "disabled\n"); 2312 pI830->fb_compression = FALSE; 2313 2314 if (i830_try_memory_allocation(pScrn)) 2315 return TRUE; 2316 2317 return FALSE; 2318} 2319 2320void 2321i830_init_bufmgr(ScrnInfoPtr pScrn) 2322{ 2323 I830Ptr pI830 = I830PTR(pScrn); 2324 2325 if (pI830->bufmgr) 2326 return; 2327 2328 if (pI830->have_gem) { 2329 int batch_size; 2330 2331 batch_size = 4096 * 4; 2332 2333 /* The 865 has issues with larger-than-page-sized batch buffers. */ 2334 if (IS_I865G(pI830)) 2335 batch_size = 4096; 2336 2337 pI830->bufmgr = intel_bufmgr_gem_init(pI830->drmSubFD, batch_size); 2338 intel_bufmgr_gem_enable_reuse(pI830->bufmgr); 2339 } else { 2340 assert(pI830->FbBase != NULL); 2341 pI830->bufmgr = intel_bufmgr_fake_init(pI830->drmSubFD, 2342 pI830->fake_bufmgr_mem->offset, 2343 pI830->FbBase + 2344 pI830->fake_bufmgr_mem->offset, 2345 pI830->fake_bufmgr_mem->size, 2346 NULL); 2347 } 2348} 2349 2350Bool i830_crtc_on(xf86CrtcPtr crtc) 2351{ 2352 ScrnInfoPtr pScrn = crtc->scrn; 2353 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2354 I830Ptr pI830 = I830PTR(pScrn); 2355 2356 if (pI830->use_drm_mode) { 2357 int i, active_outputs = 0; 2358 2359 /* Kernel manages CRTC status based out output config */ 2360 for (i = 0; i < xf86_config->num_output; i++) { 2361 xf86OutputPtr output = xf86_config->output[i]; 2362 if (output->crtc == crtc && 2363 drmmode_output_dpms_status(output) == DPMSModeOn) 2364 active_outputs++; 2365 } 2366 2367 if (active_outputs) 2368 return TRUE; 2369 return FALSE; 2370 } else { 2371 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 2372 2373 if (intel_crtc->dpms_mode == DPMSModeOn) 2374 return TRUE; 2375 return FALSE; 2376 } 2377} 2378 2379int i830_crtc_to_pipe(xf86CrtcPtr crtc) 2380{ 2381 ScrnInfoPtr pScrn = crtc->scrn; 2382 I830Ptr pI830 = I830PTR(pScrn); 2383 int pipe; 2384 2385 if (pI830->use_drm_mode) { 2386 pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc); 2387 } else { 2388 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 2389 pipe = intel_crtc->pipe; 2390 } 2391 2392 return pipe; 2393} 2394 2395static void 2396I830AdjustMemory(ScreenPtr pScreen) 2397{ 2398 ScrnInfoPtr pScrn; 2399 I830Ptr pI830; 2400 unsigned long sys_mem; 2401 MessageType from; 2402 2403 pScrn = xf86Screens[pScreen->myNum]; 2404 pI830 = I830PTR(pScrn); 2405 2406 /* Limit videoRam to how much we might be able to allocate from AGP */ 2407 sys_mem = I830CheckAvailableMemory(pScrn); 2408 if (sys_mem == -1) { 2409 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2410 "/dev/agpgart is either not available, or no memory " 2411 "is available\nfor allocation. Please enable agpgart\n."); 2412 pScrn->videoRam = pI830->stolen_size / KB(1); 2413 } 2414 if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) { 2415 pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024); 2416 from = X_PROBED; 2417 if (sys_mem + (pI830->stolen_size / 1024) < 2418 pI830->pEnt->device->videoRam) { 2419 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2420 "VideoRAM reduced to %d kByte " 2421 "(limited to available sysmem)\n", pScrn->videoRam); 2422 } 2423 } 2424 2425 /* Limit video RAM to the actual aperture size */ 2426 if (pScrn->videoRam > pI830->FbMapSize / 1024) { 2427 pScrn->videoRam = pI830->FbMapSize / 1024; 2428 if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) { 2429 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2430 "VideoRam reduced to %d kByte (limited to aperture " 2431 "size)\n", 2432 pScrn->videoRam); 2433 } 2434 } 2435 2436 /* Make sure it's on a page boundary */ 2437 if (pScrn->videoRam & 3) { 2438 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB " 2439 "(page aligned - was %d KB)\n", 2440 pScrn->videoRam & ~3, pScrn->videoRam); 2441 pScrn->videoRam &= ~3; 2442 } 2443 2444 if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { 2445 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2446 "Cannot support DRI with frame buffer width > 2048.\n"); 2447 pI830->directRenderingType = DRI_DISABLED; 2448 } 2449} 2450 2451static void 2452I830SwapPipes(ScrnInfoPtr pScrn) 2453{ 2454 I830Ptr pI830 = I830PTR(pScrn); 2455 xf86CrtcConfigPtr config; 2456 int c; 2457 2458 config = XF86_CRTC_CONFIG_PTR(pScrn); 2459 2460 /* 2461 * If an LVDS display is present, swap the plane/pipe mappings so we can 2462 * use FBC on the builtin display. 2463 * Note: 965+ chips can compress either plane, so we leave the mapping 2464 * alone in that case. 2465 * Also make sure the DRM can handle the swap. 2466 */ 2467 if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830)) { 2468 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings " 2469 "to allow for framebuffer compression\n"); 2470 for (c = 0; c < config->num_crtc; c++) { 2471 xf86CrtcPtr crtc = config->crtc[c]; 2472 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 2473 2474 if (intel_crtc->pipe == 0) 2475 intel_crtc->plane = 1; 2476 else if (intel_crtc->pipe == 1) 2477 intel_crtc->plane = 0; 2478 } 2479 } 2480} 2481 2482static void 2483i830_disable_render_standby(ScrnInfoPtr pScrn) 2484{ 2485 I830Ptr pI830 = I830PTR(pScrn); 2486 uint32_t render_standby; 2487 2488 /* Render Standby might cause hang issue, try always disable it.*/ 2489 if (IS_I965GM(pI830) || IS_GM45(pI830)) { 2490 render_standby = INREG(MCHBAR_RENDER_STANDBY); 2491 if (render_standby & RENDER_STANDBY_ENABLE) { 2492 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disable render standby.\n"); 2493 OUTREG(MCHBAR_RENDER_STANDBY, 2494 (render_standby & (~RENDER_STANDBY_ENABLE))); 2495 } 2496 } 2497} 2498 2499static Bool 2500I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 2501{ 2502 ScrnInfoPtr pScrn; 2503 vgaHWPtr hwp = NULL; 2504 I830Ptr pI830; 2505 VisualPtr visual; 2506 MessageType from; 2507 2508 pScrn = xf86Screens[pScreen->myNum]; 2509 pI830 = I830PTR(pScrn); 2510 2511 if (!pI830->use_drm_mode) 2512 hwp = VGAHWPTR(pScrn); 2513 2514 pScrn->displayWidth = i830_pad_drawable_width(pScrn->virtualX, pI830->cpp); 2515 2516 /* 2517 * The "VideoRam" config file parameter specifies the maximum amount of 2518 * memory that will be used/allocated. When not present, we allow the 2519 * driver to allocate as much memory as it wishes to satisfy its 2520 * allocations, but if agpgart support isn't available, it gets limited 2521 * to the amount of pre-allocated ("stolen") memory. 2522 * 2523 * Note that in using this value for allocator initialization, we're 2524 * limiting aperture allocation to the VideoRam option, rather than limiting 2525 * actual memory allocation, so alignment and things will cause less than 2526 * VideoRam to be actually used. 2527 */ 2528 if (pI830->pEnt->device->videoRam == 0) { 2529 from = X_DEFAULT; 2530 pScrn->videoRam = pI830->FbMapSize / KB(1); 2531 } else { 2532#if 0 2533 from = X_CONFIG; 2534 pScrn->videoRam = pI830->pEnt->device->videoRam; 2535#else 2536 /* Disable VideoRam configuration, at least for now. Previously, 2537 * VideoRam was necessary to avoid overly low limits on allocated 2538 * memory, so users created larger, yet still small, fixed allocation 2539 * limits in their config files. Now, the driver wants to allocate more, 2540 * and the old intention of the VideoRam lines that had been entered is 2541 * obsolete. 2542 */ 2543 from = X_DEFAULT; 2544 pScrn->videoRam = pI830->FbMapSize / KB(1); 2545 2546 if (pScrn->videoRam != pI830->pEnt->device->videoRam) { 2547 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2548 "VideoRam configuration found, which is no longer " 2549 "recommended.\n"); 2550 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2551 "Continuing with default %dkB VideoRam instead of %d " 2552 "kB.\n", 2553 pScrn->videoRam, pI830->pEnt->device->videoRam); 2554 } 2555#endif 2556 } 2557 2558 if (pI830->use_drm_mode) { 2559 struct pci_device *const device = pI830->PciInfo; 2560 int fb_bar = IS_I9XX(pI830) ? 2 : 0; 2561 2562 pScrn->videoRam = device->regions[fb_bar].size / 1024; 2563 } else { 2564 I830AdjustMemory(pScreen); 2565 } 2566 2567#ifdef DRI2 2568 if (pI830->directRenderingType == DRI_NONE && I830DRI2ScreenInit(pScreen)) 2569 pI830->directRenderingType = DRI_DRI2; 2570#endif 2571 2572 /* Enable tiling by default */ 2573 pI830->tiling = TRUE; 2574 2575 /* Allow user override if they set a value */ 2576 if (xf86IsOptionSet(pI830->Options, OPTION_TILING)) { 2577 if (xf86ReturnOptValBool(pI830->Options, OPTION_TILING, FALSE)) 2578 pI830->tiling = TRUE; 2579 else 2580 pI830->tiling = FALSE; 2581 } 2582 2583 /* Enable FB compression if possible */ 2584 if (i830_fb_compression_supported(pI830)) 2585 pI830->fb_compression = TRUE; 2586 else 2587 pI830->fb_compression = FALSE; 2588 2589 /* Again, allow user override if set */ 2590 if (xf86IsOptionSet(pI830->Options, OPTION_FBC)) { 2591 if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE)) 2592 pI830->fb_compression = TRUE; 2593 else 2594 pI830->fb_compression = FALSE; 2595 } 2596 2597 if (pI830->use_drm_mode && pI830->fb_compression == TRUE) { 2598 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2599 "Kernel mode setting active, disabling FBC.\n"); 2600 pI830->fb_compression = FALSE; 2601 } 2602 2603 /* SwapBuffers delays to avoid tearing */ 2604 pI830->swapbuffers_wait = TRUE; 2605 2606 /* Allow user override if they set a value */ 2607 if (xf86IsOptionSet(pI830->Options, OPTION_SWAPBUFFERS_WAIT)) { 2608 if (xf86ReturnOptValBool(pI830->Options, OPTION_SWAPBUFFERS_WAIT, FALSE)) 2609 pI830->swapbuffers_wait = TRUE; 2610 else 2611 pI830->swapbuffers_wait = FALSE; 2612 } 2613 2614 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n", 2615 pI830->fb_compression ? "en" : "dis"); 2616 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ? 2617 "en" : "dis"); 2618 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "SwapBuffers wait %sabled\n", 2619 pI830->swapbuffers_wait ? "en" : "dis"); 2620 2621 pI830->last_3d = LAST_3D_OTHER; 2622 pI830->overlayOn = FALSE; 2623 2624 /* 2625 * Set this so that the overlay allocation is factored in when 2626 * appropriate. 2627 */ 2628 pI830->XvEnabled = TRUE; 2629 2630 /* Need MMIO mapped to do GTT lookups during memory allocation. */ 2631 if (!pI830->use_drm_mode) 2632 I830MapMMIO(pScrn); 2633 2634 /* Need FB mapped to access non-GEM objects like 2635 * a UMS frame buffer, or the fake bufmgr. 2636 */ 2637 if (!pI830->use_drm_mode) { 2638 if (!I830MapMem(pScrn)) 2639 return FALSE; 2640 pScrn->memPhysBase = (unsigned long)pI830->FbBase; 2641 } 2642 2643 if (!i830_memory_init(pScrn)) { 2644 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2645 "Couldn't allocate video memory\n"); 2646 return FALSE; 2647 } 2648 2649 i830_fixup_mtrrs(pScrn); 2650 2651 pI830->starting = TRUE; 2652 2653 miClearVisualTypes(); 2654 if (!miSetVisualTypes(pScrn->depth, 2655 miGetDefaultVisualMask(pScrn->depth), 2656 pScrn->rgbBits, pScrn->defaultVisual)) 2657 return FALSE; 2658 if (!miSetPixmapDepths()) 2659 return FALSE; 2660 2661 if (!pI830->use_drm_mode) { 2662 vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0); 2663 vgaHWGetIOBase(hwp); 2664 DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n"); 2665 if (!vgaHWMapMem(pScrn)) 2666 return FALSE; 2667 } 2668 2669 DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n"); 2670 2671 if (pScrn->virtualX > pScrn->displayWidth) 2672 pScrn->displayWidth = pScrn->virtualX; 2673 2674 /* If the front buffer is not a BO, we need to 2675 * set the initial framebuffer pixmap to point at 2676 * it 2677 */ 2678 pScrn->fbOffset = pI830->front_buffer->offset; 2679 2680 DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n"); 2681 if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset, 2682 pScrn->virtualX, pScrn->virtualY, 2683 pScrn->xDpi, pScrn->yDpi, 2684 pScrn->displayWidth, pScrn->bitsPerPixel)) 2685 return FALSE; 2686 2687 if (pScrn->bitsPerPixel > 8) { 2688 /* Fixup RGB ordering */ 2689 visual = pScreen->visuals + pScreen->numVisuals; 2690 while (--visual >= pScreen->visuals) { 2691 if ((visual->class | DynamicClass) == DirectColor) { 2692 visual->offsetRed = pScrn->offset.red; 2693 visual->offsetGreen = pScrn->offset.green; 2694 visual->offsetBlue = pScrn->offset.blue; 2695 visual->redMask = pScrn->mask.red; 2696 visual->greenMask = pScrn->mask.green; 2697 visual->blueMask = pScrn->mask.blue; 2698 } 2699 } 2700 } 2701 2702 fbPictureInit(pScreen, NULL, 0); 2703 2704 xf86SetBlackWhitePixels(pScreen); 2705 2706 if (!I830AccelInit(pScreen)) { 2707 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2708 "Hardware acceleration initialization failed\n"); 2709 return FALSE; 2710 } 2711 2712 if (IS_I965G(pI830)) 2713 pI830->batch_flush_notify = i965_batch_flush_notify; 2714 else if (IS_I9XX(pI830)) 2715 pI830->batch_flush_notify = i915_batch_flush_notify; 2716 else 2717 pI830->batch_flush_notify = i830_batch_flush_notify; 2718 2719 xf86SetBackingStore(pScreen); 2720 xf86SetSilkenMouse(pScreen); 2721 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 2722 2723 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing HW Cursor\n"); 2724 if (!I830CursorInit(pScreen)) 2725 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2726 "Hardware cursor initialization failed\n"); 2727 2728 /* Must force it before EnterVT, so we are in control of VT and 2729 * later memory should be bound when allocating, e.g rotate_mem */ 2730 pScrn->vtSema = TRUE; 2731 2732 if (!I830EnterVT(scrnIndex, 0)) 2733 return FALSE; 2734 2735 pI830->BlockHandler = pScreen->BlockHandler; 2736 pScreen->BlockHandler = I830BlockHandler; 2737 2738 pScreen->SaveScreen = xf86SaveScreen; 2739 pI830->CloseScreen = pScreen->CloseScreen; 2740 pScreen->CloseScreen = I830CloseScreen; 2741 pI830->CreateScreenResources = pScreen->CreateScreenResources; 2742 pScreen->CreateScreenResources = i830CreateScreenResources; 2743 2744 if (!xf86CrtcScreenInit (pScreen)) 2745 return FALSE; 2746 2747 DPRINTF(PFX, "assert( if(!miCreateDefColormap(pScreen)) )\n"); 2748 if (!miCreateDefColormap(pScreen)) 2749 return FALSE; 2750 2751 DPRINTF(PFX, "assert( if(!xf86HandleColormaps(pScreen, ...)) )\n"); 2752 if (!xf86HandleColormaps(pScreen, 256, 8, I830LoadPalette, NULL, 2753 CMAP_RELOAD_ON_MODE_SWITCH | 2754 CMAP_PALETTED_TRUECOLOR)) { 2755 return FALSE; 2756 } 2757 2758 xf86DPMSInit(pScreen, xf86DPMSSet, 0); 2759 2760#ifdef INTEL_XVMC 2761 pI830->XvMCEnabled = FALSE; 2762 from = ((pI830->directRenderingType == DRI_DRI2) && 2763 xf86GetOptValBool(pI830->Options, OPTION_XVMC, 2764 &pI830->XvMCEnabled) ? X_CONFIG : X_DEFAULT); 2765 xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n", 2766 pI830->XvMCEnabled ? "en" : "dis"); 2767#endif 2768 /* Init video */ 2769 if (pI830->XvEnabled) 2770 I830InitVideo(pScreen); 2771 2772 /* Setup 3D engine, needed for rotation too */ 2773 IntelEmitInvarientState(pScrn); 2774 2775#if defined(DRI2) 2776 switch (pI830->directRenderingType) { 2777 case DRI_DRI2: 2778 pI830->directRenderingOpen = TRUE; 2779 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: DRI2 Enabled\n"); 2780 break; 2781 case DRI_DISABLED: 2782 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Disabled\n"); 2783 break; 2784 case DRI_NONE: 2785 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Failed\n"); 2786 break; 2787 } 2788#else 2789 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Not available\n"); 2790#endif 2791 2792 if (serverGeneration == 1) 2793 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 2794 2795 pI830->starting = FALSE; 2796 pI830->closing = FALSE; 2797 pI830->suspended = FALSE; 2798 2799 return TRUE; 2800} 2801 2802static void 2803i830AdjustFrame(int scrnIndex, int x, int y, int flags) 2804{ 2805 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 2806 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 2807 I830Ptr pI830 = I830PTR(pScrn); 2808 xf86OutputPtr output = config->output[config->compat_output]; 2809 xf86CrtcPtr crtc = output->crtc; 2810 2811 DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n", 2812 x, crtc->desiredX, y, crtc->desiredY); 2813 2814 if (pI830->use_drm_mode) 2815 return; 2816 2817 if (crtc && crtc->enabled) 2818 { 2819 /* Sync the engine before adjust frame */ 2820 I830Sync(pScrn); 2821 i830PipeSetBase(crtc, crtc->desiredX + x, crtc->desiredY + y); 2822 crtc->x = output->initial_x + x; 2823 crtc->y = output->initial_y + y; 2824 } 2825} 2826 2827static void 2828I830FreeScreen(int scrnIndex, int flags) 2829{ 2830 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 2831#ifdef INTEL_XVMC 2832 I830Ptr pI830 = I830PTR(pScrn); 2833 if (pI830 && pI830->XvMCEnabled) 2834 intel_xvmc_finish(xf86Screens[scrnIndex]); 2835#endif 2836 2837 i830_close_drm_master(pScrn); 2838 2839 I830FreeRec(xf86Screens[scrnIndex]); 2840 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 2841 vgaHWFreeHWRec(xf86Screens[scrnIndex]); 2842} 2843 2844static void 2845I830LeaveVT(int scrnIndex, int flags) 2846{ 2847 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 2848 I830Ptr pI830 = I830PTR(pScrn); 2849 int ret; 2850 2851 DPRINTF(PFX, "Leave VT\n"); 2852 2853 pI830->leaving = TRUE; 2854 2855 if (pI830->devicesTimer) 2856 TimerFree(pI830->devicesTimer); 2857 pI830->devicesTimer = NULL; 2858 2859 i830SetHotkeyControl(pScrn, HOTKEY_BIOS_SWITCH); 2860 2861 xf86RotateFreeShadow(pScrn); 2862 2863 xf86_hide_cursors (pScrn); 2864 2865 I830Sync(pScrn); 2866 2867 if (!pI830->use_drm_mode) { 2868 RestoreHWState(pScrn); 2869 /* Evict everything from the bufmgr, as we're about to lose ownership of 2870 * the graphics memory. 2871 */ 2872 if (!pI830->have_gem) { 2873 intel_bufmgr_fake_evict_all(pI830->bufmgr); 2874 i830_stop_ring(pScrn, TRUE); 2875 } 2876 2877 if (pI830->debug_modes) { 2878 i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); 2879 i830DumpRegs (pScrn); 2880 } 2881 } 2882 2883 intel_batch_teardown(pScrn); 2884 2885 i830_unbind_all_memory(pScrn); 2886 2887 if (pI830->have_gem && !pI830->use_drm_mode) { 2888 int ret; 2889 2890 /* Tell the kernel to evict all buffer objects and block GTT usage while 2891 * we're no longer in control of the chip. 2892 */ 2893 ret = drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_LEAVEVT); 2894 if (ret != 0) 2895 FatalError("DRM_I915_LEAVEVT failed: %s\n", strerror(ret)); 2896 } 2897 2898 if (IS_I965G(pI830)) 2899 gen4_render_state_cleanup(pScrn); 2900 2901 ret = drmDropMaster(pI830->drmSubFD); 2902 if (ret) 2903 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2904 "drmDropMaster failed: %s\n", strerror(errno)); 2905} 2906 2907/* 2908 * This gets called when gaining control of the VT, and from ScreenInit(). 2909 */ 2910static Bool 2911I830EnterVT(int scrnIndex, int flags) 2912{ 2913 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 2914 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2915 I830Ptr pI830 = I830PTR(pScrn); 2916 int i, ret; 2917 2918 DPRINTF(PFX, "Enter VT\n"); 2919 2920 ret = drmSetMaster(pI830->drmSubFD); 2921 if (ret) { 2922 if (errno == EINVAL) { 2923 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2924 "drmSetMaster failed: 2.6.29 or newer kernel required for " 2925 "multi-server DRI\n"); 2926 } else { 2927 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2928 "drmSetMaster failed: %s\n", strerror(errno)); 2929 } 2930 } 2931 2932 /* 2933 * Only save state once per server generation since that's what most 2934 * drivers do. Could change this to save state at each VT enter. 2935 */ 2936 if (pI830->SaveGeneration != serverGeneration) { 2937 pI830->SaveGeneration = serverGeneration; 2938 if (!pI830->use_drm_mode) 2939 SaveHWState(pScrn); 2940 } 2941 2942 /* Get the hardware into a known state if needed */ 2943 if (!pI830->use_drm_mode) { 2944 2945 I830SwapPipes(pScrn); 2946 2947 /* Disable outputs */ 2948 for (i = 0; i < xf86_config->num_output; i++) { 2949 xf86OutputPtr output = xf86_config->output[i]; 2950 output->funcs->dpms(output, DPMSModeOff); 2951 } 2952 i830WaitForVblank(pScrn); 2953 2954 /* Disable pipes */ 2955 for (i = 0; i < xf86_config->num_crtc; i++) { 2956 xf86CrtcPtr crtc = xf86_config->crtc[i]; 2957 i830_crtc_disable(crtc, TRUE); 2958 } 2959 i830WaitForVblank(pScrn); 2960 } 2961 2962 pI830->leaving = FALSE; 2963 2964 if (!pI830->use_drm_mode) 2965 i830_disable_render_standby(pScrn); 2966 2967 if (pI830->have_gem && !pI830->use_drm_mode) { 2968 int ret; 2969 2970 /* Tell the kernel that we're back in control and ready for GTT 2971 * usage. 2972 */ 2973 ret = drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_ENTERVT); 2974 if (ret != 0) 2975 FatalError("DRM_I915_ENTERVT failed: %s\n", strerror(ret)); 2976 } 2977 2978 if (!i830_bind_all_memory(pScrn)) 2979 return FALSE; 2980 2981 i830_describe_allocations(pScrn, 1, ""); 2982 2983 intel_batch_init(pScrn); 2984 2985 if (IS_I965G(pI830)) 2986 gen4_render_state_init(pScrn); 2987 2988 if (!pI830->use_drm_mode) { 2989 if (i830_check_error_state(pScrn)) { 2990 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2991 "Existing errors found in hardware state.\n"); 2992 } 2993 2994 /* Re-set up the ring. */ 2995 if (!pI830->have_gem) { 2996 i830_stop_ring(pScrn, FALSE); 2997 i830_start_ring(pScrn); 2998 } 2999 I830InitHWCursor(pScrn); 3000 3001 /* Tell the BIOS that we're in control of mode setting now. */ 3002 i830_init_bios_control(pScrn); 3003 3004 i830_init_clock_gating(pScrn); 3005 3006 if (pI830->power_context) 3007 OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN); 3008 /* Clear the framebuffer */ 3009 memset(pI830->FbBase + pScrn->fbOffset, 0, 3010 pScrn->virtualY * pScrn->displayWidth * pI830->cpp); 3011 } 3012 3013 if (!xf86SetDesiredModes (pScrn)) 3014 return FALSE; 3015 3016 if (!pI830->use_drm_mode) { 3017 if (pI830->debug_modes) { 3018 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n"); 3019 i830DumpRegs (pScrn); 3020 } 3021 i830DescribeOutputConfiguration(pScrn); 3022 } 3023 3024 /* Set the hotkey to just notify us. We could check its results 3025 * periodically and attempt to do something, but it seems like we basically 3026 * never get results when we should, and this should all be better handled 3027 * through ACPI putting the key events out through evdev and your desktop 3028 * environment picking it up. 3029 */ 3030 i830SetHotkeyControl(pScrn, HOTKEY_DRIVER_NOTIFY); 3031 3032 /* Mark 3D state as being clobbered and setup the basics */ 3033 pI830->last_3d = LAST_3D_OTHER; 3034 IntelEmitInvarientState(pScrn); 3035 3036 return TRUE; 3037} 3038 3039static Bool 3040I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 3041{ 3042 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3043 3044 return xf86SetSingleMode (pScrn, mode, RR_Rotate_0); 3045} 3046 3047static Bool 3048I830CloseScreen(int scrnIndex, ScreenPtr pScreen) 3049{ 3050 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3051 I830Ptr pI830 = I830PTR(pScrn); 3052 3053 pI830->closing = TRUE; 3054 3055 if (pScrn->vtSema == TRUE) { 3056 I830LeaveVT(scrnIndex, 0); 3057 } 3058 3059 if (pI830->devicesTimer) 3060 TimerFree(pI830->devicesTimer); 3061 pI830->devicesTimer = NULL; 3062 3063 if (!pI830->use_drm_mode) { 3064 DPRINTF(PFX, "\nUnmapping memory\n"); 3065 I830UnmapMem(pScrn); 3066 vgaHWUnmapMem(pScrn); 3067 } 3068 3069 if (pI830->uxa_driver) { 3070 uxa_driver_fini (pScreen); 3071 xfree (pI830->uxa_driver); 3072 pI830->uxa_driver = NULL; 3073 } 3074 if (pI830->front_buffer) { 3075 i830_set_pixmap_bo(pScreen->GetScreenPixmap(pScreen), NULL); 3076 if (pI830->use_drm_mode) 3077 drmmode_closefb(pScrn); 3078 i830_free_memory(pScrn, pI830->front_buffer); 3079 pI830->front_buffer = NULL; 3080 } 3081 3082 xf86_cursors_fini (pScreen); 3083 3084 i830_allocator_fini(pScrn); 3085 3086 i965_free_video(pScrn); 3087 free(pI830->offscreenImages); 3088 pI830->offscreenImages = NULL; 3089 3090 pScreen->CloseScreen = pI830->CloseScreen; 3091 (*pScreen->CloseScreen) (scrnIndex, pScreen); 3092 3093 if (pI830->directRenderingOpen && pI830->directRenderingType == DRI_DRI2) { 3094 pI830->directRenderingOpen = FALSE; 3095 I830DRI2CloseScreen(pScreen); 3096 } 3097 3098 xf86GARTCloseScreen(scrnIndex); 3099 3100 pScrn->vtSema = FALSE; 3101 pI830->closing = FALSE; 3102 return TRUE; 3103} 3104 3105static ModeStatus 3106I830ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 3107{ 3108 if (mode->Flags & V_INTERLACE) { 3109 if (verbose) { 3110 xf86DrvMsg(scrnIndex, X_PROBED, 3111 "Removing interlaced mode \"%s\"\n", mode->name); 3112 } 3113 return MODE_BAD; 3114 } 3115 return MODE_OK; 3116} 3117 3118#ifndef SUSPEND_SLEEP 3119#define SUSPEND_SLEEP 0 3120#endif 3121#ifndef RESUME_SLEEP 3122#define RESUME_SLEEP 0 3123#endif 3124 3125/* 3126 * This function is only required if we need to do anything differently from 3127 * DoApmEvent() in common/xf86PM.c, including if we want to see events other 3128 * than suspend/resume. 3129 */ 3130static Bool 3131I830PMEvent(int scrnIndex, pmEvent event, Bool undo) 3132{ 3133 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3134 I830Ptr pI830 = I830PTR(pScrn); 3135 3136 DPRINTF(PFX, "Enter VT, event %d, undo: %s\n", event, BOOLTOSTRING(undo)); 3137 3138 switch(event) { 3139 case XF86_APM_SYS_SUSPEND: 3140 case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend?*/ 3141 case XF86_APM_USER_SUSPEND: 3142 case XF86_APM_SYS_STANDBY: 3143 case XF86_APM_USER_STANDBY: 3144 if (!undo && !pI830->suspended) { 3145 pScrn->LeaveVT(scrnIndex, 0); 3146 pI830->suspended = TRUE; 3147 sleep(SUSPEND_SLEEP); 3148 } else if (undo && pI830->suspended) { 3149 sleep(RESUME_SLEEP); 3150 pScrn->EnterVT(scrnIndex, 0); 3151 pI830->suspended = FALSE; 3152 } 3153 break; 3154 case XF86_APM_STANDBY_RESUME: 3155 case XF86_APM_NORMAL_RESUME: 3156 case XF86_APM_CRITICAL_RESUME: 3157 if (pI830->suspended) { 3158 sleep(RESUME_SLEEP); 3159 pScrn->EnterVT(scrnIndex, 0); 3160 pI830->suspended = FALSE; 3161 /* 3162 * Turn the screen saver off when resuming. This seems to be 3163 * needed to stop xscreensaver kicking in (when used). 3164 * 3165 * XXX DoApmEvent() should probably call this just like 3166 * xf86VTSwitch() does. Maybe do it here only in 4.2 3167 * compatibility mode. 3168 */ 3169 SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); 3170 } 3171 break; 3172 /* This is currently used for ACPI */ 3173 case XF86_APM_CAPABILITY_CHANGED: 3174 ErrorF("I830PMEvent: Capability change\n"); 3175 3176 SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); 3177 if (pI830->quirk_flag & QUIRK_RESET_MODES) 3178 xf86SetDesiredModes(pScrn); 3179 3180 break; 3181 default: 3182 ErrorF("I830PMEvent: received APM event %d\n", event); 3183 } 3184 return TRUE; 3185} 3186 3187xf86CrtcPtr 3188i830_pipe_to_crtc(ScrnInfoPtr pScrn, int pipe) 3189{ 3190 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); 3191 int c; 3192 3193 for (c = 0; c < config->num_crtc; c++) { 3194 xf86CrtcPtr crtc = config->crtc[c]; 3195 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 3196 3197 if (intel_crtc->pipe == pipe) 3198 return crtc; 3199 } 3200 3201 return NULL; 3202} 3203 3204void 3205I830InitpScrn(ScrnInfoPtr pScrn) 3206{ 3207 pScrn->PreInit = I830PreInit; 3208 pScrn->ScreenInit = I830ScreenInit; 3209 pScrn->SwitchMode = I830SwitchMode; 3210 pScrn->AdjustFrame = i830AdjustFrame; 3211 pScrn->EnterVT = I830EnterVT; 3212 pScrn->LeaveVT = I830LeaveVT; 3213 pScrn->FreeScreen = I830FreeScreen; 3214 pScrn->ValidMode = I830ValidMode; 3215 pScrn->PMEvent = I830PMEvent; 3216} 3217