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

📄 aticlock.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
        }        /* Adjust divided clocks */        for (ClockIndex = NumberOfUndividedClocks;             ClockIndex < NumberOfClocks;             ClockIndex++)            pScreenInfo->clock[ClockIndex] = ATIDivide(                pScreenInfo->clock[ClockIndex % NumberOfUndividedClocks],                (ClockIndex / NumberOfUndividedClocks) + 1, 0, 0);    }    /* Tell user about fixed clocks */    xf86ShowClocks(pScreenInfo, pATI->OptionProbeClocks ? X_PROBED : X_CONFIG);    /* Prevent selection of high clocks, even by V_CLKDIV2 modes */    for (ClockIndex = 0;  ClockIndex < NumberOfClocks;  ClockIndex++)        if (pScreenInfo->clock[ClockIndex] > pRange->maxClock)            pScreenInfo->clock[ClockIndex] = 0;}/* * ATIClockSave -- * * This function saves that part of an ATIHWRec that relates to clocks. */voidATIClockSave(    ScrnInfoPtr pScreenInfo,    ATIPtr      pATI,    ATIHWPtr    pATIHW){    if (pScreenInfo->vtSema && (pATI->ProgrammableClock > ATI_CLOCK_FIXED))    {#ifndef AVOID_CPIO        if (pATIHW->crtc == ATI_CRTC_VGA)        {            pATIHW->ClockMap = ATIVGAProgrammableClockMap;            pATIHW->ClockUnmap = ATIVGAProgrammableClockUnmap;        }        else#endif /* AVOID_CPIO */        {            pATIHW->ClockMap = ATIProgrammableClockMap;            pATIHW->ClockUnmap = ATIProgrammableClockUnmap;        }    }    else    {#ifndef AVOID_CPIO        if (pATIHW->crtc != ATI_CRTC_VGA)#endif /* AVOID_CPIO */        {            pATIHW->ClockMap = ATIAcceleratorClockMap;            pATIHW->ClockUnmap = ATIAcceleratorClockUnmap;        }#ifndef AVOID_CPIO        else if (pATI->Chip < ATI_CHIP_68800)        {            pATIHW->ClockMap = ATIVGAWonderClockMap;            pATIHW->ClockUnmap = ATIVGAWonderClockUnmap;        }        else        {            pATIHW->ClockMap = ATIMachVGAClockMap;            pATIHW->ClockUnmap = ATIMachVGAClockUnmap;        }#endif /* AVOID_CPIO */    }}/* * ATIClockCalculate -- * * This function is called to generate, if necessary, the data needed for clock * programming, and set clock select bits in various register values. */BoolATIClockCalculate(    int            iScreen,    ATIPtr         pATI,    ATIHWPtr       pATIHW,    DisplayModePtr pMode){    int N, M, D;    int ClockSelect, N1, MinimumGap;    int Frequency, Multiple;            /* Used as temporaries */    /* Set default values */    pATIHW->FeedbackDivider = pATIHW->ReferenceDivider = pATIHW->PostDivider = 0;    if ((pATI->ProgrammableClock <= ATI_CLOCK_FIXED) ||        ((pATI->ProgrammableClock == ATI_CLOCK_CH8398) &&         (pMode->ClockIndex < 2)))    {        /* Use a fixed clock */        ClockSelect = pMode->ClockIndex;    }    else    {        /* Generate clock programme word, using units of kHz */        MinimumGap = ((unsigned int)(-1)) >> 1;        /* Loop through reference dividers */        for (M = pATI->ClockDescriptor.MinM;             M <= pATI->ClockDescriptor.MaxM;             M++)        {            /* Loop through post-dividers */            for (D = 0;  D < pATI->ClockDescriptor.NumD;  D++)            {                if (!pATI->ClockDescriptor.PostDividers[D])                    continue;                /* Limit undivided VCO to maxClock */                if (pATI->maxClock &&                    ((pATI->maxClock / pATI->ClockDescriptor.PostDividers[D]) <                     pMode->Clock))                    continue;                /*                 * Calculate closest feedback divider and apply its                 * restrictions.                 */                Multiple = M * pATI->ReferenceDenominator *                    pATI->ClockDescriptor.PostDividers[D];                N = ATIDivide(pMode->Clock * Multiple,                    pATI->ReferenceNumerator, 0, 0);                if (N < pATI->ClockDescriptor.MinN)                    N = pATI->ClockDescriptor.MinN;                else if (N > pATI->ClockDescriptor.MaxN)                    N = pATI->ClockDescriptor.MaxN;                N -= pATI->ClockDescriptor.NAdjust;                N1 = (N / pATI->ClockDescriptor.N1) * pATI->ClockDescriptor.N2;                if (N > N1)                    N = ATIDivide(N1 + 1, pATI->ClockDescriptor.N1, 0, 1);                N += pATI->ClockDescriptor.NAdjust;                N1 += pATI->ClockDescriptor.NAdjust;                for (;  ;  N = N1)                {                    /* Pick the closest setting */                    Frequency = abs(ATIDivide(N * pATI->ReferenceNumerator,                        Multiple, 0, 0) - pMode->Clock);                    if ((Frequency < MinimumGap) ||                        ((Frequency == MinimumGap) &&                         (pATIHW->FeedbackDivider < N)))                    {                        /* Save settings */                        pATIHW->FeedbackDivider = N;                        pATIHW->ReferenceDivider = M;                        pATIHW->PostDivider = D;                        MinimumGap = Frequency;                    }                    if (N <= N1)                        break;                }            }        }        Multiple = pATIHW->ReferenceDivider * pATI->ReferenceDenominator *            pATI->ClockDescriptor.PostDividers[pATIHW->PostDivider];        Frequency = pATIHW->FeedbackDivider * pATI->ReferenceNumerator;        Frequency = ATIDivide(Frequency, Multiple, 0, 0);        if (abs(Frequency - pMode->Clock) > CLOCK_TOLERANCE)        {            xf86DrvMsg(iScreen, X_ERROR,                "Unable to programme clock %.3fMHz for mode %s.\n",                (double)(pMode->Clock) / 1000.0, pMode->name);            return FALSE;        }        pMode->SynthClock = Frequency;        ClockSelect = pATI->ClockNumberToProgramme;        xf86ErrorFVerb(4,            "\n Programming clock %d to %.3fMHz for mode %s."            "  N=%d, M=%d, D=%d.\n",            ClockSelect, (double)Frequency / 1000.0, pMode->name,            pATIHW->FeedbackDivider, pATIHW->ReferenceDivider,            pATIHW->PostDivider);        if (pATI->Chip >= ATI_CHIP_264VTB)            ATIDSPCalculate(pATI, pATIHW, pMode);    }    /* Set clock select bits, after remapping them */    pATIHW->clock = ClockSelect;        /* Save pre-map clock number */    ClockSelect = MapClockIndex(pATIHW->ClockMap, ClockSelect);    switch (pATIHW->crtc)    {#ifndef AVOID_CPIO        case ATI_CRTC_VGA:            pATIHW->genmo = (pATIHW->genmo & 0xF3U) |                ((ClockSelect << 2) & 0x0CU);            if (pATI->CPIO_VGAWonder)            {                /* Set ATI clock select bits */                if (pATI->Chip <= ATI_CHIP_18800)                {                    pATIHW->b2 = (pATIHW->b2 & 0xBFU) |                        ((ClockSelect << 4) & 0x40U);                }                else                {                    pATIHW->be = (pATIHW->be & 0xEFU) |                        ((ClockSelect << 2) & 0x10U);                    if (pATI->Adapter != ATI_ADAPTER_V4)                    {                        ClockSelect >>= 1;                        pATIHW->b9 = (pATIHW->b9 & 0xFDU) |                            ((ClockSelect >> 1) & 0x02U);                    }                }                /* Set clock divider bits */                pATIHW->b8 = (pATIHW->b8 & 0x3FU) |                    ((ClockSelect << 3) & 0xC0U);            }            break;#endif /* AVOID_CPIO */        case ATI_CRTC_MACH64:            pATIHW->clock_cntl = CLOCK_STROBE |                SetBits(ClockSelect, CLOCK_SELECT | CLOCK_DIVIDER);            break;        default:            break;    }    return TRUE;}/* * ATIClockSet -- * * This function is called to programme a clock for the mode being set. */voidATIClockSet(    ATIPtr      pATI,    ATIHWPtr    pATIHW){    CARD32 crtc_gen_cntl, tmp;    CARD8 clock_cntl0;    CARD8 tmp2;    unsigned int Programme;    int N = pATIHW->FeedbackDivider - pATI->ClockDescriptor.NAdjust;    int M = pATIHW->ReferenceDivider - pATI->ClockDescriptor.MAdjust;    int D = pATIHW->PostDivider;    /* Temporarily switch to accelerator mode */    crtc_gen_cntl = inr(CRTC_GEN_CNTL);    if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))        outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN);    switch (pATI->ProgrammableClock)    {        case ATI_CLOCK_ICS2595:            clock_cntl0 = in8(CLOCK_CNTL);            Programme = (SetBits(pATIHW->clock, ICS2595_CLOCK) |                SetBits(N, ICS2595_FB_DIV) | SetBits(D, ICS2595_POST_DIV)) ^                ICS2595_TOGGLE;            ATIDelay(50000);            /* 50 milliseconds */            (void)xf86DisableInterrupts();            /* Send all 20 bits of programme word */            while (Programme >= CLOCK_BIT)            {                tmp = (Programme & CLOCK_BIT) | CLOCK_STROBE;                out8(CLOCK_CNTL, tmp);                ATIDelay(26);           /* 26 microseconds */                out8(CLOCK_CNTL, tmp | CLOCK_PULSE);                ATIDelay(26);           /* 26 microseconds */                Programme >>= 1;            }            xf86EnableInterrupts();            /* Restore register */            out8(CLOCK_CNTL, clock_cntl0 | CLOCK_STROBE);            break;        case ATI_CLOCK_STG1703:            (void)ATIGetDACCmdReg(pATI);            (void)in8(M64_DAC_MASK);            out8(M64_DAC_MASK, (pATIHW->clock << 1) + 0x20U);            out8(M64_DAC_MASK, 0);            out8(M64_DAC_MASK, SetBits(N, 0xFFU));            out8(M64_DAC_MASK, SetBits(M, 0x1FU) | SetBits(D, 0xE0U));            break;        case ATI_CLOCK_CH8398:            tmp = inr(DAC_CNTL) | (DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3);            outr(DAC_CNTL, tmp);            out8(M64_DAC_WRITE, pATIHW->clock);            out8(M64_DAC_DATA, SetBits(N, 0xFFU));            out8(M64_DAC_DATA, SetBits(M, 0x3FU) | SetBits(D, 0xC0U));            out8(M64_DAC_MASK, 0x04U);            outr(DAC_CNTL, tmp & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3));            tmp2 = in8(M64_DAC_WRITE);            out8(M64_DAC_WRITE, (tmp2 & 0x70U) | 0x80U);            outr(DAC_CNTL, tmp & ~DAC_EXT_SEL_RS2);            break;        case ATI_CLOCK_INTERNAL:            /* Reset VCLK generator */            ATIMach64PutPLLReg(PLL_VCLK_CNTL, pATIHW->pll_vclk_cntl);            /* Set post-divider */            tmp2 = pATIHW->clock << 1;            tmp = ATIMach64GetPLLReg(PLL_VCLK_POST_DIV);            tmp &= ~(0x03U << tmp2);            tmp |= SetBits(D, 0x03U) << tmp2;            ATIMach64PutPLLReg(PLL_VCLK_POST_DIV, tmp);            /* Set extended post-divider */            tmp = ATIMach64GetPLLReg(PLL_XCLK_CNTL);            tmp &= ~(SetBits(1, PLL_VCLK0_XDIV) << pATIHW->clock);            tmp |= SetBits(D >> 2, PLL_VCLK0_XDIV) << pATIHW->clock;            ATIMach64PutPLLReg(PLL_XCLK_CNTL, tmp);            /* Set feedback divider */            tmp = PLL_VCLK0_FB_DIV + pATIHW->clock;            ATIMach64PutPLLReg(tmp, SetBits(N, 0xFFU));            /* End VCLK generator reset */            ATIMach64PutPLLReg(PLL_VCLK_CNTL,                pATIHW->pll_vclk_cntl & ~PLL_VCLK_RESET);            /* Reset write bit */            ATIMach64AccessPLLReg(pATI, 0, FALSE);            break;        case ATI_CLOCK_ATT20C408:            (void)ATIGetDACCmdReg(pATI);            tmp = in8(M64_DAC_MASK);            (void)ATIGetDACCmdReg(pATI);            out8(M64_DAC_MASK, tmp | 1);            out8(M64_DAC_WRITE, 1);            out8(M64_DAC_MASK, tmp | 9);            ATIDelay(400);              /* 400 microseconds */            tmp2 = (pATIHW->clock << 2) + 0x40U;            out8(M64_DAC_WRITE, tmp2);            out8(M64_DAC_MASK, SetBits(N, 0xFFU));            out8(M64_DAC_WRITE, ++tmp2);            out8(M64_DAC_MASK, SetBits(M, 0x3FU) | SetBits(D, 0xC0U));            out8(M64_DAC_WRITE, ++tmp2);            out8(M64_DAC_MASK, 0x77U);            ATIDelay(400);              /* 400 microseconds */            out8(M64_DAC_WRITE, 1);            out8(M64_DAC_MASK, tmp);            break;        case ATI_CLOCK_IBMRGB514:            /*             * Here, only update in-core data.  It will be written out later by             * ATIRGB514Set().             */            tmp = (pATIHW->clock << 1) + 0x20U;            pATIHW->ibmrgb514[tmp] =                (SetBits(N, 0x3FU) | SetBits(D, 0xC0U)) ^ 0xC0U;            pATIHW->ibmrgb514[tmp + 1] = SetBits(M, 0x3FU);            break;        default:            break;    }    (void)in8(M64_DAC_WRITE);    /* Clear DAC counter */    /* Restore register */    if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))        outr(CRTC_GEN_CNTL, crtc_gen_cntl);}

⌨️ 快捷键说明

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