[Openchrome-devel] xf86-video-openchrome: 2 commits - configure.ac src/via_outputs.c src/via_tmds.c src/via_ums.h src/via_vt1632.c

Kevin Brace kevinbrace at kemper.freedesktop.org
Wed Aug 3 07:44:56 UTC 2016


 configure.ac      |    2 
 src/via_outputs.c |    8 
 src/via_tmds.c    |  636 ++++++++++++++++++++++++++++++++++++++++++++++--------
 src/via_ums.h     |   17 +
 src/via_vt1632.c  |  148 ++++++++----
 5 files changed, 668 insertions(+), 143 deletions(-)

New commits:
commit 28de9ed296802d10588cede16177890e0bf0fca2
Author: Kevin Brace <kevinbrace at gmx.com>
Date:   Wed Aug 3 00:41:17 2016 -0700

    Version bumped to 0.5.111
    
    This version adds initial support for VIA Technologies IGP integrated
    TMDS transmitter. (DVI) Now, LVDS FP (Flat Panel) and DVI can work
    simultaneously. (with some limitations) Testing was done on Sylvania
    g netbook. (VIA Technologies NanoBook reference design equivalent;
    VX700 chipset) Resume from ACPI S3 State resume appears to work as
    well. (i.e., DVI comes back to life after standby resume.)
    
    Signed-off-by: Kevin Brace <kevinbrace at gmx.com>

diff --git a/configure.ac b/configure.ac
index caf899c..284fb74 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@
 # Initialize Autoconf
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-openchrome],
-        [0.5.110],
+        [0.5.111],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/openchrome],
         [xf86-video-openchrome])
 
commit ef66151ee4c4674f63ec3f50a91ca28513700b92
Author: Kevin Brace <kevinbrace at gmx.com>
Date:   Wed Aug 3 00:14:44 2016 -0700

    Initial support for integrated TMDS transmitter (DVI)
    
    This commit incorporates the initial support for VIA Technologies
    IGP integrated TMDS transmitter. Previously, the code to support
    the integrated TMDS transmitter was reusing the code written for
    handling integrated LVDS transmitters. This was causing number of
    problems, so totally new code was written to support the integrated
    TMDS transmitter only. The integrated TMDS transmitter identifies
    itself as DVI (Digital Visual Interface). The code was written in a
    way to coexist with the existing code that initializes VIA
    Technologies VT1632(A) external TMDS transmitter.
    
    Signed-off-by: Kevin Brace <kevinbrace at gmx.com>

diff --git a/src/via_outputs.c b/src/via_outputs.c
index 9b88cb4..72e3969 100644
--- a/src/via_outputs.c
+++ b/src/via_outputs.c
@@ -329,18 +329,18 @@ viaOutputDetect(ScrnInfoPtr pScrn)
        display detection purposes. */
     viaProbePinStrapping(pScrn);
 
-    /* LVDS */
-    via_lvds_init(pScrn);
-
     /* VGA */
     via_analog_init(pScrn);
 
     /* TV */
     via_tv_init(pScrn);
 
-    /* External TMDS Transmitter (DVI) */
+    /* DVI */
     via_dvi_init(pScrn);
 
+    /* LVDS */
+    via_lvds_init(pScrn);
+
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                         "Exiting viaOutputDetect.\n"));
 }
diff --git a/src/via_tmds.c b/src/via_tmds.c
index 14c64d6..a6b665e 100644
--- a/src/via_tmds.c
+++ b/src/via_tmds.c
@@ -42,6 +42,162 @@
 #include "via_vt1632.h"
 
 
+/*
+ * Initializes most registers related to VIA Technologies IGP
+ * integrated TMDS transmitter. Synchronization polarity and
+ * display output source need to be set separately. */
+static void
+viaTMDSInitRegisters(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered viaTMDSInitRegisters.\n"));
+
+    /* Activate DVI + LVDS2 mode. */
+    /* 3X5.D2[5:4] - Display Channel Select
+     *               00: LVDS1 + LVDS2
+     *               01: DVI + LVDS2
+     *               10: One Dual LVDS Channel (High Resolution Pannel)
+     *               11: Single Channel DVI */
+    ViaCrtcMask(hwp, 0xD2, 0x10, 0x30);
+
+    /* Various DVI PLL settings should be set to default settings. */
+    /* 3X5.D1[7]   - PLL2 Reference Clock Edge Select Bit
+     *               0: PLLCK lock to rising edge of reference clock
+     *               1: PLLCK lock to falling edge of reference clock
+     * 3X5.D1[6:5] - PLL2 Charge Pump Current Set Bits
+     *               00: ICH = 12.5 uA
+     *               01: ICH = 25.0 uA
+     *               10: ICH = 37.5 uA
+     *               11: ICH = 50.0 uA
+     * 3X5.D1[4:1] - Reserved
+     * 3X5.D1[0]   - PLL2 Control Voltage Measurement Enable Bit */
+    ViaCrtcMask(hwp, 0xD1, 0x00, 0xE1);
+
+    /* Disable DVI test mode. */
+    /* 3X5.D5[7] - PD1 Enable Selection
+     *             1: Select by power flag
+     *             0: By register
+     * 3X5.D5[5] - DVI Testing Mode Enable
+     * 3X5.D5[4] - DVI Testing Format Selection
+     *             0: Half cycle
+     *             1: LFSR mode */
+    ViaCrtcMask(hwp, 0xD5, 0x00, 0xB0);
+
+    /* Disable DVI sense interrupt. */
+    /* 3C5.2B[7] - DVI Sense Interrupt Enable
+     *             0: Disable
+     *             1: Enable */
+    ViaSeqMask(hwp, 0x2B, 0x00, 0x80);
+
+    /* Clear DVI sense interrupt status. */
+    /* 3C5.2B[6] - DVI Sense Interrupt Status
+     *             (This bit has a RW1C attribute.) */
+    ViaSeqMask(hwp, 0x2B, 0x40, 0x40);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting viaTMDSInitRegisters.\n"));
+}
+
+/*
+ * Sets the polarity of horizontal synchronization and vertical
+ * synchronization.
+ */
+static void
+viaTMDSSetSyncPolarity(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD8 cr97;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered viaTMDSSetSyncPolarity.\n"));
+
+    /* 3X5.97[6] - DVI (TMDS) VSYNC Polarity
+     *             0: Positive
+     *             1: Negative
+     * 3X5.97[5] - DVI (TMDS) HSYNC Polarity
+     *             0: Positive
+     *             1: Negative */
+    cr97 = hwp->readCrtc(hwp, 0x97);
+    if (mode->Flags & V_NHSYNC) {
+        cr97 |= 0x20;
+    } else {
+        cr97 &= (~0x20);
+    }
+
+    if (mode->Flags & V_NVSYNC) {
+        cr97 |= 0x40;
+    } else {
+        cr97 &= (~0x40);
+    }
+
+    ViaCrtcMask(hwp, 0x97, cr97, 0x60);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting viaTMDSSetSyncPolarity.\n"));
+}
+
+/*
+ * Sets IGA1 or IGA2 as the display output source for VIA Technologies IGP
+ * integrated TMDS transmitter.
+ */
+static void
+viaTMDSSetSource(ScrnInfoPtr pScrn, CARD8 displaySource)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD8 temp = displaySource;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered viaTMDSSetSource.\n"));
+
+    /* Set integrated TMDS transmitter display output source.
+     * The integrated TMDS transmitter appears to utilize LVDS1's data
+     * source selection bit (3X5.99[4]). */
+    /* 3X5.99[4] - LVDS Channel1 Data Source Selection
+     *             0: Primary Display
+     *             1: Secondary Display */
+    ViaCrtcMask(hwp, 0x99, temp << 4, 0x10);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                "Integrated TMDS Transmitter Display Output Source: IGA%d\n",
+                (temp & 0x01) + 1);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting viaTMDSSetSource.\n"));
+}
+
+/*
+ * Returns TMDS receiver detection state for VIA Technologies IGP
+ * integrated TMDS transmitter.
+ */
+static Bool
+viaTMDSSense(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD8 sr1a;
+    Bool tmdsReceiverDetected = FALSE;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered viaTMDSSense.\n"));
+
+    /* Detect the presence of DVI. */
+    /* 3C5.1A[4] - DVI Sense
+     *             0: No connect
+     *             1: Connected */
+    sr1a = hwp->readSeq(hwp, 0x1A);
+    if (sr1a & 0x20) {
+        tmdsReceiverDetected = TRUE;
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                "Integrated TMDS transmitter %s a TMDS receiver.\n",
+                tmdsReceiverDetected ? "detected" : "did not detect");
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting viaTMDSSense.\n"));
+    return tmdsReceiverDetected;
+}
+
 void
 viaTMDSPower(ScrnInfoPtr pScrn, Bool On)
 {
@@ -185,7 +341,7 @@ via_dvi_destroy(xf86OutputPtr output)
 {
 }
 
-static const xf86OutputFuncsRec via_dvi_funcs = {
+const xf86OutputFuncsRec via_dvi_funcs = {
     .create_resources   = via_dvi_create_resources,
 #ifdef RANDR_12_INTERFACE
     .set_property       = via_dvi_set_property,
@@ -206,6 +362,369 @@ static const xf86OutputFuncsRec via_dvi_funcs = {
     .destroy            = via_dvi_destroy,
 };
 
+
+static void
+via_tmds_create_resources(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_create_resources.\n"));
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_create_resources.\n"));
+}
+
+static void
+via_tmds_dpms(xf86OutputPtr output, int mode)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_dpms.\n"));
+
+    switch (mode) {
+    case DPMSModeOn:
+        viaTMDSPower(pScrn, TRUE);
+        break;
+    case DPMSModeStandby:
+    case DPMSModeSuspend:
+    case DPMSModeOff:
+        viaTMDSPower(pScrn, FALSE);
+        break;
+    default:
+        break;
+    }
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_dpms.\n"));
+}
+
+static void
+via_tmds_save(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_save.\n"));
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_save.\n"));
+}
+
+static void
+via_tmds_restore(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_restore.\n"));
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_restore.\n"));
+}
+
+static int
+via_tmds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    int status;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_mode_valid.\n"));
+
+    if (!ViaModeDotClockTranslate(pScrn, pMode)) {
+        status = MODE_NOCLOCK;
+    } else {
+        status = MODE_OK;
+    }
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_mode_valid.\n"));
+    return status;
+}
+
+static Bool
+via_tmds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
+                      DisplayModePtr adjusted_mode)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_mode_fixup.\n"));
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_mode_fixup.\n"));
+    return TRUE;
+}
+
+static void
+via_tmds_prepare(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_prepare.\n"));
+
+    viaTMDSPower(pScrn, FALSE);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_prepare.\n"));
+}
+
+static void
+via_tmds_commit(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_commit.\n"));
+
+    viaTMDSPower(pScrn, TRUE);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_commit.\n"));
+}
+
+static void
+via_tmds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+                    DisplayModePtr adjusted_mode)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    drmmode_crtc_private_ptr iga = output->crtc->driver_private;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_mode_set.\n"));
+
+    /* Initialize VIA IGP integrated TMDS transmitter registers. */
+    viaTMDSInitRegisters(pScrn);
+
+    /* Set integrated TMDS transmitter synchronization polarity for
+     * both horizontal synchronization and vertical synchronization. */
+    viaTMDSSetSyncPolarity(pScrn, adjusted_mode);
+
+    if (output->crtc) {
+        viaTMDSSetSource(pScrn, iga->index ? 0x01 : 0x00);
+    }
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_mode_set.\n"));
+}
+
+static xf86OutputStatus
+via_tmds_detect(xf86OutputPtr output)
+{
+    xf86MonPtr mon;
+    xf86OutputStatus status = XF86OutputStatusDisconnected;
+    ScrnInfoPtr pScrn = output->scrn;
+    VIAPtr pVia = VIAPTR(pScrn);
+    VIATMDSRecPtr pVIATMDSRec = output->driver_private;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_detect.\n"));
+
+    /* Check for DVI presence by sensing the TMDS receiver connected
+     * to the integrated TMDS transmitter. */
+    if (viaTMDSSense(pScrn)) {
+
+        if (!pVia->pI2CBus2) {
+            goto exit;
+        }
+
+        /* Assume that only I2C bus 2 is used for the DVI connected to the
+         * integrated TMDS transmitter. */
+        if (!xf86I2CProbeAddress(pVia->pI2CBus2, 0xA0)) {
+            xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+                        "I2C device on I2C Bus 2 does not support EDID.\n");
+            goto exit;
+        }
+
+        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+                    "Obtaining EDID for DVI.\n");
+
+        /* Since DVI presence was established, access the I2C bus,
+         * in order to obtain EDID from the monitor. */
+        mon = xf86OutputGetEDID(output, pVia->pI2CBus2);
+
+        /* Is the interface type digital? */
+        if (mon && DIGITAL(mon->features.input_type)) {
+            status = XF86OutputStatusConnected;
+            xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+                        "Detected a monitor connected to DVI.\n");
+            xf86OutputSetEDID(output, mon);
+        } else {
+            xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+                        "Could not obtain EDID from a monitor "
+                        "connected to DVI.\n");
+        }
+    }
+
+exit:
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_detect.\n"));
+    return status;
+}
+
+#ifdef RANDR_12_INTERFACE
+static Bool
+via_tmds_set_property(xf86OutputPtr output, Atom property,
+                     RRPropertyValuePtr value)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_set_property.\n"));
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_set_property.\n"));
+    return TRUE;
+}
+#endif
+
+#ifdef RANDR_13_INTERFACE
+static Bool
+via_tmds_get_property(xf86OutputPtr output, Atom property)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_get_property.\n"));
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_get_property.\n"));
+    return FALSE;
+}
+#endif
+
+static void
+via_tmds_destroy(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered via_tmds_destroy.\n"));
+
+    if (output->driver_private) {
+        free(output->driver_private);
+    }
+
+    output->driver_private = NULL;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting via_tmds_destroy.\n"));
+}
+
+
+
+
+static const xf86OutputFuncsRec via_tmds_funcs = {
+    .create_resources   = via_tmds_create_resources,
+    .dpms               = via_tmds_dpms,
+    .save               = via_tmds_save,
+    .restore            = via_tmds_restore,
+    .mode_valid         = via_tmds_mode_valid,
+    .mode_fixup         = via_tmds_mode_fixup,
+    .prepare            = via_tmds_prepare,
+    .commit             = via_tmds_commit,
+    .mode_set           = via_tmds_mode_set,
+    .detect             = via_tmds_detect,
+    .get_modes          = xf86OutputGetEDIDModes,
+#ifdef RANDR_12_INTERFACE
+    .set_property       = via_tmds_set_property,
+#endif
+#ifdef RANDR_13_INTERFACE
+    .get_property       = via_tmds_get_property,
+#endif
+    .destroy            = via_tmds_destroy,
+};
+
+
+Bool
+viaTMDSInit(ScrnInfoPtr pScrn)
+{
+    xf86OutputPtr output;
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    VIAPtr pVia = VIAPTR(pScrn);
+    VIATMDSRecPtr pVIATMDSRec = NULL;
+    CARD8 sr13, sr5a, cr3e;
+    Bool status = FALSE;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered viaTMDSInit.\n"));
+
+    sr5a = hwp->readSeq(hwp, 0x5A);
+    ViaSeqMask(hwp, 0x5A, sr5a | 0x01, 0x01);
+
+    /* 3C5.13[7:6] - Integrated LVDS / DVI Mode Select
+     *               (DVP1D15-14 pin strapping)
+     *               00: LVDS1 + LVDS2
+     *               01: DVI + LVDS2
+     *               10: Dual LVDS Channel (High Resolution Panel)
+     *               11: One DVI only (decrease the clock jitter) */
+    sr13 = hwp->readSeq(hwp, 0x13);
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "SR13: 0x%02X\n", sr13));
+    hwp->writeSeq(hwp, 0x5A, sr5a);
+    sr13 &= 0xC0;
+    if ((sr13 == 0x40) || (sr13 == 0xC0)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                    "Integrated TMDS transmitter found via pin strapping.\n");
+    } else {
+        /* 3X5.3E[5] supposedly signals the presence of
+         * a DVI connector coming from an integrated TMDS transmitter.
+         * This check is done if the pin strapping does not indicate
+         * the presence of a DVI connector. Note that 3X5.3E is set by
+         * VIA Technologies VGA BIOS. */
+        cr3e = hwp->readCrtc(hwp, 0x3E);
+        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                            "CR3E: 0x%02X\n", cr3e));
+        if (cr3e & 0x20) {
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Integrated TMDS transmitter found via "
+                        "VIA Technologies VGA BIOS scratch pad register.\n");
+        } else {
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Integrated TMDS transmitter not found.\n");
+            goto exit;
+        }
+    }
+
+    pVIATMDSRec = xnfcalloc(1, sizeof(VIATMDSRec));
+    if (!pVIATMDSRec) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                    "Failed to allocate working storage for integrated "
+                    "TMDS transmitter.\n");
+        goto exit;
+    }
+
+    output = xf86OutputCreate(pScrn, &via_tmds_funcs, "DVI-1");
+    if (!output) {
+        free(pVIATMDSRec);
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                    "Failed to allocate X Server display output record for "
+                    "integrated TMDS transmitter.\n");
+        goto exit;
+    }
+
+    output->driver_private = pVIATMDSRec;
+
+    /* Since there are two (2) display controllers registered with the
+     * X.Org Server and both IGA1 and IGA2 can handle DVI without any
+     * limitations, possible_crtcs should be set to 0x3 (0b11) so that
+     * either display controller can get assigned to handle DVI. */
+    output->possible_crtcs = (1 << 1) | (1 << 0);
+
+    output->possible_clones = 0;
+    output->interlaceAllowed = FALSE;
+    output->doubleScanAllowed = FALSE;
+
+    status = TRUE;
+exit:
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Exiting viaTMDSInit.\n"));
+    return status;
+}
+
 void
 via_dvi_init(ScrnInfoPtr pScrn)
 {
@@ -227,97 +746,44 @@ via_dvi_init(ScrnInfoPtr pScrn)
         return;
     }
 
-    if (xf86I2CProbeAddress(pVia->pI2CBus3, addr)) {
-        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
-                            "Will probe I2C Bus 3 for a possible "
-                            "external TMDS transmitter.\n"));
-        pBus = pVia->pI2CBus3;
-    } else if (xf86I2CProbeAddress(pVia->pI2CBus2, addr)) {
-        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
-                            "Will probe I2C Bus 2 for a possible "
-                            "external TMDS transmitter.\n"));
-        pBus = pVia->pI2CBus2;
-    } else {
-        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
-                    "Did not find a possible external TMDS transmitter "
-                    "on I2C Bus 2 or I2C Bus 3.\n");
-        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                            "Exiting via_dvi_init.\n"));
-        return;
-    }
-
-    pDev = xf86CreateI2CDevRec();
-    if (!pDev) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                    "Failed to create an I2C bus structure.\n");
-        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                            "Exiting via_dvi_init.\n"));
-        return;
-    }
-
-    pDev->DevName = "VT1632A";
-    pDev->SlaveAddr = addr;
-    pDev->pI2CBus = pBus;
-    if (!xf86I2CDevInit(pDev)) {
-        xf86DestroyI2CDevRec(pDev, TRUE);
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                    "Failed to initialize a device on I2C bus.\n");
-        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                            "Exiting via_dvi_init.\n"));
-        return;
-    }
+    /* Check to see if we are dealing with the latest VIA chipsets. */
+    if ((pVia->Chipset == VIA_CX700)
+        || (pVia->Chipset == VIA_VX800)
+        || (pVia->Chipset == VIA_VX855)
+        || (pVia->Chipset == VIA_VX900)) {
 
-    if (!via_vt1632_probe(pScrn, pDev)) {
-        xf86DestroyI2CDevRec(pDev, TRUE);
-        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                            "Exiting via_dvi_init.\n"));
-        return;
+        if (!viaTMDSInit(pScrn)) {
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Integrated TMDS transmitter for DVI not found.\n");
+        } else {
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Integrated TMDS transmitter for DVI was "
+                        "initialized successfully.\n");
+        }
     }
 
-    private_data = via_vt1632_init(pScrn, pDev);
-    if (!private_data) {
-        xf86DestroyI2CDevRec(pDev, TRUE);
-        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                            "Exiting via_dvi_init.\n"));
-        return;
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                "Probing I2C Bus 2 for VT1632.\n");
+    if (!viaVT1632Init(pScrn, pVia->pI2CBus2)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                    "I2C Bus 2 was not initialized for DVI use.\n");
+    } else {
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                    "VT1632 attached to I2C Bus 2 was initialized "
+                    "successfully for DVI use.\n");
     }
 
-    output = xf86OutputCreate(pScrn, &via_dvi_funcs, "DVI-1");
-    if (output) {
-        output->driver_private = private_data;
-        output->possible_crtcs = 0x2;
-        output->possible_clones = 0;
-        output->interlaceAllowed = FALSE;
-        output->doubleScanAllowed = FALSE;
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                "Probing I2C Bus 3 for VT1632.\n");
+    if (!viaVT1632Init(pScrn, pVia->pI2CBus3)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                    "I2C Bus 3 was not initialized for DVI use.\n");
+    } else {
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                    "VT1632 attached to I2C Bus 3 was initialized "
+                    "successfully for DVI use.\n");
     }
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                         "Exiting via_dvi_init.\n"));
 }
-
-#ifdef HAVE_DEBUG
-/*
- * Returns:
- *   Bit[7] 2nd Path
- *   Bit[6] 1/0 MHS Enable/Disable
- *   Bit[5] 0 = Bypass Callback, 1 = Enable Callback
- *   Bit[4] 0 = Hot-Key Sequence Control (OEM Specific)
- *   Bit[3] LCD
- *   Bit[2] TV
- *   Bit[1] CRT
- *   Bit[0] DVI
- */
-/*
-static CARD8
-VIAGetActiveDisplay(ScrnInfoPtr pScrn)
-{
-    vgaHWPtr hwp = VGAHWPTR(pScrn);
-    CARD8 tmp;
-
-    tmp = (hwp->readCrtc(hwp, 0x3E) >> 4);
-    tmp |= ((hwp->readCrtc(hwp, 0x3B) & 0x18) << 3);
-
-    return tmp;
-}
-*/
-#endif /* HAVE_DEBUG */
diff --git a/src/via_ums.h b/src/via_ums.h
index 11d4bb3..b9bd737 100644
--- a/src/via_ums.h
+++ b/src/via_ums.h
@@ -116,7 +116,15 @@
 #define     VIA_DI_PORT_DVP0        0x1
 #define     VIA_DI_PORT_DVP1        0x2
 #define     VIA_DI_PORT_DFPLOW      0x4
+#define     VIA_DI_PORT_LVDS1       0x4
+#define     VIA_DI_PORT_TMDS        0x4
 #define     VIA_DI_PORT_DFPHIGH     0x8
+#define     VIA_DI_PORT_LVDS2       0x8
+
+/* External TMDS (DVI) Transmitter Type */
+#define     VIA_TMDS_NONE           0x0
+#define     VIA_TMDS_VT1632         0x1
+
 
 typedef struct ViaPanelMode {
     int Width ;
@@ -180,6 +188,14 @@ typedef struct _VIABIOSINFO {
 
 } VIABIOSInfoRec, *VIABIOSInfoPtr;
 
+
+typedef struct _VIATMDSRec {
+    I2CBusPtr pVIATMDSI2CBus;
+} VIATMDSRec, *VIATMDSRecPtr;
+
+
+
+
 /* via_ums.c */
 void viaUnmapMMIO(ScrnInfoPtr pScrn);
 void viaDisableVQ(ScrnInfoPtr pScrn);
@@ -224,6 +240,7 @@ void via_analog_init(ScrnInfoPtr pScrn);
 void via_lvds_init(ScrnInfoPtr pScrn);
 
 /* via_tmds.c */
+const xf86OutputFuncsRec via_dvi_funcs;
 void viaTMDSPower(ScrnInfoPtr pScrn, Bool On);
 void via_dvi_init(ScrnInfoPtr pScrn);
 
diff --git a/src/via_vt1632.c b/src/via_vt1632.c
index 3cc6c83..2a3c995 100644
--- a/src/via_vt1632.c
+++ b/src/via_vt1632.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright 2016 Kevin Brace
+ * Copyright 2016 The OpenChrome Project
+ *                [http://www.freedesktop.org/wiki/Openchrome]
  * Copyright 2014 SHS SERVICES GmbH
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -224,78 +227,117 @@ via_vt1632_detect(xf86OutputPtr output)
     return status;
 }
 
-BOOL
-via_vt1632_probe(ScrnInfoPtr pScrn, I2CDevPtr pDev) {
-    CARD8 buf = 0;
-    CARD16 VendorID = 0;
-    CARD16 DeviceID = 0;
+Bool
+viaVT1632Init(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus)
+{
+    xf86OutputPtr output;
+    VIAPtr pVia = VIAPTR(pScrn);
+    ViaVT1632Ptr pVIAVT1632Rec = NULL;
+    I2CDevPtr pI2CDevice = NULL;
+    I2CSlaveAddr i2cAddr = 0x10;
+    CARD8 buf;
+    CARD16 vendorID, deviceID;
+    Bool status = FALSE;
 
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-                        "Entered via_vt1632_probe.\n"));
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                        "Entered viaVT1632Init.\n"));
 
-    xf86I2CReadByte(pDev, 0, &buf);
-    VendorID = buf;
-    xf86I2CReadByte(pDev, 1, &buf);
-    VendorID |= buf << 8;
+    if (!xf86I2CProbeAddress(pI2CBus, i2cAddr)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+                    "I2C device not found.\n");
+        goto exit;
+    }
+
+    pI2CDevice = xf86CreateI2CDevRec();
+    if (!pI2CDevice) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                    "Failed to create an I2C bus device record.\n");
+        goto exit;
+    }
+
+    pI2CDevice->DevName = "VT1632";
+    pI2CDevice->SlaveAddr = i2cAddr;
+    pI2CDevice->pI2CBus = pI2CBus;
+    if (!xf86I2CDevInit(pI2CDevice)) {
+        xf86DestroyI2CDevRec(pI2CDevice, TRUE);
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                    "Failed to initialize a device on I2C bus.\n");
+        goto exit;
+    }
+
+    xf86I2CReadByte(pI2CDevice, 0, &buf);
+    vendorID = buf;
+    xf86I2CReadByte(pI2CDevice, 1, &buf);
+    vendorID |= buf << 8;
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                        "Vendor ID: 0x%04x\n", VendorID));
+                        "Vendor ID: 0x%04x\n", vendorID));
 
-    xf86I2CReadByte(pDev, 2, &buf);
-    DeviceID = buf;
-    xf86I2CReadByte(pDev, 3, &buf);
-    DeviceID |= buf << 8;
+    xf86I2CReadByte(pI2CDevice, 2, &buf);
+    deviceID = buf;
+    xf86I2CReadByte(pI2CDevice, 3, &buf);
+    deviceID |= buf << 8;
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                        "Device ID: 0x%04x\n", DeviceID));
+                        "Device ID: 0x%04x\n", deviceID));
 
-    if ((VendorID != 0x1106) || (DeviceID != 0x3192)) {
+    if ((vendorID != 0x1106) || (deviceID != 0x3192)) {
+        xf86DestroyI2CDevRec(pI2CDevice, TRUE);
         xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
-                    "VT1632A DVI transmitter not detected.\n");
-        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                            "Exiting via_vt1632_probe.\n"));
-        return FALSE;
+                    "VT1632 external TMDS transmitter not detected.\n");
+        goto exit;
     }
 
     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
-                "VT1632A DVI transmitter detected.\n");
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                        "Exiting via_vt1632_probe.\n"));
-    return TRUE;
-}
+                "VT1632 external TMDS transmitter detected.\n");
 
-ViaVT1632Ptr
-via_vt1632_init(ScrnInfoPtr pScrn, I2CDevPtr pDev)
-{
-    VIAPtr pVia = VIAPTR(pScrn);
-    ViaVT1632Ptr Private = NULL;
-    CARD8 buf = 0;
+    pVIAVT1632Rec = xnfcalloc(1, sizeof(ViaVT1632Rec));
+    if (!pVIAVT1632Rec) {
+        xf86DestroyI2CDevRec(pI2CDevice, TRUE);
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                    "Failed to allocate working storage for VT1632.\n");
+        goto exit;
+    }
 
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                        "Entered via_vt1632_init.\n"));
+    // Remembering which I2C bus is used for VT1632.
+    pVIAVT1632Rec->VT1632I2CDev = pI2CDevice;
 
-    Private = xnfcalloc(1, sizeof(ViaVT1632Rec));
-    if (!Private) {
+    xf86I2CReadByte(pI2CDevice, 0x06, &buf);
+    pVIAVT1632Rec->DotclockMin = buf * 1000;
+
+    xf86I2CReadByte(pI2CDevice, 0x07, &buf);
+    pVIAVT1632Rec->DotclockMax = (buf + 65) * 1000;
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Supported VT1632 Dot Clock Range: "
+                "%d to %d MHz\n",
+                pVIAVT1632Rec->DotclockMin / 1000,
+                pVIAVT1632Rec->DotclockMax / 1000);
+
+    output = xf86OutputCreate(pScrn, &via_dvi_funcs, "DVI-2");
+    if (!output) {
+        free(pVIAVT1632Rec);
+        xf86DestroyI2CDevRec(pI2CDevice, TRUE);
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                    "Failed to allocate memory for DVI initialization.\n");
-        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                            "Exiting via_vt1632_init.\n"));
-        return NULL;
+                    "Failed to allocate X Server display output record for "
+                    "VT1632.\n");
+        goto exit;
     }
-    Private->VT1632I2CDev = pDev;
 
-    xf86I2CReadByte(pDev, 0x06, &buf);
-    Private->DotclockMin = buf * 1000;
+    output->driver_private = pVIAVT1632Rec;
 
-    xf86I2CReadByte(pDev, 0x07, &buf);
-    Private->DotclockMax = (buf + 65) * 1000;
+    /* Since there are two (2) display controllers registered with the
+     * X.Org Server and both IGA1 and IGA2 can handle DVI without any
+     * limitations, possible_crtcs should be set to 0x3 (0b11) so that
+     * either display controller can get assigned to handle DVI. */
+    output->possible_crtcs = (1 << 1) | (1 << 0);
 
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1632A Dot Clock Range: "
-                "%d to %d MHz\n",
-                Private->DotclockMin / 1000,
-                Private->DotclockMax / 1000);
+    output->possible_clones = 0;
+    output->interlaceAllowed = FALSE;
+    output->doubleScanAllowed = FALSE;
 
-    via_vt1632_dump_registers(pScrn, pDev);
+    via_vt1632_dump_registers(pScrn, pI2CDevice);
 
+    status = TRUE;
+exit:
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                        "Exiting via_vt1632_init.\n"));
-    return Private;
+                        "Exiting viaVT1632Init.\n"));
+    return status;
 }


More information about the Openchrome-devel mailing list