1/*
2 * Copyright (c) 2005 ASPEED Technology Inc.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the authors not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  The authors makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26#include "xf86.h"
27#include "xf86_OSproc.h"
28#include "xf86cmap.h"
29#include "compiler.h"
30#include "vgaHW.h"
31#include "mipointer.h"
32#include "micmap.h"
33
34#include "fb.h"
35#include "regionstr.h"
36#include "xf86xv.h"
37#include <X11/extensions/Xv.h>
38
39#include "xf86Pci.h"
40
41/* framebuffer offscreen manager */
42#include "xf86fbman.h"
43
44/* include xaa includes */
45#include "xaarop.h"
46
47/* H/W cursor support */
48#include "xf86Cursor.h"
49
50/* usleep() */
51#include <unistd.h>
52
53/* Driver specific headers */
54#include "ast.h"
55#include "ast_mode.h"
56#include "ast_vgatool.h"
57
58static VBIOS_STDTABLE_STRUCT StdTable[] = {
59    /* MD_2_3_400 */
60    {
61        0x67,
62        {0x00,0x03,0x00,0x02},
63        {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
64         0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
65         0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
66         0xff},
67        {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
68         0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
69         0x0c,0x00,0x0f,0x08},
70        {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
71         0xff}
72    },
73    /* Mode12/ExtEGATable */
74    {
75        0xe3,
76        {0x01,0x0f,0x00,0x06},
77        {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
78         0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
79         0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
80         0xff},
81        {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
82         0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
83         0x01,0x00,0x0f,0x00},
84        {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
85         0xff}
86    },
87    /* ExtVGATable */
88    {
89        0x2f,
90        {0x01,0x0f,0x00,0x0e},
91        {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
92         0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
93         0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
94         0xff},
95        {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
96         0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
97         0x01,0x00,0x00,0x00},
98        {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
99         0xff}
100    },
101    /* ExtHiCTable */
102    {
103        0x2f,
104        {0x01,0x0f,0x00,0x0e},
105        {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
106         0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
107         0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
108         0xff},
109        {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
110         0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
111         0x01,0x00,0x00,0x00},
112        {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
113         0xff}
114    },
115    /* ExtTrueCTable */
116    {
117        0x2f,
118        {0x01,0x0f,0x00,0x0e},
119        {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
120         0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
121         0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
122         0xff},
123        {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
124         0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
125         0x01,0x00,0x00,0x00},
126        {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
127         0xff}
128    },
129};
130
131static VBIOS_ENHTABLE_STRUCT  Res640x480Table[] = {
132    { 800, 640, 8, 96, 525, 480, 2, 2, VCLK25_175,	/* 60Hz */
133      (SyncNN | HBorder | VBorder | Charx8Dot), 60, 1, 0x2E },
134    { 832, 640, 16, 40, 520, 480, 1, 3, VCLK31_5,	/* 72Hz */
135      (SyncNN | HBorder | VBorder | Charx8Dot), 72, 2, 0x2E  },
136    { 840, 640, 16, 64, 500, 480, 1, 3, VCLK31_5,	/* 75Hz */
137      (SyncNN | Charx8Dot) , 75, 3, 0x2E },
138    { 832, 640, 56, 56, 509, 480, 1, 3, VCLK36,		/* 85Hz */
139      (SyncNN | Charx8Dot) , 85, 4, 0x2E },
140    { 832, 640, 56, 56, 509, 480, 1, 3, VCLK36,		/* end */
141      (SyncNN | Charx8Dot) , 0xFF, 4, 0x2E },
142};
143
144
145static VBIOS_ENHTABLE_STRUCT  Res800x600Table[] = {
146    {1024, 800, 24, 72, 625, 600, 1, 2, VCLK36,		/* 56Hz */
147      (SyncPP | Charx8Dot), 56, 1, 0x30 },
148    {1056, 800, 40, 128, 628, 600, 1, 4, VCLK40,	/* 60Hz */
149      (SyncPP | Charx8Dot), 60, 2, 0x30 },
150    {1040, 800, 56, 120, 666, 600, 37, 6, VCLK50,	/* 72Hz */
151      (SyncPP | Charx8Dot), 72, 3, 0x30 },
152    {1056, 800, 16, 80, 625, 600, 1, 3, VCLK49_5,	/* 75Hz */
153      (SyncPP | Charx8Dot), 75, 4, 0x30 },
154    {1048, 800, 32, 64, 631, 600, 1, 3, VCLK56_25,	/* 85Hz */
155      (SyncPP | Charx8Dot), 84, 5, 0x30 },
156    {1048, 800, 32, 64, 631, 600, 1, 3, VCLK56_25,	/* end */
157      (SyncPP | Charx8Dot), 0xFF, 5, 0x30 },
158};
159
160static VBIOS_ENHTABLE_STRUCT  Res1024x768Table[] = {
161    {1344, 1024, 24, 136, 806, 768, 3, 6, VCLK65,	/* 60Hz */
162      (SyncNN | Charx8Dot), 60, 1, 0x31 },
163    {1328, 1024, 24, 136, 806, 768, 3, 6, VCLK75,	/* 70Hz */
164      (SyncNN | Charx8Dot), 70, 2, 0x31 },
165    {1312, 1024, 16, 96, 800, 768, 1, 3, VCLK78_75,	/* 75Hz */
166      (SyncPP | Charx8Dot), 75, 3, 0x31 },
167    {1376, 1024, 48, 96, 808, 768, 1, 3, VCLK94_5,	/* 85Hz */
168      (SyncPP | Charx8Dot), 84, 4, 0x31 },
169    {1376, 1024, 48, 96, 808, 768, 1, 3, VCLK94_5,	/* end */
170      (SyncPP | Charx8Dot), 0xFF, 4, 0x31 },
171};
172
173static VBIOS_ENHTABLE_STRUCT  Res1280x1024Table[] = {
174    {1688, 1280, 48, 112, 1066, 1024, 1, 3, VCLK108,	/* 60Hz */
175      (SyncPP | Charx8Dot), 60, 1, 0x32 },
176    {1688, 1280, 16, 144, 1066, 1024, 1, 3, VCLK135,	/* 75Hz */
177      (SyncPP | Charx8Dot), 75, 2, 0x32 },
178    {1728, 1280, 64, 160, 1072, 1024, 1, 3, VCLK157_5,	/* 85Hz */
179      (SyncPP | Charx8Dot), 85, 3, 0x32 },
180    {1728, 1280, 64, 160, 1072, 1024, 1, 3, VCLK157_5,	/* end */
181      (SyncPP | Charx8Dot), 0xFF, 3, 0x32 },
182};
183
184static VBIOS_ENHTABLE_STRUCT  Res1600x1200Table[] = {
185    {2160, 1600, 64, 192, 1250, 1200, 1, 3, VCLK162,	/* 60Hz */
186      (SyncPP | Charx8Dot), 60, 1, 0x33 },
187    {2160, 1600, 64, 192, 1250, 1200, 1, 3, VCLK162,	/* end */
188      (SyncPP | Charx8Dot), 0xFF, 1, 0x33 },
189};
190
191/* 16:9 */
192static VBIOS_ENHTABLE_STRUCT  Res1360x768Table[] = {
193    {1792, 1360, 64,112, 795,  768, 3, 6, VCLK85_5,	/* 60Hz */
194      (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x39 },
195    {1792, 1360, 64,112, 795,  768, 3, 6, VCLK85_5,	/* end */
196      (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x39 },
197};
198
199static VBIOS_ENHTABLE_STRUCT  Res1600x900Table[] = {
200    {1760, 1600, 48, 32, 926,  900, 3, 5, VCLK97_75,	/* 60Hz CVT RB */
201      (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 60, 2, 0x3A },
202    {2112, 1600, 88,168, 934,  900, 3, 5, VCLK118_25,	/* 60Hz CVT */
203      (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x3A },
204    {2112, 1600, 88,168, 934,  900, 3, 5, VCLK118_25,	/* end */
205      (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x3A },
206};
207
208static VBIOS_ENHTABLE_STRUCT  Res1920x1080Table[] = {
209    {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5,	/* HDTV 60Hz */
210      (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 60, 1, 0x38 },
211    {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5,	/* end */
212      (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 0xFF, 1, 0x38 },
213};
214
215/* 16:10 */
216static VBIOS_ENHTABLE_STRUCT  Res1280x800Table[] = {
217    {1440, 1280, 48, 32,  823,  800, 3, 6, VCLK71,		/* 60Hz CVT RB */
218      (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 60, 2, 0x35 },
219    {1680, 1280, 72,128,  831,  800, 3, 6, VCLK83_5,	/* 60Hz CVT */
220      (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x35 },
221    {1680, 1280, 72,128,  831,  800, 3, 6, VCLK83_5,	/* end */
222      (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x35 },
223};
224
225static VBIOS_ENHTABLE_STRUCT  Res1440x900Table[] = {
226    {1600, 1440, 48, 32,  926,  900, 3, 6, VCLK88_75,	/* 60Hz CVT RB */
227      (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 60, 2, 0x36 },
228    {1904, 1440, 80,152,  934,  900, 3, 6, VCLK106_5,	/* 60Hz CVT */
229      (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x36 },
230    {1904, 1440, 80,152,  934,  900, 3, 6, VCLK106_5,	/* end */
231      (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x36 },
232};
233
234static VBIOS_ENHTABLE_STRUCT  Res1680x1050Table[] = {
235    {1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119,		/* 60Hz CVT RB */
236      (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 60, 2, 0x37 },
237    {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25,	/* 60Hz CVT */
238      (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x37 },
239    {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25,	/* end */
240      (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x37 },
241};
242
243static VBIOS_ENHTABLE_STRUCT  Res1920x1200Table[] = {
244    {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154,		/* 60Hz CVT RB */
245      (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 60, 1, 0x34 },
246    {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154,		/* end */
247      (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x34 },
248};
249
250static VBIOS_DCLK_INFO DCLKTable [] = {
251    {0x2C, 0xE7, 0x03},					/* 00: VCLK25_175	*/
252    {0x95, 0x62, 0x03},					/* 01: VCLK28_322	*/
253    {0x67, 0x63, 0x01},					/* 02: VCLK31_5     */
254    {0x76, 0x63, 0x01},					/* 03: VCLK36		*/
255    {0xEE, 0x67, 0x01},					/* 04: VCLK40		*/
256    {0x82, 0x62, 0x01},					/* 05: VCLK49_5		*/
257    {0xC6, 0x64, 0x01},					/* 06: VCLK50		*/
258    {0x94, 0x62, 0x01},					/* 07: VCLK56_25	*/
259    {0x80, 0x64, 0x00},					/* 08: VCLK65		*/
260    {0x7B, 0x63, 0x00},					/* 09: VCLK75		*/
261    {0x67, 0x62, 0x00},					/* 0A: VCLK78_75	*/
262    {0x7C, 0x62, 0x00},					/* 0B: VCLK94_5		*/
263    {0x8E, 0x62, 0x00},					/* 0C: VCLK108		*/
264    {0x85, 0x24, 0x00},					/* 0D: VCLK135		*/
265    {0x67, 0x22, 0x00},					/* 0E: VCLK157_5	*/
266    {0x6A, 0x22, 0x00},					/* 0F: VCLK162		*/
267    {0x4d, 0x4c, 0x80},				    /* 10: VCLK154      */
268    {0xa7, 0x78, 0x80},					/* 11: VCLK83.5     */
269    {0x28, 0x49, 0x80},					/* 12: VCLK106.5    */
270    {0x37, 0x49, 0x80},					/* 13: VCLK146.25   */
271    {0x1f, 0x45, 0x80},					/* 14: VCLK148.5    */
272    {0x47, 0x6c, 0x80},					/* 15: VCLK71       */
273    {0x25, 0x65, 0x80},					/* 16: VCLK88.75    */
274    {0x77, 0x58, 0x80},					/* 17: VCLK119      */
275    {0x32, 0x67, 0x80},				    /* 18: VCLK85_5     */
276    {0x6a, 0x6d, 0x80},					/* 19: VCLK97_75	*/
277    {0x3b, 0x2c, 0x81},					/* 1A: VCLK118_25	*/
278};
279
280static VBIOS_DCLK_INFO DCLKTable_AST2100 [] = {
281    {0x2C, 0xE7, 0x03},					/* 00: VCLK25_175	*/
282    {0x95, 0x62, 0x03},					/* 01: VCLK28_322	*/
283    {0x67, 0x63, 0x01},					/* 02: VCLK31_5     */
284    {0x76, 0x63, 0x01},					/* 03: VCLK36		*/
285    {0xEE, 0x67, 0x01},					/* 04: VCLK40		*/
286    {0x82, 0x62, 0x01},					/* 05: VCLK49_5		*/
287    {0xC6, 0x64, 0x01},					/* 06: VCLK50		*/
288    {0x94, 0x62, 0x01},					/* 07: VCLK56_25	*/
289    {0x80, 0x64, 0x00},					/* 08: VCLK65		*/
290    {0x7B, 0x63, 0x00},					/* 09: VCLK75		*/
291    {0x67, 0x62, 0x00},					/* 0A: VCLK78_75	*/
292    {0x7C, 0x62, 0x00},					/* 0B: VCLK94_5		*/
293    {0x8E, 0x62, 0x00},					/* 0C: VCLK108		*/
294    {0x85, 0x24, 0x00},					/* 0D: VCLK135		*/
295    {0x67, 0x22, 0x00},					/* 0E: VCLK157_5	*/
296    {0x6A, 0x22, 0x00},					/* 0F: VCLK162		*/
297    {0x4d, 0x4c, 0x80},				    /* 10: VCLK154      */
298    {0x68, 0x6f, 0x80},					/* 11: VCLK83.5     */
299    {0x28, 0x49, 0x80},					/* 12: VCLK106.5    */
300    {0x37, 0x49, 0x80},					/* 13: VCLK146.25   */
301    {0x1f, 0x45, 0x80},					/* 14: VCLK148.5    */
302    {0x47, 0x6c, 0x80},					/* 15: VCLK71       */
303    {0x25, 0x65, 0x80},					/* 16: VCLK88.75    */
304    {0x77, 0x58, 0x80},					/* 17: VCLK119      */
305    {0x32, 0x67, 0x80},				    /* 18: VCLK85_5     */
306    {0x6a, 0x6d, 0x80},					/* 19: VCLK97_75	*/
307    {0x3b, 0x2c, 0x81},					/* 1A: VCLK118_25	*/
308};
309
310static VBIOS_DCLK_INFO DCLKTable_AST2500 [] = {
311    {0x40, 0x38, 0x73},					/* 00: VCLK25_175	*/
312    {0x3A, 0x38, 0x43},					/* 01: VCLK28_322	*/
313    {0x3E, 0x70, 0x73},					/* 02: VCLK31_5         */
314    {0x35, 0x70, 0x43},					/* 03: VCLK36		*/
315    {0x31, 0x28, 0x73},					/* 04: VCLK40		*/
316    {0x41, 0x68, 0x73},					/* 05: VCLK49_5		*/
317    {0x31, 0x68, 0x53},					/* 06: VCLK50		*/
318    {0x4A, 0x68, 0x73},					/* 07: VCLK56_25	*/
319    {0x40, 0x68, 0x53},					/* 08: VCLK65		*/
320    {0x31, 0x60, 0x73},					/* 09: VCLK75		*/
321    {0x3A, 0x28, 0x43},					/* 0A: VCLK78_75	*/
322    {0x3E, 0x60, 0x73},					/* 0B: VCLK94_5		*/
323    {0x35, 0x60, 0x63},					/* 0C: VCLK108		*/
324    {0x3D, 0x40, 0x63},					/* 0D: VCLK135		*/
325    {0x4E, 0x60, 0x63},					/* 0E: VCLK157_5	*/
326    {0x35, 0x60, 0x53},					/* 0F: VCLK162		*/
327    {0x4C, 0x60, 0x63},				    /* 10: VCLK154      	*/
328    {0x4F, 0x48, 0x53},					/* 11: VCLK83.5         */
329    {0x46, 0x60, 0x73},					/* 12: VCLK106.5        */
330    {0x3C, 0x20, 0x63},					/* 13: VCLK146.25       */
331    {0x3D, 0x20, 0x63},					/* 14: VCLK148.5        */
332    {0x46, 0x68, 0x53},					/* 15: VCLK71           */
333    {0x49, 0x68, 0x43},					/* 16: VCLK88.75        */
334    {0x4e, 0x60, 0x73},					/* 17: VCLK119          */
335    {0x38, 0x60, 0x73},				    /* 18: VCLK85_5         */
336    {0x38, 0x20, 0x73},					/* 19: VCLK97_75 */
337    {0x4e, 0x60, 0x73},					/* 1A: VCLK118_25 */
338};
339
340static VBIOS_DCLK_INFO DCLKTable_AST2500A1 [] = {
341    {0x2C, 0xE7, 0x03},					/* 00: VCLK25_175	*/
342    {0x95, 0x62, 0x03},					/* 01: VCLK28_322	*/
343    {0x67, 0x63, 0x01},					/* 02: VCLK31_5         */
344    {0x76, 0x63, 0x01},					/* 03: VCLK36		*/
345    {0xEE, 0x67, 0x01},					/* 04: VCLK40		*/
346    {0x82, 0x62, 0x01},					/* 05: VCLK49_5		*/
347    {0xC6, 0x64, 0x01},					/* 06: VCLK50		*/
348    {0x94, 0x62, 0x01},					/* 07: VCLK56_25	*/
349    {0x80, 0x64, 0x00},					/* 08: VCLK65		*/
350    {0x7B, 0x63, 0x00},					/* 09: VCLK75		*/
351    {0x67, 0x62, 0x00},					/* 0A: VCLK78_75	*/
352    {0x7C, 0x62, 0x00},					/* 0B: VCLK94_5		*/
353    {0x8E, 0x62, 0x00},					/* 0C: VCLK108		*/
354    {0x85, 0x24, 0x00},					/* 0D: VCLK135		*/
355    {0x67, 0x22, 0x00},					/* 0E: VCLK157_5	*/
356    {0x6A, 0x22, 0x00},					/* 0F: VCLK162		*/
357    {0x4d, 0x4c, 0x80},				        /* 10: VCLK154      	*/
358    {0x68, 0x6f, 0x80},					/* 11: VCLK83.5         */
359    {0x28, 0x49, 0x80},					/* 12: VCLK106.5        */
360    {0x37, 0x49, 0x80},					/* 13: VCLK146.25       */
361    {0x1f, 0x45, 0x80},					/* 14: VCLK148.5        */
362    {0x47, 0x6c, 0x80},					/* 15: VCLK71           */
363    {0x25, 0x65, 0x80},					/* 16: VCLK88.75        */
364    {0x58, 0x01, 0x42},					/* 17: VCLK119          */
365    {0x32, 0x67, 0x80},				        /* 18: VCLK85_5         */
366    {0x6a, 0x6d, 0x80},					/* 19: VCLK97_75 */
367    {0x44, 0x20, 0x43},					/* 1A: VCLK118_25 */
368};
369
370#if 0
371static VBIOS_DAC_INFO DAC_TEXT[] = {
372 { 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x2a },  { 0x00, 0x2a, 0x00 },  { 0x00, 0x2a, 0x2a },
373 { 0x2a, 0x00, 0x00 },  { 0x2a, 0x00, 0x2a },  { 0x2a, 0x2a, 0x00 },  { 0x2a, 0x2a, 0x2a },
374 { 0x00, 0x00, 0x15 },  { 0x00, 0x00, 0x3f },  { 0x00, 0x2a, 0x15 },  { 0x00, 0x2a, 0x3f },
375 { 0x2a, 0x00, 0x15 },  { 0x2a, 0x00, 0x3f },  { 0x2a, 0x2a, 0x15 },  { 0x2a, 0x2a, 0x3f },
376 { 0x00, 0x15, 0x00 },  { 0x00, 0x15, 0x2a },  { 0x00, 0x3f, 0x00 },  { 0x00, 0x3f, 0x2a },
377 { 0x2a, 0x15, 0x00 },  { 0x2a, 0x15, 0x2a },  { 0x2a, 0x3f, 0x00 },  { 0x2a, 0x3f, 0x2a },
378 { 0x00, 0x15, 0x15 },  { 0x00, 0x15, 0x3f },  { 0x00, 0x3f, 0x15 },  { 0x00, 0x3f, 0x3f },
379 { 0x2a, 0x15, 0x15 },  { 0x2a, 0x15, 0x3f },  { 0x2a, 0x3f, 0x15 },  { 0x2a, 0x3f, 0x3f },
380 { 0x15, 0x00, 0x00 },  { 0x15, 0x00, 0x2a },  { 0x15, 0x2a, 0x00 },  { 0x15, 0x2a, 0x2a },
381 { 0x3f, 0x00, 0x00 },  { 0x3f, 0x00, 0x2a },  { 0x3f, 0x2a, 0x00 },  { 0x3f, 0x2a, 0x2a },
382 { 0x15, 0x00, 0x15 },  { 0x15, 0x00, 0x3f },  { 0x15, 0x2a, 0x15 },  { 0x15, 0x2a, 0x3f },
383 { 0x3f, 0x00, 0x15 },  { 0x3f, 0x00, 0x3f },  { 0x3f, 0x2a, 0x15 },  { 0x3f, 0x2a, 0x3f },
384 { 0x15, 0x15, 0x00 },  { 0x15, 0x15, 0x2a },  { 0x15, 0x3f, 0x00 },  { 0x15, 0x3f, 0x2a },
385 { 0x3f, 0x15, 0x00 },  { 0x3f, 0x15, 0x2a },  { 0x3f, 0x3f, 0x00 },  { 0x3f, 0x3f, 0x2a },
386 { 0x15, 0x15, 0x15 },  { 0x15, 0x15, 0x3f },  { 0x15, 0x3f, 0x15 },  { 0x15, 0x3f, 0x3f },
387 { 0x3f, 0x15, 0x15 },  { 0x3f, 0x15, 0x3f },  { 0x3f, 0x3f, 0x15 },  { 0x3f, 0x3f, 0x3f },
388};
389
390static VBIOS_DAC_INFO DAC_EGA[] = {
391 { 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x2a },  { 0x00, 0x2a, 0x00 },  { 0x00, 0x2a, 0x2a },
392 { 0x2a, 0x00, 0x00 },  { 0x2a, 0x00, 0x2a },  { 0x2a, 0x2a, 0x00 },  { 0x2a, 0x2a, 0x2a },
393 { 0x00, 0x00, 0x15 },  { 0x00, 0x00, 0x3f },  { 0x00, 0x2a, 0x15 },  { 0x00, 0x2a, 0x3f },
394 { 0x2a, 0x00, 0x15 },  { 0x2a, 0x00, 0x3f },  { 0x2a, 0x2a, 0x15 },  { 0x2a, 0x2a, 0x3f },
395 { 0x00, 0x15, 0x00 },  { 0x00, 0x15, 0x2a },  { 0x00, 0x3f, 0x00 },  { 0x00, 0x3f, 0x2a },
396 { 0x2a, 0x15, 0x00 },  { 0x2a, 0x15, 0x2a },  { 0x2a, 0x3f, 0x00 },  { 0x2a, 0x3f, 0x2a },
397 { 0x00, 0x15, 0x15 },  { 0x00, 0x15, 0x3f },  { 0x00, 0x3f, 0x15 },  { 0x00, 0x3f, 0x3f },
398 { 0x2a, 0x15, 0x15 },  { 0x2a, 0x15, 0x3f },  { 0x2a, 0x3f, 0x15 },  { 0x2a, 0x3f, 0x3f },
399 { 0x15, 0x00, 0x00 },  { 0x15, 0x00, 0x2a },  { 0x15, 0x2a, 0x00 },  { 0x15, 0x2a, 0x2a },
400 { 0x3f, 0x00, 0x00 },  { 0x3f, 0x00, 0x2a },  { 0x3f, 0x2a, 0x00 },  { 0x3f, 0x2a, 0x2a },
401 { 0x15, 0x00, 0x15 },  { 0x15, 0x00, 0x3f },  { 0x15, 0x2a, 0x15 },  { 0x15, 0x2a, 0x3f },
402 { 0x3f, 0x00, 0x15 },  { 0x3f, 0x00, 0x3f },  { 0x3f, 0x2a, 0x15 },  { 0x3f, 0x2a, 0x3f },
403 { 0x15, 0x15, 0x00 },  { 0x15, 0x15, 0x2a },  { 0x15, 0x3f, 0x00 },  { 0x15, 0x3f, 0x2a },
404 { 0x3f, 0x15, 0x00 },  { 0x3f, 0x15, 0x2a },  { 0x3f, 0x3f, 0x00 },  { 0x3f, 0x3f, 0x2a },
405 { 0x15, 0x15, 0x15 },  { 0x15, 0x15, 0x3f },  { 0x15, 0x3f, 0x15 },  { 0x15, 0x3f, 0x3f },
406 { 0x3f, 0x15, 0x15 },  { 0x3f, 0x15, 0x3f },  { 0x3f, 0x3f, 0x15 },  { 0x3f, 0x3f, 0x3f },
407};
408#endif
409
410static VBIOS_DAC_INFO DAC_VGA[] = {
411 { 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x2a },  { 0x00, 0x2a, 0x00 },  { 0x00, 0x2a, 0x2a },
412 { 0x2a, 0x00, 0x00 },  { 0x2a, 0x00, 0x2a },  { 0x2a, 0x15, 0x00 },  { 0x2a, 0x2a, 0x2a },
413 { 0x15, 0x15, 0x15 },  { 0x15, 0x15, 0x3f },  { 0x15, 0x3f, 0x15 },  { 0x15, 0x3f, 0x3f },
414 { 0x3f, 0x15, 0x15 },  { 0x3f, 0x15, 0x3f },  { 0x3f, 0x3f, 0x15 },  { 0x3f, 0x3f, 0x3f },
415 { 0x00, 0x00, 0x00 },  { 0x05, 0x05, 0x05 },  { 0x08, 0x08, 0x08 },  { 0x0b, 0x0b, 0x0b },
416 { 0x0e, 0x0e, 0x0e },  { 0x11, 0x11, 0x11 },  { 0x14, 0x14, 0x14 },  { 0x18, 0x18, 0x18 },
417 { 0x1c, 0x1c, 0x1c },  { 0x20, 0x20, 0x20 },  { 0x24, 0x24, 0x24 },  { 0x28, 0x28, 0x28 },
418 { 0x2d, 0x2d, 0x2d },  { 0x32, 0x32, 0x32 },  { 0x38, 0x38, 0x38 },  { 0x3f, 0x3f, 0x3f },
419 { 0x00, 0x00, 0x3f },  { 0x10, 0x00, 0x3f },  { 0x1f, 0x00, 0x3f },  { 0x2f, 0x00, 0x3f },
420 { 0x3f, 0x00, 0x3f },  { 0x3f, 0x00, 0x2f },  { 0x3f, 0x00, 0x1f },  { 0x3f, 0x00, 0x10 },
421 { 0x3f, 0x00, 0x00 },  { 0x3f, 0x10, 0x00 },  { 0x3f, 0x1f, 0x00 },  { 0x3f, 0x2f, 0x00 },
422 { 0x3f, 0x3f, 0x00 },  { 0x2f, 0x3f, 0x00 },  { 0x1f, 0x3f, 0x00 },  { 0x10, 0x3f, 0x00 },
423 { 0x00, 0x3f, 0x00 },  { 0x00, 0x3f, 0x10 },  { 0x00, 0x3f, 0x1f },  { 0x00, 0x3f, 0x2f },
424 { 0x00, 0x3f, 0x3f },  { 0x00, 0x2f, 0x3f },  { 0x00, 0x1f, 0x3f },  { 0x00, 0x10, 0x3f },
425 { 0x1f, 0x1f, 0x3f },  { 0x27, 0x1f, 0x3f },  { 0x2f, 0x1f, 0x3f },  { 0x37, 0x1f, 0x3f },
426 { 0x3f, 0x1f, 0x3f },  { 0x3f, 0x1f, 0x37 },  { 0x3f, 0x1f, 0x2f },  { 0x3f, 0x1f, 0x27 },
427 { 0x3f, 0x1f, 0x1f },  { 0x3f, 0x27, 0x1f },  { 0x3f, 0x2f, 0x1f },  { 0x3f, 0x37, 0x1f },
428 { 0x3f, 0x3f, 0x1f },  { 0x37, 0x3f, 0x1f },  { 0x2f, 0x3f, 0x1f },  { 0x27, 0x3f, 0x1f },
429 { 0x1f, 0x3f, 0x1f },  { 0x1f, 0x3f, 0x27 },  { 0x1f, 0x3f, 0x2f },  { 0x1f, 0x3f, 0x37 },
430 { 0x1f, 0x3f, 0x3f },  { 0x1f, 0x37, 0x3f },  { 0x1f, 0x2f, 0x3f },  { 0x1f, 0x27, 0x3f },
431 { 0x2d, 0x2d, 0x3f },  { 0x31, 0x2d, 0x3f },  { 0x36, 0x2d, 0x3f },  { 0x3a, 0x2d, 0x3f },
432 { 0x3f, 0x2d, 0x3f },  { 0x3f, 0x2d, 0x3a },  { 0x3f, 0x2d, 0x36 },  { 0x3f, 0x2d, 0x31 },
433 { 0x3f, 0x2d, 0x2d },  { 0x3f, 0x31, 0x2d },  { 0x3f, 0x36, 0x2d },  { 0x3f, 0x3a, 0x2d },
434 { 0x3f, 0x3f, 0x2d },  { 0x3a, 0x3f, 0x2d },  { 0x36, 0x3f, 0x2d },  { 0x31, 0x3f, 0x2d },
435 { 0x2d, 0x3f, 0x2d },  { 0x2d, 0x3f, 0x31 },  { 0x2d, 0x3f, 0x36 },  { 0x2d, 0x3f, 0x3a },
436 { 0x2d, 0x3f, 0x3f },  { 0x2d, 0x3a, 0x3f },  { 0x2d, 0x36, 0x3f },  { 0x2d, 0x31, 0x3f },
437 { 0x00, 0x00, 0x1c },  { 0x07, 0x00, 0x1c },  { 0x0e, 0x00, 0x1c },  { 0x15, 0x00, 0x1c },
438 { 0x1c, 0x00, 0x1c },  { 0x1c, 0x00, 0x15 },  { 0x1c, 0x00, 0x0e },  { 0x1c, 0x00, 0x07 },
439 { 0x1c, 0x00, 0x00 },  { 0x1c, 0x07, 0x00 },  { 0x1c, 0x0e, 0x00 },  { 0x1c, 0x15, 0x00 },
440 { 0x1c, 0x1c, 0x00 },  { 0x15, 0x1c, 0x00 },  { 0x0e, 0x1c, 0x00 },  { 0x07, 0x1c, 0x00 },
441 { 0x00, 0x1c, 0x00 },  { 0x00, 0x1c, 0x07 },  { 0x00, 0x1c, 0x0e },  { 0x00, 0x1c, 0x15 },
442 { 0x00, 0x1c, 0x1c },  { 0x00, 0x15, 0x1c },  { 0x00, 0x0e, 0x1c },  { 0x00, 0x07, 0x1c },
443 { 0x0e, 0x0e, 0x1c },  { 0x11, 0x0e, 0x1c },  { 0x15, 0x0e, 0x1c },  { 0x18, 0x0e, 0x1c },
444 { 0x1c, 0x0e, 0x1c },  { 0x1c, 0x0e, 0x18 },  { 0x1c, 0x0e, 0x15 },  { 0x1c, 0x0e, 0x11 },
445 { 0x1c, 0x0e, 0x0e },  { 0x1c, 0x11, 0x0e },  { 0x1c, 0x15, 0x0e },  { 0x1c, 0x18, 0x0e },
446 { 0x1c, 0x1c, 0x0e },  { 0x18, 0x1c, 0x0e },  { 0x15, 0x1c, 0x0e },  { 0x11, 0x1c, 0x0e },
447 { 0x0e, 0x1c, 0x0e },  { 0x0e, 0x1c, 0x11 },  { 0x0e, 0x1c, 0x15 },  { 0x0e, 0x1c, 0x18 },
448 { 0x0e, 0x1c, 0x1c },  { 0x0e, 0x18, 0x1c },  { 0x0e, 0x15, 0x1c },  { 0x0e, 0x11, 0x1c },
449 { 0x14, 0x14, 0x1c },  { 0x16, 0x14, 0x1c },  { 0x18, 0x14, 0x1c },  { 0x1a, 0x14, 0x1c },
450 { 0x1c, 0x14, 0x1c },  { 0x1c, 0x14, 0x1a },  { 0x1c, 0x14, 0x18 },  { 0x1c, 0x14, 0x16 },
451 { 0x1c, 0x14, 0x14 },  { 0x1c, 0x16, 0x14 },  { 0x1c, 0x18, 0x14 },  { 0x1c, 0x1a, 0x14 },
452 { 0x1c, 0x1c, 0x14 },  { 0x1a, 0x1c, 0x14 },  { 0x18, 0x1c, 0x14 },  { 0x16, 0x1c, 0x14 },
453 { 0x14, 0x1c, 0x14 },  { 0x14, 0x1c, 0x16 },  { 0x14, 0x1c, 0x18 },  { 0x14, 0x1c, 0x1a },
454 { 0x14, 0x1c, 0x1c },  { 0x14, 0x1a, 0x1c },  { 0x14, 0x18, 0x1c },  { 0x14, 0x16, 0x1c },
455 { 0x00, 0x00, 0x10 },  { 0x04, 0x00, 0x10 },  { 0x08, 0x00, 0x10 },  { 0x0c, 0x00, 0x10 },
456 { 0x10, 0x00, 0x10 },  { 0x10, 0x00, 0x0c },  { 0x10, 0x00, 0x08 },  { 0x10, 0x00, 0x04 },
457 { 0x10, 0x00, 0x00 },  { 0x10, 0x04, 0x00 },  { 0x10, 0x08, 0x00 },  { 0x10, 0x0c, 0x00 },
458 { 0x10, 0x10, 0x00 },  { 0x0c, 0x10, 0x00 },  { 0x08, 0x10, 0x00 },  { 0x04, 0x10, 0x00 },
459 { 0x00, 0x10, 0x00 },  { 0x00, 0x10, 0x04 },  { 0x00, 0x10, 0x08 },  { 0x00, 0x10, 0x0c },
460 { 0x00, 0x10, 0x10 },  { 0x00, 0x0c, 0x10 },  { 0x00, 0x08, 0x10 },  { 0x00, 0x04, 0x10 },
461 { 0x08, 0x08, 0x10 },  { 0x0a, 0x08, 0x10 },  { 0x0c, 0x08, 0x10 },  { 0x0e, 0x08, 0x10 },
462 { 0x10, 0x08, 0x10 },  { 0x10, 0x08, 0x0e },  { 0x10, 0x08, 0x0c },  { 0x10, 0x08, 0x0a },
463 { 0x10, 0x08, 0x08 },  { 0x10, 0x0a, 0x08 },  { 0x10, 0x0c, 0x08 },  { 0x10, 0x0e, 0x08 },
464 { 0x10, 0x10, 0x08 },  { 0x0e, 0x10, 0x08 },  { 0x0c, 0x10, 0x08 },  { 0x0a, 0x10, 0x08 },
465 { 0x08, 0x10, 0x08 },  { 0x08, 0x10, 0x0a },  { 0x08, 0x10, 0x0c },  { 0x08, 0x10, 0x0e },
466 { 0x08, 0x10, 0x10 },  { 0x08, 0x0e, 0x10 },  { 0x08, 0x0c, 0x10 },  { 0x08, 0x0a, 0x10 },
467 { 0x0b, 0x0b, 0x10 },  { 0x0c, 0x0b, 0x10 },  { 0x0d, 0x0b, 0x10 },  { 0x0f, 0x0b, 0x10 },
468 { 0x10, 0x0b, 0x10 },  { 0x10, 0x0b, 0x0f },  { 0x10, 0x0b, 0x0d },  { 0x10, 0x0b, 0x0c },
469 { 0x10, 0x0b, 0x0b },  { 0x10, 0x0c, 0x0b },  { 0x10, 0x0d, 0x0b },  { 0x10, 0x0f, 0x0b },
470 { 0x10, 0x10, 0x0b },  { 0x0f, 0x10, 0x0b },  { 0x0d, 0x10, 0x0b },  { 0x0c, 0x10, 0x0b },
471 { 0x0b, 0x10, 0x0b },  { 0x0b, 0x10, 0x0c },  { 0x0b, 0x10, 0x0d },  { 0x0b, 0x10, 0x0f },
472 { 0x0b, 0x10, 0x10 },  { 0x0b, 0x0f, 0x10 },  { 0x0b, 0x0d, 0x10 },  { 0x0b, 0x0c, 0x10 },
473 { 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x00 },
474 { 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x00 },
475};
476
477/* Prototype type declaration*/
478static Bool bGetAST1000VGAModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
479static void vSetStdReg(ScrnInfoPtr pScrn,  DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
480static void vSetCRTCReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
481static void vSetOffsetReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
482static void vSetDCLKReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
483static void vSetExtReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
484static void vSetSyncReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
485static Bool bSetDACReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
486static BOOL bSetAST1180CRTCReg(ScrnInfoPtr pScrn,  DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
487static BOOL bSetAST1180OffsetReg(ScrnInfoPtr pScrn,  DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
488static BOOL bSetAST1180DCLKReg(ScrnInfoPtr pScrn,  DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
489static BOOL bSetAST1180ExtReg(ScrnInfoPtr pScrn,  DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
490static void vInitChrontelReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo);
491
492Bool
493ASTSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
494{
495    ASTRecPtr pAST;
496    VBIOS_MODE_INFO vgamodeinfo;
497
498    pAST = ASTPTR(pScrn);
499
500    /* pre set mode */
501    bGetAST1000VGAModeInfo(pScrn, mode, &vgamodeinfo);
502
503    /* set mode */
504    if (pAST->jChipType == AST1180)
505    {
506        bASTInitAST1180(pScrn);
507
508        bSetAST1180CRTCReg(pScrn, mode, &vgamodeinfo);
509        bSetAST1180OffsetReg(pScrn, mode, &vgamodeinfo);
510        bSetAST1180DCLKReg(pScrn, mode, &vgamodeinfo);
511        bSetAST1180ExtReg(pScrn, mode, &vgamodeinfo);
512
513        vInitChrontelReg(pScrn, mode, &vgamodeinfo);
514    }
515    else
516    {
517        vASTOpenKey(pScrn);
518        bASTRegInit(pScrn);
519
520        vAST1000DisplayOff(pScrn);
521
522        vSetStdReg(pScrn, mode, &vgamodeinfo);
523        vSetCRTCReg(pScrn, mode, &vgamodeinfo);
524        vSetOffsetReg(pScrn, mode, &vgamodeinfo);
525        vSetDCLKReg(pScrn, mode, &vgamodeinfo);
526        vSetExtReg(pScrn, mode, &vgamodeinfo);
527        vSetSyncReg(pScrn, mode, &vgamodeinfo);
528        bSetDACReg(pScrn, mode, &vgamodeinfo);
529
530        /* clear video buffer to avoid display noise */
531        memset(pAST->FBVirtualAddr, 0x00, pAST->VideoModeInfo.ScreenPitch*pAST->VideoModeInfo.ScreenHeight);
532
533        vAST1000DisplayOn(pScrn);
534    }
535
536    /* post set mode */
537#ifdef	Accel_2D
538   if (!pAST->noAccel) {
539       if (!bASTEnable2D(pScrn, pAST)) {
540           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Enable 2D failed\n");
541           pAST->noAccel = TRUE;
542       }
543   }
544#endif
545#ifdef	HWC
546   if (!pAST->noHWC) {
547       if (!bASTInitHWC(pScrn, pAST)) {
548           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Init HWC failed\n");
549           pAST->noHWC = TRUE;
550       }
551   }
552#endif
553
554    return (TRUE);
555}
556
557
558static Bool bGetAST1000VGAModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
559{
560    ASTRecPtr pAST;
561    ULONG ulModeID, ulColorIndex, ulRefreshRate, ulRefreshRateIndex = 0;
562    ULONG ulHBorder, ulVBorder;
563    Bool check_sync;
564    PVBIOS_ENHTABLE_STRUCT loop, best = NULL;
565
566    pAST = ASTPTR(pScrn);
567
568    switch (pScrn->bitsPerPixel)
569    {
570    case 8:
571         pVGAModeInfo->pStdTableEntry = (PVBIOS_STDTABLE_STRUCT) &StdTable[VGAModeIndex];
572	 ulColorIndex = VGAModeIndex-1;
573         break;
574    case 16:
575         pVGAModeInfo->pStdTableEntry = (PVBIOS_STDTABLE_STRUCT) &StdTable[HiCModeIndex];
576	 ulColorIndex = HiCModeIndex;
577         break;
578    case 24:
579    case 32:
580         pVGAModeInfo->pStdTableEntry = (PVBIOS_STDTABLE_STRUCT) &StdTable[TrueCModeIndex];
581	 ulColorIndex = TrueCModeIndex;
582	 break;
583    default:
584         return (FALSE);
585    }
586
587    switch (mode->CrtcHDisplay)
588    {
589    case 640:
590	 pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res640x480Table[ulRefreshRateIndex];
591	 break;
592    case 800:
593	 pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res800x600Table[ulRefreshRateIndex];
594	 break;
595    case 1024:
596	 pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res1024x768Table[ulRefreshRateIndex];
597	 break;
598    case 1280:
599         if (mode->CrtcVDisplay == 800)
600             pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res1280x800Table[ulRefreshRateIndex];
601         else
602             pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res1280x1024Table[ulRefreshRateIndex];
603	 break;
604    case 1360:
605         pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res1360x768Table[ulRefreshRateIndex];
606         break;
607    case 1440:
608         pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res1440x900Table[ulRefreshRateIndex];
609         break;
610    case 1600:
611         if (mode->CrtcVDisplay == 900)
612	     pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res1600x900Table[ulRefreshRateIndex];
613         else
614	     pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res1600x1200Table[ulRefreshRateIndex];
615	 break;
616    case 1680:
617         pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res1680x1050Table[ulRefreshRateIndex];
618         break;
619    case 1920:
620         if (mode->CrtcVDisplay == 1080)
621             pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res1920x1080Table[ulRefreshRateIndex];
622         else
623             pVGAModeInfo->pEnhTableEntry = (PVBIOS_ENHTABLE_STRUCT) &Res1920x1200Table[ulRefreshRateIndex];
624         break;
625    default:
626	 return (FALSE);
627    }
628
629    /* Get Proper Mode Index */
630    ulRefreshRate = (mode->Clock * 1000) / (mode->HTotal * mode->VTotal) + 1;
631    loop = pVGAModeInfo->pEnhTableEntry;
632    check_sync = loop->Flags & WideScreenMode;
633    do {
634	while (loop->ulRefreshRate != 0xff) {
635		if ((check_sync) &&
636		    (((mode->Flags & V_NVSYNC)  &&
637		      (loop->Flags & PVSync))  ||
638		     ((mode->Flags & V_PVSYNC)  &&
639		      (loop->Flags & NVSync))  ||
640		     ((mode->Flags & V_NHSYNC)  &&
641		      (loop->Flags & PHSync))  ||
642		     ((mode->Flags & V_PHSYNC)  &&
643		      (loop->Flags & NHSync)))) {
644			loop++;
645			continue;
646		}
647	if (loop->ulRefreshRate <= ulRefreshRate
648		    && (!best || loop->ulRefreshRate > best->ulRefreshRate))
649			best = loop;
650			loop++;
651	}
652	if (best || !check_sync)
653		break;
654	check_sync = 0;
655    } while (1);
656    if (best)
657	pVGAModeInfo->pEnhTableEntry = best;
658
659    /* Update mode CRTC info */
660    ulHBorder = (pVGAModeInfo->pEnhTableEntry->Flags & HBorder) ? 8:0;
661    ulVBorder = (pVGAModeInfo->pEnhTableEntry->Flags & VBorder) ? 8:0;
662
663    mode->CrtcHTotal      = (int) pVGAModeInfo->pEnhTableEntry->HT;
664    mode->CrtcHBlankStart = (int) (pVGAModeInfo->pEnhTableEntry->HDE + ulHBorder);
665    mode->CrtcHBlankEnd   = (int) (pVGAModeInfo->pEnhTableEntry->HT - ulHBorder);
666    mode->CrtcHSyncStart  = (int) (pVGAModeInfo->pEnhTableEntry->HDE + ulHBorder
667                                   + pVGAModeInfo->pEnhTableEntry->HFP);
668    mode->CrtcHSyncEnd    = (int) (pVGAModeInfo->pEnhTableEntry->HDE + ulHBorder
669                                   + pVGAModeInfo->pEnhTableEntry->HFP
670                                   + pVGAModeInfo->pEnhTableEntry->HSYNC);
671
672    mode->CrtcVTotal      = (int) pVGAModeInfo->pEnhTableEntry->VT;
673    mode->CrtcVBlankStart = (int) (pVGAModeInfo->pEnhTableEntry->VDE + ulVBorder);
674    mode->CrtcVBlankEnd   = (int) (pVGAModeInfo->pEnhTableEntry->VT - ulVBorder);
675    mode->CrtcVSyncStart  = (int) (pVGAModeInfo->pEnhTableEntry->VDE + ulVBorder
676                                   + pVGAModeInfo->pEnhTableEntry->VFP);
677    mode->CrtcVSyncEnd    = (int) (pVGAModeInfo->pEnhTableEntry->VDE + ulVBorder
678                                   + pVGAModeInfo->pEnhTableEntry->VFP
679                                   + pVGAModeInfo->pEnhTableEntry->VSYNC);
680
681    /* Write mode info to scratch */
682    ulRefreshRateIndex = pVGAModeInfo->pEnhTableEntry->ulRefreshRateIndex;
683    ulModeID = pVGAModeInfo->pEnhTableEntry->ulModeID;
684
685    if (pAST->jChipType == AST1180)
686    {
687        /* TODO */
688    }
689    else
690    {
691        SetIndexReg(CRTC_PORT, 0x8C, (UCHAR) ((ulColorIndex & 0x0F) << 4));
692        SetIndexReg(CRTC_PORT, 0x8D, (UCHAR) (ulRefreshRateIndex & 0xFF));
693        SetIndexReg(CRTC_PORT, 0x8E, (UCHAR) (ulModeID & 0xFF));
694
695        /* NewModeInfo */
696        SetIndexReg(CRTC_PORT, 0x91, 0x00);	/* clear signature */
697        if (pVGAModeInfo->pEnhTableEntry->Flags & NewModeInfo)
698        {
699            SetIndexReg(CRTC_PORT, 0x91, 0xA8);	/* signature */
700            SetIndexReg(CRTC_PORT, 0x92, (UCHAR) (pScrn->bitsPerPixel) );
701            SetIndexReg(CRTC_PORT, 0x93, (UCHAR) (mode->Clock / 1000) );
702            SetIndexReg(CRTC_PORT, 0x94, (UCHAR) (mode->CrtcHDisplay) );
703            SetIndexReg(CRTC_PORT, 0x95, (UCHAR) (mode->CrtcHDisplay >> 8) );	/* color depth */
704            SetIndexReg(CRTC_PORT, 0x96, (UCHAR) (mode->CrtcVDisplay) );
705            SetIndexReg(CRTC_PORT, 0x97, (UCHAR) (mode->CrtcVDisplay >> 8) );	/* color depth */
706        }
707    }
708
709    return (TRUE);
710}
711
712static void vSetStdReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
713{
714
715    PVBIOS_STDTABLE_STRUCT pStdModePtr;
716    ASTRecPtr pAST;
717    ULONG i;
718    UCHAR jReg;
719
720    pStdModePtr = pVGAModeInfo->pStdTableEntry;
721    pAST = ASTPTR(pScrn);
722
723    /* Set Misc */
724    jReg = pStdModePtr->MISC;
725    SetReg(MISC_PORT_WRITE,jReg);
726
727    /* Set Seq */
728    SetIndexReg(SEQ_PORT,0x00, 0x03);
729    for (i=0; i<4; i++)
730    {
731        jReg = pStdModePtr->SEQ[i];
732    	if (!i) (jReg |= 0x20);			/* display off */
733        SetIndexReg(SEQ_PORT,(UCHAR) (i+1), jReg);
734    }
735
736    /* Set CRTC */
737    SetIndexRegMask(CRTC_PORT,0x11, 0x7F, 0x00);
738    for (i=0; i<25; i++)
739    {
740        jReg = pStdModePtr->CRTC[i];
741        SetIndexReg(CRTC_PORT,(UCHAR) i, jReg);
742    }
743
744    /* Set AR */
745    jReg = GetReg(INPUT_STATUS1_READ);
746    for (i=0; i<20; i++)
747    {
748        jReg = pStdModePtr->AR[i];
749        SetReg(AR_PORT_WRITE, (UCHAR) i);
750        SetReg(AR_PORT_WRITE, jReg);
751    }
752    SetReg(AR_PORT_WRITE, 0x14);
753    SetReg(AR_PORT_WRITE, 0x00);
754
755    jReg = GetReg(INPUT_STATUS1_READ);
756    SetReg (AR_PORT_WRITE, 0x20);		/* set POS */
757
758    /* Set GR */
759    for (i=0; i<9; i++)
760    {
761        jReg = pStdModePtr->GR[i];
762        SetIndexReg(GR_PORT,(UCHAR) i, jReg);
763
764    }
765
766
767}
768
769static void
770vSetCRTCReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
771{
772    ASTRecPtr pAST;
773    USHORT usTemp, ulPreCache = 0;
774    UCHAR jReg05, jReg07, jReg09, jRegAC, jRegAD, jRegAE;
775
776    pAST = ASTPTR(pScrn);
777    jReg05 = jReg07 = jReg09 = jRegAC = jRegAD = jRegAE = 0;
778
779    /* init value */
780    if ((pAST->jChipType == AST2500) && (pVGAModeInfo->pEnhTableEntry->Flags & AST2500PreCatchCRT))
781    	ulPreCache = 40;
782
783    /* unlock CRTC */
784    SetIndexRegMask(CRTC_PORT,0x11, 0x7F, 0x00);
785
786    /* Horizontal Timing Programming */
787    usTemp = (mode->CrtcHTotal >> 3) - 5;
788    if (usTemp & 0x100) jRegAC |= 0x01;			/* HT D[8] */
789    SetIndexRegMask(CRTC_PORT,0x00, 0x00, (UCHAR) usTemp);
790    usTemp = (mode->CrtcHDisplay >> 3) - 1;
791    if (usTemp & 0x100) jRegAC |= 0x04;			/* HDE D[8] */
792    SetIndexRegMask(CRTC_PORT,0x01, 0x00, (UCHAR) usTemp);
793    usTemp = (mode->CrtcHBlankStart >> 3) - 1;
794    if (usTemp & 0x100) jRegAC |= 0x10;			/* HBS D[8] */
795    SetIndexRegMask(CRTC_PORT,0x02, 0x00, (UCHAR) usTemp);
796    usTemp = ((mode->CrtcHBlankEnd >> 3) - 1) & 0x7F;
797    if (usTemp & 0x20) jReg05 |= 0x80;			/* HBE D[5] */
798    if (usTemp & 0x40) jRegAD |= 0x01;			/* HBE D[6] */
799    SetIndexRegMask(CRTC_PORT,0x03, 0xE0, (UCHAR) (usTemp & 0x1F));
800    usTemp = ((mode->CrtcHSyncStart - ulPreCache) >> 3 ) - 1;
801    if (usTemp & 0x100) jRegAC |= 0x40;			/* HRS D[5] */
802    SetIndexRegMask(CRTC_PORT,0x04, 0x00, (UCHAR) (usTemp));
803    usTemp = (((mode->CrtcHSyncEnd - ulPreCache) >> 3 ) - 1) & 0x3F;
804    if (usTemp & 0x20) jRegAD |= 0x04;			/* HRE D[5] */
805    SetIndexRegMask(CRTC_PORT,0x05, 0x60, (UCHAR) ((usTemp & 0x1F) | jReg05));
806
807    SetIndexRegMask(CRTC_PORT,0xAC, 0x00, (UCHAR) jRegAC);
808    SetIndexRegMask(CRTC_PORT,0xAD, 0x00, (UCHAR) jRegAD);
809
810    /* Vetical Timing Programming */
811    usTemp = (mode->CrtcVTotal) - 2;
812    if (usTemp & 0x100) jReg07 |= 0x01;			/* VT D[8] */
813    if (usTemp & 0x200) jReg07 |= 0x20;
814    if (usTemp & 0x400) jRegAE |= 0x01;			/* VT D[10] */
815    SetIndexRegMask(CRTC_PORT,0x06, 0x00, (UCHAR) usTemp);
816    usTemp = (mode->CrtcVSyncStart) - 1;
817    if (usTemp & 0x100) jReg07 |= 0x04;			/* VRS D[8] */
818    if (usTemp & 0x200) jReg07 |= 0x80;			/* VRS D[9] */
819    if (usTemp & 0x400) jRegAE |= 0x08;			/* VRS D[10] */
820    SetIndexRegMask(CRTC_PORT,0x10, 0x00, (UCHAR) usTemp);
821    usTemp = ((mode->CrtcVSyncEnd) - 1) & 0x3F;
822    if (usTemp & 0x10) jRegAE |= 0x20;			/* VRE D[4] */
823    if (usTemp & 0x20) jRegAE |= 0x40;			/* VRE D[5] */
824    SetIndexRegMask(CRTC_PORT,0x11, 0x70, (UCHAR) (usTemp & 0x0F));
825    usTemp = (mode->CrtcVDisplay) - 1;
826    if (usTemp & 0x100) jReg07 |= 0x02;			/* VDE D[8] */
827    if (usTemp & 0x200) jReg07 |= 0x40;			/* VDE D[9] */
828    if (usTemp & 0x400) jRegAE |= 0x02;			/* VDE D[10] */
829    SetIndexRegMask(CRTC_PORT,0x12, 0x00, (UCHAR) usTemp);
830    usTemp = (mode->CrtcVBlankStart) - 1;
831    if (usTemp & 0x100) jReg07 |= 0x08;			/* VBS D[8] */
832    if (usTemp & 0x200) jReg09 |= 0x20;			/* VBS D[9] */
833    if (usTemp & 0x400) jRegAE |= 0x04;			/* VBS D[10] */
834    SetIndexRegMask(CRTC_PORT,0x15, 0x00, (UCHAR) usTemp);
835    usTemp = (mode->CrtcVBlankEnd) - 1 ;
836    if (usTemp & 0x100) jRegAE |= 0x10;			/* VBE D[8] */
837    SetIndexRegMask(CRTC_PORT,0x16, 0x00, (UCHAR) usTemp);
838
839    SetIndexRegMask(CRTC_PORT,0x07, 0x00, (UCHAR) jReg07);
840    SetIndexRegMask(CRTC_PORT,0x09, 0xDF, (UCHAR) jReg09);
841    SetIndexRegMask(CRTC_PORT,0xAE, 0x00, (UCHAR) (jRegAE | 0x80));	/* disable line compare */
842
843    if ((pAST->jChipType == AST2500) && (pVGAModeInfo->pEnhTableEntry->Flags & AST2500PreCatchCRT))
844    {
845    	SetIndexRegMask(CRTC_PORT,0xB6, 0x3F, 0x80);
846	}
847	else
848	{
849    	SetIndexRegMask(CRTC_PORT,0xB6, 0x3F, 0x00);
850	}
851
852    /* lock CRTC */
853    SetIndexRegMask(CRTC_PORT,0x11, 0x7F, 0x80);
854
855}
856
857static void vSetOffsetReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
858{
859    ASTRecPtr pAST;
860    USHORT usOffset;
861
862    pAST = ASTPTR(pScrn);
863
864    usOffset = 	pAST->VideoModeInfo.ScreenPitch >> 3;		/* Unit: char */
865
866    SetIndexReg(CRTC_PORT,0x13, (UCHAR) (usOffset & 0xFF));
867    SetIndexReg(CRTC_PORT,0xB0, (UCHAR) ((usOffset >> 8) & 0x3F));
868
869}
870
871static void vSetDCLKReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
872{
873    PVBIOS_ENHTABLE_STRUCT pEnhModePtr;
874    PVBIOS_DCLK_INFO pDCLKPtr;
875    ASTRecPtr pAST;
876
877    pAST = ASTPTR(pScrn);
878
879    pEnhModePtr = pVGAModeInfo->pEnhTableEntry;
880    if ((pAST->jChipType == AST2500) && (PCI_DEV_REVISION(pAST->PciInfo) > 0x40))
881        pDCLKPtr = &DCLKTable_AST2500A1[pEnhModePtr->DCLKIndex];
882    else if ((pAST->jChipType == AST2500) && (PCI_DEV_REVISION(pAST->PciInfo) == 0x40))
883        pDCLKPtr = &DCLKTable_AST2500[pEnhModePtr->DCLKIndex];
884    else if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST1100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2150) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400))
885        pDCLKPtr = &DCLKTable_AST2100[pEnhModePtr->DCLKIndex];
886    else
887        pDCLKPtr = &DCLKTable[pEnhModePtr->DCLKIndex];
888
889    SetIndexRegMask(CRTC_PORT,0xC0, 0x00,  pDCLKPtr->Param1);
890    SetIndexRegMask(CRTC_PORT,0xC1, 0x00,  pDCLKPtr->Param2);
891    if ((pAST->jChipType == AST2500) && (PCI_DEV_REVISION(pAST->PciInfo) == 0x40))
892    {
893        SetIndexRegMask(CRTC_PORT,0xBB, 0x0F, (pDCLKPtr->Param3 & 0xF0));
894    }
895    else
896    {
897        SetIndexRegMask(CRTC_PORT,0xBB, 0x0F, (pDCLKPtr->Param3 & 0xC0) | ((pDCLKPtr->Param3 & 0x03) << 4) );
898    }
899
900}
901
902
903static void vSetExtReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
904{
905
906    ASTRecPtr pAST;
907    UCHAR jRegA0, jRegA3, jRegA8;
908
909    pAST = ASTPTR(pScrn);
910
911    jRegA0=jRegA3=jRegA8=0;
912    /* Mode Type Setting */
913    switch (pScrn->bitsPerPixel) {
914    case 8:
915        jRegA0 = 0x70;
916        jRegA3 = 0x01;
917        jRegA8 = 0x00;
918        break;
919    case 15:
920    case 16:
921        jRegA0 = 0x70;
922        jRegA3 = 0x04;
923        jRegA8 = 0x02;
924        break;
925    case 32:
926        jRegA0 = 0x70;
927        jRegA3 = 0x08;
928        jRegA8 = 0x02;
929        break;
930    }
931    SetIndexRegMask(CRTC_PORT,0xA0, 0x8F, (UCHAR) jRegA0);
932    SetIndexRegMask(CRTC_PORT,0xA3, 0xF0, (UCHAR) jRegA3);
933    SetIndexRegMask(CRTC_PORT,0xA8, 0xFD, (UCHAR) jRegA8);
934
935#if	defined(__sparc__)
936    UCHAR jRegA2 = 0x80;
937    if ((pScrn->bitsPerPixel == 15) || (pScrn->bitsPerPixel == 16) )
938        jRegA2 |= 0x40;
939    SetIndexRegMask(CRTC_PORT,0xA2, 0x3F, (UCHAR) jRegA2);
940#endif
941
942    /* Set Threshold */
943    if ((pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500))
944    {
945        SetIndexReg(CRTC_PORT,0xA7, 0x78);
946        SetIndexReg(CRTC_PORT,0xA6, 0x60);
947    }
948    else if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST1100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2150) )
949    {
950        SetIndexReg(CRTC_PORT,0xA7, 0x3F);
951        SetIndexReg(CRTC_PORT,0xA6, 0x2F);
952    }
953    else
954    {
955        SetIndexReg(CRTC_PORT,0xA7, 0x2F);
956        SetIndexReg(CRTC_PORT,0xA6, 0x1F);
957    }
958
959}
960
961static void vSetSyncReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
962{
963    PVBIOS_ENHTABLE_STRUCT pEnhModePtr;
964    ASTRecPtr pAST;
965    UCHAR jReg;
966
967    pAST = ASTPTR(pScrn);
968    pEnhModePtr = pVGAModeInfo->pEnhTableEntry;
969
970    jReg  = GetReg(MISC_PORT_READ);
971    jReg &= ~0xC0;
972	if (pEnhModePtr->Flags & NVSync) jReg |= 0x80;
973	if (pEnhModePtr->Flags & NHSync) jReg |= 0x40;
974    SetReg(MISC_PORT_WRITE,jReg);
975}
976
977static Bool bSetDACReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
978{
979    PVBIOS_DAC_INFO pDACPtr;
980    ASTRecPtr pAST;
981    ULONG i, ulDACNumber;
982    UCHAR DACR, DACG, DACB;
983
984    pAST = ASTPTR(pScrn);
985
986    switch (pScrn->bitsPerPixel)
987    {
988    case 8:
989         ulDACNumber = DAC_NUM_VGA;
990         pDACPtr = (PVBIOS_DAC_INFO) &DAC_VGA[0];
991         break;
992    default:
993         return (FALSE);
994    }
995
996    for (i=0; i<ulDACNumber; i++)
997    {
998    	DACR = pDACPtr->DACR;
999    	DACG = pDACPtr->DACG;
1000    	DACB = pDACPtr->DACB;
1001
1002        VGA_LOAD_PALETTE_INDEX (i, DACR, DACG, DACB);
1003
1004        pDACPtr++;
1005    }
1006
1007    return (TRUE);
1008
1009}
1010
1011static ULONG AST1180DCLKTable [] = {
1012    0x0008676b,						/* 00: VCLK25_175	*/
1013    0x00086342,				        	/* 01: VCLK28_322	*/
1014    0x00086568,				        	/* 02: VCLK31_5         */
1015    0x00082118,				        	/* 03: VCLK36         	*/
1016    0x0008232e,				        	/* 04: VCLK40          	*/
1017    0x000c256d, 		        		/* 05: VCLK49_5        	*/
1018    0x00082016,                        	        	/* 06: VCLK50          	*/
1019    0x000c0010,                        	        	/* 07: VCLK56_25       	*/
1020    0x000c0332,                        	        	/* 08: VCLK65		*/
1021    0x00080010,                        	        	/* 09: VCLK75	        */
1022    0x000c033d,				        	/* 0A: VCLK78_75       	*/
1023    0x000c0568,                        	        	/* 0B: VCLK94_5        	*/
1024    0x00040118,                        	        	/* 0C: VCLK108         	*/
1025    0x00040334,                        	        	/* 0D: VCLK135         	*/
1026    0x0004033d,                        	        	/* 0E: VCLK157_5       	*/
1027    0x00040018,				        	/* 0F: VCLK162         	*/
1028    0x00040123,						/* 10: VCLK154          */
1029    0x000c0669,						/* 11: VCLK83_5         */
1030    0x0004074b,						/* 12: VCLK106_5        */
1031    0x0004022d,						/* 13: VCLK146_25       */
1032    0x00040769,						/* 14: VCLK148_5        */
1033};
1034
1035static BOOL bSetAST1180CRTCReg(ScrnInfoPtr pScrn,  DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
1036{
1037    ASTRecPtr pAST = ASTPTR(pScrn);
1038
1039    ULONG HTIndex, HRIndex, VTIndex, VRIndex;
1040    ULONG HT, HDE, HBS, HBE, HRS, HRE;
1041    ULONG VT, VDE, VBS, VBE, VRS, VRE;
1042    ULONG HT2, HDE2, HRS2, HRE2;
1043    ULONG VT2, VDE2, VRS2, VRE2;
1044
1045    /* Reg. Index Select */
1046    {
1047        HTIndex =  AST1180_VGA1_HTREG;
1048        HRIndex =  AST1180_VGA1_HRREG;
1049        VTIndex =  AST1180_VGA1_VTREG;
1050        VRIndex =  AST1180_VGA1_VRREG;
1051    }
1052
1053    /* Get CRTC Info */
1054    HT = mode->CrtcHTotal;
1055    HDE= mode->CrtcHDisplay;
1056    HBS= mode->CrtcHBlankStart;
1057    HBE= mode->CrtcHBlankEnd;
1058    HRS= mode->CrtcHSyncStart;
1059    HRE= mode->CrtcHSyncEnd;
1060    VT = mode->CrtcVTotal;
1061    VDE= mode->CrtcVDisplay;
1062    VBS= mode->CrtcVBlankStart;
1063    VBE= mode->CrtcVBlankEnd;
1064    VRS= mode->CrtcVSyncStart;
1065    VRE= mode->CrtcVSyncEnd;
1066
1067    /* Calculate CRTC Reg Setting */
1068    HT2  = HT - 1;
1069    HDE2 = HDE - 1;
1070    HRS2 = HRS - 1;
1071    HRE2 = HRE - 1;
1072    VT2  = VT  - 1;
1073    VDE2 = VDE - 1;
1074    VRS2 = VRS - 1;
1075    VRE2 = VRE - 1;
1076
1077    /* Write Reg */
1078    WriteAST1180SOC(AST1180_GFX_BASE + HTIndex, (ULONG)(HDE2 << 16) | (ULONG) (HT2));
1079    WriteAST1180SOC(AST1180_GFX_BASE + HRIndex, (ULONG)(HRE2 << 16) | (ULONG) (HRS2));
1080    WriteAST1180SOC(AST1180_GFX_BASE + VTIndex, (ULONG)(VDE2 << 16) | (ULONG) (VT2));
1081    WriteAST1180SOC(AST1180_GFX_BASE + VRIndex, (ULONG)(VRE2 << 16) | (ULONG) (VRS2));
1082
1083    return (TRUE);
1084
1085} /* bSetAST1180CRTCReg */
1086
1087static BOOL bSetAST1180OffsetReg(ScrnInfoPtr pScrn,  DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
1088{
1089    ASTRecPtr pAST = ASTPTR(pScrn);
1090    ULONG ulOffset, ulTermalCount;
1091
1092    ulOffset      = pAST->VideoModeInfo.ScreenPitch;
1093    ulTermalCount = (pAST->VideoModeInfo.ScreenPitch + 7) >> 3;
1094
1095    /* Write Reg */
1096    WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_OFFSET, (ULONG) (ulTermalCount << 16) | (ULONG) (ulOffset));
1097
1098    return (TRUE);
1099
1100} /* bSetAST1180OffsetReg */
1101
1102static BOOL bSetAST1180DCLKReg(ScrnInfoPtr pScrn,  DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
1103{
1104    PVBIOS_ENHTABLE_STRUCT pEnhModePtr;
1105    ASTRecPtr pAST = ASTPTR(pScrn);
1106    ULONG ulDCLK;
1107
1108    pEnhModePtr = pVGAModeInfo->pEnhTableEntry;
1109    ulDCLK = AST1180DCLKTable[pEnhModePtr->DCLKIndex];
1110    if (pEnhModePtr->Flags & HalfDCLK)
1111        ulDCLK |= 0x00400000;		/* D[22]: div by 2 */
1112    WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_PLL, ulDCLK);
1113
1114    return (TRUE);
1115}
1116
1117static BOOL bSetAST1180ExtReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
1118{
1119    PVBIOS_ENHTABLE_STRUCT pEnhModePtr;
1120    ASTRecPtr pAST = ASTPTR(pScrn);
1121
1122    ULONG ulCtlRegIndex, ulCtlReg;			/* enable display */
1123    ULONG ulCtlReg2Index, ulCtlReg2 = 0x80;		/* single edge */
1124    ULONG ulThresholdRegIndex ;				/* Threshold */
1125    ULONG ulStartAddressIndex;				/* ulStartAddress */
1126    ULONG ulStartAddress = pAST->ulVRAMBase;
1127
1128    /* Reg. Index Select */
1129    {
1130        ulCtlRegIndex       = AST1180_VGA1_CTRL;
1131        ulCtlReg2Index      = AST1180_VGA1_CTRL2;
1132        ulThresholdRegIndex = AST1180_VGA1_THRESHOLD;
1133        ulStartAddressIndex = AST1180_VGA1_STARTADDR;
1134    }
1135
1136    /* Mode Type Setting */
1137    ulCtlReg = 0x30000000;
1138    {
1139        switch (pScrn->bitsPerPixel) {
1140        case 15:
1141        case 16:
1142            ulCtlReg |= 0x100001;            	/* RGB565, SCREEN OFF, ENABLE */
1143            break;
1144        case 32:
1145            ulCtlReg |= 0x100101;            	/* XRGB8888, SCREEN OFF, ENABLE */
1146            break;
1147        }
1148    }
1149
1150    /* Polarity */
1151    pEnhModePtr = pVGAModeInfo->pEnhTableEntry;
1152    ulCtlReg   |= (ULONG) (pEnhModePtr->Flags & SyncNN) << 10;
1153
1154    /* Single/Dual Edge */
1155    ulCtlReg2 |= 0x40;				/* dual-edge */
1156
1157    /* Write Reg */
1158    WriteAST1180SOC(AST1180_GFX_BASE + ulStartAddressIndex, ulStartAddress);
1159    WriteAST1180SOC(AST1180_GFX_BASE + ulThresholdRegIndex, ((ULONG) CRT_HIGH_THRESHOLD_VALUE << 8) | (ULONG) (CRT_LOW_THRESHOLD_VALUE));
1160    WriteAST1180SOC(AST1180_GFX_BASE + ulCtlReg2Index, ulCtlReg2);
1161    WriteAST1180SOC(AST1180_GFX_BASE + ulCtlRegIndex, ulCtlReg);
1162
1163    return (TRUE);
1164
1165} /* bSetAST1180ExtReg */
1166
1167#define I2C_BASE_AST1180	0x80fcb000
1168#define I2C_DEVICEADDR_AST1180	0x0EC			/* slave addr */
1169
1170static void SetChrontelReg(ASTRecPtr pAST, UCHAR jChannel, UCHAR jIndex, UCHAR jData )
1171{
1172    ULONG ulData, ulI2CAddr, ulI2CPortBase;
1173    ULONG retry;
1174
1175    {
1176        ulI2CPortBase = I2C_BASE_AST1180 + 0x40 * jChannel;
1177        ulI2CAddr = I2C_DEVICEADDR_AST1180;
1178    }
1179
1180    WriteAST1180SOC(ulI2CPortBase + 0x00, 0x00);
1181    WriteAST1180SOC(ulI2CPortBase + 0x04, 0x77743355);
1182    WriteAST1180SOC(ulI2CPortBase + 0x08, 0x0);
1183    WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff);
1184    WriteAST1180SOC(ulI2CPortBase + 0x00, 0x1);
1185    WriteAST1180SOC(ulI2CPortBase + 0x0C, 0xAF);
1186    WriteAST1180SOC(ulI2CPortBase + 0x20, ulI2CAddr);
1187    WriteAST1180SOC(ulI2CPortBase + 0x14, 0x03);
1188    retry = 0;
1189    do {
1190        ReadAST1180SOC(ulI2CPortBase + 0x10, ulData);
1191        usleep(10);
1192        if (retry++ > 1000)
1193            goto Exit_SetChrontelReg;
1194    } while (!(ulData & 0x01));
1195
1196    WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff);
1197    WriteAST1180SOC(ulI2CPortBase + 0x20, (ULONG) jIndex);
1198    WriteAST1180SOC(ulI2CPortBase + 0x14, 0x02);
1199    do {
1200        ReadAST1180SOC(ulI2CPortBase + 0x10, ulData);
1201     } while (!(ulData & 0x01));
1202
1203    WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff);
1204    WriteAST1180SOC(ulI2CPortBase + 0x20, (ULONG) jData);
1205    WriteAST1180SOC(ulI2CPortBase + 0x14, 0x02);
1206    do {
1207        ReadAST1180SOC(ulI2CPortBase + 0x10, ulData);
1208     } while (!(ulData & 0x01));
1209
1210    WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff);
1211    WriteAST1180SOC(ulI2CPortBase + 0x0C, 0xBF);
1212    WriteAST1180SOC(ulI2CPortBase + 0x14, 0x20);
1213    do {
1214        ReadAST1180SOC(ulI2CPortBase + 0x10, ulData);
1215    } while (!(ulData & 0x10));
1216
1217    ReadAST1180SOC(ulI2CPortBase + 0x0C, ulData);
1218    ulData &= 0xffffffef;
1219    WriteAST1180SOC(ulI2CPortBase + 0x0C, ulData);
1220    WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff);
1221
1222Exit_SetChrontelReg:
1223    ;
1224}
1225
1226static UCHAR GetChrontelReg(ASTRecPtr pAST, UCHAR jChannel, UCHAR jIndex)
1227{
1228    ULONG ulData, ulI2CAddr, ulI2CPortBase;
1229    UCHAR jData;
1230    ULONG retry;
1231
1232    {
1233        ulI2CPortBase = I2C_BASE_AST1180 + 0x40 * jChannel;
1234        ulI2CAddr = I2C_DEVICEADDR_AST1180;
1235    }
1236
1237    WriteAST1180SOC(ulI2CPortBase + 0x00, 0x00);
1238    WriteAST1180SOC(ulI2CPortBase + 0x04, 0x77743355);
1239    WriteAST1180SOC(ulI2CPortBase + 0x08, 0x0);
1240    WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff);
1241    WriteAST1180SOC(ulI2CPortBase + 0x00, 0x1);
1242    WriteAST1180SOC(ulI2CPortBase + 0x0C, 0xAF);
1243    WriteAST1180SOC(ulI2CPortBase + 0x20, ulI2CAddr);
1244    WriteAST1180SOC(ulI2CPortBase + 0x14, 0x03);
1245    retry = 0;
1246    do {
1247        ReadAST1180SOC(ulI2CPortBase + 0x10, ulData);
1248        usleep(10);
1249        if (retry++ > 1000)
1250            return 0;
1251    } while (!(ulData & 0x01));
1252
1253    WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff);
1254    WriteAST1180SOC(ulI2CPortBase + 0x20, (ULONG) jIndex);
1255    WriteAST1180SOC(ulI2CPortBase + 0x14, 0x02);
1256    do {
1257        ReadAST1180SOC(ulI2CPortBase + 0x10, ulData);
1258     } while (!(ulData & 0x01));
1259
1260    WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff);
1261    WriteAST1180SOC(ulI2CPortBase + 0x20, (ULONG) (ulI2CAddr + 1) );
1262    WriteAST1180SOC(ulI2CPortBase + 0x14, 0x1B);
1263    do {
1264        ReadAST1180SOC(ulI2CPortBase + 0x10, ulData);
1265     } while (!(ulData & 0x04));
1266
1267    WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff);
1268    WriteAST1180SOC(ulI2CPortBase + 0x0C, 0xBF);
1269    WriteAST1180SOC(ulI2CPortBase + 0x14, 0x20);
1270    do {
1271        ReadAST1180SOC(ulI2CPortBase + 0x10, ulData);
1272    } while (!(ulData & 0x10));
1273
1274    ReadAST1180SOC(ulI2CPortBase + 0x0C, ulData);
1275    ulData &= 0xffffffef;
1276    WriteAST1180SOC(ulI2CPortBase + 0x0C, ulData);
1277    WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff);
1278
1279    ReadAST1180SOC(ulI2CPortBase + 0x20, ulData);
1280    jData = (UCHAR) ((ulData & 0xFF00) >> 8);
1281
1282    return (jData);
1283}
1284
1285static void vInitChrontelReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo)
1286{
1287
1288    PVBIOS_ENHTABLE_STRUCT pEnhModePtr = pVGAModeInfo->pEnhTableEntry;
1289    ASTRecPtr pAST = ASTPTR(pScrn);
1290    ULONG ulDCLK = 65;					/* todo */
1291    UCHAR jReg;
1292
1293    jReg = GetChrontelReg(pAST, 1, 0x4A);		/* get vendor id */
1294    if (jReg == 0x95)
1295    {
1296        jReg = GetChrontelReg(pAST, 1, 0x20);		/* DVI/D-Sub */
1297        if (jReg & 0x20)			        /* DVI */
1298        {
1299
1300            /* DVI PLL Filter */
1301            if (ulDCLK > 65)
1302            {
1303                SetChrontelReg(pAST, 1, 0x33, 0x06);
1304                SetChrontelReg(pAST, 1, 0x34, 0x26);
1305                SetChrontelReg(pAST, 1, 0x36, 0xA0);
1306            }
1307            else
1308        	{
1309                SetChrontelReg(pAST, 1, 0x33, 0x08);
1310                SetChrontelReg(pAST, 1, 0x34, 0x16);
1311                SetChrontelReg(pAST, 1, 0x36, 0x60);
1312            }
1313
1314            SetChrontelReg(pAST, 1, 0x49, 0xc0);
1315        }
1316        else						/* D-Sub */
1317        {
1318
1319            SetChrontelReg(pAST, 1, 0x21, 0x09);
1320            SetChrontelReg(pAST, 1, 0x49, 0x00);
1321            SetChrontelReg(pAST, 1, 0x56, 0x00);
1322        }
1323    }
1324
1325}
1326
1327