/drivers/video/sis/init301.c
C | 11260 lines | 9172 code | 1583 blank | 505 comment | 3524 complexity | f965b504f6b9a385cf8db7cb0d0906b8 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, GPL-2.0, LGPL-2.0, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- /* $XFree86$ */
- /* $XdotOrg$ */
- /*
- * Mode initializing code (CRT2 section)
- * for SiS 300/305/540/630/730,
- * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
- * XGI V3XT/V5/V8, Z7
- * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
- *
- * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
- *
- * If distributed as part of the Linux kernel, the following license terms
- * apply:
- *
- * * This program is free software; you can redistribute it and/or modify
- * * it under the terms of the GNU General Public License as published by
- * * the Free Software Foundation; either version 2 of the named License,
- * * or any later version.
- * *
- * * This program is distributed in the hope that it will be useful,
- * * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * * GNU General Public License for more details.
- * *
- * * You should have received a copy of the GNU General Public License
- * * along with this program; if not, write to the Free Software
- * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
- *
- * Otherwise, the following license terms apply:
- *
- * * Redistribution and use in source and binary forms, with or without
- * * modification, are permitted provided that the following conditions
- * * are met:
- * * 1) Redistributions of source code must retain the above copyright
- * * notice, this list of conditions and the following disclaimer.
- * * 2) Redistributions in binary form must reproduce the above copyright
- * * notice, this list of conditions and the following disclaimer in the
- * * documentation and/or other materials provided with the distribution.
- * * 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 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,
- * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Author: Thomas Winischhofer <thomas@winischhofer.net>
- *
- * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
- * Used by permission.
- *
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #if 1
- #define SET_EMI /* 302LV/ELV: Set EMI values */
- #endif
- #if 1
- #define SET_PWD /* 301/302LV: Set PWD */
- #endif
- #define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
- #define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
- #define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
- #include "init301.h"
- #ifdef SIS300
- #include "oem300.h"
- #endif
- #ifdef SIS315H
- #include "oem310.h"
- #endif
- #define SiS_I2CDELAY 1000
- #define SiS_I2CDELAYSHORT 150
- static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
- #ifdef SIS_LINUX_KERNEL
- static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
- #endif
- /*********************************************/
- /* HELPER: Lock/Unlock CRT2 */
- /*********************************************/
- void
- SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
- {
- if(SiS_Pr->ChipType == XGI_20)
- return;
- else if(SiS_Pr->ChipType >= SIS_315H)
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
- else
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
- }
- #ifdef SIS_LINUX_KERNEL
- static
- #endif
- void
- SiS_LockCRT2(struct SiS_Private *SiS_Pr)
- {
- if(SiS_Pr->ChipType == XGI_20)
- return;
- else if(SiS_Pr->ChipType >= SIS_315H)
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
- else
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
- }
- /*********************************************/
- /* HELPER: Write SR11 */
- /*********************************************/
- static void
- SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
- {
- if(SiS_Pr->ChipType >= SIS_661) {
- DataAND &= 0x0f;
- DataOR &= 0x0f;
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
- }
- /*********************************************/
- /* HELPER: Get Pointer to LCD structure */
- /*********************************************/
- #ifdef SIS315H
- static unsigned char *
- GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
- {
- unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
- unsigned char *myptr = NULL;
- unsigned short romindex = 0, reg = 0, idx = 0;
- /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
- * due to the variaty of panels the BIOS doesn't know about.
- * Exception: If the BIOS has better knowledge (such as in case
- * of machines with a 301C and a panel that does not support DDC)
- * use the BIOS data as well.
- */
- if((SiS_Pr->SiS_ROMNew) &&
- ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
- if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
- else reg = 0x7d;
- idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
- if(idx < (8*26)) {
- myptr = (unsigned char *)&SiS_LCDStruct661[idx];
- }
- romindex = SISGETROMW(0x100);
- if(romindex) {
- romindex += idx;
- myptr = &ROMAddr[romindex];
- }
- }
- return myptr;
- }
- static unsigned short
- GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
- {
- unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
- unsigned short romptr = 0;
- /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
- * due to the variaty of panels the BIOS doesn't know about.
- * Exception: If the BIOS has better knowledge (such as in case
- * of machines with a 301C and a panel that does not support DDC)
- * use the BIOS data as well.
- */
- if((SiS_Pr->SiS_ROMNew) &&
- ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
- romptr = SISGETROMW(0x102);
- romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
- }
- return romptr;
- }
- #endif
- /*********************************************/
- /* Adjust Rate for CRT2 */
- /*********************************************/
- static bool
- SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
- unsigned short RRTI, unsigned short *i)
- {
- unsigned short checkmask=0, modeid, infoflag;
- modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
- checkmask |= SupportRAMDAC2;
- if(SiS_Pr->ChipType >= SIS_315H) {
- checkmask |= SupportRAMDAC2_135;
- if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
- checkmask |= SupportRAMDAC2_162;
- if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
- checkmask |= SupportRAMDAC2_202;
- }
- }
- }
- } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- checkmask |= SupportLCD;
- if(SiS_Pr->ChipType >= SIS_315H) {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- if(modeid == 0x2e) checkmask |= Support64048060Hz;
- }
- }
- }
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- checkmask |= SupportHiVision;
- } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
- checkmask |= SupportTV;
- if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
- checkmask |= SupportTV1024;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
-