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