[Intel-gfx] [RFC][PATCH] drm/i915: set lvds dual channel according to VBT

ling.ma at intel.com ling.ma at intel.com
Tue Jul 7 07:18:24 CEST 2009


We judge whether integrated lvds is dual channel or single channel
from LVDS register set by vbios code, the patch try to fetch dual
channel information from VBT, and set corresponding bits besides
original approach.

Signed-off-by: Ma Ling <ling.ma at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    1 +
 drivers/gpu/drm/i915/intel_bios.c    |   13 ++++++++++++-
 drivers/gpu/drm/i915/intel_bios.h    |    1 +
 drivers/gpu/drm/i915/intel_display.c |    9 +++++----
 4 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 47ecb61..af1d2b1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -219,6 +219,7 @@ typedef struct drm_i915_private {
 	unsigned int lvds_vbt:1;
 	unsigned int int_crt_support:1;
 	unsigned int lvds_use_ssc:1;
+	unsigned int lvds_dual_channel:1;
 	int lvds_ssc_freq;
 
 	struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index da22863..cb8639f 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -32,6 +32,7 @@
 
 #define	SLAVE_ADDR1	0x70
 #define	SLAVE_ADDR2	0x72
+#define LVDS_DUAL_CHANNEL	0x2
 
 static void *
 find_section(struct bdb_header *bdb, int section_id)
@@ -104,19 +105,29 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
 	struct lvds_dvo_timing *dvo_timing;
 	struct drm_display_mode *panel_fixed_mode;
 	int lfp_data_size;
+	uint32_t channel_bits;
 
 	/* Defaults if we can't find VBT info */
 	dev_priv->lvds_dither = 0;
 	dev_priv->lvds_vbt = 0;
+	dev_priv->lvds_dual_channel = 0;
 
 	lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
 	if (!lvds_options)
 		return;
 
+	/* Fetch lvds channel info */
+	channel_bits = lvds_options->lvds_channel_bits &
+		       (3 << lvds_options->panel_type);
+	if (channel_bits) {
+		channel_bits = channel_bits >> lvds_options->panel_type;
+		if (channel_bits == LVDS_DUAL_CHANNEL)
+			dev_priv->lvds_dual_channel = 1;
+	}
+
 	dev_priv->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;
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index fe72e1c..520afd8 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -255,6 +255,7 @@ struct bdb_lvds_options {
 	u8 lvds_edid:1;
 	u8 rsvd2:1;
 	u8 rsvd4;
+	u32 lvds_channel_bits;
 } __attribute__((packed));
 
 /* LFP pointer table contains entries to the struct below */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 508838e..7c63a0f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -510,11 +510,11 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
 
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
 		if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-		    LVDS_CLKB_POWER_UP)
+		    LVDS_CLKB_POWER_UP || dev_priv->lvds_dual_channel)
 			/* LVDS with dual channel */
 			limit = &intel_limits_g4x_dual_channel_lvds;
 		else
-			/* LVDS with dual channel */
+			/* LVDS with single channel */
 			limit = &intel_limits_g4x_single_channel_lvds;
 	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) ||
 		   intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
@@ -645,7 +645,8 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 	int err = target;
 
 	if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
-	    (I915_READ(LVDS) & LVDS_PORT_EN) != 0) {
+	    ((I915_READ(LVDS) & LVDS_PORT_EN) != 0 ||
+	     dev_priv->lvds_dual_channel)) {
 		/*
 		 * For LVDS, if the panel is on, just rely on its current
 		 * settings for dual-channel.  We haven't figured out how to
@@ -765,7 +766,7 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
 		if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-		    LVDS_CLKB_POWER_UP)
+		    LVDS_CLKB_POWER_UP || dev_priv->lvds_dual_channel)
 			clock.p2 = limit->p2.p2_fast;
 		else
 			clock.p2 = limit->p2.p2_slow;
-- 
1.5.4.4




More information about the Intel-gfx mailing list