summaryrefslogtreecommitdiff
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
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.
-rw-r--r--src/bios_reader/bios_reader.c9
-rw-r--r--src/i830_bios.c59
-rw-r--r--src/i830_bios.h52
3 files changed, 104 insertions, 16 deletions
diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c
index a52bcc72..9ec73c13 100644
--- a/src/bios_reader/bios_reader.c
+++ b/src/bios_reader/bios_reader.c
@@ -30,16 +30,11 @@
#include <string.h>
#include <sys/types.h>
+#include "../i830_bios.h"
+
#define _PARSE_EDID_
#include "edid.h"
-/* Define some types so we can reuse i830_bios.h */
-typedef void *ScrnInfoPtr;
-typedef int Bool;
-#define TRUE 1
-#define FALSE 0
-#include "../i830_bios.h"
-
/* Make a fake pI830 so we can easily pull i830_bios.c code in here. */
struct _fake_i830 {
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;
+}
diff --git a/src/i830_bios.h b/src/i830_bios.h
index 881d5c86..cb7666e3 100644
--- a/src/i830_bios.h
+++ b/src/i830_bios.h
@@ -25,6 +25,11 @@
*
*/
+#ifndef _I830_BIOS_H_
+#define _I830_BIOS_H_
+
+#include <xf86str.h>
+
struct vbt_header {
char signature[20]; /**< Always starts with 'VBT$' */
CARD16 version; /**< decimal */
@@ -33,10 +38,7 @@ struct vbt_header {
CARD8 vbt_checksum;
CARD8 reserved0;
CARD32 bdb_offset; /**< from beginning of VBT */
- CARD32 aim1_offset; /**< from beginning of VBT */
- CARD32 aim2_offset; /**< from beginning of VBT */
- CARD32 aim3_offset; /**< from beginning of VBT */
- CARD32 aim4_offset; /**< from beginning of VBT */
+ CARD32 aim_offset[4]; /**< from beginning of VBT */
} __attribute__((packed));
struct bdb_header {
@@ -114,3 +116,45 @@ struct lvds_bdb_2 {
CARD8 table_size; /* not sure on this one */
struct lvds_bdb_2_entry panels[16];
} __attribute__((packed));
+
+struct aimdb_header {
+ char signature[16];
+ char oem_device[20];
+ CARD16 aimdb_version;
+ CARD16 aimdb_header_size;
+ CARD16 aimdb_size;
+} __attribute__((packed));
+
+struct aimdb_block {
+ CARD8 aimdb_id;
+ CARD16 aimdb_size;
+} __attribute__((packed));
+
+struct vch_bdb_20 {
+} __attribute__((packed));
+
+struct vch_panel_data {
+ CARD16 fp_timing_offset;
+ CARD8 fp_timing_size;
+ CARD16 dvo_timing_offset;
+ CARD8 dvo_timing_size;
+ CARD16 text_fitting_offset;
+ CARD8 text_fitting_size;
+ CARD16 graphics_fitting_offset;
+ CARD8 graphics_fitting_size;
+} __attribute__((packed));
+
+struct vch_bdb_22 {
+ struct aimdb_block aimdb_block;
+ struct vch_panel_data panels[16];
+} __attribute__((packed));
+
+unsigned char *
+i830_bios_get (ScrnInfoPtr pScrn);
+
+DisplayModePtr i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither);
+
+unsigned char *
+i830_bios_get_aim_data_block (ScrnInfoPtr pScrn, int aim, int data_block);
+
+#endif /* _I830_BIOS_H_ */