xf86-video-intel: 6 commits - src/i830_accel.c src/i830_driver.c src/i830_memory.c

Zhenyu Wang zhen at kemper.freedesktop.org
Wed Mar 5 19:53:24 PST 2008


 src/i830_accel.c  |    3 
 src/i830_driver.c |  763 ++++++++++++++++++++++++++++--------------------------
 src/i830_memory.c |    2 
 3 files changed, 400 insertions(+), 368 deletions(-)

New commits:
commit 502e41f6dff91393cfeaf08c9ba312781d1b7267
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Mar 6 19:32:29 2008 +0800

    remove extra dri checking
    
    And directRenderingDisabled already has config check result.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 2ba69b6..854e377 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2663,11 +2663,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    }
 
 #ifdef XF86DRI
-   /* Check for appropriate bpp and module support to initialize DRI. */
-   if (!I830CheckDRIAvailable(pScrn)) {
-      pI830->directRenderingDisabled = TRUE;
-   }
-
    /* If DRI hasn't been explicitly disabled, try to initialize it.
     * It will be used by the memory allocator.
     */
commit ea58d66cf778c0477c30e5bfe3142b64e8b971d5
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Mar 6 19:31:33 2008 +0800

    No ring, no sync

diff --git a/src/i830_accel.c b/src/i830_accel.c
index 7501c2b..fdc713b 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -173,6 +173,9 @@ I830Sync(ScrnInfoPtr pScrn)
    if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC))
       ErrorF("I830Sync\n");
 
+   if (pI830->noAccel)
+       return;
+
 #ifdef XF86DRI
    /* VT switching tries to do this.
     */
commit c823fb00a20f523f50a2779c36aa1c014ba01535
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Thu Mar 6 19:29:22 2008 +0800

    Pull chipset detection out of PreInit into its own function

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 9b671a2..2ba69b6 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1036,6 +1036,211 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode)
    pI830->writeControl(pI830, GRX, 0x18, gr18);
 }
 
+static Bool
+i830_detect_chipset(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    MessageType from = X_PROBED;
+    const char *chipname;
+    uint32_t capid;
+    int fb_bar, mmio_bar;
+
+    switch (DEVICE_ID(pI830->PciInfo)) {
+    case PCI_CHIP_I830_M:
+	chipname = "830M";
+	break;
+    case PCI_CHIP_845_G:
+	chipname = "845G";
+	break;
+    case PCI_CHIP_I855_GM:
+	/* Check capid register to find the chipset variant */
+#if XSERVER_LIBPCIACCESS
+	pci_device_cfg_read_u32 (pI830->PciInfo, &capid, I85X_CAPID);
+#else
+	capid = pciReadLong (pI830->PciTag, I85X_CAPID);
+#endif
+	pI830->variant = (capid >> I85X_VARIANT_SHIFT) & I85X_VARIANT_MASK;
+	switch (pI830->variant) {
+	case I855_GM:
+	    chipname = "855GM";
+	    break;
+	case I855_GME:
+	    chipname = "855GME";
+	    break;
+	case I852_GM:
+	    chipname = "852GM";
+	    break;
+	case I852_GME:
+	    chipname = "852GME";
+	    break;
+	default:
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "Unknown 852GM/855GM variant: 0x%x)\n", pI830->variant);
+	    chipname = "852GM/855GM (unknown variant)";
+	    break;
+	}
+	break;
+    case PCI_CHIP_I865_G:
+	chipname = "865G";
+	break;
+    case PCI_CHIP_I915_G:
+	chipname = "915G";
+	break;
+    case PCI_CHIP_E7221_G:
+	chipname = "E7221 (i915)";
+	break;
+    case PCI_CHIP_I915_GM:
+	chipname = "915GM";
+	break;
+    case PCI_CHIP_I945_G:
+	chipname = "945G";
+	break;
+    case PCI_CHIP_I945_GM:
+	chipname = "945GM";
+	break;
+    case PCI_CHIP_I945_GME:
+	chipname = "945GME";
+	break;
+    case PCI_CHIP_I965_G:
+	chipname = "965G";
+	break;
+    case PCI_CHIP_G35_G:
+	chipname = "G35";
+	break;
+    case PCI_CHIP_I965_Q:
+	chipname = "965Q";
+	break;
+    case PCI_CHIP_I946_GZ:
+	chipname = "946GZ";
+	break;
+    case PCI_CHIP_I965_GM:
+	chipname = "965GM";
+	break;
+    case PCI_CHIP_I965_GME:
+	chipname = "965GME/GLE";
+	break;
+    case PCI_CHIP_G33_G:
+	chipname = "G33";
+	break;
+    case PCI_CHIP_Q35_G:
+	chipname = "Q35";
+	break;
+    case PCI_CHIP_Q33_G:
+	chipname = "Q33";
+	break;
+    case PCI_CHIP_IGD_GM:
+	chipname = "Intel Integrated Graphics Device";
+	break;
+   default:
+	chipname = "unknown chipset";
+	break;
+    }
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Integrated Graphics Chipset: Intel(R) %s\n", chipname);
+
+    /* Set the Chipset and ChipRev, allowing config file entries to override. */
+    if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) {
+	pScrn->chipset = pI830->pEnt->device->chipset;
+	from = X_CONFIG;
+    } else if (pI830->pEnt->device->chipID >= 0) {
+	pScrn->chipset = (char *)xf86TokenToString(I830Chipsets,
+						   pI830->pEnt->device->chipID);
+	from = X_CONFIG;
+	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+		   pI830->pEnt->device->chipID);
+	DEVICE_ID(pI830->PciInfo) = pI830->pEnt->device->chipID;
+    } else {
+	from = X_PROBED;
+	pScrn->chipset = (char *)xf86TokenToString(I830Chipsets,
+						   DEVICE_ID(pI830->PciInfo));
+    }
+
+    if (pI830->pEnt->device->chipRev >= 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+		   pI830->pEnt->device->chipRev);
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
+	       (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx");
+
+    /* Now that we know the chipset, figure out the resource base addrs */
+    if (IS_I9XX(pI830)) {
+	fb_bar = 2;
+	mmio_bar = 0;
+    } else {
+	fb_bar = 0;
+	mmio_bar = 1;
+    }
+
+    if (pI830->pEnt->device->MemBase != 0) {
+	pI830->LinearAddr = pI830->pEnt->device->MemBase;
+	from = X_CONFIG;
+    } else {
+	pI830->LinearAddr = I810_MEMBASE (pI830->PciInfo, fb_bar);
+	if (pI830->LinearAddr == 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "No valid FB address in PCI config space\n");
+	    PreInitCleanup(pScrn);
+	    return FALSE;
+	}
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+	       (unsigned long)pI830->LinearAddr);
+
+    if (pI830->pEnt->device->IOBase != 0) {
+	pI830->MMIOAddr = pI830->pEnt->device->IOBase;
+	from = X_CONFIG;
+    } else {
+	pI830->MMIOAddr = I810_MEMBASE (pI830->PciInfo, mmio_bar);
+	if (pI830->MMIOAddr == 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "No valid MMIO address in PCI config space\n");
+	    PreInitCleanup(pScrn);
+	    return FALSE;
+	}
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n",
+	       (unsigned long)pI830->MMIOAddr);
+
+    /* Now figure out mapsize on 8xx chips */
+    if (IS_I830(pI830) || IS_845G(pI830)) {
+#if XSERVER_LIBPCIACCESS
+	uint16_t		gmch_ctrl;
+	struct pci_device *bridge;
+
+	bridge = intel_host_bridge ();
+	pci_device_cfg_read_u16 (bridge, &gmch_ctrl, I830_GMCH_CTRL);
+#else
+	PCITAG bridge;
+	CARD16 gmch_ctrl;
+
+	bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
+	gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
+#endif
+	if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
+	    pI830->FbMapSize = 0x8000000;
+	} else {
+	    pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */
+	}
+    } else {
+	if (IS_I9XX(pI830)) {
+#if XSERVER_LIBPCIACCESS
+	    pI830->FbMapSize = pI830->PciInfo->regions[fb_bar].size;
+#else
+	    pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE,
+						     NULL);
+#endif
+	} else {
+	    /* 128MB aperture for later i8xx series. */
+	    pI830->FbMapSize = 0x8000000;
+	}
+    }
+
+    return TRUE;
+}
+
 /**
  * This is called per zaphod head (so usually just once) to do initialization
  * before the Screen is created.
@@ -1057,11 +1262,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
    int i;
    char *s;
    pointer pVBEModule = NULL;
-   const char *chipname;
    int num_pipe;
    int max_width, max_height;
-   uint32_t	capid;
-   int fb_bar, mmio_bar;
 
    if (pScrn->numEntities != 1)
       return FALSE;
@@ -1201,166 +1403,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
    /* We have to use PIO to probe, because we haven't mapped yet. */
    I830SetPIOAccess(pI830);
 
-   switch (DEVICE_ID(pI830->PciInfo)) {
-   case PCI_CHIP_I830_M:
-      chipname = "830M";
-      break;
-   case PCI_CHIP_845_G:
-      chipname = "845G";
-      break;
-   case PCI_CHIP_I855_GM:
-      /* Check capid register to find the chipset variant */
-#if XSERVER_LIBPCIACCESS
-      pci_device_cfg_read_u32 (pI830->PciInfo, &capid, I85X_CAPID);
-#else
-      capid = pciReadLong (pI830->PciTag, I85X_CAPID);
-#endif
-      pI830->variant = (capid >> I85X_VARIANT_SHIFT) & I85X_VARIANT_MASK;
-      switch (pI830->variant) {
-      case I855_GM:
-	 chipname = "855GM";
-	 break;
-      case I855_GME:
-	 chipname = "855GME";
-	 break;
-      case I852_GM:
-	 chipname = "852GM";
-	 break;
-      case I852_GME:
-	 chipname = "852GME";
-	 break;
-      default:
-	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		    "Unknown 852GM/855GM variant: 0x%x)\n", pI830->variant);
-	 chipname = "852GM/855GM (unknown variant)";
-	 break;
-      }
-      break;
-   case PCI_CHIP_I865_G:
-      chipname = "865G";
-      break;
-   case PCI_CHIP_I915_G:
-      chipname = "915G";
-      break;
-   case PCI_CHIP_E7221_G:
-      chipname = "E7221 (i915)";
-      break;
-   case PCI_CHIP_I915_GM:
-      chipname = "915GM";
-      break;
-   case PCI_CHIP_I945_G:
-      chipname = "945G";
-      break;
-   case PCI_CHIP_I945_GM:
-      chipname = "945GM";
-      break;
-   case PCI_CHIP_I945_GME:
-      chipname = "945GME";
-      break;
-   case PCI_CHIP_I965_G:
-      chipname = "965G";
-      break;
-   case PCI_CHIP_G35_G:
-      chipname = "G35";
-      break;
-   case PCI_CHIP_I965_Q:
-      chipname = "965Q";
-      break;
-   case PCI_CHIP_I946_GZ:
-      chipname = "946GZ";
-      break;
-   case PCI_CHIP_I965_GM:
-      chipname = "965GM";
-      break;
-   case PCI_CHIP_I965_GME:
-      chipname = "965GME/GLE";
-      break;
-   case PCI_CHIP_G33_G:
-      chipname = "G33";
-      break;
-   case PCI_CHIP_Q35_G:
-      chipname = "Q35";
-      break;
-   case PCI_CHIP_Q33_G:
-      chipname = "Q33";
-      break;
-   case PCI_CHIP_IGD_GM:
-      chipname = "Intel Integrated Graphics Device";
-      break;
-   default:
-      chipname = "unknown chipset";
-      break;
-   }
-   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	      "Integrated Graphics Chipset: Intel(R) %s\n", chipname);
-
-   /* Set the Chipset and ChipRev, allowing config file entries to override. */
-   if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) {
-      pScrn->chipset = pI830->pEnt->device->chipset;
-      from = X_CONFIG;
-   } else if (pI830->pEnt->device->chipID >= 0) {
-      pScrn->chipset = (char *)xf86TokenToString(I830Chipsets,
-						 pI830->pEnt->device->chipID);
-      from = X_CONFIG;
-      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
-		 pI830->pEnt->device->chipID);
-      DEVICE_ID(pI830->PciInfo) = pI830->pEnt->device->chipID;
-   } else {
-      from = X_PROBED;
-      pScrn->chipset = (char *)xf86TokenToString(I830Chipsets,
-						 DEVICE_ID(pI830->PciInfo));
-   }
-
-   if (pI830->pEnt->device->chipRev >= 0) {
-      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
-		 pI830->pEnt->device->chipRev);
-   }
-
-   xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
-	      (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx");
-
-   if (IS_I9XX(pI830))
-   {
-      fb_bar = 2;
-      mmio_bar = 0;
-   }
-   else
-   {
-      fb_bar = 0;
-      mmio_bar = 1;
-   }
-
-   if (pI830->pEnt->device->MemBase != 0) {
-      pI830->LinearAddr = pI830->pEnt->device->MemBase;
-      from = X_CONFIG;
-   } else {
-      pI830->LinearAddr = I810_MEMBASE (pI830->PciInfo, fb_bar);
-      if (pI830->LinearAddr == 0) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		    "No valid FB address in PCI config space\n");
-	 PreInitCleanup(pScrn);
-	 return FALSE;
-      }
-   }
-
-   xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
-	      (unsigned long)pI830->LinearAddr);
-
-   if (pI830->pEnt->device->IOBase != 0) {
-      pI830->MMIOAddr = pI830->pEnt->device->IOBase;
-      from = X_CONFIG;
-   } else {
-      pI830->MMIOAddr = I810_MEMBASE (pI830->PciInfo, mmio_bar);
-      if (pI830->MMIOAddr == 0) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		    "No valid MMIO address in PCI config space\n");
-	 PreInitCleanup(pScrn);
-	 return FALSE;
-      }
-   }
-
-   xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n",
-	      (unsigned long)pI830->MMIOAddr);
+   if (!i830_detect_chipset(pScrn))
+       return FALSE;
 
    /* check quirks */
    i830_fixup_devices(pScrn);
@@ -1380,39 +1424,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
    }
    xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height);
 
-   if (IS_I830(pI830) || IS_845G(pI830)) {
-#if XSERVER_LIBPCIACCESS
-      uint16_t		gmch_ctrl;
-      struct pci_device *bridge;
-
-      bridge = intel_host_bridge ();
-      pci_device_cfg_read_u16 (bridge, &gmch_ctrl, I830_GMCH_CTRL);
-#else
-      PCITAG bridge;
-      CARD16 gmch_ctrl;
-
-      bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
-      gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
-#endif
-      if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
-	 pI830->FbMapSize = 0x8000000;
-      } else {
-	 pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */
-      }
-   } else {
-      if (IS_I9XX(pI830)) {
-#if XSERVER_LIBPCIACCESS
-	 pI830->FbMapSize = pI830->PciInfo->regions[fb_bar].size;
-#else
-	 pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE,
-						  NULL);
-#endif
-      } else {
-	 /* 128MB aperture for later i8xx series. */
-	 pI830->FbMapSize = 0x8000000;
-      }
-   }
-
    /* Some of the probing needs MMIO access, so map it here. */
    I830MapMMIO(pScrn);
 
commit 6b16cee0786b636dc849826193b26e898832a73c
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Thu Mar 6 19:27:42 2008 +0800

    Account for FBC LL cache in memory reservation
    
    When we reserve memory (memory that won't be managed by the kernel) make
    sure to reserve space for the FBC LL cache as well.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 1861c64..ad34f19 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -470,7 +470,7 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 		    ROUND_TO(HWCURSOR_SIZE_ARGB, GTT_PAGE_SIZE));
 	}
 	if (pI830->fb_compression)
-	    mmsize -= MB(6);
+	    mmsize -= MB(6) + ROUND_TO_PAGE(FBC_LL_SIZE + FBC_LL_PAD);
 	/* Can't do TTM on stolen memory */
 	mmsize -= pI830->stolen_size;
 
commit 6f04d02471f1cebc76eab637a9a78c4004fd3cc9
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Thu Mar 6 19:27:07 2008 +0800

    Move MTRR fixup to its own routine

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 0aaf9df..9b671a2 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2365,6 +2365,50 @@ I830BlockHandler(int i,
     I830VideoBlockHandler(i, blockData, pTimeout, pReadmask);
 }
 
+static void
+i830_fixup_mtrrs(ScrnInfoPtr pScrn)
+{
+#ifdef HAS_MTRR_SUPPORT
+    I830Ptr pI830 = I830PTR(pScrn);
+    int fd;
+    struct mtrr_gentry gentry;
+    struct mtrr_sentry sentry;
+
+    if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) != -1 ) {
+	for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
+		++gentry.regnum) {
+
+	    if (gentry.size < 1) {
+		/* DISABLED */
+		continue;
+	    }
+
+	    /* Check the MTRR range is one we like and if not - remove it.
+	     * The Xserver common layer will then setup the right range
+	     * for us.
+	     */
+	    if (gentry.base == pI830->LinearAddr && 
+		    gentry.size < pI830->FbMapSize) {
+
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			"Removing bad MTRR range (base 0x%lx, size 0x%x)\n",
+			gentry.base, gentry.size);
+
+		sentry.base = gentry.base;
+		sentry.size = gentry.size;
+		sentry.type = gentry.type;
+
+		if (ioctl (fd, MTRRIOC_DEL_ENTRY, &sentry) == -1) {
+		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			    "Failed to remove bad MTRR range\n");
+		}
+	    }
+	}
+	close(fd);
+    }
+#endif
+}
+
 static Bool
 i830_try_memory_allocation(ScrnInfoPtr pScrn)
 {
@@ -2707,46 +2751,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 
    I830UnmapMMIO(pScrn);
 
-#ifdef HAS_MTRR_SUPPORT
-   {
-      int fd;
-      struct mtrr_gentry gentry;
-      struct mtrr_sentry sentry;
-
-      if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) != -1 ) {
-         for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
-	      ++gentry.regnum) {
-
-	    if (gentry.size < 1) {
-	       /* DISABLED */
-	       continue;
-	    }
-
-            /* Check the MTRR range is one we like and if not - remove it.
-             * The Xserver common layer will then setup the right range
-             * for us.
-             */
-	    if (gentry.base == pI830->LinearAddr && 
-	        gentry.size < pI830->FbMapSize) {
-
-               xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		  "Removing bad MTRR range (base 0x%lx, size 0x%x)\n",
-		  gentry.base, gentry.size);
-
-    	       sentry.base = gentry.base;
-               sentry.size = gentry.size;
-               sentry.type = gentry.type;
-
-               if (ioctl (fd, MTRRIOC_DEL_ENTRY, &sentry) == -1) {
-                  xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		     "Failed to remove bad MTRR range\n");
-               }
-	    }
-         }
-         close(fd);
-      }
-   }
-#endif
+   i830_fixup_mtrrs(pScrn);
 
    pI830->starting = TRUE;
 
commit 750beb9232b51223d8e650878ce8dad071f0d0b3
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Thu Mar 6 19:24:47 2008 +0800

    Refactor memory allocation into a separate function
    
    This simplifies the memory allocation code and fixes a number of bugs.
    Prior to this change, some flags may have been set after memory
    allocation occurred, meaning they had no effect.  It should also make
    the allocation logic clearer.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5cd0a34..0aaf9df 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2366,6 +2366,141 @@ I830BlockHandler(int i,
 }
 
 static Bool
+i830_try_memory_allocation(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    Bool tiled = pI830->tiling;
+    Bool dri = pI830->directRenderingEnabled;
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	    "Attempting memory allocation with %stiled buffers.\n",
+	    tiled ? "" : "un");
+
+    if (!i830_allocate_2d_memory(pScrn))
+	goto failed;
+
+    if (dri && !i830_allocate_3d_memory(pScrn))
+	goto failed;
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%siled allocation successful.\n",
+	    tiled ? "T" : "Unt");
+    return TRUE;
+
+failed:
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%siled allocation failed.\n",
+	    tiled ? "T" : "Unt");
+    return FALSE;
+}
+
+/*
+ * Try to allocate memory in several ways:
+ *  1) If direct rendering is enabled, try to allocate enough memory for tiled
+ *     surfaces by rounding up the display width to a tileable one.
+ *  2) If that fails or the allocations themselves fail, try again with untiled
+ *     allocations (if this works DRI will stay enabled).
+ *  3) And if all else fails, disable DRI and try just 2D allocations.
+ *  4) Give up and fail ScreenInit.
+ */
+static Bool
+i830_memory_init(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int savedDisplayWidth = pScrn->displayWidth;
+    int i;
+    Bool tiled = FALSE;
+
+    /*
+     * Adjust the display width to allow for front buffer tiling if possible
+     */
+    if (pI830->tiling) {
+	if (IS_I965G(pI830)) {
+	    int tile_pixels = 512 / pI830->cpp;
+	    pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) &
+		~(tile_pixels - 1);
+	    tiled = TRUE;
+	} else {
+	    /* Good pitches to allow tiling.  Don't care about pitches < 1024
+	     * pixels.
+	     */
+	    static const int pitches[] = {
+		1024,
+		2048,
+		4096,
+		8192,
+		0
+	    };
+
+	    for (i = 0; pitches[i] != 0; i++) {
+		if (pitches[i] >= pScrn->displayWidth) {
+		    pScrn->displayWidth = pitches[i];
+		    tiled = TRUE;
+		    break;
+		}
+	    }
+	}
+    }
+    /* Set up our video memory allocator for the chosen videoRam */
+    if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		"Couldn't initialize video memory allocator\n");
+	PreInitCleanup(pScrn);
+	return FALSE;
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex,
+	    pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT,
+	    "VideoRam: %d KB\n", pScrn->videoRam);
+
+    if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES,
+		&(pI830->CacheLines))) {
+	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n",
+		pI830->CacheLines);
+    } else {
+	pI830->CacheLines = -1;
+    }
+
+    /* Tiled first if we got a good displayWidth */
+    if (tiled) {
+	if (i830_try_memory_allocation(pScrn))
+	    return TRUE;
+	else {
+	    i830_reset_allocations(pScrn);
+	    pI830->tiling = FALSE;
+	}
+    }
+
+    /* If tiling fails we have to disable page flipping & FBC */
+    pScrn->displayWidth = savedDisplayWidth;
+    if (pI830->allowPageFlip)
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		"Couldn't allocate tiled memory, page flipping "
+		"disabled\n");
+    pI830->allowPageFlip = FALSE;
+    if (pI830->fb_compression)
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		"Couldn't allocate tiled memory, fb compression "
+		"disabled\n");
+    pI830->fb_compression = FALSE;
+
+    /* Try again, but leave DRI enabled */
+    if (pI830->directRenderingEnabled) {
+	if (i830_try_memory_allocation(pScrn))
+	    return TRUE;
+	else {
+	    i830_reset_allocations(pScrn);
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Couldn't allocate 3D memory, "
+		    "disabling DRI.\n");
+	    pI830->directRenderingEnabled = FALSE;
+	}
+    }
+
+    if (i830_try_memory_allocation(pScrn))
+	return TRUE;
+
+    return FALSE;
+}
+
+static Bool
 I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 {
    ScrnInfoPtr pScrn;
@@ -2374,8 +2509,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    VisualPtr visual;
    I830Ptr pI8301 = NULL;
    unsigned long sys_mem;
-   int i, c;
-   Bool allocation_done = FALSE;
+   int c;
    MessageType from;
 #ifdef XF86DRI
    xf86CrtcConfigPtr config;
@@ -2490,26 +2624,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    pI830->directRenderingEnabled = FALSE;
 #endif
 
-   /* Set up our video memory allocator for the chosen videoRam */
-   if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) {
-      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		 "Couldn't initialize video memory allocator\n");
-      PreInitCleanup(pScrn);
-      return FALSE;
-   }
-
-   xf86DrvMsg(pScrn->scrnIndex,
-	      pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT,
-	      "VideoRam: %d KB\n", pScrn->videoRam);
-
-   if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES,
-			    &(pI830->CacheLines))) {
-      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n",
-		 pI830->CacheLines);
-   } else {
-      pI830->CacheLines = -1;
-   }
-
    /* Enable tiling by default */
    pI830->tiling = TRUE;
 
@@ -2567,16 +2681,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
       pI830->last_3d = pI8301->last_3d;
    }
 
-   /* Need MMIO mapped to do GTT lookups during memory allocation. */
-   I830MapMMIO(pScrn);
-
-#if defined(XF86DRI)
-   /*
-    * If DRI is potentially usable, check if there is enough memory available
-    * for it, and if there's also enough to allow tiling to be enabled.
-    */
-
-
 #ifdef I830_XV
     /*
      * Set this so that the overlay allocation is factored in when
@@ -2585,103 +2689,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     pI830->XvEnabled = !pI830->XvDisabled;
 #endif
 
-   if (pI830->directRenderingEnabled) {
-      int savedDisplayWidth = pScrn->displayWidth;
-      Bool tiled = FALSE;
-
-      if (IS_I965G(pI830)) {
-	 int tile_pixels = 512 / pI830->cpp;
-	 pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) &
-	    ~(tile_pixels - 1);
-	 tiled = TRUE;
-      } else {
-	 /* Good pitches to allow tiling.  Don't care about pitches < 1024
-	  * pixels.
-	  */
-	 static const int pitches[] = {
-	    1024,
-	    2048,
-	    4096,
-	    8192,
-	    0
-	 };
-
-	 for (i = 0; pitches[i] != 0; i++) {
-	    if (pitches[i] >= pScrn->displayWidth) {
-	       pScrn->displayWidth = pitches[i];
-	       tiled = TRUE;
-	       break;
-	    }
-	 }
-      }
-
-      /* Attempt two rounds of allocation to get 2d and 3d memory to fit:
-       *
-       * 0: untiled
-       * 1: tiled
-       */
-
-#define MM_TURNS 2
-      for (i = 0; i < MM_TURNS; i++) {
-	 if (!tiled && i == 0)
-	    continue;
-
-	 if (i >= 1) {
-	    /* For further allocations, disable tiling */
-	    pI830->tiling = FALSE;
-	    pScrn->displayWidth = savedDisplayWidth;
-	    if (pI830->allowPageFlip)
-	       xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-			  "Couldn't allocate tiled memory, page flipping "
-			  "disabled\n");
-	    pI830->allowPageFlip = FALSE;
-	    if (pI830->fb_compression)
-	       xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-			  "Couldn't allocate tiled memory, fb compression "
-			  "disabled\n");
-	    pI830->fb_compression = FALSE;
-	 }
-
-	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		    "Attempting memory allocation with %s buffers.\n",
-		    (i & 1) ? "untiled" : "tiled");
-
-	 if (i830_allocate_2d_memory(pScrn) &&
-	     i830_allocate_3d_memory(pScrn))
-	 {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Success.\n");
-	    if (pScrn->displayWidth != savedDisplayWidth) {
-	       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-			  "Increasing the scanline pitch to allow tiling mode "
-			  "(%d -> %d).\n",
-			  savedDisplayWidth, pScrn->displayWidth);
-	    }
-	    allocation_done = TRUE;
-	    break;
-	 }
-
-	 i830_reset_allocations(pScrn);
-      }
-
-      if (i == MM_TURNS) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		    "Not enough video memory.  Disabling DRI.\n");
-	 pI830->directRenderingEnabled = FALSE;
-      }
-   }
-#endif
-
-   if (!allocation_done) {
-      if (!i830_allocate_2d_memory(pScrn)) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		    "Couldn't allocate video memory\n");
-	 return FALSE;
-      }
-      allocation_done = TRUE;
-   }
-
-   I830UnmapMMIO(pScrn);
-
    if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		 "Cannot support DRI with frame buffer width > 2048.\n");
@@ -2689,6 +2696,17 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
       pI830->directRenderingEnabled = FALSE;
    }
 
+   /* Need MMIO mapped to do GTT lookups during memory allocation. */
+   I830MapMMIO(pScrn);
+
+   if (!i830_memory_init(pScrn)) {
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+	       "Couldn't allocate video memory\n");
+       return FALSE;
+   }
+
+   I830UnmapMMIO(pScrn);
+
 #ifdef HAS_MTRR_SUPPORT
    {
       int fd;


More information about the xorg-commit mailing list