📄 atimode.c
字号:
/* * Copyright 2000 through 2004 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. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#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"#ifdef TV_OUT#include "vbe.h"static const char *vbeSymbols[] = { "VBESetVBEMode", "vbeFree", NULL};#endif /* TV_OUT */#ifndef AVOID_CPIO/* * ATICopyVGAMemory -- * * This function is called to copy one or all banks of a VGA plane. */static voidATICopyVGAMemory( 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 voidATISwap( 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); 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. */voidATIModePreInit( 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. */voidATIModeSave( ScrnInfoPtr pScreenInfo, ATIPtr pATI, ATIHWPtr pATIHW){#ifndef AVOID_CPIO int Index; /* Get back 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -