aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2015-04-17 12:31:22 -0400
committerJani Nikula <jani.nikula@intel.com>2015-04-30 05:33:09 -0400
commitfaa0cdbec1c258896bff8bb59051bbada4fd6f09 (patch)
tree3657cdbe783e300128362642ff3147d9ec222ad6
parenta1e6ad667550a9be173d0a0cfbba236d9252f837 (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.h5
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c28
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 */
259static void intel_prepare_ddi_buffers(struct drm_device *dev, 259static 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 */
381void intel_prepare_ddi(struct drm_device *dev) 380void 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