xf86-video-intel: configure.ac src/i830_dvo.c src/Makefile.am src/tfp410/Makefile.am src/tfp410/tfp410.c src/tfp410/tfp410.h src/tfp410/tfp410_module.c src/tfp410/tfp410_reg.h

Eric Anholt anholt at kemper.freedesktop.org
Fri Jun 22 16:51:00 PDT 2007


 configure.ac               |    1 
 src/Makefile.am            |    2 
 src/i830_dvo.c             |   13 ++
 src/tfp410/Makefile.am     |   16 ++
 src/tfp410/tfp410.c        |  265 +++++++++++++++++++++++++++++++++++++++++++++
 src/tfp410/tfp410.h        |   33 +++++
 src/tfp410/tfp410_module.c |   38 ++++++
 src/tfp410/tfp410_reg.h    |  104 +++++++++++++++++
 8 files changed, 471 insertions(+), 1 deletion(-)

New commits:
diff-tree 66aa0e61e1e8d2216a9c0555be5be004ed0a3192 (from f8d7cbc6e1322acad3351591336cefcfba7d9aaf)
Author: Dave Mueller <dave.mueller at gmx.ch>
Date:   Fri Jun 22 16:45:27 2007 -0700

    Bug #11171: Add support for the Ti TFP410 DVO TMDS transmitter.

diff --git a/configure.ac b/configure.ac
index 66992fc..51203fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -230,5 +230,6 @@ AC_OUTPUT([
 	src/ivch/Makefile
 	src/reg_dumper/Makefile
 	src/sil164/Makefile
+	src/tfp410/Makefile
 	man/Makefile
 ])
diff --git a/src/Makefile.am b/src/Makefile.am
index 2b5799c..858ffd1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,7 +22,7 @@ if HAVE_PCIACCESS
 REGDUMPER = reg_dumper
 endif
 
-SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 $(REGDUMPER)
+SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 tfp410 $(REGDUMPER)
 
 # this is obnoxious:
 # -module lets us name the module exactly how we want
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 5666d26..2521ee3 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -36,11 +36,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "sil164/sil164.h"
 #include "ch7xxx/ch7xxx.h"
+#include "tfp410/tfp410.h"
 
 static const char *SIL164Symbols[] = {
     "Sil164VidOutput",
     NULL
 };
+static const char *TFP410Symbols[] = {
+    "Tfp410VidOutput",
+    NULL
+};
 static const char *CH7xxxSymbols[] = {
     "CH7xxxVidOutput",
     NULL
@@ -84,6 +89,14 @@ struct _I830DVODriver i830_dvo_drivers[]
 	.address = 0x04, /* Might also be 0x44, 0x84, 0xc4 */
 	.symbols = ivch_symbols
     },
+    {
+	.type = I830_OUTPUT_DVO_TMDS,
+	.modulename = "tfp410",
+	.fntablename = "TFP410VidOutput",
+	.dvo_reg = DVOC,
+	.address = (TFP410_ADDR_1<<1),
+	.symbols = TFP410Symbols
+    },
     /*
     { I830_OUTPUT_DVO_LVDS, "ch7017", "ch7017_methods",
       0xea, ch7017_symbols, NULL, NULL, NULL }
diff --git a/src/tfp410/Makefile.am b/src/tfp410/Makefile.am
new file mode 100644
index 0000000..89a27d0
--- /dev/null
+++ b/src/tfp410/Makefile.am
@@ -0,0 +1,16 @@
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@
+
+tfp410_la_LTLIBRARIES = tfp410.la
+tfp410_la_LDFLAGS = -module -avoid-version
+tfp410_ladir = @moduledir@/drivers
+
+tfp410_la_SOURCES = \
+	tfp410.c \
+	tfp410_module.c \
+	tfp410.h \
+	tfp410_reg.h
diff --git a/src/tfp410/tfp410.c b/src/tfp410/tfp410.c
new file mode 100644
index 0000000..fecb64c
--- /dev/null
+++ b/src/tfp410/tfp410.c
@@ -0,0 +1,265 @@
+/* -*- c-basic-offset: 4 -*- */
+/*
+ * Copyright © 2007 Dave Mueller
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Dave Mueller <dave.mueller at gmx.ch>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "compiler.h"
+#include "miscstruct.h"
+#include "xf86i2c.h"
+#include "xf86Crtc.h"
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+
+#include "../i2c_vid.h"
+#include "tfp410.h"
+#include "tfp410_reg.h"
+
+static Bool
+tfp410ReadByte(TFP410Ptr tfp, int addr, CARD8 *ch)
+{
+    if (!xf86I2CReadByte(&(tfp->d), addr, ch)) {
+	xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR,
+		   "Unable to read from %s Slave %d.\n",
+		   tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr);
+	return FALSE;
+    }
+    return TRUE;
+}
+
+static Bool
+tfp410WriteByte(TFP410Ptr tfp, int addr, CARD8 ch)
+{
+    if (!xf86I2CWriteByte(&(tfp->d), addr, ch)) {
+	xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR,
+		   "Unable to write to %s Slave %d.\n",
+		   tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr);
+	return FALSE;
+    }
+    return TRUE;
+}
+
+static int
+tfp410GetID(TFP410Ptr tfp, int addr)
+{
+    unsigned char ch1, ch2;
+
+    if (tfp410ReadByte(tfp, addr+0, &ch1) &&
+        tfp410ReadByte(tfp, addr+1, &ch2)) {
+
+	return ((ch2<<8) & 0xFF00) | (ch1 & 0x00FF);
+    }
+    return -1;
+}
+
+/* Ti TFP410 driver for chip on i2c bus */
+static void *
+tfp410_init(I2CBusPtr b, I2CSlaveAddr addr)
+{
+    /* this will detect the tfp410 chip on the specified i2c bus */
+    TFP410Ptr tfp;
+    int id;
+
+    xf86DrvMsg(b->scrnIndex, X_INFO, "detecting tfp410\n");
+
+    tfp = xcalloc(1, sizeof(TFP410Rec));
+    if (tfp == NULL)
+	return NULL;
+
+    tfp->d.DevName = "TFP410 TMDS Controller";
+    tfp->d.SlaveAddr = addr;
+    tfp->d.pI2CBus = b;
+    tfp->d.StartTimeout = b->StartTimeout;
+    tfp->d.BitTimeout = b->BitTimeout;
+    tfp->d.AcknTimeout = b->AcknTimeout;
+    tfp->d.ByteTimeout = b->ByteTimeout;
+    tfp->d.DriverPrivate.ptr = tfp;
+
+    if ((id = tfp410GetID(tfp, TFP410_VID_LO)) != TFP410_VID) {
+	xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR,
+		   "tfp410 not detected got VID %X: from %s Slave %d.\n",
+		   id, tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr);
+	goto out;
+    }
+
+    if ((id = tfp410GetID(tfp, TFP410_DID_LO)) != TFP410_DID) {
+	xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR,
+		   "tfp410 not detected got DID %X: from %s Slave %d.\n",
+		   id, tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr);
+	goto out;
+    }
+
+    if (!xf86I2CDevInit(&(tfp->d))) {
+	goto out;
+    }
+
+    return tfp;
+
+out:
+    xfree(tfp);
+    return NULL;
+}
+
+static xf86OutputStatus
+tfp410_detect(I2CDevPtr d)
+{
+    TFP410Ptr tfp = TFPPTR(d);
+    xf86OutputStatus ret = XF86OutputStatusDisconnected;
+    unsigned char ctl2;
+
+    if (tfp410ReadByte(tfp, TFP410_CTL_2, &ctl2)) {
+	if (ctl2 & TFP410_CTL_2_HTPLG)
+	    ret = XF86OutputStatusConnected;
+	else
+	    ret = XF86OutputStatusDisconnected;
+    }
+
+    return ret;
+}
+
+static ModeStatus
+tfp410_mode_valid(I2CDevPtr d, DisplayModePtr mode)
+{
+    return MODE_OK;
+}
+
+static void
+tfp410_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
+{
+    /* As long as the basics are set up, since we don't have clock dependencies
+     * in the mode setup, we can just leave the registers alone and everything
+     * will work fine.
+     */
+    /* don't do much */
+    return;
+}
+
+/* set the tfp410 power state */
+static void
+tfp410_dpms(I2CDevPtr d, int mode)
+{
+    TFP410Ptr tfp = TFPPTR(d);
+    unsigned char ctl1;
+
+    if (!tfp410ReadByte(tfp, TFP410_CTL_1, &ctl1))
+	return;
+
+    if (mode == DPMSModeOn)
+	ctl1 |= TFP410_CTL_1_PD;
+    else
+	ctl1 &= ~TFP410_CTL_1_PD;
+
+    tfp410WriteByte(tfp, TFP410_CTL_1, ctl1);
+}
+
+static void
+tfp410_dump_regs(I2CDevPtr d)
+{
+    TFP410Ptr tfp = TFPPTR(d);
+    CARD8 val, val2;
+
+    tfp410ReadByte(tfp, TFP410_REV, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_REV: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_CTL_1, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_CTL1: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_CTL_2, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_CTL2: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_CTL_3, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_CTL3: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_USERCFG, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_USERCFG: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_DE_DLY, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_DE_DLY: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_DE_CTL, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_DE_CTL: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_DE_TOP, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_DE_TOP: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_DE_CNT_LO, &val);
+    tfp410ReadByte(tfp, TFP410_DE_CNT_HI, &val2);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
+    tfp410ReadByte(tfp, TFP410_DE_LIN_LO, &val);
+    tfp410ReadByte(tfp, TFP410_DE_LIN_HI, &val2);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
+    tfp410ReadByte(tfp, TFP410_H_RES_LO, &val);
+    tfp410ReadByte(tfp, TFP410_H_RES_HI, &val2);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_H_RES: 0x%02X%02X\n", val2, val);
+    tfp410ReadByte(tfp, TFP410_V_RES_LO, &val);
+    tfp410ReadByte(tfp, TFP410_V_RES_HI, &val2);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_V_RES: 0x%02X%02X\n", val2, val);
+}
+
+static void
+tfp410_save(I2CDevPtr d)
+{
+    TFP410Ptr tfp = TFPPTR(d);
+
+    if (!tfp410ReadByte(tfp, TFP410_CTL_1, &tfp->SavedReg.ctl1))
+	return;
+
+    if (!tfp410ReadByte(tfp, TFP410_CTL_2, &tfp->SavedReg.ctl2))
+	return;
+}
+
+static void
+tfp410_restore(I2CDevPtr d)
+{
+    TFP410Ptr tfp = TFPPTR(d);
+
+    /* Restore it powered down initially */
+    tfp410WriteByte(tfp, TFP410_CTL_1, tfp->SavedReg.ctl1 & ~0x1);
+
+    tfp410WriteByte(tfp, TFP410_CTL_2, tfp->SavedReg.ctl2);
+    tfp410WriteByte(tfp, TFP410_CTL_1, tfp->SavedReg.ctl1);
+}
+
+I830I2CVidOutputRec TFP410VidOutput = {
+    .init = tfp410_init,
+    .detect = tfp410_detect,
+    .mode_valid = tfp410_mode_valid,
+    .mode_set = tfp410_mode_set,
+    .dpms = tfp410_dpms,
+    .dump_regs = tfp410_dump_regs,
+    .save = tfp410_save,
+    .restore = tfp410_restore,
+};
diff --git a/src/tfp410/tfp410.h b/src/tfp410/tfp410.h
new file mode 100644
index 0000000..fb3f452
--- /dev/null
+++ b/src/tfp410/tfp410.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2007 Dave Mueller
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Dave Mueller <dave.mueller at gmx.ch>
+ *
+ */
+
+#ifndef TFP410_H
+#define TFP410_H
+
+#define TFP410_ADDR_1 0x38
+
+#endif
diff --git a/src/tfp410/tfp410_module.c b/src/tfp410/tfp410_module.c
new file mode 100644
index 0000000..c05b21a
--- /dev/null
+++ b/src/tfp410/tfp410_module.c
@@ -0,0 +1,38 @@
+/* -*- c-basic-offset: 4 -*- */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(tfp410Setup);
+
+static XF86ModuleVersionInfo tfp410VersRec = {
+    "tfp410",
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    1, 0, 0,
+    ABI_CLASS_VIDEODRV,
+    ABI_VIDEODRV_VERSION,
+    MOD_CLASS_NONE,
+    { 0,0,0,0 }
+};
+
+_X_EXPORT XF86ModuleData tfp410ModuleData = {
+    &tfp410VersRec,
+    tfp410Setup,
+    NULL
+};
+
+static pointer
+tfp410Setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+    return (pointer)1;
+}
diff --git a/src/tfp410/tfp410_reg.h b/src/tfp410/tfp410_reg.h
new file mode 100644
index 0000000..45afa9b
--- /dev/null
+++ b/src/tfp410/tfp410_reg.h
@@ -0,0 +1,104 @@
+/* -*- c-basic-offset: 4 -*- */
+/*
+ * Copyright © 2007 Dave Mueller
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Dave Mueller <dave.mueller at gmx.ch>
+ *
+ */
+
+#ifndef TFP410_REG_H
+#define TFP410_REG_H
+
+/* register definitions according to the TFP410 data sheet */
+#define TFP410_VID 0x014C
+#define TFP410_DID 0x0410
+
+#define TFP410_VID_LO 0x00
+#define TFP410_VID_HI 0x01
+#define TFP410_DID_LO 0x02
+#define TFP410_DID_HI 0x03
+#define TFP410_REV    0x04
+
+#define TFP410_CTL_1 0x08
+#define TFP410_CTL_1_TDIS (1<<6)
+#define TFP410_CTL_1_VEN (1<<5)
+#define TFP410_CTL_1_HEN (1<<4)
+#define TFP410_CTL_1_DSEL (1<<3)
+#define TFP410_CTL_1_BSEL (1<<2)
+#define TFP410_CTL_1_EDGE (1<<1)
+#define TFP410_CTL_1_PD   (1<<0)
+
+#define TFP410_CTL_2 0x09
+#define TFP410_CTL_2_VLOW (1<<7)
+#define TFP410_CTL_2_MSEL_MASK (0x7<<4)
+#define TFP410_CTL_2_MSEL (1<<4)
+#define TFP410_CTL_2_TSEL (1<<3)
+#define TFP410_CTL_2_RSEN (1<<2)
+#define TFP410_CTL_2_HTPLG (1<<1)
+#define TFP410_CTL_2_MDI (1<<0)
+
+#define TFP410_CTL_3 0x0A
+#define TFP410_CTL_3_DK_MASK (0x7<<5)
+#define TFP410_CTL_3_DK (1<<5)
+#define TFP410_CTL_3_DKEN (1<<4)
+#define TFP410_CTL_3_CTL_MASK (0x7<<1)
+#define TFP410_CTL_3_CTL (1<<1)
+
+#define TFP410_USERCFG 0x0B
+
+#define TFP410_DE_DLY 0x32
+
+#define TFP410_DE_CTL 0x33
+#define TFP410_DE_CTL_DEGEN (1<<6)
+#define TFP410_DE_CTL_VSPOL (1<<5)
+#define TFP410_DE_CTL_HSPOL (1<<4)
+#define TFP410_DE_CTL_DEDLY8 (1<<0)
+
+#define TFP410_DE_TOP 0x34
+
+#define TFP410_DE_CNT_LO 0x36
+#define TFP410_DE_CNT_HI 0x37
+
+#define TFP410_DE_LIN_LO 0x38
+#define TFP410_DE_LIN_HI 0x39
+
+#define TFP410_H_RES_LO 0x3A
+#define TFP410_H_RES_HI 0x3B
+
+#define TFP410_V_RES_LO 0x3C
+#define TFP410_V_RES_HI 0x3D
+
+typedef struct _TFP410SaveRec {
+    CARD8 ctl1;
+    CARD8 ctl2;
+} TFP410SaveRec;
+
+typedef struct {
+    I2CDevRec d;
+    TFP410SaveRec SavedReg;
+    TFP410SaveRec ModeReg;
+} TFP410Rec, *TFP410Ptr;
+
+#define TFPPTR(d) ((TFP410Ptr)(d->DriverPrivate.ptr))
+
+#endif


More information about the xorg-commit mailing list