コード例 #1
0
Bool
I810UnbindGARTMemory(ScrnInfoPtr pScrn)
{
   I810Ptr pI810 = I810PTR(pScrn);

   if (xf86AgpGARTSupported() && !pI810->directRenderingEnabled
       && pI810->GttBound) {
      if (pI810->VramKey != -1
	  && !xf86UnbindGARTMemory(pScrn->scrnIndex, pI810->VramKey))
	 return FALSE;

      if (pI810->DcacheKey != -1
	  && !xf86UnbindGARTMemory(pScrn->scrnIndex, pI810->DcacheKey))
	 return FALSE;

      if (pI810->HwcursKey != -1
	  && !xf86UnbindGARTMemory(pScrn->scrnIndex, pI810->HwcursKey))
	 return FALSE;

      if (pI810->ARGBHwcursKey != -1
	  && !xf86UnbindGARTMemory(pScrn->scrnIndex, pI810->ARGBHwcursKey))
	 return FALSE;

      if (!xf86ReleaseGART(pScrn->scrnIndex))
	 return FALSE;

      pI810->GttBound = 0;
   }

   return TRUE;
}
コード例 #2
0
Bool
I810BindGARTMemory(ScrnInfoPtr pScrn)
{
   I810Ptr pI810 = I810PTR(pScrn);

   if (xf86AgpGARTSupported() && !pI810->directRenderingEnabled
       && !pI810->GttBound) {
      if (!xf86AcquireGART(pScrn->scrnIndex))
	 return FALSE;

      if (pI810->VramKey != -1
	  && !xf86BindGARTMemory(pScrn->scrnIndex, pI810->VramKey,
				 pI810->VramOffset))
	 return FALSE;

      if (pI810->DcacheKey != -1
	  && !xf86BindGARTMemory(pScrn->scrnIndex, pI810->DcacheKey,
				 pI810->DcacheOffset))
	 return FALSE;

      if (pI810->HwcursKey != -1
	  && !xf86BindGARTMemory(pScrn->scrnIndex, pI810->HwcursKey,
				 pI810->HwcursOffset))
	 return FALSE;

      if (pI810->ARGBHwcursKey != -1
	  && !xf86BindGARTMemory(pScrn->scrnIndex, pI810->ARGBHwcursKey,
				 pI810->ARGBHwcursOffset))
	 return FALSE;

      pI810->GttBound = 1;
   }

   return TRUE;
}
コード例 #3
0
ファイル: i830_memory.c プロジェクト: gvsurenderreddy/theqvd
Bool
I830UnbindGARTMemory(ScrnInfoPtr pScrn)
{
   I830Ptr pI830 = I830PTR(pScrn);

   DPRINTF(PFX,
	   "I830UnbindGARTMemory: StolenOnly is %s, pI830->GttBound is %s\n",
	   BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound));

   if (pI830->StolenOnly == TRUE)
      return TRUE;

   if (xf86AgpGARTSupported() && pI830->GttBound) {

#if REMAP_RESERVED
      /* "unbind" the pre-allocated region. */
      UnbindMemRange(pScrn, &(pI830->Dummy));
#endif

      if (!UnbindMemRange(pScrn, &(pI830->StolenPool.Allocated)))
	 return FALSE;
      if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer)))
	 return FALSE;
      if (!UnbindMemRange(pScrn, &(pI830->CursorMem)))
	 return FALSE;
      if (!UnbindMemRange(pScrn, &(pI830->LpRing.mem)))
	 return FALSE;
      if (!UnbindMemRange(pScrn, &(pI830->Scratch)))
	 return FALSE;
#ifdef I830_XV
      if (!UnbindMemRange(pScrn, &(pI830->OverlayMem)))
	 return FALSE;
#endif
#ifdef XF86DRI
      if (pI830->directRenderingEnabled) {
	 if (!UnbindMemRange(pScrn, &(pI830->BackBuffer)))
	    return FALSE;
	 if (!UnbindMemRange(pScrn, &(pI830->DepthBuffer)))
	    return FALSE;
	 if (!UnbindMemRange(pScrn, &(pI830->ContextMem)))
	    return FALSE;
	 if (!UnbindMemRange(pScrn, &(pI830->BufferMem)))
	    return FALSE;
	 if (!UnbindMemRange(pScrn, &(pI830->TexMem)))
	    return FALSE;
      }
#endif
      if (!xf86ReleaseGART(pScrn->scrnIndex))
	 return FALSE;

      pI830->GttBound = 0;
   }

   return TRUE;
}
コード例 #4
0
int
I810CheckAvailableMemory(ScrnInfoPtr pScrn)
{
   AgpInfoPtr agpinf;
   int maxPages;

   if (!xf86AgpGARTSupported() ||
       !xf86AcquireGART(pScrn->scrnIndex) ||
       (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL ||
       !xf86ReleaseGART(pScrn->scrnIndex))
      return -1;

   maxPages = agpinf->totalPages - agpinf->usedPages;
   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %dk available\n",
		  "I810CheckAvailableMemory", maxPages * 4);

   return maxPages * 4;
}
コード例 #5
0
int
I810AllocateGARTMemory(ScrnInfoPtr pScrn)
{
   unsigned long size = pScrn->videoRam * 1024;
   I810Ptr pI810 = I810PTR(pScrn);
   int key;
   long tom = 0;
   unsigned long physical;

   if (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex)) {
      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		 "AGP GART support is either not available or cannot be used.\n"
		 "\tMake sure your kernel has agpgart support or has the\n"
		 "\tagpgart module loaded.\n");
      return FALSE;
   }

   /* This allows the 2d only Xserver to regen */
   pI810->agpAcquired2d = TRUE;

   /*
    * I810/I815
    *
    * Treat the gart like video memory - we assume we own all that is
    * there, so ignore EBUSY errors.  Don't try to remove it on
    * failure, either, as other X server may be using it.
    */

   if ((key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL)) == -1)
      return FALSE;

   pI810->VramOffset = 0;
   pI810->VramKey = key;

   if (!xf86BindGARTMemory(pScrn->scrnIndex, key, 0))
      return FALSE;

   pI810->SysMem.Start = 0;
   pI810->SysMem.Size = size;
   pI810->SysMem.End = size;
   pI810->SavedSysMem = pI810->SysMem;

   tom = pI810->SysMem.End;

   pI810->DcacheMem.Start = 0;
   pI810->DcacheMem.End = 0;
   pI810->DcacheMem.Size = 0;
   pI810->CursorPhysical = 0;
   pI810->CursorARGBPhysical = 0;

   /*
    * Dcache - half the speed of normal ram, so not really useful for
    * a 2d server.  Don't bother reporting its presence.  This is
    * mapped in addition to the requested amount of system ram.
    */

   size = 1024 * 4096;

   /*
    * Keep it 512K aligned for the sake of tiled regions.
    */

   tom += 0x7ffff;
   tom &= ~0x7ffff;

   if ((key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 1, NULL)) != -1) {
      pI810->DcacheOffset = tom;
      pI810->DcacheKey = key;
      if (!xf86BindGARTMemory(pScrn->scrnIndex, key, tom)) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "Allocation of %ld bytes for DCACHE failed\n", size);
	 pI810->DcacheKey = -1;
      } else {
	 pI810->DcacheMem.Start = tom;
	 pI810->DcacheMem.Size = size;
	 pI810->DcacheMem.End = pI810->DcacheMem.Start + pI810->DcacheMem.Size;
	 tom = pI810->DcacheMem.End;
      }
   } else {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "No physical memory available for %ld bytes of DCACHE\n",
		 size);
      pI810->DcacheKey = -1;
   }

   /*
    * Mouse cursor -- The i810 (crazy) needs a physical address in
    * system memory from which to upload the cursor.  We get this from
    * the agpgart module using a special memory type.
    */

   /*
    * 4k for the cursor is excessive, I'm going to steal 3k for
    * overlay registers later
    */

   size = 4096;

   if ((key =
	xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, &physical)) == -1) {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "No physical memory available for HW cursor\n");
      pI810->HwcursKey = -1;
      pI810->CursorStart = 0;
   } else {
      pI810->HwcursOffset = tom;
      pI810->HwcursKey = key;
      if (!xf86BindGARTMemory(pScrn->scrnIndex, key, tom)) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "Allocation of %ld bytes for HW cursor failed\n", size);
	 pI810->HwcursKey = -1;
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "Allocated of %ld bytes for HW cursor\n", size);
	 pI810->CursorPhysical = physical;
	 pI810->CursorStart = tom;
	 tom += size;
      }
   }

   /*
    * 16k for the ARGB cursor
    */

   size = 16384;

   if ((key =
	xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, &physical)) == -1) {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "No physical memory available for ARGB HW cursor\n");
      pI810->ARGBHwcursKey = -1;
      pI810->CursorARGBStart = 0;
   } else {
      pI810->ARGBHwcursOffset = tom;
      pI810->ARGBHwcursKey = key;
      if (!xf86BindGARTMemory(pScrn->scrnIndex, key, tom)) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "Allocation of %ld bytes for ARGB HW cursor failed\n", size);
	 pI810->ARGBHwcursKey = -1;
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "Allocated of %ld bytes for ARGB HW cursor\n", size);
	 pI810->CursorARGBPhysical = physical;
	 pI810->CursorARGBStart = tom;
	 tom += size;
      }
   }

   /*
    * Overlay register buffer -- Just like the cursor, the i810 needs a
    * physical address in system memory from which to upload the overlay
    * registers.
    */

   if (pI810->CursorStart != 0) {
      pI810->OverlayPhysical = pI810->CursorPhysical + 1024;
      pI810->OverlayStart = pI810->CursorStart + 1024;
   }

   pI810->GttBound = 1;

   return TRUE;
}
コード例 #6
0
ファイル: i830_memory.c プロジェクト: gvsurenderreddy/theqvd
Bool
I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
{
   I830Ptr pI830 = I830PTR(pScrn);
   unsigned long size, alloced;
   Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
   int verbosity = dryrun ? 4 : 1;
   const char *s = dryrun ? "[dryrun] " : "";
   Bool tileable;
   int align, alignflags;

   DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n",
	   BOOLTOSTRING(flags & ALLOC_INITIAL));

   if (!pI830->StolenOnly &&
       (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) {
      if (!dryrun) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "AGP GART support is either not available or cannot "
		    "be used.\n"
		    "\tMake sure your kernel has agpgart support or has the\n"
		    "\tagpgart module loaded.\n");
      }
      return FALSE;
   }


   /*
    * The I830 is slightly different from the I830/I815, it has no
    * dcache and it has stolen memory by default in its gtt.  All
    * additional memory must go after it.
    */

   DPRINTF(PFX,
	   "size == %luk (%lu bytes == pScrn->videoRam)\n"
	   "pI830->StolenSize == %luk (%lu bytes)\n",
	   pScrn->videoRam, pScrn->videoRam * 1024,
	   pI830->StolenPool.Free.Size / 1024,
	   pI830->StolenPool.Free.Size);

   if (flags & ALLOC_INITIAL) {
      unsigned long minspace, avail, lineSize;
      int cacheLines, maxCacheLines;

      if (pI830->NeedRingBufferLow)
	 AllocateRingBuffer(pScrn, flags | FORCE_LOW);

      /* Clear everything first. */
      memset(&(pI830->FbMemBox), 0, sizeof(pI830->FbMemBox));
      memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer));
      pI830->FrontBuffer.Key = -1;

      pI830->FbMemBox.x1 = 0;
      pI830->FbMemBox.x2 = pScrn->displayWidth;
      pI830->FbMemBox.y1 = 0;
      pI830->FbMemBox.y2 = pScrn->virtualY;

      /*
       * Calculate how much framebuffer memory to allocate.  For the
       * initial allocation, calculate a reasonable minimum.  This is
       * enough for the virtual screen size, plus some pixmap cache
       * space.
       */

      lineSize = pScrn->displayWidth * pI830->cpp;
      minspace = lineSize * pScrn->virtualY;
      avail = pScrn->videoRam * 1024;
      maxCacheLines = (avail - minspace) / lineSize;
      /* This shouldn't happen. */
      if (maxCacheLines < 0) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "Internal Error: "
		    "maxCacheLines < 0 in I830Allocate2DMemory()\n");
	 maxCacheLines = 0;
      }
      if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pScrn->virtualY))
	 maxCacheLines = MAX_DISPLAY_HEIGHT - pScrn->virtualY;

      if (pI830->CacheLines >= 0) {
	 cacheLines = pI830->CacheLines;
      } else {
#if 1
	 /* Make sure there is enough for two DVD sized YUV buffers */
	 cacheLines = (pScrn->depth == 24) ? 256 : 384;
	 if (pScrn->displayWidth <= 1024)
	    cacheLines *= 2;
#else
	 /*
	  * Make sure there is enough for two DVD sized YUV buffers.
	  * Make that 1.5MB, which is around what was allocated with
	  * the old algorithm
	  */
	 cacheLines = (MB(1) + KB(512)) / pI830->cpp / pScrn->displayWidth;
#endif
      }
      if (cacheLines > maxCacheLines)
	 cacheLines = maxCacheLines;

      pI830->FbMemBox.y2 += cacheLines;

      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		     "%sAllocating at least %d scanlines for pixmap cache\n",
		     s, cacheLines);

      tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
		 IsTileable(pScrn->displayWidth * pI830->cpp);
      if (tileable) {
	 align = KB(512);
	 alignflags = ALIGN_BOTH_ENDS;
      } else {
	 align = KB(64);
	 alignflags = 0;
      }

      size = lineSize * (pScrn->virtualY + cacheLines);
      size = ROUND_TO_PAGE(size);
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		     "%sInitial framebuffer allocation size: %d kByte\n", s,
		     size / 1024);
      alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
				&(pI830->StolenPool), size, align,
				flags | alignflags |
				FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
      if (alloced < size) {
	 if (!dryrun) {
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		       "Failed to allocate framebuffer.\n");
	 }
	 return FALSE;
      }
   } else {
      unsigned long lineSize;
      unsigned long extra = 0;
      unsigned long maxFb = 0;

      /*
       * XXX Need to "free" up any 3D allocations if the DRI ended up
       * and make them available for 2D.  The best way to do this would
       * be position all of those regions contiguously at the end of the
       * StolenPool.
       */
      extra = GetFreeSpace(pScrn);

      if (extra == 0)
	 return TRUE;

      maxFb = pI830->FrontBuffer.Size + extra;
      lineSize = pScrn->displayWidth * pI830->cpp;
      maxFb = ROUND_DOWN_TO(maxFb, lineSize);
      if (maxFb > lineSize * MAX_DISPLAY_HEIGHT)
	 maxFb = lineSize * MAX_DISPLAY_HEIGHT;
      if (maxFb > pI830->FrontBuffer.Size) {
	 unsigned long oldsize;
	 /*
	  * Sanity check -- the fb should be the last thing allocated at
	  * the bottom of the stolen pool.
	  */
	 if (pI830->StolenPool.Free.Start != pI830->FrontBuffer.End) {
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		       "Internal error in I830Allocate2DMemory():\n\t"
		       "Framebuffer isn't the last allocation at the bottom"
		       " of StolenPool\n\t(%x != %x).\n",
		       pI830->FrontBuffer.End,
		       pI830->StolenPool.Free.Start);
	    return FALSE;
	 }
	 /*
	  * XXX Maybe should have a "Free" function.  This should be
	  * the only place where a region is resized, and we know that
	  * the fb is always at the bottom of the aperture/stolen pool,
	  * and is the only region that is allocated bottom-up.
	  * Allowing for more general realloction would require a smarter
	  * allocation system.
	  */
	 oldsize = pI830->FrontBuffer.Size;
	 pI830->StolenPool.Free.Size += pI830->FrontBuffer.Size;
	 pI830->StolenPool.Free.Start -= pI830->FrontBuffer.Size;
	 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
			"%sUpdated framebuffer allocation size from %d "
			"to %d kByte\n", s, oldsize / 1024, maxFb / 1024);
	 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
			"%sUpdated pixmap cache from %d scanlines to %d "
			"scanlines\n", s,
			oldsize / lineSize - pScrn->virtualY,
			maxFb / lineSize - pScrn->virtualY);
	 pI830->FbMemBox.y2 = maxFb / lineSize;
	 tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
		 IsTileable(pScrn->displayWidth * pI830->cpp);
	 if (tileable) {
	    align = KB(512);
	    alignflags = ALIGN_BOTH_ENDS;
	 } else {
	    align = KB(64);
	    alignflags = 0;
	 }
	 alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
				   &(pI830->StolenPool), maxFb, align,
				   flags | alignflags |
				   FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
	 if (alloced < maxFb) {
	    if (!dryrun) {
	       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			  "Failed to re-allocate framebuffer\n");
	    }
	    return FALSE;
	 }
      }
      return TRUE;
   }

#if REMAP_RESERVED
   /*
    * Allocate a dummy page to pass when attempting to rebind the
    * pre-allocated region.
    */
   if (!dryrun) {
      memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy));
      pI830->Dummy.Key =
	   xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
      pI830->Dummy.Offset = 0;
   }
#endif

   /* Clear cursor info */
   memset(&(pI830->CursorMem), 0, sizeof(pI830->CursorMem));
   pI830->CursorMem.Key = -1;

   if (!pI830->SWCursor) {
      int cursFlags = 0;
      /*
       * Mouse cursor -- The i810-i830 need a physical address in system
       * memory from which to upload the cursor.  We get this from
       * the agpgart module using a special memory type.
       */

      size = HWCURSOR_SIZE;
      cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP;
      if (pI830->CursorNeedsPhysical)
	 cursFlags |= NEED_PHYSICAL_ADDR;

      alloced = I830AllocVidMem(pScrn, &(pI830->CursorMem),
				&(pI830->StolenPool), size,
				GTT_PAGE_SIZE, flags | cursFlags);
      if (alloced < size) {
	 if (!dryrun) {
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		       "Failed to allocate HW cursor space.\n");
	 }
      } else {
	 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
			"%sAllocated %d kB for HW cursor at 0x%x", s,
			alloced / 1024, pI830->CursorMem.Start);
	 if (pI830->CursorNeedsPhysical)
	    xf86ErrorFVerb(verbosity, " (0x%08x)", pI830->CursorMem.Physical);
	 xf86ErrorFVerb(verbosity, "\n");
      }
   }

#ifdef I830_XV
   AllocateOverlay(pScrn, flags);
#endif

   if (!pI830->NeedRingBufferLow)
      AllocateRingBuffer(pScrn, flags);

   /* Clear scratch info */
   memset(&(pI830->Scratch), 0, sizeof(pI830->Scratch));
   pI830->Scratch.Key = -1;

   if (!pI830->noAccel) {
      size = MAX_SCRATCH_BUFFER_SIZE;
      alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), &(pI830->StolenPool),
				size, GTT_PAGE_SIZE,
				flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
      if (alloced < size) {
	 size = MIN_SCRATCH_BUFFER_SIZE;
         alloced = I830AllocVidMem(pScrn, &(pI830->Scratch),
				   &(pI830->StolenPool), size,
				   GTT_PAGE_SIZE,
				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
      }
      if (alloced < size) {
	 if (!dryrun) {
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		       "Failed to allocate scratch buffer space\n");
	 }
	 return FALSE;
      }
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		    "%sAllocated %d kB for the scratch buffer at 0x%x\n", s,
		    alloced / 1024, pI830->Scratch.Start);
   }
   return TRUE;
}