1fa225cbcSrjs/* 2fa225cbcSrjs * Copyright � 2006 Intel Corporation 3fa225cbcSrjs * 4fa225cbcSrjs * Permission is hereby granted, free of charge, to any person obtaining a 5fa225cbcSrjs * copy of this software and associated documentation files (the "Software"), 6fa225cbcSrjs * to deal in the Software without restriction, including without limitation 7fa225cbcSrjs * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8fa225cbcSrjs * and/or sell copies of the Software, and to permit persons to whom the 9fa225cbcSrjs * Software is furnished to do so, subject to the following conditions: 10fa225cbcSrjs * 11fa225cbcSrjs * The above copyright notice and this permission notice (including the next 12fa225cbcSrjs * paragraph) shall be included in all copies or substantial portions of the 13fa225cbcSrjs * Software. 14fa225cbcSrjs * 15fa225cbcSrjs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16fa225cbcSrjs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17fa225cbcSrjs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18fa225cbcSrjs * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19fa225cbcSrjs * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20fa225cbcSrjs * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21fa225cbcSrjs * SOFTWARE. 22fa225cbcSrjs * 23fa225cbcSrjs * Authors: 24fa225cbcSrjs * Eric Anholt <eric@anholt.net> 25fa225cbcSrjs * 26fa225cbcSrjs */ 27fa225cbcSrjs 28fa225cbcSrjs#include <errno.h> 29fa225cbcSrjs#include <fcntl.h> 30fa225cbcSrjs#include <stdio.h> 31fa225cbcSrjs#include <stdlib.h> 32fa225cbcSrjs#include <string.h> 33fa225cbcSrjs#include <unistd.h> 34fa225cbcSrjs#include <sys/mman.h> 35fa225cbcSrjs#include <sys/stat.h> 36fa225cbcSrjs#include <sys/types.h> 37fa225cbcSrjs 38fa225cbcSrjs 39fa225cbcSrjs#include "../i830_bios.h" 40fa225cbcSrjs 41fa225cbcSrjs#include <X11/Xfuncproto.h> 42fa225cbcSrjs#include <X11/Xmd.h> 43fa225cbcSrjs#define _PARSE_EDID_ 44fa225cbcSrjs#include "edid.h" 45fa225cbcSrjs 46fa225cbcSrjs 47fa225cbcSrjs/* Make a fake pI830 so we can easily pull i830_bios.c code in here. */ 48fa225cbcSrjsstruct _fake_i830 { 49fa225cbcSrjs uint8_t *VBIOS; 50fa225cbcSrjs}; 51fa225cbcSrjsstruct _fake_i830 I830; 52fa225cbcSrjsstruct _fake_i830 *pI830 = &I830; 53fa225cbcSrjs 54fa225cbcSrjs#define INTEL_BIOS_8(_addr) (pI830->VBIOS[_addr]) 55fa225cbcSrjs#define INTEL_BIOS_16(_addr) (pI830->VBIOS[_addr] | \ 56fa225cbcSrjs (pI830->VBIOS[_addr + 1] << 8)) 57fa225cbcSrjs#define INTEL_BIOS_32(_addr) (pI830->VBIOS[_addr] | \ 58fa225cbcSrjs (pI830->VBIOS[_addr + 1] << 8) | \ 59fa225cbcSrjs (pI830->VBIOS[_addr + 2] << 16) | \ 60fa225cbcSrjs (pI830->VBIOS[_addr + 3] << 24)) 61fa225cbcSrjs 62fa225cbcSrjs#define YESNO(val) ((val) ? "yes" : "no") 63fa225cbcSrjs 64fa225cbcSrjsstruct bdb_block { 65fa225cbcSrjs uint8_t id; 66fa225cbcSrjs uint16_t size; 67fa225cbcSrjs void *data; 68fa225cbcSrjs}; 69fa225cbcSrjs 70fa225cbcSrjsstruct bdb_header *bdb; 71fa225cbcSrjsstatic int tv_present; 72fa225cbcSrjsstatic int lvds_present; 73fa225cbcSrjsstatic int panel_type; 74fa225cbcSrjs 75fa225cbcSrjsstatic struct bdb_block *find_section(int section_id) 76fa225cbcSrjs{ 77fa225cbcSrjs struct bdb_block *block; 78fa225cbcSrjs unsigned char *base = (unsigned char *)bdb; 79fa225cbcSrjs int index = 0; 80fa225cbcSrjs uint16_t total, current_size; 81fa225cbcSrjs unsigned char current_id; 82fa225cbcSrjs 83fa225cbcSrjs /* skip to first section */ 84fa225cbcSrjs index += bdb->header_size; 85fa225cbcSrjs total = bdb->bdb_size; 86fa225cbcSrjs 87fa225cbcSrjs block = malloc(sizeof(*block)); 88fa225cbcSrjs if (!block) { 89fa225cbcSrjs fprintf(stderr, "out of memory\n"); 90fa225cbcSrjs exit(-1); 91fa225cbcSrjs } 92fa225cbcSrjs 93fa225cbcSrjs /* walk the sections looking for section_id */ 94fa225cbcSrjs while (index < total) { 95fa225cbcSrjs current_id = *(base + index); 96fa225cbcSrjs index++; 97fa225cbcSrjs current_size = *((uint16_t *)(base + index)); 98fa225cbcSrjs index += 2; 99fa225cbcSrjs if (current_id == section_id) { 100fa225cbcSrjs block->id = current_id; 101fa225cbcSrjs block->size = current_size; 102fa225cbcSrjs block->data = base + index; 103fa225cbcSrjs return block; 104fa225cbcSrjs } 105fa225cbcSrjs index += current_size; 106fa225cbcSrjs } 107fa225cbcSrjs 108fa225cbcSrjs free(block); 109fa225cbcSrjs return NULL; 110fa225cbcSrjs} 111fa225cbcSrjs 112fa225cbcSrjsstatic void dump_general_features(void) 113fa225cbcSrjs{ 114fa225cbcSrjs struct bdb_general_features *features; 115fa225cbcSrjs struct bdb_block *block; 116fa225cbcSrjs 117fa225cbcSrjs block = find_section(BDB_GENERAL_FEATURES); 118fa225cbcSrjs 119fa225cbcSrjs if (!block) 120fa225cbcSrjs return; 121fa225cbcSrjs 122fa225cbcSrjs features = block->data; 123fa225cbcSrjs 124fa225cbcSrjs printf("General features block:\n"); 125fa225cbcSrjs 126fa225cbcSrjs printf("\tPanel fitting: "); 127fa225cbcSrjs switch (features->panel_fitting) { 128fa225cbcSrjs case 0: 129fa225cbcSrjs printf("disabled\n"); 130fa225cbcSrjs break; 131fa225cbcSrjs case 1: 132fa225cbcSrjs printf("text only\n"); 133fa225cbcSrjs break; 134fa225cbcSrjs case 2: 135fa225cbcSrjs printf("graphics only\n"); 136fa225cbcSrjs break; 137fa225cbcSrjs case 3: 138fa225cbcSrjs printf("text & graphics\n"); 139fa225cbcSrjs break; 140fa225cbcSrjs } 141fa225cbcSrjs printf("\tFlexaim: %s\n", YESNO(features->flexaim)); 142fa225cbcSrjs printf("\tMessage: %s\n", YESNO(features->msg_enable)); 143fa225cbcSrjs printf("\tClear screen: %d\n", features->clear_screen); 144fa225cbcSrjs printf("\tDVO color flip required: %s\n", YESNO(features->color_flip)); 145fa225cbcSrjs printf("\tExternal VBT: %s\n", YESNO(features->download_ext_vbt)); 146fa225cbcSrjs printf("\tEnable SSC: %s\n", YESNO(features->enable_ssc)); 147fa225cbcSrjs if (features->enable_ssc) 148fa225cbcSrjs printf("\tSSC frequency: %s\n", features->ssc_freq ? 149fa225cbcSrjs "100 MHz (66 MHz on 855)" : "96 MHz (48 MHz on 855)"); 150fa225cbcSrjs printf("\tLFP on override: %s\n", YESNO(features->enable_lfp_on_override)); 151fa225cbcSrjs printf("\tDisable SSC on clone: %s\n", YESNO(features->disable_ssc_ddt)); 152fa225cbcSrjs printf("\tDisable smooth vision: %s\n", 153fa225cbcSrjs YESNO(features->disable_smooth_vision)); 154fa225cbcSrjs printf("\tSingle DVI for CRT/DVI: %s\n", YESNO(features->single_dvi)); 155fa225cbcSrjs printf("\tLegacy monitor detect: %s\n", 156fa225cbcSrjs YESNO(features->legacy_monitor_detect)); 157fa225cbcSrjs printf("\tIntegrated CRT: %s\n", YESNO(features->int_crt_support)); 158fa225cbcSrjs printf("\tIntegrated TV: %s\n", YESNO(features->int_tv_support)); 159fa225cbcSrjs 160fa225cbcSrjs tv_present = 1; /* should be based on whether TV DAC exists */ 161fa225cbcSrjs lvds_present = 1; /* should be based on IS_MOBILE() */ 162fa225cbcSrjs 163fa225cbcSrjs free(block); 164fa225cbcSrjs} 165fa225cbcSrjs 166fa225cbcSrjsstatic void dump_backlight_info(void) 167fa225cbcSrjs{ 168fa225cbcSrjs struct bdb_block *block; 169fa225cbcSrjs struct bdb_lvds_backlight *backlight; 170fa225cbcSrjs struct blc_struct *blc; 171fa225cbcSrjs 172fa225cbcSrjs block = find_section(BDB_LVDS_BACKLIGHT); 173fa225cbcSrjs 174fa225cbcSrjs if (!block) 175fa225cbcSrjs return; 176fa225cbcSrjs 177fa225cbcSrjs backlight = block->data; 178fa225cbcSrjs 179fa225cbcSrjs printf("Backlight info block (len %d):\n", block->size); 180fa225cbcSrjs 181fa225cbcSrjs if (sizeof(struct blc_struct) != backlight->blcstruct_size) { 182fa225cbcSrjs printf("\tBacklight struct sizes don't match (expected %d, got %d), skipping\n", 183fa225cbcSrjs sizeof(struct blc_struct), backlight->blcstruct_size); 184fa225cbcSrjs return; 185fa225cbcSrjs } 186fa225cbcSrjs 187fa225cbcSrjs blc = &backlight->panels[panel_type]; 188fa225cbcSrjs 189fa225cbcSrjs printf("\tInverter type: %d\n", blc->inverter_type); 190fa225cbcSrjs printf("\t polarity: %d\n", blc->inverter_polarity); 191fa225cbcSrjs printf("\t GPIO pins: %d\n", blc->gpio_pins); 192fa225cbcSrjs printf("\t GMBUS speed: %d\n", blc->gmbus_speed); 193fa225cbcSrjs printf("\t PWM freq: %d\n", blc->pwm_freq); 194fa225cbcSrjs printf("\tMinimum brightness: %d\n", blc->min_brightness); 195fa225cbcSrjs printf("\tI2C slave addr: 0x%02x\n", blc->i2c_slave_addr); 196fa225cbcSrjs printf("\tI2C command: 0x%02x\n", blc->i2c_cmd); 197fa225cbcSrjs} 198fa225cbcSrjs 199fa225cbcSrjsstatic void dump_general_definitions(void) 200fa225cbcSrjs{ 201fa225cbcSrjs struct bdb_block *block; 202fa225cbcSrjs struct bdb_general_definitions *defs; 203fa225cbcSrjs struct child_device_config *child; 204fa225cbcSrjs int i; 205fa225cbcSrjs char child_id[11]; 206fa225cbcSrjs int child_device_num; 207fa225cbcSrjs 208fa225cbcSrjs block = find_section(BDB_GENERAL_DEFINITIONS); 209fa225cbcSrjs 210fa225cbcSrjs if (!block) 211fa225cbcSrjs return; 212fa225cbcSrjs 213fa225cbcSrjs defs = block->data; 214fa225cbcSrjs 215fa225cbcSrjs printf("General definitions block:\n"); 216fa225cbcSrjs 217fa225cbcSrjs printf("\tCRT DDC GMBUS addr: 0x%02x\n", defs->crt_ddc_gmbus_pin); 218fa225cbcSrjs printf("\tUse ACPI DPMS CRT power states: %s\n", YESNO(defs->dpms_acpi)); 219fa225cbcSrjs printf("\tSkip CRT detect at boot: %s\n", 220fa225cbcSrjs YESNO(defs->skip_boot_crt_detect)); 221fa225cbcSrjs printf("\tUse DPMS on AIM devices: %s\n", YESNO(defs->dpms_aim)); 222fa225cbcSrjs printf("\tBoot display type: 0x%02x%02x\n", defs->boot_display[1], 223fa225cbcSrjs defs->boot_display[0]); 224fa225cbcSrjs printf("\tTV data block present: %s\n", YESNO(tv_present)); 225fa225cbcSrjs child_device_num = (block->size - sizeof(*defs)) / sizeof(*child); 226fa225cbcSrjs for (i = 0; i < child_device_num; i++) { 227fa225cbcSrjs child = &defs->devices[i]; 228fa225cbcSrjs if (!child->device_type) { 229fa225cbcSrjs printf("\tChild device %d not present\n", i); 230fa225cbcSrjs continue; 231fa225cbcSrjs } 232fa225cbcSrjs strncpy(child_id, (char *)child->device_id, 10); 233fa225cbcSrjs child_id[10] = 0; 234fa225cbcSrjs printf("\tChild %d device info:\n", i); 235fa225cbcSrjs printf("\t\tSignature: %s\n", child_id); 236fa225cbcSrjs printf("\t\tAIM offset: %d\n", child->addin_offset); 237fa225cbcSrjs printf("\t\tDVO port: 0x%02x\n", child->dvo_port); 238fa225cbcSrjs } 239fa225cbcSrjs 240fa225cbcSrjs free(block); 241fa225cbcSrjs} 242fa225cbcSrjs 243fa225cbcSrjs#if 0 244fa225cbcSrjsstatic void dump_child_devices(void) 245fa225cbcSrjs{ 246fa225cbcSrjs struct bdb_block *block; 247fa225cbcSrjs struct bdb_child_devices *child_devs; 248fa225cbcSrjs struct child_device_config *child; 249fa225cbcSrjs int i; 250fa225cbcSrjs 251fa225cbcSrjs block = find_section(BDB_CHILD_DEVICE_TABLE); 252fa225cbcSrjs if (!block) { 253fa225cbcSrjs printf("No child device table found\n"); 254fa225cbcSrjs return; 255fa225cbcSrjs } 256fa225cbcSrjs 257fa225cbcSrjs child_devs = block->data; 258fa225cbcSrjs 259fa225cbcSrjs printf("Child devices block:\n"); 260fa225cbcSrjs for (i = 0; i < DEVICE_CHILD_SIZE; i++) { 261fa225cbcSrjs child = &child_devs->children[i]; 262fa225cbcSrjs /* Skip nonexistent children */ 263fa225cbcSrjs if (!child->device_type) 264fa225cbcSrjs continue; 265fa225cbcSrjs printf("\tChild device %d\n", i); 266fa225cbcSrjs printf("\t\tType: 0x%04x\n", child->device_type); 267fa225cbcSrjs printf("\t\tDVO port: 0x%02x\n", child->dvo_port); 268fa225cbcSrjs printf("\t\tI2C pin: 0x%02x\n", child->i2c_pin); 269fa225cbcSrjs printf("\t\tSlave addr: 0x%02x\n", child->slave_addr); 270fa225cbcSrjs printf("\t\tDDC pin: 0x%02x\n", child->ddc_pin); 271fa225cbcSrjs printf("\t\tDVO config: 0x%02x\n", child->dvo_cfg); 272fa225cbcSrjs printf("\t\tDVO wiring: 0x%02x\n", child->dvo_wiring); 273fa225cbcSrjs } 274fa225cbcSrjs 275fa225cbcSrjs free(block); 276fa225cbcSrjs} 277fa225cbcSrjs#endif 278fa225cbcSrjs 279fa225cbcSrjsstatic void dump_lvds_options(void) 280fa225cbcSrjs{ 281fa225cbcSrjs struct bdb_block *block; 282fa225cbcSrjs struct bdb_lvds_options *options; 283fa225cbcSrjs 284fa225cbcSrjs block = find_section(BDB_LVDS_OPTIONS); 285fa225cbcSrjs if (!block) { 286fa225cbcSrjs printf("No LVDS options block\n"); 287fa225cbcSrjs return; 288fa225cbcSrjs } 289fa225cbcSrjs 290fa225cbcSrjs options = block->data; 291fa225cbcSrjs 292fa225cbcSrjs printf("LVDS options block:\n"); 293fa225cbcSrjs 294fa225cbcSrjs panel_type = options->panel_type; 295fa225cbcSrjs printf("\tPanel type: %d\n", panel_type); 296fa225cbcSrjs printf("\tLVDS EDID available: %s\n", YESNO(options->lvds_edid)); 297fa225cbcSrjs printf("\tPixel dither: %s\n", YESNO(options->pixel_dither)); 298fa225cbcSrjs printf("\tPFIT auto ratio: %s\n", YESNO(options->pfit_ratio_auto)); 299fa225cbcSrjs printf("\tPFIT enhanced graphics mode: %s\n", 300fa225cbcSrjs YESNO(options->pfit_gfx_mode_enhanced)); 301fa225cbcSrjs printf("\tPFIT enhanced text mode: %s\n", 302fa225cbcSrjs YESNO(options->pfit_text_mode_enhanced)); 303fa225cbcSrjs printf("\tPFIT mode: %d\n", options->pfit_mode); 304fa225cbcSrjs 305fa225cbcSrjs free(block); 306fa225cbcSrjs} 307fa225cbcSrjs 308fa225cbcSrjsstatic void dump_lvds_ptr_data(void) 309fa225cbcSrjs{ 310fa225cbcSrjs struct bdb_block *block; 311fa225cbcSrjs struct bdb_lvds_lfp_data *lvds_data; 312fa225cbcSrjs struct bdb_lvds_lfp_data_ptrs *ptrs; 313fa225cbcSrjs struct lvds_fp_timing *fp_timing; 314fa225cbcSrjs struct bdb_lvds_lfp_data_entry *entry; 315fa225cbcSrjs int lfp_data_size; 316fa225cbcSrjs 317fa225cbcSrjs block = find_section(BDB_LVDS_LFP_DATA_PTRS); 318fa225cbcSrjs if (!block) { 319fa225cbcSrjs printf("No LFP data pointers block\n"); 320fa225cbcSrjs return; 321fa225cbcSrjs } 322fa225cbcSrjs ptrs = block->data; 323fa225cbcSrjs 324fa225cbcSrjs block = find_section(BDB_LVDS_LFP_DATA); 325fa225cbcSrjs if (!block) { 326fa225cbcSrjs printf("No LVDS data block\n"); 327fa225cbcSrjs return; 328fa225cbcSrjs } 329fa225cbcSrjs lvds_data = block->data; 330fa225cbcSrjs 331fa225cbcSrjs lfp_data_size = ptrs->ptr[1].fp_timing_offset - ptrs->ptr[0].fp_timing_offset; 332fa225cbcSrjs entry = (struct bdb_lvds_lfp_data_entry *)((uint8_t *)lvds_data->data + 333fa225cbcSrjs (lfp_data_size * panel_type)); 334fa225cbcSrjs fp_timing = &entry->fp_timing; 335fa225cbcSrjs 336fa225cbcSrjs printf("LVDS timing pointer data:\n"); 337fa225cbcSrjs printf(" Number of entries: %d\n", ptrs->lvds_entries); 338fa225cbcSrjs 339fa225cbcSrjs printf("\tpanel type %02i: %dx%d\n", panel_type, fp_timing->x_res, 340fa225cbcSrjs fp_timing->y_res); 341fa225cbcSrjs 342fa225cbcSrjs free(block); 343fa225cbcSrjs} 344fa225cbcSrjs 345fa225cbcSrjsstatic void dump_lvds_data(void) 346fa225cbcSrjs{ 347fa225cbcSrjs struct bdb_block *block; 348fa225cbcSrjs struct bdb_lvds_lfp_data *lvds_data; 349fa225cbcSrjs struct bdb_lvds_lfp_data_ptrs *ptrs; 350fa225cbcSrjs int num_entries; 351fa225cbcSrjs int i; 352fa225cbcSrjs int hdisplay, hsyncstart, hsyncend, htotal; 353fa225cbcSrjs int vdisplay, vsyncstart, vsyncend, vtotal; 354fa225cbcSrjs float clock; 355fa225cbcSrjs int lfp_data_size, dvo_offset; 356fa225cbcSrjs 357fa225cbcSrjs block = find_section(BDB_LVDS_LFP_DATA_PTRS); 358fa225cbcSrjs if (!block) { 359fa225cbcSrjs printf("No LVDS ptr block\n"); 360fa225cbcSrjs return; 361fa225cbcSrjs } 362fa225cbcSrjs ptrs = block->data; 363fa225cbcSrjs lfp_data_size = ptrs->ptr[1].fp_timing_offset - ptrs->ptr[0].fp_timing_offset; 364fa225cbcSrjs dvo_offset = ptrs->ptr[0].dvo_timing_offset - ptrs->ptr[0].fp_timing_offset; 365fa225cbcSrjs free(block); 366fa225cbcSrjs 367fa225cbcSrjs block = find_section(BDB_LVDS_LFP_DATA); 368fa225cbcSrjs if (!block) { 369fa225cbcSrjs printf("No LVDS data block\n"); 370fa225cbcSrjs return; 371fa225cbcSrjs } 372fa225cbcSrjs 373fa225cbcSrjs lvds_data = block->data; 374fa225cbcSrjs num_entries = block->size / lfp_data_size; 375fa225cbcSrjs 376fa225cbcSrjs printf("LVDS panel data block (preferred block marked with '*'):\n"); 377fa225cbcSrjs printf(" Number of entries: %d\n", num_entries); 378fa225cbcSrjs 379fa225cbcSrjs for (i = 0; i < num_entries; i++) { 380fa225cbcSrjs uint8_t *lfp_data_ptr = (uint8_t *)lvds_data->data + lfp_data_size * i; 381fa225cbcSrjs uint8_t *timing_data = lfp_data_ptr + dvo_offset; 382fa225cbcSrjs struct bdb_lvds_lfp_data_entry *lfp_data = 383fa225cbcSrjs (struct bdb_lvds_lfp_data_entry *)lfp_data_ptr; 384fa225cbcSrjs char marker; 385fa225cbcSrjs 386fa225cbcSrjs if (i == panel_type) 387fa225cbcSrjs marker = '*'; 388fa225cbcSrjs else 389fa225cbcSrjs marker = ' '; 390fa225cbcSrjs 391fa225cbcSrjs hdisplay = _H_ACTIVE(timing_data); 392fa225cbcSrjs hsyncstart = hdisplay + _H_SYNC_OFF(timing_data); 393fa225cbcSrjs hsyncend = hsyncstart + _H_SYNC_WIDTH(timing_data); 394fa225cbcSrjs htotal = hdisplay + _H_BLANK(timing_data); 395fa225cbcSrjs 396fa225cbcSrjs vdisplay = _V_ACTIVE(timing_data); 397fa225cbcSrjs vsyncstart = vdisplay + _V_SYNC_OFF(timing_data); 398fa225cbcSrjs vsyncend = vsyncstart + _V_SYNC_WIDTH(timing_data); 399fa225cbcSrjs vtotal = vdisplay + _V_BLANK(timing_data); 400fa225cbcSrjs clock = _PIXEL_CLOCK(timing_data) / 1000; 401fa225cbcSrjs 402fa225cbcSrjs printf("%c\tpanel type %02i: %dx%d clock %d\n", marker, 403fa225cbcSrjs i, lfp_data->fp_timing.x_res, lfp_data->fp_timing.y_res, 404fa225cbcSrjs _PIXEL_CLOCK(timing_data)); 405fa225cbcSrjs printf("\t\tinfo:\n"); 406fa225cbcSrjs printf("\t\t LVDS: 0x%08lx\n", 407fa225cbcSrjs (unsigned long)lfp_data->fp_timing.lvds_reg_val); 408fa225cbcSrjs printf("\t\t PP_ON_DELAYS: 0x%08lx\n", 409fa225cbcSrjs (unsigned long)lfp_data->fp_timing.pp_on_reg_val); 410fa225cbcSrjs printf("\t\t PP_OFF_DELAYS: 0x%08lx\n", 411fa225cbcSrjs (unsigned long)lfp_data->fp_timing.pp_off_reg_val); 412fa225cbcSrjs printf("\t\t PP_DIVISOR: 0x%08lx\n", 413fa225cbcSrjs (unsigned long)lfp_data->fp_timing.pp_cycle_reg_val); 414fa225cbcSrjs printf("\t\t PFIT: 0x%08lx\n", 415fa225cbcSrjs (unsigned long)lfp_data->fp_timing.pfit_reg_val); 416fa225cbcSrjs printf("\t\ttimings: %d %d %d %d %d %d %d %d %.2f (%s)\n", 417fa225cbcSrjs hdisplay, hsyncstart, hsyncend, htotal, 418fa225cbcSrjs vdisplay, vsyncstart, vsyncend, vtotal, clock, 419fa225cbcSrjs (hsyncend > htotal || vsyncend > vtotal) ? 420fa225cbcSrjs "BAD!" : "good"); 421fa225cbcSrjs } 422fa225cbcSrjs free(block); 423fa225cbcSrjs} 424fa225cbcSrjs 425fa225cbcSrjsstatic void dump_driver_feature(void) 426fa225cbcSrjs{ 427fa225cbcSrjs struct bdb_block *block; 428fa225cbcSrjs struct bdb_driver_feature *feature; 429fa225cbcSrjs 430fa225cbcSrjs block = find_section(BDB_DRIVER_FEATURES); 431fa225cbcSrjs if (!block) { 432fa225cbcSrjs printf("No Driver feature data block\n"); 433fa225cbcSrjs return; 434fa225cbcSrjs } 435fa225cbcSrjs feature = block->data; 436fa225cbcSrjs 437fa225cbcSrjs printf("Driver feature Data Block:\n"); 438fa225cbcSrjs printf("\tBoot Device Algorithm: %s\n", feature->boot_dev_algorithm ? 439fa225cbcSrjs "driver default": "os default"); 440fa225cbcSrjs printf("\tBlock display switching when DVD active: %s\n", 441fa225cbcSrjs YESNO(feature->block_display_switch)); 442fa225cbcSrjs printf("\tAllow display switching when in Full Screen DOS: %s\n", 443fa225cbcSrjs YESNO(feature->allow_display_switch)); 444fa225cbcSrjs printf("\tHot Plug DVO: %s\n", YESNO(feature->hotplug_dvo)); 445fa225cbcSrjs printf("\tDual View Zoom: %s\n", YESNO(feature->dual_view_zoom)); 446fa225cbcSrjs printf("\tDriver INT 15h hook: %s\n", YESNO(feature->int15h_hook)); 447fa225cbcSrjs printf("\tEnable Sprite in Clone Mode: %s\n", YESNO(feature->sprite_in_clone)); 448fa225cbcSrjs printf("\tUse 00000110h ID for Primary LFP: %s\n", YESNO(feature->primary_lfp_id)); 449fa225cbcSrjs printf("\tBoot Mode X: %u\n", feature->boot_mode_x); 450fa225cbcSrjs printf("\tBoot Mode Y: %u\n", feature->boot_mode_y); 451fa225cbcSrjs printf("\tBoot Mode Bpp: %u\n", feature->boot_mode_bpp); 452fa225cbcSrjs printf("\tBoot Mode Refresh: %u\n", feature->boot_mode_refresh); 453fa225cbcSrjs printf("\tEnable LFP as primary: %s\n", YESNO(feature->enable_lfp_primary)); 454fa225cbcSrjs printf("\tSelective Mode Pruning: %s\n", YESNO(feature->selective_mode_pruning)); 455fa225cbcSrjs printf("\tDual-Frequency Graphics Technology: %s\n", YESNO(feature->dual_frequency)); 456fa225cbcSrjs printf("\tDefault Render Clock Frequency: %s\n", feature->render_clock_freq ? "low" : "high"); 457fa225cbcSrjs printf("\tNT 4.0 Dual Display Clone Support: %s\n", YESNO(feature->nt_clone_support)); 458fa225cbcSrjs printf("\tDefault Power Scheme user interface: %s\n", feature->power_scheme_ui ? "3rd party":"CUI"); 459fa225cbcSrjs printf("\tSprite Display Assignment when Overlay is Active in Clone Mode: %s\n", 460fa225cbcSrjs feature->sprite_display_assign ? "primary" : "secondary"); 461fa225cbcSrjs printf("\tDisplay Maintain Aspect Scaling via CUI: %s\n", YESNO(feature->cui_aspect_scaling)); 462fa225cbcSrjs printf("\tPreserve Aspect Ratio: %s\n", YESNO(feature->preserve_aspect_ratio)); 463fa225cbcSrjs printf("\tEnable SDVO device power down: %s\n", YESNO(feature->sdvo_device_power_down)); 464fa225cbcSrjs printf("\tCRT hotplug: %s\n", YESNO(feature->crt_hotplug)); 465fa225cbcSrjs printf("\tLVDS config: "); 466fa225cbcSrjs switch (feature->lvds_config) { 467fa225cbcSrjs case BDB_DRIVER_NO_LVDS: 468fa225cbcSrjs printf("No LVDS\n"); 469fa225cbcSrjs break; 470fa225cbcSrjs case BDB_DRIVER_INT_LVDS: 471fa225cbcSrjs printf("Integrated LVDS\n"); 472fa225cbcSrjs break; 473fa225cbcSrjs case BDB_DRIVER_SDVO_LVDS: 474fa225cbcSrjs printf("SDVO LVDS\n"); 475fa225cbcSrjs break; 476fa225cbcSrjs case BDB_DRIVER_EDP: 477fa225cbcSrjs printf("Embedded DisplayPort\n"); 478fa225cbcSrjs break; 479fa225cbcSrjs } 480fa225cbcSrjs printf("\tDefine Display statically: %s\n", YESNO(feature->static_display)); 481fa225cbcSrjs printf("\tLegacy CRT max X: %d\n", feature->legacy_crt_max_x); 482fa225cbcSrjs printf("\tLegacy CRT max Y: %d\n", feature->legacy_crt_max_y); 483fa225cbcSrjs printf("\tLegacy CRT max refresh: %d\n", feature->legacy_crt_max_refresh); 484fa225cbcSrjs free(block); 485fa225cbcSrjs} 486fa225cbcSrjs 487fa225cbcSrjsint main(int argc, char **argv) 488fa225cbcSrjs{ 489fa225cbcSrjs int fd; 490fa225cbcSrjs struct vbt_header *vbt = NULL; 491fa225cbcSrjs int vbt_off, bdb_off, i; 492fa225cbcSrjs char *filename = "bios"; 493fa225cbcSrjs struct stat finfo; 494fa225cbcSrjs struct bdb_block *block; 495fa225cbcSrjs char signature[17]; 496fa225cbcSrjs 497fa225cbcSrjs if (argc != 2) { 498fa225cbcSrjs printf("usage: %s <rom file>\n", argv[0]); 499fa225cbcSrjs return 1; 500fa225cbcSrjs } 501fa225cbcSrjs 502fa225cbcSrjs filename = argv[1]; 503fa225cbcSrjs 504fa225cbcSrjs fd = open(filename, O_RDONLY); 505fa225cbcSrjs if (fd == -1) { 506fa225cbcSrjs printf("Couldn't open \"%s\": %s\n", filename, strerror(errno)); 507fa225cbcSrjs return 1; 508fa225cbcSrjs } 509fa225cbcSrjs 510fa225cbcSrjs if (stat(filename, &finfo)) { 511fa225cbcSrjs printf("failed to stat \"%s\": %s\n", filename, strerror(errno)); 512fa225cbcSrjs return 1; 513fa225cbcSrjs } 514fa225cbcSrjs 515fa225cbcSrjs pI830->VBIOS = mmap(NULL, finfo.st_size, PROT_READ, MAP_SHARED, fd, 0); 516fa225cbcSrjs if (pI830->VBIOS == MAP_FAILED) { 517fa225cbcSrjs printf("failed to map \"%s\": %s\n", filename, strerror(errno)); 518fa225cbcSrjs return 1; 519fa225cbcSrjs } 520fa225cbcSrjs 521fa225cbcSrjs /* Scour memory looking for the VBT signature */ 522fa225cbcSrjs for (i = 0; i + 4 < finfo.st_size; i++) { 523fa225cbcSrjs if (!memcmp(pI830->VBIOS + i, "$VBT", 4)) { 524fa225cbcSrjs vbt_off = i; 525fa225cbcSrjs vbt = (struct vbt_header *)(pI830->VBIOS + i); 526fa225cbcSrjs break; 527fa225cbcSrjs } 528fa225cbcSrjs } 529fa225cbcSrjs 530fa225cbcSrjs if (!vbt) { 531fa225cbcSrjs printf("VBT signature missing\n"); 532fa225cbcSrjs return 1; 533fa225cbcSrjs } 534fa225cbcSrjs 535fa225cbcSrjs printf("VBT vers: %d.%d\n", vbt->version / 100, vbt->version % 100); 536fa225cbcSrjs 537fa225cbcSrjs bdb_off = vbt_off + vbt->bdb_offset; 538fa225cbcSrjs bdb = (struct bdb_header *)(pI830->VBIOS + bdb_off); 539fa225cbcSrjs strncpy(signature, (char *)bdb->signature, 16); 540fa225cbcSrjs signature[16] = 0; 541fa225cbcSrjs printf("BDB sig: %s\n", signature); 542fa225cbcSrjs printf("BDB vers: %d.%d\n", bdb->version / 100, bdb->version % 100); 543fa225cbcSrjs 544fa225cbcSrjs printf("Available sections: "); 545fa225cbcSrjs for (i = 0; i < 256; i++) { 546fa225cbcSrjs block = find_section(i); 547fa225cbcSrjs if (!block) 548fa225cbcSrjs continue; 549fa225cbcSrjs printf("%d ", i); 550fa225cbcSrjs free(block); 551fa225cbcSrjs } 552fa225cbcSrjs printf("\n"); 553fa225cbcSrjs 554fa225cbcSrjs dump_general_features(); 555fa225cbcSrjs dump_general_definitions(); 556fa225cbcSrjs// dump_child_devices(); 557fa225cbcSrjs dump_lvds_options(); 558fa225cbcSrjs dump_lvds_data(); 559fa225cbcSrjs dump_lvds_ptr_data(); 560fa225cbcSrjs dump_backlight_info(); 561fa225cbcSrjs 562fa225cbcSrjs dump_driver_feature(); 563fa225cbcSrjs 564fa225cbcSrjs return 0; 565fa225cbcSrjs} 566