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 | |