2
* Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
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 copyright
7
* notice and this permission notice appear in supporting documentation, and
8
* that the name of Marc Aurele La France not be used in advertising or
9
* publicity pertaining to distribution of the software without specific,
10
* written prior permission. Marc Aurele La France 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
* MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
16
* EVENT SHALL MARC AURELE LA FRANCE 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.
24
* Leif Delgass <ldelgass@retinalburn.net>
31
#include "xorgVersion.h"
35
#include "atimach64.h"
36
#include "atimach64io.h"
38
#include "atistruct.h"
40
#include "atividmem.h"
41
#include "aticonsole.h"
44
#include "mach64_common.h"
52
#include "atioption.h"
60
* This function is a screen saver hook for DIX.
69
ScrnInfoPtr pScreenInfo;
72
if ((Mode != SCREEN_SAVER_ON) && (Mode != SCREEN_SAVER_CYCLE))
73
SetTimeSinceLastInputEvent();
78
pScreenInfo = xf86ScreenToScrn(pScreen);
79
if (!pScreenInfo->vtSema)
82
pATI = ATIPTR(pScreenInfo);
84
ATIMach64SaveScreen(pATI, Mode);
93
* This function sets the adapter's VESA Display Power Management Signaling
99
ScrnInfoPtr pScreenInfo,
106
if (!pScreenInfo || !pScreenInfo->vtSema)
109
pATI = ATIPTR(pScreenInfo);
112
ATIMach64SetDPMSMode(pScreenInfo, pATI, DPMSMode);
119
ATIProbeAndSetActiveDisplays
121
ScrnInfoPtr pScreenInfo,
126
Bool tv_attached, crt_attached, lcd_attached;
128
ATITVStandard tv_std, tv_std_request;
130
if (xf86GetVerbosity() > 3) {
131
xf86ErrorFVerb(4, "\n Before TV-Out queries\n\n");
132
ATIPrintRegisters(pATI);
135
pATI->tvActive = FALSE;
138
/* LT Pro, XL, Mobility specific BIOS functions */
139
if (pATI->Chip == ATI_CHIP_264LTPRO ||
140
pATI->Chip == ATI_CHIP_264XL ||
141
pATI->Chip == ATI_CHIP_MOBILITY) {
143
/* Get attached display(s) - LTPro, XL, Mobility */
144
pVbe->pInt10->num = 0x10;
145
pVbe->pInt10->ax = 0xa083;
146
pVbe->pInt10->cx = 0x0700; /* ch=0x07 - probe all, 0x01 CRT, 0x02 TV, 0x04 LCD */
147
xf86ExecX86int10(pVbe->pInt10);
149
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
150
"Attached displays: ax=0x%04x, cx=0x%04x\n",
151
pVbe->pInt10->ax, pVbe->pInt10->cx);
153
tv_attached = crt_attached = lcd_attached = FALSE;
154
if (pVbe->pInt10->ax & 0xff00) {
155
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
156
"Failed to detect attached displays\n");
159
if (pVbe->pInt10->cx & 0x3)
161
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
166
crt_attached = FALSE;
168
if ((pVbe->pInt10->cx >> 2) & 0x3)
170
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
171
" DFP/LCD attached\n");
175
lcd_attached = FALSE;
177
switch ((pVbe->pInt10->cx >> 4) & 0x3) {
179
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
180
" No TV attached\n");
183
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
184
" TV attached (composite connector)\n");
188
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
189
" TV attached (S-video connector)\n");
193
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
194
" TV attached (S-video/composite connectors)\n");
198
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
199
"Unrecognized return code: 0x%04x\n",
205
/* Get active display - LTPro, XL, Mobility */
206
pVbe->pInt10->num = 0x10;
207
pVbe->pInt10->ax = 0xa084;
208
pVbe->pInt10->bx = 0x0000; /* bh=0x00 get active, bh=0x01 set active */
209
xf86ExecX86int10(pVbe->pInt10);
211
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
212
"Active displays: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
213
pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
215
if (pVbe->pInt10->ax & 0xff00) {
216
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
217
"Failed to detect active display\n");
219
if (pVbe->pInt10->bx & 0x1)
220
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
221
" DFP/LCD is active\n");
223
if (pVbe->pInt10->bx & 0x2)
224
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
227
if (pVbe->pInt10->bx & 0x4) {
229
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
233
/* tv not connected - disable tv */
236
disp_request |= 0x02; /* enable CRT */
237
if (lcd_attached && pATI->OptionPanelDisplay)
238
disp_request |= 0x01; /* enable DFP/LCD */
240
pVbe->pInt10->num = 0x10;
241
pVbe->pInt10->ax = 0xa084;
242
pVbe->pInt10->bx = 0x0100; /* bh=0x01 set active */
243
pVbe->pInt10->cx = disp_request;
244
xf86ExecX86int10(pVbe->pInt10);
246
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
247
"TV not present, disabling: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
248
pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
249
if (pVbe->pInt10->ax & 0xff00) {
250
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
251
"Disabling TV failed\n");
254
pATI->tvActive = TRUE;
257
} else if (tv_attached && (pVbe->pInt10->bx & 0x0400)) {
258
/* tv connected and available - enable TV */
259
disp_request = 0x04; /* enable TV */
262
/* This works, but CRT image is vertically compressed */
264
disp_request |= 0x02; /* enable CRT */
265
/* NOTE: For me, LCD+TV does NOT work */
266
/*if (lcd_attached && pATI->OptionPanelDisplay)
267
disp_request |= 0x01; * enable DFP/LCD */
270
pVbe->pInt10->num = 0x10;
271
pVbe->pInt10->ax = 0xa084;
272
pVbe->pInt10->bx = 0x0100; /* bh=0x01 set active */
273
pVbe->pInt10->cx = disp_request; /* try to activate TV */
274
xf86ExecX86int10(pVbe->pInt10);
276
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
277
"Setting TV active: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
278
pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
279
if (pVbe->pInt10->ax & 0xff00) {
280
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
281
"Setting TV active failed\n");
283
pATI->tvActive = TRUE;
288
} else { /* pATI->Chip < ATI_CHIP_264LTPRO */
289
/* TVOut Hooks - Check for TVOut BIOS/hardware */
290
pVbe->pInt10->num = 0x10;
291
pVbe->pInt10->ax = 0xa019;
292
pVbe->pInt10->cx = 0x0000; /* TVOut BIOS query */
293
xf86ExecX86int10(pVbe->pInt10);
297
if (pVbe->pInt10->ax & 0xff00) {
298
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
299
"Failed to detect TV-Out BIOS\n");
301
switch (pVbe->pInt10->ax & 0x0003) {
303
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
304
"TV-Out BIOS detected and active\n");
306
/* TV attached query */
307
pVbe->pInt10->num = 0x10;
308
pVbe->pInt10->ax = 0xa070;
309
pVbe->pInt10->bx = 0x0002; /* Sub-function: return tv attached info */
310
xf86ExecX86int10(pVbe->pInt10);
312
if (pVbe->pInt10->ax & 0xff00) {
313
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
314
"Failed to detect if TV is attached\n");
316
switch (pVbe->pInt10->cx & 0x0003) {
318
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
319
"TV attached to composite and S-video connectors\n");
323
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
324
"TV attached to S-video connector\n");
328
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
329
"TV attached to composite connector\n");
333
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
334
"TV is not attached\n");
339
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
340
"TV-Out BIOS service is not available due to"
341
"a system BIOS error or TV-Out hardware not being installed\n");
344
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
345
"No TV-Out BIOS or hardware detected\n");
350
/* Return TV-Out configuration
351
* see Programmer's Guide under "TV Out Specific Functions"
352
* It's not clear exactly which adapters support these
354
pVbe->pInt10->num = 0x10;
355
pVbe->pInt10->ax = 0xa070;
356
pVbe->pInt10->bx = 0x00;
357
xf86ExecX86int10(pVbe->pInt10);
359
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
360
"TV-Out query: ax=0x%04x, bx=0x%04x, cx=0x%04x, dx=0x%04x\n",
361
pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx, pVbe->pInt10->dx);
363
if (pVbe->pInt10->ax & 0xff00) {
365
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
366
"Failed to detect TV-Out configuration.\n");
368
} else if (pVbe->pInt10->bx == 0) {
369
if (pVbe->pInt10->dx == 0) {
370
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
371
"TV-Out is not detected.\n");
373
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
374
"TV-Out is detected but not supported.\n");
377
} else if ((pVbe->pInt10->cx & 0xff) == 0) {
379
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
380
"TV-Out is currently disabled.\n");
381
if (tv_attached && pATI->Chip < ATI_CHIP_264LTPRO) {
382
/* Try to enable TV-Out */
383
pVbe->pInt10->num = 0x10;
384
pVbe->pInt10->ax = 0xa070;
385
pVbe->pInt10->bx = 0x0001; /* Sub-function: Select TV Out */
386
/* cl=0x001 enable, cl=0x000 disable,
387
* cl=0x080 disable with feature connector bit preserved
389
pVbe->pInt10->cx = 0x0001;
391
xf86ExecX86int10(pVbe->pInt10);
392
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
393
"Setting TV active: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
394
pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
396
if (pVbe->pInt10->ax & 0xff00) {
397
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
398
"Setting TV active failed\n");
400
pATI->tvActive = TRUE;
405
pATI->tvActive = TRUE;
407
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
408
"TV-Out is currently enabled (TV-Out revision code: %d).\n",
409
(pVbe->pInt10->dx >> 8) & 0xff);
411
switch ((pVbe->pInt10->cx >> 8) & 0xff) {
413
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 29.49892\n");
416
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 28.63636\n");
419
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 14.31818\n");
422
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 27.00000\n");
425
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
426
"Unknown reference frequency cx=0x%04x\n", pVbe->pInt10->cx);
430
/* Return TV standard
431
* see Programmer's Guide under "TV Out Specific Functions"
432
* It's not clear exactly which adapters support these
434
pVbe->pInt10->num = 0x10;
435
pVbe->pInt10->ax = 0xa071;
436
pVbe->pInt10->bx = 0x00;
437
xf86ExecX86int10(pVbe->pInt10);
439
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
440
"TV standard query result: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
441
pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
443
if (pVbe->pInt10->ax & 0xff00) {
445
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
446
"Failed to return TV standard.\n");
448
tv_std = pVbe->pInt10->cx & 0x00ff;
450
case ATI_TV_STD_NTSC:
452
case ATI_TV_STD_PALM:
453
case ATI_TV_STD_PAL60:
454
case ATI_TV_STD_NTSCJ:
455
case ATI_TV_STD_PALCN:
456
case ATI_TV_STD_PALN:
457
case ATI_TV_STD_SCARTPAL:
458
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
459
"Current TV standard: %s\n", ATITVStandardNames[tv_std]);
462
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
463
"Unrecognized TV standard return code cx=0x%04x\n",
467
tv_std_request = pATI->OptionTvStd;
468
if (tv_std_request < 0 ||
469
tv_std_request > ATI_TV_STD_NONE ||
470
tv_std_request == ATI_TV_STD_RESERVED1 ||
471
tv_std_request == ATI_TV_STD_RESERVED2) {
472
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
473
"Invalid TV standard requested, please check configuration file\n");
474
} else if (tv_std_request != ATI_TV_STD_NONE) {
475
/* Set TV standard if requested (LT Pro not supported) */
476
if (pATI->Chip != ATI_CHIP_264LTPRO &&
477
tv_std_request != tv_std) {
479
pVbe->pInt10->num = 0x10;
480
pVbe->pInt10->ax = 0xa070;
481
pVbe->pInt10->bx = 0x0003; /* sub-function: set TV standard */
482
pVbe->pInt10->cx = tv_std_request;
483
xf86ExecX86int10(pVbe->pInt10);
484
if (pVbe->pInt10->ax & 0xff00)
485
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
486
"Failed to set TV standard\n");
488
xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
489
"Set TV standard to %s\n", ATITVStandardNames[tv_std_request]);
491
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
492
"Setting TV standard not supported on ATI Rage LT Pro\n");
499
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded\n");
506
* ATIEnterGraphics --
508
* This function sets the hardware to a graphics video state.
514
ScrnInfoPtr pScreenInfo,
519
if (!ATIMapApertures(pScreenInfo->scrnIndex, pATI))
525
/* Calculate hardware data */
527
!ATIModeCalculate(pScreenInfo->scrnIndex, pATI, &pATI->NewHW,
528
pScreenInfo->currentMode))
531
pScreenInfo->vtSema = TRUE;
534
if (pATI->OptionTvOut) {
537
if (VBEGetVBEMode(pATI->pVBE, &pATI->vbemode)) {
538
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Saving VESA mode: 0x%x\n",
545
/* Save current state */
546
ATIModeSave(pScreenInfo, pATI, &pATI->OldHW);
549
if (pATI->OptionTvOut)
550
ATIProbeAndSetActiveDisplays(pScreenInfo, pATI);
553
/* Set graphics state */
554
ATIModeSet(pScreenInfo, pATI, &pATI->NewHW);
556
/* Possibly blank the screen */
558
(void)ATISaveScreen(pScreen, SCREEN_SAVER_ON);
560
/* Position the screen */
561
(*pScreenInfo->AdjustFrame)(ADJUST_FRAME_ARGS(pScreenInfo,
562
pScreenInfo->frameX0, pScreenInfo->frameY0));
564
SetTimeSinceLastInputEvent();
570
* ATILeaveGraphics --
572
* This function restores the hardware to its previous state.
577
ScrnInfoPtr pScreenInfo,
581
if (pScreenInfo->vtSema)
583
/* If not exiting, save graphics video state */
584
if (!xf86ServerIsExiting())
585
ATIModeSave(pScreenInfo, pATI, &pATI->NewHW);
588
if (pATI->OptionTvOut)
589
ATIProbeAndSetActiveDisplays(pScreenInfo, pATI);
592
/* Restore mode in effect on server entry */
593
ATIModeSet(pScreenInfo, pATI, &pATI->OldHW);
595
pScreenInfo->vtSema = FALSE;
601
/* Unmap apertures */
605
if (!pATI->Closeable)
607
#else /* AVOID_DGA */
609
if (!pATI->Closeable || !pATI->nDGAMode)
611
#endif /* AVOID_DGA */
613
ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);
615
SetTimeSinceLastInputEvent();
621
* This function switches to another graphics video state.
624
ATISwitchMode(SWITCH_MODE_ARGS_DECL)
627
ATIPtr pATI = ATIPTR(pScreenInfo);
629
/* Calculate new hardware data */
630
if (!ATIModeCalculate(pScreenInfo->scrnIndex, pATI, &pATI->NewHW, pMode))
633
/* Set new hardware state */
634
if (pScreenInfo->vtSema)
636
pScreenInfo->currentMode = pMode;
640
if (pATI->directRenderingEnabled)
642
DRILock(pScreenInfo->pScreen,0);
643
ATIDRIWaitForIdle(pATI);
646
#endif /* XF86DRI_DEVEL */
648
/* XXX Workaround for X server not hiding the cursor for Xcursor (but
649
* only for core cursor), leaving a 64x64 garbage upper-left.
651
if (pATI->pCursorInfo)
652
(*pATI->pCursorInfo->HideCursor)(pScreenInfo);
654
ATIModeSet(pScreenInfo, pATI, &pATI->NewHW);
658
if (pATI->directRenderingEnabled)
660
DRIUnlock(pScreenInfo->pScreen);
663
#endif /* XF86DRI_DEVEL */
667
SetTimeSinceLastInputEvent();
675
* This function sets the server's virtual console to a graphics video state.
678
ATIEnterVT(VT_FUNC_ARGS_DECL)
681
ScreenPtr pScreen = pScreenInfo->pScreen;
682
ATIPtr pATI = ATIPTR(pScreenInfo);
683
PixmapPtr pScreenPixmap;
684
#if (XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 99, 1, 0))
685
DevUnion PixmapPrivate;
689
if (!ATIEnterGraphics(NULL, pScreenInfo, pATI))
692
/* The rest of this isn't needed for shadowfb */
693
if (pATI->OptionShadowFB)
698
if (pATI->directRenderingEnabled)
700
/* get the Mach64 back into shape after resume */
701
ATIDRIResume(pScreen);
705
#endif /* XF86DRI_DEVEL */
710
pScreenPixmap = (*pScreen->GetScreenPixmap)(pScreen);
712
#if (XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 99, 1, 0))
713
PixmapPrivate = pScreenPixmap->devPrivate;
714
if (!PixmapPrivate.ptr)
715
pScreenPixmap->devPrivate = pScreenInfo->pixmapPrivate;
718
/* Tell framebuffer about remapped aperture */
719
Entered = (*pScreen->ModifyPixmapHeader)(pScreenPixmap,
720
-1, -1, -1, -1, -1, pATI->pMemory);
722
#if (XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 99, 1, 0))
723
if (!PixmapPrivate.ptr)
725
pScreenInfo->pixmapPrivate = pScreenPixmap->devPrivate;
726
pScreenPixmap->devPrivate.ptr = NULL;
732
if (pATI->directRenderingEnabled)
734
/* get the Mach64 back into shape after resume */
735
ATIDRIResume(pScreen);
739
#endif /* XF86DRI_DEVEL */
747
* This function restores the server's virtual console to its state on server
751
ATILeaveVT(VT_FUNC_ARGS_DECL)
754
ScreenPtr pScreen = pScreenInfo->pScreen;
755
ATIPtr pATI = ATIPTR(pScreenInfo);
759
if (pATI->directRenderingEnabled)
762
ATIDRIWaitForIdle(pATI);
765
#endif /* XF86DRI_DEVEL */
767
ATILeaveGraphics(pScreenInfo, ATIPTR(pScreenInfo));
773
* This function frees all driver data related to a screen.
776
ATIFreeScreen(FREE_SCREEN_ARGS_DECL)
779
ATIPtr pATI = ATIPTR(pScreenInfo);
781
ATII2CFreeScreen(pScreenInfo->scrnIndex);
785
free(pATI->OldHW.frame_buffer);
786
free(pATI->NewHW.frame_buffer);
788
#endif /* AVOID_CPIO */
794
free(pATI->pDGAMode);
796
#endif /* AVOID_DGA */
799
pScreenInfo->driverPrivate = NULL;