Some good news: I got the the basic 720x576 PAL mode working again.

It turns out the list of modelines in DisplayModePtr now has a ->next element that is used to go to the next item on the list. These next items were all NULL so there was only one modeline recognised by the server.

I created a helper function that creates DisplayModePtrs with next elements from a DisplayModeRec[] much like the xorg edid code does. As this affects all tv encoders I applied it throughout the codebase.

With this fix it was possible to select the 720x756 mode again which works for me (as it did in the past). Other modes are still a mess (including 720x756Over which also used to work). I'll look into the other modes next.

Patches so far are attached.

Cheers,
Harry

On 26-11-12 15:30, Harry de Boer wrote:
Hi,

I have made some progress:

- I updated the output sensing patch to support the VT1625S. The power register has the same layout as the status register. A 0 is always for the DACs that are not present, so writing all 1-bits and reading back the register results in a mask of which DACs are actually present.

- The number of tv registers on the VT1625 is 0x82, not 0x6C. This should not matter for anything currently in place.

- The tv screen is lighting up now. Apparently xf86OutputPtr->possible_crtcs should have a value of 1 or higher for it to be a valid configuration.

Don't get excited yet, the output is a complete mess. It seems the driver only reports one modeline, 640x480, which I believe has never worked for me anyway. Only 720x576 worked. I guess that is because the some of the registers are not set correctly and 720x576 works because it is the default set by the BIOS (for PAL).

But first I'll try to get the driver to report all supported modelines. Attached are the patches of what I have so far.

On 23-11-12 00:40, Willem van Asperen wrote:
I've applied Harry's patch and it now correctly senses the TV-Out, so good work Harry!

I kind of expected it to work for you since we seem to have exactly the same board :-)

Cheers,
Harry


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

>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

>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

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

Reply via email to