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

📄 r128_driver.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (info->FBDev)	fbdevHWUnmapMMIO(pScrn);    else {	xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, R128_MMIOSIZE);    }    info->MMIO = NULL;    return TRUE;}/* Memory map the frame buffer.  Used by R128MapMem, below. */static Bool R128MapFB(ScrnInfoPtr pScrn){    R128InfoPtr info          = R128PTR(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 R128UnmapMem, below. */static Bool R128UnmapFB(ScrnInfoPtr pScrn){    R128InfoPtr info          = R128PTR(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 R128MapMem(ScrnInfoPtr pScrn){    if (!R128MapMMIO(pScrn)) return FALSE;    if (!R128MapFB(pScrn)) {	R128UnmapMMIO(pScrn);	return FALSE;    }    return TRUE;}/* Unmap the MMIO region and the frame buffer. */static Bool R128UnmapMem(ScrnInfoPtr pScrn){    if (!R128UnmapMMIO(pScrn) || !R128UnmapFB(pScrn)) return FALSE;    return TRUE;}/* Read PLL information */unsigned R128INPLL(ScrnInfoPtr pScrn, int addr){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x3f);    return INREG(R128_CLOCK_CNTL_DATA);}#if 0/* Read PAL information (only used for debugging). */static int R128INPAL(int idx){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    OUTREG(R128_PALETTE_INDEX, idx << 16);    return INREG(R128_PALETTE_DATA);}#endif/* Wait for vertical sync. */void R128WaitForVerticalSync(ScrnInfoPtr pScrn){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    int           i;    OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK);    for (i = 0; i < R128_TIMEOUT; i++) {	if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break;    }}/* Blank screen. */static void R128Blank(ScrnInfoPtr pScrn){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    if(!info->IsSecondary)    {        switch(info->DisplayType)        {        case MT_LCD:            OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_DISPLAY_DIS,                 ~R128_LVDS_DISPLAY_DIS);	    break;        case MT_CRT:            OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS);	    break;        case MT_DFP:            OUTREGP(R128_FP_GEN_CNTL, R128_FP_BLANK_DIS, ~R128_FP_BLANK_DIS);	    break;        case MT_NONE:        default:           break;        }    }    else    {        OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~R128_CRTC2_DISP_DIS);    }}/* Unblank screen. */static void R128Unblank(ScrnInfoPtr pScrn){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    if(!info->IsSecondary)    {        switch(info->DisplayType)        {        case MT_LCD:            OUTREGP(R128_LVDS_GEN_CNTL, 0,                 ~R128_LVDS_DISPLAY_DIS);	    break;        case MT_CRT:            OUTREGP(R128_CRTC_EXT_CNTL, 0, ~R128_CRTC_DISPLAY_DIS);	    break;        case MT_DFP:            OUTREGP(R128_FP_GEN_CNTL, 0, ~R128_FP_BLANK_DIS);	    break;        case MT_NONE:        default:            break;        }    }    else    {        switch(info->DisplayType)        {        case MT_LCD:        case MT_DFP:        case MT_CRT:            OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~R128_CRTC2_DISP_DIS);            break;        case MT_NONE:        default:            break;        }    }}/* Compute log base 2 of val. */int R128MinBits(int val){    int bits;    if (!val) return 1;    for (bits = 0; val; val >>= 1, ++bits);    return bits;}/* Compute n/d with rounding. */static int R128Div(int n, int d){    return (n + (d / 2)) / d;}/* Read the Video BIOS block and the FP registers (if applicable). */static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10){    R128InfoPtr info = R128PTR(pScrn);    int         i;    int         FPHeader = 0;#define R128_BIOS8(v)  (info->VBIOS[v])#define R128_BIOS16(v) (info->VBIOS[v] | \			(info->VBIOS[(v) + 1] << 8))#define R128_BIOS32(v) (info->VBIOS[v] | \			(info->VBIOS[(v) + 1] << 8) | \			(info->VBIOS[(v) + 2] << 16) | \			(info->VBIOS[(v) + 3] << 24))    if (!(info->VBIOS = xalloc(R128_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),		     R128_VBIOS_SIZE);    } else {	xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, R128_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, R128_VBIOS_SIZE, info->VBIOS);	}    }    if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {	info->BIOSAddr = 0x00000000;	xfree(info->VBIOS);	info->VBIOS = NULL;	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		   "Video BIOS not found!\n");    }        if(info->HasCRTC2)        {                                 if(info->IsSecondary)             {  		/* there may be a way to detect this, for now, just assume 		   second head is CRT */                 info->DisplayType = MT_CRT;                 if(info->DisplayType > MT_NONE)                 {                     DevUnion* pPriv;                     R128EntPtr pR128Ent;                     pPriv = xf86GetEntityPrivate(pScrn->entityList[0],                          getR128EntityIndex());                     pR128Ent = pPriv->ptr;                     pR128Ent->HasSecondary = TRUE;                 }                 else return FALSE;                                  }             else             {                 /* really need some sort of detection here */		 if (info->HasPanelRegs) {		 	info->DisplayType = MT_LCD;		 } else if (info->isDFP) {			info->DisplayType = MT_DFP;                 } else                  {                     /*DVI port has no monitor connected, try CRT port.                     If something on CRT port, treat it as primary*/                     if(xf86IsEntityShared(pScrn->entityList[0]))                     {                         DevUnion* pPriv;                         R128EntPtr pR128Ent;                         pPriv = xf86GetEntityPrivate(pScrn->entityList[0],                              getR128EntityIndex());                         pR128Ent = pPriv->ptr;                         pR128Ent->BypassSecondary = TRUE;                     }                     info->DisplayType = MT_CRT;#if 0                     {                         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,                             "No monitor detected!!!\n");                         return FALSE;                     }#endif                 }             }         }         else         {             /*Regular Radeon ASIC, only one CRTC, but it could be               used for DFP with a DVI output, like AIW board*/             if(info->isDFP) info->DisplayType = MT_DFP;             else info->DisplayType = MT_CRT;         }    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Display == Type %d\n",              (info->IsSecondary ? "Secondary" : "Primary"),                info->DisplayType);    if (info->VBIOS && info->DisplayType == MT_LCD) {	info->FPBIOSstart = 0;	/* FIXME: There should be direct access to the start of the FP info	   tables, but until we find out where that offset is stored, we	   must search for the ATI signature string: "M3      ". */	for (i = 4; i < R128_VBIOS_SIZE-8; i++) {	    if (R128_BIOS8(i)   == 'M' &&		R128_BIOS8(i+1) == '3' &&		R128_BIOS8(i+2) == ' ' &&		R128_BIOS8(i+3) == ' ' &&		R128_BIOS8(i+4) == ' ' &&		R128_BIOS8(i+5) == ' ' &&		R128_BIOS8(i+6) == ' ' &&		R128_BIOS8(i+7) == ' ') {		FPHeader = i-2;		break;	    }	}	if (!FPHeader) return TRUE;	/* Assume that only one panel is attached and supported */	for (i = FPHeader+20; i < FPHeader+84; i += 2) {	    if (R128_BIOS16(i) != 0) {		info->FPBIOSstart = R128_BIOS16(i);		break;	    }	}	if (!info->FPBIOSstart) return TRUE;	if (!info->PanelXRes)	    info->PanelXRes = R128_BIOS16(info->FPBIOSstart+25);	if (!info->PanelYRes)	    info->PanelYRes = R128_BIOS16(info->FPBIOSstart+27);	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n",		   info->PanelXRes, info->PanelYRes);	info->PanelPwrDly = R128_BIOS8(info->FPBIOSstart+56);	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: ");	for (i = 1; i <= 24; i++)	    ErrorF("%c", R128_BIOS8(info->FPBIOSstart+i));	ErrorF("\n");	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: ");	i = R128_BIOS16(info->FPBIOSstart+29);	if (i & 1) ErrorF("Color, ");	else       ErrorF("Monochrome, ");	if (i & 2) ErrorF("Dual(split), ");	else       ErrorF("Single, ");	switch ((i >> 2) & 0x3f) {	case 0:  ErrorF("STN");        break;	case 1:  ErrorF("TFT");        break;	case 2:  ErrorF("Active STN"); break;	case 3:  ErrorF("EL");         break;	case 4:  ErrorF("Plasma");     break;	default: ErrorF("UNKNOWN");    break;	}	ErrorF("\n");	if (R128_BIOS8(info->FPBIOSstart+61) & 1) {	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n");	} else {	    /* FIXME: Add Non-LVDS flat pael support */	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		       "Non-LVDS panel interface detected!  "		       "This support is untested and may not "		       "function properly\n");	}    }    if (!info->PanelXRes || !info->PanelYRes) {        info->HasPanelRegs = FALSE;        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		   "Can't determine panel dimensions, and none specified.\n"		   "\tDisabling programming of FP registers.\n");    }    return TRUE;}/* Read PLL parameters from BIOS block.  Default to typical values if there   is no BIOS. */static Bool R128GetPLLParameters(ScrnInfoPtr pScrn){    R128InfoPtr   info = R128PTR(pScrn);    R128PLLPtr    pll  = &info->pll;#if defined(__powerpc__) || defined(__alpha__)    /* there is no bios under Linux PowerPC but Open Firmware       does set up the PLL registers properly and we can use       those to calculate xclk and find the reference divider */    unsigned x_mpll_ref_fb_div;    unsigned xclk_cntl;    unsigned Nx, M;    unsigned PostDivSet[] = {0, 1, 2, 4, 8, 3, 6, 12};    /* Assume REF clock is 2950 (in units of 10khz) */    /* and that all pllclk must be between 125 Mhz and 250Mhz */    pll->reference_freq = 2950;    pll->min_pll_freq   = 12500;    pll->max_pll_freq   = 25000;    /* need to memory map the io to use INPLL since it       has not been done yet at this point in the startup */    R128MapMMIO(pScrn);    x_mpll_ref_fb_div = INPLL(pScrn, R128_X_MPLL_REF_FB_DIV);    xclk_cntl = INPLL(pScrn, R128_XCLK_CNTL) & 0x7;    pll->reference_div =	INPLL(pScrn,R128_PPLL_REF_DIV) & R128_PPLL_REF_DIV_MASK;    /* unmap it again */    R128UnmapMMIO(pScrn);    Nx = (x_mpll_ref_fb_div & 0x00FF00) >> 8;    M =  (x_mpll_ref_fb_div & 0x0000FF);    pll->xclk =  R128Div((2 * Nx * pll->reference_freq),			 (M * PostDivSet[xclk_cntl]));#else /* !defined(__powerpc__) */    if (!info->VBIOS) {	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		   "Video BIOS not detected, using default PLL parameters!\n");				/* These probably aren't going to work for				   the card you are using.  Specifically,				   reference freq can be 29.50MHz,				   28.63MHz, or 14.32MHz.  YMMV. */	pll->reference_freq = 2950;	pll->reference_div  = 65;	pll->min_pll_freq   = 12500;	pll->max_pll_freq   = 25000;	pll->xclk           = 10300;    } else {	CARD16 bios_header    = R128_BIOS16(0x48);	CARD16 pll_info_block = R128_BIOS16(bios_header + 0x30);	R128TRACE(("Header at 0x%04x; PLL Information at 0x%04x\n",		   bios_header, pll_info_block));	pll->reference_freq = R128_BIOS16(pll_info_block + 0x0e);	pll->reference_div  = R128_BIOS16(pll_info_block + 0x10);	pll->min_pll_freq   = R128_BIOS32(pll_info_block + 0x12);	pll->max_pll_freq   = R128_BIOS32(pll_info_block + 0x16);	pll->xclk           = R128_BIOS16(pll_info_block + 0x08);    }#endif /* __powerpc__ */    xf86DrvMsg(pScrn->scrnIndex, X_INFO,	       "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n",	       pll->reference_freq,	       pll->reference_div,

⌨️ 快捷键说明

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