2
* Copyright 1992-2000 by Alan Hourihane, Wigan, England.
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 Alan Hourihane not be used in
9
* advertising or publicity pertaining to distribution of the software without
10
* specific, written prior permission. Alan Hourihane makes no representations
11
* about the suitability of this software for any purpose. It is provided
12
* "as is" without express or implied warranty.
14
* ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16
* EVENT SHALL ALAN HOURIHANE 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.
22
* Author: Alan Hourihane, alanh@fairlite.demon.co.uk
24
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c,v 1.70 2003/01/05 18:09:00 alanh Exp $ */
27
#include "xf86_OSproc.h"
28
#include "xf86_ansic.h"
29
#include "xf86Version.h"
30
#include "xf86PciInfo.h"
36
#include "trident_regs.h"
39
static biosMode bios1[] = {
43
static biosMode bios4[] = {
54
static biosMode bios8[] = {
65
static biosMode bios15[] = {
75
static biosMode bios16[] = {
85
static biosMode bios24[] = {
93
static newModes newModeRegs [] = {
94
{ 320, 200, 0x13, 0x30 },
95
{ 640, 480, 0x13, 0x61 },
96
{ 800, 600, 0x13, 0x61 },
97
{ 1024, 768, 0x3b, 0x63 },
98
{ 1280, 1024, 0x7b, 0x64 },
99
{ 1400, 1050, 0x11, 0x7b }
103
TridentFindMode(int xres, int yres, int depth)
111
size = sizeof(bios1) / sizeof(biosMode);
115
size = sizeof(bios4) / sizeof(biosMode);
119
size = sizeof(bios8) / sizeof(biosMode);
123
size = sizeof(bios15) / sizeof(biosMode);
127
size = sizeof(bios16) / sizeof(biosMode);
131
size = sizeof(bios24) / sizeof(biosMode);
138
for (i = 0; i < size; i++) {
139
if (xres <= mode[i].x_res) {
140
xres_s = mode[i].x_res;
141
for (; i < size; i++) {
142
if (mode[i].x_res != xres_s)
143
return mode[i-1].mode;
144
if (yres <= mode[i].y_res)
149
return mode[size - 1].mode;
153
TridentFindNewMode(int xres, int yres, CARD8 *gr5a, CARD8 *gr5c)
158
size = sizeof(newModeRegs) / sizeof(newModes);
160
for (i = 0; i < size; i++) {
161
if (xres <= newModeRegs[i].x_res) {
162
xres_s = newModeRegs[i].x_res;
163
for (; i < size; i++) {
164
if (newModeRegs[i].x_res != xres_s
165
|| yres <= newModeRegs[i].y_res) {
166
*gr5a = newModeRegs[i].GR5a;
167
*gr5c = newModeRegs[i].GR5c;
173
*gr5a = newModeRegs[size - 1].GR5a;
174
*gr5c = newModeRegs[size - 1].GR5c;
179
tridentSetBrightnessAndGamma(TRIDENTRegPtr tridentReg,
180
Bool on, double exp,int brightness)
182
int pivots[] = {0,3,15,63,255};
186
double x, x_prev = 0, y, y_prev = 0;
192
tridentReg->tridentRegs3C4[0xB4] &= ~0x80;
196
for (i = 0; i < 4; i++) {
197
x = pivots[i + 1] / 255.0;
199
slope = (y - y_prev) / (x - x_prev);
202
#define RND(x) ((((x) - (int) (x)) < 0.5) ? (int)(x) : (int)(x) + 1)
205
i_slopes[i] = (3 << 4) | (RND(slope) & 0xf);
207
i_slopes[i] = (2 << 4) | (RND(slope * 2) & 0xf);
209
i_slopes[i] = (1 << 4) | (RND(slope * 4) & 0xf);
211
i_slopes[i] = (RND(slope * 8) & 0xf);
214
intercepts[i] = (char)(y_0 * 256 / 4);
219
tridentReg->tridentRegs3C4[0xB4] = 0x80 | i_slopes[0];
220
tridentReg->tridentRegs3C4[0xB5] = i_slopes[1];
221
tridentReg->tridentRegs3C4[0xB6] = i_slopes[2];
222
tridentReg->tridentRegs3C4[0xB7] = i_slopes[3];
223
tridentReg->tridentRegs3C4[0xB8] = (intercepts[0] + brightness);
224
tridentReg->tridentRegs3C4[0xB9] = (intercepts[1] + brightness);
225
tridentReg->tridentRegs3C4[0xBA] = (intercepts[2] + brightness);
226
tridentReg->tridentRegs3C4[0xBB] = (intercepts[3] + brightness);
230
TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
232
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
233
TRIDENTRegPtr pReg = &pTrident->ModeReg;
237
int clock = pTrident->currentClock;
239
Bool fullSize = FALSE;
240
Bool isShadow = FALSE;
242
vgaHWPtr hwp = VGAHWPTR(pScrn);
243
vgaRegPtr regp = &hwp->ModeReg;
244
vgaRegPtr vgaReg = &hwp->ModeReg;
245
vgaIOBase = VGAHWPTR(pScrn)->IOBase;
248
if (pTrident->Chipset > PROVIDIA9685) {
249
OUTB(0x3C4, Protection);
250
protect = INB(0x3C5);
254
OUTB(0x3C4, 0x0B); INB(0x3C5); /* Ensure we are in New Mode */
256
pReg->tridentRegs3x4[PixelBusReg] = 0x00;
257
pReg->tridentRegsDAC[0x00] = 0x00;
258
pReg->tridentRegs3C4[NewMode2] = 0x20;
259
OUTB(0x3CE, MiscExtFunc);
260
pReg->tridentRegs3CE[MiscExtFunc] = INB(0x3CF) & 0xF0;
261
pReg->tridentRegs3x4[GraphEngReg] = 0x00;
262
pReg->tridentRegs3x4[PreEndControl] = 0;
263
pReg->tridentRegs3x4[PreEndFetch] = 0;
265
pReg->tridentRegs3x4[CRTHiOrd] = (((mode->CrtcVBlankEnd-1) & 0x400)>>4) |
266
(((mode->CrtcVTotal - 2) & 0x400) >> 3) |
267
((mode->CrtcVSyncStart & 0x400) >> 5) |
268
(((mode->CrtcVDisplay - 1) & 0x400) >> 6)|
271
pReg->tridentRegs3x4[HorizOverflow] = ((mode->CrtcHTotal & 0x800) >> 11) |
272
((mode->CrtcHBlankStart & 0x800)>>7);
274
if (pTrident->IsCyber) {
277
Bool ShadowModeActive;
279
int i = pTrident->lcdMode;
281
OUTB(0x3CE, CyberControl);
282
ShadowModeActive = ((INB(0x3CF) & 0x81) == 0x81);
284
OUTB(0x3CE, FPConfig);
285
pReg->tridentRegs3CE[FPConfig] = INB(0x3CF);
286
if (pTrident->dspOverride) {
287
if (pTrident->dspOverride & LCD_ACTIVE) {
288
pReg->tridentRegs3CE[FPConfig] |= 0x10;
291
pReg->tridentRegs3CE[FPConfig] &= ~0x10;
294
if (pTrident->dspOverride & CRT_ACTIVE)
295
pReg->tridentRegs3CE[FPConfig] |= 0x20;
297
pReg->tridentRegs3CE[FPConfig] &= ~0x20;
299
LCDActive = (pReg->tridentRegs3CE[FPConfig] & 0x10);
302
OUTB(0x3CE, CyberEnhance);
304
pReg->tridentRegs3CE[CyberEnhance] = INB(0x3CF);
306
pReg->tridentRegs3CE[CyberEnhance] = INB(0x3CF) & 0x8F;
307
if (mode->CrtcVDisplay > 1024)
308
pReg->tridentRegs3CE[CyberEnhance] |= 0x50;
310
if (mode->CrtcVDisplay > 768)
311
pReg->tridentRegs3CE[CyberEnhance] |= 0x30;
313
if (mode->CrtcVDisplay > 600)
314
pReg->tridentRegs3CE[CyberEnhance] |= 0x20;
316
if (mode->CrtcVDisplay > 480)
317
pReg->tridentRegs3CE[CyberEnhance] |= 0x10;
319
OUTB(0x3CE, CyberControl);
320
pReg->tridentRegs3CE[CyberControl] = INB(0x3CF);
322
OUTB(0x3CE,HorStretch);
323
pReg->tridentRegs3CE[HorStretch] = INB(0x3CF);
324
OUTB(0x3CE,VertStretch);
325
pReg->tridentRegs3CE[VertStretch] = INB(0x3CF);
328
if ((!((pReg->tridentRegs3CE[VertStretch] & 1) ||
329
(pReg->tridentRegs3CE[HorStretch] & 1)))
330
&& (!LCDActive || ShadowModeActive))
335
OUTB(vgaIOBase + 4,0);
336
pReg->tridentRegs3x4[0x0] = INB(vgaIOBase + 5);
337
OUTB(vgaIOBase + 4,3);
338
pReg->tridentRegs3x4[0x3] = INB(vgaIOBase + 5);
339
OUTB(vgaIOBase + 4,4);
340
pReg->tridentRegs3x4[0x4] = INB(vgaIOBase + 5);
341
OUTB(vgaIOBase + 4,5);
342
pReg->tridentRegs3x4[0x5] = INB(vgaIOBase + 5);
343
OUTB(vgaIOBase + 4,0x6);
344
pReg->tridentRegs3x4[0x6] = INB(vgaIOBase + 5);
350
pReg->tridentRegs3x4[0x0] = LCD[i].shadow_0;
351
pReg->tridentRegs3x4[0x1] = regp->CRTC[1];
352
pReg->tridentRegs3x4[0x2] = regp->CRTC[2];
353
pReg->tridentRegs3x4[0x3] = LCD[i].shadow_3;
354
pReg->tridentRegs3x4[0x4] = LCD[i].shadow_4;
355
pReg->tridentRegs3x4[0x5] = LCD[i].shadow_5;
356
pReg->tridentRegs3x4[0x6] = LCD[i].shadow_6;
357
xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,
358
"Overriding Horizontal timings.\n");
363
pReg->tridentRegs3x4[0x7] = LCD[i].shadow_7;
364
pReg->tridentRegs3x4[0x10] = LCD[i].shadow_10;
365
pReg->tridentRegs3x4[0x11] = LCD[i].shadow_11;
366
pReg->tridentRegs3x4[0x12] = regp->CRTC[0x12];
367
pReg->tridentRegs3x4[0x15] = regp->CRTC[0x15];
368
pReg->tridentRegs3x4[0x16] = LCD[i].shadow_16;
370
pReg->tridentRegs3x4[CRTHiOrd] = LCD[i].shadow_HiOrd;
373
fullSize = (pScrn->currentMode->HDisplay == LCD[i].display_x)
374
&& (pScrn->currentMode->VDisplay == LCD[i].display_y);
377
/* copy over common bits from normal VGA */
379
pReg->tridentRegs3x4[0x7] &= ~0x4A;
380
pReg->tridentRegs3x4[0x7] |= (vgaReg->CRTC[0x7] & 0x4A);
382
if (LCDActive && fullSize) {
383
regp->CRTC[0] = pReg->tridentRegs3x4[0];
384
regp->CRTC[3] = pReg->tridentRegs3x4[3];
385
regp->CRTC[4] = pReg->tridentRegs3x4[4];
386
regp->CRTC[5] = pReg->tridentRegs3x4[5];
387
regp->CRTC[6] = pReg->tridentRegs3x4[6];
388
regp->CRTC[7] = pReg->tridentRegs3x4[7];
389
regp->CRTC[0x10] = pReg->tridentRegs3x4[0x10];
390
regp->CRTC[0x11] = pReg->tridentRegs3x4[0x11];
391
regp->CRTC[0x16] = pReg->tridentRegs3x4[0x16];
393
if (LCDActive && !fullSize) {
395
* Set negative h/vsync polarity to center display nicely
396
* Seems to work on several systems.
398
regp->MiscOutReg |= 0xC0;
400
* If the LCD is active and we don't fill the entire screen
401
* and the previous mode was stretched we may need help from
402
* the BIOS to set all registers for the unstreched mode.
404
pTrident->doInit = ((pReg->tridentRegs3CE[HorStretch] & 1)
405
|| (pReg->tridentRegs3CE[VertStretch] & 1));
406
pReg->tridentRegs3CE[CyberControl] |= 0x81;
407
xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Shadow on\n");
410
pReg->tridentRegs3CE[CyberControl] &= 0x7E;
411
xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Shadow off\n");
413
if (pTrident->FPDelay < 6) {
414
pReg->tridentRegs3CE[CyberControl] &= 0xC7;
415
pReg->tridentRegs3CE[CyberControl] |= (pTrident->FPDelay + 2) << 3;
418
if (pTrident->CyberShadow) {
419
pReg->tridentRegs3CE[CyberControl] &= 0x7E;
421
xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Forcing Shadow off\n");
424
xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"H-timing shadow registers:"
425
" 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
426
pReg->tridentRegs3x4[0], pReg->tridentRegs3x4[3],
427
pReg->tridentRegs3x4[4], pReg->tridentRegs3x4[5]);
428
xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"H-timing registers: "
429
" 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
430
regp->CRTC[0], regp->CRTC[1], regp->CRTC[2],
431
regp->CRTC[3], regp->CRTC[4], regp->CRTC[5]);
432
xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"V-timing shadow registers: "
433
"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x"
434
" 0x%2.2x (0x%2.2x)\n",
435
pReg->tridentRegs3x4[6], pReg->tridentRegs3x4[7],
436
pReg->tridentRegs3x4[0x10],pReg->tridentRegs3x4[0x11],
437
pReg->tridentRegs3x4[0x16],
438
pReg->tridentRegs3x4[CRTHiOrd]);
439
xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"V-timing registers: "
440
"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
441
"0x%2.2x 0x%2.2x 0x%2.2x\n",
442
regp->CRTC[6], regp->CRTC[7], regp->CRTC[0x10],
443
regp->CRTC[0x11],regp->CRTC[0x12],
444
regp->CRTC[0x14],regp->CRTC[0x16]);
447
/* disable stretching, enable centering */
448
pReg->tridentRegs3CE[VertStretch] &= 0xFC;
449
pReg->tridentRegs3CE[VertStretch] |= 0x80;
450
pReg->tridentRegs3CE[HorStretch] &= 0xFC;
451
pReg->tridentRegs3CE[HorStretch] |= 0x80;
454
int mul = pScrn->bitsPerPixel >> 3;
459
/* this is what my BIOS does */
460
val = (pScrn->currentMode->HDisplay * mul / 8) + 16;
462
pReg->tridentRegs3x4[PreEndControl] = ((val >> 8) < 2 ? 2 :0)
463
| ((val >> 8) & 0x01);
464
pReg->tridentRegs3x4[PreEndFetch] = val & 0xff;
467
OUTB(vgaIOBase + 4,PreEndControl);
468
pReg->tridentRegs3x4[PreEndControl] = INB(vgaIOBase + 5);
469
OUTB(vgaIOBase + 4,PreEndFetch);
470
pReg->tridentRegs3x4[PreEndFetch] = INB(vgaIOBase + 5);
473
if (pTrident->Chipset < BLADEXP) {
474
pReg->tridentRegs3CE[BiosMode] = TridentFindMode(
475
pScrn->currentMode->HDisplay,
476
pScrn->currentMode->VDisplay,
478
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1,
479
"Setting BIOS Mode: %x\n",
480
pReg->tridentRegs3CE[BiosMode]);
482
TridentFindNewMode(pScrn->currentMode->HDisplay,
483
pScrn->currentMode->VDisplay,
484
&pReg->tridentRegs3CE[BiosNewMode1],
485
&pReg->tridentRegs3CE[BiosNewMode2]);
486
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1,
487
"Setting BIOS Mode Regs: %x %x\n",
488
pReg->tridentRegs3CE[BiosNewMode1],
489
pReg->tridentRegs3CE[BiosNewMode2]);
493
if (pTrident->Chipset != CYBERBLADEXPAI1)
494
pReg->tridentRegs3CE[BiosReg] = 0;
496
pReg->tridentRegs3CE[BiosReg] = 8;
498
if (pTrident->CyberStretch) {
499
pReg->tridentRegs3CE[VertStretch] |= 0x01;
500
pReg->tridentRegs3CE[HorStretch] |= 0x01;
501
xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Enabling StretchMode\n");
505
/* Enable Chipset specific options */
506
switch (pTrident->Chipset) {
507
case CYBERBLADEXPAI1:
517
OUTB(vgaIOBase + 4, RAMDACTiming);
518
pReg->tridentRegs3x4[RAMDACTiming] = INB(vgaIOBase + 5) | 0x0F;
527
if (pScrn->bitsPerPixel >= 8)
528
pReg->tridentRegs3CE[MiscExtFunc] |= 0x10;
530
pReg->tridentRegs3CE[MiscExtFunc] &= ~0x10;
531
if (!pReg->tridentRegs3x4[PreEndControl])
532
pReg->tridentRegs3x4[PreEndControl] = 0x01;
533
if (!pReg->tridentRegs3x4[PreEndFetch])
534
pReg->tridentRegs3x4[PreEndFetch] = 0xFF;
538
pReg->tridentRegs3x4[Enhancement0] = 0x40;
542
if (pTrident->UsePCIRetry)
543
pReg->tridentRegs3x4[PCIRetry] = 0xDF;
545
pReg->tridentRegs3x4[PCIRetry] = 0x1F;
549
if (pTrident->MUX && pScrn->bitsPerPixel == 8) {
550
pReg->tridentRegs3x4[PixelBusReg] |= 0x01; /* 16bit bus */
551
pReg->tridentRegs3C4[NewMode2] |= 0x02; /* half clock */
552
pReg->tridentRegsDAC[0x00] |= 0x20; /* mux mode */
556
/* Defaults for all trident chipsets follows */
557
switch (pScrn->bitsPerPixel) {
560
offset = pScrn->displayWidth >> 4;
563
pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
564
offset = pScrn->displayWidth >> 3;
567
pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
568
offset = pScrn->displayWidth >> 2;
569
if (pScrn->depth == 15)
570
pReg->tridentRegsDAC[0x00] = 0x10;
572
pReg->tridentRegsDAC[0x00] = 0x30;
573
pReg->tridentRegs3x4[PixelBusReg] = 0x04;
574
/* Reload with any chipset specific stuff here */
575
if (pTrident->Chipset >= TGUI9660)
576
pReg->tridentRegs3x4[PixelBusReg] |= 0x01;
577
if (pTrident->Chipset == TGUI9440AGi) {
578
pReg->tridentRegs3CE[MiscExtFunc] |= 0x08;/*Clock Division / 2*/
579
clock *= 2; /* Double the clock */
583
pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
584
offset = (pScrn->displayWidth * 3) >> 3;
585
pReg->tridentRegs3x4[PixelBusReg] = 0x29;
586
pReg->tridentRegsDAC[0x00] = 0xD0;
587
if (pTrident->Chipset == CYBERBLADEE4) {
588
OUTB(vgaIOBase+ 4, New32);
589
pReg->tridentRegs3x4[New32] = INB(vgaIOBase + 5) & 0x7F;
593
pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
594
if (pTrident->Chipset != CYBERBLADEE4
595
&& pTrident->Chipset != CYBERBLADEXPAI1) {
596
/* Clock Division by 2*/
597
pReg->tridentRegs3CE[MiscExtFunc] |= 0x08;
598
clock *= 2; /* Double the clock */
600
offset = pScrn->displayWidth >> 1;
601
pReg->tridentRegs3x4[PixelBusReg] = 0x09;
602
pReg->tridentRegsDAC[0x00] = 0xD0;
603
if (pTrident->Chipset == CYBERBLADEE4
604
|| pTrident->Chipset == CYBERBLADEXPAI1) {
605
OUTB(vgaIOBase+ 4, New32);
606
pReg->tridentRegs3x4[New32] = INB(vgaIOBase + 5) | 0x80;
607
/* With new mode 32bpp we set the packed flag */
608
pReg->tridentRegs3x4[PixelBusReg] |= 0x20;
612
pReg->tridentRegs3x4[Offset] = offset & 0xFF;
616
TGUISetClock(pScrn, clock, &a, &b);
617
pReg->tridentRegsClock[0x00] = (regp->MiscOutReg & 0xF3) | 0x08;
618
pReg->tridentRegsClock[0x01] = a;
619
pReg->tridentRegsClock[0x02] = b;
620
if (pTrident->MCLK > 0) {
621
TGUISetMCLK(pScrn, pTrident->MCLK, &a, &b);
622
pReg->tridentRegsClock[0x03] = a;
623
pReg->tridentRegsClock[0x04] = b;
627
pReg->tridentRegs3C4[NewMode1] = 0xC0;
628
pReg->tridentRegs3C4[Protection] = 0x92;
630
pReg->tridentRegs3x4[LinearAddReg] = 0;
631
if (pTrident->Linear) {
632
/* This is used for VLB, when we support it again in 4.0 */
633
if (pTrident->Chipset < CYBER9385)
634
pReg->tridentRegs3x4[LinearAddReg] |=
635
((pTrident->FbAddress >> 24) << 6)|
636
((pTrident->FbAddress >> 20) & 0x0F);
637
/* Turn on linear mapping */
638
pReg->tridentRegs3x4[LinearAddReg] |= 0x20;
640
pReg->tridentRegs3CE[MiscExtFunc] |= 0x04;
643
pReg->tridentRegs3x4[CRTCModuleTest] =
644
(mode->Flags & V_INTERLACE ? 0x84 : 0x80);
646
OUTB(vgaIOBase+ 4, InterfaceSel);
647
pReg->tridentRegs3x4[InterfaceSel] = INB(vgaIOBase + 5) | 0x40;
649
OUTB(vgaIOBase+ 4, Performance);
650
pReg->tridentRegs3x4[Performance] = INB(vgaIOBase + 5);
651
if (pTrident->Chipset < BLADEXP)
652
pReg->tridentRegs3x4[Performance] |= 0x10;
654
OUTB(vgaIOBase+ 4, DRAMControl);
655
pReg->tridentRegs3x4[DRAMControl] = INB(vgaIOBase + 5) | 0x10;
657
if (pTrident->IsCyber && !pTrident->MMIOonly)
658
pReg->tridentRegs3x4[DRAMControl] |= 0x20;
660
if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD) {
661
OUTB(vgaIOBase + 4, ClockControl);
662
pReg->tridentRegs3x4[ClockControl] = INB(vgaIOBase + 5) | 0x01;
665
OUTB(vgaIOBase+ 4, AddColReg);
666
pReg->tridentRegs3x4[AddColReg] = INB(vgaIOBase + 5) & 0xEF;
667
pReg->tridentRegs3x4[AddColReg] |= (offset & 0x100) >> 4;
669
if (pTrident->Chipset >= TGUI9660) {
670
pReg->tridentRegs3x4[AddColReg] &= 0xDF;
671
pReg->tridentRegs3x4[AddColReg] |= (offset & 0x200) >> 4;
674
if (IsPciCard && UseMMIO) {
675
if (!pTrident->NoAccel)
676
pReg->tridentRegs3x4[GraphEngReg] |= 0x80;
678
if (!pTrident->NoAccel)
679
pReg->tridentRegs3x4[GraphEngReg] |= 0x82;
682
OUTB(0x3CE, MiscIntContReg);
683
pReg->tridentRegs3CE[MiscIntContReg] = INB(0x3CF) | 0x04;
685
/* Fix hashing problem in > 8bpp on 9320 chipset */
686
if (pTrident->Chipset == CYBER9320 && pScrn->bitsPerPixel > 8)
687
pReg->tridentRegs3CE[MiscIntContReg] &= ~0x80;
689
OUTB(vgaIOBase+ 4, PCIReg);
690
if (IsPciCard && UseMMIO)
691
pReg->tridentRegs3x4[PCIReg] = INB(vgaIOBase + 5) & 0xF9;
693
pReg->tridentRegs3x4[PCIReg] = INB(vgaIOBase + 5) & 0xF8;
695
/* Enable PCI Bursting on capable chips */
696
if (pTrident->Chipset >= TGUI9660) {
697
if(pTrident->UsePCIBurst) {
698
pReg->tridentRegs3x4[PCIReg] |= 0x06;
700
pReg->tridentRegs3x4[PCIReg] &= 0xF9;
704
if (pTrident->Chipset >= CYBER9388) {
705
if (pTrident->GammaBrightnessOn)
706
xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,
707
"Setting Gamma: %f Brightness: %i\n",
708
pTrident->gamma, pTrident->brightness);
709
tridentSetBrightnessAndGamma(pReg,
710
pTrident->GammaBrightnessOn,
711
pTrident->gamma, pTrident->brightness);
716
pReg->tridentRegs3C4[SSetup] = INB(0x3C5) | 0x4;
717
pReg->tridentRegs3C4[SKey] = 0x00;
718
pReg->tridentRegs3C4[SPKey] = 0xC0;
720
pReg->tridentRegs3C4[Threshold] = INB(0x3C5);
721
if (pScrn->bitsPerPixel > 16)
722
pReg->tridentRegs3C4[Threshold] =
723
(pReg->tridentRegs3C4[Threshold] & 0xf0) | 0x2;
726
if (pTrident->Chipset > PROVIDIA9685) {
727
OUTB(0x3C4, Protection);
728
OUTB(0x3C5, protect);
735
TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg)
737
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
740
vgaIOBase = VGAHWPTR(pScrn)->IOBase;
742
if (pTrident->Chipset > PROVIDIA9685) {
743
OUTB(0x3C4, Protection);
747
if (pTrident->doInit && pTrident->Int10) {
755
/* Unprotect registers */
756
OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1);
763
OUTB(0x3C6, tridentReg->tridentRegsDAC[0x00]);
766
OUTW_3x4(CRTCModuleTest);
767
OUTW_3x4(LinearAddReg);
769
OUTW_3x4(CursorControl);
771
OUTW_3x4(HorizOverflow);
773
OUTW_3x4(GraphEngReg);
774
OUTW_3x4(Performance);
775
OUTW_3x4(InterfaceSel);
776
OUTW_3x4(DRAMControl);
777
OUTW_3x4(PixelBusReg);
780
OUTW_3CE(MiscIntContReg);
781
OUTW_3CE(MiscExtFunc);
783
if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD)
784
OUTW_3x4(ClockControl);
785
if (pTrident->Chipset >= CYBER9388) {
790
OUTW_3x4(PreEndControl);
791
OUTW_3x4(PreEndFetch);
796
OUTW_3C4(GBintercept1);
797
OUTW_3C4(GBintercept2);
798
OUTW_3C4(GBintercept3);
799
OUTW_3C4(GBintercept4);
801
if (pTrident->Chipset >= CYBER9385) OUTW_3x4(Enhancement0);
802
if (pTrident->Chipset >= BLADE3D) OUTW_3x4(RAMDACTiming);
803
if (pTrident->Chipset == CYBERBLADEE4) OUTW_3x4(New32);
804
if (pTrident->IsCyber) {
807
OUTW_3CE(VertStretch);
808
OUTW_3CE(HorStretch);
809
if (pTrident->Chipset < BLADEXP) {
812
OUTW_3CE(BiosNewMode1);
813
OUTW_3CE(BiosNewMode2);
817
OUTW_3CE(CyberControl);
818
OUTW_3CE(CyberEnhance);
821
if (pTrident->shadowNew) {
832
if (pTrident->shadowNew) {
842
if (!pTrident->DontSetClock)
845
OUTW(0x3C4, (tridentReg->tridentRegsClock[0x01])<<8 | ClockLow);
846
OUTW(0x3C4, (tridentReg->tridentRegsClock[0x02])<<8 | ClockHigh);
848
if (pTrident->MCLK > 0) {
849
OUTW(0x3C4,(tridentReg->tridentRegsClock[0x03])<<8 | MCLKLow);
850
OUTW(0x3C4,(tridentReg->tridentRegsClock[0x04])<<8 | MCLKHigh);
854
if (!pTrident->DontSetClock)
857
OUTB(0x43C8, tridentReg->tridentRegsClock[0x01]);
858
OUTB(0x43C9, tridentReg->tridentRegsClock[0x02]);
860
if (pTrident->MCLK > 0) {
861
OUTB(0x43C6, tridentReg->tridentRegsClock[0x03]);
862
OUTB(0x43C7, tridentReg->tridentRegsClock[0x04]);
866
if (!pTrident->DontSetClock)
869
OUTB(0x3C2, tridentReg->tridentRegsClock[0x00]);
872
if (pTrident->Chipset > PROVIDIA9685) {
873
OUTB(0x3C4, Protection);
874
OUTB(0x3C5, tridentReg->tridentRegs3C4[Protection]);
877
OUTW(0x3C4, ((tridentReg->tridentRegs3C4[NewMode1] ^ 0x02) << 8)| NewMode1);
881
TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg)
883
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
886
vgaIOBase = VGAHWPTR(pScrn)->IOBase;
893
if (pTrident->Chipset > PROVIDIA9685)
896
/* Unprotect registers */
897
OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1);
898
if (pTrident->Chipset > PROVIDIA9685)
899
OUTW(0x3C4, (0x92 << 8) | Protection);
902
INB_3x4(LinearAddReg);
903
INB_3x4(CRTCModuleTest);
905
INB_3x4(HorizOverflow);
906
INB_3x4(Performance);
907
INB_3x4(InterfaceSel);
908
INB_3x4(DRAMControl);
910
INB_3x4(PixelBusReg);
911
INB_3x4(GraphEngReg);
914
if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD)
915
INB_3x4(ClockControl);
916
if (pTrident->Chipset >= CYBER9388) {
921
INB_3x4(PreEndControl);
922
INB_3x4(PreEndFetch);
927
INB_3C4(GBintercept1);
928
INB_3C4(GBintercept2);
929
INB_3C4(GBintercept3);
930
INB_3C4(GBintercept4);
932
if (pTrident->Chipset >= CYBER9385) INB_3x4(Enhancement0);
933
if (pTrident->Chipset >= BLADE3D) INB_3x4(RAMDACTiming);
934
if (pTrident->Chipset == CYBERBLADEE4) INB_3x4(New32);
935
if (pTrident->IsCyber) {
937
INB_3CE(VertStretch);
939
if (pTrident->Chipset < BLADEXP) {
942
INB_3CE(BiosNewMode1);
943
INB_3CE(BiosNewMode2);
947
INB_3CE(CyberControl);
948
INB_3CE(CyberEnhance);
951
if (pTrident->shadowNew) {
962
if (pTrident->shadowNew) {
970
/* save cursor registers */
971
INB_3x4(CursorControl);
973
INB_3CE(MiscExtFunc);
974
INB_3CE(MiscIntContReg);
981
tridentReg->tridentRegsDAC[0x00] = INB(0x3C6);
984
tridentReg->tridentRegsClock[0x00] = INB(0x3CC);
986
OUTB(0x3C4, ClockLow);
987
tridentReg->tridentRegsClock[0x01] = INB(0x3C5);
988
OUTB(0x3C4, ClockHigh);
989
tridentReg->tridentRegsClock[0x02] = INB(0x3C5);
990
if (pTrident->MCLK > 0) {
991
OUTB(0x3C4, MCLKLow);
992
tridentReg->tridentRegsClock[0x03] = INB(0x3C5);
993
OUTB(0x3C4, MCLKHigh);
994
tridentReg->tridentRegsClock[0x04] = INB(0x3C5);
997
tridentReg->tridentRegsClock[0x01] = INB(0x43C8);
998
tridentReg->tridentRegsClock[0x02] = INB(0x43C9);
999
if (pTrident->MCLK > 0) {
1000
tridentReg->tridentRegsClock[0x03] = INB(0x43C6);
1001
tridentReg->tridentRegsClock[0x04] = INB(0x43C7);
1007
/* Protect registers */
1012
TridentShowCursor(ScrnInfoPtr pScrn)
1014
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1016
vgaIOBase = VGAHWPTR(pScrn)->IOBase;
1019
OUTW(vgaIOBase + 4, 0xC150);
1023
TridentHideCursor(ScrnInfoPtr pScrn) {
1025
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1026
vgaIOBase = VGAHWPTR(pScrn)->IOBase;
1028
OUTW(vgaIOBase + 4, 0x4150);
1032
TridentSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
1035
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1036
vgaIOBase = VGAHWPTR(pScrn)->IOBase;
1039
OUTW(vgaIOBase + 4, (-x)<<8 | 0x46);
1042
OUTW(vgaIOBase + 4, 0x0046);
1045
OUTW(vgaIOBase + 4, (-y)<<8 | 0x47);
1048
OUTW(vgaIOBase + 4, 0x0047);
1050
OUTW(vgaIOBase + 4, (x&0xFF)<<8 | 0x40);
1051
OUTW(vgaIOBase + 4, (x&0x0F00) | 0x41);
1052
OUTW(vgaIOBase + 4, (y&0xFF)<<8 | 0x42);
1053
OUTW(vgaIOBase + 4, (y&0x0F00) | 0x43);
1057
TridentSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
1060
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1061
vgaIOBase = VGAHWPTR(pScrn)->IOBase;
1062
OUTW(vgaIOBase + 4, (fg & 0x000000FF)<<8 | 0x48);
1063
OUTW(vgaIOBase + 4, (fg & 0x0000FF00) | 0x49);
1064
OUTW(vgaIOBase + 4, (fg & 0x00FF0000)>>8 | 0x4A);
1065
OUTW(vgaIOBase + 4, (fg & 0xFF000000)>>16 | 0x4B);
1066
OUTW(vgaIOBase + 4, (bg & 0x000000FF)<<8 | 0x4C);
1067
OUTW(vgaIOBase + 4, (bg & 0x0000FF00) | 0x4D);
1068
OUTW(vgaIOBase + 4, (bg & 0x00FF0000)>>8 | 0x4E);
1069
OUTW(vgaIOBase + 4, (bg & 0xFF000000)>>16 | 0x4F);
1073
TridentLoadCursorImage(
1078
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1080
vgaIOBase = VGAHWPTR(pScrn)->IOBase;
1082
memcpy((CARD8 *)pTrident->FbBase + (pScrn->videoRam * 1024) - 4096,
1083
src, pTrident->CursorInfoRec->MaxWidth *
1084
pTrident->CursorInfoRec->MaxHeight / 4);
1086
OUTW(vgaIOBase + 4, (((pScrn->videoRam-4) & 0xFF) << 8) | 0x44);
1087
OUTW(vgaIOBase + 4, ((pScrn->videoRam-4) & 0xFF00) | 0x45);
1091
TridentUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
1093
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1094
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1096
if (pTrident->MUX && pScrn->bitsPerPixel == 8) return FALSE;
1098
if (!pTrident->HWCursor) return FALSE;
1104
TridentHWCursorInit(ScreenPtr pScreen)
1106
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1107
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1108
xf86CursorInfoPtr infoPtr;
1109
int memory = pScrn->displayWidth * pScrn->virtualY * pScrn->bitsPerPixel/8;
1111
if (memory > (pScrn->videoRam * 1024 - 4096)) return FALSE;
1112
infoPtr = xf86CreateCursorInfoRec();
1113
if(!infoPtr) return FALSE;
1115
pTrident->CursorInfoRec = infoPtr;
1117
infoPtr->MaxWidth = 64;
1118
infoPtr->MaxHeight = 64;
1119
infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
1120
HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
1121
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
1122
((pTrident->Chipset == CYBERBLADEE4) ?
1123
HARDWARE_CURSOR_TRUECOLOR_AT_8BPP : 0);
1124
infoPtr->SetCursorColors = TridentSetCursorColors;
1125
infoPtr->SetCursorPosition = TridentSetCursorPosition;
1126
infoPtr->LoadCursorImage = TridentLoadCursorImage;
1127
infoPtr->HideCursor = TridentHideCursor;
1128
infoPtr->ShowCursor = TridentShowCursor;
1129
infoPtr->UseHWCursor = TridentUseHWCursor;
1131
return(xf86InitCursor(pScreen, infoPtr));
1135
Tridentddc1Read(ScrnInfoPtr pScrn)
1137
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1138
int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
1142
OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
1144
OUTB(0x3C4, NewMode1);
1146
OUTB(0x3C5, temp | 0x80);
1148
/* Define SDA as input */
1149
OUTW(vgaIOBase + 4, (0x04 << 8) | I2C);
1151
OUTW(0x3C4, (temp << 8) | NewMode1);
1153
/* Wait until vertical retrace is in progress. */
1154
while (INB(vgaIOBase + 0xA) & 0x08);
1155
while (!(INB(vgaIOBase + 0xA) & 0x08));
1157
/* Get the result */
1158
OUTB(vgaIOBase + 4, I2C);
1159
return ( INB(vgaIOBase + 5) & 0x01 );
1162
void TridentSetOverscan(
1166
vgaHWPtr hwp = VGAHWPTR(pScrn);
1168
if (overscan < 0 || overscan > 255)
1171
hwp->enablePalette(hwp);
1172
hwp->writeAttr(hwp, OVERSCAN, overscan);
1173
hwp->disablePalette(hwp);
1176
void TridentLoadPalette(
1183
vgaHWPtr hwp = VGAHWPTR(pScrn);
1184
TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1186
for(i = 0; i < numColors; i++) {
1187
index = indicies[i];
1192
OUTB(0x3c9, colors[index].red);
1194
OUTB(0x3c9, colors[index].green);
1196
OUTB(0x3c9, colors[index].blue);