summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2006-04-23 21:27:08 +0200
committerLuc Verhaegen <libv@skynet.be>2006-04-23 21:27:08 +0200
commit11828d059d1d5212d83e9496d0b8615b1180f9af (patch)
treee836f9d97ce85481bab46195d7857edd1c2281fb
parentfeb3fa4f94110f02200d2852afdfd66e1f8dabf7 (diff)
Move detection of MMIO area to Mach64MMIODetectAndMap. This takes the
appearance of BAR2 at VT into account.
-rw-r--r--src/atipreinit.c167
-rw-r--r--src/atividmem.c205
-rw-r--r--src/atividmem.h1
3 files changed, 191 insertions, 182 deletions
diff --git a/src/atipreinit.c b/src/atipreinit.c
index e460188..3412ad1 100644
--- a/src/atipreinit.c
+++ b/src/atipreinit.c
@@ -73,150 +73,6 @@ Mach64GetRec(ScrnInfoPtr pScrn)
return TRUE;
}
-#ifdef DEBUG
-static void
-Mach64MMIOTestDump(ATIPtr pATI, pointer IOAddress)
-{
- int Index;
-
- xf86ErrorF("MMIO register values (%p):\n", IOAddress);
-
- for (Index = 0; Index < 256; Index+= 4) {
- if (!(Index & 15))
- xf86ErrorF("\n 0x%02X: ", Index);
- xf86ErrorF(" %08lX", MMIO_IN32(IOAddress, Index));
- }
- xf86ErrorF("\n");
-}
-#endif
-
-/*
- * Test MMIO range.
- */
-static Bool
-Mach64MMIOTest(ATIPtr pATI, pointer IOAddress)
-{
- CARD16 ChipID = MMIO_IN32(IOAddress, 0xE0) & 0xFFFF;
-
- /* of course GX/CX has to be different */
- if (pATI->Chip < ATI_CHIP_264CT) {
- if (pATI->Chip == ATI_CHIP_88800CX) {
- if (ChipID == 0x57)
- return TRUE;
- } else if (ChipID == 0xD7)
- return TRUE;
- } else {
- if (ChipID == pATI->PCIInfo->chipType)
- return TRUE;
-
- /* Some early GT's are detected as VT's */
- if ((ChipID == ATI_CHIP_264VT) &&
- (pATI->PCIInfo->chipType == ATI_CHIP_264GT))
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*
- * Temporarily map IO address and test it.
- */
-static Bool
-Mach64MMIOProbeMap(ATIPtr pATI, unsigned long Address)
-{
- char *IOAddress;
- unsigned long PageSize = getpagesize();
- unsigned long MMIOBase = Address & ~(PageSize - 1);
- Bool Result = FALSE;
-
- IOAddress = xf86MapPciMem(pATI->scrnIndex, VIDMEM_MMIO,
- ((pciConfigPtr) pATI->PCIInfo->thisCard)->tag,
- MMIOBase, PageSize);
- if (!IOAddress)
- return FALSE;
-
- Result = Mach64MMIOTest(pATI, IOAddress + (Address - MMIOBase));
-
- xf86UnMapVidMem(pATI->scrnIndex, IOAddress, PageSize);
- return Result;
-}
-
-/*
- * This function attempts to locate the MMIO area.
- *
- * TODO: ClaimFixedResource sparse IO address 0x6AEC when no seperate IO range.
- *
- * When do we get a seperate IO bar? Currently we know that IO sits at:
- * End of BAR0: at least as late as a 264CT
- * BAR2: at least as early as 264GTB
- *
- * So where does this change happen? ET? VT? VTB? GT?
- * I guess VT, but this needs verification. -- libv.
- */
-static unsigned long
-Mach64MMIOProbe(ATIPtr pATI)
-{
- pciVideoPtr pVideo = pATI->PCIInfo;
- unsigned long Address;
-
- /*
- * Probe through auxiliary MMIO aperture if one exists. Because such
- * apertures can be enabled/disabled only through PCI, this probes no
- * further.
- */
- if ((pATI->Chip > ATI_CHIP_264CT) && (pVideo->size[2] >= 12)) {
- if (pVideo->memBase[2] &&
- (pVideo->memBase[2] < (CARD32)(-1 << pVideo->size[2]))) {
- Address = pVideo->memBase[2] + 0x400;
-
- if (Mach64MMIOProbeMap(pATI, Address)) {
- xf86DrvMsg(pATI->scrnIndex, X_PROBED,
- "MMIO area detected in the third BAR.\n");
- return Address;
- }
- }
- }
-
- /*
- * Probe through the primary MMIO aperture that exists at the tail end
- * of the linear aperture. Test for both 8MB and 4MB linear apertures.
- */
- if ((pATI->Chip < ATI_CHIP_264GTB) && pVideo->memBase[0]) {
- /* Check if our linear memory aperture is enabled */
- if (!(inw(0x6AEC) & 0x3)) {
- CARD32 tmp = inw(0x6AEC);
- xf86DrvMsg(pATI->scrnIndex, X_WARNING, "Linear memory aperture "
- "not set up. Correcting.\n");
-
- outw(0x6AEC, tmp | 0x2); /* Go for 8MB anyway */
- }
-
- if (pVideo->size[0] >= 23) {
- Address = pVideo->memBase[0] + 0x007FFC00;
-
- if (Mach64MMIOProbeMap(pATI, Address)) {
- xf86DrvMsg(pATI->scrnIndex, X_PROBED,
- "MMIO area detected in the first BAR.\n");
- return Address;
- }
- }
-
- if (pVideo->size[0] >= 22) {
- Address = pVideo->memBase[0] + 0x003FFC00;
-
- if (Mach64MMIOProbeMap(pATI, Address)) {
- xf86DrvMsg(pATI->scrnIndex, X_PROBED,
- "MMIO area detected in the first BAR.\n");
- return Address;
- }
- }
- }
-
- xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Unable to find MMIO Area.\n");
- return 0;
-}
-
-
/*
* Collect IO range information.
*/
@@ -1583,28 +1439,7 @@ ATIPreInit(ScrnInfoPtr pScreenInfo, int flags)
xfree(pEntity);
- /*
- * Set up MMIO.
- * If we don't manage to access it now, then when will we?
- */
- pATI->Block0Base = Mach64MMIOProbe(pATI);
- if (!pATI->Block0Base) {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, "Unable to locate MMIO "
- "area for %02x:%02x:%01x. Exiting.\n", pATI->PCIInfo->bus,
- pATI->PCIInfo->device, pATI->PCIInfo->func);
- return FALSE;
- }
-
- xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "Using Block 0 MMIO aperture"
- " at 0x%08lX.\n", pATI->Block0Base);
-
- /* Set Block1 MMIO address if supported */
- if (pATI->Chip >= ATI_CHIP_264VT) {
- pATI->Block1Base = pATI->Block0Base - 0x00000400U;
- xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "Using Block 1 MMIO aperture"
- " at 0x%08lX.\n", pATI->Block1Base);
- }
- Mach64MMIOMap(pATI);
+ Mach64MMIODetectAndMap(pATI);
Mach64CPIOSetup(pATI); /* work me out */
diff --git a/src/atividmem.c b/src/atividmem.c
index cff3b66..47fdb25 100644
--- a/src/atividmem.c
+++ b/src/atividmem.c
@@ -30,6 +30,8 @@
#include "atistruct.h"
#include "atividmem.h"
+#include "atichip.h"
+#include "atimach64io.h"
/* Memory types for 68800's and 88800GX's */
const char *ATIMemoryTypeNames_Mach[] =
@@ -133,39 +135,210 @@ Mach64CursorUnmap(ATIPtr pATI)
pATI->pCursorPage = pATI->pCursorImage = NULL;
}
+#define PIO_CONFIG_CNTL 0x6AEC
+#define MMIO_CONFIG_CNTL 0xDC
+#define MMIO_CONFIG_CHIP_ID 0xE0
+
+/*
+ * Test MMIO range.
+ */
+static Bool
+Mach64MMIOTest(ATIPtr pATI, pointer IOAddress)
+{
+ CARD16 ChipID = MMIO_IN32(IOAddress, MMIO_CONFIG_CHIP_ID) & 0xFFFF;
+
+ /* of course GX/CX has to be different */
+ if (pATI->Chip < ATI_CHIP_264CT) {
+ if (pATI->Chip == ATI_CHIP_88800CX) {
+ if (ChipID == 0x57)
+ return TRUE;
+ } else if (ChipID == 0xD7)
+ return TRUE;
+ } else {
+ if (ChipID == pATI->PCIInfo->chipType)
+ return TRUE;
+
+ /* Some early GT's are detected as VT's */
+ if ((ChipID == ATI_CHIP_264VT) &&
+ (pATI->PCIInfo->chipType == ATI_CHIP_264GT))
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*
*
*/
+static void
+Mach64MMIOUnmap(ATIPtr pATI)
+{
+ if (pATI->pMMIO)
+ xf86UnMapVidMem(pATI->scrnIndex, pATI->pMMIO, getpagesize());
+
+ pATI->pMMIO = pATI->pBlock[0] = pATI->pBlock[1] = NULL;
+}
+
+/* Find and Map MMIO area, also verifies BAR0 and BAR2.
+ *
+ * We do assume that page size is at least 1kb, which should be pretty safe.
+ *
+ * TODO: FixedResource sparse IO address 0x6AEC for < 264CT.
+ */
Bool
-Mach64MMIOMap(ATIPtr pATI)
+Mach64MMIODetectAndMap(ATIPtr pATI)
{
+ pciVideoPtr pVideo = pATI->PCIInfo;
+ PCITAG tag = ((pciConfigPtr) pVideo->thisCard)->tag;
unsigned long PageSize = getpagesize();
- unsigned long MMIOBase = pATI->Block0Base & ~(PageSize - 1);
+ unsigned long Tmp;
+
+ /* Check whether the first aperture is set up correctly. */
+ if (!pVideo->memBase[0] && (pVideo->size[0] < 22) &&
+ (pVideo->memBase[0] >= (CARD32)(-1 << pVideo->size[0]))) {
+ xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Unable to get to Linear "
+ "Aperture. BAR not set up correctly.\n");
+ return FALSE;
+ }
- pATI->pMMIO = xf86MapPciMem(pATI->scrnIndex, VIDMEM_MMIO,
- ((pciConfigPtr) pATI->PCIInfo->thisCard)->tag,
- MMIOBase, PageSize);
- if (!pATI->pMMIO)
- return FALSE;
+ /* First, try to get IO from the third BAR */
+ if (pATI->Chip >= ATI_CHIP_264VT) {
+ if ((pVideo->size[2] >= 12) && pVideo->memBase[2] &&
+ (pVideo->memBase[2] < (CARD32)(-1 << pVideo->size[2]))) {
+ Tmp = pVideo->memBase[2] & ~(PageSize - 1);
+
+ pATI->pMMIO = xf86MapPciMem(pATI->scrnIndex, VIDMEM_MMIO, tag, Tmp,
+ PageSize);
+
+ if (!pATI->pMMIO) {
+ xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Unable to map MMIO at "
+ "0x%08lX.\n", pVideo->memBase[2]);
+ Mach64MMIOUnmap(pATI);
+ return FALSE;
+ }
+
+ pATI->pBlock[1] = (char *)pATI->pMMIO + (pVideo->memBase[2] - Tmp);
+ pATI->pBlock[0] = (char *)pATI->pBlock[1] + 0x400;
+
+ pATI->Block1Base = pVideo->memBase[2];
+ pATI->Block0Base = pVideo->memBase[2] + 0x400;
+ xf86DrvMsg(pATI->scrnIndex, X_PROBED, "Using Block 0 MMIO aperture"
+ " at 0x%08lX.\n", pATI->Block0Base);
+ xf86DrvMsg(pATI->scrnIndex, X_PROBED, "Using Block 1 MMIO aperture"
+ " at 0x%08lX.\n", pATI->Block1Base);
+ } else {
+ xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Unable to get auxilliary MMIO"
+ " aperture. BAR not set up correctly.\n");
+ Mach64MMIOUnmap(pATI);
+ return FALSE;
+ }
+ } else { /* Gx/Cx/CT/ET have IO as the last kB of the FB aperture. */
+ /* Check if our linear memory aperture is properly enabled */
+ if (!(inw(PIO_CONFIG_CNTL) & 0x3)) {
+ CARD32 tmp = inw(PIO_CONFIG_CNTL);
+ xf86DrvMsg(pATI->scrnIndex, X_WARNING, "Linear memory aperture "
+ "not set up. Correcting.\n");
+
+ outw(PIO_CONFIG_CNTL, tmp | 0x2); /* Go for 8MB anyway */
+ } else if ((inw(PIO_CONFIG_CNTL) & 0x3) == 0x3) {
+ xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Linear memory aperture "
+ "has impossible size. Aborting.\n");
+ Mach64MMIOUnmap(pATI);
+ return FALSE;
+ }
+
+ /* Check size of aperture. */
+ if (((inw(PIO_CONFIG_CNTL) & 0x3) == 0x2) && (pVideo->size[0] >= 23))
+ Tmp = 0x00800000 - PageSize;
+ else
+ Tmp = 0x00400000 - PageSize;
+
+ pATI->pMMIO = xf86MapPciMem(pATI->scrnIndex, VIDMEM_MMIO, tag,
+ pVideo->memBase[0] + Tmp, PageSize);
+ if (!pATI->pMMIO) {
+ xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Unable to map MMIO at "
+ "0x%08lX.\n", pVideo->memBase[0] + Tmp);
+ Mach64MMIOUnmap(pATI);
+ return FALSE;
+ }
+
+ pATI->pBlock[0] = (char *)pATI->pMMIO + PageSize - 0x400;
- pATI->pBlock[0] = (char *)pATI->pMMIO + (pATI->Block0Base - MMIOBase);
+ pATI->Block0Base = pVideo->memBase[0] + (Tmp + PageSize - 0x400);
+ xf86DrvMsg(pATI->scrnIndex, X_PROBED, "Using Block 0 MMIO aperture"
+ " at 0x%08lX.\n", pATI->Block0Base);
+ }
- if (pATI->Block1Base)
- pATI->pBlock[1] = (char *)pATI->pBlock[0] - 0x00000400U;
+ /* Verify that our MMIO range really is accessible. */
+ if (!Mach64MMIOTest(pATI, pATI->pBlock[0])) {
+ xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Unable to verify functionality "
+ "of MMIO.\n");
+ Mach64MMIOUnmap(pATI);
+ return FALSE;
+ }
+
+#if 0
+ /* Get adapter's linear aperture configuration */
+ pATI->LinearBase = pVideo->memBase[0];
+ pATI->LinearSize = MMIO_IN32(pATI->pBlock[0], MMIO_CONFIG_CNTL) & 0x3;
+ pATI->LinearSize *= 4 * 1024 * 1024;
+
+ /* Account for our MMIO area */
+ if (pATI->Chip < ATI_CHIP_264VT)
+ pATI->LinearSize -= PageSize;
+ else if (pATI->Chip == ATI_CHIP_264VT) /* predates BUS_APER_REG_DIS */
+ pATI->LinearSize -= 2*1024;
+#endif
return TRUE;
}
/*
- *
+ * Map MMIO without much testing.
*/
-static void
-Mach64MMIOUnmap(ATIPtr pATI)
+Bool
+Mach64MMIOMap(ATIPtr pATI)
{
- if (pATI->pMMIO)
- xf86UnMapVidMem(pATI->scrnIndex, pATI->pMMIO, getpagesize());
+ pciVideoPtr pVideo = pATI->PCIInfo;
+ PCITAG tag = ((pciConfigPtr) pVideo->thisCard)->tag;
+ unsigned long PageSize = getpagesize();
+ unsigned long Tmp;
- pATI->pMMIO = pATI->pBlock[0] = pATI->pBlock[1] = NULL;
+ /* First, try to get IO from the third BAR */
+ if (pATI->Chip >= ATI_CHIP_264VT) {
+ Tmp = pVideo->memBase[2] & ~(PageSize - 1);
+
+ pATI->pMMIO = xf86MapPciMem(pATI->scrnIndex, VIDMEM_MMIO, tag, Tmp,
+ PageSize);
+
+ if (!pATI->pMMIO) {
+ xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Unable to map MMIO at "
+ "0x%08lX.\n", pVideo->memBase[2]);
+ Mach64MMIOUnmap(pATI);
+ return FALSE;
+ }
+
+ pATI->pBlock[1] = (char *)pATI->pMMIO + (pVideo->memBase[2] - Tmp);
+ pATI->pBlock[0] = (char *)pATI->pBlock[1] + 0x400;
+ } else { /* Gx/Cx/CT/ET have IO as the last kB of the FB aperture. */
+ /* Check size of aperture. */
+ if (((inw(PIO_CONFIG_CNTL) & 0x3) == 0x2) && (pVideo->size[0] >= 23))
+ Tmp = 0x00800000 - PageSize;
+ else
+ Tmp = 0x00400000 - PageSize;
+
+ pATI->pMMIO = xf86MapPciMem(pATI->scrnIndex, VIDMEM_MMIO, tag,
+ pVideo->memBase[0] + Tmp, PageSize);
+ if (!pATI->pMMIO) {
+ xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Unable to map MMIO at "
+ "0x%08lX.\n", pVideo->memBase[0] + Tmp);
+ Mach64MMIOUnmap(pATI);
+ return FALSE;
+ }
+
+ pATI->pBlock[0] = (char *)pATI->pMMIO + PageSize - 0x400;
+ }
+
+ return TRUE;
}
/*
diff --git a/src/atividmem.h b/src/atividmem.h
index 205c408..57edeef 100644
--- a/src/atividmem.h
+++ b/src/atividmem.h
@@ -71,5 +71,6 @@ extern const char *ATIMemoryTypeNames_264xT[];
Bool Mach64AperturesMap(ATIPtr pATI);
void Mach64AperturesUnmap(ATIPtr pATI);
Bool Mach64MMIOMap(ATIPtr pATI);
+Bool Mach64MMIODetectAndMap(ATIPtr pATI);
#endif /* ___ATIVIDMEM_H___ */