summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2009-06-10 11:37:02 +0800
committerZhenyu Wang <zhenyu.z.wang@intel.com>2009-06-15 14:56:56 +0800
commit51b87b9913ba164d4d5de79e558233915b37a0a5 (patch)
treec56aec099130e69c7e6f490b68619a866558a9f8
parent6ba148bbd78783f59eed3d898638c39b950dcd89 (diff)
parse general definition block to get the SDVO device info
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.zhao@intel.com>
-rw-r--r--src/i830.h8
-rw-r--r--src/i830_bios.c81
2 files changed, 88 insertions, 1 deletions
diff --git a/src/i830.h b/src/i830.h
index a69f47ce..19b189c2 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -328,7 +328,12 @@ enum dri_type {
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;
@@ -608,6 +613,7 @@ typedef struct _I830Rec {
/** 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))
diff --git a/src/i830_bios.c b/src/i830_bios.c
index 9c1f1017..2f129e97 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -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 @@ parse_driver_feature(I830Ptr pI830, struct bdb_header *bdb)
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 @@ i830_bios_init(ScrnInfoPtr pScrn)
parse_general_features(pI830, bdb);
parse_panel_data(pI830, bdb);
parse_driver_feature(pI830, bdb);
+ parse_sdvo_mapping(pScrn, bdb);
xfree(bios);