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

📄 radeon_driver.c

📁 ati driver
💻 C
📖 第 1 页 / 共 5 页
字号:
	else if((pRADEONEnt->MonType1 = 		 RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo1))) {	  ddc_crt2_used = TRUE;	} else if ((info->IsMobility) && 		   (info->VBIOS && (INREG(RADEON_BIOS_4_SCRATCH) & 4))) {	    /* non-DDC laptop panel connected on primary */	    pRADEONEnt->MonType1 = MT_LCD;	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Non-DDC laptop panel detected\n");	} else {	    /* CRT on DVI, TODO: not reliable, make it always return false for now*/	    pRADEONEnt->MonType1 = RADEONCrtIsPhysicallyConnected(pScrn, pRADEONEnt->ReversedDAC);	}	/* Secondary Head (mostly VGA, can be DVI on some OEM boards)*/	if((pRADEONEnt->MonType2 = 	    RADEONDisplayDDCConnected(pScrn, DDC_VGA, &pRADEONEnt->MonInfo2)));	else if(!ddc_crt2_used) 	  pRADEONEnt->MonType2 = 		 RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo2);	if (!pRADEONEnt->MonType2)	    pRADEONEnt->MonType2 = RADEONCrtIsPhysicallyConnected(pScrn, !pRADEONEnt->ReversedDAC);	if(pRADEONEnt->ReversedTMDS) {	    /* always keep internal TMDS as primary head */	    if (pRADEONEnt->MonType1 == MT_DFP || 		pRADEONEnt->MonType2 == MT_DFP) {		int tmp1 = pRADEONEnt->MonType1;		xf86MonPtr MonInfo = pRADEONEnt->MonInfo1;		pRADEONEnt->MonInfo1 = pRADEONEnt->MonInfo2;		pRADEONEnt->MonInfo2 = MonInfo;		pRADEONEnt->MonType1 = pRADEONEnt->MonType2;		pRADEONEnt->MonType2 = tmp1;		if ((pRADEONEnt->MonType1 == MT_CRT) || 		    (pRADEONEnt->MonType2 == MT_CRT)) {		    pRADEONEnt->ReversedDAC ^= 1;		}	    }	}	/* no display detected on DVI port*/	if (pRADEONEnt->MonType1 == MT_NONE) {	    if (pRADEONEnt->MonType2 != MT_NONE) {		/* Only one detected on VGA, let it to be primary */		pRADEONEnt->MonType1 = pRADEONEnt->MonType2;		pRADEONEnt->MonInfo1 = pRADEONEnt->MonInfo2;		pRADEONEnt->MonType2 = MT_NONE;		pRADEONEnt->MonInfo2 = NULL;	    } else {		/* Non detected, Default to a CRT connected */		pRADEONEnt->MonType1 = MT_CRT;	    }	}    }    if(s) {	xf86DrvMsg(pScrn->scrnIndex, X_INFO, 		   "Displays Configured by MonitorLayout: \n\tMonitor1--Type %d, Monitor2--Type %d\n\n", 		   pRADEONEnt->MonType1, pRADEONEnt->MonType2);    } else {	xf86DrvMsg(pScrn->scrnIndex, X_INFO, 		   "Displays Detected: Monitor1--Type %d, Monitor2--Type %d\n\n", 		   pRADEONEnt->MonType1, pRADEONEnt->MonType2);    }    if(ignore_edid) {	pRADEONEnt->MonInfo1 = NULL;	pRADEONEnt->MonInfo2 = NULL;    }    if (!ignore_edid) {	if (pRADEONEnt->MonInfo1) {	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitor1 EDID data ---------------------------\n");	    xf86PrintEDID( pRADEONEnt->MonInfo1 );	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of Monitor1 EDID data --------------------\n");	}	if (pRADEONEnt->MonInfo2) {	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitor2 EDID data ---------------------------\n");	    xf86PrintEDID( pRADEONEnt->MonInfo2 );	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of Monitor2 EDID data --------------------\n");	}    }        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\n");    info->OverlayOnCRTC2 = FALSE;   if (xf86ReturnOptValBool(info->Options, OPTION_CRTC2_OVERLAY, FALSE)) {	info->OverlayOnCRTC2 = TRUE;    }    if (pRADEONEnt->MonType2 == MT_NONE) 	pRADEONEnt->HasSecondary = FALSE;}/* Read the Video BIOS block and the FP registers (if applicable). */static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10){    RADEONInfoPtr  info            = RADEONPTR(pScrn);    unsigned long  tmp, i;    unsigned char *RADEONMMIO;    if (!(info->VBIOS = xalloc(RADEON_VBIOS_SIZE))) {	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		   "Cannot allocate space for hold Video BIOS!\n");	return FALSE;    }    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) {	xfree(info->VBIOS);	info->FPBIOSstart = 0;	info->VBIOS = NULL;	info->BIOSAddr = 0x00000000;	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		   "Video BIOS not found!\n");    } else	info->FPBIOSstart = RADEON_BIOS16(0x48);    info->OverlayOnCRTC2 = FALSE;    if (!info->IsSecondary)	RADEONQueryConnectedDisplays(pScrn, pInt10);    {	RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);	RADEONMMIO = info->MMIO;	info->Clone = FALSE;	info->CloneType = MT_NONE;	if(info->HasCRTC2) {   	    if(info->IsSecondary) {               		if(!(info->DisplayType = pRADEONEnt->MonType2)) return FALSE;	    } else {		info->DisplayType = pRADEONEnt->MonType1; 		if(!pRADEONEnt->HasSecondary) {		    if ((info->CloneType = pRADEONEnt->MonType2))			info->Clone = TRUE;		} 	    }	} else {	    info->DisplayType = pRADEONEnt->MonType1; 	}	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Display == Type %d\n",		   (info->IsSecondary ? "Secondary" : "Primary"), 		   info->DisplayType);	if (info->Clone)	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clone Display == Type %d\n",		       info->CloneType);         	info->HBlank     = 0;	info->HOverPlus  = 0;	info->HSyncWidth = 0;	info->VBlank     = 0;	info->VOverPlus  = 0;	info->VSyncWidth = 0;	info->DotClock   = 0;	info->UseBiosDividers = FALSE;	if (info->DisplayType == MT_LCD && info->VBIOS &&	    !(xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {	    tmp = RADEON_BIOS16(info->FPBIOSstart + 0x40);            if (!tmp) {		info->PanelPwrDly = 200;		xf86DrvMsg(pScrn->scrnIndex, X_INFO,                           "No Panel Info Table found in BIOS!\n");            } else {		char  stmp[30];		int   tmp0;		for (i = 0; i < 24; i++)		    stmp[i] = RADEON_BIOS8(tmp+i+1);		stmp[24] = 0;		xf86DrvMsg(pScrn->scrnIndex, X_INFO,                           "Panel ID string: %s\n", stmp);		info->PanelXRes = RADEON_BIOS16(tmp+25);		info->PanelYRes = RADEON_BIOS16(tmp+27);		xf86DrvMsg(0, X_INFO, "Panel Size from BIOS: %dx%d\n",			   info->PanelXRes, info->PanelYRes);		 		info->PanelPwrDly = RADEON_BIOS16(tmp+44);		if (info->PanelPwrDly > 2000 || info->PanelPwrDly < 0)		    info->PanelPwrDly = 2000;		/* some panels only work well with certain divider combinations.		 */		info->RefDivider = RADEON_BIOS16(tmp+46);		info->PostDivider = RADEON_BIOS8(tmp+48);		info->FeedbackDivider = RADEON_BIOS16(tmp+49);		if ((info->RefDivider != 0) && 		    (info->FeedbackDivider > 3)) {		  info->UseBiosDividers = TRUE;		  xf86DrvMsg(pScrn->scrnIndex, X_INFO, 			     "BIOS provided dividers will be used.\n");		}		/* We don't use a while loop here just in case we have a corrupted BIOS image.		   The max number of table entries is 23 at present, but may grow in future.		   To ensure it works with future revisions we loop it to 32.		*/		for (i = 0; i < 32; i++) {		    tmp0 = RADEON_BIOS16(tmp+64+i*2);		    if (tmp0 == 0) break;		    if ((RADEON_BIOS16(tmp0) == info->PanelXRes) &&			(RADEON_BIOS16(tmp0+2) == info->PanelYRes)) {			info->HBlank     = (RADEON_BIOS16(tmp0+17) -					    RADEON_BIOS16(tmp0+19)) * 8;			info->HOverPlus  = (RADEON_BIOS16(tmp0+21) -					    RADEON_BIOS16(tmp0+19) - 1) * 8;			info->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8;			info->VBlank     = (RADEON_BIOS16(tmp0+24) -					    RADEON_BIOS16(tmp0+26));			info->VOverPlus  = ((RADEON_BIOS16(tmp0+28) & 0x7ff) -					    RADEON_BIOS16(tmp0+26));			info->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11);			info->DotClock   = RADEON_BIOS16(tmp0+9) * 10;			info->Flags = 0;		    }		}		if (info->DotClock == 0) {		    DisplayModePtr  tmp_mode = NULL;		    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,			       "No valid timing info from BIOS.\n");		    /* No timing information for the native mode, 		       use whatever specified in the Modeline.		       If no Modeline specified, we'll just pick 		       the VESA mode at 60Hz refresh rate which 		       is likely to be the best for a flat panel.		    */ 		    tmp_mode = pScrn->monitor->Modes;		    while(tmp_mode) {			if ((tmp_mode->HDisplay == info->PanelXRes) && 			    (tmp_mode->VDisplay == info->PanelYRes)) {			    float  refresh =				(float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal;			    if ((abs(60.0 - refresh) < 1.0) ||				(tmp_mode->type == 0)) {				info->HBlank     = tmp_mode->HTotal - tmp_mode->HDisplay;				info->HOverPlus  = tmp_mode->HSyncStart - tmp_mode->HDisplay;				info->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart;				info->VBlank     = tmp_mode->VTotal - tmp_mode->VDisplay;				info->VOverPlus  = tmp_mode->VSyncStart - tmp_mode->VDisplay;				info->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart;				info->DotClock   = tmp_mode->Clock;				info->Flags = 0;				break;			    }			    tmp_mode = tmp_mode->next;			}		    }		    if ((info->DotClock == 0) && !pRADEONEnt->MonInfo1) {			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,				   "Panel size is not correctly detected.\n"				   "Please try to use PanelSize option for correct settings.\n");			return FALSE;		    }		}	    }	}     }             if (info->VBIOS) {	tmp = RADEON_BIOS16(info->FPBIOSstart + 0x30);	info->sclk = RADEON_BIOS16(tmp + 8) / 100.0;	info->mclk = RADEON_BIOS16(tmp + 10) / 100.0;    } else {	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No valid info for SCLK/MCLK for display bandwidth calculation.\n"); 	info->sclk = 200.00;	info->mclk = 200.00;    }    return TRUE;}static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn){    RADEONInfoPtr info = RADEONPTR(pScrn);    RADEONPLLPtr  pll  = &info->pll;    unsigned char *RADEONMMIO = info->MMIO;    unsigned char ppll_div_sel;    unsigned Nx, M;    unsigned xclk, tmp, ref_div;    int hTotal, vTotal, num, denom, m, n;    float hz, vclk, xtal;    long start_secs, start_usecs, stop_secs, stop_usecs, total_usecs;    int i;    tmp = INREG(RADEON_DEVICE_ID);     for(i=0; i<1000000; i++)	if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0)	    break;     xf86getsecs(&start_secs, &start_usecs);     for(i=0; i<1000000; i++)	if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) != 0)	    break;     for(i=0; i<1000000; i++)	if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0)	    break;     xf86getsecs(&stop_secs, &stop_usecs);     total_usecs = abs(stop_usecs - start_usecs);    hz = 1000000/total_usecs;     hTotal = ((INREG(RADEON_CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8;    vTotal = ((INREG(RADEON_CRTC_V_TOTAL_DISP) & 0x3ff) + 1);    vclk = (float)(hTotal * (float)(vTotal * hz));    switch((INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x30000) >> 16) {    case 0:    default:        num = 1;        denom = 1;        break;    case 1:        n = ((INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV) >> 16) & 0xff);        m = (INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV) & 0xff);        num = 2*n;        denom = 2*m;        break;    case 2:        n = ((INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV) >> 8) & 0xff);        m = (INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV) & 0xff);        num = 2*n;        denom = 2*m;        break;     }     OUTREG(RADEON_CLOCK_CNTL_INDEX, 1);    ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_DATA + 1) & 0x3;    n = (INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel) & 0x7ff);    m = (INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x3ff);    num *= n;    denom *= m;       switch ((INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel) >> 16) & 0x7) {    case 1:        denom *= 2;        break;    case 2:        denom *= 4;        break;    case 3:        denom *= 8;        break;    case 4:        denom *= 3;        break;    case 6:        denom *= 6;           break;    case 7:        denom *= 12;        break;    }    xtal = (int)(vclk *(float)denom/(float)num);    if ((xtal > 26900000) && (xtal < 27100000))        xtal = 2700;    else if ((xtal > 14200000) && (xtal < 14400000))        xtal = 1432;    else if ((xtal > 29400000) && (xtal < 29600000))        xtal = 2950;    else	return FALSE;    tmp = INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV);    ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x3ff;    Nx = (tmp & 0xff00) >> 8;    M = (tmp & 0xff);    xclk = RADEONDiv((2 * Nx * xtal), (2 * M));    /* we're done, hopefully these are sane values */    pll->reference_div = ref_div;    pll->xclk = xclk;    pll->reference_freq = xtal;    return TRUE;}static void RADEONGetTMDSInfo(ScrnInfoPtr pScrn){    RADEONInfoPtr  info = RADEONPTR(pScrn);    CARD32 tmp;    int i, n;    for (i=0; i<4; i++) {	info->tmds_pll[i].value = 0;	info->tmds_pll[i].freq = 0;    }    if (info->VBIOS) {	tmp = RADEON_BIOS16(info->FPBIOSstart + 0x34);	if (tmp) {	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,		       "DFP table revision: %d\n", RADEON_BIOS8(tmp));	    if (RADEON_BIOS8(tmp) == 3) {		n = RADEON_BIOS8(tmp + 5) + 1;		if (n > 4) n = 4;		for (i=0; i<n; i++) {		    info->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08);		    info->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10);		}		return;

⌨️ 快捷键说明

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