diff options
author | Imre Deak <imre.deak@intel.com> | 2015-04-17 12:31:22 -0400 |
---|---|---|
committer | Jani Nikula <jani.nikula@intel.com> | 2015-04-30 05:33:09 -0400 |
commit | faa0cdbec1c258896bff8bb59051bbada4fd6f09 (patch) | |
tree | 3657cdbe783e300128362642ff3147d9ec222ad6 | |
parent | a1e6ad667550a9be173d0a0cfbba236d9252f837 (diff) |
drm/i915: fix intel_prepare_ddi
At the moment intel_prepare_ddi buffer will iterate through both MST and
CRT encoders, which is incorrect. Neither of these encoder types have an
embedding intel_digital_port object, so for these encoder types we will
use random data when dereferencing the corresponding
intel_digital_port->port field.
Introduced in
commit b403745c84592b26a0713e6944c2b109f6df5c82
Author: Damien Lespiau <damien.lespiau@intel.com>
Date: Mon Aug 4 22:01:33 2014 +0100
drm/i915: Iterate through the initialized DDIs to prepare their buffers
v2:
- fix getting at the port for MST encoders too
- make sure that intel_prepare_ddi_buffers() gets called for port E too
(Paulo)
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90067
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 28 |
2 files changed, 18 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6c030639f8d9..e08cd85eb519 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -251,11 +251,6 @@ enum hpd_pin { | |||
251 | &dev->mode_config.connector_list, \ | 251 | &dev->mode_config.connector_list, \ |
252 | base.head) | 252 | base.head) |
253 | 253 | ||
254 | #define for_each_digital_port(dev, digital_port) \ | ||
255 | list_for_each_entry(digital_port, \ | ||
256 | &dev->mode_config.encoder_list, \ | ||
257 | base.base.head) | ||
258 | |||
259 | #define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \ | 254 | #define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \ |
260 | list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ | 255 | list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ |
261 | if ((intel_encoder)->base.crtc == (__crtc)) | 256 | if ((intel_encoder)->base.crtc == (__crtc)) |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 903d395b27cc..9c1e74a3a277 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -256,12 +256,11 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port) | |||
256 | * in either FDI or DP modes only, as HDMI connections will work with both | 256 | * in either FDI or DP modes only, as HDMI connections will work with both |
257 | * of those | 257 | * of those |
258 | */ | 258 | */ |
259 | static void intel_prepare_ddi_buffers(struct drm_device *dev, | 259 | static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, |
260 | struct intel_digital_port *intel_dig_port) | 260 | bool supports_hdmi) |
261 | { | 261 | { |
262 | struct drm_i915_private *dev_priv = dev->dev_private; | 262 | struct drm_i915_private *dev_priv = dev->dev_private; |
263 | u32 reg; | 263 | u32 reg; |
264 | int port = intel_dig_port->port; | ||
265 | int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry, | 264 | int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry, |
266 | size; | 265 | size; |
267 | int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; | 266 | int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; |
@@ -272,7 +271,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, | |||
272 | const struct ddi_buf_trans *ddi_translations; | 271 | const struct ddi_buf_trans *ddi_translations; |
273 | 272 | ||
274 | if (IS_BROXTON(dev)) { | 273 | if (IS_BROXTON(dev)) { |
275 | if (!intel_dig_port_supports_hdmi(intel_dig_port)) | 274 | if (!supports_hdmi) |
276 | return; | 275 | return; |
277 | 276 | ||
278 | /* Vswing programming for HDMI */ | 277 | /* Vswing programming for HDMI */ |
@@ -360,7 +359,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, | |||
360 | reg += 4; | 359 | reg += 4; |
361 | } | 360 | } |
362 | 361 | ||
363 | if (!intel_dig_port_supports_hdmi(intel_dig_port)) | 362 | if (!supports_hdmi) |
364 | return; | 363 | return; |
365 | 364 | ||
366 | /* Choose a good default if VBT is badly populated */ | 365 | /* Choose a good default if VBT is badly populated */ |
@@ -380,18 +379,27 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, | |||
380 | */ | 379 | */ |
381 | void intel_prepare_ddi(struct drm_device *dev) | 380 | void intel_prepare_ddi(struct drm_device *dev) |
382 | { | 381 | { |
383 | struct intel_digital_port *intel_dig_port; | 382 | struct intel_encoder *intel_encoder; |
384 | bool visited[I915_MAX_PORTS] = { 0, }; | 383 | bool visited[I915_MAX_PORTS] = { 0, }; |
385 | 384 | ||
386 | if (!HAS_DDI(dev)) | 385 | if (!HAS_DDI(dev)) |
387 | return; | 386 | return; |
388 | 387 | ||
389 | for_each_digital_port(dev, intel_dig_port) { | 388 | for_each_intel_encoder(dev, intel_encoder) { |
390 | if (visited[intel_dig_port->port]) | 389 | struct intel_digital_port *intel_dig_port; |
390 | enum port port; | ||
391 | bool supports_hdmi; | ||
392 | |||
393 | ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port); | ||
394 | |||
395 | if (visited[port]) | ||
391 | continue; | 396 | continue; |
392 | 397 | ||
393 | intel_prepare_ddi_buffers(dev, intel_dig_port); | 398 | supports_hdmi = intel_dig_port && |
394 | visited[intel_dig_port->port] = true; | 399 | intel_dig_port_supports_hdmi(intel_dig_port); |
400 | |||
401 | intel_prepare_ddi_buffers(dev, port, supports_hdmi); | ||
402 | visited[port] = true; | ||
395 | } | 403 | } |
396 | } | 404 | } |
397 | 405 | ||