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

Florian Mickler florian at mickler.org
Thu Jul 16 13:37:21 CEST 2009


On Thu, 16 Jul 2009 17:23:10 +0800
ling.ma at intel.com wrote:

> 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.

s/or/else/


> 
> Signed-off-by: Ma Ling <ling.ma at intel.com>

Tested-By: Florian Mickler <florian at mickler.org>

i tested this commit and it fixes bug #22262 for me. 


@eric: if this approach is right (and dualchannel is indeed a
consequence of said panel-properties), then this replaces the patch you
queued up:
http://git.kernel.org/?p=linux/kernel/git/anholt/drm-intel.git;a=commit;h=832cc28d5bc676331e6376d940ae45d5937aa688

thx,
Florian


> ---
>  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:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20090716/a76244a1/attachment.sig>


More information about the Intel-gfx mailing list