File xf86-video-intel-commit-88f766b_ea0b00e.diff of Package xorg-x11-driver-video
From 9e7ee50bea5f65003f1d70cc06d8c1ace1282548 Mon Sep 17 00:00:00 2001
From: Ma Ling <ling.ma@intel.com>
Date: Mon, 1 Jun 2009 17:13:22 +0800
Subject: [PATCH 1/2] Fetch mode line from VBT, then keep it.
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Parse SDVO LVDS option section, then according to panel type
fetch fixed mode line from SDVO LVDS DTDS section .
Signed-off-by: Ma Ling <ling.ma@intel.com>
---
src/i830.h | 1 +
src/i830_bios.c | 89 ++++++++++++++++++++++++++++++++++++++++---------------
src/i830_bios.h | 17 ++++++++++
3 files changed, 83 insertions(+), 24 deletions(-)
diff --git a/src/i830.h b/src/i830.h
index 8854286..2d9e905 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -498,6 +498,7 @@ typedef struct _I830Rec {
int lvds_ssc_freq; /* in MHz */
Bool lvds_dither;
DisplayModePtr lvds_fixed_mode;
+ DisplayModePtr sdvo_lvds_fixed_mode;
Bool skip_panel_detect;
Bool integrated_lvds; /* LVDS config from driver feature BDB */
diff --git a/src/i830_bios.c b/src/i830_bios.c
index 73c097a..9c1f101 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -73,6 +73,36 @@ find_section(struct bdb_header *bdb, int section_id)
return NULL;
}
+static void
+fill_detail_timing_data(DisplayModePtr fixed_mode, unsigned char *timing_ptr)
+{
+ 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;
+
+ /* Some VBTs have bogus h/vtotal values */
+ if (fixed_mode->HSyncEnd > fixed_mode->HTotal)
+ fixed_mode->HTotal = fixed_mode->HSyncEnd + 1;
+ if (fixed_mode->VSyncEnd > fixed_mode->VTotal)
+ fixed_mode->VTotal = fixed_mode->VSyncEnd + 1;
+
+ xf86SetModeDefaultName(fixed_mode);
+
+}
+
/**
* Returns the BIOS's fixed panel mode.
*
@@ -82,7 +112,7 @@ find_section(struct bdb_header *bdb, int section_id)
* detecting the panel mode is preferable.
*/
static void
-parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
+parse_integrated_panel_data(I830Ptr pI830, struct bdb_header *bdb)
{
struct bdb_lvds_options *lvds_options;
struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
@@ -118,32 +148,43 @@ parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
/* 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;
+ fill_detail_timing_data(fixed_mode, timing_ptr);
+ pI830->lvds_fixed_mode = fixed_mode;
+}
- /* Some VBTs have bogus h/vtotal values */
- if (fixed_mode->HSyncEnd > fixed_mode->HTotal)
- fixed_mode->HTotal = fixed_mode->HSyncEnd + 1;
- if (fixed_mode->VSyncEnd > fixed_mode->VTotal)
- fixed_mode->VTotal = fixed_mode->VSyncEnd + 1;
+static void
+parse_sdvo_panel_data(I830Ptr pI830, struct bdb_header *bdb)
+{
+ DisplayModePtr fixed_mode;
+ struct bdb_sdvo_lvds_options *sdvo_lvds_options;
+ unsigned char *timing_ptr;
- xf86SetModeDefaultName(fixed_mode);
+ pI830->sdvo_lvds_fixed_mode = NULL;
- pI830->lvds_fixed_mode = fixed_mode;
+ sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
+ if (sdvo_lvds_options == NULL)
+ return;
+
+ timing_ptr = find_section(bdb, BDB_SDVO_PANEL_DTDS);
+ if (timing_ptr == NULL)
+ return;
+
+ fixed_mode = xnfalloc(sizeof(DisplayModeRec));
+ if (fixed_mode == NULL)
+ return;
+
+ memset(fixed_mode, 0, sizeof(*fixed_mode));
+ fill_detail_timing_data(fixed_mode, timing_ptr +
+ (sdvo_lvds_options->panel_type * DET_TIMING_INFO_LEN));
+ pI830->sdvo_lvds_fixed_mode = fixed_mode;
+
+}
+
+static void
+parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
+{
+ parse_integrated_panel_data(pI830, bdb);
+ parse_sdvo_panel_data(pI830, bdb);
}
static void
diff --git a/src/i830_bios.h b/src/i830_bios.h
index 78af830..1f1f1aa 100644
--- a/src/i830_bios.h
+++ b/src/i830_bios.h
@@ -436,6 +436,23 @@ struct bdb_driver_feature {
uint8_t legacy_crt_max_refresh;
} __attribute__((packed));
+struct bdb_sdvo_lvds_options {
+ uint8_t panel_backlight;
+ uint8_t h40_set_panel_type;
+ uint8_t panel_type;
+ uint8_t ssc_clk_freq;
+ uint16_t als_low_trip;
+ uint16_t als_high_trip;
+ uint8_t sclalarcoeff_tab_row_num;
+ uint8_t sclalarcoeff_tab_row_size;
+ uint8_t coefficient[8];
+ uint8_t panel_misc_bits_1;
+ uint8_t panel_misc_bits_2;
+ uint8_t panel_misc_bits_3;
+ uint8_t panel_misc_bits_4;
+} __attribute__((packed));
+
+
#ifndef REG_DUMPER
int i830_bios_init(ScrnInfoPtr pScrn);
#endif
--
1.6.3
From ea0b00e675281b2914450992501566122f9affe0 Mon Sep 17 00:00:00 2001
From: Ma Ling <ling.ma@intel.com>
Date: Mon, 1 Jun 2009 17:13:53 +0800
Subject: [PATCH 2/2] Provide mode line from VBT to xorg.
If sdvo get modes function can't find modes from EDID,
transmit sdvo lvds modes from VBT to xorg.
Signed-off-by: Ma Ling <ling.ma@intel.com>
---
src/i830_sdvo.c | 60 +++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index a4c9120..cfba482 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -91,6 +91,10 @@ struct i830_sdvo_priv {
* This is set if we treat the device as HDMI, instead of DVI.
*/
Bool is_hdmi;
+ /**
+ * This is set if we detect output of sdvo device as LVDS.
+ */
+ Bool is_lvds;
/**
* Returned SDTV resolutions allowed for the current format, if the
@@ -1550,6 +1554,31 @@ i830_sdvo_check_hdmi_encode (xf86OutputPtr output)
return FALSE;
}
+/* This function will try to fetch native modes for sdvo lvds output*/
+static DisplayModePtr i830_sdvo_lvds_fetch_modes(xf86OutputPtr output)
+{
+ I830Ptr pI830 = I830PTR(output->scrn);
+ DisplayModePtr modes;
+
+ /*
+ * Attempt to get the mode list from DDC.
+ * Assume that the preferred modes are
+ * arranged in priority order,
+ */
+ modes = i830_ddc_get_modes(output);
+ if (modes != NULL)
+ goto end;
+
+ if (pI830->sdvo_lvds_fixed_mode != NULL)
+ modes = xf86DuplicateModes(output->scrn, pI830->sdvo_lvds_fixed_mode);
+
+end:
+ /* Guarantee the the first preferred mode is chosen by xserver */
+ if (modes != NULL)
+ modes->type |= (M_T_DRIVER | M_T_PREFERRED);
+ return modes;
+}
+
static void i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv);
static Bool
@@ -1568,6 +1597,7 @@ i830_sdvo_output_setup (xf86OutputPtr output, uint16_t flag)
/* clear up privates */
dev_priv->is_tv = FALSE;
intel_output->needs_tv_clock = FALSE;
+ dev_priv->is_lvds = FALSE;
if (flag & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
{
@@ -1608,14 +1638,14 @@ i830_sdvo_output_setup (xf86OutputPtr output, uint16_t flag)
dev_priv->controlled_output = SDVO_OUTPUT_RGB1;
output->subpixel_order = SubPixelHorizontalRGB;
name_prefix="VGA";
- } else if (flag & SDVO_OUTPUT_LVDS0) {
- dev_priv->controlled_output = SDVO_OUTPUT_LVDS0;
- output->subpixel_order = SubPixelHorizontalRGB;
- name_prefix="LVDS";
- } else if (flag & SDVO_OUTPUT_LVDS1) {
- dev_priv->controlled_output = SDVO_OUTPUT_LVDS1;
- output->subpixel_order = SubPixelHorizontalRGB;
- name_prefix="LVDS";
+ } else if (flag & (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) {
+ if (flag & SDVO_OUTPUT_LVDS0)
+ dev_priv->controlled_output = SDVO_OUTPUT_LVDS0;
+ else
+ dev_priv->controlled_output = SDVO_OUTPUT_LVDS1;
+ output->subpixel_order = SubPixelHorizontalRGB;
+ name_prefix="LVDS";
+ dev_priv->is_lvds = TRUE;
} else {
unsigned char bytes[2];
@@ -1746,11 +1776,15 @@ i830_sdvo_get_ddc_modes(xf86OutputPtr output)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
DisplayModePtr modes = NULL;
xf86OutputPtr crt;
- I830OutputPrivatePtr intel_output;
+ I830OutputPrivatePtr intel_output =output->driver_private;
xf86MonPtr edid_mon = NULL;
- struct i830_sdvo_priv *dev_priv;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
+
+ if (dev_priv->is_lvds)
+ modes = i830_sdvo_lvds_fetch_modes(output);
+ else
+ modes = i830_ddc_get_modes(output);
- modes = i830_ddc_get_modes(output);
if (modes != NULL)
goto check_hdmi;
@@ -1774,9 +1808,6 @@ i830_sdvo_get_ddc_modes(xf86OutputPtr output)
check_hdmi:
/* Check if HDMI encode, setup it and set the flag for HDMI audio */
- intel_output = output->driver_private;
- dev_priv = intel_output->dev_priv;
-
if (dev_priv->caps.output_flags & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
{
if (!i830_sdvo_check_hdmi_encode(output)) {
@@ -2105,7 +2136,6 @@ i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv)
dev_priv->ddc_bus = 1 << num_bits;
}
-
Bool
i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
{
--
1.6.3