#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"
#include "i810.h"
#include "i810_reg.h"
int
I810AllocLow(I810MemRange * result, I810MemRange * pool, int size)
{
if (size > pool->Size)
return 0;
pool->Size -= size;
result->Size = size;
result->Start = pool->Start;
result->End = pool->Start += size;
return 1;
}
int
I810AllocHigh(I810MemRange * result, I810MemRange * pool, int size)
{
if (size > pool->Size)
return 0;
pool->Size -= size;
result->Size = size;
result->End = pool->End;
result->Start = pool->End -= size;
return 1;
}
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;
}
pI810->agpAcquired2d = TRUE;
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;
size = 1024 * 4096;
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;
}
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 {
pI810->CursorPhysical = physical;
pI810->CursorStart = tom;
tom += size;
}
}
if (pI810->CursorStart != 0) {
pI810->OverlayPhysical = pI810->CursorPhysical + 1024;
pI810->OverlayStart = pI810->CursorStart + 1024;
}
pI810->GttBound = 1;
return TRUE;
}
void
I810SetTiledMemory(ScrnInfoPtr pScrn, int nr, unsigned int start,
unsigned int pitch, unsigned int size)
{
I810Ptr pI810 = I810PTR(pScrn);
I810RegPtr i810Reg = &pI810->ModeReg;
CARD32 val;
CARD32 fence_mask = 0;
if (nr < 0 || nr > 7) {
xf86DrvMsg(X_WARNING, pScrn->scrnIndex, "%s - fence %d out of range\n",
"I810SetTiledMemory", nr);
return;
}
i810Reg->Fence[nr] = 0;
fence_mask = ~FENCE_START_MASK;
if (start & fence_mask) {
xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
"%s %d: start (%x) is not 512k aligned\n",
"I810SetTiledMemory", nr, start);
return;
}
if (start % size) {
xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
"%s %d: start (%x) is not size (%x) aligned\n",
"I810SetTiledMemory", nr, start, size);
return;
}
if (pitch & 127) {
xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
"%s %d: pitch (%x) not a multiple of 128 bytes\n",
"I810SetTiledMemory", nr, pitch);
return;
}
val = (start | FENCE_X_MAJOR | FENCE_VALID);
switch (size) {
case KB(512):
val |= FENCE_SIZE_512K;
break;
case MB(1):
val |= FENCE_SIZE_1M;
break;
case MB(2):
val |= FENCE_SIZE_2M;
break;
case MB(4):
val |= FENCE_SIZE_4M;
break;
case MB(8):
val |= FENCE_SIZE_8M;
break;
case MB(16):
val |= FENCE_SIZE_16M;
break;
case MB(32):
val |= FENCE_SIZE_32M;
break;
default:
xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
"%s %d: illegal size (0x%x)\n", "I810SetTiledMemory", nr,
size);
return;
}
switch (pitch / 128) {
case 1:
val |= FENCE_PITCH_1;
break;
case 2:
val |= FENCE_PITCH_2;
break;
case 4:
val |= FENCE_PITCH_4;
break;
case 8:
val |= FENCE_PITCH_8;
break;
case 16:
val |= FENCE_PITCH_16;
break;
case 32:
val |= FENCE_PITCH_32;
break;
default:
xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
"%s %d: illegal size (0x%x)\n", "I810SetTiledMemory", nr,
size);
return;
}
i810Reg->Fence[nr] = val;
}
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;
pI810->GttBound = 1;
}
return TRUE;
}
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 (!xf86ReleaseGART(pScrn->scrnIndex))
return FALSE;
pI810->GttBound = 0;
}
return TRUE;
}
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;
}