diff options
author | George Sapountzis <gsap7@yahoo.gr> | 2007-03-18 15:50:41 +0200 |
---|---|---|
committer | George Sapountzis <gsap7@yahoo.gr> | 2007-03-21 20:18:51 +0200 |
commit | e674338a98c50800637b8ebc01adf3aec2a3eb38 (patch) | |
tree | ad6227dbf50f1b7c2a15821374a2426034bd634f | |
parent | e7969de8ec572d8801806f9525a9a081a58a03f1 (diff) |
[mach64] Single mapping per BAR.
- We reset write-combining of the FB when MMIO registers fall in the linear
aperture.
- We set MMIOInLinear in all three aperture mappings since the mapping code
depends on it.
- We map the linear aperture in its entirety for MMIOInLinear also.
This simplifies mapping of HW cursor and the LE aperture on BE archs, as
they always fall in the linear aperture.
- I assumed that BAR[2] is page-aligned (we know it's 4K-aligned for sure).
-rw-r--r-- | src/atipreinit.c | 6 | ||||
-rw-r--r-- | src/atiprobe.c | 7 | ||||
-rw-r--r-- | src/atistruct.h | 2 | ||||
-rw-r--r-- | src/atividmem.c | 170 |
4 files changed, 83 insertions, 102 deletions
diff --git a/src/atipreinit.c b/src/atipreinit.c index 2e5903d1..62bd9267 100644 --- a/src/atipreinit.c +++ b/src/atipreinit.c @@ -429,6 +429,8 @@ ATIPreInit if (pATI->CPIODecoding == BLOCK_IO) pATI->CPIOBase = pVideo->ioBase[1]; + pATI->MMIOInLinear = FALSE; + /* Set MMIO address from PCI configuration space, if available */ if ((pATI->Block0Base = pVideo->memBase[2])) { @@ -451,6 +453,8 @@ ATIPreInit /* Check tail end of linear (8MB or 4MB) aperture */ if ((pATI->Block0Base = pVideo->memBase[0])) { + pATI->MMIOInLinear = TRUE; + pATI->Block0Base += 0x007FFC00U; ATIMach64Map(pScreenInfo->scrnIndex, pATI); if (pATI->pBlock[0]) @@ -1808,6 +1812,8 @@ ATIPreInit { int AcceleratorVideoRAM = 0, ServerVideoRAM; + pATI->MMIOInLinear = FALSE; + /* * Unless specified in PCI configuration space, set MMIO * address to tail end of linear aperture. diff --git a/src/atiprobe.c b/src/atiprobe.c index 01c5763e..36df11d8 100644 --- a/src/atiprobe.c +++ b/src/atiprobe.c @@ -217,6 +217,8 @@ ATIMach64Probe { CARD16 ChipType = pVideo->chipType; + pATI->MMIOInLinear = FALSE; + /* * Probe through auxiliary MMIO aperture if one exists. Because such * apertures can be enabled/disabled only through PCI, this probes no @@ -237,8 +239,11 @@ ATIMach64Probe * 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 ((pVideo->size[0] >= 22) && (pATI->Block0Base = pVideo->memBase[0])) + if ((pVideo->size[0] >= 22) && + (pATI->Block0Base = pVideo->memBase[0])) { + pATI->MMIOInLinear = TRUE; + pATI->Block0Base += 0x007FFC00U; if ((pVideo->size[0] >= 23) && ATIMach64Detect(pATI, ChipType, Chip)) diff --git a/src/atistruct.h b/src/atistruct.h index 99be359b..a1c76dc4 100644 --- a/src/atistruct.h +++ b/src/atistruct.h @@ -336,7 +336,7 @@ typedef struct _ATIRec * Cursor-related definitions. */ xf86CursorInfoPtr pCursorInfo; - pointer pCursorPage, pCursorImage; + pointer pCursorImage; unsigned long CursorBase; CARD32 CursorOffset; CARD16 CursorXOffset, CursorYOffset; diff --git a/src/atividmem.c b/src/atividmem.c index b1a7a8dc..01b00991 100644 --- a/src/atividmem.c +++ b/src/atividmem.c @@ -67,6 +67,16 @@ const char *ATIMemoryTypeNames_264xT[] = "Unknown video memory type" }; +/* + * FIXME: This is an internal Xserver function that should be exported and + * called explicitely with pci-rework, pci-rework does not setup mtrr's. + * + * It is called implicitely by xf86MapPciMem(VIDMEM_FRAMEBUFFER). + */ +#define nop_setWC(_screenNum, _base, _size, _enable) \ +do { \ +} while (0) + #ifndef AVOID_CPIO /* @@ -103,20 +113,19 @@ ATIUnmapLinear ATIPtr pATI ) { - if (pATI->pMemory) - { - xf86UnMapVidMem(iScreen, pATI->pMemory, pATI->LinearSize); - -#if X_BYTE_ORDER != X_LITTLE_ENDIAN + pciVideoPtr pVideo = pATI->PCIInfo; - if (pATI->pMemoryLE) - xf86UnMapVidMem(iScreen, pATI->pMemoryLE, pATI->LinearSize); - -#endif /* X_BYTE_ORDER */ + if (pATI->pMemoryLE) + { + if (pATI->LinearBase) + nop_setWC(iScreen, pATI->LinearBase, pATI->LinearSize, FALSE); + xf86UnMapVidMem(iScreen, pATI->pMemoryLE, (1U << pVideo->size[0])); } pATI->pMemory = pATI->pMemoryLE = NULL; + + pATI->pCursorImage = NULL; } /* @@ -138,27 +147,14 @@ ATIUnmapMMIO } /* - * ATIUnmapCursor -- - * - * Unmap hardware cursor image area. - */ -static void -ATIUnmapCursor -( - int iScreen, - ATIPtr pATI -) -{ - if (pATI->pCursorPage) - xf86UnMapVidMem(iScreen, pATI->pCursorPage, getpagesize()); - - pATI->pCursorPage = pATI->pCursorImage = NULL; -} - -/* * ATIMapApertures -- * * This function maps all apertures used by the driver. + * + * It is called three times: + * - to setup MMIO for an MMIO-only driver during Probe + * - to setup MMIO for an MMIO-only driver during PreInit + * - to setup MMIO (with Block0Base set) and FB (with LinearBase set) */ Bool ATIMapApertures @@ -169,7 +165,7 @@ ATIMapApertures { pciVideoPtr pVideo = pATI->PCIInfo; PCITAG Tag = ((pciConfigPtr)(pVideo->thisCard))->tag; - unsigned long PageSize = getpagesize(); + int mode; if (pATI->Mapped) return TRUE; @@ -195,12 +191,21 @@ ATIMapApertures #endif /* AVOID_CPIO */ /* Map linear aperture */ - if (pATI->LinearBase) + if (pATI->LinearBase || (pATI->Block0Base && pATI->MMIOInLinear)) { - pATI->pMemory = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER, - Tag, pATI->LinearBase, pATI->LinearSize); + mode = VIDMEM_FRAMEBUFFER; + + /* Reset write-combining for the whole FB when MMIO registers fall in + * the linear aperture. + */ + if (pATI->MMIOInLinear) + mode = VIDMEM_MMIO; + + pATI->pMemoryLE = xf86MapPciMem(iScreen, mode, Tag, + pVideo->memBase[0], + (1U << pVideo->size[0])); - if (!pATI->pMemory) + if (!pATI->pMemoryLE) { #ifndef AVOID_CPIO @@ -217,58 +222,32 @@ ATIMapApertures #if X_BYTE_ORDER == X_LITTLE_ENDIAN - if ((pATI->CursorBase >= pATI->LinearBase) && - ((pATI->CursorOffset + 0x00000400UL) <= (CARD32)pATI->LinearSize)) - pATI->pCursorImage = (char *)pATI->pMemory + pATI->CursorOffset; - - pATI->pMemoryLE = pATI->pMemory; + pATI->pMemory = pATI->pMemoryLE; #else /* if X_BYTE_ORDER != X_LITTLE_ENDIAN */ - /* - * Map the little-endian aperture (used for video, etc.). Note that - * caching of this area is _not_ wanted. - */ - { - pATI->pMemoryLE = xf86MapPciMem(iScreen, VIDMEM_MMIO, Tag, - pATI->LinearBase - 0x00800000U, pATI->LinearSize); - - if (!pATI->pMemoryLE) - { - ATIUnmapLinear(iScreen, pATI); - -#ifndef AVOID_CPIO - - ATIUnmapVGA(iScreen, pATI); - -#endif /* AVOID_CPIO */ - - pATI->Mapped = FALSE; - return FALSE; - } - } + pATI->pMemory = (char *)pATI->pMemoryLE + 0x00800000U; #endif /* X_BYTE_ORDER */ + /* Set write-combining for the FB (and the HW cursor on LE) */ + if (pATI->LinearBase) + nop_setWC(iScreen, pATI->LinearBase, pATI->LinearSize, TRUE); + + if (pATI->CursorBase) + pATI->pCursorImage = (char *)pATI->pMemoryLE + pATI->CursorOffset; } /* Map MMIO aperture */ - if (pATI->Block0Base) + if (pATI->Block0Base && !pATI->MMIOInLinear) { - unsigned long MMIOBase = pATI->Block0Base & ~(PageSize - 1); - - pATI->pMMIO = xf86MapPciMem(iScreen, VIDMEM_MMIO, - Tag, MMIOBase, PageSize); + mode = VIDMEM_MMIO; + pATI->pMMIO = xf86MapPciMem(iScreen, mode, Tag, + pVideo->memBase[2], + getpagesize()); if (!pATI->pMMIO) { - -#if X_BYTE_ORDER == X_LITTLE_ENDIAN - - ATIUnmapCursor(iScreen, pATI); - -#endif /* X_BYTE_ORDER */ - ATIUnmapLinear(iScreen, pATI); #ifndef AVOID_CPIO @@ -283,38 +262,28 @@ ATIMapApertures pATI->Mapped = TRUE; - pATI->pBlock[0] = (char *)pATI->pMMIO + - (pATI->Block0Base - MMIOBase); + pATI->pBlock[0] = (char *)pATI->pMMIO + 0x00000400U; if (pATI->Block1Base) pATI->pBlock[1] = (char *)pATI->pBlock[0] - 0x00000400U; - -#if X_BYTE_ORDER == X_LITTLE_ENDIAN - - if (!pATI->pCursorImage) - -#endif /* X_BYTE_ORDER */ - - { - if ((pATI->CursorBase >= MMIOBase) && - ((pATI->CursorBase + 0x00000400UL) <= (MMIOBase + PageSize))) - pATI->pCursorImage = (char *)pATI->pMMIO + - (pATI->CursorBase - MMIOBase); - } } - - /* Map hardware cursor image area */ - if (pATI->CursorBase && !pATI->pCursorImage) + else if (pATI->Block0Base) { - unsigned long CursorBase = pATI->CursorBase & ~(PageSize - 1); + unsigned long mmio_offset, linear_size; + + mmio_offset = pATI->Block0Base - pVideo->memBase[0]; - pATI->pCursorPage = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER, - Tag, CursorBase, PageSize); + linear_size = (1 << pVideo->size[0]); - if (!pATI->pCursorPage) + pATI->pMMIO = NULL; + + /* Check that requested MMIO offset falls in the linear aperture. This + * ensures that we do not poke outside a mapped region and bails early + * for old mach64 cards with a 4MB linear aperture (unless they have an + * extended BE aperture which would give a size of 8MB). + */ + if (mmio_offset + 0x00000400U > linear_size) { - ATIUnmapCursor(iScreen, pATI); - ATIUnmapMMIO(iScreen, pATI); ATIUnmapLinear(iScreen, pATI); #ifndef AVOID_CPIO @@ -327,8 +296,12 @@ ATIMapApertures return FALSE; } - pATI->pCursorImage = (char *)pATI->pCursorPage + - (pATI->CursorBase - CursorBase); + pATI->Mapped = TRUE; + + pATI->pBlock[0] = (char *)pATI->pMemoryLE + mmio_offset; + + if (pATI->Block1Base) + pATI->pBlock[1] = (char *)pATI->pBlock[0] - 0x00000400U; } return TRUE; @@ -350,9 +323,6 @@ ATIUnmapApertures return; pATI->Mapped = FALSE; - /* Unmap hardware cursor image area */ - ATIUnmapCursor(iScreen, pATI); - /* Unmap MMIO area */ ATIUnmapMMIO(iScreen, pATI); |