Home | History | Annotate | Line # | Download | only in src
      1 /**************************************************************************
      2 
      3 Copyright 2001 VA Linux Systems Inc., Fremont, California.
      4 Copyright  2002 by David Dawes
      5 
      6 All Rights Reserved.
      7 
      8 Permission is hereby granted, free of charge, to any person obtaining a
      9 copy of this software and associated documentation files (the "Software"),
     10 to deal in the Software without restriction, including without limitation
     11 on the rights to use, copy, modify, merge, publish, distribute, sub
     12 license, and/or sell copies of the Software, and to permit persons to whom
     13 the Software is furnished to do so, subject to the following conditions:
     14 
     15 The above copyright notice and this permission notice (including the next
     16 paragraph) shall be included in all copies or substantial portions of the
     17 Software.
     18 
     19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     22 THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     25 USE OR OTHER DEALINGS IN THE SOFTWARE.
     26 
     27 **************************************************************************/
     28 
     29 /*
     30  * Authors: Jeff Hartmann <jhartmann (at) valinux.com>
     31  *          Abraham van der Merwe <abraham (at) 2d3d.co.za>
     32  *          David Dawes <dawes (at) xfree86.org>
     33  *          Alan Hourihane <alanh (at) 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* */
     91 static 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 
    124 static 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 
    163 typedef 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 
    181 static 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 
    201 static void i830AdjustFrame(int scrnIndex, int x, int y, int flags);
    202 static Bool I830CloseScreen(int scrnIndex, ScreenPtr pScreen);
    203 static Bool I830EnterVT(int scrnIndex, int flags);
    204 static Bool SaveHWState(ScrnInfoPtr pScrn);
    205 static Bool RestoreHWState(ScrnInfoPtr pScrn);
    206 
    207 /* temporary */
    208 extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
    209 
    210 #ifdef I830DEBUG
    211 void
    212 I830DPRINTF(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 */
    228 const OptionInfoRec *
    229 I830AvailableOptions(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 
    240 static Bool
    241 I830GetRec(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 
    251 static void
    252 I830FreeRec(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 
    267 static int
    268 I830DetectMemory(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 
    417 static Bool
    418 I830MapMMIO(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 
    481 static Bool
    482 I830MapMem(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 
    505 static void
    506 I830UnmapMMIO(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 
    519 static Bool
    520 I830UnmapMem(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 
    530 static void
    531 I830LoadPalette(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  */
    604 static Bool
    605 i830CreateScreenResources(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 
    619 static int
    620 i830_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  */
    642 static void
    643 I830SetupOutputs(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 
    702 static void
    703 i830_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 
    742 static void
    743 i830_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 
    755 static int
    756 I830LVDSPresent(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 
    776 static void
    777 I830PreInitDDC(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 
    798 static void
    799 PreInitCleanup(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  */
    811 Bool
    812 i830_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  */
    853 int
    854 i830_pad_drawable_width(int width, int cpp)
    855 {
    856     return (width + 63) & ~63;
    857 }
    858 
    859 static Bool
    860 i830_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 
    915 static 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  */
    930 static void
    931 i830SetHotkeyControl(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  */
    952 static 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 
    982 static Bool
    983 i830_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 
   1217 static Bool
   1218 I830LoadSyms(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 
   1235 static Bool
   1236 I830GetEarlyOptions(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 
   1274 static void
   1275 I830PreInitCrtcConfig(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 
   1299 static void
   1300 i830_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 
   1314 static Bool
   1315 i830_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 
   1362 static Bool
   1363 i830_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 
   1420 static void
   1421 i830_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 
   1430 static Bool
   1431 I830DrmModeInit(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 
   1449 static void
   1450 I830XvInit(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  */
   1487 static Bool
   1488 I830PreInit(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  */
   1642 static void
   1643 i830_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 
   1663 static void
   1664 i830_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 
   1696 void
   1697 i830_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 
   1714 enum pipe {
   1715     PIPE_A = 0,
   1716     PIPE_B,
   1717 };
   1718 
   1719 static Bool
   1720 i830_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 
   1728 static void
   1729 i830_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 
   1744 static void
   1745 i830_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 
   1760 static Bool
   1761 SaveHWState(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 */
   1882 static void
   1883 i830_dpll_settle(void)
   1884 {
   1885     usleep(10000); /* 10 ms *should* be plenty */
   1886 }
   1887 
   1888 static Bool
   1889 RestoreHWState(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  */
   2135 void
   2136 IntelEmitInvarientState(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 
   2155 static void
   2156 I830BlockHandler(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 
   2197 static void
   2198 i830_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 
   2241 static Bool
   2242 i830_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 
   2262 failed:
   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  */
   2276 static Bool
   2277 i830_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 
   2320 void
   2321 i830_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 
   2350 Bool 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 
   2379 int 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 
   2395 static void
   2396 I830AdjustMemory(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 
   2451 static void
   2452 I830SwapPipes(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 
   2482 static void
   2483 i830_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 
   2499 static Bool
   2500 I830ScreenInit(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 
   2802 static void
   2803 i830AdjustFrame(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 
   2827 static void
   2828 I830FreeScreen(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 
   2844 static void
   2845 I830LeaveVT(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  */
   2910 static Bool
   2911 I830EnterVT(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 
   3039 static Bool
   3040 I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
   3041 {
   3042    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
   3043 
   3044    return xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
   3045 }
   3046 
   3047 static Bool
   3048 I830CloseScreen(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 
   3105 static ModeStatus
   3106 I830ValidMode(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  */
   3130 static Bool
   3131 I830PMEvent(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 
   3187 xf86CrtcPtr
   3188 i830_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 
   3204 void
   3205 I830InitpScrn(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