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

📄 radeon_driver.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	    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 (IS_R300_VARIANT)		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(10000);	    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 Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn){    RADEONInfoPtr info = RADEONPTR(pScrn);    RADEONPLLPtr  pll  = &info->pll;    unsigned char *RADEONMMIO = info->MMIO;    unsigned char ppll_div_sel;    unsigned mpll_fb_div, spll_fb_div, M;    unsigned xclk, tmp, ref_div;    int hTotal, vTotal, num, denom, m, n;    float hz, prev_xtal, vclk, xtal, mpll, spll;    long start_secs, start_usecs, stop_secs, stop_usecs, total_usecs;    long to1_secs, to1_usecs, to2_secs, to2_usecs;    unsigned int f1, f2, f3;    int tries = 0;    prev_xtal = 0; again:    xtal = 0;    if (++tries > 10)           goto failed;    xf86getsecs(&to1_secs, &to1_usecs);    f1 = INREG(RADEON_CRTC_CRNT_FRAME);    for (;;) {       f2 = INREG(RADEON_CRTC_CRNT_FRAME);       if (f1 != f2)	    break;       xf86getsecs(&to2_secs, &to2_usecs);       if ((to2_secs - to1_secs) > 1) {           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Clock not counting...\n");           goto failed;       }    }    xf86getsecs(&start_secs, &start_usecs);    for(;;) {       f3 = INREG(RADEON_CRTC_CRNT_FRAME);       if (f3 != f2)	    break;       xf86getsecs(&to2_secs, &to2_usecs);       if ((to2_secs - start_secs) > 1)           goto failed;    }    xf86getsecs(&stop_secs, &stop_usecs);    if ((stop_secs - start_secs) != 0)           goto again;    total_usecs = abs(stop_usecs - start_usecs);    if (total_usecs == 0)           goto again;    hz = 1000000.0/(float)total_usecs;    hTotal = ((INREG(RADEON_CRTC_H_TOTAL_DISP) & 0x3ff) + 1) * 8;    vTotal = ((INREG(RADEON_CRTC_V_TOTAL_DISP) & 0xfff) + 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;     }    ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;    RADEONPllErrataAfterIndex(info);    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       goto again; failed:    if (xtal == 0) {       xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to probe xtal value ! "                  "Using default 27Mhz\n");       xtal = 2700;    } else {       if (prev_xtal == 0) {           prev_xtal = xtal;           tries = 0;           goto again;       } else if (prev_xtal != xtal) {           prev_xtal = 0;           goto again;       }    }    tmp = INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV);    ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x3ff;    /* Some sanity check based on the BIOS code .... */    if (ref_div < 2) {       CARD32 tmp;       tmp = INPLL(pScrn, RADEON_PPLL_REF_DIV);       if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RS300))           ref_div = (tmp & R300_PPLL_REF_DIV_ACC_MASK) >>                   R300_PPLL_REF_DIV_ACC_SHIFT;       else           ref_div = tmp & RADEON_PPLL_REF_DIV_MASK;       if (ref_div < 2)           ref_div = 12;    }    /* Calculate "base" xclk straight from MPLL, though that isn't     * really useful (hopefully). This isn't called XCLK anymore on     * radeon's...     */    mpll_fb_div = (tmp & 0xff00) >> 8;    spll_fb_div = (tmp & 0xff0000) >> 16;    M = (tmp & 0xff);    xclk = RADEONDiv((2 * mpll_fb_div * xtal), (M));    /*     * Calculate MCLK based on MCLK-A     */    mpll = (2.0 * (float)mpll_fb_div * (xtal / 100.0)) / (float)M;    spll = (2.0 * (float)spll_fb_div * (xtal / 100.0)) / (float)M;    tmp = INPLL(pScrn, RADEON_MCLK_CNTL) & 0x7;    switch(tmp) {    case 1: info->mclk = mpll; break;    case 2: info->mclk = mpll / 2.0; break;    case 3: info->mclk = mpll / 4.0; break;    case 4: info->mclk = mpll / 8.0; break;    case 7: info->mclk = spll; break;    default:           info->mclk = 200.00;           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unsupported MCLKA source"                      " setting %d, can't probe MCLK value !\n", tmp);    }    /*     * Calculate SCLK     */    tmp = INPLL(pScrn, RADEON_SCLK_CNTL) & 0x7;    switch(tmp) {    case 1: info->sclk = spll; break;    case 2: info->sclk = spll / 2.0; break;    case 3: info->sclk = spll / 4.0; break;    case 4: info->sclk = spll / 8.0; break;    case 7: info->sclk = mpll;    default:           info->sclk = 200.00;           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unsupported SCLK source"                      " setting %d, can't probe SCLK value !\n", tmp);    }    /* we're done, hopefully these are sane values */    pll->reference_div = ref_div;    pll->xclk = xclk;    pll->reference_freq = xtal;    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Probed PLL values: xtal: %f Mhz, "              "sclk: %f Mhz, mclk: %f Mhz\n", xtal/100.0, info->sclk, info->mclk);    return TRUE;}static void RADEONGetPanelInfoFromReg (ScrnInfoPtr pScrn){    RADEONInfoPtr info     = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    CARD32 fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);    CARD32 fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);    info->PanelPwrDly = 200;    if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {	info->PanelYRes = (fp_vert_stretch>>12) + 1;    } else {	info->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;    }    if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {	info->PanelXRes = ((fp_horz_stretch>>16) + 1) * 8;    } else {	info->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;    }        if ((info->PanelXRes < 640) || (info->PanelYRes < 480)) {	info->PanelXRes = 640;	info->PanelYRes = 480;    }    if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {           CARD32 ppll_div_sel, ppll_val;           ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;	   RADEONPllErrataAfterIndex(info);	   ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);           if ((ppll_val & 0x000707ff) == 0x1bb)		   goto noprobe;	   info->FeedbackDivider = ppll_val & 0x7ff;	   info->PostDivider = (ppll_val >> 16) & 0x7;	   info->RefDivider = info->pll.reference_div;	   info->UseBiosDividers = TRUE;           xf86DrvMsg(pScrn->scrnIndex, X_INFO,                      "Existing panel PLL dividers will be used.\n");    } noprobe:    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 	       "Panel size %dx%d is derived, this may not be correct.\n"		   "If not, use PanelSize option to overwrite this setting\n",	       info->PanelXRes, info->PanelYRes);}static Bool RADEONGetLVDSInfo (ScrnInfoPtr pScrn){    RADEONInfoPtr info     = RADEONPTR(pScrn);    if (!RADEONGetLVDSInfoFromBIOS(pScrn))        RADEONGetPanelInfoFromReg(pScrn);    /* The panel size we collected from BIOS may not be the     * maximum size supported by the panel.  If not, we update     * it now.  These will be used if no matching mode can be     * found from EDID data.     */    RADEONUpdatePanelSize(pScrn);    /* 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.     */    if (info->DotClock == 0) {        RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);        DisplayModePtr  tmp_mode = NULL;        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,                   "No valid timing info from BIOS.\n");        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->PortInfo[0].MonInfo) {            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,                       "Panel size is not correctly detected.\n"                       "Please try to use PanelSize option for correct settings.\n");            return FALSE;        }    }    return TRUE;}static void RADEONGetTMDSInfo(ScrnInfoPtr pScrn){    RADEONInfoPtr  info = RADEONPTR(pScrn);    int i;    for (i=0; i<4; i++) {        info->tmds_pll[i].value = 0;        info->tmds_pll[i].freq = 0;    }    if (RADEONGetTMDSInfoFromBIOS(pScrn)) return;    for (i=0; i<4; i++) {        info->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;        info->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;    }}static void RADEONGetPanelInfo (ScrnInfoPtr pScrn){    RADEONInfoPtr info     = RADEONPTR(pScrn);    char* s;    if((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {        info->PanelPwrDly = 200;        if (sscanf (s, "%dx%d", &info->PanelXRes, &info->PanelYRes) != 2) {            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);            RADEONGetPanelInfoFromReg(pScrn);        }    } else {        if(info->DisplayType == MT_LCD) {            RADEONGetLVDSInfo(pScrn);        } else if ((info->DisplayType == MT_DFP) || (info->MergeType == MT_DFP)) {            RADEONGetTMDSInfo(pScrn);            if (!pScrn->monitor->DDC)

⌨️ 快捷键说明

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