summaryrefslogtreecommitdiff
path: root/src/i830_bios.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@dulcimer.keithp.com>2007-05-16 13:59:36 -0700
committerKeith Packard <keithp@dulcimer.keithp.com>2007-05-16 13:59:36 -0700
commitb28817a87a1608e849e4a9a736dda43533a84b0c (patch)
treecd81b1f0a3607da52b0643054c3ebe1d07f91780 /src/i830_bios.c
parentb31bef1a8effa9acb6de7edd206b9d8c48d88144 (diff)
Add i830_bios_get_aim_data_block to read AIM data from BIOS
Add-in modules have per-module data in the BIOS which contains configuration information which cannot be entirely discovered.
Diffstat (limited to 'src/i830_bios.c')
-rw-r--r--src/i830_bios.c59
1 files changed, 54 insertions, 5 deletions
diff --git a/src/i830_bios.c b/src/i830_bios.c
index 0d009175..7703c806 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -77,8 +77,8 @@ i830DumpBIOSToFile(ScrnInfoPtr pScrn, unsigned char *bios)
* feed an updated VBT back through that, compared to what we'll fetch using
* this method of groping around in the BIOS data.
*/
-static unsigned char *
-i830GetBIOS(ScrnInfoPtr pScrn)
+unsigned char *
+i830_bios_get (ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
struct vbt_header *vbt;
@@ -131,7 +131,7 @@ i830GetBIOS(ScrnInfoPtr pScrn)
* detecting the panel mode is preferable.
*/
DisplayModePtr
-i830_bios_get_panel_mode(ScrnInfoPtr pScrn)
+i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither)
{
I830Ptr pI830 = I830PTR(pScrn);
struct vbt_header *vbt;
@@ -140,7 +140,7 @@ i830_bios_get_panel_mode(ScrnInfoPtr pScrn)
int panel_type = -1;
unsigned char *bios;
- bios = i830GetBIOS(pScrn);
+ bios = i830_bios_get (pScrn);
if (bios == NULL)
return NULL;
@@ -156,6 +156,7 @@ i830_bios_get_panel_mode(ScrnInfoPtr pScrn)
return NULL;
}
+ *wants_dither = FALSE;
for (bdb_block_off = bdb->header_size; bdb_block_off < bdb->bdb_size;
bdb_block_off += block_size)
{
@@ -175,7 +176,7 @@ i830_bios_get_panel_mode(ScrnInfoPtr pScrn)
lvds1 = (struct lvds_bdb_1 *)(bios + start);
panel_type = lvds1->panel_type;
if (lvds1->caps & LVDS_CAP_DITHER)
- pI830->panel_wants_dither = TRUE;
+ *wants_dither = TRUE;
break;
case 41:
if (panel_type == -1)
@@ -243,3 +244,51 @@ i830_bios_get_panel_mode(ScrnInfoPtr pScrn)
xfree(bios);
return NULL;
}
+
+unsigned char *
+i830_bios_get_aim_data_block (ScrnInfoPtr pScrn, int aim, int data_block)
+{
+ unsigned char *bios;
+ int bdb_off;
+ int vbt_off;
+ int aim_off;
+ struct vbt_header *vbt;
+ struct aimdb_header *aimdb;
+ struct aimdb_block *aimdb_block;
+
+ bios = i830_bios_get (pScrn);
+ if (!bios)
+ return NULL;
+
+ vbt_off = INTEL_BIOS_16(0x1a);
+ vbt = (struct vbt_header *)(bios + vbt_off);
+
+ aim_off = vbt->aim_offset[aim];
+ if (!aim_off)
+ {
+ free (bios);
+ return NULL;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "aim_off %d\n", aim_off);
+ aimdb = (struct aimdb_header *) (bios + vbt_off + aim_off);
+ bdb_off = aimdb->aimdb_header_size;
+ while (bdb_off < aimdb->aimdb_size)
+ {
+ aimdb_block = (struct aimdb_block *) (bios + vbt_off + aim_off + bdb_off);
+ if (aimdb_block->aimdb_id == data_block)
+ {
+ unsigned char *aim = malloc (aimdb_block->aimdb_size + sizeof (struct aimdb_block));
+ if (!aim)
+ {
+ free (bios);
+ return NULL;
+ }
+ memcpy (aim, aimdb_block, aimdb_block->aimdb_size + sizeof (struct aimdb_block));
+ free (bios);
+ return aim;
+ }
+ bdb_off += aimdb_block->aimdb_size + sizeof (struct aimdb_block);
+ }
+ free (bios);
+ return NULL;
+}