My last patch had a bug that caused the xserver to crash. It took me some time to find it as it crashed somewhere else in the xserver (and I don't have too much experience with the X code yet...).

The attached patch should fix that. It's a bit different from the previous one but I think it's a bit cleaner this way.

Harry

On 27-11-12 23:35, Willem van Asperen wrote:
On 11/27/2012 11:16 PM, Harry de Boer wrote:
About the B & W thing, that does not seem to have anything to do with the actual colours on the display: it is in my log too but I do have colour on the TV. Not sure why yours does not, can you send me the complete log and xorg.conf? Also, what connector are you using? I am guessing you are using S-Video...
Correct. It's S-Video. And the TV shows B&W...
The log is attached.

I am getting crashes too btw, I have not looked into that yet.

Getting other modes to work is probably going to take some time. It seems the modelines and tv-register tables [for the VT1625] don't line up. I already looked a bit into how analogue video and modelines work but I don't understand all the parts yet.
You are doing great work; thanks for all your efforts. I would be happy for not having all modes available...

Regards,
Willem

>From e3656c489e334adcfbd887f2e2128b4a8922f307 Mon Sep 17 00:00:00 2001
From: Harry de Boer <ha...@ijscoboer.nl>
Date: Mon, 26 Nov 2012 22:36:23 +0100
Subject: [PATCH 4/4] Create valid modeline lists for tv outputs. When
 creating a list of DisplayModePtr the ->next pointers
 should be paint to next item in the list or only the
 first modeline will be recognised. This commit adds a
 helper function to create correct modeline lists from a
 DisplayModeRec array.

---
 src/via_ch7xxx.c  |    5 +++--
 src/via_ch7xxx.h  |    7 +++----
 src/via_outputs.c |   21 ++++++++++++++++++++-
 src/via_outputs.h |   32 ++++++++++++++++++++++++++++++++
 src/via_vt162x.c  |    9 +++++----
 src/via_vt162x.h  |   13 ++++++++-----
 6 files changed, 71 insertions(+), 16 deletions(-)
 create mode 100644 src/via_outputs.h

diff --git a/src/via_ch7xxx.c b/src/via_ch7xxx.c
index 7686aa6..3e542f5 100644
--- a/src/via_ch7xxx.c
+++ b/src/via_ch7xxx.c
@@ -31,6 +31,7 @@
 
 #include "via_driver.h"
 #include "via_ch7xxx.h"
+#include "via_outputs.h"
 #include <unistd.h>
 
 #ifdef HAVE_DEBUG
@@ -613,7 +614,7 @@ ViaCH7xxxInit(ScrnInfoPtr pScrn)
             pBIOSInfo->TVModeI2C = CH7xxxModeI2C;
             pBIOSInfo->TVModeCrtc = CH7xxxModeCrtc;
             pBIOSInfo->TVPower = CH7xxxTVPower;
-            pBIOSInfo->TVModes = CH7011Modes;
+            pBIOSInfo->TVModes = viaDisplayModeRec2Ptr(CH7011Modes, numCH7011Modes);
             pBIOSInfo->LCDPower = NULL;
             pBIOSInfo->TVNumRegs = CH_7011_MAX_NUM_REG;
 #ifdef HAVE_DEBUG
@@ -629,7 +630,7 @@ ViaCH7xxxInit(ScrnInfoPtr pScrn)
             pBIOSInfo->TVModeI2C = CH7xxxModeI2C;
             pBIOSInfo->TVModeCrtc = CH7xxxModeCrtc;
             pBIOSInfo->TVPower = CH7xxxTVPower;
-            pBIOSInfo->TVModes = CH7019Modes;
+            pBIOSInfo->TVModes = viaDisplayModeRec2Ptr(CH7019Modes, numCH7019Modes);
             pBIOSInfo->LCDPower = CH7019LCDPower;
             pBIOSInfo->TVNumRegs = CH_7019_MAX_NUM_REG;
 #ifdef HAVE_DEBUG
diff --git a/src/via_ch7xxx.h b/src/via_ch7xxx.h
index 68df1b5..302fe39 100644
--- a/src/via_ch7xxx.h
+++ b/src/via_ch7xxx.h
@@ -86,10 +86,10 @@ static DisplayModeRec CH7011Modes[]={
     { MODEPREFIX("720x576"),      28500,  720,  728,  744,  760, 0,  576,  635,  643,  750, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXPAL  },
     { MODEPREFIX("720x480Noscale"), 27972,  720,  736,  768,  888, 0,  480,  480,  483,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
     { MODEPREFIX("720x576Noscale"), 28000,  720,  728,  864,  896, 0,  576,  576,  579,  625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL  },
-
-    { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC },
 };
 
+int numCH7011Modes = sizeof(CH7011Modes) / sizeof(DisplayModeRec);
+
 static DisplayModeRec CH7019Modes[]={
     { MODEPREFIX("640x480"),      23520,  640,  656,  744,  784, 0,  480,  487,  491,  600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
     { MODEPREFIX("640x480"),      30000,  640,  680,  808, 1000, 0,  480,  520,  523,  600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL  },
@@ -103,10 +103,9 @@ static DisplayModeRec CH7019Modes[]={
     { MODEPREFIX("800x600Over"),    32500,  800,  832,  928, 1000, 0,  600,  600,  604,  650, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL  },
     { MODEPREFIX("1024x768Over"),   50400, 1024, 1040, 1112, 1200, 0,  768,  772,  776,  840, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
     { MODEPREFIX("1024x768Over"),   49500, 1024, 1032, 1112, 1200, 0,  768,  771,  776,  825, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL  },
-
-    { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC },
 };
 
+int numCH7019Modes = sizeof(CH7019Modes) / sizeof(DisplayModeRec);
 
 typedef struct _VIATVMASKTABLE {
     CARD8   TV[VIA_BIOS_TABLE_NUM_TV_REG];
diff --git a/src/via_outputs.c b/src/via_outputs.c
index 0620a12..14203a7 100644
--- a/src/via_outputs.c
+++ b/src/via_outputs.c
@@ -35,7 +35,7 @@
 #include "config.h"
 #endif
 
-#include "via_driver.h"
+#include "via_outputs.h"
 #include <unistd.h>
 
 /*
@@ -1351,3 +1351,22 @@ ViaModeSecondCRTC(ScrnInfoPtr pScrn, DisplayModePtr mode)
 
     hwp->disablePalette(hwp);
 }
+
+/*
+ * Helper function to create a list of DisplayModePtr with valid ->next
+ * pointers from a DisplayModeRec array.
+ */
+DisplayModePtr
+viaDisplayModeRec2Ptr(const DisplayModeRec *modesRec, int numModes) {
+    DisplayModePtr modes = NULL;
+    DisplayModePtr mode = NULL;
+
+    DEBUG(xf86DrvMsg(0, X_INFO, "numModes: %d\n", numModes));
+
+    for (int i = 0; i < numModes; i++) {
+        mode = xf86DuplicateMode(&modesRec[i]);
+        modes = xf86ModesAdd(modes, mode);
+    }
+
+    return modes;
+}
diff --git a/src/via_outputs.h b/src/via_outputs.h
new file mode 100644
index 0000000..03a6a79
--- /dev/null
+++ b/src/via_outputs.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2012 The Openchrome Project  [openchrome.org]
+ *
+ * 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, sub license,
+ * 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 NON-INFRINGEMENT. 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.
+ */
+
+#ifndef _VIA_OUTPUTS_H_
+#define _VIA_OUTPUTS_H_ 1
+
+#include "via_driver.h"
+
+/* Helper function for modeline list creation. */
+DisplayModePtr viaDisplayModeRec2Ptr(const DisplayModeRec*, int);
+
+#endif
diff --git a/src/via_vt162x.c b/src/via_vt162x.c
index 0c558f4..ab516c4 100644
--- a/src/via_vt162x.c
+++ b/src/via_vt162x.c
@@ -29,6 +29,7 @@
 
 #include "via_driver.h"
 #include "via_vt162x.h"
+#include "via_outputs.h"
 
 static void
 ViaSetTVClockSource(xf86CrtcPtr crtc)
@@ -870,7 +871,7 @@ ViaVT162xInit(ScrnInfoPtr pScrn)
             pBIOSInfo->TVModeI2C = VT1621ModeI2C;
             pBIOSInfo->TVModeCrtc = VT1621ModeCrtc;
             pBIOSInfo->TVPower = VT1621Power;
-            pBIOSInfo->TVModes = VT1621Modes;
+            pBIOSInfo->TVModes = viaDisplayModeRec2Ptr(VT1621Modes, numVT1621Modes);
             pBIOSInfo->TVPrintRegs = VT162xPrintRegs;
             pBIOSInfo->TVNumRegs = 0x68;
             break;
@@ -882,7 +883,7 @@ ViaVT162xInit(ScrnInfoPtr pScrn)
             pBIOSInfo->TVModeI2C = VT1622ModeI2C;
             pBIOSInfo->TVModeCrtc = VT1622ModeCrtc;
             pBIOSInfo->TVPower = VT1622Power;
-            pBIOSInfo->TVModes = VT1622Modes;
+            pBIOSInfo->TVModes = viaDisplayModeRec2Ptr(VT1622Modes, numVT1622Modes);
             pBIOSInfo->TVPrintRegs = VT162xPrintRegs;
             pBIOSInfo->TVNumRegs = 0x68;
             break;
@@ -894,7 +895,7 @@ ViaVT162xInit(ScrnInfoPtr pScrn)
             pBIOSInfo->TVModeI2C = VT1622ModeI2C;
             pBIOSInfo->TVModeCrtc = VT1622ModeCrtc;
             pBIOSInfo->TVPower = VT1622Power;
-            pBIOSInfo->TVModes = VT1623Modes;
+            pBIOSInfo->TVModes = viaDisplayModeRec2Ptr(VT1623Modes, numVT1623Modes);
             pBIOSInfo->TVPrintRegs = VT162xPrintRegs;
             pBIOSInfo->TVNumRegs = 0x6C;
             break;
@@ -906,7 +907,7 @@ ViaVT162xInit(ScrnInfoPtr pScrn)
             pBIOSInfo->TVModeI2C = VT1622ModeI2C;
             pBIOSInfo->TVModeCrtc = VT1622ModeCrtc;
             pBIOSInfo->TVPower = VT1625Power;
-            pBIOSInfo->TVModes = VT1625Modes;
+            pBIOSInfo->TVModes = viaDisplayModeRec2Ptr(VT1625Modes, numVT1625Modes);
             pBIOSInfo->TVPrintRegs = VT162xPrintRegs;
             pBIOSInfo->TVNumRegs = 0x82;
             break;
diff --git a/src/via_vt162x.h b/src/via_vt162x.h
index b39134f..1023265 100644
--- a/src/via_vt162x.h
+++ b/src/via_vt162x.h
@@ -65,9 +65,10 @@ static DisplayModeRec VT1621Modes[] = {
     { MODEPREFIX("640x480Over"), 24000,  640,  672,  888,  960, 0,  480,  485,  491,  500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL  },
     { MODEPREFIX("800x600Over"), 36400,  800,  840,  960, 1040, 0,  600,  602,  604,  700, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC },
     { MODEPREFIX("800x600Over"), 29500,  800,  824,  896,  944, 0,  600,  599,  604,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL  },
-    { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC },
 };
 
+int numVT1621Modes = sizeof(VT1621Modes) / sizeof(DisplayModeRec);
+
 struct VT1621TableRec {
     char *  name;
     CARD16  Width;
@@ -185,9 +186,10 @@ static DisplayModeRec VT1622Modes[] = {
     { MODEPREFIX("720x576Over"),    30000,  720,  728,  864, 1000, 0,  576,  576,  579,  600, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXPAL  },
     { MODEPREFIX("720x480Noscale"), 27972,  720,  736,  768,  888, 0,  480,  480,  483,  525, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXNTSC },
     { MODEPREFIX("720x576Noscale"), 28000,  720,  728,  864,  896, 0,  576,  576,  579,  625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL  },
-    { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC },
 };
 
+int numVT1622Modes = sizeof(VT1622Modes) / sizeof(DisplayModeRec);
+
 struct VT162XTableRec {
     char *  name;
     CARD16  Width;
@@ -466,9 +468,10 @@ static DisplayModeRec VT1623Modes[] = {
     { MODEPREFIX("720x576Noscale"),  28000,  720,  736,  768,  896,  0,  576,  576,  579,  625,  0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL  },
     { MODEPREFIX("720x480Noscale"),  27972,  720,  736,  768,  888,  0,  480,  480,  483,  525,  0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC  },
     { MODEPREFIX("720x480pal"), 27972,  720,  736,  768,  888, 0,  480,  480,  483,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL },
-    { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC },
 };
 
+int numVT1623Modes = sizeof(VT1623Modes) / sizeof(DisplayModeRec);
+
 static struct VT162XTableRec
 VT1623Table[] = {
     { "640x480", 640, 480, TVTYPE_NTSC, 0, 0,
@@ -772,10 +775,10 @@ static DisplayModeRec VT1625Modes[] = {
     { MODEPREFIX("720x480Under"), 28224,  720,  728,  744,  784, 0,  480,  490,  496,  600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX480P  },
     { MODEPREFIX("720x480Fit"),   28980,  720,  728,  776,  840, 0,  480,  484,  499,  575, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX480P  },
     { MODEPREFIX("720x480Over"),  27027,  720,  784,  808,  858, 0,  480,  483,  486,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX480P  },
-
-    { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC },
 };
 
+int numVT1625Modes = sizeof(VT1625Modes) / sizeof(DisplayModeRec);
+
 static struct VT162XTableRec
 VT1625Table[] = {
     { "640x480", 640, 480, TVTYPE_NTSC, 0, 0,
-- 
1.7.10.4

>From c4a0fbe82b422fe4d14bf5336052b2c067ee49ee Mon Sep 17 00:00:00 2001
From: Harry de Boer <ha...@ijscoboer.nl>
Date: Thu, 22 Nov 2012 13:21:36 +0100
Subject: [PATCH 1/4] Fix VT1625 output sensing. VT1625DACSenseI2C was using
 the same code as VT162xDACSenseI2C but the DAC sensing
 bit is in a different register for the VT1625. Also
 adds support for the VT1625S which has only four DACs.

---
 src/via_vt162x.c |   43 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 11 deletions(-)

diff --git a/src/via_vt162x.c b/src/via_vt162x.c
index f13a94b..91dc8cb 100644
--- a/src/via_vt162x.c
+++ b/src/via_vt162x.c
@@ -210,21 +210,42 @@ VT162xDACSenseI2C(I2CDevPtr pDev)
 }
 
 /*
- * VT1625 moves DACa through DACd from bits 0-3 to 2-5.
+ * VT1625/VT1625S sense connected TV outputs.
+ *
+ * The lower six bits of the return byte stand for each of the six DACs:
+ *  - bit 0: DACf (Cb)
+ *  - bit 1: DACe (Cr)
+ *  - bit 2: DACd (Y)
+ *  - bit 3: DACc (Composite)
+ *  - bit 4: DACb (S-Video C)
+ *  - bit 5: DACa (S-Video Y)
+ *
+ * If a bit is 0 it means a cable is connected. Note the VT1625S only has 
+ * four DACs, corresponding to bit 0-3 above.
  */
 static CARD8
 VT1625DACSenseI2C(I2CDevPtr pDev)
 {
-    CARD8 save, sense;
-
-    xf86I2CReadByte(pDev, 0x0E, &save);
-    xf86I2CWriteByte(pDev, 0x0E, 0x00);
-    xf86I2CWriteByte(pDev, 0x0E, 0x80);
-    xf86I2CWriteByte(pDev, 0x0E, 0x00);
-    xf86I2CReadByte(pDev, 0x0F, &sense);
-    xf86I2CWriteByte(pDev, 0x0E, save);
-
-    return (sense & 0x3F);
+    CARD8 power, status, overflow, dacPresent;
+
+    xf86I2CReadByte(pDev, 0x0E, &power);     // save power state
+
+    // VT1625S will always report 0 for bits 4 and 5 of the status register as
+    // it only has four DACs instead of six. This will result in a false
+    // positive for the S-Video cable. It will also do this on the power
+    // register, which is abused to check which DACs are actually present.
+    xf86I2CWriteByte(pDev, 0x0E, 0xFF);
+    xf86I2CReadByte(pDev, 0x0E, &dacPresent);
+
+    xf86I2CWriteByte(pDev, 0x0E, 0x00);      // power on DACs/circuits
+    xf86I2CReadByte(pDev, 0x1C, &overflow);  // save overflow reg (DAC sense bit should be off)
+    xf86I2CWriteByte(pDev, 0x1C, 0x80);      // enable DAC sense bit
+    xf86I2CWriteByte(pDev, 0x1C, overflow);  // disable DAC sense bit
+    xf86I2CReadByte(pDev, 0x0F, &status);    // read connection status
+    xf86I2CWriteByte(pDev, 0x0E, power);     // restore power state
+    status |= ~dacPresent;
+
+    return (status & 0x3F);
 }
 
 /*
-- 
1.7.10.4

>From 65beba342aacba3c6de85a1450a763ccbf8d0163 Mon Sep 17 00:00:00 2001
From: Harry de Boer <ha...@ijscoboer.nl>
Date: Thu, 22 Nov 2012 22:41:50 +0100
Subject: [PATCH 2/4] VT1625 register count is 0x82

---
 src/via_vt162x.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/via_vt162x.c b/src/via_vt162x.c
index 91dc8cb..0c558f4 100644
--- a/src/via_vt162x.c
+++ b/src/via_vt162x.c
@@ -908,7 +908,7 @@ ViaVT162xInit(ScrnInfoPtr pScrn)
             pBIOSInfo->TVPower = VT1625Power;
             pBIOSInfo->TVModes = VT1625Modes;
             pBIOSInfo->TVPrintRegs = VT162xPrintRegs;
-            pBIOSInfo->TVNumRegs = 0x6C;
+            pBIOSInfo->TVNumRegs = 0x82;
             break;
         default:
             break;
-- 
1.7.10.4

>From e00d189c634c36b7c3b984894b9e048231608bf1 Mon Sep 17 00:00:00 2001
From: Harry de Boer <ha...@ijscoboer.nl>
Date: Mon, 26 Nov 2012 02:58:25 +0100
Subject: [PATCH 3/4] There is a possible crtc for TV-1

---
 src/via_driver.c  |    4 +++-
 src/via_outputs.c |    7 +++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/via_driver.c b/src/via_driver.c
index 8542ef2..bf3e1fb 100644
--- a/src/via_driver.c
+++ b/src/via_driver.c
@@ -1537,8 +1537,10 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
         }
     }
 
-    if (!xf86InitialConfiguration(pScrn, TRUE))
+    if (!xf86InitialConfiguration(pScrn, TRUE)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Initial configuration failed\n");
         return FALSE;
+    }
 
     if (!pScrn->modes) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
diff --git a/src/via_outputs.c b/src/via_outputs.c
index 75d312c..0620a12 100644
--- a/src/via_outputs.c
+++ b/src/via_outputs.c
@@ -466,6 +466,13 @@ via_tv_init(ScrnInfoPtr pScrn)
 
     output = xf86OutputCreate(pScrn, &via_tv_funcs, "TV-1");
     pVia->FirstInit = TRUE;
+
+    if (output) {
+        output->possible_crtcs = 0x1;
+    } else {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "via_tv_init: Failed to create output for TV-1.\n");
+    }
+
     pBIOSInfo->tv = output;
     /* Save now */
     pBIOSInfo->TVSave(pScrn);
-- 
1.7.10.4

_______________________________________________
Openchrome-devel mailing list
Openchrome-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/openchrome-devel

Reply via email to