diff options
-rw-r--r-- | src/i830_bios.c | 27 | ||||
-rw-r--r-- | src/i830_bios.h | 75 |
2 files changed, 96 insertions, 6 deletions
diff --git a/src/i830_bios.c b/src/i830_bios.c index a5b7fcd7..cae76c81 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -98,14 +98,16 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); struct vbt_header *vbt; struct bdb_header *bdb; - int vbt_off, bdb_block_off, block_size; + int vbt_off, bdb_off, bdb_block_off, block_size; + int panel_type = -1; if (!i830GetBIOS(pScrn)) return FALSE; vbt_off = INTEL_BIOS_16(0x1a); vbt = (struct vbt_header *)(pI830->VBIOS + vbt_off); - bdb = (struct bdb_header *)(pI830->VBIOS + vbt_off + vbt->bdb_offset); + bdb_off = vbt_off + vbt->bdb_offset; + bdb = (struct bdb_header *)(pI830->VBIOS + bdb_off); if (memcmp(bdb->signature, "BIOS_DATA_BLOCK ", 16) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad BDB signature\n"); @@ -115,12 +117,31 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn) for (bdb_block_off = bdb->header_size; bdb_block_off < bdb->bdb_size; bdb_block_off += block_size) { - int start = vbt_off + vbt->bdb_offset + bdb_block_off; + int start = bdb_off + bdb_block_off; int id; + struct lvds_bdb_1 *lvds1; + struct lvds_bdb_2 *lvds2; + struct lvds_bdb_2_fp_params *lvds2fpparam; id = INTEL_BIOS_8(start); block_size = INTEL_BIOS_16(start + 1) + 3; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found BDB block type %d\n", id); + switch (id) { + case 40: + lvds1 = (struct lvds_bdb_1 *)(pI830->VBIOS + start); + panel_type = lvds1->panel_type; + break; + case 41: + if (panel_type == -1) + break; + lvds2 = (struct lvds_bdb_2 *)(pI830->VBIOS + start); + lvds2fpparam = (struct lvds_bdb_2_fp_params *)(pI830->VBIOS + + bdb_off + lvds2->panels[panel_type].fp_params_offset); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Found panel of size %dx%d in BIOS VBT tables\n", + lvds2fpparam->x_res, lvds2fpparam->y_res); + break; + } } return TRUE; } diff --git a/src/i830_bios.h b/src/i830_bios.h index ed3f1826..9bd0db8a 100644 --- a/src/i830_bios.h +++ b/src/i830_bios.h @@ -26,7 +26,7 @@ */ struct vbt_header { - char signature[20]; /**< Always 'BIOS_DATA_BLOCK' */ + char signature[20]; /**< Always starts with 'VBT$' */ CARD16 version; /**< decimal */ CARD16 header_size; /**< in bytes */ CARD16 vbt_size; /**< in bytes */ @@ -37,14 +37,83 @@ struct vbt_header { CARD32 aim2_offset; /**< from beginning of VBT */ CARD32 aim3_offset; /**< from beginning of VBT */ CARD32 aim4_offset; /**< from beginning of VBT */ -}; +} __attribute__((packed)); struct bdb_header { char signature[16]; /**< Always 'BIOS_DATA_BLOCK' */ CARD16 version; /**< decimal */ CARD16 header_size; /**< in bytes */ CARD16 bdb_size; /**< in bytes */ -}; +} __attribute__((packed)); + +#define LVDS_CAP_EDID (1 << 6) +#define LVDS_CAP_DITHER (1 << 5) +#define LVDS_CAP_PFIT_AUTO_RATIO (1 << 4) +#define LVDS_CAP_PFIT_GRAPHICS_MODE (1 << 3) +#define LVDS_CAP_PFIT_TEXT_MODE (1 << 2) +#define LVDS_CAP_PFIT_GRAPHICS (1 << 1) +#define LVDS_CAP_PFIT_TEXT (1 << 0) +struct lvds_bdb_1 { + CARD8 id; /**< 40 */ + CARD16 size; + CARD8 panel_type; + CARD8 reserved0; + CARD16 caps; +} __attribute__((packed)); + +struct lvds_bdb_2_fp_params { + CARD16 x_res; + CARD16 y_res; + CARD32 lvds_reg; + CARD32 lvds_reg_val; + CARD32 pp_on_reg; + CARD32 pp_on_reg_val; + CARD32 pp_off_reg; + CARD32 pp_off_reg_val; + CARD32 pp_cycle_reg; + CARD32 pp_cycle_reg_val; + CARD32 pfit_reg; + CARD32 pfit_reg_val; + CARD16 terminator; +} __attribute__((packed)); + +struct lvds_bdb_2_fp_edid_dtd { + CARD16 dclk; /**< In 10khz */ + CARD8 hactive; + CARD8 hblank; + CARD8 high_h; /**< 7:4 = hactive 11:8, 3:0 = hblank 11:8 */ + CARD8 vactive; + CARD8 vblank; + CARD8 high_v; /**< 7:4 = vactive 11:8, 3:0 = vblank 11:8 */ + CARD8 hsync_off; + CARD8 hsync_pulse_width; + CARD8 vsync_off; + CARD8 high_hsync_off; /**< 7:6 = hsync off 9:8 */ + CARD8 h_image; + CARD8 v_image; + CARD8 max_hv; + CARD8 h_border; + CARD8 v_border; + CARD8 flags; +#define FP_EDID_FLAG_VSYNC_POSITIVE (1 << 2) +#define FP_EDID_FLAG_HSYNC_POSITIVE (1 << 1) +} __attribute__((packed)); + +struct lvds_bdb_2_entry { + CARD16 fp_params_offset; /**< From beginning of BDB */ + CARD8 fp_params_size; + CARD16 fp_edid_dtd_offset; + CARD8 fp_edid_dtd_size; + CARD16 fp_edid_pid_offset; + CARD8 fp_edid_pid_size; +} __attribute__((packed)); + +struct lvds_bdb_2 { + CARD8 id; /**< 41 */ + CARD16 size; + CARD8 table_size; /* not sure on this one */ + struct lvds_bdb_2_entry panels[16]; +} __attribute__((packed)); Bool i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn); |