summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2006-03-19 15:12:10 +0000
committerLuc Verhaegen <libv@skynet.be>2006-03-19 15:12:10 +0000
commit105281ceb47173f1a68b67a54c2d7623b63d6f57 (patch)
treeeabf903b0317136ef467acf053f52370e9fb653c
parentdfd1377453b0a84d8ce8df677847adfd502d895e (diff)
Move BIOS parsing out to its own functions. Take Clock handling out of the
BIOS parsing.
-rw-r--r--ChangeLog10
-rw-r--r--src/atipreinit.c793
2 files changed, 407 insertions, 396 deletions
diff --git a/ChangeLog b/ChangeLog
index d19f688..b3cc2bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2006-03-19 Luc Verhaegen <libv@skynet.be>
+ * src/atipreinit.c: (Mach64BiosPanel), (Mach64BiosClock),
+ (Mach64BIOSParse), (Mach64PreInitGetClockInfo), (ATIPreInit):
+
+ Move BIOS parsing out to its own functions.
+ Take Clock handling out of the BIOS parsing.
+
+2006-03-19 Luc Verhaegen <libv@skynet.be>
+
* src/Makefile.am:
* src/ati.c: (Mach64Probe), (Mach64Identify):
* src/atidga.c: (ATIDGAInit):
@@ -9,7 +17,7 @@
* src/atistruct.h:
Remove pATI->Chipset and move ATIIdentify to ati.c. Have
- ATIIdentify to only mention mach6.
+ ATIIdentify only mention mach64.
2006-03-17 Luc Verhaegen <libv@skynet.be>
diff --git a/src/atipreinit.c b/src/atipreinit.c
index 18a46bc..d2a9b53 100644
--- a/src/atipreinit.c
+++ b/src/atipreinit.c
@@ -559,6 +559,396 @@ Mach64ChipsetRevisions(ATIChipType Chip, CARD8 ChipRev)
}
/*
+ * For Mach64 adapters, pick up, from the BIOS, the type of programmable
+ * clock generator (if any), and various information about it.
+ */
+
+# define BIOS_SIZE 0x00010000U /* 64kB */
+# define BIOSByte(_n) ((CARD8)(BIOS[_n]))
+# define BIOSWord(_n) ((CARD16)(BIOS[_n] | \
+ (BIOS[(_n) + 1] << 8)))
+# define BIOSLong(_n) ((CARD32)(BIOS[_n] | \
+ (BIOS[(_n) + 1] << 8) | \
+ (BIOS[(_n) + 2] << 16) | \
+ (BIOS[(_n) + 3] << 24)))
+/*
+ *
+ */
+static void
+Mach64BiosPanel(ScrnInfoPtr pScrn, CARD8 *BIOS, unsigned int BIOSSize)
+{
+ ATIPtr pATI = ATIPTR(pScrn);
+ CARD16 LCDTable, LCDPanelInfo = 0;
+ int i, j;
+
+ LCDTable = BIOSWord(0x78U);
+ if ((LCDTable + BIOSByte(LCDTable + 5)) > BIOSSize)
+ LCDTable = 0;
+
+ if (LCDTable > 0) {
+ LCDPanelInfo = BIOSWord(LCDTable + 0x0AU);
+ if (((LCDPanelInfo + 0x1DU) > BIOSSize) ||
+ ((BIOSByte(LCDPanelInfo) != pATI->LCDPanelID) &&
+ (pATI->LCDPanelID || (BIOSByte(LCDPanelInfo) > 0x1FU) ||
+ (pATI->Chip <= ATI_CHIP_264LTPRO))))
+ LCDPanelInfo = 0;
+ }
+
+ if (!LCDPanelInfo) {
+ /*
+ * Scan BIOS for panel info table.
+ */
+ for (i = 0; i <= (int)(BIOSSize - 0x1DU); i++) {
+ /* Look for panel ID ... */
+ if ((BIOSByte(i) != pATI->LCDPanelID) &&
+ (pATI->LCDPanelID || (BIOSByte(i) > 0x1FU) ||
+ (pATI->Chip <= ATI_CHIP_264LTPRO)))
+ continue;
+
+ /* ... followed by 24-byte panel model name ... */
+ for (j = 0; j < 24; j++) {
+ if ((CARD8)(BIOSByte(i + j + 1) - 0x20U) > 0x5FU) {
+ i += j;
+ goto NextBIOSByte;
+ }
+ }
+
+ /* ... verify panel width ... */
+ if (pATI->LCDHorizontal &&
+ (pATI->LCDHorizontal != BIOSWord(i + 0x19U)))
+ continue;
+
+ /* ... and verify panel height */
+ if (pATI->LCDVertical &&
+ (pATI->LCDVertical != BIOSWord(i + 0x1BU)))
+ continue;
+
+ if (LCDPanelInfo) {
+ /*
+ * More than one possibility, but don't care if all
+ * tables describe panels of the same size.
+ */
+ if ((BIOSByte(LCDPanelInfo + 0x19U) ==
+ BIOSByte(i + 0x19U)) &&
+ (BIOSByte(LCDPanelInfo + 0x1AU) ==
+ BIOSByte(i + 0x1AU)) &&
+ (BIOSByte(LCDPanelInfo + 0x1BU) ==
+ BIOSByte(i + 0x1BU)) &&
+ (BIOSByte(LCDPanelInfo + 0x1CU) ==
+ BIOSByte(i + 0x1CU)))
+ continue;
+
+ LCDPanelInfo = 0;
+ break;
+ }
+
+ LCDPanelInfo = i;
+
+ NextBIOSByte: ;
+ }
+ }
+
+ if (LCDPanelInfo > 0) {
+ char Buffer[24];
+
+ pATI->LCDPanelID = BIOSByte(LCDPanelInfo);
+ pATI->LCDHorizontal = BIOSWord(LCDPanelInfo + 0x19U);
+ pATI->LCDVertical = BIOSWord(LCDPanelInfo + 0x1BU);
+
+ for (i = 0; i < 24; i++)
+ Buffer[i] = BIOSByte(LCDPanelInfo + 1 + i);
+ for (; --i >= 0; )
+ if (Buffer[i] && Buffer[i] != ' ') {
+ Buffer[i + 1] = '\0';
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel model %s.\n",
+ Buffer);
+ break;
+ }
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "BIOS Data: LCDTable=0x%04X, LCDPanelInfo=0x%04X.\n",
+ LCDTable, LCDPanelInfo);
+}
+
+static void
+Mach64BiosClock(ScrnInfoPtr pScrn, CARD8 *BIOS, unsigned int BIOSSize,
+ CARD16 Offset)
+{
+ ATIPtr pATI = ATIPTR(pScrn);
+ CARD16 ClockTable = BIOSWord(Offset + 0x10);
+ CARD16 FrequencyTable = 0;
+ int i;
+
+ if ((ClockTable + 0x20) > BIOSSize)
+ return;
+
+ FrequencyTable = BIOSWord(ClockTable - 0x02);
+ if ((FrequencyTable > 0) && ((FrequencyTable + 0x20) <= BIOSSize)) {
+ for (i = 0; i < 16; i++) {
+ pATI->BIOSClocks[i] = BIOSWord(FrequencyTable);
+ FrequencyTable += 2;
+ }
+ }
+
+ pATI->ProgrammableClock = BIOSByte(ClockTable);
+ if (pATI->ProgrammableClock == ATI_CLOCK_ICS2595)
+ pATI->ClockDescriptor.MinM =
+ pATI->ClockDescriptor.MaxM = BIOSWord(ClockTable + 0x0AU);
+
+ pATI->ClockNumberToProgramme = BIOSByte(ClockTable + 0x06);
+
+ switch (BIOSWord(ClockTable + 0x08) / 10) {
+ case 143:
+ pATI->ReferenceNumerator = 157500;
+ pATI->ReferenceDenominator = 11;
+ break;
+ case 286:
+ pATI->ReferenceNumerator = 315000;
+ pATI->ReferenceDenominator = 11;
+ break;
+ default:
+ pATI->ReferenceNumerator = BIOSWord(ClockTable + 0x08) * 10;
+ pATI->ReferenceDenominator = 1;
+ break;
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "BIOS Data: ClockTable=0x%04X, FrequencyTable=0x%04X.\n",
+ ClockTable, FrequencyTable);
+}
+
+/*
+ *
+ */
+static void
+Mach64BIOSParse(ScrnInfoPtr pScrn, CARD8 *BIOS, unsigned int BIOSSize)
+{
+ ATIPtr pATI = ATIPTR(pScrn);
+ unsigned int ROMTable = 0;
+ unsigned int VideoTable = 0;
+ unsigned int HardwareTable = 0;
+
+ ROMTable = BIOSWord(0x48U);
+ if ((ROMTable < 0x0002U) ||
+ (BIOSWord(ROMTable - 0x02U) < 0x0012U) ||
+ ((ROMTable + BIOSWord(ROMTable - 0x02U)) > BIOSSize))
+ ROMTable = 0;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "BIOS Data: Size 0x%04X, Table 0x%04X.\n",
+ BIOSSize, ROMTable);
+
+ if (ROMTable > 0) {
+ Mach64BiosClock(pScrn, BIOS, BIOSSize, ROMTable);
+
+ if (BIOSWord(ROMTable - 0x02U) >= 0x0048U) {
+ VideoTable = BIOSWord(ROMTable + 0x46U);
+ if ((VideoTable < 0x08U) ||
+ (BIOSByte(VideoTable - 0x01U) < 0x08U) ||
+ (BIOSByte(VideoTable - 0x02U) > 0x01U) ||
+ ((VideoTable + BIOSByte(VideoTable - 0x01U)) > BIOSSize))
+ VideoTable = 0;
+ }
+
+ if (BIOSWord(ROMTable - 0x02U) >= 0x004AU) {
+ HardwareTable = BIOSWord(ROMTable + 0x48U);
+ if (((HardwareTable + 0x08U) <= BIOSSize) &&
+ !memcmp(BIOS + HardwareTable, "$ATI", 4))
+ pATI->I2CType = BIOSByte(HardwareTable + 0x06U) & 0x0FU;
+ else
+ HardwareTable = 0;
+ }
+ }
+
+ /*
+ * Pick up multimedia information, which will be at different
+ * displacements depending on table revision.
+ */
+ if (VideoTable > 0) {
+ switch (BIOSByte(VideoTable - 0x02U)) {
+ case 0x00U:
+ pATI->Tuner = BIOSByte(VideoTable) & 0x1FU;
+
+ /*
+ * XXX The VideoTable[1] byte is known to have been
+ * omitted in LTPro and Mobility BIOS'es. Any others?
+ */
+ switch (pATI->Chip) {
+ case ATI_CHIP_264LTPRO:
+ case ATI_CHIP_MOBILITY:
+ pATI->Decoder = BIOSByte(VideoTable + 0x01U) & 0x07U;
+ pATI->Audio = BIOSByte(VideoTable + 0x02U) & 0x0FU;
+ break;
+ default:
+ pATI->Decoder = BIOSByte(VideoTable + 0x02U) & 0x07U;
+ pATI->Audio = BIOSByte(VideoTable + 0x03U) & 0x0FU;
+ break;
+ }
+ break;
+ case 0x01U:
+ pATI->Tuner = BIOSByte(VideoTable) & 0x1FU;
+ pATI->Audio = BIOSByte(VideoTable + 0x01U) & 0x0FU;
+ pATI->Decoder = BIOSByte(VideoTable + 0x05U) & 0x0FU;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Determine panel dimensions */
+ if (pATI->LCDPanelID >= 0)
+ Mach64BiosPanel(pScrn, BIOS, BIOSSize);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "BIOS Data: VideoTable=0x%04X, HardwareTable=0x%04X.\n",
+ VideoTable, HardwareTable);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "BIOS Data: I2CType=0x%02X, Tuner=0x%02X, Decoder=0x%02X,"
+ " Audio=0x%02X.\n",
+ pATI->I2CType, pATI->Tuner, pATI->Decoder, pATI->Audio);
+}
+
+static void
+Mach64PreInitGetClockInfo(ScrnInfoPtr pScrn, GDevPtr pGDev)
+{
+ ATIPtr pATI = ATIPTR(pScrn);
+ CARD16 ClockDac;
+
+ /*
+ * Compensate for BIOS absence. Note that the reference
+ * frequency has already been set by option processing.
+ */
+ if (pATI->ProgrammableClock > 0) {
+ if ((pATI->DAC & ~0x0FU) == ATI_DAC_INTERNAL) {
+ pATI->ProgrammableClock = ATI_CLOCK_INTERNAL;
+ } else {
+ switch (pATI->DAC) {
+ case ATI_DAC_STG1703:
+ pATI->ProgrammableClock = ATI_CLOCK_STG1703;
+ break;
+ case ATI_DAC_CH8398:
+ pATI->ProgrammableClock = ATI_CLOCK_CH8398;
+ break;
+ case ATI_DAC_ATT20C408:
+ pATI->ProgrammableClock = ATI_CLOCK_ATT20C408;
+ break;
+ case ATI_DAC_IBMRGB514:
+ pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514;
+ break;
+ default: /* Provisional */
+ pATI->ProgrammableClock = ATI_CLOCK_ICS2595;
+ break;
+ }
+ }
+
+ /* This should be safe for all generators except IBM's RGB514 */
+ pATI->ClockNumberToProgramme = 3;
+ }
+
+ if ((pATI->ProgrammableClock > ATI_CLOCK_FIXED) &&
+ (pATI->ProgrammableClock < ATI_CLOCK_MAX)) {
+ /*
+ * Graphics PRO TURBO 1600's are unusual in that an ICS2595 is used
+ * to generate clocks for VGA modes, and an IBM RGB514 is used for
+ * accelerator modes.
+ */
+ if ((pATI->ProgrammableClock == ATI_CLOCK_ICS2595) &&
+ (pATI->DAC == ATI_DAC_IBMRGB514) && (pScrn->depth >= 8))
+ pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514;
+
+ pATI->ClockDescriptor = ATIClockDescriptors[pATI->ProgrammableClock];
+ }
+
+ ClockDac = pATI->DAC;
+ switch (pATI->ProgrammableClock) {
+ case ATI_CLOCK_ICS2595:
+ /*
+ * Pick up reference divider (43 or 46) appropriate to the chip
+ * revision level.
+ */
+ if (pATI->ClockDescriptor.MinM)
+ break;
+
+ if (!xf86NameCmp(pGDev->clockchip, "ATI 18818-0"))
+ pATI->ClockDescriptor.MinM =
+ pATI->ClockDescriptor.MaxM = 43;
+ else if (!xf86NameCmp(pGDev->clockchip, "ATI 18818-1"))
+ pATI->ClockDescriptor.MinM =
+ pATI->ClockDescriptor.MaxM = 46;
+ else
+ pATI->ProgrammableClock = ATI_CLOCK_UNKNOWN;
+
+ break;
+
+ case ATI_CLOCK_STG1703:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_STG1703;
+ break;
+
+ case ATI_CLOCK_CH8398:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_CH8398;
+ break;
+
+ case ATI_CLOCK_INTERNAL:
+ /*
+ * The reference divider has already been programmed by BIOS
+ * initialisation. Because, there is only one reference
+ * divider for all generated frequencies (including MCLK), it
+ * cannot be changed without reprogramming all clocks every
+ * time one of them needs a different reference divider.
+ *
+ * Besides, it's not a good idea to change the reference
+ * divider. BIOS initialisation sets it to a value that
+ * effectively prevents generating frequencies beyond the
+ * graphics controller's tolerance.
+ */
+ pATI->ClockDescriptor.MinM = pATI->ClockDescriptor.MaxM =
+ ATIMach64GetPLLReg(PLL_REF_DIV);
+
+ /* The DAC is also integrated */
+ if ((pATI->DAC & ~0x0FU) != ATI_DAC_INTERNAL)
+ ClockDac = ATI_DAC_INTERNAL;
+
+ break;
+
+ case ATI_CLOCK_ATT20C408:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_ATT20C408;
+ break;
+
+ case ATI_CLOCK_IBMRGB514:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_IBMRGB514;
+ pATI->ClockNumberToProgramme = 7;
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * We now have up to two indications of what RAMDAC the adapter uses.
+ * They should be the same. The following test and corresponding
+ * action are under construction.
+ */
+ if (pATI->DAC != ClockDac) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mach64 RAMDAC probe discrepancy detected:\n"
+ " DAC=0x%02X; ClockDac=0x%02X.\n",
+ pATI->DAC, ClockDac);
+
+ if (pATI->DAC == ATI_DAC_IBMRGB514) {
+ pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514;
+ pATI->ClockDescriptor = ATIClockDescriptors[ATI_CLOCK_IBMRGB514];
+ pATI->ClockNumberToProgramme = 7;
+ } else
+ pATI->DAC = ClockDac; /* For now */
+ }
+}
+
+/*
* ATIReportMemory --
*
* This function reports on the amount and type of video memory found.
@@ -651,26 +1041,8 @@ ATIPrintNoiseIfRequested
* server generation.
*/
_X_EXPORT Bool
-ATIPreInit
-(
- ScrnInfoPtr pScreenInfo,
- int flags
-)
+ATIPreInit(ScrnInfoPtr pScreenInfo, int flags)
{
-# define BIOS_SIZE 0x00010000U /* 64kB */
- CARD8 BIOS[BIOS_SIZE];
-# define BIOSByte(_n) ((CARD8)(BIOS[_n]))
-# define BIOSWord(_n) ((CARD16)(BIOS[_n] | \
- (BIOS[(_n) + 1] << 8)))
-# define BIOSLong(_n) ((CARD32)(BIOS[_n] | \
- (BIOS[(_n) + 1] << 8) | \
- (BIOS[(_n) + 2] << 16) | \
- (BIOS[(_n) + 3] << 24)))
- unsigned int BIOSSize = 0;
- unsigned int ROMTable = 0, ClockTable = 0, FrequencyTable = 0;
- unsigned int LCDTable = 0, LCDPanelInfo = 0, VideoTable = 0;
- unsigned int HardwareTable = 0;
-
char Buffer[128], *Message;
ATIPtr pATI;
GDevPtr pGDev;
@@ -691,6 +1063,9 @@ ATIPreInit
LookupModeFlags Strategy = LOOKUP_CLOSEST_CLOCK;
int DefaultDepth;
+ CARD8 BIOS[BIOS_SIZE];
+ unsigned int BIOSSize = 0;
+
# define pATIHW (&pATI->OldHW)
#ifndef AVOID_CPIO
@@ -1289,372 +1664,14 @@ ATIPreInit
#endif /* AVOID_CPIO */
{
- CARD16 ClockDac;
-
/* Set up non-zero defaults */
pATI->ClockDescriptor = ATIClockDescriptors[ATI_CLOCK_FIXED];
pATI->ClockNumberToProgramme = -1;
+ pATI->ProgrammableClock = -1;
- ROMTable = BIOSWord(0x48U);
- if ((ROMTable < 0x0002U) ||
- (BIOSWord(ROMTable - 0x02U) < 0x0012U) ||
- ((ROMTable + BIOSWord(ROMTable - 0x02U)) > BIOSSize))
- ROMTable = 0;
-
- if (ROMTable > 0)
- {
- ClockTable = BIOSWord(ROMTable + 0x10U);
- if ((ClockTable + 0x20U) > BIOSSize)
- ClockTable = 0;
-
- if (BIOSWord(ROMTable - 0x02U) >= 0x0048U)
- {
- VideoTable = BIOSWord(ROMTable + 0x46U);
- if ((VideoTable < 0x08U) ||
- (BIOSByte(VideoTable - 0x01U) < 0x08U) ||
- (BIOSByte(VideoTable - 0x02U) > 0x01U) ||
- ((VideoTable + BIOSByte(VideoTable - 0x01U)) > BIOSSize))
- VideoTable = 0;
- }
-
- if (BIOSWord(ROMTable - 0x02U) >= 0x004AU)
- {
- HardwareTable = BIOSWord(ROMTable + 0x48U);
- if (((HardwareTable + 0x08U) <= BIOSSize) &&
- !memcmp(BIOS + HardwareTable, "$ATI", 4))
- pATI->I2CType = BIOSByte(HardwareTable + 0x06U) & 0x0FU;
- else
- HardwareTable = 0;
- }
- }
-
- if (ClockTable > 0)
- {
- FrequencyTable = BIOSWord(ClockTable - 0x02U);
- if ((FrequencyTable > 0) &&
- ((FrequencyTable + 0x20U) <= BIOSSize))
- {
- for (i = 0; i < 16; i++)
- {
- pATI->BIOSClocks[i] = BIOSWord(FrequencyTable);
- FrequencyTable += 2;
- }
- }
- pATI->ProgrammableClock = BIOSByte(ClockTable);
- pATI->ClockNumberToProgramme = BIOSByte(ClockTable + 0x06U);
- switch (BIOSWord(ClockTable + 0x08U) / 10)
- {
- case 143:
- pATI->ReferenceNumerator = 157500;
- pATI->ReferenceDenominator = 11;
- break;
-
- case 286:
- pATI->ReferenceNumerator = 315000;
- pATI->ReferenceDenominator = 11;
- break;
-
- default:
- pATI->ReferenceNumerator =
- BIOSWord(ClockTable + 0x08U) * 10;
- pATI->ReferenceDenominator = 1;
- break;
- }
- }
- else
- {
- /*
- * Compensate for BIOS absence. Note that the reference
- * frequency has already been set by option processing.
- */
- if ((pATI->DAC & ~0x0FU) == ATI_DAC_INTERNAL)
- {
- pATI->ProgrammableClock = ATI_CLOCK_INTERNAL;
- }
- else switch (pATI->DAC)
- {
- case ATI_DAC_STG1703:
- pATI->ProgrammableClock = ATI_CLOCK_STG1703;
- break;
-
- case ATI_DAC_CH8398:
- pATI->ProgrammableClock = ATI_CLOCK_CH8398;
- break;
-
- case ATI_DAC_ATT20C408:
- pATI->ProgrammableClock = ATI_CLOCK_ATT20C408;
- break;
-
- case ATI_DAC_IBMRGB514:
- pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514;
- break;
-
- default: /* Provisional */
- pATI->ProgrammableClock = ATI_CLOCK_ICS2595;
- break;
- }
-
- /* This should be safe for all generators except IBM's RGB514 */
- pATI->ClockNumberToProgramme = 3;
- }
-
- if ((pATI->ProgrammableClock > ATI_CLOCK_FIXED) &&
- (pATI->ProgrammableClock < ATI_CLOCK_MAX))
- {
- /*
- * Graphics PRO TURBO 1600's are unusual in that an ICS2595 is used
- * to generate clocks for VGA modes, and an IBM RGB514 is used for
- * accelerator modes.
- */
- if ((pATI->ProgrammableClock == ATI_CLOCK_ICS2595) &&
- (pATI->DAC == ATI_DAC_IBMRGB514) &&
- (pScreenInfo->depth >= 8))
- pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514;
-
- pATI->ClockDescriptor =
- ATIClockDescriptors[pATI->ProgrammableClock];
- }
-
- ClockDac = pATI->DAC;
- switch (pATI->ProgrammableClock)
- {
- case ATI_CLOCK_ICS2595:
- /*
- * Pick up reference divider (43 or 46) appropriate to the chip
- * revision level.
- */
- if (ClockTable > 0)
- pATI->ClockDescriptor.MinM =
- pATI->ClockDescriptor.MaxM =
- BIOSWord(ClockTable + 0x0AU);
- else if (!xf86NameCmp(pGDev->clockchip, "ATI 18818-0"))
- pATI->ClockDescriptor.MinM =
- pATI->ClockDescriptor.MaxM = 43;
- else if (!xf86NameCmp(pGDev->clockchip, "ATI 18818-1"))
- pATI->ClockDescriptor.MinM =
- pATI->ClockDescriptor.MaxM = 46;
- else
- pATI->ProgrammableClock = ATI_CLOCK_UNKNOWN;
- break;
-
- case ATI_CLOCK_STG1703:
- /* This one's also a RAMDAC */
- ClockDac = ATI_DAC_STG1703;
- break;
-
- case ATI_CLOCK_CH8398:
- /* This one's also a RAMDAC */
- ClockDac = ATI_DAC_CH8398;
- break;
-
- case ATI_CLOCK_INTERNAL:
- /*
- * The reference divider has already been programmed by BIOS
- * initialisation. Because, there is only one reference
- * divider for all generated frequencies (including MCLK), it
- * cannot be changed without reprogramming all clocks every
- * time one of them needs a different reference divider.
- *
- * Besides, it's not a good idea to change the reference
- * divider. BIOS initialisation sets it to a value that
- * effectively prevents generating frequencies beyond the
- * graphics controller's tolerance.
- */
- pATI->ClockDescriptor.MinM = pATI->ClockDescriptor.MaxM =
- ATIMach64GetPLLReg(PLL_REF_DIV);
-
- /* The DAC is also integrated */
- if ((pATI->DAC & ~0x0FU) != ATI_DAC_INTERNAL)
- ClockDac = ATI_DAC_INTERNAL;
-
- break;
-
- case ATI_CLOCK_ATT20C408:
- /* This one's also a RAMDAC */
- ClockDac = ATI_DAC_ATT20C408;
- break;
-
- case ATI_CLOCK_IBMRGB514:
- /* This one's also a RAMDAC */
- ClockDac = ATI_DAC_IBMRGB514;
- pATI->ClockNumberToProgramme = 7;
- break;
-
- default:
- break;
- }
-
- /*
- * We now have up to two indications of what RAMDAC the adapter uses.
- * They should be the same. The following test and corresponding
- * action are under construction.
- */
- if (pATI->DAC != ClockDac)
- {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
- "Mach64 RAMDAC probe discrepancy detected:\n"
- " DAC=0x%02X; ClockDac=0x%02X.\n",
- pATI->DAC, ClockDac);
-
- if (pATI->DAC == ATI_DAC_IBMRGB514)
- {
- pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514;
- pATI->ClockDescriptor =
- ATIClockDescriptors[ATI_CLOCK_IBMRGB514];
- pATI->ClockNumberToProgramme = 7;
- }
- else
- {
- pATI->DAC = ClockDac; /* For now */
- }
- }
-
- /*
- * Pick up multimedia information, which will be at different
- * displacements depending on table revision.
- */
- if (VideoTable > 0)
- {
- switch (BIOSByte(VideoTable - 0x02U))
- {
- case 0x00U:
- pATI->Tuner = BIOSByte(VideoTable) & 0x1FU;
-
- /*
- * XXX The VideoTable[1] byte is known to have been
- * omitted in LTPro and Mobility BIOS'es. Any others?
- */
- switch (pATI->Chip)
- {
- case ATI_CHIP_264LTPRO:
- case ATI_CHIP_MOBILITY:
- pATI->Decoder =
- BIOSByte(VideoTable + 0x01U) & 0x07U;
- pATI->Audio =
- BIOSByte(VideoTable + 0x02U) & 0x0FU;
- break;
-
- default:
- pATI->Decoder =
- BIOSByte(VideoTable + 0x02U) & 0x07U;
- pATI->Audio =
- BIOSByte(VideoTable + 0x03U) & 0x0FU;
- break;
- }
-
- break;
-
- case 0x01U:
- pATI->Tuner = BIOSByte(VideoTable) & 0x1FU;
- pATI->Audio = BIOSByte(VideoTable + 0x01U) & 0x0FU;
- pATI->Decoder = BIOSByte(VideoTable + 0x05U) & 0x0FU;
- break;
-
- default:
- break;
- }
- }
-
- /* Determine panel dimensions */
- if (pATI->LCDPanelID >= 0)
- {
- LCDTable = BIOSWord(0x78U);
- if ((LCDTable + BIOSByte(LCDTable + 5)) > BIOSSize)
- LCDTable = 0;
-
- if (LCDTable > 0)
- {
- LCDPanelInfo = BIOSWord(LCDTable + 0x0AU);
- if (((LCDPanelInfo + 0x1DU) > BIOSSize) ||
- ((BIOSByte(LCDPanelInfo) != pATI->LCDPanelID) &&
- (pATI->LCDPanelID || (BIOSByte(LCDPanelInfo) > 0x1FU) ||
- (pATI->Chip <= ATI_CHIP_264LTPRO))))
- LCDPanelInfo = 0;
- }
-
- if (!LCDPanelInfo)
- {
- /*
- * Scan BIOS for panel info table.
- */
- for (i = 0; i <= (int)(BIOSSize - 0x1DU); i++)
- {
- /* Look for panel ID ... */
- if ((BIOSByte(i) != pATI->LCDPanelID) &&
- (pATI->LCDPanelID || (BIOSByte(i) > 0x1FU) ||
- (pATI->Chip <= ATI_CHIP_264LTPRO)))
- continue;
-
- /* ... followed by 24-byte panel model name ... */
- for (j = 0; j < 24; j++)
- {
- if ((CARD8)(BIOSByte(i + j + 1) - 0x20U) > 0x5FU)
- {
- i += j;
- goto NextBIOSByte;
- }
- }
-
- /* ... verify panel width ... */
- if (pATI->LCDHorizontal &&
- (pATI->LCDHorizontal != BIOSWord(i + 0x19U)))
- continue;
-
- /* ... and verify panel height */
- if (pATI->LCDVertical &&
- (pATI->LCDVertical != BIOSWord(i + 0x1BU)))
- continue;
-
- if (LCDPanelInfo)
- {
- /*
- * More than one possibility, but don't care if all
- * tables describe panels of the same size.
- */
- if ((BIOSByte(LCDPanelInfo + 0x19U) ==
- BIOSByte(i + 0x19U)) &&
- (BIOSByte(LCDPanelInfo + 0x1AU) ==
- BIOSByte(i + 0x1AU)) &&
- (BIOSByte(LCDPanelInfo + 0x1BU) ==
- BIOSByte(i + 0x1BU)) &&
- (BIOSByte(LCDPanelInfo + 0x1CU) ==
- BIOSByte(i + 0x1CU)))
- continue;
-
- LCDPanelInfo = 0;
- break;
- }
-
- LCDPanelInfo = i;
-
- NextBIOSByte: ;
- }
- }
-
- if (LCDPanelInfo > 0)
- {
- pATI->LCDPanelID = BIOSByte(LCDPanelInfo);
- pATI->LCDHorizontal = BIOSWord(LCDPanelInfo + 0x19U);
- pATI->LCDVertical = BIOSWord(LCDPanelInfo + 0x1BU);
- }
- }
-
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3,
- "BIOS Data: BIOSSize=0x%04X, ROMTable=0x%04X.\n",
- BIOSSize, ROMTable);
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3,
- "BIOS Data: ClockTable=0x%04X, FrequencyTable=0x%04X.\n",
- ClockTable, FrequencyTable);
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3,
- "BIOS Data: LCDTable=0x%04X, LCDPanelInfo=0x%04X.\n",
- LCDTable, LCDPanelInfo);
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3,
- "BIOS Data: VideoTable=0x%04X, HardwareTable=0x%04X.\n",
- VideoTable, HardwareTable);
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3,
- "BIOS Data: I2CType=0x%02X, Tuner=0x%02X, Decoder=0x%02X,"
- " Audio=0x%02X.\n",
- pATI->I2CType, pATI->Tuner, pATI->Decoder, pATI->Audio);
+ Mach64BIOSParse(pScreenInfo, BIOS, BIOSSize);
+
+ Mach64PreInitGetClockInfo(pScreenInfo, pGDev);
}
ATIUnlock(pATI); /* Unlock registers */
@@ -2520,20 +2537,6 @@ ATIPreInit
"%dx%d panel detected.\n",
pATI->LCDHorizontal, pATI->LCDVertical);
- if (LCDPanelInfo)
- {
- for (i = 0; i < 24; i++)
- Buffer[i] = BIOSByte(LCDPanelInfo + 1 + i);
- for (; --i >= 0; )
- if (Buffer[i] && Buffer[i] != ' ')
- {
- Buffer[i + 1] = '\0';
- xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
- "Panel model %s.\n", Buffer);
- break;
- }
- }
-
/*
* Determine panel clock. This must be done after option
* processing so that the adapter's reference frequency is always