diff options
Diffstat (limited to 'src/sis_dac.c')
-rw-r--r-- | src/sis_dac.c | 208 |
1 files changed, 145 insertions, 63 deletions
diff --git a/src/sis_dac.c b/src/sis_dac.c index 296e808..3b28b0b 100644 --- a/src/sis_dac.c +++ b/src/sis_dac.c @@ -1,4 +1,5 @@ /* $XFree86$ */ +/* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c,v 1.7 2004/08/04 15:46:33 twini Exp $ */ /* * DAC helper functions (Save/Restore, MemClk, etc) * @@ -15,7 +16,7 @@ * 3) The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, @@ -28,7 +29,10 @@ * * Author: Thomas Winischhofer <thomas@winischhofer.net> * + * -------------------------------------------------------------------------- + * * SiS_compute_vclk(), SiSCalcClock() and parts of SiSMclk(): + * * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England * Written by: * Alan Hourihane <alanh@fairlite.demon.co.uk>, @@ -37,9 +41,26 @@ * Mitani Hiroshi <hmitani@drl.mei.co.jp>, * David Thomas <davtom@dream.org.uk>, * Thomas Winischhofer <thomas@winischhofer.net>. - * Licensed under the terms of the XFree86 license - * (http://www.xfree86.org/current/LICENSE1.html) * + * Licensed under the following terms: + * + * 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 appears in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * and that the name of the copyright holder not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without expressed or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDER 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 "xf86.h" @@ -72,9 +93,12 @@ static void SiS301LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, VisualPtr pVisual); static void SetBlock(CARD16 port, CARD8 from, CARD8 to, CARD8 *DataPtr); +unsigned char SiSGetCopyROP(int rop); +unsigned char SiSGetPatternROP(int rop); + static const unsigned short ch700xidx[] = { 0x00,0x07,0x08,0x0a,0x0b,0x04,0x09,0x20,0x21,0x18,0x19,0x1a, - 0x1b,0x1c,0x1d,0x1e,0x1f, /* 0x0e, - TW: Don't save the power register */ + 0x1b,0x1c,0x1d,0x1e,0x1f, /* 0x0e, - Don't save the power register */ 0x01,0x03,0x06,0x0d,0x11,0x13,0x14,0x15,0x17,0x22,0x23,0x24 }; @@ -412,7 +436,7 @@ SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) sisReg->sisRegs3C2 = inSISREG(SISMISCR); /* Misc */ - /* TW: Save TV registers */ + /* Save TV registers */ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { outSISIDXREG(SISCR, 0x80, 0x86); for(i = 0x00; i <= 0x44; i++) { @@ -479,7 +503,7 @@ SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) usleep(10000); outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ - /* TW: Restore TV registers */ + /* Restore TV registers */ pSiS->SiS6326Flags &= ~SIS6326_TVON; if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { for(i = 0x01; i <= 0x44; i++) { @@ -566,14 +590,11 @@ SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) #endif /* Save Mode number */ -#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) - if(!(pSiS->UseVESA)) -#endif - pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); + sisReg->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS mode ds:449 = 0x%x\n", pSiS->BIOSModeSave); + "BIOS mode ds:449 = 0x%x\n", sisReg->BIOSModeSave); #endif } @@ -721,10 +742,7 @@ SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ /* Restore mode number */ -#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) - if(!(pSiS->UseVESA)) -#endif - SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave); + SiS_GetSetModeID(pScrn,sisReg->BIOSModeSave); } /* Save SiS315 series register contents */ @@ -765,16 +783,16 @@ SiS315Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) /* Save video capture registers */ for(i = 0x00; i <= 0x4f; i++) { inSISIDXREG(SISCAP, i, sisReg->sisCapt[i]); -#ifdef TWDEBUG +#ifdef TWDEBUG_VID xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Capt%02X Contents - %02X \n", i,sisReg->sisCapt[i]); #endif } /* Save video playback registers */ - for(i = 0x00; i <= 0x3f; i++) { + for(i = 0x00; i <= 0x3f; i++) { inSISIDXREG(SISVID, i, sisReg->sisVid[i]); -#ifdef TWDEBUG +#ifdef TWDEBUG_VID xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vid%02X Contents - %02X \n", i,sisReg->sisVid[i]); #endif @@ -798,14 +816,11 @@ SiS315Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) #endif /* Save mode number */ -#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) - if(!(pSiS->UseVESA)) -#endif - pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); + sisReg->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS mode ds:449 = 0x%x\n", pSiS->BIOSModeSave); + "BIOS mode ds:449 = 0x%x\n", sisReg->BIOSModeSave); #endif } @@ -837,11 +852,12 @@ SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) * or application is running and which queue mode it * uses. */ - outSISIDXREG(SISSR, 0x27, 0x1F); + andSISIDXREG(SISCR, 0x55, 0x33); outSISIDXREG(SISSR, 0x26, 0x01); + outSISIDXREG(SISSR, 0x27, 0x1F); /* Restore extended CR registers */ - for(i = 0x19; i < 0x5C; i++) { + for(i = 0x19; i < 0x5C; i++) { outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); } if(pSiS->sishw_ext.jChipType < SIS_661) { @@ -850,18 +866,27 @@ SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISCR, pSiS->myCR63, sisReg->sisRegs3D4[pSiS->myCR63]); /* Leave PCI_IO_ENABLE on if accelerators are on (Is this required?) */ - if(sisReg->sisRegs3C4[0x1e] & 0x50) { /*0x40=2D, 0x10=3D*/ + if(sisReg->sisRegs3C4[0x1e] & 0x50) { /* 0x40=2D, 0x10=3D */ sisReg->sisRegs3C4[0x20] |= 0x20; outSISIDXREG(SISSR, 0x20, sisReg->sisRegs3C4[0x20]); } - - /* Restore extended SR registers */ + if(pSiS->sishw_ext.jChipType >= SIS_661) { sisReg->sisRegs3C4[0x11] &= 0x0f; } + + /* Restore extended SR registers */ for(i = 0x06; i <= 0x3F; i++) { - outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); + if(i == 0x26) { + continue; + } else if(i == 0x27) { + outSISIDXREG(SISSR, 0x27, sisReg->sisRegs3C4[0x27]); + outSISIDXREG(SISSR, 0x26, sisReg->sisRegs3C4[0x26]); + } else { + outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); + } } + /* Restore VCLK and ECLK */ andSISIDXREG(SISSR,0x31,0xcf); if(pSiS->VBFlags & VB_LVDS) { @@ -918,10 +943,7 @@ SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ /* Restore Mode number */ -#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) - if(!(pSiS->UseVESA)) -#endif - SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave); + SiS_GetSetModeID(pScrn,sisReg->BIOSModeSave); } static void @@ -1147,7 +1169,7 @@ SiSLVDSChrontelSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) int i; /* Save Part1 */ - for(i=0; i<0x46; i++) { + for(i=0; i<0x46; i++) { inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]); #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -1224,7 +1246,7 @@ SiSLVDSChrontelRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) } if((!(sisReg->sisRegs3D4[0x30] & 0x03)) && - (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ + (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); return; } @@ -1289,13 +1311,14 @@ SiSMclk(SISPtr pSiS) case PCI_CHIP_SIS300: case PCI_CHIP_SIS540: case PCI_CHIP_SIS630: - case PCI_CHIP_SIS550: - case PCI_CHIP_SIS650: case PCI_CHIP_SIS315: case PCI_CHIP_SIS315H: case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS650: case PCI_CHIP_SIS330: case PCI_CHIP_SIS660: + case PCI_CHIP_SIS340: /* Numerator */ inSISIDXREG(SISSR, 0x28, Num); mclk = 14318 * ((Num & 0x7f) + 1); @@ -1372,9 +1395,12 @@ SiSEstimateCRT2Clock(ScrnInfoPtr pScrn, BOOLEAN IsForMergedFBCRT2) } else if(pSiS->VBLCDFlags & VB_LCD_1280x768) { return 81000; } else if(pSiS->VBLCDFlags & VB_LCD_1280x800) { + return 83000; /* Use this any way; BIOS timing seems wrong */ +#if 0 /* Must fake clock; built-in mode shows 83 for VGA, but uses only 70 for LCD */ if(IsForMergedFBCRT2) return 83000; else return 70000; +#endif } else if(pSiS->VBLCDFlags & VB_LCD_1400x1050) { /* Must fake clock; built-in mode shows 122 for VGA, but uses only 108 for LCD */ if(IsForMergedFBCRT2) return 123000; @@ -1387,10 +1413,12 @@ SiSEstimateCRT2Clock(ScrnInfoPtr pScrn, BOOLEAN IsForMergedFBCRT2) else return 122000; } else if(pSiS->VBLCDFlags & VB_LCD_1600x1200) { return 162000; - } else if((pSiS->VBLCDFlags & VB_LCD_CUSTOM) && (pSiS->SiS_Pr->CP_HaveCustomData)) { + } else if((pSiS->VBLCDFlags & VB_LCD_CUSTOM) && (pSiS->SiS_Pr->CP_MaxClock)) { return pSiS->SiS_Pr->CP_MaxClock; - } else - return 108000; + } else { + if(pSiS->VBFlags & VB_301C) return 162000; + else return 108000; + } } else if(pSiS->VBFlags & CRT2_TV) { if(pSiS->VBFlags & VB_CHRONTEL) { switch(pSiS->VGAEngine) { @@ -1428,10 +1456,8 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2) #ifdef __SUNPRO_C #define const #endif - const float magic300[4] = { 1.2, 1.368421, 2.263158, 1.2}; - const float magic630[4] = { 1.441177, 1.441177, 2.588235, 1.441177 }; - const float magic315[4] = { 1.2, 1.368421, 1.368421, 1.2 }; - const float magic550[4] = { 1.441177, 1.441177, 2.588235, 1.441177 }; + const float magicDED[4] = { 1.2, 1.368421, 2.263158, 1.2}; + const float magicINT[4] = { 1.441177, 1.441177, 2.588235, 1.441177 }; #ifdef __SUNPRO_C #undef const #endif @@ -1473,39 +1499,44 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2) case PCI_CHIP_SIS650: case PCI_CHIP_SIS330: case PCI_CHIP_SIS660: + case PCI_CHIP_SIS340: switch(pSiS->Chipset) { case PCI_CHIP_SIS300: - magic = magic300[bus/64]; + magic = magicDED[bus/64]; max = 540000; break; case PCI_CHIP_SIS540: case PCI_CHIP_SIS630: - magic = magic630[bus/64]; + magic = magicINT[bus/64]; max = 540000; break; case PCI_CHIP_SIS315: case PCI_CHIP_SIS315H: case PCI_CHIP_SIS315PRO: case PCI_CHIP_SIS330: - magic = magic315[bus/64]; + magic = magicDED[bus/64]; max = 780000; break; case PCI_CHIP_SIS550: - magic = magic550[bus/64]; + magic = magicINT[bus/64]; max = 620000; break; case PCI_CHIP_SIS650: - magic = magic550[bus/64]; + magic = magicINT[bus/64]; max = 680000; break; case PCI_CHIP_SIS660: if((pSiS->sishw_ext.jChipType >= SIS_660) && (!(pSiS->ChipFlags & SiSCF_760UMA))) { - magic = magic315[bus/64]; + magic = magicDED[bus/64]; } else { - magic = magic550[bus/64]; + magic = magicINT[bus/64]; } - max = 680000; + max = 800000; + case PCI_CHIP_SIS340: + magic = magicDED[bus/64]; + max = 800000; + break; } PDEBUG(ErrorF("mclk: %d, bus: %d, magic: %g, bpp: %d\n", @@ -1528,7 +1559,7 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2) crt2used = 0.0; crt2clock = SiSEstimateCRT2Clock(pScrn, IsForCRT2); if(crt2clock) { - crt2used = crt2clock + 2000; + crt2used = crt2clock + 2000; } DHM = FALSE; GetForCRT1 = FALSE; @@ -1550,17 +1581,17 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2) if(!GetForCRT1) { - /* TW: First head = CRT2 */ + /* First head = CRT2 */ if(crt2clock) { - /* TW: We use the mem bandwidth as max clock; this - * might exceed the 70% limit a bit, but that - * does not matter; we take care of that limit - * when we calc CRT1. Overall, we might use up - * to 85% of the memory bandwidth, which seems - * enough to use accel and video. - * The "* macic" is just to compensate the - * calculation below. + /* We use the mem bandwidth as max clock; this + * might exceed the 70% limit a bit, but that + * does not matter; we take care of that limit + * when we calc CRT1. Overall, we might use up + * to 85% of the memory bandwidth, which seems + * enough to use accel and video. + * The "* macic" is just to compensate the + * calculation below. */ total = crt2used * magic; @@ -1587,7 +1618,7 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2) } else { #ifdef SISDUALHEAD - /* TW: Second head = CRT1 */ + /* Second head = CRT1 */ /* Now We know about the first head's depth, * so we can calculate more accurately. @@ -1885,6 +1916,7 @@ SISDACPreInit(ScrnInfoPtr pScrn) case PCI_CHIP_SIS315PRO: case PCI_CHIP_SIS330: case PCI_CHIP_SIS660: + case PCI_CHIP_SIS340: pSiS->MaxClock = SiSMemBandWidth(pScrn, FALSE); pSiS->SiSSave = SiS315Save; pSiS->SiSSave2 = SiS301Save; @@ -1971,3 +2003,53 @@ SiS6326GetXXReg(ScrnInfoPtr pScrn, CARD8 index) inSISIDXREG(SISCR, 0xE3, data); return(data); } + +unsigned char SiSGetCopyROP(int rop) +{ + const unsigned char sisALUConv[] = + { + 0x00, /* dest = 0; 0, GXclear, 0 */ + 0x88, /* dest &= src; DSa, GXand, 0x1 */ + 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */ + 0xCC, /* dest = src; S, GXcopy, 0x3 */ + 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */ + 0xAA, /* dest = dest; D, GXnoop, 0x5 */ + 0x66, /* dest = ^src; DSx, GXxor, 0x6 */ + 0xEE, /* dest |= src; DSo, GXor, 0x7 */ + 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */ + 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */ + 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ + 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */ + 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */ + 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */ + 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */ + 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ + }; + + return(sisALUConv[rop]); +} + +unsigned char SiSGetPatternROP(int rop) +{ + const unsigned char sisPatALUConv[] = + { + 0x00, /* dest = 0; 0, GXclear, 0 */ + 0xA0, /* dest &= src; DPa, GXand, 0x1 */ + 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */ + 0xF0, /* dest = src; P, GXcopy, 0x3 */ + 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */ + 0xAA, /* dest = dest; D, GXnoop, 0x5 */ + 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */ + 0xFA, /* dest |= src; DPo, GXor, 0x7 */ + 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */ + 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */ + 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ + 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */ + 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */ + 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */ + 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */ + 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ + }; + + return(sisPatALUConv[rop]); +} |