0097241
From 5c19e5ee394c36652c59c247855a3c7e5a83a015 Mon Sep 17 00:00:00 2001
0097241
From: Jani Nikula <jani.nikula@intel.com>
0097241
Date: Thu, 7 Jan 2016 10:29:10 +0200
0097241
Subject: [PATCH 01/26] drm/i915: shut up gen8+ SDE irq dmesg noise, again
0097241
0097241
We still keep getting
0097241
0097241
[    4.249930] [drm:gen8_irq_handler [i915]] *ERROR* The master control interrupt lied (SDE)!
0097241
0097241
This reverts
0097241
0097241
commit 820da7ae46332fa709b171eb7ba57cbd023fa6df
0097241
Author: Jani Nikula <jani.nikula@intel.com>
0097241
Date:   Wed Nov 25 16:47:23 2015 +0200
0097241
0097241
    Revert "drm/i915: shut up gen8+ SDE irq dmesg noise"
0097241
0097241
which in itself is a revert, so this is just doing
0097241
0097241
commit 97e5ed1111dcc5300a0f59a55248cd243937a8ab
0097241
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Date:   Fri Oct 23 10:56:12 2015 +0200
0097241
0097241
    drm/i915: shut up gen8+ SDE irq dmesg noise
0097241
0097241
all over again. I'll stop pretending I understand what's going on like I
0097241
did when I thought I'd fixed this for good in
0097241
0097241
commit 6a39d7c986be4fd18eb019e9cdbf774ec36c9f77
0097241
Author: Jani Nikula <jani.nikula@intel.com>
0097241
Date:   Wed Nov 25 16:47:22 2015 +0200
0097241
0097241
    drm/i915: fix the SDE irq dmesg warnings properly
0097241
0097241
Reported-by: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Reference: http://mid.gmane.org/20151213124945.GA5715@nuc-i3427.alporthouse.com
0097241
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92084
0097241
Cc: drm-intel-fixes@lists.freedesktop.org
0097241
Fixes: 820da7ae4633 ("Revert "drm/i915: shut up gen8+ SDE irq dmesg noise"")
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
0097241
[Backported to 4.3.y by Josh Boyer <jwboyer@fedoraproject.org>]
0097241
---
0097241
 drivers/gpu/drm/i915/i915_irq.c | 9 +++++++--
0097241
 1 file changed, 7 insertions(+), 2 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
0097241
index 39d73dbc1c47..fa7f82d54762 100644
0097241
--- a/drivers/gpu/drm/i915/i915_irq.c
0097241
+++ b/drivers/gpu/drm/i915/i915_irq.c
0097241
@@ -2168,8 +2168,13 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
0097241
 			I915_WRITE(SDEIIR, pch_iir);
0097241
 			ret = IRQ_HANDLED;
0097241
 			cpt_irq_handler(dev, pch_iir);
0097241
-		} else
0097241
-			DRM_ERROR("The master control interrupt lied (SDE)!\n");
0097241
+		} else {
0097241
+			/*
0097241
+			 * Like on previous PCH there seems to be something
0097241
+			 * fishy going on with forwarding PCH interrupts.
0097241
+			 */
0097241
+			DRM_DEBUG_DRIVER("The master control interrupt lied (SDE)!\n");
0097241
+		}
0097241
 
0097241
 	}
0097241
 
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 65dcf0f52e9705d0094e76a9225bbe770329c96d Mon Sep 17 00:00:00 2001
0097241
From: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Date: Thu, 1 Oct 2015 12:34:46 +0100
0097241
Subject: [PATCH 02/26] drm/i915: Fix userptr deadlock with aliased GTT
0097241
 mmappings
0097241
MIME-Version: 1.0
0097241
Content-Type: text/plain; charset=UTF-8
0097241
Content-Transfer-Encoding: 8bit
0097241
0097241
Upstream commit e4b946bfe1e36680e27a5f39163980979fa61a5d
0097241
0097241
Michał Winiarski found a really evil way to trigger a struct_mutex
0097241
deadlock with userptr. He found that if he allocated a userptr bo and
0097241
then GTT mmaped another bo, or even itself, at the same address as the
0097241
userptr using MAP_FIXED, he could then cause a deadlock any time we then
0097241
had to invalidate the GTT mmappings (so at will). Tvrtko then found by
0097241
repeatedly allocating GTT mmappings he could alias with an old userptr
0097241
mmap and also trigger the deadlock.
0097241
0097241
To counter act the deadlock, we make the observation that we only need
0097241
to take the struct_mutex if the object has any pages to revoke, and that
0097241
before userspace can alias with the userptr address space, it must have
0097241
invalidated the userptr->pages. Thus if we can check for those pages
0097241
outside of the struct_mutex, we can avoid the deadlock. To do so we
0097241
introduce a separate flag for userptr objects that we can inspect from
0097241
the mmu-notifier underneath its spinlock.
0097241
0097241
The patch makes one eye-catching change. That is the removal serial=0
0097241
after detecting a to-be-freed object inside the invalidate walker. I
0097241
felt setting serial=0 was a questionable pessimisation: it denies us the
0097241
chance to reuse the current iterator for the next loop (before it is
0097241
freed) and being explicit makes the reader question the validity of the
0097241
locking (since the object-free race could occur elsewhere). The
0097241
serialisation of the iterator is through the spinlock, if the object is
0097241
freed before the next loop then the notifier.serial will be incremented
0097241
and we start the walk from the beginning as we detect the invalid cache.
0097241
0097241
To try and tame the error paths and interactions with the userptr->active
0097241
flag, we have to do a fair amount of rearranging of get_pages_userptr().
0097241
0097241
v2: Grammar fixes
0097241
v3: Reorder set-active so that it is only set when obj->pages is set
0097241
(and so needs cancellation). Only the order of setting obj->pages and
0097241
the active-flag is crucial. Calling gup after invalidate-range begin
0097241
means the userptr sees the new set of backing storage (and so will not
0097241
need to invalidate its new pages), but we have to be careful not to set
0097241
the active-flag prior to successfully establishing obj->pages.
0097241
v4: Take the active->flag early so we know in the mmu-notifier when we
0097241
have to cancel a pending gup-worker.
0097241
v5: Rearrange the error path so that is not so convoluted
0097241
v6: Set pinned to 0 when negative before calling release_pages()
0097241
0097241
Reported-by: Michał Winiarski <michal.winiarski@intel.com>
0097241
Testcase: igt/gem_userptr_blits/map-fixed*
0097241
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Cc: Michał Winiarski <michal.winiarski@intel.com>
0097241
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
0097241
Cc: stable@vger.kernel.org
0097241
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
0097241
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
---
0097241
 drivers/gpu/drm/i915/i915_gem_userptr.c | 176 ++++++++++++++++++++------------
0097241
 1 file changed, 110 insertions(+), 66 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
0097241
index a96b9006a51e..ba321f0c41c5 100644
0097241
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
0097241
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
0097241
@@ -59,6 +59,7 @@ struct i915_mmu_object {
0097241
 	struct interval_tree_node it;
0097241
 	struct list_head link;
0097241
 	struct drm_i915_gem_object *obj;
0097241
+	bool active;
0097241
 	bool is_linear;
0097241
 };
0097241
 
0097241
@@ -114,7 +115,8 @@ restart:
0097241
 
0097241
 		obj = mo->obj;
0097241
 
0097241
-		if (!kref_get_unless_zero(&obj->base.refcount))
0097241
+		if (!mo->active ||
0097241
+		    !kref_get_unless_zero(&obj->base.refcount))
0097241
 			continue;
0097241
 
0097241
 		spin_unlock(&mn->lock);
0097241
@@ -151,7 +153,8 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
0097241
 		else
0097241
 			it = interval_tree_iter_first(&mn->objects, start, end);
0097241
 		if (it != NULL) {
0097241
-			obj = container_of(it, struct i915_mmu_object, it)->obj;
0097241
+			struct i915_mmu_object *mo =
0097241
+				container_of(it, struct i915_mmu_object, it);
0097241
 
0097241
 			/* The mmu_object is released late when destroying the
0097241
 			 * GEM object so it is entirely possible to gain a
0097241
@@ -160,11 +163,9 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
0097241
 			 * the struct_mutex - and consequently use it after it
0097241
 			 * is freed and then double free it.
0097241
 			 */
0097241
-			if (!kref_get_unless_zero(&obj->base.refcount)) {
0097241
-				spin_unlock(&mn->lock);
0097241
-				serial = 0;
0097241
-				continue;
0097241
-			}
0097241
+			if (mo->active &&
0097241
+			    kref_get_unless_zero(&mo->obj->base.refcount))
0097241
+				obj = mo->obj;
0097241
 
0097241
 			serial = mn->serial;
0097241
 		}
0097241
@@ -566,6 +567,30 @@ __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj,
0097241
 }
0097241
 
0097241
 static void
0097241
+__i915_gem_userptr_set_active(struct drm_i915_gem_object *obj,
0097241
+			      bool value)
0097241
+{
0097241
+	/* During mm_invalidate_range we need to cancel any userptr that
0097241
+	 * overlaps the range being invalidated. Doing so requires the
0097241
+	 * struct_mutex, and that risks recursion. In order to cause
0097241
+	 * recursion, the user must alias the userptr address space with
0097241
+	 * a GTT mmapping (possible with a MAP_FIXED) - then when we have
0097241
+	 * to invalidate that mmaping, mm_invalidate_range is called with
0097241
+	 * the userptr address *and* the struct_mutex held.  To prevent that
0097241
+	 * we set a flag under the i915_mmu_notifier spinlock to indicate
0097241
+	 * whether this object is valid.
0097241
+	 */
0097241
+#if defined(CONFIG_MMU_NOTIFIER)
0097241
+	if (obj->userptr.mmu_object == NULL)
0097241
+		return;
0097241
+
0097241
+	spin_lock(&obj->userptr.mmu_object->mn->lock);
0097241
+	obj->userptr.mmu_object->active = value;
0097241
+	spin_unlock(&obj->userptr.mmu_object->mn->lock);
0097241
+#endif
0097241
+}
0097241
+
0097241
+static void
0097241
 __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
0097241
 {
0097241
 	struct get_pages_work *work = container_of(_work, typeof(*work), work);
0097241
@@ -612,6 +637,9 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
0097241
 
0097241
 			pinned = 0;
0097241
 		}
0097241
+		obj->userptr.work = ERR_PTR(ret);
0097241
+		if (ret)
0097241
+			__i915_gem_userptr_set_active(obj, false);
0097241
 	}
0097241
 
0097241
 	obj->userptr.work = ERR_PTR(ret);
0097241
@@ -627,11 +655,60 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
0097241
 }
0097241
 
0097241
 static int
0097241
+__i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj,
0097241
+				      bool *active)
0097241
+{
0097241
+	struct get_pages_work *work;
0097241
+
0097241
+	/* Spawn a worker so that we can acquire the
0097241
+	 * user pages without holding our mutex. Access
0097241
+	 * to the user pages requires mmap_sem, and we have
0097241
+	 * a strict lock ordering of mmap_sem, struct_mutex -
0097241
+	 * we already hold struct_mutex here and so cannot
0097241
+	 * call gup without encountering a lock inversion.
0097241
+	 *
0097241
+	 * Userspace will keep on repeating the operation
0097241
+	 * (thanks to EAGAIN) until either we hit the fast
0097241
+	 * path or the worker completes. If the worker is
0097241
+	 * cancelled or superseded, the task is still run
0097241
+	 * but the results ignored. (This leads to
0097241
+	 * complications that we may have a stray object
0097241
+	 * refcount that we need to be wary of when
0097241
+	 * checking for existing objects during creation.)
0097241
+	 * If the worker encounters an error, it reports
0097241
+	 * that error back to this function through
0097241
+	 * obj->userptr.work = ERR_PTR.
0097241
+	 */
0097241
+	if (obj->userptr.workers >= I915_GEM_USERPTR_MAX_WORKERS)
0097241
+		return -EAGAIN;
0097241
+
0097241
+	work = kmalloc(sizeof(*work), GFP_KERNEL);
0097241
+	if (work == NULL)
0097241
+		return -ENOMEM;
0097241
+
0097241
+	obj->userptr.work = &work->work;
0097241
+	obj->userptr.workers++;
0097241
+
0097241
+	work->obj = obj;
0097241
+	drm_gem_object_reference(&obj->base);
0097241
+
0097241
+	work->task = current;
0097241
+	get_task_struct(work->task);
0097241
+
0097241
+	INIT_WORK(&work->work, __i915_gem_userptr_get_pages_worker);
0097241
+	schedule_work(&work->work);
0097241
+
0097241
+	*active = true;
0097241
+	return -EAGAIN;
0097241
+}
0097241
+
0097241
+static int
0097241
 i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
0097241
 {
0097241
 	const int num_pages = obj->base.size >> PAGE_SHIFT;
0097241
 	struct page **pvec;
0097241
 	int pinned, ret;
0097241
+	bool active;
0097241
 
0097241
 	/* If userspace should engineer that these pages are replaced in
0097241
 	 * the vma between us binding this page into the GTT and completion
0097241
@@ -649,6 +726,18 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
0097241
 	 * to the vma (discard or cloning) which should prevent the more
0097241
 	 * egregious cases from causing harm.
0097241
 	 */
0097241
+	if (IS_ERR(obj->userptr.work)) {
0097241
+		/* active flag will have been dropped already by the worker */
0097241
+		ret = PTR_ERR(obj->userptr.work);
0097241
+		obj->userptr.work = NULL;
0097241
+		return ret;
0097241
+	}
0097241
+	if (obj->userptr.work)
0097241
+		/* active flag should still be held for the pending work */
0097241
+		return -EAGAIN;
0097241
+
0097241
+	/* Let the mmu-notifier know that we have begun and need cancellation */
0097241
+	__i915_gem_userptr_set_active(obj, true);
0097241
 
0097241
 	pvec = NULL;
0097241
 	pinned = 0;
0097241
@@ -657,73 +746,27 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
0097241
 			       GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
0097241
 		if (pvec == NULL) {
0097241
 			pvec = drm_malloc_ab(num_pages, sizeof(struct page *));
0097241
-			if (pvec == NULL)
0097241
+			if (pvec == NULL) {
0097241
+				__i915_gem_userptr_set_active(obj, false);
0097241
 				return -ENOMEM;
0097241
+			}
0097241
 		}
0097241
 
0097241
 		pinned = __get_user_pages_fast(obj->userptr.ptr, num_pages,
0097241
 					       !obj->userptr.read_only, pvec);
0097241
 	}
0097241
-	if (pinned < num_pages) {
0097241
-		if (pinned < 0) {
0097241
-			ret = pinned;
0097241
-			pinned = 0;
0097241
-		} else {
0097241
-			/* Spawn a worker so that we can acquire the
0097241
-			 * user pages without holding our mutex. Access
0097241
-			 * to the user pages requires mmap_sem, and we have
0097241
-			 * a strict lock ordering of mmap_sem, struct_mutex -
0097241
-			 * we already hold struct_mutex here and so cannot
0097241
-			 * call gup without encountering a lock inversion.
0097241
-			 *
0097241
-			 * Userspace will keep on repeating the operation
0097241
-			 * (thanks to EAGAIN) until either we hit the fast
0097241
-			 * path or the worker completes. If the worker is
0097241
-			 * cancelled or superseded, the task is still run
0097241
-			 * but the results ignored. (This leads to
0097241
-			 * complications that we may have a stray object
0097241
-			 * refcount that we need to be wary of when
0097241
-			 * checking for existing objects during creation.)
0097241
-			 * If the worker encounters an error, it reports
0097241
-			 * that error back to this function through
0097241
-			 * obj->userptr.work = ERR_PTR.
0097241
-			 */
0097241
-			ret = -EAGAIN;
0097241
-			if (obj->userptr.work == NULL &&
0097241
-			    obj->userptr.workers < I915_GEM_USERPTR_MAX_WORKERS) {
0097241
-				struct get_pages_work *work;
0097241
-
0097241
-				work = kmalloc(sizeof(*work), GFP_KERNEL);
0097241
-				if (work != NULL) {
0097241
-					obj->userptr.work = &work->work;
0097241
-					obj->userptr.workers++;
0097241
-
0097241
-					work->obj = obj;
0097241
-					drm_gem_object_reference(&obj->base);
0097241
-
0097241
-					work->task = current;
0097241
-					get_task_struct(work->task);
0097241
-
0097241
-					INIT_WORK(&work->work, __i915_gem_userptr_get_pages_worker);
0097241
-					schedule_work(&work->work);
0097241
-				} else
0097241
-					ret = -ENOMEM;
0097241
-			} else {
0097241
-				if (IS_ERR(obj->userptr.work)) {
0097241
-					ret = PTR_ERR(obj->userptr.work);
0097241
-					obj->userptr.work = NULL;
0097241
-				}
0097241
-			}
0097241
-		}
0097241
-	} else {
0097241
+
0097241
+	active = false;
0097241
+	if (pinned < 0)
0097241
+		ret = pinned, pinned = 0;
0097241
+	else if (pinned < num_pages)
0097241
+		ret = __i915_gem_userptr_get_pages_schedule(obj, &active);
0097241
+	else
0097241
 		ret = __i915_gem_userptr_set_pages(obj, pvec, num_pages);
0097241
-		if (ret == 0) {
0097241
-			obj->userptr.work = NULL;
0097241
-			pinned = 0;
0097241
-		}
0097241
+	if (ret) {
0097241
+		__i915_gem_userptr_set_active(obj, active);
0097241
+		release_pages(pvec, pinned, 0);
0097241
 	}
0097241
-
0097241
-	release_pages(pvec, pinned, 0);
0097241
 	drm_free_large(pvec);
0097241
 	return ret;
0097241
 }
0097241
@@ -734,6 +777,7 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj)
0097241
 	struct sg_page_iter sg_iter;
0097241
 
0097241
 	BUG_ON(obj->userptr.work != NULL);
0097241
+	__i915_gem_userptr_set_active(obj, false);
0097241
 
0097241
 	if (obj->madv != I915_MADV_WILLNEED)
0097241
 		obj->dirty = 0;
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From d9cc6dc69e3a5f7f68e22227baf0e0f7743e448c Mon Sep 17 00:00:00 2001
0097241
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
0097241
Date: Thu, 22 Oct 2015 13:56:34 +0200
0097241
Subject: [PATCH 03/26] drm/i915/skl: Prevent unclaimed register writes on
0097241
 skylake.
0097241
0097241
Upstream commit b10f1b20171945b49988b2b1fe68cb312cc36d32
0097241
0097241
I'm getting unclaimed register writes when checking the WM registers
0097241
after the crtc is disabled. So I would imagine those are guarded by
0097241
the crtc power well. Fix this by not reading out wm state when the
0097241
power well is off.
0097241
0097241
Cc: stable@vger.kernel.org # v4.3
0097241
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
0097241
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92181
0097241
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_pm.c | 5 +++++
0097241
 1 file changed, 5 insertions(+)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
0097241
index ddbb7ed0a193..5e91e795fd99 100644
0097241
--- a/drivers/gpu/drm/i915/intel_pm.c
0097241
+++ b/drivers/gpu/drm/i915/intel_pm.c
0097241
@@ -2899,7 +2899,12 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
0097241
 	int plane;
0097241
 	u32 val;
0097241
 
0097241
+	memset(ddb, 0, sizeof(*ddb));
0097241
+
0097241
 	for_each_pipe(dev_priv, pipe) {
0097241
+		if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe)))
0097241
+			continue;
0097241
+
0097241
 		for_each_plane(dev_priv, pipe, plane) {
0097241
 			val = I915_READ(PLANE_BUF_CFG(pipe, plane));
0097241
 			skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane],
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 0ee1dd6b04a4e8eb34f948842fe4385c09695270 Mon Sep 17 00:00:00 2001
0097241
From: Jani Nikula <jani.nikula@intel.com>
0097241
Date: Fri, 30 Oct 2015 14:50:24 +0200
0097241
Subject: [PATCH 04/26] drm/i915: add quirk to enable backlight on Dell
0097241
 Chromebook 11 (2015)
0097241
0097241
Upstream commit 9be64eee3a87dc03218ca9a12834d1150a57b8a8
0097241
0097241
Reported-by: Keith Webb <khwebb@gmail.com>
0097241
Suggested-by: Keith Webb <khwebb@gmail.com>
0097241
Cc: stable@vger.kernel.org
0097241
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=106671
0097241
Reviewed-by: Clint Taylor <Clinton.A.Taylor@intel.com>
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1446209424-28801-1-git-send-email-jani.nikula@intel.com
0097241
---
0097241
 drivers/gpu/drm/i915/intel_display.c | 3 +++
0097241
 1 file changed, 3 insertions(+)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
0097241
index 1d2ff8e6fb4a..8f258092cada 100644
0097241
--- a/drivers/gpu/drm/i915/intel_display.c
0097241
+++ b/drivers/gpu/drm/i915/intel_display.c
0097241
@@ -14678,6 +14678,9 @@ static struct intel_quirk intel_quirks[] = {
0097241
 
0097241
 	/* Dell Chromebook 11 */
0097241
 	{ 0x0a06, 0x1028, 0x0a35, quirk_backlight_present },
0097241
+
0097241
+	/* Dell Chromebook 11 (2015 version) */
0097241
+	{ 0x0a16, 0x1028, 0x0a35, quirk_backlight_present },
0097241
 };
0097241
 
0097241
 static void intel_init_quirks(struct drm_device *dev)
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 06d7e7fe18b63244ec4e6e633fc40dd5bea39099 Mon Sep 17 00:00:00 2001
0097241
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
0097241
Date: Tue, 3 Nov 2015 08:31:41 +0100
0097241
Subject: [PATCH 05/26] drm/i915: Extend DSL readout fix to BDW and SKL.
0097241
MIME-Version: 1.0
0097241
Content-Type: text/plain; charset=UTF-8
0097241
Content-Transfer-Encoding: 8bit
0097241
0097241
Upstream commit b291681926a142958112eedde62823230d6afb84
0097241
0097241
Those platforms have the same bug as haswell, and the same fix applies
0097241
to them.
0097241
0097241
The original HSW fix that this extends is
0097241
0097241
commit 41b578fb0e8b930f2470d3f673b0fa279e77a7b8
0097241
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
0097241
Date:   Tue Sep 22 12:15:54 2015 -0700
0097241
0097241
    drm/i915: workaround bad DSL readout v3
0097241
0097241
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
0097241
Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
0097241
Cc: stable@vger.kernel.org # v4.3
0097241
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91579
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1446535913-31970-3-git-send-email-maarten.lankhorst@linux.intel.com
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/i915_irq.c | 2 +-
0097241
 1 file changed, 1 insertion(+), 1 deletion(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
0097241
index fa7f82d54762..d83d12eeb3fe 100644
0097241
--- a/drivers/gpu/drm/i915/i915_irq.c
0097241
+++ b/drivers/gpu/drm/i915/i915_irq.c
0097241
@@ -651,7 +651,7 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
0097241
 	 * problem.  We may need to extend this to include other platforms,
0097241
 	 * but so far testing only shows the problem on HSW.
0097241
 	 */
0097241
-	if (IS_HASWELL(dev) && !position) {
0097241
+	if (HAS_DDI(dev) && !position) {
0097241
 		int i, temp;
0097241
 
0097241
 		for (i = 0; i < 100; i++) {
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From f5268273f194155f0a5f3cbfa7bf271774a7a9d6 Mon Sep 17 00:00:00 2001
0097241
From: Jani Nikula <jani.nikula@intel.com>
0097241
Date: Thu, 5 Nov 2015 11:49:59 +0200
0097241
Subject: [PATCH 06/26] drm/i915: quirk backlight present on Macbook 4, 1
0097241
0097241
Upstream commit 1b9448b071caa7d10bb2569fabe3020a2c25ae59
0097241
0097241
Unsurprisingly macbooks have backlights, just the VBT doesn't seem to
0097241
know it in this case.
0097241
0097241
Reported-and-tested-by: Daniel Nicoletti <dantti12@gmail.com>
0097241
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88325
0097241
Fixes: c675949ec58c ("drm/i915: do not setup backlight if not available according to VBT")
0097241
Cc: stable@vger.kernel.org # v3.15+
0097241
Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1446716999-1796-1-git-send-email-jani.nikula@intel.com
0097241
---
0097241
 drivers/gpu/drm/i915/intel_display.c | 3 +++
0097241
 1 file changed, 3 insertions(+)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
0097241
index 8f258092cada..2e348788ecaa 100644
0097241
--- a/drivers/gpu/drm/i915/intel_display.c
0097241
+++ b/drivers/gpu/drm/i915/intel_display.c
0097241
@@ -14670,6 +14670,9 @@ static struct intel_quirk intel_quirks[] = {
0097241
 	/* Apple Macbook 2,1 (Core 2 T7400) */
0097241
 	{ 0x27a2, 0x8086, 0x7270, quirk_backlight_present },
0097241
 
0097241
+	/* Apple Macbook 4,1 */
0097241
+	{ 0x2a02, 0x106b, 0x00a1, quirk_backlight_present },
0097241
+
0097241
 	/* Toshiba CB35 Chromebook (Celeron 2955U) */
0097241
 	{ 0x0a06, 0x1179, 0x0a88, quirk_backlight_present },
0097241
 
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From dddd84b8b5f7f8c0b0037a1bb53f81f5bc70115b Mon Sep 17 00:00:00 2001
0097241
From: Imre Deak <imre.deak@intel.com>
0097241
Date: Wed, 4 Nov 2015 21:25:32 +0200
0097241
Subject: [PATCH 07/26] drm/i915: get runtime PM reference around GEM
0097241
 set_caching IOCTL
0097241
0097241
Upstream commit fd0fe6acf1dd88aabfbf383f7e4c16315387a7b7
0097241
0097241
After Damien's D3 fix I started to get runtime suspend residency for the
0097241
first time and that revealed a breakage on the set_caching IOCTL path
0097241
that accesses the HW but doesn't take an RPM ref. Fix this up.
0097241
0097241
Signed-off-by: Imre Deak <imre.deak@intel.com>
0097241
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
0097241
Cc: stable@vger.kernel.org
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1446665132-22491-1-git-send-email-imre.deak@intel.com
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/i915_gem.c | 8 +++++++-
0097241
 1 file changed, 7 insertions(+), 1 deletion(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
0097241
index 4d631a946481..dee065c2b6d8 100644
0097241
--- a/drivers/gpu/drm/i915/i915_gem.c
0097241
+++ b/drivers/gpu/drm/i915/i915_gem.c
0097241
@@ -3728,6 +3728,7 @@ int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
0097241
 int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
0097241
 			       struct drm_file *file)
0097241
 {
0097241
+	struct drm_i915_private *dev_priv = dev->dev_private;
0097241
 	struct drm_i915_gem_caching *args = data;
0097241
 	struct drm_i915_gem_object *obj;
0097241
 	enum i915_cache_level level;
0097241
@@ -3747,9 +3748,11 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
0097241
 		return -EINVAL;
0097241
 	}
0097241
 
0097241
+	intel_runtime_pm_get(dev_priv);
0097241
+
0097241
 	ret = i915_mutex_lock_interruptible(dev);
0097241
 	if (ret)
0097241
-		return ret;
0097241
+		goto rpm_put;
0097241
 
0097241
 	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
0097241
 	if (&obj->base == NULL) {
0097241
@@ -3762,6 +3765,9 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
0097241
 	drm_gem_object_unreference(&obj->base);
0097241
 unlock:
0097241
 	mutex_unlock(&dev->struct_mutex);
0097241
+rpm_put:
0097241
+	intel_runtime_pm_put(dev_priv);
0097241
+
0097241
 	return ret;
0097241
 }
0097241
 
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From df79b28d6a73835c70222506405bdb54774395c9 Mon Sep 17 00:00:00 2001
0097241
From: Maarten Lankhorst <maarten@mblankhorst.nl>
0097241
Date: Mon, 16 Nov 2015 12:49:14 +0100
0097241
Subject: [PATCH 08/26] drm/i915: Clear intel_crtc->atomic before updating it.
0097241
MIME-Version: 1.0
0097241
Content-Type: text/plain; charset=UTF-8
0097241
Content-Transfer-Encoding: 8bit
0097241
0097241
Upstream commit ba8af3e592f7175b5f9a92d2cfcc00b82097d1be
0097241
0097241
If an atomic update fails intel_crtc->atomic may have have some values left
0097241
from the last atomic check. One example is atomic->wait_for_vblank,
0097241
which results in spurious errors in kms_flip.
0097241
0097241
[ 1551.892708] ------------[ cut here ]------------
0097241
[ 1551.892721] WARNING: CPU: 3 PID: 4179 at ../drivers/gpu/drm/drm_irq.c:1199 drm_wait_one_vblank+0x197/0x1a0 [drm]()
0097241
[ 1551.892722] vblank not available on crtc 2, ret=-22
0097241
[ 1551.892751] Modules linked in: snd_hda_intel i915 drm_kms_helper drm
0097241
intel_gtt i2c_algo_bit cfbfillrect syscopyarea cfbimgblt sysfillrect
0097241
sysimgblt fb_sys_fops cfbcopyarea agpgart cfg80211 binfmt_misc
0097241
snd_hda_codec_hdmi intel_rapl iosf_mbi x86_pkg_temp_thermal coretemp
0097241
kvm_intel snd_hda_codec_realtek kvm snd_hda_codec_generic iTCO_wdt
0097241
aesni_intel aes_x86_64 glue_helper lrw snd_hda_codec gf128mul
0097241
ablk_helper cryptd snd_hwdep psmouse snd_hda_core pcspkr snd_pcm
0097241
snd_timer snd lpc_ich i2c_i801 mfd_core soundcore wmi evdev [last
0097241
unloaded: drm]
0097241
[ 1551.892753] CPU: 3 PID: 4179 Comm: kms_pipe_crc_ba Tainted: G     U  W       4.3.0-reg+ #6
0097241
[ 1551.892754] Hardware name:                  /DZ77BH-55K, BIOS BHZ7710H.86A.0100.2013.0517.0942 05/17/2013
0097241
[ 1551.892758]  ffffffffa03128d8 ffff8800cec73890 ffffffff812c0f3c ffff8800cec738d8
0097241
[ 1551.892760]  ffff8800cec738c8 ffffffff8104ff36 ffff880116ae2290 0000000000000002
0097241
[ 1551.892762]  ffff8800d39fcda0 ffff8800d038b4d0 ffff8800d42b5550 ffff8800cec73928
0097241
[ 1551.892763] Call Trace:
0097241
[ 1551.892768]  [<ffffffff812c0f3c>] dump_stack+0x4e/0x82
0097241
[ 1551.892771]  [<ffffffff8104ff36>] warn_slowpath_common+0x86/0xc0
0097241
[ 1551.892773]  [<ffffffff8104ffbc>] warn_slowpath_fmt+0x4c/0x50
0097241
[ 1551.892781]  [<ffffffffa02e6708>] ? drm_vblank_get+0x78/0xd0 [drm]
0097241
[ 1551.892787]  [<ffffffffa02e6d47>] drm_wait_one_vblank+0x197/0x1a0 [drm]
0097241
[ 1551.892813]  [<ffffffffa03d052f>] intel_post_plane_update+0xef/0x120 [i915]
0097241
[ 1551.892832]  [<ffffffffa03d11d2>] intel_atomic_commit+0x4c2/0x1600 [i915]
0097241
[ 1551.892862]  [<ffffffffa02ff0c7>] ? drm_atomic_check_only+0x147/0x5e0 [drm]
0097241
[ 1551.892872]  [<ffffffffa02feeb7>] ? drm_atomic_add_affected_connectors+0x27/0xf0 [drm]
0097241
[ 1551.892881]  [<ffffffffa02ff597>] drm_atomic_commit+0x37/0x60 [drm]
0097241
[ 1551.892887]  [<ffffffffa034301a>] restore_fbdev_mode+0x28a/0x2c0 [drm_kms_helper]
0097241
[ 1551.892895]  [<ffffffffa0345253>] drm_fb_helper_restore_fbdev_mode_unlocked+0x33/0x80 [drm_kms_helper]
0097241
[ 1551.892900]  [<ffffffffa03452cd>] drm_fb_helper_set_par+0x2d/0x50 [drm_kms_helper]
0097241
[ 1551.892920]  [<ffffffffa03e7a9a>] intel_fbdev_set_par+0x1a/0x60 [i915]
0097241
[ 1551.892923]  [<ffffffff8131a5a7>] fb_set_var+0x1a7/0x3f0
0097241
[ 1551.892927]  [<ffffffff8109732f>] ? trace_hardirqs_on_caller+0x12f/0x1c0
0097241
[ 1551.892931]  [<ffffffff81314f32>] fbcon_blank+0x212/0x2f0
0097241
[ 1551.892935]  [<ffffffff81373f4a>] do_unblank_screen+0xba/0x1d0
0097241
[ 1551.892937]  [<ffffffff8136b725>] vt_ioctl+0x13d5/0x1450
0097241
[ 1551.892940]  [<ffffffff8107cdd1>] ? preempt_count_sub+0x41/0x50
0097241
[ 1551.892943]  [<ffffffff8135d8a3>] tty_ioctl+0x423/0xe30
0097241
[ 1551.892947]  [<ffffffff8119f721>] do_vfs_ioctl+0x301/0x560
0097241
[ 1551.892949]  [<ffffffff8119b1e3>] ? putname+0x53/0x60
0097241
[ 1551.892952]  [<ffffffff811ab376>] ? __fget_light+0x66/0x90
0097241
[ 1551.892955]  [<ffffffff8119f9f9>] SyS_ioctl+0x79/0x90
0097241
[ 1551.892958]  [<ffffffff81552e97>] entry_SYSCALL_64_fastpath+0x12/0x6f
0097241
[ 1551.892961] ---[ end trace 3e764d4b6628c91c ]---
0097241
0097241
Testcase: kms_flip
0097241
Reported-and-tested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
0097241
Cc: stable@vger.kernel.org #v4.3
0097241
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
0097241
Reviewed-by: Daniel Stone <daniels@collabora.com>
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/5649C2BA.6080300@mblankhorst.nl
0097241
---
0097241
 drivers/gpu/drm/i915/intel_display.c | 3 +++
0097241
 1 file changed, 3 insertions(+)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
0097241
index 2e348788ecaa..7e13bea3b4d5 100644
0097241
--- a/drivers/gpu/drm/i915/intel_display.c
0097241
+++ b/drivers/gpu/drm/i915/intel_display.c
0097241
@@ -13005,6 +13005,9 @@ static int intel_atomic_check(struct drm_device *dev,
0097241
 		struct intel_crtc_state *pipe_config =
0097241
 			to_intel_crtc_state(crtc_state);
0097241
 
0097241
+		memset(&to_intel_crtc(crtc)->atomic, 0,
0097241
+		       sizeof(struct intel_crtc_atomic_commit));
0097241
+
0097241
 		/* Catch I915_MODE_FLAG_INHERITED */
0097241
 		if (crtc_state->mode.private_flags != crtc->state->mode.private_flags)
0097241
 			crtc_state->mode_changed = true;
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From eb02e7a4b15ec47b50fd7447471ac3bb75cce53f Mon Sep 17 00:00:00 2001
0097241
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
0097241
Date: Wed, 11 Nov 2015 19:11:28 +0200
0097241
Subject: [PATCH 09/26] drm/i915: Don't clobber the addfb2 ioctl params
0097241
MIME-Version: 1.0
0097241
Content-Type: text/plain; charset=UTF-8
0097241
Content-Transfer-Encoding: 8bit
0097241
0097241
Upstream commit 76dc3769d7c3cdcfa7c4c7768a7cb87cd91af12f
0097241
0097241
We try to convert the old way of of specifying fb tiling (obj->tiling)
0097241
into the new fb modifiers. We store the result in the passed in mode_cmd
0097241
structure. But that structure comes directly from the addfb2 ioctl, and
0097241
gets copied back out to userspace, which means we're clobbering the
0097241
modifiers that the user provided (all 0 since the DRM_MODE_FB_MODIFIERS
0097241
flag wasn't even set by the user). Hence if the user reuses the struct
0097241
for another addfb2, the ioctl will be rejected since it's now asking for
0097241
some modifiers w/o the flag set.
0097241
0097241
Fix the problem by making a copy of the user provided structure. We can
0097241
play any games we want with the copy.
0097241
0097241
IGT-Version: 1.12-git (x86_64) (Linux: 4.4.0-rc1-stereo+ x86_64)
0097241
...
0097241
Subtest basic-X-tiled: SUCCESS (0.001s)
0097241
Test assertion failure function pitch_tests, file kms_addfb_basic.c:167:
0097241
Failed assertion: drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0
0097241
Last errno: 22, Invalid argument
0097241
Stack trace:
0097241
  #0 [__igt_fail_assert+0x101]
0097241
  #1 [pitch_tests+0x619]
0097241
  #2 [__real_main426+0x2f]
0097241
  #3 [main+0x23]
0097241
  #4 [__libc_start_main+0xf0]
0097241
  #5 [_start+0x29]
0097241
  #6 [<unknown>+0x29]
0097241
  Subtest framebuffer-vs-set-tiling failed.
0097241
  **** DEBUG ****
0097241
  Test assertion failure function pitch_tests, file kms_addfb_basic.c:167:
0097241
  Failed assertion: drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0
0097241
  Last errno: 22, Invalid argument
0097241
  ****  END  ****
0097241
  Subtest framebuffer-vs-set-tiling: FAIL (0.003s)
0097241
  ...
0097241
0097241
IGT-Version: 1.12-git (x86_64) (Linux: 4.4.0-rc1-stereo+ x86_64)
0097241
Subtest framebuffer-vs-set-tiling: SUCCESS (0.000s)
0097241
0097241
Cc: stable@vger.kernel.org # v4.1+
0097241
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
0097241
Fixes: 2a80eada326f ("drm/i915: Add fb format modifier support")
0097241
Testcase: igt/kms_addfb_basic/clobbered-modifier
0097241
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
0097241
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1447261890-3960-1-git-send-email-ville.syrjala@linux.intel.com
0097241
---
0097241
 drivers/gpu/drm/i915/intel_display.c | 7 ++++---
0097241
 1 file changed, 4 insertions(+), 3 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
0097241
index 7e13bea3b4d5..d07d98aeb72c 100644
0097241
--- a/drivers/gpu/drm/i915/intel_display.c
0097241
+++ b/drivers/gpu/drm/i915/intel_display.c
0097241
@@ -14330,16 +14330,17 @@ static int intel_framebuffer_init(struct drm_device *dev,
0097241
 static struct drm_framebuffer *
0097241
 intel_user_framebuffer_create(struct drm_device *dev,
0097241
 			      struct drm_file *filp,
0097241
-			      struct drm_mode_fb_cmd2 *mode_cmd)
0097241
+			      struct drm_mode_fb_cmd2 *user_mode_cmd)
0097241
 {
0097241
 	struct drm_i915_gem_object *obj;
0097241
+	struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd;
0097241
 
0097241
 	obj = to_intel_bo(drm_gem_object_lookup(dev, filp,
0097241
-						mode_cmd->handles[0]));
0097241
+						mode_cmd.handles[0]));
0097241
 	if (&obj->base == NULL)
0097241
 		return ERR_PTR(-ENOENT);
0097241
 
0097241
-	return intel_framebuffer_create(dev, mode_cmd, obj);
0097241
+	return intel_framebuffer_create(dev, &mode_cmd, obj);
0097241
 }
0097241
 
0097241
 #ifndef CONFIG_DRM_FBDEV_EMULATION
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 687b4f4810c6a23420994e9cf4bb2d420a80217d Mon Sep 17 00:00:00 2001
0097241
From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
0097241
Date: Tue, 17 Nov 2015 18:14:26 +0200
0097241
Subject: [PATCH 10/26] drm/i915: Fix gpu frequency change tracing
0097241
MIME-Version: 1.0
0097241
Content-Type: text/plain; charset=UTF-8
0097241
Content-Transfer-Encoding: 8bit
0097241
0097241
Upstream commit 0f94592efd36213c961145fe1ab0c3bc323ec053
0097241
0097241
With gen < 9 we have had always 50Mhz units as our hw
0097241
ratio. With gen >= 9 the hw ratio changed to 16.667Mhz (50/3).
0097241
The result was that our gpu frequency tracing started to output
0097241
values 3 times larger than expected due to hardcoded scaling
0097241
value. Fix this by using  Use intel_gpu_freq() when generating Mhz
0097241
value from ratio for 'intel_gpu_freq_change' trace event.
0097241
0097241
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92591
0097241
Cc: stable@vger.kernel.org # v4.3+
0097241
Reported-by: Eero Tamminen <eero.t.tamminen@intel.com>
0097241
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
0097241
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1447776866-29384-1-git-send-email-mika.kuoppala@intel.com
0097241
---
0097241
 drivers/gpu/drm/i915/intel_pm.c | 2 +-
0097241
 1 file changed, 1 insertion(+), 1 deletion(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
0097241
index 5e91e795fd99..2a689522cd89 100644
0097241
--- a/drivers/gpu/drm/i915/intel_pm.c
0097241
+++ b/drivers/gpu/drm/i915/intel_pm.c
0097241
@@ -4503,7 +4503,7 @@ static void gen6_set_rps(struct drm_device *dev, u8 val)
0097241
 	POSTING_READ(GEN6_RPNSWREQ);
0097241
 
0097241
 	dev_priv->rps.cur_freq = val;
0097241
-	trace_intel_gpu_freq_change(val * 50);
0097241
+	trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
0097241
 }
0097241
 
0097241
 static void valleyview_set_rps(struct drm_device *dev, u8 val)
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From efee83c75bf454e745ebaddd96b9fe741c706317 Mon Sep 17 00:00:00 2001
0097241
From: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Date: Thu, 19 Nov 2015 09:58:05 +0000
0097241
Subject: [PATCH 11/26] drm/i915: Mark uneven memory banks on gen4 desktop as
0097241
 unknown swizzling
0097241
MIME-Version: 1.0
0097241
Content-Type: text/plain; charset=UTF-8
0097241
Content-Transfer-Encoding: 8bit
0097241
0097241
Upstream commit 0b466dc238cb660bbdb9ef6e121e1757057484c3
0097241
0097241
We have varied reports of swizzling corruption on gen4 desktop, and
0097241
confirmation that one at least is triggered by uneven memory banks
0097241
(L-shaped memory). The implication is that the swizzling varies between
0097241
the paired channels and the remainder of memory on the single channel. As
0097241
the object then has unpredictable swizzling (it will vary depending on
0097241
exact page allocation and may even change during the object's lifetime as
0097241
the pages are replaced), we have to report to userspace that the swizzling
0097241
is unknown.
0097241
0097241
However, some existing userspace is buggy when it meets an unknown
0097241
swizzling configuration and so we need to tell another white lie and
0097241
mark the swizzling as NONE but report it as UNKNOWN through the extended
0097241
get-tiling-ioctl. See
0097241
0097241
commit 5eb3e5a5e11d14f9deb2a4b83555443b69ab9940
0097241
Author: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Date:   Sun Jun 28 09:19:26 2015 +0100
0097241
0097241
    drm/i915: Declare the swizzling unknown for L-shaped configurations
0097241
0097241
for the previous example where we found that telling the truth to
0097241
userspace just ends up in a world of hurt.
0097241
0097241
Also since we don't truly know what the swizzling is on the pages, we
0097241
need to keep them pinned to prevent swapping as the reports also
0097241
suggest that some gen4 devices have previously undetected bit17
0097241
swizzling.
0097241
0097241
v2: Combine unknown + quirk patches to prevent userspace ever seeing
0097241
unknown swizzling through the normal get-tiling-ioctl. Also use the same
0097241
path for the existing uneven bank detection for mobile gen4.
0097241
0097241
Reported-by: Matti Hämäläinen <ccr@tnsp.org>
0097241
Tested-by: Matti Hämäläinen <ccr@tnsp.org>
0097241
References: https://bugs.freedesktop.org/show_bug.cgi?id=90725
0097241
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Cc: Matti Hämäläinen <ccr@tnsp.org>
0097241
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Cc: Jani Nikula <jani.nikula@intel.com>
0097241
Cc: stable@vger.kernel.org
0097241
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1447927085-31726-1-git-send-email-chris@chris-wilson.co.uk
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/i915_gem_fence.c | 36 ++++++++++++++++++++++++++---------
0097241
 1 file changed, 27 insertions(+), 9 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
0097241
index af1f8c461060..716c3d8f027c 100644
0097241
--- a/drivers/gpu/drm/i915/i915_gem_fence.c
0097241
+++ b/drivers/gpu/drm/i915/i915_gem_fence.c
0097241
@@ -647,11 +647,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
0097241
 		}
0097241
 
0097241
 		/* check for L-shaped memory aka modified enhanced addressing */
0097241
-		if (IS_GEN4(dev)) {
0097241
-			uint32_t ddc2 = I915_READ(DCC2);
0097241
-
0097241
-			if (!(ddc2 & DCC2_MODIFIED_ENHANCED_DISABLE))
0097241
-				dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
0097241
+		if (IS_GEN4(dev) &&
0097241
+		    !(I915_READ(DCC2) & DCC2_MODIFIED_ENHANCED_DISABLE)) {
0097241
+			swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
0097241
+			swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
0097241
 		}
0097241
 
0097241
 		if (dcc == 0xffffffff) {
0097241
@@ -680,16 +679,35 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
0097241
 		 * matching, which was the case for the swizzling required in
0097241
 		 * the table above, or from the 1-ch value being less than
0097241
 		 * the minimum size of a rank.
0097241
+		 *
0097241
+		 * Reports indicate that the swizzling actually
0097241
+		 * varies depending upon page placement inside the
0097241
+		 * channels, i.e. we see swizzled pages where the
0097241
+		 * banks of memory are paired and unswizzled on the
0097241
+		 * uneven portion, so leave that as unknown.
0097241
 		 */
0097241
-		if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) {
0097241
-			swizzle_x = I915_BIT_6_SWIZZLE_NONE;
0097241
-			swizzle_y = I915_BIT_6_SWIZZLE_NONE;
0097241
-		} else {
0097241
+		if (I915_READ16(C0DRB3) == I915_READ16(C1DRB3)) {
0097241
 			swizzle_x = I915_BIT_6_SWIZZLE_9_10;
0097241
 			swizzle_y = I915_BIT_6_SWIZZLE_9;
0097241
 		}
0097241
 	}
0097241
 
0097241
+	if (swizzle_x == I915_BIT_6_SWIZZLE_UNKNOWN ||
0097241
+	    swizzle_y == I915_BIT_6_SWIZZLE_UNKNOWN) {
0097241
+		/* Userspace likes to explode if it sees unknown swizzling,
0097241
+		 * so lie. We will finish the lie when reporting through
0097241
+		 * the get-tiling-ioctl by reporting the physical swizzle
0097241
+		 * mode as unknown instead.
0097241
+		 *
0097241
+		 * As we don't strictly know what the swizzling is, it may be
0097241
+		 * bit17 dependent, and so we need to also prevent the pages
0097241
+		 * from being moved.
0097241
+		 */
0097241
+		dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
0097241
+		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
0097241
+		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
0097241
+	}
0097241
+
0097241
 	dev_priv->mm.bit_6_swizzle_x = swizzle_x;
0097241
 	dev_priv->mm.bit_6_swizzle_y = swizzle_y;
0097241
 }
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From b9aa6e409916793c7b2c6302df80f9a8c36ddcf2 Mon Sep 17 00:00:00 2001
0097241
From: Takashi Iwai <tiwai@suse.de>
0097241
Date: Wed, 25 Nov 2015 15:26:47 +0100
0097241
Subject: [PATCH 12/26] drm/i915: Don't compare has_drrs strictly in pipe
0097241
 config
0097241
0097241
Upstream commit 13b13dfaaa39ab52b0f433c6744f4638793cbf7b
0097241
0097241
The commit [cfb23ed622d0: drm/i915: Allow fuzzy matching in
0097241
pipe_config_compare, v2] relaxed the way to compare the pipe
0097241
configurations, but one new comparison sneaked in there: it added the
0097241
strict has_drrs value check.  This causes a regression on many
0097241
machines, typically HP laptops with a docking port, where the kernel
0097241
spews warnings and eventually fails to set the mode properly like:
0097241
 [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in has_drrs (expected 1, found 0)
0097241
 ------------[ cut here ]------------
0097241
 WARNING: CPU: 0 PID: 79 at drivers/gpu/drm/i915/intel_display.c:12700 intel_modeset_check_state+0x5aa/0x870 [i915]()
0097241
 pipe state doesn't match!
0097241
 ....
0097241
0097241
This patch just removes the check again for fixing the regression.
0097241
0097241
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=104041
0097241
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92456
0097241
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=956397
0097241
Fixes: cfb23ed622d0 ('drm/i915: Allow fuzzy matching in pipe_config_compare, v2')
0097241
Cc: <stable@vger.kernel.org> # v4.3+
0097241
Reported-and-tested-by: Max Lin <mlin@suse.com>
0097241
Signed-off-by: Takashi Iwai <tiwai@suse.de>
0097241
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1448461607-16868-1-git-send-email-tiwai@suse.de
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_display.c | 1 -
0097241
 1 file changed, 1 deletion(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
0097241
index d07d98aeb72c..58e08fb47d1f 100644
0097241
--- a/drivers/gpu/drm/i915/intel_display.c
0097241
+++ b/drivers/gpu/drm/i915/intel_display.c
0097241
@@ -12427,7 +12427,6 @@ intel_pipe_config_compare(struct drm_device *dev,
0097241
 	if (INTEL_INFO(dev)->gen < 8) {
0097241
 		PIPE_CONF_CHECK_M_N(dp_m_n);
0097241
 
0097241
-		PIPE_CONF_CHECK_I(has_drrs);
0097241
 		if (current_config->has_drrs)
0097241
 			PIPE_CONF_CHECK_M_N(dp_m2_n2);
0097241
 	} else
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 17e09098ed89ccc44a9420b0eee361b2e4f1f58c Mon Sep 17 00:00:00 2001
0097241
From: Takashi Iwai <tiwai@suse.de>
0097241
Date: Thu, 19 Nov 2015 12:09:56 +0100
0097241
Subject: [PATCH 13/26] drm/i915: Don't override output type for DDI HDMI
0097241
0097241
Upstream commit 2540058f7a9d9a843b4d9a28d4f8168dd034d030
0097241
0097241
Currently a DDI port may register the DP hotplug handler even though
0097241
it's used with HDMI, and the DP HPD handler overrides the encoder
0097241
type forcibly to DP.  This caused the inconsistency on a machine
0097241
connected with a HDMI monitor; upon a hotplug event, the DDI port is
0097241
suddenly switched to be handled as a DP although the same monitor is
0097241
kept connected, and this leads to the erroneous blank output.
0097241
0097241
This patch papers over the bug by excluding the previous HDMI encoder
0097241
type from this override.  This should be fixed more fundamentally,
0097241
e.g. by moving the encoder type reset from the HPD or by having
0097241
individual encoder objects for HDMI and DP.  But since the bug has
0097241
been present for a long time (3.17), it's better to have a
0097241
quick-n-dirty fix for now, and keep working on a cleaner fix.
0097241
0097241
Bugzilla: http://bugzilla.opensuse.org/show_bug.cgi?id=955190
0097241
Fixes: 0e32b39ceed6 ('drm/i915: add DP 1.2 MST support (v0.7)')
0097241
Cc: <stable@vger.kernel.org> # v3.17+
0097241
Signed-off-by: Takashi Iwai <tiwai@suse.de>
0097241
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1447931396-19147-1-git-send-email-tiwai@suse.de
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_dp.c | 3 ++-
0097241
 1 file changed, 2 insertions(+), 1 deletion(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
0097241
index 0a2e33fbf20d..a7b7a64d8d27 100644
0097241
--- a/drivers/gpu/drm/i915/intel_dp.c
0097241
+++ b/drivers/gpu/drm/i915/intel_dp.c
0097241
@@ -4921,7 +4921,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
0097241
 	enum intel_display_power_domain power_domain;
0097241
 	enum irqreturn ret = IRQ_NONE;
0097241
 
0097241
-	if (intel_dig_port->base.type != INTEL_OUTPUT_EDP)
0097241
+	if (intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
0097241
+	    intel_dig_port->base.type != INTEL_OUTPUT_HDMI)
0097241
 		intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
0097241
 
0097241
 	if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) {
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 5cbff55f4355dc1cec8124c8741fdfd98f644c73 Mon Sep 17 00:00:00 2001
0097241
From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Date: Sat, 12 Sep 2015 10:17:50 +0530
0097241
Subject: [PATCH 14/26] drm/i915: Add IS_SKL_GT3 and IS_SKL_GT4 macro.
0097241
0097241
Upstream commit 7a58bad0e63295dfa803973efcebc80cb730c7bd
0097241
0097241
It will be usefull to specify w/a that affects only SKL GT3 and GT4.
0097241
0097241
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Reviewed-by: Alex Dai <yu.dai@intel.com>
0097241
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
---
0097241
 drivers/gpu/drm/i915/i915_drv.h | 5 +++++
0097241
 1 file changed, 5 insertions(+)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
0097241
index e1db8de52851..3c16f6237251 100644
0097241
--- a/drivers/gpu/drm/i915/i915_drv.h
0097241
+++ b/drivers/gpu/drm/i915/i915_drv.h
0097241
@@ -2475,6 +2475,11 @@ struct drm_i915_cmd_table {
0097241
 #define IS_SKL_ULX(dev)		(INTEL_DEVID(dev) == 0x190E || \
0097241
 				 INTEL_DEVID(dev) == 0x1915 || \
0097241
 				 INTEL_DEVID(dev) == 0x191E)
0097241
+#define IS_SKL_GT3(dev)		(IS_SKYLAKE(dev) && \
0097241
+				 (INTEL_DEVID(dev) & 0x00F0) == 0x0020)
0097241
+#define IS_SKL_GT4(dev)		(IS_SKYLAKE(dev) && \
0097241
+				 (INTEL_DEVID(dev) & 0x00F0) == 0x0030)
0097241
+
0097241
 #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
0097241
 
0097241
 #define SKL_REVID_A0		(0x0)
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From baed978880f2c32e82587cc514227aad82daecd5 Mon Sep 17 00:00:00 2001
0097241
From: Arun Siluvery <arun.siluvery@linux.intel.com>
0097241
Date: Fri, 18 Sep 2015 17:52:47 +0100
0097241
Subject: [PATCH 15/26] drm/i915/bxt: Update revision id for BXT C0
0097241
0097241
Upstream commit 5ca4163a612068d8f942c454218d3d631f22af1b
0097241
0097241
Cc: Nick Hoath <nicholas.hoath@intel.com>
0097241
Cc: Imre Deak <imre.deak@intel.com>
0097241
Signed-off-by: Arun Siluvery <arun.siluvery@linux.intel.com>
0097241
Reviewed-by: Imre Deak <imre.deak@intel.com>
0097241
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
---
0097241
 drivers/gpu/drm/i915/i915_drv.h | 2 +-
0097241
 1 file changed, 1 insertion(+), 1 deletion(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
0097241
index 3c16f6237251..475b03e9d584 100644
0097241
--- a/drivers/gpu/drm/i915/i915_drv.h
0097241
+++ b/drivers/gpu/drm/i915/i915_drv.h
0097241
@@ -2491,7 +2491,7 @@ struct drm_i915_cmd_table {
0097241
 
0097241
 #define BXT_REVID_A0		(0x0)
0097241
 #define BXT_REVID_B0		(0x3)
0097241
-#define BXT_REVID_C0		(0x6)
0097241
+#define BXT_REVID_C0		(0x9)
0097241
 
0097241
 /*
0097241
  * The genX designation typically refers to the render engine, so render
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From c80bd95bfeb85ce970c5f7711718a274e4b38b55 Mon Sep 17 00:00:00 2001
0097241
From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Date: Sat, 12 Sep 2015 10:17:51 +0530
0097241
Subject: [PATCH 16/26] drm/i915: WaRsDisableCoarsePowerGating
0097241
0097241
Upstream commit f2d2fe95072acd5404f8051b8bf1195c61a47fb5
0097241
0097241
WaRsDisableCoarsePowerGating: Coarse Power Gating (CPG) needs to be
0097241
disabled for platforms prior to BXT B0 and SKL GT3/GT4 till E0.
0097241
0097241
v2: Added GT3/GT4 Check.
0097241
0097241
Change-Id: Ia3c4c16e050c88d3e259f601054875c812d69c3a
0097241
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Reviewed-by: Alex Dai <yu.dai@intel.com>
0097241
[danvet: Align continuation properly.]
0097241
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_pm.c | 11 +++++++----
0097241
 1 file changed, 7 insertions(+), 4 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
0097241
index 2a689522cd89..56a5568ffeb7 100644
0097241
--- a/drivers/gpu/drm/i915/intel_pm.c
0097241
+++ b/drivers/gpu/drm/i915/intel_pm.c
0097241
@@ -4851,11 +4851,14 @@ static void gen9_enable_rc6(struct drm_device *dev)
0097241
 
0097241
 	/*
0097241
 	 * 3b: Enable Coarse Power Gating only when RC6 is enabled.
0097241
-	 * WaDisableRenderPowerGating:skl,bxt - Render PG need to be disabled with RC6.
0097241
+	 * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6.
0097241
 	 */
0097241
-	I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
0097241
-			GEN9_MEDIA_PG_ENABLE : 0);
0097241
-
0097241
+	if ((IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) ||
0097241
+	    ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_E0)))
0097241
+		I915_WRITE(GEN9_PG_ENABLE, 0);
0097241
+	else
0097241
+		I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
0097241
+				(GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE) : 0);
0097241
 
0097241
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
0097241
 
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From c6b1dd5d44c09a9c0032066415ccf8539efb5856 Mon Sep 17 00:00:00 2001
0097241
From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Date: Sat, 12 Sep 2015 10:17:52 +0530
0097241
Subject: [PATCH 17/26] drm/i915: WaRsUseTimeoutMode
0097241
0097241
Upstream commit e3429cd240b06c79df3ea90f28065a7e011744cd
0097241
0097241
Enable TO mode for RC6 for SKL till D0 and BXT till A0.
0097241
0097241
Cc: Tom O'Rourke <Tom.O'Rourke@intel.com>
0097241
Cc: Akash Goel <akash.goel@intel.com>
0097241
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Reviewed-by: Alex Dai <yu.dai@intel.com>
0097241
[danvet: Fixup line continuation alignment.]
0097241
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_pm.c | 13 ++++++++++---
0097241
 1 file changed, 10 insertions(+), 3 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
0097241
index 56a5568ffeb7..ab54c645c2ee 100644
0097241
--- a/drivers/gpu/drm/i915/intel_pm.c
0097241
+++ b/drivers/gpu/drm/i915/intel_pm.c
0097241
@@ -4845,9 +4845,16 @@ static void gen9_enable_rc6(struct drm_device *dev)
0097241
 		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
0097241
 	DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
0097241
 			"on" : "off");
0097241
-	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
0097241
-				   GEN6_RC_CTL_EI_MODE(1) |
0097241
-				   rc6_mask);
0097241
+
0097241
+	if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_D0) ||
0097241
+	    (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0))
0097241
+		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
0097241
+			   GEN7_RC_CTL_TO_MODE |
0097241
+			   rc6_mask);
0097241
+	else
0097241
+		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
0097241
+			   GEN6_RC_CTL_EI_MODE(1) |
0097241
+			   rc6_mask);
0097241
 
0097241
 	/*
0097241
 	 * 3b: Enable Coarse Power Gating only when RC6 is enabled.
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From a7af36dfaaa2136be0454787130f73d207c2f34d Mon Sep 17 00:00:00 2001
0097241
From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Date: Sat, 12 Sep 2015 10:17:53 +0530
0097241
Subject: [PATCH 18/26] drm/i915: WaRsDoubleRc6WrlWithCoarsePowerGating
0097241
0097241
Upstream commit 63a4dec2c168b74a39df1eac494501f0f6bf3708
0097241
0097241
Cc: Tom O'Rourke <Tom.O'Rourke@intel.com>
0097241
Cc: Akash Goel <akash.goel@intel.com>
0097241
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Reviewed-by: Alex Dai <yu.dai@intel.com>
0097241
[danvet: Fix continuation alignment.]
0097241
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_pm.c | 8 +++++++-
0097241
 1 file changed, 7 insertions(+), 1 deletion(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
0097241
index ab54c645c2ee..7c7b6386121f 100644
0097241
--- a/drivers/gpu/drm/i915/intel_pm.c
0097241
+++ b/drivers/gpu/drm/i915/intel_pm.c
0097241
@@ -4828,7 +4828,13 @@ static void gen9_enable_rc6(struct drm_device *dev)
0097241
 	I915_WRITE(GEN6_RC_CONTROL, 0);
0097241
 
0097241
 	/* 2b: Program RC6 thresholds.*/
0097241
-	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
0097241
+
0097241
+	/* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */
0097241
+	if (IS_SKYLAKE(dev) && !((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) &&
0097241
+				 (INTEL_REVID(dev) <= SKL_REVID_E0)))
0097241
+		I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
0097241
+	else
0097241
+		I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
0097241
 	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
0097241
 	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
0097241
 	for_each_ring(ring, dev_priv, unused)
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From b925cfd49203fc37c491fa28310221be23a2634d Mon Sep 17 00:00:00 2001
0097241
From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
0097241
Date: Mon, 7 Dec 2015 18:29:44 +0200
0097241
Subject: [PATCH 19/26] drm/i915/skl: Disable coarse power gating up until F0
0097241
0097241
Upstream commit 344df9809f4521c8c11d67c5ef18764b54358950
0097241
0097241
There is conflicting info between E0 and F0 steppings
0097241
for this workarounds. Trust more authoritative source and
0097241
be conservative and extend also for F0.
0097241
0097241
This prevents numerous (>50) gpu hangs with SKL GT4e
0097241
during piglit run.
0097241
0097241
References: HSD: gen9lp/2134184
0097241
Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
0097241
Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1449505785-20812-1-git-send-email-mika.kuoppala@intel.com
0097241
(cherry picked from commit 6686ece19f7446f0e29c77d9e0402e1d0ce10c48)
0097241
Cc: stable@vger.kernel.org # v4.3+
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_pm.c | 2 +-
0097241
 1 file changed, 1 insertion(+), 1 deletion(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
0097241
index 7c7b6386121f..d04f123f4ccf 100644
0097241
--- a/drivers/gpu/drm/i915/intel_pm.c
0097241
+++ b/drivers/gpu/drm/i915/intel_pm.c
0097241
@@ -4867,7 +4867,7 @@ static void gen9_enable_rc6(struct drm_device *dev)
0097241
 	 * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6.
0097241
 	 */
0097241
 	if ((IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) ||
0097241
-	    ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_E0)))
0097241
+	    ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_F0)))
0097241
 		I915_WRITE(GEN9_PG_ENABLE, 0);
0097241
 	else
0097241
 		I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 302e759f64e1c4bed49f31459329acbb2cddce8a Mon Sep 17 00:00:00 2001
0097241
From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
0097241
Date: Mon, 7 Dec 2015 18:29:45 +0200
0097241
Subject: [PATCH 20/26] drm/i915/skl: Double RC6 WRL always on
0097241
0097241
Upstream commit 6704d45528537ea6088aeea0667d87b605b82d51
0097241
0097241
WaRsDoubleRc6WrlWithCoarsePowerGating should
0097241
be enabled for all Skylakes. Make it so.
0097241
0097241
Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
0097241
Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1449505785-20812-2-git-send-email-mika.kuoppala@intel.com
0097241
(cherry picked from commit e7674b8c31717dd0c58b3a9493d43249722071eb)
0097241
Cc: stable@vger.kernel.org # v4.3+
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_pm.c | 3 +--
0097241
 1 file changed, 1 insertion(+), 2 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
0097241
index d04f123f4ccf..33db474fae02 100644
0097241
--- a/drivers/gpu/drm/i915/intel_pm.c
0097241
+++ b/drivers/gpu/drm/i915/intel_pm.c
0097241
@@ -4830,8 +4830,7 @@ static void gen9_enable_rc6(struct drm_device *dev)
0097241
 	/* 2b: Program RC6 thresholds.*/
0097241
 
0097241
 	/* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */
0097241
-	if (IS_SKYLAKE(dev) && !((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) &&
0097241
-				 (INTEL_REVID(dev) <= SKL_REVID_E0)))
0097241
+	if (IS_SKYLAKE(dev))
0097241
 		I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
0097241
 	else
0097241
 		I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From c4c390176eaf6b4321c1f90065107711845e9aff Mon Sep 17 00:00:00 2001
0097241
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
0097241
Date: Mon, 23 Nov 2015 10:25:28 +0100
0097241
Subject: [PATCH 21/26] drm/i915: Do a better job at disabling primary plane in
0097241
 the noatomic case.
0097241
0097241
Upstream commit 634b3a4a476e96816d5d6cd5bb9f8900a53f56ba
0097241
0097241
When disable_noatomic is called plane_mask is not correct yet, and
0097241
plane_state->visible = true is left as true after disabling the primary
0097241
plane.
0097241
0097241
Other planes are already disabled as part of crtc sanitization, only the
0097241
primary is left active. But the plane_mask is not updated here. It gets
0097241
updated during fb takeover in modeset_gem_init, or set to the new value
0097241
on resume.
0097241
0097241
This means that to disable the primary plane 1 << drm_plane_index(primary)
0097241
needs to be used.
0097241
0097241
Afterwards because the crtc is no longer active it's forbidden to keep
0097241
plane_state->visible set, or a WARN_ON in
0097241
intel_plane_atomic_calc_changes triggers. There are other code points
0097241
that rely on accurate plane_state->visible too, so make sure the bool is
0097241
cleared.
0097241
0097241
The other planes are already disabled in intel_sanitize_crtc, so they
0097241
don't have to be handled here.
0097241
0097241
Cc: stable@vger.kernel.org #v4.3, v4.2?
0097241
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92655
0097241
Tested-by: Tomas Mezzadra <tmezzadra@gmail.com>
0097241
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
0097241
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/5652DB88.9070208@linux.intel.com
0097241
(cherry picked from commit 54a4196188eab82e6f0a5f05716626e9f18b8fb6)
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_display.c | 4 +++-
0097241
 1 file changed, 3 insertions(+), 1 deletion(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
0097241
index 58e08fb47d1f..35fad110cc26 100644
0097241
--- a/drivers/gpu/drm/i915/intel_display.c
0097241
+++ b/drivers/gpu/drm/i915/intel_display.c
0097241
@@ -6225,9 +6225,11 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
0097241
 	if (to_intel_plane_state(crtc->primary->state)->visible) {
0097241
 		intel_crtc_wait_for_pending_flips(crtc);
0097241
 		intel_pre_disable_primary(crtc);
0097241
+
0097241
+		intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
0097241
+		to_intel_plane_state(crtc->primary->state)->visible = false;
0097241
 	}
0097241
 
0097241
-	intel_crtc_disable_planes(crtc, crtc->state->plane_mask);
0097241
 	dev_priv->display.crtc_disable(crtc);
0097241
 	intel_disable_shared_dpll(intel_crtc);
0097241
 
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 42ab5c413c7cf61fab4b2fbce9cb4ab7f7be6356 Mon Sep 17 00:00:00 2001
0097241
From: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Date: Fri, 11 Dec 2015 11:32:57 +0000
0097241
Subject: [PATCH 22/26] drm/i915: Break busywaiting for requests on pending
0097241
 signals
0097241
0097241
Upstream commit e7571f7fd66c77a760338340adbe41d994fe93ac
0097241
0097241
The busywait in __i915_spin_request() does not respect pending signals
0097241
and so may consume the entire timeslice for the task instead of
0097241
returning to userspace to handle the signal.
0097241
0097241
In the worst case this could cause a delay in signal processing of 20ms,
0097241
which would be a noticeable jitter in cursor tracking. If a higher
0097241
resolution signal was being used, for example to provide fairness of a
0097241
server timeslices between clients, we could expect to detect some
0097241
unfairness between clients (i.e. some windows not updating as fast as
0097241
others). This issue was noticed when inspecting a report of poor
0097241
interactivity resulting from excessively high __i915_spin_request usage.
0097241
0097241
Fixes regression from
0097241
commit 2def4ad99befa25775dd2f714fdd4d92faec6e34 [v4.2]
0097241
Author: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Date:   Tue Apr 7 16:20:41 2015 +0100
0097241
0097241
     drm/i915: Optimistically spin for the request completion
0097241
0097241
v2: Try to assess the impact of the bug
0097241
0097241
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
0097241
Cc: Jens Axboe <axboe@kernel.dk>
0097241
Cc; "Rogozhkin, Dmitry V" <dmitry.v.rogozhkin@intel.com>
0097241
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
0097241
Cc: Eero Tamminen <eero.t.tamminen@intel.com>
0097241
Cc: "Rantala, Valtteri" <valtteri.rantala@intel.com>
0097241
Cc: stable@vger.kernel.org
0097241
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1449833608-22125-2-git-send-email-chris@chris-wilson.co.uk
0097241
(cherry picked from commit 91b0c352ace9afec1fb51590c7b8bd60e0eb9fbd)
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/i915_gem.c | 13 ++++++++-----
0097241
 1 file changed, 8 insertions(+), 5 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
0097241
index dee065c2b6d8..c6e3ab72882f 100644
0097241
--- a/drivers/gpu/drm/i915/i915_gem.c
0097241
+++ b/drivers/gpu/drm/i915/i915_gem.c
0097241
@@ -1144,7 +1144,7 @@ static bool missed_irq(struct drm_i915_private *dev_priv,
0097241
 	return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings);
0097241
 }
0097241
 
0097241
-static int __i915_spin_request(struct drm_i915_gem_request *req)
0097241
+static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
0097241
 {
0097241
 	unsigned long timeout;
0097241
 
0097241
@@ -1156,6 +1156,9 @@ static int __i915_spin_request(struct drm_i915_gem_request *req)
0097241
 		if (i915_gem_request_completed(req, true))
0097241
 			return 0;
0097241
 
0097241
+		if (signal_pending_state(state, current))
0097241
+			break;
0097241
+
0097241
 		if (time_after_eq(jiffies, timeout))
0097241
 			break;
0097241
 
0097241
@@ -1195,6 +1198,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
0097241
 	struct drm_i915_private *dev_priv = dev->dev_private;
0097241
 	const bool irq_test_in_progress =
0097241
 		ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring);
0097241
+	int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
0097241
 	DEFINE_WAIT(wait);
0097241
 	unsigned long timeout_expire;
0097241
 	s64 before, now;
0097241
@@ -1219,7 +1223,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
0097241
 	before = ktime_get_raw_ns();
0097241
 
0097241
 	/* Optimistic spin for the next jiffie before touching IRQs */
0097241
-	ret = __i915_spin_request(req);
0097241
+	ret = __i915_spin_request(req, state);
0097241
 	if (ret == 0)
0097241
 		goto out;
0097241
 
0097241
@@ -1231,8 +1235,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
0097241
 	for (;;) {
0097241
 		struct timer_list timer;
0097241
 
0097241
-		prepare_to_wait(&ring->irq_queue, &wait,
0097241
-				interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
0097241
+		prepare_to_wait(&ring->irq_queue, &wait, state);
0097241
 
0097241
 		/* We need to check whether any gpu reset happened in between
0097241
 		 * the caller grabbing the seqno and now ... */
0097241
@@ -1250,7 +1253,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
0097241
 			break;
0097241
 		}
0097241
 
0097241
-		if (interruptible && signal_pending(current)) {
0097241
+		if (signal_pending_state(state, current)) {
0097241
 			ret = -ERESTARTSYS;
0097241
 			break;
0097241
 		}
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 8cbf415a2aadd85cf9dfab28296a821ffea96d87 Mon Sep 17 00:00:00 2001
0097241
From: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Date: Fri, 11 Dec 2015 11:32:58 +0000
0097241
Subject: [PATCH 23/26] drm/i915: Limit the busy wait on requests to 5us not
0097241
 10ms!
0097241
0097241
Upstream commit f87a780f07b22b6dc4642dbaf44af65112076cb8
0097241
0097241
When waiting for high frequency requests, the finite amount of time
0097241
required to set up the irq and wait upon it limits the response rate. By
0097241
busywaiting on the request completion for a short while we can service
0097241
the high frequency waits as quick as possible. However, if it is a slow
0097241
request, we want to sleep as quickly as possible. The tradeoff between
0097241
waiting and sleeping is roughly the time it takes to sleep on a request,
0097241
on the order of a microsecond. Based on measurements of synchronous
0097241
workloads from across big core and little atom, I have set the limit for
0097241
busywaiting as 10 microseconds. In most of the synchronous cases, we can
0097241
reduce the limit down to as little as 2 miscroseconds, but that leaves
0097241
quite a few test cases regressing by factors of 3 and more.
0097241
0097241
The code currently uses the jiffie clock, but that is far too coarse (on
0097241
the order of 10 milliseconds) and results in poor interactivity as the
0097241
CPU ends up being hogged by slow requests. To get microsecond resolution
0097241
we need to use a high resolution timer. The cheapest of which is polling
0097241
local_clock(), but that is only valid on the same CPU. If we switch CPUs
0097241
because the task was preempted, we can also use that as an indicator that
0097241
 the system is too busy to waste cycles on spinning and we should sleep
0097241
instead.
0097241
0097241
__i915_spin_request was introduced in
0097241
commit 2def4ad99befa25775dd2f714fdd4d92faec6e34 [v4.2]
0097241
Author: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Date:   Tue Apr 7 16:20:41 2015 +0100
0097241
0097241
     drm/i915: Optimistically spin for the request completion
0097241
0097241
v2: Drop full u64 for unsigned long - the timer is 32bit wraparound safe,
0097241
so we can use native register sizes on smaller architectures. Mention
0097241
the approximate microseconds units for elapsed time and add some extra
0097241
comments describing the reason for busywaiting.
0097241
0097241
v3: Raise the limit to 10us
0097241
v4: Now 5us.
0097241
0097241
Reported-by: Jens Axboe <axboe@kernel.dk>
0097241
Link: https://lkml.org/lkml/2015/11/12/621
0097241
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
0097241
Cc: "Rogozhkin, Dmitry V" <dmitry.v.rogozhkin@intel.com>
0097241
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
0097241
Cc: Eero Tamminen <eero.t.tamminen@intel.com>
0097241
Cc: "Rantala, Valtteri" <valtteri.rantala@intel.com>
0097241
Cc: stable@vger.kernel.org
0097241
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1449833608-22125-3-git-send-email-chris@chris-wilson.co.uk
0097241
(cherry picked from commit ca5b721e238226af1d767103ac852aeb8e4c0764)
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/i915_gem.c | 47 +++++++++++++++++++++++++++++++++++++++--
0097241
 1 file changed, 45 insertions(+), 2 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
0097241
index c6e3ab72882f..205316d056f1 100644
0097241
--- a/drivers/gpu/drm/i915/i915_gem.c
0097241
+++ b/drivers/gpu/drm/i915/i915_gem.c
0097241
@@ -1144,14 +1144,57 @@ static bool missed_irq(struct drm_i915_private *dev_priv,
0097241
 	return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings);
0097241
 }
0097241
 
0097241
+static unsigned long local_clock_us(unsigned *cpu)
0097241
+{
0097241
+	unsigned long t;
0097241
+
0097241
+	/* Cheaply and approximately convert from nanoseconds to microseconds.
0097241
+	 * The result and subsequent calculations are also defined in the same
0097241
+	 * approximate microseconds units. The principal source of timing
0097241
+	 * error here is from the simple truncation.
0097241
+	 *
0097241
+	 * Note that local_clock() is only defined wrt to the current CPU;
0097241
+	 * the comparisons are no longer valid if we switch CPUs. Instead of
0097241
+	 * blocking preemption for the entire busywait, we can detect the CPU
0097241
+	 * switch and use that as indicator of system load and a reason to
0097241
+	 * stop busywaiting, see busywait_stop().
0097241
+	 */
0097241
+	*cpu = get_cpu();
0097241
+	t = local_clock() >> 10;
0097241
+	put_cpu();
0097241
+
0097241
+	return t;
0097241
+}
0097241
+
0097241
+static bool busywait_stop(unsigned long timeout, unsigned cpu)
0097241
+{
0097241
+	unsigned this_cpu;
0097241
+
0097241
+	if (time_after(local_clock_us(&this_cpu), timeout))
0097241
+		return true;
0097241
+
0097241
+	return this_cpu != cpu;
0097241
+}
0097241
+
0097241
 static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
0097241
 {
0097241
 	unsigned long timeout;
0097241
+	unsigned cpu;
0097241
+
0097241
+	/* When waiting for high frequency requests, e.g. during synchronous
0097241
+	 * rendering split between the CPU and GPU, the finite amount of time
0097241
+	 * required to set up the irq and wait upon it limits the response
0097241
+	 * rate. By busywaiting on the request completion for a short while we
0097241
+	 * can service the high frequency waits as quick as possible. However,
0097241
+	 * if it is a slow request, we want to sleep as quickly as possible.
0097241
+	 * The tradeoff between waiting and sleeping is roughly the time it
0097241
+	 * takes to sleep on a request, on the order of a microsecond.
0097241
+	 */
0097241
 
0097241
 	if (i915_gem_request_get_ring(req)->irq_refcount)
0097241
 		return -EBUSY;
0097241
 
0097241
-	timeout = jiffies + 1;
0097241
+	timeout = local_clock_us(&cpu) + 5;
0097241
 	while (!need_resched()) {
0097241
 		if (i915_gem_request_completed(req, true))
0097241
 			return 0;
0097241
@@ -1159,7 +1202,7 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
0097241
 		if (signal_pending_state(state, current))
0097241
 			break;
0097241
 
0097241
-		if (time_after_eq(jiffies, timeout))
0097241
+		if (busywait_stop(timeout, cpu))
0097241
 			break;
0097241
 
0097241
 		cpu_relax_lowlatency();
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 7b94b8683d8d2ac4b29099e24e351e03f163e462 Mon Sep 17 00:00:00 2001
0097241
From: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Date: Fri, 11 Dec 2015 11:32:59 +0000
0097241
Subject: [PATCH 24/26] drm/i915: Only spin whilst waiting on the current
0097241
 request
0097241
0097241
Upstream commit 0f0cd472062eca6f9fac8be0cd5585f9a2df1ab2
0097241
0097241
Limit busywaiting only to the request currently being processed by the
0097241
GPU. If the request is not currently being processed by the GPU, there
0097241
is a very low likelihood of it being completed within the 2 microsecond
0097241
spin timeout and so we will just be wasting CPU cycles.
0097241
0097241
v2: Check for logical inversion when rebasing - we were incorrectly
0097241
checking for this request being active, and instead busywaiting for
0097241
when the GPU was not yet processing the request of interest.
0097241
0097241
v3: Try another colour for the seqno names.
0097241
v4: Another colour for the function names.
0097241
0097241
v5: Remove the forced coherency when checking for the active request. On
0097241
reflection and plenty of recent experimentation, the issue is not a
0097241
cache coherency problem - but an irq/seqno ordering problem (timing issue).
0097241
Here, we do not need the w/a to force ordering of the read with an
0097241
interrupt.
0097241
0097241
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
0097241
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
0097241
Cc: "Rogozhkin, Dmitry V" <dmitry.v.rogozhkin@intel.com>
0097241
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
0097241
Cc: Eero Tamminen <eero.t.tamminen@intel.com>
0097241
Cc: "Rantala, Valtteri" <valtteri.rantala@intel.com>
0097241
Cc: stable@vger.kernel.org
0097241
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1449833608-22125-4-git-send-email-chris@chris-wilson.co.uk
0097241
(cherry picked from commit 821485dc2ad665f136c57ee589bf7a8210160fe2)
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/i915_drv.h | 27 +++++++++++++++++++--------
0097241
 drivers/gpu/drm/i915/i915_gem.c |  8 +++++++-
0097241
 2 files changed, 26 insertions(+), 9 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
0097241
index 475b03e9d584..bd6df685ae61 100644
0097241
--- a/drivers/gpu/drm/i915/i915_drv.h
0097241
+++ b/drivers/gpu/drm/i915/i915_drv.h
0097241
@@ -2178,8 +2178,17 @@ struct drm_i915_gem_request {
0097241
 	struct drm_i915_private *i915;
0097241
 	struct intel_engine_cs *ring;
0097241
 
0097241
-	/** GEM sequence number associated with this request. */
0097241
-	uint32_t seqno;
0097241
+	 /** GEM sequence number associated with the previous request,
0097241
+	  * when the HWS breadcrumb is equal to this the GPU is processing
0097241
+	  * this request.
0097241
+	  */
0097241
+	u32 previous_seqno;
0097241
+
0097241
+	 /** GEM sequence number associated with this request,
0097241
+	  * when the HWS breadcrumb is equal or greater than this the GPU
0097241
+	  * has finished processing this request.
0097241
+	  */
0097241
+	u32 seqno;
0097241
 
0097241
 	/** Position in the ringbuffer of the start of the request */
0097241
 	u32 head;
0097241
@@ -2880,15 +2889,17 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
0097241
 	return (int32_t)(seq1 - seq2) >= 0;
0097241
 }
0097241
 
0097241
+static inline bool i915_gem_request_started(struct drm_i915_gem_request *req,
0097241
+					   bool lazy_coherency)
0097241
+{
0097241
+	u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
0097241
+	return i915_seqno_passed(seqno, req->previous_seqno);
0097241
+}
0097241
+
0097241
 static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
0097241
 					      bool lazy_coherency)
0097241
 {
0097241
-	u32 seqno;
0097241
-
0097241
-	BUG_ON(req == NULL);
0097241
-
0097241
-	seqno = req->ring->get_seqno(req->ring, lazy_coherency);
0097241
-
0097241
+	u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
0097241
 	return i915_seqno_passed(seqno, req->seqno);
0097241
 }
0097241
 
0097241
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
0097241
index 205316d056f1..1bf658dc6553 100644
0097241
--- a/drivers/gpu/drm/i915/i915_gem.c
0097241
+++ b/drivers/gpu/drm/i915/i915_gem.c
0097241
@@ -1191,9 +1191,13 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
0097241
 	 * takes to sleep on a request, on the order of a microsecond.
0097241
 	 */
0097241
 
0097241
-	if (i915_gem_request_get_ring(req)->irq_refcount)
0097241
+	if (req->ring->irq_refcount)
0097241
 		return -EBUSY;
0097241
 
0097241
+	/* Only spin if we know the GPU is processing this request */
0097241
+	if (!i915_gem_request_started(req, true))
0097241
+		return -EAGAIN;
0097241
+
0097241
 	timeout = local_clock_us(&cpu) + 5;
0097241
 	while (!need_resched()) {
0097241
 		if (i915_gem_request_completed(req, true))
0097241
@@ -1207,6 +1211,7 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
0097241
 
0097241
 		cpu_relax_lowlatency();
0097241
 	}
0097241
+
0097241
 	if (i915_gem_request_completed(req, false))
0097241
 		return 0;
0097241
 
0097241
@@ -2591,6 +2596,7 @@ void __i915_add_request(struct drm_i915_gem_request *request,
0097241
 	request->batch_obj = obj;
0097241
 
0097241
 	request->emitted_jiffies = jiffies;
0097241
+	request->previous_seqno = ring->last_submitted_seqno;
0097241
 	ring->last_submitted_seqno = request->seqno;
0097241
 	list_add_tail(&request->list, &ring->request_list);
0097241
 
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From bf0176f1bb4bb6316102f4ca4d9314a20c228098 Mon Sep 17 00:00:00 2001
0097241
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
0097241
Date: Fri, 18 Dec 2015 19:24:39 +0200
0097241
Subject: [PATCH 25/26] drm/i915: Workaround CHV pipe C cursor fail
0097241
MIME-Version: 1.0
0097241
Content-Type: text/plain; charset=UTF-8
0097241
Content-Transfer-Encoding: 8bit
0097241
0097241
Upstream commit ef8dd37af85a8f37ca3a29074647511e52c56181
0097241
0097241
Turns out CHV pipe C was glued on somewhat poorly, and there's something
0097241
wrong with the cursor. If the cursor straddles the left screen edge,
0097241
and is then moved away from the edge or disabled, the pipe will often
0097241
underrun. If enough underruns are triggered quickly enough the pipe
0097241
will fall over and die (it just scans out a solid color and reports
0097241
a constant underrun). We need to turn the disp2d power well off and
0097241
on again to recover the pipe.
0097241
0097241
None of that is very nice for the user, so let's just refuse to place
0097241
the cursor in the compromised position. The ddx appears to fall back
0097241
to swcursor when the ioctl returns an error, so theoretically there's
0097241
no loss of functionality for the user (discounting swcursor bugs).
0097241
I suppose most cursors images actually have the hotspot not exactly
0097241
at 0,0 so under typical conditions the fallback will in fact kick in
0097241
as soon as the cursor touches the left edge of the screen.
0097241
0097241
Any atomic compositor should anyway be prepared to fall back to
0097241
GPU composition when things don't work out, so there should be no
0097241
problem with those.
0097241
0097241
Other things that I tried to solve this include flipping all
0097241
display related clock gating knobs I could find, increasing the
0097241
minimum gtt alignment all the way up to 512k. I also tried to see
0097241
if there are more specific screen coordinates that hit the bug, but
0097241
the findings were somewhat inconclusive. Sometimes the failures
0097241
happen almost across the whole left edge, sometimes more at the very
0097241
top and around the bottom half. I wasn't able to find any real pattern
0097241
to these variations, so it seems our only choice is to just refuse
0097241
to straddle the left screen edge at all.
0097241
0097241
Cc: stable@vger.kernel.org
0097241
Cc: Jason Plum <max@warheads.net>
0097241
Testcase: igt/kms_chv_cursor_fail
0097241
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92826
0097241
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1450459479-16286-1-git-send-email-ville.syrjala@linux.intel.com
0097241
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
(cherry picked from commit b29ec92c4f5e6d45d8bae8194e664427a01c6687)
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++++
0097241
 1 file changed, 17 insertions(+)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
0097241
index 35fad110cc26..c70a6cb8914f 100644
0097241
--- a/drivers/gpu/drm/i915/intel_display.c
0097241
+++ b/drivers/gpu/drm/i915/intel_display.c
0097241
@@ -13614,6 +13614,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
0097241
 	struct drm_crtc *crtc = crtc_state->base.crtc;
0097241
 	struct drm_framebuffer *fb = state->base.fb;
0097241
 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
0097241
+	enum pipe pipe = to_intel_plane(plane)->pipe;
0097241
 	unsigned stride;
0097241
 	int ret;
0097241
 
0097241
@@ -13647,6 +13648,22 @@ intel_check_cursor_plane(struct drm_plane *plane,
0097241
 		return -EINVAL;
0097241
 	}
0097241
 
0097241
+	/*
0097241
+	 * There's something wrong with the cursor on CHV pipe C.
0097241
+	 * If it straddles the left edge of the screen then
0097241
+	 * moving it away from the edge or disabling it often
0097241
+	 * results in a pipe underrun, and often that can lead to
0097241
+	 * dead pipe (constant underrun reported, and it scans
0097241
+	 * out just a solid color). To recover from that, the
0097241
+	 * display power well must be turned off and on again.
0097241
+	 * Refuse the put the cursor into that compromised position.
0097241
+	 */
0097241
+	if (IS_CHERRYVIEW(plane->dev) && pipe == PIPE_C &&
0097241
+	    state->visible && state->base.crtc_x < 0) {
0097241
+		DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
0097241
+		return -EINVAL;
0097241
+	}
0097241
+
0097241
 	return 0;
0097241
 }
0097241
 
0097241
-- 
0097241
2.5.0
0097241
0097241
0097241
From 036933da945df1526e0b5ee17fe8a8a77c1380e7 Mon Sep 17 00:00:00 2001
0097241
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
0097241
Date: Thu, 10 Dec 2015 18:22:31 +0200
0097241
Subject: [PATCH 26/26] drm/i915: Unbreak check_digital_port_conflicts()
0097241
MIME-Version: 1.0
0097241
Content-Type: text/plain; charset=UTF-8
0097241
Content-Transfer-Encoding: 8bit
0097241
0097241
Upstream commit ae35b56e367b9fef7f5de701cf8c1c3dd954dded
0097241
0097241
Atomic changes broke check_digital_port_conflicts(). It needs to look
0097241
at the global situation instead of just trying to find a conflict
0097241
within the current atomic state.
0097241
0097241
This bug made my HSW explode spectacularly after I had split the DDI
0097241
encoders into separate DP and HDMI encoders. With the fix, things
0097241
seem much more solid.
0097241
0097241
I hope holding the connection_mutex is enough protection that we can
0097241
actually walk the connectors even if they're not part of the current
0097241
atomic state...
0097241
0097241
v2: Regenerate the patch so that it actually applies (Jani)
0097241
0097241
Cc: stable@vger.kernel.org
0097241
Cc: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
0097241
Fixes: 5448a00d3f06 ("drm/i915: Don't use staged config in check_digital_port_conflicts()")
0097241
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
0097241
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
0097241
Link: http://patchwork.freedesktop.org/patch/msgid/1449764551-12466-1-git-send-email-ville.syrjala@linux.intel.com
0097241
(cherry picked from commit 0bff4858653312a10c83709e0009c3adb87e6f1e)
0097241
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
0097241
---
0097241
 drivers/gpu/drm/i915/intel_display.c | 12 ++++++++----
0097241
 1 file changed, 8 insertions(+), 4 deletions(-)
0097241
0097241
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
0097241
index c70a6cb8914f..aafe3e3de3ae 100644
0097241
--- a/drivers/gpu/drm/i915/intel_display.c
0097241
+++ b/drivers/gpu/drm/i915/intel_display.c
0097241
@@ -12026,18 +12026,22 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
0097241
 static bool check_digital_port_conflicts(struct drm_atomic_state *state)
0097241
 {
0097241
 	struct drm_device *dev = state->dev;
0097241
-	struct intel_encoder *encoder;
0097241
 	struct drm_connector *connector;
0097241
-	struct drm_connector_state *connector_state;
0097241
 	unsigned int used_ports = 0;
0097241
-	int i;
0097241
 
0097241
 	/*
0097241
 	 * Walk the connector list instead of the encoder
0097241
 	 * list to detect the problem on ddi platforms
0097241
 	 * where there's just one encoder per digital port.
0097241
 	 */
0097241
-	for_each_connector_in_state(state, connector, connector_state, i) {
0097241
+	drm_for_each_connector(connector, dev) {
0097241
+		struct drm_connector_state *connector_state;
0097241
+		struct intel_encoder *encoder;
0097241
+
0097241
+		connector_state = drm_atomic_get_existing_connector_state(state, connector);
0097241
+		if (!connector_state)
0097241
+			connector_state = connector->state;
0097241
+
0097241
 		if (!connector_state->best_encoder)
0097241
 			continue;
0097241
 
0097241
-- 
0097241
2.5.0
0097241