diff options
Diffstat (limited to 'src/atimode.c')
-rw-r--r-- | src/atimode.c | 1185 |
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); - } -} |