diff options
author | Luc Verhaegen <libv@skynet.be> | 2006-03-19 15:12:10 +0000 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2006-03-19 15:12:10 +0000 |
commit | 105281ceb47173f1a68b67a54c2d7623b63d6f57 (patch) | |
tree | eabf903b0317136ef467acf053f52370e9fb653c | |
parent | dfd1377453b0a84d8ce8df677847adfd502d895e (diff) |
Move BIOS parsing out to its own functions. Take Clock handling out of the
BIOS parsing.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | src/atipreinit.c | 793 |
2 files changed, 407 insertions, 396 deletions
@@ -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 |