Commit | Line | Data |
---|---|---|
1da177e4 LT |
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; | |
16afe814 | 20 | volatile u32 count = 0, i; |
1da177e4 LT |
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 | } |