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

yakui yakui.zhao at intel.com
Tue Jul 7 07:48:16 CEST 2009


On Tue, 2009-07-07 at 13:18 +0800, ling.ma at intel.com wrote:
> 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.
It looks reasonable.
Acked-by: Zhao Yakui <yakui.zhao at intel.com>
> 
> 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;




More information about the Intel-gfx mailing list