summaryrefslogtreecommitdiff
path: root/src/smi_501.c
diff options
context:
space:
mode:
authorPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-10-03 18:55:14 -0300
committerPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-10-03 18:55:14 -0300
commit1656fb6de5308ff586676e8d6a8aa8d4579ebf4c (patch)
tree274d4a63b5e50fc98690175c0158bfc4f0f613d3 /src/smi_501.c
parentda789f720e2d772dff92adc10aa024a6a921fbbd (diff)
Don't use the 1 multiplier on older chipsets.
It is not in the specs, so don't use it on chipsets older then the 502. Some review should be done in SMI501_FindPLLClock() as when hardcoding it to use the clock selection code for older chips, it appears to choose a better refresh rate (no flicking at 1024x600).
Diffstat (limited to 'src/smi_501.c')
-rw-r--r--src/smi_501.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/src/smi_501.c b/src/smi_501.c
index 17239b2..8bc0d34 100644
--- a/src/smi_501.c
+++ b/src/smi_501.c
@@ -48,10 +48,9 @@ authorization from The XFree86 Project or Silicon Motion.
static void SMI501_ModeSet(ScrnInfoPtr pScrn, MSOCRegPtr mode);
static char *format_integer_base2(int32_t word);
-static double SMI501_FindClock(double clock, int max_divider,
- int32_t *x2_1xclck,
- int32_t *x2_select,
- int32_t *x2_divider, int32_t *x2_shift);
+static double SMI501_FindClock(double clock, int max_divider, Bool has1xclck,
+ int32_t *x2_1xclck, int32_t *x2_select,
+ int32_t *x2_divider, int32_t *x2_shift);
static double SMI501_FindPLLClock(double clock, int32_t *m, int32_t *n,
int32_t *xclck);
static void SMI501_PrintRegs(ScrnInfoPtr pScrn);
@@ -316,8 +315,10 @@ SMI501_ModeInit(ScrnInfoPtr pScrn, DisplayModePtr xf86mode)
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV,
"Clock request %5.2f (max_divider %d)\n",
(double)xf86mode->Clock, 5);
- p2_diff = SMI501_FindClock(xf86mode->Clock, 5, &x2_1xclck,
- &x2_select, &x2_divider, &x2_shift);
+ p2_diff = SMI501_FindClock(xf86mode->Clock, 5,
+ (uint32_t)mode->device_id.f.revision >= 0xc0,
+ &x2_1xclck, &x2_select, &x2_divider,
+ &x2_shift);
mode->clock.f.p2_select = x2_select;
mode->clock.f.p2_divider = x2_divider;
mode->clock.f.p2_shift = x2_shift;
@@ -409,8 +410,9 @@ SMI501_ModeInit(ScrnInfoPtr pScrn, DisplayModePtr xf86mode)
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV,
"Clock request %5.2f (max_divider %d)\n",
(double)xf86mode->Clock, 3);
- (void)SMI501_FindClock(xf86mode->Clock, 3, &x2_1xclck,
- &x2_select, &x2_divider, &x2_shift);
+ (void)SMI501_FindClock(xf86mode->Clock, 3,
+ (uint32_t)mode->device_id.f.revision >= 0xc0,
+ &x2_1xclck, &x2_select, &x2_divider, &x2_shift);
mode->clock.f.v2_select = x2_select;
mode->clock.f.v2_divider = x2_divider;
mode->clock.f.v2_shift = x2_shift;
@@ -611,7 +613,8 @@ format_integer_base2(int32_t word)
}
static double
-SMI501_FindClock(double clock, int32_t max_divider, int32_t *x2_1xclck,
+SMI501_FindClock(double clock, int32_t max_divider, Bool has1xclck,
+ int32_t *x2_1xclck,
int32_t *x2_select, int32_t *x2_divider, int32_t *x2_shift)
{
double diff, best, mclk;
@@ -628,8 +631,8 @@ SMI501_FindClock(double clock, int32_t max_divider, int32_t *x2_1xclck,
multiplier += 2, mclk = multiplier * 24 * 1000.0) {
for (divider = 1; divider <= max_divider; divider += 2) {
for (shift = 0; shift < 8; shift++) {
- /* FIXME is divider 1 available for cards older then 502? */
- for (xclck = 0; xclck <= 1; xclck++) {
+ /* Divider 1 not in specs form cards older then 502 */
+ for (xclck = has1xclck != FALSE; xclck <= 1; xclck++) {
diff = (mclk / (divider << shift << xclck)) - clock;
if (fabs(diff) < best) {
*x2_shift = shift;
@@ -669,7 +672,6 @@ SMI501_FindPLLClock(double clock, int32_t *m, int32_t *n, int32_t *xclck)
* those divisions. In this method, N can be any integer between 2
* and 24, M can be any positive, 7 bits integer, and K is either 1
* or 2.
- * FIXME Needs a better description for K?
* To calculate the programmable PLL, the following formula is
* used:
*
@@ -677,6 +679,9 @@ SMI501_FindPLLClock(double clock, int32_t *m, int32_t *n, int32_t *xclck)
*
* Input Frequency is the crystal input frequency value (24 MHz in
* the SMI VGX Demo Board).
+ *
+ * K is a divisor, used by setting bit 15 of the PLL_CTL
+ * (PLL Output Divided by 2).
*/
best = 0x7fffffff;