via_display.c revision 44802259
1/*
2 * Copyright 2005-2015 The Openchrome Project
3 *                     [http://www.freedesktop.org/wiki/Openchrome]
4 * Copyright 2004-2005 The Unichrome Project  [unichrome.sf.net]
5 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
6 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sub license,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include "via_driver.h"
32
33/*
34 * Enables the second display channel.
35 */
36void
37ViaSecondDisplayChannelEnable(ScrnInfoPtr pScrn)
38{
39    vgaHWPtr hwp = VGAHWPTR(pScrn);
40
41    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
42                     "ViaSecondDisplayChannelEnable\n"));
43    ViaCrtcMask(hwp, 0x6A, 0x00, 1 << 6);
44    ViaCrtcMask(hwp, 0x6A, 1 << 7, 1 << 7);
45    ViaCrtcMask(hwp, 0x6A, 1 << 6, 1 << 6);
46}
47
48/*
49 * Disables the second display channel.
50 */
51void
52ViaSecondDisplayChannelDisable(ScrnInfoPtr pScrn)
53{
54    vgaHWPtr hwp = VGAHWPTR(pScrn);
55
56    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
57                     "ViaSecondDisplayChannelDisable\n"));
58
59    ViaCrtcMask(hwp, 0x6A, 0x00, 1 << 6);
60    ViaCrtcMask(hwp, 0x6A, 0x00, 1 << 7);
61    ViaCrtcMask(hwp, 0x6A, 1 << 6, 1 << 6);
62}
63
64/*
65 * Initial settings for displays.
66 */
67void
68ViaDisplayInit(ScrnInfoPtr pScrn)
69{
70    VIAPtr pVia = VIAPTR(pScrn);
71    vgaHWPtr hwp = VGAHWPTR(pScrn);
72
73    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplayInit\n"));
74
75    ViaSecondDisplayChannelDisable(pScrn);
76    ViaCrtcMask(hwp, 0x6A, 0x00, 0x3D);
77
78    hwp->writeCrtc(hwp, 0x6B, 0x00);
79    hwp->writeCrtc(hwp, 0x6C, 0x00);
80    hwp->writeCrtc(hwp, 0x79, 0x00);
81
82    /* (IGA1 Timing Plus 2, added in VT3259 A3 or later) */
83    if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400)
84        ViaCrtcMask(hwp, 0x47, 0x00, 0xC8);
85}
86
87/*
88 * Enables simultaneous mode.
89 */
90void
91ViaDisplayEnableSimultaneous(ScrnInfoPtr pScrn)
92{
93    vgaHWPtr hwp = VGAHWPTR(pScrn);
94
95    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
96                     "ViaDisplayEnableSimultaneous\n"));
97    ViaCrtcMask(hwp, 0x6B, 0x08, 0x08);
98}
99
100/*
101 * Disables simultaneous mode.
102 */
103void
104ViaDisplayDisableSimultaneous(ScrnInfoPtr pScrn)
105{
106    vgaHWPtr hwp = VGAHWPTR(pScrn);
107
108    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
109                     "ViaDisplayDisableSimultaneous\n"));
110    ViaCrtcMask(hwp, 0x6B, 0x00, 0x08);
111}
112
113/*
114 * Sets the primary or secondary display stream on internal TMDS.
115 */
116void
117ViaDisplaySetStreamOnDFP(ScrnInfoPtr pScrn, Bool primary)
118{
119    vgaHWPtr hwp = VGAHWPTR(pScrn);
120
121    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplaySetStreamOnDFP\n"));
122
123    if (primary)
124        ViaCrtcMask(hwp, 0x99, 0x00, 0x10);
125    else
126        ViaCrtcMask(hwp, 0x99, 0x10, 0x10);
127}
128
129static void
130ViaCRTCSetGraphicsRegisters(ScrnInfoPtr pScrn)
131{
132    vgaHWPtr hwp = VGAHWPTR(pScrn);
133
134    /* graphics registers */
135    hwp->writeGr(hwp, 0x00, 0x00);
136    hwp->writeGr(hwp, 0x01, 0x00);
137    hwp->writeGr(hwp, 0x02, 0x00);
138    hwp->writeGr(hwp, 0x03, 0x00);
139    hwp->writeGr(hwp, 0x04, 0x00);
140    hwp->writeGr(hwp, 0x05, 0x40);
141    hwp->writeGr(hwp, 0x06, 0x05);
142    hwp->writeGr(hwp, 0x07, 0x0F);
143    hwp->writeGr(hwp, 0x08, 0xFF);
144
145    ViaGrMask(hwp, 0x20, 0, 0xFF);
146    ViaGrMask(hwp, 0x21, 0, 0xFF);
147    ViaGrMask(hwp, 0x22, 0, 0xFF);
148}
149
150static void
151ViaCRTCSetAttributeRegisters(ScrnInfoPtr pScrn)
152{
153    vgaHWPtr hwp = VGAHWPTR(pScrn);
154    CARD8 i;
155
156    /* attribute registers */
157    for (i = 0; i <= 0xF; i++) {
158        hwp->writeAttr(hwp, i, i);
159    }
160    hwp->writeAttr(hwp, 0x10, 0x41);
161    hwp->writeAttr(hwp, 0x11, 0xFF);
162    hwp->writeAttr(hwp, 0x12, 0x0F);
163    hwp->writeAttr(hwp, 0x13, 0x00);
164    hwp->writeAttr(hwp, 0x14, 0x00);
165}
166
167void
168VIALoadRgbLut(ScrnInfoPtr pScrn, int start, int numColors, LOCO *colors)
169{
170    vgaHWPtr hwp = VGAHWPTR(pScrn);
171    int i, j;
172
173    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIALoadRgbLut\n"));
174
175    hwp->enablePalette(hwp);
176    hwp->writeDacMask(hwp, 0xFF);
177
178    /* We need the same palette contents for both 16 and 24 bits, but X doesn't
179     * play: X's colormap handling is hopelessly intertwined with almost every
180     * X subsystem.  So we just space out RGB values over the 256*3. */
181
182    switch (pScrn->bitsPerPixel) {
183        case 16:
184            for (i = start; i < numColors; i++) {
185                hwp->writeDacWriteAddr(hwp, i * 4);
186                for (j = 0; j < 4; j++) {
187                    hwp->writeDacData(hwp, colors[i / 2].red);
188                    hwp->writeDacData(hwp, colors[i].green);
189                    hwp->writeDacData(hwp, colors[i / 2].blue);
190                }
191            }
192            break;
193        case 8:
194        case 24:
195        case 32:
196            for (i = start; i < numColors; i++) {
197                hwp->writeDacWriteAddr(hwp, i);
198                hwp->writeDacData(hwp, colors[i].red);
199                hwp->writeDacData(hwp, colors[i].green);
200                hwp->writeDacData(hwp, colors[i].blue);
201            }
202            break;
203        default:
204            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
205                       "Unsupported bitdepth: %d\n", pScrn->bitsPerPixel);
206            break;
207    }
208    hwp->disablePalette(hwp);
209}
210
211void
212ViaGammaDisable(ScrnInfoPtr pScrn)
213{
214    VIAPtr pVia = VIAPTR(pScrn);
215    vgaHWPtr hwp = VGAHWPTR(pScrn);
216
217    switch (pVia->Chipset) {
218        case VIA_CLE266:
219        case VIA_KM400:
220            ViaSeqMask(hwp, 0x16, 0x00, 0x80);
221            break;
222        default:
223            ViaCrtcMask(hwp, 0x33, 0x00, 0x80);
224            break;
225    }
226
227    /* Disable gamma on secondary */
228    /* This is needed or the hardware will lockup */
229    ViaSeqMask(hwp, 0x1A, 0x00, 0x01);
230    ViaCrtcMask(hwp, 0x6A, 0x00, 0x02);
231    switch (pVia->Chipset) {
232        case VIA_CLE266:
233        case VIA_KM400:
234        case VIA_K8M800:
235        case VIA_PM800:
236            break;
237        default:
238            ViaCrtcMask(hwp, 0x6A, 0x00, 0x20);
239            break;
240    }
241}
242
243void
244ViaCRTCInit(ScrnInfoPtr pScrn)
245{
246    vgaHWPtr hwp = VGAHWPTR(pScrn);
247
248    hwp->writeSeq(hwp, 0x10, 0x01); /* unlock extended registers */
249    ViaCrtcMask(hwp, 0x47, 0x00, 0x01); /* unlock CRT registers */
250    ViaCRTCSetGraphicsRegisters(pScrn);
251    ViaCRTCSetAttributeRegisters(pScrn);
252}
253
254void
255ViaFirstCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
256{
257    vgaHWPtr hwp = VGAHWPTR(pScrn);
258    VIAPtr pVia = VIAPTR(pScrn);
259    CARD16 temp;
260
261    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCSetMode\n"));
262
263    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting up %s\n", mode->name));
264
265    ViaCrtcMask(hwp, 0x11, 0x00, 0x80); /* modify starting address */
266    ViaCrtcMask(hwp, 0x03, 0x80, 0x80); /* enable vertical retrace access */
267
268    /* Set Misc Register */
269    temp = 0x23;
270    if (mode->Flags & V_NHSYNC)
271        temp |= 0x40;
272    if (mode->Flags & V_NVSYNC)
273        temp |= 0x80;
274    temp |= 0x0C; /* Undefined/external clock */
275    hwp->writeMiscOut(hwp, temp);
276
277    /* Sequence registers */
278    hwp->writeSeq(hwp, 0x00, 0x00);
279
280#if 0
281    if (mode->Flags & V_CLKDIV2)
282        hwp->writeSeq(hwp, 0x01, 0x09);
283    else
284#endif
285        hwp->writeSeq(hwp, 0x01, 0x01);
286
287    hwp->writeSeq(hwp, 0x02, 0x0F);
288    hwp->writeSeq(hwp, 0x03, 0x00);
289    hwp->writeSeq(hwp, 0x04, 0x0E);
290
291    ViaSeqMask(hwp, 0x15, 0x02, 0x02);
292
293    /* bpp */
294    switch (pScrn->bitsPerPixel) {
295        case 8:
296            /* Only CLE266.AX use 6bits LUT. */
297            if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev < 15)
298                ViaSeqMask(hwp, 0x15, 0x22, 0xFE);
299            else
300                ViaSeqMask(hwp, 0x15, 0xA2, 0xFE);
301            break;
302        case 16:
303            ViaSeqMask(hwp, 0x15, 0xB6, 0xFE);
304            break;
305        case 24:
306        case 32:
307            ViaSeqMask(hwp, 0x15, 0xAE, 0xFE);
308            break;
309        default:
310            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled bitdepth: %d\n",
311                       pScrn->bitsPerPixel);
312            break;
313    }
314
315    switch (pVia->ChipId) {
316        case VIA_CX700:
317        case VIA_K8M890:
318        case VIA_P4M900:
319        case VIA_VX800:
320        case VIA_VX855:
321        case VIA_VX900:
322            break;
323        default:
324            ViaSeqMask(hwp, 0x16, 0x08, 0xBF);
325            ViaSeqMask(hwp, 0x17, 0x1F, 0xFF);
326            ViaSeqMask(hwp, 0x18, 0x4E, 0xFF);
327            ViaSeqMask(hwp, 0x1A, 0x08, 0xF9);
328            break;
329    }
330
331    /* Crtc registers */
332    /* horizontal total : 4100 */
333    temp = (mode->CrtcHTotal >> 3) - 5;
334    hwp->writeCrtc(hwp, 0x00, temp & 0xFF);
335    ViaCrtcMask(hwp, 0x36, temp >> 5, 0x08);
336
337    /* horizontal address : 2048 */
338    temp = (mode->CrtcHDisplay >> 3) - 1;
339    hwp->writeCrtc(hwp, 0x01, temp & 0xFF);
340
341    /* horizontal blanking start : 2048 */
342    /* temp = (mode->CrtcHDisplay >> 3) - 1; */
343    temp = (mode->CrtcHBlankStart >> 3) - 1;
344    hwp->writeCrtc(hwp, 0x02, temp & 0xFF);
345    /* If HblankStart has more bits anywhere, add them here */
346
347    /* horizontal blanking end : start + 1025 */
348    /* temp = (mode->CrtcHTotal >> 3) - 1; */
349    temp = (mode->CrtcHBlankEnd >> 3) - 1;
350    ViaCrtcMask(hwp, 0x03, temp, 0x1F);
351    ViaCrtcMask(hwp, 0x05, temp << 2, 0x80);
352    ViaCrtcMask(hwp, 0x33, temp >> 1, 0x20);
353
354    /* CrtcHSkew ??? */
355
356    /* horizontal sync start : 4095 */
357    temp = mode->CrtcHSyncStart >> 3;
358    hwp->writeCrtc(hwp, 0x04, temp & 0xFF);
359    ViaCrtcMask(hwp, 0x33, temp >> 4, 0x10);
360
361    /* horizontal sync end : start + 256 */
362    temp = mode->CrtcHSyncEnd >> 3;
363    ViaCrtcMask(hwp, 0x05, temp, 0x1F);
364
365    /* vertical total : 2049 */
366    temp = mode->CrtcVTotal - 2;
367    hwp->writeCrtc(hwp, 0x06, temp & 0xFF);
368    ViaCrtcMask(hwp, 0x07, temp >> 8, 0x01);
369    ViaCrtcMask(hwp, 0x07, temp >> 4, 0x20);
370    ViaCrtcMask(hwp, 0x35, temp >> 10, 0x01);
371
372    /* vertical address : 2048 */
373    temp = mode->CrtcVDisplay - 1;
374    hwp->writeCrtc(hwp, 0x12, temp & 0xFF);
375    ViaCrtcMask(hwp, 0x07, temp >> 7, 0x02);
376    ViaCrtcMask(hwp, 0x07, temp >> 3, 0x40);
377    ViaCrtcMask(hwp, 0x35, temp >> 8, 0x04);
378
379    /* Primary starting address -> 0x00, adjustframe does the rest */
380    hwp->writeCrtc(hwp, 0x0C, 0x00);
381    hwp->writeCrtc(hwp, 0x0D, 0x00);
382    ViaCrtcMask(hwp, 0x48, 0x00, 0x03); /* is this even possible on CLE266A ? */
383    hwp->writeCrtc(hwp, 0x34, 0x00);
384
385    /* vertical sync start : 2047 */
386    temp = mode->CrtcVSyncStart;
387    hwp->writeCrtc(hwp, 0x10, temp & 0xFF);
388    ViaCrtcMask(hwp, 0x07, temp >> 6, 0x04);
389    ViaCrtcMask(hwp, 0x07, temp >> 2, 0x80);
390    ViaCrtcMask(hwp, 0x35, temp >> 9, 0x02);
391
392    /* vertical sync end : start + 16 -- other bits someplace? */
393    ViaCrtcMask(hwp, 0x11, mode->CrtcVSyncEnd, 0x0F);
394
395    /* line compare: We are not doing splitscreen so 0x3FFF */
396    hwp->writeCrtc(hwp, 0x18, 0xFF);
397    ViaCrtcMask(hwp, 0x07, 0x10, 0x10);
398    ViaCrtcMask(hwp, 0x09, 0x40, 0x40);
399    ViaCrtcMask(hwp, 0x33, 0x06, 0x07);
400    ViaCrtcMask(hwp, 0x35, 0x10, 0x10);
401
402    /* zero Maximum scan line */
403    ViaCrtcMask(hwp, 0x09, 0x00, 0x1F);
404    hwp->writeCrtc(hwp, 0x14, 0x00);
405
406    /* vertical blanking start : 2048 */
407    /* temp = mode->CrtcVDisplay - 1; */
408    temp = mode->CrtcVBlankStart - 1;
409    hwp->writeCrtc(hwp, 0x15, temp & 0xFF);
410    ViaCrtcMask(hwp, 0x07, temp >> 5, 0x08);
411    ViaCrtcMask(hwp, 0x09, temp >> 4, 0x20);
412    ViaCrtcMask(hwp, 0x35, temp >> 7, 0x08);
413
414    /* vertical blanking end : start + 257 */
415    /* temp = mode->CrtcVTotal - 1; */
416    temp = mode->CrtcVBlankEnd - 1;
417    hwp->writeCrtc(hwp, 0x16, temp);
418
419    /* FIXME: check if this is really necessary here */
420    switch (pVia->ChipId) {
421        case VIA_CX700:
422        case VIA_K8M890:
423        case VIA_P4M900:
424        case VIA_VX800:
425        case VIA_VX855:
426        case VIA_VX900:
427            break;
428        default:
429            /* some leftovers */
430            hwp->writeCrtc(hwp, 0x08, 0x00);
431            ViaCrtcMask(hwp, 0x32, 0, 0xFF);  /* ? */
432            ViaCrtcMask(hwp, 0x33, 0, 0xC8);
433            break;
434    }
435
436    /* offset */
437    temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3;
438    /* Make sure that this is 32-byte aligned. */
439    if (temp & 0x03) {
440        temp += 0x03;
441        temp &= ~0x03;
442    }
443    hwp->writeCrtc(hwp, 0x13, temp & 0xFF);
444    ViaCrtcMask(hwp, 0x35, temp >> 3, 0xE0);
445
446    /* fetch count */
447    temp = (mode->CrtcHDisplay * (pScrn->bitsPerPixel >> 3)) >> 3;
448    /* Make sure that this is 32-byte aligned. */
449    if (temp & 0x03) {
450        temp += 0x03;
451        temp &= ~0x03;
452    }
453
454    hwp->writeSeq(hwp, 0x1C, ((temp >> 1)+1) & 0xFF);
455    ViaSeqMask(hwp, 0x1D, temp >> 9, 0x03);
456
457    switch (pVia->ChipId) {
458        case VIA_CX700:
459        case VIA_K8M890:
460        case VIA_P4M900:
461        case VIA_VX800:
462        case VIA_VX855:
463        case VIA_VX900:
464            break;
465        default:
466            /* some leftovers */
467            ViaCrtcMask(hwp, 0x32, 0, 0xFF);
468            ViaCrtcMask(hwp, 0x33, 0, 0xC8);
469            break;
470    }
471}
472
473void
474ViaFirstCRTCSetStartingAddress(xf86CrtcPtr crtc, int x, int y)
475{
476    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
477    drmmode_ptr drmmode = drmmode_crtc->drmmode;
478    ScrnInfoPtr pScrn = crtc->scrn;
479    VIAPtr pVia = VIAPTR(pScrn);
480    vgaHWPtr hwp = VGAHWPTR(pScrn);
481    CARD32 Base;
482
483    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCSetStartingAddress\n"));
484
485    Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8);
486    Base = (Base + drmmode->front_bo->offset) >> 1;
487
488    hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8);
489    hwp->writeCrtc(hwp, 0x0D, Base & 0xFF);
490    /* FIXME The proper starting address for CR48 is 0x1F - Bits[28:24] */
491    if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev)))
492        ViaCrtcMask(hwp, 0x48, Base >> 24, 0x0F);
493    /* CR34 are fire bits. Must be written after CR0C CR0D CR48.  */
494    hwp->writeCrtc(hwp, 0x34, (Base & 0xFF0000) >> 16);
495}
496
497void
498ViaSecondCRTCSetStartingAddress(xf86CrtcPtr crtc, int x, int y)
499{
500    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
501    drmmode_ptr drmmode = drmmode_crtc->drmmode;
502    ScrnInfoPtr pScrn = crtc->scrn;
503    vgaHWPtr hwp = VGAHWPTR(pScrn);
504    CARD32 Base, tmp;
505
506    Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8);
507    Base = (Base + drmmode->front_bo->offset) >> 3;
508
509    tmp = hwp->readCrtc(hwp, 0x62) & 0x01;
510    tmp |= (Base & 0x7F) << 1;
511    hwp->writeCrtc(hwp, 0x62, tmp);
512
513    hwp->writeCrtc(hwp, 0x63, (Base & 0x7F80) >> 7);
514    hwp->writeCrtc(hwp, 0x64, (Base & 0x7F8000) >> 15);
515    hwp->writeCrtc(hwp, 0xA3, (Base & 0x03800000) >> 23);
516}
517
518void
519ViaSecondCRTCHorizontalQWCount(ScrnInfoPtr pScrn, int width)
520{
521    vgaHWPtr hwp = VGAHWPTR(pScrn);
522    CARD16 temp;
523
524    /* fetch count */
525    temp = (width * (pScrn->bitsPerPixel >> 3)) >> 3;
526    /* Make sure that this is 32-byte aligned. */
527    if (temp & 0x03) {
528        temp += 0x03;
529        temp &= ~0x03;
530    }
531    hwp->writeCrtc(hwp, 0x65, (temp >> 1) & 0xFF);
532    ViaCrtcMask(hwp, 0x67, temp >> 7, 0x0C);
533}
534
535void
536ViaSecondCRTCHorizontalOffset(ScrnInfoPtr pScrn)
537{
538    vgaHWPtr hwp = VGAHWPTR(pScrn);
539    CARD16 temp;
540
541    /* offset */
542    temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3;
543    /* Make sure that this is 32-byte aligned. */
544    if (temp & 0x03) {
545        temp += 0x03;
546        temp &= ~0x03;
547        }
548
549    hwp->writeCrtc(hwp, 0x66, temp & 0xFF);
550    ViaCrtcMask(hwp, 0x67, temp >> 8, 0x03);
551}
552
553void
554ViaSecondCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
555{
556    VIAPtr pVia = VIAPTR(pScrn);
557    vgaHWPtr hwp = VGAHWPTR(pScrn);
558    CARD16 temp;
559
560    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mode: %p\n", mode);
561    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mode->name: %p\n", mode->name);
562    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mode->name: %s\n", mode->name);
563
564
565    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSecondCRTCSetMode\n"));
566    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting up %s\n", mode->name));
567    /* bpp */
568    switch (pScrn->bitsPerPixel) {
569        case 8:
570            ViaCrtcMask(hwp, 0x67, 0x00, 0xC0);
571            break;
572        case 16:
573            ViaCrtcMask(hwp, 0x67, 0x40, 0xC0);
574            break;
575        case 24:
576        case 32:
577            ViaCrtcMask(hwp, 0x67, 0xC0, 0xC0);
578            break;
579        default:
580            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled bitdepth: %d\n",
581                       pScrn->bitsPerPixel);
582            break;
583    }
584
585    switch (pVia->ChipId) {
586        case VIA_CX700:
587        case VIA_K8M890:
588        case VIA_P4M900:
589        case VIA_VX800:
590        case VIA_VX855:
591        case VIA_VX900:
592            break;
593        default:
594            ViaSeqMask(hwp, 0x16, 0x08, 0xBF);
595            ViaSeqMask(hwp, 0x17, 0x1F, 0xFF);
596            ViaSeqMask(hwp, 0x18, 0x4E, 0xFF);
597            ViaSeqMask(hwp, 0x1A, 0x08, 0xF9);
598            break;
599    }
600
601    /* Crtc registers */
602    /* horizontal total : 4096 */
603    temp = mode->CrtcHTotal - 1;
604    hwp->writeCrtc(hwp, 0x50, temp & 0xFF);
605    ViaCrtcMask(hwp, 0x55, temp >> 8, 0x0F);
606
607    /* horizontal address : 2048 */
608    temp = mode->CrtcHDisplay - 1;
609    hwp->writeCrtc(hwp, 0x51, temp & 0xFF);
610    ViaCrtcMask(hwp, 0x55, temp >> 4, 0x70);
611
612    /* horizontal blanking start : 2048 */
613    /* temp = mode->CrtcHDisplay - 1; */
614    temp = mode->CrtcHBlankStart - 1;
615    hwp->writeCrtc(hwp, 0x52, temp & 0xFF);
616    ViaCrtcMask(hwp, 0x54, temp >> 8, 0x07);
617
618    /* horizontal blanking end : 4096 */
619    /* temp = mode->CrtcHTotal - 1; */
620    temp = mode->CrtcHBlankEnd - 1;
621    hwp->writeCrtc(hwp, 0x53, temp & 0xFF);
622    ViaCrtcMask(hwp, 0x54, temp >> 5, 0x38);
623    ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x40);
624
625    /* horizontal sync start : 2047 */
626    temp = mode->CrtcHSyncStart;
627    hwp->writeCrtc(hwp, 0x56, temp & 0xFF);
628    ViaCrtcMask(hwp, 0x54, temp >> 2, 0xC0);
629    ViaCrtcMask(hwp, 0x5C, temp >> 3, 0x80);
630
631    if (pVia->ChipId != VIA_CLE266 && pVia->ChipId != VIA_KM400)
632        ViaCrtcMask(hwp, 0x5D, temp >> 4, 0x80);
633
634    /* horizontal sync end : sync start + 512 */
635    temp = mode->CrtcHSyncEnd;
636    hwp->writeCrtc(hwp, 0x57, temp & 0xFF);
637    ViaCrtcMask(hwp, 0x5C, temp >> 2, 0x40);
638
639    /* vertical total : 2048 */
640    temp = mode->CrtcVTotal - 1;
641    hwp->writeCrtc(hwp, 0x58, temp & 0xFF);
642    ViaCrtcMask(hwp, 0x5D, temp >> 8, 0x07);
643
644
645    /* vertical address : 2048 */
646    temp = mode->CrtcVDisplay - 1;
647    hwp->writeCrtc(hwp, 0x59, temp & 0xFF);
648    ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x38);
649
650    /* vertical blanking start : 2048 */
651    /* temp = mode->CrtcVDisplay - 1; */
652    temp = mode->CrtcVBlankStart - 1;
653    hwp->writeCrtc(hwp, 0x5A, temp & 0xFF);
654    ViaCrtcMask(hwp, 0x5C, temp >> 8, 0x07);
655
656    /* vertical blanking end : 2048 */
657    /* temp = mode->CrtcVTotal - 1; */
658    temp = mode->CrtcVBlankEnd - 1;
659    hwp->writeCrtc(hwp, 0x5B, temp & 0xFF);
660    ViaCrtcMask(hwp, 0x5C, temp >> 5, 0x38);
661
662    /* vertical sync start : 2047 */
663    temp = mode->CrtcVSyncStart;
664    hwp->writeCrtc(hwp, 0x5E, temp & 0xFF);
665    ViaCrtcMask(hwp, 0x5F, temp >> 3, 0xE0);
666
667    /* vertical sync end : start + 32 */
668    temp = mode->CrtcVSyncEnd;
669    ViaCrtcMask(hwp, 0x5F, temp, 0x1F);
670
671    switch (pVia->ChipId) {
672        case VIA_CX700:
673        case VIA_K8M890:
674        case VIA_P4M900:
675        case VIA_VX800:
676        case VIA_VX855:
677        case VIA_VX900:
678            break;
679        default:
680            /* some leftovers */
681            hwp->writeCrtc(hwp, 0x08, 0x00);
682            ViaCrtcMask(hwp, 0x32, 0, 0xFF);  /* ? */
683            ViaCrtcMask(hwp, 0x33, 0, 0xC8);
684            break;
685    }
686
687    ViaSecondCRTCHorizontalOffset(pScrn);
688    ViaSecondCRTCHorizontalQWCount(pScrn, mode->CrtcHDisplay);
689}
690
691/*
692 * Checks for limitations imposed by the available VGA timing registers.
693 */
694static ModeStatus
695ViaFirstCRTCModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode)
696{
697    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCModeValid\n"));
698
699    if (mode->CrtcHTotal > 4100)
700        return MODE_BAD_HVALUE;
701
702    if (mode->CrtcHDisplay > 2048)
703        return MODE_BAD_HVALUE;
704
705    if (mode->CrtcHBlankStart > 2048)
706        return MODE_BAD_HVALUE;
707
708    if ((mode->CrtcHBlankEnd - mode->CrtcHBlankStart) > 1025)
709        return MODE_HBLANK_WIDE;
710
711    if (mode->CrtcHSyncStart > 4095)
712        return MODE_BAD_HVALUE;
713
714    if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 256)
715        return MODE_HSYNC_WIDE;
716
717    if (mode->CrtcVTotal > 2049)
718        return MODE_BAD_VVALUE;
719
720    if (mode->CrtcVDisplay > 2048)
721        return MODE_BAD_VVALUE;
722
723    if (mode->CrtcVSyncStart > 2047)
724        return MODE_BAD_VVALUE;
725
726    if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 16)
727        return MODE_VSYNC_WIDE;
728
729    if (mode->CrtcVBlankStart > 2048)
730        return MODE_BAD_VVALUE;
731
732    if ((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) > 257)
733        return MODE_VBLANK_WIDE;
734
735    return MODE_OK;
736}
737
738static ModeStatus
739ViaSecondCRTCModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode)
740{
741    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSecondCRTCModeValid\n"));
742
743    if (mode->CrtcHTotal > 4096)
744        return MODE_BAD_HVALUE;
745
746    if (mode->CrtcHDisplay > 2048)
747        return MODE_BAD_HVALUE;
748
749    if (mode->CrtcHBlankStart > 2048)
750        return MODE_BAD_HVALUE;
751
752    if (mode->CrtcHBlankEnd > 4096)
753        return MODE_HBLANK_WIDE;
754
755    if (mode->CrtcHSyncStart > 2047)
756        return MODE_BAD_HVALUE;
757
758    if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 512)
759        return MODE_HSYNC_WIDE;
760
761    if (mode->CrtcVTotal > 2048)
762        return MODE_BAD_VVALUE;
763
764    if (mode->CrtcVDisplay > 2048)
765        return MODE_BAD_VVALUE;
766
767    if (mode->CrtcVBlankStart > 2048)
768        return MODE_BAD_VVALUE;
769
770    if (mode->CrtcVBlankEnd > 2048)
771        return MODE_VBLANK_WIDE;
772
773    if (mode->CrtcVSyncStart > 2047)
774        return MODE_BAD_VVALUE;
775
776    if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 32)
777        return MODE_VSYNC_WIDE;
778
779    return MODE_OK;
780}
781
782/*
783 * Not tested yet
784 */
785void
786ViaShadowCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
787{
788    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaShadowCRTCSetMode\n"));
789
790    vgaHWPtr hwp = VGAHWPTR(pScrn);
791    CARD16 temp;
792
793    temp = (mode->CrtcHTotal >> 3) - 5;
794    hwp->writeCrtc(hwp, 0x6D, temp & 0xFF);
795    ViaCrtcMask(hwp, 0x71, temp >> 5, 0x08);
796
797    temp = (mode->CrtcHBlankEnd >> 3) - 1;
798    hwp->writeCrtc(hwp, 0x6E, temp & 0xFF);
799
800    temp = mode->CrtcVTotal - 2;
801    hwp->writeCrtc(hwp, 0x6F, temp & 0xFF);
802    ViaCrtcMask(hwp, 0x71, temp >> 8, 0x07);
803
804    temp = mode->CrtcVDisplay - 1;
805    hwp->writeCrtc(hwp, 0x70, temp & 0xFF);
806    ViaCrtcMask(hwp, 0x71, temp >> 4, 0x70);
807
808    temp = mode->CrtcVBlankStart - 1;
809    hwp->writeCrtc(hwp, 0x72, temp & 0xFF);
810    ViaCrtcMask(hwp, 0x74, temp >> 4, 0x70);
811
812    temp = mode->CrtcVTotal - 1;
813    hwp->writeCrtc(hwp, 0x73, temp & 0xFF);
814    ViaCrtcMask(hwp, 0x74, temp >> 8, 0x07);
815
816    ViaCrtcMask(hwp, 0x76, mode->CrtcVSyncEnd, 0x0F);
817
818    temp = mode->CrtcVSyncStart;
819    hwp->writeCrtc(hwp, 0x75, temp & 0xFF);
820    ViaCrtcMask(hwp, 0x76, temp >> 4, 0x70);
821}
822
823static void
824iga1_crtc_dpms(xf86CrtcPtr crtc, int mode)
825{
826    ScrnInfoPtr pScrn = crtc->scrn;
827    VIAPtr pVia = VIAPTR(pScrn);
828    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
829
830    switch (mode) {
831    case DPMSModeOn:
832        if (pBIOSInfo->SimultaneousEnabled)
833            ViaDisplayEnableSimultaneous(pScrn);
834        break;
835
836    case DPMSModeStandby:
837    case DPMSModeSuspend:
838    case DPMSModeOff:
839        if (pBIOSInfo->SimultaneousEnabled)
840            ViaDisplayDisableSimultaneous(pScrn);
841        break;
842
843	default:
844        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n",
845                    mode);
846        break;
847    }
848    //vgaHWSaveScreen(pScrn->pScreen, mode);
849
850}
851
852static void
853iga1_crtc_save(xf86CrtcPtr crtc)
854{
855    ScrnInfoPtr pScrn = crtc->scrn;
856    vgaHWPtr hwp = VGAHWPTR(pScrn);
857    VIAPtr pVia = VIAPTR(pScrn);
858
859    VIASave(pScrn);
860    vgaHWUnlock(hwp);
861}
862
863static void
864iga1_crtc_restore(xf86CrtcPtr crtc)
865{
866    ScrnInfoPtr pScrn = crtc->scrn;
867    vgaHWPtr hwp = VGAHWPTR(pScrn);
868    VIAPtr pVia = VIAPTR(pScrn);
869
870    VIARestore(pScrn);
871
872    /* A soft reset helps to avoid a 3D hang on VT switch. */
873    switch (pVia->Chipset) {
874    case VIA_K8M890:
875    case VIA_P4M900:
876    case VIA_VX800:
877    case VIA_VX855:
878    case VIA_VX900:
879        break;
880
881    default:
882        hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40);
883        break;
884    }
885    vgaHWLock(hwp);
886}
887
888static Bool
889iga1_crtc_lock(xf86CrtcPtr crtc)
890{
891    return FALSE;
892}
893
894static void
895iga1_crtc_unlock(xf86CrtcPtr crtc)
896{
897}
898
899static Bool
900iga1_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
901                        DisplayModePtr adjusted_mode)
902{
903    ScrnInfoPtr pScrn = crtc->scrn;
904    VIAPtr pVia = VIAPTR(pScrn);
905    CARD32 temp;
906    ModeStatus modestatus;
907
908    if ((mode->Clock < pScrn->clockRanges->minClock) ||
909        (mode->Clock > pScrn->clockRanges->maxClock)) {
910        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
911                   "Clock for mode \"%s\" outside of allowed range (%u (%u - %u))\n",
912                   mode->name, mode->Clock, pScrn->clockRanges->minClock,
913                   pScrn->clockRanges->maxClock);
914        return FALSE;
915    }
916
917    modestatus = ViaFirstCRTCModeValid(pScrn, mode);
918    if (modestatus != MODE_OK) {
919        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" : %s.\n",
920                   mode->name, xf86ModeStatusToString(modestatus));
921        return FALSE;
922    }
923
924    temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh *
925            (pScrn->bitsPerPixel >> 3);
926    if (pVia->pBIOSInfo->Bandwidth < temp) {
927        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
928                    "Required bandwidth is not available. (%u > %u)\n",
929                    (unsigned)temp, (unsigned)pVia->pBIOSInfo->Bandwidth);
930        return FALSE;
931    }
932    return TRUE;
933}
934
935static void
936iga1_crtc_prepare (xf86CrtcPtr crtc)
937{
938}
939
940static void
941iga1_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
942{
943    ScrnInfoPtr pScrn = crtc->scrn;
944    VIAPtr pVia = VIAPTR(pScrn);
945
946    ViaFirstCRTCSetStartingAddress(crtc, x, y);
947    VIAVidAdjustFrame(pScrn, x, y);
948}
949
950static void
951iga1_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
952					DisplayModePtr adjusted_mode,
953					int x, int y)
954{
955    ScrnInfoPtr pScrn = crtc->scrn;
956    VIAPtr pVia = VIAPTR(pScrn);
957
958    if (!vgaHWInit(pScrn, adjusted_mode))
959        return;
960
961    ViaCRTCInit(pScrn);
962    ViaModeFirstCRTC(pScrn, adjusted_mode);
963
964    if (pVia->pBIOSInfo->SimultaneousEnabled)
965        ViaDisplayEnableSimultaneous(pScrn);
966    else
967        ViaDisplayDisableSimultaneous(pScrn);
968
969    iga1_crtc_set_origin(crtc, crtc->x, crtc->y);
970}
971
972static void
973iga1_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
974					int size)
975{
976    ScrnInfoPtr pScrn = crtc->scrn;
977    vgaHWPtr hwp = VGAHWPTR(pScrn);
978    VIAPtr pVia = VIAPTR(pScrn);
979    int SR1A, SR1B, CR67, CR6A;
980    LOCO *colors;
981    int i;
982
983    colors = malloc(size * sizeof(*colors));
984    if (colors == NULL)
985	return;
986
987    for (i = 0; i < size; i++) {
988        colors[i].red = red[i] >> 8;
989        colors[i].green = green[i] >> 8;
990        colors[i].blue = blue[i] >> 8;
991    }
992
993    if (pScrn->bitsPerPixel != 8) {
994        switch (pVia->Chipset) {
995        case VIA_CLE266:
996        case VIA_KM400:
997            ViaSeqMask(hwp, 0x16, 0x80, 0x80);
998            break;
999        default:
1000            ViaCrtcMask(hwp, 0x33, 0x80, 0x80);
1001            break;
1002        }
1003
1004        ViaSeqMask(hwp, 0x1A, 0x00, 0x01);
1005        VIALoadRgbLut(pScrn, 0, size, colors);
1006
1007    } else {
1008
1009        SR1A = hwp->readSeq(hwp, 0x1A);
1010        SR1B = hwp->readSeq(hwp, 0x1B);
1011        CR67 = hwp->readCrtc(hwp, 0x67);
1012        CR6A = hwp->readCrtc(hwp, 0x6A);
1013
1014        for (i = 0; i < size; i++) {
1015            hwp->writeDacWriteAddr(hwp, i);
1016            hwp->writeDacData(hwp, colors[i].red);
1017            hwp->writeDacData(hwp, colors[i].green);
1018            hwp->writeDacData(hwp, colors[i].blue);
1019        }
1020    }
1021    free(colors);
1022}
1023
1024static void *
1025iga1_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
1026{
1027    return NULL;
1028}
1029
1030static PixmapPtr
1031iga1_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
1032{
1033    return NULL;
1034}
1035
1036static void
1037iga1_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
1038{
1039}
1040
1041/*
1042    Set the cursor foreground and background colors.  In 8bpp, fg and
1043    bg are indices into the current colormap unless the
1044    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set.  In that case
1045    and in all other bpps the fg and bg are in 8-8-8 RGB format.
1046*/
1047static void
1048iga1_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
1049{
1050    ScrnInfoPtr pScrn = crtc->scrn;
1051    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1052    VIAPtr pVia = VIAPTR(pScrn);
1053    CARD32 temp;
1054
1055    if (xf86_config->cursor_fg)
1056        return;
1057
1058    /* Don't recolour the image if we don't have to. */
1059    if (fg == xf86_config->cursor_fg && bg == xf86_config->cursor_bg)
1060        return;
1061
1062    switch(pVia->Chipset) {
1063    case VIA_CX700:
1064    case VIA_P4M890:
1065    case VIA_P4M900:
1066    case VIA_VX800:
1067    case VIA_VX855:
1068    case VIA_VX900:
1069        temp = VIAGETREG(PRIM_HI_CTRL);
1070        VIASETREG(PRIM_HI_CTRL, temp & 0xFFFFFFFE);
1071        break;
1072
1073    default:
1074        temp = VIAGETREG(HI_CONTROL);
1075        VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE);
1076        break;
1077    }
1078
1079    xf86_config->cursor_fg = fg;
1080    xf86_config->cursor_bg = bg;
1081}
1082
1083static void
1084iga1_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
1085{
1086    ScrnInfoPtr pScrn = crtc->scrn;
1087    VIAPtr pVia = VIAPTR(pScrn);
1088    unsigned xoff, yoff;
1089
1090    if (x < 0) {
1091        xoff = ((-x) & 0xFE);
1092        x = 0;
1093    } else {
1094        xoff = 0;
1095    }
1096
1097    if (y < 0) {
1098        yoff = ((-y) & 0xFE);
1099        y = 0;
1100    } else {
1101        yoff = 0;
1102    }
1103
1104    switch(pVia->Chipset) {
1105    case VIA_CX700:
1106    case VIA_P4M890:
1107    case VIA_P4M900:
1108    case VIA_VX800:
1109    case VIA_VX855:
1110    case VIA_VX900:
1111        VIASETREG(PRIM_HI_POSSTART,    ((x    << 16) | (y    & 0x07ff)));
1112        VIASETREG(PRIM_HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff)));
1113        break;
1114
1115    default:
1116        VIASETREG(HI_POSSTART,    ((x    << 16) | (y    & 0x07ff)));
1117        VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff)));
1118        break;
1119    }
1120}
1121
1122static void
1123iga1_crtc_show_cursor (xf86CrtcPtr crtc)
1124{
1125    drmmode_crtc_private_ptr iga = crtc->driver_private;
1126    ScrnInfoPtr pScrn = crtc->scrn;
1127    VIAPtr pVia = VIAPTR(pScrn);
1128
1129    switch(pVia->Chipset) {
1130    case VIA_CX700:
1131    case VIA_P4M890:
1132    case VIA_P4M900:
1133    case VIA_VX800:
1134    case VIA_VX855:
1135    case VIA_VX900:
1136        VIASETREG(PRIM_HI_FBOFFSET, iga->cursor_bo->offset);
1137        VIASETREG(PRIM_HI_CTRL, 0x36000005);
1138        break;
1139
1140    default:
1141        /* Mono Cursor Display Path [bit31]: Primary */
1142        VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset);
1143        VIASETREG(HI_CONTROL, 0x76000005);
1144        break;
1145    }
1146}
1147
1148static void
1149iga1_crtc_hide_cursor (xf86CrtcPtr crtc)
1150{
1151    ScrnInfoPtr pScrn = crtc->scrn;
1152    VIAPtr pVia = VIAPTR(pScrn);
1153    CARD32 temp;
1154
1155    switch(pVia->Chipset) {
1156    case VIA_CX700:
1157    case VIA_P4M890:
1158    case VIA_P4M900:
1159    case VIA_VX800:
1160    case VIA_VX855:
1161    case VIA_VX900:
1162        temp = VIAGETREG(PRIM_HI_CTRL);
1163        VIASETREG(PRIM_HI_CTRL, temp & 0xFFFFFFFA);
1164        break;
1165
1166    default:
1167        temp = VIAGETREG(HI_CONTROL);
1168        /* Hardware cursor disable [bit0] */
1169        VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA);
1170        break;
1171    }
1172}
1173
1174static void
1175iga_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
1176{
1177    drmmode_crtc_private_ptr iga = crtc->driver_private;
1178    ScrnInfoPtr pScrn = crtc->scrn;
1179    void *dst;
1180
1181    dst = drm_bo_map(pScrn, iga->cursor_bo);
1182    memset(dst, 0x00, iga->cursor_bo->size);
1183    memcpy(dst, image, iga->cursor_bo->size);
1184    drm_bo_unmap(pScrn, iga->cursor_bo);
1185}
1186
1187static void
1188iga_crtc_commit(xf86CrtcPtr crtc)
1189{
1190    ScrnInfoPtr pScrn = crtc->scrn;
1191    VIAPtr pVia = VIAPTR(pScrn);
1192
1193    if (crtc->scrn->pScreen != NULL && pVia->drmmode.hwcursor)
1194        xf86_reload_cursors(crtc->scrn->pScreen);
1195}
1196
1197static void
1198iga_crtc_destroy(xf86CrtcPtr crtc)
1199{
1200    if (crtc->driver_private)
1201        free(crtc->driver_private);
1202}
1203
1204static const xf86CrtcFuncsRec iga1_crtc_funcs = {
1205    .dpms                   = iga1_crtc_dpms,
1206    .save                   = iga1_crtc_save,
1207    .restore                = iga1_crtc_restore,
1208    .lock                   = iga1_crtc_lock,
1209    .unlock                 = iga1_crtc_unlock,
1210    .mode_fixup             = iga1_crtc_mode_fixup,
1211    .prepare                = iga1_crtc_prepare,
1212    .mode_set               = iga1_crtc_mode_set,
1213    .commit                 = iga_crtc_commit,
1214    .gamma_set              = iga1_crtc_gamma_set,
1215    .shadow_create          = iga1_crtc_shadow_create,
1216    .shadow_allocate        = iga1_crtc_shadow_allocate,
1217    .shadow_destroy         = iga1_crtc_shadow_destroy,
1218    .set_cursor_colors      = iga1_crtc_set_cursor_colors,
1219    .set_cursor_position    = iga1_crtc_set_cursor_position,
1220    .show_cursor            = iga1_crtc_show_cursor,
1221    .hide_cursor            = iga1_crtc_hide_cursor,
1222    .load_cursor_argb       = iga_crtc_load_cursor_argb,
1223#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) > 2
1224    .set_origin             = iga1_crtc_set_origin,
1225#endif
1226    .destroy                = iga_crtc_destroy,
1227};
1228
1229static void
1230iga2_crtc_dpms(xf86CrtcPtr crtc, int mode)
1231{
1232    ScrnInfoPtr pScrn = crtc->scrn;
1233    VIAPtr pVia = VIAPTR(pScrn);
1234    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
1235
1236    switch (mode) {
1237    case DPMSModeOn:
1238        if (pBIOSInfo->SimultaneousEnabled)
1239            ViaDisplayEnableSimultaneous(pScrn);
1240        break;
1241
1242    case DPMSModeStandby:
1243    case DPMSModeSuspend:
1244    case DPMSModeOff:
1245        if (pBIOSInfo->SimultaneousEnabled)
1246            ViaDisplayDisableSimultaneous(pScrn);
1247        break;
1248
1249    default:
1250        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n",
1251                    mode);
1252        break;
1253    }
1254    //vgaHWSaveScreen(pScrn->pScreen, mode);
1255}
1256
1257static void
1258iga2_crtc_save(xf86CrtcPtr crtc)
1259{
1260    ScrnInfoPtr pScrn = crtc->scrn;
1261    vgaHWPtr hwp = VGAHWPTR(pScrn);
1262    VIAPtr pVia = VIAPTR(pScrn);
1263
1264    VIASave(pScrn);
1265    vgaHWUnlock(hwp);
1266}
1267
1268static void
1269iga2_crtc_restore(xf86CrtcPtr crtc)
1270{
1271    ScrnInfoPtr pScrn = crtc->scrn;
1272    vgaHWPtr hwp = VGAHWPTR(pScrn);
1273    VIAPtr pVia = VIAPTR(pScrn);
1274
1275    VIARestore(pScrn);
1276    vgaHWLock(hwp);
1277}
1278
1279static Bool
1280iga2_crtc_lock(xf86CrtcPtr crtc)
1281{
1282    return FALSE;
1283}
1284
1285static void
1286iga2_crtc_unlock(xf86CrtcPtr crtc)
1287{
1288}
1289
1290static Bool
1291iga2_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
1292                        DisplayModePtr adjusted_mode)
1293{
1294    ScrnInfoPtr pScrn = crtc->scrn;
1295    VIAPtr pVia = VIAPTR(pScrn);
1296    CARD32 temp;
1297    ModeStatus modestatus;
1298
1299    if ((mode->Clock < pScrn->clockRanges->minClock) ||
1300        (mode->Clock > pScrn->clockRanges->maxClock)) {
1301        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1302                   "Clock for mode \"%s\" outside of allowed range (%u (%u - %u))\n",
1303                   mode->name, mode->Clock, pScrn->clockRanges->minClock,
1304                   pScrn->clockRanges->maxClock);
1305        return FALSE;
1306    }
1307
1308    modestatus = ViaFirstCRTCModeValid(pScrn, mode);
1309    if (modestatus != MODE_OK) {
1310        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" : %s.\n",
1311                   mode->name, xf86ModeStatusToString(modestatus));
1312        return FALSE;
1313    }
1314
1315    temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh *
1316            (pScrn->bitsPerPixel >> 3);
1317    if (pVia->pBIOSInfo->Bandwidth < temp) {
1318        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1319                    "Required bandwidth is not available. (%u > %u)\n",
1320			        (unsigned)temp, (unsigned)pVia->pBIOSInfo->Bandwidth);
1321        return FALSE;
1322    }
1323    return TRUE;
1324}
1325
1326static void
1327iga2_crtc_prepare (xf86CrtcPtr crtc)
1328{
1329}
1330
1331static void
1332iga2_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
1333{
1334    ScrnInfoPtr pScrn = crtc->scrn;
1335    VIAPtr pVia = VIAPTR(pScrn);
1336
1337    ViaSecondCRTCSetStartingAddress(crtc, x, y);
1338    VIAVidAdjustFrame(pScrn, x, y);
1339}
1340
1341static void
1342iga2_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
1343                    DisplayModePtr adjusted_mode, int x, int y)
1344{
1345    ScrnInfoPtr pScrn = crtc->scrn;
1346    VIAPtr pVia = VIAPTR(pScrn);
1347
1348    if (!vgaHWInit(pScrn, adjusted_mode))
1349        return;
1350
1351    ViaCRTCInit(pScrn);
1352    ViaModeSecondCRTC(pScrn, adjusted_mode);
1353    ViaSecondDisplayChannelEnable(pScrn);
1354
1355    if (pVia->pBIOSInfo->SimultaneousEnabled)
1356        ViaDisplayEnableSimultaneous(pScrn);
1357    else
1358        ViaDisplayDisableSimultaneous(pScrn);
1359
1360    iga2_crtc_set_origin(crtc, crtc->x, crtc->y);
1361}
1362
1363static void
1364iga2_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
1365					int size)
1366{
1367    ScrnInfoPtr pScrn = crtc->scrn;
1368    vgaHWPtr hwp = VGAHWPTR(pScrn);
1369    VIAPtr pVia = VIAPTR(pScrn);
1370    int SR1A, SR1B, CR67, CR6A;
1371    int i;
1372    LOCO *colors;
1373
1374    colors = malloc(size * sizeof(*colors));
1375    if (colors == NULL)
1376	return;
1377
1378    for (i = 0; i < size; i++) {
1379        colors[i].red = red[i] >> 8;
1380        colors[i].green = green[i] >> 8;
1381        colors[i].blue = blue[i] >> 8;
1382    }
1383
1384    if (pScrn->bitsPerPixel != 8) {
1385        if (!(pVia->Chipset == VIA_CLE266 &&
1386            CLE266_REV_IS_AX(pVia->ChipRev))) {
1387            ViaSeqMask(hwp, 0x1A, 0x01, 0x01);
1388            ViaCrtcMask(hwp, 0x6A, 0x02, 0x02);
1389
1390            switch (pVia->Chipset) {
1391            case VIA_CLE266:
1392            case VIA_KM400:
1393            case VIA_K8M800:
1394            case VIA_PM800:
1395                break;
1396
1397            default:
1398                ViaCrtcMask(hwp, 0x6A, 0x20, 0x20);
1399                break;
1400            }
1401            VIALoadRgbLut(pScrn, 0, size, colors);
1402        }
1403    } else {
1404        SR1A = hwp->readSeq(hwp, 0x1A);
1405        SR1B = hwp->readSeq(hwp, 0x1B);
1406        CR67 = hwp->readCrtc(hwp, 0x67);
1407        CR6A = hwp->readCrtc(hwp, 0x6A);
1408
1409        ViaSeqMask(hwp, 0x1A, 0x01, 0x01);
1410        ViaSeqMask(hwp, 0x1B, 0x80, 0x80);
1411        ViaCrtcMask(hwp, 0x67, 0x00, 0xC0);
1412        ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0);
1413
1414        for (i = 0; i < size; i++) {
1415            hwp->writeDacWriteAddr(hwp, i);
1416            hwp->writeDacData(hwp, colors[i].red);
1417            hwp->writeDacData(hwp, colors[i].green);
1418            hwp->writeDacData(hwp, colors[i].blue);
1419        }
1420
1421        hwp->writeSeq(hwp, 0x1A, SR1A);
1422        hwp->writeSeq(hwp, 0x1B, SR1B);
1423        hwp->writeCrtc(hwp, 0x67, CR67);
1424        hwp->writeCrtc(hwp, 0x6A, CR6A);
1425
1426        /* Screen 0 palette was changed by mode setting of Screen 1,
1427         * so load it again. */
1428        for (i = 0; i < size; i++) {
1429            hwp->writeDacWriteAddr(hwp, i);
1430            hwp->writeDacData(hwp, colors[i].red);
1431            hwp->writeDacData(hwp, colors[i].green);
1432            hwp->writeDacData(hwp, colors[i].blue);
1433        }
1434    }
1435    free(colors);
1436}
1437
1438static void *
1439iga2_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
1440{
1441    return NULL;
1442}
1443
1444static PixmapPtr
1445iga2_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
1446{
1447    return NULL;
1448}
1449
1450static void
1451iga2_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
1452{
1453}
1454
1455/*
1456    Set the cursor foreground and background colors.  In 8bpp, fg and
1457    bg are indices into the current colormap unless the
1458    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set.  In that case
1459    and in all other bpps the fg and bg are in 8-8-8 RGB format.
1460*/
1461static void
1462iga2_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
1463{
1464    drmmode_crtc_private_ptr iga = crtc->driver_private;
1465    ScrnInfoPtr pScrn = crtc->scrn;
1466    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1467    int height = 64, width = 64, i;
1468    VIAPtr pVia = VIAPTR(pScrn);
1469    CARD32 pixel, temp, *dst;
1470
1471    if (xf86_config->cursor_fg)
1472        return;
1473
1474    fg |= 0xff000000;
1475    bg |= 0xff000000;
1476
1477    /* Don't recolour the image if we don't have to. */
1478    if (fg == xf86_config->cursor_fg && bg == xf86_config->cursor_bg)
1479        return;
1480
1481    switch(pVia->Chipset) {
1482    case VIA_CX700:
1483    case VIA_P4M890:
1484    case VIA_P4M900:
1485    case VIA_VX800:
1486    case VIA_VX855:
1487    case VIA_VX900:
1488        temp = VIAGETREG(HI_CONTROL);
1489        VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE);
1490        break;
1491
1492    default:
1493        temp = VIAGETREG(HI_CONTROL);
1494        VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE);
1495        height = width = 32;
1496        break;
1497    }
1498
1499    dst = drm_bo_map(pScrn, iga->cursor_bo);
1500    for (i = 0; i < width * height; i++, dst++)
1501        if ((pixel = *dst))
1502            *dst = (pixel == xf86_config->cursor_fg) ? fg : bg;
1503    drm_bo_unmap(pScrn, iga->cursor_bo);
1504
1505    xf86_config->cursor_fg = fg;
1506    xf86_config->cursor_bg = bg;
1507}
1508
1509static void
1510iga2_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
1511{
1512    ScrnInfoPtr pScrn = crtc->scrn;
1513    VIAPtr pVia = VIAPTR(pScrn);
1514    unsigned xoff, yoff;
1515
1516    if (x < 0) {
1517        xoff = ((-x) & 0xFE);
1518        x = 0;
1519    } else {
1520        xoff = 0;
1521    }
1522
1523    if (y < 0) {
1524        yoff = ((-y) & 0xFE);
1525        y = 0;
1526    } else {
1527        yoff = 0;
1528    }
1529
1530    switch(pVia->Chipset) {
1531    case VIA_CX700:
1532    case VIA_P4M890:
1533    case VIA_P4M900:
1534    case VIA_VX800:
1535    case VIA_VX855:
1536    case VIA_VX900:
1537        VIASETREG(HI_POSSTART,    ((x    << 16) | (y    & 0x07ff)));
1538        VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff)));
1539        break;
1540
1541    default:
1542        VIASETREG(HI_POSSTART,    ((x    << 16) | (y    & 0x07ff)));
1543        VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff)));
1544        break;
1545    }
1546}
1547
1548static void
1549iga2_crtc_show_cursor(xf86CrtcPtr crtc)
1550{
1551    drmmode_crtc_private_ptr iga = crtc->driver_private;
1552    ScrnInfoPtr pScrn = crtc->scrn;
1553    VIAPtr pVia = VIAPTR(pScrn);
1554
1555    switch(pVia->Chipset) {
1556    case VIA_CX700:
1557    case VIA_P4M890:
1558    case VIA_P4M900:
1559    case VIA_VX800:
1560    case VIA_VX855:
1561    case VIA_VX900:
1562        VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset);
1563        VIASETREG(HI_CONTROL, 0xB6000005);
1564        break;
1565
1566    default:
1567        /* Mono Cursor Display Path [bit31]: Secondary */
1568        /* FIXME For CLE266 and KM400 try to enable 32x32 cursor size [bit1] */
1569        VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset);
1570        VIASETREG(HI_CONTROL, 0xF6000005);
1571        break;
1572    }
1573}
1574
1575static void
1576iga2_crtc_hide_cursor(xf86CrtcPtr crtc)
1577{
1578    ScrnInfoPtr pScrn = crtc->scrn;
1579    VIAPtr pVia = VIAPTR(pScrn);
1580    CARD32 temp;
1581
1582    switch(pVia->Chipset) {
1583    case VIA_CX700:
1584    case VIA_P4M890:
1585    case VIA_P4M900:
1586    case VIA_VX800:
1587    case VIA_VX855:
1588    case VIA_VX900:
1589	    temp = VIAGETREG(HI_CONTROL);
1590        VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA);
1591        break;
1592
1593    default:
1594        temp = VIAGETREG(HI_CONTROL);
1595        /* Hardware cursor disable [bit0] */
1596        VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA);
1597        break;
1598	}
1599}
1600
1601static const xf86CrtcFuncsRec iga2_crtc_funcs = {
1602    .dpms                   = iga2_crtc_dpms,
1603    .save                   = iga2_crtc_save,
1604    .restore                = iga2_crtc_restore,
1605    .lock                   = iga2_crtc_lock,
1606    .unlock                 = iga2_crtc_unlock,
1607    .mode_fixup             = iga2_crtc_mode_fixup,
1608    .prepare                = iga2_crtc_prepare,
1609    .mode_set               = iga2_crtc_mode_set,
1610    .commit                 = iga_crtc_commit,
1611    .gamma_set              = iga2_crtc_gamma_set,
1612    .shadow_create          = iga2_crtc_shadow_create,
1613    .shadow_allocate        = iga2_crtc_shadow_allocate,
1614    .shadow_destroy         = iga2_crtc_shadow_destroy,
1615    .set_cursor_colors      = iga2_crtc_set_cursor_colors,
1616    .set_cursor_position    = iga2_crtc_set_cursor_position,
1617    .show_cursor            = iga2_crtc_show_cursor,
1618    .hide_cursor            = iga2_crtc_hide_cursor,
1619    .load_cursor_argb       = iga_crtc_load_cursor_argb,
1620#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) > 2
1621    .set_origin             = iga2_crtc_set_origin,
1622#endif
1623    .destroy                = iga_crtc_destroy,
1624};
1625
1626Bool
1627UMSCrtcInit(ScrnInfoPtr pScrn)
1628{
1629    drmmode_crtc_private_ptr iga1_rec = NULL, iga2_rec = NULL;
1630    vgaHWPtr hwp = VGAHWPTR(pScrn);
1631    VIAPtr pVia = VIAPTR(pScrn);
1632#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0)
1633    ClockRangePtr clockRanges;
1634#else
1635    ClockRangesPtr clockRanges;
1636#endif
1637    int max_pitch, max_height;
1638    VIABIOSInfoPtr pBIOSInfo;
1639    xf86CrtcPtr iga1, iga2;
1640
1641    /* Read memory bandwidth from registers. */
1642    pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4;
1643    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1644                     "Detected MemClk %d\n", pVia->MemClk));
1645    if (pVia->MemClk >= VIA_MEM_END) {
1646        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1647                   "Unknown Memory clock: %d\n", pVia->MemClk);
1648        pVia->MemClk = VIA_MEM_END - 1;
1649    }
1650    pBIOSInfo = pVia->pBIOSInfo;
1651    pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn);
1652
1653    if (pBIOSInfo->TVType == TVTYPE_NONE) {
1654        /* Use jumper to determine TV type. */
1655        if (hwp->readCrtc(hwp, 0x3B) & 0x02) {
1656            pBIOSInfo->TVType = TVTYPE_PAL;
1657            DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1658                             "Detected TV standard: PAL.\n"));
1659        } else {
1660            pBIOSInfo->TVType = TVTYPE_NTSC;
1661            DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1662                             "Detected TV standard: NTSC.\n"));
1663        }
1664    }
1665
1666    if (pVia->drmmode.hwcursor) {
1667        if (!xf86LoadSubModule(pScrn, "ramdac"))
1668            return FALSE;
1669    }
1670
1671    if (!xf86LoadSubModule(pScrn, "i2c"))
1672        return FALSE;
1673    else
1674        ViaI2CInit(pScrn);
1675
1676    if (!xf86LoadSubModule(pScrn, "ddc"))
1677        return FALSE;
1678
1679    /*
1680     * Set up ClockRanges, which describe what clock ranges are
1681     * available, and what sort of modes they can be used for.
1682     */
1683
1684#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0)
1685    clockRanges = xnfalloc(sizeof(ClockRange));
1686#else
1687    clockRanges = xnfalloc(sizeof(ClockRanges));
1688#endif
1689    clockRanges->next = NULL;
1690    clockRanges->minClock = 20000;
1691    clockRanges->maxClock = 230000;
1692
1693    clockRanges->clockIndex = -1;
1694    clockRanges->interlaceAllowed = TRUE;
1695    clockRanges->doubleScanAllowed = FALSE;
1696    pScrn->clockRanges = clockRanges;
1697
1698    /*
1699     * Now handle the outputs
1700     */
1701    iga1_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
1702    if (!iga1_rec) {
1703        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n");
1704        return FALSE;
1705    }
1706
1707    iga1 = xf86CrtcCreate(pScrn, &iga1_crtc_funcs);
1708    if (!iga1) {
1709        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n");
1710        free(iga1_rec);
1711        return FALSE;
1712    }
1713    iga1_rec->drmmode = &pVia->drmmode;
1714    iga1_rec->index = 0;
1715    iga1->driver_private = iga1_rec;
1716
1717    iga2_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
1718    if (!iga2_rec) {
1719        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n");
1720        xf86CrtcDestroy(iga1);
1721        return FALSE;
1722    }
1723
1724    iga2 = xf86CrtcCreate(pScrn, &iga2_crtc_funcs);
1725    if (!iga2) {
1726        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n");
1727        xf86CrtcDestroy(iga1);
1728        free(iga2_rec);
1729        return FALSE;
1730    }
1731    iga2_rec->drmmode = &pVia->drmmode;
1732    iga2_rec->index = 1;
1733    iga2->driver_private = iga2_rec;
1734
1735    /*
1736     * CLE266A:
1737     *   Max Line Pitch: 4080, (FB corruption when higher, driver problem?)
1738     *   Max Height: 4096 (and beyond)
1739     *
1740     * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited
1741     * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1).
1742     * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please.
1743     *
1744     * We should be able to limit the memory available for a mode to 32 MB,
1745     * but miScanLineWidth fails to catch this properly (apertureSize).
1746     */
1747    switch (pVia->Chipset) {
1748    case VIA_CLE266:
1749    case VIA_KM400:
1750    case VIA_K8M800:
1751    case VIA_PM800:
1752    case VIA_P4M800PRO:
1753        max_pitch = 3344;
1754        max_height = 2508;
1755        break;
1756
1757    case VIA_CX700:
1758    case VIA_P4M890:
1759    case VIA_K8M890:
1760    case VIA_P4M900:
1761        max_pitch = 8192/(pScrn->bitsPerPixel >> 3)-1;
1762        max_height = max_pitch;
1763        break;
1764
1765    default:
1766        max_pitch = 16384/(pScrn->bitsPerPixel >> 3)-1;
1767        max_height = max_pitch;
1768        break;
1769    }
1770
1771    /* Init HI_X0 for cursor */
1772    switch (pVia->Chipset) {
1773    case VIA_CX700:
1774    /* case VIA_CN750: */
1775    case VIA_P4M890:
1776    case VIA_P4M900:
1777    case VIA_VX800:
1778    case VIA_VX855:
1779    case VIA_VX900:
1780        /* set 0 as transparent color key for IGA 2 */
1781        VIASETREG(HI_TRANSPARENT_COLOR, 0);
1782        VIASETREG(HI_INVTCOLOR, 0X00FFFFFF);
1783        VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0xE0000);
1784        VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000);
1785
1786        /* set 0 as transparent color key for IGA 1 */
1787        VIASETREG(PRIM_HI_TRANSCOLOR, 0);
1788        VIASETREG(PRIM_HI_FIFO, 0x0D000D0F);
1789        VIASETREG(PRIM_HI_INVTCOLOR, 0x00FFFFFF);
1790        VIASETREG(V327_HI_INVTCOLOR, 0x00FFFFFF);
1791        break;
1792
1793    default:
1794        VIASETREG(HI_TRANSPARENT_COLOR, 0);
1795        VIASETREG(HI_INVTCOLOR, 0X00FFFFFF);
1796        VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0xE0000);
1797        VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000);
1798        break;
1799    }
1800
1801    xf86CrtcSetSizeRange(pScrn, 320, 200, max_pitch, max_height);
1802
1803    ViaOutputsDetect(pScrn);
1804
1805    return TRUE;
1806}
1807