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

📄 radeon_driver.c

📁 ati driver
💻 C
📖 第 1 页 / 共 5 页
字号:
static RADEONMonitorTypeRADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac){    RADEONInfoPtr info       = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    int	          bConnected = 0;    /* the monitor either wasn't connected or it is a non-DDC CRT.     * try to probe it     */    if(IsCrtDac) {	unsigned long ulOrigVCLK_ECP_CNTL;	unsigned long ulOrigDAC_CNTL;	unsigned long ulOrigDAC_EXT_CNTL;	unsigned long ulOrigCRTC_EXT_CNTL;	unsigned long ulData;	unsigned long ulMask;	ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);	ulData              = ulOrigVCLK_ECP_CNTL;	ulData             &= ~(RADEON_PIXCLK_ALWAYS_ONb				| RADEON_PIXCLK_DAC_ALWAYS_ONb);	ulMask              = ~(RADEON_PIXCLK_ALWAYS_ONb				|RADEON_PIXCLK_DAC_ALWAYS_ONb);	OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);	ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);	ulData              = ulOrigCRTC_EXT_CNTL;	ulData             |= RADEON_CRTC_CRT_ON;	OUTREG(RADEON_CRTC_EXT_CNTL, ulData);   	ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);	ulData             = ulOrigDAC_EXT_CNTL;	ulData            &= ~RADEON_DAC_FORCE_DATA_MASK;	ulData            |=  (RADEON_DAC_FORCE_BLANK_OFF_EN			       |RADEON_DAC_FORCE_DATA_EN			       |RADEON_DAC_FORCE_DATA_SEL_MASK);	if ((info->ChipFamily == CHIP_FAMILY_RV250) ||	    (info->ChipFamily == CHIP_FAMILY_RV280))	    ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);	else	    ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);	OUTREG(RADEON_DAC_EXT_CNTL, ulData);	ulOrigDAC_CNTL     = INREG(RADEON_DAC_CNTL);	ulData             = ulOrigDAC_CNTL;	ulData            |= RADEON_DAC_CMP_EN;	ulData            &= ~(RADEON_DAC_RANGE_CNTL_MASK			       | RADEON_DAC_PDWN);	ulData            |= 0x2;	OUTREG(RADEON_DAC_CNTL, ulData);	usleep(1000);	ulData     = INREG(RADEON_DAC_CNTL);	bConnected =  (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;  	ulData    = ulOrigVCLK_ECP_CNTL;	ulMask    = 0xFFFFFFFFL;	OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);	OUTREG(RADEON_DAC_CNTL,      ulOrigDAC_CNTL     );	OUTREG(RADEON_DAC_EXT_CNTL,  ulOrigDAC_EXT_CNTL );	OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);    } else { /* TV DAC */        /* This doesn't seem to work reliably (maybe worse on some OEM cards),            for now we always return false. If one wants to connected a            non-DDC monitor on the DVI port when CRT port is also connected,            he will need to explicitly tell the driver in the config file            with Option MonitorLayout.        */        bConnected = FALSE;#if 0	if (info->ChipFamily == CHIP_FAMILY_R200) {	    unsigned long ulOrigGPIO_MONID;	    unsigned long ulOrigFP2_GEN_CNTL;	    unsigned long ulOrigDISP_OUTPUT_CNTL;	    unsigned long ulOrigCRTC2_GEN_CNTL;	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;	    unsigned long ulOrigCRTC2_H_TOTAL_DISP;	    unsigned long ulOrigCRTC2_V_TOTAL_DISP;	    unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;	    unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;	    unsigned long ulData, i;	    ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);	    ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);	    ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);	    ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);	    ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);	    ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);	    ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);	    ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);	    ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);	    ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);	    ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);	    ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);	    ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);	    ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);	    ulData     = INREG(RADEON_GPIO_MONID);	    ulData    &= ~RADEON_GPIO_A_0;	    OUTREG(RADEON_GPIO_MONID, ulData);	    OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);	    OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);	    OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);	    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);	    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);	    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);	    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);	    for (i = 0; i < 200; i++) {		ulData     = INREG(RADEON_GPIO_MONID);		bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;		if (!bConnected) break;   		usleep(1000);	    }	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);	    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);	    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);	    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);	    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);	    OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);	    OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);	    OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);	    OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);        } else {	    unsigned long ulOrigPIXCLKSDATA;	    unsigned long ulOrigTV_MASTER_CNTL;	    unsigned long ulOrigTV_DAC_CNTL;	    unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;	    unsigned long ulOrigDAC_CNTL2;	    unsigned long ulData;	    unsigned long ulMask;        	    ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);	    ulData            = ulOrigPIXCLKSDATA;	    ulData           &= ~(RADEON_PIX2CLK_ALWAYS_ONb				  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);	    ulMask            = ~(RADEON_PIX2CLK_ALWAYS_ONb			  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);	    ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);	    ulData               = ulOrigTV_MASTER_CNTL;	    ulData              &= ~RADEON_TVCLK_ALWAYS_ONb;	    OUTREG(RADEON_TV_MASTER_CNTL, ulData);	    ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);	    ulData          = ulOrigDAC_CNTL2; 	    ulData          &= ~RADEON_DAC2_DAC2_CLK_SEL;	    OUTREG(RADEON_DAC_CNTL2, ulData);        	    ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);	    ulData  = 0x00880213;	    OUTREG(RADEON_TV_DAC_CNTL, ulData);	    ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);	    ulData  =  (RADEON_Y_RED_EN			| RADEON_C_GRN_EN			| RADEON_CMP_BLU_EN			| RADEON_RED_MX_FORCE_DAC_DATA			| RADEON_GRN_MX_FORCE_DAC_DATA			| RADEON_BLU_MX_FORCE_DAC_DATA);            if ((info->ChipFamily == CHIP_FAMILY_R300) ||		(info->ChipFamily == CHIP_FAMILY_R350) ||		(info->ChipFamily == CHIP_FAMILY_RV350))		ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;	    else		ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);	    usleep(1000);	    ulData     = INREG(RADEON_TV_DAC_CNTL);	    bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0; 	    ulData    = ulOrigPIXCLKSDATA;	    ulMask    = 0xFFFFFFFFL;	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);        	    OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);	    OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);	    OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);	}#endif    }      return(bConnected ? MT_CRT : MT_NONE);}static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10){    RADEONInfoPtr info        = RADEONPTR(pScrn);    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    const char *s;    Bool ignore_edid = FALSE, ddc_crt2_used = FALSE;#define RADEON_BIOS8(v)  (info->VBIOS[v])#define RADEON_BIOS16(v) (info->VBIOS[v] | \			  (info->VBIOS[(v) + 1] << 8))#define RADEON_BIOS32(v) (info->VBIOS[v] | \			  (info->VBIOS[(v) + 1] << 8) | \			  (info->VBIOS[(v) + 2] << 16) | \			  (info->VBIOS[(v) + 3] << 24))     pRADEONEnt->MonType1 = MT_NONE;    pRADEONEnt->MonType2 = MT_NONE;    pRADEONEnt->MonInfo1 = NULL;    pRADEONEnt->MonInfo2 = NULL;    pRADEONEnt->ReversedDAC = FALSE;    pRADEONEnt->ReversedTMDS = FALSE;    /* IgnoreEDID option is different from NoDDC options used by DDC module     * When IgnoreEDID is used, monitor detection will still use DDC     * detection, but all EDID data will not be used in mode validation.     */    if (xf86GetOptValBool(info->Options, OPTION_IGNORE_EDID, &ignore_edid)) {	if (ignore_edid)	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 		       "IgnoreEDID is specified, EDID data will be ignored\n");     }    /*      * MonitorLayout option takes a string for two monitors connected in following format:     * Option "MonitorLayout" "primary-port-display, secondary-port-display"     * primary and secondary port displays can have one of following:      *    NONE, CRT, LVDS, TMDS                             * With this option, driver will bring up monitors as specified,      * not using auto-detection routines to probe monitors.     */    /* current monitor mapping scheme:     *  Two displays connected:     *     Primary Port:     *     CRTC1 -> FP/TMDS  -> DVI port -> TMDS panel  --> Primary or     *     CRTC1 -> FP/LVDS  -> Int. LCD -> LVDS panel  --> Primary or     *     CRTC1 -> TV DAC   -> DVI port -> CRT monitor --> Primary     *     *     Secondary Port     *     CRTC2 -> CRT DAC  -> VGA port -> CRT monitor --> Secondary or     *     CRTC2 -> FP2/Ext. -> DVI port -> TMDS panel  --> Secondary     *     *  Only DVI (or Int. LDC) conneced:     *     CRTC1 -> FP/TMDS  -> DVI port -> TMDS panel  --> Primary or     *     CRTC1 -> FP/LVDS  -> Int. LCD -> LVDS panel  --> Primary or     *     CRTC1 -> TV DAC   -> DVI port -> CRT monitor --> Primary     *          *  Only VGA (can be DVI on some dual-DVI boards) connected:     *     CRTC1 -> CRT DAC  -> VGA port -> CRT monitor --> Primary or     *     CRTC1 -> FP2/Ext. -> DVI port -> TMDS panel  --> Primary (not supported)     *     * Note, this is different from Windows scheme where     *   if a digital panel is connected to DVI port, DVI will be the 1st port     *   otherwise, VGA port will be treated as 1st port     *     *   Here we always treat DVI port as primary if both ports are connected.     *   When only one port is connected, it will be treated as      *   primary regardless which port or what type of display is involved.      */    if ((s = xf86GetOptValString(info->Options, OPTION_MONITOR_LAYOUT))) {	char s1[5], s2[5];	int i = 0, second = 0;        	/* When using user specified monitor types, we will not do DDC detection	 *  	 */	do {	    switch(*s)             {            case ',':		s1[i] = '\0';		i = 0;		second = 1;		break;	    case ' ':	    case '\t':	    case '\n':	    case '\r':		break;	    default:		if (second)		    s2[i] = *s;		else		    s1[i] = *s;		i++;		if (i == 4) break;	    }	} while(*s++);	s2[i] = '\0';	if (strcmp(s1, "NONE") == 0)	    pRADEONEnt->MonType1 = MT_NONE;	else if (strcmp(s1, "CRT") == 0)	    pRADEONEnt->MonType1 = MT_CRT;	else if (strcmp(s1, "TMDS") == 0)	    pRADEONEnt->MonType1 = MT_DFP;	else if (strcmp(s1, "LVDS") == 0)	    pRADEONEnt->MonType1 = MT_LCD;	else 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 		       "Invalid Monitor type specified for 1st port \n"); 	if (strcmp(s2, "NONE") == 0)	    pRADEONEnt->MonType2 = MT_NONE;	else if (strcmp(s2, "CRT") == 0)	    pRADEONEnt->MonType2 = MT_CRT;	else if (strcmp(s2, "TMDS") == 0)	    pRADEONEnt->MonType2 = MT_DFP;	else if (strcmp(s2, "LVDS") == 0)	    pRADEONEnt->MonType2 = MT_LCD;	else 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 		       "Invalid Monitor type specified for 2nd port \n"); 	if (!ignore_edid) {	    if (pRADEONEnt->MonType1)  /* assuming the first port using DDC_DVI */	        if(!RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->MonInfo1)) {		    RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo1);		    ddc_crt2_used = TRUE;	        }	    if (pRADEONEnt->MonType2) {  /* assuming the second port using DDC_VGA/DDC_CRT2 */		if(!RADEONDisplayDDCConnected(pScrn, DDC_VGA, &pRADEONEnt->MonInfo2))		    if (!ddc_crt2_used)		        RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo2);	    }	}	if (!pRADEONEnt->MonType1) {	    if (pRADEONEnt->MonType2) {		pRADEONEnt->MonType1 = pRADEONEnt->MonType2;		pRADEONEnt->MonInfo1 = pRADEONEnt->MonInfo2;	    } else {		pRADEONEnt->MonType1 = MT_CRT;		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,                        "No valid monitor specified, force to CRT on 1st port\n"); 	    }	    pRADEONEnt->MonType2 = MT_NONE;	    pRADEONEnt->MonInfo2 = NULL;	}    } else {	/* Auto detection */	int i;	CARD32 tmp;	/* Old single head radeon cards */        if(!info->HasCRTC2) {	    if((pRADEONEnt->MonType1 = RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->MonInfo1)));	    else if((pRADEONEnt->MonType1 = RADEONDisplayDDCConnected(pScrn, DDC_VGA, &pRADEONEnt->MonInfo1)));	    else if((pRADEONEnt->MonType1 = RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo1)));	    else if (pInt10) {		if (xf86LoadSubModule(pScrn, "vbe")) {		    vbeInfoPtr  pVbe;		    pVbe = VBEInit(pInt10, info->pEnt->index);		    if (pVbe) {			for (i = 0; i < 5; i++) {			    pRADEONEnt->MonInfo1 = vbeDoEDID(pVbe, NULL);			}			if (pRADEONEnt->MonInfo1->rawData[0x14] & 0x80)			    pRADEONEnt->MonType1 = MT_DFP;			else pRADEONEnt->MonType1 = MT_CRT;		    }		}	    } else		pRADEONEnt->MonType1 = MT_CRT;	    pRADEONEnt->HasSecondary = FALSE;	    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");		}	    }	    return;	}	/* Normally the port uses DDC_DVI connected with TVDAC,	 * But this is not true for OEM cards which have TVDAC and CRT DAC reversed.	 * If that's the case, we need also reverse the port arrangement.	 * BIOS settings are supposed report this correctly, work fine for all cards tested.	 * But there may be some exceptions, in that case, user can reverse their monitor	 * definition in config file to correct the problem. 	 */ 	if (info->VBIOS && (tmp = RADEON_BIOS16(info->FPBIOSstart + 0x50))) {	    for (i = 1; i < 4; i++) {		unsigned int tmp0;		if (!RADEON_BIOS8(tmp + i*2) && i > 1) break;		tmp0 = RADEON_BIOS16(tmp + i*2);		if ((!(tmp0 & 0x01)) && (((tmp0 >> 8) & 0xf) == DDC_DVI)) {		    pRADEONEnt->ReversedDAC = TRUE;		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reversed DACs detected\n");		}		if ((((tmp0 >> 8) & 0x0f) == DDC_DVI ) && ((tmp0 >> 4) & 0x1)) {		    pRADEONEnt->ReversedTMDS = TRUE;		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reversed TMDS detected\n");		    		}	    }	}	/* Primary Head (DVI or Laptop Int. panel)*/	/* A ddc capable display connected on DVI port */	if((pRADEONEnt->MonType1 = RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->MonInfo1)));

⌨️ 快捷键说明

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