summaryrefslogtreecommitdiff
path: root/src/atimode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/atimode.c')
-rw-r--r--src/atimode.c1185
1 files changed, 0 insertions, 1185 deletions
diff --git a/src/atimode.c b/src/atimode.c
deleted file mode 100644
index 02cf3193..00000000
--- a/src/atimode.c
+++ /dev/null
@@ -1,1185 +0,0 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimode.c,v 1.17 2003/04/23 21:51:29 tsi Exp $ */
-/*
- * Copyright 2000 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of Marc Aurele La France not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. Marc Aurele La France makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as-is" without express or implied warranty.
- *
- * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
- * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "ati.h"
-#include "atiadapter.h"
-#include "atichip.h"
-#include "atidac.h"
-#include "atidsp.h"
-#include "atimach64.h"
-#include "atimach64io.h"
-#include "atimode.h"
-#include "atiprint.h"
-#include "atirgb514.h"
-#include "ativga.h"
-#include "atiwonder.h"
-#include "atiwonderio.h"
-
-#ifndef AVOID_CPIO
-
-/*
- * ATICopyVGAMemory --
- *
- * This function is called to copy one or all banks of a VGA plane.
- */
-static void
-ATICopyVGAMemory
-(
- ATIPtr pATI,
- ATIHWPtr pATIHW,
- pointer *saveptr,
- pointer *from,
- pointer *to
-)
-{
- unsigned int iBank;
-
- for (iBank = 0; iBank < pATIHW->nBank; iBank++)
- {
- (*pATIHW->SetBank)(pATI, iBank);
- (void)memcpy(*to, *from, 0x00010000U);
- *saveptr = (char *)(*saveptr) + 0x00010000U;
- }
-}
-
-/*
- * ATISwap --
- *
- * This function saves/restores video memory contents during video mode
- * switches.
- */
-static void
-ATISwap
-(
- int iScreen,
- ATIPtr pATI,
- ATIHWPtr pATIHW,
- Bool ToFB
-)
-{
- pointer save, *from, *to;
- unsigned int iPlane = 0, PlaneMask = 1;
- CARD8 seq2, seq4, gra1, gra3, gra4, gra5, gra6, gra8;
-
- /*
- * This is only done for non-accelerator modes. If the video state on
- * server entry was an accelerator mode, the application that relinquished
- * the console had better do the Right Thing (tm) anyway by saving and
- * restoring its own video memory contents.
- */
- if (pATIHW->crtc != ATI_CRTC_VGA)
- return;
-
- if (ToFB)
- {
- if (!pATIHW->frame_buffer)
- return;
-
- from = &save;
- to = &pATI->pBank;
- }
- else
- {
- /* Allocate the memory */
- if (!pATIHW->frame_buffer)
- {
- pATIHW->frame_buffer =
- (pointer)xalloc(pATIHW->nBank * pATIHW->nPlane * 0x00010000U);
- if (!pATIHW->frame_buffer)
- {
- xf86DrvMsg(iScreen, X_WARNING,
- "Temporary frame buffer could not be allocated.\n");
- return;
- }
- }
-
- from = &pATI->pBank;
- to = &save;
- }
-
- /* Turn off screen */
- ATIVGASaveScreen(pATI, SCREEN_SAVER_ON);
-
- /* Save register values to be modified */
- seq2 = GetReg(SEQX, 0x02U);
- seq4 = GetReg(SEQX, 0x04U);
- gra1 = GetReg(GRAX, 0x01U);
- gra3 = GetReg(GRAX, 0x03U);
- gra4 = GetReg(GRAX, 0x04U);
- gra5 = GetReg(GRAX, 0x05U);
- gra6 = GetReg(GRAX, 0x06U);
- gra8 = GetReg(GRAX, 0x08U);
-
- save = pATIHW->frame_buffer;
-
- /* Temporarily normalise the mode */
- if (gra1 != 0x00U)
- PutReg(GRAX, 0x01U, 0x00U);
- if (gra3 != 0x00U)
- PutReg(GRAX, 0x03U, 0x00U);
- if (gra6 != 0x05U)
- PutReg(GRAX, 0x06U, 0x05U);
- if (gra8 != 0xFFU)
- PutReg(GRAX, 0x08U, 0xFFU);
-
- if (seq4 & 0x08U)
- {
- /* Setup packed mode memory */
- if (seq2 != 0x0FU)
- PutReg(SEQX, 0x02U, 0x0FU);
- if (seq4 != 0x0AU)
- PutReg(SEQX, 0x04U, 0x0AU);
- if (pATI->Chip < ATI_CHIP_264CT)
- {
- if (gra5 != 0x00U)
- PutReg(GRAX, 0x05U, 0x00U);
- }
- else
- {
- if (gra5 != 0x40U)
- PutReg(GRAX, 0x05U, 0x40U);
- }
-
- ATICopyVGAMemory(pATI, pATIHW, &save, from, to);
-
- if (seq2 != 0x0FU)
- PutReg(SEQX, 0x02U, seq2);
- if (seq4 != 0x0AU)
- PutReg(SEQX, 0x04U, seq4);
- if (pATI->Chip < ATI_CHIP_264CT)
- {
- if (gra5 != 0x00U)
- PutReg(GRAX, 0x05U, gra5);
- }
- else
- {
- if (gra5 != 0x40U)
- PutReg(GRAX, 0x05U, gra5);
- }
- }
- else
- {
- gra4 = GetReg(GRAX, 0x04U);
-
- /* Setup planar mode memory */
- if (seq4 != 0x06U)
- PutReg(SEQX, 0x04U, 0x06U);
- if (gra5 != 0x00U)
- PutReg(GRAX, 0x05U, 0x00U);
-
- for (; iPlane < pATIHW->nPlane; iPlane++)
- {
- PutReg(SEQX, 0x02U, PlaneMask);
- PutReg(GRAX, 0x04U, iPlane);
- ATICopyVGAMemory(pATI, pATIHW, &save, from, to);
- PlaneMask <<= 1;
- }
-
- PutReg(SEQX, 0x02U, seq2);
- if (seq4 != 0x06U)
- PutReg(SEQX, 0x04U, seq4);
- PutReg(GRAX, 0x04U, gra4);
- if (gra5 != 0x00U)
- PutReg(GRAX, 0x05U, gra5);
- }
-
- /* Restore registers */
- if (gra1 != 0x00U)
- PutReg(GRAX, 0x01U, gra1);
- if (gra3 != 0x00U)
- PutReg(GRAX, 0x03U, gra3);
- if (gra6 != 0x05U)
- PutReg(GRAX, 0x06U, gra6);
- if (gra8 != 0xFFU)
- PutReg(GRAX, 0x08U, gra8);
-
- /* Back to bank 0 */
- (*pATIHW->SetBank)(pATI, 0);
-
- /*
- * If restoring video memory for a server video mode, free the frame buffer
- * save area.
- */
- if (ToFB && (pATIHW == &pATI->NewHW))
- {
- xfree(pATIHW->frame_buffer);
- pATIHW->frame_buffer = NULL;
- }
-}
-
-#endif /* AVOID_CPIO */
-
-/*
- * ATIModePreInit --
- *
- * This function initialises an ATIHWRec with information common to all video
- * states generated by the driver.
- */
-void
-ATIModePreInit
-(
- ScrnInfoPtr pScreenInfo,
- ATIPtr pATI,
- ATIHWPtr pATIHW
-)
-{
- CARD32 lcd_index;
-
-#ifndef AVOID_CPIO
-
- if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
- {
- /* Fill in VGA data */
- ATIVGAPreInit(pATI, pATIHW);
-
- /* Fill in VGA Wonder data */
- if (pATI->CPIO_VGAWonder)
- ATIVGAWonderPreInit(pATI, pATIHW);
- }
-
- if (pATI->Chip >= ATI_CHIP_88800GXC)
-
-#endif /* AVOID_CPIO */
-
- {
- /* Fill in Mach64 data */
- ATIMach64PreInit(pScreenInfo, pATI, pATIHW);
-
- if (pATI->Chip >= ATI_CHIP_264CT)
- {
- /* Ensure proper VCLK source */
- pATIHW->pll_vclk_cntl = ATIMach64GetPLLReg(PLL_VCLK_CNTL) |
- (PLL_VCLK_SRC_SEL | PLL_VCLK_RESET);
-
- /* Set provisional values for other PLL registers */
- pATIHW->pll_vclk_post_div = ATIMach64GetPLLReg(PLL_VCLK_POST_DIV);
- pATIHW->pll_vclk0_fb_div = ATIMach64GetPLLReg(PLL_VCLK0_FB_DIV);
- pATIHW->pll_vclk1_fb_div = ATIMach64GetPLLReg(PLL_VCLK1_FB_DIV);
- pATIHW->pll_vclk2_fb_div = ATIMach64GetPLLReg(PLL_VCLK2_FB_DIV);
- pATIHW->pll_vclk3_fb_div = ATIMach64GetPLLReg(PLL_VCLK3_FB_DIV);
- pATIHW->pll_xclk_cntl = ATIMach64GetPLLReg(PLL_XCLK_CNTL);
-
- /* For now disable extended reference and feedback dividers */
- if (pATI->Chip >= ATI_CHIP_264LT)
- pATIHW->pll_ext_vpll_cntl =
- ATIMach64GetPLLReg(PLL_EXT_VPLL_CNTL) &
- ~(PLL_EXT_VPLL_EN | PLL_EXT_VPLL_VGA_EN |
- PLL_EXT_VPLL_INSYNC);
-
- /* Initialise CRTC data for LCD panels */
- if (pATI->LCDPanelID >= 0)
- {
- if (pATI->Chip == ATI_CHIP_264LT)
- {
- 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)) */
- {
- lcd_index = inr(LCD_INDEX);
- pATIHW->lcd_index = lcd_index &
- ~(LCD_REG_INDEX | LCD_DISPLAY_DIS | LCD_SRC_SEL |
- LCD_CRTC2_DISPLAY_DIS);
- if (pATI->Chip != ATI_CHIP_264XL)
- pATIHW->lcd_index |= LCD_CRTC2_DISPLAY_DIS;
- pATIHW->config_panel =
- ATIMach64GetLCDReg(LCD_CONFIG_PANEL) |
- DONT_SHADOW_HEND;
- pATIHW->lcd_gen_ctrl =
- ATIMach64GetLCDReg(LCD_GEN_CNTL) & ~CRTC_RW_SELECT;
- outr(LCD_INDEX, lcd_index);
- }
-
- pATIHW->lcd_gen_ctrl &=
- ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | MCLK_PM_EN |
- VCLK_DAC_PM_EN | USE_SHADOWED_VEND |
- USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
- pATIHW->lcd_gen_ctrl |= DONT_SHADOW_VPAR | LOCK_8DOT;
-
- if (!pATI->OptionPanelDisplay)
- {
- /*
- * Use primary CRTC to drive the CRT. Turn off panel
- * interface.
- */
- pATIHW->lcd_gen_ctrl &= ~LCD_ON;
- pATIHW->lcd_gen_ctrl |= CRT_ON;
- }
- else
- {
- /* Use primary CRTC to drive the panel */
- pATIHW->lcd_gen_ctrl |= LCD_ON;
-
- /* If requested, also force CRT on */
- if (pATI->OptionCRTDisplay)
- pATIHW->lcd_gen_ctrl |= CRT_ON;
- }
- }
- }
- else if (pATI->DAC == ATI_DAC_IBMRGB514)
- {
- ATIRGB514PreInit(pATI, pATIHW);
- }
- }
-
- /* Set RAMDAC data */
- ATIDACPreInit(pScreenInfo, pATI, pATIHW);
-}
-
-/*
- * ATIModeSave --
- *
- * This function saves the current video state.
- */
-void
-ATIModeSave
-(
- ScrnInfoPtr pScreenInfo,
- ATIPtr pATI,
- ATIHWPtr pATIHW
-)
-{
-
-#ifndef AVOID_CPIO
-
- int Index;
-
- /* Get bank to bank 0 */
- (*pATIHW->SetBank)(pATI, 0);
-
-#endif /* AVOID_CPIO */
-
- /* Save clock data */
- ATIClockSave(pScreenInfo, pATI, pATIHW);
-
- if (pATI->Chip >= ATI_CHIP_264CT)
- {
- pATIHW->pll_vclk_cntl = ATIMach64GetPLLReg(PLL_VCLK_CNTL) |
- PLL_VCLK_RESET;
- pATIHW->pll_vclk_post_div = ATIMach64GetPLLReg(PLL_VCLK_POST_DIV);
- pATIHW->pll_vclk0_fb_div = ATIMach64GetPLLReg(PLL_VCLK0_FB_DIV);
- pATIHW->pll_vclk1_fb_div = ATIMach64GetPLLReg(PLL_VCLK1_FB_DIV);
- pATIHW->pll_vclk2_fb_div = ATIMach64GetPLLReg(PLL_VCLK2_FB_DIV);
- pATIHW->pll_vclk3_fb_div = ATIMach64GetPLLReg(PLL_VCLK3_FB_DIV);
- pATIHW->pll_xclk_cntl = ATIMach64GetPLLReg(PLL_XCLK_CNTL);
- if (pATI->Chip >= ATI_CHIP_264LT)
- pATIHW->pll_ext_vpll_cntl = ATIMach64GetPLLReg(PLL_EXT_VPLL_CNTL);
-
- /* Save LCD registers */
- if (pATI->LCDPanelID >= 0)
- {
- if (pATI->Chip == ATI_CHIP_264LT)
- {
- pATIHW->horz_stretching = inr(HORZ_STRETCHING);
- pATIHW->vert_stretching = inr(VERT_STRETCHING);
- pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
-
- /* Set up to save non-shadow registers */
- 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);
- pATIHW->horz_stretching =
- ATIMach64GetLCDReg(LCD_HORZ_STRETCHING);
- pATIHW->vert_stretching =
- ATIMach64GetLCDReg(LCD_VERT_STRETCHING);
- pATIHW->ext_vert_stretch =
- ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH);
-
- /* Set up to save non-shadow registers */
- ATIMach64PutLCDReg(LCD_GEN_CNTL,
- pATIHW->lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
- }
- }
- }
-
-#ifndef AVOID_CPIO
-
- if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
- {
- /* Save VGA data */
- ATIVGASave(pATI, pATIHW);
-
- /* Save VGA Wonder data */
- if (pATI->CPIO_VGAWonder)
- ATIVGAWonderSave(pATI, pATIHW);
- }
-
- if (pATI->Chip >= ATI_CHIP_88800GXC)
-
-#endif /* AVOID_CPIO */
-
- {
- /* Save Mach64 data */
- ATIMach64Save(pATI, pATIHW);
-
- if (pATI->Chip >= ATI_CHIP_264VTB)
- {
- /* Save DSP data */
- ATIDSPSave(pATI, pATIHW);
-
- if (pATI->LCDPanelID >= 0)
- {
- /* 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 & ~CRTC_RW_SELECT) |
- SHADOW_RW_EN);
-
-#ifndef AVOID_CPIO
-
- /* Save shadow VGA CRTC registers */
- for (Index = 0;
- Index < NumberOf(pATIHW->shadow_vga);
- Index++)
- pATIHW->shadow_vga[Index] =
- GetReg(CRTX(pATI->CPIO_VGABase), Index);
-
-#endif /* AVOID_CPIO */
-
- /* Save shadow Mach64 CRTC 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);
-
- /* Restore CRTC selection and shadow state */
- 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);
- }
- }
- }
- else if (pATI->DAC == ATI_DAC_IBMRGB514)
- ATIRGB514Save(pATI, pATIHW);
- }
-
-#ifndef AVOID_CPIO
-
- /*
- * For some unknown reason, CLKDIV2 needs to be turned off to save the
- * DAC's LUT reliably on VGA Wonder VLB adapters.
- */
- if ((pATI->Adapter == ATI_ADAPTER_NONISA) && (pATIHW->seq[1] & 0x08U))
- PutReg(SEQX, 0x01U, pATIHW->seq[1] & ~0x08U);
-
-#endif /* AVOID_CPIO */
-
- /* Save RAMDAC state */
- ATIDACSave(pATI, pATIHW);
-
-#ifndef AVOID_CPIO
-
- if ((pATI->Adapter == ATI_ADAPTER_NONISA) && (pATIHW->seq[1] & 0x08U))
- PutReg(SEQX, 0x01U, pATIHW->seq[1]);
-
-#endif /* AVOID_CPIO */
-
- /*
- * The server has already saved video memory contents when switching out of
- * its virtual console, so don't do it again.
- */
- if (pATIHW != &pATI->NewHW)
- {
- pATIHW->FeedbackDivider = 0; /* Don't programme clock */
-
-#ifndef AVOID_CPIO
-
- /* Save video memory */
- ATISwap(pScreenInfo->scrnIndex, pATI, pATIHW, FALSE);
-
-#endif /* AVOID_CPIO */
-
- }
-
-#ifndef AVOID_CPIO
-
- if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
- ATIVGASaveScreen(pATI, SCREEN_SAVER_OFF); /* Turn on screen */
-
-#endif /* AVOID_CPIO */
-
-}
-
-/*
- * ATIModeCalculate --
- *
- * This function fills in an ATIHWRec with all register values needed to enable
- * a video state. It's important that this be done without modifying the
- * current video state.
- */
-Bool
-ATIModeCalculate
-(
- int iScreen,
- ATIPtr pATI,
- ATIHWPtr pATIHW,
- DisplayModePtr pMode
-)
-{
- CARD32 lcd_index;
- int Index, ECPClock, MaxScalerClock;
-
- /* Clobber mode timings */
- if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0) &&
- !pMode->CrtcHAdjusted && !pMode->CrtcVAdjusted &&
- (!pATI->OptionLCDSync || (pMode->type & M_T_BUILTIN)))
- {
- int VScan;
-
- pMode->Clock = pATI->LCDClock;
- pMode->Flags &= ~(V_DBLSCAN | V_INTERLACE | V_CLKDIV2);
-
- /*
- * Use doublescanning or multiscanning to get around vertical blending
- * limitations.
- */
- VScan = pATI->LCDVertical / pMode->VDisplay;
- switch (pATIHW->crtc)
- {
-
-#ifndef AVOID_CPIO
-
- case ATI_CRTC_VGA:
- if (VScan > 64)
- VScan = 64;
- pMode->VScan = VScan;
- break;
-
-#endif /* AVOID_CPIO */
-
- case ATI_CRTC_MACH64:
- pMode->VScan = 0;
- if (VScan <= 1)
- break;
- VScan = 2;
- pMode->Flags |= V_DBLSCAN;
- break;
-
- default:
- break;
- }
-
- pMode->HSyncStart = pMode->HDisplay + pATI->LCDHSyncStart;
- pMode->HSyncEnd = pMode->HSyncStart + pATI->LCDHSyncWidth;
- pMode->HTotal = pMode->HDisplay + pATI->LCDHBlankWidth;
-
- pMode->VSyncStart = pMode->VDisplay +
- ATIDivide(pATI->LCDVSyncStart, VScan, 0, 0);
- pMode->VSyncEnd = pMode->VSyncStart +
- ATIDivide(pATI->LCDVSyncWidth, VScan, 0, 1);
- pMode->VTotal = pMode->VDisplay +
- ATIDivide(pATI->LCDVBlankWidth, VScan, 0, 0);
- }
-
- switch (pATIHW->crtc)
- {
-
-#ifndef AVOID_CPIO
-
- case ATI_CRTC_VGA:
- /* Fill in VGA data */
- ATIVGACalculate(pATI, pATIHW, pMode);
-
- /* Fill in VGA Wonder data */
- if (pATI->CPIO_VGAWonder)
- ATIVGAWonderCalculate(pATI, pATIHW, pMode);
-
- if (pATI->Chip >= ATI_CHIP_88800GXC)
- {
- if (pATI->Chip >= ATI_CHIP_264CT)
- {
- /*
- * Selected bits of accelerator & VGA CRTC registers are
- * actually copies of each other.
- */
- pATIHW->crtc_h_total_disp =
- SetBits(pMode->CrtcHTotal, CRTC_H_TOTAL) |
- SetBits(pMode->CrtcHDisplay, CRTC_H_DISP);
- pATIHW->crtc_h_sync_strt_wid =
- SetBits(pMode->CrtcHSyncStart, CRTC_H_SYNC_STRT) |
- SetBits(pMode->CrtcHSkew, CRTC_H_SYNC_DLY) | /* ? */
- SetBits(GetBits(pMode->CrtcHSyncStart, 0x0100U),
- CRTC_H_SYNC_STRT_HI) |
- SetBits(pMode->CrtcHSyncEnd, CRTC_H_SYNC_WID);
- if (pMode->Flags & V_NHSYNC)
- pATIHW->crtc_h_sync_strt_wid |= CRTC_H_SYNC_POL;
-
- pATIHW->crtc_v_total_disp =
- SetBits(pMode->CrtcVTotal, CRTC_V_TOTAL) |
- SetBits(pMode->CrtcVDisplay, CRTC_V_DISP);
- pATIHW->crtc_v_sync_strt_wid =
- SetBits(pMode->CrtcVSyncStart, CRTC_V_SYNC_STRT) |
- SetBits(pMode->CrtcVSyncEnd, CRTC_V_SYNC_WID);
- if (pMode->Flags & V_NVSYNC)
- pATIHW->crtc_v_sync_strt_wid |= CRTC_V_SYNC_POL;
- }
-
- pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL) &
- ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN |
- CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_CSYNC_EN |
- CRTC_PIX_BY_2_EN | CRTC_DISPLAY_DIS |
- CRTC_VGA_XOVERSCAN | CRTC_PIX_WIDTH |
- CRTC_BYTE_PIX_ORDER | CRTC_VGA_128KAP_PAGING |
- CRTC_VFC_SYNC_TRISTATE |
- CRTC_LOCK_REGS | /* Already off, but ... */
- CRTC_SYNC_TRISTATE | CRTC_EXT_DISP_EN |
- CRTC_DISP_REQ_EN | CRTC_VGA_LINEAR | CRTC_VGA_TEXT_132 |
- CRTC_CUR_B_TEST);
- /* Some of these are not relevent, but that doesn't matter */
- switch (pATI->depth)
- {
- case 1:
- pATIHW->crtc_gen_cntl |=
- SetBits(PIX_WIDTH_1BPP, CRTC_PIX_WIDTH);
- break;
-
- case 4:
- pATIHW->crtc_gen_cntl |=
- SetBits(PIX_WIDTH_4BPP, CRTC_PIX_WIDTH);
- break;
-
- case 8:
- pATIHW->crtc_gen_cntl |=
- SetBits(PIX_WIDTH_8BPP, CRTC_PIX_WIDTH);
- break;
-
- case 15:
- pATIHW->crtc_gen_cntl |=
- SetBits(PIX_WIDTH_15BPP, CRTC_PIX_WIDTH);
- break;
-
- case 16:
- pATIHW->crtc_gen_cntl |=
- SetBits(PIX_WIDTH_16BPP, CRTC_PIX_WIDTH);
- break;
-
- case 24:
- if (pATI->bitsPerPixel == 24)
- {
- pATIHW->crtc_gen_cntl |=
- SetBits(PIX_WIDTH_24BPP, CRTC_PIX_WIDTH);
- break;
- }
- if (pATI->bitsPerPixel != 32)
- break;
- /* Fall through */
-
- case 32:
- pATIHW->crtc_gen_cntl |=
- SetBits(PIX_WIDTH_32BPP, CRTC_PIX_WIDTH);
- break;
-
- default:
- break;
- }
-#if 0 /* This isn't needed, but is kept for reference */
- if (pMode->Flags & V_DBLSCAN)
- pATIHW->crtc_gen_cntl |= CRTC_DBL_SCAN_EN;
-#endif
- if (pMode->Flags & V_INTERLACE)
- pATIHW->crtc_gen_cntl |= CRTC_INTERLACE_EN;
- if ((pMode->Flags & (V_CSYNC | V_PCSYNC)) || pATI->OptionCSync)
- pATIHW->crtc_gen_cntl |= CRTC_CSYNC_EN;
- if (pATI->depth <= 4)
- pATIHW->crtc_gen_cntl |= CRTC_EN | CRTC_CNT_EN;
- else
- pATIHW->crtc_gen_cntl |=
- CRTC_EN | CRTC_VGA_LINEAR | CRTC_CNT_EN;
- }
- break;
-
-#endif /* AVOID_CPIO */
-
- case ATI_CRTC_MACH64:
- /* Fill in Mach64 data */
- ATIMach64Calculate(pATI, pATIHW, pMode);
- break;
-
- default:
- break;
- }
-
- /* Set up LCD register values */
- if (pATI->LCDPanelID >= 0)
- {
- int VDisplay = pMode->VDisplay;
-
- if (pMode->Flags & V_DBLSCAN)
- VDisplay <<= 1;
- if (pMode->VScan > 1)
- VDisplay *= pMode->VScan;
- if (pMode->Flags & V_INTERLACE)
- VDisplay >>= 1;
-
- /* Ensure secondary CRTC is completely disabled */
- pATIHW->crtc_gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
-
- if (pATI->Chip == ATI_CHIP_264LT)
- {
- pATIHW->horz_stretching = inr(HORZ_STRETCHING);
- }
- else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
- (pATI->Chip == ATI_CHIP_264XL) ||
- (pATI->Chip == ATI_CHIP_MOBILITY)) */
- {
- lcd_index = inr(LCD_INDEX);
- pATIHW->horz_stretching = ATIMach64GetLCDReg(LCD_HORZ_STRETCHING);
- pATIHW->ext_vert_stretch =
- ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH) &
- ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
-
- /*
- * Don't use vertical blending if the mode is too wide or not
- * vertically stretched.
- */
- if (pATI->OptionPanelDisplay &&
- (pMode->HDisplay <= pATI->LCDVBlendFIFOSize) &&
- (VDisplay < pATI->LCDVertical))
- pATIHW->ext_vert_stretch |= VERT_STRETCH_MODE;
-
- outr(LCD_INDEX, lcd_index);
- }
-
- pATIHW->horz_stretching &=
- ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
- HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
- if (pATI->OptionPanelDisplay &&
- (pMode->HDisplay < pATI->LCDHorizontal))
- do
- {
- /*
- * The horizontal blender misbehaves when HDisplay is less than a
- * a certain threshold (440 for a 1024-wide panel). It doesn't
- * stretch such modes enough. Use pixel replication instead of
- * blending to stretch modes that can be made to exactly fit the
- * panel width. The undocumented "NoLCDBlend" option allows the
- * pixel-replicated mode to be slightly wider or narrower than the
- * panel width. It also causes a mode that is exactly half as wide
- * as the panel to be pixel-replicated, rather than blended.
- */
- int HDisplay = pMode->HDisplay & ~7;
- int nStretch = pATI->LCDHorizontal / HDisplay;
- int Remainder = pATI->LCDHorizontal % HDisplay;
-
- if ((!Remainder && ((nStretch > 2) || !pATI->OptionBlend)) ||
- (((HDisplay * 16) / pATI->LCDHorizontal) < 7))
- {
- static const char StretchLoops[] = {10, 12, 13, 15, 16};
- int horz_stretch_loop = -1, BestRemainder;
- int Numerator = HDisplay, Denominator = pATI->LCDHorizontal;
-
- ATIReduceRatio(&Numerator, &Denominator);
-
- BestRemainder = (Numerator * 16) / Denominator;
- Index = NumberOf(StretchLoops);
- while (--Index >= 0)
- {
- Remainder =
- ((Denominator - Numerator) * StretchLoops[Index]) %
- Denominator;
- if (Remainder < BestRemainder)
- {
- horz_stretch_loop = Index;
- if (!(BestRemainder = Remainder))
- break;
- }
-#if 0
- /*
- * Enabling this code allows the pixel-replicated mode to
- * be slightly wider than the panel width.
- */
- Remainder = Denominator - Remainder;
- if (Remainder < BestRemainder)
- {
- horz_stretch_loop = Index;
- BestRemainder = Remainder;
- }
-#endif
- }
-
- if ((horz_stretch_loop >= 0) &&
- (!BestRemainder || !pATI->OptionBlend))
- {
- int horz_stretch_ratio = 0, Accumulator = 0;
- int reuse_previous = 1;
-
- Index = StretchLoops[horz_stretch_loop];
-
- while (--Index >= 0)
- {
- if (Accumulator > 0)
- horz_stretch_ratio |= reuse_previous;
- else
- Accumulator += Denominator;
- Accumulator -= Numerator;
- reuse_previous <<= 1;
- }
-
- pATIHW->horz_stretching |= HORZ_STRETCH_EN |
- SetBits(horz_stretch_loop, HORZ_STRETCH_LOOP) |
- SetBits(horz_stretch_ratio, HORZ_STRETCH_RATIO);
- break; /* Out of the do { ... } while (0) */
- }
- }
-
- pATIHW->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN) |
- SetBits((HDisplay * (MaxBits(HORZ_STRETCH_BLEND) + 1)) /
- pATI->LCDHorizontal, HORZ_STRETCH_BLEND);
- } while (0);
-
- if (!pATI->OptionPanelDisplay || (VDisplay >= pATI->LCDVertical))
- {
- pATIHW->vert_stretching = 0;
- }
- else
- {
- pATIHW->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN) |
- SetBits((VDisplay * (MaxBits(VERT_STRETCH_RATIO0) + 1)) /
- pATI->LCDVertical, VERT_STRETCH_RATIO0);
- }
-
-#ifndef AVOID_CPIO
-
- /* Copy non-shadow CRTC register values to the shadow set */
- for (Index = 0; Index < NumberOf(pATIHW->shadow_vga); Index++)
- pATIHW->shadow_vga[Index] = pATIHW->crt[Index];
-
-#endif /* AVOID_CPIO */
-
- pATIHW->shadow_h_total_disp = pATIHW->crtc_h_total_disp;
- pATIHW->shadow_h_sync_strt_wid = pATIHW->crtc_h_sync_strt_wid;
- pATIHW->shadow_v_total_disp = pATIHW->crtc_v_total_disp;
- pATIHW->shadow_v_sync_strt_wid = pATIHW->crtc_v_sync_strt_wid;
- }
-
- /* Fill in clock data */
- if (!ATIClockCalculate(iScreen, pATI, pATIHW, pMode))
- return FALSE;
-
- /* Setup ECP clock divider */
- if (pATI->Chip >= ATI_CHIP_264VT)
- {
- if (pATI->Chip <= ATI_CHIP_264VT3)
- MaxScalerClock = 80000;
- else if (pATI->Chip <= ATI_CHIP_264GT2C)
- MaxScalerClock = 100000;
- else if (pATI->Chip == ATI_CHIP_264GTPRO)
- MaxScalerClock = 125000;
- else if (pATI->Chip <= ATI_CHIP_MOBILITY)
- MaxScalerClock = 135000;
- else
- MaxScalerClock = 80000; /* Conservative */
- pATIHW->pll_vclk_cntl &= ~PLL_ECP_DIV;
- /* XXX Don't do this for TVOut! */
- ECPClock = pMode->SynthClock;
- for (Index = 0; (ECPClock > MaxScalerClock) && (Index < 2); Index++)
- ECPClock >>= 1;
- pATIHW->pll_vclk_cntl |= SetBits(Index, PLL_ECP_DIV);
- }
- else if (pATI->DAC == ATI_DAC_IBMRGB514)
- {
- ATIRGB514Calculate(pATI, pATIHW, pMode);
- }
-
- return TRUE;
-}
-
-/*
- * ATIModeSet --
- *
- * This function sets a video mode. It writes out all video state data that
- * has been previously calculated or saved.
- */
-void
-ATIModeSet
-(
- ScrnInfoPtr pScreenInfo,
- ATIPtr pATI,
- ATIHWPtr pATIHW
-)
-{
-
-#ifndef AVOID_CPIO
-
- int Index;
-
- /* Get back to bank 0 */
- (*pATIHW->SetBank)(pATI, 0);
-
-#endif /* AVOID_CPIO */
-
- if (pATI->Chip >= ATI_CHIP_88800GXC)
- {
- /* Stop CRTC */
- outr(CRTC_GEN_CNTL,
- pATIHW->crtc_gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN));
-
- if (pATI->Chip >= ATI_CHIP_264CT)
- {
- ATIMach64PutPLLReg(PLL_VCLK_CNTL, pATIHW->pll_vclk_cntl);
- ATIMach64PutPLLReg(PLL_VCLK_POST_DIV, pATIHW->pll_vclk_post_div);
- ATIMach64PutPLLReg(PLL_VCLK0_FB_DIV, pATIHW->pll_vclk0_fb_div);
- ATIMach64PutPLLReg(PLL_VCLK1_FB_DIV, pATIHW->pll_vclk1_fb_div);
- ATIMach64PutPLLReg(PLL_VCLK2_FB_DIV, pATIHW->pll_vclk2_fb_div);
- ATIMach64PutPLLReg(PLL_VCLK3_FB_DIV, pATIHW->pll_vclk3_fb_div);
- ATIMach64PutPLLReg(PLL_XCLK_CNTL, pATIHW->pll_xclk_cntl);
- if (pATI->Chip >= ATI_CHIP_264LT)
- ATIMach64PutPLLReg(PLL_EXT_VPLL_CNTL,
- pATIHW->pll_ext_vpll_cntl);
- ATIMach64PutPLLReg(PLL_VCLK_CNTL,
- pATIHW->pll_vclk_cntl & ~PLL_VCLK_RESET);
-
- /* Load LCD registers */
- if (pATI->LCDPanelID >= 0)
- {
- if (pATI->Chip == ATI_CHIP_264LT)
- {
- /* Update non-shadow registers first */
- outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
-
- /* Temporarily disable stretching */
- outr(HORZ_STRETCHING, pATIHW->horz_stretching &
- ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN));
- outr(VERT_STRETCHING, pATIHW->vert_stretching &
- ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
- VERT_STRETCH_USE0 | VERT_STRETCH_EN));
- }
- else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
- (pATI->Chip == ATI_CHIP_264XL) ||
- (pATI->Chip == ATI_CHIP_MOBILITY)) */
- {
- /* Update non-shadow registers first */
- ATIMach64PutLCDReg(LCD_CONFIG_PANEL, pATIHW->config_panel);
- ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl &
- ~(CRTC_RW_SELECT | SHADOW_RW_EN));
-
- /* Temporarily disable stretching */
- ATIMach64PutLCDReg(LCD_HORZ_STRETCHING,
- pATIHW->horz_stretching &
- ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN));
- ATIMach64PutLCDReg(LCD_VERT_STRETCHING,
- pATIHW->vert_stretching &
- ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
- VERT_STRETCH_USE0 | VERT_STRETCH_EN));
- }
- }
- }
- }
-
- switch (pATIHW->crtc)
- {
-
-#ifndef AVOID_CPIO
-
- case ATI_CRTC_VGA:
- /* Start sequencer reset */
- PutReg(SEQX, 0x00U, 0x00U);
-
- /* Set pixel clock */
- if ((pATIHW->FeedbackDivider > 0) &&
- (pATI->ProgrammableClock > ATI_CLOCK_FIXED))
- ATIClockSet(pATI, pATIHW);
-
- /* Set up RAMDAC */
- if (pATI->DAC == ATI_DAC_IBMRGB514)
- ATIRGB514Set(pATI, pATIHW);
-
- /* Load VGA Wonder */
- if (pATI->CPIO_VGAWonder)
- ATIVGAWonderSet(pATI, pATIHW);
-
- /* Load VGA device */
- ATIVGASet(pATI, pATIHW);
-
- /* Load Mach64 registers */
- if (pATI->Chip >= ATI_CHIP_88800GXC)
- {
- /* Load MMIO registers */
- if (pATI->Block0Base)
- ATIMach64Set(pATI, pATIHW);
-
- outr(CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl);
- outr(CUR_CLR0, pATIHW->cur_clr0);
- outr(CUR_CLR1, pATIHW->cur_clr1);
- outr(CUR_OFFSET, pATIHW->cur_offset);
- outr(CUR_HORZ_VERT_POSN, pATIHW->cur_horz_vert_posn);
- outr(CUR_HORZ_VERT_OFF, pATIHW->cur_horz_vert_off);
- outr(BUS_CNTL, pATIHW->bus_cntl);
- outr(MEM_VGA_WP_SEL, pATIHW->mem_vga_wp_sel);
- outr(MEM_VGA_RP_SEL, pATIHW->mem_vga_rp_sel);
- outr(DAC_CNTL, pATIHW->dac_cntl);
- outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
- outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl);
- outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
- outr(CONFIG_CNTL, pATIHW->config_cntl);
- if (pATI->Chip >= ATI_CHIP_264CT)
- {
- outr(CRTC_H_TOTAL_DISP, pATIHW->crtc_h_total_disp);
- outr(CRTC_H_SYNC_STRT_WID, pATIHW->crtc_h_sync_strt_wid);
- outr(CRTC_V_TOTAL_DISP, pATIHW->crtc_v_total_disp);
- outr(CRTC_V_SYNC_STRT_WID, pATIHW->crtc_v_sync_strt_wid);
- outr(CRTC_OFF_PITCH, pATIHW->crtc_off_pitch);
- if (pATI->Chip >= ATI_CHIP_264VTB)
- {
- outr(MEM_CNTL, pATIHW->mem_cntl);
- outr(MPP_CONFIG, pATIHW->mpp_config);
- outr(MPP_STROBE_SEQ, pATIHW->mpp_strobe_seq);
- outr(TVO_CNTL, pATIHW->tvo_cntl);
- }
- }
- }
-
- break;
-
-#endif /* AVOID_CPIO */
-
- case ATI_CRTC_MACH64:
- /* Load Mach64 CRTC registers */
- ATIMach64Set(pATI, pATIHW);
-
-#ifndef AVOID_CPIO
-
- if (pATI->UseSmallApertures)
- {
- /* Oddly enough, these need to be set also, maybe others */
- PutReg(SEQX, 0x02U, pATIHW->seq[2]);
- PutReg(SEQX, 0x04U, pATIHW->seq[4]);
- PutReg(GRAX, 0x06U, pATIHW->gra[6]);
- if (pATI->CPIO_VGAWonder)
- ATIModifyExtReg(pATI, 0xB6U, -1, 0x00U, pATIHW->b6);
- }
-
-#endif /* AVOID_CPIO */
-
- break;
-
- default:
- break;
- }
-
- if (pATI->LCDPanelID >= 0)
- {
- /* 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 & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
-
- /* Restore shadow registers */
- switch (pATIHW->crtc)
- {
-
-#ifndef AVOID_CPIO
-
- case ATI_CRTC_VGA:
- for (Index = 0;
- Index < NumberOf(pATIHW->shadow_vga);
- Index++)
- PutReg(CRTX(pATI->CPIO_VGABase), Index,
- pATIHW->shadow_vga[Index]);
- /* Fall through */
-
-#endif /* AVOID_CPIO */
-
- case ATI_CRTC_MACH64:
- outr(CRTC_H_TOTAL_DISP, pATIHW->shadow_h_total_disp);
- outr(CRTC_H_SYNC_STRT_WID, pATIHW->shadow_h_sync_strt_wid);
- outr(CRTC_V_TOTAL_DISP, pATIHW->shadow_v_total_disp);
- outr(CRTC_V_SYNC_STRT_WID, pATIHW->shadow_v_sync_strt_wid);
- break;
-
- default:
- break;
- }
-
- /* Restore CRTC selection & shadow state and enable stretching */
- if (pATI->Chip == ATI_CHIP_264LT)
- {
- outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
- outr(HORZ_STRETCHING, pATIHW->horz_stretching);
- outr(VERT_STRETCHING, pATIHW->vert_stretching);
- }
- 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);
- ATIMach64PutLCDReg(LCD_HORZ_STRETCHING, pATIHW->horz_stretching);
- ATIMach64PutLCDReg(LCD_VERT_STRETCHING, pATIHW->vert_stretching);
- ATIMach64PutLCDReg(LCD_EXT_VERT_STRETCH, pATIHW->ext_vert_stretch);
- outr(LCD_INDEX, pATIHW->lcd_index);
- }
- }
-
- /*
- * Set DSP registers. Note that, for some reason, sequencer resets clear
- * the DSP_CONFIG register on early integrated controllers.
- */
- if (pATI->Chip >= ATI_CHIP_264VTB)
- ATIDSPSet(pATI, pATIHW);
-
- /* Load RAMDAC */
- ATIDACSet(pATI, pATIHW);
-
- /* Reset hardware cursor caching */
- pATI->CursorXOffset = pATI->CursorYOffset = (CARD16)(-1);
-
-#ifndef AVOID_CPIO
-
- /* Restore video memory */
- ATISwap(pScreenInfo->scrnIndex, pATI, pATIHW, TRUE);
-
- if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
- ATIVGASaveScreen(pATI, SCREEN_SAVER_OFF); /* Turn on screen */
-
-#endif /* AVOID_CPIO */
-
- if ((xf86GetVerbosity() > 3) && (pATIHW == &pATI->NewHW))
- {
- xf86ErrorFVerb(4, "\n After setting mode \"%s\":\n\n",
- pScreenInfo->currentMode->name);
- ATIPrintMode(pScreenInfo->currentMode);
- ATIPrintRegisters(pATI);
- }
-}