summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2009-10-15 18:29:42 +0200
committerLuc Verhaegen <libv@skynet.be>2009-10-15 18:29:42 +0200
commitafb4f69a2ff3c4d6b242ac39be45da40146e1a0b (patch)
treecd31d538fb430944d5c4abf6a29bc56a4b3d8de3
parente4ee741e0a00f697b201976643fa200f715ad4f3 (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.c119
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);
}
/*