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

📄 radeon_driver.c

📁 ati driver
💻 C
📖 第 1 页 / 共 5 页
字号:
    SaveStruct.MEM_CNTL = INREG(RADEON_MEM_CNTL);    SaveStruct.MEMSIZE = INREG(RADEON_CONFIG_MEMSIZE);    SaveStruct.MPP_TB_CONFIG = INREG(RADEON_MPP_TB_CONFIG);    /*      * Zap MEM_CNTL and set MPP_TB_CONFIG<31:24> to 4     */    OUTREG(RADEON_MEM_CNTL, 0);    CardTmp = SaveStruct.MPP_TB_CONFIG & 0x00ffffffu;    CardTmp |= 0x04 << 24;    OUTREG(RADEON_MPP_TB_CONFIG, CardTmp);    *pPtr = (void *)&SaveStruct;}static voidRADEONPostInt10Check(ScrnInfoPtr pScrn, void *ptr){    RADEONInfoPtr  info   = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    struct RADEONInt10Save *pSave = ptr;    CARD32 CardTmp;    /* If we don't have a valid (non-zero) saved MEM_CNTL, get out now */    if (!pSave || !pSave->MEM_CNTL)	return;    /*     * If either MEM_CNTL is currently zero or inconistent (configured for     * two channels with the two channels configured differently), restore     * the saved registers.     */    CardTmp = INREG(RADEON_MEM_CNTL);    if (!CardTmp || 	((CardTmp & 1) && 	 (((CardTmp >> 8) & 0xff) != ((CardTmp >> 24) & 0xff)))) {	/* Restore the saved registers */	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		   "Restoring MEM_CNTL (%08lx), setting to %08lx\n",		   (unsigned long)CardTmp, (unsigned long)pSave->MEM_CNTL);	OUTREG(RADEON_MEM_CNTL, pSave->MEM_CNTL);	CardTmp = INREG(RADEON_CONFIG_MEMSIZE);	if (CardTmp != pSave->MEMSIZE) {	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		       "Restoring CONFIG_MEMSIZE (%08lx), setting to %08lx\n",		       (unsigned long)CardTmp, (unsigned long)pSave->MEMSIZE);	    OUTREG(RADEON_CONFIG_MEMSIZE, pSave->MEMSIZE);	}    }    CardTmp = INREG(RADEON_MPP_TB_CONFIG);    if ((CardTmp & 0xff000000u) != (pSave->MPP_TB_CONFIG & 0xff000000u)) {	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	           "Restoring MPP_TB_CONFIG<31:24> (%02lx), setting to %02lx\n",	 	   (unsigned long)CardTmp >> 24,		   (unsigned long)pSave->MPP_TB_CONFIG >> 24);	CardTmp &= 0x00ffffffu;	CardTmp |= (pSave->MPP_TB_CONFIG & 0xff000000u);	OUTREG(RADEON_MPP_TB_CONFIG, CardTmp);    }}/* Allocate our private RADEONInfoRec */static Bool RADEONGetRec(ScrnInfoPtr pScrn){    if (pScrn->driverPrivate) return TRUE;    pScrn->driverPrivate = xnfcalloc(sizeof(RADEONInfoRec), 1);    return TRUE;}/* Free our private RADEONInfoRec */static void RADEONFreeRec(ScrnInfoPtr pScrn){    if (!pScrn || !pScrn->driverPrivate) return;    xfree(pScrn->driverPrivate);    pScrn->driverPrivate = NULL;}/* Memory map the MMIO region.  Used during pre-init and by RADEONMapMem, * below */static Bool RADEONMapMMIO(ScrnInfoPtr pScrn){    RADEONInfoPtr  info = RADEONPTR(pScrn);    if (info->FBDev) {	info->MMIO = fbdevHWMapMMIO(pScrn);    } else {	info->MMIO = xf86MapPciMem(pScrn->scrnIndex,				   VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,				   info->PciTag,				   info->MMIOAddr,				   RADEON_MMIOSIZE);    }    if (!info->MMIO) return FALSE;    return TRUE;}/* Unmap the MMIO region.  Used during pre-init and by RADEONUnmapMem, * below */static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn){    RADEONInfoPtr  info = RADEONPTR(pScrn);    if (info->FBDev)	fbdevHWUnmapMMIO(pScrn);    else {	xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, RADEON_MMIOSIZE);    }    info->MMIO = NULL;    return TRUE;}/* Memory map the frame buffer.  Used by RADEONMapMem, below. */static Bool RADEONMapFB(ScrnInfoPtr pScrn){    RADEONInfoPtr  info = RADEONPTR(pScrn);    if (info->FBDev) {	info->FB = fbdevHWMapVidmem(pScrn);    } else {	info->FB = xf86MapPciMem(pScrn->scrnIndex,				 VIDMEM_FRAMEBUFFER,				 info->PciTag,				 info->LinearAddr,				 info->FbMapSize);    }    if (!info->FB) return FALSE;    return TRUE;}/* Unmap the frame buffer.  Used by RADEONUnmapMem, below. */static Bool RADEONUnmapFB(ScrnInfoPtr pScrn){    RADEONInfoPtr  info = RADEONPTR(pScrn);    if (info->FBDev)	fbdevHWUnmapVidmem(pScrn);    else	xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);    info->FB = NULL;    return TRUE;}/* Memory map the MMIO region and the frame buffer */static Bool RADEONMapMem(ScrnInfoPtr pScrn){    if (!RADEONMapMMIO(pScrn)) return FALSE;    if (!RADEONMapFB(pScrn)) {	RADEONUnmapMMIO(pScrn);	return FALSE;    }    return TRUE;}/* Unmap the MMIO region and the frame buffer */static Bool RADEONUnmapMem(ScrnInfoPtr pScrn){    if (!RADEONUnmapMMIO(pScrn) || !RADEONUnmapFB(pScrn)) return FALSE;    return TRUE;}/* This function is required to workaround a hardware bug in some (all?) * revisions of the R300.  This workaround should be called after every * CLOCK_CNTL_INDEX register access.  If not, register reads afterward * may not be correct. */void R300CGWorkaround(ScrnInfoPtr pScrn) {    RADEONInfoPtr  info       = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    CARD32         save, tmp;    save = INREG(RADEON_CLOCK_CNTL_INDEX);    tmp = save & ~(0x3f | RADEON_PLL_WR_EN);    OUTREG(RADEON_CLOCK_CNTL_INDEX, tmp);    tmp = INREG(RADEON_CLOCK_CNTL_DATA);    OUTREG(RADEON_CLOCK_CNTL_INDEX, save);}/* Read PLL information */unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr){    RADEONInfoPtr  info       = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    CARD32         data;    OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f);    data = INREG(RADEON_CLOCK_CNTL_DATA);    if (info->R300CGWorkaround) R300CGWorkaround(pScrn);    return data;}#if 0/* Read PAL information (only used for debugging) */static int RADEONINPAL(int idx){    RADEONInfoPtr  info       = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    OUTREG(RADEON_PALETTE_INDEX, idx << 16);    return INREG(RADEON_PALETTE_DATA);}#endif/* Wait for vertical sync on primary CRTC */void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn){    RADEONInfoPtr  info       = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    int            i;    /* Clear the CRTC_VBLANK_SAVE bit */    OUTREG(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR);    /* Wait for it to go back up */    for (i = 0; i < RADEON_TIMEOUT/1000; i++) {	if (INREG(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_SAVE) break;	usleep(1);    }}/* Wait for vertical sync on secondary CRTC */void RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn){    RADEONInfoPtr  info       = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    int            i;    /* Clear the CRTC2_VBLANK_SAVE bit */    OUTREG(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR);    /* Wait for it to go back up */    for (i = 0; i < RADEON_TIMEOUT/1000; i++) {	if (INREG(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_SAVE) break;	usleep(1);    }}/* Blank screen */static void RADEONBlank(ScrnInfoPtr pScrn){    RADEONInfoPtr  info       = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    if (!info->IsSecondary) {	switch(info->DisplayType) {	case MT_LCD:	case MT_CRT:	case MT_DFP:	    OUTREGP(RADEON_CRTC_EXT_CNTL,		    RADEON_CRTC_DISPLAY_DIS,		    ~(RADEON_CRTC_DISPLAY_DIS));	    break;	case MT_NONE:	default:	    break;	}	if (info->Clone)	    OUTREGP(RADEON_CRTC2_GEN_CNTL,		    RADEON_CRTC2_DISP_DIS,		    ~(RADEON_CRTC2_DISP_DIS));    } else {	OUTREGP(RADEON_CRTC2_GEN_CNTL,		RADEON_CRTC2_DISP_DIS,		~(RADEON_CRTC2_DISP_DIS));    }}/* Unblank screen */static void RADEONUnblank(ScrnInfoPtr pScrn){    RADEONInfoPtr  info       = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    if (!info->IsSecondary) {	switch (info->DisplayType) {	case MT_LCD:	case MT_CRT:	case MT_DFP:	    OUTREGP(RADEON_CRTC_EXT_CNTL,		    RADEON_CRTC_CRT_ON,		    ~(RADEON_CRTC_DISPLAY_DIS));	    break;	case MT_NONE:	default:	    break;	}	if (info->Clone)	    OUTREGP(RADEON_CRTC2_GEN_CNTL,		    0,		    ~(RADEON_CRTC2_DISP_DIS));    } else {	switch (info->DisplayType) {	case MT_LCD:	case MT_DFP:	case MT_CRT:	    OUTREGP(RADEON_CRTC2_GEN_CNTL,		    0,		    ~(RADEON_CRTC2_DISP_DIS));	    break;	case MT_NONE:	default:	    break;	}    }}/* Compute log base 2 of val */int RADEONMinBits(int val){    int  bits;    if (!val) return 1;    for (bits = 0; val; val >>= 1, ++bits);    return bits;}/* Compute n/d with rounding */static int RADEONDiv(int n, int d){    return (n + (d / 2)) / d;}static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, xf86MonPtr* MonInfo){    RADEONInfoPtr info = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    unsigned long DDCReg;    RADEONMonitorType MonType = MT_NONE;    int i, j;    DDCReg = info->DDCReg;    switch(DDCType)    {    case DDC_MONID:	info->DDCReg = RADEON_GPIO_MONID;	break;    case DDC_DVI:	info->DDCReg = RADEON_GPIO_DVI_DDC;	break;    case DDC_VGA:	info->DDCReg = RADEON_GPIO_VGA_DDC;	break;    case DDC_CRT2:	info->DDCReg = RADEON_GPIO_CRT2_DDC;	break;    default:	info->DDCReg = DDCReg;	return MT_NONE;    }    /* Read and output monitor info using DDC2 over I2C bus */    if (info->pI2CBus && info->ddc2) {	OUTREG(info->DDCReg, INREG(info->DDCReg) &	       (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));	/* For some old monitors (like Compaq Presario FP500), we need	 * following process to initialize/stop DDC	 */	OUTREG(info->DDCReg, INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1));	for (j = 0; j < 3; j++) {	    OUTREG(info->DDCReg,		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0));	    usleep(13000);	    OUTREG(info->DDCReg,		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1));	    for (i = 0; i < 3; i++) {		usleep(15000);		if (INREG(info->DDCReg) & RADEON_GPIO_Y_1)		    break;	    }	    if (i == 10) continue;	    usleep(15000);	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);	    usleep(15000);	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);	    usleep(15000);	    OUTREG(info->DDCReg,		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0));	    usleep(15000);	    *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus);	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);	    usleep(15000);	    OUTREG(info->DDCReg,		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1));	    for (i = 0; i < 5; i++) {		usleep(15000);		if (INREG(info->DDCReg) & RADEON_GPIO_Y_1)		    break;	    }	    usleep(15000);	    OUTREG(info->DDCReg,		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0));	    usleep(15000);	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);	    usleep(15000);	    if(*MonInfo) break;	}    } else {	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");	MonType = MT_NONE;    }    if (*MonInfo) {	if ((*MonInfo)->rawData[0x14] & 0x80) {	    if (INREG(RADEON_LVDS_GEN_CNTL) & RADEON_LVDS_ON) MonType = MT_LCD;	    else MonType = MT_DFP;	} else MonType = MT_CRT;    } else MonType = MT_NONE;    info->DDCReg = DDCReg;    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 	       "DDC Type: %d, Detected Type: %d\n", DDCType, MonType);    return MonType;}

⌨️ 快捷键说明

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