diff options
author | Luc Verhaegen <libv@skynet.be> | 2009-04-28 13:30:38 +0200 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2009-04-28 13:30:38 +0200 |
commit | 6251ccdde58aedea06c726ac887e0ec957bdd989 (patch) | |
tree | e6654c5c5104238266aace4812a1e5b60005fc96 | |
parent | cd35f8e8978e93c502e5a76a154573888dcfb49c (diff) |
CRTC: Split up some functions into device specific callbacks.
PLLSet, Crtc1GammaEnable, Crtc2ScaleSet.
-rw-r--r-- | src/via_crtc.c | 452 | ||||
-rw-r--r-- | src/via_crtc.h | 2 | ||||
-rw-r--r-- | src/via_driver.c | 6 |
3 files changed, 299 insertions, 161 deletions
diff --git a/src/via_crtc.c b/src/via_crtc.c index 7382b21..0156ec9 100644 --- a/src/via_crtc.c +++ b/src/via_crtc.c @@ -143,60 +143,95 @@ VT3108PLLGenerate(struct ViaCrtc *Crtc, int Clock) * */ static void -ViaCrtc1PLLSet(struct ViaCrtc *Crtc, CARD32 Clock, int flags) +ViaBusClockSet(struct ViaCrtc *Crtc, int flags) +{ + if (flags & PLL_FLAG_EXTERNAL) + VGACRMask(Crtc, 0x6B, 0x01, 0x01); + else + VGACRMask(Crtc, 0x6B, 0x00, 0x01); +} + +/* + * + */ +static void +ViaCrtc1ClockDividerSet(struct ViaCrtc *Crtc, int flags) +{ + if (flags & PLL_FLAG_HALVE) + VGACRMask(Crtc, 0x6B, 0x80, 0xC0); + else if (flags & PLL_FLAG_QUARTER) + VGACRMask(Crtc, 0x6B, 0xC0, 0xC0); + else + VGACRMask(Crtc, 0x6B, 0x00, 0xC0); +} + +/* + * + */ +static void +ViaCrtc2ClockDividerSet(struct ViaCrtc *Crtc, int flags) +{ + if (flags & PLL_FLAG_HALVE) + VGACRMask(Crtc, 0x6B, 0x20, 0x30); + else if (flags & PLL_FLAG_QUARTER) + VGACRMask(Crtc, 0x6B, 0x30, 0x30); + else + VGACRMask(Crtc, 0x6B, 0x00, 0x30); +} + +/* + * + */ +static void +VT3122Crtc1PLLSet(struct ViaCrtc *Crtc, CARD32 Clock, int flags) { VIAPtr pVia = VIAPTR(xf86Screens[Crtc->scrnIndex]); CARD32 PLL; - switch(pVia->Chipset) { - case VT3122: - case VT7205: - if (flags & PLL_FLAG_EXTERNAL) { - if ((pVia->Chipset == VT3122) && VT3122_REV_IS_AX(pVia->HostRev)) - PLL = 0x471C; - else - PLL = 0x871C; - } else - PLL = VT3122PLLGenerate(Crtc, Clock); + if (flags & PLL_FLAG_EXTERNAL) { + if ((pVia->Chipset == VT3122) && VT3122_REV_IS_AX(pVia->HostRev)) + PLL = 0x471C; + else + PLL = 0x871C; + } else + PLL = VT3122PLLGenerate(Crtc, Clock); - ViaDebug(Crtc->scrnIndex, "%s: %dkHz -> 0x%04X.\n", - __func__, Clock, PLL); + ViaDebug(Crtc->scrnIndex, "%s: %dkHz -> 0x%04X.\n", + __func__, Clock, PLL); - VGASRWrite(Crtc, 0x46, PLL >> 8); - VGASRWrite(Crtc, 0x47, PLL & 0xFF); + VGASRWrite(Crtc, 0x46, PLL >> 8); + VGASRWrite(Crtc, 0x47, PLL & 0xFF); - break; - case VT3108: - case VT3344: - if (flags & PLL_FLAG_EXTERNAL) - break; /* seem perfectly happy like this??? */ - else - PLL = VT3108PLLGenerate(Crtc, Clock); + ViaCrtc1ClockDividerSet(Crtc, flags); + ViaBusClockSet(Crtc, flags); + + VGASRMask(Crtc, 0x40, 0x02, 0x02); + VGASRMask(Crtc, 0x40, 0x00, 0x02); + + /* Set VGA clock to external */ + VGAMiscMask(Crtc, 0x0C, 0x0C); +} - ViaDebug(Crtc->scrnIndex, "%s: %dkHz -> 0x%06X.\n", - __func__, Clock, PLL); +/* + * + */ +static void +VT3108Crtc1PLLSet(struct ViaCrtc *Crtc, CARD32 Clock, int flags) +{ + if (!(flags & PLL_FLAG_EXTERNAL)) { + CARD32 PLL = VT3108PLLGenerate(Crtc, Clock); + + ViaDebug(Crtc->scrnIndex, "%s: %dkHz -> 0x%06X.\n", + __func__, Clock, PLL); VGASRWrite(Crtc, 0x44, PLL & 0xFF); VGASRWrite(Crtc, 0x45, (PLL >> 8) & 0xFF); VGASRWrite(Crtc, 0x46, PLL >> 16); + } else + ; /* hw seems perfectly happy like this??? */ - break; - default: - xf86DrvMsg(Crtc->scrnIndex, X_ERROR, "%s: Unhandled Chipset\n", __func__); - return; - } - - if (flags & PLL_FLAG_HALVE) - VGACRMask(Crtc, 0x6B, 0x80, 0xC0); - else if (flags & PLL_FLAG_QUARTER) - VGACRMask(Crtc, 0x6B, 0xC0, 0xC0); - else - VGACRMask(Crtc, 0x6B, 0x00, 0xC0); - - if (flags & PLL_FLAG_EXTERNAL) - VGACRMask(Crtc, 0x6B, 0x01, 0x01); - else - VGACRMask(Crtc, 0x6B, 0x00, 0x01); + ViaCrtc1ClockDividerSet(Crtc, flags); + ViaBusClockSet(Crtc, flags); VGASRMask(Crtc, 0x40, 0x02, 0x02); VGASRMask(Crtc, 0x40, 0x00, 0x02); @@ -209,62 +244,53 @@ ViaCrtc1PLLSet(struct ViaCrtc *Crtc, CARD32 Clock, int flags) * */ static void -ViaCrtc2PLLSet(struct ViaCrtc *Crtc, CARD32 Clock, int flags) +VT3122Crtc2PLLSet(struct ViaCrtc *Crtc, CARD32 Clock, int flags) { - ScrnInfoPtr pScrn = xf86Screens[Crtc->scrnIndex]; - VIAPtr pVia = VIAPTR(pScrn); + VIAPtr pVia = VIAPTR(xf86Screens[Crtc->scrnIndex]); CARD32 PLL; - switch(pVia->Chipset) { - case VT3122: - case VT7205: - if (flags & PLL_FLAG_EXTERNAL) { - if ((pVia->Chipset == VT3122) && VT3122_REV_IS_AX(pVia->HostRev)) - PLL = 0x471C; - else - PLL = 0x871C; - } else - PLL = VT3122PLLGenerate(Crtc, Clock); + if (flags & PLL_FLAG_EXTERNAL) { + if ((pVia->Chipset == VT3122) && VT3122_REV_IS_AX(pVia->HostRev)) + PLL = 0x471C; + else + PLL = 0x871C; + } else + PLL = VT3122PLLGenerate(Crtc, Clock); - ViaDebug(Crtc->scrnIndex, "%s: %dkHz -> 0x%04X.\n", - __func__, Clock, PLL); + ViaDebug(Crtc->scrnIndex, "%s: %dkHz -> 0x%04X.\n", + __func__, Clock, PLL); - VGASRWrite(Crtc, 0x44, PLL >> 8); - VGASRWrite(Crtc, 0x45, PLL & 0xFF); + VGASRWrite(Crtc, 0x44, PLL >> 8); + VGASRWrite(Crtc, 0x45, PLL & 0xFF); - break; - case VT3108: - case VT3344: - if (flags & PLL_FLAG_EXTERNAL) - break; /* seem perfectly happy like this??? */ - else - PLL = VT3108PLLGenerate(Crtc, Clock); + ViaCrtc2ClockDividerSet(Crtc, flags); + ViaBusClockSet(Crtc, flags); - ViaDebug(Crtc->scrnIndex, "%s: %dkHz -> 0x%06X.\n", - __func__, Clock, PLL); + /* TESTME: shouldn't this be bit0? */ + VGASRMask(Crtc, 0x40, 0x04, 0x04); + VGASRMask(Crtc, 0x40, 0x00, 0x04); +} - VGASRWrite(Crtc, 0x4A, PLL & 0xFF); - VGASRWrite(Crtc, 0x4B, (PLL >> 8) & 0xFF); - VGASRWrite(Crtc, 0x4C, PLL >> 16); +/* + * + */ +static void +VT3108Crtc2PLLSet(struct ViaCrtc *Crtc, CARD32 Clock, int flags) +{ + if (!(flags & PLL_FLAG_EXTERNAL)) { + CARD32 PLL = VT3108PLLGenerate(Crtc, Clock); - break; - default: - xf86DrvMsg(Crtc->scrnIndex, X_ERROR, "%s: Unhandled Chipset: %s\n", - __func__, pScrn->chipset); - return; - } + ViaDebug(Crtc->scrnIndex, "%s: %dkHz -> 0x%06X.\n", + __func__, Clock, PLL); - if (flags & PLL_FLAG_HALVE) - VGACRMask(Crtc, 0x6B, 0x20, 0x30); - else if (flags & PLL_FLAG_QUARTER) - VGACRMask(Crtc, 0x6B, 0x30, 0x30); - else - VGACRMask(Crtc, 0x6B, 0x00, 0x30); + VGASRWrite(Crtc, 0x4A, PLL & 0xFF); + VGASRWrite(Crtc, 0x4B, (PLL >> 8) & 0xFF); + VGASRWrite(Crtc, 0x4C, PLL >> 16); + } else + ; /* hw seems perfectly happy like this??? */ - if (flags & PLL_FLAG_EXTERNAL) - VGACRMask(Crtc, 0x6B, 0x01, 0x01); - else - VGACRMask(Crtc, 0x6B, 0x00, 0x01); + ViaCrtc2ClockDividerSet(Crtc, flags); + ViaBusClockSet(Crtc, flags); VGASRMask(Crtc, 0x40, 0x04, 0x04); VGASRMask(Crtc, 0x40, 0x00, 0x04); @@ -1169,8 +1195,32 @@ ViaCrtc2FBSet(struct ViaCrtc *Crtc, int Width, int Height, int bpp, int Offset) * */ static void -ViaCrtc2ScaleSet(struct ViaCrtc *Crtc, int Width, int Height, - int ScaledWidth, int ScaledHeight) +ViaCrtc2ScaleEnable(struct ViaCrtc *Crtc, Bool Enable, + Bool HInterpolate, Bool VInterpolate) +{ + if (!Enable) + VGACRMask(Crtc, 0x79, 0x00, 0x01); + else { + if (HInterpolate) + VGACRMask(Crtc, 0x79, 0x02, 0x02); + else + VGACRMask(Crtc, 0x79, 0x00, 0x02); + + if (VInterpolate) + VGACRMask(Crtc, 0x79, 0x04, 0x04); + else + VGACRMask(Crtc, 0x79, 0x00, 0x04); + + VGACRMask(Crtc, 0x79, 0x01, 0x01); + } +} + +/* + * + */ +static void +VT3122Crtc2ScaleSet(struct ViaCrtc *Crtc, int Width, int Height, + int ScaledWidth, int ScaledHeight) { VIAPtr pVia = VIAPTR(xf86Screens[Crtc->scrnIndex]); CARD32 temp; @@ -1179,62 +1229,66 @@ ViaCrtc2ScaleSet(struct ViaCrtc *Crtc, int Width, int Height, (!Width || !ScaledWidth || !Height || !ScaledHeight)) { xf86DrvMsg(Crtc->scrnIndex, X_INFO, "No scaling.\n"); - VGACRMask(Crtc, 0x79, 0x00, 0x01); /* Disable Scaling */ - } else { - xf86DrvMsg(Crtc->scrnIndex, X_INFO, "Scaling from %dx%d to %dx%d\n", - Width, Height, ScaledWidth, ScaledHeight); + ViaCrtc2ScaleEnable(Crtc, FALSE, 0, 0); + return; + } - switch (pVia->Chipset) { - case VT3122: - case VT7205: - temp = (Width - 1) * 1024 / (ScaledWidth - 1); - if (temp >= 1024) /* Width == ScaledWidth */ - temp = 0xFFFF; - VGACRWrite(Crtc, 0x77, temp); - VGACRMask(Crtc, 0x79, temp >> 4, 0x30); - - temp = (Height - 1) * 1024 / (ScaledHeight - 1); - if (temp >= 1024) - temp = 0xFFFF; - VGACRWrite(Crtc, 0x78, temp); - VGACRMask(Crtc, 0x79, temp >> 2, 0xC0); - - break; - case VT3108: - case VT3344: - temp = (Width - 1) * 4096 / (ScaledWidth - 1); - if (temp >= 4096) - temp = 0xFFFF; - VGACRMask(Crtc, 0x9F, temp, 0x03); - VGACRWrite(Crtc, 0x77, temp >> 2); - VGACRMask(Crtc, 0x79, temp >> 6, 0x30); - - temp = (Height - 1) * 2048 / (ScaledHeight - 1); - if (temp >= 2048) - temp = 0xFFFF; - VGACRMask(Crtc, 0x79, temp << 3, 0x08); - VGACRWrite(Crtc, 0x78, temp >> 1); - VGACRMask(Crtc, 0x79, temp >> 3, 0xC0); - - break; - default: - xf86DrvMsg(Crtc->scrnIndex, X_ERROR, - "%s: Chipset %d not implemented\n", - __func__, pVia->Chipset); - return; - } + xf86DrvMsg(Crtc->scrnIndex, X_INFO, "Scaling from %dx%d to %dx%d\n", + Width, Height, ScaledWidth, ScaledHeight); - if (pVia->Crtc2HScaleInterpolate) - VGACRMask(Crtc, 0x79, 0x02, 0x02); - else - VGACRMask(Crtc, 0x79, 0x00, 0x02); - if (pVia->Crtc2VScaleInterpolate) - VGACRMask(Crtc, 0x79, 0x04, 0x04); - else - VGACRMask(Crtc, 0x79, 0x00, 0x04); + temp = (Width - 1) * 1024 / (ScaledWidth - 1); + if (temp >= 1024) /* Width == ScaledWidth */ + temp = 0xFFFF; + VGACRWrite(Crtc, 0x77, temp); + VGACRMask(Crtc, 0x79, temp >> 4, 0x30); + + temp = (Height - 1) * 1024 / (ScaledHeight - 1); + if (temp >= 1024) + temp = 0xFFFF; + VGACRWrite(Crtc, 0x78, temp); + VGACRMask(Crtc, 0x79, temp >> 2, 0xC0); - VGACRMask(Crtc, 0x79, 0x01, 0x01); /* Enable */ + ViaCrtc2ScaleEnable(Crtc, TRUE, pVia->Crtc2HScaleInterpolate, + pVia->Crtc2VScaleInterpolate); +} + +/* + * + */ +static void +VT3108Crtc2ScaleSet(struct ViaCrtc *Crtc, int Width, int Height, + int ScaledWidth, int ScaledHeight) +{ + VIAPtr pVia = VIAPTR(xf86Screens[Crtc->scrnIndex]); + CARD32 temp; + + if (((Width == ScaledWidth) && (Height = ScaledHeight)) || + (!Width || !ScaledWidth || !Height || !ScaledHeight)) { + xf86DrvMsg(Crtc->scrnIndex, X_INFO, "No scaling.\n"); + + ViaCrtc2ScaleEnable(Crtc, FALSE, 0, 0); + return; } + + xf86DrvMsg(Crtc->scrnIndex, X_INFO, "Scaling from %dx%d to %dx%d\n", + Width, Height, ScaledWidth, ScaledHeight); + + temp = (Width - 1) * 4096 / (ScaledWidth - 1); + if (temp >= 4096) + temp = 0xFFFF; + VGACRMask(Crtc, 0x9F, temp, 0x03); + VGACRWrite(Crtc, 0x77, temp >> 2); + VGACRMask(Crtc, 0x79, temp >> 6, 0x30); + + temp = (Height - 1) * 2048 / (ScaledHeight - 1); + if (temp >= 2048) + temp = 0xFFFF; + VGACRMask(Crtc, 0x79, temp << 3, 0x08); + VGACRWrite(Crtc, 0x78, temp >> 1); + VGACRMask(Crtc, 0x79, temp >> 3, 0xC0); + + ViaCrtc2ScaleEnable(Crtc, TRUE, pVia->Crtc2HScaleInterpolate, + pVia->Crtc2VScaleInterpolate); } /* @@ -1422,23 +1476,28 @@ ViaCrtc2FrameSet(struct ViaCrtc *Crtc, int X, int Y) * */ static void -ViaCrtc1GammaEnable(struct ViaCrtc *Crtc, Bool Enable) +VT3122Crtc1GammaEnable(struct ViaCrtc *Crtc, Bool Enable) { - VIAPtr pVia = VIAPTR(xf86Screens[Crtc->scrnIndex]); + VIAFUNC(Crtc); + if (Enable) + VGASRMask(Crtc, 0x16, 0x80, 0x80); + else + VGASRMask(Crtc, 0x16, 0x00, 0x80); +} + +/* + * + */ +static void +VT3108Crtc1GammaEnable(struct ViaCrtc *Crtc, Bool Enable) +{ VIAFUNC(Crtc); - if (pVia->Chipset < VT3108) { - if (Enable) - VGASRMask(Crtc, 0x16, 0x80, 0x80); - else - VGASRMask(Crtc, 0x16, 0x00, 0x80); - } else { - if (Enable) - VGACRMask(Crtc, 0x33, 0x80, 0x80); - else - VGACRMask(Crtc, 0x33, 0x00, 0x80); - } + if (Enable) + VGACRMask(Crtc, 0x33, 0x80, 0x80); + else + VGACRMask(Crtc, 0x33, 0x00, 0x80); } /* @@ -1595,12 +1654,23 @@ ViaCrtc2Reset(struct ViaCrtc *Crtc, Bool Reset) * Sets up our CRTCs. Only call this from the primary. * */ -void +Bool ViaCrtcInit(ScrnInfoPtr pScrn) { VIAPtr pVia = VIAPTR(pScrn); struct ViaCrtc *Crtc; + switch (pVia->Chipset) { + case VT3122: + case VT7205: + case VT3108: + case VT3344: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Unsupported chipset\n", __func__); + return FALSE; + } + if (!pVia->Crtc[0]) { Crtc = xnfcalloc(1, sizeof(struct ViaCrtc)); pVia->Crtc[0] = Crtc; @@ -1636,15 +1706,46 @@ ViaCrtcInit(ScrnInfoPtr pScrn) Crtc->FIFOSet = VT3344Crtc1FIFOSet; break; default: + /* should never happen, fix up the check at the top of this function */ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: unsupported chipset\n", __func__); Crtc->FIFOSet = NULL; break; } - Crtc->PLLSet = ViaCrtc1PLLSet; + switch (pVia->Chipset) { + case VT3122: + case VT7205: + Crtc->PLLSet = VT3122Crtc1PLLSet; + break; + case VT3108: + case VT3344: + Crtc->PLLSet = VT3108Crtc1PLLSet; + break; + default: + /* should never happen, fix up the check at the top of this function */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Unsupported chipset\n", __func__); + Crtc->PLLSet = NULL; + break; + } + Crtc->FrameSet = ViaCrtc1FrameSet; Crtc->ScaleSet = NULL; - Crtc->GammaEnable = ViaCrtc1GammaEnable; + + switch (pVia->Chipset) { + case VT3122: + case VT7205: + Crtc->GammaEnable = VT3122Crtc1GammaEnable; + break; + case VT3108: + case VT3344: + Crtc->GammaEnable = VT3108Crtc1GammaEnable; + break; + default: + /* should never happen, fix up the check at the top of this function */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Unsupported chipset\n", __func__); + Crtc->GammaEnable = NULL; + break; + } Crtc->GammaSet = ViaCrtc1GammaSet; Crtc->FixedMode = NULL; @@ -1676,7 +1777,6 @@ ViaCrtcInit(ScrnInfoPtr pScrn) Crtc->FBSet = ViaCrtc2FBSet; Crtc->ModeSet = ViaCrtc2ModeSet; - switch (pVia->Chipset) { case VT3122: if (VT3122_REV_IS_AX(pVia->HostRev)) @@ -1697,14 +1797,46 @@ ViaCrtcInit(ScrnInfoPtr pScrn) Crtc->FIFOSet = VT3344Crtc2FIFOSet; break; default: + /* should never happen, fix up the check at the top of this function */ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: unsupported chipset\n", __func__); Crtc->FIFOSet = NULL; break; } - Crtc->PLLSet = ViaCrtc2PLLSet; + switch (pVia->Chipset) { + case VT3122: + case VT7205: + Crtc->PLLSet = VT3122Crtc2PLLSet; + break; + case VT3108: + case VT3344: + Crtc->PLLSet = VT3108Crtc2PLLSet; + break; + default: + /* should never happen, fix up the check at the top of this function */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Unsupported chipset\n", __func__); + Crtc->PLLSet = NULL; + break; + } + Crtc->FrameSet = ViaCrtc2FrameSet; - Crtc->ScaleSet = ViaCrtc2ScaleSet; + + switch (pVia->Chipset) { + case VT3122: + case VT7205: + Crtc->ScaleSet = VT3122Crtc2ScaleSet; + break; + case VT3108: + case VT3344: + Crtc->ScaleSet = VT3108Crtc2ScaleSet; + break; + default: + /* should never happen, fix up the check at the top of this function */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Unsupported chipset\n", __func__); + Crtc->ScaleSet = NULL; + break; + } + Crtc->GammaEnable = ViaCrtc2GammaEnable; Crtc->GammaSet = ViaCrtc2GammaSet; @@ -1718,6 +1850,8 @@ ViaCrtcInit(ScrnInfoPtr pScrn) Crtc->FixedMode = NULL; } + + return TRUE; } /* diff --git a/src/via_crtc.h b/src/via_crtc.h index f8a1156..ebcf1da 100644 --- a/src/via_crtc.h +++ b/src/via_crtc.h @@ -79,7 +79,7 @@ struct ViaCrtc { }; /* prototypes */ -void ViaCrtcInit(ScrnInfoPtr pScrn); +Bool ViaCrtcInit(ScrnInfoPtr pScrn); void ViaCrtcModeSetInitial(ScrnInfoPtr pScrn); void ViaCrtc2SimultaneousModeSet(struct ViaCrtc *Crtc, DisplayModePtr Mode); diff --git a/src/via_driver.c b/src/via_driver.c index c1a397d..4a7929f 100644 --- a/src/via_driver.c +++ b/src/via_driver.c @@ -1420,7 +1420,11 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags) if (pVia->hwcursor && !VIACursorFBGrab(pScrn)) pVia->hwcursor = FALSE; - ViaCrtcInit(pScrn); + if (!ViaCrtcInit(pScrn)) { + ViaPciDeviceDisable(pVia); + VIAFreeRec(pScrn); + return FALSE; + } ViaOutputsDetect(pScrn->scrnIndex); if (!ViaLayOutCrtcsAndOutputs(pScrn->scrnIndex)) { |