xserver-xorg-video-intel: Changes to 'debian-experimental'
configure.ac | 2
debian/changelog | 8
man/intel.man | 65 +++++-
src/bios_reader/bios_reader.c | 291 +++++++++++++++++++++---------
src/common.h | 2
src/i810_reg.h | 2
src/i830.h | 6
src/i830_bios.c | 401 ++++++++++++------------------------------
src/i830_bios.h | 72 ++++---
src/i830_display.c | 62 +++---
src/i830_dri.c | 2
src/i830_driver.c | 18 +
src/i830_dvo.c | 43 ++--
src/i830_hdmi.c | 9
src/i830_lvds.c | 158 ++++++----------
src/i830_quirks.c | 5
src/i830_sdvo.c | 39 +++-
src/i830_sdvo_regs.h | 2
src/i830_tv.c | 1
19 files changed, 621 insertions(+), 567 deletions(-)
New commits:
commit cfdf9391594f7bb34a0924d0225541728ac5c4c8
Author: Timo Aaltonen <tjaalton@cc.hut.fi>
Date: Wed Aug 20 13:05:00 2008 +0300
Update changelog
diff --git a/debian/changelog b/debian/changelog
index d6b4f26..967e734 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+xserver-xorg-video-intel (2:2.4.1-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+ * Cherry-picked d5fd845aab407 from 2.4-branch:
+ "Fix reverted LVDS bios capability dword definition"
+
+ -- Timo Aaltonen <tepsipakki@ubuntu.com> Wed, 20 Aug 2008 13:03:29 +0300
+
xserver-xorg-video-intel (2:2.4.0-1) experimental; urgency=low
* New upstream release.
commit 461e2c7da2fc7de906419eed70ec37a464888f82
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date: Tue Aug 19 07:30:01 2008 +0800
Fix reverted LVDS bios capability dword definition
Issue found by Peter Clifton.
(cherry picked from commit 0e6759bb6ad7293b6447bd20e3d7d8fdee46aba7)
diff --git a/src/i830_bios.h b/src/i830_bios.h
index a8d9add..2b073f3 100644
--- a/src/i830_bios.h
+++ b/src/i830_bios.h
@@ -152,13 +152,13 @@ struct bdb_lvds_options {
uint8_t panel_type;
uint8_t rsvd1;
/* LVDS capabilities, stored in a dword */
- uint8_t rsvd2:1;
- uint8_t lvds_edid:1;
- uint8_t pixel_dither:1;
- uint8_t pfit_ratio_auto:1;
- uint8_t pfit_gfx_mode_enhanced:1;
- uint8_t pfit_text_mode_enhanced:1;
uint8_t pfit_mode:2;
+ uint8_t pfit_text_mode_enhanced:1;
+ uint8_t pfit_gfx_mode_enhanced:1;
+ uint8_t pfit_ratio_auto:1;
+ uint8_t pixel_dither:1;
+ uint8_t lvds_edid:1;
+ uint8_t rsvd2:1;
uint8_t rsvd4;
} __attribute__((packed));
commit 4281b0116b8aa7201f523c21abf91f63e12cbccf
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date: Fri Aug 15 13:05:06 2008 +0800
Bump version 2.4.1
diff --git a/configure.ac b/configure.ac
index 6694773..0e155ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
AC_PREREQ(2.57)
AC_INIT([xf86-video-intel],
- 2.4.0,
+ 2.4.1,
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
xf86-video-intel)
commit 01bbdbc6d83a526654abf501bd6cd203f8373774
Author: Alan Coopersmith <alan.coopersmith@sun.com>
Date: Thu Jul 31 20:02:21 2008 -0700
Man page typo fixes
(cherry picked from commit 27e9506fda86e90fd67de1715fa32d23aaa8a683)
diff --git a/man/intel.man b/man/intel.man
index f363ab1..e9ae240 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -382,9 +382,9 @@ what is needed. Set LVDSFixedMode to false and then the user has full
control over the resolution and timings sent to the LVDS-connected
device, through the usual means in xorg.
-.SH MUTLIHEAD CONFIGURATIONS
+.SH MULTIHEAD CONFIGURATIONS
-The number of independent outputs is dicated by the number of CRTCs
+The number of independent outputs is dictated by the number of CRTCs
(in X parlance) a given chip supports. Most recent Intel chips have
two CRTCs, meaning that two separate framebuffers can be displayed
simultaneously, in an extended desktop configuration. If a chip
commit 4ac91c2eb6b539fa23d218ca714cadf998ae8eb6
Author: Jesse Barnes <jbarnes@eee.(none)>
Date: Thu Jul 31 19:21:36 2008 -0700
Update man page
Add example dual head config, add info on bug reporting.
(cherry picked from commit da2eb83fb9a52291ea98f3285aee7bee2d55e0ca)
diff --git a/man/intel.man b/man/intel.man
index aac0efa..f363ab1 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -33,10 +33,10 @@ details. This section only covers configuration details specific to this
driver.
.PP
The Intel 8xx and 9xx families of integrated graphics chipsets have a unified
-memory architecture and uses system memory for video ram. For the i810 and
-i815 family of chipset, operating system support for allocating system
-memory for video use is required in order to use this driver. For the 830M
-and later, this is required in order for the driver to use more video ram
+memory architecture meaning that system memory is used as video RAM. For the
+i810 and i815 family of chipsets, operating system support for allocating system
+memory is required in order to use this driver. For the 830M
+and later, this is required in order for the driver to use more video RAM
than has been pre-allocated at boot time by the BIOS. This is usually
achieved with an "agpgart" or "agp" kernel driver. Linux, FreeBSD, OpenBSD,
NetBSD, and Solaris have such kernel drivers available.
@@ -44,7 +44,7 @@ NetBSD, and Solaris have such kernel drivers available.
By default, the i810 will use 8 megabytes
of system memory for graphics. For the 830M and later, the driver will
automatically size its memory allocation according to the features it will
-support. The
+support. Therefore, the
.B VideoRam
option, which in the past had been necessary to allow more than some small
amount of memory to be allocated, is now ignored.
@@ -84,7 +84,8 @@ Default: enabled on supported configurations.
.TP
.BI "Option \*qTiling\*q \*q" boolean \*q
This option controls whether memory buffers are allocated in tiled mode. In
-many cases (especially for complex rendering), tiling can improve performance.
+most cases (especially for complex rendering), tiling dramatically improves
+performance.
Default: enabled.
.TP
.BI "Option \*qDRI\*q \*q" boolean \*q
@@ -180,8 +181,7 @@ the server log.
Force the driver to leave pipe A enabled. May be necessary in configurations
where the BIOS accesses pipe registers during display hotswitch or lid close,
causing a crash. If you find that your platform needs this option, please file
-a bug against xf86-video-intel at http://bugs.freedesktop.org which includes
-the output of 'lspci -v' and 'lspci -vn'.
+a bug (see REPORTING BUGS below) including the output of 'lspci -v' and 'lspci -vn'.
.TP
.BI "Option \*qLVDS24Bit\*q \*q" boolean \*q
Specify 24 bit pixel format (i.e. 8 bits per color) to be used for the
@@ -220,7 +220,7 @@ detected outputs. You can use the
.B xrandr
tool to control outputs on the command line. Each output listed below may have
one or more properties associated with it (like a binary EDID block if one is
-found). Some outputs have unique properties which are described below.
+found). Some outputs have unique properties which are described below. See the "MULTIHEAD CONFIGURATIONS" section below for additional information.
.SS "VGA"
VGA output port (typically exposed via an HD15 connector).
@@ -382,6 +382,53 @@ what is needed. Set LVDSFixedMode to false and then the user has full
control over the resolution and timings sent to the LVDS-connected
device, through the usual means in xorg.
+.SH MUTLIHEAD CONFIGURATIONS
+
+The number of independent outputs is dicated by the number of CRTCs
+(in X parlance) a given chip supports. Most recent Intel chips have
+two CRTCs, meaning that two separate framebuffers can be displayed
+simultaneously, in an extended desktop configuration. If a chip
+supports more outputs than it has CRTCs (say local flat panel, VGA and
+TV in the case of many outputs), two of the outputs will have to be
+"cloned", meaning that they display the same framebuffer contents (or
+one displays a subset of another's framebuffer if the modes aren't
+equal).
+
+You can use the "xrandr" tool, or various desktop utilities, to change
+your output configuration at runtime. To statically configure your
+outputs, you can use the "Monitor-<type>" options along with
+additional monitor sections in your xorg.conf to create your screen
+topology. The example below puts the VGA output to the right of the
+builtin laptop screen, both running at 1024x768.
+
+.nf
+.B "Section \*qMonitor\*q"
+.BI " Identifier \*qLaptop FooBar Internal Display\*q"
+.BI " Option \*qPosition\*q \*q0 0\*q"
+.B "EndSection"
+
+.B "Section \*qMonitor\*q"
+.BI " Identifier \*qSome Random CRT\*q"
+.BI " Option \*qPosition\*q \*q1024 0\*q"
+.BI " Option \*qRightOf\*q \*qLaptop FoodBar Internal Display\*q"
+.B "EndSection"
+
+.B "Section \*qDevice\*q"
+.BI " Driver \*qintel\*q"
+.BI " Option \*qmonitor-LVDS\*q \*qLaptop FooBar Internal Display\*q"
+.BI " Option \*qmonitor-VGA\*q \*qSome Random CRT\*q"
+.B "EndSection"
+
+.SH REPORTING BUGS
+
+The xf86-video-intel driver is part of the X.Org and Freedesktop.org
+umbrella projects. Details on bug reporting can be found at
+http://www.intellinuxgraphics.org/how_to_report_bug.html. Mailing
+lists are also commonly used to report experiences and ask questions
+about configuration and other topics. See lists.freedesktop.org for
+more information (the xorg@lists.freedesktop.org mailing list is the
+most appropriate place to ask X.Org and driver related questions).
+
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
.SH AUTHORS
commit 280be2a193063c9e2f062cbab9fa967a408dc290
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date: Fri Aug 15 10:10:43 2008 +0800
Always check and free driver private in LVDS destroy
(cherry picked from commit ed7269e0a377b3135b06cacecc59119f06958feb)
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 78fd2d8..96e9f00 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -824,11 +824,9 @@ i830_lvds_destroy (xf86OutputPtr output)
I830Ptr pI830 = I830PTR(pScrn);
I830OutputPrivatePtr intel_output = output->driver_private;
- if (pI830->lvds_fixed_mode)
- {
- xf86DeleteMode (&pI830->lvds_fixed_mode, pI830->lvds_fixed_mode);
+ xf86DeleteMode (&pI830->lvds_fixed_mode, pI830->lvds_fixed_mode);
+ if (intel_output)
xfree (intel_output);
- }
}
#ifdef RANDR_12_INTERFACE
commit 1f558fab4eef3b54de4853bc5247fbd0d24b68bf
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date: Fri Aug 15 10:02:44 2008 +0800
Make skip_panel_detect clear for its meaning
(cherry picked from commit f4cb9a135dca9279af8186a9b18bf62ef7351019)
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 64d0db1..6f87c51 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1503,9 +1503,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) {
- pI830->skip_panel_detect = TRUE;
- } else {
pI830->skip_panel_detect = FALSE;
+ } else {
+ pI830->skip_panel_detect = TRUE;
}
if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE))
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index a885627..78fd2d8 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -1255,7 +1255,7 @@ i830_lvds_init(ScrnInfoPtr pScrn)
*/
I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOC, "LVDSDDC_C");
- if (!pI830->skip_panel_detect) {
+ if (pI830->skip_panel_detect) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Skipping any attempt to determine panel fixed mode.\n");
goto found_mode;
commit 532e47a4a169e829ad34fdc8bb85e4eb81721af3
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Thu Aug 14 16:02:37 2008 -0700
Fix pipe A force quirk
Last commit introduced a logic buglet, we went from (foo & BLAH) -> (!foo &
BLAH) rather than !(foo & BLAH), so fix it up to make my laptop work again.
(cherry picked from commit 22918f62c89a4314fb5d01c58f22fee5b9a15a27)
diff --git a/src/i830_display.c b/src/i830_display.c
index 622209b..2f1e7ab 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -858,7 +858,7 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
OUTREG(VGACNTRL, VGA_DISP_DISABLE);
/* May need to leave pipe A on */
- if ((pipe != 0) || (!pI830->quirk_flag & QUIRK_PIPEA_FORCE))
+ if ((pipe != 0) || !(pI830->quirk_flag & QUIRK_PIPEA_FORCE))
{
/* Disable display plane */
temp = INREG(dspcntr_reg);
commit ac740398569dfa02d3d26a2abeb5c848717e6c03
Author: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon Aug 11 12:07:32 2008 -0400
Fix DPMS off in the presence of the pipe A quirk.
Still turn off the VGA plane, and also handle the DRI path at the end.
(cherry picked from commit 9ec36e0c8bd8a4bd7c40569412fc1a21219b5af9)
diff --git a/src/i830_display.c b/src/i830_display.c
index e1dad03..622209b 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -854,44 +854,43 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
/* Give the overlay scaler a chance to disable if it's on this pipe */
i830_crtc_dpms_video(crtc, FALSE);
- /* May need to leave pipe A on */
- if ((pipe == 0) && (pI830->quirk_flag & QUIRK_PIPEA_FORCE))
- return;
-
/* Disable the VGA plane that we never use */
OUTREG(VGACNTRL, VGA_DISP_DISABLE);
- /* Disable display plane */
- temp = INREG(dspcntr_reg);
- if ((temp & DISPLAY_PLANE_ENABLE) != 0)
+ /* May need to leave pipe A on */
+ if ((pipe != 0) || (!pI830->quirk_flag & QUIRK_PIPEA_FORCE))
{
- OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
- /* Flush the plane changes */
- OUTREG(dspbase_reg, INREG(dspbase_reg));
- POSTING_READ(dspbase_reg);
- }
+ /* Disable display plane */
+ temp = INREG(dspcntr_reg);
+ if ((temp & DISPLAY_PLANE_ENABLE) != 0)
+ {
+ OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
+ /* Flush the plane changes */
+ OUTREG(dspbase_reg, INREG(dspbase_reg));
+ POSTING_READ(dspbase_reg);
+ }
- if (!IS_I9XX(pI830)) {
- /* Wait for vblank for the disable to take effect */
- i830WaitForVblank(pScrn);
- }
+ if (!IS_I9XX(pI830)) {
+ /* Wait for vblank for the disable to take effect */
+ i830WaitForVblank(pScrn);
+ }
- /* Next, disable display pipes */
- temp = INREG(pipeconf_reg);
- if ((temp & PIPEACONF_ENABLE) != 0) {
- OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
- POSTING_READ(pipeconf_reg);
- }
+ /* Next, disable display pipes */
+ temp = INREG(pipeconf_reg);
+ if ((temp & PIPEACONF_ENABLE) != 0) {
+ OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
+ POSTING_READ(pipeconf_reg);
+ }
- /* Wait for vblank for the disable to take effect. */
- i830WaitForVblank(pScrn);
+ /* Wait for vblank for the disable to take effect. */
+ i830WaitForVblank(pScrn);
- temp = INREG(dpll_reg);
- if ((temp & DPLL_VCO_ENABLE) != 0) {
- OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE);
- POSTING_READ(dpll_reg);
+ temp = INREG(dpll_reg);
+ if ((temp & DPLL_VCO_ENABLE) != 0) {
+ OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE);
+ POSTING_READ(dpll_reg);
+ }
}
-
/* Wait for the clocks to turn off. */
usleep(150);
break;
commit 9b03fd49b0f27c9add19dece55d00a58ed73c978
Author: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon Aug 11 11:30:51 2008 -0400
Apply pipe A quirk to 845 as well.
(cherry picked from commit 445c2e9ef8fc1d49bbb03e07bf36e0339be16a80)
diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 6fc8e53..a3ed044 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -315,6 +315,7 @@ static i830_quirk i830_quirk_list[] = {
/* 855 & before need to leave pipe A & dpll A up */
{ PCI_CHIP_I855_GM, SUBSYS_ANY, SUBSYS_ANY, quirk_pipea_force },
+ { PCI_CHIP_845_G, SUBSYS_ANY, SUBSYS_ANY, quirk_pipea_force },
{ 0, 0, 0, NULL },
};
commit d1b47cf0cb66fb1b7c991fbd4f4518c6ccdbc643
Author: Eric Anholt <eric@anholt.net>
Date: Fri Aug 8 16:35:25 2008 -0700
Set lvds_ddc_mode before use to avoid a segfault on mac mini.
(cherry picked from commit fe90c0522f65f60c4c431787c889b7fb639ab61b)
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 9f20579..a885627 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -1213,7 +1213,7 @@ i830_lvds_init(ScrnInfoPtr pScrn)
xf86OutputPtr output;
I830OutputPrivatePtr intel_output;
DisplayModePtr modes, scan;
- DisplayModePtr lvds_ddc_mode;
+ DisplayModePtr lvds_ddc_mode = NULL;
struct i830_lvds_priv *dev_priv;
if (pI830->quirk_flag & QUIRK_IGNORE_LVDS)
commit 86b10601e8798974240ae17539b413c1798d34e1
Author: Jesse Barnes <jbarnes@jbarnes-t61.(none)>
Date: Tue Aug 5 13:37:38 2008 -0700
Reorganize VBIOS code
Make VBT parsing happen at driver init time rather than in each output init
function, to save time and better separate VBIOS code into i830_bios.[ch]. The
changes end up touching the output files due to field name changes, and allow
us to reorder & simplify our LFP mode detection code.
(cherry picked from commit a21d4794b6812ce05d08f06dc47b26c4fb1c1fef)
diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c
index ffa27f0..dbcd150 100644
--- a/src/bios_reader/bios_reader.c
+++ b/src/bios_reader/bios_reader.c
@@ -25,11 +25,17 @@
*
*/
+#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
#include <sys/types.h>
+
#include "../i830_bios.h"
#define _PARSE_EDID_
@@ -51,108 +57,223 @@ struct _fake_i830 *pI830 = &I830;
(pI830->VBIOS[_addr + 2] << 16) \
(pI830->VBIOS[_addr + 3] << 24))
+#define YESNO(val) ((val) ? "yes" : "no")
+
+static int tv_present;
+static int lvds_present;
+static int panel_type;
+
+static void *find_section(struct bdb_header *bdb, 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;
+ }
+
+ return NULL;
+}
+
+static void dump_general_features(void *data)
+{
+ struct bdb_general_features *features = data;
+
+ if (!data)
+ return;
+
+ printf("General features block:\n");
+
+ printf("\tPanel fitting: ");
+ switch (features->panel_fitting) {
+ case 0:
+ printf("disabled\n");
+ break;
+ case 1:
+ printf("text only\n");
+ break;
+ case 2:
+ printf("graphics only\n");
+ break;
+ case 3:
+ printf("text & graphics\n");
+ break;
+ }
+ printf("\tFlexaim: %s\n", YESNO(features->flexaim));
+ printf("\tMessage: %s\n", YESNO(features->msg_enable));
+ printf("\tClear screen: %d\n", features->clear_screen);
+ printf("\tDVO color flip required: %s\n", YESNO(features->color_flip));
+ printf("\tExternal VBT: %s\n", YESNO(features->download_ext_vbt));
+ printf("\tEnable SSC: %s\n", YESNO(features->enable_ssc));
+ if (features->enable_ssc)
+ printf("\tSSC frequency: %s\n", features->ssc_freq ?
+ "100 MHz (66 MHz on 855)" : "96 MHz (48 MHz on 855)");
+ printf("\tLFP on override: %s\n", YESNO(features->enable_lfp_on_override));
+ printf("\tDisable SSC on clone: %s\n", YESNO(features->disable_ssc_ddt));
+ printf("\tDisable smooth vision: %s\n",
+ YESNO(features->disable_smooth_vision));
+ printf("\tSingle DVI for CRT/DVI: %s\n", YESNO(features->single_dvi));
+ printf("\tLegacy monitor detect: %s\n",
+ YESNO(features->legacy_monitor_detect));
+ printf("\tIntegrated CRT: %s\n", YESNO(features->int_crt_support));
+ printf("\tIntegrated TV: %s\n", YESNO(features->int_tv_support));
+
+ tv_present = 1; /* should be based on whether TV DAC exists */
+ lvds_present = 1; /* should be based on IS_MOBILE() */
+}
+
+static void dump_general_definitions(void *data)
+{
+ struct bdb_general_definitions *defs = data;
+ unsigned char *lvds_data = defs->tv_or_lvds_info;
+
+ if (!data)
+ return;
+
+ printf("General definitions block:\n");
+
+ printf("\tCRT DDC GMBUS addr: 0x%02x\n", defs->crt_ddc_gmbus_pin);
+ printf("\tUse ACPI DPMS CRT power states: %s\n", YESNO(defs->dpms_acpi));
+ printf("\tSkip CRT detect at boot: %s\n",
+ YESNO(defs->skip_boot_crt_detect));
+ printf("\tUse DPMS on AIM devices: %s\n", YESNO(defs->dpms_aim));
+ printf("\tBoot display type: 0x%02x%02x\n", defs->boot_display[1],
+ defs->boot_display[0]);
+ printf("\tTV data block present: %s\n", YESNO(tv_present));
+ if (tv_present)
+ lvds_data += 33;
+ if (lvds_present)
+ printf("\tLFP DDC GMBUS addr: 0x%02x\n", lvds_data[19]);
+}
+
+static void dump_lvds_options(void *data)
+{
+ struct bdb_lvds_options *options = data;
+
+ if (!data)
+ return;
+
+ printf("LVDS options block:\n");
+
+ panel_type = options->panel_type;
+ printf("\tPanel type: %d\n", panel_type);
+ printf("\tLVDS EDID available: %s\n", YESNO(options->lvds_edid));
+ printf("\tPixel dither: %s\n", YESNO(options->pixel_dither));
+ printf("\tPFIT auto ratio: %s\n", YESNO(options->pfit_ratio_auto));
+ printf("\tPFIT enhanced graphics mode: %s\n",
+ YESNO(options->pfit_gfx_mode_enhanced));
+ printf("\tPFIT enhanced text mode: %s\n",
+ YESNO(options->pfit_text_mode_enhanced));
+ printf("\tPFIT mode: %d\n", options->pfit_mode);
+}
+
+static void dump_lvds_data(void *data, unsigned char *base)
+{
+ struct bdb_lvds_lfp_data *lvds_data = data;
+ int i;
+
+ if (!data)
+ return;
+
+ printf("LVDS panel data block (preferred block marked with '*'):\n");
+
+ for (i = 0; i < 16; 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;
+
+ if (i == panel_type)
+ marker = '*';
+ else
+ 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\ttimings: %d %d %d %d %d %d %d %d\n",
+ _H_ACTIVE(timing_data),
+ _H_BLANK(timing_data),
+ _H_SYNC_OFF(timing_data),
+ _H_SYNC_WIDTH(timing_data),
+ _V_ACTIVE(timing_data),
+ _V_BLANK(timing_data),
+ _V_SYNC_OFF(timing_data),
+ _V_SYNC_WIDTH(timing_data));
+ }
+
+}
+
int main(int argc, char **argv)
{
- FILE *f;
- int bios_size = 65536;
- struct vbt_header *vbt;
+ int fd;
+ struct vbt_header *vbt = NULL;
struct bdb_header *bdb;
- int vbt_off, bdb_off, bdb_block_off, block_size;
- int panel_type = -1, i;
+ int vbt_off, bdb_off, i;
char *filename = "bios";
+ struct stat finfo;
- if (argc == 2)
- filename = argv[1];
+ if (argc != 2) {
+ printf("usage: %s <rom file>\n", argv[0]);
+ return 1;
+ }
+
+ filename = argv[1];
- f = fopen(filename, "r");
- if (!f) {
- printf("Couldn't open %s\n", filename);
+ fd = open(filename, O_RDONLY);
+ if (fd == -1) {
+ printf("Couldn't open \"%s\": %s\n", filename, strerror(errno));
return 1;
}
- pI830->VBIOS = calloc(1, bios_size);
- if (fread(pI830->VBIOS, 1, bios_size, f) != bios_size)
+ if (stat(filename, &finfo)) {
+ printf("failed to stat \"%s\": %s\n", filename, strerror(errno));
return 1;
+ }
+
+ pI830->VBIOS = mmap(NULL, finfo.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (pI830->VBIOS == MAP_FAILED) {
+ printf("failed to map \"%s\": %s\n", filename, strerror(errno));
+ return 1;
+ }
+
+ /* Scour memory looking for the VBT signature */
+ for (i = 0; i + 4 < finfo.st_size; i++) {
+ if (!memcmp(pI830->VBIOS + i, "$VBT", 4)) {
+ vbt_off = i;
+ vbt = (struct vbt_header *)(pI830->VBIOS + i);
+ break;
+ }
+ }
+
+ if (!vbt) {
+ printf("VBT signature missing\n");
+ return 1;
+ }
- vbt_off = INTEL_BIOS_16(0x1a);
- printf("VBT offset: %08x\n", vbt_off);
- vbt = (struct vbt_header *)(pI830->VBIOS + vbt_off);
- printf("VBT sig: %20s\n", vbt->signature);
printf("VBT vers: %d.%d\n", vbt->version / 100, vbt->version % 100);
bdb_off = vbt_off + vbt->bdb_offset;
bdb = (struct bdb_header *)(pI830->VBIOS + bdb_off);
printf("BDB sig: %16s\n", bdb->signature);
printf("BDB vers: %d.%d\n", bdb->version / 100, bdb->version % 100);
- for (bdb_block_off = bdb->header_size; bdb_block_off < bdb->bdb_size;
- bdb_block_off += block_size)
- {
- 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 *fpparam;
- struct lvds_bdb_2_fp_edid_dtd *fptiming;
- uint8_t *timing_ptr;
-
- id = INTEL_BIOS_8(start);
- block_size = INTEL_BIOS_16(start + 1) + 3;
- printf("BDB block type %03d size %d\n", id, block_size);
- switch (id) {
- case 40:
- lvds1 = (struct lvds_bdb_1 *)(pI830->VBIOS + start);
- panel_type = lvds1->panel_type;
- printf("Panel type: %d, caps %04x\n", panel_type, lvds1->caps);
- break;
- case 41:
- if (panel_type == -1) {
- printf("Found panel block with no panel type\n");
- break;
- }
-
- lvds2 = (struct lvds_bdb_2 *)(pI830->VBIOS + start);
-
- printf("Entries per table: %d\n", lvds2->table_size);
- for (i = 0; i < 16; i++) {
- char marker;
- fpparam = (struct lvds_bdb_2_fp_params *)(pI830->VBIOS +
- bdb_off + lvds2->panels[i].fp_params_offset);
- fptiming = (struct lvds_bdb_2_fp_edid_dtd *)(pI830->VBIOS +
- bdb_off + lvds2->panels[i].fp_edid_dtd_offset);
- timing_ptr = pI830->VBIOS + bdb_off +
- lvds2->panels[i].fp_edid_dtd_offset;
- if (fpparam->terminator != 0xffff) {
- /* Apparently the offsets are wrong for some BIOSes, so we
- * try the other offsets if we find a bad terminator.
- */
- fpparam = (struct lvds_bdb_2_fp_params *)(pI830->VBIOS +
- bdb_off + lvds2->panels[i].fp_params_offset + 8);
- fptiming = (struct lvds_bdb_2_fp_edid_dtd *)(pI830->VBIOS +
- bdb_off + lvds2->panels[i].fp_edid_dtd_offset + 8);
- timing_ptr = pI830->VBIOS + bdb_off +
- lvds2->panels[i].fp_edid_dtd_offset + 8;
-
- if (fpparam->terminator != 0xffff)
- continue;
- }
- if (i == panel_type)
- marker = '*';
- else
- marker = ' ';
- printf("%c Panel index %02i xres %d yres %d clock %d\n", marker,
- i, fpparam->x_res, fpparam->y_res,
- _PIXEL_CLOCK(timing_ptr));
- printf(" %d %d %d %d %d %d %d %d\n",
- _H_ACTIVE(timing_ptr), _H_BLANK(timing_ptr),
- _H_SYNC_OFF(timing_ptr), _H_SYNC_WIDTH(timing_ptr),
- _V_ACTIVE(timing_ptr), _V_BLANK(timing_ptr),
- _V_SYNC_OFF(timing_ptr), _V_SYNC_WIDTH(timing_ptr));
- }
-
- printf("Panel of size %dx%d\n", fpparam->x_res, fpparam->y_res);
- break;
- }
- }
+
+ 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), bdb);
return 0;
}
diff --git a/src/i830.h b/src/i830.h
index 68690f7..6a5de6b 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -251,8 +251,6 @@ struct _I830DVODriver {
I830I2CVidOutputRec *vid_rec;
void *dev_priv;
pointer modhandle;
- DisplayModePtr panel_fixed_mode;
- Bool panel_wants_dither;
};
extern const char *i830_output_type_names[];
@@ -556,6 +554,9 @@ typedef struct _I830Rec {
Bool lvds_24_bit_mode;
Bool lvds_use_ssc;
int lvds_ssc_freq; /* in MHz */
+ Bool lvds_dither;
+ DisplayModePtr lvds_fixed_mode;
+ Bool skip_panel_detect;
Bool tv_present; /* TV connector present (from VBIOS) */
@@ -663,7 +664,6 @@ typedef struct _I830Rec {
/** Enables logging of debug output related to mode switching. */
Bool debug_modes;
- Bool lvds_fixed_mode;
unsigned int quirk_flag;
} I830Rec;
diff --git a/src/i830_bios.c b/src/i830_bios.c
index a8193fc..fe55d23 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -40,84 +40,152 @@
#include "edid.h"
#define INTEL_BIOS_8(_addr) (bios[_addr])
-#define INTEL_BIOS_16(_addr) (bios[_addr] | \
+#define INTEL_BIOS_16(_addr) (bios[_addr] | \
(bios[_addr + 1] << 8))
-#define INTEL_BIOS_32(_addr) (bios[_addr] | \
- (bios[_addr + 1] << 8) \
- (bios[_addr + 2] << 16) \
+#define INTEL_BIOS_32(_addr) (bios[_addr] | \
+ (bios[_addr + 1] << 8) \
+ (bios[_addr + 2] << 16) \
(bios[_addr + 3] << 24))
/* XXX */
#define INTEL_VBIOS_SIZE (64 * 1024)
+static void *
+find_section(struct bdb_header *bdb, 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;
+ }
+
+ return NULL;
+}
+
+/**
+ * Returns the BIOS's fixed panel mode.
+ *
+ * Note that many BIOSes will have the appropriate tables for a panel even when
+ * a panel is not attached. Additionally, many BIOSes adjust table sizes or
+ * offsets, such that this parsing fails. Thus, almost any other method for
+ * detecting the panel mode is preferable.
+ */
static void
-i830DumpBIOSToFile(ScrnInfoPtr pScrn, unsigned char *bios)
+parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
{
- const char *filename = "/tmp/xf86-video-intel-VBIOS";
- FILE *f;
+ struct bdb_lvds_options *lvds_options;
+ struct bdb_lvds_lfp_data *lvds_lfp_data;
+ struct bdb_lvds_lfp_data_entry *entry;
+ DisplayModePtr fixed_mode;
+ unsigned char *timing_ptr;
- f = fopen(filename, "w");
- if (f == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't open %s\n", filename);
+ /* Defaults if we can't find VBT info */
+ pI830->lvds_dither = 0;
+
+ lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
+ if (!lvds_options)
+ return;
+
+ pI830->lvds_dither = lvds_options->pixel_dither;
+ if (lvds_options->panel_type == 0xff)
+ return;
+
+ lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
+ if (!lvds_lfp_data)
return;
- }
- if (fwrite(bios, INTEL_VBIOS_SIZE, 1, f) != 1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't write BIOS data\n");
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Wrote BIOS contents to %s\n",
- filename);
- fclose(f);
+ entry = &lvds_lfp_data->data[lvds_options->panel_type];
+ timing_ptr = (unsigned char *)&entry->dvo_timing;
+
+ fixed_mode = xnfalloc(sizeof(DisplayModeRec));
+ memset(fixed_mode, 0, sizeof(*fixed_mode));
+
+ /* Since lvds_bdb_2_fp_edid_dtd is just an EDID detailed timing
+ * block, pull the contents out using EDID macros.
+ */
+ fixed_mode->HDisplay = _H_ACTIVE(timing_ptr);
+ fixed_mode->VDisplay = _V_ACTIVE(timing_ptr);
+ fixed_mode->HSyncStart = fixed_mode->HDisplay +
+ _H_SYNC_OFF(timing_ptr);
+ fixed_mode->HSyncEnd = fixed_mode->HSyncStart +
+ _H_SYNC_WIDTH(timing_ptr);
+ fixed_mode->HTotal = fixed_mode->HDisplay +
+ _H_BLANK(timing_ptr);
+ fixed_mode->VSyncStart = fixed_mode->VDisplay +
+ _V_SYNC_OFF(timing_ptr);
+ fixed_mode->VSyncEnd = fixed_mode->VSyncStart +
+ _V_SYNC_WIDTH(timing_ptr);
+ fixed_mode->VTotal = fixed_mode->VDisplay +
+ _V_BLANK(timing_ptr);
+ fixed_mode->Clock = _PIXEL_CLOCK(timing_ptr) / 1000;
+ fixed_mode->type = M_T_PREFERRED;
+
+ xf86SetModeDefaultName(fixed_mode);
+
+ pI830->lvds_fixed_mode = fixed_mode;
}
-static void *
-find_section(struct bdb_header *bdb, int section_id)
+static void
+parse_general_features(I830Ptr pI830, struct bdb_header *bdb)
{
- 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;
- }
-
- return NULL;
+ struct bdb_general_features *general;
+
+ /* Set sensible defaults in case we can't find the general block */
+ pI830->tv_present = 1;
+
+ general = find_section(bdb, BDB_GENERAL_FEATURES);
+ if (!general)
+ return;
+
+ pI830->tv_present = general->int_tv_support;
+ pI830->lvds_use_ssc = general->enable_ssc;
+ if (pI830->lvds_use_ssc) {
+ if (IS_I855(pI830))
+ pI830->lvds_ssc_freq = general->ssc_freq ? 66 : 48;
+ else
+ pI830->lvds_ssc_freq = general->ssc_freq ? 100 : 96;
+ }
Reply to: