[Intel-gfx] [PATCH] drm/i915: Fix DDC bus selection for multifunction SDVO
ykzhao
yakui.zhao at intel.com
Mon Apr 26 05:52:48 CEST 2010
On Sat, 2010-04-24 at 04:16 +0800, Adam Jackson wrote:
> Multifunction SDVO cards stopped working after 14571b4, and would report
> something that looked remarkably like an ADD2 SPD ROM instead of EDID.
> This appears to be because DDC bus selection was utterly horked by that
> commit; controlled_output was no longer always a single bit, so
> intel_sdvo_select_ddc_bus would pick bus 0, which is (unsurprisingly)
> the SPD ROM bus, not a DDC bus.
thanks for caring this issue.
It seems that now the incorrect DDC bus is selected for the this
multi-function SDVO card.
>the DDC bus will be selected as 1. Then the SPD rom is obtained
instead of EDID.
>
> So, instead of that, let's just use the DDC bus the child device table
> tells us to use. I'm guessing at the bitmask and shifting from VBIOS
> dumps, but it can't possibly be worse.
>
> cf. https://bugzilla.redhat.com/584229
I get the vbios.dump from the bugzilla. The the child device structure
in vbios.dump will report that the value of ddc_pin is 0x1D. And then we
still get the wrong argument for DDC bus switch command.
Now I have such one card in my hand. I can also work on this issue.
Thanks.
Yakui
> Signed-off-by: Adam Jackson <ajax at redhat.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 1 +
> drivers/gpu/drm/i915/intel_bios.c | 1 +
> drivers/gpu/drm/i915/intel_sdvo.c | 41 ++++++++----------------------------
> 3 files changed, 11 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index a43a4f5..5d609a8 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -135,6 +135,7 @@ struct sdvo_device_mapping {
> u8 slave_addr;
> u8 dvo_wiring;
> u8 initialized;
> + u8 ddc_pin;
> };
>
> struct drm_i915_error_state {
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index f9ba452..4c748d8 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -366,6 +366,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
> p_mapping->dvo_port = p_child->dvo_port;
> p_mapping->slave_addr = p_child->slave_addr;
> p_mapping->dvo_wiring = p_child->dvo_wiring;
> + p_mapping->ddc_pin = p_child->ddc_pin;
> p_mapping->initialized = 1;
> } else {
> DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index df9f997..ad96360 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -2053,40 +2053,17 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
> * outputs, then LVDS outputs.
> */
> static void
> -intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv)
> +intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
> + struct intel_sdvo_priv *sdvo, u32 reg)
> {
> - uint16_t mask = 0;
> - unsigned int num_bits;
> + struct sdvo_device_mapping *mapping;
>
> - /* Make a mask of outputs less than or equal to our own priority in the
> - * list.
> - */
> - switch (dev_priv->controlled_output) {
> - case SDVO_OUTPUT_LVDS1:
> - mask |= SDVO_OUTPUT_LVDS1;
> - case SDVO_OUTPUT_LVDS0:
> - mask |= SDVO_OUTPUT_LVDS0;
> - case SDVO_OUTPUT_TMDS1:
> - mask |= SDVO_OUTPUT_TMDS1;
> - case SDVO_OUTPUT_TMDS0:
> - mask |= SDVO_OUTPUT_TMDS0;
> - case SDVO_OUTPUT_RGB1:
> - mask |= SDVO_OUTPUT_RGB1;
> - case SDVO_OUTPUT_RGB0:
> - mask |= SDVO_OUTPUT_RGB0;
> - break;
> - }
> -
> - /* Count bits to find what number we are in the priority list. */
> - mask &= dev_priv->caps.output_flags;
> - num_bits = hweight16(mask);
> - if (num_bits > 3) {
> - /* if more than 3 outputs, default to DDC bus 3 for now */
> - num_bits = 3;
> - }
> + if (IS_SDVOB(reg))
> + mapping = &(dev_priv->sdvo_mappings[0]);
> + else
> + mapping = &(dev_priv->sdvo_mappings[1]);
>
> - /* Corresponds to SDVO_CONTROL_BUS_DDCx */
> - dev_priv->ddc_bus = 1 << num_bits;
> + sdvo->ddc_bus = (mapping->ddc_pin & 0xf0) >> 4;
> }
>
> static bool
> @@ -2863,7 +2840,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
> goto err_i2c;
> }
>
> - intel_sdvo_select_ddc_bus(sdvo_priv);
> + intel_sdvo_select_ddc_bus(dev_priv, sdvo_priv, sdvo_reg);
>
> /* Set the input timing to the screen. Assume always input 0. */
> intel_sdvo_set_target_input(intel_encoder, true, false);
More information about the Intel-gfx
mailing list