summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2006-04-17 04:13:44 +0200
committerLuc Verhaegen <libv@skynet.be>2006-04-17 04:23:58 +0200
commit484262fdcffdc1ba008d324561543dd723ad3e57 (patch)
treed7ab9f5070a298275b845815217bae04a3293186
parentd9cca7244b524da90fde29f6269f20dfc1f90ff5 (diff)
[PATCH] Move 3 large Panel related blocks out of PreInit into their own functions.
-rw-r--r--src/atipreinit.c1456
-rw-r--r--src/atistruct.h2
2 files changed, 696 insertions, 762 deletions
diff --git a/src/atipreinit.c b/src/atipreinit.c
index e8b513b..f457424 100644
--- a/src/atipreinit.c
+++ b/src/atipreinit.c
@@ -65,6 +65,9 @@ ATIGetRec(ScrnInfoPtr pScrn)
if (!pScrn->driverPrivate) {
pScrn->driverPrivate = xnfcalloc(sizeof(ATIRec), 1);
memset(pScrn->driverPrivate, 0, sizeof(ATIRec));
+
+ ((ATIPtr) pScrn->driverPrivate)->scrnIndex = pScrn->scrnIndex;
+
}
return TRUE;
@@ -780,6 +783,684 @@ Mach64PreInitGetClockInfo(ScrnInfoPtr pScrn, GDevPtr pGDev)
}
}
+/* kill me */
+#define pATIHW (&pATI->OldHW)
+
+/*
+ * Call this before going into the BIOS code, as the BIOS
+ * code depends on LCDPanelID.
+ */
+static void
+Mach64PanelScratchInfoGet(ATIPtr pATI)
+{
+ CARD32 IOValue;
+
+ IOValue = inr(CONFIG_STATUS64_0);
+
+ /* Get LCD panel id */
+ if (pATI->Chip == ATI_CHIP_264LT) {
+ pATI->LCDPanelID = GetBits(IOValue, CFG_PANEL_ID);
+
+ pATIHW->horz_stretching = inr(HORZ_STRETCHING);
+ pATIHW->vert_stretching = inr(VERT_STRETCHING);
+ pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
+ } else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) {
+ pATI->LCDPanelID = GetBits(IOValue, CFG_PANEL_ID);
+
+ pATIHW->lcd_index = inr(LCD_INDEX);
+ pATIHW->horz_stretching = ATIMach64GetLCDReg(LCD_HORZ_STRETCHING);
+ pATI->LCDHorizontal = GetBits(pATIHW->horz_stretching,
+ HORZ_PANEL_SIZE);
+ if (pATI->LCDHorizontal) {
+ if (pATI->LCDHorizontal == MaxBits(HORZ_PANEL_SIZE))
+ pATI->LCDHorizontal = 0;
+ else
+ pATI->LCDHorizontal = (pATI->LCDHorizontal + 1) << 3;
+ }
+ pATIHW->ext_vert_stretch = ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH);
+ pATI->LCDVertical = GetBits(pATIHW->ext_vert_stretch,
+ VERT_PANEL_SIZE);
+ if (pATI->LCDVertical) {
+ if (pATI->LCDVertical == MaxBits(VERT_PANEL_SIZE))
+ pATI->LCDVertical = 0;
+ else
+ pATI->LCDVertical++;
+ }
+ pATIHW->vert_stretching = ATIMach64GetLCDReg(LCD_VERT_STRETCHING);
+ pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
+ outr(LCD_INDEX, pATIHW->lcd_index);
+ }
+
+ /*
+ * Don't bother with panel support if it hasn't been previously
+ * enabled.
+ */
+ if ((pATI->LCDPanelID >= 0) &&
+ !(pATIHW->horz_stretching & HORZ_STRETCH_EN) &&
+ !(pATIHW->vert_stretching & VERT_STRETCH_EN) &&
+ !(pATIHW->lcd_gen_ctrl & LCD_ON)) {
+ /*
+ * At this point, if an XL or Mobility BIOS hasn't set
+ * panel dimensions, then there is no panel. Otherwise,
+ * keep any panel disabled to allow for modes greater than
+ * the panel's dimensions.
+ */
+ if ((pATI->Chip >= ATI_CHIP_264XL) &&
+ (!pATI->LCDHorizontal || !pATI->LCDVertical))
+ pATI->LCDPanelID = -1;
+ else
+ pATI->OptionPanelDisplay = FALSE;
+ }
+}
+
+/*
+ * Decide between the CRT and the panel.
+ */
+static Bool
+Mach64PanelInfoGet(ATIPtr pATI)
+{
+ int Numerator, Denominator, i, j;
+ unsigned HDisplay, VDisplay;
+ CARD8 ClockMask, PostMask;
+ CARD32 IOValue;
+
+ /*
+ * Determine porch data. This groks the mode on entry to extract
+ * the width and position of its sync and blanking pulses, and
+ * considers any overscan as part of the displayed area, given that
+ * the overscan is also stretched.
+ *
+ * This also attempts to determine panel dimensions but cannot do
+ * so for one that is "auto-stretched".
+ */
+
+ if (pATI->Chip == ATI_CHIP_264LT) {
+ pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
+
+ /* Set up to read non-shadow registers */
+ if (pATIHW->lcd_gen_ctrl & SHADOW_RW_EN)
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
+ } else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */ {
+
+ pATIHW->lcd_index = inr(LCD_INDEX);
+ pATIHW->config_panel = ATIMach64GetLCDReg(LCD_CONFIG_PANEL);
+ pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
+
+ /* Set up to read non-shadow registers */
+ if (pATIHW->lcd_gen_ctrl & SHADOW_RW_EN)
+ ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
+ }
+
+#ifndef AVOID_CPIO
+
+ if (!(pATIHW->crtc_gen_cntl & CRTC_EXT_DISP_EN)) {
+ unsigned HBlankStart, HSyncStart, HSyncEnd, HBlankEnd, HTotal;
+ unsigned VBlankStart, VSyncStart, VSyncEnd, VBlankEnd, VTotal;
+
+ pATIHW->clock = (inb(R_GENMO) & 0x0CU) >> 2;
+
+ pATIHW->crt[2] = GetReg(CRTX(pATI->CPIO_VGABase), 0x02U);
+ pATIHW->crt[3] = GetReg(CRTX(pATI->CPIO_VGABase), 0x03U);
+ pATIHW->crt[5] = GetReg(CRTX(pATI->CPIO_VGABase), 0x05U);
+ pATIHW->crt[7] = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U);
+ pATIHW->crt[9] = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U);
+ pATIHW->crt[21] = GetReg(CRTX(pATI->CPIO_VGABase), 0x15U);
+ pATIHW->crt[22] = GetReg(CRTX(pATI->CPIO_VGABase), 0x16U);
+
+ pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP);
+ pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
+ pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP);
+ pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
+
+ /* Switch to shadow registers */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
+
+ pATIHW->shadow_vga[2] = GetReg(CRTX(pATI->CPIO_VGABase), 0x02U);
+ pATIHW->shadow_vga[3] = GetReg(CRTX(pATI->CPIO_VGABase), 0x03U);
+ pATIHW->shadow_vga[5] = GetReg(CRTX(pATI->CPIO_VGABase), 0x05U);
+ pATIHW->shadow_vga[7] = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U);
+ pATIHW->shadow_vga[9] = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U);
+ pATIHW->shadow_vga[21] = GetReg(CRTX(pATI->CPIO_VGABase), 0x15U);
+ pATIHW->shadow_vga[22] = GetReg(CRTX(pATI->CPIO_VGABase), 0x16U);
+
+ pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP);
+ pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
+ pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP);
+ pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
+
+ /*
+ * HSyncStart and HSyncEnd should equal their shadow
+ * counterparts. Otherwise, due to a chip bug, the panel might
+ * not sync, regardless of which register set is used to drive
+ * the panel. There are certain combinations of register
+ * values where the panel does in fact sync, but it remains
+ * impossible to accurately determine the horizontal sync pulse
+ * timing actually seen by the panel.
+ *
+ * Note that this hardware bug does not affect the CRT output.
+ */
+ if (((pATIHW->crtc_h_sync_strt_wid ^ pATIHW->shadow_h_sync_strt_wid) &
+ (CRTC_H_SYNC_STRT | CRTC_H_SYNC_STRT_HI | CRTC_H_SYNC_WID))) {
+ xf86DrvMsgVerb(pATI->scrnIndex, X_NOTICE, 0, "Invalid horizontal "
+ "sync pulse timing detected in mode on server "
+ "entry.\n");
+
+ /* Don't trust input timing */
+ pATI->OptionLCDSync = TRUE;
+ }
+
+ /* Merge in shadow registers as appropriate */
+ if (pATIHW->lcd_gen_ctrl & SHADOW_EN) {
+ pATIHW->crt[2] = pATIHW->shadow_vga[2];
+ pATIHW->crt[3] = pATIHW->shadow_vga[3];
+ pATIHW->crt[5] = pATIHW->shadow_vga[5];
+
+ /* XXX Does this apply to VGA? If so, what about the LT? */
+ if ((pATI->Chip < ATI_CHIP_264LTPRO) ||
+ !(pATIHW->config_panel & DONT_SHADOW_HEND)) {
+ pATIHW->crtc_h_total_disp &= ~CRTC_H_DISP;
+ pATIHW->crtc_h_total_disp |=
+ pATIHW->shadow_h_total_disp & CRTC_H_DISP;
+ }
+
+ pATIHW->crtc_h_total_disp &= ~CRTC_H_TOTAL;
+ pATIHW->crtc_h_total_disp |=
+ pATIHW->shadow_h_total_disp & CRTC_H_TOTAL;
+ pATIHW->crtc_h_sync_strt_wid = pATIHW->shadow_h_sync_strt_wid;
+
+ /* XXX Does this apply to VGA? */
+ if (pATIHW->lcd_gen_ctrl & USE_SHADOWED_VEND) {
+ pATIHW->crtc_v_total_disp &= ~CRTC_V_DISP;
+ pATIHW->crtc_v_total_disp |=
+ pATIHW->shadow_v_total_disp & CRTC_V_DISP;
+ }
+
+ if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR)) {
+ pATIHW->crt[7] = pATIHW->shadow_vga[7];
+ pATIHW->crt[9] = pATIHW->shadow_vga[9];
+ pATIHW->crt[21] = pATIHW->shadow_vga[21];
+ pATIHW->crt[22] = pATIHW->shadow_vga[22];
+
+ pATIHW->crtc_v_total_disp &= ~CRTC_V_TOTAL;
+ pATIHW->crtc_v_total_disp |=
+ pATIHW->shadow_v_total_disp & CRTC_V_TOTAL;
+ }
+ }
+
+ if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR))
+ pATIHW->crtc_v_sync_strt_wid = pATIHW->shadow_v_sync_strt_wid;
+
+ /*
+ * Decipher input timing. This is complicated by the fact that
+ * the full width of all timing parameters, except for the
+ * blanking pulses, is only available through the accelerator
+ * registers, not the VGA ones. Blanking pulse boundaries must
+ * then be interpolated.
+ *
+ * Note that, in VGA mode, the accelerator's sync width fields
+ * are actually end positions, not widths.
+ */
+ HDisplay = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_DISP);
+ HSyncStart = (GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT_HI) *
+ (MaxBits(CRTC_H_SYNC_STRT) + 1)) |
+ GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT);
+ HSyncEnd = (HSyncStart & ~MaxBits(CRTC_H_SYNC_WID)) |
+ GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_WID);
+ if (HSyncStart >= HSyncEnd)
+ HSyncEnd += MaxBits(CRTC_H_SYNC_WID) + 1;
+ HTotal = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_TOTAL);
+
+ HBlankStart = (HDisplay & ~0xFFU) | pATIHW->crt[2];
+ if (HDisplay > HBlankStart)
+ HBlankStart += 0x0100U;
+ HBlankEnd = (HSyncEnd & ~0x3FU) | ((pATIHW->crt[5] >> 2) & 0x20U) |
+ (pATIHW->crt[3] & 0x1FU);
+ if (HSyncEnd > (HBlankEnd + 1))
+ HBlankEnd += 0x40U;
+
+ VDisplay = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_DISP);
+ VSyncStart = GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_STRT);
+ VSyncEnd = (VSyncStart & ~MaxBits(CRTC_V_SYNC_END_VGA)) |
+ GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_END_VGA);
+ if (VSyncStart > VSyncEnd)
+ VSyncEnd += MaxBits(CRTC_V_SYNC_END_VGA) + 1;
+ VTotal = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_TOTAL);
+
+ VBlankStart = (VDisplay & ~0x03FFU) | ((pATIHW->crt[9] << 4) & 0x0200U) |
+ ((pATIHW->crt[7] << 5) & 0x0100U) | pATIHW->crt[21];
+ if (VDisplay > VBlankStart)
+ VBlankStart += 0x0400U;
+ VBlankEnd = (VSyncEnd & ~0x00FFU) | pATIHW->crt[22];
+ if (VSyncEnd > (VBlankEnd + 1))
+ VBlankEnd += 0x0100U;
+
+ pATI->LCDHBlankWidth = HBlankEnd - HBlankStart;
+ pATI->LCDHSyncStart = HSyncStart - HBlankStart;
+ pATI->LCDHSyncWidth = HSyncEnd - HSyncStart;
+
+ pATI->LCDVBlankWidth = VBlankEnd - VBlankStart;
+ pATI->LCDVSyncStart = VSyncStart - VBlankStart;
+ pATI->LCDVSyncWidth = VSyncEnd - VSyncStart;
+
+ HDisplay = HTotal + 5 - pATI->LCDHBlankWidth;
+ VDisplay = VTotal + 2 - pATI->LCDVBlankWidth;
+ } else
+
+#endif /* AVOID_CPIO */
+
+ {
+ pATIHW->clock = inr(CLOCK_CNTL) & 0x03U;
+
+ pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP);
+ pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
+ pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP);
+ pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
+ pATIHW->ovr_wid_left_right = inr(OVR_WID_LEFT_RIGHT);
+ pATIHW->ovr_wid_top_bottom = inr(OVR_WID_TOP_BOTTOM);
+
+ /* Switch to shadow registers */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */
+ ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
+
+ /* Oddly enough, there are no shadow overscan registers */
+ pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP);
+ pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
+ pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP);
+ pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
+
+ /*
+ * HSyncStart and HSyncEnd should equal their shadow
+ * counterparts. Otherwise, due to a chip bug, the panel might
+ * not sync, regardless of which register set is used to drive
+ * the panel. There are certain combinations of register
+ * values where the panel does in fact sync, but it remains
+ * impossible to accurately determine the horizontal sync pulse
+ * timing actually seen by the panel.
+ *
+ * Note that this hardware bug does not affect the CRT output.
+ */
+ if (((pATIHW->crtc_h_sync_strt_wid ^ pATIHW->shadow_h_sync_strt_wid) &
+ (CRTC_H_SYNC_STRT | CRTC_H_SYNC_STRT_HI | CRTC_H_SYNC_WID))) {
+ xf86DrvMsgVerb(pATI->scrnIndex, X_NOTICE, 0,
+ "Invalid horizontal sync pulse timing detected "
+ "in mode on server entry.\n");
+
+ /* Don't trust input timing */
+ pATI->OptionLCDSync = TRUE;
+ }
+
+ /* Merge in shadow registers as appropriate */
+ if (pATIHW->lcd_gen_ctrl & SHADOW_EN) {
+ /* XXX What about the LT? */
+ if ((pATI->Chip < ATI_CHIP_264LTPRO) ||
+ !(pATIHW->config_panel & DONT_SHADOW_HEND)) {
+ pATIHW->crtc_h_total_disp &= ~CRTC_H_DISP;
+ pATIHW->crtc_h_total_disp |=
+ pATIHW->shadow_h_total_disp & CRTC_H_DISP;
+ }
+
+ pATIHW->crtc_h_total_disp &= ~CRTC_H_TOTAL;
+ pATIHW->crtc_h_total_disp |=
+ pATIHW->shadow_h_total_disp & CRTC_H_TOTAL;
+ pATIHW->crtc_h_sync_strt_wid = pATIHW->shadow_h_sync_strt_wid;
+
+ if (pATIHW->lcd_gen_ctrl & USE_SHADOWED_VEND) {
+ pATIHW->crtc_v_total_disp &= ~CRTC_V_DISP;
+ pATIHW->crtc_v_total_disp |=
+ pATIHW->shadow_v_total_disp & CRTC_V_DISP;
+ }
+
+ if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR)) {
+ pATIHW->crtc_v_total_disp &= ~CRTC_V_TOTAL;
+ pATIHW->crtc_v_total_disp |=
+ pATIHW->shadow_v_total_disp & CRTC_V_TOTAL;
+ }
+ }
+
+ if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR))
+ pATIHW->crtc_v_sync_strt_wid = pATIHW->shadow_v_sync_strt_wid;
+
+ /* Decipher input timing */
+ HDisplay = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_DISP) +
+ GetBits(pATIHW->ovr_wid_left_right, OVR_WID_LEFT) +
+ GetBits(pATIHW->ovr_wid_left_right, OVR_WID_RIGHT);
+ VDisplay = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_DISP) +
+ GetBits(pATIHW->ovr_wid_top_bottom, OVR_WID_TOP) +
+ GetBits(pATIHW->ovr_wid_top_bottom, OVR_WID_BOTTOM);
+
+ pATI->LCDHSyncStart =
+ (GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT_HI) *
+ (MaxBits(CRTC_H_SYNC_STRT) + 1)) +
+ GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT) -
+ HDisplay;
+ pATI->LCDHSyncWidth =
+ GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_WID);
+ pATI->LCDHBlankWidth =
+ GetBits(pATIHW->crtc_h_total_disp, CRTC_H_TOTAL) - HDisplay;
+ pATI->LCDVSyncStart =
+ GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_STRT) - VDisplay;
+ pATI->LCDVSyncWidth =
+ GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_WID);
+ pATI->LCDVBlankWidth =
+ GetBits(pATIHW->crtc_v_total_disp, CRTC_V_TOTAL) - VDisplay;
+
+ HDisplay++;
+ VDisplay++;
+ }
+
+ /* Restore LCD registers */
+ if (pATI->Chip == ATI_CHIP_264LT) {
+ outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
+ } else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL) ||
+ (pATI->Chip == ATI_CHIP_MOBILITY)) */ {
+ ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl);
+ outr(LCD_INDEX, pATIHW->lcd_index);
+ }
+
+ HDisplay <<= 3;
+ pATI->LCDHSyncStart <<= 3;
+ pATI->LCDHSyncWidth <<= 3;
+ pATI->LCDHBlankWidth <<= 3;
+
+ /* Calculate panel dimensions implied by the input timing */
+ if ((pATIHW->horz_stretching & (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) ==
+ HORZ_STRETCH_EN) {
+ if (pATIHW->horz_stretching & HORZ_STRETCH_MODE) {
+ if (pATIHW->horz_stretching & HORZ_STRETCH_BLEND)
+ HDisplay = (HDisplay * (MaxBits(HORZ_STRETCH_BLEND) + 1)) /
+ GetBits(pATIHW->horz_stretching, HORZ_STRETCH_BLEND);
+ } else if (((pATIHW->horz_stretching & HORZ_STRETCH_LOOP) > HORZ_STRETCH_LOOP15) ||
+ (pATIHW->horz_stretching & SetBits(1, HORZ_STRETCH_RATIO))) {
+ xf86DrvMsg(pATI->scrnIndex, X_WARNING, "Ignoring invalid horizontal"
+ " stretch ratio in mode on server entry.\n");
+ } else {
+ IOValue = GetBits(pATIHW->horz_stretching, HORZ_STRETCH_RATIO);
+
+ switch (GetBits(pATIHW->horz_stretching, HORZ_STRETCH_LOOP)) {
+ case GetBits(HORZ_STRETCH_LOOP09, HORZ_STRETCH_LOOP):
+ i = 9;
+ IOValue &= (1 << 9) - 1;
+ break;
+
+ case GetBits(HORZ_STRETCH_LOOP11, HORZ_STRETCH_LOOP):
+ i = 11;
+ IOValue &= (1 << 11) - 1;
+ break;
+
+ case GetBits(HORZ_STRETCH_LOOP12, HORZ_STRETCH_LOOP):
+ i = 12;
+ IOValue &= (1 << 12) - 1;
+ break;
+
+ case GetBits(HORZ_STRETCH_LOOP14, HORZ_STRETCH_LOOP):
+ i = 14;
+ IOValue &= (1 << 14) - 1;
+ break;
+
+ case GetBits(HORZ_STRETCH_LOOP15, HORZ_STRETCH_LOOP):
+ default: /* Muffle compiler */
+ i = 15;
+ IOValue &= (1 << 15) - 1;
+ break;
+ }
+
+ if (IOValue) {
+ /* Count the number of bits in IOValue */
+ j = (IOValue >> 1) & 0x36DBU;
+ j = IOValue - j - ((j >> 1) & 0x36DBU);
+ j = ((j + (j >> 3)) & 0x71C7U) % 0x3FU;
+
+ HDisplay = (HDisplay * i) / j;
+ }
+ }
+ }
+
+ if ((pATIHW->vert_stretching & VERT_STRETCH_EN) &&
+ !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO)) {
+ if ((pATIHW->vert_stretching & VERT_STRETCH_USE0) || (VDisplay <= 350))
+ IOValue = GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO0);
+ else if (VDisplay <= 400)
+ IOValue = GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO1);
+ else if ((VDisplay <= 480) || !(pATIHW->ext_vert_stretch & VERT_STRETCH_RATIO3))
+ IOValue = GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO2);
+ else
+ IOValue = GetBits(pATIHW->ext_vert_stretch, VERT_STRETCH_RATIO3);
+
+ if (IOValue)
+ VDisplay = (VDisplay * (MaxBits(VERT_STRETCH_RATIO0) + 1)) / IOValue;
+ }
+
+ /* Match calculated dimensions to probed dimensions */
+ if (!pATI->LCDHorizontal) {
+ if ((pATIHW->horz_stretching & (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) !=
+ (HORZ_STRETCH_EN | AUTO_HORZ_RATIO))
+ pATI->LCDHorizontal = HDisplay;
+ } else if (pATI->LCDHorizontal != (int)HDisplay) {
+ if ((pATIHW->horz_stretching & (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) !=
+ (HORZ_STRETCH_EN | AUTO_HORZ_RATIO))
+ xf86DrvMsgVerb(pATI->scrnIndex, X_WARNING, 4, "Inconsistent panel "
+ "horizontal dimension: %d and %d.\n",
+ pATI->LCDHorizontal, HDisplay);
+ HDisplay = pATI->LCDHorizontal;
+ }
+
+ if (!pATI->LCDVertical) {
+ if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) ||
+ !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO))
+ pATI->LCDVertical = VDisplay;
+ } else if (pATI->LCDVertical != (int)VDisplay) {
+ if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) ||
+ !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO))
+ xf86DrvMsgVerb(pATI->scrnIndex, X_WARNING, 4, "Inconsistent panel "
+ "vertical dimension: %d and %d.\n",
+ pATI->LCDVertical, VDisplay);
+ VDisplay = pATI->LCDVertical;
+ }
+
+ if (!pATI->LCDHorizontal || !pATI->LCDVertical) {
+ if (pATI->LCDPanelID || (pATI->Chip <= ATI_CHIP_264LTPRO))
+ xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Unable to determine dimensions"
+ " of panel (ID %d).\n", pATI->LCDPanelID);
+ else
+ xf86DrvMsg(pATI->scrnIndex, X_ERROR, "Unable to determine dimensions"
+ " of panel.\n");
+ return FALSE;
+ }
+
+ /* If the mode on entry wasn't stretched, adjust timings */
+ if (!(pATIHW->horz_stretching & HORZ_STRETCH_EN) &&
+ (pATI->LCDHorizontal > (int)HDisplay)) {
+ HDisplay = pATI->LCDHorizontal - HDisplay;
+ if (pATI->LCDHSyncStart >= HDisplay)
+ pATI->LCDHSyncStart -= HDisplay;
+ else
+ pATI->LCDHSyncStart = 0;
+ pATI->LCDHBlankWidth -= HDisplay;
+ HDisplay = pATI->LCDHSyncStart + pATI->LCDHSyncWidth;
+ if (pATI->LCDHBlankWidth < HDisplay)
+ pATI->LCDHBlankWidth = HDisplay;
+ }
+
+ if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) &&
+ (pATI->LCDVertical > (int)VDisplay)) {
+ VDisplay = pATI->LCDVertical - VDisplay;
+ if (pATI->LCDVSyncStart >= VDisplay)
+ pATI->LCDVSyncStart -= VDisplay;
+ else
+ pATI->LCDVSyncStart = 0;
+ pATI->LCDVBlankWidth -= VDisplay;
+ VDisplay = pATI->LCDVSyncStart + pATI->LCDVSyncWidth;
+ if (pATI->LCDVBlankWidth < VDisplay)
+ pATI->LCDVBlankWidth = VDisplay;
+ }
+
+ if (pATI->LCDPanelID || (pATI->Chip <= ATI_CHIP_264LTPRO))
+ xf86DrvMsg(pATI->scrnIndex, X_PROBED,
+ "%dx%d panel (ID %d) detected.\n",
+ pATI->LCDHorizontal, pATI->LCDVertical, pATI->LCDPanelID);
+ else
+ xf86DrvMsg(pATI->scrnIndex, X_PROBED,
+ "%dx%d panel detected.\n",
+ pATI->LCDHorizontal, pATI->LCDVertical);
+
+ /*
+ * Determine panel clock. This must be done after option
+ * processing so that the adapter's reference frequency is always
+ * available.
+ *
+ * Get post divider. A GCC bug has caused the following expression
+ * to be broken down into its individual components.
+ */
+ ClockMask = PLL_VCLK0_XDIV << pATIHW->clock;
+ PostMask = PLL_VCLK0_POST_DIV << (pATIHW->clock * 2);
+ i = GetBits(ATIMach64GetPLLReg(PLL_XCLK_CNTL), ClockMask);
+ i *= MaxBits(PLL_VCLK0_POST_DIV) + 1;
+ i |= GetBits(ATIMach64GetPLLReg(PLL_VCLK_POST_DIV), PostMask);
+
+ /* Calculate clock of mode on entry */
+ Numerator = ATIMach64GetPLLReg(PLL_VCLK0_FB_DIV + pATIHW->clock) *
+ pATI->ReferenceNumerator;
+ Denominator = pATI->ClockDescriptor.MinM * pATI->ReferenceDenominator *
+ pATI->ClockDescriptor.PostDividers[i];
+ pATI->LCDClock = ATIDivide(Numerator, Denominator, 1, 0);
+
+ xf86DrvMsg(pATI->scrnIndex, X_PROBED, "Panel clock is %.3f MHz.\n",
+ (double)(pATI->LCDClock) / 1000.0);
+
+ xf86DrvMsg(pATI->scrnIndex, X_INFO, "Using digital flat panel interface%s.\n",
+ pATI->OptionCRTDisplay ? " to display on both CRT and panel" : "");
+ return TRUE;
+}
+
+/*
+ * Set up pScrn->monitor for use with panel.
+ */
+static void
+Mach64PanelMonitor(ScrnInfoPtr pScrn)
+{
+ ATIPtr pATI = ATIPTR(pScrn);
+ int i;
+
+ if (!pATI->OptionLCDSync) {
+ /*
+ * Add a mode to the end of the monitor's list for the panel's
+ * native resolution.
+ */
+ DisplayModePtr pMode = xnfcalloc(1, SizeOf(DisplayModeRec));
+
+ pMode->name = "Native panel mode";
+ pMode->type = M_T_BUILTIN;
+ pMode->Clock = pATI->LCDClock;
+ pMode->HDisplay = pATI->LCDHorizontal;
+ pMode->VDisplay = pATI->LCDVertical;
+
+ /*
+ * These timings are bogus, but enough to survive sync tolerance
+ * checks.
+ */
+ pMode->HSyncStart = pMode->HDisplay;
+
+ if (pATI->Chip >= ATI_CHIP_264CT) {
+ pMode->HSyncEnd += 8;
+ pMode->HTotal += 8;
+ } else {
+ pMode->HSyncEnd += 16;
+ pMode->HTotal += 16;
+ }
+
+ pMode->VSyncStart = pMode->VDisplay;
+ pMode->VSyncEnd = pMode->VSyncStart + 1;
+ pMode->VTotal = pMode->VSyncEnd + 1;
+
+ pMode->CrtcHDisplay = pMode->HDisplay;
+ pMode->CrtcHBlankStart = pMode->HDisplay;
+ pMode->CrtcHSyncStart = pMode->HSyncStart;
+ pMode->CrtcHSyncEnd = pMode->HSyncEnd;
+ pMode->CrtcHBlankEnd = pMode->HTotal;
+ pMode->CrtcHTotal = pMode->HTotal;
+
+ pMode->CrtcVDisplay = pMode->VDisplay;
+ pMode->CrtcVBlankStart = pMode->VDisplay;
+ pMode->CrtcVSyncStart = pMode->VSyncStart;
+ pMode->CrtcVSyncEnd = pMode->VSyncEnd;
+ pMode->CrtcVBlankEnd = pMode->VTotal;
+ pMode->CrtcVTotal = pMode->VTotal;
+
+ if (!pScrn->monitor->Modes)
+ pScrn->monitor->Modes = pMode;
+ else {
+ pScrn->monitor->Last->next = pMode;
+ pMode->prev = pScrn->monitor->Last;
+ }
+
+ pScrn->monitor->Last = pMode;
+ }
+
+ /*
+ * Defeat Xconfigurator brain damage. Ignore all HorizSync and
+ * VertRefresh specifications. For now, this does not take
+ * SYNC_TOLERANCE into account.
+ */
+ if (pScrn->monitor->nHsync > 0) {
+ double hsync = (double)pATI->LCDClock /
+ (pATI->LCDHorizontal + pATI->LCDHBlankWidth);
+
+ for (i = 0; ; i++) {
+ if (i >= pScrn->monitor->nHsync) {
+ xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, "Conflicting "
+ "XF86Config HorizSync specification(s) ignored.\n");
+ break;
+ }
+
+ if ((hsync >= pScrn->monitor->hsync[i].lo) &&
+ (hsync <= pScrn->monitor->hsync[i].hi)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Extraneous "
+ "XF86Config HorizSync specification(s) ignored.\n");
+ break;
+ }
+ }
+
+ pScrn->monitor->nHsync = 0;
+ }
+
+ if (pScrn->monitor->nVrefresh > 0) {
+ double vrefresh = ((double)pATI->LCDClock * 1000.0) /
+ ((pATI->LCDHorizontal + pATI->LCDHBlankWidth) *
+ (pATI->LCDVertical + pATI->LCDVBlankWidth));
+
+ for (i = 0; ; i++) {
+ if (i >= pScrn->monitor->nVrefresh) {
+ xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, "Conflicting "
+ "XF86Config VertRefresh specification(s) ignored.\n");
+ break;
+ }
+
+ if ((vrefresh >= pScrn->monitor->vrefresh[i].lo) &&
+ (vrefresh <= pScrn->monitor->vrefresh[i].hi)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Extraneous "
+ "XF86Config VertRefresh specification(s) ignored.\n");
+ break;
+ }
+ }
+
+ pScrn->monitor->nVrefresh = 0;
+ }
+}
+
/*
* ATIReportMemory --
*
@@ -885,15 +1566,12 @@ ATIPreInit(ScrnInfoPtr pScreenInfo, int flags)
int DefaultmaxClock = 0;
int minPitch, maxPitch = 0xFFU, maxHeight = 0;
int ApertureSize = 0x00010000U;
- int ModeType = M_T_BUILTIN;
LookupModeFlags Strategy = LOOKUP_CLOSEST_CLOCK;
int DefaultDepth;
CARD8 BIOS[BIOS_SIZE];
unsigned int BIOSSize = 0;
-# define pATIHW (&pATI->OldHW)
-
#ifndef AVOID_CPIO
xf86Int10InfoPtr pInt10Info = NULL;
@@ -1252,62 +1930,7 @@ ATIPreInit(ScrnInfoPtr pScreenInfo, int flags)
if (pATI->Chip >= ATI_CHIP_264CT) {
pATI->MemoryType = GetBits(IOValue, CFG_MEM_TYPE_T);
- /* Get LCD panel id */
- if (pATI->Chip == ATI_CHIP_264LT) {
- pATI->LCDPanelID = GetBits(IOValue, CFG_PANEL_ID);
-
- pATIHW->horz_stretching = inr(HORZ_STRETCHING);
- pATIHW->vert_stretching = inr(VERT_STRETCHING);
- pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
- } else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
- (pATI->Chip == ATI_CHIP_264XL) ||
- (pATI->Chip == ATI_CHIP_MOBILITY)) {
- pATI->LCDPanelID = GetBits(IOValue, CFG_PANEL_ID);
-
- pATIHW->lcd_index = inr(LCD_INDEX);
- pATIHW->horz_stretching = ATIMach64GetLCDReg(LCD_HORZ_STRETCHING);
- pATI->LCDHorizontal = GetBits(pATIHW->horz_stretching,
- HORZ_PANEL_SIZE);
- if (pATI->LCDHorizontal) {
- if (pATI->LCDHorizontal == MaxBits(HORZ_PANEL_SIZE))
- pATI->LCDHorizontal = 0;
- else
- pATI->LCDHorizontal = (pATI->LCDHorizontal + 1) << 3;
- }
- pATIHW->ext_vert_stretch = ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH);
- pATI->LCDVertical = GetBits(pATIHW->ext_vert_stretch,
- VERT_PANEL_SIZE);
- if (pATI->LCDVertical) {
- if (pATI->LCDVertical == MaxBits(VERT_PANEL_SIZE))
- pATI->LCDVertical = 0;
- else
- pATI->LCDVertical++;
- }
- pATIHW->vert_stretching = ATIMach64GetLCDReg(LCD_VERT_STRETCHING);
- pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
- outr(LCD_INDEX, pATIHW->lcd_index);
- }
-
- /*
- * Don't bother with panel support if it hasn't been previously
- * enabled.
- */
- if ((pATI->LCDPanelID >= 0) &&
- !(pATIHW->horz_stretching & HORZ_STRETCH_EN) &&
- !(pATIHW->vert_stretching & VERT_STRETCH_EN) &&
- !(pATIHW->lcd_gen_ctrl & LCD_ON)) {
- /*
- * At this point, if an XL or Mobility BIOS hasn't set
- * panel dimensions, then there is no panel. Otherwise,
- * keep any panel disabled to allow for modes greater than
- * the panel's dimensions.
- */
- if ((pATI->Chip >= ATI_CHIP_264XL) &&
- (!pATI->LCDHorizontal || !pATI->LCDVertical))
- pATI->LCDPanelID = -1;
- else
- pATI->OptionPanelDisplay = FALSE;
- }
+ Mach64PanelScratchInfoGet(pATI);
} else {
pATI->MemoryType = GetBits(IOValue, CFG_MEM_TYPE);
@@ -1531,592 +2154,21 @@ ATIPreInit(ScrnInfoPtr pScreenInfo, int flags)
#endif /* AVOID_CPIO */
- /*
- * Decide between the CRT and the panel.
- */
- if (pATI->LCDPanelID >= 0)
- {
+ if (pATI->LCDPanelID >= 0) {
if (!pATI->OptionPanelDisplay)
- {
xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
"Using CRT interface and disabling digital flat panel.\n");
- }
+ else if (!Mach64PanelInfoGet(pATI)) {
+ ATILock(pATI);
+ ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize);
+ ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);
+ return FALSE;
+ } else if (pATI->OptionCRTDisplay)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Using digital flat "
+ "panel interface to display on both CRT and panel.\n");
else
- {
- unsigned HDisplay, VDisplay;
- CARD8 ClockMask, PostMask;
-
- /*
- * Determine porch data. This groks the mode on entry to extract
- * the width and position of its sync and blanking pulses, and
- * considers any overscan as part of the displayed area, given that
- * the overscan is also stretched.
- *
- * This also attempts to determine panel dimensions but cannot do
- * so for one that is "auto-stretched".
- */
-
- if (pATI->Chip == ATI_CHIP_264LT)
- {
- pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
-
- /* Set up to read non-shadow registers */
- if (pATIHW->lcd_gen_ctrl & SHADOW_RW_EN)
- outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
- }
- else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
- (pATI->Chip == ATI_CHIP_264XL) ||
- (pATI->Chip == ATI_CHIP_MOBILITY)) */
- {
- pATIHW->lcd_index = inr(LCD_INDEX);
- pATIHW->config_panel = ATIMach64GetLCDReg(LCD_CONFIG_PANEL);
- pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
-
- /* Set up to read non-shadow registers */
- if (pATIHW->lcd_gen_ctrl & SHADOW_RW_EN)
- ATIMach64PutLCDReg(LCD_GEN_CNTL,
- pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
- }
-
-#ifndef AVOID_CPIO
-
- if (!(pATIHW->crtc_gen_cntl & CRTC_EXT_DISP_EN))
- {
- unsigned HBlankStart, HSyncStart, HSyncEnd, HBlankEnd, HTotal;
- unsigned VBlankStart, VSyncStart, VSyncEnd, VBlankEnd, VTotal;
-
- pATIHW->clock = (inb(R_GENMO) & 0x0CU) >> 2;
-
- pATIHW->crt[2] = GetReg(CRTX(pATI->CPIO_VGABase), 0x02U);
- pATIHW->crt[3] = GetReg(CRTX(pATI->CPIO_VGABase), 0x03U);
- pATIHW->crt[5] = GetReg(CRTX(pATI->CPIO_VGABase), 0x05U);
- pATIHW->crt[7] = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U);
- pATIHW->crt[9] = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U);
- pATIHW->crt[21] = GetReg(CRTX(pATI->CPIO_VGABase), 0x15U);
- pATIHW->crt[22] = GetReg(CRTX(pATI->CPIO_VGABase), 0x16U);
-
- pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP);
- pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
- pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP);
- pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
-
- /* Switch to shadow registers */
- if (pATI->Chip == ATI_CHIP_264LT)
- outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
- else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
- (pATI->Chip == ATI_CHIP_264XL) ||
- (pATI->Chip == ATI_CHIP_MOBILITY)) */
- ATIMach64PutLCDReg(LCD_GEN_CNTL,
- pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
-
- pATIHW->shadow_vga[2] =
- GetReg(CRTX(pATI->CPIO_VGABase), 0x02U);
- pATIHW->shadow_vga[3] =
- GetReg(CRTX(pATI->CPIO_VGABase), 0x03U);
- pATIHW->shadow_vga[5] =
- GetReg(CRTX(pATI->CPIO_VGABase), 0x05U);
- pATIHW->shadow_vga[7] =
- GetReg(CRTX(pATI->CPIO_VGABase), 0x07U);
- pATIHW->shadow_vga[9] =
- GetReg(CRTX(pATI->CPIO_VGABase), 0x09U);
- pATIHW->shadow_vga[21] =
- GetReg(CRTX(pATI->CPIO_VGABase), 0x15U);
- pATIHW->shadow_vga[22] =
- GetReg(CRTX(pATI->CPIO_VGABase), 0x16U);
-
- pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP);
- pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
- pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP);
- pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
-
- /*
- * HSyncStart and HSyncEnd should equal their shadow
- * counterparts. Otherwise, due to a chip bug, the panel might
- * not sync, regardless of which register set is used to drive
- * the panel. There are certain combinations of register
- * values where the panel does in fact sync, but it remains
- * impossible to accurately determine the horizontal sync pulse
- * timing actually seen by the panel.
- *
- * Note that this hardware bug does not affect the CRT output.
- */
- if (((pATIHW->crtc_h_sync_strt_wid ^
- pATIHW->shadow_h_sync_strt_wid) &
- (CRTC_H_SYNC_STRT | CRTC_H_SYNC_STRT_HI |
- CRTC_H_SYNC_WID)))
- {
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_NOTICE, 0,
- "Invalid horizontal sync pulse timing detected in mode"
- " on server entry.\n");
-
- /* Don't trust input timing */
- pATI->OptionLCDSync = TRUE;
- ModeType = 0;
- }
-
- /* Merge in shadow registers as appropriate */
- if (pATIHW->lcd_gen_ctrl & SHADOW_EN)
- {
- pATIHW->crt[2] = pATIHW->shadow_vga[2];
- pATIHW->crt[3] = pATIHW->shadow_vga[3];
- pATIHW->crt[5] = pATIHW->shadow_vga[5];
-
- /* XXX Does this apply to VGA? If so, what about the LT? */
- if ((pATI->Chip < ATI_CHIP_264LTPRO) ||
- !(pATIHW->config_panel & DONT_SHADOW_HEND))
- {
- pATIHW->crtc_h_total_disp &= ~CRTC_H_DISP;
- pATIHW->crtc_h_total_disp |=
- pATIHW->shadow_h_total_disp & CRTC_H_DISP;
- }
-
- pATIHW->crtc_h_total_disp &= ~CRTC_H_TOTAL;
- pATIHW->crtc_h_total_disp |=
- pATIHW->shadow_h_total_disp & CRTC_H_TOTAL;
- pATIHW->crtc_h_sync_strt_wid =
- pATIHW->shadow_h_sync_strt_wid;
-
- /* XXX Does this apply to VGA? */
- if (pATIHW->lcd_gen_ctrl & USE_SHADOWED_VEND)
- {
- pATIHW->crtc_v_total_disp &= ~CRTC_V_DISP;
- pATIHW->crtc_v_total_disp |=
- pATIHW->shadow_v_total_disp & CRTC_V_DISP;
- }
-
- if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR))
- {
- pATIHW->crt[7] = pATIHW->shadow_vga[7];
- pATIHW->crt[9] = pATIHW->shadow_vga[9];
- pATIHW->crt[21] = pATIHW->shadow_vga[21];
- pATIHW->crt[22] = pATIHW->shadow_vga[22];
-
- pATIHW->crtc_v_total_disp &= ~CRTC_V_TOTAL;
- pATIHW->crtc_v_total_disp |=
- pATIHW->shadow_v_total_disp & CRTC_V_TOTAL;
- }
- }
-
- if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR))
- pATIHW->crtc_v_sync_strt_wid =
- pATIHW->shadow_v_sync_strt_wid;
-
- /*
- * Decipher input timing. This is complicated by the fact that
- * the full width of all timing parameters, except for the
- * blanking pulses, is only available through the accelerator
- * registers, not the VGA ones. Blanking pulse boundaries must
- * then be interpolated.
- *
- * Note that, in VGA mode, the accelerator's sync width fields
- * are actually end positions, not widths.
- */
- HDisplay = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_DISP);
- HSyncStart =
- (GetBits(pATIHW->crtc_h_sync_strt_wid,
- CRTC_H_SYNC_STRT_HI) *
- (MaxBits(CRTC_H_SYNC_STRT) + 1)) |
- GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT);
- HSyncEnd = (HSyncStart & ~MaxBits(CRTC_H_SYNC_WID)) |
- GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_WID);
- if (HSyncStart >= HSyncEnd)
- HSyncEnd += MaxBits(CRTC_H_SYNC_WID) + 1;
- HTotal = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_TOTAL);
-
- HBlankStart = (HDisplay & ~0xFFU) | pATIHW->crt[2];
- if (HDisplay > HBlankStart)
- HBlankStart += 0x0100U;
- HBlankEnd = (HSyncEnd & ~0x3FU) |
- ((pATIHW->crt[5] >> 2) & 0x20U) |
- (pATIHW->crt[3] & 0x1FU);
- if (HSyncEnd > (HBlankEnd + 1))
- HBlankEnd += 0x40U;
-
- VDisplay = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_DISP);
- VSyncStart =
- GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_STRT);
- VSyncEnd = (VSyncStart & ~MaxBits(CRTC_V_SYNC_END_VGA)) |
- GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_END_VGA);
- if (VSyncStart > VSyncEnd)
- VSyncEnd += MaxBits(CRTC_V_SYNC_END_VGA) + 1;
- VTotal = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_TOTAL);
-
- VBlankStart = (VDisplay & ~0x03FFU) |
- ((pATIHW->crt[9] << 4) & 0x0200U) |
- ((pATIHW->crt[7] << 5) & 0x0100U) | pATIHW->crt[21];
- if (VDisplay > VBlankStart)
- VBlankStart += 0x0400U;
- VBlankEnd = (VSyncEnd & ~0x00FFU) | pATIHW->crt[22];
- if (VSyncEnd > (VBlankEnd + 1))
- VBlankEnd += 0x0100U;
-
- pATI->LCDHBlankWidth = HBlankEnd - HBlankStart;
- pATI->LCDHSyncStart = HSyncStart - HBlankStart;
- pATI->LCDHSyncWidth = HSyncEnd - HSyncStart;
-
- pATI->LCDVBlankWidth = VBlankEnd - VBlankStart;
- pATI->LCDVSyncStart = VSyncStart - VBlankStart;
- pATI->LCDVSyncWidth = VSyncEnd - VSyncStart;
-
- HDisplay = HTotal + 5 - pATI->LCDHBlankWidth;
- VDisplay = VTotal + 2 - pATI->LCDVBlankWidth;
- }
- else
-
-#endif /* AVOID_CPIO */
-
- {
- pATIHW->clock = inr(CLOCK_CNTL) & 0x03U;
-
- pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP);
- pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
- pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP);
- pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
- pATIHW->ovr_wid_left_right = inr(OVR_WID_LEFT_RIGHT);
- pATIHW->ovr_wid_top_bottom = inr(OVR_WID_TOP_BOTTOM);
-
- /* Switch to shadow registers */
- if (pATI->Chip == ATI_CHIP_264LT)
- outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
- else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
- (pATI->Chip == ATI_CHIP_264XL) ||
- (pATI->Chip == ATI_CHIP_MOBILITY)) */
- ATIMach64PutLCDReg(LCD_GEN_CNTL,
- pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
-
- /* Oddly enough, there are no shadow overscan registers */
- pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP);
- pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
- pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP);
- pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
-
- /*
- * HSyncStart and HSyncEnd should equal their shadow
- * counterparts. Otherwise, due to a chip bug, the panel might
- * not sync, regardless of which register set is used to drive
- * the panel. There are certain combinations of register
- * values where the panel does in fact sync, but it remains
- * impossible to accurately determine the horizontal sync pulse
- * timing actually seen by the panel.
- *
- * Note that this hardware bug does not affect the CRT output.
- */
- if (((pATIHW->crtc_h_sync_strt_wid ^
- pATIHW->shadow_h_sync_strt_wid) &
- (CRTC_H_SYNC_STRT | CRTC_H_SYNC_STRT_HI |
- CRTC_H_SYNC_WID)))
- {
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_NOTICE, 0,
- "Invalid horizontal sync pulse timing detected in mode"
- " on server entry.\n");
-
- /* Don't trust input timing */
- pATI->OptionLCDSync = TRUE;
- ModeType = 0;
- }
-
- /* Merge in shadow registers as appropriate */
- if (pATIHW->lcd_gen_ctrl & SHADOW_EN)
- {
- /* XXX What about the LT? */
- if ((pATI->Chip < ATI_CHIP_264LTPRO) ||
- !(pATIHW->config_panel & DONT_SHADOW_HEND))
- {
- pATIHW->crtc_h_total_disp &= ~CRTC_H_DISP;
- pATIHW->crtc_h_total_disp |=
- pATIHW->shadow_h_total_disp & CRTC_H_DISP;
- }
-
- pATIHW->crtc_h_total_disp &= ~CRTC_H_TOTAL;
- pATIHW->crtc_h_total_disp |=
- pATIHW->shadow_h_total_disp & CRTC_H_TOTAL;
- pATIHW->crtc_h_sync_strt_wid =
- pATIHW->shadow_h_sync_strt_wid;
-
- if (pATIHW->lcd_gen_ctrl & USE_SHADOWED_VEND)
- {
- pATIHW->crtc_v_total_disp &= ~CRTC_V_DISP;
- pATIHW->crtc_v_total_disp |=
- pATIHW->shadow_v_total_disp & CRTC_V_DISP;
- }
-
- if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR))
- {
- pATIHW->crtc_v_total_disp &= ~CRTC_V_TOTAL;
- pATIHW->crtc_v_total_disp |=
- pATIHW->shadow_v_total_disp & CRTC_V_TOTAL;
- }
- }
-
- if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR))
- pATIHW->crtc_v_sync_strt_wid =
- pATIHW->shadow_v_sync_strt_wid;
-
- /* Decipher input timing */
- HDisplay = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_DISP) +
- GetBits(pATIHW->ovr_wid_left_right, OVR_WID_LEFT) +
- GetBits(pATIHW->ovr_wid_left_right, OVR_WID_RIGHT);
- VDisplay = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_DISP) +
- GetBits(pATIHW->ovr_wid_top_bottom, OVR_WID_TOP) +
- GetBits(pATIHW->ovr_wid_top_bottom, OVR_WID_BOTTOM);
-
- pATI->LCDHSyncStart =
- (GetBits(pATIHW->crtc_h_sync_strt_wid,
- CRTC_H_SYNC_STRT_HI) *
- (MaxBits(CRTC_H_SYNC_STRT) + 1)) +
- GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT) -
- HDisplay;
- pATI->LCDHSyncWidth =
- GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_WID);
- pATI->LCDHBlankWidth =
- GetBits(pATIHW->crtc_h_total_disp, CRTC_H_TOTAL) -
- HDisplay;
- pATI->LCDVSyncStart =
- GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_STRT) -
- VDisplay;
- pATI->LCDVSyncWidth =
- GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_WID);
- pATI->LCDVBlankWidth =
- GetBits(pATIHW->crtc_v_total_disp, CRTC_V_TOTAL) -
- VDisplay;
-
- HDisplay++;
- VDisplay++;
- }
-
- /* Restore LCD registers */
- if (pATI->Chip == ATI_CHIP_264LT)
- {
- outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
- }
- else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
- (pATI->Chip == ATI_CHIP_264XL) ||
- (pATI->Chip == ATI_CHIP_MOBILITY)) */
- {
- ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl);
- outr(LCD_INDEX, pATIHW->lcd_index);
- }
-
- HDisplay <<= 3;
- pATI->LCDHSyncStart <<= 3;
- pATI->LCDHSyncWidth <<= 3;
- pATI->LCDHBlankWidth <<= 3;
-
- /* Calculate panel dimensions implied by the input timing */
- if ((pATIHW->horz_stretching &
- (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) ==
- HORZ_STRETCH_EN)
- {
- if (pATIHW->horz_stretching & HORZ_STRETCH_MODE)
- {
- if (pATIHW->horz_stretching & HORZ_STRETCH_BLEND)
- {
- HDisplay =
- (HDisplay * (MaxBits(HORZ_STRETCH_BLEND) + 1)) /
- GetBits(pATIHW->horz_stretching,
- HORZ_STRETCH_BLEND);
- }
- }
- else if (((pATIHW->horz_stretching & HORZ_STRETCH_LOOP) >
- HORZ_STRETCH_LOOP15) ||
- (pATIHW->horz_stretching &
- SetBits(1, HORZ_STRETCH_RATIO)))
- {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
- "Ignoring invalid horizontal stretch ratio in mode on"
- " server entry.\n");
- }
- else
- {
- IOValue =
- GetBits(pATIHW->horz_stretching, HORZ_STRETCH_RATIO);
-
- switch (GetBits(pATIHW->horz_stretching,
- HORZ_STRETCH_LOOP))
- {
- case GetBits(HORZ_STRETCH_LOOP09, HORZ_STRETCH_LOOP):
- i = 9;
- IOValue &= (1 << 9) - 1;
- break;
-
- case GetBits(HORZ_STRETCH_LOOP11, HORZ_STRETCH_LOOP):
- i = 11;
- IOValue &= (1 << 11) - 1;
- break;
-
- case GetBits(HORZ_STRETCH_LOOP12, HORZ_STRETCH_LOOP):
- i = 12;
- IOValue &= (1 << 12) - 1;
- break;
-
- case GetBits(HORZ_STRETCH_LOOP14, HORZ_STRETCH_LOOP):
- i = 14;
- IOValue &= (1 << 14) - 1;
- break;
-
- case GetBits(HORZ_STRETCH_LOOP15, HORZ_STRETCH_LOOP):
- default: /* Muffle compiler */
- i = 15;
- IOValue &= (1 << 15) - 1;
- break;
- }
-
- if (IOValue)
- {
- /* Count the number of bits in IOValue */
- j = (IOValue >> 1) & 0x36DBU;
- j = IOValue - j - ((j >> 1) & 0x36DBU);
- j = ((j + (j >> 3)) & 0x71C7U) % 0x3FU;
-
- HDisplay = (HDisplay * i) / j;
- }
- }
- }
-
- if ((pATIHW->vert_stretching & VERT_STRETCH_EN) &&
- !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO))
- {
- if ((pATIHW->vert_stretching & VERT_STRETCH_USE0) ||
- (VDisplay <= 350))
- IOValue =
- GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO0);
- else if (VDisplay <= 400)
- IOValue =
- GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO1);
- else if ((VDisplay <= 480) ||
- !(pATIHW->ext_vert_stretch & VERT_STRETCH_RATIO3))
- IOValue =
- GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO2);
- else
- IOValue =
- GetBits(pATIHW->ext_vert_stretch, VERT_STRETCH_RATIO3);
-
- if (IOValue)
- VDisplay =
- (VDisplay * (MaxBits(VERT_STRETCH_RATIO0) + 1)) /
- IOValue;
- }
-
- /* Match calculated dimensions to probed dimensions */
- if (!pATI->LCDHorizontal)
- {
- if ((pATIHW->horz_stretching &
- (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) !=
- (HORZ_STRETCH_EN | AUTO_HORZ_RATIO))
- pATI->LCDHorizontal = HDisplay;
- }
- else if (pATI->LCDHorizontal != (int)HDisplay)
- {
- if ((pATIHW->horz_stretching &
- (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) !=
- (HORZ_STRETCH_EN | AUTO_HORZ_RATIO))
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 4,
- "Inconsistent panel horizontal dimension:"
- " %d and %d.\n", pATI->LCDHorizontal, HDisplay);
- HDisplay = pATI->LCDHorizontal;
- }
-
- if (!pATI->LCDVertical)
- {
- if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) ||
- !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO))
- pATI->LCDVertical = VDisplay;
- }
- else if (pATI->LCDVertical != (int)VDisplay)
- {
- if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) ||
- !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO))
- xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 4,
- "Inconsistent panel vertical dimension: %d and %d.\n",
- pATI->LCDVertical, VDisplay);
- VDisplay = pATI->LCDVertical;
- }
-
- if (!pATI->LCDHorizontal || !pATI->LCDVertical)
- {
- if (pATI->LCDPanelID || (pATI->Chip <= ATI_CHIP_264LTPRO))
- xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
- "Unable to determine dimensions of panel (ID %d).\n",
- pATI->LCDPanelID);
- else
- xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
- "Unable to determine dimensions of panel.\n");
-
- ATILock(pATI);
- ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize);
- ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);
- return FALSE;
- }
-
- /* If the mode on entry wasn't stretched, adjust timings */
- if (!(pATIHW->horz_stretching & HORZ_STRETCH_EN) &&
- (pATI->LCDHorizontal > (int)HDisplay))
- {
- HDisplay = pATI->LCDHorizontal - HDisplay;
- if (pATI->LCDHSyncStart >= HDisplay)
- pATI->LCDHSyncStart -= HDisplay;
- else
- pATI->LCDHSyncStart = 0;
- pATI->LCDHBlankWidth -= HDisplay;
- HDisplay = pATI->LCDHSyncStart + pATI->LCDHSyncWidth;
- if (pATI->LCDHBlankWidth < HDisplay)
- pATI->LCDHBlankWidth = HDisplay;
- }
-
- if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) &&
- (pATI->LCDVertical > (int)VDisplay))
- {
- VDisplay = pATI->LCDVertical - VDisplay;
- if (pATI->LCDVSyncStart >= VDisplay)
- pATI->LCDVSyncStart -= VDisplay;
- else
- pATI->LCDVSyncStart = 0;
- pATI->LCDVBlankWidth -= VDisplay;
- VDisplay = pATI->LCDVSyncStart + pATI->LCDVSyncWidth;
- if (pATI->LCDVBlankWidth < VDisplay)
- pATI->LCDVBlankWidth = VDisplay;
- }
-
- if (pATI->LCDPanelID || (pATI->Chip <= ATI_CHIP_264LTPRO))
- xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
- "%dx%d panel (ID %d) detected.\n",
- pATI->LCDHorizontal, pATI->LCDVertical, pATI->LCDPanelID);
- else
- xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
- "%dx%d panel detected.\n",
- pATI->LCDHorizontal, pATI->LCDVertical);
-
- /*
- * Determine panel clock. This must be done after option
- * processing so that the adapter's reference frequency is always
- * available.
- *
- * Get post divider. A GCC bug has caused the following expression
- * to be broken down into its individual components.
- */
- ClockMask = PLL_VCLK0_XDIV << pATIHW->clock;
- PostMask = PLL_VCLK0_POST_DIV << (pATIHW->clock * 2);
- i = GetBits(ATIMach64GetPLLReg(PLL_XCLK_CNTL), ClockMask);
- i *= MaxBits(PLL_VCLK0_POST_DIV) + 1;
- i |= GetBits(ATIMach64GetPLLReg(PLL_VCLK_POST_DIV), PostMask);
-
- /* Calculate clock of mode on entry */
- Numerator = ATIMach64GetPLLReg(PLL_VCLK0_FB_DIV + pATIHW->clock) *
- pATI->ReferenceNumerator;
- Denominator = pATI->ClockDescriptor.MinM *
- pATI->ReferenceDenominator *
- pATI->ClockDescriptor.PostDividers[i];
- pATI->LCDClock = ATIDivide(Numerator, Denominator, 1, 0);
-
- xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
- "Panel clock is %.3f MHz.\n",
- (double)(pATI->LCDClock) / 1000.0);
-
- xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
- "Using digital flat panel interface%s.\n",
- pATI->OptionCRTDisplay ?
- " to display on both CRT and panel" : "");
- }
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Using digital flat panel interface.\n");
}
/*
@@ -2802,127 +2854,7 @@ ATIPreInit(ScrnInfoPtr pScreenInfo, int flags)
}
if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
- {
- /*
- * Given LCD modes are more tightly controlled than CRT modes, allow
- * the user the option of not specifying a panel's horizontal sync
- * and/or vertical refresh tolerances.
- */
- Strategy |= LOOKUP_OPTIONAL_TOLERANCES;
-
- if (ModeType == M_T_BUILTIN)
- {
- /*
- * Add a mode to the end of the monitor's list for the panel's
- * native resolution.
- */
- pMode = (DisplayModePtr)xnfcalloc(1, SizeOf(DisplayModeRec));
- pMode->name = "Native panel mode";
- pMode->type = M_T_BUILTIN;
- pMode->Clock = pATI->LCDClock;
- pMode->HDisplay = pATI->LCDHorizontal;
- pMode->VDisplay = pATI->LCDVertical;
-
- /*
- * These timings are bogus, but enough to survive sync tolerance
- * checks.
- */
- pMode->HSyncStart = pMode->HDisplay;
- pMode->HSyncEnd = pMode->HSyncStart + minPitch;
- pMode->HTotal = pMode->HSyncEnd + minPitch;
- pMode->VSyncStart = pMode->VDisplay;
- pMode->VSyncEnd = pMode->VSyncStart + 1;
- pMode->VTotal = pMode->VSyncEnd + 1;
-
- pMode->CrtcHDisplay = pMode->HDisplay;
- pMode->CrtcHBlankStart = pMode->HDisplay;
- pMode->CrtcHSyncStart = pMode->HSyncStart;
- pMode->CrtcHSyncEnd = pMode->HSyncEnd;
- pMode->CrtcHBlankEnd = pMode->HTotal;
- pMode->CrtcHTotal = pMode->HTotal;
-
- pMode->CrtcVDisplay = pMode->VDisplay;
- pMode->CrtcVBlankStart = pMode->VDisplay;
- pMode->CrtcVSyncStart = pMode->VSyncStart;
- pMode->CrtcVSyncEnd = pMode->VSyncEnd;
- pMode->CrtcVBlankEnd = pMode->VTotal;
- pMode->CrtcVTotal = pMode->VTotal;
-
- if (!pScreenInfo->monitor->Modes)
- {
- pScreenInfo->monitor->Modes = pMode;
- }
- else
- {
- pScreenInfo->monitor->Last->next = pMode;
- pMode->prev = pScreenInfo->monitor->Last;
- }
-
- pScreenInfo->monitor->Last = pMode;
- }
-
- /*
- * Defeat Xconfigurator brain damage. Ignore all HorizSync and
- * VertRefresh specifications. For now, this does not take
- * SYNC_TOLERANCE into account.
- */
- if (pScreenInfo->monitor->nHsync > 0)
- {
- double hsync = (double)pATI->LCDClock /
- (pATI->LCDHorizontal + pATI->LCDHBlankWidth);
-
- for (i = 0; ; i++)
- {
- if (i >= pScreenInfo->monitor->nHsync)
- {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
- "Conflicting XF86Config HorizSync specification(s)"
- " ignored.\n");
- break;
- }
-
- if ((hsync >= pScreenInfo->monitor->hsync[i].lo) &&
- (hsync <= pScreenInfo->monitor->hsync[i].hi))
- {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
- "Extraneous XF86Config HorizSync specification(s)"
- " ignored.\n");
- break;
- }
- }
-
- pScreenInfo->monitor->nHsync = 0;
- }
-
- if (pScreenInfo->monitor->nVrefresh > 0)
- {
- double vrefresh = ((double)pATI->LCDClock * 1000.0) /
- ((pATI->LCDHorizontal + pATI->LCDHBlankWidth) *
- (pATI->LCDVertical + pATI->LCDVBlankWidth));
-
- for (i = 0; ; i++)
- {
- if (i >= pScreenInfo->monitor->nVrefresh)
- {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
- "Conflicting XF86Config VertRefresh specification(s)"
- " ignored.\n");
- break;
- }
-
- if ((vrefresh >= pScreenInfo->monitor->vrefresh[i].lo) &&
- (vrefresh <= pScreenInfo->monitor->vrefresh[i].hi))
- {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
- "Extraneous XF86Config VertRefresh specification(s)"
- " ignored.\n");
- break;
- }
- }
-
- pScreenInfo->monitor->nVrefresh = 0;
- }
- }
+ Mach64PanelMonitor(pScreenInfo);
i = xf86ValidateModes(pScreenInfo,
pScreenInfo->monitor->Modes, pScreenInfo->display->modes,
diff --git a/src/atistruct.h b/src/atistruct.h
index 08bbb0e..3078aaf 100644
--- a/src/atistruct.h
+++ b/src/atistruct.h
@@ -181,6 +181,8 @@ typedef struct _ATIHWRec
*/
typedef struct _ATIRec
{
+ int scrnIndex; /* stop us from passing pScrn everywhere */
+
#ifndef AVOID_CPIO
Bool IsVGA;