This is nothing more than a HUNK fixed copy of the TVOut patch found on
leif's linux page.  With this patch the TVOut and other related options
are evaluated and it is posible to use atitvout while in X.  However I
notesed some problems with this patch that only a reboot would fix.  There
was coruption of 2d texture offsets making the FB filled with odd things
from display memory.  Something like the GDM login name prompt came in
clearly while the rest of the screen was messed up.  I'l see if I can't
get some screenshots of this.


__________________________________
Do you Yahoo!?
Yahoo! Finance Tax Center - File online. File on time.
http://taxes.yahoo.com/filing.html
Index: Imakefile
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v
retrieving revision 1.16.10.1
diff -u -r1.16.10.1 Imakefile
--- Imakefile   6 Feb 2004 11:15:40 -0000       1.16.10.1
+++ Imakefile   21 Mar 2004 00:21:51 -0000
@@ -147,7 +147,24 @@
 
 #endif
 
-DEFINES = $(CPIODEFINES) $(DGADEFINES) $(NONPCIDEFINES) $(DRIDEFINES)
+/* 
+ * TV-out only supported on x86
+ */
+#if ATIAvoidCPIO
+# undef ATITVOut
+# define ATITVOut NO
+#elif defined(i386Architecture)
+# undef ATITVOut
+# define ATITVOut YES
+#endif
+
+#if ATITVOut
+
+TVOUTDEFINES = -DTV_OUT
+
+#endif
+
+DEFINES = $(CPIODEFINES) $(DGADEFINES) $(NONPCIDEFINES) $(DRIDEFINES) $(TVOUTDEFINES)
 
 SRCS1 = ati.c atiadapter.c atibus.c atichip.c atiident.c atioption.c \
         atiprobe.c atividmem.c $(CPIOSRCS1) $(MODSRCS1) \
Index: aticonfig.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/aticonfig.c,v
retrieving revision 1.2.12.3
diff -u -r1.2.12.3 aticonfig.c
--- aticonfig.c 14 Feb 2004 09:31:58 -0000      1.2.12.3
+++ aticonfig.c 21 Mar 2004 00:21:52 -0000
@@ -123,6 +123,13 @@
 
 #endif /* XF86DRI */
 
+#ifdef TV_OUT
+
+#   define TvOut        PublicOption[ATI_OPTION_TV_OUT].value.bool
+#   define TvStd        PublicOption[ATI_OPTION_TV_STD].value.str
+
+#endif /* TV_OUT */
+
 #   define CacheMMIO     PublicOption[ATI_OPTION_MMIO_CACHE].value.bool
 #   define TestCacheMMIO PublicOption[ATI_OPTION_TEST_MMIO_CACHE].value.bool
 #   define PanelDisplay  PublicOption[ATI_OPTION_PANEL_DISPLAY].value.bool
@@ -154,6 +161,11 @@
 
 #endif /* AVOID_CPIO */
 
+#ifdef TV_OUT
+
+       TvStd = "None";  /* No tv standard change requested */
+
+#endif
     }
 
     ReferenceClock = ((double)157500000.0) / ((double)11.0);
@@ -202,6 +214,31 @@
 
 #endif /* AVOID_CPIO */
 
+#ifdef TV_OUT
+
+    if (TvOut && pATI->Chip < ATI_CHIP_264GT) {
+       /* Only allow this for 3D Rage (I) or greater chip ID
+       * AFAIK, no chips before this supported TV-Out
+       * mach64VT has support for TV tuner, but no TV-Out
+       */
+       xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+                "TV Out not supported for this chip.\n");
+    } else {
+       ATITVStandard std;
+       pATI->OptionTvOut = TvOut;
+       pATI->OptionTvStd = ATI_TV_STD_INVALID;
+       for (std = 0; std < ATI_TV_STDS_MAX_VALID; std++) {
+           if (std != ATI_TV_STD_RESERVED1 && std != ATI_TV_STD_RESERVED2) {
+               if (strncasecmp(TvStd, ATITVStandardNames[std], 
ATI_TV_STDS_NAME_MAXLEN)==0) {
+                   pATI->OptionTvStd = std;
+                   break;
+               }
+           }
+       }
+    }
+
+#endif /* TV_OUT */
+
     pATI->OptionMMIOCache = CacheMMIO;
     pATI->OptionTestMMIOCache = TestCacheMMIO;
     pATI->OptionProbeClocks = ProbeClocks;
Index: aticonsole.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.c,v
retrieving revision 1.2.12.2
diff -u -r1.2.12.2 aticonsole.c
--- aticonsole.c        13 Feb 2004 11:49:54 -0000      1.2.12.2
+++ aticonsole.c        21 Mar 2004 00:21:53 -0000
@@ -42,6 +42,20 @@
 
 #include "xf86.h"
 
+#ifdef TV_OUT
+
+#include "atichip.h"
+#include "atiprint.h"
+#include "atioption.h"
+#include "vbe.h"
+
+static const char *vbeSymbols[] = {
+    "VBEGetVBEMode",
+    NULL
+};
+
+#endif /* TV_OUT */
+
 /*
  * ATISaveScreen --
  *
@@ -135,6 +149,398 @@
     }
 }
 
+#ifdef TV_OUT
+
+static void
+ATIProbeAndSetActiveDisplays
+(
+    ScrnInfoPtr pScreenInfo,
+    ATIPtr      pATI
+)
+{
+    vbeInfoPtr pVbe;
+    Bool tv_attached, crt_attached, lcd_attached;
+    int disp_request;
+    ATITVStandard tv_std, tv_std_request;
+
+    xf86LoaderRefSymLists(vbeSymbols, NULL);
+
+    if (xf86GetVerbosity() > 3) {
+       xf86ErrorFVerb(4, "\n Before TV-Out queries\n\n",
+                      pScreenInfo->currentMode->name);
+       ATIPrintRegisters(pATI);
+    }
+
+    pATI->tvActive = FALSE;
+    pVbe = pATI->pVBE;
+    if (pVbe) {
+       /* LT Pro, XL, Mobility specific BIOS functions */
+       if (pATI->Chip == ATI_CHIP_264LTPRO ||
+           pATI->Chip == ATI_CHIP_264XL || 
+           pATI->Chip == ATI_CHIP_MOBILITY) {
+    
+           /* Get attached display(s) - LTPro, XL, Mobility */
+           pVbe->pInt10->num = 0x10;
+           pVbe->pInt10->ax = 0xa083;
+           pVbe->pInt10->cx = 0x0700; /* ch=0x07 - probe all, 0x01 CRT, 0x02 TV, 0x04 
LCD */
+           xf86ExecX86int10(pVbe->pInt10);
+
+           xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                      "Attached displays: ax=0x%04x, cx=0x%04x\n",
+                      pVbe->pInt10->ax, pVbe->pInt10->cx);
+
+           tv_attached = crt_attached = lcd_attached = FALSE;
+           if (pVbe->pInt10->ax & 0xff00) {
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                          "Failed to detect attached displays\n");
+           } else {
+                       
+               if (pVbe->pInt10->cx & 0x3)
+               {
+                       xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                                  "   CRT attached\n");
+                       crt_attached = TRUE;
+               }
+               else
+                   crt_attached = FALSE;
+
+               if ((pVbe->pInt10->cx >> 2) & 0x3)
+               {
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "   DFP/LCD attached\n");
+                   lcd_attached = TRUE;
+               }
+               else
+                   lcd_attached = FALSE;
+
+               switch ((pVbe->pInt10->cx >> 4) & 0x3) {
+               case 0:
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "   No TV attached\n");
+                   break;
+               case 1:
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "   TV attached (composite connector)\n");
+                   tv_attached = TRUE;
+                   break;
+               case 2:
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "   TV attached (S-video connector)\n");
+                   tv_attached = TRUE;
+                   break;
+               case 3:
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "   TV attached (S-video/composite connectors)\n");
+                   tv_attached = TRUE;
+                   break;
+               default:
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                              "Unrecognized return code: 0x%04x\n", 
+                              pVbe->pInt10->cx);
+               }
+
+           }
+
+           /* Get active display  - LTPro, XL, Mobility */
+           pVbe->pInt10->num = 0x10;
+           pVbe->pInt10->ax = 0xa084;
+           pVbe->pInt10->bx = 0x0000; /* bh=0x00 get active, bh=0x01 set active */
+           xf86ExecX86int10(pVbe->pInt10);
+
+           xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                      "Active displays: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
+                      pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
+
+           if (pVbe->pInt10->ax & 0xff00) {
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                          "Failed to detect active display\n");
+           } else {
+               if (pVbe->pInt10->bx & 0x1) 
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,                 
+                              "   DFP/LCD is active\n");
+
+               if (pVbe->pInt10->bx & 0x2) 
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "   CRT is active\n");
+
+               if (pVbe->pInt10->bx & 0x4) {
+                   
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "   TV is active\n");
+
+                   if (!tv_attached) {
+                       /* tv not connected - disable tv */
+                       disp_request = 0x00;
+                       if (crt_attached)
+                           disp_request |= 0x02; /* enable CRT */
+                       if (lcd_attached && pATI->OptionPanelDisplay)
+                           disp_request |= 0x01; /* enable DFP/LCD */
+
+                       pVbe->pInt10->num = 0x10;
+                       pVbe->pInt10->ax = 0xa084;
+                       pVbe->pInt10->bx = 0x0100; /* bh=0x01 set active */
+                       pVbe->pInt10->cx = disp_request; 
+                       xf86ExecX86int10(pVbe->pInt10);
+
+                       xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                                  "TV not present, disabling: ax=0x%04x, bx=0x%04x, 
cx=0x%04x\n",
+                                  pVbe->pInt10->ax, pVbe->pInt10->bx, 
pVbe->pInt10->cx);
+                       if (pVbe->pInt10->ax & 0xff00) {
+                           xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                                      "Disabling TV failed\n");
+                       }
+                   } else {
+                       pATI->tvActive = TRUE;
+                   }
+
+               } else if (tv_attached && (pVbe->pInt10->bx & 0x0400)) {
+                   /* tv connected and available - enable TV */
+                   disp_request = 0x04;          /* enable TV */
+
+#if 0
+                   /* This works, but CRT image is vertically compressed */
+                   if (crt_attached)
+                           disp_request |= 0x02; /* enable CRT */
+                   /* NOTE: For me, LCD+TV does NOT work */
+                   /*if (lcd_attached && pATI->OptionPanelDisplay)
+                           disp_request |= 0x01; * enable DFP/LCD */
+#endif
+
+                   pVbe->pInt10->num = 0x10;
+                   pVbe->pInt10->ax = 0xa084;
+                   pVbe->pInt10->bx = 0x0100; /* bh=0x01 set active */
+                   pVbe->pInt10->cx = disp_request; /* try to activate TV */
+                   xf86ExecX86int10(pVbe->pInt10);
+                   
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "Setting TV active: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
+                              pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
+                   if (pVbe->pInt10->ax & 0xff00) {
+                       xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                                  "Setting TV active failed\n");
+                   } else {
+                       pATI->tvActive = TRUE;
+                   }
+               }
+           }
+
+       } else { /* pATI->Chip < ATI_CHIP_264LTPRO */
+           /* TVOut Hooks - Check for TVOut BIOS/hardware */
+           pVbe->pInt10->num = 0x10;
+           pVbe->pInt10->ax = 0xa019;
+           pVbe->pInt10->cx = 0x0000; /* TVOut BIOS query */
+           xf86ExecX86int10(pVbe->pInt10);
+
+           tv_attached = FALSE;
+
+           if (pVbe->pInt10->ax & 0xff00) {
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                          "Failed to detect TV-Out BIOS\n");
+           } else {
+               switch (pVbe->pInt10->ax & 0x0003) {
+               case 3:
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "TV-Out BIOS detected and active\n");
+
+                   /* TV attached query */
+                   pVbe->pInt10->num = 0x10;
+                   pVbe->pInt10->ax = 0xa070;
+                   pVbe->pInt10->bx = 0x0002; /* Sub-function: return tv attached 
info */
+                   xf86ExecX86int10(pVbe->pInt10);
+
+                   if (pVbe->pInt10->ax & 0xff00) {
+                       xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                                  "Failed to detect if TV is attached\n");
+                   } else {
+                       switch (pVbe->pInt10->cx & 0x0003) {
+                       case 3:
+                           xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                                      "TV attached to composite and S-video 
connectors\n");
+                           tv_attached = TRUE;
+                           break;
+                       case 2:
+                           xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                                      "TV attached to S-video connector\n");
+                           tv_attached = TRUE;
+                           break;
+                       case 1:
+                           xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                                      "TV attached to composite connector\n");
+                           tv_attached = TRUE;
+                           break;
+                       default:
+                           xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                                      "TV is not attached\n");
+                       }
+                   }
+                   break;
+               case 1:
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "TV-Out BIOS service is not available due to" 
+                              "a system BIOS error or TV-Out hardware not being 
installed\n");
+                   break;
+               default:
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "No TV-Out BIOS or hardware detected\n");
+               }
+           }
+       }
+
+       /* Return TV-Out configuration 
+        * see Programmer's Guide under "TV Out Specific Functions"
+        * It's not clear exactly which adapters support these
+        */
+       pVbe->pInt10->num = 0x10;
+       pVbe->pInt10->ax = 0xa070;
+       pVbe->pInt10->bx = 0x00;
+       xf86ExecX86int10(pVbe->pInt10);
+
+       xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                  "TV-Out query: ax=0x%04x, bx=0x%04x, cx=0x%04x, dx=0x%04x\n",
+                  pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx, 
pVbe->pInt10->dx);
+
+       if (pVbe->pInt10->ax & 0xff00) {
+
+           xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                      "Failed to detect TV-Out configuration.\n");
+
+       } else if (pVbe->pInt10->bx == 0) {
+           if (pVbe->pInt10->dx == 0) {
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                          "TV-Out is not detected.\n");
+           } else {
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                          "TV-Out is detected but not supported.\n");
+           }
+
+       } else if ((pVbe->pInt10->cx & 0xff) == 0) {
+
+           xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                      "TV-Out is currently disabled.\n");
+           if (tv_attached && pATI->Chip < ATI_CHIP_264LTPRO) {
+               /* Try to enable TV-Out */
+               pVbe->pInt10->num = 0x10;
+               pVbe->pInt10->ax = 0xa070;
+               pVbe->pInt10->bx = 0x0001; /* Sub-function: Select TV Out */
+               /* cl=0x001 enable, cl=0x000 disable, 
+                * cl=0x080 disable with feature connector bit preserved 
+                */
+               pVbe->pInt10->cx = 0x0001;
+                       
+               xf86ExecX86int10(pVbe->pInt10);
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                          "Setting TV active: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
+                          pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
+
+               if (pVbe->pInt10->ax & 0xff00) {
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                              "Setting TV active failed\n");
+               } else {
+                   pATI->tvActive = TRUE;
+               }
+           }
+
+       } else {
+           pATI->tvActive = TRUE;
+
+           xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                      "TV-Out is currently enabled (TV-Out revision code: %d).\n",
+                      (pVbe->pInt10->dx >> 8) & 0xff);
+
+           switch ((pVbe->pInt10->cx >> 8) & 0xff) {
+           case 0:
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 
29.49892\n");
+               break;
+           case 1:
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 
28.63636\n");
+               break;
+           case 2:
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 
14.31818\n");
+               break;
+           case 3:
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Reference frequency 
27.00000\n");
+               break;
+           default:
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                          "Unknown reference frequency cx=0x%04x\n", 
pVbe->pInt10->cx);
+                   
+           }
+
+           /* Return TV standard
+            * see Programmer's Guide under "TV Out Specific Functions"
+            * It's not clear exactly which adapters support these
+            */
+           pVbe->pInt10->num = 0x10;
+           pVbe->pInt10->ax = 0xa071;
+           pVbe->pInt10->bx = 0x00;
+           xf86ExecX86int10(pVbe->pInt10);
+
+           xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                      "TV standard query result: ax=0x%04x, bx=0x%04x, cx=0x%04x\n",
+                      pVbe->pInt10->ax, pVbe->pInt10->bx, pVbe->pInt10->cx);
+
+           if (pVbe->pInt10->ax & 0xff00) {
+
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                          "Failed to return TV standard.\n");
+           } else {
+               tv_std = pVbe->pInt10->cx & 0x00ff;
+               switch (tv_std) {
+               case ATI_TV_STD_NTSC:
+               case ATI_TV_STD_PAL:
+               case ATI_TV_STD_PALM:
+               case ATI_TV_STD_PAL60:
+               case ATI_TV_STD_NTSCJ:
+               case ATI_TV_STD_PALCN:
+               case ATI_TV_STD_PALN:
+               case ATI_TV_STD_SCARTPAL:
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                              "Current TV standard: %s\n", 
ATITVStandardNames[tv_std]);
+                   break;
+               default:
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                              "Unrecognized TV standard return code cx=0x%04x\n", 
+                              pVbe->pInt10->cx);
+               }
+
+               tv_std_request = pATI->OptionTvStd;
+               if (tv_std_request < 0 || 
+                   tv_std_request > ATI_TV_STD_NONE || 
+                   tv_std_request == ATI_TV_STD_RESERVED1 || 
+                   tv_std_request == ATI_TV_STD_RESERVED2) {
+                   xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                              "Invalid TV standard requested, please check 
configuration file\n");
+               } else if (tv_std_request != ATI_TV_STD_NONE) {
+                   /* Set TV standard if requested (LT Pro not supported) */
+                   if (pATI->Chip != ATI_CHIP_264LTPRO &&
+                       tv_std_request != tv_std) {
+                               
+                       pVbe->pInt10->num = 0x10;
+                       pVbe->pInt10->ax = 0xa070;
+                       pVbe->pInt10->bx = 0x0003; /* sub-function: set TV standard */
+                       pVbe->pInt10->cx = tv_std_request;
+                       xf86ExecX86int10(pVbe->pInt10);
+                       if (pVbe->pInt10->ax & 0xff00)
+                           xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                                      "Failed to set TV standard\n");
+                       else
+                           xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG, 
+                                      "Set TV standard to %s\n", 
ATITVStandardNames[tv_std_request]);
+                   } else {
+                       xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 
+                                  "Setting TV standard not supported on ATI Rage LT 
Pro\n");
+                   }
+               }
+           }
+           
+       }
+    } else {
+       xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded\n");
+    }
+}
+
+#endif /* TV_OUT */
+
 /*
  * ATIEnterGraphics --
  *
@@ -163,9 +569,28 @@
 
     pScreenInfo->vtSema = TRUE;
 
+#ifdef TV_OUT
+    if (pATI->OptionTvOut) {
+
+       xf86LoaderRefSymLists(vbeSymbols, NULL);
+
+       if (pATI->pVBE) {
+           if (VBEGetVBEMode(pATI->pVBE, &pATI->vbemode)) {
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Saving VESA mode: 0x%x\n", 
+                          pATI->vbemode);
+           }
+       }
+    }
+#endif /* TV_OUT */
+
     /* Save current state */
     ATIModeSave(pScreenInfo, pATI, &pATI->OldHW);
 
+#ifdef TV_OUT
+    if (pATI->OptionTvOut) 
+       ATIProbeAndSetActiveDisplays(pScreenInfo, pATI);
+#endif /* TV_OUT */
+
     /* Set graphics state */
     ATIModeSet(pScreenInfo, pATI, &pATI->NewHW);
 
@@ -200,6 +625,11 @@
         if (!xf86ServerIsExiting())
             ATIModeSave(pScreenInfo, pATI, &pATI->NewHW);
 
+#ifdef TV_OUT
+       if (pATI->OptionTvOut) 
+           ATIProbeAndSetActiveDisplays(pScreenInfo, pATI);
+#endif /* TV_OUT */
+
         /* Restore mode in effect on server entry */
         ATIModeSet(pScreenInfo, pATI, &pATI->OldHW);
 
Index: atilock.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.c,v
retrieving revision 1.2.12.2
diff -u -r1.2.12.2 atilock.c
--- atilock.c   8 Feb 2004 12:12:54 -0000       1.2.12.2
+++ atilock.c   21 Mar 2004 00:21:53 -0000
@@ -154,9 +154,14 @@
              */
             if (pATI->Chip != ATI_CHIP_264XL)
             {
-                pATI->LockData.scratch_reg3 = inr(SCRATCH_REG3);
-                outr(SCRATCH_REG3,
-                    pATI->LockData.scratch_reg3 | DISPLAY_SWITCH_DISABLE);
+#ifdef TV_OUT
+               pATI->LockData.scratch_reg3 = inr(SCRATCH_REG3) & 
~DISPLAY_SWITCH_DISABLE;
+               outr(SCRATCH_REG3, pATI->LockData.scratch_reg3);
+#else
+               pATI->LockData.scratch_reg3 = inr(SCRATCH_REG3);
+               outr(SCRATCH_REG3,
+                    pATI->LockData.scratch_reg3 | DISPLAY_SWITCH_DISABLE);
+#endif /* TV_OUT */
             }
         }
 
@@ -575,14 +580,18 @@
         if ((pATI->LCDPanelID >= 0) && (pATI->Chip != ATI_CHIP_264LT))
         {
             outr(LCD_INDEX, pATI->LockData.lcd_index);
+#ifndef TV_OUT
             if (pATI->Chip != ATI_CHIP_264XL)
                 outr(SCRATCH_REG3, pATI->LockData.scratch_reg3);
+#endif /* TV_OUT */
         }
         if (pATI->Chip >= ATI_CHIP_264VTB)
         {
             outr(MPP_CONFIG, pATI->LockData.mpp_config);
             outr(MPP_STROBE_SEQ, pATI->LockData.mpp_strobe_seq);
+#ifndef TV_OUT
             outr(TVO_CNTL, pATI->LockData.tvo_cntl);
+#endif /* TV_OUT */
             if (pATI->Chip >= ATI_CHIP_264GT2C)
             {
                 outr(HW_DEBUG, pATI->LockData.hw_debug);
Index: atimach64.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c,v
retrieving revision 1.2.12.1
diff -u -r1.2.12.1 atimach64.c
--- atimach64.c 8 Feb 2004 11:12:36 -0000       1.2.12.1
+++ atimach64.c 21 Mar 2004 00:21:55 -0000
@@ -617,7 +617,11 @@
     {
         pMode->Flags &= ~(V_PHSYNC | V_NHSYNC | V_PVSYNC | V_NVSYNC);
 
-        if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
+        if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0)
+#ifdef TV_OUT
+       && !pATI->tvActive
+#endif
+)
             VDisplay = pATI->LCDVertical;
         else
             VDisplay = pMode->CrtcVDisplay;
Index: atimode.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/atimode.c,v
retrieving revision 1.2
diff -u -r1.2 atimode.c
--- atimode.c   12 Sep 2003 20:07:15 -0000      1.2
+++ atimode.c   21 Mar 2004 00:21:56 -0000
@@ -35,6 +35,18 @@
 #include "atiwonder.h"
 #include "atiwonderio.h"
 
+#ifdef TV_OUT
+
+#include "vbe.h"
+
+static const char *vbeSymbols[] = {
+    "VBESetVBEMode",
+    "vbeFree",
+    NULL
+};
+
+#endif /* TV_OUT */
+
 #ifndef AVOID_CPIO
 
 /*
@@ -908,11 +920,17 @@
         else
             MaxScalerClock = 80000;     /* Conservative */
         pATIHW->pll_vclk_cntl &= ~PLL_ECP_DIV;
-        /* XXX Don't do this for TVOut! */
-        ECPClock = pMode->SynthClock;
-        for (Index = 0;  (ECPClock > MaxScalerClock) && (Index < 2);  Index++)
-            ECPClock >>= 1;
-        pATIHW->pll_vclk_cntl |= SetBits(Index, PLL_ECP_DIV);
+#ifdef TV_OUT
+       if (!pATI->OptionTvOut) {
+#endif /* TV_OUT */
+          /* XXX Don't do this for TVOut! */
+          ECPClock = pMode->SynthClock;
+          for (Index = 0;  (ECPClock > MaxScalerClock) && (Index < 2);  Index++)
+             ECPClock >>= 1;
+          pATIHW->pll_vclk_cntl |= SetBits(Index, PLL_ECP_DIV);
+#ifdef TV_OUT
+       }
+#endif /* TV_OUT */
     }
     else if (pATI->DAC == ATI_DAC_IBMRGB514)
     {
@@ -922,6 +940,108 @@
     return TRUE;
 }
 
+#ifdef TV_OUT
+
+static void
+ATISetVBEMode
+(
+    ScrnInfoPtr pScreenInfo,
+    ATIPtr      pATI,
+    ATIHWPtr    pATIHW
+)
+{
+
+    xf86LoaderRefSymLists(vbeSymbols, NULL);
+
+    if (pATIHW->crtc == ATI_CRTC_MACH64) {
+       int vbemode, modekey;
+
+       /* Find a suitable VESA VBE mode, if one exists */
+       modekey = (pScreenInfo->depth << 16) | 
+           (pScreenInfo->currentMode->HDisplay);
+
+       switch (modekey) {
+       case (15<<16)|(640):
+           vbemode = 0x110;
+           break;
+       case (16<<16)|(640):
+           vbemode = 0x111;
+           break;
+#if 0
+       case (24<<16)|(640):
+           vbemode = 0x112;
+           break;
+#endif
+       case (15<<16)|(800):
+           vbemode = 0x113;
+           break;
+       case (16<<16)|(800):
+           vbemode = 0x114;
+           break;
+#if 0
+       case (24<<16)|(800):
+           vbemode = 0x115;
+           break;
+#endif
+       case (15<<16)|(1024):
+           vbemode = 0x116;
+           break;
+       case (16<<16)|(1024):
+           vbemode = 0x117;
+           break;
+#if 0
+       case (24<<16)|(1024):
+           vbemode = 0x118;
+           break;
+#endif
+       default:
+           xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                      "Mode not supported for TV-Out: depth: %ld HDisplay: %ld\n", 
+                      modekey>>16, modekey & 0xffff);
+           return;
+       }
+
+       if (pATI->pVBE) {
+
+            /* Preserve video memory contents */
+            vbemode |= (1<<15);
+
+           if (VBESetVBEMode(pATI->pVBE, vbemode, NULL)) {
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
+                          "VBESetMode: 0x%X (width: %d, pitch: %d, depth: %d)\n",
+                          vbemode, 
+                          pScreenInfo->currentMode->HDisplay,     
+                          pScreenInfo->displayWidth,
+                          pScreenInfo->depth);
+               outr(CRTC_OFF_PITCH,
+                    SetBits(pScreenInfo->displayWidth>>3, CRTC_PITCH));
+           } else {
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBESetMode failed.\n");
+           }
+       } else {
+           xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded.\n");
+       }
+    } else {
+       /* restore text mode with VBESetMode */
+       if (pATI->pVBE) {
+           if (VBESetVBEMode(pATI->pVBE, pATI->vbemode, NULL)) {
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Restoring VESA mode: 
0x%x\n", 
+                          pATI->vbemode);
+           } else {
+               xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBESetMode failed.\n");
+           }
+       } else {
+           xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded.\n");
+       }
+    }
+    if (xf86ServerIsExiting()) {
+       if (pATI->pVBE) vbeFree(pATI->pVBE);
+       if (pATI->pInt10) xf86FreeInt10(pATI->pInt10);
+    }
+}
+
+#endif /* TV_OUT */
+
 /*
  * ATIModeSet --
  *
@@ -1165,6 +1285,14 @@
     /* Reset hardware cursor caching */
     pATI->CursorXOffset = pATI->CursorYOffset = (CARD16)(-1);
 
+#ifdef TV_OUT
+
+    /* Set VBE mode for TV-Out */
+    if (pATI->OptionTvOut /* && pATI->tvActive */)
+       ATISetVBEMode(pScreenInfo, pATI, pATIHW);
+
+#endif /* TV_OUT */
+
 #ifndef AVOID_CPIO
 
     /* Restore video memory */
Index: atioption.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c,v
retrieving revision 1.2.12.2
diff -u -r1.2.12.2 atioption.c
--- atioption.c 13 Feb 2004 11:49:54 -0000      1.2.12.2
+++ atioption.c 21 Mar 2004 00:21:56 -0000
@@ -30,6 +30,28 @@
 #include "radeon_probe.h"
 #include "r128_probe.h"
 
+#ifdef TV_OUT
+
+/*
+ * List of supported TV standard names
+ */
+const char *ATITVStandardNames[ATI_TV_STDS_MAX_VALID+1] = {
+    "NTSC",
+    "PAL",
+    "PAL-M",
+    "PAL-60",
+    "NTSC-J",
+    "PAL-CN",
+    "PAL-N",
+    "Reserved1",
+    "Reserved2",
+    "SCART-PAL",
+    "None",
+    "Invalid"
+};
+
+#endif /* TV_OUT */
+
 /*
  * Recognised XF86Config options.
  */
@@ -76,6 +98,24 @@
 
 #endif /* AVOID_CPIO */
 
+#ifdef TV_OUT
+    {
+        ATI_OPTION_TV_OUT,
+        "tv_out",
+        OPTV_BOOLEAN,
+        {0, },
+        FALSE
+    },
+    {
+        ATI_OPTION_TV_STD,
+        "tv_standard",
+        OPTV_STRING,
+        {0, },
+        FALSE
+    },
+
+#endif /* TV_OUT */
+
 #ifdef XF86DRI
 
     {
Index: atioption.h
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.h,v
retrieving revision 1.2.12.1
diff -u -r1.2.12.1 atioption.h
--- atioption.h 6 Feb 2004 11:15:40 -0000       1.2.12.1
+++ atioption.h 21 Mar 2004 00:21:57 -0000
@@ -58,6 +58,13 @@
                                                                                       
         
 #endif /* XF86DRI */
 
+#ifdef TV_OUT
+
+    ATI_OPTION_TV_OUT,
+    ATI_OPTION_TV_STD,
+
+#endif /* TV_OUT */
+
     ATI_OPTION_MMIO_CACHE,
     ATI_OPTION_TEST_MMIO_CACHE,
     ATI_OPTION_PANEL_DISPLAY,
@@ -67,6 +74,30 @@
     ATI_OPTION_SWCURSOR
 } ATIPublicOptionType;
 
+#ifdef TV_OUT
+
+#define ATI_TV_STDS_MAX_VALID   11
+#define ATI_TV_STDS_NAME_MAXLEN 9
+
+typedef enum {
+    ATI_TV_STD_NTSC = 0,
+    ATI_TV_STD_PAL,
+    ATI_TV_STD_PALM,
+    ATI_TV_STD_PAL60,
+    ATI_TV_STD_NTSCJ,
+    ATI_TV_STD_PALCN,
+    ATI_TV_STD_PALN,
+    ATI_TV_STD_RESERVED1, /* NOT usable */
+    ATI_TV_STD_RESERVED2, /* NOT usable */
+    ATI_TV_STD_SCARTPAL,
+    ATI_TV_STD_NONE,      /* OK, means no tv standard change requested */
+    ATI_TV_STD_INVALID    /* Invalid tv standard requested */
+} ATITVStandard;
+
+extern const char          * ATITVStandardNames[];
+
+#endif /* TV_OUT */
+
 extern const OptionInfoRec   ATIPublicOptions[];
 extern const unsigned long   ATIPublicOptionSize;
 
Index: atipreinit.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.c,v
retrieving revision 1.2
diff -u -r1.2 atipreinit.c
--- atipreinit.c        12 Sep 2003 20:07:15 -0000      1.2
+++ atipreinit.c        21 Mar 2004 00:22:01 -0000
@@ -597,6 +597,13 @@
 
 #else /* AVOID_CPIO */
 
+#ifdef TV_OUT
+
+    pATI->pVBE = NULL;
+    pATI->pInt10 = NULL;
+
+#endif /* TV_OUT */
+
     /*
      * If there is an ix86-style BIOS, ensure its initialisation entry point
      * has been executed, and retrieve DDC and VBE information from it.
@@ -629,9 +636,17 @@
             if ((pVBE = VBEInit(pInt10Info, pATI->iEntity)))
             {
                 ConfiguredMonitor = vbeDoEDID(pVBE, pDDCModule);
+#ifdef TV_OUT
+               pATI->pInt10 = pInt10Info;
+               pATI->pVBE = pVBE;
+               pVBE = NULL;
+#else
                 vbeFree(pVBE);
+#endif /* TV_OUT */
             }
+#ifndef TV_OUT
             xf86UnloadSubModule(pVBEModule);
+#endif /* TV_OUT */
         }
 
         if (!(flags & PROBE_DETECT))
@@ -654,9 +669,13 @@
         }
     }
 
+#ifndef TV_OUT
     /* De-activate int10 */
     xf86FreeInt10(pInt10Info);
     xf86UnloadSubModule(pInt10Module);
+#else
+    pInt10Info = NULL;
+#endif /* TV_OUT */
 
     if (flags & PROBE_DETECT)
     {
Index: atiscreen.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.c,v
retrieving revision 1.2.12.2
diff -u -r1.2.12.2 atiscreen.c
--- atiscreen.c 8 Feb 2004 12:12:54 -0000       1.2.12.2
+++ atiscreen.c 21 Mar 2004 00:22:02 -0000
@@ -45,6 +45,12 @@
 #include "mach64_dri.h"
 #include "mach64_sarea.h"
 
+#ifdef TV_OUT
+
+#include "atichip.h"
+
+#endif /* TV_OUT */
+
 #include "shadowfb.h"
 #include "xf86cmap.h"
 
@@ -549,6 +555,14 @@
     if (serverGeneration == 1)
         xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options);
 
+#ifdef TV_OUT
+
+    /* Fix-up TV out after ImpacTV probe */
+    if (pATI->OptionTvOut && pATI->Chip < ATI_CHIP_264GTPRO)
+       ATISwitchMode(0, pScreenInfo->currentMode, 0);
+
+#endif /* TV_OUT */
+
 #ifdef XF86DRI
 
     /* DRI finalization */
Index: atistruct.h
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/atistruct.h,v
retrieving revision 1.2.12.1
diff -u -r1.2.12.1 atistruct.h
--- atistruct.h 6 Feb 2004 11:15:40 -0000       1.2.12.1
+++ atistruct.h 21 Mar 2004 00:22:03 -0000
@@ -46,6 +46,12 @@
  
 #endif /* XF86DRI */
 
+#ifdef TV_OUT
+
+#include "vbe.h"
+
+#endif /* TV_OUT */
+
 #include "xaa.h"
 #include "xf86Cursor.h"
 #include "xf86Pci.h"
@@ -436,6 +442,13 @@
 
 #endif /* AVOID_CPIO */
 
+#ifdef TV_OUT
+
+    CARD8 OptionTvOut;          /* Enable TV out if TV is connected */
+    CARD8 OptionTvStd;          /* Requested TV standard - see ATITVStandard enum in 
atioption.h */
+
+#endif /* TV_OUT */
+
     CARD8 OptionMMIOCache;      /* Cache MMIO writes */
     CARD8 OptionTestMMIOCache;  /* Test MMIO cache integrity */
     CARD8 OptionPanelDisplay;   /* Prefer CRT over digital panel */
@@ -484,6 +497,13 @@
                                                                                 
 #endif /* XF86DRI */
 
+#ifdef TV_OUT
+    /* TV out */
+    vbeInfoPtr pVBE;
+    xf86Int10InfoPtr pInt10;
+    int vbemode; /* saved text mode */
+    Bool tvActive;
+#endif /* TV_OUT */
 } ATIRec;
 
 #define ATIPTR(_p) ((ATIPtr)((_p)->driverPrivate))

Reply via email to