1 /* 2 * linux/drivers/video/kyro/STG4000VTG.c 3 * 4 * Copyright (C) 2002 STMicroelectronics 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file COPYING in the main directory of this archive 8 * for more details. 9 */ 10 11 #include <linux/types.h> 12 #include <video/kyro.h> 13 14 #include "STG4000Reg.h" 15 #include "STG4000Interface.h" 16 17 void DisableVGA(volatile STG4000REG __iomem *pSTGReg) 18 { 19 u32 tmp; 20 volatile u32 count = 0, i; 21 22 /* Reset the VGA registers */ 23 tmp = STG_READ_REG(SoftwareReset); 24 CLEAR_BIT(8); 25 STG_WRITE_REG(SoftwareReset, tmp); 26 27 /* Just for Delay */ 28 for (i = 0; i < 1000; i++) { 29 count++; 30 } 31 32 /* Pull-out the VGA registers from reset */ 33 tmp = STG_READ_REG(SoftwareReset); 34 tmp |= SET_BIT(8); 35 STG_WRITE_REG(SoftwareReset, tmp); 36 } 37 38 void StopVTG(volatile STG4000REG __iomem *pSTGReg) 39 { 40 u32 tmp = 0; 41 42 /* Stop Ver and Hor Sync Generator */ 43 tmp = (STG_READ_REG(DACSyncCtrl)) | SET_BIT(0) | SET_BIT(2); 44 CLEAR_BIT(31); 45 STG_WRITE_REG(DACSyncCtrl, tmp); 46 } 47 48 void StartVTG(volatile STG4000REG __iomem *pSTGReg) 49 { 50 u32 tmp = 0; 51 52 /* Start Ver and Hor Sync Generator */ 53 tmp = ((STG_READ_REG(DACSyncCtrl)) | SET_BIT(31)); 54 CLEAR_BIT(0); 55 CLEAR_BIT(2); 56 STG_WRITE_REG(DACSyncCtrl, tmp); 57 } 58 59 void SetupVTG(volatile STG4000REG __iomem *pSTGReg, 60 const struct kyrofb_info * pTiming) 61 { 62 u32 tmp = 0; 63 u32 margins = 0; 64 u32 ulBorder; 65 u32 xRes = pTiming->XRES; 66 u32 yRes = pTiming->YRES; 67 68 /* Horizontal */ 69 u32 HAddrTime, HRightBorder, HLeftBorder; 70 u32 HBackPorcStrt, HFrontPorchStrt, HTotal, 71 HLeftBorderStrt, HRightBorderStrt, HDisplayStrt; 72 73 /* Vertical */ 74 u32 VDisplayStrt, VBottomBorder, VTopBorder; 75 u32 VBackPorchStrt, VTotal, VTopBorderStrt, 76 VFrontPorchStrt, VBottomBorderStrt, VAddrTime; 77 78 /* Need to calculate the right border */ 79 if ((xRes == 640) && (yRes == 480)) { 80 if ((pTiming->VFREQ == 60) || (pTiming->VFREQ == 72)) { 81 margins = 8; 82 } 83 } 84 85 /* Work out the Border */ 86 ulBorder = 87 (pTiming->HTot - 88 (pTiming->HST + (pTiming->HBP - margins) + xRes + 89 (pTiming->HFP - margins))) >> 1; 90 91 /* Border the same for Vertical and Horizontal */ 92 VBottomBorder = HLeftBorder = VTopBorder = HRightBorder = ulBorder; 93 94 /************ Get Timing values for Horizontal ******************/ 95 HAddrTime = xRes; 96 HBackPorcStrt = pTiming->HST; 97 HTotal = pTiming->HTot; 98 HDisplayStrt = 99 pTiming->HST + (pTiming->HBP - margins) + HLeftBorder; 100 HLeftBorderStrt = HDisplayStrt - HLeftBorder; 101 HFrontPorchStrt = 102 pTiming->HST + (pTiming->HBP - margins) + HLeftBorder + 103 HAddrTime + HRightBorder; 104 HRightBorderStrt = HFrontPorchStrt - HRightBorder; 105 106 /************ Get Timing values for Vertical ******************/ 107 VAddrTime = yRes; 108 VBackPorchStrt = pTiming->VST; 109 VTotal = pTiming->VTot; 110 VDisplayStrt = 111 pTiming->VST + (pTiming->VBP - margins) + VTopBorder; 112 VTopBorderStrt = VDisplayStrt - VTopBorder; 113 VFrontPorchStrt = 114 pTiming->VST + (pTiming->VBP - margins) + VTopBorder + 115 VAddrTime + VBottomBorder; 116 VBottomBorderStrt = VFrontPorchStrt - VBottomBorder; 117 118 /* Set Hor Timing 1, 2, 3 */ 119 tmp = STG_READ_REG(DACHorTim1); 120 CLEAR_BITS_FRM_TO(0, 11); 121 CLEAR_BITS_FRM_TO(16, 27); 122 tmp |= (HTotal) | (HBackPorcStrt << 16); 123 STG_WRITE_REG(DACHorTim1, tmp); 124 125 tmp = STG_READ_REG(DACHorTim2); 126 CLEAR_BITS_FRM_TO(0, 11); 127 CLEAR_BITS_FRM_TO(16, 27); 128 tmp |= (HDisplayStrt << 16) | HLeftBorderStrt; 129 STG_WRITE_REG(DACHorTim2, tmp); 130 131 tmp = STG_READ_REG(DACHorTim3); 132 CLEAR_BITS_FRM_TO(0, 11); 133 CLEAR_BITS_FRM_TO(16, 27); 134 tmp |= (HFrontPorchStrt << 16) | HRightBorderStrt; 135 STG_WRITE_REG(DACHorTim3, tmp); 136 137 /* Set Ver Timing 1, 2, 3 */ 138 tmp = STG_READ_REG(DACVerTim1); 139 CLEAR_BITS_FRM_TO(0, 11); 140 CLEAR_BITS_FRM_TO(16, 27); 141 tmp |= (VBackPorchStrt << 16) | (VTotal); 142 STG_WRITE_REG(DACVerTim1, tmp); 143 144 tmp = STG_READ_REG(DACVerTim2); 145 CLEAR_BITS_FRM_TO(0, 11); 146 CLEAR_BITS_FRM_TO(16, 27); 147 tmp |= (VDisplayStrt << 16) | VTopBorderStrt; 148 STG_WRITE_REG(DACVerTim2, tmp); 149 150 tmp = STG_READ_REG(DACVerTim3); 151 CLEAR_BITS_FRM_TO(0, 11); 152 CLEAR_BITS_FRM_TO(16, 27); 153 tmp |= (VFrontPorchStrt << 16) | VBottomBorderStrt; 154 STG_WRITE_REG(DACVerTim3, tmp); 155 156 /* Set Verical and Horizontal Polarity */ 157 tmp = STG_READ_REG(DACSyncCtrl) | SET_BIT(3) | SET_BIT(1); 158 159 if ((pTiming->HSP > 0) && (pTiming->VSP < 0)) { /* +hsync -vsync */ 160 tmp &= ~0x8; 161 } else if ((pTiming->HSP < 0) && (pTiming->VSP > 0)) { /* -hsync +vsync */ 162 tmp &= ~0x2; 163 } else if ((pTiming->HSP < 0) && (pTiming->VSP < 0)) { /* -hsync -vsync */ 164 tmp &= ~0xA; 165 } else if ((pTiming->HSP > 0) && (pTiming->VSP > 0)) { /* +hsync -vsync */ 166 tmp &= ~0x0; 167 } 168 169 STG_WRITE_REG(DACSyncCtrl, tmp); 170 } 171