132b578d3Smrg/* 232b578d3Smrg * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 332b578d3Smrg * 432b578d3Smrg * Permission to use, copy, modify, distribute, and sell this software and its 532b578d3Smrg * documentation for any purpose is hereby granted without fee, provided that 632b578d3Smrg * the above copyright notice appear in all copies and that both that copyright 732b578d3Smrg * notice and this permission notice appear in supporting documentation, and 832b578d3Smrg * that the name of Marc Aurele La France not be used in advertising or 932b578d3Smrg * publicity pertaining to distribution of the software without specific, 1032b578d3Smrg * written prior permission. Marc Aurele La France makes no representations 1132b578d3Smrg * about the suitability of this software for any purpose. It is provided 1232b578d3Smrg * "as-is" without express or implied warranty. 1332b578d3Smrg * 1432b578d3Smrg * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1532b578d3Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 1632b578d3Smrg * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1732b578d3Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1832b578d3Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1932b578d3Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2032b578d3Smrg * PERFORMANCE OF THIS SOFTWARE. 2132b578d3Smrg */ 2232b578d3Smrg 2332b578d3Smrg#ifdef HAVE_CONFIG_H 2432b578d3Smrg#include "config.h" 2532b578d3Smrg#endif 2632b578d3Smrg 2732b578d3Smrg#include "ati.h" 2832b578d3Smrg#include "atichip.h" 2932b578d3Smrg#include "atilock.h" 3032b578d3Smrg#include "atimach64io.h" 3132b578d3Smrg#include "atiwonderio.h" 3232b578d3Smrg 3332b578d3Smrg/* 3432b578d3Smrg * ATIUnlock -- 3532b578d3Smrg * 3632b578d3Smrg * This function is entered to unlock registers and disable unwanted 3732b578d3Smrg * emulations. It saves the current state for later restoration by ATILock(). 3832b578d3Smrg */ 3932b578d3Smrgvoid 4032b578d3SmrgATIUnlock 4132b578d3Smrg( 4232b578d3Smrg ATIPtr pATI 4332b578d3Smrg) 4432b578d3Smrg{ 4532b578d3Smrg CARD32 tmp; 4632b578d3Smrg 4732b578d3Smrg#ifndef AVOID_CPIO 4832b578d3Smrg 4932b578d3Smrg CARD32 saved_lcd_gen_ctrl = 0, lcd_gen_ctrl = 0; 5032b578d3Smrg 5132b578d3Smrg#endif /* AVOID_CPIO */ 5232b578d3Smrg 5332b578d3Smrg if (pATI->Unlocked) 5432b578d3Smrg return; 5532b578d3Smrg pATI->Unlocked = TRUE; 5632b578d3Smrg 5732b578d3Smrg { 5832b578d3Smrg /* Reset everything */ 5932b578d3Smrg pATI->LockData.bus_cntl = inr(BUS_CNTL); 6032b578d3Smrg if (pATI->Chip < ATI_CHIP_264VT4) 6132b578d3Smrg { 6232b578d3Smrg pATI->LockData.bus_cntl = 6332b578d3Smrg (pATI->LockData.bus_cntl & ~BUS_HOST_ERR_INT_EN) | 6432b578d3Smrg BUS_HOST_ERR_INT; 6532b578d3Smrg if (pATI->Chip < ATI_CHIP_264VTB) 6632b578d3Smrg pATI->LockData.bus_cntl = 6732b578d3Smrg (pATI->LockData.bus_cntl & ~BUS_FIFO_ERR_INT_EN) | 6832b578d3Smrg BUS_FIFO_ERR_INT; 6932b578d3Smrg } 7032b578d3Smrg tmp = pATI->LockData.bus_cntl & ~BUS_ROM_DIS; 7132b578d3Smrg if (pATI->Chip < ATI_CHIP_264VTB) 7232b578d3Smrg tmp |= SetBits(15, BUS_FIFO_WS); 7332b578d3Smrg else 7432b578d3Smrg tmp &= ~BUS_MASTER_DIS; 7532b578d3Smrg if (pATI->Chip >= ATI_CHIP_264VT) 7632b578d3Smrg tmp |= BUS_EXT_REG_EN; /* Enable Block 1 */ 7732b578d3Smrg outr(BUS_CNTL, tmp); 7832b578d3Smrg pATI->LockData.crtc_int_cntl = inr(CRTC_INT_CNTL); 7932b578d3Smrg outr(CRTC_INT_CNTL, (pATI->LockData.crtc_int_cntl & ~CRTC_INT_ENS) | 8032b578d3Smrg CRTC_INT_ACKS); 8132b578d3Smrg 8232b578d3Smrg#ifdef XF86DRI_DEVEL 8332b578d3Smrg 8432b578d3Smrg if (pATI->irq > 0) 8532b578d3Smrg outr(CRTC_INT_CNTL, (inr(CRTC_INT_CNTL) & ~CRTC_INT_ACKS) | 8632b578d3Smrg CRTC_VBLANK_INT_EN); /* Enable VBLANK interrupt - handled by DRM */ 8732b578d3Smrg 8832b578d3Smrg#endif /* XF86DRI_DEVEL */ 8932b578d3Smrg 9032b578d3Smrg pATI->LockData.gen_test_cntl = inr(GEN_TEST_CNTL) & 9132b578d3Smrg (GEN_OVR_OUTPUT_EN | GEN_OVR_POLARITY | GEN_CUR_EN | 9232b578d3Smrg GEN_BLOCK_WR_EN); 9332b578d3Smrg tmp = pATI->LockData.gen_test_cntl & ~GEN_CUR_EN; 9432b578d3Smrg outr(GEN_TEST_CNTL, tmp | GEN_GUI_EN); 9532b578d3Smrg outr(GEN_TEST_CNTL, tmp); 9632b578d3Smrg outr(GEN_TEST_CNTL, tmp | GEN_GUI_EN); 9732b578d3Smrg tmp = pATI->LockData.crtc_gen_cntl = inr(CRTC_GEN_CNTL) & 9832b578d3Smrg ~(CRTC_EN | CRTC_LOCK_REGS); 9932b578d3Smrg if (pATI->Chip >= ATI_CHIP_264XL) 10032b578d3Smrg tmp = (tmp & ~CRTC_INT_ENS_X) | CRTC_INT_ACKS_X; 10132b578d3Smrg outr(CRTC_GEN_CNTL, tmp | CRTC_EN); 10232b578d3Smrg outr(CRTC_GEN_CNTL, tmp); 10332b578d3Smrg outr(CRTC_GEN_CNTL, tmp | CRTC_EN); 10432b578d3Smrg if ((pATI->LCDPanelID >= 0) && (pATI->Chip != ATI_CHIP_264LT)) 10532b578d3Smrg { 10632b578d3Smrg pATI->LockData.lcd_index = inr(LCD_INDEX); 10732b578d3Smrg if (pATI->Chip >= ATI_CHIP_264XL) 10832b578d3Smrg outr(LCD_INDEX, pATI->LockData.lcd_index & 10932b578d3Smrg ~(LCD_MONDET_INT_EN | LCD_MONDET_INT)); 11032b578d3Smrg 11132b578d3Smrg /* 11232b578d3Smrg * Prevent BIOS initiated display switches on dual-CRT controllers. 11332b578d3Smrg */ 11432b578d3Smrg if (!pATI->OptionBIOSDisplay && (pATI->Chip != ATI_CHIP_264XL)) 11532b578d3Smrg { 11632b578d3Smrg#ifdef TV_OUT 11732b578d3Smrg pATI->LockData.scratch_reg3 = inr(SCRATCH_REG3) & ~DISPLAY_SWITCH_DISABLE; 11832b578d3Smrg outr(SCRATCH_REG3, pATI->LockData.scratch_reg3); 11932b578d3Smrg#else 12032b578d3Smrg pATI->LockData.scratch_reg3 = inr(SCRATCH_REG3); 12132b578d3Smrg outr(SCRATCH_REG3, 12232b578d3Smrg pATI->LockData.scratch_reg3 | DISPLAY_SWITCH_DISABLE); 12332b578d3Smrg#endif /* TV_OUT */ 12432b578d3Smrg } 12532b578d3Smrg } 12632b578d3Smrg 12732b578d3Smrg pATI->LockData.mem_cntl = inr(MEM_CNTL); 12832b578d3Smrg if (pATI->Chip < ATI_CHIP_264CT) 12932b578d3Smrg outr(MEM_CNTL, pATI->LockData.mem_cntl & 13032b578d3Smrg ~(CTL_MEM_BNDRY | CTL_MEM_BNDRY_EN)); 13132b578d3Smrg 13232b578d3Smrg /* Disable feature connector on integrated controllers */ 13332b578d3Smrg tmp = pATI->LockData.dac_cntl = inr(DAC_CNTL); 13432b578d3Smrg if (pATI->Chip >= ATI_CHIP_264CT) 13532b578d3Smrg tmp &= ~DAC_FEA_CON_EN; 13632b578d3Smrg 13732b578d3Smrg#ifndef AVOID_CPIO 13832b578d3Smrg 13932b578d3Smrg /* Ensure VGA aperture is enabled */ 14032b578d3Smrg pATI->LockData.config_cntl = inr(CONFIG_CNTL); 14132b578d3Smrg tmp |= DAC_VGA_ADR_EN; 14232b578d3Smrg outr(CONFIG_CNTL, pATI->LockData.config_cntl & ~CFG_VGA_DIS); 14332b578d3Smrg 14432b578d3Smrg#endif /* AVOID_CPIO */ 14532b578d3Smrg 14632b578d3Smrg outr(DAC_CNTL, tmp); 14732b578d3Smrg 14832b578d3Smrg if (pATI->Chip >= ATI_CHIP_264VTB) 14932b578d3Smrg { 15032b578d3Smrg pATI->LockData.mpp_config = inr(MPP_CONFIG); 15132b578d3Smrg pATI->LockData.mpp_strobe_seq = inr(MPP_STROBE_SEQ); 15232b578d3Smrg pATI->LockData.tvo_cntl = inr(TVO_CNTL); 15332b578d3Smrg 15432b578d3Smrg if (pATI->Chip >= ATI_CHIP_264GT2C) 15532b578d3Smrg { 15632b578d3Smrg pATI->LockData.hw_debug = inr(HW_DEBUG); 15732b578d3Smrg 15832b578d3Smrg if (pATI->Chip >= ATI_CHIP_264GTPRO) 15932b578d3Smrg { 16032b578d3Smrg if (!(pATI->LockData.hw_debug & CMDFIFO_SIZE_EN)) 16132b578d3Smrg outr(HW_DEBUG, 16232b578d3Smrg pATI->LockData.hw_debug | CMDFIFO_SIZE_EN); 16332b578d3Smrg 16432b578d3Smrg pATI->LockData.i2c_cntl_0 = 16532b578d3Smrg inr(I2C_CNTL_0) | (I2C_CNTL_STAT | I2C_CNTL_HPTR_RST); 16632b578d3Smrg outr(I2C_CNTL_0, 16732b578d3Smrg pATI->LockData.i2c_cntl_0 & ~I2C_CNTL_INT_EN); 16832b578d3Smrg pATI->LockData.i2c_cntl_1 = inr(I2C_CNTL_1); 16932b578d3Smrg } 17032b578d3Smrg else 17132b578d3Smrg { 17232b578d3Smrg if (pATI->LockData.hw_debug & CMDFIFO_SIZE_DIS) 17332b578d3Smrg outr(HW_DEBUG, 17432b578d3Smrg pATI->LockData.hw_debug & ~CMDFIFO_SIZE_DIS); 17532b578d3Smrg } 17632b578d3Smrg } 17732b578d3Smrg } 17832b578d3Smrg } 17932b578d3Smrg 18032b578d3Smrg#ifndef AVOID_CPIO 18132b578d3Smrg 18232b578d3Smrg if (pATI->VGAAdapter) 18332b578d3Smrg { 18432b578d3Smrg if (pATI->CPIO_VGAWonder) 18532b578d3Smrg { 18632b578d3Smrg /* 18732b578d3Smrg * Ensure all registers are read/write and disable all non-VGA 18832b578d3Smrg * emulations. 18932b578d3Smrg */ 19032b578d3Smrg pATI->LockData.b1 = ATIGetExtReg(0xB1U); 19132b578d3Smrg ATIModifyExtReg(pATI, 0xB1U, pATI->LockData.b1, 0xFCU, 0x00U); 19232b578d3Smrg pATI->LockData.b4 = ATIGetExtReg(0xB4U); 19332b578d3Smrg ATIModifyExtReg(pATI, 0xB4U, pATI->LockData.b4, 0x00U, 0x00U); 19432b578d3Smrg pATI->LockData.b5 = ATIGetExtReg(0xB5U); 19532b578d3Smrg ATIModifyExtReg(pATI, 0xB5U, pATI->LockData.b5, 0xBFU, 0x00U); 19632b578d3Smrg pATI->LockData.b6 = ATIGetExtReg(0xB6U); 19732b578d3Smrg ATIModifyExtReg(pATI, 0xB6U, pATI->LockData.b6, 0xDDU, 0x00U); 19832b578d3Smrg pATI->LockData.b8 = ATIGetExtReg(0xB8U); 19932b578d3Smrg ATIModifyExtReg(pATI, 0xB8U, pATI->LockData.b8, 0xC0U, 0x00U); 20032b578d3Smrg pATI->LockData.b9 = ATIGetExtReg(0xB9U); 20132b578d3Smrg ATIModifyExtReg(pATI, 0xB9U, pATI->LockData.b9, 0x7FU, 0x00U); 20232b578d3Smrg { 20332b578d3Smrg pATI->LockData.be = ATIGetExtReg(0xBEU); 20432b578d3Smrg ATIModifyExtReg(pATI, 0xBEU, pATI->LockData.be, 0xFAU, 0x01U); 20532b578d3Smrg { 20632b578d3Smrg pATI->LockData.a6 = ATIGetExtReg(0xA6U); 20732b578d3Smrg ATIModifyExtReg(pATI, 0xA6U, pATI->LockData.a6, 20832b578d3Smrg 0x7FU, 0x00U); 20932b578d3Smrg pATI->LockData.ab = ATIGetExtReg(0xABU); 21032b578d3Smrg ATIModifyExtReg(pATI, 0xABU, pATI->LockData.ab, 21132b578d3Smrg 0xE7U, 0x00U); 21232b578d3Smrg } 21332b578d3Smrg } 21432b578d3Smrg } 21532b578d3Smrg 21632b578d3Smrg if (pATI->LCDPanelID >= 0) 21732b578d3Smrg { 21832b578d3Smrg if (pATI->Chip == ATI_CHIP_264LT) 21932b578d3Smrg { 22032b578d3Smrg saved_lcd_gen_ctrl = inr(LCD_GEN_CTRL); 22132b578d3Smrg 22232b578d3Smrg /* Setup to unlock non-shadow registers */ 22332b578d3Smrg lcd_gen_ctrl = saved_lcd_gen_ctrl & ~SHADOW_RW_EN; 22432b578d3Smrg outr(LCD_GEN_CTRL, lcd_gen_ctrl); 22532b578d3Smrg } 22632b578d3Smrg else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || 22732b578d3Smrg (pATI->Chip == ATI_CHIP_264XL) || 22832b578d3Smrg (pATI->Chip == ATI_CHIP_MOBILITY)) */ 22932b578d3Smrg { 23032b578d3Smrg saved_lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL); 23132b578d3Smrg 23232b578d3Smrg /* Setup to unlock non-shadow registers */ 23332b578d3Smrg lcd_gen_ctrl = saved_lcd_gen_ctrl & 23432b578d3Smrg ~(CRTC_RW_SELECT | SHADOW_RW_EN); 23532b578d3Smrg ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl); 23632b578d3Smrg } 23732b578d3Smrg } 23832b578d3Smrg 23932b578d3Smrg ATISetVGAIOBase(pATI, inb(R_GENMO)); 24032b578d3Smrg 24132b578d3Smrg /* 24232b578d3Smrg * There's a bizarre interaction here. If bit 0x80 of CRTC[17] is on, 24332b578d3Smrg * then CRTC[3] is read-only. If bit 0x80 of CRTC[3] is off, then 24432b578d3Smrg * CRTC[17] is write-only (or a read attempt actually returns bits from 24532b578d3Smrg * C/EGA's light pen position). This means that if both conditions are 24632b578d3Smrg * met, CRTC[17]'s value on server entry cannot be retrieved. 24732b578d3Smrg */ 24832b578d3Smrg 24932b578d3Smrg pATI->LockData.crt03 = tmp = GetReg(CRTX(pATI->CPIO_VGABase), 0x03U); 25032b578d3Smrg if ((tmp & 0x80U) || 25132b578d3Smrg ((outb(CRTD(pATI->CPIO_VGABase), tmp | 0x80U), 25232b578d3Smrg tmp = inb(CRTD(pATI->CPIO_VGABase))) & 0x80U)) 25332b578d3Smrg { 25432b578d3Smrg /* CRTC[16-17] should be readable */ 25532b578d3Smrg pATI->LockData.crt11 = tmp = 25632b578d3Smrg GetReg(CRTX(pATI->CPIO_VGABase), 0x11U); 25732b578d3Smrg if (tmp & 0x80U) /* Unprotect CRTC[0-7] */ 25832b578d3Smrg outb(CRTD(pATI->CPIO_VGABase), tmp & 0x7FU); 25932b578d3Smrg } 26032b578d3Smrg else 26132b578d3Smrg { 26232b578d3Smrg /* 26332b578d3Smrg * Could not make CRTC[17] readable, so unprotect CRTC[0-7] 26432b578d3Smrg * replacing VSyncEnd with zero. This zero will be replaced after 26532b578d3Smrg * acquiring the needed access. 26632b578d3Smrg */ 26732b578d3Smrg unsigned int VSyncEnd, VBlankStart, VBlankEnd; 26832b578d3Smrg CARD8 crt07, crt09; 26932b578d3Smrg 27032b578d3Smrg PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, 0x20U); 27132b578d3Smrg /* Make CRTC[16-17] readable */ 27232b578d3Smrg PutReg(CRTX(pATI->CPIO_VGABase), 0x03U, tmp | 0x80U); 27332b578d3Smrg /* Make vertical synch pulse as wide as possible */ 27432b578d3Smrg crt07 = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U); 27532b578d3Smrg crt09 = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U); 27632b578d3Smrg VBlankStart = (((crt09 & 0x20U) << 4) | ((crt07 & 0x08U) << 5) | 27732b578d3Smrg GetReg(CRTX(pATI->CPIO_VGABase), 0x15U)) + 1; 27832b578d3Smrg VBlankEnd = (VBlankStart & 0x0300U) | 27932b578d3Smrg GetReg(CRTX(pATI->CPIO_VGABase), 0x16U); 28032b578d3Smrg if (VBlankEnd <= VBlankStart) 28132b578d3Smrg VBlankEnd += 0x0100U; 28232b578d3Smrg VSyncEnd = (((crt07 & 0x80U) << 2) | ((crt07 & 0x04U) << 6) | 28332b578d3Smrg GetReg(CRTX(pATI->CPIO_VGABase), 0x10U)) + 0x0FU; 28432b578d3Smrg if (VSyncEnd >= VBlankEnd) 28532b578d3Smrg VSyncEnd = VBlankEnd - 1; 28632b578d3Smrg pATI->LockData.crt11 = (VSyncEnd & 0x0FU) | 0x20U; 28732b578d3Smrg PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, pATI->LockData.crt11); 28832b578d3Smrg pATI->LockData.crt11 |= 0x80U; 28932b578d3Smrg } 29032b578d3Smrg 29132b578d3Smrg if (pATI->LCDPanelID >= 0) 29232b578d3Smrg { 29332b578d3Smrg /* Setup to unlock shadow registers */ 29432b578d3Smrg lcd_gen_ctrl |= SHADOW_RW_EN; 29532b578d3Smrg 29632b578d3Smrg if (pATI->Chip == ATI_CHIP_264LT) 29732b578d3Smrg outr(LCD_GEN_CTRL, lcd_gen_ctrl); 29832b578d3Smrg else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || 29932b578d3Smrg (pATI->Chip == ATI_CHIP_264XL) || 30032b578d3Smrg (pATI->Chip == ATI_CHIP_MOBILITY)) */ 30132b578d3Smrg ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl); 30232b578d3Smrg 30332b578d3Smrg /* Unlock shadow registers */ 30432b578d3Smrg ATISetVGAIOBase(pATI, inb(R_GENMO)); 30532b578d3Smrg 30632b578d3Smrg pATI->LockData.shadow_crt03 = tmp = 30732b578d3Smrg GetReg(CRTX(pATI->CPIO_VGABase), 0x03U); 30832b578d3Smrg if ((tmp & 0x80U) || 30932b578d3Smrg ((outb(CRTD(pATI->CPIO_VGABase), tmp | 0x80U), 31032b578d3Smrg tmp = inb(CRTD(pATI->CPIO_VGABase))) & 0x80U)) 31132b578d3Smrg { 31232b578d3Smrg /* CRTC[16-17] should be readable */ 31332b578d3Smrg pATI->LockData.shadow_crt11 = tmp = 31432b578d3Smrg GetReg(CRTX(pATI->CPIO_VGABase), 0x11U); 31532b578d3Smrg if (tmp & 0x80U) /* Unprotect CRTC[0-7] */ 31632b578d3Smrg { 31732b578d3Smrg outb(CRTD(pATI->CPIO_VGABase), tmp & 0x7FU); 31832b578d3Smrg } 31932b578d3Smrg else if (!tmp && pATI->LockData.crt11) 32032b578d3Smrg { 32132b578d3Smrg pATI->LockData.shadow_crt11 = tmp = pATI->LockData.crt11; 32232b578d3Smrg outb(CRTD(pATI->CPIO_VGABase), tmp & 0x7FU); 32332b578d3Smrg } 32432b578d3Smrg } 32532b578d3Smrg else 32632b578d3Smrg { 32732b578d3Smrg /* 32832b578d3Smrg * Could not make CRTC[17] readable, so unprotect CRTC[0-7] 32932b578d3Smrg * replacing VSyncEnd with zero. This zero will be replaced 33032b578d3Smrg * after acquiring the needed access. 33132b578d3Smrg */ 33232b578d3Smrg unsigned int VSyncEnd, VBlankStart, VBlankEnd; 33332b578d3Smrg CARD8 crt07, crt09; 33432b578d3Smrg 33532b578d3Smrg PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, 0x20U); 33632b578d3Smrg /* Make CRTC[16-17] readable */ 33732b578d3Smrg PutReg(CRTX(pATI->CPIO_VGABase), 0x03U, tmp | 0x80U); 33832b578d3Smrg /* Make vertical synch pulse as wide as possible */ 33932b578d3Smrg crt07 = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U); 34032b578d3Smrg crt09 = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U); 34132b578d3Smrg VBlankStart = (((crt09 & 0x20U) << 4) | 34232b578d3Smrg ((crt07 & 0x08U) << 5) | 34332b578d3Smrg GetReg(CRTX(pATI->CPIO_VGABase), 0x15U)) + 1; 34432b578d3Smrg VBlankEnd = (VBlankStart & 0x0300U) | 34532b578d3Smrg GetReg(CRTX(pATI->CPIO_VGABase), 0x16U); 34632b578d3Smrg if (VBlankEnd <= VBlankStart) 34732b578d3Smrg VBlankEnd += 0x0100U; 34832b578d3Smrg VSyncEnd = (((crt07 & 0x80U) << 2) | ((crt07 & 0x04U) << 6) | 34932b578d3Smrg GetReg(CRTX(pATI->CPIO_VGABase), 0x10U)) + 0x0FU; 35032b578d3Smrg if (VSyncEnd >= VBlankEnd) 35132b578d3Smrg VSyncEnd = VBlankEnd - 1; 35232b578d3Smrg pATI->LockData.shadow_crt11 = (VSyncEnd & 0x0FU) | 0x20U; 35332b578d3Smrg PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, 35432b578d3Smrg pATI->LockData.shadow_crt11); 35532b578d3Smrg pATI->LockData.shadow_crt11 |= 0x80U; 35632b578d3Smrg } 35732b578d3Smrg 35832b578d3Smrg /* Restore selection */ 35932b578d3Smrg if (pATI->Chip == ATI_CHIP_264LT) 36032b578d3Smrg { 36132b578d3Smrg outr(LCD_GEN_CTRL, saved_lcd_gen_ctrl); 36232b578d3Smrg } 36332b578d3Smrg else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || 36432b578d3Smrg (pATI->Chip == ATI_CHIP_264XL) || 36532b578d3Smrg (pATI->Chip == ATI_CHIP_MOBILITY)) */ 36632b578d3Smrg { 36732b578d3Smrg ATIMach64PutLCDReg(LCD_GEN_CNTL, saved_lcd_gen_ctrl); 36832b578d3Smrg 36932b578d3Smrg /* Restore LCD index */ 37032b578d3Smrg out8(LCD_INDEX, GetByte(pATI->LockData.lcd_index, 0)); 37132b578d3Smrg } 37232b578d3Smrg } 37332b578d3Smrg } 37432b578d3Smrg 37532b578d3Smrg#endif /* AVOID_CPIO */ 37632b578d3Smrg 37732b578d3Smrg} 37832b578d3Smrg 37932b578d3Smrg/* 38032b578d3Smrg * ATILock -- 38132b578d3Smrg * 38232b578d3Smrg * This function restores the state saved by ATIUnlock() above. 38332b578d3Smrg */ 38432b578d3Smrgvoid 38532b578d3SmrgATILock 38632b578d3Smrg( 38732b578d3Smrg ATIPtr pATI 38832b578d3Smrg) 38932b578d3Smrg{ 39032b578d3Smrg 39132b578d3Smrg#ifndef AVOID_CPIO 39232b578d3Smrg 39332b578d3Smrg CARD32 saved_lcd_gen_ctrl = 0, lcd_gen_ctrl = 0; 39432b578d3Smrg 39532b578d3Smrg#endif /* AVOID_CPIO */ 39632b578d3Smrg 39732b578d3Smrg if (!pATI->Unlocked) 39832b578d3Smrg return; 39932b578d3Smrg pATI->Unlocked = FALSE; 40032b578d3Smrg 40132b578d3Smrg#ifndef AVOID_CPIO 40232b578d3Smrg 40332b578d3Smrg if (pATI->VGAAdapter) 40432b578d3Smrg { 40532b578d3Smrg if (pATI->LCDPanelID >= 0) 40632b578d3Smrg { 40732b578d3Smrg if (pATI->Chip == ATI_CHIP_264LT) 40832b578d3Smrg { 40932b578d3Smrg saved_lcd_gen_ctrl = inr(LCD_GEN_CTRL); 41032b578d3Smrg 41132b578d3Smrg /* Setup to lock non-shadow registers */ 41232b578d3Smrg lcd_gen_ctrl = saved_lcd_gen_ctrl & ~SHADOW_RW_EN; 41332b578d3Smrg outr(LCD_GEN_CTRL, lcd_gen_ctrl); 41432b578d3Smrg } 41532b578d3Smrg else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || 41632b578d3Smrg (pATI->Chip == ATI_CHIP_264XL) || 41732b578d3Smrg (pATI->Chip == ATI_CHIP_MOBILITY)) */ 41832b578d3Smrg { 41932b578d3Smrg saved_lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL); 42032b578d3Smrg 42132b578d3Smrg /* Setup to lock non-shadow registers */ 42232b578d3Smrg lcd_gen_ctrl = saved_lcd_gen_ctrl & 42332b578d3Smrg ~(CRTC_RW_SELECT | SHADOW_RW_EN); 42432b578d3Smrg ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl); 42532b578d3Smrg } 42632b578d3Smrg } 42732b578d3Smrg 42832b578d3Smrg ATISetVGAIOBase(pATI, inb(R_GENMO)); 42932b578d3Smrg 43032b578d3Smrg /* Restore VGA locks */ 43132b578d3Smrg PutReg(CRTX(pATI->CPIO_VGABase), 0x03U, pATI->LockData.crt03); 43232b578d3Smrg PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, pATI->LockData.crt11); 43332b578d3Smrg 43432b578d3Smrg if (pATI->LCDPanelID >= 0) 43532b578d3Smrg { 43632b578d3Smrg /* Setup to lock shadow registers */ 43732b578d3Smrg lcd_gen_ctrl |= SHADOW_RW_EN; 43832b578d3Smrg 43932b578d3Smrg if (pATI->Chip == ATI_CHIP_264LT) 44032b578d3Smrg outr(LCD_GEN_CTRL, lcd_gen_ctrl); 44132b578d3Smrg else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || 44232b578d3Smrg (pATI->Chip == ATI_CHIP_264XL) || 44332b578d3Smrg (pATI->Chip == ATI_CHIP_MOBILITY)) */ 44432b578d3Smrg ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl); 44532b578d3Smrg 44632b578d3Smrg /* Lock shadow registers */ 44732b578d3Smrg ATISetVGAIOBase(pATI, inb(R_GENMO)); 44832b578d3Smrg 44932b578d3Smrg PutReg(CRTX(pATI->CPIO_VGABase), 0x03U, 45032b578d3Smrg pATI->LockData.shadow_crt03); 45132b578d3Smrg PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, 45232b578d3Smrg pATI->LockData.shadow_crt11); 45332b578d3Smrg 45432b578d3Smrg /* Restore selection */ 45532b578d3Smrg if (pATI->Chip == ATI_CHIP_264LT) 45632b578d3Smrg outr(LCD_GEN_CTRL, saved_lcd_gen_ctrl); 45732b578d3Smrg else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || 45832b578d3Smrg (pATI->Chip == ATI_CHIP_264XL) || 45932b578d3Smrg (pATI->Chip == ATI_CHIP_MOBILITY)) */ 46032b578d3Smrg ATIMach64PutLCDReg(LCD_GEN_CNTL, saved_lcd_gen_ctrl); 46132b578d3Smrg } 46232b578d3Smrg 46332b578d3Smrg if (pATI->CPIO_VGAWonder) 46432b578d3Smrg { 46532b578d3Smrg /* 46632b578d3Smrg * Restore emulation and protection bits in ATI extended VGA 46732b578d3Smrg * registers. 46832b578d3Smrg */ 46932b578d3Smrg ATIModifyExtReg(pATI, 0xB1U, -1, 0xFCU, pATI->LockData.b1); 47032b578d3Smrg ATIModifyExtReg(pATI, 0xB4U, -1, 0x00U, pATI->LockData.b4); 47132b578d3Smrg ATIModifyExtReg(pATI, 0xB5U, -1, 0xBFU, pATI->LockData.b5); 47232b578d3Smrg ATIModifyExtReg(pATI, 0xB6U, -1, 0xDDU, pATI->LockData.b6); 47332b578d3Smrg ATIModifyExtReg(pATI, 0xB8U, -1, 0xC0U, pATI->LockData.b8 & 0x03U); 47432b578d3Smrg ATIModifyExtReg(pATI, 0xB9U, -1, 0x7FU, pATI->LockData.b9); 47532b578d3Smrg { 47632b578d3Smrg ATIModifyExtReg(pATI, 0xBEU, -1, 0xFAU, pATI->LockData.be); 47732b578d3Smrg { 47832b578d3Smrg ATIModifyExtReg(pATI, 0xA6U, -1, 0x7FU, pATI->LockData.a6); 47932b578d3Smrg ATIModifyExtReg(pATI, 0xABU, -1, 0xE7U, pATI->LockData.ab); 48032b578d3Smrg } 48132b578d3Smrg } 48232b578d3Smrg ATIModifyExtReg(pATI, 0xB8U, -1, 0xC0U, pATI->LockData.b8); 48332b578d3Smrg } 48432b578d3Smrg } 48532b578d3Smrg 48632b578d3Smrg#endif /* AVOID_CPIO */ 48732b578d3Smrg 48832b578d3Smrg { 48932b578d3Smrg /* Reset everything */ 49032b578d3Smrg outr(BUS_CNTL, pATI->LockData.bus_cntl); 49132b578d3Smrg 49232b578d3Smrg outr(CRTC_INT_CNTL, pATI->LockData.crtc_int_cntl); 49332b578d3Smrg 49432b578d3Smrg outr(GEN_TEST_CNTL, pATI->LockData.gen_test_cntl | GEN_GUI_EN); 49532b578d3Smrg outr(GEN_TEST_CNTL, pATI->LockData.gen_test_cntl); 49632b578d3Smrg outr(GEN_TEST_CNTL, pATI->LockData.gen_test_cntl | GEN_GUI_EN); 49732b578d3Smrg 49832b578d3Smrg outr(CRTC_GEN_CNTL, pATI->LockData.crtc_gen_cntl | CRTC_EN); 49932b578d3Smrg outr(CRTC_GEN_CNTL, pATI->LockData.crtc_gen_cntl); 50032b578d3Smrg outr(CRTC_GEN_CNTL, pATI->LockData.crtc_gen_cntl | CRTC_EN); 50132b578d3Smrg 50232b578d3Smrg#ifndef AVOID_CPIO 50332b578d3Smrg 50432b578d3Smrg outr(CONFIG_CNTL, pATI->LockData.config_cntl); 50532b578d3Smrg 50632b578d3Smrg#endif /* AVOID_CPIO */ 50732b578d3Smrg 50832b578d3Smrg outr(DAC_CNTL, pATI->LockData.dac_cntl); 50932b578d3Smrg if (pATI->Chip < ATI_CHIP_264CT) 51032b578d3Smrg outr(MEM_CNTL, pATI->LockData.mem_cntl); 51132b578d3Smrg if ((pATI->LCDPanelID >= 0) && (pATI->Chip != ATI_CHIP_264LT)) 51232b578d3Smrg { 51332b578d3Smrg outr(LCD_INDEX, pATI->LockData.lcd_index); 51432b578d3Smrg#ifndef TV_OUT 51532b578d3Smrg if (!pATI->OptionBIOSDisplay && (pATI->Chip != ATI_CHIP_264XL)) 51632b578d3Smrg outr(SCRATCH_REG3, pATI->LockData.scratch_reg3); 51732b578d3Smrg#endif /* TV_OUT */ 51832b578d3Smrg } 51932b578d3Smrg if (pATI->Chip >= ATI_CHIP_264VTB) 52032b578d3Smrg { 52132b578d3Smrg outr(MPP_CONFIG, pATI->LockData.mpp_config); 52232b578d3Smrg outr(MPP_STROBE_SEQ, pATI->LockData.mpp_strobe_seq); 52332b578d3Smrg#ifndef TV_OUT 52432b578d3Smrg outr(TVO_CNTL, pATI->LockData.tvo_cntl); 52532b578d3Smrg#endif /* TV_OUT */ 52632b578d3Smrg if (pATI->Chip >= ATI_CHIP_264GT2C) 52732b578d3Smrg { 52832b578d3Smrg outr(HW_DEBUG, pATI->LockData.hw_debug); 52932b578d3Smrg if (pATI->Chip >= ATI_CHIP_264GTPRO) 53032b578d3Smrg { 53132b578d3Smrg outr(I2C_CNTL_0, pATI->LockData.i2c_cntl_0); 53232b578d3Smrg outr(I2C_CNTL_1, pATI->LockData.i2c_cntl_1); 53332b578d3Smrg } 53432b578d3Smrg } 53532b578d3Smrg } 53632b578d3Smrg } 53732b578d3Smrg} 538