[Intel-gfx] [PATCH] drm/i915: Detect lvds channel according to fixed mode line

ling.ma at intel.com ling.ma at intel.com
Thu Jul 16 11:23:10 CEST 2009


As vbios does, detect lvds channel type by following steps:
(We use lvds fixed mode line regardless of EDID available)
1. Set lvds single channel as default
2. If DTD.hdisplay < 1280, return, or go to step 3
3. If DTD.vdisplay < 800/1024 return, or go to setp 4
4. Set dual lvds channel.

Signed-off-by: Ma Ling <ling.ma at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    1 +
 drivers/gpu/drm/i915/intel_display.c |   24 ++++++++----------------
 drivers/gpu/drm/i915/intel_lvds.c    |   28 ++++++++++++++++++++++++++++
 3 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b05b44d..d6bedc9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -209,6 +209,7 @@ typedef struct drm_i915_private {
 	/* LVDS info */
 	int backlight_duty_cycle;  /* restore backlight to this value */
 	bool panel_wants_dither;
+	bool lvds_is_dual_channel;
 	struct drm_display_mode *panel_fixed_mode;
 	struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
 	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3fa0d63..d581a56 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -509,8 +509,7 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
 	const intel_limit_t *limit;
 
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-		if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-		    LVDS_CLKB_POWER_UP)
+		if (dev_priv->lvds_is_dual_channel)
 			/* LVDS with dual channel */
 			limit = &intel_limits_g4x_dual_channel_lvds;
 		else
@@ -644,16 +643,9 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 	intel_clock_t clock;
 	int err = target;
 
-	if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
-	    (I915_READ(LVDS)) != 0) {
-		/*
-		 * For LVDS, if the panel is on, just rely on its current
-		 * settings for dual-channel.  We haven't figured out how to
-		 * reliably set up different single/dual channel state, if we
-		 * even can.
-		 */
-		if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-		    LVDS_CLKB_POWER_UP)
+	if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+
+		if (dev_priv->lvds_is_dual_channel)
 			clock.p2 = limit->p2.p2_fast;
 		else
 			clock.p2 = limit->p2.p2_slow;
@@ -709,8 +701,8 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 	found = false;
 
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-		if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-		    LVDS_CLKB_POWER_UP)
+
+		if (dev_priv->lvds_is_dual_channel)
 			clock.p2 = limit->p2.p2_fast;
 		else
 			clock.p2 = limit->p2.p2_slow;
@@ -764,8 +756,8 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 	found = false;
 
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-		if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-		    LVDS_CLKB_POWER_UP)
+
+		if (dev_priv->lvds_is_dual_channel)
 			clock.p2 = limit->p2.p2_fast;
 		else
 			clock.p2 = limit->p2.p2_slow;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 43c7d9a..6803b15 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -856,6 +856,31 @@ static int intel_lid_present(void)
 }
 #endif
 
+/*
+ * We determin lvds channel type based on panel fixed mode.
+ * The algorithm is from vbios code.
+ */
+static void intel_lvds_detect_channel_type(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int hdisplay, vdisplay;
+
+	/* Default to Single Channel */
+	dev_priv->lvds_is_dual_channel = false;
+
+	hdisplay = 1280;
+	if (IS_GM45(dev))
+		vdisplay = 801; /*vdisplay <= 800 is for single channel*/
+	else
+		vdisplay = 1024;
+
+
+	if (dev_priv->panel_fixed_mode->hdisplay >= hdisplay &&
+	    dev_priv->panel_fixed_mode->vdisplay >= vdisplay)
+		dev_priv->lvds_is_dual_channel = true;
+
+}
+
 /**
  * intel_lvds_init - setup LVDS connectors on this device
  * @dev: drm device
@@ -1018,6 +1043,9 @@ out:
 		I915_WRITE(BLC_PWM_PCH_CTL1, pwm);
 	}
 	drm_sysfs_connector_add(connector);
+
+	intel_lvds_detect_channel_type(dev_priv);
+
 	return;
 
 failed:
-- 
1.5.4.4




More information about the Intel-gfx mailing list