diff options
author | Luc Verhaegen <libv@skynet.be> | 2006-04-23 21:27:08 +0200 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2006-04-23 21:27:08 +0200 |
commit | 11828d059d1d5212d83e9496d0b8615b1180f9af (patch) | |
tree | e836f9d97ce85481bab46195d7857edd1c2281fb | |
parent | feb3fa4f94110f02200d2852afdfd66e1f8dabf7 (diff) |
Move detection of MMIO area to Mach64MMIODetectAndMap. This takes the
appearance of BAR2 at VT into account.
-rw-r--r-- | src/atipreinit.c | 167 | ||||
-rw-r--r-- | src/atividmem.c | 205 | ||||
-rw-r--r-- | src/atividmem.h | 1 |
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___ */ |