diff options
author | Luc Verhaegen <libv@skynet.be> | 2009-10-15 18:29:42 +0200 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2009-10-15 18:29:42 +0200 |
commit | afb4f69a2ff3c4d6b242ac39be45da40146e1a0b (patch) | |
tree | cd31d538fb430944d5c4abf6a29bc56a4b3d8de3 | |
parent | e4ee741e0a00f697b201976643fa200f715ad4f3 (diff) |
PLL: Sanitise the 4 different routines.
* Improve debug output by showing multiplier, divider, postdivider.
* Change logic to prefer lower multiplier/divider combinations when
the result is the same.
* Tighten up layout and structure.
-rw-r--r-- | src/via_crtc.c | 119 |
1 files changed, 62 insertions, 57 deletions
diff --git a/src/via_crtc.c b/src/via_crtc.c index b2f2442..9604620 100644 --- a/src/via_crtc.c +++ b/src/via_crtc.c @@ -44,16 +44,15 @@ */ /* - * The below information has been gathered using nothing but a lot of time and - * perseverance. + * Suited for VT3122Ax, VT3122Cx and VT7205. */ static CARD32 VT3122PLLGenerate(struct ViaCrtc *Crtc, int Clock) { - CARD32 PLL = 0; + CARD32 BestDivider = 0, BestShift = 0, BestMultiplier = 0; CARD32 Divider, Shift, Multiplier; int RoundUp; - CARD32 Diff = INT_MAX, NewDiff; + CARD32 BestDiff = INT_MAX, Diff; VIAFUNC(Crtc); @@ -72,26 +71,31 @@ VT3122PLLGenerate(struct ViaCrtc *Crtc, int Clock) if (Multiplier > 0x80) continue; + /* this limit is this awkward because there is not that much + wriggle room for this PLL calculation. Later PLLs are + much more forgiving and are able to much closer approximate + the required dotclocks. */ if (Divider > 11) /* 9, 10, 11 should never be hit */ if (Multiplier < (8 * (Divider - 9) - 1)) continue; - NewDiff = abs(((14318000 * Multiplier) / (Divider << Shift)) - - (Clock * 1000)); - if (NewDiff > Diff) - continue; - - Diff = NewDiff; + Diff = abs(((14318000 * Multiplier) / (Divider << Shift)) - + (Clock * 1000)); - PLL = (Shift << 14) | (Divider << 8) | Multiplier; + if (Diff < BestDiff) { + BestDiff = Diff; + BestMultiplier = Multiplier; + BestDivider = Divider; + BestShift = Shift; + } } } } - ViaDebug(Crtc->scrnIndex, "%s: PLL: 0x%04X (%d off from %d)\n", - __func__, PLL, Diff / 1000, Clock); + ViaDebug(Crtc->scrnIndex, "%s: PLL: %d %d %d (%dkHz off)\n", __func__, + BestMultiplier, BestDivider, 1 << BestShift, BestDiff / 1000); - return PLL; + return (BestShift << 14) | (BestDivider << 8) | BestMultiplier; } /* @@ -100,10 +104,10 @@ VT3122PLLGenerate(struct ViaCrtc *Crtc, int Clock) static CARD32 VT3108PLLGenerate(struct ViaCrtc *Crtc, int Clock) { - CARD32 PLL = 0; + CARD32 BestDivider = 0, BestShift = 0, BestMultiplier = 0; CARD32 Divider, Shift, Multiplier; CARD32 RoundUp; - int Diff = INT_MAX, NewDiff; + int BestDiff = INT_MAX, Diff; VIAFUNC(Crtc); @@ -115,40 +119,41 @@ VT3108PLLGenerate(struct ViaCrtc *Crtc, int Clock) else Multiplier = ((Clock * Divider) << Shift) / 14318; - if (Multiplier > 257) - continue; - - if (Multiplier < (5 * (Divider - 2))) + if ((Multiplier > 257) || (Multiplier < 2)) continue; - NewDiff = abs(((14318000 * Multiplier) / (Divider << Shift)) - - (Clock * 1000)); - if (NewDiff > Diff) + if (Multiplier < (5 * Divider - 10)) continue; - Diff = NewDiff; + Diff = abs(((14318000 * Multiplier) / (Divider << Shift)) - + (Clock * 1000)); - PLL = ((Divider - 2) << 16) | (Shift << 10) | (Multiplier - 2); + if (Diff < BestDiff) { + BestDiff = Diff; + BestMultiplier = Multiplier; + BestDivider = Divider; + BestShift = Shift; + } } } } - ViaDebug(Crtc->scrnIndex, "%s: PLL: 0x%06X (%d off from %d)\n", - __func__, PLL, Diff / 1000, Clock); + ViaDebug(Crtc->scrnIndex, "%s: PLL: %d %d %d (%dkHz off)\n", __func__, + BestMultiplier, BestDivider, 1 << BestShift, BestDiff / 1000); - return PLL; + return ((BestDivider - 2) << 16) | (BestShift << 10) | (BestMultiplier - 2); } /* - * No flies on this PLL. + * Suited for VT3118. */ static CARD32 VT3118PLLGenerate(struct ViaCrtc *Crtc, int Clock) { - CARD32 PLL = 0; + CARD32 BestDivider = 0, BestShift = 0, BestMultiplier = 0; CARD32 Divider, Shift, Multiplier; CARD32 RoundUp; - int Diff = INT_MAX, NewDiff; + int BestDiff = INT_MAX, Diff; VIAFUNC(Crtc); @@ -160,29 +165,28 @@ VT3118PLLGenerate(struct ViaCrtc *Crtc, int Clock) else Multiplier = ((Clock * Divider) << Shift) / 14318; - /* keep the internal frequencies low to avoid noise */ - if (Multiplier > 257) - continue; - - if (Multiplier < 2) /* register limit */ + if ((Multiplier > 257) || (Multiplier < 2)) continue; - NewDiff = abs(((14318000 * Multiplier) / (Divider << Shift)) - - (Clock * 1000)); - if (NewDiff > Diff) - continue; + /* No flies on this PLL. */ - Diff = NewDiff; + Diff = abs(((14318000 * Multiplier) / (Divider << Shift)) - + (Clock * 1000)); - PLL = ((Divider - 2) << 16) | (Shift << 10) | (Multiplier - 2); + if (Diff < BestDiff) { + BestDiff = Diff; + BestMultiplier = Multiplier; + BestDivider = Divider; + BestShift = Shift; + } } } } - ViaDebug(Crtc->scrnIndex, "%s: PLL: 0x%06X (%d off from %d)\n", - __func__, PLL, Diff / 1000, Clock); + ViaDebug(Crtc->scrnIndex, "%s: PLL: %d %d %d (%dkHz off)\n", __func__, + BestMultiplier, BestDivider, 1 << BestShift, BestDiff / 1000); - return PLL; + return ((BestDivider - 2) << 16) | (BestShift << 10) | (BestMultiplier - 2); } /* @@ -193,10 +197,10 @@ VT3118PLLGenerate(struct ViaCrtc *Crtc, int Clock) static CARD32 VT3230PLLGenerate(struct ViaCrtc *Crtc, int Clock) { - CARD32 PLL = 0; + CARD32 BestDivider = 0, BestShift = 0, BestMultiplier = 0; CARD32 Divider, Shift, Multiplier; CARD32 RoundUp; - int Diff = INT_MAX, NewDiff; + int BestDiff = INT_MAX, Diff; VIAFUNC(Crtc); @@ -214,22 +218,23 @@ VT3230PLLGenerate(struct ViaCrtc *Crtc, int Clock) if (Multiplier < (13 * Divider / 2 - 56)) continue; - NewDiff = abs(((14318000 * Multiplier) / (Divider << Shift)) - - (Clock * 1000)); - if (NewDiff > Diff) - continue; - - Diff = NewDiff; + Diff = abs(((14318000 * Multiplier) / (Divider << Shift)) - + (Clock * 1000)); - PLL = ((Divider - 2) << 16) | (Shift << 10) | (Multiplier - 2); + if (Diff < BestDiff) { + BestDiff = Diff; + BestMultiplier = Multiplier; + BestDivider = Divider; + BestShift = Shift; + } } } } - ViaDebug(Crtc->scrnIndex, "%s: PLL: 0x%06X (%d off from %d)\n", - __func__, PLL, Diff / 1000, Clock); + ViaDebug(Crtc->scrnIndex, "%s: PLL: %d %d %d (%dkHz off)\n", __func__, + BestMultiplier, BestDivider, 1 << BestShift, BestDiff / 1000); - return PLL; + return ((BestDivider - 2) << 16) | (BestShift << 10) | (BestMultiplier - 2); } /* |