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