[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

(finally) PATCH: TV-Out on ATI-AIW 16/AGP, probably generally r128.



Peter Surda proudly announces a patch which adds (finally) support for TV-Out
for r128. Note that in this stage it is a dirty hardcoded hack with limited
use. Someone will have to make it nicer. It shouldn't really be a problem but
I think there are people who can do it much faster than me. Many thanks to
Mike A. Harris <mharris@redhat.com> who helped me navigate and understand the
source code of XFree86 drivers and explained the terminology late on saturday
night. Without him this probably wouldn't be possible.

The patch works in such a way that after initializing a video mode, it calls
int10 to initialize a VESA mode (this tells the ATI BIOS to turn TV-Out on).
Then it adjusts the timing so that the line width is correct.

Prerequisities:
- you must boot with the svideo cable plugged in. otherwise bios won't ever
  initialize the TV-out

Features:
- 800x600 mode is supported
- everything (DRI, Xv) should work. Tested on Q3Arena, gears, aviplay and
  xawtv.

Quirks/Bugs:
- not optional, hardcoded, may collide with monitor output (I don't have a
  monitor so I can't test it)
- only 800x600@16bit is supported (VESA mode 0x114). You must only use this
  mode in XF86Config, otherwise strange stuff may happen.
- doesn't correctly reinitialize VT, so text mode may become fscked.
- VBI not supported (no idea how to do this)

It is not ready for including into main driver, but I am sure some of the
developers can refine the quirks very fast (I really don't have experience
with XFree86 drivers so it would take me too long).

Everyone who needs TV-Out on r128 should give it a shot and report (into the
mailing list, no need to CC me, I've been subscribed for many months). The
patch is against CVS snapshot from 1 or 2 days ago.

I have received no information from ATI, so despite their efforts to prevent
linux (i.e. non-windows) users from having TV-Out, we have it anyway. I would
be very happy if ATI worked more closely with people who want to use their
products.

Bye,

Peter Surda (Shurdeek) <shurdeek@panorama.sth.ac.at>, ICQ 10236103, +436505122023

--
            It is easier to fix Unix than to live with NT.
Only in ati.2: Makefile
diff -u ati.2.nonvesa/r128_driver.c ati.2/r128_driver.c
--- ati.2.nonvesa/r128_driver.c	Mon Jun  4 00:03:49 2001
+++ ati.2/r128_driver.c	Sun Aug 26 02:12:17 2001
@@ -1329,6 +1329,11 @@
 {
     R128InfoPtr      info;
     xf86Int10InfoPtr pInt10 = NULL;
+    /*
+    pointer pVbeModule;
+    EntityInfoPtr pEnt;
+    vbeInfoPtr pVbe;
+    */
 
     R128TRACE(("R128PreInit\n"));
 
@@ -1379,6 +1384,14 @@
 	return FALSE;
     }
 
+    /* Load vbe module */
+    /*
+    if ((pVbeModule = xf86LoadSubModule(pScrn, "vbe")) == NULL)
+        return (FALSE);
+    if ((pVbe = VBEInit(NULL, pEnt->index)) == NULL)
+        return (FALSE);
+	*/
+
     info->PciInfo      = xf86GetPciInfoForEntity(info->pEnt->index);
     info->PciTag       = pciTag(info->PciInfo->bus,
 				info->PciInfo->device,
@@ -2235,6 +2248,9 @@
     save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID);
     save->crtc_offset          = INREG(R128_CRTC_OFFSET);
     save->crtc_offset_cntl     = INREG(R128_CRTC_OFFSET_CNTL);
+    /*
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Offset: %d:%d\n", save->crtc_offset, save->crtc_offset_cntl);
+    */
     save->crtc_pitch           = INREG(R128_CRTC_PITCH);
 }
 
@@ -2802,12 +2818,71 @@
 static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
 {
     R128InfoPtr info      = R128PTR(pScrn);
+    int vbemode;
+    vbeInfoPtr pVbe;
+    EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+    unsigned char *R128MMIO = info->MMIO;
+    R128SavePtr restore = &info->ModeReg;
+    /*
+    vbeInfoPtr pVbe = VBEInit(NULL, pEnt->index);
+    */
 
     if (!R128Init(pScrn, mode, &info->ModeReg)) return FALSE;
 				/* FIXME?  DRILock/DRIUnlock here? */
     pScrn->vtSema = TRUE;
     R128Blank(pScrn);
     R128RestoreMode(pScrn, &info->ModeReg);
+    
+    if (xf86LoadSubModule(pScrn, "vbe")) {
+#ifdef XFree86LOADER
+	xf86LoaderReqSymLists(vbeSymbols,NULL);
+#endif
+	pVbe = VBEInit(NULL,pEnt->index);
+	if (pVbe) {
+	    xf86DrvMsg(0, X_INFO, "VBEInit ok\n");
+	    pVbe->pInt10->num = 0x10;
+	    pVbe->pInt10->ax = 0x4f03;
+	    xf86ExecX86int10(pVbe->pInt10);
+	    if (pVbe->pInt10->ax == 0x4f) {
+	    	xf86DrvMsg(0, X_INFO, "VBEGetMode ok\n");
+		/*
+		vbemode = pVbe->pInt10->bx;
+		*/
+		vbemode = 0x114;
+	    	pVbe->pInt10->num = 0x10;
+	    	pVbe->pInt10->ax = 0x4f02;
+	    	pVbe->pInt10->bx = vbemode;
+	    	xf86ExecX86int10(pVbe->pInt10);
+		if (pVbe->pInt10->ax == 0x4f)
+		    xf86DrvMsg(0, X_INFO, "VBESetMode ok\n");
+		else
+		    xf86DrvMsg(0, X_INFO, "VBESetMode NOT ok\n");
+	    } else {
+	    	xf86DrvMsg(0, X_INFO, "VBEGetMode NOT ok\n");
+	    }
+	    /*
+	    return (pVbe->pInt10->ax == 0x4f);
+	    */
+	    vbeFree(pVbe);
+	} else {
+	    xf86DrvMsg(0, X_INFO, "VBEInit NOT ok\n");
+	}
+    }
+
+    /*
+    OUTREG(R128_CRTC_H_TOTAL_DISP,    restore->crtc_h_total_disp);
+    OUTREG(R128_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid);
+    OUTREG(R128_CRTC_V_TOTAL_DISP,    restore->crtc_v_total_disp);
+    OUTREG(R128_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid);
+    OUTREG(R128_CRTC_OFFSET,          restore->crtc_offset);
+    OUTREG(R128_CRTC_OFFSET_CNTL,     restore->crtc_offset_cntl);
+    OUTREG(R128_CRTC_PITCH,           restore->crtc_pitch);
+    */
+
+    xf86DrvMsg(0, X_INFO, "Pitch: %d\n", (int) restore->crtc_pitch);
+    
+    OUTREG(R128_CRTC_PITCH, 104);
+
     R128Unblank(pScrn);
 
     info->CurrentLayout.mode = mode;

PGP signature