18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * linux/drivers/video/kyro/STG4000VTG.c 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2002 STMicroelectronics 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 78c2ecf20Sopenharmony_ci * License. See the file COPYING in the main directory of this archive 88c2ecf20Sopenharmony_ci * for more details. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/types.h> 128c2ecf20Sopenharmony_ci#include <video/kyro.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include "STG4000Reg.h" 158c2ecf20Sopenharmony_ci#include "STG4000Interface.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_civoid DisableVGA(volatile STG4000REG __iomem *pSTGReg) 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci u32 tmp; 208c2ecf20Sopenharmony_ci volatile u32 count = 0, i; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci /* Reset the VGA registers */ 238c2ecf20Sopenharmony_ci tmp = STG_READ_REG(SoftwareReset); 248c2ecf20Sopenharmony_ci CLEAR_BIT(8); 258c2ecf20Sopenharmony_ci STG_WRITE_REG(SoftwareReset, tmp); 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci /* Just for Delay */ 288c2ecf20Sopenharmony_ci for (i = 0; i < 1000; i++) { 298c2ecf20Sopenharmony_ci count++; 308c2ecf20Sopenharmony_ci } 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci /* Pull-out the VGA registers from reset */ 338c2ecf20Sopenharmony_ci tmp = STG_READ_REG(SoftwareReset); 348c2ecf20Sopenharmony_ci tmp |= SET_BIT(8); 358c2ecf20Sopenharmony_ci STG_WRITE_REG(SoftwareReset, tmp); 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_civoid StopVTG(volatile STG4000REG __iomem *pSTGReg) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci u32 tmp = 0; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci /* Stop Ver and Hor Sync Generator */ 438c2ecf20Sopenharmony_ci tmp = (STG_READ_REG(DACSyncCtrl)) | SET_BIT(0) | SET_BIT(2); 448c2ecf20Sopenharmony_ci CLEAR_BIT(31); 458c2ecf20Sopenharmony_ci STG_WRITE_REG(DACSyncCtrl, tmp); 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_civoid StartVTG(volatile STG4000REG __iomem *pSTGReg) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci u32 tmp = 0; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci /* Start Ver and Hor Sync Generator */ 538c2ecf20Sopenharmony_ci tmp = ((STG_READ_REG(DACSyncCtrl)) | SET_BIT(31)); 548c2ecf20Sopenharmony_ci CLEAR_BIT(0); 558c2ecf20Sopenharmony_ci CLEAR_BIT(2); 568c2ecf20Sopenharmony_ci STG_WRITE_REG(DACSyncCtrl, tmp); 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_civoid SetupVTG(volatile STG4000REG __iomem *pSTGReg, 608c2ecf20Sopenharmony_ci const struct kyrofb_info * pTiming) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci u32 tmp = 0; 638c2ecf20Sopenharmony_ci u32 margins = 0; 648c2ecf20Sopenharmony_ci u32 ulBorder; 658c2ecf20Sopenharmony_ci u32 xRes = pTiming->XRES; 668c2ecf20Sopenharmony_ci u32 yRes = pTiming->YRES; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci /* Horizontal */ 698c2ecf20Sopenharmony_ci u32 HAddrTime, HRightBorder, HLeftBorder; 708c2ecf20Sopenharmony_ci u32 HBackPorcStrt, HFrontPorchStrt, HTotal, 718c2ecf20Sopenharmony_ci HLeftBorderStrt, HRightBorderStrt, HDisplayStrt; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci /* Vertical */ 748c2ecf20Sopenharmony_ci u32 VDisplayStrt, VBottomBorder, VTopBorder; 758c2ecf20Sopenharmony_ci u32 VBackPorchStrt, VTotal, VTopBorderStrt, 768c2ecf20Sopenharmony_ci VFrontPorchStrt, VBottomBorderStrt, VAddrTime; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci /* Need to calculate the right border */ 798c2ecf20Sopenharmony_ci if ((xRes == 640) && (yRes == 480)) { 808c2ecf20Sopenharmony_ci if ((pTiming->VFREQ == 60) || (pTiming->VFREQ == 72)) { 818c2ecf20Sopenharmony_ci margins = 8; 828c2ecf20Sopenharmony_ci } 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci /* Work out the Border */ 868c2ecf20Sopenharmony_ci ulBorder = 878c2ecf20Sopenharmony_ci (pTiming->HTot - 888c2ecf20Sopenharmony_ci (pTiming->HST + (pTiming->HBP - margins) + xRes + 898c2ecf20Sopenharmony_ci (pTiming->HFP - margins))) >> 1; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci /* Border the same for Vertical and Horizontal */ 928c2ecf20Sopenharmony_ci VBottomBorder = HLeftBorder = VTopBorder = HRightBorder = ulBorder; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci /************ Get Timing values for Horizontal ******************/ 958c2ecf20Sopenharmony_ci HAddrTime = xRes; 968c2ecf20Sopenharmony_ci HBackPorcStrt = pTiming->HST; 978c2ecf20Sopenharmony_ci HTotal = pTiming->HTot; 988c2ecf20Sopenharmony_ci HDisplayStrt = 998c2ecf20Sopenharmony_ci pTiming->HST + (pTiming->HBP - margins) + HLeftBorder; 1008c2ecf20Sopenharmony_ci HLeftBorderStrt = HDisplayStrt - HLeftBorder; 1018c2ecf20Sopenharmony_ci HFrontPorchStrt = 1028c2ecf20Sopenharmony_ci pTiming->HST + (pTiming->HBP - margins) + HLeftBorder + 1038c2ecf20Sopenharmony_ci HAddrTime + HRightBorder; 1048c2ecf20Sopenharmony_ci HRightBorderStrt = HFrontPorchStrt - HRightBorder; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci /************ Get Timing values for Vertical ******************/ 1078c2ecf20Sopenharmony_ci VAddrTime = yRes; 1088c2ecf20Sopenharmony_ci VBackPorchStrt = pTiming->VST; 1098c2ecf20Sopenharmony_ci VTotal = pTiming->VTot; 1108c2ecf20Sopenharmony_ci VDisplayStrt = 1118c2ecf20Sopenharmony_ci pTiming->VST + (pTiming->VBP - margins) + VTopBorder; 1128c2ecf20Sopenharmony_ci VTopBorderStrt = VDisplayStrt - VTopBorder; 1138c2ecf20Sopenharmony_ci VFrontPorchStrt = 1148c2ecf20Sopenharmony_ci pTiming->VST + (pTiming->VBP - margins) + VTopBorder + 1158c2ecf20Sopenharmony_ci VAddrTime + VBottomBorder; 1168c2ecf20Sopenharmony_ci VBottomBorderStrt = VFrontPorchStrt - VBottomBorder; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci /* Set Hor Timing 1, 2, 3 */ 1198c2ecf20Sopenharmony_ci tmp = STG_READ_REG(DACHorTim1); 1208c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 1218c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 1228c2ecf20Sopenharmony_ci tmp |= (HTotal) | (HBackPorcStrt << 16); 1238c2ecf20Sopenharmony_ci STG_WRITE_REG(DACHorTim1, tmp); 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci tmp = STG_READ_REG(DACHorTim2); 1268c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 1278c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 1288c2ecf20Sopenharmony_ci tmp |= (HDisplayStrt << 16) | HLeftBorderStrt; 1298c2ecf20Sopenharmony_ci STG_WRITE_REG(DACHorTim2, tmp); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci tmp = STG_READ_REG(DACHorTim3); 1328c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 1338c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 1348c2ecf20Sopenharmony_ci tmp |= (HFrontPorchStrt << 16) | HRightBorderStrt; 1358c2ecf20Sopenharmony_ci STG_WRITE_REG(DACHorTim3, tmp); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci /* Set Ver Timing 1, 2, 3 */ 1388c2ecf20Sopenharmony_ci tmp = STG_READ_REG(DACVerTim1); 1398c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 1408c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 1418c2ecf20Sopenharmony_ci tmp |= (VBackPorchStrt << 16) | (VTotal); 1428c2ecf20Sopenharmony_ci STG_WRITE_REG(DACVerTim1, tmp); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci tmp = STG_READ_REG(DACVerTim2); 1458c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 1468c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 1478c2ecf20Sopenharmony_ci tmp |= (VDisplayStrt << 16) | VTopBorderStrt; 1488c2ecf20Sopenharmony_ci STG_WRITE_REG(DACVerTim2, tmp); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci tmp = STG_READ_REG(DACVerTim3); 1518c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(0, 11); 1528c2ecf20Sopenharmony_ci CLEAR_BITS_FRM_TO(16, 27); 1538c2ecf20Sopenharmony_ci tmp |= (VFrontPorchStrt << 16) | VBottomBorderStrt; 1548c2ecf20Sopenharmony_ci STG_WRITE_REG(DACVerTim3, tmp); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci /* Set Verical and Horizontal Polarity */ 1578c2ecf20Sopenharmony_ci tmp = STG_READ_REG(DACSyncCtrl) | SET_BIT(3) | SET_BIT(1); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci if ((pTiming->HSP > 0) && (pTiming->VSP < 0)) { /* +hsync -vsync */ 1608c2ecf20Sopenharmony_ci tmp &= ~0x8; 1618c2ecf20Sopenharmony_ci } else if ((pTiming->HSP < 0) && (pTiming->VSP > 0)) { /* -hsync +vsync */ 1628c2ecf20Sopenharmony_ci tmp &= ~0x2; 1638c2ecf20Sopenharmony_ci } else if ((pTiming->HSP < 0) && (pTiming->VSP < 0)) { /* -hsync -vsync */ 1648c2ecf20Sopenharmony_ci tmp &= ~0xA; 1658c2ecf20Sopenharmony_ci } else if ((pTiming->HSP > 0) && (pTiming->VSP > 0)) { /* +hsync -vsync */ 1668c2ecf20Sopenharmony_ci tmp &= ~0x0; 1678c2ecf20Sopenharmony_ci } 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci STG_WRITE_REG(DACSyncCtrl, tmp); 1708c2ecf20Sopenharmony_ci} 171