The general definition block contains the child device tables, which include
the child device info. For example: device slave address, device dvo port,
device type.
We will get the info of SDVO device by parsing the general definition blocks.
Only when a valid slave address is found, it is regarded as the SDVO device.
And the info of DVO port and slave address is recorded.

http://bugs.freedesktop.org/show_bug.cgi?id=20429

Signed-off-by: Zhao Yakui <yakui.z...@intel.com>
---
 src/i830.h      |    8 ++++-
 src/i830_bios.c |   81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+), 1 deletion(-)

Index: xf86_video_intel/src/i830_bios.c
===================================================================
--- xf86_video_intel.orig/src/i830_bios.c       2009-06-08 09:57:38.000000000 
+0800
+++ xf86_video_intel/src/i830_bios.c    2009-06-08 10:08:17.000000000 +0800
@@ -47,6 +47,8 @@
                                 (bios[_addr + 2] << 16) |      \
                                 (bios[_addr + 3] << 24))
 
+#define                SLAVE_ADDR1     0x70
+#define                SLAVE_ADDR2     0x72
 static void *
 find_section(struct bdb_header *bdb, int section_id)
 {
@@ -236,6 +238,84 @@
        pI830->integrated_lvds = FALSE;
 }
 
+static
+void parse_sdvo_mapping(ScrnInfoPtr pScrn, struct bdb_header *bdb)
+{
+    unsigned int block_size;
+    uint16_t *block_ptr;
+    struct bdb_general_definitions *defs;
+    struct child_device_config *child;
+    int i, child_device_num, count;
+    struct sdvo_device_mapping *p_mapping;
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+    if (!defs) {
+       xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                       "can't find the general definition blocks\n");
+       return;
+    }
+    /* Get the block size of general defintion block */
+    block_ptr = (uint16_t *)((char *)defs - 2);
+    block_size = *block_ptr;
+    child_device_num = (block_size - sizeof(*defs)) / sizeof(*child);
+    count = 0;
+
+    for (i = 0; i < child_device_num; i++) {
+       child = &defs->devices[i];
+       if (!child->device_type) {
+               /* skip invalid child device type*/
+                continue;
+       }
+       if (child->slave_addr == SLAVE_ADDR1 ||
+               child->slave_addr == SLAVE_ADDR2) {
+           if (child->dvo_port != DEVICE_PORT_DVOB &&
+                       child->dvo_port != DEVICE_PORT_DVOC) {
+               /* skip the incorrect sdvo port */
+               xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                               "Incorrect SDVO port\n");
+               continue;
+           }
+           xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                       "the SDVO device with slave addr %x "
+                       "is found on DVO %x port\n",
+                       child->slave_addr, child->dvo_port);
+           /* fill the primary dvo port */
+           p_mapping = &(pI830->sdvo_mappings[child->dvo_port - 1]);
+           if (!p_mapping->initialized) {
+               p_mapping->dvo_port = child->dvo_port;
+               p_mapping->dvo_wiring = child->dvo_wiring;
+               p_mapping->initialized = 1;
+               p_mapping->slave_addr = child->slave_addr;
+           } else {
+               xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                               "One DVO port is shared by two slave "
+                               "address. Maybe it can't be handled\n");
+           }
+           /* If there exists the slave2_addr, maybe it is a sdvo
+            * device that contain multiple inputs. And it can't
+            * handled by SDVO driver.
+            * Ignore the dvo mapping of slave2_addr
+            * of course its mapping info won't be added.
+            */
+           if (child->slave2_addr) {
+               xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                               "Two DVO ports uses the same slave address."
+                               "Maybe it can't be handled by SDVO driver\n");
+           }
+           count++;
+       } else {
+           /* if the slave address is neither 0x70 nor 0x72, skip it. */
+           continue;
+       }
+    }
+    /* If the count is zero, it indicates that no sdvo device is found */
+    if (!count)
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                       "No SDVO device is found in VBT\n");
+
+    return;
+}
 #define INTEL_VBIOS_SIZE (64 * 1024)   /* XXX */
 
 /**
@@ -302,6 +382,7 @@
     parse_general_features(pI830, bdb);
     parse_panel_data(pI830, bdb);
     parse_driver_feature(pI830, bdb);
+    parse_sdvo_mapping(pScrn, bdb);
 
     xfree(bios);
 
Index: xf86_video_intel/src/i830.h
===================================================================
--- xf86_video_intel.orig/src/i830.h    2009-06-08 09:57:38.000000000 +0800
+++ xf86_video_intel/src/i830.h 2009-06-08 10:08:17.000000000 +0800
@@ -328,7 +328,12 @@
     DRI_NONE,
     DRI_DRI2
 };
-
+struct sdvo_device_mapping {
+   uint8_t dvo_port;
+   uint8_t slave_addr;
+   uint8_t dvo_wiring;
+   uint8_t initialized;
+};
 typedef struct _I830Rec {
    unsigned char *MMIOBase;
    unsigned char *GTTBase;
@@ -607,6 +612,7 @@
 
     /** User option to print acceleration fallback info to the server log. */
    Bool fallback_debug;
+   struct sdvo_device_mapping sdvo_mappings[2];
 } I830Rec;
 
 #define I830PTR(p) ((I830Ptr)((p)->driverPrivate))



------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises 
looking to deploy the next generation of Solaris that includes the latest 
innovations from Sun and the OpenSource community. Download a copy and 
enjoy capabilities such as Networking, Storage and Virtualization. 
Go to: http://p.sf.net/sfu/opensolaris-get
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to