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