summaryrefslogtreecommitdiff
path: root/src/smilynx_crtc.c
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@gmail.com>2008-12-27 00:52:05 +0100
committerPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-12-29 13:52:26 -0200
commit46741589529809c17aa1e9719492a4b623de6ddf (patch)
treea86bf8f79f0d83935e31534cb1eec3317ff3a29d /src/smilynx_crtc.c
parent439adf4455c651926040eeeec52a092f14f3196b (diff)
Some more quirks for the SM712.
* Program the MCLK to 157MHz on startup. * Adjust the requested pixel clock if it's near one of the known stable frequencies. * Prefer the clock alternative with post scalar turned on when the denominator is even.
Diffstat (limited to 'src/smilynx_crtc.c')
-rw-r--r--src/smilynx_crtc.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/src/smilynx_crtc.c b/src/smilynx_crtc.c
index 508184f..e5963ff 100644
--- a/src/smilynx_crtc.c
+++ b/src/smilynx_crtc.c
@@ -227,6 +227,34 @@ SMILynx_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y)
LEAVE();
}
+static Bool
+SMILynx_CrtcModeFixup(xf86CrtcPtr crtc,
+ DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ ScrnInfoPtr pScrn=crtc->scrn;
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER();
+
+ if (pSmi->Chipset == SMI_LYNXEMplus) {
+ /* Adjust the pixel clock in case it is near one of the known
+ stable frequencies (KHz) */
+ int stable_clocks[] = {46534,};
+ int epsilon = 2000;
+ int i;
+
+ for (i=0; i < sizeof(stable_clocks)/sizeof(int); i++) {
+ if ( abs(mode->Clock - stable_clocks[i]) < epsilon) {
+ adjusted_mode->Clock = stable_clocks[i];
+ break;
+ }
+ }
+ }
+
+ LEAVE(TRUE);
+}
+
static void
SMILynx_CrtcModeSet_vga(xf86CrtcPtr crtc,
DisplayModePtr mode,
@@ -254,13 +282,13 @@ SMILynx_CrtcModeSet_vga(xf86CrtcPtr crtc,
/* calculate vclk1 */
if (SMI_LYNX_SERIES(pSmi->Chipset)) {
- SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock,
+ SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock,
1, 1, 63, 0, 3,
pSmi->clockRange.minClock,
pSmi->clockRange.maxClock,
&reg->SR6C, &reg->SR6D);
} else {
- SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock,
+ SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock,
1, 1, 63, 0, 1,
pSmi->clockRange.minClock,
pSmi->clockRange.maxClock,
@@ -348,13 +376,13 @@ SMILynx_CrtcModeSet_crt(xf86CrtcPtr crtc,
/* calculate vclk1 */
if (SMI_LYNX_SERIES(pSmi->Chipset)) {
- SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock,
+ SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock,
1, 1, 63, 0, 3,
pSmi->clockRange.minClock,
pSmi->clockRange.maxClock,
&reg->SR6C, &reg->SR6D);
} else {
- SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock,
+ SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock,
1, 1, 63, 0, 1,
pSmi->clockRange.minClock,
pSmi->clockRange.maxClock,
@@ -456,19 +484,20 @@ SMILynx_CrtcModeSet_lcd(xf86CrtcPtr crtc,
/* Program the PLL */
/* calculate vclk2 */
- if (pSmi->Chipset == SMI_LYNX3DM) {
- SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock,
- 1, 1, 63, 0, 1,
+ if (SMI_LYNX_SERIES(pSmi->Chipset)) {
+ SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock,
+ 1, 1, 63, 0, 0,
pSmi->clockRange.minClock,
pSmi->clockRange.maxClock,
&reg->SR6E, &reg->SR6F);
} else {
- SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock,
- 1, 1, 63, 0, 0,
+ SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock,
+ 1, 1, 63, 0, 1,
pSmi->clockRange.minClock,
pSmi->clockRange.maxClock,
&reg->SR6E, &reg->SR6F);
}
+
VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E, reg->SR6E);
VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F, reg->SR6F);
@@ -866,6 +895,7 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn)
crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga;
}
+ crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup;
crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame;
crtcPriv->video_init = SMI730_CrtcVideoInit;
crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt;
@@ -886,6 +916,7 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn)
/* CRTC is LCD*/
SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv);
crtcFuncs->mode_set = SMILynx_CrtcModeSet_lcd;
+ crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup;
crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame;
crtcPriv->video_init = SMILynx_CrtcVideoInit_lcd;
crtcPriv->load_lut = SMILynx_CrtcLoadLUT_lcd;
@@ -898,6 +929,7 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn)
SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv);
crtcFuncs->dpms = SMILynx_CrtcDPMS_crt;
crtcFuncs->mode_set = SMILynx_CrtcModeSet_crt;
+ crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup;
crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame;
crtcPriv->video_init = SMILynx_CrtcVideoInit_crt;
crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt;
@@ -918,6 +950,7 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn)
crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga;
}
+ crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup;
crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame;
crtcPriv->video_init = SMILynx_CrtcVideoInit_crt;
crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt;