xf86-video-intel: 2 commits - src/bios_reader/bios_reader.c src/i830_bios.c

Jesse Barnes jbarnes at kemper.freedesktop.org
Tue Sep 30 12:49:37 PDT 2008


 src/bios_reader/bios_reader.c |  157 ++++++++++++++++++++++++++++++------------
 src/i830_bios.c               |   13 +--
 2 files changed, 121 insertions(+), 49 deletions(-)

New commits:
commit a4568740ee296bc392843fd324d2a047e7862187
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Sep 30 12:48:32 2008 -0700

    Be more verbose about panel data in VBIOS dumper
    
    Dump more panel data, including number of expected entries.  Had to
    refactor things a bit, but now each function should get size information
    so further checking can be added more easily.

diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c
index 9e05317..29c3edb 100644
--- a/src/bios_reader/bios_reader.c
+++ b/src/bios_reader/bios_reader.c
@@ -59,42 +59,66 @@ struct _fake_i830 *pI830 = &I830;
 
 #define YESNO(val) ((val) ? "yes" : "no")
 
+struct bdb_block {
+    uint8_t id;
+    uint16_t size;
+    void *data;
+};
+
+struct bdb_header *bdb;
 static int tv_present;
 static int lvds_present;
 static int panel_type;
 
-static void *find_section(struct bdb_header *bdb, int section_id)
+static struct bdb_block *find_section(int section_id)
 {
-	unsigned char *base = (unsigned char *)bdb;
-	int index = 0;
-	uint16_t total, current_size;
-	unsigned char current_id;
-
-	/* skip to first section */
-	index += bdb->header_size;
-	total = bdb->bdb_size;
-
-	/* walk the sections looking for section_id */
-	while (index < total) {
-		current_id = *(base + index);
-		index++;
-		current_size = *((uint16_t *)(base + index));
-		index += 2;
-		if (current_id == section_id)
-			return base + index;
-		index += current_size;
+    struct bdb_block *block;
+    unsigned char *base = (unsigned char *)bdb;
+    int index = 0;
+    uint16_t total, current_size;
+    unsigned char current_id;
+
+    /* skip to first section */
+    index += bdb->header_size;
+    total = bdb->bdb_size;
+
+    block = malloc(sizeof(*block));
+    if (!block) {
+	fprintf(stderr, "out of memory\n");
+	exit(-1);
+    }
+
+    /* walk the sections looking for section_id */
+    while (index < total) {
+	current_id = *(base + index);
+	index++;
+	current_size = *((uint16_t *)(base + index));
+	index += 2;
+	if (current_id == section_id) {
+	    block->id = current_id;
+	    block->size = current_size;
+	    block->data = base + index;
+	    return block;
 	}
+	index += current_size;
+    }
 
-	return NULL;
+    free(block);
+    return NULL;
 }
 
-static void dump_general_features(void *data)
+static void dump_general_features(void)
 {
-    struct bdb_general_features *features = data;
+    struct bdb_general_features *features;
+    struct bdb_block *block;
+
+    block = find_section(BDB_GENERAL_FEATURES);
 
-    if (!data)
+    if (!block)
 	return;
 
+    features = block->data;
+
     printf("General features block:\n");
 
     printf("\tPanel fitting: ");
@@ -133,16 +157,24 @@ static void dump_general_features(void *data)
 
     tv_present = 1; /* should be based on whether TV DAC exists */
     lvds_present = 1; /* should be based on IS_MOBILE() */
+
+    free(block);
 }
 
-static void dump_general_definitions(void *data)
+static void dump_general_definitions(void)
 {
-    struct bdb_general_definitions *defs = data;
-    unsigned char *lvds_data = defs->tv_or_lvds_info;
+    struct bdb_block *block;
+    struct bdb_general_definitions *defs;
+    unsigned char *lvds_data;
+
+    block = find_section(BDB_GENERAL_DEFINITIONS);
 
-    if (!data)
+    if (!block)
 	return;
 
+    defs = block->data;
+    lvds_data = defs->tv_or_lvds_info;
+
     printf("General definitions block:\n");
 
     printf("\tCRT DDC GMBUS addr: 0x%02x\n", defs->crt_ddc_gmbus_pin);
@@ -157,15 +189,22 @@ static void dump_general_definitions(void *data)
 	lvds_data += 33;
     if (lvds_present)
 	printf("\tLFP DDC GMBUS addr: 0x%02x\n", lvds_data[19]);
+
+    free(block);
 }
 
-static void dump_lvds_options(void *data)
+static void dump_lvds_options(void)
 {
-    struct bdb_lvds_options *options = data;
+    struct bdb_block *block;
+    struct bdb_lvds_options *options;
+
+    block = find_section(BDB_LVDS_OPTIONS);
 
-    if (!data)
+    if (!block)
 	return;
 
+    options = block->data;
+
     printf("LVDS options block:\n");
 
     panel_type = options->panel_type;
@@ -178,19 +217,51 @@ static void dump_lvds_options(void *data)
     printf("\tPFIT enhanced text mode: %s\n",
 	   YESNO(options->pfit_text_mode_enhanced));
     printf("\tPFIT mode: %d\n", options->pfit_mode);
+
+    free(block);
 }
 
-static void dump_lvds_data(void *data, unsigned char *base)
+static void dump_lvds_ptr_data(void)
 {
-    struct bdb_lvds_lfp_data *lvds_data = data;
+    struct bdb_block *block;
+    struct bdb_lvds_lfp_data_ptrs *ptrs;
+    struct lvds_fp_timing *fp_timing;
+
+    block = find_section(BDB_LVDS_LFP_DATA_PTRS);
+    if (!block)
+	return;
+
+    ptrs = block->data;
+    fp_timing =	(struct lvds_fp_timing *)((uint8_t *)bdb +
+					  ptrs->ptr[panel_type].fp_timing_offset);
+
+    printf("LVDS timing pointer data:\n");
+    printf("  Number of entries: %d\n", ptrs->lvds_entries);
+
+    printf("\tpanel type %02i: %dx%d\n", panel_type, fp_timing->x_res,
+	   fp_timing->y_res);
+
+    free(block);
+}
+
+static void dump_lvds_data(void)
+{
+    struct bdb_block *block;
+    struct bdb_lvds_lfp_data *lvds_data;
+    int num_entries;
     int i;
 
-    if (!data)
+    block = find_section(BDB_LVDS_LFP_DATA);
+    if (!block)
 	return;
 
+    lvds_data = block->data;
+    num_entries = block->size / sizeof(struct bdb_lvds_lfp_data_entry);
+
     printf("LVDS panel data block (preferred block marked with '*'):\n");
+    printf("  Number of entries: %d\n", num_entries);
 
-    for (i = 0; i < 16; i++) {
+    for (i = 0; i < num_entries; i++) {
 	struct bdb_lvds_lfp_data_entry *lfp_data = &lvds_data->data[i];
 	uint8_t *timing_data = (uint8_t *)&lfp_data->dvo_timing;
 	char marker;
@@ -198,13 +269,13 @@ static void dump_lvds_data(void *data, unsigned char *base)
 	if (i == panel_type)
 	    marker = '*';
 	else
-	    continue;
+	    marker = ' ';
 
 	printf("%c\tpanel type %02i: %dx%d clock %d\n", marker,
 	       i, lfp_data->fp_timing.x_res, lfp_data->fp_timing.y_res,
 	       _PIXEL_CLOCK(timing_data));
 	printf("\t\tinfo:\n");
-	printf("\t\t  LVDS: 0x%08lx\n", 
+	printf("\t\t  LVDS: 0x%08lx\n",
 	       (unsigned long)lfp_data->fp_timing.lvds_reg_val);
 	printf("\t\t  PP_ON_DELAYS: 0x%08lx\n",
 	       (unsigned long)lfp_data->fp_timing.pp_on_reg_val);
@@ -224,14 +295,13 @@ static void dump_lvds_data(void *data, unsigned char *base)
 	       _V_SYNC_OFF(timing_data),
 	       _V_SYNC_WIDTH(timing_data));
     }
-
+    free(block);
 }
 
 int main(int argc, char **argv)
 {
     int fd;
     struct vbt_header *vbt = NULL;
-    struct bdb_header *bdb;
     int vbt_off, bdb_off, i;
     char *filename = "bios";
     struct stat finfo;
@@ -240,7 +310,7 @@ int main(int argc, char **argv)
 	printf("usage: %s <rom file>\n", argv[0]);
 	return 1;
     }
-	
+
     filename = argv[1];
 
     fd = open(filename, O_RDONLY);
@@ -281,10 +351,11 @@ int main(int argc, char **argv)
     printf("BDB sig: %16s\n", bdb->signature);
     printf("BDB vers: %d.%d\n", bdb->version / 100, bdb->version % 100);
 
-    dump_general_features(find_section(bdb, BDB_GENERAL_FEATURES));
-    dump_general_definitions(find_section(bdb, BDB_GENERAL_DEFINITIONS));
-    dump_lvds_options(find_section(bdb, BDB_LVDS_OPTIONS));
-    dump_lvds_data(find_section(bdb, BDB_LVDS_LFP_DATA), (unsigned char *)bdb);
+    dump_general_features();
+    dump_general_definitions();
+    dump_lvds_options();
+    dump_lvds_data();
+    dump_lvds_ptr_data();
 
     return 0;
 }
commit fa2586a40f20e73ec7420466638e8f595e0da987
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Sep 30 12:46:20 2008 -0700

    Use VBT LFP info pointers by default
    
    On some machines it appears that the LFP info pointers give us more
    accurate panel info than if we index into the LFP data table using the
    panel type index.  Early reports indicate that using the pointers
    doesn't cause regressions, so switch to them by default to help 8xx
    machines.
    
    Fixes bug 17310 (and hopefully 17658 too).

diff --git a/src/i830_bios.c b/src/i830_bios.c
index ff49025..2cb0b07 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -88,8 +88,8 @@ static void
 parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
 {
     struct bdb_lvds_options *lvds_options;
-    struct bdb_lvds_lfp_data *lvds_lfp_data;
-    struct bdb_lvds_lfp_data_entry *entry;
+    struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
+    int timing_offset;
     DisplayModePtr fixed_mode;
     unsigned char *timing_ptr;
 
@@ -104,12 +104,13 @@ parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
     if (lvds_options->panel_type == 0xff)
 	return;
 
-    lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
-    if (!lvds_lfp_data)
+    lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS);
+    if (!lvds_lfp_data_ptrs)
 	return;
 
-    entry = &lvds_lfp_data->data[lvds_options->panel_type];
-    timing_ptr = (unsigned char *)&entry->dvo_timing;
+    timing_offset =
+	lvds_lfp_data_ptrs->ptr[lvds_options->panel_type].dvo_timing_offset;
+    timing_ptr = (unsigned char *)bdb + timing_offset;
 
     fixed_mode = xnfalloc(sizeof(DisplayModeRec));
     memset(fixed_mode, 0, sizeof(*fixed_mode));


More information about the xorg-commit mailing list