drm/i915: Fix bogus dig_port_map[] assignment for pre-HSW
authorTakashi Iwai <tiwai@suse.de>
Wed, 24 Feb 2016 14:35:22 +0000 (15:35 +0100)
committerJani Nikula <jani.nikula@intel.com>
Mon, 7 Mar 2016 15:51:28 +0000 (17:51 +0200)
The recent commit [0bdf5a05647a: drm/i915: Add reverse mapping between
port and intel_encoder] introduced a reverse mapping to retrieve
intel_dig_port object from the port number.  The code assumed that the
port vs intel_dig_port are 1:1 mapping.  But in reality, this was a
too naive assumption.

As Martin reported about the missing HDMI audio on his SNB machine,
pre-HSW chips may have multiple intel_dig_port objects corresponding
to the same port.  Since we assign the mapping statically at the init
time and the multiple objects override the map, it may not match with
the actually enabled output.

This patch tries to address the regression above.  The reverse mapping
is provided basically only for the audio callbacks, so now we set /
clear the mapping dynamically at enabling and disabling HDMI/DP audio,
so that we can always track the latest and correct object
corresponding to the given port.

Fixes: 0bdf5a05647a ('drm/i915: Add reverse mapping between port and intel_encoder')
Reported-and-tested-by: Martin Kepplinger <martink@posteo.de>
Cc: drm-intel-fixes@lists.freedesktop.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456324522-21591-1-git-send-email-tiwai@suse.de
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_hdmi.c

index 31f6d212fb1bbbfa1ce64efe8cebde2a5f9f575d..30f921421b0c944217832ba86856a6904f8fef11 100644 (file)
@@ -527,6 +527,8 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
 
        mutex_lock(&dev_priv->av_mutex);
        intel_dig_port->audio_connector = connector;
+       /* referred in audio callbacks */
+       dev_priv->dig_port_map[port] = intel_encoder;
        mutex_unlock(&dev_priv->av_mutex);
 
        if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
@@ -554,6 +556,7 @@ void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
 
        mutex_lock(&dev_priv->av_mutex);
        intel_dig_port->audio_connector = NULL;
+       dev_priv->dig_port_map[port] = NULL;
        mutex_unlock(&dev_priv->av_mutex);
 
        if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
index 21a9b83f3bfcc10c9702bb58ea16096e1892b45a..62de9f4bce09959a8deb756c0e51ecb4e202315a 100644 (file)
@@ -3326,7 +3326,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
        intel_encoder->get_config = intel_ddi_get_config;
 
        intel_dig_port->port = port;
-       dev_priv->dig_port_map[port] = intel_encoder;
        intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
                                          (DDI_BUF_PORT_REVERSAL |
                                           DDI_A_4_LANES);
index 7a0f99db47b02777f6c3b242648f572eb4593764..109ae6166db11c8b9f50f85c4c6ee0d3519ff8c2 100644 (file)
@@ -6045,7 +6045,6 @@ intel_dp_init(struct drm_device *dev,
        }
 
        intel_dig_port->port = port;
-       dev_priv->dig_port_map[port] = intel_encoder;
        intel_dig_port->dp.output_reg = output_reg;
        intel_dig_port->max_lanes = 4;
 
index d8060e6251f8c4b0bdced645919c215c05962f85..e2dab4828508d7778a82e5e86bc6ca6e6fb09f9c 100644 (file)
@@ -2164,7 +2164,6 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 void intel_hdmi_init(struct drm_device *dev,
                     i915_reg_t hdmi_reg, enum port port)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_digital_port *intel_dig_port;
        struct intel_encoder *intel_encoder;
        struct intel_connector *intel_connector;
@@ -2233,7 +2232,6 @@ void intel_hdmi_init(struct drm_device *dev,
                intel_encoder->cloneable |= 1 << INTEL_OUTPUT_HDMI;
 
        intel_dig_port->port = port;
-       dev_priv->dig_port_map[port] = intel_encoder;
        intel_dig_port->hdmi.hdmi_reg = hdmi_reg;
        intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
        intel_dig_port->max_lanes = 4;
This page took 0.033706 seconds and 5 git commands to generate.