| /* |
| * 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); |
| } |