diff options
author | mdaenzer <mdaenzer> | 2003-08-19 23:19:48 +0000 |
---|---|---|
committer | mdaenzer <mdaenzer> | 2003-08-19 23:19:48 +0000 |
commit | 71cafc7d24cdeac4bfbfcf5cc80da83992decdc0 (patch) | |
tree | 3a12185e26d329d52d85a1f1dc99b6680235537a /xc/programs/Xserver | |
parent | 41f6aa7ea97671949c672871a7b542af9ef4b9fd (diff) |
Merge radeon driver from XFree86 CVS (these need to be merged as well for
"ati" to work the same as "radeon")
Diffstat (limited to 'xc/programs/Xserver')
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c | 358 | ||||
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h | 106 | ||||
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c | 2000 |
3 files changed, 1734 insertions, 730 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c index 91a60f955..f1fa25e7a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c @@ -1,6 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c,v 1.6 1999/08/21 13:48:31 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c,v 1.35 2003/07/02 17:31:28 martin Exp $ */ /* - * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -24,7 +24,7 @@ #include "ati.h" #include "atibus.h" #include "atichip.h" -#include "atiio.h" +#include "atimach64io.h" #include "ativersion.h" /* @@ -33,6 +33,9 @@ const char *ATIChipNames[] = { "Unknown", + +#ifndef AVOID_CPIO + "IBM VGA or compatible", "ATI 18800", "ATI 18800-1", @@ -48,6 +51,9 @@ const char *ATIChipNames[] = "ATI 68800-6", "ATI 68800LX", "ATI 68800AX", + +#endif /* AVOID_CPIO */ + "ATI 88800GX-C", "ATI 88800GX-D", "ATI 88800GX-E", @@ -68,11 +74,40 @@ const char *ATIChipNames[] = "ATI 3D Rage Pro", "ATI 3D Rage LT Pro", "ATI 3D Rage XL or XC", + "ATI 3D Rage Mobility", "ATI unknown Mach64", + "ATI Rage 128 GL", + "ATI Rage 128 VR", + "ATI Rage 128 Pro GL", + "ATI Rage 128 Pro VR", + "ATI Rage 128 Pro ULTRA", + "ATI Rage 128 Mobility M3", + "ATI Rage 128 Mobility M4", + "ATI unknown Rage 128" + "ATI Radeon 7200", + "ATI Radeon 7000 (VE)", + "ATI Radeon Mobility M6", + "ATI Radeon IGP320", + "ATI Radeon IGP330/340/350", + "ATI Radeon 7000 IGP", + "ATI Radeon 7500", + "ATI Radeon Mobility M7", + "ATI Radeon 8500/9100", + "ATI Radeon 9000", + "ATI Radeon Mobility M9", + "ATI Radeon 9000 IGP", + "ATI Radeon 9200", + "ATI Radeon Mobility M9+", + "ATI Radeon 9700/9500", + "ATI Radeon 9600", + "ATI Radeon 9800", + "ATI Rage HDTV" }; const char *ATIFoundryNames[] = - { "SGS", "NEC", "KCS", "UMC", "4", "5", "6", "UMC" }; + { "SGS", "NEC", "KCS", "UMC", "TSMC", "5", "6", "UMC" }; + +#ifndef AVOID_CPIO /* * ATIMach32ChipID -- @@ -116,6 +151,8 @@ ATIMach32ChipID } } +#endif /* AVOID_CPIO */ + /* * ATIMach64ChipID -- * @@ -129,13 +166,13 @@ ATIMach64ChipID const CARD16 ExpectedChipType ) { - CARD32 IOValue = inl(ATIIOPort(CONFIG_CHIP_ID)); - pATI->ChipType = GetBits(IOValue, 0xFFFFU); - pATI->ChipClass = GetBits(IOValue, CFG_CHIP_CLASS); - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REV); - pATI->ChipVersion = GetBits(IOValue, CFG_CHIP_VERSION); - pATI->ChipFoundry = GetBits(IOValue, CFG_CHIP_FOUNDRY); - pATI->ChipRev = pATI->ChipRevision; + pATI->config_chip_id = inr(CONFIG_CHIP_ID); + pATI->ChipType = GetBits(pATI->config_chip_id, 0xFFFFU); + pATI->ChipClass = GetBits(pATI->config_chip_id, CFG_CHIP_CLASS); + pATI->ChipRevision = GetBits(pATI->config_chip_id, CFG_CHIP_REV); + pATI->ChipVersion = GetBits(pATI->config_chip_id, CFG_CHIP_VERSION); + pATI->ChipFoundry = GetBits(pATI->config_chip_id, CFG_CHIP_FOUNDRY); + pATI->ChipRev = pATI->ChipRevision; switch (pATI->ChipType) { case OldChipID('G', 'X'): @@ -174,7 +211,8 @@ ATIMach64ChipID case OldChipID('C', 'T'): pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('C', 'T'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264CT; pATI->BusType = ATI_BUS_PCI; break; @@ -182,7 +220,8 @@ ATIMach64ChipID case OldChipID('E', 'T'): pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('E', 'T'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264ET; pATI->BusType = ATI_BUS_PCI; break; @@ -190,7 +229,8 @@ ATIMach64ChipID case OldChipID('V', 'T'): pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('V', 'T'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264VT; pATI->BusType = ATI_BUS_PCI; /* Some early GT's are detected as VT's */ @@ -211,7 +251,8 @@ ATIMach64ChipID case OldChipID('G', 'T'): pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('G', 'T'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->BusType = ATI_BUS_PCI; if (!pATI->ChipVersion) pATI->Chip = ATI_CHIP_264GT; @@ -222,7 +263,8 @@ ATIMach64ChipID case OldChipID('V', 'U'): pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('V', 'U'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264VT3; pATI->BusType = ATI_BUS_PCI; break; @@ -230,7 +272,8 @@ ATIMach64ChipID case OldChipID('G', 'U'): pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('G', 'U'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264GTDVD; pATI->BusType = ATI_BUS_PCI; break; @@ -238,7 +281,8 @@ ATIMach64ChipID case OldChipID('L', 'G'): pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('L', 'G'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264LT; pATI->BusType = ATI_BUS_PCI; break; @@ -246,15 +290,19 @@ ATIMach64ChipID case OldChipID('V', 'V'): pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('V', 'V'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264VT4; pATI->BusType = ATI_BUS_PCI; break; case OldChipID('G', 'V'): + case OldChipID('G', 'Y'): pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('G', 'V'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + case NewChipID('G', 'Y'): + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264GT2C; pATI->BusType = ATI_BUS_PCI; break; @@ -264,7 +312,8 @@ ATIMach64ChipID pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('G', 'W'): case NewChipID('G', 'Z'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264GT2C; pATI->BusType = ATI_BUS_AGP; break; @@ -276,7 +325,8 @@ ATIMach64ChipID case NewChipID('G', 'I'): case NewChipID('G', 'P'): case NewChipID('G', 'Q'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264GTPRO; pATI->BusType = ATI_BUS_PCI; break; @@ -286,17 +336,21 @@ ATIMach64ChipID pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('G', 'B'): case NewChipID('G', 'D'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264GTPRO; pATI->BusType = ATI_BUS_AGP; break; case OldChipID('L', 'I'): case OldChipID('L', 'P'): + case OldChipID('L', 'Q'): pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('L', 'I'): case NewChipID('L', 'P'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + case NewChipID('L', 'Q'): + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264LTPRO; pATI->BusType = ATI_BUS_PCI; pATI->LCDVBlendFIFOSize = 800; @@ -307,20 +361,24 @@ ATIMach64ChipID pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('L', 'B'): case NewChipID('L', 'D'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264LTPRO; pATI->BusType = ATI_BUS_AGP; pATI->LCDVBlendFIFOSize = 800; break; + case OldChipID('G', 'L'): case OldChipID('G', 'O'): case OldChipID('G', 'R'): case OldChipID('G', 'S'): pATI->ChipType = OldToNewChipID(pATI->ChipType); + case NewChipID('G', 'L'): case NewChipID('G', 'O'): case NewChipID('G', 'R'): case NewChipID('G', 'S'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264XL; pATI->BusType = ATI_BUS_PCI; pATI->LCDVBlendFIFOSize = 1024; @@ -331,12 +389,37 @@ ATIMach64ChipID pATI->ChipType = OldToNewChipID(pATI->ChipType); case NewChipID('G', 'M'): case NewChipID('G', 'N'): - pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION); + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); pATI->Chip = ATI_CHIP_264XL; pATI->BusType = ATI_BUS_AGP; pATI->LCDVBlendFIFOSize = 1024; break; + case OldChipID('L', 'R'): + case OldChipID('L', 'S'): + pATI->ChipType = OldToNewChipID(pATI->ChipType); + case NewChipID('L', 'R'): + case NewChipID('L', 'S'): + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); + pATI->Chip = ATI_CHIP_MOBILITY; + pATI->BusType = ATI_BUS_PCI; + pATI->LCDVBlendFIFOSize = 1024; + break; + + case OldChipID('L', 'M'): + case OldChipID('L', 'N'): + pATI->ChipType = OldToNewChipID(pATI->ChipType); + case NewChipID('L', 'M'): + case NewChipID('L', 'N'): + pATI->ChipRevision = + GetBits(pATI->config_chip_id, CFG_CHIP_REVISION); + pATI->Chip = ATI_CHIP_MOBILITY; + pATI->BusType = ATI_BUS_AGP; + pATI->LCDVBlendFIFOSize = 1024; + break; + default: pATI->Chip = ATI_CHIP_Mach64; break; @@ -344,7 +427,7 @@ ATIMach64ChipID } /* - * ATIPCIChip -- + * ATIChipID -- * * This returns the ATI_CHIP_* value (generally) associated with a particular * ChipID/ChipRev combination. @@ -358,20 +441,41 @@ ATIChipID { switch (ChipID) { + +#ifndef AVOID_CPIO + case OldChipID('A', 'A'): case NewChipID('A', 'A'): return ATI_CHIP_68800_3; case OldChipID('X', 'X'): case NewChipID('X', 'X'): return ATI_CHIP_68800_6; - case OldChipID('L', 'X'): case NewChipID('L', 'X'): + case OldChipID('L', 'X'): return ATI_CHIP_68800LX; case OldChipID('A', 'X'): case NewChipID('A', 'X'): return ATI_CHIP_68800AX; +#endif /* AVOID_CPIO */ + case OldChipID('G', 'X'): case NewChipID('G', 'X'): - return ATI_CHIP_88800GX; + switch (ChipRev) + { + case 0x00U: + return ATI_CHIP_88800GXC; + + case 0x01U: + return ATI_CHIP_88800GXD; + + case 0x02U: + return ATI_CHIP_88800GXE; + + case 0x03U: + return ATI_CHIP_88800GXF; + + default: + return ATI_CHIP_88800GX; + } case OldChipID('C', 'X'): case NewChipID('C', 'X'): return ATI_CHIP_88800CX; @@ -407,6 +511,7 @@ ATIChipID case OldChipID('G', 'V'): case NewChipID('G', 'V'): case OldChipID('G', 'W'): case NewChipID('G', 'W'): + case OldChipID('G', 'Y'): case NewChipID('G', 'Y'): case OldChipID('G', 'Z'): case NewChipID('G', 'Z'): return ATI_CHIP_264GT2C; @@ -421,8 +526,10 @@ ATIChipID case OldChipID('L', 'D'): case NewChipID('L', 'D'): case OldChipID('L', 'I'): case NewChipID('L', 'I'): case OldChipID('L', 'P'): case NewChipID('L', 'P'): + case OldChipID('L', 'Q'): case NewChipID('L', 'Q'): return ATI_CHIP_264LTPRO; + case OldChipID('G', 'L'): case NewChipID('G', 'L'): case OldChipID('G', 'M'): case NewChipID('G', 'M'): case OldChipID('G', 'N'): case NewChipID('G', 'N'): case OldChipID('G', 'O'): case NewChipID('G', 'O'): @@ -430,7 +537,198 @@ ATIChipID case OldChipID('G', 'S'): case NewChipID('G', 'S'): return ATI_CHIP_264XL; + case OldChipID('L', 'M'): case NewChipID('L', 'M'): + case OldChipID('L', 'N'): case NewChipID('L', 'N'): + case OldChipID('L', 'R'): case NewChipID('L', 'R'): + case OldChipID('L', 'S'): case NewChipID('L', 'S'): + return ATI_CHIP_MOBILITY; + + case NewChipID('R', 'E'): + case NewChipID('R', 'F'): + case NewChipID('R', 'G'): + case NewChipID('S', 'K'): + case NewChipID('S', 'L'): + case NewChipID('S', 'M'): + /* "SN" is listed as ATI_CHIP_RAGE128_4X in ATI docs */ + case NewChipID('S', 'N'): + return ATI_CHIP_RAGE128GL; + + case NewChipID('R', 'K'): + case NewChipID('R', 'L'): + /* + * ATI documentation lists SE/SF/SG under both ATI_CHIP_RAGE128VR + * and ATI_CHIP_RAGE128_4X, and lists SH/SK/SL under Rage 128 4X only. + * I'm stuffing them here for now until this can be clarified as ATI + * documentation doesn't mention their details. <mharris@redhat.com> + */ + case NewChipID('S', 'E'): + case NewChipID('S', 'F'): + case NewChipID('S', 'G'): + case NewChipID('S', 'H'): + return ATI_CHIP_RAGE128VR; + + /* case NewChipID('S', 'H'): */ + /* case NewChipID('S', 'K'): */ + /* case NewChipID('S', 'L'): */ + /* case NewChipID('S', 'N'): */ + /* return ATI_CHIP_RAGE128_4X; */ + + case NewChipID('P', 'A'): + case NewChipID('P', 'B'): + case NewChipID('P', 'C'): + case NewChipID('P', 'D'): + case NewChipID('P', 'E'): + case NewChipID('P', 'F'): + return ATI_CHIP_RAGE128PROGL; + + case NewChipID('P', 'G'): + case NewChipID('P', 'H'): + case NewChipID('P', 'I'): + case NewChipID('P', 'J'): + case NewChipID('P', 'K'): + case NewChipID('P', 'L'): + case NewChipID('P', 'M'): + case NewChipID('P', 'N'): + case NewChipID('P', 'O'): + case NewChipID('P', 'P'): + case NewChipID('P', 'Q'): + case NewChipID('P', 'R'): + case NewChipID('P', 'S'): + case NewChipID('P', 'T'): + case NewChipID('P', 'U'): + case NewChipID('P', 'V'): + case NewChipID('P', 'W'): + case NewChipID('P', 'X'): + return ATI_CHIP_RAGE128PROVR; + + case NewChipID('T', 'F'): + case NewChipID('T', 'L'): + case NewChipID('T', 'R'): + case NewChipID('T', 'S'): + case NewChipID('T', 'T'): + case NewChipID('T', 'U'): + return ATI_CHIP_RAGE128PROULTRA; + + case NewChipID('L', 'E'): + case NewChipID('L', 'F'): + /* + * "LK" and "LL" are not in any ATI documentation I can find + * - mharris + */ + case NewChipID('L', 'K'): + case NewChipID('L', 'L'): + return ATI_CHIP_RAGE128MOBILITY3; + + case NewChipID('M', 'F'): + case NewChipID('M', 'L'): + return ATI_CHIP_RAGE128MOBILITY4; + + case NewChipID('Q', 'D'): + case NewChipID('Q', 'E'): + case NewChipID('Q', 'F'): + case NewChipID('Q', 'G'): + return ATI_CHIP_RADEON; + + case NewChipID('Q', 'Y'): + case NewChipID('Q', 'Z'): + return ATI_CHIP_RADEONVE; + + case NewChipID('L', 'Y'): + case NewChipID('L', 'Z'): + return ATI_CHIP_RADEONMOBILITY6; + + case NewChipID('A', '6'): + case NewChipID('C', '6'): + return ATI_CHIP_RS100; + + case NewChipID('A', '7'): + case NewChipID('C', '7'): + return ATI_CHIP_RS200; + + case NewChipID('D', '7'): + case NewChipID('B', '7'): + return ATI_CHIP_RS250; + + case NewChipID('L', 'W'): + case NewChipID('L', 'X'): + return ATI_CHIP_RADEONMOBILITY7; + + case NewChipID('Q', 'H'): + case NewChipID('Q', 'I'): + case NewChipID('Q', 'J'): + case NewChipID('Q', 'K'): + case NewChipID('Q', 'L'): + case NewChipID('Q', 'M'): + case NewChipID('Q', 'N'): + case NewChipID('Q', 'O'): + case NewChipID('Q', 'h'): + case NewChipID('Q', 'i'): + case NewChipID('Q', 'j'): + case NewChipID('Q', 'k'): + case NewChipID('Q', 'l'): + case NewChipID('B', 'B'): + return ATI_CHIP_R200; + + case NewChipID('Q', 'W'): + case NewChipID('Q', 'X'): + return ATI_CHIP_RV200; + + case NewChipID('I', 'd'): + case NewChipID('I', 'e'): + case NewChipID('I', 'f'): + case NewChipID('I', 'g'): + return ATI_CHIP_RV250; + + case NewChipID('L', 'd'): + case NewChipID('L', 'e'): + case NewChipID('L', 'f'): + case NewChipID('L', 'g'): + return ATI_CHIP_RADEONMOBILITY9; + + case NewChipID('X', '4'): + case NewChipID('X', '5'): + return ATI_CHIP_RS300; + + case NewChipID('Y', '\''): + case NewChipID('Y', 'a'): + case NewChipID('I', 'b'): + case NewChipID('I', 'c'): + return ATI_CHIP_RV280; + + case NewChipID('Y', 'h'): + case NewChipID('Y', 'i'): + case NewChipID('Y', 'j'): + case NewChipID('Y', 'k'): + return ATI_CHIP_RADEONMOBILITY9PLUS; + + case NewChipID('A', 'D'): + case NewChipID('A', 'E'): + case NewChipID('A', 'F'): + case NewChipID('A', 'G'): + case NewChipID('N', 'D'): + case NewChipID('N', 'E'): + case NewChipID('N', 'F'): + case NewChipID('N', 'G'): + return ATI_CHIP_R300; + + case NewChipID('A', 'K'): + case NewChipID('N', 'H'): + case NewChipID('N', 'K'): + return ATI_CHIP_R350; + + case NewChipID('N', 'P'): + case NewChipID('A', 'P'): + case NewChipID('A', 'R'): + return ATI_CHIP_RV350; + + case NewChipID('H', 'D'): + return ATI_CHIP_HDTV; + default: + /* + * I'd say it's a Rage128 or a Radeon here, except that I don't + * support them. + */ return ATI_CHIP_Mach64; } } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h index 8bcf4d448..96d56ba6f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h @@ -1,6 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h,v 1.5 1999/07/06 11:38:25 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h,v 1.24 2003/07/02 17:31:29 martin Exp $ */ /* - * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -27,48 +27,83 @@ #include "atipriv.h" #include "atiregs.h" +#include "Xmd.h" + /* * Chip-related definitions. */ typedef enum { ATI_CHIP_NONE = 0, - ATI_CHIP_VGA, /* Generic VGA */ + +#ifndef AVOID_CPIO + + ATI_CHIP_VGA, /* Generic VGA */ ATI_CHIP_18800, ATI_CHIP_18800_1, ATI_CHIP_28800_2, ATI_CHIP_28800_4, ATI_CHIP_28800_5, ATI_CHIP_28800_6, - ATI_CHIP_8514A, /* 8514/A */ - ATI_CHIP_CT480, /* 8514/A clone */ - ATI_CHIP_38800_1, /* Mach8 */ - ATI_CHIP_68800, /* Mach32 */ - ATI_CHIP_68800_3, /* Mach32 */ - ATI_CHIP_68800_6, /* Mach32 */ - ATI_CHIP_68800LX, /* Mach32 */ - ATI_CHIP_68800AX, /* Mach32 */ - ATI_CHIP_88800GXC, /* Mach64 */ - ATI_CHIP_88800GXD, /* Mach64 */ - ATI_CHIP_88800GXE, /* Mach64 */ - ATI_CHIP_88800GXF, /* Mach64 */ - ATI_CHIP_88800GX, /* Mach64 */ - ATI_CHIP_88800CX, /* Mach64 */ - ATI_CHIP_264CT, /* Mach64 */ - ATI_CHIP_264ET, /* Mach64 */ - ATI_CHIP_264VT, /* Mach64 */ - ATI_CHIP_264GT, /* Mach64 */ - ATI_CHIP_264VTB, /* Mach64 */ - ATI_CHIP_264GTB, /* Mach64 */ - ATI_CHIP_264VT3, /* Mach64 */ - ATI_CHIP_264GTDVD, /* Mach64 */ - ATI_CHIP_264LT, /* Mach64 */ - ATI_CHIP_264VT4, /* Mach64 */ - ATI_CHIP_264GT2C, /* Mach64 */ - ATI_CHIP_264GTPRO, /* Mach64 */ - ATI_CHIP_264LTPRO, /* Mach64 */ - ATI_CHIP_264XL, /* Mach64 */ - ATI_CHIP_Mach64 /* Mach64 */ + ATI_CHIP_8514A, /* 8514/A */ + ATI_CHIP_CT480, /* 8514/A clone */ + ATI_CHIP_38800_1, /* Mach8 */ + ATI_CHIP_68800, /* Mach32 */ + ATI_CHIP_68800_3, /* Mach32 */ + ATI_CHIP_68800_6, /* Mach32 */ + ATI_CHIP_68800LX, /* Mach32 */ + ATI_CHIP_68800AX, /* Mach32 */ + +#endif /* AVOID_CPIO */ + + ATI_CHIP_88800GXC, /* Mach64 */ + ATI_CHIP_88800GXD, /* Mach64 */ + ATI_CHIP_88800GXE, /* Mach64 */ + ATI_CHIP_88800GXF, /* Mach64 */ + ATI_CHIP_88800GX, /* Mach64 */ + ATI_CHIP_88800CX, /* Mach64 */ + ATI_CHIP_264CT, /* Mach64 */ + ATI_CHIP_264ET, /* Mach64 */ + ATI_CHIP_264VT, /* Mach64 */ + ATI_CHIP_264GT, /* Mach64 */ + ATI_CHIP_264VTB, /* Mach64 */ + ATI_CHIP_264GTB, /* Mach64 */ + ATI_CHIP_264VT3, /* Mach64 */ + ATI_CHIP_264GTDVD, /* Mach64 */ + ATI_CHIP_264LT, /* Mach64 */ + ATI_CHIP_264VT4, /* Mach64 */ + ATI_CHIP_264GT2C, /* Mach64 */ + ATI_CHIP_264GTPRO, /* Mach64 */ + ATI_CHIP_264LTPRO, /* Mach64 */ + ATI_CHIP_264XL, /* Mach64 */ + ATI_CHIP_MOBILITY, /* Mach64 */ + ATI_CHIP_Mach64, /* Mach64 */ + ATI_CHIP_RAGE128GL, /* Rage128 */ + ATI_CHIP_RAGE128VR, /* Rage128 */ + ATI_CHIP_RAGE128PROGL, /* Rage128 */ + ATI_CHIP_RAGE128PROVR, /* Rage128 */ + ATI_CHIP_RAGE128PROULTRA, /* Rage128 */ + ATI_CHIP_RAGE128MOBILITY3, /* Rage128 */ + ATI_CHIP_RAGE128MOBILITY4, /* Rage128 */ + ATI_CHIP_Rage128, /* Rage128 */ + ATI_CHIP_RADEON, /* Radeon */ + ATI_CHIP_RADEONVE, /* Radeon VE */ + ATI_CHIP_RADEONMOBILITY6, /* Radeon M6 */ + ATI_CHIP_RS100, /* IGP320 */ + ATI_CHIP_RS200, /* IGP340 */ + ATI_CHIP_RS250, /* Radoen 7000 IGP */ + ATI_CHIP_RV200, /* RV200 */ + ATI_CHIP_RADEONMOBILITY7, /* Radeon M7 */ + ATI_CHIP_R200, /* R200 */ + ATI_CHIP_RV250, /* RV250 */ + ATI_CHIP_RADEONMOBILITY9, /* Radeon M9 */ + ATI_CHIP_RS300, /* Radoen 9000 IGP */ + ATI_CHIP_RV280, /* RV250 */ + ATI_CHIP_RADEONMOBILITY9PLUS, /* Radeon M9+ */ + ATI_CHIP_R300, /* R300 */ + ATI_CHIP_RV350, /* RV350 */ + ATI_CHIP_R350, /* R350 */ + ATI_CHIP_HDTV /* HDTV */ } ATIChipType; extern const char *ATIChipNames[]; @@ -82,7 +117,7 @@ typedef enum ATI_FOUNDRY_NEC, /* NEC */ ATI_FOUNDRY_KSC, /* KSC (?) */ ATI_FOUNDRY_UMC, /* United Microelectronics Corporation */ - ATI_FOUNDRY_4, + ATI_FOUNDRY_TSMC, /* Taiwan Semiconductor Manufacturing Company */ ATI_FOUNDRY_5, ATI_FOUNDRY_6, ATI_FOUNDRY_UMCA /* UMC alternate */ @@ -90,7 +125,12 @@ typedef enum extern const char *ATIFoundryNames[]; +#ifndef AVOID_CPIO + extern void ATIMach32ChipID FunctionPrototype((ATIPtr)); + +#endif /* AVOID_CPIO */ + extern void ATIMach64ChipID FunctionPrototype((ATIPtr, const CARD16)); extern ATIChipType ATIChipID FunctionPrototype((const CARD16, const CARD8)); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c index 4ff6dad1e..5e2c31bb3 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c @@ -1,6 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c,v 1.10 1999/08/21 13:48:32 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c,v 1.58 2003/07/02 17:31:29 martin Exp $ */ /* - * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -24,17 +24,24 @@ #include "ati.h" #include "atiadapter.h" #include "atiadjust.h" -#include "atibios.h" #include "atibus.h" #include "atichip.h" #include "aticonsole.h" #include "atiident.h" -#include "atiio.h" +#include "atimach64io.h" +#include "atimodule.h" #include "atipreinit.h" #include "atiprobe.h" #include "atiscreen.h" #include "ativalid.h" #include "ativersion.h" +#include "atividmem.h" +#include "atiwonderio.h" + +#include "radeon_probe.h" +#include "radeon_version.h" +#include "r128_probe.h" +#include "r128_version.h" /* * NOTES: @@ -50,21 +57,34 @@ * largely ignored. */ +#ifdef XFree86LOADER + /* - * Definitions for I/O conflict avoidance. + * The following exists to prevent the compiler from considering entry points + * defined in a separate module from being constants. */ -#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 -{ - CARD16 Base; - CARD8 Size; - CARD8 Flag; -} PortRec, *PortPtr; +static xf86PreInitProc * const volatile PreInitProc = ATIPreInit; +static xf86ScreenInitProc * const volatile ScreenInitProc = ATIScreenInit; +static xf86SwitchModeProc * const volatile SwitchModeProc = ATISwitchMode; +static xf86AdjustFrameProc * const volatile AdjustFrameProc = ATIAdjustFrame; +static xf86EnterVTProc * const volatile EnterVTProc = ATIEnterVT; +static xf86LeaveVTProc * const volatile LeaveVTProc = ATILeaveVT; +static xf86FreeScreenProc * const volatile FreeScreenProc = ATIFreeScreen; +static xf86ValidModeProc * const volatile ValidModeProc = ATIValidMode; + +#define ATIPreInit PreInitProc +#define ATIScreenInit ScreenInitProc +#define ATISwitchMode SwitchModeProc +#define ATIAdjustFrame AdjustFrameProc +#define ATIEnterVT EnterVTProc +#define ATILeaveVT LeaveVTProc +#define ATIFreeScreen FreeScreenProc +#define ATIValidMode ValidModeProc + +#endif + +/* Used as a temporary buffer */ +#define Identifier ((char *)(pATI->MMIOCache)) /* * An internal structure definition to facilitate the matching of detected @@ -77,6 +97,24 @@ typedef struct _ATIGDev 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 -- * @@ -93,8 +131,8 @@ ATIScanPCIBases const CARD8 ProbeFlag ) { - int i, j; - CARD16 Base; + IOADDRESS Base; + int i, j; for (i = 6; --i >= 0; pBase++, pSize++) { @@ -139,33 +177,38 @@ ATIScanPCIBases static CARD8 ATICheckSparseIOBases ( - CARD8 *ProbeFlags, - const CARD16 IOBase, - const int Count, - const Bool Override + pciVideoPtr pVideo, + CARD8 *ProbeFlags, + const IOADDRESS IOBase, + const int Count, + const Bool Override ) { - CARD32 FirstPort = LongPort(IOBase), - LastPort = LongPort(IOBase + Count - 1); + CARD32 FirstPort, LastPort; - for (; FirstPort <= LastPort; FirstPort++) + if (!pVideo || !xf86IsPrimaryPci(pVideo)) { - CARD8 ProbeFlag = ProbeFlags[FirstPort]; + FirstPort = LongPort(IOBase); + LastPort = LongPort(IOBase + Count - 1); - if (ProbeFlag & DoProbe) - continue; + for (; FirstPort <= LastPort; FirstPort++) + { + CARD8 ProbeFlag = ProbeFlags[FirstPort]; - if (!(ProbeFlag & Allowed)) - return ProbeFlag; + if (ProbeFlag & DoProbe) + continue; - if (Override) - continue; + if (!(ProbeFlag & Allowed)) + return ProbeFlag; - /* User might wish to override this decision */ - xf86Msg(X_WARNING, - ATI_NAME ": Sparse I/O base 0x%04X not probed." ATI_README, - IOBase); - return Allowed; + if (Override) + continue; + + /* User might wish to override this decision */ + xf86Msg(X_WARNING, + ATI_NAME ": Sparse I/O base 0x%04X not probed.\n", IOBase); + return Allowed; + } } return DoProbe; @@ -180,10 +223,10 @@ ATICheckSparseIOBases static void ATIClaimSparseIOBases ( - CARD8 *ProbeFlags, - const CARD16 IOBase, - const int Count, - const CARD8 ProbeFlag + CARD8 *ProbeFlags, + const IOADDRESS IOBase, + const int Count, + const CARD8 ProbeFlag ) { CARD32 FirstPort = LongPort(IOBase), @@ -216,15 +259,15 @@ ATIVGAProbe * need to unlock them. */ ATISetVGAIOBase(pVGA, inb(R_GENMO)); - (void) inb(GENS1(pVGA->CPIO_VGABase)); + (void)inb(GENS1(pVGA->CPIO_VGABase)); IOValue1 = inb(ATTRX); - (void) inb(GENS1(pVGA->CPIO_VGABase)); + (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)); + (void)inb(GENS1(pVGA->CPIO_VGABase)); if (IOValue3 == (IOValue2 ^ 0x0FU)) { /* VGA device detected */ @@ -236,7 +279,9 @@ ATIVGAProbe pVGA->Adapter = ATI_ADAPTER_VGA; } else + { pVGA->VGAAdapter = ATI_ADAPTER_NONE; + } return pVGA; } @@ -251,20 +296,22 @@ ATIVGAProbe static void ATIVGAWonderProbe ( - ATIPtr pATI, - ATIPtr p8514, - CARD8 *ProbeFlags + pciVideoPtr pVideo, + ATIPtr pATI, + ATIPtr p8514, + CARD8 *ProbeFlags ) { CARD8 IOValue1, IOValue2, IOValue3, IOValue4, IOValue5, IOValue6; - switch (ATICheckSparseIOBases(ProbeFlags, pATI->CPIO_VGAWonder, 2, TRUE)) + 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%04X because it would conflict with" - " a non-video PCI device." ATI_README, pATI->CPIO_VGAWonder); + " a non-video PCI/AGP device.\n", pATI->CPIO_VGAWonder); pATI->CPIO_VGAWonder = 0; break; @@ -272,7 +319,7 @@ ATIVGAWonderProbe xf86Msg(X_WARNING, ATI_NAME ": Expected VGA Wonder capability could not be" " detected at I/O port 0x%04X because it would conflict with" - " a %s %s." ATI_README, pATI->CPIO_VGAWonder, + " a %s %s.\n", pATI->CPIO_VGAWonder, ATIBusNames[p8514->BusType], ATIAdapterNames[p8514->Adapter]); pATI->CPIO_VGAWonder = 0; break; @@ -281,12 +328,20 @@ ATIVGAWonderProbe xf86Msg(X_WARNING, ATI_NAME ": Expected VGA Wonder capability could not be" " detected at I/O port 0x%04X because it would conflict with" - " a Mach64." ATI_README, pATI->CPIO_VGAWonder); + " a Mach64.\n", pATI->CPIO_VGAWonder); pATI->CPIO_VGAWonder = 0; break; case DetectedVGA: default: /* Must be DoProbe */ + 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); + } /* * Register 0xBB is used by the BIOS to keep track of various * things (monitor type, etc.). Except for 18800-x's, register @@ -306,15 +361,22 @@ ATIVGAWonderProbe else IOValue6 = ATIGetExtReg(0xBCU); ATIPutExtReg(IOValue1, IOValue2); + if ((IOValue4 == (IOValue3 ^ 0xAAU)) && (IOValue5 == (IOValue3 ^ 0x55U)) && (IOValue6 == 0)) - break; - - xf86Msg(X_WARNING, - ATI_NAME ": Expected VGA Wonder capability at I/O port 0x%04X" - " was not detected." ATI_README); - pATI->CPIO_VGAWonder = 0; + { + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": VGA Wonder at I/O port 0x%04X detected.\n", + pATI->CPIO_VGAWonder); + } + else + { + xf86Msg(X_WARNING, + ATI_NAME ": Expected VGA Wonder capability at I/O port" + " 0x%04X was not detected.\n", pATI->CPIO_VGAWonder); + pATI->CPIO_VGAWonder = 0; + } break; } } @@ -373,7 +435,7 @@ ATI8514Probe return NULL; } - /* Ensure and Mach8 or Mach32 is not in 8514/A emulation mode */ + /* Ensure any Mach8 or Mach32 is not in 8514/A emulation mode */ IOValue1 = inw(CLOCK_SEL); outw(CLOCK_SEL, IOValue1); ProbeWaitIdleEmpty(); @@ -443,7 +505,8 @@ ATI8514Probe if (!(IOValue1 & (_8514_ONLY | CHIP_DIS))) { pATI->VGAAdapter = ATI_ADAPTER_MACH32; - if ((ATIReadBIOS(pATI, &pATI->CPIO_VGAWonder, 0x10U, + if ((xf86ReadBIOS(pATI->BIOSBase, 0x10U, + (pointer)(&pATI->CPIO_VGAWonder), SizeOf(pATI->CPIO_VGAWonder)) < SizeOf(pATI->CPIO_VGAWonder)) || !(pATI->CPIO_VGAWonder &= SPARSE_IO_PORT)) @@ -461,92 +524,226 @@ ATI8514Probe return pATI; } +#endif /* AVOID_CPIO */ + /* - * ATIMach64Probe -- + * ATIMach64Detect -- * - * This function looks for a Mach64 at a particular I/O base address and - * returns an ATIRec if one is found. + * This function determines if a Mach64 is detectable at a particular base + * address. */ -static ATIPtr -ATIMach64Probe +static Bool +ATIMach64Detect ( - const CARD16 IOBase, - const CARD8 IODecoding, + ATIPtr pATI, const CARD16 ChipType, const ATIChipType Chip ) { - ATIPtr pATI; CARD32 IOValue, bus_cntl, gen_test_cntl; - CARD16 IOPort; - pATI = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec)); - pATI->CPIOBase = IOBase; - pATI->CPIODecoding = IODecoding; + (void)ATIMapApertures(-1, pATI); /* Ignore errors */ + +#ifdef AVOID_CPIO + + if (!pATI->pBlock[0]) + { + ATIUnmapApertures(-1, pATI); + return FALSE; + } + +#endif /* AVOID_CPIO */ /* Make sure any Mach64 is not in some weird state */ - pATI->CPIO_BUS_CNTL = ATIIOPort(BUS_CNTL); - bus_cntl = inl(pATI->CPIO_BUS_CNTL); + bus_cntl = inr(BUS_CNTL); if (Chip < ATI_CHIP_264VTB) - outl(pATI->CPIO_BUS_CNTL, + outr(BUS_CNTL, (bus_cntl & ~(BUS_HOST_ERR_INT_EN | BUS_FIFO_ERR_INT_EN)) | (BUS_HOST_ERR_INT | BUS_FIFO_ERR_INT)); - else - outl(pATI->CPIO_BUS_CNTL, (bus_cntl & ~BUS_HOST_ERR_INT_EN) | - BUS_HOST_ERR_INT); + else if (Chip < ATI_CHIP_264VT4) + outr(BUS_CNTL, (bus_cntl & ~BUS_HOST_ERR_INT_EN) | BUS_HOST_ERR_INT); - pATI->CPIO_GEN_TEST_CNTL = ATIIOPort(GEN_TEST_CNTL); - gen_test_cntl = inl(pATI->CPIO_GEN_TEST_CNTL); + gen_test_cntl = inr(GEN_TEST_CNTL); IOValue = gen_test_cntl & (GEN_OVR_OUTPUT_EN | GEN_OVR_POLARITY | GEN_CUR_EN | GEN_BLOCK_WR_EN); - outl(pATI->CPIO_GEN_TEST_CNTL, IOValue | GEN_GUI_EN); - outl(pATI->CPIO_GEN_TEST_CNTL, IOValue); - outl(pATI->CPIO_GEN_TEST_CNTL, IOValue | GEN_GUI_EN); + outr(GEN_TEST_CNTL, IOValue | GEN_GUI_EN); + outr(GEN_TEST_CNTL, IOValue); + outr(GEN_TEST_CNTL, IOValue | GEN_GUI_EN); /* See if a Mach64 answers */ - IOPort = ATIIOPort(SCRATCH_REG0); - IOValue = inl(IOPort); + IOValue = inr(SCRATCH_REG0); /* Test odd bits */ - outl(IOPort, 0x55555555U); - if (inl(IOPort) == 0x55555555U) + outr(SCRATCH_REG0, 0x55555555U); + if (inr(SCRATCH_REG0) == 0x55555555U) { /* Test even bits */ - outl(IOPort, 0xAAAAAAAAU); - if (inl(IOPort) == 0xAAAAAAAAU) + outr(SCRATCH_REG0, 0xAAAAAAAAU); + if (inr(SCRATCH_REG0) == 0xAAAAAAAAU) { /* - * *Something* has a R/W 32-bit register at this I/O address. Try - * to make sure it's a Mach64. The following assumes that ATI will + * *Something* has a R/W 32-bit register at this address. Try to + * make sure it's a Mach64. The following assumes that ATI will * not be producing any more adapters that do not register * themselves in PCI configuration space. */ ATIMach64ChipID(pATI, ChipType); - if ((pATI->Chip != ATI_CHIP_Mach64) || (IODecoding == BLOCK_IO)) + if ((pATI->Chip != ATI_CHIP_Mach64) || + (pATI->CPIODecoding == BLOCK_IO)) pATI->Adapter = ATI_ADAPTER_MACH64; } } /* Restore clobbered register value */ - outl(IOPort, IOValue); + outr(SCRATCH_REG0, IOValue); /* If no Mach64 was detected, return now */ if (pATI->Adapter != ATI_ADAPTER_MACH64) { - outl(pATI->CPIO_GEN_TEST_CNTL, gen_test_cntl); - outl(pATI->CPIO_BUS_CNTL, bus_cntl); - xfree(pATI); - return NULL; + outr(GEN_TEST_CNTL, gen_test_cntl); + outr(BUS_CNTL, bus_cntl); + ATIUnmapApertures(-1, pATI); + return FALSE; } /* Determine legacy BIOS address */ pATI->BIOSBase = 0x000C0000U + - (GetBits(inl(ATIIOPort(SCRATCH_REG1)), BIOS_BASE_SEGMENT) << 11); + (GetBits(inr(SCRATCH_REG1), BIOS_BASE_SEGMENT) << 11); - /* Determine VGA capability */ - IOValue = inl(ATIIOPort(CONFIG_STATUS64_0)); - if (pATI->Chip < ATI_CHIP_264CT) + ATIUnmapApertures(-1, pATI); + pATI->PCIInfo = NULL; + return TRUE; +} + +#ifdef AVOID_CPIO + +/* + * ATIMach64Probe -- + * + * This function looks for a Mach64 at a particular MMIO address and returns an + * ATIRec if one is found. + */ +static ATIPtr +ATIMach64Probe +( + 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; + + /* + * Probe through auxiliary MMIO aperture if one exists. Because such + * apertures can be enabled/disabled only through PCI, this probes no + * further. + */ + if ((pVideo->size[2] >= 12) && + (pATI->Block0Base = pVideo->memBase[2]) && + (pATI->Block0Base < (CARD32)(-1 << pVideo->size[2]))) + { + pATI->Block0Base += 0x00000400U; + goto LastProbe; + } + + /* + * Probe through the primary MMIO aperture that exists at the tail end + * of the linear aperture. Test for both 8MB and 4MB linear apertures. + */ + if ((pVideo->size[0] >= 22) && (pATI->Block0Base = pVideo->memBase[0])) + { + pATI->Block0Base += 0x007FFC00U; + if ((pVideo->size[0] >= 23) && + ATIMach64Detect(pATI, ChipType, Chip)) + return pATI; + + pATI->Block0Base -= 0x00400000U; + if (ATIMach64Detect(pATI, ChipType, Chip)) + return pATI; + } + } + + /* + * A last, perhaps desparate, probe attempt. Note that if this succeeds, + * there's a VGA in the system and it's likely the PIO version of the + * driver should be used instead (barring OS issues). + */ + pATI->Block0Base = 0x000BFC00U; + +LastProbe: + if (ATIMach64Detect(pATI, ChipType, Chip)) + return pATI; + + xfree(pATI); + return NULL; +} + +#else /* AVOID_CPIO */ + +/* + * ATIMach64Probe -- + * + * This function looks for a Mach64 at a particular PIO address and returns an + * ATIRec if one is found. + */ +static ATIPtr +ATIMach64Probe +( + pciVideoPtr pVideo, + const IOADDRESS IOBase, + const CARD8 IODecoding, + const ATIChipType Chip +) +{ + ATIPtr pATI; + CARD32 IOValue; + CARD16 ChipType = 0; + + if (!IOBase) + return NULL; + + if (pVideo) { + if ((IODecoding == BLOCK_IO) && + ((pVideo->size[1] < 8) || + (IOBase >= (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; + } + + /* + * Determine VGA capability. VGA can always be enabled on integrated + * controllers. For the GX/CX, it's a board strap. + */ + if (pATI->Chip >= ATI_CHIP_264CT) + { + pATI->VGAAdapter = ATI_ADAPTER_MACH64; + } + else + { + IOValue = inr(CONFIG_STATUS64_0); pATI->BusType = GetBits(IOValue, CFG_BUS_TYPE); IOValue &= (CFG_VGA_EN | CFG_CHIP_EN); if (pATI->Chip == ATI_CHIP_88800CX) @@ -558,11 +755,6 @@ ATIMach64Probe pATI->VGAOffset = 0x80U; } } - else - { - if ((pATI->Chip < ATI_CHIP_264VT) || (IOValue & CFG_VGA_EN_T)) - pATI->VGAAdapter = ATI_ADAPTER_MACH64; - } return pATI; } @@ -579,10 +771,11 @@ ATIMach64Probe static void ATIAssignVGA ( - ATIPtr *ppVGA, - ATIPtr pATI, - ATIPtr p8514, - CARD8 *ProbeFlags + pciVideoPtr pVideo, + ATIPtr *ppVGA, + ATIPtr pATI, + ATIPtr p8514, + CARD8 *ProbeFlags ) { ATIPtr pVGA = *ppVGA; @@ -605,10 +798,10 @@ ATIAssignVGA */ OldDACMask = inb(VGA_DAC_MASK); - if (inb(DAC_MASK) == OldDACMask) + if (inb(IBM_DAC_MASK) == OldDACMask) { outb(VGA_DAC_MASK, 0xA5U); - if (inb(DAC_MASK) == 0xA5U) + if (inb(IBM_DAC_MASK) == 0xA5U) pATI->VGAAdapter = ATI_ADAPTER_VGA; } @@ -627,10 +820,10 @@ ATIAssignVGA OldDACMask = inb(VGA_DAC_MASK); - if (inb(DAC_MASK) == OldDACMask) + if (inb(IBM_DAC_MASK) == OldDACMask) { outb(VGA_DAC_MASK, 0xA5U); - if (inb(DAC_MASK) == 0xA5U) + if (inb(IBM_DAC_MASK) == 0xA5U) pATI->VGAAdapter = ATI_ADAPTER_VGA; } @@ -656,10 +849,10 @@ ATIAssignVGA OldDACMask = inb(VGA_DAC_MASK); - if (inb(DAC_MASK) == OldDACMask) + if (inb(IBM_DAC_MASK) == OldDACMask) { outb(VGA_DAC_MASK, 0xA5U); - if (inb(DAC_MASK) == 0xA5U) + if (inb(IBM_DAC_MASK) == 0xA5U) pATI->VGAAdapter = ATI_ADAPTER_MACH32; } @@ -674,26 +867,24 @@ ATIAssignVGA case ATI_ADAPTER_MACH64: { - CARD16 DACMaskPort = ATIIOPort(DAC_REGS) + 2, - DACCntlPort = ATIIOPort(DAC_CNTL); - CARD32 DACCntl = inl(DACCntlPort); + CARD32 DACCntl = inr(DAC_CNTL); if (!(DACCntl & DAC_VGA_ADR_EN)) - outl(DACCntlPort, DACCntl | DAC_VGA_ADR_EN); + outr(DAC_CNTL, DACCntl | DAC_VGA_ADR_EN); OldDACMask = inb(VGA_DAC_MASK); - if (inb(DACMaskPort) == OldDACMask) + if (in8(M64_DAC_MASK) == OldDACMask) { outb(VGA_DAC_MASK, 0xA5U); - if (inb(DACMaskPort) == 0xA5U) + if (in8(M64_DAC_MASK) == 0xA5U) pATI->VGAAdapter = ATI_ADAPTER_MACH64; } outb(VGA_DAC_MASK, OldDACMask); if (!(DACCntl & DAC_VGA_ADR_EN)) - outl(DACCntlPort, DACCntl); + outr(DAC_CNTL, DACCntl); } break; @@ -709,15 +900,17 @@ ATIAssignVGA if (pATI->CPIO_VGAWonder) { - ATIVGAWonderProbe(pATI, p8514, ProbeFlags); + ATIVGAWonderProbe(pVideo, pATI, p8514, ProbeFlags); if (!pATI->CPIO_VGAWonder) { /* * Some adapters are reputed to append ATI extended VGA registers - * to the VGA Graphics controller registers. + * to the VGA Graphics controller registers. In particular, 0x01CE + * cannot, in general, be used in a PCI environment due to routing + * of I/O through the bus tree. */ pATI->CPIO_VGAWonder = GRAX; - ATIVGAWonderProbe(pATI, p8514, ProbeFlags); + ATIVGAWonderProbe(pVideo, pATI, p8514, ProbeFlags); } } @@ -730,6 +923,8 @@ ATIAssignVGA /* Assign the VGA to this adapter */ xfree(pVGA); *ppVGA = pATI; + + xf86MsgVerb(X_INFO, 3, ATI_NAME ": VGA assigned to this adapter.\n"); } /* @@ -741,21 +936,23 @@ ATIAssignVGA static void ATIClaimVGA ( - ATIPtr *ppVGA, - ATIPtr pATI, - ATIPtr p8514, - CARD8 *ProbeFlags, - int Detected + pciVideoPtr pVideo, + ATIPtr *ppVGA, + ATIPtr pATI, + ATIPtr p8514, + CARD8 *ProbeFlags, + int Detected ) { - ATIAssignVGA(ppVGA, pATI, p8514, ProbeFlags); - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - { - ATIClaimSparseIOBases(ProbeFlags, MonochromeIOBase, 48, Detected); - if (pATI->CPIO_VGAWonder) - ATIClaimSparseIOBases(ProbeFlags, pATI->CPIO_VGAWonder, 2, - 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); } /* @@ -767,24 +964,37 @@ ATIClaimVGA static void ATIFindVGA ( - ATIPtr *ppVGA, - ATIPtr *ppATI, - ATIPtr p8514, - CARD8 *ProbeFlags + pciVideoPtr pVideo, + ATIPtr *ppVGA, + ATIPtr *ppATI, + ATIPtr p8514, + CARD8 *ProbeFlags ) { ATIPtr pATI = *ppATI; - if (*ppVGA) - ATIAssignVGA(ppVGA, pATI, p8514, ProbeFlags); - else + 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. + */ + outb(GENENA, 0x16U); + outb(GENVS, 0x01U); + outb(GENENA, 0x0EU); + pATI = ATIVGAProbe(pATI); - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIAssignVGA(ppATI, pATI, p8514, ProbeFlags); + if (pATI->VGAAdapter == ATI_ADAPTER_NONE) + return; + + ppVGA = ppATI; } + + ATIAssignVGA(pVideo, ppVGA, pATI, p8514, ProbeFlags); } +#endif /* AVOID_CPIO */ + /* * ATIProbe -- * @@ -798,92 +1008,126 @@ ATIProbe int flags ) { - ATIPtr pATI, *ATIPtrs = NULL, pVGA, p8514 = NULL; - ATIPtr pMach64[3] = {NULL, NULL, NULL}; - GDevPtr *GDevs, pGDev; - pciVideoPtr pVideo, *xf86PciVideoInfo = xf86GetPciVideoInfo(); - pciConfigPtr pPCI, *xf86PciInfo = xf86GetPciConfigInfo(); - ATIGDev *ATIGDevs, *pATIGDev; - ScrnInfoPtr pScreenInfo; - PortPtr PCIPorts = NULL; - CARD32 PciReg; - int i, j, k; - int nGDev, nATIGDev = 0, nATIPtr = 0, nPCIPort = 0; - int nScreen = 0; - int Chipset; - CARD8 fChipsets[ATI_CHIPSET_MAX]; - ATIChipType Chip; - static const CARD16 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) (*((CARD16 *)(BIOS + (_n)))) - -# define AddAdapter(_p) \ + ATIPtr pATI, *ATIPtrs = NULL; + GDevPtr *GDevs, pGDev; + pciVideoPtr pVideo, *xf86PciVideoInfo = xf86GetPciVideoInfo(); + pciConfigPtr pPCI; + ATIGDev *ATIGDevs = NULL, *pATIGDev; + ScrnInfoPtr pScreenInfo; + CARD32 PciReg; + Bool ProbeSuccess = FALSE; + Bool DoRage128 = FALSE, DoRadeon = FALSE; + int i, j, k; + int nGDev, nATIGDev = -1, nATIPtr = 0; + int Chipset; + ATIChipType Chip; + +#ifndef AVOID_CPIO + + ATIPtr pVGA = NULL, p8514 = NULL; + ATIPtr pMach64[3] = {NULL, NULL, 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) + } while (0) - /* - * 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 recognized by - * the driver. Those device sections that specify a "ChipRev" without a - * "ChipID" are also weeded out. - */ - if ((nGDev = xf86MatchDevice(ATI_NAME, &GDevs)) <= 0) - return FALSE; +#ifndef AVOID_CPIO + + (void)memset(fChipsets, FALSE, SizeOf(fChipsets)); - ATIGDevs = (ATIGDevPtr)xnfcalloc(nGDev, SizeOf(ATIGDev)); - memset(fChipsets, FALSE, SizeOf(fChipsets)); +#endif /* AVOID_CPIO */ - for (i = 0, pATIGDev = ATIGDevs; i < nGDev; i++) + if (!(flags & PROBE_DETECT)) { - pGDev = GDevs[i]; - Chipset = ATIIdentProbe(pGDev->chipset); - if (Chipset == -1) - continue; + /* + * 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)); - if ((pGDev->chipID > (int)((CARD16)(-1))) || - (pGDev->chipRev > (int)((CARD8)(-1)))) - continue; + for (i = 0, pATIGDev = ATIGDevs; i < nGDev; i++) + { + pGDev = GDevs[i]; + Chipset = ATIIdentProbe(pGDev->chipset); + if (Chipset == -1) + continue; - if (pGDev->chipID >= 0) - { - if (ATIChipID(pGDev->chipID, 0) == ATI_CHIP_Mach64) - continue; - } - else - { - if (pGDev->chipRev >= 0) - continue; - } + if ((pGDev->chipID > (int)((CARD16)(-1))) || + (pGDev->chipRev > (int)((CARD8)(-1)))) + continue; - pATIGDev->pGDev = pGDev; - pATIGDev->Chipset = Chipset; - nATIGDev++; - pATIGDev++; - fChipsets[Chipset] = TRUE; - } + if (pGDev->chipID >= 0) + { + if (ATIChipID(pGDev->chipID, 0) == ATI_CHIP_Mach64) + continue; + } + else + { + if (pGDev->chipRev >= 0) + continue; + } - xfree(GDevs); + pATIGDev->pGDev = pGDev; + pATIGDev->Chipset = Chipset; + nATIGDev++; + pATIGDev++; - /* If no device sections remain, return now */ - if (!nATIGDev) - { - xfree(ATIGDevs); - return FALSE; + 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. @@ -909,363 +1153,563 @@ ATIProbe * same I/O ports as 8514/A's or ATI sparse I/O devices without registering * them in PCI configuration space. */ - if (xf86PciVideoInfo) - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) + if (nATIGDev) + { + if (xf86PciVideoInfo) { - pPCI = (pciConfigPtr)(pVideo->thisCard); - - if (pVideo->vendor == PCI_VENDOR_ATI) + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) { - if (pVideo->chipType == PCI_CHIP_MACH32) + if ((pVideo->vendor == PCI_VENDOR_ATI) || + !(pPCI = pVideo->thisCard)) continue; - /* - * Some PCI Mach64's are not properly configured for sparse or - * block I/O. Correct PCI's USERCONFIG register, if necessary. - */ - PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); - if (IsATIBlockIOBase(pVideo->ioBase[1])) - { - /* This is block I/O */ - if (!(PciReg & 0x00000004U)) - pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, - PciReg | 0x00000004U); - } - else - { - /* This is sparse I/O */ - if (PciReg & 0x00000004U) - pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, - PciReg & ~0x00000004U); - } - continue; + ATIScanPCIBases(&PCIPorts, &nPCIPort, + &pPCI->pci_base0, pVideo->size, + (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) & + PCI_CMD_IO_ENABLE) ? 0 : Allowed); } - - 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))) + /* 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 */ - memset(ProbeFlags, Allowed | DoProbe, SizeOf(ProbeFlags)); - for (i = 0; i < nPCIPort; i++) - { - CARD32 Base = PCIPorts[i].Base; - CARD16 Count = (1 << PCIPorts[i].Size) - 1; - CARD8 ProbeFlag = PCIPorts[i].Flag; + /* Generate ProbeFlags array from list of registered PCI I/O bases */ + (void)memset(ProbeFlags, Allowed | DoProbe, SizeOf(ProbeFlags)); + for (i = 0; i < nPCIPort; i++) + { + CARD32 Base = PCIPorts[i].Base; + CARD16 Count = (1 << PCIPorts[i].Size) - 1; + CARD8 ProbeFlag = PCIPorts[i].Flag; + + /* + * 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; + } + + xfree(PCIPorts); /* - * The following reduction of Count is based on the assumption that - * PCI-registered I/O port ranges do not overlap. + * 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. + * + * 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. */ - for (j = 0; j < nPCIPort; j++) + if (ATICheckSparseIOBases(NULL, ProbeFlags, ATTRX, 16, TRUE) == + DoProbe) { - CARD32 Base2 = PCIPorts[j].Base; + pATI = ATIVGAProbe(NULL); + if (pATI->Adapter == ATI_ADAPTER_NONE) + { + xfree(pATI); + + 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); - if (Base < Base2) - while ((Base + Count) >= Base2) - Count >>= 1; + 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"); } - Base = LongPort(Base); - Count = LongPort((Count | IO_BYTE_SELECT) + 1); - while (Count--) - ProbeFlags[Base++] &= ProbeFlag; - } + 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); - xfree(PCIPorts); + AddAdapter(p8514 = pATI); - /* - * 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. - * - * 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. - */ - if (ATICheckSparseIOBases(ProbeFlags, ATTRX, 16, TRUE) == DoProbe) - { - pVGA = ATIVGAProbe(NULL); - if (pVGA->Adapter == ATI_ADAPTER_NONE) - { - xfree(pVGA); - pVGA = NULL; + if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) || + (pATI->Coprocessor != ATI_CHIP_NONE)) + ATIClaimVGA(NULL, &pVGA, pATI, p8514, ProbeFlags, + Detected8514A); + + ATIClaimSparseIOBases(ProbeFlags, 0x02E8U, 8, Detected8514A); + } + else + { + xf86MsgVerb(X_INFO, 4, + ATI_NAME ": Unshared 8514/A 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); + xf86MsgVerb(X_INFO, 2, + ATI_NAME ": Unshared 8514/A not probed.\n"); } - } - - if ((ATICheckSparseIOBases(ProbeFlags, 0x02E8U, 8, - fChipsets[ATI_CHIPSET_IBM8514] || - fChipsets[ATI_CHIPSET_MACH8] || - fChipsets[ATI_CHIPSET_MACH32]) == DoProbe) && - (pATI = ATI8514Probe(NULL))) - { - AddAdapter(p8514 = pATI); - - if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) || - (pATI->Coprocessor != ATI_CHIP_NONE)) - ATIClaimVGA(&pVGA, pATI, p8514, ProbeFlags, Detected8514A); - ATIClaimSparseIOBases(ProbeFlags, 0x02E8U, 8, Detected8514A); - } + for (i = 0; i < NumberOf(Mach64SparseIOBases); i++) + { + if (ATICheckSparseIOBases(NULL, ProbeFlags, Mach64SparseIOBases[i], + 4, fChipsets[ATI_CHIPSET_MACH64]) != DoProbe) + { + xf86MsgVerb(X_INFO, 2, + ATI_NAME ": Unshared Mach64 at PIO base 0x%04X not" + " probed.\n", + Mach64SparseIOBases[i]); + continue; + } - for (i = 0; i < NumberOf(Mach64SparseIOBases); i++) - { - if (ATICheckSparseIOBases(ProbeFlags, Mach64SparseIOBases[i], 4, - fChipsets[ATI_CHIPSET_MACH64]) != DoProbe) - continue; + pATI = ATIMach64Probe(NULL, Mach64SparseIOBases[i], SPARSE_IO, 0); + if (!pATI) + { + xf86MsgVerb(X_INFO, 4, + ATI_NAME ": Unshared Mach64 at PIO base 0x%04X not" + " detected.\n", Mach64SparseIOBases[i]); + continue; + } - if (!(pATI = ATIMach64Probe(Mach64SparseIOBases[i], SPARSE_IO, 0, 0))) - 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); + AddAdapter(pMach64[i] = pATI); - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIClaimVGA(&pVGA, pATI, p8514, ProbeFlags, DetectedMach64); + if (pATI->VGAAdapter != ATI_ADAPTER_NONE) + ATIClaimVGA(NULL, &pVGA, pATI, p8514, ProbeFlags, + DetectedMach64); - ATIClaimSparseIOBases(ProbeFlags, Mach64SparseIOBases[i], 4, - DetectedMach64); + ATIClaimSparseIOBases(ProbeFlags, Mach64SparseIOBases[i], 4, + DetectedMach64); + } } +#endif /* AVOID_CPIO */ + if (xf86PciVideoInfo) { - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) + if (nATIGDev) { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - !IsATIBlockIOBase(pVideo->ioBase[1])) - continue; - pATI = ATIMach64Probe(pVideo->ioBase[1], BLOCK_IO, - pVideo->chipType, - ATIChipID(pVideo->chipType, pVideo->chipRev)); - if (!pATI) - continue; +#ifndef AVOID_NON_PCI - AddAdapter(pATI); +#ifdef AVOID_CPIO - /* This is probably not necessary */ - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIClaimVGA(&pVGA, pATI, p8514, ProbeFlags, DetectedMach64); - } + /* 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%08X.\n", + Identifier, pATI->Block0Base); + AddAdapter(pATI); + pATI->PCIInfo = pVideo; + } + +#endif /* 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 have - * been previously initialized by their BIOS. - */ - if (ATICheckSparseIOBases(ProbeFlags, ATTRX, 16, TRUE) == DoProbe) - { for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) { - if ((pVideo->vendor == PCI_VENDOR_ATI) || - !(((pciConfigPtr)(pVideo->thisCard))->pci_command & - PCI_CMD_IO_ENABLE) || - (pVideo->interface != 0) || - (((pVideo->class != PCI_CLASS_PREHISTORIC) || - (pVideo->subclass != PCI_SUBCLASS_PREHISTORIC_VGA)) && - ((pVideo->class != PCI_CLASS_DISPLAY) || - (pVideo->subclass != PCI_SUBCLASS_DISPLAY_VGA)))) + 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; - xf86SetPciVideo(pVideo, IO); + 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 - pATI = ATIVGAProbe(NULL); - if (pATI->Adapter == ATI_ADAPTER_NONE) + /* + * 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++]); ) { - xfree(pATI); - xf86Msg(X_WARNING, - ATI_NAME ": PCI VGA-compatible in slot %d:%d:%d" - " could not be detected!" ATI_README, + 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 - { - AddAdapter(pATI); - pATI->SharedVGA = TRUE; - pATI->BusType = ATI_BUS_PCI; - pATI->PCIInfo = pVideo; - } + } + 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); + 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(ProbeFlags, 0x02E8U, 8, TRUE)) + /* Next, look for PCI Mach32's */ + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) { - case 0: - xf86Msg(X_WARNING, + 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 device." ATI_README, + " non-video PCI/AGP device.\n", pVideo->bus, pVideo->device, pVideo->func); - break; + break; - case Detected8514A: - if ((p8514->BusType >= ATI_BUS_PCI) && !p8514->PCIInfo) - p8514->PCIInfo = pVideo; - else - xf86Msg(X_WARNING, + 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." ATI_README, + " another %s %s.\n", pVideo->bus, pVideo->device, pVideo->func, ATIBusNames[p8514->BusType], ATIAdapterNames[p8514->Adapter]); - break; + break; - case DetectedMach64: - xf86Msg(X_WARNING, + 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." - ATI_README, + " be enabled\n because it conflicts with a Mach64" + " at I/O base 0x02EC.\n", pVideo->bus, pVideo->device, pVideo->func); - break; + break; - default: /* Must be DoProbe */ - xf86SetPciVideo(pVideo, IO); + default: /* Must be DoProbe */ + if (!xf86CheckPciSlot(pVideo->bus, + pVideo->device, + pVideo->func)) + continue; - if (!(pATI = ATI8514Probe(pVideo))) - xf86Msg(X_WARNING, + xf86SetPciVideo(pVideo, MEM_IO); + + if (!(pATI = ATI8514Probe(pVideo))) + { + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach32 in slot %d:%d:%d could" - " not be detected!" ATI_README, + " not be detected!\n", pVideo->bus, pVideo->device, pVideo->func); - else - { - if (pATI->Adapter != ATI_ADAPTER_MACH32) - xf86Msg(X_WARNING, + } + 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!" - ATI_README, + " could only be detected as an %s!\n", pVideo->bus, pVideo->device, pVideo->func, ATIAdapterNames[pATI->Adapter]); - AddAdapter(pATI); - pATI->SharedAccelerator = TRUE; + AddAdapter(pATI); + pATI->SharedAccelerator = TRUE; - if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) || - (pATI->Coprocessor != ATI_CHIP_NONE)) - ATIFindVGA(&pVGA, &pATI, p8514, ProbeFlags); - } + if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) || + (pATI->Coprocessor != ATI_CHIP_NONE)) + ATIFindVGA(pVideo, &pVGA, &pATI, p8514, + ProbeFlags); + } - xf86SetPciVideo(NULL, NONE); - break; + xf86SetPciVideo(NULL, NONE); + break; + } } - } - /* Next, look for sparse I/O Mach64's */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - IsATIBlockIOBase(pVideo->ioBase[1])) - continue; + /* Next, look for sparse I/O Mach64's */ + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) + { + if ((pVideo->vendor != PCI_VENDOR_ATI) || + (pVideo->chipType == PCI_CHIP_MACH32) || + pVideo->size[1]) + continue; - pPCI = (pciConfigPtr)(pVideo->thisCard); - PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); - j = PciReg & 0x03U; - if (j == 0x03U) - xf86Msg(X_WARNING, + pPCI = pVideo->thisCard; + 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." ATI_README, + " sparse, I/O base.\n", pVideo->bus, pVideo->device, pVideo->func); - else switch(ATICheckSparseIOBases(ProbeFlags, - Mach64SparseIOBases[j], 4, TRUE)) - { - case 0: - xf86Msg(X_WARNING, + } + 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." ATI_README, + " non-video PCI device.\n", pVideo->bus, pVideo->device, pVideo->func); - break; + break; - case Detected8514A: - xf86Msg(X_WARNING, + 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." - ATI_README, + " be enabled\n because it conflicts with an %s.\n", pVideo->bus, pVideo->device, pVideo->func, ATIAdapterNames[p8514->Adapter]); - break; + break; - case DetectedMach64: - pATI = pMach64[j]; - if ((pATI->BusType >= ATI_BUS_PCI) && !pATI->PCIInfo) - pATI->PCIInfo = pVideo; - else - xf86Msg(X_WARNING, + 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%04X." - ATI_README, + " another %s Mach64 at sparse I/O base" + " 0x%04X.\n", pVideo->bus, pVideo->device, pVideo->func, ATIBusNames[pATI->BusType], Mach64SparseIOBases[j]); - break; + break; - default: /* Must be DoProbe */ - xf86SetPciVideo(pVideo, IO); + default: /* Must be DoProbe */ + if (!xf86CheckPciSlot(pVideo->bus, + pVideo->device, + pVideo->func)) + continue; - pATI = ATIMach64Probe(Mach64SparseIOBases[j], SPARSE_IO, - pVideo->chipType, - ATIChipID(pVideo->chipType, pVideo->chipRev)); - if (!pATI) - xf86Msg(X_WARNING, + /* 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!" ATI_README, + " not be detected!\n", pVideo->bus, pVideo->device, pVideo->func); - else - { - AddAdapter(pATI); - pATI->SharedAccelerator = TRUE; - pATI->PCIInfo = pVideo; + } + 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%04X" + " detected.\n", Identifier, + Mach64SparseIOBases[j]); + AddAdapter(pATI); + pATI->SharedAccelerator = TRUE; + pATI->PCIInfo = pVideo; - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIFindVGA(&pVGA, &pATI, p8514, ProbeFlags); - } + if (pATI->VGAAdapter != ATI_ADAPTER_NONE) + ATIFindVGA(pVideo, &pVGA, &pATI, p8514, + ProbeFlags); + } - xf86SetPciVideo(NULL, NONE); - break; + xf86SetPciVideo(NULL, NONE); + break; + } } + +#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%08X 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 */ @@ -1273,7 +1717,52 @@ ATIProbe { if ((pVideo->vendor != PCI_VENDOR_ATI) || (pVideo->chipType == PCI_CHIP_MACH32) || - !IsATIBlockIOBase(pVideo->ioBase[1])) + !pVideo->size[1]) + continue; + + /* Check for Rage128's, Radeon's and later adapters */ + Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); + if (Chip > ATI_CHIP_Mach64) + { + switch (Chip) + { + case ATI_CHIP_RAGE128GL: + case ATI_CHIP_RAGE128VR: + case ATI_CHIP_RAGE128PROULTRA: + case ATI_CHIP_RAGE128PROGL: + case ATI_CHIP_RAGE128PROVR: + case ATI_CHIP_RAGE128MOBILITY3: + case ATI_CHIP_RAGE128MOBILITY4: + DoRage128 = TRUE; + continue; + + case ATI_CHIP_RADEON: + case ATI_CHIP_RADEONVE: + case ATI_CHIP_RADEONMOBILITY6: + case ATI_CHIP_RS100: + case ATI_CHIP_RS200: + case ATI_CHIP_RS250: + case ATI_CHIP_RADEONMOBILITY7: + case ATI_CHIP_R200: + case ATI_CHIP_RV200: + case ATI_CHIP_RV250: + case ATI_CHIP_RADEONMOBILITY9: + case ATI_CHIP_RS300: + case ATI_CHIP_RV280: + case ATI_CHIP_RADEONMOBILITY9PLUS: + case ATI_CHIP_R300: + case ATI_CHIP_RV350: + case ATI_CHIP_R350: + DoRadeon = TRUE; + continue; + + case ATI_CHIP_HDTV: + default: + continue; + } + } + + if (!nATIGDev) continue; /* Check if this one has already been detected */ @@ -1284,19 +1773,29 @@ ATIProbe goto SetPCIInfo; } + if (!xf86CheckPciSlot(pVideo->bus, pVideo->device, pVideo->func)) + continue; + /* Probe for it */ - xf86SetPciVideo(pVideo, IO); + xf86SetPciVideo(pVideo, MEM_IO); - pATI = ATIMach64Probe(pVideo->ioBase[1], BLOCK_IO, - pVideo->chipType, - ATIChipID(pVideo->chipType, pVideo->chipRev)); + 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(&pVGA, &pATI, p8514, ProbeFlags); + ATIFindVGA(pVideo, &pVGA, &pATI, p8514, ProbeFlags); + +#endif /* AVOID_CPIO */ + } xf86SetPciVideo(NULL, NONE); @@ -1304,9 +1803,8 @@ ATIProbe if (!pATI) { xf86Msg(X_WARNING, - ATI_NAME ": PCI Mach64 in slot %d:%d:%d could not be" - " detected!" ATI_README, - pVideo->bus, pVideo->device, pVideo->func); + ATI_NAME ": PCI/AGP Mach64 in slot %d:%d:%d could not be" + " detected!\n", pVideo->bus, pVideo->device, pVideo->func); continue; } @@ -1315,23 +1813,41 @@ ATIProbe } } +#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 (!pVGA || (pVGA->VGAAdapter > ATI_ADAPTER_VGA)) + 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; + /* Look for its BIOS */ - for (BIOSBase = 0x000C0000U; ; BIOSBase += 0x00000200U) + for(; ; BIOSBase += 0x00000200U) { - if (BIOSBase >= 0x000F0000U) + if (!BIOSBase) + goto SkipBiosSegment; + + if (BIOSBase >= 0x000F8000U) goto NoVGAWonder; /* Skip over those that are already known */ @@ -1345,7 +1861,7 @@ ATIProbe goto NoVGAWonder; if ((BIOS[0x00U] != 0x55U) || (BIOS[0x01U] != 0xAAU)) - continue; + goto SkipBiosSegment; if ((BIOS[0x1EU] == 'I') && (BIOS[0x1FU] == 'B') && @@ -1358,7 +1874,12 @@ ATIProbe (BIOS[0x22U] == 'I')) break; - SkipBiosSegment: ; + SkipBiosSegment: + if (pATI) + continue; + + pATI = pVGA; + BIOSBase = 0x000C0000U - 0x00000200U; } pVGA->BIOSBase = BIOSBase; @@ -1432,7 +1953,7 @@ ATIProbe if (!pVGA->CPIO_VGAWonder) pVGA->CPIO_VGAWonder = 0x01CEU; - ATIVGAWonderProbe(pVGA, p8514, ProbeFlags); + ATIVGAWonderProbe(NULL, pVGA, p8514, ProbeFlags); break; #if 0 case '2': @@ -1460,244 +1981,389 @@ ATIProbe NoVGAWonder:; } while (0); - /* If no appropriate adapters have been detected, return now */ - if (!nATIPtr) - { - xfree(ATIGDevs); - return FALSE; - } +#endif /* AVOID_CPIO */ /* - * 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. + * Re-order list of detected devices so that the primary device is before + * any other PCI device. */ - for (i = 0, pATIGDev = ATIGDevs; i < nATIGDev; i++, pATIGDev++) + for (i = 0; i < nATIPtr; i++) { - pGDev = pATIGDev->pGDev; + if (!ATIPtrs[i]->PCIInfo) + continue; - for (j = 0; j < nATIPtr; j++) + 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; + } + + 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++) + { + pATI = ATIPtrs[i]; + +#ifndef AVOID_CPIO + + if ((pATI->Adapter != ATI_ADAPTER_VGA) && + ((pATI->Adapter != ATI_ADAPTER_8514A) || + ((pATI->VGAAdapter != ATI_ADAPTER_VGA) && + (pATI->VGAAdapter != ATI_ADAPTER_NONE)))) + +#endif /* AVOID_CPIO */ - /* - * 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: - if (pATI->Adapter == ATI_ADAPTER_VGA) - continue; - if (pATI->Adapter != ATI_ADAPTER_8514A) - break; - /* Fall through */ + 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; + } + } - case ATI_CHIPSET_ATIVGA: - if (pATI->VGAAdapter == ATI_ADAPTER_VGA) - continue; - /* Fall through */ + 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++) + { + pGDev = pATIGDev->pGDev; - case ATI_CHIPSET_IBMVGA: - if (pATI->VGAAdapter == ATI_ADAPTER_NONE) - continue; - break; + for (j = 0; j < nATIPtr; j++) + { + pATI = ATIPtrs[j]; - case ATI_CHIPSET_VGAWONDER: - if (!pATI->CPIO_VGAWonder) - continue; - break; + /* + * 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: - case ATI_CHIPSET_IBM8514: - if (pATI->Adapter == ATI_ADAPTER_8514A) - break; - /* Fall through */ +#ifndef AVOID_CPIO - case ATI_CHIPSET_MACH8: - if (pATI->Adapter == ATI_ADAPTER_MACH8) - break; - /* Fall through */ + if (pATI->Adapter == ATI_ADAPTER_VGA) + continue; + if (pATI->Adapter != ATI_ADAPTER_8514A) + break; + /* Fall through */ - case ATI_CHIPSET_MACH32: - if (pATI->Adapter == ATI_ADAPTER_MACH32) + 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; - continue; - case ATI_CHIPSET_MACH64: - if (pATI->Adapter == ATI_ADAPTER_MACH64) + case ATI_CHIPSET_VGAWONDER: + if (!pATI->CPIO_VGAWonder) + continue; break; - continue; - default: - continue; - } + case ATI_CHIPSET_IBM8514: + if (pATI->Adapter == ATI_ADAPTER_8514A) + break; + /* Fall through */ - /* - * 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 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 unrecognized. - */ - if (pGDev->chipID >= 0) - { - if (pATI->ChipType != pGDev->chipID) - { - if ((pATI->Adapter != ATI_ADAPTER_MACH64) || - (pATI->Chip != ATI_CHIP_Mach64)) + 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; - Chip = ATIChipID(pGDev->chipID, 0); - if ((Chip <= ATI_CHIP_264GTB) || (Chip == ATI_CHIP_Mach64)) +#endif /* AVOID_CPIO */ + + case ATI_CHIPSET_MACH64: + if (pATI->Adapter == ATI_ADAPTER_MACH64) + break; + continue; + + default: continue; } - if ((pGDev->chipRev >= 0) && (pATI->ChipRev != pGDev->chipRev)) + + /* + * 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->Adapter != ATI_ADAPTER_MACH64) - continue; + 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->Chip != ATI_CHIP_Mach64)) + (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; + +#ifndef AVOID_CPIO + + if (!pVideo) + continue; + +#endif /* AVOID_CPIO */ + + 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; } + } - /* - * 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)) + /* + * 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; + + j = pATIGDev->iATIPtr; + if (j <= 0) 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]) + for (k = i; ++k < nATIGDev; ) { - if (!(pVideo = pATI->PCIInfo)) - continue; - if (!xf86ComparePciBusString(pGDev->busID, - pVideo->bus, pVideo->device, pVideo->func)) - continue; + 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; + } } + j = ATIGDevs[i].iATIPtr; + if (j <= 0) + continue; + + pATI = ATIPtrs[j - 1]; + + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": %s assigned to %sactive \"Device\" section" + " \"%s\".\n", + Identifier, pGDev->active ? "" : "in", pGDev->identifier); + /* - * Ensure no two adapters are assigned to the same XF86Config - * Device section. + * Attach adapter to XF86Config Device section and register its + * resources. */ - if (pATIGDev->iATIPtr) + if (ATIClaimBusSlot(pDriver, pATIGDev->Chipset, + pGDev, pGDev->active, pATI) < 0) { - if (pATIGDev->iATIPtr < 0) - break; - xf86Msg(X_ERROR, - ATI_NAME ": XF86Config Device section \"%s\" may not" - " be assigned to more than one adapter." ATI_README, - pGDev->identifier); - pATIGDev->iATIPtr = -1; - break; + ATI_NAME ": Could not claim bus slot for %s.\n", + Identifier); + continue; } - /* Assign adapter */ - pATIGDev->iATIPtr = j + 1; + if (!pGDev->active) + continue; - /* - * For compatibility with previous releases, assign the first - * applicable adapter if there is only one Device section. - */ - if (nATIGDev == 1) - break; - } - } + /* Allocate screen */ + pScreenInfo = xf86AllocateScreen(pDriver, 0); - /* - * 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; - - j = pATIGDev->iATIPtr; - if (j <= 0) - continue; +#ifdef XFree86LOADER - for (k = i; ++k < nATIGDev; ) - { - if (j == ATIGDevs[k].iATIPtr) + if (!xf86LoadSubModule(pScreenInfo, "atimisc")) { xf86Msg(X_ERROR, - ATI_NAME ": XF86Config Device sections \"%s\" and" - " \"%s\" may not be assigned to the same adapter." - ATI_README, pGDev->identifier, - ATIGDevs[k].pGDev->identifier); - pATIGDev->iATIPtr = ATIGDevs[k].iATIPtr = -1; + ATI_NAME ": Failed to load \"atimisc\" module.\n"); + xf86DeleteScreen(pScreenInfo->scrnIndex, 0); + continue; } - } - j = ATIGDevs[i].iATIPtr; - if (j <= 0) - continue; + xf86LoaderReqSymLists(ATISymbols, NULL); - pATI = ATIPtrs[j - 1]; +#endif - /* - * Attach adapter to XF86Config Device section and register its - * resources. - */ - if (ATIClaimBusSlot(pDriver, pATIGDev->Chipset, - pGDev, pGDev->active, pATI) < 0) - continue; + /* Attach device to screen */ + xf86AddEntityToScreen(pScreenInfo, pATI->iEntity); - if (!pGDev->active) - continue; + ATIPtrs[j - 1] = NULL; - /* Allocate screen */ - pScreenInfo = xf86AllocateScreen(pDriver, 0); + /* Fill in probe data */ + pScreenInfo->driverVersion = ATI_VERSION_CURRENT; + pScreenInfo->driverName = ATI_DRIVER_NAME; + pScreenInfo->name = ATI_NAME; + pScreenInfo->Probe = ATIProbe; + pScreenInfo->PreInit = ATIPreInit; + pScreenInfo->ScreenInit = ATIScreenInit; + pScreenInfo->SwitchMode = ATISwitchMode; + pScreenInfo->AdjustFrame = ATIAdjustFrame; + pScreenInfo->EnterVT = ATIEnterVT; + pScreenInfo->LeaveVT = ATILeaveVT; + pScreenInfo->FreeScreen = ATIFreeScreen; + pScreenInfo->ValidMode = ATIValidMode; - /* Attach device to screen */ - xf86AddEntityToScreen(pScreenInfo, pATI->iEntity); + pScreenInfo->driverPrivate = pATI; - ATIPtrs[j - 1] = NULL; + pATI->Chipset = pATIGDev->Chipset; - /* Fill in probe data */ - pScreenInfo->driverVersion = ATI_VERSION_CURRENT; - pScreenInfo->driverName = ATI_DRIVER_NAME; - pScreenInfo->name = ATI_NAME; - pScreenInfo->Probe = ATIProbe; - pScreenInfo->PreInit = ATIPreInit; - pScreenInfo->ScreenInit = ATIScreenInit; - pScreenInfo->SwitchMode = ATISwitchMode; - pScreenInfo->AdjustFrame = ATIAdjustFrame; - pScreenInfo->EnterVT = ATIEnterVT; - pScreenInfo->LeaveVT = ATILeaveVT; - pScreenInfo->FreeScreen = ATIFreeScreen; - pScreenInfo->ValidMode = ATIValidMode; + ProbeSuccess = TRUE; + } - pScreenInfo->driverPrivate = pATI; + /* Deal with unassigned adapters */ + for (i = 0; i < nATIPtr; i++) + { + if (!(pATI = ATIPtrs[i])) + continue; - pATI->Chipset = pATIGDev->Chipset; +#ifndef AVOID_CPIO - nScreen++; - } + if (pATI->Adapter > ATI_ADAPTER_VGA) - /* Deal with unassigned adapters */ - for (i = 0; i < nATIPtr; i++) - { - if (!(pATI = ATIPtrs[i])) - continue; +#endif /* AVOID_CPIO */ - if ((pATI->Adapter > ATI_ADAPTER_VGA) && (pATI->iEntity < 0)) - (void)ATIClaimBusSlot(pDriver, 0, NULL, FALSE, pATI); - xfree(pATI); + { + if (pATI->iEntity < 0) + (void)ATIClaimBusSlot(pDriver, 0, NULL, FALSE, pATI); + } + + xfree(pATI); + } + + xfree(ATIGDevs); } + xfree(ATIPtrs); - xfree(ATIGDevs); - return (nScreen != 0); + /* Call Rage 128 driver probe */ + if (DoRage128 && R128Probe(pDriver, flags)) + ProbeSuccess = TRUE; + + /* Call Radeon driver probe */ + if (DoRadeon && RADEONProbe(pDriver, flags)) + ProbeSuccess = TRUE; + + return ProbeSuccess; } |