aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2010-08-18 16:20:54 -0400
committerEric Anholt <eric@anholt.net>2010-08-22 01:59:23 -0400
commit9d0498a2bf7455159b317f19531a3e5db2ecc9c4 (patch)
tree41f2a8b1013d2ee12852d8885b9952120f3d6ebb /drivers
parentd240f20f545fa4ed78ce48d1eb62ab529f2b1467 (diff)
drm/i915: wait for actual vblank, not just 20ms
Waiting for a hard coded 20ms isn't always enough to make sure a vblank period has actually occurred, so add code to make sure we really have passed through a vblank period (or that the pipe is off when disabling). This prevents problems with mode setting and link training, and seems to fix a bug like https://bugs.freedesktop.org/show_bug.cgi?id=29278, but on an HP 8440p instead. Hopefully also fixes https://bugs.freedesktop.org/show_bug.cgi?id=29141. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c78
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c3
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h3
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c3
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c9
7 files changed, 69 insertions, 30 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a63e9a176386..67e3ec1a6af9 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2081,6 +2081,7 @@
2081#define PIPE_DITHER_TYPE_ST01 (1 << 2) 2081#define PIPE_DITHER_TYPE_ST01 (1 << 2)
2082/* Pipe A */ 2082/* Pipe A */
2083#define PIPEADSL 0x70000 2083#define PIPEADSL 0x70000
2084#define DSL_LINEMASK 0x00000fff
2084#define PIPEACONF 0x70008 2085#define PIPEACONF 0x70008
2085#define PIPEACONF_ENABLE (1<<31) 2086#define PIPEACONF_ENABLE (1<<31)
2086#define PIPEACONF_DISABLE 0 2087#define PIPEACONF_DISABLE 0
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index c43176d77549..eb31fdf758e8 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -328,7 +328,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder
328 I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); 328 I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
329 /* Wait for next Vblank to substitue 329 /* Wait for next Vblank to substitue
330 * border color for Color info */ 330 * border color for Color info */
331 intel_wait_for_vblank(dev); 331 intel_wait_for_vblank(dev, pipe);
332 st00 = I915_READ8(VGA_MSR_WRITE); 332 st00 = I915_READ8(VGA_MSR_WRITE);
333 status = ((st00 & (1 << 4)) != 0) ? 333 status = ((st00 & (1 << 4)) != 0) ?
334 connector_status_connected : 334 connector_status_connected :
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 14c45b1e8778..bdea9464b678 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -977,14 +977,54 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
977 return true; 977 return true;
978} 978}
979 979
980void 980/**
981intel_wait_for_vblank(struct drm_device *dev) 981 * intel_wait_for_vblank - wait for vblank on a given pipe
982 * @dev: drm device
983 * @pipe: pipe to wait for
984 *
985 * Wait for vblank to occur on a given pipe. Needed for various bits of
986 * mode setting code.
987 */
988void intel_wait_for_vblank(struct drm_device *dev, int pipe)
982{ 989{
983 /* Wait for 20ms, i.e. one cycle at 50hz. */ 990 struct drm_i915_private *dev_priv = dev->dev_private;
984 if (in_dbg_master()) 991 int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT);
985 mdelay(20); /* The kernel debugger cannot call msleep() */ 992
986 else 993 /* Wait for vblank interrupt bit to set */
987 msleep(20); 994 if (wait_for((I915_READ(pipestat_reg) &
995 PIPE_VBLANK_INTERRUPT_STATUS) == 0,
996 50, 0))
997 DRM_DEBUG_KMS("vblank wait timed out\n");
998}
999
1000/**
1001 * intel_wait_for_vblank_off - wait for vblank after disabling a pipe
1002 * @dev: drm device
1003 * @pipe: pipe to wait for
1004 *
1005 * After disabling a pipe, we can't wait for vblank in the usual way,
1006 * spinning on the vblank interrupt status bit, since we won't actually
1007 * see an interrupt when the pipe is disabled.
1008 *
1009 * So this function waits for the display line value to settle (it
1010 * usually ends up stopping at the start of the next frame).
1011 */
1012void intel_wait_for_vblank_off(struct drm_device *dev, int pipe)
1013{
1014 struct drm_i915_private *dev_priv = dev->dev_private;
1015 int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);
1016 unsigned long timeout = jiffies + msecs_to_jiffies(100);
1017 u32 last_line;
1018
1019 /* Wait for the display line to settle */
1020 do {
1021 last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
1022 mdelay(5);
1023 } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) &&
1024 time_after(timeout, jiffies));
1025
1026 if (time_after(jiffies, timeout))
1027 DRM_DEBUG_KMS("vblank wait timed out\n");
988} 1028}
989 1029
990/* Parameters have changed, update FBC info */ 1030/* Parameters have changed, update FBC info */
@@ -1057,8 +1097,6 @@ void i8xx_disable_fbc(struct drm_device *dev)
1057 return; 1097 return;
1058 } 1098 }
1059 1099
1060 intel_wait_for_vblank(dev);
1061
1062 DRM_DEBUG_KMS("disabled FBC\n"); 1100 DRM_DEBUG_KMS("disabled FBC\n");
1063} 1101}
1064 1102
@@ -1115,7 +1153,6 @@ void g4x_disable_fbc(struct drm_device *dev)
1115 dpfc_ctl = I915_READ(DPFC_CONTROL); 1153 dpfc_ctl = I915_READ(DPFC_CONTROL);
1116 dpfc_ctl &= ~DPFC_CTL_EN; 1154 dpfc_ctl &= ~DPFC_CTL_EN;
1117 I915_WRITE(DPFC_CONTROL, dpfc_ctl); 1155 I915_WRITE(DPFC_CONTROL, dpfc_ctl);
1118 intel_wait_for_vblank(dev);
1119 1156
1120 DRM_DEBUG_KMS("disabled FBC\n"); 1157 DRM_DEBUG_KMS("disabled FBC\n");
1121} 1158}
@@ -1176,7 +1213,6 @@ void ironlake_disable_fbc(struct drm_device *dev)
1176 dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); 1213 dpfc_ctl = I915_READ(ILK_DPFC_CONTROL);
1177 dpfc_ctl &= ~DPFC_CTL_EN; 1214 dpfc_ctl &= ~DPFC_CTL_EN;
1178 I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); 1215 I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl);
1179 intel_wait_for_vblank(dev);
1180 1216
1181 DRM_DEBUG_KMS("disabled FBC\n"); 1217 DRM_DEBUG_KMS("disabled FBC\n");
1182} 1218}
@@ -1475,7 +1511,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
1475 if ((IS_I965G(dev) || plane == 0)) 1511 if ((IS_I965G(dev) || plane == 0))
1476 intel_update_fbc(crtc, &crtc->mode); 1512 intel_update_fbc(crtc, &crtc->mode);
1477 1513
1478 intel_wait_for_vblank(dev); 1514 intel_wait_for_vblank(dev, intel_crtc->pipe);
1479 intel_increase_pllclock(crtc, true); 1515 intel_increase_pllclock(crtc, true);
1480 1516
1481 return 0; 1517 return 0;
@@ -1593,7 +1629,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1593 if ((IS_I965G(dev) || plane == 0)) 1629 if ((IS_I965G(dev) || plane == 0))
1594 intel_update_fbc(crtc, &crtc->mode); 1630 intel_update_fbc(crtc, &crtc->mode);
1595 1631
1596 intel_wait_for_vblank(dev); 1632 intel_wait_for_vblank(dev, pipe);
1597 1633
1598 if (old_fb) { 1634 if (old_fb) {
1599 intel_fb = to_intel_framebuffer(old_fb); 1635 intel_fb = to_intel_framebuffer(old_fb);
@@ -2343,10 +2379,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
2343 I915_READ(dspbase_reg); 2379 I915_READ(dspbase_reg);
2344 } 2380 }
2345 2381
2346 if (!IS_I9XX(dev)) { 2382 /* Wait for vblank for the disable to take effect */
2347 /* Wait for vblank for the disable to take effect */ 2383 intel_wait_for_vblank_off(dev, pipe);
2348 intel_wait_for_vblank(dev);
2349 }
2350 2384
2351 /* Don't disable pipe A or pipe A PLLs if needed */ 2385 /* Don't disable pipe A or pipe A PLLs if needed */
2352 if (pipeconf_reg == PIPEACONF && 2386 if (pipeconf_reg == PIPEACONF &&
@@ -2361,7 +2395,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
2361 } 2395 }
2362 2396
2363 /* Wait for vblank for the disable to take effect. */ 2397 /* Wait for vblank for the disable to take effect. */
2364 intel_wait_for_vblank(dev); 2398 intel_wait_for_vblank_off(dev, pipe);
2365 2399
2366 temp = I915_READ(dpll_reg); 2400 temp = I915_READ(dpll_reg);
2367 if ((temp & DPLL_VCO_ENABLE) != 0) { 2401 if ((temp & DPLL_VCO_ENABLE) != 0) {
@@ -4096,7 +4130,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
4096 I915_WRITE(pipeconf_reg, pipeconf); 4130 I915_WRITE(pipeconf_reg, pipeconf);
4097 I915_READ(pipeconf_reg); 4131 I915_READ(pipeconf_reg);
4098 4132
4099 intel_wait_for_vblank(dev); 4133 intel_wait_for_vblank(dev, pipe);
4100 4134
4101 if (IS_IRONLAKE(dev)) { 4135 if (IS_IRONLAKE(dev)) {
4102 /* enable address swizzle for tiling buffer */ 4136 /* enable address swizzle for tiling buffer */
@@ -4508,7 +4542,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
4508 encoder_funcs->commit(encoder); 4542 encoder_funcs->commit(encoder);
4509 } 4543 }
4510 /* let the connector get through one full cycle before testing */ 4544 /* let the connector get through one full cycle before testing */
4511 intel_wait_for_vblank(dev); 4545 intel_wait_for_vblank(dev, intel_crtc->pipe);
4512 4546
4513 return crtc; 4547 return crtc;
4514} 4548}
@@ -4713,7 +4747,7 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule)
4713 dpll &= ~DISPLAY_RATE_SELECT_FPA1; 4747 dpll &= ~DISPLAY_RATE_SELECT_FPA1;
4714 I915_WRITE(dpll_reg, dpll); 4748 I915_WRITE(dpll_reg, dpll);
4715 dpll = I915_READ(dpll_reg); 4749 dpll = I915_READ(dpll_reg);
4716 intel_wait_for_vblank(dev); 4750 intel_wait_for_vblank(dev, pipe);
4717 dpll = I915_READ(dpll_reg); 4751 dpll = I915_READ(dpll_reg);
4718 if (dpll & DISPLAY_RATE_SELECT_FPA1) 4752 if (dpll & DISPLAY_RATE_SELECT_FPA1)
4719 DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); 4753 DRM_DEBUG_DRIVER("failed to upclock LVDS!\n");
@@ -4757,7 +4791,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
4757 dpll |= DISPLAY_RATE_SELECT_FPA1; 4791 dpll |= DISPLAY_RATE_SELECT_FPA1;
4758 I915_WRITE(dpll_reg, dpll); 4792 I915_WRITE(dpll_reg, dpll);
4759 dpll = I915_READ(dpll_reg); 4793 dpll = I915_READ(dpll_reg);
4760 intel_wait_for_vblank(dev); 4794 intel_wait_for_vblank(dev, pipe);
4761 dpll = I915_READ(dpll_reg); 4795 dpll = I915_READ(dpll_reg);
4762 if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) 4796 if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
4763 DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); 4797 DRM_DEBUG_DRIVER("failed to downclock LVDS!\n");
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index caaaa8f9db3e..9caccd03dccb 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1145,12 +1145,13 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
1145{ 1145{
1146 struct drm_device *dev = intel_dp->base.enc.dev; 1146 struct drm_device *dev = intel_dp->base.enc.dev;
1147 struct drm_i915_private *dev_priv = dev->dev_private; 1147 struct drm_i915_private *dev_priv = dev->dev_private;
1148 struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc);
1148 int ret; 1149 int ret;
1149 1150
1150 I915_WRITE(intel_dp->output_reg, dp_reg_value); 1151 I915_WRITE(intel_dp->output_reg, dp_reg_value);
1151 POSTING_READ(intel_dp->output_reg); 1152 POSTING_READ(intel_dp->output_reg);
1152 if (first) 1153 if (first)
1153 intel_wait_for_vblank(dev); 1154 intel_wait_for_vblank(dev, intel_crtc->pipe);
1154 1155
1155 intel_dp_aux_native_write_1(intel_dp, 1156 intel_dp_aux_native_write_1(intel_dp,
1156 DP_TRAINING_PATTERN_SET, 1157 DP_TRAINING_PATTERN_SET,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6ba56e1796ce..0e92aa07b382 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -219,7 +219,8 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
219 struct drm_crtc *crtc); 219 struct drm_crtc *crtc);
220int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, 220int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
221 struct drm_file *file_priv); 221 struct drm_file *file_priv);
222extern void intel_wait_for_vblank(struct drm_device *dev); 222extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe);
223extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
223extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); 224extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
224extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, 225extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
225 struct drm_connector *connector, 226 struct drm_connector *connector,
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 5c765bb0845d..093e914e8a41 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1218,6 +1218,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
1218 struct drm_device *dev = encoder->dev; 1218 struct drm_device *dev = encoder->dev;
1219 struct drm_i915_private *dev_priv = dev->dev_private; 1219 struct drm_i915_private *dev_priv = dev->dev_private;
1220 struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); 1220 struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
1221 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
1221 u32 temp; 1222 u32 temp;
1222 1223
1223 if (mode != DRM_MODE_DPMS_ON) { 1224 if (mode != DRM_MODE_DPMS_ON) {
@@ -1240,7 +1241,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
1240 if ((temp & SDVO_ENABLE) == 0) 1241 if ((temp & SDVO_ENABLE) == 0)
1241 intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE); 1242 intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE);
1242 for (i = 0; i < 2; i++) 1243 for (i = 0; i < 2; i++)
1243 intel_wait_for_vblank(dev); 1244 intel_wait_for_vblank(dev, intel_crtc->pipe);
1244 1245
1245 status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); 1246 status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
1246 /* Warn if the device reported failure to sync. 1247 /* Warn if the device reported failure to sync.
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 1bd6e8795011..d2029efee982 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1158,11 +1158,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
1158 1158
1159 /* Wait for vblank for the disable to take effect */ 1159 /* Wait for vblank for the disable to take effect */
1160 if (!IS_I9XX(dev)) 1160 if (!IS_I9XX(dev))
1161 intel_wait_for_vblank(dev); 1161 intel_wait_for_vblank(dev, intel_crtc->pipe);
1162 1162
1163 I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); 1163 I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
1164 /* Wait for vblank for the disable to take effect. */ 1164 /* Wait for vblank for the disable to take effect. */
1165 intel_wait_for_vblank(dev); 1165 intel_wait_for_vblank(dev, intel_crtc->pipe);
1166 1166
1167 /* Filter ctl must be set before TV_WIN_SIZE */ 1167 /* Filter ctl must be set before TV_WIN_SIZE */
1168 I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); 1168 I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
@@ -1231,6 +1231,7 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
1231 struct drm_encoder *encoder = &intel_tv->base.enc; 1231 struct drm_encoder *encoder = &intel_tv->base.enc;
1232 struct drm_device *dev = encoder->dev; 1232 struct drm_device *dev = encoder->dev;
1233 struct drm_i915_private *dev_priv = dev->dev_private; 1233 struct drm_i915_private *dev_priv = dev->dev_private;
1234 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
1234 unsigned long irqflags; 1235 unsigned long irqflags;
1235 u32 tv_ctl, save_tv_ctl; 1236 u32 tv_ctl, save_tv_ctl;
1236 u32 tv_dac, save_tv_dac; 1237 u32 tv_dac, save_tv_dac;
@@ -1267,11 +1268,11 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
1267 DAC_C_0_7_V); 1268 DAC_C_0_7_V);
1268 I915_WRITE(TV_CTL, tv_ctl); 1269 I915_WRITE(TV_CTL, tv_ctl);
1269 I915_WRITE(TV_DAC, tv_dac); 1270 I915_WRITE(TV_DAC, tv_dac);
1270 intel_wait_for_vblank(dev); 1271 intel_wait_for_vblank(dev, intel_crtc->pipe);
1271 tv_dac = I915_READ(TV_DAC); 1272 tv_dac = I915_READ(TV_DAC);
1272 I915_WRITE(TV_DAC, save_tv_dac); 1273 I915_WRITE(TV_DAC, save_tv_dac);
1273 I915_WRITE(TV_CTL, save_tv_ctl); 1274 I915_WRITE(TV_CTL, save_tv_ctl);
1274 intel_wait_for_vblank(dev); 1275 intel_wait_for_vblank(dev, intel_crtc->pipe);
1275 /* 1276 /*
1276 * A B C 1277 * A B C
1277 * 0 1 1 Composite 1278 * 0 1 1 Composite