diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2015-10-30 13:23:22 -0400 |
---|---|---|
committer | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2015-11-10 09:23:28 -0500 |
commit | 0c241d5b2770d4a50d3367ed591d0d0236b69b51 (patch) | |
tree | 083cd90810c292e3bed7295d5a1caa4cafd6ab0b | |
parent | c465613bc97ed996f2278116c79d2c6adec3998d (diff) |
drm/i915: Disable FIFO underrun reporting around IBX transcoder B workaround
Doing the IBX transcoder B workaround causes underruns on
pipe/transcoder A. Just hide them by disabling underrun reporting for
pipe A around the workaround.
It might be possible to avoid the underruns by moving the workaround
to be applied only when enabling pipe A. But I was too lazy to try it
right now, and the current method has been proven to work, so didn't
want to change it too hastily.
Note that this can re-enable underrun reporting on pipe A if was
already disabled due to a previous actual underrun. But that's OK, we
may just get a second underrun report if another real underron occurrs
on pipe A.
v2: Note that pipe A underruns can get re-enabled due to this (Jani)
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v1)
Link: http://patchwork.freedesktop.org/patch/msgid/1446225802-11180-1-git-send-email-ville.syrjala@linux.intel.com
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 11 |
4 files changed, 42 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5264887311f1..278f025f4b20 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -3655,6 +3655,13 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
3655 | * matching HDMI port to be enabled on transcoder A. | 3655 | * matching HDMI port to be enabled on transcoder A. |
3656 | */ | 3656 | */ |
3657 | if (HAS_PCH_IBX(dev) && crtc->pipe == PIPE_B && port != PORT_A) { | 3657 | if (HAS_PCH_IBX(dev) && crtc->pipe == PIPE_B && port != PORT_A) { |
3658 | /* | ||
3659 | * We get CPU/PCH FIFO underruns on the other pipe when | ||
3660 | * doing the workaround. Sweep them under the rug. | ||
3661 | */ | ||
3662 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false); | ||
3663 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); | ||
3664 | |||
3658 | /* always enable with pattern 1 (as per spec) */ | 3665 | /* always enable with pattern 1 (as per spec) */ |
3659 | DP &= ~(DP_PIPEB_SELECT | DP_LINK_TRAIN_MASK); | 3666 | DP &= ~(DP_PIPEB_SELECT | DP_LINK_TRAIN_MASK); |
3660 | DP |= DP_PORT_EN | DP_LINK_TRAIN_PAT_1; | 3667 | DP |= DP_PORT_EN | DP_LINK_TRAIN_PAT_1; |
@@ -3664,6 +3671,10 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
3664 | DP &= ~DP_PORT_EN; | 3671 | DP &= ~DP_PORT_EN; |
3665 | I915_WRITE(intel_dp->output_reg, DP); | 3672 | I915_WRITE(intel_dp->output_reg, DP); |
3666 | POSTING_READ(intel_dp->output_reg); | 3673 | POSTING_READ(intel_dp->output_reg); |
3674 | |||
3675 | intel_wait_for_vblank_if_active(dev_priv->dev, PIPE_A); | ||
3676 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); | ||
3677 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); | ||
3667 | } | 3678 | } |
3668 | 3679 | ||
3669 | msleep(intel_dp->panel_power_down_delay); | 3680 | msleep(intel_dp->panel_power_down_delay); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d45677436170..f32a59493a09 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -1079,6 +1079,15 @@ intel_wait_for_vblank(struct drm_device *dev, int pipe) | |||
1079 | { | 1079 | { |
1080 | drm_wait_one_vblank(dev, pipe); | 1080 | drm_wait_one_vblank(dev, pipe); |
1081 | } | 1081 | } |
1082 | static inline void | ||
1083 | intel_wait_for_vblank_if_active(struct drm_device *dev, int pipe) | ||
1084 | { | ||
1085 | const struct intel_crtc *crtc = | ||
1086 | to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe)); | ||
1087 | |||
1088 | if (crtc->active) | ||
1089 | intel_wait_for_vblank(dev, pipe); | ||
1090 | } | ||
1082 | int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp); | 1091 | int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp); |
1083 | void vlv_wait_port_ready(struct drm_i915_private *dev_priv, | 1092 | void vlv_wait_port_ready(struct drm_i915_private *dev_priv, |
1084 | struct intel_digital_port *dport, | 1093 | struct intel_digital_port *dport, |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 013bd7d522ca..bccbe701649b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -1108,6 +1108,13 @@ static void intel_disable_hdmi(struct intel_encoder *encoder) | |||
1108 | * matching DP port to be enabled on transcoder A. | 1108 | * matching DP port to be enabled on transcoder A. |
1109 | */ | 1109 | */ |
1110 | if (HAS_PCH_IBX(dev) && crtc->pipe == PIPE_B) { | 1110 | if (HAS_PCH_IBX(dev) && crtc->pipe == PIPE_B) { |
1111 | /* | ||
1112 | * We get CPU/PCH FIFO underruns on the other pipe when | ||
1113 | * doing the workaround. Sweep them under the rug. | ||
1114 | */ | ||
1115 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false); | ||
1116 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); | ||
1117 | |||
1111 | temp &= ~SDVO_PIPE_B_SELECT; | 1118 | temp &= ~SDVO_PIPE_B_SELECT; |
1112 | temp |= SDVO_ENABLE; | 1119 | temp |= SDVO_ENABLE; |
1113 | /* | 1120 | /* |
@@ -1122,6 +1129,10 @@ static void intel_disable_hdmi(struct intel_encoder *encoder) | |||
1122 | temp &= ~SDVO_ENABLE; | 1129 | temp &= ~SDVO_ENABLE; |
1123 | I915_WRITE(intel_hdmi->hdmi_reg, temp); | 1130 | I915_WRITE(intel_hdmi->hdmi_reg, temp); |
1124 | POSTING_READ(intel_hdmi->hdmi_reg); | 1131 | POSTING_READ(intel_hdmi->hdmi_reg); |
1132 | |||
1133 | intel_wait_for_vblank_if_active(dev_priv->dev, PIPE_A); | ||
1134 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); | ||
1135 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); | ||
1125 | } | 1136 | } |
1126 | 1137 | ||
1127 | intel_hdmi->set_infoframes(&encoder->base, false, NULL); | 1138 | intel_hdmi->set_infoframes(&encoder->base, false, NULL); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index c42b636c2087..267e6cb76c4a 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1464,12 +1464,23 @@ static void intel_disable_sdvo(struct intel_encoder *encoder) | |||
1464 | * matching DP port to be enabled on transcoder A. | 1464 | * matching DP port to be enabled on transcoder A. |
1465 | */ | 1465 | */ |
1466 | if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) { | 1466 | if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) { |
1467 | /* | ||
1468 | * We get CPU/PCH FIFO underruns on the other pipe when | ||
1469 | * doing the workaround. Sweep them under the rug. | ||
1470 | */ | ||
1471 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false); | ||
1472 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); | ||
1473 | |||
1467 | temp &= ~SDVO_PIPE_B_SELECT; | 1474 | temp &= ~SDVO_PIPE_B_SELECT; |
1468 | temp |= SDVO_ENABLE; | 1475 | temp |= SDVO_ENABLE; |
1469 | intel_sdvo_write_sdvox(intel_sdvo, temp); | 1476 | intel_sdvo_write_sdvox(intel_sdvo, temp); |
1470 | 1477 | ||
1471 | temp &= ~SDVO_ENABLE; | 1478 | temp &= ~SDVO_ENABLE; |
1472 | intel_sdvo_write_sdvox(intel_sdvo, temp); | 1479 | intel_sdvo_write_sdvox(intel_sdvo, temp); |
1480 | |||
1481 | intel_wait_for_vblank_if_active(dev_priv->dev, PIPE_A); | ||
1482 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); | ||
1483 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); | ||
1473 | } | 1484 | } |
1474 | } | 1485 | } |
1475 | 1486 | ||