[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