162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * linux/drivers/video/kyro/STG4000VTG.c 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2002 STMicroelectronics 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 762306a36Sopenharmony_ci * License. See the file COPYING in the main directory of this archive 862306a36Sopenharmony_ci * for more details. 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/types.h> 1262306a36Sopenharmony_ci#include <video/kyro.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include "STG4000Reg.h" 1562306a36Sopenharmony_ci#include "STG4000Interface.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_civoid DisableVGA(volatile STG4000REG __iomem *pSTGReg) 1862306a36Sopenharmony_ci{ 1962306a36Sopenharmony_ci u32 tmp; 2062306a36Sopenharmony_ci volatile u32 count = 0, i; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci /* Reset the VGA registers */ 2362306a36Sopenharmony_ci tmp = STG_READ_REG(SoftwareReset); 2462306a36Sopenharmony_ci CLEAR_BIT(8); 2562306a36Sopenharmony_ci STG_WRITE_REG(SoftwareReset, tmp); 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci /* Just for Delay */ 2862306a36Sopenharmony_ci for (i = 0; i < 1000; i++) { 2962306a36Sopenharmony_ci count++; 3062306a36Sopenharmony_ci } 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci /* Pull-out the VGA registers from reset */ 3362306a36Sopenharmony_ci tmp = STG_READ_REG(SoftwareReset); 3462306a36Sopenharmony_ci tmp |= SET_BIT(8); 3562306a36Sopenharmony_ci STG_WRITE_REG(SoftwareReset, tmp); 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_civoid StopVTG(volatile STG4000REG __iomem *pSTGReg) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci u32 tmp = 0; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci /* Stop Ver and Hor Sync Generator */ 4362306a36Sopenharmony_ci tmp = (STG_READ_REG(DACSyncCtrl)) | SET_BIT(0) | SET_BIT(2); 4462306a36Sopenharmony_ci CLEAR_BIT(31); 4562306a36Sopenharmony_ci STG_WRITE_REG(DACSyncCtrl, tmp); 4662306a36Sopenharmony_ci} 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_civoid StartVTG(volatile STG4000REG __iomem *pSTGReg) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci u32 tmp = 0; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci /* Start Ver and Hor Sync Generator */ 5362306a36Sopenharmony_ci tmp = ((STG_READ_REG(DACSyncCtrl)) | SET_BIT(31)); 5462306a36Sopenharmony_ci CLEAR_BIT(0); 5562306a36Sopenharmony_ci CLEAR_BIT(2); 5662306a36Sopenharmony_ci STG_WRITE_REG(DACSyncCtrl, tmp); 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_civoid SetupVTG(volatile STG4000REG __iomem *pSTGReg, 6062306a36Sopenharmony_ci const struct kyrofb_info * pTiming) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci u32 tmp = 0; 6362306a36Sopenharmony_ci u32 margins = 0; 6462306a36Sopenharmony_ci u32 ulBorder; 6562306a36Sopenharmony_ci u32 xRes = pTiming->XRES; 6662306a36Sopenharmony_ci u32 yRes = pTiming->YRES; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci /* Horizontal */ 6962306a36Sopenharmony_ci u32 HAddrTime, HRightBorder, HLeftBorder; 7062306a36Sopenharmony_ci u32 HBackPorcStrt, HFrontPorchStrt, HTotal, 7162306a36Sopenharmony_ci HLeftBorderStrt, HRightBorderStrt, HDisplayStrt; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci /* Vertical */ 7462306a36Sopenharmony_ci u32 VDisplayStrt, VBottomBorder, VTopBorder; 7562306a36Sopenharmony_ci u32 VBackPorchStrt, VTotal, VTopBorderStrt, 7662306a36Sopenharmony_ci VFrontPorchStrt, VBottomBorderStrt, VAddrTime; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci /* Need to calculate the right border */ 7962306a36Sopenharmony_ci if ((xRes == 640) && (yRes == 480)) { 8062306a36Sopenharmony_ci if ((pTiming->VFREQ == 60) || (pTiming->VFREQ == 72)) { 8162306a36Sopenharmony_ci margins = 8; 8262306a36Sopenharmony_ci } 8362306a36Sopenharmony_ci } 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci /* Work out the Border */ 8662306a36Sopenharmony_ci ulBorder = 8762306a36Sopenharmony_ci (pTiming->HTot - 8862306a36Sopenharmony_ci (pTiming->HST + (pTiming->HBP - margins) + xRes + 8962306a36Sopenharmony_ci (pTiming->HFP - margins))) >> 1; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci /* Border the same for Vertical and Horizontal */ 9262306a36Sopenharmony_ci VBottomBorder = HLeftBorder = VTopBorder = HRightBorder = ulBorder; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci /************ Get Timing values for Horizontal ******************/ 9562306a36Sopenharmony_ci HAddrTime = xRes; 9662306a36Sopenharmony_ci HBackPorcStrt = pTiming->HST; 9762306a36Sopenharmony_ci HTotal = pTiming->HTot; 9862306a36Sopenharmony_ci HDisplayStrt = 9962306a36Sopenharmony_ci pTiming->HST + (pTiming->HBP - margins) + HLeftBorder; 10062306a36Sopenharmony_ci HLeftBorderStrt = HDisplayStrt - HLeftBorder; 10162306a36Sopenharmony_ci HFrontPorchStrt = 10262306a36Sopenharmony_ci pTiming->HST + (pTiming->HBP - margins) + HLeftBorder + 10362306a36Sopenharmony_ci HAddrTime + HRightBorder; 10462306a36Sopenharmony_ci HRightBorderStrt = HFrontPorchStrt - HRightBorder; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci /************ Get Timing values for Vertical ******************/ 10762306a36Sopenharmony_ci VAddrTime = yRes; 10862306a36Sopenharmony_ci VBackPorchStrt = pTiming->VST; 10962306a36Sopenharmony_ci VTotal = pTiming->VTot; 11062306a36Sopenharmony_ci VDisplayStrt = 11162306a36Sopenharmony_ci pTiming->VST + (pTiming->VBP - margins) + VTopBorder; 11262306a36Sopenharmony_ci VTopBorderStrt = VDisplayStrt - VTopBorder; 11362306a36Sopenharmony_ci VFrontPorchStrt = 11462306a36Sopenharmony_ci pTiming->VST + (pTiming->VBP - margins) + VTopBorder + 11562306a36Sopenharmony_ci VAddrTime + VBottomBorder; 11662306a36Sopenharmony_ci VBottomBorderStrt = VFrontPorchStrt - VBottomBorder; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci /* Set Hor Timing 1, 2, 3 */ 11962306a36Sopenharmony_ci tmp = STG_READ_REG(DACHorTim1); 12062306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 12162306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 12262306a36Sopenharmony_ci tmp |= (HTotal) | (HBackPorcStrt << 16); 12362306a36Sopenharmony_ci STG_WRITE_REG(DACHorTim1, tmp); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci tmp = STG_READ_REG(DACHorTim2); 12662306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 12762306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 12862306a36Sopenharmony_ci tmp |= (HDisplayStrt << 16) | HLeftBorderStrt; 12962306a36Sopenharmony_ci STG_WRITE_REG(DACHorTim2, tmp); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci tmp = STG_READ_REG(DACHorTim3); 13262306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 13362306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 13462306a36Sopenharmony_ci tmp |= (HFrontPorchStrt << 16) | HRightBorderStrt; 13562306a36Sopenharmony_ci STG_WRITE_REG(DACHorTim3, tmp); 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci /* Set Ver Timing 1, 2, 3 */ 13862306a36Sopenharmony_ci tmp = STG_READ_REG(DACVerTim1); 13962306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 14062306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 14162306a36Sopenharmony_ci tmp |= (VBackPorchStrt << 16) | (VTotal); 14262306a36Sopenharmony_ci STG_WRITE_REG(DACVerTim1, tmp); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci tmp = STG_READ_REG(DACVerTim2); 14562306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 14662306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 14762306a36Sopenharmony_ci tmp |= (VDisplayStrt << 16) | VTopBorderStrt; 14862306a36Sopenharmony_ci STG_WRITE_REG(DACVerTim2, tmp); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci tmp = STG_READ_REG(DACVerTim3); 15162306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 15262306a36Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 15362306a36Sopenharmony_ci tmp |= (VFrontPorchStrt << 16) | VBottomBorderStrt; 15462306a36Sopenharmony_ci STG_WRITE_REG(DACVerTim3, tmp); 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci /* Set Verical and Horizontal Polarity */ 15762306a36Sopenharmony_ci tmp = STG_READ_REG(DACSyncCtrl) | SET_BIT(3) | SET_BIT(1); 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci if ((pTiming->HSP > 0) && (pTiming->VSP < 0)) { /* +hsync -vsync */ 16062306a36Sopenharmony_ci tmp &= ~0x8; 16162306a36Sopenharmony_ci } else if ((pTiming->HSP < 0) && (pTiming->VSP > 0)) { /* -hsync +vsync */ 16262306a36Sopenharmony_ci tmp &= ~0x2; 16362306a36Sopenharmony_ci } else if ((pTiming->HSP < 0) && (pTiming->VSP < 0)) { /* -hsync -vsync */ 16462306a36Sopenharmony_ci tmp &= ~0xA; 16562306a36Sopenharmony_ci } else if ((pTiming->HSP > 0) && (pTiming->VSP > 0)) { /* +hsync -vsync */ 16662306a36Sopenharmony_ci tmp &= ~0x0; 16762306a36Sopenharmony_ci } 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci STG_WRITE_REG(DACSyncCtrl, tmp); 17062306a36Sopenharmony_ci} 171