| /* | |
| * linux/drivers/video/kyro/STG4000VTG.c | |
| * | |
| * Copyright (C) 2002 STMicroelectronics | |
| * | |
| * This file is subject to the terms and conditions of the GNU General Public | |
| * License. See the file COPYING in the main directory of this archive | |
| * for more details. | |
| */ | |
| #include <linux/types.h> | |
| #include <video/kyro.h> | |
| #include "STG4000Reg.h" | |
| #include "STG4000Interface.h" | |
| void DisableVGA(volatile STG4000REG __iomem *pSTGReg) | |
| { | |
| u32 tmp; | |
| volatile u32 count = 0, i; | |
| /* Reset the VGA registers */ | |
| tmp = STG_READ_REG(SoftwareReset); | |
| CLEAR_BIT(8); | |
| STG_WRITE_REG(SoftwareReset, tmp); | |
| /* Just for Delay */ | |
| for (i = 0; i < 1000; i++) { | |
| count++; | |
| } | |
| /* Pull-out the VGA registers from reset */ | |
| tmp = STG_READ_REG(SoftwareReset); | |
| tmp |= SET_BIT(8); | |
| STG_WRITE_REG(SoftwareReset, tmp); | |
| } | |
| void StopVTG(volatile STG4000REG __iomem *pSTGReg) | |
| { | |
| u32 tmp = 0; | |
| /* Stop Ver and Hor Sync Generator */ | |
| tmp = (STG_READ_REG(DACSyncCtrl)) | SET_BIT(0) | SET_BIT(2); | |
| CLEAR_BIT(31); | |
| STG_WRITE_REG(DACSyncCtrl, tmp); | |
| } | |
| void StartVTG(volatile STG4000REG __iomem *pSTGReg) | |
| { | |
| u32 tmp = 0; | |
| /* Start Ver and Hor Sync Generator */ | |
| tmp = ((STG_READ_REG(DACSyncCtrl)) | SET_BIT(31)); | |
| CLEAR_BIT(0); | |
| CLEAR_BIT(2); | |
| STG_WRITE_REG(DACSyncCtrl, tmp); | |
| } | |
| void SetupVTG(volatile STG4000REG __iomem *pSTGReg, | |
| const struct kyrofb_info * pTiming) | |
| { | |
| u32 tmp = 0; | |
| u32 margins = 0; | |
| u32 ulBorder; | |
| u32 xRes = pTiming->XRES; | |
| u32 yRes = pTiming->YRES; | |
| /* Horizontal */ | |
| u32 HAddrTime, HRightBorder, HLeftBorder; | |
| u32 HBackPorcStrt, HFrontPorchStrt, HTotal, | |
| HLeftBorderStrt, HRightBorderStrt, HDisplayStrt; | |
| /* Vertical */ | |
| u32 VDisplayStrt, VBottomBorder, VTopBorder; | |
| u32 VBackPorchStrt, VTotal, VTopBorderStrt, | |
| VFrontPorchStrt, VBottomBorderStrt, VAddrTime; | |
| /* Need to calculate the right border */ | |
| if ((xRes == 640) && (yRes == 480)) { | |
| if ((pTiming->VFREQ == 60) || (pTiming->VFREQ == 72)) { | |
| margins = 8; | |
| } | |
| } | |
| /* Work out the Border */ | |
| ulBorder = | |
| (pTiming->HTot - | |
| (pTiming->HST + (pTiming->HBP - margins) + xRes + | |
| (pTiming->HFP - margins))) >> 1; | |
| /* Border the same for Vertical and Horizontal */ | |
| VBottomBorder = HLeftBorder = VTopBorder = HRightBorder = ulBorder; | |
| /************ Get Timing values for Horizontal ******************/ | |
| HAddrTime = xRes; | |
| HBackPorcStrt = pTiming->HST; | |
| HTotal = pTiming->HTot; | |
| HDisplayStrt = | |
| pTiming->HST + (pTiming->HBP - margins) + HLeftBorder; | |
| HLeftBorderStrt = HDisplayStrt - HLeftBorder; | |
| HFrontPorchStrt = | |
| pTiming->HST + (pTiming->HBP - margins) + HLeftBorder + | |
| HAddrTime + HRightBorder; | |
| HRightBorderStrt = HFrontPorchStrt - HRightBorder; | |
| /************ Get Timing values for Vertical ******************/ | |
| VAddrTime = yRes; | |
| VBackPorchStrt = pTiming->VST; | |
| VTotal = pTiming->VTot; | |
| VDisplayStrt = | |
| pTiming->VST + (pTiming->VBP - margins) + VTopBorder; | |
| VTopBorderStrt = VDisplayStrt - VTopBorder; | |
| VFrontPorchStrt = | |
| pTiming->VST + (pTiming->VBP - margins) + VTopBorder + | |
| VAddrTime + VBottomBorder; | |
| VBottomBorderStrt = VFrontPorchStrt - VBottomBorder; | |
| /* Set Hor Timing 1, 2, 3 */ | |
| tmp = STG_READ_REG(DACHorTim1); | |
| CLEAR_BITS_FRM_TO(0, 11); | |
| CLEAR_BITS_FRM_TO(16, 27); | |
| tmp |= (HTotal) | (HBackPorcStrt << 16); | |
| STG_WRITE_REG(DACHorTim1, tmp); | |
| tmp = STG_READ_REG(DACHorTim2); | |
| CLEAR_BITS_FRM_TO(0, 11); | |
| CLEAR_BITS_FRM_TO(16, 27); | |
| tmp |= (HDisplayStrt << 16) | HLeftBorderStrt; | |
| STG_WRITE_REG(DACHorTim2, tmp); | |
| tmp = STG_READ_REG(DACHorTim3); | |
| CLEAR_BITS_FRM_TO(0, 11); | |
| CLEAR_BITS_FRM_TO(16, 27); | |
| tmp |= (HFrontPorchStrt << 16) | HRightBorderStrt; | |
| STG_WRITE_REG(DACHorTim3, tmp); | |
| /* Set Ver Timing 1, 2, 3 */ | |
| tmp = STG_READ_REG(DACVerTim1); | |
| CLEAR_BITS_FRM_TO(0, 11); | |
| CLEAR_BITS_FRM_TO(16, 27); | |
| tmp |= (VBackPorchStrt << 16) | (VTotal); | |
| STG_WRITE_REG(DACVerTim1, tmp); | |
| tmp = STG_READ_REG(DACVerTim2); | |
| CLEAR_BITS_FRM_TO(0, 11); | |
| CLEAR_BITS_FRM_TO(16, 27); | |
| tmp |= (VDisplayStrt << 16) | VTopBorderStrt; | |
| STG_WRITE_REG(DACVerTim2, tmp); | |
| tmp = STG_READ_REG(DACVerTim3); | |
| CLEAR_BITS_FRM_TO(0, 11); | |
| CLEAR_BITS_FRM_TO(16, 27); | |
| tmp |= (VFrontPorchStrt << 16) | VBottomBorderStrt; | |
| STG_WRITE_REG(DACVerTim3, tmp); | |
| /* Set Verical and Horizontal Polarity */ | |
| tmp = STG_READ_REG(DACSyncCtrl) | SET_BIT(3) | SET_BIT(1); | |
| if ((pTiming->HSP > 0) && (pTiming->VSP < 0)) { /* +hsync -vsync */ | |
| tmp &= ~0x8; | |
| } else if ((pTiming->HSP < 0) && (pTiming->VSP > 0)) { /* -hsync +vsync */ | |
| tmp &= ~0x2; | |
| } else if ((pTiming->HSP < 0) && (pTiming->VSP < 0)) { /* -hsync -vsync */ | |
| tmp &= ~0xA; | |
| } else if ((pTiming->HSP > 0) && (pTiming->VSP > 0)) { /* +hsync -vsync */ | |
| tmp &= ~0x0; | |
| } | |
| STG_WRITE_REG(DACSyncCtrl, tmp); | |
| } |