aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-10-03 05:56:11 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-10-03 05:56:11 -0400
commit58e10eb92d36a62568349d985c9140d9be16a99c (patch)
tree6ffaf65e64db390f6a28c1dca8c43d4eb1493f94 /drivers
parent1cdf7fef793c715d8c4998575aba3741fa4a0b01 (diff)
parentab7ad7f6451580aa7eccc0ba62807c872088a8f9 (diff)
Merge branch 'drm-intel-fixes' into drm-intel-next
Conflicts: drivers/gpu/drm/i915/i915_gem_evict.c drivers/gpu/drm/i915/intel_display.c drivers/gpu/drm/i915/intel_dp.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c42
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h5
-rw-r--r--drivers/gpu/drm/i915/intel_display.c57
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c23
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c2
7 files changed, 74 insertions, 59 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a78c97340605..19acf123c1f1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3379,6 +3379,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
3379 (int) reloc->offset, 3379 (int) reloc->offset,
3380 reloc->read_domains, 3380 reloc->read_domains,
3381 reloc->write_domain); 3381 reloc->write_domain);
3382 drm_gem_object_unreference(target_obj);
3383 i915_gem_object_unpin(obj);
3382 return -EINVAL; 3384 return -EINVAL;
3383 } 3385 }
3384 if (reloc->write_domain & I915_GEM_DOMAIN_CPU || 3386 if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index c503c81f4cdf..3d7fbf32bb18 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -93,7 +93,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
93{ 93{
94 drm_i915_private_t *dev_priv = dev->dev_private; 94 drm_i915_private_t *dev_priv = dev->dev_private;
95 struct list_head eviction_list, unwind_list; 95 struct list_head eviction_list, unwind_list;
96 struct drm_i915_gem_object *obj_priv, *tmp_obj_priv; 96 struct drm_i915_gem_object *obj_priv;
97 struct list_head *render_iter, *bsd_iter; 97 struct list_head *render_iter, *bsd_iter;
98 int ret = 0; 98 int ret = 0;
99 99
@@ -175,36 +175,34 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
175 return -ENOSPC; 175 return -ENOSPC;
176 176
177found: 177found:
178 /* drm_mm doesn't allow any other other operations while
179 * scanning, therefore store to be evicted objects on a
180 * temporary list. */
178 INIT_LIST_HEAD(&eviction_list); 181 INIT_LIST_HEAD(&eviction_list);
179 list_for_each_entry_safe(obj_priv, tmp_obj_priv, 182 while (!list_empty(&unwind_list)) {
180 &unwind_list, evict_list) { 183 obj_priv = list_first_entry(&unwind_list,
184 struct drm_i915_gem_object,
185 evict_list);
181 if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { 186 if (drm_mm_scan_remove_block(obj_priv->gtt_space)) {
182 /* drm_mm doesn't allow any other other operations while
183 * scanning, therefore store to be evicted objects on a
184 * temporary list. */
185 list_move(&obj_priv->evict_list, &eviction_list); 187 list_move(&obj_priv->evict_list, &eviction_list);
186 } else 188 continue;
187 drm_gem_object_unreference(&obj_priv->base); 189 }
190 list_del(&obj_priv->evict_list);
191 drm_gem_object_unreference(&obj_priv->base);
188 } 192 }
189 193
190 /* Unbinding will emit any required flushes */ 194 /* Unbinding will emit any required flushes */
191 list_for_each_entry_safe(obj_priv, tmp_obj_priv, 195 while (!list_empty(&eviction_list)) {
192 &eviction_list, evict_list) { 196 obj_priv = list_first_entry(&eviction_list,
193 ret = i915_gem_object_unbind(&obj_priv->base); 197 struct drm_i915_gem_object,
194 if (ret) 198 evict_list);
195 return ret; 199 if (ret == 0)
196 200 ret = i915_gem_object_unbind(&obj_priv->base);
201 list_del(&obj_priv->evict_list);
197 drm_gem_object_unreference(&obj_priv->base); 202 drm_gem_object_unreference(&obj_priv->base);
198 } 203 }
199 204
200 /* The just created free hole should be on the top of the free stack 205 return ret;
201 * maintained by drm_mm, so this BUG_ON actually executes in O(1).
202 * Furthermore all accessed data has just recently been used, so it
203 * should be really fast, too. */
204 BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size,
205 alignment, 0));
206
207 return 0;
208} 206}
209 207
210int 208int
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 58cfea25a645..d02de212e6ad 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2105,7 +2105,7 @@
2105 2105
2106/* Pipe A */ 2106/* Pipe A */
2107#define PIPEADSL 0x70000 2107#define PIPEADSL 0x70000
2108#define DSL_LINEMASK 0x00000fff 2108#define DSL_LINEMASK 0x00000fff
2109#define PIPEACONF 0x70008 2109#define PIPEACONF 0x70008
2110#define PIPECONF_ENABLE (1<<31) 2110#define PIPECONF_ENABLE (1<<31)
2111#define PIPECONF_DISABLE 0 2111#define PIPECONF_DISABLE 0
@@ -2162,13 +2162,14 @@
2162#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ 2162#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
2163#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) 2163#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
2164#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0) 2164#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
2165#define PIPE_BPC_MASK (7 << 5) /* Ironlake */ 2165#define PIPE_BPC_MASK (7 << 5) /* Ironlake */
2166#define PIPE_8BPC (0 << 5) 2166#define PIPE_8BPC (0 << 5)
2167#define PIPE_10BPC (1 << 5) 2167#define PIPE_10BPC (1 << 5)
2168#define PIPE_6BPC (2 << 5) 2168#define PIPE_6BPC (2 << 5)
2169#define PIPE_12BPC (3 << 5) 2169#define PIPE_12BPC (3 << 5)
2170 2170
2171#define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF) 2171#define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF)
2172#define PIPEDSL(pipe) _PIPE(pipe, PIPEADSL, PIPEBDSL)
2172 2173
2173#define DSPARB 0x70030 2174#define DSPARB 0x70030
2174#define DSPARB_CSTART_MASK (0x7f << 7) 2175#define DSPARB_CSTART_MASK (0x7f << 7)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 00214c123ec2..a2e8e15b8f5a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1017,8 +1017,8 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
1017 DRM_DEBUG_KMS("vblank wait timed out\n"); 1017 DRM_DEBUG_KMS("vblank wait timed out\n");
1018} 1018}
1019 1019
1020/** 1020/*
1021 * intel_wait_for_vblank_off - wait for vblank after disabling a pipe 1021 * intel_wait_for_pipe_off - wait for pipe to turn off
1022 * @dev: drm device 1022 * @dev: drm device
1023 * @pipe: pipe to wait for 1023 * @pipe: pipe to wait for
1024 * 1024 *
@@ -1026,26 +1026,39 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
1026 * spinning on the vblank interrupt status bit, since we won't actually 1026 * spinning on the vblank interrupt status bit, since we won't actually
1027 * see an interrupt when the pipe is disabled. 1027 * see an interrupt when the pipe is disabled.
1028 * 1028 *
1029 * So this function waits for the display line value to settle (it 1029 * On Gen4 and above:
1030 * usually ends up stopping at the start of the next frame). 1030 * wait for the pipe register state bit to turn off
1031 *
1032 * Otherwise:
1033 * wait for the display line value to settle (it usually
1034 * ends up stopping at the start of the next frame).
1035 *
1031 */ 1036 */
1032void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) 1037void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
1033{ 1038{
1034 struct drm_i915_private *dev_priv = dev->dev_private; 1039 struct drm_i915_private *dev_priv = dev->dev_private;
1035 int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); 1040
1036 unsigned long timeout = jiffies + msecs_to_jiffies(100); 1041 if (INTEL_INFO(dev)->gen >= 4) {
1037 u32 last_line, line; 1042 int reg = PIPECONF(pipe);
1038 1043
1039 /* Wait for the display line to settle */ 1044 /* Wait for the Pipe State to go off */
1040 line = I915_READ(pipedsl_reg) & DSL_LINEMASK; 1045 if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0,
1041 do { 1046 100))
1042 last_line = line; 1047 DRM_DEBUG_KMS("pipe_off wait timed out\n");
1043 MSLEEP(5); 1048 } else {
1044 line = I915_READ(pipedsl_reg) & DSL_LINEMASK; 1049 u32 last_line;
1045 } while (line != last_line && time_after(timeout, jiffies)); 1050 int reg = PIPEDSL(pipe);
1046 1051 unsigned long timeout = jiffies + msecs_to_jiffies(100);
1047 if (line != last_line) 1052
1048 DRM_DEBUG_KMS("vblank wait timed out\n"); 1053 /* Wait for the display line to settle */
1054 do {
1055 last_line = I915_READ(reg) & DSL_LINEMASK;
1056 mdelay(5);
1057 } while (((I915_READ(reg) & DSL_LINEMASK) != last_line) &&
1058 time_after(timeout, jiffies));
1059 if (time_after(jiffies, timeout))
1060 DRM_DEBUG_KMS("pipe_off wait timed out\n");
1061 }
1049} 1062}
1050 1063
1051static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) 1064static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
@@ -2406,7 +2419,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
2406 2419
2407 /* Wait for vblank for the disable to take effect */ 2420 /* Wait for vblank for the disable to take effect */
2408 if (IS_GEN2(dev)) 2421 if (IS_GEN2(dev))
2409 intel_wait_for_vblank_off(dev, pipe); 2422 intel_wait_for_vblank(dev, pipe);
2410 } 2423 }
2411 2424
2412 /* Don't disable pipe A or pipe A PLLs if needed */ 2425 /* Don't disable pipe A or pipe A PLLs if needed */
@@ -2419,9 +2432,9 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
2419 if (temp & PIPECONF_ENABLE) { 2432 if (temp & PIPECONF_ENABLE) {
2420 I915_WRITE(reg, temp & ~PIPECONF_ENABLE); 2433 I915_WRITE(reg, temp & ~PIPECONF_ENABLE);
2421 2434
2422 /* Wait for vblank for the disable to take effect. */ 2435 /* Wait for the pipe to turn off */
2423 POSTING_READ(reg); 2436 POSTING_READ(reg);
2424 intel_wait_for_vblank_off(dev, pipe); 2437 intel_wait_for_pipe_off(dev, pipe);
2425 } 2438 }
2426 2439
2427 reg = DPLL(pipe); 2440 reg = DPLL(pipe);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d19334aa66ad..9e8fe122b0af 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1186,25 +1186,22 @@ intel_channel_eq_ok(struct intel_dp *intel_dp)
1186static bool 1186static bool
1187intel_dp_set_link_train(struct intel_dp *intel_dp, 1187intel_dp_set_link_train(struct intel_dp *intel_dp,
1188 uint32_t dp_reg_value, 1188 uint32_t dp_reg_value,
1189 uint8_t dp_train_pat, 1189 uint8_t dp_train_pat)
1190 bool first)
1191{ 1190{
1192 struct drm_device *dev = intel_dp->base.base.dev; 1191 struct drm_device *dev = intel_dp->base.base.dev;
1193 struct drm_i915_private *dev_priv = dev->dev_private; 1192 struct drm_i915_private *dev_priv = dev->dev_private;
1194 struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
1195 int ret; 1193 int ret;
1196 1194
1197 I915_WRITE(intel_dp->output_reg, dp_reg_value); 1195 I915_WRITE(intel_dp->output_reg, dp_reg_value);
1198 POSTING_READ(intel_dp->output_reg); 1196 POSTING_READ(intel_dp->output_reg);
1199 if (first)
1200 intel_wait_for_vblank(dev, intel_crtc->pipe);
1201 1197
1202 intel_dp_aux_native_write_1(intel_dp, 1198 intel_dp_aux_native_write_1(intel_dp,
1203 DP_TRAINING_PATTERN_SET, 1199 DP_TRAINING_PATTERN_SET,
1204 dp_train_pat); 1200 dp_train_pat);
1205 1201
1206 ret = intel_dp_aux_native_write(intel_dp, 1202 ret = intel_dp_aux_native_write(intel_dp,
1207 DP_TRAINING_LANE0_SET, intel_dp->train_set, 4); 1203 DP_TRAINING_LANE0_SET,
1204 intel_dp->train_set, 4);
1208 if (ret != 4) 1205 if (ret != 4)
1209 return false; 1206 return false;
1210 1207
@@ -1216,14 +1213,20 @@ static void
1216intel_dp_start_link_train(struct intel_dp *intel_dp) 1213intel_dp_start_link_train(struct intel_dp *intel_dp)
1217{ 1214{
1218 struct drm_device *dev = intel_dp->base.base.dev; 1215 struct drm_device *dev = intel_dp->base.base.dev;
1216 struct drm_i915_private *dev_priv = dev->dev_private;
1217 struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
1219 int i; 1218 int i;
1220 uint8_t voltage; 1219 uint8_t voltage;
1221 bool clock_recovery = false; 1220 bool clock_recovery = false;
1222 bool first = true;
1223 int tries; 1221 int tries;
1224 u32 reg; 1222 u32 reg;
1225 uint32_t DP = intel_dp->DP; 1223 uint32_t DP = intel_dp->DP;
1226 1224
1225 /* Enable output, wait for it to become active */
1226 I915_WRITE(intel_dp->output_reg, intel_dp->DP);
1227 POSTING_READ(intel_dp->output_reg);
1228 intel_wait_for_vblank(dev, intel_crtc->pipe);
1229
1227 /* Write the link configuration data */ 1230 /* Write the link configuration data */
1228 intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, 1231 intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
1229 intel_dp->link_configuration, 1232 intel_dp->link_configuration,
@@ -1255,9 +1258,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
1255 reg = DP | DP_LINK_TRAIN_PAT_1; 1258 reg = DP | DP_LINK_TRAIN_PAT_1;
1256 1259
1257 if (!intel_dp_set_link_train(intel_dp, reg, 1260 if (!intel_dp_set_link_train(intel_dp, reg,
1258 DP_TRAINING_PATTERN_1, first)) 1261 DP_TRAINING_PATTERN_1))
1259 break; 1262 break;
1260 first = false;
1261 /* Set training pattern 1 */ 1263 /* Set training pattern 1 */
1262 1264
1263 udelay(100); 1265 udelay(100);
@@ -1324,8 +1326,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
1324 1326
1325 /* channel eq pattern */ 1327 /* channel eq pattern */
1326 if (!intel_dp_set_link_train(intel_dp, reg, 1328 if (!intel_dp_set_link_train(intel_dp, reg,
1327 DP_TRAINING_PATTERN_2, 1329 DP_TRAINING_PATTERN_2))
1328 false))
1329 break; 1330 break;
1330 1331
1331 udelay(400); 1332 udelay(400);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 60ce9305e772..40e99bf27ff7 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -242,8 +242,8 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
242 struct drm_crtc *crtc); 242 struct drm_crtc *crtc);
243int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, 243int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
244 struct drm_file *file_priv); 244 struct drm_file *file_priv);
245extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe);
246extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); 245extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
246extern void intel_wait_for_pipe_off(struct drm_device *dev, int pipe);
247extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, 247extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
248 struct drm_connector *connector, 248 struct drm_connector *connector,
249 struct drm_display_mode *mode, 249 struct drm_display_mode *mode,
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 106560bc84db..2f7681989316 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1170,7 +1170,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
1170 1170
1171 I915_WRITE(pipeconf_reg, pipeconf & ~PIPECONF_ENABLE); 1171 I915_WRITE(pipeconf_reg, pipeconf & ~PIPECONF_ENABLE);
1172 /* Wait for vblank for the disable to take effect. */ 1172 /* Wait for vblank for the disable to take effect. */
1173 intel_wait_for_vblank_off(dev, intel_crtc->pipe); 1173 intel_wait_for_pipe_off(dev, intel_crtc->pipe);
1174 1174
1175 /* Filter ctl must be set before TV_WIN_SIZE */ 1175 /* Filter ctl must be set before TV_WIN_SIZE */
1176 I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); 1176 I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);