[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