summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-01-17 16:02:19 -0500
committerDave Airlie <airlied@redhat.com>2016-01-17 16:02:19 -0500
commit1df59b8497f47495e873c23abd6d3d290c730505 (patch)
tree8fe819870ce75e21c413aabaa483b699c186d938 /drivers/gpu
parent28f03607bb2e7a3dab71d0a377fd13f6ed3ebb9f (diff)
parent48ea1e32c39db94c59b63580b965222c7782112f (diff)
Merge tag 'drm-intel-next-fixes-2016-01-14' of git://anongit.freedesktop.org/drm-intel into drm-next
misc i915 fixes all over the place. * tag 'drm-intel-next-fixes-2016-01-14' of git://anongit.freedesktop.org/drm-intel: drm/i915/gen9: Set PIN_ZONE_4G end to 4GB - 1 page drm/i915: Widen return value for reservation_object_wait_timeout_rcu to long. drm/i915: intel_hpd_init(): Fix suspend/resume reprobing drm/i915: shut up gen8+ SDE irq dmesg noise, again drm/i915: Restore inhibiting the load of the default context drm/i915: Tune down rpm wakelock debug checks drm/i915: Avoid writing relocs with addresses in non-canonical form drm/i915: Move Braswell stop_machine GGTT insertion workaround
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c6
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c52
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c50
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c10
-rw-r--r--drivers/gpu/drm/i915/intel_display.c14
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h6
-rw-r--r--drivers/gpu/drm/i915/intel_hotplug.c9
8 files changed, 108 insertions, 41 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6c60e04fc09c..ddc21d4b388d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3488,7 +3488,7 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
3488 if (flags & PIN_MAPPABLE) 3488 if (flags & PIN_MAPPABLE)
3489 end = min_t(u64, end, dev_priv->gtt.mappable_end); 3489 end = min_t(u64, end, dev_priv->gtt.mappable_end);
3490 if (flags & PIN_ZONE_4G) 3490 if (flags & PIN_ZONE_4G)
3491 end = min_t(u64, end, (1ULL << 32)); 3491 end = min_t(u64, end, (1ULL << 32) - PAGE_SIZE);
3492 3492
3493 if (alignment == 0) 3493 if (alignment == 0)
3494 alignment = flags & PIN_MAPPABLE ? fence_alignment : 3494 alignment = flags & PIN_MAPPABLE ? fence_alignment :
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 900ffd044db8..c25083c78ba7 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -347,6 +347,10 @@ void i915_gem_context_reset(struct drm_device *dev)
347 i915_gem_context_unreference(lctx); 347 i915_gem_context_unreference(lctx);
348 ring->last_context = NULL; 348 ring->last_context = NULL;
349 } 349 }
350
351 /* Force the GPU state to be reinitialised on enabling */
352 if (ring->default_context)
353 ring->default_context->legacy_hw_ctx.initialized = false;
350 } 354 }
351} 355}
352 356
@@ -715,7 +719,7 @@ static int do_switch(struct drm_i915_gem_request *req)
715 if (ret) 719 if (ret)
716 goto unpin_out; 720 goto unpin_out;
717 721
718 if (!to->legacy_hw_ctx.initialized) { 722 if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to)) {
719 hw_flags |= MI_RESTORE_INHIBIT; 723 hw_flags |= MI_RESTORE_INHIBIT;
720 /* NB: If we inhibit the restore, the context is not allowed to 724 /* NB: If we inhibit the restore, the context is not allowed to
721 * die because future work may end up depending on valid address 725 * die because future work may end up depending on valid address
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 5d01ea680dc1..dccb517361b3 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -249,6 +249,31 @@ static inline int use_cpu_reloc(struct drm_i915_gem_object *obj)
249 obj->cache_level != I915_CACHE_NONE); 249 obj->cache_level != I915_CACHE_NONE);
250} 250}
251 251
252/* Used to convert any address to canonical form.
253 * Starting from gen8, some commands (e.g. STATE_BASE_ADDRESS,
254 * MI_LOAD_REGISTER_MEM and others, see Broadwell PRM Vol2a) require the
255 * addresses to be in a canonical form:
256 * "GraphicsAddress[63:48] are ignored by the HW and assumed to be in correct
257 * canonical form [63:48] == [47]."
258 */
259#define GEN8_HIGH_ADDRESS_BIT 47
260static inline uint64_t gen8_canonical_addr(uint64_t address)
261{
262 return sign_extend64(address, GEN8_HIGH_ADDRESS_BIT);
263}
264
265static inline uint64_t gen8_noncanonical_addr(uint64_t address)
266{
267 return address & ((1ULL << (GEN8_HIGH_ADDRESS_BIT + 1)) - 1);
268}
269
270static inline uint64_t
271relocation_target(struct drm_i915_gem_relocation_entry *reloc,
272 uint64_t target_offset)
273{
274 return gen8_canonical_addr((int)reloc->delta + target_offset);
275}
276
252static int 277static int
253relocate_entry_cpu(struct drm_i915_gem_object *obj, 278relocate_entry_cpu(struct drm_i915_gem_object *obj,
254 struct drm_i915_gem_relocation_entry *reloc, 279 struct drm_i915_gem_relocation_entry *reloc,
@@ -256,7 +281,7 @@ relocate_entry_cpu(struct drm_i915_gem_object *obj,
256{ 281{
257 struct drm_device *dev = obj->base.dev; 282 struct drm_device *dev = obj->base.dev;
258 uint32_t page_offset = offset_in_page(reloc->offset); 283 uint32_t page_offset = offset_in_page(reloc->offset);
259 uint64_t delta = reloc->delta + target_offset; 284 uint64_t delta = relocation_target(reloc, target_offset);
260 char *vaddr; 285 char *vaddr;
261 int ret; 286 int ret;
262 287
@@ -292,7 +317,7 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
292{ 317{
293 struct drm_device *dev = obj->base.dev; 318 struct drm_device *dev = obj->base.dev;
294 struct drm_i915_private *dev_priv = dev->dev_private; 319 struct drm_i915_private *dev_priv = dev->dev_private;
295 uint64_t delta = reloc->delta + target_offset; 320 uint64_t delta = relocation_target(reloc, target_offset);
296 uint64_t offset; 321 uint64_t offset;
297 void __iomem *reloc_page; 322 void __iomem *reloc_page;
298 int ret; 323 int ret;
@@ -347,7 +372,7 @@ relocate_entry_clflush(struct drm_i915_gem_object *obj,
347{ 372{
348 struct drm_device *dev = obj->base.dev; 373 struct drm_device *dev = obj->base.dev;
349 uint32_t page_offset = offset_in_page(reloc->offset); 374 uint32_t page_offset = offset_in_page(reloc->offset);
350 uint64_t delta = (int)reloc->delta + target_offset; 375 uint64_t delta = relocation_target(reloc, target_offset);
351 char *vaddr; 376 char *vaddr;
352 int ret; 377 int ret;
353 378
@@ -395,7 +420,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
395 target_i915_obj = target_vma->obj; 420 target_i915_obj = target_vma->obj;
396 target_obj = &target_vma->obj->base; 421 target_obj = &target_vma->obj->base;
397 422
398 target_offset = target_vma->node.start; 423 target_offset = gen8_canonical_addr(target_vma->node.start);
399 424
400 /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and 425 /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
401 * pipe_control writes because the gpu doesn't properly redirect them 426 * pipe_control writes because the gpu doesn't properly redirect them
@@ -994,6 +1019,21 @@ validate_exec_list(struct drm_device *dev,
994 if (exec[i].flags & invalid_flags) 1019 if (exec[i].flags & invalid_flags)
995 return -EINVAL; 1020 return -EINVAL;
996 1021
1022 /* Offset can be used as input (EXEC_OBJECT_PINNED), reject
1023 * any non-page-aligned or non-canonical addresses.
1024 */
1025 if (exec[i].flags & EXEC_OBJECT_PINNED) {
1026 if (exec[i].offset !=
1027 gen8_canonical_addr(exec[i].offset & PAGE_MASK))
1028 return -EINVAL;
1029
1030 /* From drm_mm perspective address space is continuous,
1031 * so from this point we're always using non-canonical
1032 * form internally.
1033 */
1034 exec[i].offset = gen8_noncanonical_addr(exec[i].offset);
1035 }
1036
997 if (exec[i].alignment && !is_power_of_2(exec[i].alignment)) 1037 if (exec[i].alignment && !is_power_of_2(exec[i].alignment))
998 return -EINVAL; 1038 return -EINVAL;
999 1039
@@ -1687,6 +1727,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
1687 1727
1688 /* Copy the new buffer offsets back to the user's exec list. */ 1728 /* Copy the new buffer offsets back to the user's exec list. */
1689 for (i = 0; i < args->buffer_count; i++) { 1729 for (i = 0; i < args->buffer_count; i++) {
1730 exec2_list[i].offset =
1731 gen8_canonical_addr(exec2_list[i].offset);
1690 ret = __copy_to_user(&user_exec_list[i].offset, 1732 ret = __copy_to_user(&user_exec_list[i].offset,
1691 &exec2_list[i].offset, 1733 &exec2_list[i].offset,
1692 sizeof(user_exec_list[i].offset)); 1734 sizeof(user_exec_list[i].offset));
@@ -1752,6 +1794,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
1752 int i; 1794 int i;
1753 1795
1754 for (i = 0; i < args->buffer_count; i++) { 1796 for (i = 0; i < args->buffer_count; i++) {
1797 exec2_list[i].offset =
1798 gen8_canonical_addr(exec2_list[i].offset);
1755 ret = __copy_to_user(&user_exec_list[i].offset, 1799 ret = __copy_to_user(&user_exec_list[i].offset,
1756 &exec2_list[i].offset, 1800 &exec2_list[i].offset,
1757 sizeof(user_exec_list[i].offset)); 1801 sizeof(user_exec_list[i].offset));
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 52bc6c3dfe04..56f4f2e58d53 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2384,6 +2384,32 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
2384 assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); 2384 assert_rpm_atomic_end(dev_priv, rpm_atomic_seq);
2385} 2385}
2386 2386
2387struct insert_entries {
2388 struct i915_address_space *vm;
2389 struct sg_table *st;
2390 uint64_t start;
2391 enum i915_cache_level level;
2392 u32 flags;
2393};
2394
2395static int gen8_ggtt_insert_entries__cb(void *_arg)
2396{
2397 struct insert_entries *arg = _arg;
2398 gen8_ggtt_insert_entries(arg->vm, arg->st,
2399 arg->start, arg->level, arg->flags);
2400 return 0;
2401}
2402
2403static void gen8_ggtt_insert_entries__BKL(struct i915_address_space *vm,
2404 struct sg_table *st,
2405 uint64_t start,
2406 enum i915_cache_level level,
2407 u32 flags)
2408{
2409 struct insert_entries arg = { vm, st, start, level, flags };
2410 stop_machine(gen8_ggtt_insert_entries__cb, &arg, NULL);
2411}
2412
2387/* 2413/*
2388 * Binds an object into the global gtt with the specified cache level. The object 2414 * Binds an object into the global gtt with the specified cache level. The object
2389 * will be accessible to the GPU via commands whose operands reference offsets 2415 * will be accessible to the GPU via commands whose operands reference offsets
@@ -2560,26 +2586,6 @@ static int ggtt_bind_vma(struct i915_vma *vma,
2560 return 0; 2586 return 0;
2561} 2587}
2562 2588
2563struct ggtt_bind_vma__cb {
2564 struct i915_vma *vma;
2565 enum i915_cache_level cache_level;
2566 u32 flags;
2567};
2568
2569static int ggtt_bind_vma__cb(void *_arg)
2570{
2571 struct ggtt_bind_vma__cb *arg = _arg;
2572 return ggtt_bind_vma(arg->vma, arg->cache_level, arg->flags);
2573}
2574
2575static int ggtt_bind_vma__BKL(struct i915_vma *vma,
2576 enum i915_cache_level cache_level,
2577 u32 flags)
2578{
2579 struct ggtt_bind_vma__cb arg = { vma, cache_level, flags };
2580 return stop_machine(ggtt_bind_vma__cb, &arg, NULL);
2581}
2582
2583static int aliasing_gtt_bind_vma(struct i915_vma *vma, 2589static int aliasing_gtt_bind_vma(struct i915_vma *vma,
2584 enum i915_cache_level cache_level, 2590 enum i915_cache_level cache_level,
2585 u32 flags) 2591 u32 flags)
@@ -3048,8 +3054,8 @@ static int gen8_gmch_probe(struct drm_device *dev,
3048 dev_priv->gtt.base.bind_vma = ggtt_bind_vma; 3054 dev_priv->gtt.base.bind_vma = ggtt_bind_vma;
3049 dev_priv->gtt.base.unbind_vma = ggtt_unbind_vma; 3055 dev_priv->gtt.base.unbind_vma = ggtt_unbind_vma;
3050 3056
3051 if (IS_CHERRYVIEW(dev)) 3057 if (IS_CHERRYVIEW(dev_priv))
3052 dev_priv->gtt.base.bind_vma = ggtt_bind_vma__BKL; 3058 dev_priv->gtt.base.insert_entries = gen8_ggtt_insert_entries__BKL;
3053 3059
3054 return ret; 3060 return ret;
3055} 3061}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 3f8c753997ba..fa8afa7860ae 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2414,9 +2414,13 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
2414 spt_irq_handler(dev, pch_iir); 2414 spt_irq_handler(dev, pch_iir);
2415 else 2415 else
2416 cpt_irq_handler(dev, pch_iir); 2416 cpt_irq_handler(dev, pch_iir);
2417 } else 2417 } else {
2418 DRM_ERROR("The master control interrupt lied (SDE)!\n"); 2418 /*
2419 2419 * Like on previous PCH there seems to be something
2420 * fishy going on with forwarding PCH interrupts.
2421 */
2422 DRM_DEBUG_DRIVER("The master control interrupt lied (SDE)!\n");
2423 }
2420 } 2424 }
2421 2425
2422 I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); 2426 I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ceaea7a3641a..580d094bfc1e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13763,13 +13763,15 @@ intel_prepare_plane_fb(struct drm_plane *plane,
13763 13763
13764 /* For framebuffer backed by dmabuf, wait for fence */ 13764 /* For framebuffer backed by dmabuf, wait for fence */
13765 if (obj && obj->base.dma_buf) { 13765 if (obj && obj->base.dma_buf) {
13766 ret = reservation_object_wait_timeout_rcu(obj->base.dma_buf->resv, 13766 long lret;
13767 false, true, 13767
13768 MAX_SCHEDULE_TIMEOUT); 13768 lret = reservation_object_wait_timeout_rcu(obj->base.dma_buf->resv,
13769 if (ret == -ERESTARTSYS) 13769 false, true,
13770 return ret; 13770 MAX_SCHEDULE_TIMEOUT);
13771 if (lret == -ERESTARTSYS)
13772 return lret;
13771 13773
13772 WARN_ON(ret < 0); 13774 WARN(lret < 0, "waiting returns %li\n", lret);
13773 } 13775 }
13774 13776
13775 if (!obj) { 13777 if (!obj) {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d523ebb2f89d..ea5415851c6e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1442,8 +1442,10 @@ static inline void
1442assert_rpm_wakelock_held(struct drm_i915_private *dev_priv) 1442assert_rpm_wakelock_held(struct drm_i915_private *dev_priv)
1443{ 1443{
1444 assert_rpm_device_not_suspended(dev_priv); 1444 assert_rpm_device_not_suspended(dev_priv);
1445 WARN_ONCE(!atomic_read(&dev_priv->pm.wakeref_count), 1445 /* FIXME: Needs to be converted back to WARN_ONCE, but currently causes
1446 "RPM wakelock ref not held during HW access"); 1446 * too much noise. */
1447 if (!atomic_read(&dev_priv->pm.wakeref_count))
1448 DRM_DEBUG_DRIVER("RPM wakelock ref not held during HW access");
1447} 1449}
1448 1450
1449static inline int 1451static inline int
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index a294a3cbaea1..bee673005d48 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -468,9 +468,14 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
468 list_for_each_entry(connector, &mode_config->connector_list, head) { 468 list_for_each_entry(connector, &mode_config->connector_list, head) {
469 struct intel_connector *intel_connector = to_intel_connector(connector); 469 struct intel_connector *intel_connector = to_intel_connector(connector);
470 connector->polled = intel_connector->polled; 470 connector->polled = intel_connector->polled;
471 if (connector->encoder && !connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE) 471
472 connector->polled = DRM_CONNECTOR_POLL_HPD; 472 /* MST has a dynamic intel_connector->encoder and it's reprobing
473 * is all handled by the MST helpers. */
473 if (intel_connector->mst_port) 474 if (intel_connector->mst_port)
475 continue;
476
477 if (!connector->polled && I915_HAS_HOTPLUG(dev) &&
478 intel_connector->encoder->hpd_pin > HPD_NONE)
474 connector->polled = DRM_CONNECTOR_POLL_HPD; 479 connector->polled = DRM_CONNECTOR_POLL_HPD;
475 } 480 }
476 481