summaryrefslogtreecommitdiff
path: root/src/aticlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/aticlock.c')
-rw-r--r--src/aticlock.c992
1 files changed, 8 insertions, 984 deletions
diff --git a/src/aticlock.c b/src/aticlock.c
index 05c3a6d5..2aa65c48 100644
--- a/src/aticlock.c
+++ b/src/aticlock.c
@@ -21,157 +21,6 @@
*/
/*
- * Adapters prior to V5 use 4 crystals. Adapters V5 and later use a clock
- * generator chip. V3 and V4 adapters differ when it comes to choosing clock
- * frequencies.
- *
- * VGA Wonder V3/V4 Adapter Clock Frequencies
- * R E G I S T E R S
- * 1CE(*) 3C2 3C2 Frequency
- * B2h/BEh
- * Bit 6/4 Bit 3 Bit 2 (MHz)
- * ------- ------- ------- -------
- * 0 0 0 50.000
- * 0 0 1 56.644
- * 0 1 0 Spare 1
- * 0 1 1 44.900
- * 1 0 0 44.900
- * 1 0 1 50.000
- * 1 1 0 Spare 2
- * 1 1 1 36.000
- *
- * (*): V3 uses index B2h, bit 6; V4 uses index BEh, bit 4
- *
- * V5, PLUS, XL and XL24 usually have an ATI 18810 clock generator chip, but
- * some have an ATI 18811-0, and it's quite conceivable that some exist with
- * ATI 18811-1's or ATI 18811-2's. Mach32 adapters are known to use any one of
- * these clock generators. Mach32 adapters also use a different dot clock
- * ordering. ATI says there is no reliable way for the driver to determine
- * which clock generator is on the adapter, but this driver will do its best to
- * do so anyway.
- *
- * VGA Wonder V5/PLUS/XL/XL24 Clock Frequencies
- * R E G I S T E R S
- * 1CE 1CE 3C2 3C2 Frequency
- * B9h BEh (MHz) 18811-0 18811-1
- * Bit 1 Bit 4 Bit 3 Bit 2 18810 18812-0 18811-2 (*5)
- * ------- ------- ------- ------- ------- ------- ------- -------
- * 0 0 0 0 30.240 30.240 135.000 75.000
- * 0 0 0 1 32.000 32.000 32.000 77.500
- * 0 0 1 0 37.500 110.000 110.000 80.000
- * 0 0 1 1 39.000 80.000 80.000 90.000
- * 0 1 0 0 42.954 42.954 100.000 25.175
- * 0 1 0 1 48.771 48.771 126.000 28.322
- * 0 1 1 0 (*1) 92.400 92.400 31.500
- * 0 1 1 1 36.000 36.000 36.000 36.000
- * 1 0 0 0 40.000 39.910 39.910 100.000
- * 1 0 0 1 (*4) 44.900 44.900 110.000
- * 1 0 1 0 75.000 75.000 75.000 126.000
- * 1 0 1 1 65.000 65.000 65.000 135.000
- * 1 1 0 0 50.350 50.350 50.350 40.000
- * 1 1 0 1 56.640 56.640 56.640 44.900
- * 1 1 1 0 (*2) (*3) (*3) 50.000
- * 1 1 1 1 44.900 44.900 44.900 65.000
- *
- * (*1) External 0 (supposedly 16.657 Mhz)
- * (*2) External 1 (supposedly 28.322 MHz)
- * (*3) This setting doesn't seem to generate anything
- * (*4) This setting is documented to be 56.644 MHz, but something close to 82
- * MHz has also been encountered.
- * (*5) This setting is for Dell OmniPlex 590 systems, with a 68800AX on the
- * motherboard, along with an AT&T21C498 DAC (which is reported as an
- * STG1700) and ICS2494AM clock generator (a.k.a. ATI 18811-?).
- *
- * Mach32 Clock Frequencies
- * R E G I S T E R S
- * 1CE 1CE 3C2 3C2 Frequency
- * B9h BEh (MHz) 18811-0 18811-1
- * Bit 1 Bit 4 Bit 3 Bit 2 18810 18812-0 18811-2 (*5)
- * ------- ------- ------- ------- ------- ------- ------- -------
- * 0 0 0 0 42.954 42.954 100.000 25.175
- * 0 0 0 1 48.771 48.771 126.000 28.322
- * 0 0 1 0 (*1) 92.400 92.400 31.500
- * 0 0 1 1 36.000 36.000 36.000 36.000
- * 0 1 0 0 30.240 30.240 135.000 75.000
- * 0 1 0 1 32.000 32.000 32.000 77.500
- * 0 1 1 0 37.500 110.000 110.000 80.000
- * 0 1 1 1 39.000 80.000 80.000 90.000
- * 1 0 0 0 50.350 50.350 50.350 40.000
- * 1 0 0 1 56.640 56.640 56.640 44.900
- * 1 0 1 0 (*2) (*3) (*3) 50.000
- * 1 0 1 1 44.900 44.900 44.900 65.000
- * 1 1 0 0 40.000 39.910 39.910 100.000
- * 1 1 0 1 (*4) 44.900 44.900 110.000
- * 1 1 1 0 75.000 75.000 75.000 126.000
- * 1 1 1 1 65.000 65.000 65.000 135.000
- *
- * (*1) External 0 (supposedly 16.657 Mhz)
- * (*2) External 1 (supposedly 28.322 MHz)
- * (*3) This setting doesn't seem to generate anything
- * (*4) This setting is documented to be 56.644 MHz, but something close to 82
- * MHz has also been encountered.
- * (*5) This setting is for Dell OmniPlex 590 systems, with a 68800AX on the
- * motherboard, along with an AT&T21C498 DAC (which is reported as an
- * STG1700) and ICS2494AM clock generator (a.k.a. ATI 18811-?).
- *
- * Note that, to reduce confusion, this driver masks out the different clock
- * ordering.
- *
- * For all adapters, these frequencies can be divided by 1 or 2. For all
- * adapters, except Mach32's and Mach64's, frequencies can also be divided by 3
- * or 4.
- *
- * Register 1CE, index B8h
- * Bit 7 Bit 6
- * ------- -------
- * 0 0 Divide by 1
- * 0 1 Divide by 2
- * 1 0 Divide by 3
- * 1 1 Divide by 4
- *
- * With respect to clocks, Mach64's are entirely different animals.
- *
- * The oldest Mach64's use one of the non-programmable clock generators
- * described above. In this case, the driver will handle clocks in much the
- * same way as it would for a Mach32.
- *
- * All other Mach64 adapters use a programmable clock generator. BIOS
- * initialisation programmes an initial set of frequencies. Two of these are
- * reserved to allow for the setting of modes that do not use a frequency from
- * this initial set. One of these reserved slots is used by the BIOS mode set
- * routine, the other by the particular accelerated driver used (MS-Windows,
- * AutoCAD, etc.). The slots reserved in this way are dependent on the
- * particular clock generator used by the adapter.
- *
- * If the driver does not support the adapter's clock generator, it will try to
- * match the (probed or specified) clocks to one of the following sets.
- *
- * Mach64 Clock Frequencies for unsupported programmable clock generators
- * R E G I S T E R S
- * 1CE 1CE 3C2 3C2 Frequency
- * B9h BEh (MHz)
- * Bit 1 Bit 4 Bit 3 Bit 2 Set 1 Set 2 Set 3
- * ------- ------- ------- ------- ------- ------- -------
- * 0 0 0 0 50.350 25.180 25.180
- * 0 0 0 1 56.640 28.320 28.320
- * 0 0 1 0 63.000 31.500 0.000
- * 0 0 1 1 72.000 36.000 0.000
- * 0 1 0 0 0.000 0.000 0.000
- * 0 1 0 1 110.000 110.000 0.000
- * 0 1 1 0 126.000 126.000 0.000
- * 0 1 1 1 135.000 135.000 0.000
- * 1 0 0 0 40.000 40.000 0.000
- * 1 0 0 1 44.900 44.900 0.000
- * 1 0 1 0 49.500 49.500 0.000
- * 1 0 1 1 50.000 50.000 0.000
- * 1 1 0 0 0.000 0.000 0.000
- * 1 1 0 1 80.000 80.000 0.000
- * 1 1 1 0 75.000 75.000 0.000
- * 1 1 1 1 65.000 65.000 0.000
- *
- * The driver will never select a setting of 0.000 MHz. The above comments on
- * clock ordering and clock divider apply here also.
- *
* For all supported programmable clock generators, the driver will ignore any
* XF86Config clock line and programme, as needed, the clock number reserved by
* the BIOS for accelerated drivers. The driver's mode initialisation routine
@@ -205,23 +54,6 @@
#include "atiwonderio.h"
/*
- * Definitions related to non-programmable clock generators.
- */
-const char *ATIClockNames[] =
-{
- "unknown",
- "IBM VGA compatible",
- "crystals",
- "ATI 18810 or similar",
- "ATI 18811-0 or similar",
- "ATI 18811-1 or similar",
- "ICS 2494-AM or similar",
- "Programmable (BIOS setting 1)",
- "Programmable (BIOS setting 2)",
- "Programmable (BIOS setting 3)"
-};
-
-/*
* Definitions related to programmable clock generators.
*/
static CARD16 ATIPostDividers[] = {1, 2, 4, 8, 16, 32, 64, 128},
@@ -273,239 +105,6 @@ ClockRec ATIClockDescriptors[] =
};
/*
- * XF86Config clocks line that start with the following will either be rejected
- * for ATI adapters, or accepted for non-ATI adapters.
- */
-static const int
-ATIVGAClocks[] =
-{
- 25175, 28322,
- -1
-};
-
-/*
- * The driver will attempt to match fixed clocks to one of the following
- * specifications.
- */
-static const int
-ATICrystalFrequencies[] =
-{
- 50000, 56644, 0, 44900, 44900, 50000, 0, 36000,
- -1
-},
-ATI18810Frequencies[] =
-{
- 30240, 32000, 37500, 39000, 42954, 48771, 0, 36000,
- 40000, 0, 75000, 65000, 50350, 56640, 0, 44900
-},
-ATI188110Frequencies[] =
-{
- 30240, 32000, 110000, 80000, 42954, 48771, 92400, 36000,
- 39910, 44900, 75000, 65000, 50350, 56640, 0, 44900
-},
-ATI188111Frequencies[] =
-{
- 135000, 32000, 110000, 80000, 100000, 126000, 92400, 36000,
- 39910, 44900, 75000, 65000, 50350, 56640, 0, 44900
-},
-ATI2494AMFrequencies[] =
-{
- 75000, 77500, 80000, 90000, 25175, 28322, 31500, 36000,
- 100000, 110000, 126000, 135000, 40000, 44900, 50000, 65000
-},
-ATIMach64AFrequencies[] =
-{
- 0, 110000, 126000, 135000, 50350, 56640, 63000, 72000,
- 0, 80000, 75000, 65000, 40000, 44900, 49500, 50000
-},
-ATIMach64BFrequencies[] =
-{
- 0, 110000, 126000, 135000, 25180, 28320, 31500, 36000,
- 0, 80000, 75000, 65000, 40000, 44900, 49500, 50000
-},
-ATIMach64CFrequencies[] =
-{
- 0, 0, 0, 0, 25180, 28320, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
-},
-*SpecificationClockLine[] =
-{
- NULL,
- ATIVGAClocks,
- ATICrystalFrequencies,
- ATI18810Frequencies,
- ATI188110Frequencies,
- ATI188111Frequencies,
- ATI2494AMFrequencies,
- ATIMach64AFrequencies,
- ATIMach64BFrequencies,
- ATIMach64CFrequencies,
- NULL
-};
-
-/*
- * The driver will reject XF86Config clocks lines that start with, or are an
- * initial subset of, one of the following.
- */
-static const int
-ATIPre_2_1_1_Clocks_A[] = /* Based on 18810 */
-{
- 18000, 22450, 25175, 28320, 36000, 44900, 50350, 56640,
- 30240, 32000, 37500, 39000, 40000, 0, 75000, 65000,
- -1
-},
-ATIPre_2_1_1_Clocks_B[] = /* Based on 18811-0 */
-{
- 18000, 22450, 25175, 28320, 36000, 44900, 50350, 56640,
- 30240, 32000, 110000, 80000, 39910, 44900, 75000, 65000,
- -1
-},
-ATIPre_2_1_1_Clocks_C[] = /* Based on 18811-1 (or -2) */
-{
- 18000, 22450, 25175, 28320, 36000, 44900, 50350, 56640,
- 135000, 32000, 110000, 80000, 39910, 44900, 75000, 65000,
- -1
-},
-ATIPre_2_1_1_Clocks_D[] = /* Based on ICS 2494AM */
-{
- 18000, 32500, 20000, 22450, 36000, 65000, 40000, 44900,
- 75000, 77500, 80000, 90000, 100000, 110000, 126000, 135000,
- -1
-},
-ATIPre_2_1_1_Clocks_E[] = /* Based on programmable setting 1 */
-{
- 36000, 25000, 20000, 22450, 72000, 50000, 40000, 44900,
- 0, 110000, 126000, 135000, 0, 80000, 75000, 65000,
- -1
-},
-ATIPre_2_1_1_Clocks_F[] = /* Based on programmable setting 2 */
-{
- 18000, 25000, 20000, 22450, 36000, 50000, 40000, 44900,
- 0, 110000, 126000, 135000, 0, 80000, 75000, 65000,
- -1
-},
-*InvalidClockLine[] =
-{
- NULL,
- ATIVGAClocks,
- ATIPre_2_1_1_Clocks_A,
- ATIPre_2_1_1_Clocks_B,
- ATIPre_2_1_1_Clocks_C,
- ATIPre_2_1_1_Clocks_D,
- ATIPre_2_1_1_Clocks_E,
- ATIPre_2_1_1_Clocks_F,
- NULL
-};
-
-/*
- * Clock maps.
- */
-static const CARD8 ClockMaps[][4] =
-{
- /* Null map */
- { 0, 1, 2, 3},
- /* VGA Wonder map <-> Mach{8,32,64} */
- { 1, 0, 3, 2},
- /* VGA Wonder map <-> Accelerator */
- { 0, 2, 1, 3},
- /* VGA -> Accelerator map */
- { 2, 0, 3, 1},
- /* Accelerator -> VGA map */
- { 1, 3, 0, 2}
-};
-#define ATIVGAWonderClockMap ClockMaps[0]
-#define ATIVGAWonderClockUnmap ATIVGAWonderClockMap
-#define ATIMachVGAClockMap ClockMaps[1]
-#define ATIMachVGAClockUnmap ATIMachVGAClockMap
-#define ATIVGAProgrammableClockMap ClockMaps[2]
-#define ATIVGAProgrammableClockUnmap ATIVGAProgrammableClockMap
-#define ATIAcceleratorClockMap ClockMaps[3]
-#define ATIAcceleratorClockUnmap ClockMaps[4]
-#define ATIProgrammableClockMap ClockMaps[0]
-#define ATIProgrammableClockUnmap ATIProgrammableClockMap
-#define MapClockIndex(_ClockMap, _Index) \
- (SetBits((_ClockMap)[GetBits(_Index, 0x0CU)], 0x0CU) | \
- ((_Index) & ~0x0CU))
-
-/*
- * ATIMatchClockLine --
- *
- * This function tries to match the XF86Config clocks to one of an array of
- * clock lines. It returns a clock line number or 0.
- */
-static int
-ATIMatchClockLine
-(
- ScrnInfoPtr pScreenInfo,
- ATIPtr pATI,
- const int **ClockLine,
- const unsigned short int NumberOfClocks,
- const int CalibrationClockNumber,
- const int ClockMap
-)
-{
- int ClockChip = 0, ClockChipIndex = 0;
- int NumberOfMatchingClocks = 0;
- int MinimumGap = CLOCK_TOLERANCE + 1;
-
- /* For ATI adapters, reject generic VGA clocks */
- {
- if (ClockLine == SpecificationClockLine)
- ClockChipIndex++;
- }
-
- /* If checking for XF86Config clock order, skip crystals */
- if (ClockMap)
- ClockChipIndex++;
-
- for (; ClockLine[++ClockChipIndex]; )
- {
- int MaximumGap = 0, ClockCount = 0, ClockIndex = 0;
-
- for (; ClockIndex < NumberOfClocks; ClockIndex++)
- {
- int Gap, XF86ConfigClock, SpecificationClock;
-
- SpecificationClock = ClockLine[ClockChipIndex]
- [MapClockIndex(ClockMaps[ClockMap], ClockIndex)];
- if (SpecificationClock < 0)
- break;
- if (!SpecificationClock)
- continue;
-
- XF86ConfigClock = pScreenInfo->clock[ClockIndex];
- if (!XF86ConfigClock)
- continue;
-
- Gap = abs(XF86ConfigClock - SpecificationClock);
- if (Gap >= MinimumGap)
- goto SkipThisClockGenerator;
- if (!Gap)
- {
- if (ClockIndex == CalibrationClockNumber)
- continue;
- }
- else if (Gap > MaximumGap)
- {
- MaximumGap = Gap;
- }
- ClockCount++;
- }
-
- if (ClockCount <= NumberOfMatchingClocks)
- continue;
- NumberOfMatchingClocks = ClockCount;
- ClockChip = ClockChipIndex;
- if (!(MinimumGap = MaximumGap))
- break;
-
-SkipThisClockGenerator:;
- }
-
- return ClockChip;
-}
-
-/*
* ATIClockPreInit --
*
* This function is called by ATIPreInit() and handles the XF86Config clocks
@@ -515,60 +114,16 @@ void
ATIClockPreInit
(
ScrnInfoPtr pScreenInfo,
- ATIPtr pATI,
- GDevPtr pGDev,
- ClockRangePtr pRange
+ ATIPtr pATI
)
{
- double ScaleFactor;
- unsigned short int NumberOfUndividedClocks;
- unsigned short int NumberOfDividers, NumberOfClocks;
- int CalibrationClockNumber, CalibrationClockValue;
- int ClockIndex, SpecificationClock, ClockMap = 0, Index;
- CARD8 CanDisableInterrupts;
-
-#ifndef AVOID_CPIO
-
- CARD8 genmo;
-
-#endif /* AVOID_CPIO */
-
- /*
- * Decide what to do about the XF86Config clocks for programmable clock
- * generators.
- */
- if (pATI->ProgrammableClock != ATI_CLOCK_FIXED)
- {
- /* Check for those that are not (yet) handled */
- if ((pATI->ProgrammableClock == ATI_CLOCK_UNKNOWN) ||
- (pATI->ProgrammableClock > NumberOf(ATIClockDescriptors)))
- {
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
- "Unknown programmable clock generator type (0x%02X)"
- " detected.\n", pATI->ProgrammableClock);
- }
- else if (pATI->ClockDescriptor.MaxN <= 0)
- {
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
- "Unsupported programmable clock generator detected: %s.\n",
- pATI->ClockDescriptor.ClockName);
- }
- else
- {
/*
* Recognise supported clock generators. This involves telling the
* rest of the server about it and (re-)initializing the XF86Config
* clocks line.
*/
- pRange->clockIndex = -1;
pScreenInfo->progClock = TRUE;
- /* Set internal clock ordering */
- {
- pATI->NewHW.ClockMap = ATIProgrammableClockMap;
- pATI->NewHW.ClockUnmap = ATIProgrammableClockUnmap;
- }
-
xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
"%s programmable clock generator detected.\n",
pATI->ClockDescriptor.ClockName);
@@ -584,11 +139,6 @@ ATIClockPreInit
(double)pATI->ReferenceNumerator /
((double)pATI->ReferenceDenominator * 1000.0));
- /* Clobber XF86Config clocks line */
- if (pGDev->numclocks)
- xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
- "XF86Config clocks specification ignored.\n");
-
if (pATI->ProgrammableClock == ATI_CLOCK_CH8398)
{ /* First two are fixed */
pScreenInfo->numClocks = 2;
@@ -603,531 +153,6 @@ ATIClockPreInit
*/
pATI->ReferenceNumerator <<= 1;
}
-
- return; /* ... to ATIPreInit() */
- }
- }
-
-#ifndef AVOID_CPIO
-
- /* Set default clock maps */
- pATI->NewHW.ClockMap = ATIVGAWonderClockMap;
- pATI->NewHW.ClockUnmap = ATIVGAWonderClockUnmap;
-
-#endif /* AVOID_CPIO */
-
- /*
- * Determine the number of clock values the adapter should be able to
- * generate and the dot clock to use for probe calibration.
- */
-ProbeClocks:
-
- {
- if (pATI->Chip >= ATI_CHIP_264CT)
- {
- NumberOfDividers = 1;
- NumberOfUndividedClocks = 4;
- CalibrationClockNumber = 1;
- CalibrationClockValue = 28322;
- }
- else
- {
- NumberOfDividers = 2;
- NumberOfUndividedClocks = 16;
- CalibrationClockNumber = 10 /* or 11 */;
- CalibrationClockValue = 75000 /* or 65000 */;
- }
-
- /*
- * When selecting clocks, all ATI accelerators use a different
- * clock ordering.
- */
- {
- pATI->NewHW.ClockMap = ATIAcceleratorClockMap;
- pATI->NewHW.ClockUnmap = ATIAcceleratorClockUnmap;
- }
- }
-
- pATI->OldHW.ClockMap = pATI->NewHW.ClockMap;
- pATI->OldHW.ClockUnmap = pATI->NewHW.ClockUnmap;
-
- NumberOfClocks = NumberOfUndividedClocks * NumberOfDividers;
-
- /*
- * Respect any XF86Config clocks line. Well, that's the theory, anyway.
- * In practice, however, the regular use of probed values is widespread, at
- * times causing otherwise inexplicable results. So, attempt to normalise
- * the clocks to known (i.e. specification) values.
- */
- if (!pGDev->numclocks || pATI->OptionProbeClocks ||
- xf86ServerIsOnlyProbing())
- {
- if (pATI->ProgrammableClock != ATI_CLOCK_FIXED)
- {
- /*
- * For unsupported programmable clock generators, pick the highest
- * frequency set by BIOS initialisation for clock calibration.
- */
- CalibrationClockNumber = CalibrationClockValue = 0;
- for (ClockIndex = 0;
- ClockIndex < NumberOfUndividedClocks;
- ClockIndex++)
- {
- if (CalibrationClockValue < pATI->BIOSClocks[ClockIndex])
- {
- CalibrationClockNumber = ClockIndex;
- CalibrationClockValue = pATI->BIOSClocks[ClockIndex];
- }
- }
- CalibrationClockNumber =
- MapClockIndex(pATI->NewHW.ClockUnmap, CalibrationClockNumber);
- CalibrationClockValue *= 10;
- }
-
-#ifndef AVOID_CPIO
-
- if (pATI->VGAAdapter)
- {
- /*
- * The current video state needs to be saved before the clock
- * probe, and restored after. Video memory corruption and other
- * effects occur because, at this early stage, the clock probe
- * cannot reliably be prevented from enabling frequencies that are
- * greater than what the adapter can handle.
- */
- ATIModeSave(pScreenInfo, pATI, &pATI->OldHW);
-
- /* Ensure clock select pins are not OR'ed with anything */
- if (pATI->CPIO_VGAWonder && (pATI->OldHW.crtc == ATI_CRTC_VGA))
- ATIModifyExtReg(pATI, 0xB5U, pATI->OldHW.b5, 0x7FU, 0x00U);
- }
-
-#endif /* AVOID_CPIO */
-
- /*
- * Probe the adapter for clock values. The following is essentially
- * the common layer's xf86GetClocks() reworked to fit. One difference
- * is the ability to monitor a VSync bit in MMIO space.
- */
- CanDisableInterrupts = TRUE; /* An assumption verified below */
-
- for (ClockIndex = 0; ClockIndex < NumberOfClocks; ClockIndex++)
- {
- pScreenInfo->clock[ClockIndex] = 0;
-
- /* Remap clock number */
- Index = MapClockIndex(pATI->OldHW.ClockMap, ClockIndex);
-
- /* Select the clock */
- switch (pATI->OldHW.crtc)
- {
-
-#ifndef AVOID_CPIO
-
- case ATI_CRTC_VGA:
- /* Get generic two low-order bits */
- genmo = (inb(R_GENMO) & 0xF3U) | ((Index << 2) & 0x0CU);
-
- if (pATI->CPIO_VGAWonder)
- {
- /* Start sequencer reset */
- PutReg(SEQX, 0x00U, 0x00U);
-
- {
- ATIModifyExtReg(pATI, 0xBEU, -1, 0xEFU,
- Index << 2);
- {
- Index >>= 1;
- ATIModifyExtReg(pATI, 0xB9U, -1, 0xFDU,
- Index >> 1);
- }
- }
-
- /* Set clock divider bits */
- ATIModifyExtReg(pATI, 0xB8U, -1, 0x00U,
- (Index << 3) & 0xC0U);
- }
- else
- {
- /*
- * Reject clocks that cannot be selected.
- */
- if (Index & ~0x03U)
- continue;
-
- /* Start sequencer reset */
- PutReg(SEQX, 0x00U, 0x00U);
- }
-
- /* Must set miscellaneous output register last */
- outb(GENMO, genmo);
-
- /* End sequencer reset */
- PutReg(SEQX, 0x00U, 0x03U);
-
- break;
-
-#endif /* AVOID_CPIO */
-
- case ATI_CRTC_MACH64:
- out8(CLOCK_CNTL, CLOCK_STROBE |
- SetBits(Index, CLOCK_SELECT | CLOCK_DIVIDER));
- break;
-
- default:
- continue;
- }
-
- usleep(50000); /* Let clock stabilise */
-
- xf86SetPriority(TRUE);
-
- /* Try to disable interrupts */
- if (CanDisableInterrupts && !xf86DisableInterrupts())
- {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
- "Unable to disable interrupts; Clock probe will not be as"
- " accurate.\n");
- CanDisableInterrupts = FALSE;
- }
-
- /*
- * Generate a count while monitoring the vertical sync or blanking
- * pulse. This is dependent on the CRTC used by the mode on server
- * entry.
- */
- switch (pATI->OldHW.crtc)
- {
-
-#ifndef AVOID_CPIO
-
- case ATI_CRTC_VGA:
- /* Verify vertical sync pulses are in fact occurring */
- Index = 1 << 19;
- while (!(inb(GENS1(pATI->CPIO_VGABase)) & 0x08U))
- if (Index-- <= 0)
- goto EnableInterrupts;
- Index = 1 << 19;
- while (inb(GENS1(pATI->CPIO_VGABase)) & 0x08U)
- if (Index-- <= 0)
- goto EnableInterrupts;
- Index = 1 << 19;
- while (!(inb(GENS1(pATI->CPIO_VGABase)) & 0x08U))
- if (Index-- <= 0)
- goto EnableInterrupts;
-
- /* Generate the count */
- for (Index = 0; Index < 8; Index++)
- {
- while (inb(GENS1(pATI->CPIO_VGABase)) & 0x08U)
- pScreenInfo->clock[ClockIndex]++;
- while (!(inb(GENS1(pATI->CPIO_VGABase)) & 0x08U))
- pScreenInfo->clock[ClockIndex]++;
- }
- break;
-
-#endif /* AVOID_CPIO */
-
- case ATI_CRTC_MACH64:
- /* Verify vertical blanking pulses are in fact occurring */
- Index = 1 << 19;
- while (!(inr(CRTC_INT_CNTL) & CRTC_VBLANK))
- if (Index-- <= 0)
- goto EnableInterrupts;
- Index = 1 << 19;
- while (inr(CRTC_INT_CNTL) & CRTC_VBLANK)
- if (Index-- <= 0)
- goto EnableInterrupts;
- Index = 1 << 19;
- while (!(inr(CRTC_INT_CNTL) & CRTC_VBLANK))
- if (Index-- <= 0)
- goto EnableInterrupts;
-
- /* Generate the count */
- for (Index = 0; Index < 4; Index++)
- {
- while (inr(CRTC_INT_CNTL) & CRTC_VBLANK)
- pScreenInfo->clock[ClockIndex]++;
- while (!(inr(CRTC_INT_CNTL) & CRTC_VBLANK))
- pScreenInfo->clock[ClockIndex]++;
- }
- break;
-
- default:
- break;
- }
-
- EnableInterrupts:
- if (CanDisableInterrupts)
- xf86EnableInterrupts();
-
- xf86SetPriority(FALSE);
- }
-
- ScaleFactor = (double)CalibrationClockValue *
- (double)pScreenInfo->clock[CalibrationClockNumber];
-
- /* Scale the clocks from counts to kHz */
- for (ClockIndex = 0; ClockIndex < NumberOfClocks; ClockIndex++)
- {
- if (ClockIndex == CalibrationClockNumber)
- pScreenInfo->clock[ClockIndex] = CalibrationClockValue;
- else if (pScreenInfo->clock[ClockIndex])
- /* Round to the nearest 10 kHz */
- pScreenInfo->clock[ClockIndex] =
- (int)(((ScaleFactor /
- (double)pScreenInfo->clock[ClockIndex]) +
- 5) / 10) * 10;
- }
-
- pScreenInfo->numClocks = NumberOfClocks;
-
-#ifndef AVOID_CPIO
-
- if (pATI->VGAAdapter)
- {
- /* Restore video state */
- ATIModeSet(pScreenInfo, pATI, &pATI->OldHW);
- xfree(pATI->OldHW.frame_buffer);
- pATI->OldHW.frame_buffer = NULL;
- }
-
-#endif /* AVOID_CPIO */
-
- /* Tell user clocks were probed, instead of supplied */
- pATI->OptionProbeClocks = TRUE;
-
- /* Attempt to match probed clocks to a known specification */
- pATI->Clock = ATIMatchClockLine(pScreenInfo, pATI,
- SpecificationClockLine, NumberOfUndividedClocks,
- CalibrationClockNumber, 0);
-
- {
- /* All others don't have crystals */
- if (pATI->Clock == ATI_CLOCK_CRYSTALS)
- pATI->Clock = ATI_CLOCK_NONE;
- }
- }
- else
- {
- /*
- * Allow for an initial subset of specification clocks. Can't allow
- * for any more than that though...
- */
- if (NumberOfClocks > pGDev->numclocks)
- {
- NumberOfClocks = pGDev->numclocks;
- if (NumberOfUndividedClocks > NumberOfClocks)
- NumberOfUndividedClocks = NumberOfClocks;
- }
-
- /* Move XF86Config clocks into the ScrnInfoRec */
- for (ClockIndex = 0; ClockIndex < NumberOfClocks; ClockIndex++)
- pScreenInfo->clock[ClockIndex] = pGDev->clock[ClockIndex];
- pScreenInfo->numClocks = NumberOfClocks;
-
- /* Attempt to match clocks to a known specification */
- pATI->Clock = ATIMatchClockLine(pScreenInfo, pATI,
- SpecificationClockLine, NumberOfUndividedClocks, -1, 0);
-
- {
- if (pATI->Clock == ATI_CLOCK_NONE)
- {
- /*
- * Reject certain clock lines that are obviously wrong. This
- * includes the standard VGA clocks for ATI adapters, and clock
- * lines that could have been used with the pre-2.1.1 driver.
- */
- if (ATIMatchClockLine(pScreenInfo, pATI, InvalidClockLine,
- NumberOfClocks, -1, 0))
- {
- pATI->OptionProbeClocks = TRUE;
- }
- else
- {
- /*
- * Check for clocks that are specified in the wrong order.
- * This is meant to catch those who are trying to use the
- * clock order intended for the old accelerated servers.
- */
- while ((++ClockMap, ClockMap %= NumberOf(ClockMaps)))
- {
- pATI->Clock = ATIMatchClockLine(pScreenInfo, pATI,
- SpecificationClockLine, NumberOfUndividedClocks,
- -1, ClockMap);
- if (pATI->Clock != ATI_CLOCK_NONE)
- {
- xf86DrvMsgVerb(pScreenInfo->scrnIndex,
- X_WARNING, 0,
- "XF86Config clock ordering incorrect. Clocks"
- " will be reordered.\n");
- break;
- }
- }
- }
- }
- else
- /* Ensure crystals are not matched to clock chips, and vice versa */
- {
- if (pATI->Clock == ATI_CLOCK_CRYSTALS)
- pATI->OptionProbeClocks = TRUE;
- }
-
- if (pATI->OptionProbeClocks)
- {
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
- "Invalid or obsolete XF86Config clocks line rejected.\n"
- " Clocks will be probed.\n");
- goto ProbeClocks;
- }
- }
- }
-
- if (pATI->ProgrammableClock != ATI_CLOCK_FIXED)
- {
- pATI->ProgrammableClock = ATI_CLOCK_FIXED;
- }
- else if (pATI->Clock == ATI_CLOCK_NONE)
- {
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
- "Unknown clock generator detected.\n");
- }
- else
-
-#ifndef AVOID_CPIO
-
- if (pATI->Clock == ATI_CLOCK_CRYSTALS)
- {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
- "This adapter uses crystals to generate clock frequencies.\n");
- }
- else if (pATI->Clock != ATI_CLOCK_VGA)
-
-#endif /* AVOID_CPIO */
-
- {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
- "%s clock chip detected.\n", ATIClockNames[pATI->Clock]);
- }
-
- if (pATI->Clock != ATI_CLOCK_NONE)
- {
- /* Replace undivided clocks with specification values */
- for (ClockIndex = 0;
- ClockIndex < NumberOfUndividedClocks;
- ClockIndex++)
- {
- /*
- * Don't replace clocks that are probed, documented, or set by the
- * user to zero. One exception is that we need to override the
- * user's value for the spare settings on a crystal-based adapter.
- * Another exception is when the user specifies the clock ordering
- * intended for the old accelerated servers.
- */
- SpecificationClock =
- SpecificationClockLine[pATI->Clock][ClockIndex];
- if (SpecificationClock < 0)
- break;
- if (!ClockMap)
- {
- if (!pScreenInfo->clock[ClockIndex])
- continue;
- if (!SpecificationClock)
- {
- if (pATI->Clock != ATI_CLOCK_CRYSTALS)
- continue;
- }
- else
- {
- /*
- * Due to the way clock lines are matched, the following
- * can prevent the override if the clock is probed,
- * documented or set by the user to a value greater than
- * maxClock.
- */
- if (abs(SpecificationClock -
- pScreenInfo->clock[ClockIndex]) > CLOCK_TOLERANCE)
- continue;
- }
- }
- pScreenInfo->clock[ClockIndex] = SpecificationClock;
- }
-
- /* Adjust divided clocks */
- for (ClockIndex = NumberOfUndividedClocks;
- ClockIndex < NumberOfClocks;
- ClockIndex++)
- pScreenInfo->clock[ClockIndex] = ATIDivide(
- pScreenInfo->clock[ClockIndex % NumberOfUndividedClocks],
- (ClockIndex / NumberOfUndividedClocks) + 1, 0, 0);
- }
-
- /* Tell user about fixed clocks */
- xf86ShowClocks(pScreenInfo, pATI->OptionProbeClocks ? X_PROBED : X_CONFIG);
-
- /* Prevent selection of high clocks, even by V_CLKDIV2 modes */
- for (ClockIndex = 0; ClockIndex < NumberOfClocks; ClockIndex++)
- if (pScreenInfo->clock[ClockIndex] > pRange->maxClock)
- pScreenInfo->clock[ClockIndex] = 0;
-}
-
-/*
- * ATIClockSave --
- *
- * This function saves that part of an ATIHWRec that relates to clocks.
- */
-void
-ATIClockSave
-(
- ScrnInfoPtr pScreenInfo,
- ATIPtr pATI,
- ATIHWPtr pATIHW
-)
-{
- if (pScreenInfo->vtSema && (pATI->ProgrammableClock > ATI_CLOCK_FIXED))
- {
-
-#ifndef AVOID_CPIO
-
- if (pATIHW->crtc == ATI_CRTC_VGA)
- {
- pATIHW->ClockMap = ATIVGAProgrammableClockMap;
- pATIHW->ClockUnmap = ATIVGAProgrammableClockUnmap;
- }
- else
-
-#endif /* AVOID_CPIO */
-
- {
- pATIHW->ClockMap = ATIProgrammableClockMap;
- pATIHW->ClockUnmap = ATIProgrammableClockUnmap;
- }
- }
- else
- {
-
-#ifndef AVOID_CPIO
-
- if (pATIHW->crtc != ATI_CRTC_VGA)
-
-#endif /* AVOID_CPIO */
-
- {
- pATIHW->ClockMap = ATIAcceleratorClockMap;
- pATIHW->ClockUnmap = ATIAcceleratorClockUnmap;
- }
-
-#ifndef AVOID_CPIO
-
- else
- {
- pATIHW->ClockMap = ATIMachVGAClockMap;
- pATIHW->ClockUnmap = ATIMachVGAClockUnmap;
- }
-
-#endif /* AVOID_CPIO */
-
- }
}
/*
@@ -1152,14 +177,14 @@ ATIClockCalculate
/* Set default values */
pATIHW->FeedbackDivider = pATIHW->ReferenceDivider = pATIHW->PostDivider = 0;
- if ((pATI->ProgrammableClock <= ATI_CLOCK_FIXED) ||
- ((pATI->ProgrammableClock == ATI_CLOCK_CH8398) &&
+ if (((pATI->ProgrammableClock == ATI_CLOCK_CH8398) &&
(pMode->ClockIndex < 2)))
{
- /* Use a fixed clock */
- ClockSelect = pMode->ClockIndex;
+ xf86DrvMsg(iScreen, X_ERROR,
+ "First two clocks of Chrontel 8398 clock generator are fixed\n");
+ return FALSE;
}
- else
+
{
/* Generate clock programme word, using units of kHz */
MinimumGap = ((unsigned int)(-1)) >> 1;
@@ -1247,9 +272,8 @@ ATIClockCalculate
ATIDSPCalculate(pATI, pATIHW, pMode);
}
- /* Set clock select bits, after remapping them */
- pATIHW->clock = ClockSelect; /* Save pre-map clock number */
- ClockSelect = MapClockIndex(pATIHW->ClockMap, ClockSelect);
+ /* Set clock select bits */
+ pATIHW->clock = ClockSelect;
{
pATIHW->clock_cntl = CLOCK_STROBE |