⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radeon_bios.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_bios.c,v 1.0 Exp $ *//* * Copyright 2004 ATI Technologies Inc., Markham, Ontario * * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation on the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "xf86.h"#include "xf86_OSproc.h"#include "radeon.h"#include "radeon_reg.h"#include "radeon_macros.h"#include "radeon_probe.h"#include "vbe.h"/* Read the Video BIOS block and the FP registers (if applicable). */Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10){    RADEONInfoPtr info     = RADEONPTR(pScrn);    int tmp;    unsigned short dptr;    if (!(info->VBIOS = xalloc(RADEON_VBIOS_SIZE))) {	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		   "Cannot allocate space for hold Video BIOS!\n");	return FALSE;    } else {	if (pInt10) {	    info->BIOSAddr = pInt10->BIOSseg << 4;	    (void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr),			 RADEON_VBIOS_SIZE);	} else {	    xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, RADEON_VBIOS_SIZE);	    if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,			   "Video BIOS not detected in PCI space!\n");		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,			   "Attempting to read Video BIOS from "			   "legacy ISA space!\n");		info->BIOSAddr = 0x000c0000;		xf86ReadDomainMemory(info->PciTag, info->BIOSAddr,				     RADEON_VBIOS_SIZE, info->VBIOS);	    }	}    }    if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		   "Unrecognized BIOS signature, BIOS data will not be used\n");	xfree (info->VBIOS);	info->VBIOS = NULL;	return FALSE;    }    /* Verify it's an x86 BIOS not OF firmware, copied from radeonfb */    dptr = RADEON_BIOS16(0x18);    /* If PCI data signature is wrong assume x86 video BIOS anyway */    if (RADEON_BIOS32(dptr) != (('R' << 24) | ('I' << 16) | ('C' << 8) | 'P')) {       xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		   "ROM PCI data signature incorrect, ignoring\n");    }    else if (info->VBIOS[dptr + 0x14] != 0x0) {	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		   "Not an x86 BIOS ROM image, BIOS data will not be used\n");	xfree (info->VBIOS);	info->VBIOS = NULL;	return FALSE;    }    if (info->VBIOS) info->ROMHeaderStart = RADEON_BIOS16(0x48);    if(!info->ROMHeaderStart) {	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		   "Invalid ROM pointer, BIOS data will not be used\n");	xfree (info->VBIOS);	info->VBIOS = NULL;	return FALSE;    }     tmp = info->ROMHeaderStart + 4;    if ((RADEON_BIOS8(tmp)   == 'A' &&	 RADEON_BIOS8(tmp+1) == 'T' &&	 RADEON_BIOS8(tmp+2) == 'O' &&	 RADEON_BIOS8(tmp+3) == 'M') ||	(RADEON_BIOS8(tmp)   == 'M' &&	 RADEON_BIOS8(tmp+1) == 'O' &&	 RADEON_BIOS8(tmp+2) == 'T' &&	 RADEON_BIOS8(tmp+3) == 'A'))	info->IsAtomBios = TRUE;    else	info->IsAtomBios = FALSE;    if (info->IsAtomBios) 	info->MasterDataStart = RADEON_BIOS16 (info->ROMHeaderStart + 32);    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s BIOS detected\n",	       info->IsAtomBios ? "ATOM":"Legacy");    return TRUE;}Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn){    RADEONInfoPtr info = RADEONPTR (pScrn);    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);    int i = 0, j, tmp, tmp0=0, tmp1=0;    if(!info->VBIOS) return FALSE;    if (info->IsAtomBios) {	if((tmp = RADEON_BIOS16 (info->MasterDataStart + 22))) {	    int crtc = 0, id[2];	    tmp1 = RADEON_BIOS16 (tmp + 4);	    for (i=0; i<8; i++) {		if(tmp1 & (1<<i)) {		    CARD16 portinfo = RADEON_BIOS16(tmp+6+i*2);		    if (crtc < 2) {			if ((i==2) || (i==6)) continue; /* ignore TV here */			if (crtc == 1) {			    /* sharing same port with id[0] */			    if (((portinfo>>8) & 0xf) == id[0]) {				if (i == 3) 				    pRADEONEnt->PortInfo[0].TMDSType = TMDS_INT;				else if (i == 7)				    pRADEONEnt->PortInfo[0].TMDSType = TMDS_EXT;				if (pRADEONEnt->PortInfo[0].DACType == DAC_UNKNOWN)				    pRADEONEnt->PortInfo[0].DACType = (portinfo & 0xf) - 1;				continue;			    }			}			id[crtc] = (portinfo>>8) & 0xf; 			pRADEONEnt->PortInfo[crtc].DACType = (portinfo & 0xf) - 1;			pRADEONEnt->PortInfo[crtc].ConnectorType = (portinfo>>4) & 0xf;			if (i == 3) 			    pRADEONEnt->PortInfo[crtc].TMDSType = TMDS_INT;			else if (i == 7)			    pRADEONEnt->PortInfo[crtc].TMDSType = TMDS_EXT;						if((tmp0 = RADEON_BIOS16 (info->MasterDataStart + 24)) && id[crtc]) {			    switch (RADEON_BIOS16 (tmp0 + 4 + 27 * id[crtc]) * 4) 			    {			    case RADEON_GPIO_MONID:				pRADEONEnt->PortInfo[crtc].DDCType = DDC_MONID;				break;			    case RADEON_GPIO_DVI_DDC:				pRADEONEnt->PortInfo[crtc].DDCType = DDC_DVI;				break;			    case RADEON_GPIO_VGA_DDC:				pRADEONEnt->PortInfo[crtc].DDCType = DDC_VGA;				break;			    case RADEON_GPIO_CRT2_DDC:				pRADEONEnt->PortInfo[crtc].DDCType = DDC_CRT2;				break;			    default:				pRADEONEnt->PortInfo[crtc].DDCType = DDC_NONE_DETECTED;				break;			    }			} else {			    pRADEONEnt->PortInfo[crtc].DDCType = DDC_NONE_DETECTED;			}			crtc++;		    } else {			/* we have already had two CRTCs assigned. the rest may share the same			 * port with the existing connector, fill in them accordingly.			 */			for (j=0; j<2; j++) {			    if (((portinfo>>8) & 0xf) == id[j]) {				if (i == 3) 				    pRADEONEnt->PortInfo[j].TMDSType = TMDS_INT;				else if (i == 7)				    pRADEONEnt->PortInfo[j].TMDSType = TMDS_EXT;				if (pRADEONEnt->PortInfo[j].DACType == DAC_UNKNOWN)				    pRADEONEnt->PortInfo[j].DACType = (portinfo & 0xf) - 1;			    }			}		    }		}	    }	    for (i=0; i<2; i++) {		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",			   i, pRADEONEnt->PortInfo[i].DDCType, pRADEONEnt->PortInfo[i].DACType,			   pRADEONEnt->PortInfo[i].TMDSType, pRADEONEnt->PortInfo[i].ConnectorType);	    }	    	} else {	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n");	    return FALSE;	}    } else {	/* Some laptops only have one connector (VGA) listed in the connector table, 	 * we need to add LVDS in as a non-DDC display. 	 * Note, we can't assume the listed VGA will be filled in PortInfo[0],	 * when walking through connector table. connector_found has following meaning: 	 * 0 -- nothing found, 	 * 1 -- only PortInfo[0] filled, 	 * 2 -- only PortInfo[1] filled,	 * 3 -- both are filled.	 */	int connector_found = 0;	if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x50))) {	    for (i = 1; i < 4; i++) {		if (!RADEON_BIOS16(tmp + i*2))			break; /* end of table */				tmp0 = RADEON_BIOS16(tmp + i*2);		if (((tmp0 >> 12) & 0x0f) == 0) continue;     /* no connector */		if (connector_found > 0) {		    if (pRADEONEnt->PortInfo[tmp1].DDCType == ((tmp0 >> 8) & 0x0f))			continue;                             /* same connector */		}		/* internal DDC_DVI port will get assigned to PortInfo[0], or if there is no DDC_DVI (like in some IGPs). */		tmp1 = ((((tmp0 >> 8) & 0xf) == DDC_DVI) || (tmp1 == 1)) ? 0 : 1; /* determine port info index */				pRADEONEnt->PortInfo[tmp1].DDCType        = (tmp0 >> 8) & 0x0f;		if (pRADEONEnt->PortInfo[tmp1].DDCType > DDC_CRT2) pRADEONEnt->PortInfo[tmp1].DDCType = DDC_NONE_DETECTED;		pRADEONEnt->PortInfo[tmp1].DACType        = (tmp0 & 0x01) ? DAC_TVDAC : DAC_PRIMARY;		pRADEONEnt->PortInfo[tmp1].ConnectorType  = (tmp0 >> 12) & 0x0f;		if (pRADEONEnt->PortInfo[tmp1].ConnectorType > CONNECTOR_UNSUPPORTED) pRADEONEnt->PortInfo[tmp1].ConnectorType = CONNECTOR_UNSUPPORTED;		pRADEONEnt->PortInfo[tmp1].TMDSType       = ((tmp0 >> 4) & 0x01) ? TMDS_EXT : TMDS_INT;		/* some sanity checks */		if (((pRADEONEnt->PortInfo[tmp1].ConnectorType != CONNECTOR_DVI_D) &&		     (pRADEONEnt->PortInfo[tmp1].ConnectorType != CONNECTOR_DVI_I)) &&		    pRADEONEnt->PortInfo[tmp1].TMDSType == TMDS_INT)		    pRADEONEnt->PortInfo[tmp1].TMDSType = TMDS_UNKNOWN;				connector_found += (tmp1 + 1);	    }	} else {	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Connector Info Table found!\n");	    return FALSE;	}	if (info->IsMobility) {	    /* For the cases where only one VGA connector is found, 	       we assume LVDS is not listed in the connector table, 	       add it in here as the first port.	    */	    if ((connector_found < 3) && (pRADEONEnt->PortInfo[tmp1].ConnectorType == CONNECTOR_CRT)) {		if (connector_found == 1) {		    memcpy (&pRADEONEnt->PortInfo[1], &pRADEONEnt->PortInfo[0], 			    sizeof (pRADEONEnt->PortInfo[0]));		}		pRADEONEnt->PortInfo[0].DACType = DAC_TVDAC;		pRADEONEnt->PortInfo[0].TMDSType = TMDS_UNKNOWN;		pRADEONEnt->PortInfo[0].DDCType = DDC_NONE_DETECTED;		pRADEONEnt->PortInfo[0].ConnectorType = CONNECTOR_PROPRIETARY;		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "LVDS port is not in connector table, added in.\n");		if (connector_found == 0) connector_found = 1;		else connector_found = 3;	    }	    if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42))) {	        if ((tmp0 = RADEON_BIOS16(tmp + 0x15))) {		    if ((tmp1 = RADEON_BIOS8(tmp0+2) & 0x07)) {	    			pRADEONEnt->PortInfo[0].DDCType	= tmp1;      			if (pRADEONEnt->PortInfo[0].DDCType > DDC_CRT2) {			    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,				       "Unknown DDCType %d found\n",				       pRADEONEnt->PortInfo[0].DDCType);			    pRADEONEnt->PortInfo[0].DDCType = DDC_NONE_DETECTED;			}			xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n");		    }		}	    } 	} else if (connector_found == 2) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -