summaryrefslogtreecommitdiff
path: root/src/atiprobe.c
diff options
context:
space:
mode:
authorGeorge Sapountzis <gsap7@yahoo.gr>2007-02-05 19:16:51 +0200
committerGeorge Sapountzis <gsap7@yahoo.gr>2007-02-05 19:16:51 +0200
commit9d77aabdff919360f0c9333105436c31f1f5749a (patch)
treefa0617724e538435cf2b04b7a63ef006fc73fe04 /src/atiprobe.c
parentff8ea19fcdce099732f9359e53cd62b9a04bfa6d (diff)
parent57822be75740f339445f2375d44632560f4bbe57 (diff)
Merge branch 'mach64-pci-1'
Diffstat (limited to 'src/atiprobe.c')
-rw-r--r--src/atiprobe.c2192
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))