/* * linux/drivers/video/kyro/STG4000InitDevice.c * * Copyright (C) 2000 Imagination Technologies Ltd * Copyright (C) 2002 STMicroelectronics * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details.
*/
/* Translate clock in Hz */
coreClock *= 100; /* in Hz */
refClock *= 1000; /* in Hz */
/* Work out acceptable clock * The method calculates ~ +- 0.4% (1/256)
*/
ulMinClock = coreClock - (coreClock >> 8);
ulMaxClock = coreClock + (coreClock >> 8);
/* Scale clock required for use in calculations */
ulScaleClockReq = coreClock >> STG4K3_PLL_SCALER;
/* Iterate through post divider values */ for (ODIndex = 0; ODIndex < 3; ODIndex++) {
OD = ODValues[ODIndex];
R = STG4K3_PLL_MIN_R;
/* loop for pre-divider from min to max */ while (R <= STG4K3_PLL_MAX_R) { /* estimate required feedback multiplier */
ulTmp = R * (ulScaleClockReq << OD);
/* F = ClkRequired * R * (2^OD) / Fref */
F = (u32)(ulTmp / (refClock >> STG4K3_PLL_SCALER));
/* compensate for accuracy */ if (F > STG4K3_PLL_MIN_F)
F--;
/* * We should be close to our target frequency (if it's * achievable with current OD & R) let's iterate * through F for best fit
*/ while ((F >= STG4K3_PLL_MIN_F) &&
(F <= STG4K3_PLL_MAX_F)) { /* Calc VCO at full accuracy */
ulVCO = refClock / R;
ulVCO = F * ulVCO;
/* * Check it's within restricted VCO range * unless of course the desired frequency is * above the restricted range, then test * against VCO limit
*/ if ((ulVCO >= STG4K3_PLL_MINR_VCO) &&
((ulVCO <= STG4K3_PLL_MAXR_VCO) ||
((coreClock > STG4K3_PLL_MAXR_VCO)
&& (ulVCO <= STG4K3_PLL_MAX_VCO)))) {
ulTmp = (ulVCO >> OD); /* Clock = VCO / (2^OD) */
/* Is this clock good enough? */ if ((ulTmp >= ulMinClock)
&& (ulTmp <= ulMaxClock)) {
ulPhaseScore = (((refClock / R) - (refClock / STG4K3_PLL_MAX_R))) / ((refClock - (refClock / STG4K3_PLL_MAX_R)) >> 10);
if (!ulBestScore) {
ulBestOD = OD;
ulBestF = F;
ulBestR = R;
ulBestClk = ulTmp;
ulBestScore =
ulScore;
} /* is this better, ( aim for highest Score) */ /*-------------------------------------------------------------------------- Here we want to use a scoring system which will take account of both the value at the phase comparater and the VCO output to do this we will use a cumulative score between the two The way this ends up is that we choose the first value in the loop anyway but we shall keep this code in case new restrictions come into play
--------------------------------------------------------------------------*/ if ((ulScore >= ulBestScore) && (OD > 0)) {
ulBestOD = OD;
ulBestF = F;
ulBestR = R;
ulBestClk = ulTmp;
ulBestScore =
ulScore;
}
}
}
F++;
}
R++;
}
}
/* did we find anything? Then return RFOD
*/ if (ulBestScore) {
*ROut = ulBestR;
*FOut = ulBestF;
/* Need to play around to reset TA */
STG_WRITE_REG(TAConfiguration, 0);
STG_WRITE_REG(SoftwareReset,
PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_ROM_RST);
STG_WRITE_REG(SoftwareReset,
PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_TA_RST |
PMX2_SOFTRESET_ROM_RST);
/* Send bits 0:7 of the Core PLL Mode register */
tmp = ((CORE_PLL_MODE_REG_0_7 << 8) | (core_pll & 0x00FF));
pci_write_config_word(pDev, CorePllControl, tmp); /* Without some delay between the PCI config writes the clock does not reliably set when the code is compiled -O3
*/
OS_DELAY(1000000);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.