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