Skip to content

Commit

Permalink
drm/i915: Fix bogus dig_port_map[] assignment for pre-HSW
Browse files Browse the repository at this point in the history
The recent commit [0bdf5a0: 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: 0bdf5a0 ('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>
Tested-by: Martin Kepplinger <martink@posteo.de>
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
(cherry picked from commit 9dfbffc)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
  • Loading branch information
Takashi Iwai authored and Jani Nikula committed Mar 7, 2016
1 parent f6cede5 commit 2f79190
Show file tree
Hide file tree
Showing 4 changed files with 3 additions and 4 deletions.
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/intel_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/i915/intel_ddi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3358,7 +3358,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);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
Expand Down
2 changes: 0 additions & 2 deletions drivers/gpu/drm/i915/intel_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2154,7 +2154,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;
Expand Down Expand Up @@ -2223,7 +2222,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;

Expand Down

0 comments on commit 2f79190

Please sign in to comment.