xref: /OK3568_Linux_fs/kernel/drivers/video/fbdev/kyro/STG4000VTG.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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