diff options
author | George Sapountzis <gsap7@yahoo.gr> | 2007-02-05 19:16:51 +0200 |
---|---|---|
committer | George Sapountzis <gsap7@yahoo.gr> | 2007-02-05 19:16:51 +0200 |
commit | 9d77aabdff919360f0c9333105436c31f1f5749a (patch) | |
tree | fa0617724e538435cf2b04b7a63ef006fc73fe04 /src/atiprobe.c | |
parent | ff8ea19fcdce099732f9359e53cd62b9a04bfa6d (diff) | |
parent | 57822be75740f339445f2375d44632560f4bbe57 (diff) |
Merge branch 'mach64-pci-1'
Diffstat (limited to 'src/atiprobe.c')
-rw-r--r-- | src/atiprobe.c | 2192 |
1 files changed, 292 insertions, 1900 deletions
diff --git a/src/atiprobe.c b/src/atiprobe.c index 9c30a314..e869bf0d 100644 --- a/src/atiprobe.c +++ b/src/atiprobe.c @@ -28,7 +28,6 @@ #include <stdio.h> #include "ati.h" -#include "atiadapter.h" #include "atiadjust.h" #include "atibus.h" #include "atichip.h" @@ -50,228 +49,9 @@ #include "r128_probe.h" #include "r128_version.h" -/* - * NOTES: - * - * - The driver private structures (ATIRec's) are allocated here, rather than - * in ATIPreInit(). This allows ATIProbe() to pass information to later - * stages. - * - A minor point, perhaps, is that XF86Config Chipset names denote functional - * levels, rather than specific graphics controller chips. - * - ATIProbe() does not call xf86MatchPciInstances(), because ATIProbe() - * should be able to match a mix of PCI and non-PCI devices to XF86Config - * Device sections. Also, PCI configuration space for Mach32's is to be - * largely ignored. - */ - -/* Used as a temporary buffer */ -#define Identifier ((char *)(pATI->MMIOCache)) - -/* - * An internal structure definition to facilitate the matching of detected - * adapters to XF86Config Device sections. - */ -typedef struct _ATIGDev -{ - GDevPtr pGDev; - int iATIPtr; - CARD8 Chipset; -} ATIGDev, *ATIGDevPtr; - #ifndef AVOID_CPIO /* - * Definitions for I/O conflict avoidance. - */ -#define LongPort(_Port) GetBits(_Port, PCIGETIO(SPARSE_IO_BASE)) -#define DetectedVGA (1 << 0) -#define Detected8514A (1 << 1) -#define DetectedMach64 (1 << 2) -#define Allowed (1 << 3) -#define DoProbe (1 << 4) -typedef struct -{ - IOADDRESS Base; - CARD8 Size; - CARD8 Flag; -} PortRec, *PortPtr; - -/* - * ATIScanPCIBases -- - * - * This function loops though a device's PCI registered bases and accumulates - * a list of block I/O bases in use in the system. - */ -static void -ATIScanPCIBases -( - PortPtr *PCIPorts, - int *nPCIPort, - const CARD32 *pBase, - const int *pSize, - const CARD8 ProbeFlag -) -{ - IOADDRESS Base; - int i, j; - - for (i = 6; --i >= 0; pBase++, pSize++) - { - if (*pBase & PCI_MAP_IO) - { - Base = *pBase & ~IO_BYTE_SELECT; - for (j = 0; ; j++) - { - if (j >= *nPCIPort) - { - (*nPCIPort)++; - *PCIPorts = (PortPtr)xnfrealloc(*PCIPorts, - *nPCIPort * SizeOf(PortRec)); - (*PCIPorts)[j].Base = Base; - (*PCIPorts)[j].Size = (CARD8)*pSize; - (*PCIPorts)[j].Flag = ProbeFlag; - break; - } - - if (Base == (*PCIPorts)[j].Base) - break; - } - - continue; - } - - /* Allow for 64-bit addresses */ - if (!PCI_MAP_IS64BITMEM(*pBase)) - continue; - - i--; - pBase++; - pSize++; - } -} - -/* - * ATICheckSparseIOBases -- - * - * This function checks whether a sparse I/O base can safely be probed. - */ -static CARD8 -ATICheckSparseIOBases -( - pciVideoPtr pVideo, - CARD8 *ProbeFlags, - const IOADDRESS IOBase, - const int Count, - const Bool Override -) -{ - CARD32 FirstPort, LastPort; - - if (!pVideo || !xf86IsPrimaryPci(pVideo)) - { - FirstPort = LongPort(IOBase); - LastPort = LongPort(IOBase + Count - 1); - - for (; FirstPort <= LastPort; FirstPort++) - { - CARD8 ProbeFlag = ProbeFlags[FirstPort]; - - if (ProbeFlag & DoProbe) - continue; - - if (!(ProbeFlag & Allowed)) - return ProbeFlag; - - if (Override) - continue; - - /* User might wish to override this decision */ - xf86Msg(X_WARNING, - ATI_NAME ": Sparse I/O base 0x%04lX not probed.\n", IOBase); - return Allowed; - } - } - - return DoProbe; -} - -#ifndef AVOID_NON_PCI - -/* - * ATIClaimSparseIOBases -- - * - * This function updates the sparse I/O base table with information from the - * hardware probes. - */ -static void -ATIClaimSparseIOBases -( - CARD8 *ProbeFlags, - const IOADDRESS IOBase, - const int Count, - const CARD8 ProbeFlag -) -{ - CARD32 FirstPort = LongPort(IOBase), - LastPort = LongPort(IOBase + Count - 1); - - for (; FirstPort <= LastPort; FirstPort++) - ProbeFlags[FirstPort] = ProbeFlag; -} - -#endif /* AVOID_NON_PCI */ - -/* - * ATIVGAProbe -- - * - * This function looks for an IBM standard VGA, or clone, and sets - * pATI->VGAAdapter if one is found. - */ -static ATIPtr -ATIVGAProbe -( - ATIPtr pVGA -) -{ - CARD8 IOValue1, IOValue2, IOValue3; - - if (!pVGA) - pVGA = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec)); - - /* - * VGA has one more attribute register than EGA. See if it can be read and - * written. Note that the CRTC registers are not used here, so there's no - * need to unlock them. - */ - ATISetVGAIOBase(pVGA, inb(R_GENMO)); - (void)inb(GENS1(pVGA->CPIO_VGABase)); - IOValue1 = inb(ATTRX); - (void)inb(GENS1(pVGA->CPIO_VGABase)); - IOValue2 = GetReg(ATTRX, 0x14U | 0x20U); - outb(ATTRX, IOValue2 ^ 0x0FU); - IOValue3 = GetReg(ATTRX, 0x14U | 0x20U); - outb(ATTRX, IOValue2); - outb(ATTRX, IOValue1); - (void)inb(GENS1(pVGA->CPIO_VGABase)); - if (IOValue3 == (IOValue2 ^ 0x0FU)) - { - /* VGA device detected */ - if (pVGA->Chip == ATI_CHIP_NONE) - pVGA->Chip = ATI_CHIP_VGA; - if (pVGA->VGAAdapter == ATI_ADAPTER_NONE) - pVGA->VGAAdapter = ATI_ADAPTER_VGA; - if (pVGA->Adapter == ATI_ADAPTER_NONE) - pVGA->Adapter = ATI_ADAPTER_VGA; - } - else - { - pVGA->VGAAdapter = ATI_ADAPTER_NONE; - } - - return pVGA; -} - -/* * ATIVGAWonderProbe -- * * This function determines if ATI extended VGA registers can be accessed @@ -282,50 +62,29 @@ static void ATIVGAWonderProbe ( pciVideoPtr pVideo, - ATIPtr pATI, - ATIPtr p8514, - CARD8 *ProbeFlags + ATIPtr pATI ) { CARD8 IOValue1, IOValue2, IOValue3, IOValue4, IOValue5, IOValue6; - switch (ATICheckSparseIOBases(pVideo, ProbeFlags, - pATI->CPIO_VGAWonder, 2, TRUE)) - { - case 0: - xf86Msg(X_WARNING, - ATI_NAME ": Expected VGA Wonder capability could not be" - " detected at I/O port 0x%04lX because it would conflict with" - " a non-video PCI/AGP device.\n", pATI->CPIO_VGAWonder); - pATI->CPIO_VGAWonder = 0; - break; - - case Detected8514A: - xf86Msg(X_WARNING, - ATI_NAME ": Expected VGA Wonder capability could not be" - " detected at I/O port 0x%04lX because it would conflict with" - " a %s %s.\n", pATI->CPIO_VGAWonder, - ATIBusNames[p8514->BusType], ATIAdapterNames[p8514->Adapter]); - pATI->CPIO_VGAWonder = 0; - break; - - case DetectedMach64: - xf86Msg(X_WARNING, - ATI_NAME ": Expected VGA Wonder capability could not be" - " detected at I/O port 0x%04lX because it would conflict with" - " a Mach64.\n", pATI->CPIO_VGAWonder); - pATI->CPIO_VGAWonder = 0; - break; - - case DetectedVGA: - default: /* Must be DoProbe */ + if (!pATI->OptionProbeSparse) + { + xf86Msg(X_WARNING, + ATI_NAME ": Expected VGA Wonder capability at I/O port" + " 0x%04lX will not be probed\n" + "set option \"probe_sparse\" to force probing.\n", + pATI->CPIO_VGAWonder); + + pATI->CPIO_VGAWonder = 0; + return; + } + if (pVideo && !xf86IsPrimaryPci(pVideo) && (pATI->Chip <= ATI_CHIP_88800GXD)) { /* Set up extended VGA register addressing */ PutReg(GRAX, 0x50U, GetByte(pATI->CPIO_VGAWonder, 0)); - PutReg(GRAX, 0x51U, - GetByte(pATI->CPIO_VGAWonder, 1) | pATI->VGAOffset); + PutReg(GRAX, 0x51U, GetByte(pATI->CPIO_VGAWonder, 1) | 0x80U); } /* * Register 0xBB is used by the BIOS to keep track of various @@ -341,10 +100,7 @@ ATIVGAWonderProbe ATIPutExtReg(0xBBU, IOValue3 ^ 0x55U); IOValue5 = ATIGetExtReg(0xBBU); ATIPutExtReg(0xBBU, IOValue3); - if (pATI->Chip <= ATI_CHIP_18800_1) - IOValue6 = 0; - else - IOValue6 = ATIGetExtReg(0xBCU); + IOValue6 = ATIGetExtReg(0xBCU); ATIPutExtReg(IOValue1, IOValue2); if ((IOValue4 == (IOValue3 ^ 0xAAU)) && @@ -362,151 +118,6 @@ ATIVGAWonderProbe " 0x%04lX was not detected.\n", pATI->CPIO_VGAWonder); pATI->CPIO_VGAWonder = 0; } - break; - } -} - -/* - * ATI8514Probe -- - * - * This function looks for an 8514/A compatible and returns an ATIRec if one is - * found. The function also determines whether or not the detected 8514/A - * compatible device is actually a Mach8 or Mach32, and sets pATI->Adapter - * accordingly. - */ -static ATIPtr -ATI8514Probe -( - pciVideoPtr pVideo -) -{ - ATIPtr pATI = NULL; - CARD16 IOValue1, IOValue2; - - /* - * Save register value to be modified, just in case there is no 8514/A - * compatible accelerator. Note that, in more ways than one, - * SUBSYS_STAT == SUBSYS_CNTL. - */ - IOValue1 = inw(SUBSYS_STAT); - IOValue2 = IOValue1 & _8PLANE; - - /* Reset any 8514/A compatible adapter that might be present */ - outw(SUBSYS_CNTL, IOValue2 | (GPCTRL_RESET | CHPTEST_NORMAL)); - outw(SUBSYS_CNTL, IOValue2 | (GPCTRL_ENAB | CHPTEST_NORMAL | - RVBLNKFLG | RPICKFLAG | RINVALIDIO | RGPIDLE)); - - /* Probe for an 8514/A compatible */ - IOValue2 = inw(ERR_TERM); - outw(ERR_TERM, 0x5A5AU); - ProbeWaitIdleEmpty(); - if (inw(ERR_TERM) == 0x5A5AU) - { - outw(ERR_TERM, 0x2525U); - if (inw(ERR_TERM) == 0x2525U) - { - pATI = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec)); - pATI->Adapter = ATI_ADAPTER_8514A; - pATI->ChipHasSUBSYS_CNTL = TRUE; - pATI->PCIInfo = pVideo; - } - } - outw(ERR_TERM, IOValue2); - - /* Restore register value clobbered by 8514/A reset attempt */ - if (!pATI) - { - outw(SUBSYS_CNTL, IOValue1); - return NULL; - } - - /* Ensure any Mach8 or Mach32 is not in 8514/A emulation mode */ - IOValue1 = inw(CLOCK_SEL); - outw(CLOCK_SEL, IOValue1); - ProbeWaitIdleEmpty(); - - IOValue1 = IOValue2 = inw(ROM_ADDR_1); - outw(ROM_ADDR_1, 0x5555U); - ProbeWaitIdleEmpty(); - if (inw(ROM_ADDR_1) == 0x5555U) - { - outw(ROM_ADDR_1, 0x2A2AU); - ProbeWaitIdleEmpty(); - if (inw(ROM_ADDR_1) == 0x2A2AU) - pATI->Adapter = ATI_ADAPTER_MACH8; - } - outw(ROM_ADDR_1, IOValue1); - - if (pATI->Adapter == ATI_ADAPTER_MACH8) - { - /* A Mach8 or Mach32 has been detected */ - IOValue1 = inw(READ_SRC_X); - outw(DESTX_DIASTP, 0xAAAAU); - ProbeWaitIdleEmpty(); - if (inw(READ_SRC_X) == 0x02AAU) - pATI->Adapter = ATI_ADAPTER_MACH32; - - outw(DESTX_DIASTP, 0x5555U); - ProbeWaitIdleEmpty(); - if (inw(READ_SRC_X) == 0x0555U) - { - if (pATI->Adapter != ATI_ADAPTER_MACH32) - pATI->Adapter = ATI_ADAPTER_8514A; - } - else - { - if (pATI->Adapter != ATI_ADAPTER_MACH8) - pATI->Adapter = ATI_ADAPTER_8514A; - } - outw(DESTX_DIASTP, IOValue1); - } - - switch (pATI->Adapter) - { - case ATI_ADAPTER_8514A: - pATI->Coprocessor = ATI_CHIP_8514A; - IOValue1 = inb(EXT_CONFIG_3); - outb(EXT_CONFIG_3, IOValue1 & 0x0FU); - if (!(inb(EXT_CONFIG_3) & 0xF0U)) - { - outb(EXT_CONFIG_3, IOValue1 | 0xF0U); - if ((inb(EXT_CONFIG_3) & 0xF0U) == 0xF0U) - pATI->Coprocessor = ATI_CHIP_CT480; - } - outb(EXT_CONFIG_3, IOValue1); - break; - - case ATI_ADAPTER_MACH8: - pATI->Coprocessor = ATI_CHIP_38800_1; - if (inw(CONFIG_STATUS_1) & MC_BUS) - pATI->BusType = ATI_BUS_MCA16; - break; - - case ATI_ADAPTER_MACH32: - IOValue1 = inw(CONFIG_STATUS_1); - pATI->BusType = GetBits(IOValue1, BUS_TYPE); - pATI->BIOSBase = 0x000C0000U + - (GetBits(IOValue2, BIOS_BASE_SEGMENT) << 11); - if (!(IOValue1 & (_8514_ONLY | CHIP_DIS))) - { - pATI->VGAAdapter = ATI_ADAPTER_MACH32; - if ((xf86ReadBIOS(pATI->BIOSBase, 0x10U, - (pointer)(&pATI->CPIO_VGAWonder), - SizeOf(pATI->CPIO_VGAWonder)) < - SizeOf(pATI->CPIO_VGAWonder)) || - !(pATI->CPIO_VGAWonder &= SPARSE_IO_PORT)) - pATI->CPIO_VGAWonder = 0x01CEU; - pATI->VGAOffset = 0x80U; - } - - ATIMach32ChipID(pATI); - break; - - default: - break; - } - - return pATI; } #endif /* AVOID_CPIO */ @@ -526,6 +137,7 @@ ATIMach64Detect ) { CARD32 IOValue, bus_cntl, gen_test_cntl; + Bool DetectSuccess = FALSE; (void)ATIMapApertures(-1, pATI); /* Ignore errors */ @@ -575,7 +187,7 @@ ATIMach64Detect ATIMach64ChipID(pATI, ChipType); if ((pATI->Chip != ATI_CHIP_Mach64) || (pATI->CPIODecoding == BLOCK_IO)) - pATI->Adapter = ATI_ADAPTER_MACH64; + DetectSuccess = TRUE; } } @@ -583,7 +195,7 @@ ATIMach64Detect outr(SCRATCH_REG0, IOValue); /* If no Mach64 was detected, return now */ - if (pATI->Adapter != ATI_ADAPTER_MACH64) + if (!DetectSuccess) { outr(GEN_TEST_CNTL, gen_test_cntl); outr(BUS_CNTL, bus_cntl); @@ -596,7 +208,6 @@ ATIMach64Detect (GetBits(inr(SCRATCH_REG1), BIOS_BASE_SEGMENT) << 11); ATIUnmapApertures(-1, pATI); - pATI->PCIInfo = NULL; return TRUE; } @@ -611,22 +222,12 @@ ATIMach64Detect static ATIPtr ATIMach64Probe ( + ATIPtr pATI, pciVideoPtr pVideo, - const IOADDRESS IOBase, - const CARD8 IODecoding, const ATIChipType Chip ) { - ATIPtr pATI = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec)); - CARD16 ChipType = 0; - - pATI->CPIOBase = IOBase; - pATI->CPIODecoding = IODecoding; - - if (pVideo) - { - pATI->PCIInfo = pVideo; - ChipType = pVideo->chipType; + CARD16 ChipType = pVideo->chipType; /* * Probe through auxiliary MMIO aperture if one exists. Because such @@ -656,7 +257,6 @@ ATIMach64Probe if (ATIMach64Detect(pATI, ChipType, Chip)) return pATI; } - } /* * A last, perhaps desparate, probe attempt. Note that if this succeeds, @@ -669,7 +269,6 @@ LastProbe: if (ATIMach64Detect(pATI, ChipType, Chip)) return pATI; - xfree(pATI); return NULL; } @@ -681,40 +280,24 @@ LastProbe: * This function looks for a Mach64 at a particular PIO address and returns an * ATIRec if one is found. */ -static ATIPtr +ATIPtr ATIMach64Probe ( + ATIPtr pATI, pciVideoPtr pVideo, - const IOADDRESS IOBase, - const CARD8 IODecoding, const ATIChipType Chip ) { - ATIPtr pATI; CARD32 IOValue; - CARD16 ChipType = 0; - - if (!IOBase) - return NULL; + CARD16 ChipType = pVideo->chipType; - if (pVideo) - { - if ((IODecoding == BLOCK_IO) && + if ((pATI->CPIODecoding == BLOCK_IO) && ((pVideo->size[1] < 8) || - (IOBase >= (CARD32)(-1 << pVideo->size[1])))) + (pATI->CPIOBase >= (CARD32)(-1 << pVideo->size[1])))) return NULL; - ChipType = pVideo->chipType; - } - - pATI = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec)); - pATI->CPIOBase = IOBase; - pATI->CPIODecoding = IODecoding; - pATI->PCIInfo = pVideo; - if (!ATIMach64Detect(pATI, ChipType, Chip)) { - xfree(pATI); return NULL; } @@ -724,7 +307,7 @@ ATIMach64Probe */ if (pATI->Chip >= ATI_CHIP_264CT) { - pATI->VGAAdapter = ATI_ADAPTER_MACH64; + pATI->VGAAdapter = TRUE; } else { @@ -735,153 +318,24 @@ ATIMach64Probe IOValue |= CFG_VGA_EN; if (IOValue == (CFG_VGA_EN | CFG_CHIP_EN)) { - pATI->VGAAdapter = ATI_ADAPTER_MACH64; + pATI->VGAAdapter = TRUE; pATI->CPIO_VGAWonder = 0x01CEU; - pATI->VGAOffset = 0x80U; } } return pATI; } -/* - * ATIAssignVGA -- - * - * This function is called to associate a VGA interface with an accelerator. - * This is done by temporarily configuring the accelerator to route VGA RAMDAC - * I/O through the accelerator's RAMDAC. A value is then written through the - * VGA DAC ports and a check is made to see if the same value shows up on the - * accelerator side. - */ static void ATIAssignVGA ( pciVideoPtr pVideo, - ATIPtr *ppVGA, - ATIPtr pATI, - ATIPtr p8514, - CARD8 *ProbeFlags + ATIPtr pATI ) { - ATIPtr pVGA = *ppVGA; - CARD8 OldDACMask; - - /* Assume unassignable VGA */ - pATI->VGAAdapter = ATI_ADAPTER_NONE; - - /* If no assignable VGA, return now */ - if ((pATI != pVGA) && (!pVGA || (pVGA->Adapter > ATI_ADAPTER_VGA))) - return; - - switch (pATI->Adapter) - { - case ATI_ADAPTER_8514A: - { - /* - * Assumption: Bit DISABPASSTHRU in ADVFUNC_CNTL is already - * off. - */ - OldDACMask = inb(VGA_DAC_MASK); - - if (inb(IBM_DAC_MASK) == OldDACMask) - { - outb(VGA_DAC_MASK, 0xA5U); - if (inb(IBM_DAC_MASK) == 0xA5U) - pATI->VGAAdapter = ATI_ADAPTER_VGA; - outb(VGA_DAC_MASK, OldDACMask); - } - } - break; - - case ATI_ADAPTER_MACH8: - { - CARD16 ClockSel = inw(CLOCK_SEL); - - if (ClockSel & DISABPASSTHRU) - outw(CLOCK_SEL, ClockSel & ~DISABPASSTHRU); - - ProbeWaitIdleEmpty(); - - OldDACMask = inb(VGA_DAC_MASK); - - if (inb(IBM_DAC_MASK) == OldDACMask) - { - outb(VGA_DAC_MASK, 0xA5U); - if (inb(IBM_DAC_MASK) == 0xA5U) - pATI->VGAAdapter = ATI_ADAPTER_VGA; - outb(VGA_DAC_MASK, OldDACMask); - } - - if (ClockSel & DISABPASSTHRU) - outw(CLOCK_SEL, ClockSel); - } - break; - - case ATI_ADAPTER_MACH32: - { - CARD16 ClockSel = inw(CLOCK_SEL), - MiscOptions = inw(MISC_OPTIONS); - - if (ClockSel & DISABPASSTHRU) - outw(CLOCK_SEL, ClockSel & ~DISABPASSTHRU); - if (MiscOptions & (DISABLE_VGA | DISABLE_DAC)) - outw(MISC_OPTIONS, - MiscOptions & ~(DISABLE_VGA | DISABLE_DAC)); - - ProbeWaitIdleEmpty(); - - OldDACMask = inb(VGA_DAC_MASK); - - if (inb(IBM_DAC_MASK) == OldDACMask) - { - outb(VGA_DAC_MASK, 0xA5U); - if (inb(IBM_DAC_MASK) == 0xA5U) - pATI->VGAAdapter = ATI_ADAPTER_MACH32; - outb(VGA_DAC_MASK, OldDACMask); - } - - if (ClockSel & DISABPASSTHRU) - outw(CLOCK_SEL, ClockSel); - if (MiscOptions & (DISABLE_VGA | DISABLE_DAC)) - outw(MISC_OPTIONS, MiscOptions); - } - break; - - case ATI_ADAPTER_MACH64: - { - CARD32 DACCntl = inr(DAC_CNTL); - - if (!(DACCntl & DAC_VGA_ADR_EN)) - outr(DAC_CNTL, DACCntl | DAC_VGA_ADR_EN); - - OldDACMask = inb(VGA_DAC_MASK); - - if (in8(M64_DAC_MASK) == OldDACMask) - { - outb(VGA_DAC_MASK, 0xA5U); - if (in8(M64_DAC_MASK) == 0xA5U) - pATI->VGAAdapter = ATI_ADAPTER_MACH64; - outb(VGA_DAC_MASK, OldDACMask); - } - - if (!(DACCntl & DAC_VGA_ADR_EN)) - outr(DAC_CNTL, DACCntl); - } - break; - - default: - break; - } - - if (pATI->VGAAdapter == ATI_ADAPTER_NONE) - { - pATI->CPIO_VGAWonder = 0; - return; - } - if (pATI->CPIO_VGAWonder) { - ATIVGAWonderProbe(pVideo, pATI, p8514, ProbeFlags); + ATIVGAWonderProbe(pVideo, pATI); if (!pATI->CPIO_VGAWonder) { /* @@ -891,55 +345,11 @@ ATIAssignVGA * of I/O through the bus tree. */ pATI->CPIO_VGAWonder = GRAX; - ATIVGAWonderProbe(pVideo, pATI, p8514, ProbeFlags); + ATIVGAWonderProbe(pVideo, pATI); } } - - if (pATI == pVGA) - { - pATI->SharedVGA = TRUE; - return; - } - - /* Assign the VGA to this adapter */ - xfree(pVGA); - *ppVGA = pATI; - - xf86MsgVerb(X_INFO, 3, ATI_NAME ": VGA assigned to this adapter.\n"); -} - -#ifndef AVOID_NON_PCI - -/* - * ATIClaimVGA -- - * - * Attempt to assign a non-shareable VGA to an accelerator. If successful, - * update ProbeFlags array. - */ -static void -ATIClaimVGA -( - pciVideoPtr pVideo, - ATIPtr *ppVGA, - ATIPtr pATI, - ATIPtr p8514, - CARD8 *ProbeFlags, - int Detected -) -{ - ATIAssignVGA(pVideo, ppVGA, pATI, p8514, ProbeFlags); - if (pATI->VGAAdapter == ATI_ADAPTER_NONE) - return; - - ATIClaimSparseIOBases(ProbeFlags, MonochromeIOBase, 48, Detected); - if (!pATI->CPIO_VGAWonder) - return; - - ATIClaimSparseIOBases(ProbeFlags, pATI->CPIO_VGAWonder, 2, Detected); } -#endif /* AVOID_NON_PCI */ - /* * ATIFindVGA -- * @@ -950,16 +360,9 @@ static void ATIFindVGA ( pciVideoPtr pVideo, - ATIPtr *ppVGA, - ATIPtr *ppATI, - ATIPtr p8514, - CARD8 *ProbeFlags + ATIPtr pATI ) { - ATIPtr pATI = *ppATI; - - if (!*ppVGA) - { /* * An ATI PCI adapter has been detected at this point, and its VGA, if * any, is shareable. Ensure the VGA isn't in sleep mode. @@ -968,1330 +371,290 @@ ATIFindVGA outb(GENVS, 0x01U); outb(GENENA, 0x0EU); - pATI = ATIVGAProbe(pATI); - if (pATI->VGAAdapter == ATI_ADAPTER_NONE) - return; - - ppVGA = ppATI; - } - - ATIAssignVGA(pVideo, ppVGA, pATI, p8514, ProbeFlags); + ATIAssignVGA(pVideo, pATI); } #endif /* AVOID_CPIO */ /* - * ATIProbe -- + * ATIMach64ProbeIO -- * - * This function is called once, at the start of the first server generation to - * do a minimal probe for supported hardware. + * This function determines the IO method and IO base of the ATI PCI adapter. */ Bool -ATIProbe +ATIMach64ProbeIO ( - DriverPtr pDriver, - int flags + pciVideoPtr pVideo, + ATIPtr pATI ) { - ATIPtr pATI, *ATIPtrs = NULL; - GDevPtr *GDevs, pGDev; - pciVideoPtr pVideo, *xf86PciVideoInfo = xf86GetPciVideoInfo(); - ATIGDev *ATIGDevs = NULL, *pATIGDev; - ScrnInfoPtr pScreenInfo; - Bool ProbeSuccess = FALSE; - Bool DoRage128 = FALSE, DoRadeon = FALSE; - int i, j, k; - int nGDev, nATIGDev = -1, nATIPtr = 0; - int Chipset; - ATIChipType Chip; - -#if !defined(AVOID_NON_PCI) || !defined(AVOID_CPIO) - pciConfigPtr pPCI; - CARD32 PciReg; -#endif /* AVOID_NON_PCI || AVOID_CPIO */ - -#ifndef AVOID_NON_PCI - ATIPtr pMach64[3] = {NULL, NULL, NULL}; -#endif - -#ifndef AVOID_CPIO - - ATIPtr pVGA = NULL, p8514 = NULL; - pciConfigPtr *xf86PciInfo = xf86GetPciConfigInfo(); - PortPtr PCIPorts = NULL; - int nPCIPort = 0; - CARD8 fChipsets[ATI_CHIPSET_MAX]; - static const IOADDRESS Mach64SparseIOBases[] = {0x02ECU, 0x01CCU, 0x01C8U}; - CARD8 ProbeFlags[LongPort(SPARSE_IO_BASE) + 1]; - - unsigned long BIOSBase; - static const CARD8 ATISignature[] = " 761295520"; -# define SignatureSize 10 -# define PrefixSize 0x50U -# define BIOSSignature 0x30U - CARD8 BIOS[PrefixSize]; -# define BIOSWord(_n) (BIOS[_n] | (BIOS[(_n) + 1] << 8)) - -#endif /* AVOID_CPIO */ - -# define AddAdapter(_p) \ - do \ - { \ - nATIPtr++; \ - ATIPtrs = (ATIPtr *)xnfrealloc(ATIPtrs, SizeOf(ATIPtr) * nATIPtr); \ - ATIPtrs[nATIPtr - 1] = (_p); \ - (_p)->iEntity = -2; \ - } while (0) + Bool ProbeSuccess = FALSE; #ifndef AVOID_CPIO - (void)memset(fChipsets, FALSE, SizeOf(fChipsets)); - -#endif /* AVOID_CPIO */ - - if (!(flags & PROBE_DETECT)) + /* Next, look for sparse I/O Mach64's */ + if (!pVideo->size[1]) { - /* - * Get a list of XF86Config device sections whose "Driver" is either - * not specified, or specified as this driver. From this list, - * eliminate those device sections that specify a "Chipset" or a - * "ChipID" not recognised by the driver. Those device sections that - * specify a "ChipRev" without a "ChipID" are also weeded out. - */ - nATIGDev = 0; - if ((nGDev = xf86MatchDevice(ATI_NAME, &GDevs)) > 0) - { - ATIGDevs = (ATIGDevPtr)xnfcalloc(nGDev, SizeOf(ATIGDev)); - - for (i = 0, pATIGDev = ATIGDevs; i < nGDev; i++) - { - pGDev = GDevs[i]; - Chipset = ATIIdentProbe(pGDev->chipset); - if (Chipset == -1) - continue; - - if ((pGDev->chipID > (int)((CARD16)(-1))) || - (pGDev->chipRev > (int)((CARD8)(-1)))) - continue; - - if (pGDev->chipID >= 0) - { - if (ATIChipID(pGDev->chipID, 0) == ATI_CHIP_Mach64) - continue; - } - else - { - if (pGDev->chipRev >= 0) - continue; - } - - pATIGDev->pGDev = pGDev; - pATIGDev->Chipset = Chipset; - nATIGDev++; - pATIGDev++; - - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": Candidate \"Device\" section \"%s\".\n", - pGDev->identifier); - -#ifndef AVOID_CPIO - - fChipsets[Chipset] = TRUE; - -#endif /* AVOID_CPIO */ - - } - - xfree(GDevs); - - if (!nATIGDev) - { - xfree(ATIGDevs); - ATIGDevs = NULL; - } - } - - if (xf86MatchDevice(R128_NAME, NULL) > 0) - DoRage128 = TRUE; - if (xf86MatchDevice(RADEON_NAME, NULL) > 0) - DoRadeon = TRUE; - } - -#ifndef AVOID_CPIO - - /* - * Collect hardware information. This must be done with care to avoid - * lockups due to overlapping I/O port assignments. - * - * First, scan PCI configuration space for registered I/O ports (which will - * be block I/O bases). Each such port is used to generate a list of - * sparse I/O bases it precludes. This list is then used to decide whether - * or not certain sparse I/O probes are done. Unfortunately, this assumes - * that any registered I/O base actually reserves upto the full 256 ports - * allowed by the PCI specification. This assumption holds true for PCI - * Mach64, but probably doesn't for other device types. For some things, - * such as video devices, the number of ports a base represents is - * determined by the server's PCI probe, but, for other devices, this - * cannot be done by a user-level process without jeopardizing system - * integrity. This information should ideally be retrieved from the OS's - * own PCI probe (if any), but there's currently no portable way of doing - * so. The following allows sparse I/O probes to be forced in certain - * circumstances when an appropriate chipset specification is used in any - * XF86Config Device section. - * - * Note that this is not bullet-proof. Lockups can still occur, but they - * will usually be due to devices that are misconfigured to respond to the - * same I/O ports as 8514/A's or ATI sparse I/O devices without registering - * them in PCI configuration space. - */ - if (nATIGDev) - { - if (xf86PciVideoInfo) - { - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor == PCI_VENDOR_ATI) || - !(pPCI = pVideo->thisCard)) - continue; - - ATIScanPCIBases(&PCIPorts, &nPCIPort, - &pPCI->pci_base0, pVideo->size, - (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) & - PCI_CMD_IO_ENABLE) ? 0 : Allowed); - } - } - - /* Check non-video PCI devices for I/O bases */ - if (xf86PciInfo) - { - for (i = 0; (pPCI = xf86PciInfo[i++]); ) - { - if ((pPCI->pci_vendor == PCI_VENDOR_ATI) || - (pPCI->pci_base_class == PCI_CLASS_BRIDGE) || - (pPCI->pci_header_type & - ~GetByte(PCI_HEADER_MULTIFUNCTION, 2))) - continue; - - ATIScanPCIBases(&PCIPorts, &nPCIPort, - &pPCI->pci_base0, pPCI->basesize, - (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) & - PCI_CMD_IO_ENABLE) ? 0 : Allowed); - } - } - - /* Generate ProbeFlags array from list of registered PCI I/O bases */ - (void)memset(ProbeFlags, Allowed | DoProbe, SizeOf(ProbeFlags)); - for (i = 0; i < nPCIPort; i++) + static const IOADDRESS Mach64SparseIOBases[] = { + 0x02ECU, + 0x01CCU, + 0x01C8U + }; + pciConfigPtr pPCI = pVideo->thisCard; + CARD32 PciReg; + CARD32 j; + + if (pPCI == NULL) + goto SkipSparse; + + PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); + j = PciReg & 0x03U; + + if (j == 0x03U) { - CARD32 Base = PCIPorts[i].Base; - CARD16 Count = (1 << PCIPorts[i].Size) - 1; - CARD8 ProbeFlag = PCIPorts[i].Flag; + xf86Msg(X_WARNING, ATI_NAME ": " + "PCI Mach64 in slot %d:%d:%d cannot be enabled\n" + "because it has neither a block, nor a sparse, I/O base.\n", + pVideo->bus, pVideo->device, pVideo->func); - /* - * The following reduction of Count is based on the assumption that - * PCI-registered I/O port ranges do not overlap. - */ - for (j = 0; j < nPCIPort; j++) - { - CARD32 Base2 = PCIPorts[j].Base; - - if (Base < Base2) - while ((Base + Count) >= Base2) - Count >>= 1; - } - - Base = LongPort(Base); - Count = LongPort((Count | IO_BYTE_SELECT) + 1); - while (Count--) - ProbeFlags[Base++] &= ProbeFlag; + goto SkipSparse; } - xfree(PCIPorts); - -#ifndef AVOID_NON_PCI - - /* - * A note on probe strategy. I/O and memory response by certain PCI - * devices has been disabled by the common layer at this point, - * including any devices this driver might be interested in. The - * following does sparse I/O probes, followed by block I/O probes. - * Block I/O probes are dictated by what is found to be of interest in - * PCI configuration space. All this will detect ATI adapters that do - * not implement this disablement, pre-PCI or not. + /* FIXME: + * Should not probe at sparse I/O bases which have been registered to + * other PCI devices. The old ATIProbe() would scan the PCI space and + * build a list of registered I/O ports. If there was a conflict + * between a mach64 sparse I/O base and a registered I/0 port, probing + * that port was not allowed... * - * PCI configuration space is then scanned again for ATI devices that - * failed to be detected the first time around. Each such device is - * probed for again, this time with I/O temporarily enabled through - * PCI. + * We just add an option and let the user decide, this will not work + * with "X -configure" though... */ - if (ATICheckSparseIOBases(NULL, ProbeFlags, ATTRX, 16, TRUE) == - DoProbe) + if (!pATI->OptionProbeSparse) { - pATI = ATIVGAProbe(NULL); - if (pATI->Adapter == ATI_ADAPTER_NONE) - { - xfree(pATI); + xf86Msg(X_WARNING, ATI_NAME ": " + "PCI Mach64 in slot %d:%d:%d will not be probed\n" + "set option \"probe_sparse\" to force sparse I/O probing.\n", + pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 4, - ATI_NAME ": Unshared VGA not detected.\n"); - } - else - { - /* - * Claim all MDA/HGA/CGA/EGA/VGA I/O ports. This might need to - * be more selective. - */ - ATIClaimSparseIOBases(ProbeFlags, MonochromeIOBase, 48, - DetectedVGA); - - pVGA = pATI; - strcpy(Identifier, "Unshared VGA"); - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s detected.\n", Identifier); - } - } - else - { - xf86MsgVerb(X_INFO, 2, ATI_NAME ": Unshared VGA not probed.\n"); + goto SkipSparse; } - /* - * Mach8/32 probing doesn't work well on some legacy free ia64 - * However if we use AVOID_CPIO we don't get here at all. - */ - if (ATICheckSparseIOBases(NULL, ProbeFlags, 0x02E8U, 8, - fChipsets[ATI_CHIPSET_IBM8514] || - fChipsets[ATI_CHIPSET_MACH8] || - fChipsets[ATI_CHIPSET_MACH32]) == DoProbe) - { - if ((pATI = ATI8514Probe(NULL))) - { - strcpy(Identifier, "Unshared 8514/A"); - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s detected.\n", Identifier); - - AddAdapter(p8514 = pATI); + /* Possibly fix block I/O indicator */ + if (PciReg & 0x00000004U) + pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, PciReg & ~0x00000004U); - if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) || - (pATI->Coprocessor != ATI_CHIP_NONE)) - ATIClaimVGA(NULL, &pVGA, pATI, p8514, ProbeFlags, - Detected8514A); + pATI->CPIOBase = Mach64SparseIOBases[j]; + pATI->CPIODecoding = SPARSE_IO; + pATI->PCIInfo = pVideo; - ATIClaimSparseIOBases(ProbeFlags, 0x02E8U, 8, Detected8514A); - } - else - { - xf86MsgVerb(X_INFO, 4, - ATI_NAME ": Unshared 8514/A not detected.\n"); - } - } - else + if (!ATIMach64Probe(pATI, pVideo, pATI->Chip)) { - xf86MsgVerb(X_INFO, 2, - ATI_NAME ": Unshared 8514/A not probed.\n"); + xf86Msg(X_WARNING, ATI_NAME ": " + "PCI Mach64 in slot %d:%d:%d could not be detected!\n", + pVideo->bus, pVideo->device, pVideo->func); } - - /* - * Also NONPCI Mach64 probing is evil on legacy free platforms. - * However if we use AVOID_CPIO we don't get here at all. - */ - for (i = 0; i < NumberOf(Mach64SparseIOBases); i++) + else { - if (ATICheckSparseIOBases(NULL, ProbeFlags, Mach64SparseIOBases[i], - 4, fChipsets[ATI_CHIPSET_MACH64]) != DoProbe) - { - xf86MsgVerb(X_INFO, 2, - ATI_NAME ": Unshared Mach64 at PIO base 0x%04lX not" - " probed.\n", - Mach64SparseIOBases[i]); - continue; - } - - pATI = ATIMach64Probe(NULL, Mach64SparseIOBases[i], SPARSE_IO, 0); - if (!pATI) - { - xf86MsgVerb(X_INFO, 4, - ATI_NAME ": Unshared Mach64 at PIO base 0x%04lX not" - " detected.\n", Mach64SparseIOBases[i]); - continue; - } - - sprintf(Identifier, "Unshared Mach64 at sparse PIO base 0x%04lX", - Mach64SparseIOBases[i]); - xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", Identifier); - - AddAdapter(pMach64[i] = pATI); - - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIClaimVGA(NULL, &pVGA, pATI, p8514, ProbeFlags, - DetectedMach64); - - ATIClaimSparseIOBases(ProbeFlags, Mach64SparseIOBases[i], 4, - DetectedMach64); + ProbeSuccess = TRUE; + xf86Msg(X_INFO, ATI_NAME ": " + "Shared PCI Mach64 in slot %d:%d:%d with sparse PIO base" + " 0x%04lX detected.\n", + pVideo->bus, pVideo->device, pVideo->func, + Mach64SparseIOBases[j]); + + if (pATI->VGAAdapter) + ATIFindVGA(pVideo, pATI); } -#endif /* AVOID_NON_PCI */ - } -#endif /* AVOID_CPIO */ - - if (xf86PciVideoInfo) - { - if (nATIGDev) - { - -#ifndef AVOID_NON_PCI - -#ifdef AVOID_CPIO - - /* PCI sparse I/O adapters can still be used through MMIO */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - pVideo->size[1] || - !(pPCI = pVideo->thisCard)) - continue; - - PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); - - /* Possibly fix block I/O indicator */ - if (PciReg & 0x00000004U) - pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, - PciReg & ~0x00000004U); - - Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); - - /* - * The CPIO base used by the adapter is of little concern here. - */ - pATI = ATIMach64Probe(pVideo, 0, SPARSE_IO, Chip); - if (!pATI) - continue; - - sprintf(Identifier, - "Unshared PCI sparse I/O Mach64 in slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s detected through Block 0 at 0x%08lX.\n", - Identifier, pATI->Block0Base); - AddAdapter(pATI); - pATI->PCIInfo = pVideo; - } - -#endif /* AVOID_CPIO */ - - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - !pVideo->size[1]) - continue; - - /* For now, ignore Rage128's and Radeon's */ - Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); - if ((Chip > ATI_CHIP_Mach64) || - !(pPCI = pVideo->thisCard)) - continue; - - /* - * Possibly fix block I/O indicator in PCI configuration space. - */ - PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); - if (!(PciReg & 0x00000004U)) - pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, - PciReg | 0x00000004U); - - pATI = - ATIMach64Probe(pVideo, pVideo->ioBase[1], BLOCK_IO, Chip); - if (!pATI) - continue; - - sprintf(Identifier, "Unshared PCI/AGP Mach64 in slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s detected.\n", Identifier); - AddAdapter(pATI); - -#ifndef AVOID_CPIO - - /* This is probably not necessary */ - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIClaimVGA(pVideo, &pVGA, pATI, p8514, - ProbeFlags, DetectedMach64); - -#endif /* AVOID_CPIO */ - - } - -#endif /* AVOID_NON_PCI */ - -#ifndef AVOID_CPIO - - /* - * This is the second pass through PCI configuration space. Much - * of this is verbiage to deal with potential situations that are - * very unlikely to occur in practice. - * - * First, look for non-ATI shareable VGA's. For now, these must - * the primary device. - */ - if (ATICheckSparseIOBases(NULL, ProbeFlags, ATTRX, 16, TRUE) == - DoProbe) - { - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor == PCI_VENDOR_ATI) || - !xf86IsPrimaryPci(pVideo)) - continue; - - if (!xf86CheckPciSlot(pVideo->bus, - pVideo->device, - pVideo->func)) - continue; - - xf86SetPciVideo(pVideo, MEM_IO); - - pATI = ATIVGAProbe(NULL); - if (pATI->Adapter == ATI_ADAPTER_NONE) - { - xfree(pATI); - xf86Msg(X_WARNING, - ATI_NAME ": PCI/AGP VGA compatible in slot" - " %d:%d:%d could not be detected!\n", - pVideo->bus, pVideo->device, pVideo->func); - } - else - { - sprintf(Identifier, - "Shared non-ATI VGA in PCI/AGP slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", - Identifier); - AddAdapter(pATI); - pATI->SharedVGA = TRUE; - pATI->BusType = ATI_BUS_PCI; - pATI->PCIInfo = pVideo; - } - - xf86SetPciVideo(NULL, NONE); - } - } - - /* Next, look for PCI Mach32's */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType != PCI_CHIP_MACH32)) - continue; - - switch (ATICheckSparseIOBases(pVideo, ProbeFlags, - 0x02E8U, 8, TRUE)) - { - case 0: - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach32 in slot %d:%d:%d will not" - " be enabled\n because it conflicts with a" - " non-video PCI/AGP device.\n", - pVideo->bus, pVideo->device, pVideo->func); - break; - -#ifndef AVOID_NON_PCI - - case Detected8514A: - if ((p8514->BusType >= ATI_BUS_PCI) && !p8514->PCIInfo) - p8514->PCIInfo = pVideo; - else - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach32 in slot %d:%d:%d will" - " not be enabled\n because it conflicts with" - " another %s %s.\n", - pVideo->bus, pVideo->device, pVideo->func, - ATIBusNames[p8514->BusType], - ATIAdapterNames[p8514->Adapter]); - break; - - case DetectedMach64: - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach32 in slot %d:%d:%d will not" - " be enabled\n because it conflicts with a Mach64" - " at I/O base 0x02EC.\n", - pVideo->bus, pVideo->device, pVideo->func); - break; - -#endif /* AVOID_NON_PCI */ - - default: /* Must be DoProbe */ - if (!xf86CheckPciSlot(pVideo->bus, - pVideo->device, - pVideo->func)) - continue; - - xf86SetPciVideo(pVideo, MEM_IO); - - if (!(pATI = ATI8514Probe(pVideo))) - { - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach32 in slot %d:%d:%d could" - " not be detected!\n", - pVideo->bus, pVideo->device, pVideo->func); - } - else - { - sprintf(Identifier, - "Shared 8514/A in PCI slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s detected.\n", Identifier); - if (pATI->Adapter != ATI_ADAPTER_MACH32) - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach32 in slot %d:%d:%d" - " could only be detected as an %s!\n", - pVideo->bus, pVideo->device, pVideo->func, - ATIAdapterNames[pATI->Adapter]); - - AddAdapter(pATI); - pATI->SharedAccelerator = TRUE; - - if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) || - (pATI->Coprocessor != ATI_CHIP_NONE)) - ATIFindVGA(pVideo, &pVGA, &pATI, p8514, - ProbeFlags); - } - xf86SetPciVideo(NULL, NONE); - break; - } - } - - /* Next, look for sparse I/O Mach64's */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - /* For some Radeons, pvideo->size[1] is not there but the card - * still works properly. Thus adding check that if the chip was - * correctly identified as being Rage128 or a Radeon, continue - * also in that case. See fd.o bug 6796. */ - Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - (Chip > ATI_CHIP_Mach64) || - pVideo->size[1]) - continue; - - pPCI = pVideo->thisCard; - if (pPCI == NULL) - continue; - - PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); - j = PciReg & 0x03U; - if (j == 0x03U) - { - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach64 in slot %d:%d:%d cannot be" - " enabled\n because it has neither a block, nor a" - " sparse, I/O base.\n", - pVideo->bus, pVideo->device, pVideo->func); - } - else switch(ATICheckSparseIOBases(pVideo, ProbeFlags, - Mach64SparseIOBases[j], 4, TRUE)) - { - case 0: - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach64 in slot %d:%d:%d will not" - " be enabled\n because it conflicts with another" - " non-video PCI device.\n", - pVideo->bus, pVideo->device, pVideo->func); - break; - -#ifndef AVOID_NON_PCI - - case Detected8514A: - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach64 in slot %d:%d:%d will not" - " be enabled\n because it conflicts with an %s.\n", - pVideo->bus, pVideo->device, pVideo->func, - ATIAdapterNames[p8514->Adapter]); - break; - - case DetectedMach64: - pATI = pMach64[j]; - if ((pATI->BusType >= ATI_BUS_PCI) && !pATI->PCIInfo) - pATI->PCIInfo = pVideo; - else - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach64 in slot %d:%d:%d will" - " not be enabled\n because it conflicts with" - " another %s Mach64 at sparse I/O base" - " 0x%04lX.\n", - pVideo->bus, pVideo->device, pVideo->func, - ATIBusNames[pATI->BusType], - Mach64SparseIOBases[j]); - break; - -#endif /* AVOID_NON_PCI */ - - default: /* Must be DoProbe */ - if (!xf86CheckPciSlot(pVideo->bus, - pVideo->device, - pVideo->func)) - continue; - - /* Possibly fix block I/O indicator */ - if (PciReg & 0x00000004U) - pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, - PciReg & ~0x00000004U); - - xf86SetPciVideo(pVideo, MEM_IO); - - Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); - pATI = ATIMach64Probe(pVideo, Mach64SparseIOBases[j], - SPARSE_IO, Chip); - if (!pATI) - { - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach64 in slot %d:%d:%d could" - " not be detected!\n", - pVideo->bus, pVideo->device, pVideo->func); - } - else - { - sprintf(Identifier, - "Shared PCI Mach64 in slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s with sparse PIO base 0x%04lX" - " detected.\n", Identifier, - Mach64SparseIOBases[j]); - AddAdapter(pATI); - pATI->SharedAccelerator = TRUE; - pATI->PCIInfo = pVideo; - - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIFindVGA(pVideo, &pVGA, &pATI, p8514, - ProbeFlags); - } - - xf86SetPciVideo(NULL, NONE); - break; - } - } +SkipSparse: #else /* AVOID_CPIO */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - pVideo->size[1]) - continue; - - /* Check if this one has already been detected */ - for (j = 0; j < nATIPtr; j++) - { - pATI = ATIPtrs[j]; - if (pATI->PCIInfo == pVideo) - goto SkipThisSlot; - } - - if (!xf86CheckPciSlot(pVideo->bus, - pVideo->device, - pVideo->func)) - continue; - - xf86SetPciVideo(pVideo, MEM_IO); - - Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); - - /* The adapter's CPIO base is of little concern here */ - pATI = ATIMach64Probe(pVideo, 0, SPARSE_IO, Chip); - if (pATI) - { - sprintf(Identifier, "Shared PCI Mach64 in slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s with Block 0 base 0x%08lX detected.\n", - Identifier, pATI->Block0Base); - AddAdapter(pATI); - pATI->SharedAccelerator = TRUE; - pATI->PCIInfo = pVideo; - } - else - { - xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach64 in slot %d:%d:%d could not be" - " detected!\n", - pVideo->bus, pVideo->device, pVideo->func); - } - - xf86SetPciVideo(NULL, NONE); - - SkipThisSlot:; - } - -#endif /* AVOID_CPIO */ - - } - - /* Lastly, look for block I/O devices */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - /* For some Radeons, !pvideo->size[1] applies but the card still - * works properly. Thus don't make !pVideo->size[1] check to continue - * automatically (instead check that the chip actually is below - * ATI_CHIP_Mach64 (includes ATI_CHIP_NONE)). See fd.o bug 6796. */ - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - (!pVideo->size[1] && Chip < ATI_CHIP_Mach64)) - continue; - - /* Check for Rage128's, Radeon's and later adapters */ - Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); - if (Chip > ATI_CHIP_Mach64) - { - if (Chip <= ATI_CHIP_Rage128) - DoRage128 = TRUE; - else if (Chip <= ATI_CHIP_Radeon) - DoRadeon = TRUE; - - continue; - } - - if (!nATIGDev) - continue; - - /* Check if this one has already been detected */ - for (j = 0; j < nATIPtr; j++) - { - pATI = ATIPtrs[j]; - if (pATI->CPIOBase == pVideo->ioBase[1]) - goto SetPCIInfo; - } - - if (!xf86CheckPciSlot(pVideo->bus, pVideo->device, pVideo->func)) - continue; - - /* Probe for it */ - xf86SetPciVideo(pVideo, MEM_IO); - - pATI = ATIMach64Probe(pVideo, pVideo->ioBase[1], BLOCK_IO, Chip); - if (pATI) - { - sprintf(Identifier, "Shared PCI/AGP Mach64 in slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", - Identifier); - AddAdapter(pATI); - pATI->SharedAccelerator = TRUE; - -#ifndef AVOID_CPIO - - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIFindVGA(pVideo, &pVGA, &pATI, p8514, ProbeFlags); - -#endif /* AVOID_CPIO */ - - } - - xf86SetPciVideo(NULL, NONE); - - if (!pATI) - { - xf86Msg(X_WARNING, - ATI_NAME ": PCI/AGP Mach64 in slot %d:%d:%d could not be" - " detected!\n", pVideo->bus, pVideo->device, pVideo->func); - continue; - } - - SetPCIInfo: - pATI->PCIInfo = pVideo; - } - } - -#ifndef AVOID_CPIO - - /* - * At this point, if there's a non-shareable VGA with its own framebuffer, - * find out if it's an ATI VGA Wonder. - */ - do + if (!pVideo->size[1]) { - if (!nATIGDev || !pVGA || (pVGA->VGAAdapter > ATI_ADAPTER_VGA)) - break; - - /* If it has not been assigned to a coprocessor, keep track of it */ - if (pVGA->Coprocessor == ATI_CHIP_NONE) - AddAdapter(pVGA); - - /* - * A VGA should have installed its int 10 vector. Use that to find the - * VGA BIOS. If this fails, scan all legacy BIOS segments, in 512-byte - * increments. - */ - if (xf86ReadBIOS(0U, 0x42U, BIOS, 2) != 2) - goto NoVGAWonder; - - pATI = NULL; - BIOSBase = 0; - if (!(BIOS[0] & 0x1FU)) /* Otherwise there's no 512-byte alignment */ - BIOSBase = ((BIOS[1] << 8) | BIOS[0]) << 4; + /* The adapter's CPIO base is of little concern here */ + pATI->CPIOBase = 0; + pATI->CPIODecoding = SPARSE_IO; + pATI->PCIInfo = pVideo; - /* Look for its BIOS */ - for(; ; BIOSBase += 0x00000200U) + if (ATIMach64Probe(pATI, pVideo, pATI->Chip)) { - if (!BIOSBase) - goto SkipBiosSegment; - - if (BIOSBase >= 0x000F8000U) - goto NoVGAWonder; - - /* Skip over those that are already known */ - for (i = 0; i < nATIPtr; i++) - if (ATIPtrs[i]->BIOSBase == BIOSBase) - goto SkipBiosSegment; - - /* Get first 80 bytes of video BIOS */ - if (xf86ReadBIOS(BIOSBase, 0, BIOS, SizeOf(BIOS)) != - SizeOf(BIOS)) - goto NoVGAWonder; - - if ((BIOS[0x00U] != 0x55U) || (BIOS[0x01U] != 0xAAU)) - goto SkipBiosSegment; - - if ((BIOS[0x1EU] == 'I') && - (BIOS[0x1FU] == 'B') && - (BIOS[0x20U] == 'M')) - break; - - /* XXX Should PCI BIOS signature be checked for here ? */ - if ((BIOS[0x20U] == 'P') && - (BIOS[0x21U] == 'C') && - (BIOS[0x22U] == 'I')) - break; - - SkipBiosSegment: - if (pATI) - continue; - - pATI = pVGA; - BIOSBase = 0x000C0000U - 0x00000200U; + ProbeSuccess = TRUE; + xf86Msg(X_INFO, ATI_NAME ": " + "Shared PCI Mach64 in slot %d:%d:%d with Block 0 base" + " 0x%08lX detected.\n", + pVideo->bus, pVideo->device, pVideo->func, + pATI->Block0Base); } - - pVGA->BIOSBase = BIOSBase; - - /* Look for the ATI signature string */ - if (memcmp(BIOS + BIOSSignature, ATISignature, SignatureSize)) - break; - - if (BIOS[0x40U] != '3') - break; - - switch (BIOS[0x41U]) + else { - case '1': - /* This is a Mach8 or VGA Wonder adapter of some kind */ - if ((BIOS[0x43U] >= '1') && (BIOS[0x43U] <= '6')) - pVGA->Chip = BIOS[0x43U] - ('1' - ATI_CHIP_18800); - - switch (BIOS[0x43U]) - { - case '1': /* ATI_CHIP_18800 */ - pVGA->VGAOffset = 0xB0U; - pVGA->VGAAdapter = ATI_ADAPTER_V3; - break; - - case '2': /* ATI_CHIP_18800_1 */ - pVGA->VGAOffset = 0xB0U; - if (BIOS[0x42U] & 0x10U) - pVGA->VGAAdapter = ATI_ADAPTER_V5; - else - pVGA->VGAAdapter = ATI_ADAPTER_V4; - break; - - case '3': /* ATI_CHIP_28800_2 */ - case '4': /* ATI_CHIP_28800_4 */ - case '5': /* ATI_CHIP_28800_5 */ - case '6': /* ATI_CHIP_28800_6 */ - pVGA->VGAOffset = 0xA0U; - if (BIOS[0x44U] & 0x80U) - pVGA->VGAAdapter = ATI_ADAPTER_XL; - else - pVGA->VGAAdapter = ATI_ADAPTER_PLUS; - break; - - case 'a': /* A crippled Mach32 */ - case 'b': - case 'c': - pVGA->VGAOffset = 0x80U; - pVGA->VGAAdapter = ATI_ADAPTER_NONISA; - ATIMach32ChipID(pVGA); - ProbeWaitIdleEmpty(); - if (inw(SUBSYS_STAT) != (CARD16)(-1)) - pVGA->ChipHasSUBSYS_CNTL = TRUE; - break; -#if 0 - case ' ': /* A crippled Mach64 */ - pVGA->VGAOffset = 0x80U; - pVGA->VGAAdapter = ATI_ADAPTER_NONISA; - ATIMach64ChipID(pVGA, 0); - break; -#endif - default: - break; - } - - if (pVGA->VGAAdapter == ATI_ADAPTER_NONE) - break; - - /* Set VGA Wonder I/O port */ - pVGA->CPIO_VGAWonder = BIOSWord(0x10U) & SPARSE_IO_PORT; - if (!pVGA->CPIO_VGAWonder) - pVGA->CPIO_VGAWonder = 0x01CEU; - - ATIVGAWonderProbe(NULL, pVGA, p8514, ProbeFlags); - break; -#if 0 - case '2': - pVGA->VGAOffset = 0xB0U; /* Presumably */ - pVGA->VGAAdapter = ATI_ADAPTER_EGA_PLUS; - break; - - case '3': - pVGA->VGAOffset = 0xB0U; /* Presumably */ - pVGA->VGAAdapter = ATI_ADAPTER_BASIC; - break; - - case '?': /* A crippled Mach64 */ - pVGA->VGAAdapter = ATI_ADAPTER_NONISA; - ATIMach64ChipID(pVGA, 0); - break; -#endif - default: - break; + xf86Msg(X_WARNING, ATI_NAME ": " + "PCI Mach64 in slot %d:%d:%d could not be detected!\n", + pVideo->bus, pVideo->device, pVideo->func); } - - if (pVGA->Adapter <= ATI_ADAPTER_VGA) - pVGA->Adapter = pVGA->VGAAdapter; - -NoVGAWonder:; - } while (0); + } #endif /* AVOID_CPIO */ - /* - * Re-order list of detected devices so that the primary device is before - * any other PCI device. - */ - for (i = 0; i < nATIPtr; i++) + /* Lastly, look for block I/O devices */ + if (pVideo->size[1]) { - if (!ATIPtrs[i]->PCIInfo) - continue; - - for (j = i; j < nATIPtr; j++) - { - pATI = ATIPtrs[j]; - if (!xf86IsPrimaryPci(pATI->PCIInfo)) - continue; - - for (; j > i; j--) - ATIPtrs[j] = ATIPtrs[j - 1]; - ATIPtrs[j] = pATI; - break; - } - - break; - } + pATI->CPIOBase = pVideo->ioBase[1]; + pATI->CPIODecoding = BLOCK_IO; + pATI->PCIInfo = pVideo; - if (flags & PROBE_DETECT) - { - /* - * No XF86Config information available, so use the default Chipset of - * "ati", and as many device sections as there are adapters. - */ - for (i = 0; i < nATIPtr; i++) + if (ATIMach64Probe(pATI, pVideo, pATI->Chip)) { - pATI = ATIPtrs[i]; + ProbeSuccess = TRUE; + xf86Msg(X_INFO, ATI_NAME ": " + "Shared PCI/AGP Mach64 in slot %d:%d:%d detected.\n", + pVideo->bus, pVideo->device, pVideo->func); #ifndef AVOID_CPIO - if ((pATI->Adapter != ATI_ADAPTER_VGA) && - ((pATI->Adapter != ATI_ADAPTER_8514A) || - ((pATI->VGAAdapter != ATI_ADAPTER_VGA) && - (pATI->VGAAdapter != ATI_ADAPTER_NONE)))) + if (pATI->VGAAdapter) + ATIFindVGA(pVideo, pATI); #endif /* AVOID_CPIO */ - { - ProbeSuccess = TRUE; - pGDev = xf86AddDeviceToConfigure(ATI_DRIVER_NAME, - pATI->PCIInfo, ATI_CHIPSET_ATI); - if (pGDev) - { - /* Fill in additional information */ - pGDev->vendor = ATI_NAME; - pGDev->chipset = (char *)ATIChipsetNames[ATI_CHIPSET_ATI]; - if (!pATI->PCIInfo) - pGDev->busID = NULL; - } - } - - xfree(pATI); } - } - else - { - /* - * Assign detected devices to XF86Config Device sections. This is done - * by comparing certain Device section specifications against the - * corresponding adapter information. Begin with those specifications - * that are independent of the adapter's bus location. - */ - for (i = 0, pATIGDev = ATIGDevs; i < nATIGDev; i++, pATIGDev++) + else { - pGDev = pATIGDev->pGDev; - - for (j = 0; j < nATIPtr; j++) - { - pATI = ATIPtrs[j]; - - /* - * First check the Chipset specification. The placement of - * "break" and "continue" statements here is carefully chosen - * to produce the intended behaviour for each Chipset value. - */ - switch (pATIGDev->Chipset) - { - case ATI_CHIPSET_ATI: - -#ifndef AVOID_CPIO - - if (pATI->Adapter == ATI_ADAPTER_VGA) - continue; - if (pATI->Adapter != ATI_ADAPTER_8514A) - break; - /* Fall through */ - - case ATI_CHIPSET_ATIVGA: - if (pATI->VGAAdapter == ATI_ADAPTER_VGA) - continue; - /* Fall through */ - - case ATI_CHIPSET_IBMVGA: - if (pATI->VGAAdapter == ATI_ADAPTER_NONE) - continue; - break; - - case ATI_CHIPSET_VGAWONDER: - if (!pATI->CPIO_VGAWonder) - continue; - break; - - case ATI_CHIPSET_IBM8514: - if (pATI->Adapter == ATI_ADAPTER_8514A) - break; - /* Fall through */ - - case ATI_CHIPSET_MACH8: - if (pATI->Adapter == ATI_ADAPTER_MACH8) - break; - /* Fall through */ - - case ATI_CHIPSET_MACH32: - if (pATI->Adapter == ATI_ADAPTER_MACH32) - break; - continue; - -#endif /* AVOID_CPIO */ - - case ATI_CHIPSET_MACH64: - if (pATI->Adapter == ATI_ADAPTER_MACH64) - break; - continue; - - default: - continue; - } - - /* - * The ChipID and ChipRev specifications are compared next. - * First, require these to be unspecified for anything other - * than Mach32 or Mach64 adapters. ChipRev is also required to - * be unspecified for Mach32's. ChipID is optional for - * Mach32's, and both specifications are optional for Mach64's. - * Lastly, allow both specifications to override their detected - * value in the case of Mach64 adapters whose ChipID is - * unrecognised. - */ - pVideo = pATI->PCIInfo; - if (pGDev->chipID >= 0) - { - if ((pATI->ChipType != pGDev->chipID) && - (!pVideo || (pGDev->chipID != pVideo->chipType))) - { - if ((pATI->Adapter != ATI_ADAPTER_MACH64) || - (pATI->Chip != ATI_CHIP_Mach64)) - continue; - - Chip = ATIChipID(pGDev->chipID, 0); - if ((Chip <= ATI_CHIP_264GTB) || - (Chip == ATI_CHIP_Mach64)) - continue; - } - if ((pGDev->chipRev >= 0) && - (pATI->ChipRev != pGDev->chipRev) && - (!pVideo || (pGDev->chipRev != pVideo->chipRev) || - (pGDev->chipID != pVideo->chipType))) - { - if (pATI->Chip < ATI_CHIP_264CT) - continue; - - if (pATI->Chip != ATI_CHIP_Mach64) - { - /* - * There are two foundry codes for UMC. Some - * adapters will advertise one in CONFIG_CHIP_ID - * and the other in PCI configuration space. For - * matching purposes, make both codes compare - * equal. - */ -# define UMC_IGNORE \ - (ATI_FOUNDRY_UMC ^ ATI_FOUNDRY_UMCA) -# define UMC_NOCARE \ - GetBits(SetBits(UMC_IGNORE, CFG_CHIP_FOUNDRY), \ - CFG_CHIP_REV) - - if ((pATI->ChipRev ^ pGDev->chipRev) & ~UMC_NOCARE) - continue; - - if ((pATI->ChipFoundry != ATI_FOUNDRY_UMC) && - (pATI->ChipFoundry != ATI_FOUNDRY_UMCA)) - continue; - - k = GetBits(pGDev->chipRev, - GetBits(CFG_CHIP_FOUNDRY, CFG_CHIP_REV)); - if ((k != ATI_FOUNDRY_UMC) && - (k != ATI_FOUNDRY_UMCA)) - continue; - } - } - } - - /* - * IOBase is next. This is the first specification that is - * potentially dependent on bus location. It is only allowed - * for Mach64 adapters, and is optional. - */ - if (pGDev->IOBase && (pATI->CPIOBase != pGDev->IOBase)) - continue; - - /* - * Compare BusID's. This specification is only allowed for PCI - * Mach32's or Mach64's and is optional. - */ - if (pGDev->busID && pGDev->busID[0]) - { - pVideo = pATI->PCIInfo; + xf86Msg(X_WARNING, ATI_NAME ": " + "PCI/AGP Mach64 in slot %d:%d:%d could not be detected!\n", + pVideo->bus, pVideo->device, pVideo->func); + } + } -#ifndef AVOID_CPIO + return ProbeSuccess; +} - if (!pVideo) - continue; +static SymTabRec +Mach64Chipsets[] = { + {ATI_CHIP_88800GXC, "ATI 88800GX-C"}, + {ATI_CHIP_88800GXD, "ATI 88800GX-D"}, + {ATI_CHIP_88800GXE, "ATI 88800GX-E"}, + {ATI_CHIP_88800GXF, "ATI 88800GX-F"}, + {ATI_CHIP_88800GX, "ATI 88800GX"}, + {ATI_CHIP_88800CX, "ATI 88800CX"}, + {ATI_CHIP_264CT, "ATI 264CT"}, + {ATI_CHIP_264ET, "ATI 264ET"}, + {ATI_CHIP_264VT, "ATI 264VT"}, + {ATI_CHIP_264VTB, "ATI 264VT-B"}, + {ATI_CHIP_264GT, "ATI 3D Rage"}, + {ATI_CHIP_264GTB, "ATI 3D Rage II"}, + {ATI_CHIP_264VT3, "ATI 264VT3"}, + {ATI_CHIP_264GTDVD, "ATI 3D Rage II+DVD"}, + {ATI_CHIP_264LT, "ATI 3D Rage LT"}, + {ATI_CHIP_264VT4, "ATI 264VT4"}, + {ATI_CHIP_264GT2C, "ATI 3D Rage IIc"}, + {ATI_CHIP_264GTPRO, "ATI 3D Rage Pro"}, + {ATI_CHIP_264LTPRO, "ATI 3D Rage LT Pro"}, + {ATI_CHIP_264XL, "ATI 3D Rage XL or XC"}, + {ATI_CHIP_MOBILITY, "ATI 3D Rage Mobility"}, + {-1, NULL } +}; -#endif /* AVOID_CPIO */ +/* + * This table maps a PCI device ID to a chipset family identifier. + */ +static PciChipsets +Mach64PciChipsets[] = { + {ATI_CHIP_88800GX, PCI_CHIP_MACH64GX, RES_SHARED_VGA}, + {ATI_CHIP_88800CX, PCI_CHIP_MACH64CX, RES_SHARED_VGA}, + {ATI_CHIP_264CT, PCI_CHIP_MACH64CT, RES_SHARED_VGA}, + {ATI_CHIP_264ET, PCI_CHIP_MACH64ET, RES_SHARED_VGA}, + {ATI_CHIP_264VT, PCI_CHIP_MACH64VT, RES_SHARED_VGA}, + {ATI_CHIP_264GT, PCI_CHIP_MACH64GT, RES_SHARED_VGA}, + {ATI_CHIP_264VT3, PCI_CHIP_MACH64VU, RES_SHARED_VGA}, + {ATI_CHIP_264GTDVD, PCI_CHIP_MACH64GU, RES_SHARED_VGA}, + {ATI_CHIP_264LT, PCI_CHIP_MACH64LG, RES_SHARED_VGA}, + {ATI_CHIP_264VT4, PCI_CHIP_MACH64VV, RES_SHARED_VGA}, + {ATI_CHIP_264GT2C, PCI_CHIP_MACH64GV, RES_SHARED_VGA}, + {ATI_CHIP_264GT2C, PCI_CHIP_MACH64GW, RES_SHARED_VGA}, + {ATI_CHIP_264GT2C, PCI_CHIP_MACH64GY, RES_SHARED_VGA}, + {ATI_CHIP_264GT2C, PCI_CHIP_MACH64GZ, RES_SHARED_VGA}, + {ATI_CHIP_264GTPRO, PCI_CHIP_MACH64GB, RES_SHARED_VGA}, + {ATI_CHIP_264GTPRO, PCI_CHIP_MACH64GD, RES_SHARED_VGA}, + {ATI_CHIP_264GTPRO, PCI_CHIP_MACH64GI, RES_SHARED_VGA}, + {ATI_CHIP_264GTPRO, PCI_CHIP_MACH64GP, RES_SHARED_VGA}, + {ATI_CHIP_264GTPRO, PCI_CHIP_MACH64GQ, RES_SHARED_VGA}, + {ATI_CHIP_264LTPRO, PCI_CHIP_MACH64LB, RES_SHARED_VGA}, + {ATI_CHIP_264LTPRO, PCI_CHIP_MACH64LD, RES_SHARED_VGA}, + {ATI_CHIP_264LTPRO, PCI_CHIP_MACH64LI, RES_SHARED_VGA}, + {ATI_CHIP_264LTPRO, PCI_CHIP_MACH64LP, RES_SHARED_VGA}, + {ATI_CHIP_264LTPRO, PCI_CHIP_MACH64LQ, RES_SHARED_VGA}, + {ATI_CHIP_264XL, PCI_CHIP_MACH64GL, RES_SHARED_VGA}, + {ATI_CHIP_264XL, PCI_CHIP_MACH64GM, RES_SHARED_VGA}, + {ATI_CHIP_264XL, PCI_CHIP_MACH64GN, RES_SHARED_VGA}, + {ATI_CHIP_264XL, PCI_CHIP_MACH64GO, RES_SHARED_VGA}, + {ATI_CHIP_264XL, PCI_CHIP_MACH64GR, RES_SHARED_VGA}, + {ATI_CHIP_264XL, PCI_CHIP_MACH64GS, RES_SHARED_VGA}, + {ATI_CHIP_MOBILITY, PCI_CHIP_MACH64LM, RES_SHARED_VGA}, + {ATI_CHIP_MOBILITY, PCI_CHIP_MACH64LN, RES_SHARED_VGA}, + {ATI_CHIP_MOBILITY, PCI_CHIP_MACH64LR, RES_SHARED_VGA}, + {ATI_CHIP_MOBILITY, PCI_CHIP_MACH64LS, RES_SHARED_VGA}, + {-1, -1, RES_UNDEFINED} +}; - if (!xf86ComparePciBusString(pGDev->busID, - pVideo->bus, pVideo->device, pVideo->func)) - continue; - } - - /* - * Ensure no two adapters are assigned to the same XF86Config - * Device section. - */ - if (pATIGDev->iATIPtr) - { - if (pATIGDev->iATIPtr < 0) - break; - - xf86Msg(X_ERROR, - ATI_NAME ": XF86Config Device section \"%s\" may not" - " be assigned to more than one adapter.\n", - pGDev->identifier); - pATIGDev->iATIPtr = -1; - break; - } - - /* Assign adapter */ - pATIGDev->iATIPtr = j + 1; - - /* - * For compatibility with previous releases, assign the first - * applicable adapter if there is only one Device section. - */ - if (nATIGDev == 1) - break; - } - } +/* + * Mach64Probe -- + * + * This function is called once, at the start of the first server generation to + * do a minimal probe for supported hardware. + */ +static Bool +Mach64Probe(DriverPtr pDriver, int flags) +{ + GDevPtr *devSections; + int *usedChips; + int numDevSections; + int numUsed; + Bool ProbeSuccess = FALSE; - /* - * Ensure no two XF86Config Device sections are assigned to the same - * adapter. Then, generate screens for any that are left. - */ - for (i = 0, pATIGDev = ATIGDevs; i < nATIGDev; i++, pATIGDev++) - { - pGDev = pATIGDev->pGDev; + if ((numDevSections = xf86MatchDevice(ATI_DRIVER_NAME, &devSections)) <= 0) + return FALSE; - j = pATIGDev->iATIPtr; - if (j <= 0) - continue; + if (xf86GetPciVideoInfo() == NULL) + return FALSE; - for (k = i; ++k < nATIGDev; ) - { - if (j == ATIGDevs[k].iATIPtr) - { - xf86Msg(X_ERROR, - ATI_NAME ": XF86Config Device sections \"%s\" and" - " \"%s\" may not be assigned to the same adapter.\n", - pGDev->identifier, ATIGDevs[k].pGDev->identifier); - pATIGDev->iATIPtr = ATIGDevs[k].iATIPtr = -1; - } - } + numUsed = xf86MatchPciInstances(ATI_DRIVER_NAME, PCI_VENDOR_ATI, + Mach64Chipsets, Mach64PciChipsets, + devSections, numDevSections, + pDriver, &usedChips); + xfree(devSections); - j = ATIGDevs[i].iATIPtr; - if (j <= 0) - continue; + if (numUsed <= 0) + return FALSE; - pATI = ATIPtrs[j - 1]; + if (flags & PROBE_DETECT) { + ProbeSuccess = TRUE; + } else { + int i; - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s assigned to %sactive \"Device\" section" - " \"%s\".\n", - Identifier, pGDev->active ? "" : "in", pGDev->identifier); + for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn; + EntityInfoPtr pEnt; + pciVideoPtr pVideo; - /* - * Attach adapter to XF86Config Device section and register its - * resources. - */ - if (ATIClaimBusSlot(pDriver, pATIGDev->Chipset, - pGDev, pGDev->active, pATI) < 0) - { - xf86Msg(X_ERROR, - ATI_NAME ": Could not claim bus slot for %s.\n", - Identifier); - continue; - } + pScrn = xf86ConfigPciEntity(NULL, 0, usedChips[i], Mach64PciChipsets, + 0, 0, 0, 0, NULL); - if (!pGDev->active) + if (!pScrn) continue; - /* Allocate screen */ - pScreenInfo = xf86AllocateScreen(pDriver, 0); + pEnt = xf86GetEntityInfo(usedChips[i]); + pVideo = xf86GetPciInfoForEntity(usedChips[i]); #ifdef XFree86LOADER - if (!xf86LoadSubModule(pScreenInfo, "atimisc")) + if (!xf86LoadSubModule(pScrn, "atimisc")) { xf86Msg(X_ERROR, ATI_NAME ": Failed to load \"atimisc\" module.\n"); - xf86DeleteScreen(pScreenInfo->scrnIndex, 0); + xf86DeleteScreen(pScrn->scrnIndex, 0); continue; } @@ -2299,45 +662,74 @@ NoVGAWonder:; #endif - /* Attach device to screen */ - xf86AddEntityToScreen(pScreenInfo, pATI->iEntity); - - ATIPtrs[j - 1] = NULL; - - /* Fill in probe data */ - ATIFillInScreenInfo(pScreenInfo); + ATIFillInScreenInfo(pScrn); - pScreenInfo->driverPrivate = pATI; - - pATI->Chipset = pATIGDev->Chipset; + pScrn->Probe = Mach64Probe; ProbeSuccess = TRUE; } + } - /* Deal with unassigned adapters */ - for (i = 0; i < nATIPtr; i++) - { - if (!(pATI = ATIPtrs[i])) - continue; + return ProbeSuccess; +} -#ifndef AVOID_CPIO +/* + * ATIProbe -- + * + * This function is called once, at the start of the first server generation to + * do a minimal probe for supported hardware. + */ +Bool +ATIProbe +( + DriverPtr pDriver, + int flags +) +{ + pciVideoPtr pVideo, *xf86PciVideoInfo = xf86GetPciVideoInfo(); + Bool ProbeSuccess = FALSE; + Bool DoMach64 = FALSE; + Bool DoRage128 = FALSE, DoRadeon = FALSE; + int i; + ATIChipType Chip; - if (pATI->Adapter > ATI_ADAPTER_VGA) + if (!(flags & PROBE_DETECT)) + { + if (xf86MatchDevice(ATI_NAME, NULL) > 0) + DoMach64 = TRUE; + if (xf86MatchDevice(R128_NAME, NULL) > 0) + DoRage128 = TRUE; + if (xf86MatchDevice(RADEON_NAME, NULL) > 0) + DoRadeon = TRUE; + } -#endif /* AVOID_CPIO */ + if (xf86PciVideoInfo) + { + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) + { + if ((pVideo->vendor != PCI_VENDOR_ATI) || + (pVideo->chipType == PCI_CHIP_MACH32)) + continue; + /* Check for Rage128's, Radeon's and later adapters */ + Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); + if (Chip > ATI_CHIP_Mach64) { - if (pATI->iEntity < 0) - (void)ATIClaimBusSlot(pDriver, 0, NULL, FALSE, pATI); + if (Chip <= ATI_CHIP_Rage128) + DoRage128 = TRUE; + else if (Chip <= ATI_CHIP_Radeon) + DoRadeon = TRUE; + + continue; } - xfree(pATI); + DoMach64 = TRUE; } - - xfree(ATIGDevs); } - xfree(ATIPtrs); + /* Call Mach64 driver probe */ + if (DoMach64 && Mach64Probe(pDriver, flags)) + ProbeSuccess = TRUE; /* Call Rage 128 driver probe */ if (DoRage128 && R128Probe(pDriver, flags)) |